[PATCH v3 4/7] mmc: sdhci-pxav3: Modify clock settings for the SDR50 and DDR50 modes

Ulf Hansson ulf.hansson at linaro.org
Wed Jan 28 12:44:06 PST 2015


On 23 January 2015 at 17:46, Gregory CLEMENT
<gregory.clement at free-electrons.com> wrote:
> From: Marcin Wojtas <mw at semihalf.com>
>
> According to erratum 'FE-2946959' both SDR50 and DDR50 modes require
> specific clock adjustments in SDIO3 Configuration register.
>
> This commit add the support of this register and for SDR50 or DDR50
> mode use it as suggested by the erratum:
> - Set the SDIO3 Clock Inv field in SDIO3 Configuration register to not
> inverted.
> - Set the Sample FeedBack Clock field to 0x1
>
> [gregory.clement at free-electrons.com: port from 3.10]
>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
> ---
>  drivers/mmc/host/sdhci-pxav3.c | 60 ++++++++++++++++++++++++++++++++++++------
>  1 file changed, 52 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index cf017fc39143..a3ebb4404849 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -62,6 +62,7 @@ struct sdhci_pxa {
>         struct clk *clk_core;
>         struct clk *clk_io;
>         u8      power_mode;
> +       void __iomem *sdio3_conf_reg;
>  };
>
>  /*
> @@ -72,6 +73,14 @@ struct sdhci_pxa {
>  #define SDHCI_WINDOW_BASE(i)   (0x84 + ((i) << 3))
>  #define SDHCI_MAX_WIN_NUM      8
>
> +/*
> + * Fields below belong to SDIO3 Configuration Register (third register
> + * region for the Armada 38x flavor)
> + */
> +
> +#define SDIO3_CONF_CLK_INV     BIT(0)
> +#define SDIO3_CONF_SD_FB_CLK   BIT(2)
> +
>  static int mv_conf_mbus_windows(struct platform_device *pdev,
>                                 const struct mbus_dram_target_info *dram)
>  {
> @@ -122,16 +131,31 @@ static int armada_38x_quirks(struct platform_device *pdev,
>                              struct sdhci_host *host)
>  {
>         struct device_node *np = pdev->dev.of_node;
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct sdhci_pxa *pxa = pltfm_host->priv;
> +       struct resource *res;
>
>         host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
> -       /*
> -        * According to erratum 'FE-2946959' both SDR50 and DDR50
> -        * modes require specific clock adjustments in SDIO3
> -        * Configuration register, if the adjustment is not done,
> -        * remove them from the capabilities.
> -        */
> -       host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
> -       host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50);
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> +                                          "conf-sdio3");
> +       if (res) {
> +               pxa->sdio3_conf_reg = devm_ioremap_resource(&pdev->dev, res);
> +               if (IS_ERR(pxa->sdio3_conf_reg))
> +                       return PTR_ERR(pxa->sdio3_conf_reg);
> +       } else {
> +               /*
> +                * According to erratum 'FE-2946959' both SDR50 and DDR50
> +                * modes require specific clock adjustments in SDIO3
> +                * Configuration register, if the adjustment is not done,
> +                * remove them from the capabilities.
> +                */
> +               host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
> +               host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50);
> +
> +               dev_warn(&pdev->dev, "conf-sdio3 register not found\n");
> +               dev_warn(&pdev->dev, "disabling SDR50 and DDR50 modes\n");
> +               dev_warn(&pdev->dev, "consider updating your dtb\n");

One dev_warn() should be enough. Also I don't think checkpatch
complains about long lines for dev_warn().

> +       }
>
>         /*
>          * According to erratum 'ERR-7878951' Armada 38x SDHCI
> @@ -226,6 +250,8 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host *host, u8 power_mode)
>
>  static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
>  {
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct sdhci_pxa *pxa = pltfm_host->priv;
>         u16 ctrl_2;
>
>         /*
> @@ -255,6 +281,24 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
>                 break;
>         }
>
> +       /*
> +        * Update SDIO3 Configuration register according to erratum
> +        * FE-2946959
> +        */
> +       if (pxa->sdio3_conf_reg) {
> +               u8 reg_val  = readb(pxa->sdio3_conf_reg);
> +
> +               if (uhs == MMC_TIMING_UHS_SDR50 ||
> +                   uhs == MMC_TIMING_UHS_DDR50) {
> +                       reg_val &= ~SDIO3_CONF_CLK_INV;
> +                       reg_val |= SDIO3_CONF_SD_FB_CLK;
> +               } else {
> +                       reg_val |= SDIO3_CONF_CLK_INV;
> +                       reg_val &= ~SDIO3_CONF_SD_FB_CLK;
> +               }
> +               writeb(reg_val, pxa->sdio3_conf_reg);
> +       }
> +
>         sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
>         dev_dbg(mmc_dev(host->mmc),
>                 "%s uhs = %d, ctrl_2 = %04X\n",
> --
> 2.1.0
>

Kind regards
Uffe



More information about the linux-arm-kernel mailing list