Message ID | 20220708131404.1489347-7-sumit.garg@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | New boards support: db845c and qcs404-evb | expand |
On Fri, Jul 8, 2022 at 4:14 PM Sumit Garg <sumit.garg@linaro.org> wrote: > > For SDCC version 5.0.0, MCI registers are removed from SDCC interface > and some registers are moved to HC. So add support to use the new > compatible string "qcom,sdhci-msm-v5". Based on this new msm variant, > pick the relevant variant data and use it to detect MCI presence thereby > configuring register read/write to msm specific registers. > > Signed-off-by: Sumit Garg <sumit.garg@linaro.org> > --- > drivers/mmc/msm_sdhci.c | 96 +++++++++++++++++++++++++++-------------- > 1 file changed, 64 insertions(+), 32 deletions(-) > > diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c > index d63d7b3a2c..604f9c3ff9 100644 > --- a/drivers/mmc/msm_sdhci.c > +++ b/drivers/mmc/msm_sdhci.c > @@ -22,18 +22,17 @@ > #define SDCC_MCI_POWER_SW_RST BIT(7) > > /* This is undocumented register */ > -#define SDCC_MCI_VERSION 0x50 > -#define SDCC_MCI_VERSION_MAJOR_SHIFT 28 > -#define SDCC_MCI_VERSION_MAJOR_MASK (0xf << SDCC_MCI_VERSION_MAJOR_SHIFT) > -#define SDCC_MCI_VERSION_MINOR_MASK 0xff > +#define SDCC_MCI_VERSION 0x50 > +#define SDCC_V5_VERSION 0x318 > + > +#define SDCC_VERSION_MAJOR_SHIFT 28 > +#define SDCC_VERSION_MAJOR_MASK (0xf << SDCC_VERSION_MAJOR_SHIFT) > +#define SDCC_VERSION_MINOR_MASK 0xff > > #define SDCC_MCI_STATUS2 0x6C > #define SDCC_MCI_STATUS2_MCI_ACT 0x1 > #define SDCC_MCI_HC_MODE 0x78 > > -/* Offset to SDHCI registers */ > -#define SDCC_SDHCI_OFFSET 0x900 > - > /* Non standard (?) SDHCI register */ > #define SDHCI_VENDOR_SPEC_CAPABILITIES0 0x11c > > @@ -47,6 +46,10 @@ struct msm_sdhc { > void *base; > }; > > +struct msm_sdhc_variant_info { > + bool mci_removed; > +}; > + > DECLARE_GLOBAL_DATA_PTR; > > static int msm_sdc_clk_init(struct udevice *dev) > @@ -85,25 +88,8 @@ static int msm_sdc_clk_init(struct udevice *dev) > return 0; > } > > -static int msm_sdc_probe(struct udevice *dev) > +static int msm_sdc_mci_init(struct msm_sdhc *prv) > { > - struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > - struct msm_sdhc_plat *plat = dev_get_plat(dev); > - struct msm_sdhc *prv = dev_get_priv(dev); > - struct sdhci_host *host = &prv->host; > - u32 core_version, core_minor, core_major; > - u32 caps; > - int ret; > - > - host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; > - > - host->max_clk = 0; > - > - /* Init clocks */ > - ret = msm_sdc_clk_init(dev); > - if (ret) > - return ret; > - > /* Reset the core and Enable SDHC mode */ > writel(readl(prv->base + SDCC_MCI_POWER) | SDCC_MCI_POWER_SW_RST, > prv->base + SDCC_MCI_POWER); > @@ -126,12 +112,45 @@ static int msm_sdc_probe(struct udevice *dev) > /* Enable host-controller mode */ > writel(1, prv->base + SDCC_MCI_HC_MODE); > > - core_version = readl(prv->base + SDCC_MCI_VERSION); > + return 0; > +} > > - core_major = (core_version & SDCC_MCI_VERSION_MAJOR_MASK); > - core_major >>= SDCC_MCI_VERSION_MAJOR_SHIFT; > +static int msm_sdc_probe(struct udevice *dev) > +{ > + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > + struct msm_sdhc_plat *plat = dev_get_plat(dev); > + struct msm_sdhc *prv = dev_get_priv(dev); > + const struct msm_sdhc_variant_info *var_info; > + struct sdhci_host *host = &prv->host; > + u32 core_version, core_minor, core_major; > + u32 caps; > + int ret; > > - core_minor = core_version & SDCC_MCI_VERSION_MINOR_MASK; > + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; > + > + host->max_clk = 0; > + > + /* Init clocks */ > + ret = msm_sdc_clk_init(dev); > + if (ret) > + return ret; > + > + var_info = (void *)dev_get_driver_data(dev); > + if (!var_info->mci_removed) { > + ret = msm_sdc_mci_init(prv); > + if (ret) > + return ret; > + } > + > + if (!var_info->mci_removed) > + core_version = readl(prv->base + SDCC_MCI_VERSION); > + else > + core_version = readl(host->ioaddr + SDCC_V5_VERSION); > + > + core_major = (core_version & SDCC_VERSION_MAJOR_MASK); > + core_major >>= SDCC_VERSION_MAJOR_SHIFT; > + > + core_minor = core_version & SDCC_VERSION_MINOR_MASK; > > /* > * Support for some capabilities is not advertised by newer > @@ -161,9 +180,13 @@ static int msm_sdc_probe(struct udevice *dev) > static int msm_sdc_remove(struct udevice *dev) > { > struct msm_sdhc *priv = dev_get_priv(dev); > + const struct msm_sdhc_variant_info *var_info; > + > + var_info = (void *)dev_get_driver_data(dev); > > - /* Disable host-controller mode */ > - writel(0, priv->base + SDCC_MCI_HC_MODE); > + /* Disable host-controller mode */ > + if (!var_info->mci_removed) > + writel(0, priv->base + SDCC_MCI_HC_MODE); > > return 0; > } > @@ -195,8 +218,17 @@ static int msm_sdc_bind(struct udevice *dev) > return sdhci_bind(dev, &plat->mmc, &plat->cfg); > } > > +static const struct msm_sdhc_variant_info msm_sdhc_mci_var = { > + .mci_removed = false, > +}; > + > +static const struct msm_sdhc_variant_info msm_sdhc_v5_var = { > + .mci_removed = true, > +}; > + > static const struct udevice_id msm_mmc_ids[] = { > - { .compatible = "qcom,sdhci-msm-v4" }, > + { .compatible = "qcom,sdhci-msm-v4", .data = (ulong)&msm_sdhc_mci_var }, > + { .compatible = "qcom,sdhci-msm-v5", .data = (ulong)&msm_sdhc_v5_var }, > { } > }; > > -- > 2.25.1 > Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index d63d7b3a2c..604f9c3ff9 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -22,18 +22,17 @@ #define SDCC_MCI_POWER_SW_RST BIT(7) /* This is undocumented register */ -#define SDCC_MCI_VERSION 0x50 -#define SDCC_MCI_VERSION_MAJOR_SHIFT 28 -#define SDCC_MCI_VERSION_MAJOR_MASK (0xf << SDCC_MCI_VERSION_MAJOR_SHIFT) -#define SDCC_MCI_VERSION_MINOR_MASK 0xff +#define SDCC_MCI_VERSION 0x50 +#define SDCC_V5_VERSION 0x318 + +#define SDCC_VERSION_MAJOR_SHIFT 28 +#define SDCC_VERSION_MAJOR_MASK (0xf << SDCC_VERSION_MAJOR_SHIFT) +#define SDCC_VERSION_MINOR_MASK 0xff #define SDCC_MCI_STATUS2 0x6C #define SDCC_MCI_STATUS2_MCI_ACT 0x1 #define SDCC_MCI_HC_MODE 0x78 -/* Offset to SDHCI registers */ -#define SDCC_SDHCI_OFFSET 0x900 - /* Non standard (?) SDHCI register */ #define SDHCI_VENDOR_SPEC_CAPABILITIES0 0x11c @@ -47,6 +46,10 @@ struct msm_sdhc { void *base; }; +struct msm_sdhc_variant_info { + bool mci_removed; +}; + DECLARE_GLOBAL_DATA_PTR; static int msm_sdc_clk_init(struct udevice *dev) @@ -85,25 +88,8 @@ static int msm_sdc_clk_init(struct udevice *dev) return 0; } -static int msm_sdc_probe(struct udevice *dev) +static int msm_sdc_mci_init(struct msm_sdhc *prv) { - struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); - struct msm_sdhc_plat *plat = dev_get_plat(dev); - struct msm_sdhc *prv = dev_get_priv(dev); - struct sdhci_host *host = &prv->host; - u32 core_version, core_minor, core_major; - u32 caps; - int ret; - - host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; - - host->max_clk = 0; - - /* Init clocks */ - ret = msm_sdc_clk_init(dev); - if (ret) - return ret; - /* Reset the core and Enable SDHC mode */ writel(readl(prv->base + SDCC_MCI_POWER) | SDCC_MCI_POWER_SW_RST, prv->base + SDCC_MCI_POWER); @@ -126,12 +112,45 @@ static int msm_sdc_probe(struct udevice *dev) /* Enable host-controller mode */ writel(1, prv->base + SDCC_MCI_HC_MODE); - core_version = readl(prv->base + SDCC_MCI_VERSION); + return 0; +} - core_major = (core_version & SDCC_MCI_VERSION_MAJOR_MASK); - core_major >>= SDCC_MCI_VERSION_MAJOR_SHIFT; +static int msm_sdc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct msm_sdhc_plat *plat = dev_get_plat(dev); + struct msm_sdhc *prv = dev_get_priv(dev); + const struct msm_sdhc_variant_info *var_info; + struct sdhci_host *host = &prv->host; + u32 core_version, core_minor, core_major; + u32 caps; + int ret; - core_minor = core_version & SDCC_MCI_VERSION_MINOR_MASK; + host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_BROKEN_R1B; + + host->max_clk = 0; + + /* Init clocks */ + ret = msm_sdc_clk_init(dev); + if (ret) + return ret; + + var_info = (void *)dev_get_driver_data(dev); + if (!var_info->mci_removed) { + ret = msm_sdc_mci_init(prv); + if (ret) + return ret; + } + + if (!var_info->mci_removed) + core_version = readl(prv->base + SDCC_MCI_VERSION); + else + core_version = readl(host->ioaddr + SDCC_V5_VERSION); + + core_major = (core_version & SDCC_VERSION_MAJOR_MASK); + core_major >>= SDCC_VERSION_MAJOR_SHIFT; + + core_minor = core_version & SDCC_VERSION_MINOR_MASK; /* * Support for some capabilities is not advertised by newer @@ -161,9 +180,13 @@ static int msm_sdc_probe(struct udevice *dev) static int msm_sdc_remove(struct udevice *dev) { struct msm_sdhc *priv = dev_get_priv(dev); + const struct msm_sdhc_variant_info *var_info; + + var_info = (void *)dev_get_driver_data(dev); - /* Disable host-controller mode */ - writel(0, priv->base + SDCC_MCI_HC_MODE); + /* Disable host-controller mode */ + if (!var_info->mci_removed) + writel(0, priv->base + SDCC_MCI_HC_MODE); return 0; } @@ -195,8 +218,17 @@ static int msm_sdc_bind(struct udevice *dev) return sdhci_bind(dev, &plat->mmc, &plat->cfg); } +static const struct msm_sdhc_variant_info msm_sdhc_mci_var = { + .mci_removed = false, +}; + +static const struct msm_sdhc_variant_info msm_sdhc_v5_var = { + .mci_removed = true, +}; + static const struct udevice_id msm_mmc_ids[] = { - { .compatible = "qcom,sdhci-msm-v4" }, + { .compatible = "qcom,sdhci-msm-v4", .data = (ulong)&msm_sdhc_mci_var }, + { .compatible = "qcom,sdhci-msm-v5", .data = (ulong)&msm_sdhc_v5_var }, { } };
For SDCC version 5.0.0, MCI registers are removed from SDCC interface and some registers are moved to HC. So add support to use the new compatible string "qcom,sdhci-msm-v5". Based on this new msm variant, pick the relevant variant data and use it to detect MCI presence thereby configuring register read/write to msm specific registers. Signed-off-by: Sumit Garg <sumit.garg@linaro.org> --- drivers/mmc/msm_sdhci.c | 96 +++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 32 deletions(-)