[U-Boot] [PATCH 00/29] blackfin: Add driver-model and device tree suport

At present the only serial driver that is not converted to driver mode is blackfin. As I recently obtained a suitable board from a kind donor I have decided to convert the driver over, as the unpalatable alternative would be to remove blackfin support from U-Boot.
Blackfin's init sequence is someone non-standard. This series adjusts this to fit more with how things are now done, adds device-tree support, a serial driver and enables driver model on bf537-stamp.
A few CONFIG options are dropped in this series also, as these were noticed along the way.
Future work could enhance the serial driver to support v4 hardware and convert all boards to driver model.
Simon Glass (29): blackfin: Drop CONFIG_SYS_MEMTEST_START/END fdt: Allow the device tree to be set up by board init code blackfin: Add a few useful linker symbols blackfin: Drop the extra blank line in the link script blackfin: Use compiler-generated symbols for BSS blackfin: Clear the BSS in C code blackfin: Add a memory region for pre-relocation data blackfin: Use generic board to set the stack address blackfin: Avoid using bd_info in print_cpuinfo() blackfin: Avoiding using P3 in early init blackfin: Allow cpu_init_f() to return blackfin: Drop CONFIG_STACKBASE tegra: Drop CONFIG_STACKBASE in favour of TEGRA_STACKBASE sparc: Drop CONFIG_SYS_MALLOC_BASE blackfin: Drop CONFIG_SYS_MALLOC_BASE Drop CONFIG_SYS_MALLOC_END blackfin: Call C code to relocate blackfin: Don't set global_data again blackfin: Set the RAM size separately from bd_info blackfin: Set up bd_info later blackfin: Copy the device tree out of BSS blackfin: Allow use of CONFIG_OF_CONTROL blackfin: bf537-stamp: Enable CONFIG_OF_CONTROL dm: serial: Reset the watchdog when outputting characters dm: serial: pxa: Drop pxa from the serial README dm: serial: Update the serial README dm: blackfin: Add a driver-model serial driver blackfin: Set up the debug UART if enabled blackfin: Enable driver-model on bf537-stamp
arch/Kconfig | 1 + arch/blackfin/Kconfig | 9 ++ arch/blackfin/cpu/cpu.c | 69 +++++++------ arch/blackfin/cpu/start.S | 35 +++---- arch/blackfin/cpu/u-boot.lds | 24 ++++- arch/blackfin/dts/Makefile | 18 ++++ arch/blackfin/dts/bf537-stamp.dts | 11 +++ arch/blackfin/include/asm/config.h | 12 --- arch/blackfin/include/asm/serial1.h | 2 + arch/blackfin/include/asm/u-boot.h | 5 + arch/blackfin/lib/sections.c | 2 +- cmd/bdinfo.c | 2 - configs/bf537-stamp_defconfig | 8 ++ doc/driver-model/serial-howto.txt | 11 +-- drivers/serial/Kconfig | 8 ++ drivers/serial/serial-uclass.c | 2 + drivers/serial/serial_bfin.c | 192 ++++++++++++++++++++++++++++++++++++ include/configs/bf537-stamp.h | 1 + include/configs/bf609-ezkit.h | 1 - include/configs/gr_cpci_ax2000.h | 5 +- include/configs/gr_ep2s60.h | 5 +- include/configs/gr_xc3s_1500.h | 5 +- include/configs/grsim.h | 5 +- include/configs/grsim_leon2.h | 5 +- include/configs/openrisc-generic.h | 3 - include/configs/s32v234evb.h | 4 - include/configs/tegra-common.h | 2 +- include/configs/tegra114-common.h | 2 +- include/configs/tegra124-common.h | 2 +- include/configs/tegra186-common.h | 2 +- include/configs/tegra20-common.h | 2 +- include/configs/tegra210-common.h | 2 +- include/configs/tegra30-common.h | 2 +- lib/fdtdec.c | 31 +++--- scripts/config_whitelist.txt | 3 - 35 files changed, 360 insertions(+), 133 deletions(-) create mode 100644 arch/blackfin/dts/Makefile create mode 100644 arch/blackfin/dts/bf537-stamp.dts

These are not used since the 'mtest' command is not enabled on blackfin. They are also a pain since they pre-suppose the memory layout. Drop them.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/include/asm/config.h | 6 ------ include/configs/bf609-ezkit.h | 1 - 2 files changed, 7 deletions(-)
diff --git a/arch/blackfin/include/asm/config.h b/arch/blackfin/include/asm/config.h index de3c979..27e8f3d 100644 --- a/arch/blackfin/include/asm/config.h +++ b/arch/blackfin/include/asm/config.h @@ -112,12 +112,6 @@ #ifndef CONFIG_STACKBASE # define CONFIG_STACKBASE (CONFIG_SYS_MALLOC_BASE - 4) #endif -#ifndef CONFIG_SYS_MEMTEST_START -# define CONFIG_SYS_MEMTEST_START 0 -#endif -#ifndef CONFIG_SYS_MEMTEST_END -# define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 8192 + 4) -#endif #ifndef CONFIG_SYS_POST_WORD_ADDR # define CONFIG_SYS_POST_WORD_ADDR (L1_DATA_B_SRAM + L1_DATA_B_SRAM_SIZE - 4) #endif diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h index 4deb2d2..76bb485 100644 --- a/include/configs/bf609-ezkit.h +++ b/include/configs/bf609-ezkit.h @@ -138,7 +138,6 @@
#define CONFIG_CMD_SOFTSWITCH
-#define CONFIG_SYS_MEMTEST_END (CONFIG_STACKBASE - 20*1024*1024 + 4) #define CONFIG_BFIN_SOFT_SWITCH
#define CONFIG_ADI_GPIO2

On blackfin we need to relocate the device tree early on during boot because it breaks the rules of not accessing BSS before relocation. To accommodate this, add a check to see if the device tree pointer is already set up. If it is, leave it alone.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/fdtdec.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4e619c4..c484950 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1177,26 +1177,31 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index, int fdtdec_setup(void) { #if CONFIG_IS_ENABLED(OF_CONTROL) + if (!gd->fdt_blob) { # ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; + /* Get a pointer to the FDT */ + gd->fdt_blob = __dtb_dt_begin; # elif defined CONFIG_OF_SEPARATE # ifdef CONFIG_SPL_BUILD - /* FDT is at end of BSS unless it is in a different memory region */ - if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) - gd->fdt_blob = (ulong *)&_image_binary_end; - else - gd->fdt_blob = (ulong *)&__bss_end; + /* + * FDT is at end of BSS unless it is in a different memory + * region + */ + if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) + gd->fdt_blob = (ulong *)&_image_binary_end; + else + gd->fdt_blob = (ulong *)&__bss_end; # else - /* FDT is at end of image */ - gd->fdt_blob = (ulong *)&_end; + /* FDT is at end of image */ + gd->fdt_blob = (ulong *)&_end; # endif # elif defined(CONFIG_OF_HOSTFILE) - if (sandbox_read_fdt_from_file()) { - puts("Failed to read control FDT\n"); - return -1; - } + if (sandbox_read_fdt_from_file()) { + puts("Failed to read control FDT\n"); + return -1; + } # endif + } # ifndef CONFIG_SPL_BUILD /* Allow the early environment to override the fdt address */ gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,

Add _image_copy_start, __end and __image_binary_end so we can use the standard mechanism for locating the device tree. This only works if data follow text, so use an #ifdef to ensure that for now.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/u-boot.lds | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/blackfin/cpu/u-boot.lds b/arch/blackfin/cpu/u-boot.lds index f407fb2..30964ad 100644 --- a/arch/blackfin/cpu/u-boot.lds +++ b/arch/blackfin/cpu/u-boot.lds @@ -61,6 +61,9 @@ SECTIONS { .text.pre : { +#ifndef CONFIG_MEM_SIZE + _image_copy_start = .; +#endif arch/blackfin/cpu/start.o (.text .text.*)
LDS_BOARD_TEXT @@ -125,6 +128,8 @@ SECTIONS __data_l1_lma = LOADADDR(.data_l1); __data_l1_len = SIZEOF(.data_l1); ASSERT (__data_l1_len <= L1_DATA_B_SRAM_SIZE, "L1 data overflow!") + __end = __data_l1_lma; + __image_binary_end = __data_l1_lma;
.bss : {

There is an extra blank line in this script. Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/u-boot.lds | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/blackfin/cpu/u-boot.lds b/arch/blackfin/cpu/u-boot.lds index 30964ad..1c0df25 100644 --- a/arch/blackfin/cpu/u-boot.lds +++ b/arch/blackfin/cpu/u-boot.lds @@ -99,7 +99,6 @@ SECTIONS CONSTRUCTORS } >ram_data
- .u_boot_list : { KEEP(*(SORT(.u_boot_list*))); } >ram_data

Adjust the code to work as on ARM, where the compiler generates the BSS symbols. This makes it easier to move the BSS memset() to C code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/start.S | 4 ++-- arch/blackfin/cpu/u-boot.lds | 18 ++++++++++++++++-- arch/blackfin/lib/sections.c | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 823a1df..6265a51 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -196,8 +196,8 @@ ENTRY(_start) * takes care of clearing things for us. */ serial_early_puts("Zero BSS"); - r0.l = __bss_start; - r0.h = __bss_start; + r0.l = ___bss_start; + r0.h = ___bss_start; r1 = 0 (x); r2.l = __bss_len; r2.h = __bss_len; diff --git a/arch/blackfin/cpu/u-boot.lds b/arch/blackfin/cpu/u-boot.lds index 1c0df25..ba95bf3 100644 --- a/arch/blackfin/cpu/u-boot.lds +++ b/arch/blackfin/cpu/u-boot.lds @@ -130,6 +130,16 @@ SECTIONS __end = __data_l1_lma; __image_binary_end = __data_l1_lma;
+ /* + * Compiler-generated __bss_start and __bss_stop: + * see arch/blackfin/lib/sections.c + */ + .bss_start (NOLOAD) : + { + . = ALIGN(4); + KEEP(*(.__bss_start)); + } >ram_data + .bss : { . = ALIGN(4); @@ -139,8 +149,12 @@ SECTIONS *(COMMON) . = ALIGN(4); } >ram_data - __bss_end = .; - __bss_start = ADDR(.bss); + + .bss_stop (NOLOAD): + { + KEEP(*(.__bss_stop)); + } >ram_data + __bss_len = SIZEOF(.bss); __init_end = .; } diff --git a/arch/blackfin/lib/sections.c b/arch/blackfin/lib/sections.c index 86fc4df..a67530b 100644 --- a/arch/blackfin/lib/sections.c +++ b/arch/blackfin/lib/sections.c @@ -7,5 +7,5 @@ */
char __bss_start[0] __attribute__((section(".__bss_start"))); -char __bss_end[0] __attribute__((section(".__bss_end"))); +char __bss_stop[0] __attribute__((section(".__bss_stop"))); char __init_end[0] __attribute__((section(".__init_end")));

We don't need to clear BSS in assembler. Move it to C to reduce the amount of assembly code needed.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 3 +++ arch/blackfin/cpu/start.S | 13 ------------- 2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 529322a..ef362d4 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -18,6 +18,7 @@ #include <asm/blackfin.h> #include <asm/cplb.h> #include <asm/clock.h> +#include <asm/sections.h> #include <asm/mach-common/bits/core.h> #include <asm/mach-common/bits/ebiu.h> #include <asm/mach-common/bits/trace.h> @@ -323,6 +324,8 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len); }
+ memset(__bss_start, '\0', __bss_stop - __bss_start); + /* * Make sure our async settings are committed. Some bootroms * (like the BF537) will reset some registers on us after it diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 6265a51..01985ea 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -191,19 +191,6 @@ ENTRY(_start) #endif
.Lnorelocate: - /* Initialize BSS section ... we know that memset() does not - * use the BSS, so it is safe to call here. The bootrom LDR - * takes care of clearing things for us. - */ - serial_early_puts("Zero BSS"); - r0.l = ___bss_start; - r0.h = ___bss_start; - r1 = 0 (x); - r2.l = __bss_len; - r2.h = __bss_len; - call _memset; - - /* Setup the actual stack in external memory */ sp.h = HI(CONFIG_STACKBASE); sp.l = LO(CONFIG_STACKBASE);

With generic board, U-Boot expects to have a regions of memory to use before relocation for the stack and early malloc(). Blackfin works around this and 'accurately guesses' the final location of several regions very early during boot. It also uses BSS space to hold global_data.
It would be better if Blackfin followed other boards and uses the existing early allocation functions. Since RAM is set up quite early, we can put things in RAM instead of the small scratch space.
As a first step, define the top of the early memory region: CONFIG_SYS_EARLY_SP_TOP.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 0a2fb4d..934e089 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -4,6 +4,15 @@ menu "Blackfin architecture" config SYS_ARCH default "blackfin"
+config SYS_EARLY_SP_TOP + hex "Top of early memory region" + default 0x100000 + help + Before relocation U-Boot needs some space for the stack and the + early malloc() implementation. This is an arbitrary location but + since U-Boot relocates to the top of RAM it should be fairly + low to avoid conflict. + choice prompt "Target select" optional

Rather than using a hard-coded stack address, call board_init_f_alloc_reserve() and board_init_f_init_reserve() and use the stack address thus obtained. This makes blackfin more like other archs.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/start.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 01985ea..5e19ad2 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -191,11 +191,16 @@ ENTRY(_start) #endif
.Lnorelocate: + r0.l = LO(CONFIG_SYS_EARLY_SP_TOP) + r0.h = HI(CONFIG_SYS_EARLY_SP_TOP) + call _board_init_f_alloc_reserve + /* Setup the actual stack in external memory */ - sp.h = HI(CONFIG_STACKBASE); - sp.l = LO(CONFIG_STACKBASE); + sp = r0 fp = sp;
+ call _board_init_f_init_reserve + /* Now lower ourselves from the highest interrupt level to * the lowest. We do this by masking all interrupts but 15, * setting the 15 handler to ".Lenable_nested", raising the 15

We should not be setting up board info so early. With generic board the gd->bd pointer is not valid until reserve_board() is called, much later in the init sequence.
As a first step, adjust print_cpuinfo() to use the CONFIG instead of the board info.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index ef362d4..13f083f 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -242,7 +242,7 @@ int print_cpuinfo(void) char buf[32];
printf("CPU: ADSP %s (Detected Rev: 0.%d) (%s boot)\n", - gd->bd->bi_cpu, + __stringify(CONFIG_BFIN_CPU), bfin_revid(), get_bfin_boot_mode(CONFIG_BFIN_BOOT_MODE));

The P3 register is used to hold the global_data pointer. At present this is not set up until cpu_init_f() is called, but we want to instead set it up using the standard board_init_f_init_reserve() function. To avoid it being overwritten use P2 instead of P3 in early init.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/start.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 5e19ad2..0bba86b 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -219,9 +219,9 @@ ENTRY(_start) r7 = EVT_IVG15 (z); sti r7; raise 15; - p3.l = .LWAIT_HERE; - p3.h = .LWAIT_HERE; - reti = p3; + p2.l = .LWAIT_HERE; + p2.h = .LWAIT_HERE; + reti = p2; rti;
/* Enable nested interrupts before continuing with cpu init */

Adjust the call sequence a little so that it follows ARM: board_init_f() is called from assembly code.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 6 ------ arch/blackfin/cpu/start.S | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 13f083f..0ae5ac6 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -301,7 +301,6 @@ int irq_init(void) return 0; }
-__attribute__ ((__noreturn__)) void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) { #ifndef CONFIG_BFIN_BOOTROM_USES_EVT1 @@ -359,11 +358,6 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
serial_early_puts("Init global data\n"); global_board_data_init(); - - board_init_f(0); - - /* should not be reached */ - while (1); }
int arch_cpu_init(void) diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 0bba86b..404e710 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -228,7 +228,8 @@ ENTRY(_start) .Lenable_nested: cli r7; [--sp] = reti; - jump.l _cpu_init_f; + call _cpu_init_f; + call _board_init_f
.LWAIT_HERE: jump .LWAIT_HERE;

This is not needed now that we calculate the stack base at run time. Drop it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/include/asm/config.h | 3 --- 1 file changed, 3 deletions(-)
diff --git a/arch/blackfin/include/asm/config.h b/arch/blackfin/include/asm/config.h index 27e8f3d..ea30ff8 100644 --- a/arch/blackfin/include/asm/config.h +++ b/arch/blackfin/include/asm/config.h @@ -109,9 +109,6 @@ #ifndef CONFIG_SYS_MALLOC_BASE # define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) #endif -#ifndef CONFIG_STACKBASE -# define CONFIG_STACKBASE (CONFIG_SYS_MALLOC_BASE - 4) -#endif #ifndef CONFIG_SYS_POST_WORD_ADDR # define CONFIG_SYS_POST_WORD_ADDR (L1_DATA_B_SRAM + L1_DATA_B_SRAM_SIZE - 4) #endif

This should not really be a CONFIG option since it is only used as a way of controlling another option. Rename it and remove it from the whitelist.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/configs/tegra-common.h | 2 +- include/configs/tegra114-common.h | 2 +- include/configs/tegra124-common.h | 2 +- include/configs/tegra186-common.h | 2 +- include/configs/tegra20-common.h | 2 +- include/configs/tegra210-common.h | 2 +- include/configs/tegra30-common.h | 2 +- scripts/config_whitelist.txt | 1 - 8 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index 63b711b..91d7e57 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -94,7 +94,7 @@
#define CONFIG_SYS_BOOTMAPSZ (256 << 20) /* 256M */
-#define CONFIG_SYS_INIT_RAM_ADDR CONFIG_STACKBASE +#define CONFIG_SYS_INIT_RAM_ADDR TEGRA_STACKBASE #define CONFIG_SYS_INIT_RAM_SIZE CONFIG_SYS_MALLOC_LEN #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ CONFIG_SYS_INIT_RAM_SIZE - \ diff --git a/include/configs/tegra114-common.h b/include/configs/tegra114-common.h index 107a0f8..89f954f 100644 --- a/include/configs/tegra114-common.h +++ b/include/configs/tegra114-common.h @@ -16,7 +16,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x82800000 /* 40MB */ +#define TEGRA_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/include/configs/tegra124-common.h b/include/configs/tegra124-common.h index 8cf9bac..0e6d281 100644 --- a/include/configs/tegra124-common.h +++ b/include/configs/tegra124-common.h @@ -18,7 +18,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x82800000 /* 40MB */ +#define TEGRA_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/include/configs/tegra186-common.h b/include/configs/tegra186-common.h index 98e4fc2..fba88b1 100644 --- a/include/configs/tegra186-common.h +++ b/include/configs/tegra186-common.h @@ -17,7 +17,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x82800000 /* 40MB */ +#define TEGRA_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/include/configs/tegra20-common.h b/include/configs/tegra20-common.h index 793310f..d1f10c9 100644 --- a/include/configs/tegra20-common.h +++ b/include/configs/tegra20-common.h @@ -24,7 +24,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x02800000 /* 40MB */ +#define TEGRA_STACKBASE 0x02800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/include/configs/tegra210-common.h b/include/configs/tegra210-common.h index 874fe34d..6d493bd 100644 --- a/include/configs/tegra210-common.h +++ b/include/configs/tegra210-common.h @@ -18,7 +18,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x82800000 /* 40MB */ +#define TEGRA_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/include/configs/tegra30-common.h b/include/configs/tegra30-common.h index baf3d00..655a863 100644 --- a/include/configs/tegra30-common.h +++ b/include/configs/tegra30-common.h @@ -23,7 +23,7 @@ /* * Miscellaneous configurable options */ -#define CONFIG_STACKBASE 0x82800000 /* 40MB */ +#define TEGRA_STACKBASE 0x82800000 /* 40MB */
/*----------------------------------------------------------------------- * Physical Memory Map diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 8814841..e79486d 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4242,7 +4242,6 @@ CONFIG_SSI2_FREQ CONFIG_SSP1_BASE CONFIG_SSP2_BASE CONFIG_SSP3_BASE -CONFIG_STACKBASE CONFIG_STACKSIZE CONFIG_STACKSIZE_FIQ CONFIG_STACKSIZE_IRQ

This is not used in U-Boot with generic board so there is no sense in defining it. It just adds confusion.
Drop it from the config files.
Signed-off-by: Simon Glass sjg@chromium.org ---
cmd/bdinfo.c | 2 -- include/configs/gr_cpci_ax2000.h | 5 +---- include/configs/gr_ep2s60.h | 5 +---- include/configs/gr_xc3s_1500.h | 5 +---- include/configs/grsim.h | 5 +---- include/configs/grsim_leon2.h | 5 +---- include/configs/openrisc-generic.h | 3 --- include/configs/s32v234evb.h | 4 ---- 8 files changed, 5 insertions(+), 29 deletions(-)
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index ae3027a..c8041fa 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -293,8 +293,6 @@ int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) print_num("CONFIG_ENV_ADDR ", CONFIG_ENV_ADDR); printf("CONFIG_SYS_RELOC_MONITOR_BASE = 0x%x (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN); - printf("CONFIG_SYS_MALLOC_BASE = 0x%x (%d)\n", CONFIG_SYS_MALLOC_BASE, - CONFIG_SYS_MALLOC_LEN); printf("CONFIG_SYS_INIT_SP_OFFSET = 0x%x (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, CONFIG_SYS_STACK_SIZE); printf("CONFIG_SYS_PROM_OFFSET = 0x%x (%d)\n", CONFIG_SYS_PROM_OFFSET, diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index 211dc38..3c46d54 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -252,11 +252,8 @@ #define CONFIG_SYS_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-#define CONFIG_SYS_MALLOC_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MALLOC_END-CONFIG_SYS_MALLOC_LEN) - /* relocated monitor area */ -#define CONFIG_SYS_RELOC_MONITOR_MAX_END CONFIG_SYS_MALLOC_BASE +#define CONFIG_SYS_RELOC_MONITOR_MAX_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) #define CONFIG_SYS_RELOC_MONITOR_BASE (CONFIG_SYS_RELOC_MONITOR_MAX_END-CONFIG_SYS_MONITOR_LEN)
/* make un relocated address from relocated address */ diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index ad0c126..d79de54 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -215,11 +215,8 @@ #define CONFIG_SYS_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-#define CONFIG_SYS_MALLOC_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MALLOC_END-CONFIG_SYS_MALLOC_LEN) - /* relocated monitor area */ -#define CONFIG_SYS_RELOC_MONITOR_MAX_END CONFIG_SYS_MALLOC_BASE +#define CONFIG_SYS_RELOC_MONITOR_MAX_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) #define CONFIG_SYS_RELOC_MONITOR_BASE (CONFIG_SYS_RELOC_MONITOR_MAX_END-CONFIG_SYS_MONITOR_LEN)
/* make un relocated address from relocated address */ diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index b0e9001..164cb26 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -197,11 +197,8 @@ #define CONFIG_SYS_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-#define CONFIG_SYS_MALLOC_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MALLOC_END-CONFIG_SYS_MALLOC_LEN) - /* relocated monitor area */ -#define CONFIG_SYS_RELOC_MONITOR_MAX_END CONFIG_SYS_MALLOC_BASE +#define CONFIG_SYS_RELOC_MONITOR_MAX_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) #define CONFIG_SYS_RELOC_MONITOR_BASE (CONFIG_SYS_RELOC_MONITOR_MAX_END-CONFIG_SYS_MONITOR_LEN)
/* make un relocated address from relocated address */ diff --git a/include/configs/grsim.h b/include/configs/grsim.h index 17cac5a..5bb4c74 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -212,11 +212,8 @@ #define CONFIG_SYS_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-#define CONFIG_SYS_MALLOC_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MALLOC_END-CONFIG_SYS_MALLOC_LEN) - /* relocated monitor area */ -#define CONFIG_SYS_RELOC_MONITOR_MAX_END CONFIG_SYS_MALLOC_BASE +#define CONFIG_SYS_RELOC_MONITOR_MAX_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) #define CONFIG_SYS_RELOC_MONITOR_BASE (CONFIG_SYS_RELOC_MONITOR_MAX_END-CONFIG_SYS_MONITOR_LEN)
/* make un relocated address from relocated address */ diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index 1642793..c4869c6 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -207,11 +207,8 @@ #define CONFIG_SYS_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ #define CONFIG_SYS_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */
-#define CONFIG_SYS_MALLOC_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MALLOC_END-CONFIG_SYS_MALLOC_LEN) - /* relocated monitor area */ -#define CONFIG_SYS_RELOC_MONITOR_MAX_END CONFIG_SYS_MALLOC_BASE +#define CONFIG_SYS_RELOC_MONITOR_MAX_END (CONFIG_SYS_INIT_SP_OFFSET-CONFIG_SYS_STACK_SIZE) #define CONFIG_SYS_RELOC_MONITOR_BASE (CONFIG_SYS_RELOC_MONITOR_MAX_END-CONFIG_SYS_MONITOR_LEN)
/* make un relocated address from relocated address */ diff --git a/include/configs/openrisc-generic.h b/include/configs/openrisc-generic.h index 9decae7..780aa16 100644 --- a/include/configs/openrisc-generic.h +++ b/include/configs/openrisc-generic.h @@ -89,9 +89,6 @@ #define CONFIG_SYS_INIT_SP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET #define CONFIG_SYS_STACK_LENGTH 0x10000 /* 64KB */ #define CONFIG_SYS_MALLOC_LEN 0x400000 /* 4MB */ -#define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_INIT_SP_OFFSET \ - - CONFIG_SYS_STACK_LENGTH \ - - CONFIG_SYS_MALLOC_LEN) /* * MISC */ diff --git a/include/configs/s32v234evb.h b/include/configs/s32v234evb.h index 9f85fdc..977b49b 100644 --- a/include/configs/s32v234evb.h +++ b/include/configs/s32v234evb.h @@ -202,10 +202,6 @@
#define CONFIG_SYS_TEXT_BASE 0x3E800000 /* SDRAM */
-#ifdef CONFIG_RUN_FROM_IRAM_ONLY -#define CONFIG_SYS_MALLOC_BASE (DDR_BASE_ADDR) -#endif - /* * Stack sizes * The stack sizes are set up in start.S using the settings below

This is not used in U-Boot, so drop it from the config. Since this is the last user, drop it from the whitelist also.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/include/asm/config.h | 3 --- scripts/config_whitelist.txt | 1 - 2 files changed, 4 deletions(-)
diff --git a/arch/blackfin/include/asm/config.h b/arch/blackfin/include/asm/config.h index ea30ff8..bfcd703 100644 --- a/arch/blackfin/include/asm/config.h +++ b/arch/blackfin/include/asm/config.h @@ -106,9 +106,6 @@ # define CONFIG_SYS_MONITOR_BASE 0 # endif #endif -#ifndef CONFIG_SYS_MALLOC_BASE -# define CONFIG_SYS_MALLOC_BASE (CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN) -#endif #ifndef CONFIG_SYS_POST_WORD_ADDR # define CONFIG_SYS_POST_WORD_ADDR (L1_DATA_B_SRAM + L1_DATA_B_SRAM_SIZE - 4) #endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index e79486d..ea1350d 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -6258,7 +6258,6 @@ CONFIG_SYS_MACB1_BASE CONFIG_SYS_MACB2_BASE CONFIG_SYS_MACB3_BASE CONFIG_SYS_MAIN_PWR_ON -CONFIG_SYS_MALLOC_BASE CONFIG_SYS_MALLOC_CLEAR_ON_INIT CONFIG_SYS_MALLOC_END CONFIG_SYS_MALLOC_LEN

This is not used in U-Boot. Drop it from the whitelist.
Signed-off-by: Simon Glass sjg@chromium.org ---
scripts/config_whitelist.txt | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index ea1350d..8f65c0f 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -6259,7 +6259,6 @@ CONFIG_SYS_MACB2_BASE CONFIG_SYS_MACB3_BASE CONFIG_SYS_MAIN_PWR_ON CONFIG_SYS_MALLOC_CLEAR_ON_INIT -CONFIG_SYS_MALLOC_END CONFIG_SYS_MALLOC_LEN CONFIG_SYS_MALLOC_SIMPLE CONFIG_SYS_MAMR

Rather than jumping directly to the assembler relocation code, call a C function first. This will allow us to add board-specific adjustments.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 7 +++++++ arch/blackfin/cpu/start.S | 6 +++--- arch/blackfin/include/asm/u-boot.h | 5 +++++ 3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 0ae5ac6..d46e251 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -19,6 +19,7 @@ #include <asm/cplb.h> #include <asm/clock.h> #include <asm/sections.h> +#include <asm/u-boot.h> #include <asm/mach-common/bits/core.h> #include <asm/mach-common/bits/ebiu.h> #include <asm/mach-common/bits/trace.h> @@ -360,6 +361,12 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) global_board_data_init(); }
+void relocate_code(ulong sp, gd_t *new_gd, ulong relocaddr) +{ + /* Jump to board_init_r() with a new stack */ + asm_relocate_code(sp, new_gd); +} + int arch_cpu_init(void) { serial_early_puts("Init CPLB tables\n"); diff --git a/arch/blackfin/cpu/start.S b/arch/blackfin/cpu/start.S index 404e710..a5fd76c 100644 --- a/arch/blackfin/cpu/start.S +++ b/arch/blackfin/cpu/start.S @@ -245,12 +245,12 @@ LENTRY(_get_pc) rts; ENDPROC(_get_pc)
-ENTRY(_relocate_code) +ENTRY(_asm_relocate_code) /* Fake relocate code. Setup the new stack only */ sp = r0; fp = sp; - r0 = p3; + r0 = r1 r1.h = 0x2000; r1.l = 0x10; jump.l _board_init_r -ENDPROC(_relocate_code) +ENDPROC(_asm_relocate_code) diff --git a/arch/blackfin/include/asm/u-boot.h b/arch/blackfin/include/asm/u-boot.h index 1ada44e..ae035f7 100644 --- a/arch/blackfin/include/asm/u-boot.h +++ b/arch/blackfin/include/asm/u-boot.h @@ -33,4 +33,9 @@ typedef struct bd_info {
int arch_misc_init(void);
+struct global_data; +void asm_relocate_code(ulong sp, struct global_data *new_gd) + __attribute__ ((noreturn)); + + #endif /* _U_BOOT_H_ */

We have already set up gd in the standard board_init_f_init_reserve() function. Drop the duplicate setup.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index d46e251..25c97b5 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -67,22 +67,12 @@ static inline void serial_early_puts(const char *s)
static int global_board_data_init(void) { -#ifndef CONFIG_SYS_GBL_DATA_ADDR -# define CONFIG_SYS_GBL_DATA_ADDR 0 -#endif #ifndef CONFIG_SYS_BD_INFO_ADDR # define CONFIG_SYS_BD_INFO_ADDR 0 #endif
bd_t *bd;
- if (CONFIG_SYS_GBL_DATA_ADDR) { - gd = (gd_t *)(CONFIG_SYS_GBL_DATA_ADDR); - memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE); - } else { - static gd_t _bfin_gd; - gd = &_bfin_gd; - } if (CONFIG_SYS_BD_INFO_ADDR) { bd = (bd_t *)(CONFIG_SYS_BD_INFO_ADDR); memset(bd, 0, GENERATED_BD_INFO_SIZE);

Move the setting of the RAM size out of the function which now only deals with bd_info. This will allow us to rename it.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index 25c97b5..afb2b0a 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -92,8 +92,6 @@ static int global_board_data_init(void) bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
- gd->ram_size = CONFIG_SYS_MAX_RAM_SIZE; - return 0; }
@@ -348,6 +346,7 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) #endif
serial_early_puts("Init global data\n"); + gd->ram_size = CONFIG_SYS_MAX_RAM_SIZE; global_board_data_init(); }

At present bd_info is set up very early in boot, before board_init_f() is called. But the board info is supposed to be allocated in board_init_f(), with a call to reserve_board().
To fix this, drop the current static variable for board info and set up the information at the end of the board_init_f() init sequence, just before relocating.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index afb2b0a..a8aaee4 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -65,24 +65,8 @@ static inline void serial_early_puts(const char *s) #endif }
-static int global_board_data_init(void) +static int board_data_init(bd_t *bd) { -#ifndef CONFIG_SYS_BD_INFO_ADDR -# define CONFIG_SYS_BD_INFO_ADDR 0 -#endif - - bd_t *bd; - - if (CONFIG_SYS_BD_INFO_ADDR) { - bd = (bd_t *)(CONFIG_SYS_BD_INFO_ADDR); - memset(bd, 0, GENERATED_BD_INFO_SIZE); - } else { - static bd_t _bfin_bd; - bd = &_bfin_bd; - } - - gd->bd = bd; - bd->bi_r_version = version_string; bd->bi_cpu = __stringify(CONFIG_BFIN_CPU); bd->bi_board_name = CONFIG_SYS_BOARD; @@ -347,11 +331,13 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
serial_early_puts("Init global data\n"); gd->ram_size = CONFIG_SYS_MAX_RAM_SIZE; - global_board_data_init(); }
void relocate_code(ulong sp, gd_t *new_gd, ulong relocaddr) { + /* Set up the board data now, since we have a valid bd pointer */ + board_data_init(new_gd->bd); + /* Jump to board_init_r() with a new stack */ asm_relocate_code(sp, new_gd); }

Blackfin currently uses BSS variables before location. The device tree overlaps with the BSS region, meaning that it gets overwritten by any BSS variable accesses. To work around this, copy it out of the way early in boot.
The correct fix would be to adjust blackfin to avoid using BSS so early, but this is a large amount of work and involves testing on many boards. This solution is much more prudent for now.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index a8aaee4..d039c4f 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -11,6 +11,7 @@
#include <common.h> #include <command.h> +#include <libfdt.h> #include <serial.h> #include <version.h> #include <i2c.h> @@ -296,6 +297,20 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len); }
+ /* + * Blackfin uses the BSS section before relcation. This is where the + * device tree is located, so we must relocate it before any BSS + * variables are used (e.g. bfin_poweron_retx, below). Copy it to + * the end of BSS. + */ + if (IS_ENABLED(CONFIG_OF_CONTROL)) { + const void *blob = &_image_binary_end; + int fdt_size = fdt_totalsize(blob); + + memcpy(__bss_stop, blob, fdt_size); + gd->fdt_blob = __bss_stop; + } + memset(__bss_start, '\0', __bss_stop - __bss_start);
/*

Update blackfin to support device-tree control.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/Kconfig b/arch/Kconfig index ffc7b45..722889d 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -25,6 +25,7 @@ config AVR32
config BLACKFIN bool "Blackfin architecture" + select SUPPORT_OF_CONTROL
config M68K bool "M68000 architecture"

Enable device-tree control for this board, as an example for others. This pushes the size of U-Boot over the 256KB limit, so extend this limit to 512KB.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/dts/Makefile | 18 ++++++++++++++++++ arch/blackfin/dts/bf537-stamp.dts | 11 +++++++++++ configs/bf537-stamp_defconfig | 2 ++ include/configs/bf537-stamp.h | 1 + 4 files changed, 32 insertions(+) create mode 100644 arch/blackfin/dts/Makefile create mode 100644 arch/blackfin/dts/bf537-stamp.dts
diff --git a/arch/blackfin/dts/Makefile b/arch/blackfin/dts/Makefile new file mode 100644 index 0000000..757b1b0 --- /dev/null +++ b/arch/blackfin/dts/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2016 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +dtb-$(CONFIG_BLACKFIN) += bf537-stamp.dtb + +targets += $(dtb-y) + +# Add any required device tree compiler flags here +DTC_FLAGS += + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/arch/blackfin/dts/bf537-stamp.dts b/arch/blackfin/dts/bf537-stamp.dts new file mode 100644 index 0000000..84fb1ef --- /dev/null +++ b/arch/blackfin/dts/bf537-stamp.dts @@ -0,0 +1,11 @@ +/dts-v1/; + +/ { + chosen { + stdout-path = &uart0; + }; + + uart0: uart0 { + compatible = "adi,uart-v1"; + }; +}; diff --git a/configs/bf537-stamp_defconfig b/configs/bf537-stamp_defconfig index b691702..599a4a0 100644 --- a/configs/bf537-stamp_defconfig +++ b/configs/bf537-stamp_defconfig @@ -1,5 +1,6 @@ CONFIG_BLACKFIN=y CONFIG_TARGET_BF537_STAMP=y +CONFIG_DEFAULT_DEVICE_TREE="bf537-stamp" CONFIG_BOOTDELAY=5 CONFIG_SILENT_CONSOLE=y CONFIG_CMD_MMC=y @@ -16,6 +17,7 @@ CONFIG_CMD_DNS=y CONFIG_CMD_CACHE=y CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_ATMEL=y diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 4f861aa..f8639d8 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -238,6 +238,7 @@ /* * Misc Settings */ +#define CONFIG_BOARD_SIZE_LIMIT $$(( 512 * 1024 )) #define CONFIG_MISC_INIT_R #define CONFIG_RTC_BFIN #define CONFIG_UART_CONSOLE 0

In some cases it can take a enough time to output serial characters that the watchdog triggers. Add a reset call to avoid this. This mirrors a similar call on input.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/serial-uclass.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 43c028e..489bbcc 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -134,6 +134,8 @@ static void _serial_putc(struct udevice *dev, char ch)
do { err = ops->putc(dev, ch); + if (err == -EAGAIN) + WATCHDOG_RESET(); } while (err == -EAGAIN); }

This driver has been converted, so drop it from the hit list.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/driver-model/serial-howto.txt | 1 - 1 file changed, 1 deletion(-)
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index a0df9a7..67d0983 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -5,7 +5,6 @@ Almost all of the serial drivers have been converted as at January 2016. These ones remain:
serial_bfin.c - serial_pxa.c
The deadline for this work was the end of January 2016. If no one steps forward to convert these, at some point there may come a patch to remove them!

Since all drivers are now converted, we can update the README to cover this.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/driver-model/serial-howto.txt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/doc/driver-model/serial-howto.txt b/doc/driver-model/serial-howto.txt index 67d0983..3241cfd 100644 --- a/doc/driver-model/serial-howto.txt +++ b/doc/driver-model/serial-howto.txt @@ -1,13 +1,9 @@ How to port a serial driver to driver model ===========================================
-Almost all of the serial drivers have been converted as at January 2016. These -ones remain: - - serial_bfin.c - -The deadline for this work was the end of January 2016. If no one steps -forward to convert these, at some point there may come a patch to remove them! +All of the serial drivers have been converted as at December 2016. The +information in this file may be of interest to those using downstream boards. +It will be removed in 2017.
Here is a suggested approach for converting your serial driver over to driver model. Please feel free to update this file with your ideas and suggestions.

Add a serial driver that supports driver model. So far it only works with the v1 serial port.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/include/asm/serial1.h | 2 + drivers/serial/Kconfig | 8 ++ drivers/serial/serial_bfin.c | 192 ++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+)
diff --git a/arch/blackfin/include/asm/serial1.h b/arch/blackfin/include/asm/serial1.h index 467d381..be5a7a9 100644 --- a/arch/blackfin/include/asm/serial1.h +++ b/arch/blackfin/include/asm/serial1.h @@ -231,6 +231,7 @@ static inline void serial_early_do_portmux(void) SSYNC(); }
+#ifndef CONFIG_DM_SERIAL __attribute__((always_inline)) static inline int uart_init(uint32_t uart_base) { @@ -262,6 +263,7 @@ static inline int serial_early_uninit(uint32_t uart_base)
return 0; } +#endif /* !CONFIG_DM_SERIAL */
__attribute__((always_inline)) static inline void serial_set_divisor(uint32_t uart_base, uint16_t divisor) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 620dd82..3b16c40 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -161,6 +161,14 @@ config DEBUG_MVEBU_A3700_UART will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running.
+config DEBUG_UART_BLACKFIN + bool "Blackfin" + help + Select this to enable a debug UART using the serial_bfin driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver-model serial is running. This + only supports the v1 UART at present. + config DEBUG_UART_ZYNQ bool "Xilinx Zynq" help diff --git a/drivers/serial/serial_bfin.c b/drivers/serial/serial_bfin.c index 1d5be2a..8d80b05 100644 --- a/drivers/serial/serial_bfin.c +++ b/drivers/serial/serial_bfin.c @@ -38,6 +38,8 @@ */
#include <common.h> +#include <debug_uart.h> +#include <dm.h> #include <post.h> #include <watchdog.h> #include <serial.h> @@ -47,6 +49,8 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_DM_SERIAL + #ifdef CONFIG_UART_CONSOLE
#ifdef CONFIG_DEBUG_SERIAL @@ -409,3 +413,191 @@ void bfin_serial_initialize(void) serial_register(&bfin_serial_mem_device); } #endif /* CONFIG_UART_MEM */ + +#endif /* CONFIG_DM_SERIAL */ + + +#ifdef CONFIG_DM_SERIAL +struct bfin_serial_priv { + struct bfin_mmr_serial *regs; +}; + +static void dm_serial_set_divisor(struct bfin_mmr_serial *regs, + uint16_t divisor) +{ + /* Set DLAB in LCR to Access DLL and DLH */ + bfin_write_or(®s->lcr, DLAB); + SSYNC(); + + /* Program the divisor to get the baud rate we want */ + bfin_write(®s->dll, LOB(divisor)); + bfin_write(®s->dlh, HIB(divisor)); + SSYNC(); + + /* Clear DLAB in LCR to Access THR RBR IER */ + bfin_write_and(®s->lcr, ~DLAB); + SSYNC(); +} + +static void __serial_set_baud(struct bfin_mmr_serial *regs, unsigned baud) +{ + uint16_t divisor = (get_uart_clk() + (baud * 8)) / (baud * 16) + - ANOMALY_05000230; + + dm_serial_set_divisor(regs, divisor); +} + +static inline int uart_init(struct bfin_mmr_serial *regs) +{ + /* always enable UART -- avoids anomalies 05000309 and 05000350 */ + bfin_write(®s->gctl, UCEN); + + /* Set LCR to Word Lengh 8-bit word select */ + bfin_write(®s->lcr, WLS_8); + + SSYNC(); + + return 0; +} + +static int uart_tstc(struct bfin_mmr_serial *regs) +{ + WATCHDOG_RESET(); + return (_lsr_read(regs) & DR) ? 1 : 0; +} + +#if defined(CONFIG_DEBUG_UART_BLACKFIN) + +#include <debug_uart.h> + +static inline int serial_early_init(struct bfin_mmr_serial *regs) +{ + /* handle portmux crap on different Blackfins */ + serial_early_do_portmux(); + + uart_init(regs); + serial_early_set_baud((ulong)regs, CONFIG_BAUDRATE); + + return 0; +} + +static void _debug_uart_init(void) +{ + struct bfin_mmr_serial *regs = + (struct bfin_mmr_serial *)CONFIG_DEBUG_UART_BASE; + + serial_early_init(regs); +} + +static inline void _debug_uart_putc(int ch) +{ + struct bfin_mmr_serial *regs = + (struct bfin_mmr_serial *)CONFIG_DEBUG_UART_BASE; + + /* wait for the hardware fifo to clear up */ + while (!(_lsr_read(regs) & THRE)) + continue; + + /* queue the character for transmission */ + bfin_write(®s->thr, ch); + SSYNC(); +} + +DEBUG_UART_FUNCS + +#endif /* CONFIG_DEBUG_UART_BLACKFIN */ + +static int bfin_serial_probe(struct udevice *dev) +{ + struct bfin_serial_priv *priv = dev_get_priv(dev); + const unsigned short pins[] = { _P_UART(0, RX), _P_UART(0, TX), 0, }; + struct bfin_mmr_serial *regs; + + peripheral_request_list(pins, "bfin-uart"); + regs = (struct bfin_mmr_serial *)MMR_UART(0); + priv->regs = regs; + + return 0; +} + +static int bfin_serial_putc(struct udevice *dev, const char ch) +{ + struct bfin_serial_priv *priv = dev_get_priv(dev); + struct bfin_mmr_serial *regs = priv->regs; + + /* wait for the hardware fifo to clear up */ + if (!(_lsr_read(regs) & THRE)) + return -EAGAIN; + + /* queue the character for transmission */ + bfin_write(®s->thr, ch); + SSYNC(); + + return 0; +} + +static int bfin_serial_getc(struct udevice *dev) +{ + struct bfin_serial_priv *priv = dev_get_priv(dev); + struct bfin_mmr_serial *regs = priv->regs; + uint16_t uart_rbr_val; + + /* wait for data ! */ + if (!uart_tstc(regs)) + return -EAGAIN; + + /* grab the new byte */ + uart_rbr_val = bfin_read(®s->rbr); + _lsr_write(regs, -1); + + return uart_rbr_val; +} + +int bfin_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct bfin_serial_priv *priv = dev_get_priv(dev); + struct bfin_mmr_serial *regs = priv->regs; + + uart_init(regs); + __serial_set_baud(regs, baudrate); + _lsr_write(regs, -1); + + return 0; +} + +static int bfin_serial_pending(struct udevice *dev, bool input) +{ + struct bfin_serial_priv *priv = dev_get_priv(dev); + struct bfin_mmr_serial *regs = priv->regs; + + if (input) + return (_lsr_read(regs) & DR) ? 1 : 0; + else + return (_lsr_read(regs) & TEMT) ? 0 : 1; + + return 0; +} + +static const struct udevice_id bfin_uart_of_match[] = { + { .compatible = "adi,uart-v1" }, + { /* sentinel */ } +}; + +static const struct dm_serial_ops bfin_serial_ops = { + .putc = bfin_serial_putc, + .pending = bfin_serial_pending, + .getc = bfin_serial_getc, + .setbrg = bfin_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_bfin) = { + .name = "serial_bfin", + .id = UCLASS_SERIAL, + .of_match = bfin_uart_of_match, + .probe = bfin_serial_probe, + .ops = &bfin_serial_ops, + .priv_auto_alloc_size = sizeof(struct bfin_serial_priv), + .flags = DM_FLAG_PRE_RELOC, +}; + +#endif /* !CONFIG_DM_SERIAL */

The debug_uart function is useful for debugging early init problems. While blackfin has its own means of doing this, it would be better to support the standard approach. Add a call to init the debug UART early in start-up.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index d039c4f..d3f8762 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -11,6 +11,7 @@
#include <common.h> #include <command.h> +#include <debug_uart.h> #include <libfdt.h> #include <serial.h> #include <version.h> @@ -297,6 +298,10 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len); }
+#ifdef CONFIG_DEBUG_UART + debug_uart_init(); +#endif + /* * Blackfin uses the BSS section before relcation. This is where the * device tree is located, so we must relocate it before any BSS

Enable driver model and device tree on this board. Set it to use the new driver-model serial driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
configs/bf537-stamp_defconfig | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/configs/bf537-stamp_defconfig b/configs/bf537-stamp_defconfig index 599a4a0..667f5cf 100644 --- a/configs/bf537-stamp_defconfig +++ b/configs/bf537-stamp_defconfig @@ -19,6 +19,7 @@ CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y CONFIG_OF_CONTROL=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_ATMEL=y CONFIG_SPI_FLASH_EON=y @@ -27,3 +28,8 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_SST=y CONFIG_SPI_FLASH_WINBOND=y +CONFIG_DM_SERIAL=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BLACKFIN=y +CONFIG_DEBUG_UART_BASE=0xffc00400 +CONFIG_DEBUG_UART_CLOCK=0

+Tom
Hi,
On 14 December 2016 at 20:27, Simon Glass sjg@chromium.org wrote:
At present the only serial driver that is not converted to driver mode is blackfin. As I recently obtained a suitable board from a kind donor I have decided to convert the driver over, as the unpalatable alternative would be to remove blackfin support from U-Boot.
Blackfin's init sequence is someone non-standard. This series adjusts this to fit more with how things are now done, adds device-tree support, a serial driver and enables driver model on bf537-stamp.
A few CONFIG options are dropped in this series also, as these were noticed along the way.
Future work could enhance the serial driver to support v4 hardware and convert all boards to driver model.
Simon Glass (29): blackfin: Drop CONFIG_SYS_MEMTEST_START/END fdt: Allow the device tree to be set up by board init code blackfin: Add a few useful linker symbols blackfin: Drop the extra blank line in the link script blackfin: Use compiler-generated symbols for BSS blackfin: Clear the BSS in C code blackfin: Add a memory region for pre-relocation data blackfin: Use generic board to set the stack address blackfin: Avoid using bd_info in print_cpuinfo() blackfin: Avoiding using P3 in early init blackfin: Allow cpu_init_f() to return blackfin: Drop CONFIG_STACKBASE tegra: Drop CONFIG_STACKBASE in favour of TEGRA_STACKBASE sparc: Drop CONFIG_SYS_MALLOC_BASE blackfin: Drop CONFIG_SYS_MALLOC_BASE Drop CONFIG_SYS_MALLOC_END blackfin: Call C code to relocate blackfin: Don't set global_data again blackfin: Set the RAM size separately from bd_info blackfin: Set up bd_info later blackfin: Copy the device tree out of BSS blackfin: Allow use of CONFIG_OF_CONTROL blackfin: bf537-stamp: Enable CONFIG_OF_CONTROL dm: serial: Reset the watchdog when outputting characters dm: serial: pxa: Drop pxa from the serial README dm: serial: Update the serial README dm: blackfin: Add a driver-model serial driver blackfin: Set up the debug UART if enabled blackfin: Enable driver-model on bf537-stamp
arch/Kconfig | 1 + arch/blackfin/Kconfig | 9 ++ arch/blackfin/cpu/cpu.c | 69 +++++++------ arch/blackfin/cpu/start.S | 35 +++---- arch/blackfin/cpu/u-boot.lds | 24 ++++- arch/blackfin/dts/Makefile | 18 ++++ arch/blackfin/dts/bf537-stamp.dts | 11 +++ arch/blackfin/include/asm/config.h | 12 --- arch/blackfin/include/asm/serial1.h | 2 + arch/blackfin/include/asm/u-boot.h | 5 + arch/blackfin/lib/sections.c | 2 +- cmd/bdinfo.c | 2 - configs/bf537-stamp_defconfig | 8 ++ doc/driver-model/serial-howto.txt | 11 +-- drivers/serial/Kconfig | 8 ++ drivers/serial/serial-uclass.c | 2 + drivers/serial/serial_bfin.c | 192 ++++++++++++++++++++++++++++++++++++ include/configs/bf537-stamp.h | 1 + include/configs/bf609-ezkit.h | 1 - include/configs/gr_cpci_ax2000.h | 5 +- include/configs/gr_ep2s60.h | 5 +- include/configs/gr_xc3s_1500.h | 5 +- include/configs/grsim.h | 5 +- include/configs/grsim_leon2.h | 5 +- include/configs/openrisc-generic.h | 3 - include/configs/s32v234evb.h | 4 - include/configs/tegra-common.h | 2 +- include/configs/tegra114-common.h | 2 +- include/configs/tegra124-common.h | 2 +- include/configs/tegra186-common.h | 2 +- include/configs/tegra20-common.h | 2 +- include/configs/tegra210-common.h | 2 +- include/configs/tegra30-common.h | 2 +- lib/fdtdec.c | 31 +++--- scripts/config_whitelist.txt | 3 - 35 files changed, 360 insertions(+), 133 deletions(-) create mode 100644 arch/blackfin/dts/Makefile create mode 100644 arch/blackfin/dts/bf537-stamp.dts
-- 2.8.0.rc3.226.g39d4020
Any reviews on this? Will someone pick it up?
Regards, Simon
participants (1)
-
Simon Glass