RE: [PATCH v2] mmc: sdhci-of-esdhc: modify the sd clock in soc_device_match way

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

 




-----Original Message-----
From: Ulf Hansson [mailto:ulf.hansson@xxxxxxxxxx] 
Sent: 2018年5月22日 20:16
To: Yinbo Zhu <yinbo.zhu@xxxxxxx>
Cc: Y.b. Lu <yangbo.lu@xxxxxxx>; Adrian Hunter <adrian.hunter@xxxxxxxxx>; linux-mmc@xxxxxxxxxxxxxxx; Xiaobo Xie <xiaobo.xie@xxxxxxx>
Subject: Re: [PATCH v2] mmc: sdhci-of-esdhc: modify the sd clock in soc_device_match way

On 22 May 2018 at 14:06, Yinbo Zhu <yinbo.zhu@xxxxxxx> wrote:
> From: yinbo.zhu <yinbo.zhu@xxxxxxx>
>
> Convert to use soc_device_match method to fix up eSDHC clock for 
> ls1046a/ls1012a/p1010. Also add eSDHC clock fixup for ls1021a 
> according to its datasheet. The maxmum speed for ls1021a eSDHC high 
> speed mode is 46.5MHz.

>Why not use mmc DT property "max-frequency" instead?

>Why exactly do you need a different max frequency depending on the selected speed mode?

>Kind regards
>Uffe
Accroding to datasheet that the different max frequency depending on the slected speed mode and SoC,
In the current state that which only shows one of the max-frequency, so it can't use mmc DT property "max-frequency" instead  

Regards
Yinbo
>
> Signed-off-by: Yinbo Zhu <yinbo.zhu@xxxxxxx>
> ---
>  drivers/mmc/host/sdhci-of-esdhc.c |  105 
> ++++++++++++++++++++++++++++++-------
>  1 files changed, 85 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c 
> b/drivers/mmc/host/sdhci-of-esdhc.c
> index 4ffa6b1..4d82c6d 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -29,11 +29,58 @@
>  #define VENDOR_V_22    0x12
>  #define VENDOR_V_23    0x13
>
> +struct esdhc_clk_fixup {
> +       /* SD speed modes */
> +       long ds;
> +       long hs;
> +       long sdr12;
> +       long sdr25;
> +       long sdr50;
> +       long sdr104;
> +       long ddr50;
> +       /* MMC speed modes */
> +       long mmc_ds;
> +       long mmc_hs;
> +       long hs200;
> +       long ddr52;
> +};
> +
> +static struct esdhc_clk_fixup ls1021a_esdhc_clk = {
> +       .mmc_hs = 46500000,
> +       .hs = 46500000,
> +};
> +
> +static struct esdhc_clk_fixup ls1046a_esdhc_clk = {
> +       .sdr104 = 167000000,
> +       .hs200 = 167000000,
> +};
> +
> +static struct esdhc_clk_fixup ls1012a_esdhc_clk = {
> +       .sdr104 = 125000000,
> +       .hs200 = 125000000,
> +};
> +
> +static struct esdhc_clk_fixup p1010_esdhc_clk = {
> +       .ds = 20000000,
> +       .hs = 40000000,
> +       .mmc_ds = 20000000,
> +       .mmc_hs = 42000000,
> +};
> +
> +static struct soc_device_attribute soc_esdhc_clk_fixup[] = {
> +       { .family = "QorIQ LS1021A", .data = &ls1021a_esdhc_clk},
> +       { .family = "QorIQ LS1046A", .data = &ls1046a_esdhc_clk},
> +       { .family = "QorIQ LS1012A", .data = &ls1012a_esdhc_clk},
> +       { .family = "QorIQ P1010",  .data = &p1010_esdhc_clk},
> +       {},
> +};
> +
>  struct sdhci_esdhc {
>         u8 vendor_ver;
>         u8 spec_ver;
>         bool quirk_incorrect_hostver;
>         unsigned int peripheral_clock;
> +       const struct esdhc_clk_fixup *clk_fixup;
>  };
>
>  /**
> @@ -485,6 +532,14 @@ static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
>         }
>  }
>
> +static long esdhc_clock_fixup(long clock, long clock_standard, long 
> +fixup) {
> +       if (!fixup)
> +               return clock;
> +
> +       return (clock == clock_standard) ? fixup : clock; }
> +
>  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int 
> clock)  {
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ 
> -492,6 +547,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>         int pre_div = 1;
>         int div = 1;
>         ktime_t timeout;
> +       long fixup;
>         u32 temp;
>
>         host->mmc->actual_clock = 0;
> @@ -505,26 +561,31 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>         if (esdhc->vendor_ver < VENDOR_V_23)
>                 pre_div = 2;
>
> -       /*
> -        * Limit SD clock to 167MHz for ls1046a according to its datasheet
> -        */
> -       if (clock > 167000000 &&
> -           of_find_compatible_node(NULL, NULL, "fsl,ls1046a-esdhc"))
> -               clock = 167000000;
> -
> -       /*
> -        * Limit SD clock to 125MHz for ls1012a according to its datasheet
> -        */
> -       if (clock > 125000000 &&
> -           of_find_compatible_node(NULL, NULL, "fsl,ls1012a-esdhc"))
> -               clock = 125000000;
> -
> -       /* Workaround to reduce the clock frequency for p1010 esdhc */
> -       if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
> -               if (clock > 20000000)
> -                       clock -= 5000000;
> -               if (clock > 40000000)
> -                       clock -= 5000000;
> +       switch (host->mmc->ios.timing) {
> +       case MMC_TIMING_LEGACY:
> +               fixup = esdhc->clk_fixup->ds;
> +               clock = esdhc_clock_fixup(clock, FULL_SPEED_MAX_DTR, fixup);
> +               fixup = esdhc->clk_fixup->mmc_ds;
> +               clock = esdhc_clock_fixup(clock, MMC_HIGH_26_MAX_DTR, fixup);
> +               break;
> +       case MMC_TIMING_SD_HS:
> +               fixup = esdhc->clk_fixup->hs;
> +               clock = esdhc_clock_fixup(clock, HIGH_SPEED_MAX_DTR, fixup);
> +               break;
> +       case MMC_TIMING_MMC_HS:
> +               fixup = esdhc->clk_fixup->mmc_hs;
> +               clock = esdhc_clock_fixup(clock, MMC_HIGH_52_MAX_DTR, fixup);
> +               break;
> +       case MMC_TIMING_UHS_SDR104:
> +               fixup = esdhc->clk_fixup->sdr104;
> +               clock = esdhc_clock_fixup(clock, UHS_SDR104_MAX_DTR, fixup);
> +               break;
> +       case MMC_TIMING_MMC_HS200:
> +               fixup = esdhc->clk_fixup->hs200;
> +               clock = esdhc_clock_fixup(clock, MMC_HS200_MAX_DTR, fixup);
> +               break;
> +       default:
> +               break;
>         }
>
>         temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); @@ -783,6 
> +844,7 @@ static SIMPLE_DEV_PM_OPS(esdhc_of_dev_pm_ops,
>
>  static void esdhc_init(struct platform_device *pdev, struct 
> sdhci_host *host)  {
> +       const struct soc_device_attribute *matches;
>         struct sdhci_pltfm_host *pltfm_host;
>         struct sdhci_esdhc *esdhc;
>         struct device_node *np;
> @@ -802,6 +864,9 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>         else
>                 esdhc->quirk_incorrect_hostver = false;
>
> +       matches = soc_device_match(soc_esdhc_clk_fixup);
> +       if (matches)
> +               esdhc->clk_fixup = matches->data;
>         np = pdev->dev.of_node;
>         clk = of_clk_get(np, 0);
>         if (!IS_ERR(clk)) {
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" 
> in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo 
> info at  
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fvger
> .kernel.org%2Fmajordomo-info.html&data=02%7C01%7Cyinbo.zhu%40nxp.com%7
> C1c5fc7f3c1b64c675fdb08d5bfddbeb0%7C686ea1d3bc2b4c6fa92cd99c5c301635%7
> C0%7C0%7C636625881475020985&sdata=OwMQMGXVuxo4qyxqUzADM6Kg%2BozrM3HuoX
> QTWWzFbNI%3D&reserved=0
��.n��������+%������w��{.n�����{��i��)��jg��������ݢj����G�������j:+v���w�m������w�������h�����٥




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

  Powered by Linux