Hi,

CC'd Peng.

On 8/22/20 11:37 AM, John Robertson wrote:
> Refresh driver code, remove obsolete DT props and set the max clock
> rate from the source clock 'base_clk'.
> 
> Card detect is also broken. The fix implemented for erratum #15
> documented in Microchip ref. DS80000736D only needs to be done as
> in the current code (set CDSSEL, clear CDTLVL in SDHCCON1 to force
> 'detect') if the SDCD pin is not connected. If it is connected,
> card detect works fine. A vendor specific flag 'microchip,use-sdcd'
> has been added to enable real card detect functionality.
> 
> The card detect signal CDSLVL provided in the status register is
> inverted as described in erratum #16, but this does not apply to
> U-Boot because it uses the card inserted CARDINS flag. Therefore,
> 'cd-inverted' is not required.
> 
> Signed-off-by: John Robertson <john.robert...@simiatec.com>
> ---
> 
>  arch/mips/dts/pic32mzda_sk.dts  |  1 +
>  drivers/mmc/pic32_sdhci.c       | 77 ++++++++++++++++++++-------------
>  drivers/pinctrl/pinctrl_pic32.c | 28 ++++++++++++
>  3 files changed, 77 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/mips/dts/pic32mzda_sk.dts b/arch/mips/dts/pic32mzda_sk.dts
> index b3c916a6db..fc86154e0a 100644
> --- a/arch/mips/dts/pic32mzda_sk.dts
> +++ b/arch/mips/dts/pic32mzda_sk.dts
> @@ -40,6 +40,7 @@
>  };
>  
>  &sdhci {
> +     microchip,use-sdcd;
>       status = "okay";
>  };
>  
> diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
> index 029e0fbc2b..93f0532ad6 100644
> --- a/drivers/mmc/pic32_sdhci.c
> +++ b/drivers/mmc/pic32_sdhci.c
> @@ -9,62 +9,78 @@
>  #include <common.h>
>  #include <dm.h>
>  #include <sdhci.h>
> -#include <linux/errno.h>
> -#include <mach/pic32.h>
> +#include <clk.h>
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> -static int pic32_sdhci_get_cd(struct sdhci_host *host)
> -{
> -     /* PIC32 SDHCI CD errata:
> -      * - set CD_TEST and clear CD_TEST_INS bit
> -      */
> -     sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL);
> -
> -     return 0;
> -}
> -
> -static const struct sdhci_ops pic32_sdhci_ops = {
> -     .get_cd = pic32_sdhci_get_cd,
> +struct pic32_sdhci_plat {
> +     struct mmc_config cfg;
> +     struct mmc mmc;
>  };
>  
>  static int pic32_sdhci_probe(struct udevice *dev)
>  {
> +     struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
> +     struct pic32_sdhci_plat *plat = dev_get_platdata(dev);
>       struct sdhci_host *host = dev_get_priv(dev);
> -     const void *fdt = gd->fdt_blob;
> -     u32 f_min_max[2];
> +
>       fdt_addr_t addr;
>       fdt_size_t size;
> +     struct clk clk;
> +     ulong clk_rate;
>       int ret;
>  
> -     addr = fdtdec_get_addr_size(fdt, dev_of_offset(dev), "reg", &size);
> +     addr = dev_read_addr_size(dev, "reg", &size);
>       if (addr == FDT_ADDR_T_NONE)
>               return -EINVAL;
>  
> +     ret = clk_get_by_name(dev, "base_clk", &clk);
> +     if (ret)
> +             return ret;
> +
> +     clk_rate = clk_get_rate(&clk);
> +     clk_free(&clk);

There is no case about using clk? it doesn't need to free clk.

> +
> +     if (IS_ERR_VALUE(clk_rate))
> +             return clk_rate;
> +
>       host->ioaddr    = ioremap(addr, size);
>       host->name      = dev->name;
>       host->quirks    = SDHCI_QUIRK_NO_HISPD_BIT;
> -     host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
> -                                     "bus-width", 4);
> -     host->ops = &pic32_sdhci_ops;
> -
> -     ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
> -                                "clock-freq-min-max", f_min_max, 2);
> -     if (ret) {
> -             printf("sdhci: clock-freq-min-max not found\n");
> +     host->bus_width = dev_read_u32_default(dev, "bus-width", 4);

if you can use mmc_of_parse(), then bus-width will be parsed.

> +     host->max_clk   = clk_rate;
> +
> +     host->mmc = &plat->mmc;
> +     host->mmc->dev = dev;
> +
> +     ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
> +     if (ret)
>               return ret;
> -     }
>  
> -     host->max_clk   = f_min_max[1];
> +     host->mmc->priv = host;
> +     upriv->mmc = host->mmc;
>  
> -     ret = add_sdhci(host, 0, f_min_max[0]);
> +     ret = sdhci_probe(dev);
>       if (ret)
>               return ret;
> -     host->mmc->dev = dev;
> +
> +     if (!dev_read_bool(dev, "microchip,use-sdcd")) {
> +             // Use workaround 1 for erratum #15 by default

Explain workaround in more detail, plz.

> +             u8 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> +             ctrl = (ctrl & ~SDHCI_CTRL_CD_TEST_INS) | SDHCI_CTRL_CD_TEST;
> +             sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> +     }
>  
>       return 0;
>  }
>  
> +static int pic32_sdhci_bind(struct udevice *dev)
> +{
> +     struct pic32_sdhci_plat *plat = dev_get_platdata(dev);
> +
> +     return sdhci_bind(dev, &plat->mmc, &plat->cfg);
> +}
> +
>  static const struct udevice_id pic32_sdhci_ids[] = {
>       { .compatible = "microchip,pic32mzda-sdhci" },
>       { }
> @@ -74,6 +90,9 @@ U_BOOT_DRIVER(pic32_sdhci_drv) = {
>       .name                   = "pic32_sdhci",
>       .id                     = UCLASS_MMC,
>       .of_match               = pic32_sdhci_ids,
> +     .ops                    = &sdhci_ops,
> +     .bind                   = pic32_sdhci_bind,
>       .probe                  = pic32_sdhci_probe,
>       .priv_auto_alloc_size   = sizeof(struct sdhci_host),
> +     .platdata_auto_alloc_size = sizeof(struct pic32_sdhci_plat)
>  };
> diff --git a/drivers/pinctrl/pinctrl_pic32.c b/drivers/pinctrl/pinctrl_pic32.c
> index 911af1297b..899c279975 100644
> --- a/drivers/pinctrl/pinctrl_pic32.c
> +++ b/drivers/pinctrl/pinctrl_pic32.c
> @@ -222,6 +222,31 @@ static void pic32_eth_pin_config(struct udevice *dev)
>       pic32_pinconfig_set(priv, configs, ARRAY_SIZE(configs));
>  }
>  
> +static void pic32_sdhci_pin_config(struct udevice *dev)
> +{
> +     struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
> +     const struct pic32_pin_config configs[] = {
> +             /* SDWP - H2 */
> +             PIN_CONFIG(PIC32_PORT_H, 2, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDCD - A0 */
> +             PIN_CONFIG(PIC32_PORT_A, 0, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDCMD - D4 */
> +             PIN_CONFIG(PIC32_PORT_D, 4, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDCK - A6 */
> +             PIN_CONFIG(PIC32_PORT_A, 6, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDDATA0 - G13 */
> +             PIN_CONFIG(PIC32_PORT_G, 13, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDDATA1 - G12 */
> +             PIN_CONFIG(PIC32_PORT_G, 12, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDDATA2 - G14 */
> +             PIN_CONFIG(PIC32_PORT_G, 14, PIN_CONFIG_PIC32_DIGITAL),
> +             /* SDDATA3 - A7 */
> +             PIN_CONFIG(PIC32_PORT_A, 7, PIN_CONFIG_PIC32_DIGITAL),
> +     };
> +
> +     pic32_pinconfig_set(priv, configs, ARRAY_SIZE(configs));
> +}
> +
>  static int pic32_pinctrl_request(struct udevice *dev, int func, int flags)
>  {
>       struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
> @@ -240,6 +265,9 @@ static int pic32_pinctrl_request(struct udevice *dev, int 
> func, int flags)
>       case PERIPH_ID_ETH:
>               pic32_eth_pin_config(dev);
>               break;
> +     case PERIPH_ID_SDHCI:
> +             pic32_sdhci_pin_config(dev);
> +             break;
>       default:
>               debug("%s: unknown-unhandled case\n", __func__);
>               break;
> 

Reply via email to