Hi Daniel, 2012/10/30 Daniel Drake <dsd@xxxxxxxxxx>: > Hi, > > Following on from the recent thread > [PATCH 2/2] mmc: core: Power cycle card on voltage switch fail > I have tried to get a better grip on the problems being faced. > > Test setup: > OLPC XO-1.75 laptop, based on Marvell MMP2 ARM SoC (includes sdhci-pxa > interface) > 32GB Sandisk Ultra SD card being inserted into external SD slot > > The SoC apparently has support for 1.8V, but we physically do not have > the right power lines wired on the motherboard, so we need to detect > the 1.8V failure and go back to 3.3V mode. An initial question, would it be possible to solve this by disabling the UHS support in the host cap, or through a quirk? Maybe this kind of solution is not applicable in this scenario? I wonder this because I guess it will be very hard to know how a card will react if we first tell it that we're going to switch voltages and then don't, since this is out of spec. > I tracked down what causes this regression. In order to get the > failure detection working again, I have to make the following change > in mmc_set_signal_voltage(): > if (cmd11) { > host->ios.clock = 0; > - mmc_set_ios(host); > + //mmc_set_ios(host); > } > (i.e. don't mess with ios before asking sdhci to do the voltage switch) > > and at the top of sdhci_do_1_8v_signal_voltage_switch: > + /* Stop SDCLK */ > + clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); > + clk &= ~SDHCI_CLOCK_CARD_EN; > + sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); > (i.e. add the equivalent clock disabling code here) Ok, so this suggests that the SDHCI driver does not stop the clock when we set ios.clock = 0 and call mmc_set_ios? > With that change, I now get: > mmc2: Signal voltage switch failed, power cycling card (retries = 10) > mmc2: error -110 whilst initialising SD card > > The -110 error comes from mmc_send_app_op_cond(), but its worth noting > that mmc_send_if_cond() (called immediately above) silently failed > with -110 too. Neither of these failed the first time around before > 1.8V was tried. > > Full patch that I'm testing with: http://dev.laptop.org/~dsd/20121030/mmc.patch > > So, now the question is: why is the card not responding to > if_cond/app_op_cond after being powered down and up again? Is the > power down/up sequence OK? Good question. I’d guess that mmc_power_off/up does not work as expected here, that the card is not at all power cycled. But it seems that the power cycle code in sdhci_do_start_signal_voltage_switch works? What if we export a couple of debug functions from sdhci.c which allow us to power cycle and control the clock just like sdhci does, and call these functions from core.c and sd.c? If this works (and the failure is detected properly by the core layer, and 10 retries are made etc), then we know that the problems most likely depend on how mmc_set_ios and mmc_power_off/up work with sdhci. I've attached a patch suggesting this, if you'd like to give it a try (warning: the patch has not been tested). The patch does not do anything about pm_runtime, but perhaps we don't need to worry about this here. > I tried inserting the mmc_power_off, mmc_power_up, mmc_send_if_cond > sequence into various points in the codepaths being discussed. > Measuring success as the card responding to mmc_send_if_cond(0x30080) > without error (0x30080 is a known good value from when before 1.8V is > tried), I find that this "reset sequence" works just fine up until the > point when CMD11 is run. > CMD11 is sent and returns successfully without error, but from this > point, running the reset sequence will fail (send_if_cond will fail > with -110). > > Is this kind of test valid? Does this suggest that something is wrong > with the host controller hardware? My assumption is that whatever > state is modified by CMD11 should be erased here, and of course the > hope is that mmc_power_off and mmc_power_up will do a full power cycle > anyway. But whatever is happening, it looks like the effects of CMD11 > are persisting past the reset sequence and are breaking later > communication. I think that the power cycle has simply failed here, I find it hard to believe that CMD11 has persistent effects :) If mmc_power_off/up actually works, then perhaps the 1ms udelay is too small for this case? Kind regards, Johan
Attachment:
0001-Clock-and-power-control.patch
Description: Binary data