[SeaBIOS] [PATCH 04/14] sdcard: Move power setup to new function sdcard_set_power()
Kevin O'Connor
kevin at koconnor.net
Wed Aug 12 20:03:25 CET 2015
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
src/hw/sdcard.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/src/hw/sdcard.c b/src/hw/sdcard.c
index 053f8de..45f19a7 100644
--- a/src/hw/sdcard.c
+++ b/src/hw/sdcard.c
@@ -264,7 +264,7 @@ sdcard_process_op(struct disk_op_s *op)
// Initialize an SD card
static int
-sdcard_card_setup(struct sdhci_s *regs)
+sdcard_card_setup(struct sdhci_s *regs, int volt)
{
// XXX - works on QEMU; probably wont on real hardware!
@@ -274,12 +274,13 @@ sdcard_card_setup(struct sdhci_s *regs)
if (ret)
return ret;
// Let card know SDHC/SDXC is supported and confirm voltage
- param[0] = 0x1aa;
+ u32 vrange = (volt >= (1<<15) ? 0x100 : 0x200) | 0xaa;
+ param[0] = vrange;
ret = sdcard_pio(regs, SC_SEND_IF_COND, param);
if (ret)
return ret;
u32 hcs = 0;
- if (param[0] == 0x1aa)
+ if (param[0] == vrange)
hcs = 0x40000000;
// Verify SD card (instead of MMC or SDIO)
param[0] = 0x00;
@@ -289,7 +290,7 @@ sdcard_card_setup(struct sdhci_s *regs)
// Init card
u32 end = timer_calc(SDHCI_POWERUP_TIMEOUT);
for (;;) {
- param[0] = hcs | (1<<20); // SDHC support and voltage level
+ param[0] = hcs | volt; // SDHC support and voltage level
ret = sdcard_pio_app(regs, SC_APP_SEND_OP_COND, param);
if (ret)
return ret;
@@ -319,6 +320,21 @@ sdcard_card_setup(struct sdhci_s *regs)
}
static int
+sdcard_set_power(struct sdhci_s *regs)
+{
+ u32 cap = readl(®s->cap_lo);
+ if (!(cap & SD_CAPLO_V33)) {
+ dprintf(1, "SD controller does not support 3.3V power\n");
+ return -1;
+ }
+ writeb(®s->power_control, 0);
+ msleep(SDHCI_POWER_OFF_TIME);
+ writeb(®s->power_control, SPC_V33 | SPC_POWER_ON);
+ msleep(SDHCI_POWER_ON_TIME);
+ return 1<<20;
+}
+
+static int
sdcard_set_frequency(struct sdhci_s *regs, u32 khz)
{
u16 ver = readw(®s->controller_version);
@@ -328,10 +344,6 @@ sdcard_set_frequency(struct sdhci_s *regs, u32 khz)
dprintf(1, "Unknown base frequency for SD controller\n");
return -1;
}
- if (!(cap & SD_CAPLO_V33)) {
- dprintf(1, "SD controller does not support 3.3V power\n");
- return -1;
- }
// Set new frequency
u32 divisor = DIV_ROUND_UP(base_freq * 1000, khz);
u16 creg;
@@ -382,17 +394,16 @@ sdcard_controller_setup(void *data)
writew(®s->irq_enable, 0xffff);
writew(®s->error_signal, 0);
writeb(®s->timeout_control, 0x0e); // Set to max timeout
- writeb(®s->power_control, 0);
- msleep(SDHCI_POWER_OFF_TIME);
- writeb(®s->power_control, SPC_V33 | SPC_POWER_ON);
- msleep(SDHCI_POWER_ON_TIME);
+ int volt = sdcard_set_power(regs);
+ if (volt < 0)
+ return;
int ret = sdcard_set_frequency(regs, 400);
if (ret)
return;
msleep(SDHCI_CLOCK_ON_TIME);
// Initialize card
- int card_type = sdcard_card_setup(regs);
+ int card_type = sdcard_card_setup(regs, volt);
if (card_type < 0)
return;
ret = sdcard_set_frequency(regs, 25000);
--
1.9.3
More information about the SeaBIOS
mailing list