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 <robthedude@mac.com>
This commit is contained in:
Rob Newberry 2023-03-30 10:43:21 -07:00 committed by Andre Przywara
parent 2237e562fd
commit bd96d533dc
3 changed files with 7 additions and 3 deletions

View file

@ -245,13 +245,12 @@ static void rpi3_sdhost_reset(void)
static void rpi3_sdhost_initialize(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); assert((rpi3_sdhost_params.reg_base & MMC_BLOCK_MASK) == 0);
rpi3_sdhost_reset(); 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); udelay(300);
} }

View file

@ -15,6 +15,7 @@
struct rpi3_sdhost_params { struct rpi3_sdhost_params {
uintptr_t reg_base; uintptr_t reg_base;
uint32_t clk_rate; uint32_t clk_rate;
uint32_t clk_rate_initial;
uint32_t bus_width; uint32_t bus_width;
uint32_t flags; uint32_t flags;
uint32_t current_cmd; uint32_t current_cmd;
@ -57,6 +58,8 @@ void rpi3_sdhost_stop(void);
#define HC_CMD_READ 0x0040 #define HC_CMD_READ 0x0040
#define HC_CMD_COMMAND_MASK 0x003f #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_MAXVAL 0x07ff
#define HC_CLOCKDIVISOR_PREFERVAL 0x027b #define HC_CLOCKDIVISOR_PREFERVAL 0x027b
#define HC_CLOCKDIVISOR_SLOWVAL 0x0148 #define HC_CLOCKDIVISOR_SLOWVAL 0x0148

View file

@ -35,7 +35,9 @@ static void rpi3_sdhost_setup(void)
params.reg_base = RPI3_SDHOST_BASE; params.reg_base = RPI3_SDHOST_BASE;
params.bus_width = MMC_BUS_WIDTH_1; params.bus_width = MMC_BUS_WIDTH_1;
params.clk_rate = 50000000; 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.mmc_dev_type = MMC_IS_SD_HC;
mmc_info.ocr_voltage = OCR_3_2_3_3 | OCR_3_3_3_4;
rpi3_sdhost_init(&params, &mmc_info); rpi3_sdhost_init(&params, &mmc_info);
} }