Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * drivers/mmc/host/sdhci-of-sparx5.c
0004  *
0005  * MCHP Sparx5 SoC Secure Digital Host Controller Interface.
0006  *
0007  * Copyright (c) 2019 Microchip Inc.
0008  *
0009  * Author: Lars Povlsen <lars.povlsen@microchip.com>
0010  */
0011 
0012 #include <linux/sizes.h>
0013 #include <linux/delay.h>
0014 #include <linux/module.h>
0015 #include <linux/regmap.h>
0016 #include <linux/of_device.h>
0017 #include <linux/mfd/syscon.h>
0018 #include <linux/dma-mapping.h>
0019 
0020 #include "sdhci-pltfm.h"
0021 
0022 #define CPU_REGS_GENERAL_CTRL   (0x22 * 4)
0023 #define  MSHC_DLY_CC_MASK   GENMASK(16, 13)
0024 #define  MSHC_DLY_CC_SHIFT  13
0025 #define  MSHC_DLY_CC_MAX    15
0026 
0027 #define CPU_REGS_PROC_CTRL  (0x2C * 4)
0028 #define  ACP_CACHE_FORCE_ENA    BIT(4)
0029 #define  ACP_AWCACHE        BIT(3)
0030 #define  ACP_ARCACHE        BIT(2)
0031 #define  ACP_CACHE_MASK     (ACP_CACHE_FORCE_ENA|ACP_AWCACHE|ACP_ARCACHE)
0032 
0033 #define MSHC2_VERSION           0x500   /* Off 0x140, reg 0x0 */
0034 #define MSHC2_TYPE          0x504   /* Off 0x140, reg 0x1 */
0035 #define MSHC2_EMMC_CTRL         0x52c   /* Off 0x140, reg 0xB */
0036 #define  MSHC2_EMMC_CTRL_EMMC_RST_N BIT(2)
0037 #define  MSHC2_EMMC_CTRL_IS_EMMC    BIT(0)
0038 
0039 struct sdhci_sparx5_data {
0040     struct sdhci_host *host;
0041     struct regmap *cpu_ctrl;
0042     int delay_clock;
0043 };
0044 
0045 #define BOUNDARY_OK(addr, len) \
0046     ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
0047 
0048 /*
0049  * If DMA addr spans 128MB boundary, we split the DMA transfer into two
0050  * so that each DMA transfer doesn't exceed the boundary.
0051  */
0052 static void sdhci_sparx5_adma_write_desc(struct sdhci_host *host, void **desc,
0053                       dma_addr_t addr, int len,
0054                       unsigned int cmd)
0055 {
0056     int tmplen, offset;
0057 
0058     if (likely(!len || BOUNDARY_OK(addr, len))) {
0059         sdhci_adma_write_desc(host, desc, addr, len, cmd);
0060         return;
0061     }
0062 
0063     pr_debug("%s: write_desc: splitting dma len %d, offset %pad\n",
0064          mmc_hostname(host->mmc), len, &addr);
0065 
0066     offset = addr & (SZ_128M - 1);
0067     tmplen = SZ_128M - offset;
0068     sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
0069 
0070     addr += tmplen;
0071     len -= tmplen;
0072     sdhci_adma_write_desc(host, desc, addr, len, cmd);
0073 }
0074 
0075 static void sparx5_set_cacheable(struct sdhci_host *host, u32 value)
0076 {
0077     struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0078     struct sdhci_sparx5_data *sdhci_sparx5 = sdhci_pltfm_priv(pltfm_host);
0079 
0080     pr_debug("%s: Set Cacheable = 0x%x\n", mmc_hostname(host->mmc), value);
0081 
0082     /* Update ACP caching attributes in HW */
0083     regmap_update_bits(sdhci_sparx5->cpu_ctrl,
0084                CPU_REGS_PROC_CTRL, ACP_CACHE_MASK, value);
0085 }
0086 
0087 static void sparx5_set_delay(struct sdhci_host *host, u8 value)
0088 {
0089     struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
0090     struct sdhci_sparx5_data *sdhci_sparx5 = sdhci_pltfm_priv(pltfm_host);
0091 
0092     pr_debug("%s: Set DLY_CC = %u\n", mmc_hostname(host->mmc), value);
0093 
0094     /* Update DLY_CC in HW */
0095     regmap_update_bits(sdhci_sparx5->cpu_ctrl,
0096                CPU_REGS_GENERAL_CTRL,
0097                MSHC_DLY_CC_MASK,
0098                (value << MSHC_DLY_CC_SHIFT));
0099 }
0100 
0101 static void sdhci_sparx5_set_emmc(struct sdhci_host *host)
0102 {
0103     if (!mmc_card_is_removable(host->mmc)) {
0104         u8 value;
0105 
0106         value = sdhci_readb(host, MSHC2_EMMC_CTRL);
0107         if (!(value & MSHC2_EMMC_CTRL_IS_EMMC)) {
0108             value |= MSHC2_EMMC_CTRL_IS_EMMC;
0109             pr_debug("%s: Set EMMC_CTRL: 0x%08x\n",
0110                  mmc_hostname(host->mmc), value);
0111             sdhci_writeb(host, value, MSHC2_EMMC_CTRL);
0112         }
0113     }
0114 }
0115 
0116 static void sdhci_sparx5_reset_emmc(struct sdhci_host *host)
0117 {
0118     u8 value;
0119 
0120     pr_debug("%s: Toggle EMMC_CTRL.EMMC_RST_N\n", mmc_hostname(host->mmc));
0121     value = sdhci_readb(host, MSHC2_EMMC_CTRL) &
0122         ~MSHC2_EMMC_CTRL_EMMC_RST_N;
0123     sdhci_writeb(host, value, MSHC2_EMMC_CTRL);
0124     /* For eMMC, minimum is 1us but give it 10us for good measure */
0125     usleep_range(10, 20);
0126     sdhci_writeb(host, value | MSHC2_EMMC_CTRL_EMMC_RST_N,
0127              MSHC2_EMMC_CTRL);
0128     /* For eMMC, minimum is 200us but give it 300us for good measure */
0129     usleep_range(300, 400);
0130 }
0131 
0132 static void sdhci_sparx5_reset(struct sdhci_host *host, u8 mask)
0133 {
0134     pr_debug("%s: *** RESET: mask %d\n", mmc_hostname(host->mmc), mask);
0135 
0136     sdhci_reset(host, mask);
0137 
0138     /* Be sure CARD_IS_EMMC stays set */
0139     sdhci_sparx5_set_emmc(host);
0140 }
0141 
0142 static const struct sdhci_ops sdhci_sparx5_ops = {
0143     .set_clock      = sdhci_set_clock,
0144     .set_bus_width      = sdhci_set_bus_width,
0145     .set_uhs_signaling  = sdhci_set_uhs_signaling,
0146     .get_max_clock      = sdhci_pltfm_clk_get_max_clock,
0147     .reset          = sdhci_sparx5_reset,
0148     .adma_write_desc    = sdhci_sparx5_adma_write_desc,
0149 };
0150 
0151 static const struct sdhci_pltfm_data sdhci_sparx5_pdata = {
0152     .quirks  = 0,
0153     .quirks2 = SDHCI_QUIRK2_HOST_NO_CMD23 | /* Controller issue */
0154            SDHCI_QUIRK2_NO_1_8_V, /* No sdr104, ddr50, etc */
0155     .ops = &sdhci_sparx5_ops,
0156 };
0157 
0158 static int sdhci_sparx5_probe(struct platform_device *pdev)
0159 {
0160     int ret;
0161     const char *syscon = "microchip,sparx5-cpu-syscon";
0162     struct sdhci_host *host;
0163     struct sdhci_pltfm_host *pltfm_host;
0164     struct sdhci_sparx5_data *sdhci_sparx5;
0165     struct device_node *np = pdev->dev.of_node;
0166     u32 value;
0167     u32 extra;
0168 
0169     host = sdhci_pltfm_init(pdev, &sdhci_sparx5_pdata,
0170                 sizeof(*sdhci_sparx5));
0171 
0172     if (IS_ERR(host))
0173         return PTR_ERR(host);
0174 
0175     /*
0176      * extra adma table cnt for cross 128M boundary handling.
0177      */
0178     extra = DIV_ROUND_UP_ULL(dma_get_required_mask(&pdev->dev), SZ_128M);
0179     if (extra > SDHCI_MAX_SEGS)
0180         extra = SDHCI_MAX_SEGS;
0181     host->adma_table_cnt += extra;
0182 
0183     pltfm_host = sdhci_priv(host);
0184     sdhci_sparx5 = sdhci_pltfm_priv(pltfm_host);
0185     sdhci_sparx5->host = host;
0186 
0187     pltfm_host->clk = devm_clk_get(&pdev->dev, "core");
0188     if (IS_ERR(pltfm_host->clk)) {
0189         ret = PTR_ERR(pltfm_host->clk);
0190         dev_err(&pdev->dev, "failed to get core clk: %d\n", ret);
0191         goto free_pltfm;
0192     }
0193     ret = clk_prepare_enable(pltfm_host->clk);
0194     if (ret)
0195         goto free_pltfm;
0196 
0197     if (!of_property_read_u32(np, "microchip,clock-delay", &value) &&
0198         (value > 0 && value <= MSHC_DLY_CC_MAX))
0199         sdhci_sparx5->delay_clock = value;
0200 
0201     sdhci_get_of_property(pdev);
0202 
0203     ret = mmc_of_parse(host->mmc);
0204     if (ret)
0205         goto err_clk;
0206 
0207     sdhci_sparx5->cpu_ctrl = syscon_regmap_lookup_by_compatible(syscon);
0208     if (IS_ERR(sdhci_sparx5->cpu_ctrl)) {
0209         dev_err(&pdev->dev, "No CPU syscon regmap !\n");
0210         ret = PTR_ERR(sdhci_sparx5->cpu_ctrl);
0211         goto err_clk;
0212     }
0213 
0214     if (sdhci_sparx5->delay_clock >= 0)
0215         sparx5_set_delay(host, sdhci_sparx5->delay_clock);
0216 
0217     if (!mmc_card_is_removable(host->mmc)) {
0218         /* Do a HW reset of eMMC card */
0219         sdhci_sparx5_reset_emmc(host);
0220         /* Update EMMC_CTRL */
0221         sdhci_sparx5_set_emmc(host);
0222         /* If eMMC, disable SD and SDIO */
0223         host->mmc->caps2 |= (MMC_CAP2_NO_SDIO|MMC_CAP2_NO_SD);
0224     }
0225 
0226     ret = sdhci_add_host(host);
0227     if (ret)
0228         goto err_clk;
0229 
0230     /* Set AXI bus master to use un-cached access (for DMA) */
0231     if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA) &&
0232         IS_ENABLED(CONFIG_DMA_DECLARE_COHERENT))
0233         sparx5_set_cacheable(host, ACP_CACHE_FORCE_ENA);
0234 
0235     pr_debug("%s: SDHC version: 0x%08x\n",
0236          mmc_hostname(host->mmc), sdhci_readl(host, MSHC2_VERSION));
0237     pr_debug("%s: SDHC type:    0x%08x\n",
0238          mmc_hostname(host->mmc), sdhci_readl(host, MSHC2_TYPE));
0239 
0240     return ret;
0241 
0242 err_clk:
0243     clk_disable_unprepare(pltfm_host->clk);
0244 free_pltfm:
0245     sdhci_pltfm_free(pdev);
0246     return ret;
0247 }
0248 
0249 static const struct of_device_id sdhci_sparx5_of_match[] = {
0250     { .compatible = "microchip,dw-sparx5-sdhci" },
0251     { }
0252 };
0253 MODULE_DEVICE_TABLE(of, sdhci_sparx5_of_match);
0254 
0255 static struct platform_driver sdhci_sparx5_driver = {
0256     .driver = {
0257         .name = "sdhci-sparx5",
0258         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0259         .of_match_table = sdhci_sparx5_of_match,
0260         .pm = &sdhci_pltfm_pmops,
0261     },
0262     .probe = sdhci_sparx5_probe,
0263     .remove = sdhci_pltfm_unregister,
0264 };
0265 
0266 module_platform_driver(sdhci_sparx5_driver);
0267 
0268 MODULE_DESCRIPTION("Sparx5 SDHCI OF driver");
0269 MODULE_AUTHOR("Lars Povlsen <lars.povlsen@microchip.com>");
0270 MODULE_LICENSE("GPL v2");