blob: 7b9282b6eac9c91bdde1d2df2c208818d34c3487 [file] [log] [blame]
Albert Herranz7657c3a2009-12-17 15:27:20 -08001/*
2 * Freescale eSDHC controller driver.
3 *
Jerry Huangf060bc92012-02-14 14:05:37 +08004 * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
Albert Herranz7657c3a2009-12-17 15:27:20 -08005 * Copyright (c) 2009 MontaVista Software, Inc.
6 *
7 * Authors: Xiaobo Xie <X.Xie@freescale.com>
8 * Anton Vorontsov <avorontsov@ru.mvista.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
14 */
15
Oded Gabbay66b50a02013-06-27 12:00:05 -040016#include <linux/err.h>
Albert Herranz7657c3a2009-12-17 15:27:20 -080017#include <linux/io.h>
Jerry Huangf060bc92012-02-14 14:05:37 +080018#include <linux/of.h>
Albert Herranz7657c3a2009-12-17 15:27:20 -080019#include <linux/delay.h>
Paul Gortmaker88b47672011-07-03 15:15:51 -040020#include <linux/module.h>
Albert Herranz7657c3a2009-12-17 15:27:20 -080021#include <linux/mmc/host.h>
Shawn Guo38576af2011-05-27 23:48:14 +080022#include "sdhci-pltfm.h"
Wolfram Sang80872e22010-10-15 12:21:03 +020023#include "sdhci-esdhc.h"
Albert Herranz7657c3a2009-12-17 15:27:20 -080024
Jerry Huang137ccd42012-03-08 11:25:02 +080025#define VENDOR_V_22 0x12
Haijun Zhanga4071fb2012-12-04 10:41:28 +080026#define VENDOR_V_23 0x13
yangbo luf4932cf2015-10-08 18:36:36 +080027
28struct sdhci_esdhc {
29 u8 vendor_ver;
30 u8 spec_ver;
31};
32
33/**
34 * esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
35 * to make it compatible with SD spec.
36 *
37 * @host: pointer to sdhci_host
38 * @spec_reg: SD spec register address
39 * @value: 32bit eSDHC register value on spec_reg address
40 *
41 * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
42 * registers are 32 bits. There are differences in register size, register
43 * address, register function, bit position and function between eSDHC spec
44 * and SD spec.
45 *
46 * Return a fixed up register value
47 */
48static u32 esdhc_readl_fixup(struct sdhci_host *host,
49 int spec_reg, u32 value)
Jerry Huang137ccd42012-03-08 11:25:02 +080050{
yangbo luf4932cf2015-10-08 18:36:36 +080051 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
52 struct sdhci_esdhc *esdhc = pltfm_host->priv;
Jerry Huang137ccd42012-03-08 11:25:02 +080053 u32 ret;
54
Jerry Huang137ccd42012-03-08 11:25:02 +080055 /*
56 * The bit of ADMA flag in eSDHC is not compatible with standard
57 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
58 * supported by eSDHC.
59 * And for many FSL eSDHC controller, the reset value of field
yangbo luf4932cf2015-10-08 18:36:36 +080060 * SDHCI_CAN_DO_ADMA1 is 1, but some of them can't support ADMA,
Jerry Huang137ccd42012-03-08 11:25:02 +080061 * only these vendor version is greater than 2.2/0x12 support ADMA.
Jerry Huang137ccd42012-03-08 11:25:02 +080062 */
yangbo luf4932cf2015-10-08 18:36:36 +080063 if ((spec_reg == SDHCI_CAPABILITIES) && (value & SDHCI_CAN_DO_ADMA1)) {
64 if (esdhc->vendor_ver > VENDOR_V_22) {
65 ret = value | SDHCI_CAN_DO_ADMA2;
66 return ret;
67 }
Jerry Huang137ccd42012-03-08 11:25:02 +080068 }
yangbo luf4932cf2015-10-08 18:36:36 +080069 ret = value;
Jerry Huang137ccd42012-03-08 11:25:02 +080070 return ret;
71}
72
yangbo luf4932cf2015-10-08 18:36:36 +080073static u16 esdhc_readw_fixup(struct sdhci_host *host,
74 int spec_reg, u32 value)
Albert Herranz7657c3a2009-12-17 15:27:20 -080075{
76 u16 ret;
yangbo luf4932cf2015-10-08 18:36:36 +080077 int shift = (spec_reg & 0x2) * 8;
Albert Herranz7657c3a2009-12-17 15:27:20 -080078
yangbo luf4932cf2015-10-08 18:36:36 +080079 if (spec_reg == SDHCI_HOST_VERSION)
80 ret = value & 0xffff;
Albert Herranz7657c3a2009-12-17 15:27:20 -080081 else
yangbo luf4932cf2015-10-08 18:36:36 +080082 ret = (value >> shift) & 0xffff;
Xu leie51cbc92011-09-09 20:05:46 +080083 return ret;
84}
85
yangbo luf4932cf2015-10-08 18:36:36 +080086static u8 esdhc_readb_fixup(struct sdhci_host *host,
87 int spec_reg, u32 value)
Xu leie51cbc92011-09-09 20:05:46 +080088{
yangbo luf4932cf2015-10-08 18:36:36 +080089 u8 ret;
90 u8 dma_bits;
91 int shift = (spec_reg & 0x3) * 8;
92
93 ret = (value >> shift) & 0xff;
Roy Zangba8c4dc2012-01-13 15:02:01 +080094
95 /*
96 * "DMA select" locates at offset 0x28 in SD specification, but on
97 * P5020 or P3041, it locates at 0x29.
98 */
yangbo luf4932cf2015-10-08 18:36:36 +080099 if (spec_reg == SDHCI_HOST_CONTROL) {
Roy Zangba8c4dc2012-01-13 15:02:01 +0800100 /* DMA select is 22,23 bits in Protocol Control Register */
yangbo luf4932cf2015-10-08 18:36:36 +0800101 dma_bits = (value >> 5) & SDHCI_CTRL_DMA_MASK;
Roy Zangba8c4dc2012-01-13 15:02:01 +0800102 /* fixup the result */
103 ret &= ~SDHCI_CTRL_DMA_MASK;
104 ret |= dma_bits;
105 }
yangbo luf4932cf2015-10-08 18:36:36 +0800106 return ret;
107}
108
109/**
110 * esdhc_write*_fixup - Fixup the SD spec register value so that it could be
111 * written into eSDHC register.
112 *
113 * @host: pointer to sdhci_host
114 * @spec_reg: SD spec register address
115 * @value: 8/16/32bit SD spec register value that would be written
116 * @old_value: 32bit eSDHC register value on spec_reg address
117 *
118 * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
119 * registers are 32 bits. There are differences in register size, register
120 * address, register function, bit position and function between eSDHC spec
121 * and SD spec.
122 *
123 * Return a fixed up register value
124 */
125static u32 esdhc_writel_fixup(struct sdhci_host *host,
126 int spec_reg, u32 value, u32 old_value)
127{
128 u32 ret;
129
130 /*
131 * Enabling IRQSTATEN[BGESEN] is just to set IRQSTAT[BGE]
132 * when SYSCTL[RSTD] is set for some special operations.
133 * No any impact on other operation.
134 */
135 if (spec_reg == SDHCI_INT_ENABLE)
136 ret = value | SDHCI_INT_BLK_GAP;
137 else
138 ret = value;
Roy Zangba8c4dc2012-01-13 15:02:01 +0800139
Albert Herranz7657c3a2009-12-17 15:27:20 -0800140 return ret;
141}
142
yangbo luf4932cf2015-10-08 18:36:36 +0800143static u32 esdhc_writew_fixup(struct sdhci_host *host,
144 int spec_reg, u16 value, u32 old_value)
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800145{
yangbo luf4932cf2015-10-08 18:36:36 +0800146 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
147 int shift = (spec_reg & 0x2) * 8;
148 u32 ret;
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800149
yangbo luf4932cf2015-10-08 18:36:36 +0800150 switch (spec_reg) {
151 case SDHCI_TRANSFER_MODE:
152 /*
153 * Postpone this write, we must do it together with a
154 * command write that is down below. Return old value.
155 */
156 pltfm_host->xfer_mode_shadow = value;
157 return old_value;
158 case SDHCI_COMMAND:
159 ret = (value << 16) | pltfm_host->xfer_mode_shadow;
160 return ret;
161 }
162
163 ret = old_value & (~(0xffff << shift));
164 ret |= (value << shift);
165
166 if (spec_reg == SDHCI_BLOCK_SIZE) {
Albert Herranz7657c3a2009-12-17 15:27:20 -0800167 /*
168 * Two last DMA bits are reserved, and first one is used for
169 * non-standard blksz of 4096 bytes that we don't support
170 * yet. So clear the DMA boundary bits.
171 */
yangbo luf4932cf2015-10-08 18:36:36 +0800172 ret &= (~SDHCI_MAKE_BLKSZ(0x7, 0));
Albert Herranz7657c3a2009-12-17 15:27:20 -0800173 }
yangbo luf4932cf2015-10-08 18:36:36 +0800174 return ret;
Albert Herranz7657c3a2009-12-17 15:27:20 -0800175}
176
yangbo luf4932cf2015-10-08 18:36:36 +0800177static u32 esdhc_writeb_fixup(struct sdhci_host *host,
178 int spec_reg, u8 value, u32 old_value)
Albert Herranz7657c3a2009-12-17 15:27:20 -0800179{
yangbo luf4932cf2015-10-08 18:36:36 +0800180 u32 ret;
181 u32 dma_bits;
182 u8 tmp;
183 int shift = (spec_reg & 0x3) * 8;
184
Roy Zangba8c4dc2012-01-13 15:02:01 +0800185 /*
186 * "DMA select" location is offset 0x28 in SD specification, but on
187 * P5020 or P3041, it's located at 0x29.
188 */
yangbo luf4932cf2015-10-08 18:36:36 +0800189 if (spec_reg == SDHCI_HOST_CONTROL) {
Oded Gabbaydcaff042013-07-05 12:48:35 -0400190 /*
191 * If host control register is not standard, exit
192 * this function
193 */
194 if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
yangbo luf4932cf2015-10-08 18:36:36 +0800195 return old_value;
Oded Gabbaydcaff042013-07-05 12:48:35 -0400196
Roy Zangba8c4dc2012-01-13 15:02:01 +0800197 /* DMA select is 22,23 bits in Protocol Control Register */
yangbo luf4932cf2015-10-08 18:36:36 +0800198 dma_bits = (value & SDHCI_CTRL_DMA_MASK) << 5;
199 ret = (old_value & (~(SDHCI_CTRL_DMA_MASK << 5))) | dma_bits;
200 tmp = (value & (~SDHCI_CTRL_DMA_MASK)) |
201 (old_value & SDHCI_CTRL_DMA_MASK);
202 ret = (ret & (~0xff)) | tmp;
203
204 /* Prevent SDHCI core from writing reserved bits (e.g. HISPD) */
205 ret &= ~ESDHC_HOST_CONTROL_RES;
206 return ret;
Roy Zangba8c4dc2012-01-13 15:02:01 +0800207 }
208
yangbo luf4932cf2015-10-08 18:36:36 +0800209 ret = (old_value & (~(0xff << shift))) | (value << shift);
210 return ret;
211}
212
213static u32 esdhc_be_readl(struct sdhci_host *host, int reg)
214{
215 u32 ret;
216 u32 value;
217
218 value = ioread32be(host->ioaddr + reg);
219 ret = esdhc_readl_fixup(host, reg, value);
220
221 return ret;
222}
223
224static u32 esdhc_le_readl(struct sdhci_host *host, int reg)
225{
226 u32 ret;
227 u32 value;
228
229 value = ioread32(host->ioaddr + reg);
230 ret = esdhc_readl_fixup(host, reg, value);
231
232 return ret;
233}
234
235static u16 esdhc_be_readw(struct sdhci_host *host, int reg)
236{
237 u16 ret;
238 u32 value;
239 int base = reg & ~0x3;
240
241 value = ioread32be(host->ioaddr + base);
242 ret = esdhc_readw_fixup(host, reg, value);
243 return ret;
244}
245
246static u16 esdhc_le_readw(struct sdhci_host *host, int reg)
247{
248 u16 ret;
249 u32 value;
250 int base = reg & ~0x3;
251
252 value = ioread32(host->ioaddr + base);
253 ret = esdhc_readw_fixup(host, reg, value);
254 return ret;
255}
256
257static u8 esdhc_be_readb(struct sdhci_host *host, int reg)
258{
259 u8 ret;
260 u32 value;
261 int base = reg & ~0x3;
262
263 value = ioread32be(host->ioaddr + base);
264 ret = esdhc_readb_fixup(host, reg, value);
265 return ret;
266}
267
268static u8 esdhc_le_readb(struct sdhci_host *host, int reg)
269{
270 u8 ret;
271 u32 value;
272 int base = reg & ~0x3;
273
274 value = ioread32(host->ioaddr + base);
275 ret = esdhc_readb_fixup(host, reg, value);
276 return ret;
277}
278
279static void esdhc_be_writel(struct sdhci_host *host, u32 val, int reg)
280{
281 u32 value;
282
283 value = esdhc_writel_fixup(host, reg, val, 0);
284 iowrite32be(value, host->ioaddr + reg);
285}
286
287static void esdhc_le_writel(struct sdhci_host *host, u32 val, int reg)
288{
289 u32 value;
290
291 value = esdhc_writel_fixup(host, reg, val, 0);
292 iowrite32(value, host->ioaddr + reg);
293}
294
295static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg)
296{
297 int base = reg & ~0x3;
298 u32 value;
299 u32 ret;
300
301 value = ioread32be(host->ioaddr + base);
302 ret = esdhc_writew_fixup(host, reg, val, value);
303 if (reg != SDHCI_TRANSFER_MODE)
304 iowrite32be(ret, host->ioaddr + base);
305}
306
307static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg)
308{
309 int base = reg & ~0x3;
310 u32 value;
311 u32 ret;
312
313 value = ioread32(host->ioaddr + base);
314 ret = esdhc_writew_fixup(host, reg, val, value);
315 if (reg != SDHCI_TRANSFER_MODE)
316 iowrite32(ret, host->ioaddr + base);
317}
318
319static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg)
320{
321 int base = reg & ~0x3;
322 u32 value;
323 u32 ret;
324
325 value = ioread32be(host->ioaddr + base);
326 ret = esdhc_writeb_fixup(host, reg, val, value);
327 iowrite32be(ret, host->ioaddr + base);
328}
329
330static void esdhc_le_writeb(struct sdhci_host *host, u8 val, int reg)
331{
332 int base = reg & ~0x3;
333 u32 value;
334 u32 ret;
335
336 value = ioread32(host->ioaddr + base);
337 ret = esdhc_writeb_fixup(host, reg, val, value);
338 iowrite32(ret, host->ioaddr + base);
Albert Herranz7657c3a2009-12-17 15:27:20 -0800339}
340
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800341/*
342 * For Abort or Suspend after Stop at Block Gap, ignore the ADMA
343 * error(IRQSTAT[ADMAE]) if both Transfer Complete(IRQSTAT[TC])
344 * and Block Gap Event(IRQSTAT[BGE]) are also set.
345 * For Continue, apply soft reset for data(SYSCTL[RSTD]);
346 * and re-issue the entire read transaction from beginning.
347 */
yangbo luf4932cf2015-10-08 18:36:36 +0800348static void esdhc_of_adma_workaround(struct sdhci_host *host, u32 intmask)
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800349{
yangbo luf4932cf2015-10-08 18:36:36 +0800350 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
351 struct sdhci_esdhc *esdhc = pltfm_host->priv;
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800352 bool applicable;
353 dma_addr_t dmastart;
354 dma_addr_t dmanow;
355
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800356 applicable = (intmask & SDHCI_INT_DATA_END) &&
yangbo luf4932cf2015-10-08 18:36:36 +0800357 (intmask & SDHCI_INT_BLK_GAP) &&
358 (esdhc->vendor_ver == VENDOR_V_23);
Haijun Zhanga4071fb2012-12-04 10:41:28 +0800359 if (!applicable)
360 return;
361
362 host->data->error = 0;
363 dmastart = sg_dma_address(host->data->sg);
364 dmanow = dmastart + host->data->bytes_xfered;
365 /*
366 * Force update to the next DMA block boundary.
367 */
368 dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
369 SDHCI_DEFAULT_BOUNDARY_SIZE;
370 host->data->bytes_xfered = dmanow - dmastart;
371 sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
372}
373
Wolfram Sang80872e22010-10-15 12:21:03 +0200374static int esdhc_of_enable_dma(struct sdhci_host *host)
Albert Herranz7657c3a2009-12-17 15:27:20 -0800375{
yangbo luf4932cf2015-10-08 18:36:36 +0800376 u32 value;
377
378 value = sdhci_readl(host, ESDHC_DMA_SYSCTL);
379 value |= ESDHC_DMA_SNOOP;
380 sdhci_writel(host, value, ESDHC_DMA_SYSCTL);
Albert Herranz7657c3a2009-12-17 15:27:20 -0800381 return 0;
382}
383
Wolfram Sang80872e22010-10-15 12:21:03 +0200384static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
Albert Herranz7657c3a2009-12-17 15:27:20 -0800385{
Shawn Guoe3071482011-07-20 17:13:36 -0400386 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
Albert Herranz7657c3a2009-12-17 15:27:20 -0800387
Shawn Guoe3071482011-07-20 17:13:36 -0400388 return pltfm_host->clock;
Albert Herranz7657c3a2009-12-17 15:27:20 -0800389}
390
Wolfram Sang80872e22010-10-15 12:21:03 +0200391static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
Albert Herranz7657c3a2009-12-17 15:27:20 -0800392{
Shawn Guoe3071482011-07-20 17:13:36 -0400393 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
Albert Herranz7657c3a2009-12-17 15:27:20 -0800394
Shawn Guoe3071482011-07-20 17:13:36 -0400395 return pltfm_host->clock / 256 / 16;
Albert Herranz7657c3a2009-12-17 15:27:20 -0800396}
397
Jerry Huangf060bc92012-02-14 14:05:37 +0800398static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
399{
yangbo luf4932cf2015-10-08 18:36:36 +0800400 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
401 struct sdhci_esdhc *esdhc = pltfm_host->priv;
Joakim Tjernlundbd455022015-04-20 23:12:13 +0200402 int pre_div = 1;
Dong Aishengd31fc002013-09-13 19:11:32 +0800403 int div = 1;
404 u32 temp;
405
Russell King1650d0c2014-04-25 12:58:50 +0100406 host->mmc->actual_clock = 0;
407
Dong Aishengd31fc002013-09-13 19:11:32 +0800408 if (clock == 0)
Russell King373073e2014-04-25 12:58:45 +0100409 return;
Dong Aishengd31fc002013-09-13 19:11:32 +0800410
Yangbo Lu77bd2f62015-08-11 10:53:34 +0800411 /* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
yangbo luf4932cf2015-10-08 18:36:36 +0800412 if (esdhc->vendor_ver < VENDOR_V_23)
Yangbo Lu77bd2f62015-08-11 10:53:34 +0800413 pre_div = 2;
414
Jerry Huangf060bc92012-02-14 14:05:37 +0800415 /* Workaround to reduce the clock frequency for p1010 esdhc */
416 if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
417 if (clock > 20000000)
418 clock -= 5000000;
419 if (clock > 40000000)
420 clock -= 5000000;
421 }
422
Dong Aishengd31fc002013-09-13 19:11:32 +0800423 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
424 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
425 | ESDHC_CLOCK_MASK);
426 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
427
428 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
429 pre_div *= 2;
430
431 while (host->max_clk / pre_div / div > clock && div < 16)
432 div++;
433
434 dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
Dong Aishenge76b8552013-09-13 19:11:37 +0800435 clock, host->max_clk / pre_div / div);
Joakim Tjernlundbd455022015-04-20 23:12:13 +0200436 host->mmc->actual_clock = host->max_clk / pre_div / div;
Dong Aishengd31fc002013-09-13 19:11:32 +0800437 pre_div >>= 1;
438 div--;
439
440 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
441 temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
442 | (div << ESDHC_DIVIDER_SHIFT)
443 | (pre_div << ESDHC_PREDIV_SHIFT));
444 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
445 mdelay(1);
Jerry Huangf060bc92012-02-14 14:05:37 +0800446}
447
Russell King2317f562014-04-25 12:57:07 +0100448static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
Oded Gabbay66b50a02013-06-27 12:00:05 -0400449{
450 u32 ctrl;
451
yangbo luf4932cf2015-10-08 18:36:36 +0800452 ctrl = sdhci_readl(host, ESDHC_PROCTL);
453 ctrl &= (~ESDHC_CTRL_BUSWIDTH_MASK);
Oded Gabbay66b50a02013-06-27 12:00:05 -0400454 switch (width) {
455 case MMC_BUS_WIDTH_8:
yangbo luf4932cf2015-10-08 18:36:36 +0800456 ctrl |= ESDHC_CTRL_8BITBUS;
Oded Gabbay66b50a02013-06-27 12:00:05 -0400457 break;
458
459 case MMC_BUS_WIDTH_4:
yangbo luf4932cf2015-10-08 18:36:36 +0800460 ctrl |= ESDHC_CTRL_4BITBUS;
Oded Gabbay66b50a02013-06-27 12:00:05 -0400461 break;
462
463 default:
Oded Gabbay66b50a02013-06-27 12:00:05 -0400464 break;
465 }
466
yangbo luf4932cf2015-10-08 18:36:36 +0800467 sdhci_writel(host, ctrl, ESDHC_PROCTL);
Oded Gabbay66b50a02013-06-27 12:00:05 -0400468}
469
Alessio Igor Bogani304f0a92014-12-09 09:40:38 +0100470static void esdhc_reset(struct sdhci_host *host, u8 mask)
471{
472 sdhci_reset(host, mask);
473
474 sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
475 sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
476}
477
Russell King723f7922014-04-25 12:59:46 +0100478#ifdef CONFIG_PM
Russell King723f7922014-04-25 12:59:46 +0100479static u32 esdhc_proctl;
480static int esdhc_of_suspend(struct device *dev)
481{
482 struct sdhci_host *host = dev_get_drvdata(dev);
483
yangbo luf4932cf2015-10-08 18:36:36 +0800484 esdhc_proctl = sdhci_readl(host, SDHCI_HOST_CONTROL);
Russell King723f7922014-04-25 12:59:46 +0100485
486 return sdhci_suspend_host(host);
487}
488
Ulf Hansson06732b82014-05-23 10:36:44 +0200489static int esdhc_of_resume(struct device *dev)
Russell King723f7922014-04-25 12:59:46 +0100490{
491 struct sdhci_host *host = dev_get_drvdata(dev);
492 int ret = sdhci_resume_host(host);
493
494 if (ret == 0) {
495 /* Isn't this already done by sdhci_resume_host() ? --rmk */
496 esdhc_of_enable_dma(host);
yangbo luf4932cf2015-10-08 18:36:36 +0800497 sdhci_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
Russell King723f7922014-04-25 12:59:46 +0100498 }
Russell King723f7922014-04-25 12:59:46 +0100499 return ret;
500}
501
502static const struct dev_pm_ops esdhc_pmops = {
Ulf Hansson06732b82014-05-23 10:36:44 +0200503 .suspend = esdhc_of_suspend,
504 .resume = esdhc_of_resume,
Russell King723f7922014-04-25 12:59:46 +0100505};
506#define ESDHC_PMOPS (&esdhc_pmops)
507#else
508#define ESDHC_PMOPS NULL
509#endif
510
yangbo luf4932cf2015-10-08 18:36:36 +0800511static const struct sdhci_ops sdhci_esdhc_be_ops = {
512 .read_l = esdhc_be_readl,
513 .read_w = esdhc_be_readw,
514 .read_b = esdhc_be_readb,
515 .write_l = esdhc_be_writel,
516 .write_w = esdhc_be_writew,
517 .write_b = esdhc_be_writeb,
518 .set_clock = esdhc_of_set_clock,
519 .enable_dma = esdhc_of_enable_dma,
520 .get_max_clock = esdhc_of_get_max_clock,
521 .get_min_clock = esdhc_of_get_min_clock,
522 .adma_workaround = esdhc_of_adma_workaround,
523 .set_bus_width = esdhc_pltfm_set_bus_width,
524 .reset = esdhc_reset,
525 .set_uhs_signaling = sdhci_set_uhs_signaling,
526};
527
528static const struct sdhci_ops sdhci_esdhc_le_ops = {
529 .read_l = esdhc_le_readl,
530 .read_w = esdhc_le_readw,
531 .read_b = esdhc_le_readb,
532 .write_l = esdhc_le_writel,
533 .write_w = esdhc_le_writew,
534 .write_b = esdhc_le_writeb,
535 .set_clock = esdhc_of_set_clock,
536 .enable_dma = esdhc_of_enable_dma,
537 .get_max_clock = esdhc_of_get_max_clock,
538 .get_min_clock = esdhc_of_get_min_clock,
539 .adma_workaround = esdhc_of_adma_workaround,
540 .set_bus_width = esdhc_pltfm_set_bus_width,
541 .reset = esdhc_reset,
542 .set_uhs_signaling = sdhci_set_uhs_signaling,
543};
544
545static const struct sdhci_pltfm_data sdhci_esdhc_be_pdata = {
Richard Zhue481e452011-03-21 13:22:13 +0800546 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
Jerry Huang137ccd42012-03-08 11:25:02 +0800547 | SDHCI_QUIRK_NO_CARD_NO_RESET
548 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
yangbo luf4932cf2015-10-08 18:36:36 +0800549 .ops = &sdhci_esdhc_be_ops,
Albert Herranz7657c3a2009-12-17 15:27:20 -0800550};
Shawn Guo38576af2011-05-27 23:48:14 +0800551
yangbo luf4932cf2015-10-08 18:36:36 +0800552static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = {
553 .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
554 | SDHCI_QUIRK_NO_CARD_NO_RESET
555 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
556 .ops = &sdhci_esdhc_le_ops,
557};
558
559static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
560{
561 struct sdhci_pltfm_host *pltfm_host;
562 struct sdhci_esdhc *esdhc;
563 u16 host_ver;
564
565 pltfm_host = sdhci_priv(host);
566 esdhc = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_esdhc),
567 GFP_KERNEL);
568
569 host_ver = sdhci_readw(host, SDHCI_HOST_VERSION);
570 esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
571 SDHCI_VENDOR_VER_SHIFT;
572 esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
573
574 pltfm_host->priv = esdhc;
575}
576
Bill Pembertonc3be1ef2012-11-19 13:23:06 -0500577static int sdhci_esdhc_probe(struct platform_device *pdev)
Shawn Guo38576af2011-05-27 23:48:14 +0800578{
Oded Gabbay66b50a02013-06-27 12:00:05 -0400579 struct sdhci_host *host;
Oded Gabbaydcaff042013-07-05 12:48:35 -0400580 struct device_node *np;
Oded Gabbay66b50a02013-06-27 12:00:05 -0400581 int ret;
582
yangbo luf4932cf2015-10-08 18:36:36 +0800583 np = pdev->dev.of_node;
584
585 if (of_get_property(np, "little-endian", NULL))
586 host = sdhci_pltfm_init(pdev, &sdhci_esdhc_le_pdata, 0);
587 else
588 host = sdhci_pltfm_init(pdev, &sdhci_esdhc_be_pdata, 0);
589
Oded Gabbay66b50a02013-06-27 12:00:05 -0400590 if (IS_ERR(host))
591 return PTR_ERR(host);
592
yangbo luf4932cf2015-10-08 18:36:36 +0800593 esdhc_init(pdev, host);
594
Oded Gabbay66b50a02013-06-27 12:00:05 -0400595 sdhci_get_of_property(pdev);
596
Yangbo Lu74fd5e32015-06-01 13:47:12 +0800597 if (of_device_is_compatible(np, "fsl,p5040-esdhc") ||
598 of_device_is_compatible(np, "fsl,p5020-esdhc") ||
599 of_device_is_compatible(np, "fsl,p4080-esdhc") ||
600 of_device_is_compatible(np, "fsl,p1020-esdhc") ||
Yangbo Luaaa58d02015-09-16 14:36:10 +0800601 of_device_is_compatible(np, "fsl,t1040-esdhc") ||
602 of_device_is_compatible(np, "fsl,ls1021a-esdhc"))
Yangbo Lu74fd5e32015-06-01 13:47:12 +0800603 host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
604
yangbo lua22950c2015-10-08 18:36:57 +0800605 if (of_device_is_compatible(np, "fsl,ls1021a-esdhc"))
606 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
607
Oded Gabbaydcaff042013-07-05 12:48:35 -0400608 if (of_device_is_compatible(np, "fsl,p2020-esdhc")) {
609 /*
610 * Freescale messed up with P2020 as it has a non-standard
611 * host control register
612 */
613 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL;
614 }
615
Oded Gabbay66b50a02013-06-27 12:00:05 -0400616 /* call to generic mmc_of_parse to support additional capabilities */
Ulf Hanssonf0991402014-12-18 10:41:41 +0100617 ret = mmc_of_parse(host->mmc);
618 if (ret)
619 goto err;
620
Haijun Zhang490104a2013-08-26 09:19:24 +0800621 mmc_of_parse_voltage(np, &host->ocr_mask);
Oded Gabbay66b50a02013-06-27 12:00:05 -0400622
623 ret = sdhci_add_host(host);
624 if (ret)
Ulf Hanssonf0991402014-12-18 10:41:41 +0100625 goto err;
Oded Gabbay66b50a02013-06-27 12:00:05 -0400626
Ulf Hanssonf0991402014-12-18 10:41:41 +0100627 return 0;
628 err:
629 sdhci_pltfm_free(pdev);
Oded Gabbay66b50a02013-06-27 12:00:05 -0400630 return ret;
Shawn Guo38576af2011-05-27 23:48:14 +0800631}
632
Shawn Guo38576af2011-05-27 23:48:14 +0800633static const struct of_device_id sdhci_esdhc_of_match[] = {
634 { .compatible = "fsl,mpc8379-esdhc" },
635 { .compatible = "fsl,mpc8536-esdhc" },
636 { .compatible = "fsl,esdhc" },
637 { }
638};
639MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);
640
641static struct platform_driver sdhci_esdhc_driver = {
642 .driver = {
643 .name = "sdhci-esdhc",
Shawn Guo38576af2011-05-27 23:48:14 +0800644 .of_match_table = sdhci_esdhc_of_match,
Russell King723f7922014-04-25 12:59:46 +0100645 .pm = ESDHC_PMOPS,
Shawn Guo38576af2011-05-27 23:48:14 +0800646 },
647 .probe = sdhci_esdhc_probe,
Kevin Haocaebcae2015-02-27 15:47:31 +0800648 .remove = sdhci_pltfm_unregister,
Shawn Guo38576af2011-05-27 23:48:14 +0800649};
650
Axel Lind1f81a62011-11-26 12:55:43 +0800651module_platform_driver(sdhci_esdhc_driver);
Shawn Guo38576af2011-05-27 23:48:14 +0800652
653MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC");
654MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
655 "Anton Vorontsov <avorontsov@ru.mvista.com>");
656MODULE_LICENSE("GPL v2");