sdmmc v2: Refactor and fix registers

This commit is contained in:
CTCaer 2020-04-29 21:23:28 +03:00
parent 7f26981fa1
commit 66780bb4c2
6 changed files with 98 additions and 62 deletions

View file

@ -113,10 +113,14 @@ void sdmmc_set_tap_value(sdmmc_t *sdmmc)
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
{ {
const u32 dqs_trim_val = 0x28;
const u32 tap_values[] = { 4, 0, 3, 0 };
u32 tap_val = 0; u32 tap_val = 0;
if (type == SDHCI_TIMING_MMC_HS400) if (type == SDHCI_TIMING_MMC_HS400)
sdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800; sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8);
sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;
if (type == SDHCI_TIMING_MMC_HS400) if (type == SDHCI_TIMING_MMC_HS400)
@ -128,7 +132,6 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
} }
else else
{ {
static const u32 tap_values[] = { 4, 0, 3, 0 };
tap_val = tap_values[sdmmc->id]; tap_val = tap_values[sdmmc->id];
} }
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16); sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
@ -184,7 +187,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
usleep(1); usleep(1);
u32 timeout = get_tmr_ms() + 10; u32 timeout = get_tmr_ms() + 10;
while (sdmmc->regs->autocalcfg & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE) while (sdmmc->regs->autocalsts & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -211,11 +214,11 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
} }
sdmmc->regs->vendllcal |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE; sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
_sdmmc_get_clkcon(sdmmc); _sdmmc_get_clkcon(sdmmc);
u32 timeout = get_tmr_ms() + 5; u32 timeout = get_tmr_ms() + 5;
while (sdmmc->regs->vendllcal & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE) while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -225,7 +228,7 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
} }
timeout = get_tmr_ms() + 10; timeout = get_tmr_ms() + 10;
while (sdmmc->regs->dllcfgstatus & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE) while (sdmmc->regs->vendllcalcfgsts & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -591,7 +594,6 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
{ {
u32 max = 0, flag = 0; u32 max = 0, flag = 0;
sdmmc->regs->field_1C4 = 0;
switch (type) switch (type)
{ {
case SDHCI_TIMING_MMC_HS200: case SDHCI_TIMING_MMC_HS200:
@ -614,6 +616,8 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
return 0; return 0;
} }
sdmmc->regs->ventunctl1 = 0; // step_size 1.
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries.
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier. sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;

View file

@ -199,6 +199,10 @@
#define SDHCI_CAN_64BIT 0x10000000 #define SDHCI_CAN_64BIT 0x10000000
/*! SDMMC Low power features. */
#define SDMMC_AUTO_CAL_DISABLE 0
#define SDMMC_AUTO_CAL_ENABLE 1
/*! Helper for SWITCH command argument. */ /*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))

View file

@ -43,56 +43,66 @@ typedef struct _t210_sdmmc_t
vu32 rspreg3; vu32 rspreg3;
vu32 bdata; vu32 bdata;
vu32 prnsts; vu32 prnsts;
vu8 hostctl; vu8 hostctl;
vu8 pwrcon; vu8 pwrcon;
vu8 blkgap; vu8 blkgap;
vu8 wakcon; vu8 wakcon;
vu16 clkcon; vu16 clkcon;
vu8 timeoutcon; vu8 timeoutcon;
vu8 swrst; vu8 swrst;
vu16 norintsts; vu16 norintsts;
vu16 errintsts; vu16 errintsts;
vu16 norintstsen; vu16 norintstsen; // Enable irq status.
vu16 errintstsen; vu16 errintstsen; // Enable irq status.
vu16 norintsigen; vu16 norintsigen; // Enable irq signal to LIC/GIC.
vu16 errintsigen; vu16 errintsigen; // Enable irq signal to LIC/GIC.
vu16 acmd12errsts; vu16 acmd12errsts;
vu16 hostctl2; vu16 hostctl2;
vu32 capareg; vu32 capareg;
vu32 capareg_1; vu32 capareg_1;
vu32 maxcurr; vu32 maxcurr;
vu8 res3[4]; vu8 rsvd0[4]; // 4C-4F reserved for more max current.
vu16 setacmd12err; vu16 setacmd12err;
vu16 setinterr; vu16 setinterr;
vu8 admaerr; vu8 admaerr;
vu8 res4[3]; vu8 rsvd1[3]; // 55-57 reserved.
vu32 admaaddr; vu32 admaaddr;
vu32 admaaddr_hi; vu32 admaaddr_hi;
vu8 res5[156]; vu8 rsvd2[156]; // 60-FB reserved.
vu16 slotintstatus; vu16 slotintsts;
vu16 hcver; vu16 hcver;
vu32 venclkctl; vu32 venclkctl;
vu32 venspictl; vu32 vensysswctl;
vu32 venspiintsts; vu32 venerrintsts;
vu32 venceatactl; vu32 vencapover;
vu32 venbootctl; vu32 venbootctl;
vu32 venbootacktout; vu32 venbootacktout;
vu32 venbootdattout; vu32 venbootdattout;
vu32 vendebouncecnt; vu32 vendebouncecnt;
vu32 venmiscctl; vu32 venmiscctl;
vu32 res6[34]; vu32 maxcurrover;
vu32 maxcurrover_hi;
vu32 unk0[32]; // 0x12C
vu32 veniotrimctl; vu32 veniotrimctl;
vu32 vendllcal; vu32 vendllcalcfg;
vu8 res7[8]; vu32 vendllctl0;
vu32 dllcfgstatus; vu32 vendllctl1;
vu32 vendllcalcfgsts;
vu32 ventunctl0; vu32 ventunctl0;
vu32 field_1C4; vu32 ventunctl1;
vu8 field_1C8[24]; vu32 ventunsts0;
vu32 ventunsts1;
vu32 venclkgatehystcnt;
vu32 venpresetval0;
vu32 venpresetval1;
vu32 venpresetval2;
vu32 sdmemcmppadctl; vu32 sdmemcmppadctl;
vu32 autocalcfg; vu32 autocalcfg;
vu32 autocalintval; vu32 autocalintval;
vu32 autocalsts; vu32 autocalsts;
vu32 iospare; vu32 iospare;
vu32 mcciffifoctl;
vu32 timeoutwcoal;
} t210_sdmmc_t; } t210_sdmmc_t;
#endif #endif

View file

@ -113,10 +113,14 @@ void sdmmc_set_tap_value(sdmmc_t *sdmmc)
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
{ {
const u32 dqs_trim_val = 0x28;
const u32 tap_values[] = { 4, 0, 3, 0 };
u32 tap_val = 0; u32 tap_val = 0;
if (type == SDHCI_TIMING_MMC_HS400) if (type == SDHCI_TIMING_MMC_HS400)
sdmmc->regs->venceatactl = (sdmmc->regs->venceatactl & 0xFFFFC0FF) | 0x2800; sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8);
sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;
if (type == SDHCI_TIMING_MMC_HS400) if (type == SDHCI_TIMING_MMC_HS400)
@ -128,7 +132,6 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
} }
else else
{ {
static const u32 tap_values[] = { 4, 0, 3, 0 };
tap_val = tap_values[sdmmc->id]; tap_val = tap_values[sdmmc->id];
} }
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16); sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap_val << 16);
@ -184,7 +187,7 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
usleep(1); usleep(1);
u32 timeout = get_tmr_ms() + 10; u32 timeout = get_tmr_ms() + 10;
while (sdmmc->regs->autocalcfg & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE) while (sdmmc->regs->autocalsts & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -211,11 +214,11 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
} }
sdmmc->regs->vendllcal |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE; sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE;
_sdmmc_get_clkcon(sdmmc); _sdmmc_get_clkcon(sdmmc);
u32 timeout = get_tmr_ms() + 5; u32 timeout = get_tmr_ms() + 5;
while (sdmmc->regs->vendllcal & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE) while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -225,7 +228,7 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
} }
timeout = get_tmr_ms() + 10; timeout = get_tmr_ms() + 10;
while (sdmmc->regs->dllcfgstatus & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE) while (sdmmc->regs->vendllcalcfgsts & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE)
{ {
if (get_tmr_ms() > timeout) if (get_tmr_ms() > timeout)
{ {
@ -591,7 +594,6 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
{ {
u32 max = 0, flag = 0; u32 max = 0, flag = 0;
sdmmc->regs->field_1C4 = 0;
switch (type) switch (type)
{ {
case SDHCI_TIMING_MMC_HS200: case SDHCI_TIMING_MMC_HS200:
@ -614,6 +616,8 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
return 0; return 0;
} }
sdmmc->regs->ventunctl1 = 0; // step_size 1.
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries.
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier. sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW;

View file

@ -199,6 +199,10 @@
#define SDHCI_CAN_64BIT 0x10000000 #define SDHCI_CAN_64BIT 0x10000000
/*! SDMMC Low power features. */
#define SDMMC_AUTO_CAL_DISABLE 0
#define SDMMC_AUTO_CAL_ENABLE 1
/*! Helper for SWITCH command argument. */ /*! Helper for SWITCH command argument. */
#define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8))

View file

@ -43,56 +43,66 @@ typedef struct _t210_sdmmc_t
vu32 rspreg3; vu32 rspreg3;
vu32 bdata; vu32 bdata;
vu32 prnsts; vu32 prnsts;
vu8 hostctl; vu8 hostctl;
vu8 pwrcon; vu8 pwrcon;
vu8 blkgap; vu8 blkgap;
vu8 wakcon; vu8 wakcon;
vu16 clkcon; vu16 clkcon;
vu8 timeoutcon; vu8 timeoutcon;
vu8 swrst; vu8 swrst;
vu16 norintsts; vu16 norintsts;
vu16 errintsts; vu16 errintsts;
vu16 norintstsen; vu16 norintstsen; // Enable irq status.
vu16 errintstsen; vu16 errintstsen; // Enable irq status.
vu16 norintsigen; vu16 norintsigen; // Enable irq signal to LIC/GIC.
vu16 errintsigen; vu16 errintsigen; // Enable irq signal to LIC/GIC.
vu16 acmd12errsts; vu16 acmd12errsts;
vu16 hostctl2; vu16 hostctl2;
vu32 capareg; vu32 capareg;
vu32 capareg_1; vu32 capareg_1;
vu32 maxcurr; vu32 maxcurr;
vu8 res3[4]; vu8 rsvd0[4]; // 4C-4F reserved for more max current.
vu16 setacmd12err; vu16 setacmd12err;
vu16 setinterr; vu16 setinterr;
vu8 admaerr; vu8 admaerr;
vu8 res4[3]; vu8 rsvd1[3]; // 55-57 reserved.
vu32 admaaddr; vu32 admaaddr;
vu32 admaaddr_hi; vu32 admaaddr_hi;
vu8 res5[156]; vu8 rsvd2[156]; // 60-FB reserved.
vu16 slotintstatus; vu16 slotintsts;
vu16 hcver; vu16 hcver;
vu32 venclkctl; vu32 venclkctl;
vu32 venspictl; vu32 vensysswctl;
vu32 venspiintsts; vu32 venerrintsts;
vu32 venceatactl; vu32 vencapover;
vu32 venbootctl; vu32 venbootctl;
vu32 venbootacktout; vu32 venbootacktout;
vu32 venbootdattout; vu32 venbootdattout;
vu32 vendebouncecnt; vu32 vendebouncecnt;
vu32 venmiscctl; vu32 venmiscctl;
vu32 res6[34]; vu32 maxcurrover;
vu32 maxcurrover_hi;
vu32 unk0[32]; // 0x12C
vu32 veniotrimctl; vu32 veniotrimctl;
vu32 vendllcal; vu32 vendllcalcfg;
vu8 res7[8]; vu32 vendllctl0;
vu32 dllcfgstatus; vu32 vendllctl1;
vu32 vendllcalcfgsts;
vu32 ventunctl0; vu32 ventunctl0;
vu32 field_1C4; vu32 ventunctl1;
vu8 field_1C8[24]; vu32 ventunsts0;
vu32 ventunsts1;
vu32 venclkgatehystcnt;
vu32 venpresetval0;
vu32 venpresetval1;
vu32 venpresetval2;
vu32 sdmemcmppadctl; vu32 sdmemcmppadctl;
vu32 autocalcfg; vu32 autocalcfg;
vu32 autocalintval; vu32 autocalintval;
vu32 autocalsts; vu32 autocalsts;
vu32 iospare; vu32 iospare;
vu32 mcciffifoctl;
vu32 timeoutwcoal;
} t210_sdmmc_t; } t210_sdmmc_t;
#endif #endif