From fec4816387a978e651da74c83bcdd5019a6d024c Mon Sep 17 00:00:00 2001
From: Masahiro Yamada <yamada.masahiro@socionext.com>
Date: Tue, 2 Feb 2016 21:11:31 +0900
Subject: [PATCH] ARM: uniphier: support USB boot mode for ProXstream2 /
 PH1-LD6b SoC

The USB boot code is too fat and complicated to be included in SPL
(at least for now).  So, it was implemented as a separate project
(what we call USB-loader).

The expected boot sequence is as follows:

  Boot ROM -> USB-loader -> SPL -> U-Boot proper

The USB-loader loads the SPL and U-Boot proper from a USB memory
onto the locked L2 cache.  Then, SPL needs to copy the U-Boot proper
to DRAM, so this mode looks like a NOR boot from the view of SPL.
However, we want to distinguish between (genuine) NOR boot and USB
boot in some places.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
 arch/arm/mach-uniphier/board_late_init.c              |  8 +++++++-
 arch/arm/mach-uniphier/boot-mode/boot-device.h        |  2 ++
 .../mach-uniphier/boot-mode/boot-mode-proxstream2.c   |  3 +++
 arch/arm/mach-uniphier/boot-mode/boot-mode.c          | 11 ++++++++++-
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-uniphier/board_late_init.c b/arch/arm/mach-uniphier/board_late_init.c
index c2a32618acc..eba48a248dc 100644
--- a/arch/arm/mach-uniphier/board_late_init.c
+++ b/arch/arm/mach-uniphier/board_late_init.c
@@ -11,6 +11,8 @@
 #include <linux/io.h>
 #include <../drivers/mtd/nand/denali.h>
 
+#include "boot-mode/boot-device.h"
+
 static void nand_denali_wp_disable(void)
 {
 #ifdef CONFIG_NAND_DENALI
@@ -62,7 +64,7 @@ int board_late_init(void)
 {
 	puts("MODE:  ");
 
-	switch (spl_boot_device()) {
+	switch (spl_boot_device_raw()) {
 	case BOOT_DEVICE_MMC1:
 		printf("eMMC Boot\n");
 		setenv("bootmode", "emmcboot");
@@ -76,6 +78,10 @@ int board_late_init(void)
 		printf("NOR Boot\n");
 		setenv("bootmode", "norboot");
 		break;
+	case BOOT_DEVICE_USB:
+		printf("USB Boot\n");
+		setenv("bootmode", "usbboot");
+		break;
 	default:
 		printf("Unsupported Boot Mode\n");
 		return -1;
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-device.h b/arch/arm/mach-uniphier/boot-mode/boot-device.h
index 2ab5a535fa0..1c59aaa6069 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-device.h
+++ b/arch/arm/mach-uniphier/boot-mode/boot-device.h
@@ -22,4 +22,6 @@ void ph1_ld4_boot_mode_show(void);
 void ph1_pro5_boot_mode_show(void);
 void proxstream2_boot_mode_show(void);
 
+u32 spl_boot_device_raw(void);
+
 #endif /* _ASM_BOOT_DEVICE_H_ */
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c
index 3769ec555b8..1b0c183808f 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c
+++ b/arch/arm/mach-uniphier/boot-mode/boot-mode-proxstream2.c
@@ -55,6 +55,9 @@ u32 proxstream2_boot_device(void)
 {
 	int boot_mode;
 
+	if (readl(SG_PINMON0) & BIT(6))
+		return BOOT_DEVICE_USB;
+
 	boot_mode = get_boot_mode_sel();
 
 	return boot_device_table[boot_mode].type;
diff --git a/arch/arm/mach-uniphier/boot-mode/boot-mode.c b/arch/arm/mach-uniphier/boot-mode/boot-mode.c
index 0c5749badbb..935e551472c 100644
--- a/arch/arm/mach-uniphier/boot-mode/boot-mode.c
+++ b/arch/arm/mach-uniphier/boot-mode/boot-mode.c
@@ -11,7 +11,7 @@
 #include "../soc-info.h"
 #include "boot-device.h"
 
-u32 spl_boot_device(void)
+u32 spl_boot_device_raw(void)
 {
 	if (boot_is_swapped())
 		return BOOT_DEVICE_NOR;
@@ -43,3 +43,12 @@ u32 spl_boot_device(void)
 		return BOOT_DEVICE_NONE;
 	}
 }
+
+u32 spl_boot_device(void)
+{
+	u32 ret;
+
+	ret = spl_boot_device_raw();
+
+	return ret == BOOT_DEVICE_USB ? BOOT_DEVICE_NOR : ret;
+}
-- 
GitLab