1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Freescale eSDHC i.MX controller driver for the platform bus. |
4 | * |
5 | * derived from the OF-version. |
6 | * |
7 | * Copyright (c) 2010 Pengutronix e.K. |
8 | * Author: Wolfram Sang <kernel@pengutronix.de> |
9 | */ |
10 | |
11 | #include <linux/bitfield.h> |
12 | #include <linux/io.h> |
13 | #include <linux/iopoll.h> |
14 | #include <linux/delay.h> |
15 | #include <linux/err.h> |
16 | #include <linux/clk.h> |
17 | #include <linux/module.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/pm_qos.h> |
20 | #include <linux/mmc/host.h> |
21 | #include <linux/mmc/mmc.h> |
22 | #include <linux/mmc/sdio.h> |
23 | #include <linux/mmc/slot-gpio.h> |
24 | #include <linux/of.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/pinctrl/consumer.h> |
27 | #include <linux/pm_runtime.h> |
28 | #include "sdhci-cqhci.h" |
29 | #include "sdhci-pltfm.h" |
30 | #include "sdhci-esdhc.h" |
31 | #include "cqhci.h" |
32 | |
33 | #define ESDHC_SYS_CTRL_DTOCV_MASK 0x0f |
34 | #define ESDHC_CTRL_D3CD 0x08 |
35 | #define ESDHC_BURST_LEN_EN_INCR (1 << 27) |
36 | /* VENDOR SPEC register */ |
37 | #define ESDHC_VENDOR_SPEC 0xc0 |
38 | #define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 << 1) |
39 | #define ESDHC_VENDOR_SPEC_VSELECT (1 << 1) |
40 | #define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) |
41 | #define ESDHC_DEBUG_SEL_AND_STATUS_REG 0xc2 |
42 | #define ESDHC_DEBUG_SEL_REG 0xc3 |
43 | #define ESDHC_DEBUG_SEL_MASK 0xf |
44 | #define ESDHC_DEBUG_SEL_CMD_STATE 1 |
45 | #define ESDHC_DEBUG_SEL_DATA_STATE 2 |
46 | #define ESDHC_DEBUG_SEL_TRANS_STATE 3 |
47 | #define ESDHC_DEBUG_SEL_DMA_STATE 4 |
48 | #define ESDHC_DEBUG_SEL_ADMA_STATE 5 |
49 | #define ESDHC_DEBUG_SEL_FIFO_STATE 6 |
50 | #define ESDHC_DEBUG_SEL_ASYNC_FIFO_STATE 7 |
51 | #define ESDHC_WTMK_LVL 0x44 |
52 | #define ESDHC_WTMK_DEFAULT_VAL 0x10401040 |
53 | #define ESDHC_WTMK_LVL_RD_WML_MASK 0x000000FF |
54 | #define ESDHC_WTMK_LVL_RD_WML_SHIFT 0 |
55 | #define ESDHC_WTMK_LVL_WR_WML_MASK 0x00FF0000 |
56 | #define ESDHC_WTMK_LVL_WR_WML_SHIFT 16 |
57 | #define ESDHC_WTMK_LVL_WML_VAL_DEF 64 |
58 | #define ESDHC_WTMK_LVL_WML_VAL_MAX 128 |
59 | #define ESDHC_MIX_CTRL 0x48 |
60 | #define ESDHC_MIX_CTRL_DDREN (1 << 3) |
61 | #define ESDHC_MIX_CTRL_AC23EN (1 << 7) |
62 | #define ESDHC_MIX_CTRL_EXE_TUNE (1 << 22) |
63 | #define ESDHC_MIX_CTRL_SMPCLK_SEL (1 << 23) |
64 | #define ESDHC_MIX_CTRL_AUTO_TUNE_EN (1 << 24) |
65 | #define ESDHC_MIX_CTRL_FBCLK_SEL (1 << 25) |
66 | #define ESDHC_MIX_CTRL_HS400_EN (1 << 26) |
67 | #define ESDHC_MIX_CTRL_HS400_ES_EN (1 << 27) |
68 | /* Bits 3 and 6 are not SDHCI standard definitions */ |
69 | #define ESDHC_MIX_CTRL_SDHCI_MASK 0xb7 |
70 | /* Tuning bits */ |
71 | #define ESDHC_MIX_CTRL_TUNING_MASK 0x03c00000 |
72 | |
73 | /* dll control register */ |
74 | #define ESDHC_DLL_CTRL 0x60 |
75 | #define ESDHC_DLL_OVERRIDE_VAL_SHIFT 9 |
76 | #define ESDHC_DLL_OVERRIDE_EN_SHIFT 8 |
77 | |
78 | /* tune control register */ |
79 | #define ESDHC_TUNE_CTRL_STATUS 0x68 |
80 | #define ESDHC_TUNE_CTRL_STEP 1 |
81 | #define ESDHC_TUNE_CTRL_MIN 0 |
82 | #define ESDHC_TUNE_CTRL_MAX ((1 << 7) - 1) |
83 | |
84 | /* strobe dll register */ |
85 | #define ESDHC_STROBE_DLL_CTRL 0x70 |
86 | #define ESDHC_STROBE_DLL_CTRL_ENABLE (1 << 0) |
87 | #define ESDHC_STROBE_DLL_CTRL_RESET (1 << 1) |
88 | #define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT 0x7 |
89 | #define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT 3 |
90 | #define ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT (4 << 20) |
91 | |
92 | #define ESDHC_STROBE_DLL_STATUS 0x74 |
93 | #define ESDHC_STROBE_DLL_STS_REF_LOCK (1 << 1) |
94 | #define ESDHC_STROBE_DLL_STS_SLV_LOCK 0x1 |
95 | |
96 | #define ESDHC_VEND_SPEC2 0xc8 |
97 | #define ESDHC_VEND_SPEC2_EN_BUSY_IRQ (1 << 8) |
98 | #define ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN (1 << 4) |
99 | #define ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN (0 << 4) |
100 | #define ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN (2 << 4) |
101 | #define ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN (1 << 6) |
102 | #define ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK (7 << 4) |
103 | |
104 | #define ESDHC_TUNING_CTRL 0xcc |
105 | #define ESDHC_STD_TUNING_EN (1 << 24) |
106 | /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ |
107 | #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 |
108 | #define ESDHC_TUNING_START_TAP_MASK 0x7f |
109 | #define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE (1 << 7) |
110 | #define ESDHC_TUNING_STEP_DEFAULT 0x1 |
111 | #define ESDHC_TUNING_STEP_MASK 0x00070000 |
112 | #define ESDHC_TUNING_STEP_SHIFT 16 |
113 | |
114 | /* pinctrl state */ |
115 | #define ESDHC_PINCTRL_STATE_100MHZ "state_100mhz" |
116 | #define ESDHC_PINCTRL_STATE_200MHZ "state_200mhz" |
117 | |
118 | /* |
119 | * Our interpretation of the SDHCI_HOST_CONTROL register |
120 | */ |
121 | #define ESDHC_CTRL_4BITBUS (0x1 << 1) |
122 | #define ESDHC_CTRL_8BITBUS (0x2 << 1) |
123 | #define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1) |
124 | #define USDHC_GET_BUSWIDTH(c) (c & ESDHC_CTRL_BUSWIDTH_MASK) |
125 | |
126 | /* |
127 | * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC: |
128 | * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design, |
129 | * but bit28 is used as the INT DMA ERR in fsl eSDHC design. |
130 | * Define this macro DMA error INT for fsl eSDHC |
131 | */ |
132 | #define ESDHC_INT_VENDOR_SPEC_DMA_ERR (1 << 28) |
133 | |
134 | /* the address offset of CQHCI */ |
135 | #define ESDHC_CQHCI_ADDR_OFFSET 0x100 |
136 | |
137 | /* |
138 | * The CMDTYPE of the CMD register (offset 0xE) should be set to |
139 | * "11" when the STOP CMD12 is issued on imx53 to abort one |
140 | * open ended multi-blk IO. Otherwise the TC INT wouldn't |
141 | * be generated. |
142 | * In exact block transfer, the controller doesn't complete the |
143 | * operations automatically as required at the end of the |
144 | * transfer and remains on hold if the abort command is not sent. |
145 | * As a result, the TC flag is not asserted and SW received timeout |
146 | * exception. Bit1 of Vendor Spec register is used to fix it. |
147 | */ |
148 | #define ESDHC_FLAG_MULTIBLK_NO_INT BIT(1) |
149 | /* |
150 | * The flag tells that the ESDHC controller is an USDHC block that is |
151 | * integrated on the i.MX6 series. |
152 | */ |
153 | #define ESDHC_FLAG_USDHC BIT(3) |
154 | /* The IP supports manual tuning process */ |
155 | #define ESDHC_FLAG_MAN_TUNING BIT(4) |
156 | /* The IP supports standard tuning process */ |
157 | #define ESDHC_FLAG_STD_TUNING BIT(5) |
158 | /* The IP has SDHCI_CAPABILITIES_1 register */ |
159 | #define ESDHC_FLAG_HAVE_CAP1 BIT(6) |
160 | /* |
161 | * The IP has erratum ERR004536 |
162 | * uSDHC: ADMA Length Mismatch Error occurs if the AHB read access is slow, |
163 | * when reading data from the card |
164 | * This flag is also set for i.MX25 and i.MX35 in order to get |
165 | * SDHCI_QUIRK_BROKEN_ADMA, but for different reasons (ADMA capability bits). |
166 | */ |
167 | #define ESDHC_FLAG_ERR004536 BIT(7) |
168 | /* The IP supports HS200 mode */ |
169 | #define ESDHC_FLAG_HS200 BIT(8) |
170 | /* The IP supports HS400 mode */ |
171 | #define ESDHC_FLAG_HS400 BIT(9) |
172 | /* |
173 | * The IP has errata ERR010450 |
174 | * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card |
175 | * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. |
176 | */ |
177 | #define ESDHC_FLAG_ERR010450 BIT(10) |
178 | /* The IP supports HS400ES mode */ |
179 | #define ESDHC_FLAG_HS400_ES BIT(11) |
180 | /* The IP has Host Controller Interface for Command Queuing */ |
181 | #define ESDHC_FLAG_CQHCI BIT(12) |
182 | /* need request pmqos during low power */ |
183 | #define ESDHC_FLAG_PMQOS BIT(13) |
184 | /* The IP state got lost in low power mode */ |
185 | #define ESDHC_FLAG_STATE_LOST_IN_LPMODE BIT(14) |
186 | /* The IP lost clock rate in PM_RUNTIME */ |
187 | #define ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME BIT(15) |
188 | /* |
189 | * The IP do not support the ACMD23 feature completely when use ADMA mode. |
190 | * In ADMA mode, it only use the 16 bit block count of the register 0x4 |
191 | * (BLOCK_ATT) as the CMD23's argument for ACMD23 mode, which means it will |
192 | * ignore the upper 16 bit of the CMD23's argument. This will block the reliable |
193 | * write operation in RPMB, because RPMB reliable write need to set the bit31 |
194 | * of the CMD23's argument. |
195 | * imx6qpdl/imx6sx/imx6sl/imx7d has this limitation only for ADMA mode, SDMA |
196 | * do not has this limitation. so when these SoC use ADMA mode, it need to |
197 | * disable the ACMD23 feature. |
198 | */ |
199 | #define ESDHC_FLAG_BROKEN_AUTO_CMD23 BIT(16) |
200 | |
201 | /* ERR004536 is not applicable for the IP */ |
202 | #define ESDHC_FLAG_SKIP_ERR004536 BIT(17) |
203 | |
204 | enum wp_types { |
205 | ESDHC_WP_NONE, /* no WP, neither controller nor gpio */ |
206 | ESDHC_WP_CONTROLLER, /* mmc controller internal WP */ |
207 | ESDHC_WP_GPIO, /* external gpio pin for WP */ |
208 | }; |
209 | |
210 | enum cd_types { |
211 | ESDHC_CD_NONE, /* no CD, neither controller nor gpio */ |
212 | ESDHC_CD_CONTROLLER, /* mmc controller internal CD */ |
213 | ESDHC_CD_GPIO, /* external gpio pin for CD */ |
214 | ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */ |
215 | }; |
216 | |
217 | /* |
218 | * struct esdhc_platform_data - platform data for esdhc on i.MX |
219 | * |
220 | * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35. |
221 | * |
222 | * @wp_type: type of write_protect method (see wp_types enum above) |
223 | * @cd_type: type of card_detect method (see cd_types enum above) |
224 | */ |
225 | |
226 | struct esdhc_platform_data { |
227 | enum wp_types wp_type; |
228 | enum cd_types cd_type; |
229 | int max_bus_width; |
230 | unsigned int delay_line; |
231 | unsigned int tuning_step; /* The delay cell steps in tuning procedure */ |
232 | unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */ |
233 | unsigned int strobe_dll_delay_target; /* The delay cell for strobe pad (read clock) */ |
234 | }; |
235 | |
236 | struct esdhc_soc_data { |
237 | u32 flags; |
238 | }; |
239 | |
240 | static const struct esdhc_soc_data esdhc_imx25_data = { |
241 | .flags = ESDHC_FLAG_ERR004536, |
242 | }; |
243 | |
244 | static const struct esdhc_soc_data esdhc_imx35_data = { |
245 | .flags = ESDHC_FLAG_ERR004536, |
246 | }; |
247 | |
248 | static const struct esdhc_soc_data esdhc_imx51_data = { |
249 | .flags = 0, |
250 | }; |
251 | |
252 | static const struct esdhc_soc_data esdhc_imx53_data = { |
253 | .flags = ESDHC_FLAG_MULTIBLK_NO_INT, |
254 | }; |
255 | |
256 | static const struct esdhc_soc_data usdhc_imx6q_data = { |
257 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING |
258 | | ESDHC_FLAG_BROKEN_AUTO_CMD23, |
259 | }; |
260 | |
261 | static const struct esdhc_soc_data usdhc_imx6sl_data = { |
262 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
263 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536 |
264 | | ESDHC_FLAG_HS200 |
265 | | ESDHC_FLAG_BROKEN_AUTO_CMD23, |
266 | }; |
267 | |
268 | static const struct esdhc_soc_data usdhc_imx6sll_data = { |
269 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
270 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
271 | | ESDHC_FLAG_HS400 |
272 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE, |
273 | }; |
274 | |
275 | static const struct esdhc_soc_data usdhc_imx6sx_data = { |
276 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
277 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
278 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE |
279 | | ESDHC_FLAG_BROKEN_AUTO_CMD23, |
280 | }; |
281 | |
282 | static const struct esdhc_soc_data usdhc_imx6ull_data = { |
283 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
284 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
285 | | ESDHC_FLAG_ERR010450 |
286 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE, |
287 | }; |
288 | |
289 | static const struct esdhc_soc_data usdhc_imx7d_data = { |
290 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
291 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
292 | | ESDHC_FLAG_HS400 |
293 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE |
294 | | ESDHC_FLAG_BROKEN_AUTO_CMD23, |
295 | }; |
296 | |
297 | static struct esdhc_soc_data usdhc_s32g2_data = { |
298 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING |
299 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
300 | | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
301 | | ESDHC_FLAG_SKIP_ERR004536, |
302 | }; |
303 | |
304 | static struct esdhc_soc_data usdhc_imx7ulp_data = { |
305 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
306 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
307 | | ESDHC_FLAG_PMQOS | ESDHC_FLAG_HS400 |
308 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE, |
309 | }; |
310 | static struct esdhc_soc_data usdhc_imxrt1050_data = { |
311 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
312 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200, |
313 | }; |
314 | |
315 | static struct esdhc_soc_data usdhc_imx8qxp_data = { |
316 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
317 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
318 | | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
319 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE |
320 | | ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME, |
321 | }; |
322 | |
323 | static struct esdhc_soc_data usdhc_imx8mm_data = { |
324 | .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING |
325 | | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 |
326 | | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES |
327 | | ESDHC_FLAG_STATE_LOST_IN_LPMODE, |
328 | }; |
329 | |
330 | struct pltfm_imx_data { |
331 | u32 scratchpad; |
332 | struct pinctrl *pinctrl; |
333 | struct pinctrl_state *pins_100mhz; |
334 | struct pinctrl_state *pins_200mhz; |
335 | const struct esdhc_soc_data *socdata; |
336 | struct esdhc_platform_data boarddata; |
337 | struct clk *clk_ipg; |
338 | struct clk *clk_ahb; |
339 | struct clk *clk_per; |
340 | unsigned int actual_clock; |
341 | |
342 | /* |
343 | * USDHC has one limition, require the SDIO device a different |
344 | * register setting. Driver has to recognize card type during |
345 | * the card init, but at this stage, mmc_host->card is not |
346 | * available. So involve this field to save the card type |
347 | * during card init through usdhc_init_card(). |
348 | */ |
349 | unsigned int init_card_type; |
350 | |
351 | enum { |
352 | NO_CMD_PENDING, /* no multiblock command pending */ |
353 | MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */ |
354 | WAIT_FOR_INT, /* sent CMD12, waiting for response INT */ |
355 | } multiblock_status; |
356 | u32 is_ddr; |
357 | struct pm_qos_request pm_qos_req; |
358 | }; |
359 | |
360 | static const struct of_device_id imx_esdhc_dt_ids[] = { |
361 | { .compatible = "fsl,imx25-esdhc" , .data = &esdhc_imx25_data, }, |
362 | { .compatible = "fsl,imx35-esdhc" , .data = &esdhc_imx35_data, }, |
363 | { .compatible = "fsl,imx51-esdhc" , .data = &esdhc_imx51_data, }, |
364 | { .compatible = "fsl,imx53-esdhc" , .data = &esdhc_imx53_data, }, |
365 | { .compatible = "fsl,imx6sx-usdhc" , .data = &usdhc_imx6sx_data, }, |
366 | { .compatible = "fsl,imx6sl-usdhc" , .data = &usdhc_imx6sl_data, }, |
367 | { .compatible = "fsl,imx6sll-usdhc" , .data = &usdhc_imx6sll_data, }, |
368 | { .compatible = "fsl,imx6q-usdhc" , .data = &usdhc_imx6q_data, }, |
369 | { .compatible = "fsl,imx6ull-usdhc" , .data = &usdhc_imx6ull_data, }, |
370 | { .compatible = "fsl,imx7d-usdhc" , .data = &usdhc_imx7d_data, }, |
371 | { .compatible = "fsl,imx7ulp-usdhc" , .data = &usdhc_imx7ulp_data, }, |
372 | { .compatible = "fsl,imx8qxp-usdhc" , .data = &usdhc_imx8qxp_data, }, |
373 | { .compatible = "fsl,imx8mm-usdhc" , .data = &usdhc_imx8mm_data, }, |
374 | { .compatible = "fsl,imxrt1050-usdhc" , .data = &usdhc_imxrt1050_data, }, |
375 | { .compatible = "nxp,s32g2-usdhc" , .data = &usdhc_s32g2_data, }, |
376 | { /* sentinel */ } |
377 | }; |
378 | MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); |
379 | |
380 | static inline int is_imx25_esdhc(struct pltfm_imx_data *data) |
381 | { |
382 | return data->socdata == &esdhc_imx25_data; |
383 | } |
384 | |
385 | static inline int is_imx53_esdhc(struct pltfm_imx_data *data) |
386 | { |
387 | return data->socdata == &esdhc_imx53_data; |
388 | } |
389 | |
390 | static inline int esdhc_is_usdhc(struct pltfm_imx_data *data) |
391 | { |
392 | return !!(data->socdata->flags & ESDHC_FLAG_USDHC); |
393 | } |
394 | |
395 | static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg) |
396 | { |
397 | void __iomem *base = host->ioaddr + (reg & ~0x3); |
398 | u32 shift = (reg & 0x3) * 8; |
399 | |
400 | writel(val: ((readl(addr: base) & ~(mask << shift)) | (val << shift)), addr: base); |
401 | } |
402 | |
403 | #define DRIVER_NAME "sdhci-esdhc-imx" |
404 | #define ESDHC_IMX_DUMP(f, x...) \ |
405 | pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x) |
406 | static void esdhc_dump_debug_regs(struct sdhci_host *host) |
407 | { |
408 | int i; |
409 | char *debug_status[7] = { |
410 | "cmd debug status" , |
411 | "data debug status" , |
412 | "trans debug status" , |
413 | "dma debug status" , |
414 | "adma debug status" , |
415 | "fifo debug status" , |
416 | "async fifo debug status" |
417 | }; |
418 | |
419 | ESDHC_IMX_DUMP("========= ESDHC IMX DEBUG STATUS DUMP =========\n" ); |
420 | for (i = 0; i < 7; i++) { |
421 | esdhc_clrset_le(host, ESDHC_DEBUG_SEL_MASK, |
422 | ESDHC_DEBUG_SEL_CMD_STATE + i, ESDHC_DEBUG_SEL_REG); |
423 | ESDHC_IMX_DUMP("%s: 0x%04x\n" , debug_status[i], |
424 | readw(host->ioaddr + ESDHC_DEBUG_SEL_AND_STATUS_REG)); |
425 | } |
426 | |
427 | esdhc_clrset_le(host, ESDHC_DEBUG_SEL_MASK, val: 0, ESDHC_DEBUG_SEL_REG); |
428 | |
429 | } |
430 | |
431 | static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host) |
432 | { |
433 | u32 present_state; |
434 | int ret; |
435 | |
436 | ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, present_state, |
437 | (present_state & ESDHC_CLOCK_GATE_OFF), 2, 100); |
438 | if (ret == -ETIMEDOUT) |
439 | dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n" , __func__); |
440 | } |
441 | |
442 | /* Enable the auto tuning circuit to check the CMD line and BUS line */ |
443 | static inline void usdhc_auto_tuning_mode_sel_and_en(struct sdhci_host *host) |
444 | { |
445 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
446 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
447 | u32 buswidth, auto_tune_buswidth; |
448 | u32 reg; |
449 | |
450 | buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); |
451 | |
452 | switch (buswidth) { |
453 | case ESDHC_CTRL_8BITBUS: |
454 | auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN; |
455 | break; |
456 | case ESDHC_CTRL_4BITBUS: |
457 | auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN; |
458 | break; |
459 | default: /* 1BITBUS */ |
460 | auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; |
461 | break; |
462 | } |
463 | |
464 | /* |
465 | * For USDHC, auto tuning circuit can not handle the async sdio |
466 | * device interrupt correctly. When sdio device use 4 data lines, |
467 | * async sdio interrupt will use the shared DAT[1], if enable auto |
468 | * tuning circuit check these 4 data lines, include the DAT[1], |
469 | * this circuit will detect this interrupt, take this as a data on |
470 | * DAT[1], and adjust the delay cell wrongly. |
471 | * This is the hardware design limitation, to avoid this, for sdio |
472 | * device, config the auto tuning circuit only check DAT[0] and CMD |
473 | * line. |
474 | */ |
475 | if (imx_data->init_card_type == MMC_TYPE_SDIO) |
476 | auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; |
477 | |
478 | esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, |
479 | val: auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, |
480 | ESDHC_VEND_SPEC2); |
481 | |
482 | reg = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
483 | reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN; |
484 | writel(val: reg, addr: host->ioaddr + ESDHC_MIX_CTRL); |
485 | } |
486 | |
487 | static u32 esdhc_readl_le(struct sdhci_host *host, int reg) |
488 | { |
489 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
490 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
491 | u32 val = readl(addr: host->ioaddr + reg); |
492 | |
493 | if (unlikely(reg == SDHCI_PRESENT_STATE)) { |
494 | u32 = val; |
495 | /* save the least 20 bits */ |
496 | val = fsl_prss & 0x000FFFFF; |
497 | /* move dat[0-3] bits */ |
498 | val |= (fsl_prss & 0x0F000000) >> 4; |
499 | /* move cmd line bit */ |
500 | val |= (fsl_prss & 0x00800000) << 1; |
501 | } |
502 | |
503 | if (unlikely(reg == SDHCI_CAPABILITIES)) { |
504 | /* ignore bit[0-15] as it stores cap_1 register val for mx6sl */ |
505 | if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) |
506 | val &= 0xffff0000; |
507 | |
508 | /* In FSL esdhc IC module, only bit20 is used to indicate the |
509 | * ADMA2 capability of esdhc, but this bit is messed up on |
510 | * some SOCs (e.g. on MX25, MX35 this bit is set, but they |
511 | * don't actually support ADMA2). So set the BROKEN_ADMA |
512 | * quirk on MX25/35 platforms. |
513 | */ |
514 | |
515 | if (val & SDHCI_CAN_DO_ADMA1) { |
516 | val &= ~SDHCI_CAN_DO_ADMA1; |
517 | val |= SDHCI_CAN_DO_ADMA2; |
518 | } |
519 | } |
520 | |
521 | if (unlikely(reg == SDHCI_CAPABILITIES_1)) { |
522 | if (esdhc_is_usdhc(data: imx_data)) { |
523 | if (imx_data->socdata->flags & ESDHC_FLAG_HAVE_CAP1) |
524 | val = readl(addr: host->ioaddr + SDHCI_CAPABILITIES) & 0xFFFF; |
525 | else |
526 | /* imx6q/dl does not have cap_1 register, fake one */ |
527 | val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 |
528 | | SDHCI_SUPPORT_SDR50 |
529 | | SDHCI_USE_SDR50_TUNING |
530 | | FIELD_PREP(SDHCI_RETUNING_MODE_MASK, |
531 | SDHCI_TUNING_MODE_3); |
532 | |
533 | /* |
534 | * Do not advertise faster UHS modes if there are no |
535 | * pinctrl states for 100MHz/200MHz. |
536 | */ |
537 | if (IS_ERR_OR_NULL(ptr: imx_data->pins_100mhz)) |
538 | val &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_DDR50); |
539 | if (IS_ERR_OR_NULL(ptr: imx_data->pins_200mhz)) |
540 | val &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_HS400); |
541 | } |
542 | } |
543 | |
544 | if (unlikely(reg == SDHCI_MAX_CURRENT) && esdhc_is_usdhc(data: imx_data)) { |
545 | val = 0; |
546 | val |= FIELD_PREP(SDHCI_MAX_CURRENT_330_MASK, 0xFF); |
547 | val |= FIELD_PREP(SDHCI_MAX_CURRENT_300_MASK, 0xFF); |
548 | val |= FIELD_PREP(SDHCI_MAX_CURRENT_180_MASK, 0xFF); |
549 | } |
550 | |
551 | if (unlikely(reg == SDHCI_INT_STATUS)) { |
552 | if (val & ESDHC_INT_VENDOR_SPEC_DMA_ERR) { |
553 | val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR; |
554 | val |= SDHCI_INT_ADMA_ERROR; |
555 | } |
556 | |
557 | /* |
558 | * mask off the interrupt we get in response to the manually |
559 | * sent CMD12 |
560 | */ |
561 | if ((imx_data->multiblock_status == WAIT_FOR_INT) && |
562 | ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) { |
563 | val &= ~SDHCI_INT_RESPONSE; |
564 | writel(SDHCI_INT_RESPONSE, addr: host->ioaddr + |
565 | SDHCI_INT_STATUS); |
566 | imx_data->multiblock_status = NO_CMD_PENDING; |
567 | } |
568 | } |
569 | |
570 | return val; |
571 | } |
572 | |
573 | static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) |
574 | { |
575 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
576 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
577 | u32 data; |
578 | |
579 | if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE || |
580 | reg == SDHCI_INT_STATUS)) { |
581 | if ((val & SDHCI_INT_CARD_INT) && !esdhc_is_usdhc(data: imx_data)) { |
582 | /* |
583 | * Clear and then set D3CD bit to avoid missing the |
584 | * card interrupt. This is an eSDHC controller problem |
585 | * so we need to apply the following workaround: clear |
586 | * and set D3CD bit will make eSDHC re-sample the card |
587 | * interrupt. In case a card interrupt was lost, |
588 | * re-sample it by the following steps. |
589 | */ |
590 | data = readl(addr: host->ioaddr + SDHCI_HOST_CONTROL); |
591 | data &= ~ESDHC_CTRL_D3CD; |
592 | writel(val: data, addr: host->ioaddr + SDHCI_HOST_CONTROL); |
593 | data |= ESDHC_CTRL_D3CD; |
594 | writel(val: data, addr: host->ioaddr + SDHCI_HOST_CONTROL); |
595 | } |
596 | |
597 | if (val & SDHCI_INT_ADMA_ERROR) { |
598 | val &= ~SDHCI_INT_ADMA_ERROR; |
599 | val |= ESDHC_INT_VENDOR_SPEC_DMA_ERR; |
600 | } |
601 | } |
602 | |
603 | if (unlikely((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) |
604 | && (reg == SDHCI_INT_STATUS) |
605 | && (val & SDHCI_INT_DATA_END))) { |
606 | u32 v; |
607 | v = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
608 | v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK; |
609 | writel(val: v, addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
610 | |
611 | if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS) |
612 | { |
613 | /* send a manual CMD12 with RESPTYP=none */ |
614 | data = MMC_STOP_TRANSMISSION << 24 | |
615 | SDHCI_CMD_ABORTCMD << 16; |
616 | writel(val: data, addr: host->ioaddr + SDHCI_TRANSFER_MODE); |
617 | imx_data->multiblock_status = WAIT_FOR_INT; |
618 | } |
619 | } |
620 | |
621 | writel(val, addr: host->ioaddr + reg); |
622 | } |
623 | |
624 | static u16 esdhc_readw_le(struct sdhci_host *host, int reg) |
625 | { |
626 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
627 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
628 | u16 ret = 0; |
629 | u32 val; |
630 | |
631 | if (unlikely(reg == SDHCI_HOST_VERSION)) { |
632 | reg ^= 2; |
633 | if (esdhc_is_usdhc(data: imx_data)) { |
634 | /* |
635 | * The usdhc register returns a wrong host version. |
636 | * Correct it here. |
637 | */ |
638 | return SDHCI_SPEC_300; |
639 | } |
640 | } |
641 | |
642 | if (unlikely(reg == SDHCI_HOST_CONTROL2)) { |
643 | val = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
644 | if (val & ESDHC_VENDOR_SPEC_VSELECT) |
645 | ret |= SDHCI_CTRL_VDD_180; |
646 | |
647 | if (esdhc_is_usdhc(data: imx_data)) { |
648 | if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) |
649 | val = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
650 | else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) |
651 | /* the std tuning bits is in ACMD12_ERR for imx6sl */ |
652 | val = readl(addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
653 | } |
654 | |
655 | if (val & ESDHC_MIX_CTRL_EXE_TUNE) |
656 | ret |= SDHCI_CTRL_EXEC_TUNING; |
657 | if (val & ESDHC_MIX_CTRL_SMPCLK_SEL) |
658 | ret |= SDHCI_CTRL_TUNED_CLK; |
659 | |
660 | ret &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; |
661 | |
662 | return ret; |
663 | } |
664 | |
665 | if (unlikely(reg == SDHCI_TRANSFER_MODE)) { |
666 | if (esdhc_is_usdhc(data: imx_data)) { |
667 | u32 m = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
668 | ret = m & ESDHC_MIX_CTRL_SDHCI_MASK; |
669 | /* Swap AC23 bit */ |
670 | if (m & ESDHC_MIX_CTRL_AC23EN) { |
671 | ret &= ~ESDHC_MIX_CTRL_AC23EN; |
672 | ret |= SDHCI_TRNS_AUTO_CMD23; |
673 | } |
674 | } else { |
675 | ret = readw(addr: host->ioaddr + SDHCI_TRANSFER_MODE); |
676 | } |
677 | |
678 | return ret; |
679 | } |
680 | |
681 | return readw(addr: host->ioaddr + reg); |
682 | } |
683 | |
684 | static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) |
685 | { |
686 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
687 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
688 | u32 new_val = 0; |
689 | |
690 | switch (reg) { |
691 | case SDHCI_CLOCK_CONTROL: |
692 | new_val = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
693 | if (val & SDHCI_CLOCK_CARD_EN) |
694 | new_val |= ESDHC_VENDOR_SPEC_FRC_SDCLK_ON; |
695 | else |
696 | new_val &= ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON; |
697 | writel(val: new_val, addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
698 | if (!(new_val & ESDHC_VENDOR_SPEC_FRC_SDCLK_ON)) |
699 | esdhc_wait_for_card_clock_gate_off(host); |
700 | return; |
701 | case SDHCI_HOST_CONTROL2: |
702 | new_val = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
703 | if (val & SDHCI_CTRL_VDD_180) |
704 | new_val |= ESDHC_VENDOR_SPEC_VSELECT; |
705 | else |
706 | new_val &= ~ESDHC_VENDOR_SPEC_VSELECT; |
707 | writel(val: new_val, addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
708 | if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { |
709 | u32 v = readl(addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
710 | u32 m = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
711 | if (val & SDHCI_CTRL_TUNED_CLK) { |
712 | v |= ESDHC_MIX_CTRL_SMPCLK_SEL; |
713 | } else { |
714 | v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; |
715 | m &= ~ESDHC_MIX_CTRL_FBCLK_SEL; |
716 | } |
717 | |
718 | if (val & SDHCI_CTRL_EXEC_TUNING) { |
719 | v |= ESDHC_MIX_CTRL_EXE_TUNE; |
720 | m |= ESDHC_MIX_CTRL_FBCLK_SEL; |
721 | } else { |
722 | v &= ~ESDHC_MIX_CTRL_EXE_TUNE; |
723 | } |
724 | |
725 | writel(val: v, addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
726 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
727 | } |
728 | return; |
729 | case SDHCI_TRANSFER_MODE: |
730 | if ((imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT) |
731 | && (host->cmd->opcode == SD_IO_RW_EXTENDED) |
732 | && (host->cmd->data->blocks > 1) |
733 | && (host->cmd->data->flags & MMC_DATA_READ)) { |
734 | u32 v; |
735 | v = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
736 | v |= ESDHC_VENDOR_SPEC_SDIO_QUIRK; |
737 | writel(val: v, addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
738 | } |
739 | |
740 | if (esdhc_is_usdhc(data: imx_data)) { |
741 | u32 wml; |
742 | u32 m = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
743 | /* Swap AC23 bit */ |
744 | if (val & SDHCI_TRNS_AUTO_CMD23) { |
745 | val &= ~SDHCI_TRNS_AUTO_CMD23; |
746 | val |= ESDHC_MIX_CTRL_AC23EN; |
747 | } |
748 | m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK); |
749 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
750 | |
751 | /* Set watermark levels for PIO access to maximum value |
752 | * (128 words) to accommodate full 512 bytes buffer. |
753 | * For DMA access restore the levels to default value. |
754 | */ |
755 | m = readl(addr: host->ioaddr + ESDHC_WTMK_LVL); |
756 | if (val & SDHCI_TRNS_DMA) { |
757 | wml = ESDHC_WTMK_LVL_WML_VAL_DEF; |
758 | } else { |
759 | u8 ctrl; |
760 | wml = ESDHC_WTMK_LVL_WML_VAL_MAX; |
761 | |
762 | /* |
763 | * Since already disable DMA mode, so also need |
764 | * to clear the DMASEL. Otherwise, for standard |
765 | * tuning, when send tuning command, usdhc will |
766 | * still prefetch the ADMA script from wrong |
767 | * DMA address, then we will see IOMMU report |
768 | * some error which show lack of TLB mapping. |
769 | */ |
770 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
771 | ctrl &= ~SDHCI_CTRL_DMA_MASK; |
772 | sdhci_writeb(host, val: ctrl, SDHCI_HOST_CONTROL); |
773 | } |
774 | m &= ~(ESDHC_WTMK_LVL_RD_WML_MASK | |
775 | ESDHC_WTMK_LVL_WR_WML_MASK); |
776 | m |= (wml << ESDHC_WTMK_LVL_RD_WML_SHIFT) | |
777 | (wml << ESDHC_WTMK_LVL_WR_WML_SHIFT); |
778 | writel(val: m, addr: host->ioaddr + ESDHC_WTMK_LVL); |
779 | } else { |
780 | /* |
781 | * Postpone this write, we must do it together with a |
782 | * command write that is down below. |
783 | */ |
784 | imx_data->scratchpad = val; |
785 | } |
786 | return; |
787 | case SDHCI_COMMAND: |
788 | if (host->cmd->opcode == MMC_STOP_TRANSMISSION) |
789 | val |= SDHCI_CMD_ABORTCMD; |
790 | |
791 | if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) && |
792 | (imx_data->socdata->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) |
793 | imx_data->multiblock_status = MULTIBLK_IN_PROCESS; |
794 | |
795 | if (esdhc_is_usdhc(data: imx_data)) |
796 | writel(val: val << 16, |
797 | addr: host->ioaddr + SDHCI_TRANSFER_MODE); |
798 | else |
799 | writel(val: val << 16 | imx_data->scratchpad, |
800 | addr: host->ioaddr + SDHCI_TRANSFER_MODE); |
801 | return; |
802 | case SDHCI_BLOCK_SIZE: |
803 | val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); |
804 | break; |
805 | } |
806 | esdhc_clrset_le(host, mask: 0xffff, val, reg); |
807 | } |
808 | |
809 | static u8 esdhc_readb_le(struct sdhci_host *host, int reg) |
810 | { |
811 | u8 ret; |
812 | u32 val; |
813 | |
814 | switch (reg) { |
815 | case SDHCI_HOST_CONTROL: |
816 | val = readl(addr: host->ioaddr + reg); |
817 | |
818 | ret = val & SDHCI_CTRL_LED; |
819 | ret |= (val >> 5) & SDHCI_CTRL_DMA_MASK; |
820 | ret |= (val & ESDHC_CTRL_4BITBUS); |
821 | ret |= (val & ESDHC_CTRL_8BITBUS) << 3; |
822 | return ret; |
823 | } |
824 | |
825 | return readb(addr: host->ioaddr + reg); |
826 | } |
827 | |
828 | static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) |
829 | { |
830 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
831 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
832 | u32 new_val = 0; |
833 | u32 mask; |
834 | |
835 | switch (reg) { |
836 | case SDHCI_POWER_CONTROL: |
837 | /* |
838 | * FSL put some DMA bits here |
839 | * If your board has a regulator, code should be here |
840 | */ |
841 | return; |
842 | case SDHCI_HOST_CONTROL: |
843 | /* FSL messed up here, so we need to manually compose it. */ |
844 | new_val = val & SDHCI_CTRL_LED; |
845 | /* ensure the endianness */ |
846 | new_val |= ESDHC_HOST_CONTROL_LE; |
847 | /* bits 8&9 are reserved on mx25 */ |
848 | if (!is_imx25_esdhc(data: imx_data)) { |
849 | /* DMA mode bits are shifted */ |
850 | new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5; |
851 | } |
852 | |
853 | /* |
854 | * Do not touch buswidth bits here. This is done in |
855 | * esdhc_pltfm_bus_width. |
856 | * Do not touch the D3CD bit either which is used for the |
857 | * SDIO interrupt erratum workaround. |
858 | */ |
859 | mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD); |
860 | |
861 | esdhc_clrset_le(host, mask, val: new_val, reg); |
862 | return; |
863 | case SDHCI_SOFTWARE_RESET: |
864 | if (val & SDHCI_RESET_DATA) |
865 | new_val = readl(addr: host->ioaddr + SDHCI_HOST_CONTROL); |
866 | break; |
867 | } |
868 | esdhc_clrset_le(host, mask: 0xff, val, reg); |
869 | |
870 | if (reg == SDHCI_SOFTWARE_RESET) { |
871 | if (val & SDHCI_RESET_ALL) { |
872 | /* |
873 | * The esdhc has a design violation to SDHC spec which |
874 | * tells that software reset should not affect card |
875 | * detection circuit. But esdhc clears its SYSCTL |
876 | * register bits [0..2] during the software reset. This |
877 | * will stop those clocks that card detection circuit |
878 | * relies on. To work around it, we turn the clocks on |
879 | * back to keep card detection circuit functional. |
880 | */ |
881 | esdhc_clrset_le(host, mask: 0x7, val: 0x7, ESDHC_SYSTEM_CONTROL); |
882 | /* |
883 | * The reset on usdhc fails to clear MIX_CTRL register. |
884 | * Do it manually here. |
885 | */ |
886 | if (esdhc_is_usdhc(data: imx_data)) { |
887 | /* |
888 | * the tuning bits should be kept during reset |
889 | */ |
890 | new_val = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
891 | writel(val: new_val & ESDHC_MIX_CTRL_TUNING_MASK, |
892 | addr: host->ioaddr + ESDHC_MIX_CTRL); |
893 | imx_data->is_ddr = 0; |
894 | } |
895 | } else if (val & SDHCI_RESET_DATA) { |
896 | /* |
897 | * The eSDHC DAT line software reset clears at least the |
898 | * data transfer width on i.MX25, so make sure that the |
899 | * Host Control register is unaffected. |
900 | */ |
901 | esdhc_clrset_le(host, mask: 0xff, val: new_val, |
902 | SDHCI_HOST_CONTROL); |
903 | } |
904 | } |
905 | } |
906 | |
907 | static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host) |
908 | { |
909 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
910 | |
911 | return pltfm_host->clock; |
912 | } |
913 | |
914 | static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host) |
915 | { |
916 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
917 | |
918 | return pltfm_host->clock / 256 / 16; |
919 | } |
920 | |
921 | static inline void esdhc_pltfm_set_clock(struct sdhci_host *host, |
922 | unsigned int clock) |
923 | { |
924 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
925 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
926 | unsigned int host_clock = pltfm_host->clock; |
927 | int ddr_pre_div = imx_data->is_ddr ? 2 : 1; |
928 | int pre_div = 1; |
929 | int div = 1; |
930 | int ret; |
931 | u32 temp, val; |
932 | |
933 | if (esdhc_is_usdhc(data: imx_data)) { |
934 | val = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
935 | writel(val: val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, |
936 | addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
937 | esdhc_wait_for_card_clock_gate_off(host); |
938 | } |
939 | |
940 | if (clock == 0) { |
941 | host->mmc->actual_clock = 0; |
942 | return; |
943 | } |
944 | |
945 | /* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */ |
946 | if (is_imx53_esdhc(data: imx_data)) { |
947 | /* |
948 | * According to the i.MX53 reference manual, if DLLCTRL[10] can |
949 | * be set, then the controller is eSDHCv3, else it is eSDHCv2. |
950 | */ |
951 | val = readl(addr: host->ioaddr + ESDHC_DLL_CTRL); |
952 | writel(val: val | BIT(10), addr: host->ioaddr + ESDHC_DLL_CTRL); |
953 | temp = readl(addr: host->ioaddr + ESDHC_DLL_CTRL); |
954 | writel(val, addr: host->ioaddr + ESDHC_DLL_CTRL); |
955 | if (temp & BIT(10)) |
956 | pre_div = 2; |
957 | } |
958 | |
959 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); |
960 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
961 | | ESDHC_CLOCK_MASK); |
962 | sdhci_writel(host, val: temp, ESDHC_SYSTEM_CONTROL); |
963 | |
964 | if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && |
965 | (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { |
966 | unsigned int max_clock; |
967 | |
968 | max_clock = imx_data->is_ddr ? 45000000 : 150000000; |
969 | |
970 | clock = min(clock, max_clock); |
971 | } |
972 | |
973 | while (host_clock / (16 * pre_div * ddr_pre_div) > clock && |
974 | pre_div < 256) |
975 | pre_div *= 2; |
976 | |
977 | while (host_clock / (div * pre_div * ddr_pre_div) > clock && div < 16) |
978 | div++; |
979 | |
980 | host->mmc->actual_clock = host_clock / (div * pre_div * ddr_pre_div); |
981 | dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n" , |
982 | clock, host->mmc->actual_clock); |
983 | |
984 | pre_div >>= 1; |
985 | div--; |
986 | |
987 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); |
988 | temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
989 | | (div << ESDHC_DIVIDER_SHIFT) |
990 | | (pre_div << ESDHC_PREDIV_SHIFT)); |
991 | sdhci_writel(host, val: temp, ESDHC_SYSTEM_CONTROL); |
992 | |
993 | /* need to wait the bit 3 of the PRSSTAT to be set, make sure card clock is stable */ |
994 | ret = readl_poll_timeout(host->ioaddr + ESDHC_PRSSTAT, temp, |
995 | (temp & ESDHC_CLOCK_STABLE), 2, 100); |
996 | if (ret == -ETIMEDOUT) |
997 | dev_warn(mmc_dev(host->mmc), "card clock still not stable in 100us!.\n" ); |
998 | |
999 | if (esdhc_is_usdhc(data: imx_data)) { |
1000 | val = readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
1001 | writel(val: val | ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, |
1002 | addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
1003 | } |
1004 | |
1005 | } |
1006 | |
1007 | static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host) |
1008 | { |
1009 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1010 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1011 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; |
1012 | |
1013 | switch (boarddata->wp_type) { |
1014 | case ESDHC_WP_GPIO: |
1015 | return mmc_gpio_get_ro(host: host->mmc); |
1016 | case ESDHC_WP_CONTROLLER: |
1017 | return !(readl(addr: host->ioaddr + SDHCI_PRESENT_STATE) & |
1018 | SDHCI_WRITE_PROTECT); |
1019 | case ESDHC_WP_NONE: |
1020 | break; |
1021 | } |
1022 | |
1023 | return -ENOSYS; |
1024 | } |
1025 | |
1026 | static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) |
1027 | { |
1028 | u32 ctrl; |
1029 | |
1030 | switch (width) { |
1031 | case MMC_BUS_WIDTH_8: |
1032 | ctrl = ESDHC_CTRL_8BITBUS; |
1033 | break; |
1034 | case MMC_BUS_WIDTH_4: |
1035 | ctrl = ESDHC_CTRL_4BITBUS; |
1036 | break; |
1037 | default: |
1038 | ctrl = 0; |
1039 | break; |
1040 | } |
1041 | |
1042 | esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, val: ctrl, |
1043 | SDHCI_HOST_CONTROL); |
1044 | } |
1045 | |
1046 | static void esdhc_reset_tuning(struct sdhci_host *host) |
1047 | { |
1048 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1049 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1050 | u32 ctrl; |
1051 | int ret; |
1052 | |
1053 | /* Reset the tuning circuit */ |
1054 | if (esdhc_is_usdhc(data: imx_data)) { |
1055 | ctrl = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
1056 | ctrl &= ~ESDHC_MIX_CTRL_AUTO_TUNE_EN; |
1057 | if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { |
1058 | ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; |
1059 | ctrl &= ~ESDHC_MIX_CTRL_FBCLK_SEL; |
1060 | writel(val: ctrl, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1061 | writel(val: 0, addr: host->ioaddr + ESDHC_TUNE_CTRL_STATUS); |
1062 | } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { |
1063 | writel(val: ctrl, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1064 | ctrl = readl(addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
1065 | ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; |
1066 | ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE; |
1067 | writel(val: ctrl, addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
1068 | /* Make sure ESDHC_MIX_CTRL_EXE_TUNE cleared */ |
1069 | ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, |
1070 | ctrl, !(ctrl & ESDHC_MIX_CTRL_EXE_TUNE), 1, 50); |
1071 | if (ret == -ETIMEDOUT) |
1072 | dev_warn(mmc_dev(host->mmc), |
1073 | "Warning! clear execute tuning bit failed\n" ); |
1074 | /* |
1075 | * SDHCI_INT_DATA_AVAIL is W1C bit, set this bit will clear the |
1076 | * usdhc IP internal logic flag execute_tuning_with_clr_buf, which |
1077 | * will finally make sure the normal data transfer logic correct. |
1078 | */ |
1079 | ctrl = readl(addr: host->ioaddr + SDHCI_INT_STATUS); |
1080 | ctrl |= SDHCI_INT_DATA_AVAIL; |
1081 | writel(val: ctrl, addr: host->ioaddr + SDHCI_INT_STATUS); |
1082 | } |
1083 | } |
1084 | } |
1085 | |
1086 | static void usdhc_init_card(struct mmc_host *mmc, struct mmc_card *card) |
1087 | { |
1088 | struct sdhci_host *host = mmc_priv(host: mmc); |
1089 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1090 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1091 | |
1092 | imx_data->init_card_type = card->type; |
1093 | } |
1094 | |
1095 | static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) |
1096 | { |
1097 | struct sdhci_host *host = mmc_priv(host: mmc); |
1098 | int err; |
1099 | |
1100 | /* |
1101 | * i.MX uSDHC internally already uses a fixed optimized timing for |
1102 | * DDR50, normally does not require tuning for DDR50 mode. |
1103 | */ |
1104 | if (host->timing == MMC_TIMING_UHS_DDR50) |
1105 | return 0; |
1106 | |
1107 | /* |
1108 | * Reset tuning circuit logic. If not, the previous tuning result |
1109 | * will impact current tuning, make current tuning can't set the |
1110 | * correct delay cell. |
1111 | */ |
1112 | esdhc_reset_tuning(host); |
1113 | err = sdhci_execute_tuning(mmc, opcode); |
1114 | /* If tuning done, enable auto tuning */ |
1115 | if (!err && !host->tuning_err) |
1116 | usdhc_auto_tuning_mode_sel_and_en(host); |
1117 | |
1118 | return err; |
1119 | } |
1120 | |
1121 | static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val) |
1122 | { |
1123 | u32 reg; |
1124 | u8 sw_rst; |
1125 | int ret; |
1126 | |
1127 | /* FIXME: delay a bit for card to be ready for next tuning due to errors */ |
1128 | mdelay(1); |
1129 | |
1130 | /* IC suggest to reset USDHC before every tuning command */ |
1131 | esdhc_clrset_le(host, mask: 0xff, SDHCI_RESET_ALL, SDHCI_SOFTWARE_RESET); |
1132 | ret = readb_poll_timeout(host->ioaddr + SDHCI_SOFTWARE_RESET, sw_rst, |
1133 | !(sw_rst & SDHCI_RESET_ALL), 10, 100); |
1134 | if (ret == -ETIMEDOUT) |
1135 | dev_warn(mmc_dev(host->mmc), |
1136 | "warning! RESET_ALL never complete before sending tuning command\n" ); |
1137 | |
1138 | reg = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
1139 | reg |= ESDHC_MIX_CTRL_EXE_TUNE | ESDHC_MIX_CTRL_SMPCLK_SEL | |
1140 | ESDHC_MIX_CTRL_FBCLK_SEL; |
1141 | writel(val: reg, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1142 | writel(val: val << 8, addr: host->ioaddr + ESDHC_TUNE_CTRL_STATUS); |
1143 | dev_dbg(mmc_dev(host->mmc), |
1144 | "tuning with delay 0x%x ESDHC_TUNE_CTRL_STATUS 0x%x\n" , |
1145 | val, readl(host->ioaddr + ESDHC_TUNE_CTRL_STATUS)); |
1146 | } |
1147 | |
1148 | static void esdhc_post_tuning(struct sdhci_host *host) |
1149 | { |
1150 | u32 reg; |
1151 | |
1152 | reg = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
1153 | reg &= ~ESDHC_MIX_CTRL_EXE_TUNE; |
1154 | writel(val: reg, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1155 | } |
1156 | |
1157 | /* |
1158 | * find the largest pass window, and use the average delay of this |
1159 | * largest window to get the best timing. |
1160 | */ |
1161 | static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode) |
1162 | { |
1163 | int min, max, avg, ret; |
1164 | int win_length, target_min, target_max, target_win_length; |
1165 | |
1166 | min = ESDHC_TUNE_CTRL_MIN; |
1167 | max = ESDHC_TUNE_CTRL_MIN; |
1168 | target_win_length = 0; |
1169 | while (max < ESDHC_TUNE_CTRL_MAX) { |
1170 | /* find the mininum delay first which can pass tuning */ |
1171 | while (min < ESDHC_TUNE_CTRL_MAX) { |
1172 | esdhc_prepare_tuning(host, val: min); |
1173 | if (!mmc_send_tuning(host: host->mmc, opcode, NULL)) |
1174 | break; |
1175 | min += ESDHC_TUNE_CTRL_STEP; |
1176 | } |
1177 | |
1178 | /* find the maxinum delay which can not pass tuning */ |
1179 | max = min + ESDHC_TUNE_CTRL_STEP; |
1180 | while (max < ESDHC_TUNE_CTRL_MAX) { |
1181 | esdhc_prepare_tuning(host, val: max); |
1182 | if (mmc_send_tuning(host: host->mmc, opcode, NULL)) { |
1183 | max -= ESDHC_TUNE_CTRL_STEP; |
1184 | break; |
1185 | } |
1186 | max += ESDHC_TUNE_CTRL_STEP; |
1187 | } |
1188 | |
1189 | win_length = max - min + 1; |
1190 | /* get the largest pass window */ |
1191 | if (win_length > target_win_length) { |
1192 | target_win_length = win_length; |
1193 | target_min = min; |
1194 | target_max = max; |
1195 | } |
1196 | |
1197 | /* continue to find the next pass window */ |
1198 | min = max + ESDHC_TUNE_CTRL_STEP; |
1199 | } |
1200 | |
1201 | /* use average delay to get the best timing */ |
1202 | avg = (target_min + target_max) / 2; |
1203 | esdhc_prepare_tuning(host, val: avg); |
1204 | ret = mmc_send_tuning(host: host->mmc, opcode, NULL); |
1205 | esdhc_post_tuning(host); |
1206 | |
1207 | dev_dbg(mmc_dev(host->mmc), "tuning %s at 0x%x ret %d\n" , |
1208 | ret ? "failed" : "passed" , avg, ret); |
1209 | |
1210 | return ret; |
1211 | } |
1212 | |
1213 | static void esdhc_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) |
1214 | { |
1215 | struct sdhci_host *host = mmc_priv(host: mmc); |
1216 | u32 m; |
1217 | |
1218 | m = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
1219 | if (ios->enhanced_strobe) |
1220 | m |= ESDHC_MIX_CTRL_HS400_ES_EN; |
1221 | else |
1222 | m &= ~ESDHC_MIX_CTRL_HS400_ES_EN; |
1223 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1224 | } |
1225 | |
1226 | static int esdhc_change_pinstate(struct sdhci_host *host, |
1227 | unsigned int uhs) |
1228 | { |
1229 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1230 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1231 | struct pinctrl_state *pinctrl; |
1232 | |
1233 | dev_dbg(mmc_dev(host->mmc), "change pinctrl state for uhs %d\n" , uhs); |
1234 | |
1235 | if (IS_ERR(ptr: imx_data->pinctrl) || |
1236 | IS_ERR(ptr: imx_data->pins_100mhz) || |
1237 | IS_ERR(ptr: imx_data->pins_200mhz)) |
1238 | return -EINVAL; |
1239 | |
1240 | switch (uhs) { |
1241 | case MMC_TIMING_UHS_SDR50: |
1242 | case MMC_TIMING_UHS_DDR50: |
1243 | pinctrl = imx_data->pins_100mhz; |
1244 | break; |
1245 | case MMC_TIMING_UHS_SDR104: |
1246 | case MMC_TIMING_MMC_HS200: |
1247 | case MMC_TIMING_MMC_HS400: |
1248 | pinctrl = imx_data->pins_200mhz; |
1249 | break; |
1250 | default: |
1251 | /* back to default state for other legacy timing */ |
1252 | return pinctrl_select_default_state(mmc_dev(host->mmc)); |
1253 | } |
1254 | |
1255 | return pinctrl_select_state(p: imx_data->pinctrl, s: pinctrl); |
1256 | } |
1257 | |
1258 | /* |
1259 | * For HS400 eMMC, there is a data_strobe line. This signal is generated |
1260 | * by the device and used for data output and CRC status response output |
1261 | * in HS400 mode. The frequency of this signal follows the frequency of |
1262 | * CLK generated by host. The host receives the data which is aligned to the |
1263 | * edge of data_strobe line. Due to the time delay between CLK line and |
1264 | * data_strobe line, if the delay time is larger than one clock cycle, |
1265 | * then CLK and data_strobe line will be misaligned, read error shows up. |
1266 | */ |
1267 | static void esdhc_set_strobe_dll(struct sdhci_host *host) |
1268 | { |
1269 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1270 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1271 | u32 strobe_delay; |
1272 | u32 v; |
1273 | int ret; |
1274 | |
1275 | /* disable clock before enabling strobe dll */ |
1276 | writel(readl(addr: host->ioaddr + ESDHC_VENDOR_SPEC) & |
1277 | ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, |
1278 | addr: host->ioaddr + ESDHC_VENDOR_SPEC); |
1279 | esdhc_wait_for_card_clock_gate_off(host); |
1280 | |
1281 | /* force a reset on strobe dll */ |
1282 | writel(ESDHC_STROBE_DLL_CTRL_RESET, |
1283 | addr: host->ioaddr + ESDHC_STROBE_DLL_CTRL); |
1284 | /* clear the reset bit on strobe dll before any setting */ |
1285 | writel(val: 0, addr: host->ioaddr + ESDHC_STROBE_DLL_CTRL); |
1286 | |
1287 | /* |
1288 | * enable strobe dll ctrl and adjust the delay target |
1289 | * for the uSDHC loopback read clock |
1290 | */ |
1291 | if (imx_data->boarddata.strobe_dll_delay_target) |
1292 | strobe_delay = imx_data->boarddata.strobe_dll_delay_target; |
1293 | else |
1294 | strobe_delay = ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT; |
1295 | v = ESDHC_STROBE_DLL_CTRL_ENABLE | |
1296 | ESDHC_STROBE_DLL_CTRL_SLV_UPDATE_INT_DEFAULT | |
1297 | (strobe_delay << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT); |
1298 | writel(val: v, addr: host->ioaddr + ESDHC_STROBE_DLL_CTRL); |
1299 | |
1300 | /* wait max 50us to get the REF/SLV lock */ |
1301 | ret = readl_poll_timeout(host->ioaddr + ESDHC_STROBE_DLL_STATUS, v, |
1302 | ((v & ESDHC_STROBE_DLL_STS_REF_LOCK) && (v & ESDHC_STROBE_DLL_STS_SLV_LOCK)), 1, 50); |
1303 | if (ret == -ETIMEDOUT) |
1304 | dev_warn(mmc_dev(host->mmc), |
1305 | "warning! HS400 strobe DLL status REF/SLV not lock in 50us, STROBE DLL status is %x!\n" , v); |
1306 | } |
1307 | |
1308 | static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing) |
1309 | { |
1310 | u32 m; |
1311 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1312 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1313 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; |
1314 | |
1315 | /* disable ddr mode and disable HS400 mode */ |
1316 | m = readl(addr: host->ioaddr + ESDHC_MIX_CTRL); |
1317 | m &= ~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN); |
1318 | imx_data->is_ddr = 0; |
1319 | |
1320 | switch (timing) { |
1321 | case MMC_TIMING_UHS_SDR12: |
1322 | case MMC_TIMING_UHS_SDR25: |
1323 | case MMC_TIMING_UHS_SDR50: |
1324 | case MMC_TIMING_UHS_SDR104: |
1325 | case MMC_TIMING_MMC_HS: |
1326 | case MMC_TIMING_MMC_HS200: |
1327 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1328 | break; |
1329 | case MMC_TIMING_UHS_DDR50: |
1330 | case MMC_TIMING_MMC_DDR52: |
1331 | m |= ESDHC_MIX_CTRL_DDREN; |
1332 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1333 | imx_data->is_ddr = 1; |
1334 | if (boarddata->delay_line) { |
1335 | u32 v; |
1336 | v = boarddata->delay_line << |
1337 | ESDHC_DLL_OVERRIDE_VAL_SHIFT | |
1338 | (1 << ESDHC_DLL_OVERRIDE_EN_SHIFT); |
1339 | if (is_imx53_esdhc(data: imx_data)) |
1340 | v <<= 1; |
1341 | writel(val: v, addr: host->ioaddr + ESDHC_DLL_CTRL); |
1342 | } |
1343 | break; |
1344 | case MMC_TIMING_MMC_HS400: |
1345 | m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN; |
1346 | writel(val: m, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1347 | imx_data->is_ddr = 1; |
1348 | /* update clock after enable DDR for strobe DLL lock */ |
1349 | host->ops->set_clock(host, host->clock); |
1350 | esdhc_set_strobe_dll(host); |
1351 | break; |
1352 | case MMC_TIMING_LEGACY: |
1353 | default: |
1354 | esdhc_reset_tuning(host); |
1355 | break; |
1356 | } |
1357 | |
1358 | esdhc_change_pinstate(host, uhs: timing); |
1359 | } |
1360 | |
1361 | static void esdhc_reset(struct sdhci_host *host, u8 mask) |
1362 | { |
1363 | sdhci_and_cqhci_reset(host, mask); |
1364 | |
1365 | sdhci_writel(host, val: host->ier, SDHCI_INT_ENABLE); |
1366 | sdhci_writel(host, val: host->ier, SDHCI_SIGNAL_ENABLE); |
1367 | } |
1368 | |
1369 | static unsigned int esdhc_get_max_timeout_count(struct sdhci_host *host) |
1370 | { |
1371 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1372 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1373 | |
1374 | /* Doc Erratum: the uSDHC actual maximum timeout count is 1 << 29 */ |
1375 | return esdhc_is_usdhc(data: imx_data) ? 1 << 29 : 1 << 27; |
1376 | } |
1377 | |
1378 | static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
1379 | { |
1380 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1381 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1382 | |
1383 | /* use maximum timeout counter */ |
1384 | esdhc_clrset_le(host, ESDHC_SYS_CTRL_DTOCV_MASK, |
1385 | val: esdhc_is_usdhc(data: imx_data) ? 0xF : 0xE, |
1386 | SDHCI_TIMEOUT_CONTROL); |
1387 | } |
1388 | |
1389 | static u32 esdhc_cqhci_irq(struct sdhci_host *host, u32 intmask) |
1390 | { |
1391 | int cmd_error = 0; |
1392 | int data_error = 0; |
1393 | |
1394 | if (!sdhci_cqe_irq(host, intmask, cmd_error: &cmd_error, data_error: &data_error)) |
1395 | return intmask; |
1396 | |
1397 | cqhci_irq(mmc: host->mmc, intmask, cmd_error, data_error); |
1398 | |
1399 | return 0; |
1400 | } |
1401 | |
1402 | static struct sdhci_ops sdhci_esdhc_ops = { |
1403 | .read_l = esdhc_readl_le, |
1404 | .read_w = esdhc_readw_le, |
1405 | .read_b = esdhc_readb_le, |
1406 | .write_l = esdhc_writel_le, |
1407 | .write_w = esdhc_writew_le, |
1408 | .write_b = esdhc_writeb_le, |
1409 | .set_clock = esdhc_pltfm_set_clock, |
1410 | .get_max_clock = esdhc_pltfm_get_max_clock, |
1411 | .get_min_clock = esdhc_pltfm_get_min_clock, |
1412 | .get_max_timeout_count = esdhc_get_max_timeout_count, |
1413 | .get_ro = esdhc_pltfm_get_ro, |
1414 | .set_timeout = esdhc_set_timeout, |
1415 | .set_bus_width = esdhc_pltfm_set_bus_width, |
1416 | .set_uhs_signaling = esdhc_set_uhs_signaling, |
1417 | .reset = esdhc_reset, |
1418 | .irq = esdhc_cqhci_irq, |
1419 | .dump_vendor_regs = esdhc_dump_debug_regs, |
1420 | }; |
1421 | |
1422 | static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { |
1423 | .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_HISPD_BIT |
1424 | | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
1425 | | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
1426 | | SDHCI_QUIRK_BROKEN_CARD_DETECTION, |
1427 | .ops = &sdhci_esdhc_ops, |
1428 | }; |
1429 | |
1430 | static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host) |
1431 | { |
1432 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1433 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1434 | struct cqhci_host *cq_host = host->mmc->cqe_private; |
1435 | u32 tmp; |
1436 | |
1437 | if (esdhc_is_usdhc(data: imx_data)) { |
1438 | /* |
1439 | * The imx6q ROM code will change the default watermark |
1440 | * level setting to something insane. Change it back here. |
1441 | */ |
1442 | writel(ESDHC_WTMK_DEFAULT_VAL, addr: host->ioaddr + ESDHC_WTMK_LVL); |
1443 | |
1444 | /* |
1445 | * ROM code will change the bit burst_length_enable setting |
1446 | * to zero if this usdhc is chosen to boot system. Change |
1447 | * it back here, otherwise it will impact the performance a |
1448 | * lot. This bit is used to enable/disable the burst length |
1449 | * for the external AHB2AXI bridge. It's useful especially |
1450 | * for INCR transfer because without burst length indicator, |
1451 | * the AHB2AXI bridge does not know the burst length in |
1452 | * advance. And without burst length indicator, AHB INCR |
1453 | * transfer can only be converted to singles on the AXI side. |
1454 | */ |
1455 | writel(readl(addr: host->ioaddr + SDHCI_HOST_CONTROL) |
1456 | | ESDHC_BURST_LEN_EN_INCR, |
1457 | addr: host->ioaddr + SDHCI_HOST_CONTROL); |
1458 | |
1459 | /* |
1460 | * erratum ESDHC_FLAG_ERR004536 fix for MX6Q TO1.2 and MX6DL |
1461 | * TO1.1, it's harmless for MX6SL |
1462 | */ |
1463 | if (!(imx_data->socdata->flags & ESDHC_FLAG_SKIP_ERR004536)) { |
1464 | writel(readl(addr: host->ioaddr + 0x6c) & ~BIT(7), |
1465 | addr: host->ioaddr + 0x6c); |
1466 | } |
1467 | |
1468 | /* disable DLL_CTRL delay line settings */ |
1469 | writel(val: 0x0, addr: host->ioaddr + ESDHC_DLL_CTRL); |
1470 | |
1471 | /* |
1472 | * For the case of command with busy, if set the bit |
1473 | * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a |
1474 | * transfer complete interrupt when busy is deasserted. |
1475 | * When CQHCI use DCMD to send a CMD need R1b respons, |
1476 | * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ, |
1477 | * otherwise DCMD will always meet timeout waiting for |
1478 | * hardware interrupt issue. |
1479 | */ |
1480 | if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { |
1481 | tmp = readl(addr: host->ioaddr + ESDHC_VEND_SPEC2); |
1482 | tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ; |
1483 | writel(val: tmp, addr: host->ioaddr + ESDHC_VEND_SPEC2); |
1484 | |
1485 | host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; |
1486 | } |
1487 | |
1488 | if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { |
1489 | tmp = readl(addr: host->ioaddr + ESDHC_TUNING_CTRL); |
1490 | tmp |= ESDHC_STD_TUNING_EN; |
1491 | |
1492 | /* |
1493 | * ROM code or bootloader may config the start tap |
1494 | * and step, unmask them first. |
1495 | */ |
1496 | tmp &= ~(ESDHC_TUNING_START_TAP_MASK | ESDHC_TUNING_STEP_MASK); |
1497 | if (imx_data->boarddata.tuning_start_tap) |
1498 | tmp |= imx_data->boarddata.tuning_start_tap; |
1499 | else |
1500 | tmp |= ESDHC_TUNING_START_TAP_DEFAULT; |
1501 | |
1502 | if (imx_data->boarddata.tuning_step) { |
1503 | tmp |= imx_data->boarddata.tuning_step |
1504 | << ESDHC_TUNING_STEP_SHIFT; |
1505 | } else { |
1506 | tmp |= ESDHC_TUNING_STEP_DEFAULT |
1507 | << ESDHC_TUNING_STEP_SHIFT; |
1508 | } |
1509 | |
1510 | /* Disable the CMD CRC check for tuning, if not, need to |
1511 | * add some delay after every tuning command, because |
1512 | * hardware standard tuning logic will directly go to next |
1513 | * step once it detect the CMD CRC error, will not wait for |
1514 | * the card side to finally send out the tuning data, trigger |
1515 | * the buffer read ready interrupt immediately. If usdhc send |
1516 | * the next tuning command some eMMC card will stuck, can't |
1517 | * response, block the tuning procedure or the first command |
1518 | * after the whole tuning procedure always can't get any response. |
1519 | */ |
1520 | tmp |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE; |
1521 | writel(val: tmp, addr: host->ioaddr + ESDHC_TUNING_CTRL); |
1522 | } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { |
1523 | /* |
1524 | * ESDHC_STD_TUNING_EN may be configed in bootloader |
1525 | * or ROM code, so clear this bit here to make sure |
1526 | * the manual tuning can work. |
1527 | */ |
1528 | tmp = readl(addr: host->ioaddr + ESDHC_TUNING_CTRL); |
1529 | tmp &= ~ESDHC_STD_TUNING_EN; |
1530 | writel(val: tmp, addr: host->ioaddr + ESDHC_TUNING_CTRL); |
1531 | } |
1532 | |
1533 | /* |
1534 | * On i.MX8MM, we are running Dual Linux OS, with 1st Linux using SD Card |
1535 | * as rootfs storage, 2nd Linux using eMMC as rootfs storage. We let |
1536 | * the 1st linux configure power/clock for the 2nd Linux. |
1537 | * |
1538 | * When the 2nd Linux is booting into rootfs stage, we let the 1st Linux |
1539 | * to destroy the 2nd linux, then restart the 2nd linux, we met SDHCI dump. |
1540 | * After we clear the pending interrupt and halt CQCTL, issue gone. |
1541 | */ |
1542 | if (cq_host) { |
1543 | tmp = cqhci_readl(host: cq_host, CQHCI_IS); |
1544 | cqhci_writel(host: cq_host, val: tmp, CQHCI_IS); |
1545 | cqhci_writel(host: cq_host, CQHCI_HALT, CQHCI_CTL); |
1546 | } |
1547 | } |
1548 | } |
1549 | |
1550 | static void esdhc_cqe_enable(struct mmc_host *mmc) |
1551 | { |
1552 | struct sdhci_host *host = mmc_priv(host: mmc); |
1553 | struct cqhci_host *cq_host = mmc->cqe_private; |
1554 | u32 reg; |
1555 | u16 mode; |
1556 | int count = 10; |
1557 | |
1558 | /* |
1559 | * CQE gets stuck if it sees Buffer Read Enable bit set, which can be |
1560 | * the case after tuning, so ensure the buffer is drained. |
1561 | */ |
1562 | reg = sdhci_readl(host, SDHCI_PRESENT_STATE); |
1563 | while (reg & SDHCI_DATA_AVAILABLE) { |
1564 | sdhci_readl(host, SDHCI_BUFFER); |
1565 | reg = sdhci_readl(host, SDHCI_PRESENT_STATE); |
1566 | if (count-- == 0) { |
1567 | dev_warn(mmc_dev(host->mmc), |
1568 | "CQE may get stuck because the Buffer Read Enable bit is set\n" ); |
1569 | break; |
1570 | } |
1571 | mdelay(1); |
1572 | } |
1573 | |
1574 | /* |
1575 | * Runtime resume will reset the entire host controller, which |
1576 | * will also clear the DMAEN/BCEN of register ESDHC_MIX_CTRL. |
1577 | * Here set DMAEN and BCEN when enable CMDQ. |
1578 | */ |
1579 | mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); |
1580 | if (host->flags & SDHCI_REQ_USE_DMA) |
1581 | mode |= SDHCI_TRNS_DMA; |
1582 | if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) |
1583 | mode |= SDHCI_TRNS_BLK_CNT_EN; |
1584 | sdhci_writew(host, val: mode, SDHCI_TRANSFER_MODE); |
1585 | |
1586 | /* |
1587 | * Though Runtime resume reset the entire host controller, |
1588 | * but do not impact the CQHCI side, need to clear the |
1589 | * HALT bit, avoid CQHCI stuck in the first request when |
1590 | * system resume back. |
1591 | */ |
1592 | cqhci_writel(host: cq_host, val: 0, CQHCI_CTL); |
1593 | if (cqhci_readl(host: cq_host, CQHCI_CTL) & CQHCI_HALT) |
1594 | dev_err(mmc_dev(host->mmc), |
1595 | "failed to exit halt state when enable CQE\n" ); |
1596 | |
1597 | |
1598 | sdhci_cqe_enable(mmc); |
1599 | } |
1600 | |
1601 | static void esdhc_sdhci_dumpregs(struct mmc_host *mmc) |
1602 | { |
1603 | sdhci_dumpregs(host: mmc_priv(host: mmc)); |
1604 | } |
1605 | |
1606 | static const struct cqhci_host_ops esdhc_cqhci_ops = { |
1607 | .enable = esdhc_cqe_enable, |
1608 | .disable = sdhci_cqe_disable, |
1609 | .dumpregs = esdhc_sdhci_dumpregs, |
1610 | }; |
1611 | |
1612 | static int |
1613 | sdhci_esdhc_imx_probe_dt(struct platform_device *pdev, |
1614 | struct sdhci_host *host, |
1615 | struct pltfm_imx_data *imx_data) |
1616 | { |
1617 | struct device_node *np = pdev->dev.of_node; |
1618 | struct esdhc_platform_data *boarddata = &imx_data->boarddata; |
1619 | int ret; |
1620 | |
1621 | if (of_property_read_bool(np, propname: "fsl,wp-controller" )) |
1622 | boarddata->wp_type = ESDHC_WP_CONTROLLER; |
1623 | |
1624 | /* |
1625 | * If we have this property, then activate WP check. |
1626 | * Retrieveing and requesting the actual WP GPIO will happen |
1627 | * in the call to mmc_of_parse(). |
1628 | */ |
1629 | if (of_property_read_bool(np, propname: "wp-gpios" )) |
1630 | boarddata->wp_type = ESDHC_WP_GPIO; |
1631 | |
1632 | of_property_read_u32(np, propname: "fsl,tuning-step" , out_value: &boarddata->tuning_step); |
1633 | of_property_read_u32(np, propname: "fsl,tuning-start-tap" , |
1634 | out_value: &boarddata->tuning_start_tap); |
1635 | |
1636 | of_property_read_u32(np, propname: "fsl,strobe-dll-delay-target" , |
1637 | out_value: &boarddata->strobe_dll_delay_target); |
1638 | if (of_property_read_bool(np, propname: "no-1-8-v" )) |
1639 | host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V; |
1640 | |
1641 | if (of_property_read_u32(np, propname: "fsl,delay-line" , out_value: &boarddata->delay_line)) |
1642 | boarddata->delay_line = 0; |
1643 | |
1644 | mmc_of_parse_voltage(host: host->mmc, mask: &host->ocr_mask); |
1645 | |
1646 | if (esdhc_is_usdhc(data: imx_data) && !IS_ERR(ptr: imx_data->pinctrl)) { |
1647 | imx_data->pins_100mhz = pinctrl_lookup_state(p: imx_data->pinctrl, |
1648 | ESDHC_PINCTRL_STATE_100MHZ); |
1649 | imx_data->pins_200mhz = pinctrl_lookup_state(p: imx_data->pinctrl, |
1650 | ESDHC_PINCTRL_STATE_200MHZ); |
1651 | } |
1652 | |
1653 | /* call to generic mmc_of_parse to support additional capabilities */ |
1654 | ret = mmc_of_parse(host: host->mmc); |
1655 | if (ret) |
1656 | return ret; |
1657 | |
1658 | /* HS400/HS400ES require 8 bit bus */ |
1659 | if (!(host->mmc->caps & MMC_CAP_8_BIT_DATA)) |
1660 | host->mmc->caps2 &= ~(MMC_CAP2_HS400 | MMC_CAP2_HS400_ES); |
1661 | |
1662 | if (mmc_gpio_get_cd(host: host->mmc) >= 0) |
1663 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
1664 | |
1665 | return 0; |
1666 | } |
1667 | |
1668 | static int sdhci_esdhc_imx_probe(struct platform_device *pdev) |
1669 | { |
1670 | struct sdhci_pltfm_host *pltfm_host; |
1671 | struct sdhci_host *host; |
1672 | struct cqhci_host *cq_host; |
1673 | int err; |
1674 | struct pltfm_imx_data *imx_data; |
1675 | |
1676 | host = sdhci_pltfm_init(pdev, pdata: &sdhci_esdhc_imx_pdata, |
1677 | priv_size: sizeof(*imx_data)); |
1678 | if (IS_ERR(ptr: host)) |
1679 | return PTR_ERR(ptr: host); |
1680 | |
1681 | pltfm_host = sdhci_priv(host); |
1682 | |
1683 | imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1684 | |
1685 | imx_data->socdata = device_get_match_data(dev: &pdev->dev); |
1686 | |
1687 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1688 | cpu_latency_qos_add_request(req: &imx_data->pm_qos_req, value: 0); |
1689 | |
1690 | imx_data->clk_ipg = devm_clk_get(dev: &pdev->dev, id: "ipg" ); |
1691 | if (IS_ERR(ptr: imx_data->clk_ipg)) { |
1692 | err = PTR_ERR(ptr: imx_data->clk_ipg); |
1693 | goto free_sdhci; |
1694 | } |
1695 | |
1696 | imx_data->clk_ahb = devm_clk_get(dev: &pdev->dev, id: "ahb" ); |
1697 | if (IS_ERR(ptr: imx_data->clk_ahb)) { |
1698 | err = PTR_ERR(ptr: imx_data->clk_ahb); |
1699 | goto free_sdhci; |
1700 | } |
1701 | |
1702 | imx_data->clk_per = devm_clk_get(dev: &pdev->dev, id: "per" ); |
1703 | if (IS_ERR(ptr: imx_data->clk_per)) { |
1704 | err = PTR_ERR(ptr: imx_data->clk_per); |
1705 | goto free_sdhci; |
1706 | } |
1707 | |
1708 | pltfm_host->clk = imx_data->clk_per; |
1709 | pltfm_host->clock = clk_get_rate(clk: pltfm_host->clk); |
1710 | err = clk_prepare_enable(clk: imx_data->clk_per); |
1711 | if (err) |
1712 | goto free_sdhci; |
1713 | err = clk_prepare_enable(clk: imx_data->clk_ipg); |
1714 | if (err) |
1715 | goto disable_per_clk; |
1716 | err = clk_prepare_enable(clk: imx_data->clk_ahb); |
1717 | if (err) |
1718 | goto disable_ipg_clk; |
1719 | |
1720 | imx_data->pinctrl = devm_pinctrl_get(dev: &pdev->dev); |
1721 | if (IS_ERR(ptr: imx_data->pinctrl)) |
1722 | dev_warn(mmc_dev(host->mmc), "could not get pinctrl\n" ); |
1723 | |
1724 | if (esdhc_is_usdhc(data: imx_data)) { |
1725 | host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; |
1726 | host->mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; |
1727 | |
1728 | /* GPIO CD can be set as a wakeup source */ |
1729 | host->mmc->caps |= MMC_CAP_CD_WAKE; |
1730 | |
1731 | if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200)) |
1732 | host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200; |
1733 | |
1734 | /* clear tuning bits in case ROM has set it already */ |
1735 | writel(val: 0x0, addr: host->ioaddr + ESDHC_MIX_CTRL); |
1736 | writel(val: 0x0, addr: host->ioaddr + SDHCI_AUTO_CMD_STATUS); |
1737 | writel(val: 0x0, addr: host->ioaddr + ESDHC_TUNE_CTRL_STATUS); |
1738 | |
1739 | /* |
1740 | * Link usdhc specific mmc_host_ops execute_tuning function, |
1741 | * to replace the standard one in sdhci_ops. |
1742 | */ |
1743 | host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; |
1744 | |
1745 | /* |
1746 | * Link usdhc specific mmc_host_ops init card function, |
1747 | * to distinguish the card type. |
1748 | */ |
1749 | host->mmc_host_ops.init_card = usdhc_init_card; |
1750 | } |
1751 | |
1752 | if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) |
1753 | sdhci_esdhc_ops.platform_execute_tuning = |
1754 | esdhc_executing_tuning; |
1755 | |
1756 | if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) |
1757 | host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; |
1758 | |
1759 | if (imx_data->socdata->flags & ESDHC_FLAG_HS400) |
1760 | host->mmc->caps2 |= MMC_CAP2_HS400; |
1761 | |
1762 | if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) |
1763 | host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; |
1764 | |
1765 | if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { |
1766 | host->mmc->caps2 |= MMC_CAP2_HS400_ES; |
1767 | host->mmc_host_ops.hs400_enhanced_strobe = |
1768 | esdhc_hs400_enhanced_strobe; |
1769 | } |
1770 | |
1771 | if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) { |
1772 | host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; |
1773 | cq_host = devm_kzalloc(dev: &pdev->dev, size: sizeof(*cq_host), GFP_KERNEL); |
1774 | if (!cq_host) { |
1775 | err = -ENOMEM; |
1776 | goto disable_ahb_clk; |
1777 | } |
1778 | |
1779 | cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET; |
1780 | cq_host->ops = &esdhc_cqhci_ops; |
1781 | |
1782 | err = cqhci_init(cq_host, mmc: host->mmc, dma64: false); |
1783 | if (err) |
1784 | goto disable_ahb_clk; |
1785 | } |
1786 | |
1787 | err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data); |
1788 | if (err) |
1789 | goto disable_ahb_clk; |
1790 | |
1791 | sdhci_esdhc_imx_hwinit(host); |
1792 | |
1793 | err = sdhci_add_host(host); |
1794 | if (err) |
1795 | goto disable_ahb_clk; |
1796 | |
1797 | /* |
1798 | * Setup the wakeup capability here, let user to decide |
1799 | * whether need to enable this wakeup through sysfs interface. |
1800 | */ |
1801 | if ((host->mmc->pm_caps & MMC_PM_KEEP_POWER) && |
1802 | (host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)) |
1803 | device_set_wakeup_capable(dev: &pdev->dev, capable: true); |
1804 | |
1805 | pm_runtime_set_active(dev: &pdev->dev); |
1806 | pm_runtime_set_autosuspend_delay(dev: &pdev->dev, delay: 50); |
1807 | pm_runtime_use_autosuspend(dev: &pdev->dev); |
1808 | pm_suspend_ignore_children(dev: &pdev->dev, enable: 1); |
1809 | pm_runtime_enable(dev: &pdev->dev); |
1810 | |
1811 | return 0; |
1812 | |
1813 | disable_ahb_clk: |
1814 | clk_disable_unprepare(clk: imx_data->clk_ahb); |
1815 | disable_ipg_clk: |
1816 | clk_disable_unprepare(clk: imx_data->clk_ipg); |
1817 | disable_per_clk: |
1818 | clk_disable_unprepare(clk: imx_data->clk_per); |
1819 | free_sdhci: |
1820 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1821 | cpu_latency_qos_remove_request(req: &imx_data->pm_qos_req); |
1822 | sdhci_pltfm_free(pdev); |
1823 | return err; |
1824 | } |
1825 | |
1826 | static void sdhci_esdhc_imx_remove(struct platform_device *pdev) |
1827 | { |
1828 | struct sdhci_host *host = platform_get_drvdata(pdev); |
1829 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1830 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1831 | int dead; |
1832 | |
1833 | pm_runtime_get_sync(dev: &pdev->dev); |
1834 | dead = (readl(addr: host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); |
1835 | pm_runtime_disable(dev: &pdev->dev); |
1836 | pm_runtime_put_noidle(dev: &pdev->dev); |
1837 | |
1838 | sdhci_remove_host(host, dead); |
1839 | |
1840 | clk_disable_unprepare(clk: imx_data->clk_per); |
1841 | clk_disable_unprepare(clk: imx_data->clk_ipg); |
1842 | clk_disable_unprepare(clk: imx_data->clk_ahb); |
1843 | |
1844 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1845 | cpu_latency_qos_remove_request(req: &imx_data->pm_qos_req); |
1846 | |
1847 | sdhci_pltfm_free(pdev); |
1848 | } |
1849 | |
1850 | #ifdef CONFIG_PM_SLEEP |
1851 | static int sdhci_esdhc_suspend(struct device *dev) |
1852 | { |
1853 | struct sdhci_host *host = dev_get_drvdata(dev); |
1854 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1855 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1856 | int ret; |
1857 | |
1858 | if (host->mmc->caps2 & MMC_CAP2_CQE) { |
1859 | ret = cqhci_suspend(mmc: host->mmc); |
1860 | if (ret) |
1861 | return ret; |
1862 | } |
1863 | |
1864 | if ((imx_data->socdata->flags & ESDHC_FLAG_STATE_LOST_IN_LPMODE) && |
1865 | (host->tuning_mode != SDHCI_TUNING_MODE_1)) { |
1866 | mmc_retune_timer_stop(host: host->mmc); |
1867 | mmc_retune_needed(host: host->mmc); |
1868 | } |
1869 | |
1870 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
1871 | mmc_retune_needed(host: host->mmc); |
1872 | |
1873 | ret = sdhci_suspend_host(host); |
1874 | if (ret) |
1875 | return ret; |
1876 | |
1877 | ret = pinctrl_pm_select_sleep_state(dev); |
1878 | if (ret) |
1879 | return ret; |
1880 | |
1881 | ret = mmc_gpio_set_cd_wake(host: host->mmc, on: true); |
1882 | |
1883 | return ret; |
1884 | } |
1885 | |
1886 | static int sdhci_esdhc_resume(struct device *dev) |
1887 | { |
1888 | struct sdhci_host *host = dev_get_drvdata(dev); |
1889 | int ret; |
1890 | |
1891 | ret = pinctrl_pm_select_default_state(dev); |
1892 | if (ret) |
1893 | return ret; |
1894 | |
1895 | /* re-initialize hw state in case it's lost in low power mode */ |
1896 | sdhci_esdhc_imx_hwinit(host); |
1897 | |
1898 | ret = sdhci_resume_host(host); |
1899 | if (ret) |
1900 | return ret; |
1901 | |
1902 | if (host->mmc->caps2 & MMC_CAP2_CQE) |
1903 | ret = cqhci_resume(mmc: host->mmc); |
1904 | |
1905 | if (!ret) |
1906 | ret = mmc_gpio_set_cd_wake(host: host->mmc, on: false); |
1907 | |
1908 | return ret; |
1909 | } |
1910 | #endif |
1911 | |
1912 | #ifdef CONFIG_PM |
1913 | static int sdhci_esdhc_runtime_suspend(struct device *dev) |
1914 | { |
1915 | struct sdhci_host *host = dev_get_drvdata(dev); |
1916 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1917 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1918 | int ret; |
1919 | |
1920 | if (host->mmc->caps2 & MMC_CAP2_CQE) { |
1921 | ret = cqhci_suspend(mmc: host->mmc); |
1922 | if (ret) |
1923 | return ret; |
1924 | } |
1925 | |
1926 | ret = sdhci_runtime_suspend_host(host); |
1927 | if (ret) |
1928 | return ret; |
1929 | |
1930 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
1931 | mmc_retune_needed(host: host->mmc); |
1932 | |
1933 | imx_data->actual_clock = host->mmc->actual_clock; |
1934 | esdhc_pltfm_set_clock(host, clock: 0); |
1935 | clk_disable_unprepare(clk: imx_data->clk_per); |
1936 | clk_disable_unprepare(clk: imx_data->clk_ipg); |
1937 | clk_disable_unprepare(clk: imx_data->clk_ahb); |
1938 | |
1939 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1940 | cpu_latency_qos_remove_request(req: &imx_data->pm_qos_req); |
1941 | |
1942 | return ret; |
1943 | } |
1944 | |
1945 | static int sdhci_esdhc_runtime_resume(struct device *dev) |
1946 | { |
1947 | struct sdhci_host *host = dev_get_drvdata(dev); |
1948 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1949 | struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(host: pltfm_host); |
1950 | int err; |
1951 | |
1952 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1953 | cpu_latency_qos_add_request(req: &imx_data->pm_qos_req, value: 0); |
1954 | |
1955 | if (imx_data->socdata->flags & ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME) |
1956 | clk_set_rate(clk: imx_data->clk_per, rate: pltfm_host->clock); |
1957 | |
1958 | err = clk_prepare_enable(clk: imx_data->clk_ahb); |
1959 | if (err) |
1960 | goto remove_pm_qos_request; |
1961 | |
1962 | err = clk_prepare_enable(clk: imx_data->clk_per); |
1963 | if (err) |
1964 | goto disable_ahb_clk; |
1965 | |
1966 | err = clk_prepare_enable(clk: imx_data->clk_ipg); |
1967 | if (err) |
1968 | goto disable_per_clk; |
1969 | |
1970 | esdhc_pltfm_set_clock(host, clock: imx_data->actual_clock); |
1971 | |
1972 | err = sdhci_runtime_resume_host(host, soft_reset: 0); |
1973 | if (err) |
1974 | goto disable_ipg_clk; |
1975 | |
1976 | if (host->mmc->caps2 & MMC_CAP2_CQE) |
1977 | err = cqhci_resume(mmc: host->mmc); |
1978 | |
1979 | return err; |
1980 | |
1981 | disable_ipg_clk: |
1982 | clk_disable_unprepare(clk: imx_data->clk_ipg); |
1983 | disable_per_clk: |
1984 | clk_disable_unprepare(clk: imx_data->clk_per); |
1985 | disable_ahb_clk: |
1986 | clk_disable_unprepare(clk: imx_data->clk_ahb); |
1987 | remove_pm_qos_request: |
1988 | if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS) |
1989 | cpu_latency_qos_remove_request(req: &imx_data->pm_qos_req); |
1990 | return err; |
1991 | } |
1992 | #endif |
1993 | |
1994 | static const struct dev_pm_ops sdhci_esdhc_pmops = { |
1995 | SET_SYSTEM_SLEEP_PM_OPS(sdhci_esdhc_suspend, sdhci_esdhc_resume) |
1996 | SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend, |
1997 | sdhci_esdhc_runtime_resume, NULL) |
1998 | }; |
1999 | |
2000 | static struct platform_driver sdhci_esdhc_imx_driver = { |
2001 | .driver = { |
2002 | .name = "sdhci-esdhc-imx" , |
2003 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
2004 | .of_match_table = imx_esdhc_dt_ids, |
2005 | .pm = &sdhci_esdhc_pmops, |
2006 | }, |
2007 | .probe = sdhci_esdhc_imx_probe, |
2008 | .remove_new = sdhci_esdhc_imx_remove, |
2009 | }; |
2010 | |
2011 | module_platform_driver(sdhci_esdhc_imx_driver); |
2012 | |
2013 | MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC" ); |
2014 | MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>" ); |
2015 | MODULE_LICENSE("GPL v2" ); |
2016 | |