sdhc_pci.c revision 1.14.10.1 1 /* $NetBSD: sdhc_pci.c,v 1.14.10.1 2020/04/08 14:08:10 martin Exp $ */
2 /* $OpenBSD: sdhc_pci.c,v 1.7 2007/10/30 18:13:45 chl Exp $ */
3
4 /*
5 * Copyright (c) 2006 Uwe Stuehler <uwe (at) openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include <sys/cdefs.h>
21 __KERNEL_RCSID(0, "$NetBSD: sdhc_pci.c,v 1.14.10.1 2020/04/08 14:08:10 martin Exp $");
22
23 #ifdef _KERNEL_OPT
24 #include "opt_sdmmc.h"
25 #endif
26
27 #include <sys/param.h>
28 #include <sys/device.h>
29 #include <sys/systm.h>
30 #include <sys/malloc.h>
31 #include <sys/pmf.h>
32
33 #include <dev/pci/pcivar.h>
34 #include <dev/pci/pcidevs.h>
35
36 #include <dev/sdmmc/sdhcreg.h>
37 #include <dev/sdmmc/sdhcvar.h>
38 #include <dev/sdmmc/sdmmcvar.h>
39
40 /* PCI base address registers */
41 #define SDHC_PCI_BAR_START PCI_MAPREG_START
42 #define SDHC_PCI_BAR_END PCI_MAPREG_END
43
44 /* PCI interface classes */
45 #define SDHC_PCI_INTERFACE_NO_DMA 0x00
46 #define SDHC_PCI_INTERFACE_DMA 0x01
47 #define SDHC_PCI_INTERFACE_VENDOR 0x02
48
49 /*
50 * 8-bit PCI configuration register that tells us how many slots there
51 * are and which BAR entry corresponds to the first slot.
52 */
53 #define SDHC_PCI_CONF_SLOT_INFO 0x40
54 #define SDHC_PCI_NUM_SLOTS(info) ((((info) >> 4) & 0x7) + 1)
55 #define SDHC_PCI_FIRST_BAR(info) ((info) & 0x7)
56
57 struct sdhc_pci_softc {
58 struct sdhc_softc sc;
59 pci_chipset_tag_t sc_pc;
60 void *sc_ih;
61 };
62
63 static int sdhc_pci_match(device_t, cfdata_t, void *);
64 static void sdhc_pci_attach(device_t, device_t, void *);
65 static int sdhc_pci_detach(device_t, int);
66
67 CFATTACH_DECL_NEW(sdhc_pci, sizeof(struct sdhc_pci_softc),
68 sdhc_pci_match, sdhc_pci_attach, sdhc_pci_detach, NULL);
69
70 #ifdef SDHC_DEBUG
71 #define DPRINTF(s) printf s
72 #else
73 #define DPRINTF(s) /**/
74 #endif
75
76 static const struct sdhc_pci_quirk {
77 pci_vendor_id_t vendor;
78 pci_product_id_t product;
79 pci_vendor_id_t subvendor;
80 pci_product_id_t subproduct;
81 u_int function;
82
83 uint32_t flags;
84 #define SDHC_PCI_QUIRK_FORCE_DMA __BIT(0)
85 #define SDHC_PCI_QUIRK_TI_HACK __BIT(1)
86 #define SDHC_PCI_QUIRK_NO_PWR0 __BIT(2)
87 #define SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK __BIT(3)
88 #define SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK __BIT(4)
89 #define SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET __BIT(5)
90 #define SDHC_PCI_QUIRK_SINGLE_POWER_WRITE __BIT(6)
91 } sdhc_pci_quirk_table[] = {
92 {
93 PCI_VENDOR_TI,
94 PCI_PRODUCT_TI_PCI72111SD,
95 0xffff,
96 0xffff,
97 4,
98 SDHC_PCI_QUIRK_TI_HACK
99 },
100
101 {
102 PCI_VENDOR_TI,
103 PCI_PRODUCT_TI_PCIXX12SD,
104 0xffff,
105 0xffff,
106 3,
107 SDHC_PCI_QUIRK_TI_HACK
108 },
109
110 {
111 PCI_VENDOR_ENE,
112 PCI_PRODUCT_ENE_CB712,
113 0xffff,
114 0xffff,
115 0,
116 SDHC_PCI_QUIRK_NO_PWR0
117 },
118 {
119 PCI_VENDOR_RICOH,
120 PCI_PRODUCT_RICOH_Rx5U823,
121 0xffff,
122 0xffff,
123 0,
124 SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK
125 | SDHC_PCI_QUIRK_SINGLE_POWER_WRITE
126 },
127 {
128 PCI_VENDOR_RICOH,
129 PCI_PRODUCT_RICOH_Rx5C822,
130 0xffff,
131 0xffff,
132 ~0,
133 SDHC_PCI_QUIRK_FORCE_DMA
134 },
135
136 {
137 PCI_VENDOR_RICOH,
138 PCI_PRODUCT_RICOH_Rx5U822,
139 0xffff,
140 0xffff,
141 ~0,
142 SDHC_PCI_QUIRK_FORCE_DMA
143 },
144
145 {
146 PCI_VENDOR_INTEL,
147 PCI_PRODUCT_INTEL_BAYTRAIL_SCC_MMC,
148 0xffff,
149 0xffff,
150 ~0,
151 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET
152 },
153
154 {
155 PCI_VENDOR_INTEL,
156 PCI_PRODUCT_INTEL_BSW_SSC_MMC,
157 0xffff,
158 0xffff,
159 ~0,
160 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET
161 },
162
163 {
164 PCI_VENDOR_INTEL,
165 PCI_PRODUCT_INTEL_100SERIES_LP_EMMC,
166 0xffff,
167 0xffff,
168 ~0,
169 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET
170 },
171 };
172
173 static void sdhc_pci_quirk_ti_hack(struct pci_attach_args *);
174 static void sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *);
175 static void sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *,
176 struct sdhc_host *);
177
178 static uint32_t
179 sdhc_pci_lookup_quirk_flags(struct pci_attach_args *pa)
180 {
181 const struct sdhc_pci_quirk *q;
182 pcireg_t id;
183 pci_vendor_id_t vendor;
184 pci_product_id_t product;
185 int i;
186
187 for (i = 0; i < __arraycount(sdhc_pci_quirk_table); i++) {
188 q = &sdhc_pci_quirk_table[i];
189
190 if ((PCI_VENDOR(pa->pa_id) == q->vendor)
191 && (PCI_PRODUCT(pa->pa_id) == q->product)) {
192 if ((q->function != ~0)
193 && (pa->pa_function != q->function))
194 continue;
195
196 if ((q->subvendor == 0xffff)
197 && (q->subproduct == 0xffff))
198 return (q->flags);
199
200 id = pci_conf_read(pa->pa_pc, pa->pa_tag,
201 PCI_SUBSYS_ID_REG);
202 vendor = PCI_VENDOR(id);
203 product = PCI_PRODUCT(id);
204
205 if ((q->subvendor != 0xffff)
206 && (q->subproduct != 0xffff)) {
207 if ((vendor == q->subvendor)
208 && (product == q->subproduct))
209 return (q->flags);
210 } else if (q->subvendor != 0xffff) {
211 if (product == q->subproduct)
212 return (q->flags);
213 } else {
214 if (vendor == q->subvendor)
215 return (q->flags);
216 }
217 }
218 }
219 return (0);
220 }
221
222 static int
223 sdhc_pci_match(device_t parent, cfdata_t cf, void *aux)
224 {
225 struct pci_attach_args *pa = aux;
226
227 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SYSTEM &&
228 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SYSTEM_SDHC)
229 return (1);
230 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RICOH &&
231 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U822 ||
232 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U823))
233 return (1);
234 return (0);
235 }
236
237 static void
238 sdhc_pci_attach(device_t parent, device_t self, void *aux)
239 {
240 struct sdhc_pci_softc *sc = device_private(self);
241 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
242 pci_chipset_tag_t pc = pa->pa_pc;
243 pcitag_t tag = pa->pa_tag;
244 pci_intr_handle_t ih;
245 pcireg_t csr;
246 pcireg_t slotinfo;
247 char const *intrstr;
248 int nslots;
249 int reg;
250 int cnt;
251 bus_space_tag_t iot;
252 bus_space_handle_t ioh;
253 bus_size_t size;
254 uint32_t flags;
255 char intrbuf[PCI_INTRSTR_LEN];
256
257 sc->sc.sc_dev = self;
258 sc->sc.sc_dmat = pa->pa_dmat;
259 sc->sc.sc_host = NULL;
260
261 sc->sc_pc = pc;
262
263 pci_aprint_devinfo(pa, NULL);
264
265 /* Some controllers needs special treatment. */
266 flags = sdhc_pci_lookup_quirk_flags(pa);
267 if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK))
268 sdhc_pci_quirk_ti_hack(pa);
269 if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA))
270 SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA);
271 if (ISSET(flags, SDHC_PCI_QUIRK_SINGLE_POWER_WRITE))
272 SET(sc->sc.sc_flags, SDHC_FLAG_SINGLE_POWER_WRITE);
273 if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0))
274 SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0);
275 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK))
276 sdhc_pci_quirk_ricoh_lower_freq_hack(pa);
277 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK))
278 SET(sc->sc.sc_flags, SDHC_FLAG_SLOW_SDR50);
279 if (ISSET(flags, SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET))
280 sc->sc.sc_vendor_hw_reset = sdhc_pci_intel_emmc_hw_reset;
281
282 /*
283 * Map and attach all hosts supported by the host controller.
284 */
285 slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO);
286 nslots = SDHC_PCI_NUM_SLOTS(slotinfo);
287
288 /* Allocate an array big enough to hold all the possible hosts */
289 sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots,
290 M_DEVBUF, M_NOWAIT | M_ZERO);
291 if (sc->sc.sc_host == NULL) {
292 aprint_error_dev(self, "couldn't alloc memory\n");
293 goto err;
294 }
295
296 /* Enable the device. */
297 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
298 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG,
299 csr | PCI_COMMAND_MASTER_ENABLE);
300
301 /* Map and establish the interrupt. */
302 if (pci_intr_map(pa, &ih)) {
303 aprint_error_dev(self, "couldn't map interrupt\n");
304 goto err;
305 }
306
307 intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
308 sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_SDMMC, sdhc_intr,
309 &sc->sc, device_xname(self));
310 if (sc->sc_ih == NULL) {
311 aprint_error_dev(self, "couldn't establish interrupt\n");
312 goto err;
313 }
314 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
315
316 /* Enable use of DMA if supported by the interface. */
317 if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA))
318 SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA);
319
320 /* XXX: handle 64-bit BARs */
321 cnt = 0;
322 for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) *
323 sizeof(uint32_t);
324 reg < SDHC_PCI_BAR_END && nslots > 0;
325 reg += sizeof(uint32_t), nslots--) {
326 if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_MEM, 0,
327 &iot, &ioh, NULL, &size)) {
328 continue;
329 }
330
331 cnt++;
332 if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) {
333 /* XXX: sc->sc_host leak */
334 aprint_error_dev(self,
335 "couldn't initialize host (0x%x)\n", reg);
336 }
337 }
338 if (cnt == 0) {
339 aprint_error_dev(self, "couldn't map register\n");
340 goto err;
341 }
342
343 if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume,
344 sdhc_shutdown)) {
345 aprint_error_dev(self, "couldn't establish powerhook\n");
346 }
347
348 return;
349
350 err:
351 if (sc->sc.sc_host != NULL) {
352 free(sc->sc.sc_host, M_DEVBUF);
353 sc->sc.sc_host = NULL;
354 }
355 }
356
357 static int
358 sdhc_pci_detach(device_t self, int flags)
359 {
360 struct sdhc_pci_softc * const sc = device_private(self);
361 int rv;
362
363 rv = sdhc_detach(&sc->sc, flags);
364 if (rv)
365 return rv;
366
367 if (sc->sc_ih != NULL) {
368 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
369 sc->sc_ih = NULL;
370 }
371
372 if (sc->sc.sc_host != NULL) {
373 free(sc->sc.sc_host, M_DEVBUF);
374 sc->sc.sc_host = NULL;
375 }
376
377 return rv;
378 }
379
380 static void
381 sdhc_pci_conf_write(struct pci_attach_args *pa, int reg, uint8_t val)
382 {
383 pcireg_t r;
384
385 r = pci_conf_read(pa->pa_pc, pa->pa_tag, reg & ~0x3);
386 r &= ~(0xff << ((reg & 0x3) * 8));
387 r |= (val << ((reg & 0x3) * 8));
388 pci_conf_write(pa->pa_pc, pa->pa_tag, reg & ~0x3, r);
389 }
390
391 /* TI specific register */
392 #define SDHC_PCI_GENERAL_CTL 0x4c
393 #define MMC_SD_DIS 0x02
394
395 static void
396 sdhc_pci_quirk_ti_hack(struct pci_attach_args *pa)
397 {
398 pci_chipset_tag_t pc = pa->pa_pc;
399 pcitag_t tag;
400 pcireg_t id, reg;
401
402 /* Look at func - 1 for the flash device */
403 tag = pci_make_tag(pc, pa->pa_bus, pa->pa_device, pa->pa_function - 1);
404 id = pci_conf_read(pc, tag, PCI_ID_REG);
405 if (PCI_VENDOR(id) != PCI_VENDOR_TI) {
406 return;
407 }
408 switch (PCI_PRODUCT(id)) {
409 case PCI_PRODUCT_TI_PCI72111FM:
410 case PCI_PRODUCT_TI_PCIXX12FM:
411 break;
412 default:
413 return;
414 }
415
416 /*
417 * Disable MMC/SD on the flash media controller so the
418 * SD host takes over.
419 */
420 reg = pci_conf_read(pc, tag, SDHC_PCI_GENERAL_CTL);
421 reg |= MMC_SD_DIS;
422 pci_conf_write(pc, tag, SDHC_PCI_GENERAL_CTL, reg);
423 }
424
425 /* Ricoh specific register */
426 #define SDHC_PCI_MODE_KEY 0xf9
427 #define SDHC_PCI_MODE 0x150
428 #define SDHC_PCI_MODE_SD20 0x10
429 #define SDHC_PCI_BASE_FREQ_KEY 0xfc
430 #define SDHC_PCI_BASE_FREQ 0xe1
431
432 /* Some RICOH controllers need to be bumped into the right mode. */
433 static void
434 sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *pa)
435 {
436 /* Enable SD2.0 mode. */
437 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0xfc);
438 sdhc_pci_conf_write(pa, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20);
439 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0x00);
440
441 /*
442 * Some SD/MMC cards don't work with the default base
443 * clock frequency of 200MHz. Lower it to 50Hz.
444 */
445 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x01);
446 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ, 50);
447 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x00);
448 printf("quirked\n");
449 }
450
451 static void
452 sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *sc, struct sdhc_host *hp)
453 {
454 kmutex_t *plock = sdhc_host_lock(hp);
455 uint8_t reg;
456
457 mutex_enter(plock);
458
459 reg = sdhc_host_read_1(hp, SDHC_POWER_CTL);
460 reg |= 0x10;
461 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg);
462
463 sdmmc_delay(10);
464
465 reg &= ~0x10;
466 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg);
467
468 sdmmc_delay(1000);
469
470 mutex_exit(plock);
471 }
472