ARM: UniPhier: detect the number of flash banks at run-time
authorMasahiro Yamada <yamada.m@jp.panasonic.com>
Fri, 5 Dec 2014 15:03:26 +0000 (00:03 +0900)
committerMasahiro Yamada <yamada.m@jp.panasonic.com>
Mon, 8 Dec 2014 15:08:33 +0000 (00:08 +0900)
Some UniPhier boards are equipped with an expansion slot that
some optional SRAM/NOR-flash cards can be attached to.  So, run-time
detection of the number of flash banks would be more user-friendly.

Until this commit, UniPhier boards have achieved this by (ab)using
board_flash_wp_on() because the boot failed if flash_size got zero.
Fortunately, this problem was solved by commit 70879a92561a (flash:
do not fail even if flash_size is zero).

Now it is possible to throw away such a tricky workaround.  This
commit also enables CONFIG_SYS_MAX_FLASH_BANKS_DETECT for further
refactoring.

Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
arch/arm/cpu/armv7/uniphier/Makefile
arch/arm/cpu/armv7/uniphier/board_early_init_r.c [new file with mode: 0644]
arch/arm/cpu/armv7/uniphier/support_card.c
arch/arm/include/asm/arch-uniphier/board.h
include/configs/uniphier.h

index 0f64d2591c0e9c0aef7303fb7ae6a9337db76df9..4a7b8a9d0815a7fd5d87cbfdc69f1238f6889f64 100644 (file)
@@ -11,6 +11,7 @@ obj-y += cache_uniphier.o
 obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o
 obj-y += dram_init.o
 obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o
+obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o
 obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o
 obj-$(CONFIG_UNIPHIER_SMP) += smp.o
 obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o
diff --git a/arch/arm/cpu/armv7/uniphier/board_early_init_r.c b/arch/arm/cpu/armv7/uniphier/board_early_init_r.c
new file mode 100644 (file)
index 0000000..cb7e04f
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/board.h>
+
+int board_early_init_r(void)
+{
+       uniphier_board_late_init();
+       return 0;
+}
index 40d49409c27814d7831456dffe4f7c640b9010a9..419012e1ab64367ae5dcbf8f24ef27124115a60b 100644 (file)
@@ -83,6 +83,12 @@ static int support_card_show_revision(void)
 }
 #endif
 
+int check_support_card(void)
+{
+       printf("SC:    Micro Support Card ");
+       return support_card_show_revision();
+}
+
 void support_card_init(void)
 {
        /*
@@ -94,12 +100,6 @@ void support_card_init(void)
        support_card_reset_deassert();
 }
 
-int check_support_card(void)
-{
-       printf("SC:    Micro Support Card ");
-       return support_card_show_revision();
-}
-
 #if defined(CONFIG_SMC911X)
 #include <netdev.h>
 
@@ -112,18 +112,14 @@ int board_eth_init(bd_t *bis)
 #if !defined(CONFIG_SYS_NO_FLASH)
 
 #include <mtd/cfi_flash.h>
+#include <asm/arch/sbc-regs.h>
 
-#if CONFIG_SYS_MAX_FLASH_BANKS > 1
-static phys_addr_t flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS] =
-                                       CONFIG_SYS_FLASH_BANKS_LIST;
+struct memory_bank {
+       phys_addr_t base;
+       unsigned long size;
+};
 
-phys_addr_t cfi_flash_bank_addr(int i)
-{
-       return flash_banks_list[i];
-}
-#endif
-
-int mem_is_flash(phys_addr_t base)
+static int mem_is_flash(const struct memory_bank *mem)
 {
        const int loop = 128;
        u32 *scratch_addr;
@@ -131,8 +127,9 @@ int mem_is_flash(phys_addr_t base)
        int ret = 1;
        int i;
 
-       scratch_addr = map_physmem(base + 0x01e00000,
-                                       sizeof(u32) * loop, MAP_NOCACHE);
+       /* just in case, use the tail of the memory bank */
+       scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop,
+                                  sizeof(u32) * loop, MAP_NOCACHE);
 
        for (i = 0; i < loop; i++, scratch_addr++) {
                saved_value = readl(scratch_addr);
@@ -150,31 +147,79 @@ int mem_is_flash(phys_addr_t base)
        return ret;
 }
 
-int board_flash_wp_on(void)
+#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD)
+       /* {address, size} */
+static const struct memory_bank memory_banks_boot_swap_off[] = {
+       {0x02000000, 0x01f00000},
+};
+
+static const struct memory_bank memory_banks_boot_swap_on[] = {
+       {0x00000000, 0x01f00000},
+};
+#endif
+
+#if defined(CONFIG_DCC_MICRO_SUPPORT_CARD)
+static const struct memory_bank memory_banks_boot_swap_off[] = {
+       {0x04000000, 0x04000000},
+};
+
+static const struct memory_bank memory_banks_boot_swap_on[] = {
+       {0x00000000, 0x04000000},
+       {0x04000000, 0x04000000},
+};
+#endif
+
+static const struct memory_bank
+*flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT];
+
+phys_addr_t cfi_flash_bank_addr(int i)
 {
-       int i;
-       int ret = 1;
+       return flash_banks_list[i]->base;
+}
 
-       for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
-               if (mem_is_flash(cfi_flash_bank_addr(i))) {
-                       /*
-                        * We found at least one flash.
-                        * We need to return 0 and call flash_init().
-                        */
-                       ret = 0;
-               }
-#if CONFIG_SYS_MAX_FLASH_BANKS > 1
-               else {
-                       /*
-                        * We might have a SRAM here.
-                        * To prevent SRAM data from being destroyed,
-                        * we set dummy address (SDRAM).
-                        */
-                       flash_banks_list[i] = 0x80000000 + 0x10000 * i;
+unsigned long cfi_flash_bank_size(int i)
+{
+       return flash_banks_list[i]->size;
+}
+
+static void detect_num_flash_banks(void)
+{
+       const struct memory_bank *memory_bank, *end;
+
+       cfi_flash_num_flash_banks = 0;
+
+       if (boot_is_swapped()) {
+               memory_bank = memory_banks_boot_swap_on;
+               end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_on);
+       } else {
+               memory_bank = memory_banks_boot_swap_off;
+               end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_off);
+       }
+
+       for (; memory_bank < end; memory_bank++) {
+               if (cfi_flash_num_flash_banks >=
+                   CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
+                       break;
+
+               if (mem_is_flash(memory_bank)) {
+                       flash_banks_list[cfi_flash_num_flash_banks] =
+                                                               memory_bank;
+
+                       debug("flash bank found: base = 0x%lx, size = 0x%lx\n",
+                             memory_bank->base, memory_bank->size);
+                       cfi_flash_num_flash_banks++;
                }
-#endif
        }
 
-       return ret;
+       debug("number of flash banks: %d\n", cfi_flash_num_flash_banks);
+}
+#else /* ONFIG_SYS_NO_FLASH */
+void detect_num_flash_banks(void)
+{
+};
+#endif /* ONFIG_SYS_NO_FLASH */
+
+void support_card_late_init(void)
+{
+       detect_num_flash_banks();
 }
-#endif
index e6ba4e4ee4d624abacc5457cadf1d43973d44cc2..e3cba5befe2a8cdd1518caef2d47fe8f6953619b 100644 (file)
        defined(CONFIG_DCC_MICRO_SUPPORT_CARD)
 void support_card_reset(void);
 void support_card_init(void);
+void support_card_late_init(void);
 int check_support_card(void);
 #else
 #define support_card_reset() do {} while (0)
 #define support_card_init()  do {} while (0)
+#define support_card_late_init()  do {} while (0)
 static inline int check_support_card(void)
 {
        return 0;
@@ -32,4 +34,9 @@ static inline void uniphier_board_init(void)
        support_card_init();
 }
 
+static inline void uniphier_board_late_init(void)
+{
+       support_card_late_init();
+}
+
 #endif /* ARCH_BOARD_H */
index 733e6fade3836820dc3d68166fdc4939eeee43c8..dd022fb52da88ff7121a5cb7c283eda0191c9acd 100644 (file)
@@ -92,6 +92,7 @@
 
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_R
 #define CONFIG_BOARD_LATE_INIT
 
 #define CONFIG_SYS_MALLOC_LEN          (4 * 1024 * 1024)
 
 #define CONFIG_FLASH_SHOW_PROGRESS     45 /* count down from 45/5: 9..1 */
 
-#if defined(CONFIG_PFC_MICRO_SUPPORT_CARD)
-# define CONFIG_SYS_MAX_FLASH_BANKS    1
-# define CONFIG_SYS_FLASH_BANKS_LIST   {0x00000000}
-# define CONFIG_SYS_FLASH_BANKS_SIZES  {0x02000000}
-#endif
-
-#if defined(CONFIG_DCC_MICRO_SUPPORT_CARD)
-# define CONFIG_SYS_MAX_FLASH_BANKS    1
-# define CONFIG_SYS_FLASH_BANKS_LIST   {0x04000000}
-# define CONFIG_SYS_FLASH_BANKS_SIZES  {0x04000000}
-#endif
+#define CONFIG_SYS_MAX_FLASH_BANKS_DETECT 2
 
 /* serial console configuration */
 #define CONFIG_BAUDRATE                        115200