Re: [PATCH v2 1/1]sdhci-pxa: support tune_timming for various cards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 11, 2010 at 9:19 PM, zhangfei gao <zhangfei.gao@xxxxxxxxx> wrote:
> Hi, Chirs & Eric
>
> Thanks for review, here is updated version.
> 1. After clk_gating is enabled, set_clock will transfer clock=0, so
> clk_disable will be called, currently set_clock will never transfer
> clock=0.
> Later tune_timing only occurs once clock is started, currently it will
> happen when clock is changed.
>
> 2. if pdata is NULL, on-chip device can not be detected, but SD card
> is workable, though some card may have crc error at 50M.
>
>
> From 553b84abee56f36ee166564f7ce3c617950e194f Mon Sep 17 00:00:00 2001
> From: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
> Date: Tue, 2 Nov 2010 07:37:44 -0400
> Subject: [PATCH] sdhci-pxa: support tune_timing for various cards
>
>        1. Add pdata check, in case pdata is NULL
>        2. Add tune_timing to adjust read data/command timing without
> performance impact when crc error, as a result
>                a, sd could work at 50M
>                b, emmc could work at ddr50 mode
>        3. Remove clock_enable checking, since clock gating is still on-going
> in core stack.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxxx>
> ---
>  arch/arm/plat-pxa/include/plat/sdhci.h |    2 +
>  drivers/mmc/host/sdhci-pxa.c           |   47 +++++++++++++++++++++++--------
>  2 files changed, 37 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h
> b/arch/arm/plat-pxa/include/plat/sdhci.h
> index fc5ceab..f6f46db 100644
> --- a/arch/arm/plat-pxa/include/plat/sdhci.h
> +++ b/arch/arm/plat-pxa/include/plat/sdhci.h
> @@ -24,11 +24,13 @@
>  * @max_speed: the maximum speed supported
>  * @quirks: quirks of specific device
>  * @flags: flags for platform requirement
> + * @clk_delay_cycles: 1 ~ 0x1f, each step is roughly 100ps, for tuning timing
>  */
>  struct sdhci_pxa_platdata {
>        unsigned int    max_speed;
>        unsigned int    quirks;
>        unsigned int    flags;
> +       unsigned int    clk_delay_cycles;
>  };
>
>  #endif /* __PLAT_PXA_SDHCI_H */
> diff --git a/drivers/mmc/host/sdhci-pxa.c b/drivers/mmc/host/sdhci-pxa.c
> index 8455c46..2b665e4 100644
> --- a/drivers/mmc/host/sdhci-pxa.c
> +++ b/drivers/mmc/host/sdhci-pxa.c
> @@ -32,6 +32,11 @@
>  #define SD_FIFO_PARAM          0x104
>  #define DIS_PAD_SD_CLK_GATE    0x400
>
> +#define SD_CLOCK_AND_BURST_SIZE_SETUP          0x10A
> +#define SDCLK_SEL      0x100
> +#define SDCLK_DELAY_SHIFT      9
> +#define SDCLK_DELAY_MASK       0x1f
> +
>  struct sdhci_pxa {
>        struct sdhci_host               *host;
>        struct sdhci_pxa_platdata       *pdata;
> @@ -46,9 +51,28 @@ struct sdhci_pxa {
>  * SDHCI core callbacks                                                      *
>  *                                                                           *
>  \*****************************************************************************/
> +static inline void tune_timing(struct sdhci_host *host,
> +                               struct sdhci_pxa_platdata *pdata)
> +{
> +       /*
> +        * tune timing of read data/command when crc error happen
> +        * no performance impact
> +        */
> +       if (pdata && 0 != pdata->clk_delay_cycles) {
> +               u16 tmp;
> +
> +               tmp = readw(host->ioaddr + SD_CLOCK_AND_BURST_SIZE_SETUP);
> +               tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
> +                                       << SDCLK_DELAY_SHIFT;
> +               tmp |= SDCLK_SEL;
> +               writew(tmp, host->ioaddr + SD_CLOCK_AND_BURST_SIZE_SETUP);
> +       }
> +}
> +
>  static void set_clock(struct sdhci_host *host, unsigned int clock)
>  {
>        struct sdhci_pxa *pxa = sdhci_priv(host);
> +       struct sdhci_pxa_platdata *pdata = pxa->pdata;
>        u32 tmp = 0;
>
>        if (clock == 0) {
> @@ -57,15 +81,14 @@ static void set_clock(struct sdhci_host *host,
> unsigned int clock)
>                        pxa->clk_enable = 0;
>                }
>        } else {
> -               if (0 == pxa->clk_enable) {
> -                       if (pxa->pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
> -                               tmp = readl(host->ioaddr + SD_FIFO_PARAM);
> -                               tmp |= DIS_PAD_SD_CLK_GATE;
> -                               writel(tmp, host->ioaddr + SD_FIFO_PARAM);
> -                       }
> -                       clk_enable(pxa->clk);
> -                       pxa->clk_enable = 1;
> +               tune_timing(host, pdata);
> +               if (pdata && pdata->flags & PXA_FLAG_DISABLE_CLOCK_GATING) {
> +                       tmp = readl(host->ioaddr + SD_FIFO_PARAM);
> +                       tmp |= DIS_PAD_SD_CLK_GATE;
> +                       writel(tmp, host->ioaddr + SD_FIFO_PARAM);
>                }
> +               clk_enable(pxa->clk);
> +               pxa->clk_enable = 1;
>        }
>  }
>
> @@ -138,13 +161,13 @@ static int __devinit sdhci_pxa_probe(struct
> platform_device *pdev)
>        host->irq = irq;
>        host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
>
> -       if (pxa->pdata->flags & PXA_FLAG_CARD_PERMANENT) {
> +       if (pdata && pdata->flags & PXA_FLAG_CARD_PERMANENT) {
>                /* on-chip device */
>                host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
>                host->mmc->caps |= MMC_CAP_NONREMOVABLE;
>        }
>
> -       if (pdata->quirks)
> +       if (pdata && pdata->quirks)
>                host->quirks |= pdata->quirks;
>
>        ret = sdhci_add_host(host);
> @@ -153,8 +176,8 @@ static int __devinit sdhci_pxa_probe(struct
> platform_device *pdev)
>                goto out;
>        }
>
> -       if (pxa->pdata->max_speed)
> -               host->mmc->f_max = pxa->pdata->max_speed;
> +       if (pdata && pdata->max_speed)
> +               host->mmc->f_max = pdata->max_speed;
>
>        platform_set_drvdata(pdev, host);
>
> --
> 1.7.0.4
>

Acked.
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux