mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MMC, HS200/HS400 support seems to break mmc legacy support, clock probing seems to have issues.
Original source 398d5fc6af
This commit resets mmc_calculate_clock() to it's original behaviour.
This commit is contained in:
parent
f44a7c3df1
commit
c4ec367c3d
1 changed files with 29 additions and 118 deletions
|
|
@ -2117,27 +2117,31 @@ mmc_go_discovery(struct mmc_softc *sc)
|
|||
static int
|
||||
mmc_calculate_clock(struct mmc_softc *sc)
|
||||
{
|
||||
device_t dev;
|
||||
device_t *kids;
|
||||
struct mmc_ivars *ivar;
|
||||
int i;
|
||||
int host_caps, i, nkid;
|
||||
uint32_t dtr, max_dtr;
|
||||
uint16_t rca;
|
||||
enum mmc_bus_timing max_timing, timing;
|
||||
bool changed, hs400;
|
||||
bool changed;
|
||||
|
||||
dev = sc->dev;
|
||||
max_dtr = mmcbr_get_f_max(dev);
|
||||
max_timing = bus_timing_max;
|
||||
max_dtr = mmcbr_get_f_max(sc->dev);
|
||||
host_caps = mmcbr_get_caps(sc->dev);
|
||||
if ((host_caps & MMC_CAP_MMC_DDR52) != 0)
|
||||
max_timing = bus_timing_mmc_ddr52;
|
||||
else if ((host_caps & MMC_CAP_HSPEED) != 0)
|
||||
max_timing = bus_timing_hs;
|
||||
else
|
||||
max_timing = bus_timing_normal;
|
||||
if (device_get_children(sc->dev, &kids, &nkid) != 0)
|
||||
panic("can't get children");
|
||||
do {
|
||||
changed = false;
|
||||
for (i = 0; i < sc->child_count; i++) {
|
||||
ivar = device_get_ivars(sc->child_list[i]);
|
||||
if (isclr(&ivar->timings, max_timing) ||
|
||||
!mmc_host_timing(dev, max_timing)) {
|
||||
for (timing = max_timing - 1; timing >=
|
||||
for (i = 0; i < nkid; i++) {
|
||||
ivar = device_get_ivars(kids[i]);
|
||||
if (isclr(&ivar->timings, max_timing)) {
|
||||
for (timing = max_timing; timing >=
|
||||
bus_timing_normal; timing--) {
|
||||
if (isset(&ivar->timings, timing) &&
|
||||
mmc_host_timing(dev, timing)) {
|
||||
if (isset(&ivar->timings, timing)) {
|
||||
max_timing = timing;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2151,118 +2155,25 @@ mmc_calculate_clock(struct mmc_softc *sc)
|
|||
}
|
||||
}
|
||||
} while (changed == true);
|
||||
|
||||
if (bootverbose || mmc_debug) {
|
||||
device_printf(dev,
|
||||
device_printf(sc->dev,
|
||||
"setting transfer rate to %d.%03dMHz (%s timing)\n",
|
||||
max_dtr / 1000000, (max_dtr / 1000) % 1000,
|
||||
mmc_timing_to_string(max_timing));
|
||||
}
|
||||
|
||||
/*
|
||||
* HS400 must be tuned in HS200 mode, so in case of HS400 we begin
|
||||
* with HS200 following the sequence as described in "6.6.2.2 HS200
|
||||
* timing mode selection" of the eMMC specification v5.1, too, and
|
||||
* switch to max_timing later. HS400ES requires no tuning and, thus,
|
||||
* can be switch to directly, but requires the same detour via high
|
||||
* speed mode as does HS400 (see mmc_switch_to_hs400()).
|
||||
*/
|
||||
hs400 = max_timing == bus_timing_mmc_hs400;
|
||||
timing = hs400 == true ? bus_timing_mmc_hs200 : max_timing;
|
||||
for (i = 0; i < sc->child_count; i++) {
|
||||
ivar = device_get_ivars(sc->child_list[i]);
|
||||
for (i = 0; i < nkid; i++) {
|
||||
ivar = device_get_ivars(kids[i]);
|
||||
if ((ivar->timings & ~(1 << bus_timing_normal)) == 0)
|
||||
continue;
|
||||
|
||||
rca = ivar->rca;
|
||||
if (mmc_select_card(sc, rca) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address %d "
|
||||
"failed to select\n", rca);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (timing == bus_timing_mmc_hs200 || /* includes HS400 */
|
||||
timing == bus_timing_mmc_hs400es) {
|
||||
if (mmc_set_vccq(sc, ivar, timing) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Failed to set VCCQ for "
|
||||
"card at relative address %d\n", rca);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (timing == bus_timing_mmc_hs200) { /* includes HS400 */
|
||||
/* Set bus width (required for initial tuning). */
|
||||
if (mmc_set_card_bus_width(sc, ivar, timing) !=
|
||||
MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address "
|
||||
"%d failed to set bus width\n", rca);
|
||||
continue;
|
||||
}
|
||||
mmcbr_set_bus_width(dev, ivar->bus_width);
|
||||
mmcbr_update_ios(dev);
|
||||
} else if (timing == bus_timing_mmc_hs400es) {
|
||||
if (mmc_switch_to_hs400(sc, ivar, max_dtr, timing) !=
|
||||
MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address "
|
||||
"%d failed to set %s timing\n", rca,
|
||||
mmc_timing_to_string(timing));
|
||||
continue;
|
||||
}
|
||||
goto power_class;
|
||||
}
|
||||
|
||||
if (mmc_set_timing(sc, ivar, timing) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address %d "
|
||||
"failed to set %s timing\n", rca,
|
||||
mmc_timing_to_string(timing));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (timing == bus_timing_mmc_ddr52) {
|
||||
/*
|
||||
* Set EXT_CSD_BUS_WIDTH_n_DDR in EXT_CSD_BUS_WIDTH
|
||||
* (must be done after switching to EXT_CSD_HS_TIMING).
|
||||
*/
|
||||
if (mmc_set_card_bus_width(sc, ivar, timing) !=
|
||||
MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address "
|
||||
"%d failed to set bus width\n", rca);
|
||||
continue;
|
||||
}
|
||||
mmcbr_set_bus_width(dev, ivar->bus_width);
|
||||
mmcbr_update_ios(dev);
|
||||
if (mmc_set_vccq(sc, ivar, timing) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Failed to set VCCQ for "
|
||||
"card at relative address %d\n", rca);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set clock (must be done before initial tuning). */
|
||||
mmcbr_set_clock(dev, max_dtr);
|
||||
mmcbr_update_ios(dev);
|
||||
|
||||
if (mmcbr_tune(dev, hs400) != 0) {
|
||||
device_printf(dev, "Card at relative address %d "
|
||||
"failed to execute initial tuning\n", rca);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hs400 == true && mmc_switch_to_hs400(sc, ivar, max_dtr,
|
||||
max_timing) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address %d "
|
||||
"failed to set %s timing\n", rca,
|
||||
mmc_timing_to_string(max_timing));
|
||||
continue;
|
||||
}
|
||||
|
||||
power_class:
|
||||
if (mmc_set_power_class(sc, ivar) != MMC_ERR_NONE) {
|
||||
device_printf(dev, "Card at relative address %d "
|
||||
"failed to set power class\n", rca);
|
||||
}
|
||||
if (mmc_select_card(sc, ivar->rca) != MMC_ERR_NONE ||
|
||||
mmc_set_timing(sc, ivar, max_timing) != MMC_ERR_NONE)
|
||||
device_printf(sc->dev, "Card at relative address %d "
|
||||
"failed to set timing.\n", ivar->rca);
|
||||
}
|
||||
(void)mmc_select_card(sc, 0);
|
||||
mmc_select_card(sc, 0);
|
||||
free(kids, M_TEMP);
|
||||
mmcbr_set_clock(sc->dev, max_dtr);
|
||||
mmcbr_update_ios(sc->dev);
|
||||
return (max_dtr);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue