Message ID | 20200526062758.17642-3-wan.ahmad.zainie.wan.mohamad@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mmc: sdhci-of-arasan: Add support for Intel Keem Bay | expand |
On Tue, 26 May 2020 at 08:29, Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com> wrote: > > Intel Keem Bay SoC eMMC/SD/SDIO controller is based on > Arasan SD 3.0 / eMMC 5.1 host controller IP. > > However, it does not support 64-bit access as its AXI interface > has 32-bit address ports. > > Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com> > Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> Applied for next, thanks! Kind regards Uffe > --- > drivers/mmc/host/sdhci-of-arasan.c | 123 +++++++++++++++++++++++++++++ > 1 file changed, 123 insertions(+) > > diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c > index 2fe2c4dcc280..db9b544465cd 100644 > --- a/drivers/mmc/host/sdhci-of-arasan.c > +++ b/drivers/mmc/host/sdhci-of-arasan.c > @@ -75,6 +75,7 @@ struct sdhci_arasan_soc_ctl_field { > * > * @baseclkfreq: Where to find corecfg_baseclkfreq > * @clockmultiplier: Where to find corecfg_clockmultiplier > + * @support64b: Where to find SUPPORT64B bit > * @hiword_update: If true, use HIWORD_UPDATE to access the syscon > * > * It's up to the licensee of the Arsan IP block to make these available > @@ -84,6 +85,7 @@ struct sdhci_arasan_soc_ctl_field { > struct sdhci_arasan_soc_ctl_map { > struct sdhci_arasan_soc_ctl_field baseclkfreq; > struct sdhci_arasan_soc_ctl_field clockmultiplier; > + struct sdhci_arasan_soc_ctl_field support64b; > bool hiword_update; > }; > > @@ -180,6 +182,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = { > .hiword_update = false, > }; > > +static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = { > + .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 }, > + .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, > + .support64b = { .reg = 0x4, .width = 1, .shift = 24 }, > + .hiword_update = false, > +}; > + > /** > * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers > * > @@ -1095,6 +1104,50 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = { > .clk_ops = &arasan_clk_ops, > }; > > +static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = { > + .ops = &sdhci_arasan_cqe_ops, > + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | > + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > + SDHCI_QUIRK_NO_LED | > + SDHCI_QUIRK_32BIT_DMA_ADDR | > + SDHCI_QUIRK_32BIT_DMA_SIZE | > + SDHCI_QUIRK_32BIT_ADMA_SIZE, > + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | > + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | > + SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | > + SDHCI_QUIRK2_STOP_WITH_TC | > + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, > +}; > + > +static const struct sdhci_pltfm_data sdhci_keembay_sd_pdata = { > + .ops = &sdhci_arasan_ops, > + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | > + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > + SDHCI_QUIRK_NO_LED | > + SDHCI_QUIRK_32BIT_DMA_ADDR | > + SDHCI_QUIRK_32BIT_DMA_SIZE | > + SDHCI_QUIRK_32BIT_ADMA_SIZE, > + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | > + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | > + SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | > + SDHCI_QUIRK2_STOP_WITH_TC | > + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, > +}; > + > +static const struct sdhci_pltfm_data sdhci_keembay_sdio_pdata = { > + .ops = &sdhci_arasan_ops, > + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | > + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | > + SDHCI_QUIRK_NO_LED | > + SDHCI_QUIRK_32BIT_DMA_ADDR | > + SDHCI_QUIRK_32BIT_DMA_SIZE | > + SDHCI_QUIRK_32BIT_ADMA_SIZE, > + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | > + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | > + SDHCI_QUIRK2_HOST_OFF_CARD_ON | > + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, > +}; > + > static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = { > .soc_ctl_map = &rk3399_soc_ctl_map, > .pdata = &sdhci_arasan_cqe_pdata, > @@ -1140,6 +1193,21 @@ static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { > .clk_ops = &versal_clk_ops, > }; > > +static struct sdhci_arasan_of_data intel_keembay_emmc_data = { > + .soc_ctl_map = &intel_keembay_soc_ctl_map, > + .pdata = &sdhci_keembay_emmc_pdata, > +}; > + > +static struct sdhci_arasan_of_data intel_keembay_sd_data = { > + .soc_ctl_map = &intel_keembay_soc_ctl_map, > + .pdata = &sdhci_keembay_sd_pdata, > +}; > + > +static struct sdhci_arasan_of_data intel_keembay_sdio_data = { > + .soc_ctl_map = &intel_keembay_soc_ctl_map, > + .pdata = &sdhci_keembay_sdio_pdata, > +}; > + > static const struct of_device_id sdhci_arasan_of_match[] = { > /* SoC-specific compatible strings w/ soc_ctl_map */ > { > @@ -1154,6 +1222,18 @@ static const struct of_device_id sdhci_arasan_of_match[] = { > .compatible = "intel,lgm-sdhci-5.1-sdxc", > .data = &intel_lgm_sdxc_data, > }, > + { > + .compatible = "intel,keembay-sdhci-5.1-emmc", > + .data = &intel_keembay_emmc_data, > + }, > + { > + .compatible = "intel,keembay-sdhci-5.1-sd", > + .data = &intel_keembay_sd_data, > + }, > + { > + .compatible = "intel,keembay-sdhci-5.1-sdio", > + .data = &intel_keembay_sdio_data, > + }, > /* Generic compatible below here */ > { > .compatible = "arasan,sdhci-8.9a", > @@ -1297,6 +1377,40 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev) > of_clk_del_provider(dev->of_node); > } > > +/** > + * sdhci_arasan_update_support64b - Set SUPPORT_64B (64-bit System Bus Support) > + * > + * This should be set based on the System Address Bus. > + * 0: the Core supports only 32-bit System Address Bus. > + * 1: the Core supports 64-bit System Address Bus. > + * > + * NOTES: > + * - For Keem Bay, it is required to clear this bit. Its default value is 1'b1. > + * Keem Bay does not support 64-bit access. > + * > + * @host The sdhci_host > + */ > +static void sdhci_arasan_update_support64b(struct sdhci_host *host, u32 value) > +{ > + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > + struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); > + const struct sdhci_arasan_soc_ctl_map *soc_ctl_map = > + sdhci_arasan->soc_ctl_map; > + > + /* Having a map is optional */ > + if (!soc_ctl_map) > + return; > + > + /* If we have a map, we expect to have a syscon */ > + if (!sdhci_arasan->soc_ctl_base) { > + pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", > + mmc_hostname(host->mmc)); > + return; > + } > + > + sdhci_arasan_syscon_write(host, &soc_ctl_map->support64b, value); > +} > + > /** > * sdhci_arasan_register_sdclk - Register the sdcardclk for a PHY to use > * > @@ -1469,6 +1583,15 @@ static int sdhci_arasan_probe(struct platform_device *pdev) > "rockchip,rk3399-sdhci-5.1")) > sdhci_arasan_update_clockmultiplier(host, 0x0); > > + if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") || > + of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || > + of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) { > + sdhci_arasan_update_clockmultiplier(host, 0x0); > + sdhci_arasan_update_support64b(host, 0x0); > + > + host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; > + } > + > sdhci_arasan_update_baseclkfreq(host); > > ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, &pdev->dev); > -- > 2.17.1 >
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 2fe2c4dcc280..db9b544465cd 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c @@ -75,6 +75,7 @@ struct sdhci_arasan_soc_ctl_field { * * @baseclkfreq: Where to find corecfg_baseclkfreq * @clockmultiplier: Where to find corecfg_clockmultiplier + * @support64b: Where to find SUPPORT64B bit * @hiword_update: If true, use HIWORD_UPDATE to access the syscon * * It's up to the licensee of the Arsan IP block to make these available @@ -84,6 +85,7 @@ struct sdhci_arasan_soc_ctl_field { struct sdhci_arasan_soc_ctl_map { struct sdhci_arasan_soc_ctl_field baseclkfreq; struct sdhci_arasan_soc_ctl_field clockmultiplier; + struct sdhci_arasan_soc_ctl_field support64b; bool hiword_update; }; @@ -180,6 +182,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = { .hiword_update = false, }; +static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = { + .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 }, + .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, + .support64b = { .reg = 0x4, .width = 1, .shift = 24 }, + .hiword_update = false, +}; + /** * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers * @@ -1095,6 +1104,50 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = { .clk_ops = &arasan_clk_ops, }; +static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = { + .ops = &sdhci_arasan_cqe_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | + SDHCI_QUIRK_NO_LED | + SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | + SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | + SDHCI_QUIRK2_STOP_WITH_TC | + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, +}; + +static const struct sdhci_pltfm_data sdhci_keembay_sd_pdata = { + .ops = &sdhci_arasan_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | + SDHCI_QUIRK_NO_LED | + SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | + SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | + SDHCI_QUIRK2_STOP_WITH_TC | + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, +}; + +static const struct sdhci_pltfm_data sdhci_keembay_sdio_pdata = { + .ops = &sdhci_arasan_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | + SDHCI_QUIRK_NO_LED | + SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | + SDHCI_QUIRK2_HOST_OFF_CARD_ON | + SDHCI_QUIRK2_BROKEN_64_BIT_DMA, +}; + static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = { .soc_ctl_map = &rk3399_soc_ctl_map, .pdata = &sdhci_arasan_cqe_pdata, @@ -1140,6 +1193,21 @@ static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { .clk_ops = &versal_clk_ops, }; +static struct sdhci_arasan_of_data intel_keembay_emmc_data = { + .soc_ctl_map = &intel_keembay_soc_ctl_map, + .pdata = &sdhci_keembay_emmc_pdata, +}; + +static struct sdhci_arasan_of_data intel_keembay_sd_data = { + .soc_ctl_map = &intel_keembay_soc_ctl_map, + .pdata = &sdhci_keembay_sd_pdata, +}; + +static struct sdhci_arasan_of_data intel_keembay_sdio_data = { + .soc_ctl_map = &intel_keembay_soc_ctl_map, + .pdata = &sdhci_keembay_sdio_pdata, +}; + static const struct of_device_id sdhci_arasan_of_match[] = { /* SoC-specific compatible strings w/ soc_ctl_map */ { @@ -1154,6 +1222,18 @@ static const struct of_device_id sdhci_arasan_of_match[] = { .compatible = "intel,lgm-sdhci-5.1-sdxc", .data = &intel_lgm_sdxc_data, }, + { + .compatible = "intel,keembay-sdhci-5.1-emmc", + .data = &intel_keembay_emmc_data, + }, + { + .compatible = "intel,keembay-sdhci-5.1-sd", + .data = &intel_keembay_sd_data, + }, + { + .compatible = "intel,keembay-sdhci-5.1-sdio", + .data = &intel_keembay_sdio_data, + }, /* Generic compatible below here */ { .compatible = "arasan,sdhci-8.9a", @@ -1297,6 +1377,40 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev) of_clk_del_provider(dev->of_node); } +/** + * sdhci_arasan_update_support64b - Set SUPPORT_64B (64-bit System Bus Support) + * + * This should be set based on the System Address Bus. + * 0: the Core supports only 32-bit System Address Bus. + * 1: the Core supports 64-bit System Address Bus. + * + * NOTES: + * - For Keem Bay, it is required to clear this bit. Its default value is 1'b1. + * Keem Bay does not support 64-bit access. + * + * @host The sdhci_host + */ +static void sdhci_arasan_update_support64b(struct sdhci_host *host, u32 value) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); + const struct sdhci_arasan_soc_ctl_map *soc_ctl_map = + sdhci_arasan->soc_ctl_map; + + /* Having a map is optional */ + if (!soc_ctl_map) + return; + + /* If we have a map, we expect to have a syscon */ + if (!sdhci_arasan->soc_ctl_base) { + pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", + mmc_hostname(host->mmc)); + return; + } + + sdhci_arasan_syscon_write(host, &soc_ctl_map->support64b, value); +} + /** * sdhci_arasan_register_sdclk - Register the sdcardclk for a PHY to use * @@ -1469,6 +1583,15 @@ static int sdhci_arasan_probe(struct platform_device *pdev) "rockchip,rk3399-sdhci-5.1")) sdhci_arasan_update_clockmultiplier(host, 0x0); + if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") || + of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || + of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) { + sdhci_arasan_update_clockmultiplier(host, 0x0); + sdhci_arasan_update_support64b(host, 0x0); + + host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; + } + sdhci_arasan_update_baseclkfreq(host); ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, &pdev->dev);