On 23 May 2014 14:51, <srinivas.kandagatla@xxxxxxxxxx> wrote: > From: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx> > > Most of the Qcomm SD card controller registers must be updated to the MCLK > domain so subsequent writes to registers will be ignored until 3 clock cycles > have passed. > > This patch adds a 3 clock cycle delay required after writing to controller > registers on Qualcomm SOCs. Without this delay all the register writes are not > successful, resulting in not detecting cards. The write clock delay is > activated by setting up mclk_delayed_writes variable in variant data. > > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx> > Reviewed-by: Linus Walleij <linus.walleij@xxxxxxxxxx> > --- > drivers/mmc/host/mmci.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c > index 881bb24..1385554 100644 > --- a/drivers/mmc/host/mmci.c > +++ b/drivers/mmc/host/mmci.c > @@ -67,6 +67,8 @@ static unsigned int fmax = 515633; > * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock > * @busy_detect: true if busy detection on dat0 is supported > * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply > + * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates > + * are not ignored. > */ > struct variant_data { > unsigned int clkreg; > @@ -83,6 +85,7 @@ struct variant_data { > bool pwrreg_clkgate; > bool busy_detect; > bool pwrreg_nopower; > + bool mclk_delayed_writes; > }; > > static struct variant_data variant_arm = { > @@ -171,6 +174,12 @@ static struct variant_data variant_qcom = { > .datalength_bits = 24, > .blksz_datactrl4 = true, > .pwrreg_powerup = MCI_PWR_UP, > + /* > + * On QCom SD card controller, registers must be updated to the > + * MCLK domain so subsequent writes to this register will be ignored > + * for 3 clk cycles. > + */ > + .mclk_delayed_writes = true, > }; > > static inline u32 mmci_readl(struct mmci_host *host, u32 off) > @@ -181,6 +190,9 @@ static inline u32 mmci_readl(struct mmci_host *host, u32 off) > static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) > { > writel(data, host->base + off); > + > + if (host->variant->mclk_delayed_writes) > + udelay(DIV_ROUND_UP((3 * USEC_PER_SEC), host->mclk)); > } I am not sure I like this approach. For each and every writel (including pio_writes) you will add a few cpu cycles, since you need to check for "mclk_delayed_writes" no matter of variant. How about, adding a new function pointer in the struct mmci_host, for "writel operations" which you could set up in probe phase instead? Kind regards Ulf Hansson -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html