From bd96d533dc28c4c938aa54905787688823cbccac Mon Sep 17 00:00:00 2001 From: Rob Newberry Date: Thu, 30 Mar 2023 10:43:21 -0700 Subject: [PATCH] fix(rpi3): initialize SD card host controller Add initial configuration parameters for Rasperry Pi 3's sdhost controller, and then configure and use those parameters. This change allows warm reboots of UEFI on Raspberry Pi 3B+ where existing code often fails with "unknown error". See discussion at: https://github.com/pftf/RPi3/issues/24 The basic idea is that some initial configuration parameters (clock rate, bus width) aren't configured into the hardware before commands start being sent. I suspect that the particular setting that matters is the "slow card" bit, but the initial clock setting also seemed wrong to me. Change-Id: I526def340def143f23f3422f1fc14c12c937ca7f Signed-off-by: Rob Newberry --- drivers/rpi3/sdhost/rpi3_sdhost.c | 5 ++--- include/drivers/rpi3/sdhost/rpi3_sdhost.h | 3 +++ plat/rpi/rpi3/rpi3_bl2_setup.c | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/rpi3/sdhost/rpi3_sdhost.c b/drivers/rpi3/sdhost/rpi3_sdhost.c index c4b6fcafe..90c850947 100644 --- a/drivers/rpi3/sdhost/rpi3_sdhost.c +++ b/drivers/rpi3/sdhost/rpi3_sdhost.c @@ -245,13 +245,12 @@ static void rpi3_sdhost_reset(void) static void rpi3_sdhost_initialize(void) { - uintptr_t reg_base = rpi3_sdhost_params.reg_base; - assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0); rpi3_sdhost_reset(); - mmio_write_32(reg_base + HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_PREFERVAL); + rpi3_sdhost_set_ios(rpi3_sdhost_params.clk_rate_initial, + rpi3_sdhost_params.bus_width); udelay(300); } diff --git a/include/drivers/rpi3/sdhost/rpi3_sdhost.h b/include/drivers/rpi3/sdhost/rpi3_sdhost.h index 1653240c8..f4f6ec8b2 100644 --- a/include/drivers/rpi3/sdhost/rpi3_sdhost.h +++ b/include/drivers/rpi3/sdhost/rpi3_sdhost.h @@ -15,6 +15,7 @@ struct rpi3_sdhost_params { uintptr_t reg_base; uint32_t clk_rate; + uint32_t clk_rate_initial; uint32_t bus_width; uint32_t flags; uint32_t current_cmd; @@ -57,6 +58,8 @@ void rpi3_sdhost_stop(void); #define HC_CMD_READ 0x0040 #define HC_CMD_COMMAND_MASK 0x003f +#define RPI3_SDHOST_MAX_CLOCK 250000000 // technically, we should obtain this number from the mailbox + #define HC_CLOCKDIVISOR_MAXVAL 0x07ff #define HC_CLOCKDIVISOR_PREFERVAL 0x027b #define HC_CLOCKDIVISOR_SLOWVAL 0x0148 diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c index db7181794..80e4d8d8d 100644 --- a/plat/rpi/rpi3/rpi3_bl2_setup.c +++ b/plat/rpi/rpi3/rpi3_bl2_setup.c @@ -35,7 +35,9 @@ static void rpi3_sdhost_setup(void) params.reg_base = RPI3_SDHOST_BASE; params.bus_width = MMC_BUS_WIDTH_1; params.clk_rate = 50000000; + params.clk_rate_initial = (RPI3_SDHOST_MAX_CLOCK / HC_CLOCKDIVISOR_MAXVAL); mmc_info.mmc_dev_type = MMC_IS_SD_HC; + mmc_info.ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4; rpi3_sdhost_init(¶ms, &mmc_info); }