[U-Boot] [PATCH v2 0/8] dm: rockchip: Enable booting from MMC

This patchset allows u-boot on RK3288 device to load and boot kernels from MMC using the standard distro boot commands. Patchset is on top of the rockchip-working branch of u-boot dm
There are some small oddities with the support: - Linux crashes when try to use the FDT if it's re-allocated to memory locations above 512MB. So fdt_high is set to ensure it stays below that. - This SoC seems sensitive to the order in which the caches are disabled, when disabling the i-cache before the d-cache starting linux fails (unsure if it fails before or after jumping to linux though)
To fix the latter ``arm: Turn of d-cache before i-cache'' changes the ordering in the general v7 code. However i have not tested this yet on other device, so it may well need to be handled in rockchip specific code.
Tested on a Radxa Rock 2 with square baseboard, booting from SD card. I haven't tested eMMC yet however i suspect the SPL will need modifications there to load u-boot from eMMC rather then SD (which has index 0) ideally by detecting where the SPL itself got loaded from.
Changes in v2: - Check error code from uclass_get and thread it through to mmc_initialize - Also drop CONFIG_SPL_LED from the firefly defconfig - Fixed various typos and inconsitencies in commit message
Sjoerd Simons (8): doc: Fix reference to Rock pro when Rock 2 is meant mmc: Probe DM based mmc devices in u-boot rockchip: Disable sdio mmc slot on rk3288-firefly rockchip: Turn off CONFIG_SPL_LED_SUPPORT for firefly rockchip: Add config_distro_bootcmd support arm: Turn of d-cache before i-cache rockchip: Drop first 32kb of zeros from the rkSD image type rockchip: Update todo in README.rockchip
arch/arm/cpu/armv7/cpu.c | 15 ++++++++------ arch/arm/dts/rk3288-firefly.dtsi | 2 +- configs/firefly-rk3288_defconfig | 1 - doc/README.rockchip | 9 ++++----- drivers/mmc/mmc.c | 43 ++++++++++++++++++++++++++++++++++++---- include/configs/firefly-rk3288.h | 1 - include/configs/rk3288_common.h | 21 ++++++++++++++++++++ tools/rksd.c | 9 ++------- 8 files changed, 76 insertions(+), 25 deletions(-)

The Radxa Rock pro board is rk3188 based and thus won't work with U-Boot built for RK3288. Change the documentation to refer to the intended board, the Radxa Rock 2, which is an RK3288-based design very similar to the firefly
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
doc/README.rockchip | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/README.rockchip b/doc/README.rockchip index a34e198..ce8ce77 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -39,7 +39,7 @@ Building At present three RK3288 boards are supported:
- Firefly RK3288 - use firefly-rk3288 configuration - - Radxa Rock Pro - also uses firefly-rk3288 configuration + - Radxa Rock 2 - also uses firefly-rk3288 configuration - Haier Chromebook - use chromebook_jerry configuration
For example: @@ -48,8 +48,8 @@ For example:
(or you can use another cross compiler if you prefer)
-Note that the Radxa Rock Pro uses the Firefly configuration for now as -device tree files are not yet available for the Rock Pro. Clearly the two +Note that the Radxa Rock 2 uses the Firefly configuration for now as +device tree files are not yet available for the Rock 2. Clearly the two have hardware differences, so this approach will break down as more drivers are added.

During mmc initialize probe all devices with the MMC Uclass if build with CONFIG_DM_MMC
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk
---
Changes in v2: - Check error code from uclass_get and thread it through to mmc_initialize
drivers/mmc/mmc.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f12546a..371c1ec 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -10,6 +10,8 @@ #include <config.h> #include <common.h> #include <command.h> +#include <dm.h> +#include <dm/device-internal.h> #include <errno.h> #include <mmc.h> #include <part.h> @@ -1759,10 +1761,44 @@ static void do_preinit(void) } }
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD) +static int mmc_probe(bd_t *bis) +{ + return 0; +} +#elif defined(CONFIG_DM_MMC) +static int mmc_probe(bd_t *bis) +{ + int ret; + struct uclass *uc; + struct udevice *m; + + ret = uclass_get(UCLASS_MMC, &uc); + if (ret) + return ret; + + uclass_foreach_dev(m, uc) { + ret = device_probe(m); + if (ret) + printf("%s - probe failed: %d\n", m->name, ret); + } + + return 0; +} +#else +static int mmc_probe(bd_t *bis) +{ + if (board_mmc_init(bis) < 0) + cpu_mmc_init(bis); + + return 0; +} +#endif
int mmc_initialize(bd_t *bis) { static int initialized = 0; + int ret; if (initialized) /* Avoid initializing mmc multiple times */ return 0; initialized = 1; @@ -1770,10 +1806,9 @@ int mmc_initialize(bd_t *bis) INIT_LIST_HEAD (&mmc_devices); cur_dev_num = 0;
-#ifndef CONFIG_DM_MMC - if (board_mmc_init(bis) < 0) - cpu_mmc_init(bis); -#endif + ret = mmc_probe(bis); + if (ret) + return ret;
#ifndef CONFIG_SPL_BUILD print_mmc_devices(',');

On 30 August 2015 at 11:31, Sjoerd Simons sjoerd.simons@collabora.co.uk wrote:
During mmc initialize probe all devices with the MMC Uclass if build with CONFIG_DM_MMC
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk
Changes in v2:
- Check error code from uclass_get and thread it through to mmc_initialize
drivers/mmc/mmc.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-)
I hope we can make this auto-probe soon, but for now this gets things working.
Acked-by: Simon Glass sjg@chromium.org

U-Boot can't use the sdio card so turn it of to prevent things getting confused/struck when trying to use the card as storage.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
arch/arm/dts/rk3288-firefly.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/rk3288-firefly.dtsi b/arch/arm/dts/rk3288-firefly.dtsi index 8a083f0..5aec1b8 100644 --- a/arch/arm/dts/rk3288-firefly.dtsi +++ b/arch/arm/dts/rk3288-firefly.dtsi @@ -386,7 +386,7 @@ pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>; vmmc-supply = <&vcc_18>; - status = "okay"; + status = "disabled"; };
&sdmmc {

With LED support enabled the SPL easily goes over the size limit (e.g. with both Debians gcc 4.9 and 5.2 cross-compilers). Turn off LED support in the SPL to reduce the size just enough for those compilers.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk
---
Changes in v2: - Also drop CONFIG_SPL_LED from the firefly defconfig
configs/firefly-rk3288_defconfig | 1 - include/configs/firefly-rk3288.h | 1 - 2 files changed, 2 deletions(-)
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig index 4c41ae3..03fe715 100644 --- a/configs/firefly-rk3288_defconfig +++ b/configs/firefly-rk3288_defconfig @@ -17,7 +17,6 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_RESET=y CONFIG_LED=y -CONFIG_SPL_LED=y CONFIG_LED_GPIO=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_UART_BASE=0xff690000 diff --git a/include/configs/firefly-rk3288.h b/include/configs/firefly-rk3288.h index 82e7c9c..a82adc8 100644 --- a/include/configs/firefly-rk3288.h +++ b/include/configs/firefly-rk3288.h @@ -10,6 +10,5 @@ #include <configs/rk3288_common.h>
#define CONFIG_SPL_MMC_SUPPORT -#define CONFIG_SPL_LED_SUPPORT
#endif

On 30 August 2015 at 11:31, Sjoerd Simons sjoerd.simons@collabora.co.uk wrote:
With LED support enabled the SPL easily goes over the size limit (e.g. with both Debians gcc 4.9 and 5.2 cross-compilers). Turn off LED support in the SPL to reduce the size just enough for those compilers.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk
Changes in v2:
- Also drop CONFIG_SPL_LED from the firefly defconfig
configs/firefly-rk3288_defconfig | 1 - include/configs/firefly-rk3288.h | 1 - 2 files changed, 2 deletions(-)
Acked-by: Simon Glass sjg@chromium.org

Now that MMC works in U-Boot add config distro command support to start Linux in a standard fashion. One oddity here is that linux fails to load when the fdt is relocated to above 512MB, so set fdt_high to make sure it's loaded below that.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
include/configs/rk3288_common.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index ac0957a..95243b4 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -93,6 +93,27 @@
#ifndef CONFIG_SPL_BUILD #include <config_distro_defaults.h> + +#define ENV_MEM_LAYOUT_SETTINGS \ + "scriptaddr=0x00000000\0" \ + "pxefile_addr_r=0x00100000\0" \ + "fdt_addr_r=0x01f00000\0" \ + "kernel_addr_r=0x02000000\0" \ + "ramdisk_addr_r=0x04000000\0" + +/* First try to boot from SD (index 0), then eMMC (index 1 */ +#define BOOT_TARGET_DEVICES(func) \ + func(MMC, mmc, 0) \ + func(MMC, mmc, 1) + +#include <config_distro_bootcmd.h> + +/* Linux fails to load the fdt if it's loaded above 512M on a Rock 2 board, so + * limit the fdt reallocation to that */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0x1fffffff\0" \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV #endif
#endif

Booting the kernel fails on RK3288 (and probably other rockchip SoCs) when the i-cache is disabled/flushed before d-cache.
I have not investigated whether this is due to U-Boot hanging or whether it's very early in the linux boot, but following the approach of the various rockchip U-Boot forks (first disable d-cache then i-cache) makes things work.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Reviewed-by: Simon Glass sjg@chromium.org
---
Changes in v2: None
arch/arm/cpu/armv7/cpu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c index 0b0e500..6eac5ef 100644 --- a/arch/arm/cpu/armv7/cpu.c +++ b/arch/arm/cpu/armv7/cpu.c @@ -36,12 +36,6 @@ int cleanup_before_linux_select(int flags) disable_interrupts(); #endif
- /* - * Turn off I-cache and invalidate it - */ - icache_disable(); - invalidate_icache_all(); - if (flags & CBL_DISABLE_CACHES) { /* * turn off D-cache @@ -61,7 +55,16 @@ int cleanup_before_linux_select(int flags) * to avoid coherency problems for kernel */ invalidate_dcache_all(); + + icache_disable(); + invalidate_icache_all(); } else { + /* + * Turn off I-cache and invalidate it + */ + icache_disable(); + invalidate_icache_all(); + flush_dcache_all(); invalidate_icache_all(); icache_enable();

Instead of creating a rockchip SPL SD card image with 32KB of zeros which can be written to the start of an SD card, create the images with only the useful data that should be written to an offset of 32KB on the SD card.
The first 32 kilobytes aren't needed for bootup and only serve as convenient way of accidentally obliterating your partition table.
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Acked-by: Simon Glass sjg@chromium.org ---
Changes in v2: None
doc/README.rockchip | 2 +- tools/rksd.c | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/doc/README.rockchip b/doc/README.rockchip index ce8ce77..347fc05 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -90,7 +90,7 @@ Booting from an SD card To write an image that boots from an SD card (assumed to be /dev/sdc):
./firefly-rk3288/tools/mkimage -T rksd -d firefly-rk3288/spl/u-boot-spl-dtb.bin out - sudo dd if=out of=/dev/sdc + sudo dd if=out of=/dev/sdc seek=64 sudo dd if=firefly-rk3288/u-boot-dtb.img of=/dev/sdc seek=256
This puts the Rockchip header and SPL image first and then places the U-Boot diff --git a/tools/rksd.c b/tools/rksd.c index 2efcd68..a8dbe98 100644 --- a/tools/rksd.c +++ b/tools/rksd.c @@ -14,9 +14,7 @@ #include "rkcommon.h"
enum { - RKSD_HEADER0_START = 64 * RK_BLK_SIZE, - RKSD_SPL_HDR_START = RKSD_HEADER0_START + - RK_CODE1_OFFSET * RK_BLK_SIZE, + RKSD_SPL_HDR_START = RK_CODE1_OFFSET * RK_BLK_SIZE, RKSD_SPL_START = RKSD_SPL_HDR_START + 4, RKSD_HEADER_LEN = RKSD_SPL_START, }; @@ -44,11 +42,8 @@ static void rksd_set_header(void *buf, struct stat *sbuf, int ifd, unsigned int size; int ret;
- /* Zero the whole header. The first 32KB is empty */ - memset(buf, '\0', RKSD_HEADER0_START); - size = params->file_size - RKSD_SPL_HDR_START; - ret = rkcommon_set_header(buf + RKSD_HEADER0_START, size); + ret = rkcommon_set_header(buf, size); if (ret) { /* TODO(sjg@chromium.org): This method should return an error */ printf("Warning: SPL image is too large (size %#x) and will not boot\n",

MMC support works now, so it can be dropped from the todo
Signed-off-by: Sjoerd Simons sjoerd.simons@collabora.co.uk Acked-by: Simon Glass sjg@chromium.org
---
Changes in v2: - Fixed various typos and inconsitencies in commit message
doc/README.rockchip | 1 - 1 file changed, 1 deletion(-)
diff --git a/doc/README.rockchip b/doc/README.rockchip index 347fc05..feb11ff 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -161,7 +161,6 @@ Future work
Immediate priorities are:
-- MMC support (in U-Boot itself) - GPIO (driver exists but is lightly tested) - I2C (driver exists but is non-functional) - USB host
participants (2)
-
Simon Glass
-
Sjoerd Simons