1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for the MMC / SD / SDIO cell found in:
4  *
5  * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
6  *
7  * Copyright (C) 2017 Renesas Electronics Corporation
8  * Copyright (C) 2017 Horms Solutions, Simon Horman
9  * Copyright (C) 2007 Ian Molton
10  * Copyright (C) 2004 Ian Molton
11  */
12 
13 #include <linux/delay.h>
14 #include <linux/device.h>
15 #include <linux/mfd/core.h>
16 #include <linux/mfd/tmio.h>
17 #include <linux/mmc/host.h>
18 #include <linux/module.h>
19 #include <linux/pagemap.h>
20 #include <linux/scatterlist.h>
21 
22 #include "tmio_mmc.h"
23 
24 /* Registers specific to this variant */
25 #define CTL_SDIO_REGS		0x100
26 #define CTL_CLK_AND_WAIT_CTL	0x138
27 #define CTL_RESET_SDIO		0x1e0
28 
tmio_mmc_clk_start(struct tmio_mmc_host * host)29 static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
30 {
31 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
32 		sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
33 
34 	usleep_range(10000, 11000);
35 	sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
36 	usleep_range(10000, 11000);
37 }
38 
tmio_mmc_clk_stop(struct tmio_mmc_host * host)39 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
40 {
41 	sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
42 	usleep_range(10000, 11000);
43 
44 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
45 		sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
46 
47 	usleep_range(10000, 11000);
48 }
49 
tmio_mmc_set_clock(struct tmio_mmc_host * host,unsigned int new_clock)50 static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
51 			       unsigned int new_clock)
52 {
53 	unsigned int divisor;
54 	u32 clk = 0;
55 	int clk_sel;
56 
57 	if (new_clock == 0) {
58 		tmio_mmc_clk_stop(host);
59 		return;
60 	}
61 
62 	divisor = host->pdata->hclk / new_clock;
63 
64 	/* bit7 set: 1/512, ... bit0 set: 1/4, all bits clear: 1/2 */
65 	clk_sel = (divisor <= 1);
66 	clk = clk_sel ? 0 : (roundup_pow_of_two(divisor) >> 2);
67 
68 	host->pdata->set_clk_div(host->pdev, clk_sel);
69 
70 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
71 			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
72 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
73 	usleep_range(10000, 11000);
74 
75 	tmio_mmc_clk_start(host);
76 }
77 
tmio_mmc_reset(struct tmio_mmc_host * host)78 static void tmio_mmc_reset(struct tmio_mmc_host *host)
79 {
80 	/* FIXME - should we set stop clock reg here */
81 	sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
82 	sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
83 	usleep_range(10000, 11000);
84 	sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
85 	sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
86 	usleep_range(10000, 11000);
87 
88 	if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) {
89 		sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
90 		sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
91 	}
92 }
93 
94 #ifdef CONFIG_PM_SLEEP
tmio_mmc_suspend(struct device * dev)95 static int tmio_mmc_suspend(struct device *dev)
96 {
97 	struct platform_device *pdev = to_platform_device(dev);
98 	const struct mfd_cell *cell = mfd_get_cell(pdev);
99 	int ret;
100 
101 	ret = pm_runtime_force_suspend(dev);
102 
103 	/* Tell MFD core it can disable us now.*/
104 	if (!ret && cell->disable)
105 		cell->disable(pdev);
106 
107 	return ret;
108 }
109 
tmio_mmc_resume(struct device * dev)110 static int tmio_mmc_resume(struct device *dev)
111 {
112 	struct platform_device *pdev = to_platform_device(dev);
113 	const struct mfd_cell *cell = mfd_get_cell(pdev);
114 	int ret = 0;
115 
116 	/* Tell the MFD core we are ready to be enabled */
117 	if (cell->resume)
118 		ret = cell->resume(pdev);
119 
120 	if (!ret)
121 		ret = pm_runtime_force_resume(dev);
122 
123 	return ret;
124 }
125 #endif
126 
tmio_mmc_probe(struct platform_device * pdev)127 static int tmio_mmc_probe(struct platform_device *pdev)
128 {
129 	const struct mfd_cell *cell = mfd_get_cell(pdev);
130 	struct tmio_mmc_data *pdata;
131 	struct tmio_mmc_host *host;
132 	struct resource *res;
133 	int ret = -EINVAL, irq;
134 
135 	if (pdev->num_resources != 2)
136 		goto out;
137 
138 	pdata = pdev->dev.platform_data;
139 	if (!pdata || !pdata->hclk)
140 		goto out;
141 
142 	irq = platform_get_irq(pdev, 0);
143 	if (irq < 0) {
144 		ret = irq;
145 		goto out;
146 	}
147 
148 	/* Tell the MFD core we are ready to be enabled */
149 	if (cell->enable) {
150 		ret = cell->enable(pdev);
151 		if (ret)
152 			goto out;
153 	}
154 
155 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
156 	if (!res) {
157 		ret = -EINVAL;
158 		goto cell_disable;
159 	}
160 
161 	host = tmio_mmc_host_alloc(pdev, pdata);
162 	if (IS_ERR(host)) {
163 		ret = PTR_ERR(host);
164 		goto cell_disable;
165 	}
166 
167 	/* SD control register space size is 0x200, 0x400 for bus_shift=1 */
168 	host->bus_shift = resource_size(res) >> 10;
169 	host->set_clock = tmio_mmc_set_clock;
170 	host->reset = tmio_mmc_reset;
171 
172 	host->mmc->f_max = pdata->hclk;
173 	host->mmc->f_min = pdata->hclk / 512;
174 
175 	ret = tmio_mmc_host_probe(host);
176 	if (ret)
177 		goto host_free;
178 
179 	ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq,
180 			       IRQF_TRIGGER_FALLING,
181 			       dev_name(&pdev->dev), host);
182 	if (ret)
183 		goto host_remove;
184 
185 	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
186 		(unsigned long)host->ctl, irq);
187 
188 	return 0;
189 
190 host_remove:
191 	tmio_mmc_host_remove(host);
192 host_free:
193 	tmio_mmc_host_free(host);
194 cell_disable:
195 	if (cell->disable)
196 		cell->disable(pdev);
197 out:
198 	return ret;
199 }
200 
tmio_mmc_remove(struct platform_device * pdev)201 static int tmio_mmc_remove(struct platform_device *pdev)
202 {
203 	const struct mfd_cell *cell = mfd_get_cell(pdev);
204 	struct tmio_mmc_host *host = platform_get_drvdata(pdev);
205 
206 	tmio_mmc_host_remove(host);
207 	if (cell->disable)
208 		cell->disable(pdev);
209 
210 	return 0;
211 }
212 
213 /* ------------------- device registration ----------------------- */
214 
215 static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
216 	SET_SYSTEM_SLEEP_PM_OPS(tmio_mmc_suspend, tmio_mmc_resume)
217 	SET_RUNTIME_PM_OPS(tmio_mmc_host_runtime_suspend,
218 			   tmio_mmc_host_runtime_resume, NULL)
219 };
220 
221 static struct platform_driver tmio_mmc_driver = {
222 	.driver = {
223 		.name = "tmio-mmc",
224 		.pm = &tmio_mmc_dev_pm_ops,
225 	},
226 	.probe = tmio_mmc_probe,
227 	.remove = tmio_mmc_remove,
228 };
229 
230 module_platform_driver(tmio_mmc_driver);
231 
232 MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
233 MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
234 MODULE_LICENSE("GPL v2");
235 MODULE_ALIAS("platform:tmio-mmc");
236