On Tue, 26 May 2020 at 08:29, Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@xxxxxxxxx> 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@xxxxxxxxx> > Reviewed-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> 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 >