diff --git a/bootloader/config/config.c b/bootloader/config/config.c index 668340d..4848a8b 100644 --- a/bootloader/config/config.c +++ b/bootloader/config/config.c @@ -45,6 +45,7 @@ void set_default_configuration() h_cfg.autonogc = 1; h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN; h_cfg.rcm_patched = true; + h_cfg.sd_timeoff = 0; } int create_config_entry() diff --git a/bootloader/config/config.h b/bootloader/config/config.h index e12136f..93ce284 100644 --- a/bootloader/config/config.h +++ b/bootloader/config/config.h @@ -35,6 +35,7 @@ typedef struct _hekate_config u32 errors; int sept_run; bool rcm_patched; + u32 sd_timeoff; } hekate_config; typedef enum diff --git a/bootloader/soc/fuse.c b/bootloader/soc/fuse.c index 25044fb..54a93a0 100644 --- a/bootloader/soc/fuse.c +++ b/bootloader/soc/fuse.c @@ -96,7 +96,7 @@ static u32 _parity32_even(u32 *words, u32 count) lo = ((x & 0xf) ^ (x >> 4)) & 3; hi = ((x & 0xf) ^ (x >> 4)) >> 2; x = hi ^ lo; - + return (x & 1) ^ (x >> 1); } diff --git a/bootloader/storage/sdmmc.c b/bootloader/storage/sdmmc.c index ca1dfb07..a28d3dd 100644 --- a/bootloader/storage/sdmmc.c +++ b/bootloader/storage/sdmmc.c @@ -19,6 +19,7 @@ #include "sdmmc.h" #include "mmc.h" #include "sd.h" +#include "../config/config.h" #include "../gfx/gfx.h" #include "../mem/heap.h" #include "../utils/util.h" @@ -26,6 +27,8 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) +extern hekate_config h_cfg; + static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size) { const u32 mask = (size < 32 ? 1 << size : 0) - 1; @@ -833,6 +836,7 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 switch (type) { case 11: + // Fall through if not supported. if (buf[13] & SD_MODE_UHS_SDR104) { type = 11; @@ -841,7 +845,6 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8 storage->csd.busspeed = 104; break; } - //Fall through. case 10: if (buf[13] & SD_MODE_UHS_SDR50) { @@ -878,7 +881,7 @@ int _sd_storage_enable_highspeed_high_volt(sdmmc_storage_t *storage, u8 *buf) if (!_sd_storage_switch_get(storage, buf)) return 0; //gfx_hexdump(0, (u8 *)buf, 64); - if (!(buf[13] & 2)) + if (!(buf[13] & SD_MODE_HIGH_SPEED)) return 1; if (!_sd_storage_enable_highspeed(storage, 1, buf)) @@ -1012,6 +1015,11 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage) int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32 bus_width, u32 type) { int is_version_1 = 0; + + // Some cards (Sandisk U1), do not like a fast power cycle. Wait min 100ms. + u32 sd_poweroff_time = (u32)get_tmr_ms() - h_cfg.sd_timeoff; + if (id == SDMMC_1 && (sd_poweroff_time < 100)) + msleep(100 - sd_poweroff_time); memset(storage, 0, sizeof(sdmmc_storage_t)); storage->sdmmc = sdmmc; diff --git a/bootloader/storage/sdmmc_driver.c b/bootloader/storage/sdmmc_driver.c index 1283aa3..5299171 100644 --- a/bootloader/storage/sdmmc_driver.c +++ b/bootloader/storage/sdmmc_driver.c @@ -19,6 +19,7 @@ #include "mmc.h" #include "sdmmc.h" +#include "../config/config.h" #include "../gfx/gfx.h" #include "../power/max7762x.h" #include "../soc/clock.h" @@ -31,6 +32,8 @@ //#define DPRINTF(...) gfx_printf(__VA_ARGS__) #define DPRINTF(...) +extern hekate_config h_cfg; + /*! SCMMC controller base addresses. */ static const u32 _sdmmc_bases[4] = { 0x700B0000, @@ -1037,6 +1040,7 @@ void sdmmc_end(sdmmc_t *sdmmc) { gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE); max77620_regulator_enable(REGULATOR_LDO2, 0); + h_cfg.sd_timeoff = get_tmr_ms(); // Some sandisc U1 cards need 100ms for a power cycle. msleep(1); // To power cycle min 1ms without power is needed. }