mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 19:31:12 +00:00
[sdmmc] Fix Sandisk U1 fast power cycle
Some Sandisk U1 sd cards do not behave nicely if they power cycle too fast. A min 100ms wait, is enough to mitigate that. Fortunately, because of how the code paths are structured, this was never hit.
This commit is contained in:
parent
36d2da5d79
commit
25f6e91677
5 changed files with 17 additions and 3 deletions
|
@ -45,6 +45,7 @@ void set_default_configuration()
|
||||||
h_cfg.autonogc = 1;
|
h_cfg.autonogc = 1;
|
||||||
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
h_cfg.sept_run = EMC(EMC_SCRATCH0) & EMC_SEPT_RUN;
|
||||||
h_cfg.rcm_patched = true;
|
h_cfg.rcm_patched = true;
|
||||||
|
h_cfg.sd_timeoff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int create_config_entry()
|
int create_config_entry()
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct _hekate_config
|
||||||
u32 errors;
|
u32 errors;
|
||||||
int sept_run;
|
int sept_run;
|
||||||
bool rcm_patched;
|
bool rcm_patched;
|
||||||
|
u32 sd_timeoff;
|
||||||
} hekate_config;
|
} hekate_config;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
#include "sd.h"
|
#include "sd.h"
|
||||||
|
#include "../config/config.h"
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
#include "../utils/util.h"
|
#include "../utils/util.h"
|
||||||
|
@ -26,6 +27,8 @@
|
||||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||||
#define DPRINTF(...)
|
#define DPRINTF(...)
|
||||||
|
|
||||||
|
extern hekate_config h_cfg;
|
||||||
|
|
||||||
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
static inline u32 unstuff_bits(u32 *resp, u32 start, u32 size)
|
||||||
{
|
{
|
||||||
const u32 mask = (size < 32 ? 1 << size : 0) - 1;
|
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)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 11:
|
case 11:
|
||||||
|
// Fall through if not supported.
|
||||||
if (buf[13] & SD_MODE_UHS_SDR104)
|
if (buf[13] & SD_MODE_UHS_SDR104)
|
||||||
{
|
{
|
||||||
type = 11;
|
type = 11;
|
||||||
|
@ -841,7 +845,6 @@ int _sd_storage_enable_highspeed_low_volt(sdmmc_storage_t *storage, u32 type, u8
|
||||||
storage->csd.busspeed = 104;
|
storage->csd.busspeed = 104;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//Fall through.
|
|
||||||
case 10:
|
case 10:
|
||||||
if (buf[13] & SD_MODE_UHS_SDR50)
|
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))
|
if (!_sd_storage_switch_get(storage, buf))
|
||||||
return 0;
|
return 0;
|
||||||
//gfx_hexdump(0, (u8 *)buf, 64);
|
//gfx_hexdump(0, (u8 *)buf, 64);
|
||||||
if (!(buf[13] & 2))
|
if (!(buf[13] & SD_MODE_HIGH_SPEED))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!_sd_storage_enable_highspeed(storage, 1, buf))
|
if (!_sd_storage_enable_highspeed(storage, 1, buf))
|
||||||
|
@ -1013,6 +1016,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 id, u32
|
||||||
{
|
{
|
||||||
int is_version_1 = 0;
|
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));
|
memset(storage, 0, sizeof(sdmmc_storage_t));
|
||||||
storage->sdmmc = sdmmc;
|
storage->sdmmc = sdmmc;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "mmc.h"
|
#include "mmc.h"
|
||||||
#include "sdmmc.h"
|
#include "sdmmc.h"
|
||||||
|
#include "../config/config.h"
|
||||||
#include "../gfx/gfx.h"
|
#include "../gfx/gfx.h"
|
||||||
#include "../power/max7762x.h"
|
#include "../power/max7762x.h"
|
||||||
#include "../soc/clock.h"
|
#include "../soc/clock.h"
|
||||||
|
@ -31,6 +32,8 @@
|
||||||
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||||
#define DPRINTF(...)
|
#define DPRINTF(...)
|
||||||
|
|
||||||
|
extern hekate_config h_cfg;
|
||||||
|
|
||||||
/*! SCMMC controller base addresses. */
|
/*! SCMMC controller base addresses. */
|
||||||
static const u32 _sdmmc_bases[4] = {
|
static const u32 _sdmmc_bases[4] = {
|
||||||
0x700B0000,
|
0x700B0000,
|
||||||
|
@ -1037,6 +1040,7 @@ void sdmmc_end(sdmmc_t *sdmmc)
|
||||||
{
|
{
|
||||||
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
gpio_output_enable(GPIO_PORT_E, GPIO_PIN_4, GPIO_OUTPUT_DISABLE);
|
||||||
max77620_regulator_enable(REGULATOR_LDO2, 0);
|
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.
|
msleep(1); // To power cycle min 1ms without power is needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue