Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for the MMC / SD / SDIO cell found in:
0004  *
0005  * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
0006  *
0007  * Copyright (C) 2017 Renesas Electronics Corporation
0008  * Copyright (C) 2017 Horms Solutions, Simon Horman
0009  * Copyright (C) 2007 Ian Molton
0010  * Copyright (C) 2004 Ian Molton
0011  */
0012 
0013 #include <linux/delay.h>
0014 #include <linux/device.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/mfd/tmio.h>
0017 #include <linux/mmc/host.h>
0018 #include <linux/module.h>
0019 #include <linux/pagemap.h>
0020 #include <linux/scatterlist.h>
0021 
0022 #include "tmio_mmc.h"
0023 
0024 /* Registers specific to this variant */
0025 #define CTL_SDIO_REGS       0x100
0026 #define CTL_CLK_AND_WAIT_CTL    0x138
0027 #define CTL_RESET_SDIO      0x1e0
0028 
0029 static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
0030 {
0031     sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
0032         sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0033 
0034     usleep_range(10000, 11000);
0035     sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
0036     usleep_range(10000, 11000);
0037 }
0038 
0039 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
0040 {
0041     sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
0042     usleep_range(10000, 11000);
0043 
0044     sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
0045         sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0046 
0047     usleep_range(10000, 11000);
0048 }
0049 
0050 static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
0051                    unsigned int new_clock)
0052 {
0053     unsigned int divisor;
0054     u32 clk = 0;
0055     int clk_sel;
0056 
0057     if (new_clock == 0) {
0058         tmio_mmc_clk_stop(host);
0059         return;
0060     }
0061 
0062     divisor = host->pdata->hclk / new_clock;
0063 
0064     /* bit7 set: 1/512, ... bit0 set: 1/4, all bits clear: 1/2 */
0065     clk_sel = (divisor <= 1);
0066     clk = clk_sel ? 0 : (roundup_pow_of_two(divisor) >> 2);
0067 
0068     host->pdata->set_clk_div(host->pdev, clk_sel);
0069 
0070     sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
0071             sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
0072     sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
0073     usleep_range(10000, 11000);
0074 
0075     tmio_mmc_clk_start(host);
0076 }
0077 
0078 static void tmio_mmc_reset(struct tmio_mmc_host *host, bool preserve)
0079 {
0080     sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
0081     usleep_range(10000, 11000);
0082     sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
0083     usleep_range(10000, 11000);
0084 }
0085 
0086 #ifdef CONFIG_PM_SLEEP
0087 static int tmio_mmc_suspend(struct device *dev)
0088 {
0089     struct platform_device *pdev = to_platform_device(dev);
0090     const struct mfd_cell *cell = mfd_get_cell(pdev);
0091     int ret;
0092 
0093     ret = pm_runtime_force_suspend(dev);
0094 
0095     /* Tell MFD core it can disable us now.*/
0096     if (!ret && cell->disable)
0097         cell->disable(pdev);
0098 
0099     return ret;
0100 }
0101 
0102 static int tmio_mmc_resume(struct device *dev)
0103 {
0104     struct platform_device *pdev = to_platform_device(dev);
0105     const struct mfd_cell *cell = mfd_get_cell(pdev);
0106     int ret = 0;
0107 
0108     /* Tell the MFD core we are ready to be enabled */
0109     if (cell->resume)
0110         ret = cell->resume(pdev);
0111 
0112     if (!ret)
0113         ret = pm_runtime_force_resume(dev);
0114 
0115     return ret;
0116 }
0117 #endif
0118 
0119 static int tmio_mmc_probe(struct platform_device *pdev)
0120 {
0121     const struct mfd_cell *cell = mfd_get_cell(pdev);
0122     struct tmio_mmc_data *pdata;
0123     struct tmio_mmc_host *host;
0124     struct resource *res;
0125     int ret = -EINVAL, irq;
0126 
0127     if (pdev->num_resources != 2)
0128         goto out;
0129 
0130     pdata = pdev->dev.platform_data;
0131     if (!pdata || !pdata->hclk)
0132         goto out;
0133 
0134     irq = platform_get_irq(pdev, 0);
0135     if (irq < 0) {
0136         ret = irq;
0137         goto out;
0138     }
0139 
0140     /* Tell the MFD core we are ready to be enabled */
0141     if (cell->enable) {
0142         ret = cell->enable(pdev);
0143         if (ret)
0144             goto out;
0145     }
0146 
0147     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0148     if (!res) {
0149         ret = -EINVAL;
0150         goto cell_disable;
0151     }
0152 
0153     host = tmio_mmc_host_alloc(pdev, pdata);
0154     if (IS_ERR(host)) {
0155         ret = PTR_ERR(host);
0156         goto cell_disable;
0157     }
0158 
0159     /* SD control register space size is 0x200, 0x400 for bus_shift=1 */
0160     host->bus_shift = resource_size(res) >> 10;
0161     host->set_clock = tmio_mmc_set_clock;
0162     host->reset = tmio_mmc_reset;
0163 
0164     host->mmc->f_max = pdata->hclk;
0165     host->mmc->f_min = pdata->hclk / 512;
0166 
0167     ret = tmio_mmc_host_probe(host);
0168     if (ret)
0169         goto host_free;
0170 
0171     ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq,
0172                    IRQF_TRIGGER_FALLING,
0173                    dev_name(&pdev->dev), host);
0174     if (ret)
0175         goto host_remove;
0176 
0177     pr_info("%s at 0x%p irq %d\n", mmc_hostname(host->mmc), host->ctl, irq);
0178 
0179     return 0;
0180 
0181 host_remove:
0182     tmio_mmc_host_remove(host);
0183 host_free:
0184     tmio_mmc_host_free(host);
0185 cell_disable:
0186     if (cell->disable)
0187         cell->disable(pdev);
0188 out:
0189     return ret;
0190 }
0191 
0192 static int tmio_mmc_remove(struct platform_device *pdev)
0193 {
0194     const struct mfd_cell *cell = mfd_get_cell(pdev);
0195     struct tmio_mmc_host *host = platform_get_drvdata(pdev);
0196 
0197     tmio_mmc_host_remove(host);
0198     if (cell->disable)
0199         cell->disable(pdev);
0200 
0201     return 0;
0202 }
0203 
0204 /* ------------------- device registration ----------------------- */
0205 
0206 static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
0207     SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_suspend, tmio_mmc_resume)
0208     SET_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
0209                tmio_mmc_host_runtime_resume, NULL)
0210 };
0211 
0212 static struct platform_driver tmio_mmc_driver = {
0213     .driver = {
0214         .name = "tmio-mmc",
0215         .probe_type = PROBE_PREFER_ASYNCHRONOUS,
0216         .pm = &tmio_mmc_dev_pm_ops,
0217     },
0218     .probe = tmio_mmc_probe,
0219     .remove = tmio_mmc_remove,
0220 };
0221 
0222 module_platform_driver(tmio_mmc_driver);
0223 
0224 MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
0225 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
0226 MODULE_LICENSE("GPL v2");
0227 MODULE_ALIAS("platform:tmio-mmc");