2 * OpenFirmware bindings for Secure Digital Host Controller Interface.
4 * Copyright (c) 2007 Freescale Semiconductor, Inc.
5 * Copyright (c) 2009 MontaVista Software, Inc.
7 * Authors: Xiaobo Xie <X.Xie@freescale.com>
8 * Anton Vorontsov <avorontsov@ru.mvista.com>
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.
16 #include <linux/module.h>
17 #include <linux/init.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
22 #include <linux/of_platform.h>
23 #include <linux/mmc/host.h>
26 struct sdhci_of_data
{
31 struct sdhci_of_host
{
37 * Ops and quirks for the Freescale eSDHC controller.
40 #define ESDHC_DMA_SYSCTL 0x40c
41 #define ESDHC_DMA_SNOOP 0x00000040
43 #define ESDHC_SYSTEM_CONTROL 0x2c
44 #define ESDHC_CLOCK_MASK 0x0000fff0
45 #define ESDHC_PREDIV_SHIFT 8
46 #define ESDHC_DIVIDER_SHIFT 4
47 #define ESDHC_CLOCK_PEREN 0x00000004
48 #define ESDHC_CLOCK_HCKEN 0x00000002
49 #define ESDHC_CLOCK_IPGEN 0x00000001
51 static u32
esdhc_readl(struct sdhci_host
*host
, int reg
)
53 return in_be32(host
->ioaddr
+ reg
);
56 static u16
esdhc_readw(struct sdhci_host
*host
, int reg
)
58 return in_be16(host
->ioaddr
+ (reg
^ 0x2));
61 static u8
esdhc_readb(struct sdhci_host
*host
, int reg
)
63 return in_8(host
->ioaddr
+ (reg
^ 0x3));
66 static void esdhc_writel(struct sdhci_host
*host
, u32 val
, int reg
)
68 out_be32(host
->ioaddr
+ reg
, val
);
71 static void esdhc_writew(struct sdhci_host
*host
, u16 val
, int reg
)
73 struct sdhci_of_host
*of_host
= sdhci_priv(host
);
74 int base
= reg
& ~0x3;
75 int shift
= (reg
& 0x2) * 8;
78 case SDHCI_TRANSFER_MODE
:
80 * Postpone this write, we must do it together with a
81 * command write that is down below.
83 of_host
->xfer_mode_shadow
= val
;
86 esdhc_writel(host
, val
<< 16 | of_host
->xfer_mode_shadow
,
89 case SDHCI_BLOCK_SIZE
:
91 * Two last DMA bits are reserved, and first one is used for
92 * non-standard blksz of 4096 bytes that we don't support
93 * yet. So clear the DMA boundary bits.
95 val
&= ~SDHCI_MAKE_BLKSZ(0x7, 0);
98 clrsetbits_be32(host
->ioaddr
+ base
, 0xffff << shift
, val
<< shift
);
101 static void esdhc_writeb(struct sdhci_host
*host
, u8 val
, int reg
)
103 int base
= reg
& ~0x3;
104 int shift
= (reg
& 0x3) * 8;
106 clrsetbits_be32(host
->ioaddr
+ base
, 0xff << shift
, val
<< shift
);
109 static void esdhc_set_clock(struct sdhci_host
*host
, unsigned int clock
)
114 clrbits32(host
->ioaddr
+ ESDHC_SYSTEM_CONTROL
, ESDHC_CLOCK_IPGEN
|
115 ESDHC_CLOCK_HCKEN
| ESDHC_CLOCK_PEREN
| ESDHC_CLOCK_MASK
);
120 if (host
->max_clk
/ 16 > clock
) {
121 for (; pre_div
< 256; pre_div
*= 2) {
122 if (host
->max_clk
/ pre_div
< clock
* 16)
127 for (div
= 1; div
<= 16; div
++) {
128 if (host
->max_clk
/ (div
* pre_div
) <= clock
)
134 setbits32(host
->ioaddr
+ ESDHC_SYSTEM_CONTROL
, ESDHC_CLOCK_IPGEN
|
135 ESDHC_CLOCK_HCKEN
| ESDHC_CLOCK_PEREN
|
136 div
<< ESDHC_DIVIDER_SHIFT
| pre_div
<< ESDHC_PREDIV_SHIFT
);
142 static int esdhc_enable_dma(struct sdhci_host
*host
)
144 setbits32(host
->ioaddr
+ ESDHC_DMA_SYSCTL
, ESDHC_DMA_SNOOP
);
148 static unsigned int esdhc_get_max_clock(struct sdhci_host
*host
)
150 struct sdhci_of_host
*of_host
= sdhci_priv(host
);
152 return of_host
->clock
;
155 static unsigned int esdhc_get_timeout_clock(struct sdhci_host
*host
)
157 struct sdhci_of_host
*of_host
= sdhci_priv(host
);
159 return of_host
->clock
/ 1000;
162 static struct sdhci_of_data sdhci_esdhc
= {
163 .quirks
= SDHCI_QUIRK_FORCE_BLK_SZ_2048
|
164 SDHCI_QUIRK_BROKEN_CARD_DETECTION
|
165 SDHCI_QUIRK_INVERTED_WRITE_PROTECT
|
166 SDHCI_QUIRK_NO_BUSY_IRQ
|
167 SDHCI_QUIRK_NONSTANDARD_CLOCK
|
168 SDHCI_QUIRK_PIO_NEEDS_DELAY
|
169 SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET
|
170 SDHCI_QUIRK_NO_CARD_NO_RESET
,
172 .readl
= esdhc_readl
,
173 .readw
= esdhc_readw
,
174 .readb
= esdhc_readb
,
175 .writel
= esdhc_writel
,
176 .writew
= esdhc_writew
,
177 .writeb
= esdhc_writeb
,
178 .set_clock
= esdhc_set_clock
,
179 .enable_dma
= esdhc_enable_dma
,
180 .get_max_clock
= esdhc_get_max_clock
,
181 .get_timeout_clock
= esdhc_get_timeout_clock
,
187 static int sdhci_of_suspend(struct of_device
*ofdev
, pm_message_t state
)
189 struct sdhci_host
*host
= dev_get_drvdata(&ofdev
->dev
);
191 return mmc_suspend_host(host
->mmc
, state
);
194 static int sdhci_of_resume(struct of_device
*ofdev
)
196 struct sdhci_host
*host
= dev_get_drvdata(&ofdev
->dev
);
198 return mmc_resume_host(host
->mmc
);
203 #define sdhci_of_suspend NULL
204 #define sdhci_of_resume NULL
208 static int __devinit
sdhci_of_probe(struct of_device
*ofdev
,
209 const struct of_device_id
*match
)
211 struct device_node
*np
= ofdev
->node
;
212 struct sdhci_of_data
*sdhci_of_data
= match
->data
;
213 struct sdhci_host
*host
;
214 struct sdhci_of_host
*of_host
;
219 if (!of_device_is_available(np
))
222 host
= sdhci_alloc_host(&ofdev
->dev
, sizeof(*of_host
));
226 of_host
= sdhci_priv(host
);
227 dev_set_drvdata(&ofdev
->dev
, host
);
229 host
->ioaddr
= of_iomap(np
, 0);
235 host
->irq
= irq_of_parse_and_map(np
, 0);
241 host
->hw_name
= dev_name(&ofdev
->dev
);
243 host
->quirks
= sdhci_of_data
->quirks
;
244 host
->ops
= &sdhci_of_data
->ops
;
247 clk
= of_get_property(np
, "clock-frequency", &size
);
248 if (clk
&& size
== sizeof(*clk
) && *clk
)
249 of_host
->clock
= *clk
;
251 ret
= sdhci_add_host(host
);
258 irq_dispose_mapping(host
->irq
);
260 iounmap(host
->ioaddr
);
262 sdhci_free_host(host
);
266 static int __devexit
sdhci_of_remove(struct of_device
*ofdev
)
268 struct sdhci_host
*host
= dev_get_drvdata(&ofdev
->dev
);
270 sdhci_remove_host(host
, 0);
271 sdhci_free_host(host
);
272 irq_dispose_mapping(host
->irq
);
273 iounmap(host
->ioaddr
);
277 static const struct of_device_id sdhci_of_match
[] = {
278 { .compatible
= "fsl,mpc8379-esdhc", .data
= &sdhci_esdhc
, },
279 { .compatible
= "fsl,mpc8536-esdhc", .data
= &sdhci_esdhc
, },
280 { .compatible
= "generic-sdhci", },
283 MODULE_DEVICE_TABLE(of
, sdhci_of_match
);
285 static struct of_platform_driver sdhci_of_driver
= {
286 .driver
.name
= "sdhci-of",
287 .match_table
= sdhci_of_match
,
288 .probe
= sdhci_of_probe
,
289 .remove
= __devexit_p(sdhci_of_remove
),
290 .suspend
= sdhci_of_suspend
,
291 .resume
= sdhci_of_resume
,
294 static int __init
sdhci_of_init(void)
296 return of_register_platform_driver(&sdhci_of_driver
);
298 module_init(sdhci_of_init
);
300 static void __exit
sdhci_of_exit(void)
302 of_unregister_platform_driver(&sdhci_of_driver
);
304 module_exit(sdhci_of_exit
);
306 MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
307 MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
308 "Anton Vorontsov <avorontsov@ru.mvista.com>");
309 MODULE_LICENSE("GPL");