1 | /* $NetBSD: viaide.c,v 1.84 2014/03/29 19:28:25 christos Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | * |
26 | */ |
27 | |
28 | #include <sys/cdefs.h> |
29 | __KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.84 2014/03/29 19:28:25 christos Exp $" ); |
30 | |
31 | #include <sys/param.h> |
32 | #include <sys/systm.h> |
33 | #include <sys/malloc.h> |
34 | |
35 | #include <dev/pci/pcivar.h> |
36 | #include <dev/pci/pcidevs.h> |
37 | #include <dev/pci/pciidereg.h> |
38 | #include <dev/pci/pciidevar.h> |
39 | #include <dev/pci/pciide_apollo_reg.h> |
40 | |
41 | static int via_pcib_match(const struct pci_attach_args *); |
42 | static void via_chip_map(struct pciide_softc *, |
43 | const struct pci_attach_args *); |
44 | static void via_mapchan(const struct pci_attach_args *, |
45 | struct pciide_channel *, |
46 | pcireg_t, int (*)(void *)); |
47 | static void via_mapregs_compat_native(const struct pci_attach_args *, |
48 | struct pciide_channel *); |
49 | static int via_sata_chip_map_common(struct pciide_softc *, |
50 | const struct pci_attach_args *); |
51 | static void via_sata_chip_map(struct pciide_softc *, |
52 | const struct pci_attach_args *, int); |
53 | static void via_sata_chip_map_6(struct pciide_softc *, |
54 | const struct pci_attach_args *); |
55 | static void via_sata_chip_map_7(struct pciide_softc *, |
56 | const struct pci_attach_args *); |
57 | static void via_sata_chip_map_new(struct pciide_softc *, |
58 | const struct pci_attach_args *); |
59 | static void via_setup_channel(struct ata_channel *); |
60 | |
61 | static int viaide_match(device_t, cfdata_t, void *); |
62 | static void viaide_attach(device_t, device_t, void *); |
63 | static const struct pciide_product_desc * |
64 | viaide_lookup(pcireg_t); |
65 | static bool viaide_suspend(device_t, const pmf_qual_t *); |
66 | static bool viaide_resume(device_t, const pmf_qual_t *); |
67 | |
68 | CFATTACH_DECL_NEW(viaide, sizeof(struct pciide_softc), |
69 | viaide_match, viaide_attach, pciide_detach, NULL); |
70 | |
71 | static const struct pciide_product_desc pciide_amd_products[] = { |
72 | { PCI_PRODUCT_AMD_PBC756_IDE, |
73 | 0, |
74 | "AMD AMD756 IDE Controller" , |
75 | via_chip_map |
76 | }, |
77 | { PCI_PRODUCT_AMD_PBC766_IDE, |
78 | 0, |
79 | "AMD AMD766 IDE Controller" , |
80 | via_chip_map |
81 | }, |
82 | { PCI_PRODUCT_AMD_PBC768_IDE, |
83 | 0, |
84 | "AMD AMD768 IDE Controller" , |
85 | via_chip_map |
86 | }, |
87 | { PCI_PRODUCT_AMD_PBC8111_IDE, |
88 | 0, |
89 | "AMD AMD8111 IDE Controller" , |
90 | via_chip_map |
91 | }, |
92 | { PCI_PRODUCT_AMD_CS5536_IDE, |
93 | 0, |
94 | "AMD CS5536 IDE Controller" , |
95 | via_chip_map |
96 | }, |
97 | { 0, |
98 | 0, |
99 | NULL, |
100 | NULL |
101 | } |
102 | }; |
103 | |
104 | static const struct pciide_product_desc pciide_nvidia_products[] = { |
105 | { PCI_PRODUCT_NVIDIA_NFORCE_ATA100, |
106 | 0, |
107 | "NVIDIA nForce IDE Controller" , |
108 | via_chip_map |
109 | }, |
110 | { PCI_PRODUCT_NVIDIA_NFORCE2_ATA133, |
111 | 0, |
112 | "NVIDIA nForce2 IDE Controller" , |
113 | via_chip_map |
114 | }, |
115 | { PCI_PRODUCT_NVIDIA_NFORCE2_400_ATA133, |
116 | 0, |
117 | "NVIDIA nForce2 Ultra 400 IDE Controller" , |
118 | via_chip_map |
119 | }, |
120 | { PCI_PRODUCT_NVIDIA_NFORCE2_400_SATA, |
121 | 0, |
122 | "NVIDIA nForce2 Ultra 400 Serial ATA Controller" , |
123 | via_sata_chip_map_6 |
124 | }, |
125 | { PCI_PRODUCT_NVIDIA_NFORCE3_ATA133, |
126 | 0, |
127 | "NVIDIA nForce3 IDE Controller" , |
128 | via_chip_map |
129 | }, |
130 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_ATA133, |
131 | 0, |
132 | "NVIDIA nForce3 250 IDE Controller" , |
133 | via_chip_map |
134 | }, |
135 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA, |
136 | 0, |
137 | "NVIDIA nForce3 250 Serial ATA Controller" , |
138 | via_sata_chip_map_6 |
139 | }, |
140 | { PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA2, |
141 | 0, |
142 | "NVIDIA nForce3 250 Serial ATA Controller" , |
143 | via_sata_chip_map_6 |
144 | }, |
145 | { PCI_PRODUCT_NVIDIA_NFORCE4_ATA133, |
146 | 0, |
147 | "NVIDIA nForce4 IDE Controller" , |
148 | via_chip_map |
149 | }, |
150 | { PCI_PRODUCT_NVIDIA_NFORCE4_SATA1, |
151 | 0, |
152 | "NVIDIA nForce4 Serial ATA Controller" , |
153 | via_sata_chip_map_6 |
154 | }, |
155 | { PCI_PRODUCT_NVIDIA_NFORCE4_SATA2, |
156 | 0, |
157 | "NVIDIA nForce4 Serial ATA Controller" , |
158 | via_sata_chip_map_6 |
159 | }, |
160 | { PCI_PRODUCT_NVIDIA_NFORCE430_ATA133, |
161 | 0, |
162 | "NVIDIA nForce430 IDE Controller" , |
163 | via_chip_map |
164 | }, |
165 | { PCI_PRODUCT_NVIDIA_NFORCE430_SATA1, |
166 | 0, |
167 | "NVIDIA nForce430 Serial ATA Controller" , |
168 | via_sata_chip_map_6 |
169 | }, |
170 | { PCI_PRODUCT_NVIDIA_NFORCE430_SATA2, |
171 | 0, |
172 | "NVIDIA nForce430 Serial ATA Controller" , |
173 | via_sata_chip_map_6 |
174 | }, |
175 | { PCI_PRODUCT_NVIDIA_MCP04_IDE, |
176 | 0, |
177 | "NVIDIA MCP04 IDE Controller" , |
178 | via_chip_map |
179 | }, |
180 | { PCI_PRODUCT_NVIDIA_MCP04_SATA, |
181 | 0, |
182 | "NVIDIA MCP04 Serial ATA Controller" , |
183 | via_sata_chip_map_6 |
184 | }, |
185 | { PCI_PRODUCT_NVIDIA_MCP04_SATA2, |
186 | 0, |
187 | "NVIDIA MCP04 Serial ATA Controller" , |
188 | via_sata_chip_map_6 |
189 | }, |
190 | { PCI_PRODUCT_NVIDIA_MCP55_IDE, |
191 | 0, |
192 | "NVIDIA MCP55 IDE Controller" , |
193 | via_chip_map |
194 | }, |
195 | { PCI_PRODUCT_NVIDIA_MCP55_SATA, |
196 | 0, |
197 | "NVIDIA MCP55 Serial ATA Controller" , |
198 | via_sata_chip_map_6 |
199 | }, |
200 | { PCI_PRODUCT_NVIDIA_MCP55_SATA2, |
201 | 0, |
202 | "NVIDIA MCP55 Serial ATA Controller" , |
203 | via_sata_chip_map_6 |
204 | }, |
205 | { PCI_PRODUCT_NVIDIA_MCP61_IDE, |
206 | 0, |
207 | "NVIDIA MCP61 IDE Controller" , |
208 | via_chip_map |
209 | }, |
210 | { PCI_PRODUCT_NVIDIA_MCP65_IDE, |
211 | 0, |
212 | "NVIDIA MCP65 IDE Controller" , |
213 | via_chip_map |
214 | }, |
215 | { PCI_PRODUCT_NVIDIA_MCP73_IDE, |
216 | 0, |
217 | "NVIDIA MCP73 IDE Controller" , |
218 | via_chip_map |
219 | }, |
220 | { PCI_PRODUCT_NVIDIA_MCP77_IDE, |
221 | 0, |
222 | "NVIDIA MCP77 IDE Controller" , |
223 | via_chip_map |
224 | }, |
225 | { PCI_PRODUCT_NVIDIA_MCP61_SATA, |
226 | 0, |
227 | "NVIDIA MCP61 Serial ATA Controller" , |
228 | via_sata_chip_map_6 |
229 | }, |
230 | { PCI_PRODUCT_NVIDIA_MCP61_SATA2, |
231 | 0, |
232 | "NVIDIA MCP61 Serial ATA Controller" , |
233 | via_sata_chip_map_6 |
234 | }, |
235 | { PCI_PRODUCT_NVIDIA_MCP61_SATA3, |
236 | 0, |
237 | "NVIDIA MCP61 Serial ATA Controller" , |
238 | via_sata_chip_map_6 |
239 | }, |
240 | { PCI_PRODUCT_NVIDIA_MCP65_SATA, |
241 | 0, |
242 | "NVIDIA MCP65 Serial ATA Controller" , |
243 | via_sata_chip_map_6 |
244 | }, |
245 | { PCI_PRODUCT_NVIDIA_MCP65_SATA2, |
246 | 0, |
247 | "NVIDIA MCP65 Serial ATA Controller" , |
248 | via_sata_chip_map_6 |
249 | }, |
250 | { PCI_PRODUCT_NVIDIA_MCP65_SATA3, |
251 | 0, |
252 | "NVIDIA MCP65 Serial ATA Controller" , |
253 | via_sata_chip_map_6 |
254 | }, |
255 | { PCI_PRODUCT_NVIDIA_MCP65_SATA4, |
256 | 0, |
257 | "NVIDIA MCP65 Serial ATA Controller" , |
258 | via_sata_chip_map_6 |
259 | }, |
260 | { PCI_PRODUCT_NVIDIA_MCP67_IDE, |
261 | 0, |
262 | "NVIDIA MCP67 IDE Controller" , |
263 | via_chip_map, |
264 | }, |
265 | { PCI_PRODUCT_NVIDIA_MCP67_SATA, |
266 | 0, |
267 | "NVIDIA MCP67 Serial ATA Controller" , |
268 | via_sata_chip_map_6, |
269 | }, |
270 | { PCI_PRODUCT_NVIDIA_MCP67_SATA2, |
271 | 0, |
272 | "NVIDIA MCP67 Serial ATA Controller" , |
273 | via_sata_chip_map_6, |
274 | }, |
275 | { PCI_PRODUCT_NVIDIA_MCP67_SATA3, |
276 | 0, |
277 | "NVIDIA MCP67 Serial ATA Controller" , |
278 | via_sata_chip_map_6, |
279 | }, |
280 | { PCI_PRODUCT_NVIDIA_MCP67_SATA4, |
281 | 0, |
282 | "NVIDIA MCP67 Serial ATA Controller" , |
283 | via_sata_chip_map_6, |
284 | }, |
285 | { 0, |
286 | 0, |
287 | NULL, |
288 | NULL |
289 | } |
290 | }; |
291 | |
292 | static const struct pciide_product_desc pciide_via_products[] = { |
293 | { PCI_PRODUCT_VIATECH_VT82C586_IDE, |
294 | 0, |
295 | NULL, |
296 | via_chip_map, |
297 | }, |
298 | { PCI_PRODUCT_VIATECH_VT82C586A_IDE, |
299 | 0, |
300 | NULL, |
301 | via_chip_map, |
302 | }, |
303 | { PCI_PRODUCT_VIATECH_CX700_IDE, |
304 | 0, |
305 | NULL, |
306 | via_chip_map, |
307 | }, |
308 | { PCI_PRODUCT_VIATECH_CX700M2_IDE, |
309 | 0, |
310 | NULL, |
311 | via_chip_map, |
312 | }, |
313 | { PCI_PRODUCT_VIATECH_VX900_IDE, |
314 | 0, |
315 | NULL, |
316 | via_chip_map, |
317 | }, |
318 | { PCI_PRODUCT_VIATECH_VT6410_RAID, |
319 | 0, |
320 | NULL, |
321 | via_chip_map, |
322 | }, |
323 | { PCI_PRODUCT_VIATECH_VT6421_RAID, |
324 | 0, |
325 | "VIA Technologies VT6421 Serial ATA RAID Controller" , |
326 | via_sata_chip_map_new, |
327 | }, |
328 | { PCI_PRODUCT_VIATECH_VT8237_SATA, |
329 | 0, |
330 | "VIA Technologies VT8237 SATA Controller" , |
331 | via_sata_chip_map_7, |
332 | }, |
333 | { PCI_PRODUCT_VIATECH_VT8237A_SATA, |
334 | 0, |
335 | "VIA Technologies VT8237A SATA Controller" , |
336 | via_sata_chip_map_7, |
337 | }, |
338 | { PCI_PRODUCT_VIATECH_VT8237A_SATA_2, |
339 | 0, |
340 | "VIA Technologies VT8237A (5337) SATA Controller" , |
341 | via_sata_chip_map_7, |
342 | }, |
343 | { PCI_PRODUCT_VIATECH_VT8237R_SATA, |
344 | 0, |
345 | "VIA Technologies VT8237R SATA Controller" , |
346 | via_sata_chip_map_7, |
347 | }, |
348 | { PCI_PRODUCT_VIATECH_VT8237S_SATA, |
349 | 0, |
350 | "VIA Technologies VT8237S SATA Controller" , |
351 | via_sata_chip_map_7, |
352 | }, |
353 | { 0, |
354 | 0, |
355 | NULL, |
356 | NULL |
357 | } |
358 | }; |
359 | |
360 | static const struct pciide_product_desc * |
361 | viaide_lookup(pcireg_t id) |
362 | { |
363 | |
364 | switch (PCI_VENDOR(id)) { |
365 | case PCI_VENDOR_VIATECH: |
366 | return (pciide_lookup_product(id, pciide_via_products)); |
367 | |
368 | case PCI_VENDOR_AMD: |
369 | return (pciide_lookup_product(id, pciide_amd_products)); |
370 | |
371 | case PCI_VENDOR_NVIDIA: |
372 | return (pciide_lookup_product(id, pciide_nvidia_products)); |
373 | } |
374 | return (NULL); |
375 | } |
376 | |
377 | static int |
378 | viaide_match(device_t parent, cfdata_t match, void *aux) |
379 | { |
380 | const struct pci_attach_args *pa = aux; |
381 | |
382 | if (viaide_lookup(pa->pa_id) != NULL) |
383 | return (2); |
384 | return (0); |
385 | } |
386 | |
387 | static void |
388 | viaide_attach(device_t parent, device_t self, void *aux) |
389 | { |
390 | const struct pci_attach_args *pa = aux; |
391 | struct pciide_softc *sc = device_private(self); |
392 | const struct pciide_product_desc *pp; |
393 | |
394 | sc->sc_wdcdev.sc_atac.atac_dev = self; |
395 | |
396 | pp = viaide_lookup(pa->pa_id); |
397 | if (pp == NULL) |
398 | panic("viaide_attach" ); |
399 | pciide_common_attach(sc, pa, pp); |
400 | |
401 | if (!pmf_device_register(self, viaide_suspend, viaide_resume)) |
402 | aprint_error_dev(self, "couldn't establish power handler\n" ); |
403 | } |
404 | |
405 | static int |
406 | via_pcib_match(const struct pci_attach_args *pa) |
407 | { |
408 | if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && |
409 | PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA && |
410 | PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH) |
411 | return (1); |
412 | return 0; |
413 | } |
414 | |
415 | static bool |
416 | viaide_suspend(device_t dv, const pmf_qual_t *qual) |
417 | { |
418 | struct pciide_softc *sc = device_private(dv); |
419 | |
420 | sc->sc_pm_reg[0] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); |
421 | /* APO_DATATIM(sc) includes APO_UDMA(sc) */ |
422 | sc->sc_pm_reg[1] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); |
423 | /* This two are VIA-only, but should be ignored by other devices. */ |
424 | sc->sc_pm_reg[2] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)); |
425 | sc->sc_pm_reg[3] = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc)); |
426 | |
427 | return true; |
428 | } |
429 | |
430 | static bool |
431 | viaide_resume(device_t dv, const pmf_qual_t *qual) |
432 | { |
433 | struct pciide_softc *sc = device_private(dv); |
434 | |
435 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc), |
436 | sc->sc_pm_reg[0]); |
437 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), |
438 | sc->sc_pm_reg[1]); |
439 | /* This two are VIA-only, but should be ignored by other devices. */ |
440 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc), |
441 | sc->sc_pm_reg[2]); |
442 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_MISCTIM(sc), |
443 | sc->sc_pm_reg[3]); |
444 | |
445 | return true; |
446 | } |
447 | |
448 | static void |
449 | via_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) |
450 | { |
451 | struct pciide_channel *cp; |
452 | pcireg_t interface = PCI_INTERFACE(pa->pa_class); |
453 | pcireg_t vendor = PCI_VENDOR(pa->pa_id); |
454 | int channel; |
455 | u_int32_t ideconf; |
456 | pcireg_t pcib_id, pcib_class; |
457 | struct pci_attach_args pcib_pa; |
458 | |
459 | if (pciide_chipen(sc, pa) == 0) |
460 | return; |
461 | |
462 | switch (vendor) { |
463 | case PCI_VENDOR_VIATECH: |
464 | switch (PCI_PRODUCT(pa->pa_id)) { |
465 | case PCI_PRODUCT_VIATECH_VT6410_RAID: |
466 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
467 | "VIA Technologies VT6410 IDE controller\n" ); |
468 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
469 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | |
470 | PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); |
471 | break; |
472 | case PCI_PRODUCT_VIATECH_VX900_IDE: |
473 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
474 | "VIA Technologies VX900 ATA133 controller\n" ); |
475 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
476 | break; |
477 | default: |
478 | /* |
479 | * get a PCI tag for the ISA bridge. |
480 | */ |
481 | if (pci_find_device(&pcib_pa, via_pcib_match) == 0) |
482 | goto unknown; |
483 | pcib_id = pcib_pa.pa_id; |
484 | pcib_class = pcib_pa.pa_class; |
485 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
486 | "VIA Technologies " ); |
487 | switch (PCI_PRODUCT(pcib_id)) { |
488 | case PCI_PRODUCT_VIATECH_VT82C586_ISA: |
489 | aprint_normal("VT82C586 (Apollo VP) " ); |
490 | if(PCI_REVISION(pcib_class) >= 0x02) { |
491 | aprint_normal("ATA33 controller\n" ); |
492 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; |
493 | } else { |
494 | aprint_normal("controller\n" ); |
495 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; |
496 | } |
497 | break; |
498 | case PCI_PRODUCT_VIATECH_VT82C596A: |
499 | aprint_normal("VT82C596A (Apollo Pro) " ); |
500 | if (PCI_REVISION(pcib_class) >= 0x12) { |
501 | aprint_normal("ATA66 controller\n" ); |
502 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; |
503 | } else { |
504 | aprint_normal("ATA33 controller\n" ); |
505 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 2; |
506 | } |
507 | break; |
508 | case PCI_PRODUCT_VIATECH_VT82C686A_ISA: |
509 | aprint_normal("VT82C686A (Apollo KX133) " ); |
510 | if (PCI_REVISION(pcib_class) >= 0x40) { |
511 | aprint_normal("ATA100 controller\n" ); |
512 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; |
513 | } else { |
514 | aprint_normal("ATA66 controller\n" ); |
515 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; |
516 | } |
517 | break; |
518 | case PCI_PRODUCT_VIATECH_VT8231: |
519 | aprint_normal("VT8231 ATA100 controller\n" ); |
520 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; |
521 | break; |
522 | case PCI_PRODUCT_VIATECH_VT8233: |
523 | aprint_normal("VT8233 ATA100 controller\n" ); |
524 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; |
525 | break; |
526 | case PCI_PRODUCT_VIATECH_VT8233A: |
527 | aprint_normal("VT8233A ATA133 controller\n" ); |
528 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
529 | break; |
530 | case PCI_PRODUCT_VIATECH_VT8235: |
531 | aprint_normal("VT8235 ATA133 controller\n" ); |
532 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
533 | break; |
534 | case PCI_PRODUCT_VIATECH_VT8237: |
535 | aprint_normal("VT8237 ATA133 controller\n" ); |
536 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
537 | break; |
538 | case PCI_PRODUCT_VIATECH_VT8237A_ISA: |
539 | aprint_normal("VT8237A ATA133 controller\n" ); |
540 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
541 | break; |
542 | case PCI_PRODUCT_VIATECH_CX700: |
543 | aprint_normal("CX700 ATA133 controller\n" ); |
544 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
545 | break; |
546 | case PCI_PRODUCT_VIATECH_VT8251: |
547 | aprint_normal("VT8251 ATA133 controller\n" ); |
548 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
549 | break; |
550 | default: |
551 | unknown: |
552 | aprint_normal("unknown VIA ATA controller\n" ); |
553 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 0; |
554 | } |
555 | break; |
556 | } |
557 | sc->sc_apo_regbase = APO_VIA_REGBASE; |
558 | break; |
559 | case PCI_VENDOR_AMD: |
560 | switch (sc->sc_pp->ide_product) { |
561 | case PCI_PRODUCT_AMD_PBC8111_IDE: |
562 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
563 | break; |
564 | case PCI_PRODUCT_AMD_CS5536_IDE: |
565 | case PCI_PRODUCT_AMD_PBC766_IDE: |
566 | case PCI_PRODUCT_AMD_PBC768_IDE: |
567 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; |
568 | break; |
569 | default: |
570 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; |
571 | } |
572 | sc->sc_apo_regbase = APO_AMD_REGBASE; |
573 | break; |
574 | case PCI_VENDOR_NVIDIA: |
575 | switch (sc->sc_pp->ide_product) { |
576 | case PCI_PRODUCT_NVIDIA_NFORCE_ATA100: |
577 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; |
578 | break; |
579 | case PCI_PRODUCT_NVIDIA_NFORCE2_ATA133: |
580 | case PCI_PRODUCT_NVIDIA_NFORCE2_400_ATA133: |
581 | case PCI_PRODUCT_NVIDIA_NFORCE3_ATA133: |
582 | case PCI_PRODUCT_NVIDIA_NFORCE3_250_ATA133: |
583 | case PCI_PRODUCT_NVIDIA_NFORCE4_ATA133: |
584 | case PCI_PRODUCT_NVIDIA_NFORCE430_ATA133: |
585 | case PCI_PRODUCT_NVIDIA_MCP04_IDE: |
586 | case PCI_PRODUCT_NVIDIA_MCP55_IDE: |
587 | case PCI_PRODUCT_NVIDIA_MCP61_IDE: |
588 | case PCI_PRODUCT_NVIDIA_MCP65_IDE: |
589 | case PCI_PRODUCT_NVIDIA_MCP67_IDE: |
590 | case PCI_PRODUCT_NVIDIA_MCP73_IDE: |
591 | case PCI_PRODUCT_NVIDIA_MCP77_IDE: |
592 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
593 | break; |
594 | } |
595 | sc->sc_apo_regbase = APO_NVIDIA_REGBASE; |
596 | break; |
597 | default: |
598 | panic("via_chip_map: unknown vendor" ); |
599 | } |
600 | |
601 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
602 | "bus-master DMA support present" ); |
603 | pciide_mapreg_dma(sc, pa); |
604 | aprint_verbose("\n" ); |
605 | sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32; |
606 | if (sc->sc_dma_ok) { |
607 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA; |
608 | sc->sc_wdcdev.irqack = pciide_irqack; |
609 | if (sc->sc_wdcdev.sc_atac.atac_udma_cap > 0) |
610 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA; |
611 | } |
612 | sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; |
613 | sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; |
614 | sc->sc_wdcdev.sc_atac.atac_set_modes = via_setup_channel; |
615 | sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; |
616 | sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; |
617 | sc->sc_wdcdev.wdc_maxdrives = 2; |
618 | |
619 | if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && |
620 | PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) |
621 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_RAID; |
622 | |
623 | wdc_allocate_regs(&sc->sc_wdcdev); |
624 | |
625 | ATADEBUG_PRINT(("via_chip_map: old APO_IDECONF=0x%x, " |
626 | "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n" , |
627 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)), |
628 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC(sc)), |
629 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), |
630 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), |
631 | DEBUG_PROBE); |
632 | |
633 | ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF(sc)); |
634 | for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; |
635 | channel++) { |
636 | cp = &sc->pciide_channels[channel]; |
637 | if (pciide_chansetup(sc, channel, interface) == 0) |
638 | continue; |
639 | |
640 | if ((ideconf & APO_IDECONF_EN(channel)) == 0) { |
641 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
642 | "%s channel ignored (disabled)\n" , cp->name); |
643 | cp->ata_channel.ch_flags |= ATACH_DISABLED; |
644 | continue; |
645 | } |
646 | via_mapchan(pa, cp, interface, pciide_pci_intr); |
647 | } |
648 | } |
649 | |
650 | static void |
651 | via_mapchan(const struct pci_attach_args *pa, struct pciide_channel *cp, |
652 | pcireg_t interface, int (*pci_intr)(void *)) |
653 | { |
654 | struct ata_channel *wdc_cp; |
655 | struct pciide_softc *sc; |
656 | prop_bool_t compat_nat_enable; |
657 | |
658 | wdc_cp = &cp->ata_channel; |
659 | sc = CHAN_TO_PCIIDE(&cp->ata_channel); |
660 | compat_nat_enable = prop_dictionary_get( |
661 | device_properties(sc->sc_wdcdev.sc_atac.atac_dev), |
662 | "use-compat-native-irq" ); |
663 | |
664 | if (interface & PCIIDE_INTERFACE_PCI(wdc_cp->ch_channel)) { |
665 | /* native mode with irq 14/15 requested? */ |
666 | if (compat_nat_enable != NULL && |
667 | prop_bool_true(compat_nat_enable)) |
668 | via_mapregs_compat_native(pa, cp); |
669 | else |
670 | pciide_mapregs_native(pa, cp, pci_intr); |
671 | } else { |
672 | pciide_mapregs_compat(pa, cp, wdc_cp->ch_channel); |
673 | if ((cp->ata_channel.ch_flags & ATACH_DISABLED) == 0) |
674 | pciide_map_compat_intr(pa, cp, wdc_cp->ch_channel); |
675 | } |
676 | wdcattach(wdc_cp); |
677 | } |
678 | |
679 | /* |
680 | * At least under certain (mis)configurations (e.g. on the "Pegasos" board) |
681 | * the VT8231-IDE's native mode only works with irq 14/15, and cannot be |
682 | * programmed to use a single native PCI irq alone. So we install an interrupt |
683 | * handler for each channel, as in compatibility mode. |
684 | */ |
685 | static void |
686 | via_mapregs_compat_native(const struct pci_attach_args *pa, |
687 | struct pciide_channel *cp) |
688 | { |
689 | struct ata_channel *wdc_cp; |
690 | struct pciide_softc *sc; |
691 | |
692 | wdc_cp = &cp->ata_channel; |
693 | sc = CHAN_TO_PCIIDE(&cp->ata_channel); |
694 | |
695 | /* XXX prevent pciide_mapregs_native from installing a handler */ |
696 | if (sc->sc_pci_ih == NULL) |
697 | sc->sc_pci_ih = (void *)~0; |
698 | pciide_mapregs_native(pa, cp, NULL); |
699 | |
700 | /* interrupts are fixed to 14/15, as in compatibility mode */ |
701 | cp->compat = 1; |
702 | if ((wdc_cp->ch_flags & ATACH_DISABLED) == 0) { |
703 | #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH |
704 | cp->ih = pciide_machdep_compat_intr_establish( |
705 | sc->sc_wdcdev.sc_atac.atac_dev, pa, wdc_cp->ch_channel, |
706 | pciide_compat_intr, cp); |
707 | if (cp->ih == NULL) { |
708 | #endif |
709 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
710 | "no compatibility interrupt for " |
711 | "use by %s channel\n" , cp->name); |
712 | wdc_cp->ch_flags |= ATACH_DISABLED; |
713 | #ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_ESTABLISH |
714 | } |
715 | sc->sc_pci_ih = cp->ih; /* XXX */ |
716 | #endif |
717 | } |
718 | } |
719 | |
720 | static void |
721 | via_setup_channel(struct ata_channel *chp) |
722 | { |
723 | u_int32_t udmatim_reg, datatim_reg; |
724 | u_int8_t idedma_ctl; |
725 | int mode, drive, s; |
726 | struct ata_drive_datas *drvp; |
727 | struct atac_softc *atac = chp->ch_atac; |
728 | struct pciide_channel *cp = CHAN_TO_PCHAN(chp); |
729 | struct pciide_softc *sc = CHAN_TO_PCIIDE(chp); |
730 | #ifndef PCIIDE_AMD756_ENABLEDMA |
731 | int rev = PCI_REVISION( |
732 | pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG)); |
733 | #endif |
734 | |
735 | idedma_ctl = 0; |
736 | datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)); |
737 | udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc)); |
738 | datatim_reg &= ~APO_DATATIM_MASK(chp->ch_channel); |
739 | udmatim_reg &= ~APO_UDMA_MASK(chp->ch_channel); |
740 | |
741 | /* setup DMA if needed */ |
742 | pciide_channel_dma_setup(cp); |
743 | |
744 | for (drive = 0; drive < 2; drive++) { |
745 | drvp = &chp->ch_drive[drive]; |
746 | /* If no drive, skip */ |
747 | if (drvp->drive_type == ATA_DRIVET_NONE) |
748 | continue; |
749 | /* add timing values, setup DMA if needed */ |
750 | if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && |
751 | (drvp->drive_flags & ATA_DRIVE_UDMA) == 0)) { |
752 | mode = drvp->PIO_mode; |
753 | goto pio; |
754 | } |
755 | if ((atac->atac_cap & ATAC_CAP_UDMA) && |
756 | (drvp->drive_flags & ATA_DRIVE_UDMA)) { |
757 | /* use Ultra/DMA */ |
758 | s = splbio(); |
759 | drvp->drive_flags &= ~ATA_DRIVE_DMA; |
760 | splx(s); |
761 | udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) | |
762 | APO_UDMA_EN_MTH(chp->ch_channel, drive); |
763 | switch (PCI_VENDOR(sc->sc_pci_id)) { |
764 | case PCI_VENDOR_VIATECH: |
765 | if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 6) { |
766 | /* 8233a */ |
767 | udmatim_reg |= APO_UDMA_TIME( |
768 | chp->ch_channel, |
769 | drive, |
770 | via_udma133_tim[drvp->UDMA_mode]); |
771 | } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 5) { |
772 | /* 686b */ |
773 | udmatim_reg |= APO_UDMA_TIME( |
774 | chp->ch_channel, |
775 | drive, |
776 | via_udma100_tim[drvp->UDMA_mode]); |
777 | } else if (sc->sc_wdcdev.sc_atac.atac_udma_cap == 4) { |
778 | /* 596b or 686a */ |
779 | udmatim_reg |= APO_UDMA_CLK66( |
780 | chp->ch_channel); |
781 | udmatim_reg |= APO_UDMA_TIME( |
782 | chp->ch_channel, |
783 | drive, |
784 | via_udma66_tim[drvp->UDMA_mode]); |
785 | } else { |
786 | /* 596a or 586b */ |
787 | udmatim_reg |= APO_UDMA_TIME( |
788 | chp->ch_channel, |
789 | drive, |
790 | via_udma33_tim[drvp->UDMA_mode]); |
791 | } |
792 | break; |
793 | case PCI_VENDOR_AMD: |
794 | case PCI_VENDOR_NVIDIA: |
795 | udmatim_reg |= APO_UDMA_TIME(chp->ch_channel, |
796 | drive, amd7x6_udma_tim[drvp->UDMA_mode]); |
797 | break; |
798 | } |
799 | /* can use PIO timings, MW DMA unused */ |
800 | mode = drvp->PIO_mode; |
801 | } else { |
802 | /* use Multiword DMA, but only if revision is OK */ |
803 | s = splbio(); |
804 | drvp->drive_flags &= ~ATA_DRIVE_UDMA; |
805 | splx(s); |
806 | #ifndef PCIIDE_AMD756_ENABLEDMA |
807 | /* |
808 | * The workaround doesn't seem to be necessary |
809 | * with all drives, so it can be disabled by |
810 | * PCIIDE_AMD756_ENABLEDMA. It causes a hard hang if |
811 | * triggered. |
812 | */ |
813 | if (PCI_VENDOR(sc->sc_pci_id) == PCI_VENDOR_AMD && |
814 | sc->sc_pp->ide_product == |
815 | PCI_PRODUCT_AMD_PBC756_IDE && |
816 | AMD756_CHIPREV_DISABLEDMA(rev)) { |
817 | aprint_normal( |
818 | "%s:%d:%d: multi-word DMA disabled due " |
819 | "to chip revision\n" , |
820 | device_xname( |
821 | sc->sc_wdcdev.sc_atac.atac_dev), |
822 | chp->ch_channel, drive); |
823 | mode = drvp->PIO_mode; |
824 | s = splbio(); |
825 | drvp->drive_flags &= ~ATA_DRIVE_DMA; |
826 | splx(s); |
827 | goto pio; |
828 | } |
829 | #endif |
830 | /* mode = min(pio, dma+2) */ |
831 | if (drvp->PIO_mode <= (drvp->DMA_mode + 2)) |
832 | mode = drvp->PIO_mode; |
833 | else |
834 | mode = drvp->DMA_mode + 2; |
835 | } |
836 | idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); |
837 | |
838 | pio: /* setup PIO mode */ |
839 | if (mode <= 2) { |
840 | drvp->DMA_mode = 0; |
841 | drvp->PIO_mode = 0; |
842 | mode = 0; |
843 | } else { |
844 | drvp->PIO_mode = mode; |
845 | drvp->DMA_mode = mode - 2; |
846 | } |
847 | datatim_reg |= |
848 | APO_DATATIM_PULSE(chp->ch_channel, drive, |
849 | apollo_pio_set[mode]) | |
850 | APO_DATATIM_RECOV(chp->ch_channel, drive, |
851 | apollo_pio_rec[mode]); |
852 | } |
853 | if (idedma_ctl != 0) { |
854 | /* Add software bits in status register */ |
855 | bus_space_write_1(sc->sc_dma_iot, cp->dma_iohs[IDEDMA_CTL], 0, |
856 | idedma_ctl); |
857 | } |
858 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc), datatim_reg); |
859 | pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA(sc), udmatim_reg); |
860 | ATADEBUG_PRINT(("via_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n" , |
861 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM(sc)), |
862 | pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE); |
863 | } |
864 | |
865 | static int |
866 | via_sata_chip_map_common(struct pciide_softc *sc, |
867 | const struct pci_attach_args *cpa) |
868 | { |
869 | pcireg_t csr; |
870 | int maptype, ret; |
871 | struct pci_attach_args pac, *pa = &pac; |
872 | |
873 | pac = *cpa; |
874 | |
875 | if (pciide_chipen(sc, pa) == 0) |
876 | return 0; |
877 | |
878 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
879 | "bus-master DMA support present" ); |
880 | pciide_mapreg_dma(sc, pa); |
881 | aprint_verbose("\n" ); |
882 | |
883 | if (sc->sc_dma_ok) { |
884 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA | ATAC_CAP_DMA; |
885 | sc->sc_wdcdev.irqack = pciide_irqack; |
886 | } |
887 | sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; |
888 | sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; |
889 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
890 | |
891 | sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; |
892 | sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; |
893 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; |
894 | sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; |
895 | sc->sc_wdcdev.wdc_maxdrives = 2; |
896 | |
897 | if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && |
898 | PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) |
899 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_RAID; |
900 | |
901 | wdc_allocate_regs(&sc->sc_wdcdev); |
902 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, |
903 | PCI_MAPREG_START + 0x14); |
904 | switch(maptype) { |
905 | case PCI_MAPREG_TYPE_IO: |
906 | ret = pci_mapreg_map(pa, PCI_MAPREG_START + 0x14, |
907 | PCI_MAPREG_TYPE_IO, 0, &sc->sc_ba5_st, &sc->sc_ba5_sh, |
908 | NULL, &sc->sc_ba5_ss); |
909 | break; |
910 | case PCI_MAPREG_MEM_TYPE_32BIT: |
911 | /* |
912 | * Enable memory-space access if it isn't already there. |
913 | */ |
914 | csr = pci_conf_read(pa->pa_pc, pa->pa_tag, |
915 | PCI_COMMAND_STATUS_REG); |
916 | if ((csr & PCI_COMMAND_MEM_ENABLE) == 0 && |
917 | (pa->pa_flags & PCI_FLAGS_MEM_OKAY) != 0) { |
918 | |
919 | pci_conf_write(pa->pa_pc, pa->pa_tag, |
920 | PCI_COMMAND_STATUS_REG, |
921 | csr | PCI_COMMAND_MEM_ENABLE); |
922 | } |
923 | |
924 | ret = pci_mapreg_map(pa, PCI_MAPREG_START + 0x14, |
925 | PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, |
926 | 0, &sc->sc_ba5_st, &sc->sc_ba5_sh, |
927 | NULL, &sc->sc_ba5_ss); |
928 | break; |
929 | default: |
930 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
931 | "couldn't map sata regs, unsupported maptype (0x%x)\n" , |
932 | maptype); |
933 | return 0; |
934 | } |
935 | if (ret != 0) { |
936 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
937 | "couldn't map sata regs\n" ); |
938 | return 0; |
939 | } |
940 | return 1; |
941 | } |
942 | |
943 | static void |
944 | via_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa, |
945 | int satareg_shift) |
946 | { |
947 | struct pciide_channel *cp; |
948 | struct ata_channel *wdc_cp; |
949 | struct wdc_regs *wdr; |
950 | pcireg_t interface; |
951 | int channel; |
952 | |
953 | interface = PCI_INTERFACE(pa->pa_class); |
954 | |
955 | if (via_sata_chip_map_common(sc, pa) == 0) |
956 | return; |
957 | |
958 | if (interface == 0) { |
959 | ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n" ), |
960 | DEBUG_PROBE); |
961 | interface = PCIIDE_INTERFACE_BUS_MASTER_DMA | |
962 | PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); |
963 | } |
964 | |
965 | sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; |
966 | sc->sc_wdcdev.wdc_maxdrives = 1; |
967 | for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; |
968 | channel++) { |
969 | cp = &sc->pciide_channels[channel]; |
970 | if (pciide_chansetup(sc, channel, interface) == 0) |
971 | continue; |
972 | wdc_cp = &cp->ata_channel; |
973 | wdr = CHAN_TO_WDC_REGS(wdc_cp); |
974 | wdr->sata_iot = sc->sc_ba5_st; |
975 | wdr->sata_baseioh = sc->sc_ba5_sh; |
976 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
977 | (wdc_cp->ch_channel << satareg_shift) + 0x0, 4, |
978 | &wdr->sata_status) != 0) { |
979 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
980 | "couldn't map channel %d sata_status regs\n" , |
981 | wdc_cp->ch_channel); |
982 | continue; |
983 | } |
984 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
985 | (wdc_cp->ch_channel << satareg_shift) + 0x4, 4, |
986 | &wdr->sata_error) != 0) { |
987 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
988 | "couldn't map channel %d sata_error regs\n" , |
989 | wdc_cp->ch_channel); |
990 | continue; |
991 | } |
992 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
993 | (wdc_cp->ch_channel << satareg_shift) + 0x8, 4, |
994 | &wdr->sata_control) != 0) { |
995 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
996 | "couldn't map channel %d sata_control regs\n" , |
997 | wdc_cp->ch_channel); |
998 | continue; |
999 | } |
1000 | pciide_mapchan(pa, cp, interface, pciide_pci_intr); |
1001 | } |
1002 | } |
1003 | |
1004 | static void |
1005 | via_sata_chip_map_6(struct pciide_softc *sc, const struct pci_attach_args *pa) |
1006 | { |
1007 | via_sata_chip_map(sc, pa, 6); |
1008 | } |
1009 | |
1010 | static void |
1011 | via_sata_chip_map_7(struct pciide_softc *sc, const struct pci_attach_args *pa) |
1012 | { |
1013 | via_sata_chip_map(sc, pa, 7); |
1014 | } |
1015 | |
1016 | static void |
1017 | via_vt6421_mapreg_dma(struct pciide_softc *sc, const struct pci_attach_args *pa) |
1018 | { |
1019 | struct pciide_channel *pc; |
1020 | int chan, reg; |
1021 | bus_size_t size; |
1022 | |
1023 | sc->sc_dma_ok = (pci_mapreg_map(pa, PCIIDE_REG_BUS_MASTER_DMA, |
1024 | PCI_MAPREG_TYPE_IO, 0, &sc->sc_dma_iot, &sc->sc_dma_ioh, |
1025 | NULL, &sc->sc_dma_ios) == 0); |
1026 | sc->sc_dmat = pa->pa_dmat; |
1027 | if (sc->sc_dma_ok == 0) { |
1028 | aprint_verbose(", but unused (couldn't map registers)" ); |
1029 | } else { |
1030 | sc->sc_wdcdev.dma_arg = sc; |
1031 | sc->sc_wdcdev.dma_init = pciide_dma_init; |
1032 | sc->sc_wdcdev.dma_start = pciide_dma_start; |
1033 | sc->sc_wdcdev.dma_finish = pciide_dma_finish; |
1034 | } |
1035 | |
1036 | if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags & |
1037 | PCIIDE_OPTIONS_NODMA) { |
1038 | aprint_verbose( |
1039 | ", but unused (forced off by config file)" ); |
1040 | sc->sc_dma_ok = 0; |
1041 | } |
1042 | |
1043 | if (sc->sc_dma_ok == 0) |
1044 | return; |
1045 | |
1046 | for (chan = 0; chan < 4; chan++) { |
1047 | pc = &sc->pciide_channels[chan]; |
1048 | for (reg = 0; reg < IDEDMA_NREGS; reg++) { |
1049 | size = 4; |
1050 | if (size > (IDEDMA_SCH_OFFSET - reg)) |
1051 | size = IDEDMA_SCH_OFFSET - reg; |
1052 | if (bus_space_subregion(sc->sc_dma_iot, sc->sc_dma_ioh, |
1053 | IDEDMA_SCH_OFFSET * chan + reg, size, |
1054 | &pc->dma_iohs[reg]) != 0) { |
1055 | sc->sc_dma_ok = 0; |
1056 | aprint_verbose(", but can't subregion offset " |
1057 | "%d size %lu" , |
1058 | reg, (u_long)size); |
1059 | return; |
1060 | } |
1061 | } |
1062 | } |
1063 | } |
1064 | |
1065 | static int |
1066 | via_vt6421_chansetup(struct pciide_softc *sc, int channel) |
1067 | { |
1068 | struct pciide_channel *cp = &sc->pciide_channels[channel]; |
1069 | |
1070 | sc->wdc_chanarray[channel] = &cp->ata_channel; |
1071 | |
1072 | cp->ata_channel.ch_channel = channel; |
1073 | cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; |
1074 | cp->ata_channel.ch_queue = |
1075 | malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); |
1076 | if (cp->ata_channel.ch_queue == NULL) { |
1077 | aprint_error("%s channel %d: " |
1078 | "can't allocate memory for command queue" , |
1079 | device_xname(sc->sc_wdcdev.sc_atac.atac_dev), channel); |
1080 | return 0; |
1081 | } |
1082 | return 1; |
1083 | } |
1084 | |
1085 | static void |
1086 | via_sata_chip_map_new(struct pciide_softc *sc, |
1087 | const struct pci_attach_args *pa) |
1088 | { |
1089 | struct pciide_channel *cp; |
1090 | struct ata_channel *wdc_cp; |
1091 | struct wdc_regs *wdr; |
1092 | int channel; |
1093 | pci_intr_handle_t intrhandle; |
1094 | const char *intrstr; |
1095 | int i; |
1096 | char intrbuf[PCI_INTRSTR_LEN]; |
1097 | |
1098 | if (pciide_chipen(sc, pa) == 0) |
1099 | return; |
1100 | |
1101 | sc->sc_apo_regbase = APO_VIA_VT6421_REGBASE; |
1102 | |
1103 | if (pci_mapreg_map(pa, PCI_BAR(5), PCI_MAPREG_TYPE_IO, 0, |
1104 | &sc->sc_ba5_st, &sc->sc_ba5_sh, NULL, &sc->sc_ba5_ss) != 0) { |
1105 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1106 | "couldn't map SATA regs\n" ); |
1107 | } |
1108 | |
1109 | aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1110 | "bus-master DMA support present" ); |
1111 | via_vt6421_mapreg_dma(sc, pa); |
1112 | aprint_verbose("\n" ); |
1113 | |
1114 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; |
1115 | sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; |
1116 | if (sc->sc_dma_ok) { |
1117 | sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA; |
1118 | sc->sc_wdcdev.irqack = pciide_irqack; |
1119 | sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; |
1120 | sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; |
1121 | } |
1122 | sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; |
1123 | |
1124 | sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; |
1125 | sc->sc_wdcdev.sc_atac.atac_nchannels = 3; |
1126 | sc->sc_wdcdev.wdc_maxdrives = 2; |
1127 | |
1128 | wdc_allocate_regs(&sc->sc_wdcdev); |
1129 | |
1130 | if (pci_intr_map(pa, &intrhandle) != 0) { |
1131 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1132 | "couldn't map native-PCI interrupt\n" ); |
1133 | return; |
1134 | } |
1135 | intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf)); |
1136 | sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, |
1137 | intrhandle, IPL_BIO, pciide_pci_intr, sc); |
1138 | if (sc->sc_pci_ih == NULL) { |
1139 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1140 | "couldn't establish native-PCI interrupt" ); |
1141 | if (intrstr != NULL) |
1142 | aprint_error(" at %s" , intrstr); |
1143 | aprint_error("\n" ); |
1144 | return; |
1145 | } |
1146 | aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1147 | "using %s for native-PCI interrupt\n" , |
1148 | intrstr ? intrstr : "unknown interrupt" ); |
1149 | |
1150 | for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; |
1151 | channel++) { |
1152 | cp = &sc->pciide_channels[channel]; |
1153 | if (via_vt6421_chansetup(sc, channel) == 0) |
1154 | continue; |
1155 | wdc_cp = &cp->ata_channel; |
1156 | wdr = CHAN_TO_WDC_REGS(wdc_cp); |
1157 | |
1158 | wdr->sata_iot = sc->sc_ba5_st; |
1159 | wdr->sata_baseioh = sc->sc_ba5_sh; |
1160 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
1161 | (wdc_cp->ch_channel << 6) + 0x0, 4, |
1162 | &wdr->sata_status) != 0) { |
1163 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1164 | "couldn't map channel %d sata_status regs\n" , |
1165 | wdc_cp->ch_channel); |
1166 | continue; |
1167 | } |
1168 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
1169 | (wdc_cp->ch_channel << 6) + 0x4, 4, |
1170 | &wdr->sata_error) != 0) { |
1171 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1172 | "couldn't map channel %d sata_error regs\n" , |
1173 | wdc_cp->ch_channel); |
1174 | continue; |
1175 | } |
1176 | if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh, |
1177 | (wdc_cp->ch_channel << 6) + 0x8, 4, |
1178 | &wdr->sata_control) != 0) { |
1179 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1180 | "couldn't map channel %d sata_control regs\n" , |
1181 | wdc_cp->ch_channel); |
1182 | continue; |
1183 | } |
1184 | |
1185 | if (pci_mapreg_map(pa, PCI_BAR(wdc_cp->ch_channel), |
1186 | PCI_MAPREG_TYPE_IO, 0, &wdr->cmd_iot, &wdr->cmd_baseioh, |
1187 | NULL, &wdr->cmd_ios) != 0) { |
1188 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1189 | "couldn't map %s channel regs\n" , cp->name); |
1190 | } |
1191 | wdr->ctl_iot = wdr->cmd_iot; |
1192 | for (i = 0; i < WDC_NREG; i++) { |
1193 | if (bus_space_subregion(wdr->cmd_iot, |
1194 | wdr->cmd_baseioh, i, i == 0 ? 4 : 1, |
1195 | &wdr->cmd_iohs[i]) != 0) { |
1196 | aprint_error_dev( |
1197 | sc->sc_wdcdev.sc_atac.atac_dev, |
1198 | "couldn't subregion %s " |
1199 | "channel cmd regs\n" , cp->name); |
1200 | return; |
1201 | } |
1202 | } |
1203 | if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, |
1204 | WDC_NREG + 2, 1, &wdr->ctl_ioh) != 0) { |
1205 | aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev, |
1206 | "couldn't map channel %d ctl regs\n" , channel); |
1207 | return; |
1208 | } |
1209 | wdc_init_shadow_regs(wdc_cp); |
1210 | wdr->data32iot = wdr->cmd_iot; |
1211 | wdr->data32ioh = wdr->cmd_iohs[wd_data]; |
1212 | wdcattach(wdc_cp); |
1213 | } |
1214 | } |
1215 | |