2 * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include <sys/param.h>
27 #include <sys/systm.h>
30 #include <sys/kernel.h>
32 #include <sys/module.h>
33 #include <sys/mutex.h>
34 #include <sys/resource.h>
36 #include <sys/sysctl.h>
37 #include <sys/taskqueue.h>
40 #include <bus/pci/pcireg.h>
41 #include <bus/pci/pcivar.h>
44 #include <sys/resource.h>
45 #include <machine/stdarg.h>
47 #include <bus/mmc/bridge.h>
48 #include <bus/mmc/mmcreg.h>
49 #include <bus/mmc/mmcbrvar.h>
59 #define PCI_SDHCI_IFPIO 0x00
60 #define PCI_SDHCI_IFDMA 0x01
61 #define PCI_SDHCI_IFVENDOR 0x02
63 #define PCI_SLOT_INFO 0x40 /* 8 bits */
64 #define PCI_SLOT_INFO_SLOTS(x) (((x >> 4) & 7) + 1)
65 #define PCI_SLOT_INFO_FIRST_BAR(x) ((x) & 7)
68 * RICOH specific PCI registers
70 #define SDHC_PCI_MODE_KEY 0xf9
71 #define SDHC_PCI_MODE 0x150
72 #define SDHC_PCI_MODE_SD20 0x10
73 #define SDHC_PCI_BASE_FREQ_KEY 0xfc
74 #define SDHC_PCI_BASE_FREQ 0xe1
76 static const struct sdhci_device
{
82 { 0x08221180, 0xffff, "RICOH R5C822 SD",
83 SDHCI_QUIRK_FORCE_SDMA
},
84 { 0xe8221180, 0xffff, "RICOH R5CE822 SD",
85 SDHCI_QUIRK_FORCE_SDMA
|
86 SDHCI_QUIRK_LOWER_FREQUENCY
},
87 { 0xe8231180, 0xffff, "RICOH R5CE823 SD",
88 SDHCI_QUIRK_LOWER_FREQUENCY
},
89 { 0x8034104c, 0xffff, "TI XX21/XX11 SD",
90 SDHCI_QUIRK_FORCE_SDMA
},
91 { 0x05501524, 0xffff, "ENE CB712 SD",
92 SDHCI_QUIRK_BROKEN_TIMINGS
},
93 { 0x05511524, 0xffff, "ENE CB712 SD 2",
94 SDHCI_QUIRK_BROKEN_TIMINGS
},
95 { 0x07501524, 0xffff, "ENE CB714 SD",
96 SDHCI_QUIRK_RESET_ON_IOS
|
97 SDHCI_QUIRK_BROKEN_TIMINGS
},
98 { 0x07511524, 0xffff, "ENE CB714 SD 2",
99 SDHCI_QUIRK_RESET_ON_IOS
|
100 SDHCI_QUIRK_BROKEN_TIMINGS
},
101 { 0x410111ab, 0xffff, "Marvell CaFe SD",
102 SDHCI_QUIRK_INCR_TIMEOUT_CONTROL
},
103 { 0x2381197B, 0xffff, "JMicron JMB38X SD",
104 SDHCI_QUIRK_32BIT_DMA_SIZE
|
105 SDHCI_QUIRK_RESET_AFTER_REQUEST
},
106 { 0x16bc14e4, 0xffff, "Broadcom BCM577xx SDXC/MMC Card Reader",
107 SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC
},
112 struct sdhci_pci_softc
{
113 u_int quirks
; /* Chip specific quirks */
114 struct resource
*irq_res
; /* IRQ resource */
115 void *intrhand
; /* Interrupt handle */
117 int num_slots
; /* Number of slots on this controller */
118 struct sdhci_slot slots
[6];
119 struct resource
*mem_res
[6]; /* Memory resource */
120 uint8_t cfg_freq
; /* Saved mode */
121 uint8_t cfg_mode
; /* Saved frequency */
124 static int sdhci_enable_msi
= 1;
125 TUNABLE_INT("hw.sdhci_enable_msi", &sdhci_enable_msi
);
128 sdhci_pci_read_1(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
)
130 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
132 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
133 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
134 return bus_read_1(sc
->mem_res
[slot
->num
], off
);
138 sdhci_pci_write_1(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
, uint8_t val
)
140 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
142 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
143 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
144 bus_write_1(sc
->mem_res
[slot
->num
], off
, val
);
148 sdhci_pci_read_2(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
)
150 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
152 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
153 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
154 return bus_read_2(sc
->mem_res
[slot
->num
], off
);
158 sdhci_pci_write_2(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
, uint16_t val
)
160 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
162 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
163 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
164 bus_write_2(sc
->mem_res
[slot
->num
], off
, val
);
168 sdhci_pci_read_4(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
)
170 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
172 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
173 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
174 return bus_read_4(sc
->mem_res
[slot
->num
], off
);
178 sdhci_pci_write_4(device_t dev
, struct sdhci_slot
*slot
, bus_size_t off
, uint32_t val
)
180 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
182 bus_barrier(sc
->mem_res
[slot
->num
], 0, 0xFF,
183 BUS_SPACE_BARRIER_READ
| BUS_SPACE_BARRIER_WRITE
);
184 bus_write_4(sc
->mem_res
[slot
->num
], off
, val
);
188 sdhci_pci_read_multi_4(device_t dev
, struct sdhci_slot
*slot
,
189 bus_size_t off
, uint32_t *data
, bus_size_t count
)
191 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
193 bus_read_multi_stream_4(sc
->mem_res
[slot
->num
], off
, data
, count
);
197 sdhci_pci_write_multi_4(device_t dev
, struct sdhci_slot
*slot
,
198 bus_size_t off
, uint32_t *data
, bus_size_t count
)
200 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
202 bus_write_multi_stream_4(sc
->mem_res
[slot
->num
], off
, data
, count
);
205 static void sdhci_pci_intr(void *arg
);
208 sdhci_lower_frequency(device_t dev
)
210 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
214 * NB: for RICOH R5CE823, this changes the PCI device ID to 0xe822.
216 pci_write_config(dev
, SDHC_PCI_MODE_KEY
, 0xfc, 1);
217 sc
->cfg_mode
= pci_read_config(dev
, SDHC_PCI_MODE
, 1);
218 pci_write_config(dev
, SDHC_PCI_MODE
, SDHC_PCI_MODE_SD20
, 1);
219 pci_write_config(dev
, SDHC_PCI_MODE_KEY
, 0x00, 1);
222 * Some SD/MMC cards don't work with the default base
223 * clock frequency of 200 MHz. Lower it to 50 MHz.
225 pci_write_config(dev
, SDHC_PCI_BASE_FREQ_KEY
, 0x01, 1);
226 sc
->cfg_freq
= pci_read_config(dev
, SDHC_PCI_BASE_FREQ
, 1);
227 pci_write_config(dev
, SDHC_PCI_BASE_FREQ
, 50, 1);
228 pci_write_config(dev
, SDHC_PCI_BASE_FREQ_KEY
, 0x00, 1);
232 sdhci_restore_frequency(device_t dev
)
234 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
237 pci_write_config(dev
, SDHC_PCI_MODE_KEY
, 0xfc, 1);
238 pci_write_config(dev
, SDHC_PCI_MODE
, sc
->cfg_mode
, 1);
239 pci_write_config(dev
, SDHC_PCI_MODE_KEY
, 0x00, 1);
241 /* Restore frequency. */
242 pci_write_config(dev
, SDHC_PCI_BASE_FREQ_KEY
, 0x01, 1);
243 pci_write_config(dev
, SDHC_PCI_BASE_FREQ
, sc
->cfg_freq
, 1);
244 pci_write_config(dev
, SDHC_PCI_BASE_FREQ_KEY
, 0x00, 1);
248 sdhci_pci_probe(device_t dev
)
252 uint8_t class, subclass
;
255 model
= (uint32_t)pci_get_device(dev
) << 16;
256 model
|= (uint32_t)pci_get_vendor(dev
) & 0x0000ffff;
257 subvendor
= pci_get_subvendor(dev
);
258 class = pci_get_class(dev
);
259 subclass
= pci_get_subclass(dev
);
262 for (i
= 0; sdhci_devices
[i
].model
!= 0; i
++) {
263 if (sdhci_devices
[i
].model
== model
&&
264 (sdhci_devices
[i
].subvendor
== 0xffff ||
265 sdhci_devices
[i
].subvendor
== subvendor
)) {
266 device_set_desc(dev
, sdhci_devices
[i
].desc
);
267 result
= BUS_PROBE_DEFAULT
;
271 if (result
== ENXIO
&& class == PCIC_BASEPERIPH
&&
272 subclass
== PCIS_BASEPERIPH_SDHC
) {
273 device_set_desc(dev
, "Generic SD HCI");
274 result
= BUS_PROBE_GENERIC
;
281 sdhci_pci_attach(device_t dev
)
283 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
286 int bar
, err
, rid
, slots
, i
;
287 #if defined(__DragonFly__)
293 model
= (uint32_t)pci_get_device(dev
) << 16;
294 model
|= (uint32_t)pci_get_vendor(dev
) & 0x0000ffff;
295 subvendor
= pci_get_subvendor(dev
);
296 /* Apply chip specific quirks. */
297 for (i
= 0; sdhci_devices
[i
].model
!= 0; i
++) {
298 if (sdhci_devices
[i
].model
== model
&&
299 (sdhci_devices
[i
].subvendor
== 0xffff ||
300 sdhci_devices
[i
].subvendor
== subvendor
)) {
301 sc
->quirks
= sdhci_devices
[i
].quirks
;
305 /* Some controllers need to be bumped into the right mode. */
306 if (sc
->quirks
& SDHCI_QUIRK_LOWER_FREQUENCY
)
307 sdhci_lower_frequency(dev
);
308 /* Read slots info from PCI registers. */
309 slots
= pci_read_config(dev
, PCI_SLOT_INFO
, 1);
310 bar
= PCI_SLOT_INFO_FIRST_BAR(slots
);
311 slots
= PCI_SLOT_INFO_SLOTS(slots
);
312 if (slots
> 6 || bar
> 5) {
313 device_printf(dev
, "Incorrect slots information (%d, %d).\n",
319 #if defined(__DragonFly__)
320 pci_alloc_1intr(dev
, sdhci_enable_msi
, &rid
, &irq_flags
);
321 sc
->irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
, irq_flags
);
324 if (sdhci_enable_msi
!= 0) {
325 count
= pci_msi_count(dev
);
328 if (pci_alloc_msi(dev
, &i
, 1, count
) == 0) {
330 device_printf(dev
, "MSI enabled\n");
335 sc
->irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
336 RF_ACTIVE
| (rid
!= 0 ? 0 : RF_SHAREABLE
));
338 if (sc
->irq_res
== NULL
) {
339 device_printf(dev
, "Can't allocate IRQ\n");
340 pci_release_msi(dev
);
343 /* Scan all slots. */
344 for (i
= 0; i
< slots
; i
++) {
345 struct sdhci_slot
*slot
= &sc
->slots
[sc
->num_slots
];
347 /* Allocate memory. */
348 rid
= PCIR_BAR(bar
+ i
);
349 sc
->mem_res
[i
] = bus_alloc_resource_any(dev
, SYS_RES_MEMORY
,
351 if (sc
->mem_res
[i
] == NULL
) {
352 device_printf(dev
, "Can't allocate memory for slot %d\n", i
);
356 slot
->quirks
= sc
->quirks
;
358 if (sdhci_init_slot(dev
, slot
, i
) != 0)
363 device_printf(dev
, "%d slot(s) allocated\n", sc
->num_slots
);
364 /* Activate the interrupt */
365 err
= bus_setup_intr(dev
, sc
->irq_res
, INTR_MPSAFE
,
366 sdhci_pci_intr
, sc
, &sc
->intrhand
, NULL
);
368 device_printf(dev
, "Can't setup IRQ\n");
369 pci_enable_busmaster(dev
);
370 /* Process cards detection. */
371 for (i
= 0; i
< sc
->num_slots
; i
++) {
372 struct sdhci_slot
*slot
= &sc
->slots
[i
];
374 sdhci_start_slot(slot
);
381 sdhci_pci_detach(device_t dev
)
383 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
386 bus_teardown_intr(dev
, sc
->irq_res
, sc
->intrhand
);
387 bus_release_resource(dev
, SYS_RES_IRQ
,
388 rman_get_rid(sc
->irq_res
), sc
->irq_res
);
389 pci_release_msi(dev
);
391 for (i
= 0; i
< sc
->num_slots
; i
++) {
392 struct sdhci_slot
*slot
= &sc
->slots
[i
];
394 sdhci_cleanup_slot(slot
);
395 bus_release_resource(dev
, SYS_RES_MEMORY
,
396 rman_get_rid(sc
->mem_res
[i
]), sc
->mem_res
[i
]);
398 if (sc
->quirks
& SDHCI_QUIRK_LOWER_FREQUENCY
)
399 sdhci_restore_frequency(dev
);
404 sdhci_pci_shutdown(device_t dev
)
406 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
408 if (sc
->quirks
& SDHCI_QUIRK_LOWER_FREQUENCY
)
409 sdhci_restore_frequency(dev
);
414 sdhci_pci_suspend(device_t dev
)
416 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
419 err
= bus_generic_suspend(dev
);
422 for (i
= 0; i
< sc
->num_slots
; i
++)
423 sdhci_generic_suspend(&sc
->slots
[i
]);
428 sdhci_pci_resume(device_t dev
)
430 struct sdhci_pci_softc
*sc
= device_get_softc(dev
);
433 for (i
= 0; i
< sc
->num_slots
; i
++)
434 sdhci_generic_resume(&sc
->slots
[i
]);
435 return (bus_generic_resume(dev
));
439 sdhci_pci_intr(void *arg
)
441 struct sdhci_pci_softc
*sc
= (struct sdhci_pci_softc
*)arg
;
444 for (i
= 0; i
< sc
->num_slots
; i
++) {
445 struct sdhci_slot
*slot
= &sc
->slots
[i
];
446 sdhci_generic_intr(slot
);
450 static device_method_t sdhci_methods
[] = {
452 DEVMETHOD(device_probe
, sdhci_pci_probe
),
453 DEVMETHOD(device_attach
, sdhci_pci_attach
),
454 DEVMETHOD(device_detach
, sdhci_pci_detach
),
455 DEVMETHOD(device_shutdown
, sdhci_pci_shutdown
),
456 DEVMETHOD(device_suspend
, sdhci_pci_suspend
),
457 DEVMETHOD(device_resume
, sdhci_pci_resume
),
460 DEVMETHOD(bus_read_ivar
, sdhci_generic_read_ivar
),
461 DEVMETHOD(bus_write_ivar
, sdhci_generic_write_ivar
),
464 DEVMETHOD(mmcbr_update_ios
, sdhci_generic_update_ios
),
465 DEVMETHOD(mmcbr_request
, sdhci_generic_request
),
466 DEVMETHOD(mmcbr_get_ro
, sdhci_generic_get_ro
),
467 DEVMETHOD(mmcbr_acquire_host
, sdhci_generic_acquire_host
),
468 DEVMETHOD(mmcbr_release_host
, sdhci_generic_release_host
),
470 /* SDHCI registers accessors */
471 DEVMETHOD(sdhci_read_1
, sdhci_pci_read_1
),
472 DEVMETHOD(sdhci_read_2
, sdhci_pci_read_2
),
473 DEVMETHOD(sdhci_read_4
, sdhci_pci_read_4
),
474 DEVMETHOD(sdhci_read_multi_4
, sdhci_pci_read_multi_4
),
475 DEVMETHOD(sdhci_write_1
, sdhci_pci_write_1
),
476 DEVMETHOD(sdhci_write_2
, sdhci_pci_write_2
),
477 DEVMETHOD(sdhci_write_4
, sdhci_pci_write_4
),
478 DEVMETHOD(sdhci_write_multi_4
, sdhci_pci_write_multi_4
),
483 static driver_t sdhci_pci_driver
= {
486 sizeof(struct sdhci_pci_softc
),
488 static devclass_t sdhci_pci_devclass
;
490 DRIVER_MODULE(sdhci_pci
, pci
, sdhci_pci_driver
, sdhci_pci_devclass
, NULL
,
492 MODULE_DEPEND(sdhci_pci
, sdhci
, 1, 1, 1);