1a1917f14Szrj /*-
2a1917f14Szrj * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
3a1917f14Szrj * All rights reserved.
4a1917f14Szrj *
5a1917f14Szrj * Redistribution and use in source and binary forms, with or without
6a1917f14Szrj * modification, are permitted provided that the following conditions
7a1917f14Szrj * are met:
8a1917f14Szrj * 1. Redistributions of source code must retain the above copyright
9a1917f14Szrj * notice, this list of conditions and the following disclaimer,
10a1917f14Szrj * without modification, immediately at the beginning of the file.
11a1917f14Szrj * 2. Redistributions in binary form must reproduce the above copyright
12a1917f14Szrj * notice, this list of conditions and the following disclaimer in the
13a1917f14Szrj * documentation and/or other materials provided with the distribution.
14a1917f14Szrj *
15a1917f14Szrj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16a1917f14Szrj * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17a1917f14Szrj * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18a1917f14Szrj * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19a1917f14Szrj * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20a1917f14Szrj * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21a1917f14Szrj * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22a1917f14Szrj * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23a1917f14Szrj * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24a1917f14Szrj * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25a1917f14Szrj */
26a1917f14Szrj
27a1917f14Szrj /* local prototypes */
28a1917f14Szrj static int ata_nvidia_chipinit(device_t dev);
29a1917f14Szrj static int ata_nvidia_allocate(device_t dev);
30a1917f14Szrj static int ata_nvidia_status(device_t dev);
31a1917f14Szrj static void ata_nvidia_reset(device_t dev);
324b582042Szrj static void ata_nvidia_setmode(device_t dev, int mode);
33a1917f14Szrj
34853eb30dSzrj /* misc defines */
35853eb30dSzrj #define NV4 0x01
36853eb30dSzrj #define NVQ 0x02
37*560012aaSzrj #define NVAHCI 0x04
38853eb30dSzrj
39a1917f14Szrj /*
40a1917f14Szrj * nVidia chipset support functions
41a1917f14Szrj */
42a1917f14Szrj int
ata_nvidia_ident(device_t dev)43a1917f14Szrj ata_nvidia_ident(device_t dev)
44a1917f14Szrj {
45a1917f14Szrj struct ata_pci_controller *ctlr = device_get_softc(dev);
4659503772Szrj static const struct ata_chip_id ids[] =
47d6d06c59Szrj {{ ATA_NFORCE1, 0, 0, 0, ATA_UDMA5, "nForce" },
48d6d06c59Szrj { ATA_NFORCE2, 0, 0, 0, ATA_UDMA6, "nForce2" },
49d6d06c59Szrj { ATA_NFORCE2_PRO, 0, 0, 0, ATA_UDMA6, "nForce2 Pro" },
50a1917f14Szrj { ATA_NFORCE2_PRO_S1, 0, 0, 0, ATA_SA150, "nForce2 Pro" },
51d6d06c59Szrj { ATA_NFORCE3, 0, 0, 0, ATA_UDMA6, "nForce3" },
52d6d06c59Szrj { ATA_NFORCE3_PRO, 0, 0, 0, ATA_UDMA6, "nForce3 Pro" },
53a1917f14Szrj { ATA_NFORCE3_PRO_S1, 0, 0, 0, ATA_SA150, "nForce3 Pro" },
54a1917f14Szrj { ATA_NFORCE3_PRO_S2, 0, 0, 0, ATA_SA150, "nForce3 Pro" },
55d6d06c59Szrj { ATA_NFORCE_MCP04, 0, 0, 0, ATA_UDMA6, "nForce MCP" },
56d0fd322fSzrj { ATA_NFORCE_MCP04_S1, 0, NV4, 0, ATA_SA150, "nForce MCP" },
57d0fd322fSzrj { ATA_NFORCE_MCP04_S2, 0, NV4, 0, ATA_SA150, "nForce MCP" },
58d6d06c59Szrj { ATA_NFORCE_CK804, 0, 0, 0, ATA_UDMA6, "nForce CK804" },
59d0fd322fSzrj { ATA_NFORCE_CK804_S1, 0, NV4, 0, ATA_SA300, "nForce CK804" },
60d0fd322fSzrj { ATA_NFORCE_CK804_S2, 0, NV4, 0, ATA_SA300, "nForce CK804" },
61d6d06c59Szrj { ATA_NFORCE_MCP51, 0, 0, 0, ATA_UDMA6, "nForce MCP51" },
62d0fd322fSzrj { ATA_NFORCE_MCP51_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP51" },
63d0fd322fSzrj { ATA_NFORCE_MCP51_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP51" },
64d6d06c59Szrj { ATA_NFORCE_MCP55, 0, 0, 0, ATA_UDMA6, "nForce MCP55" },
65d0fd322fSzrj { ATA_NFORCE_MCP55_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP55" },
66d0fd322fSzrj { ATA_NFORCE_MCP55_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP55" },
67d6d06c59Szrj { ATA_NFORCE_MCP61, 0, 0, 0, ATA_UDMA6, "nForce MCP61" },
68d0fd322fSzrj { ATA_NFORCE_MCP61_S1, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
69d0fd322fSzrj { ATA_NFORCE_MCP61_S2, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
70d0fd322fSzrj { ATA_NFORCE_MCP61_S3, 0, NV4|NVQ, 0, ATA_SA300, "nForce MCP61" },
71d6d06c59Szrj { ATA_NFORCE_MCP65, 0, 0, 0, ATA_UDMA6, "nForce MCP65" },
72*560012aaSzrj { ATA_NFORCE_MCP65_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
73*560012aaSzrj { ATA_NFORCE_MCP65_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
74*560012aaSzrj { ATA_NFORCE_MCP65_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
75*560012aaSzrj { ATA_NFORCE_MCP65_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
76*560012aaSzrj { ATA_NFORCE_MCP65_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
77*560012aaSzrj { ATA_NFORCE_MCP65_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
78*560012aaSzrj { ATA_NFORCE_MCP65_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
79*560012aaSzrj { ATA_NFORCE_MCP65_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP65" },
80d6d06c59Szrj { ATA_NFORCE_MCP67, 0, 0, 0, ATA_UDMA6, "nForce MCP67" },
81*560012aaSzrj { ATA_NFORCE_MCP67_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
82*560012aaSzrj { ATA_NFORCE_MCP67_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
83*560012aaSzrj { ATA_NFORCE_MCP67_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
84*560012aaSzrj { ATA_NFORCE_MCP67_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
85*560012aaSzrj { ATA_NFORCE_MCP67_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
86*560012aaSzrj { ATA_NFORCE_MCP67_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
87*560012aaSzrj { ATA_NFORCE_MCP67_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
88*560012aaSzrj { ATA_NFORCE_MCP67_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
89*560012aaSzrj { ATA_NFORCE_MCP67_A8, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
90*560012aaSzrj { ATA_NFORCE_MCP67_A9, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
91*560012aaSzrj { ATA_NFORCE_MCP67_AA, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
92*560012aaSzrj { ATA_NFORCE_MCP67_AB, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
93*560012aaSzrj { ATA_NFORCE_MCP67_AC, 0, NVAHCI, 0, ATA_SA300, "nForce MCP67" },
94d6d06c59Szrj { ATA_NFORCE_MCP73, 0, 0, 0, ATA_UDMA6, "nForce MCP73" },
95*560012aaSzrj { ATA_NFORCE_MCP73_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
96*560012aaSzrj { ATA_NFORCE_MCP73_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
97*560012aaSzrj { ATA_NFORCE_MCP73_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
98*560012aaSzrj { ATA_NFORCE_MCP73_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
99*560012aaSzrj { ATA_NFORCE_MCP73_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
100*560012aaSzrj { ATA_NFORCE_MCP73_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
101*560012aaSzrj { ATA_NFORCE_MCP73_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
102*560012aaSzrj { ATA_NFORCE_MCP73_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
103*560012aaSzrj { ATA_NFORCE_MCP73_A8, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
104*560012aaSzrj { ATA_NFORCE_MCP73_A9, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
105*560012aaSzrj { ATA_NFORCE_MCP73_AA, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
106*560012aaSzrj { ATA_NFORCE_MCP73_AB, 0, NVAHCI, 0, ATA_SA300, "nForce MCP73" },
107d6d06c59Szrj { ATA_NFORCE_MCP77, 0, 0, 0, ATA_UDMA6, "nForce MCP77" },
108*560012aaSzrj { ATA_NFORCE_MCP77_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
109*560012aaSzrj { ATA_NFORCE_MCP77_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
110*560012aaSzrj { ATA_NFORCE_MCP77_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
111*560012aaSzrj { ATA_NFORCE_MCP77_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
112*560012aaSzrj { ATA_NFORCE_MCP77_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
113*560012aaSzrj { ATA_NFORCE_MCP77_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
114*560012aaSzrj { ATA_NFORCE_MCP77_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
115*560012aaSzrj { ATA_NFORCE_MCP77_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
116*560012aaSzrj { ATA_NFORCE_MCP77_A8, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
117*560012aaSzrj { ATA_NFORCE_MCP77_A9, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
118*560012aaSzrj { ATA_NFORCE_MCP77_AA, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
119*560012aaSzrj { ATA_NFORCE_MCP77_AB, 0, NVAHCI, 0, ATA_SA300, "nForce MCP77" },
120*560012aaSzrj { ATA_NFORCE_MCP79_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
121*560012aaSzrj { ATA_NFORCE_MCP79_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
122*560012aaSzrj { ATA_NFORCE_MCP79_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
123*560012aaSzrj { ATA_NFORCE_MCP79_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
124*560012aaSzrj { ATA_NFORCE_MCP79_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
125*560012aaSzrj { ATA_NFORCE_MCP79_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
126*560012aaSzrj { ATA_NFORCE_MCP79_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
127*560012aaSzrj { ATA_NFORCE_MCP79_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
128*560012aaSzrj { ATA_NFORCE_MCP79_A8, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
129*560012aaSzrj { ATA_NFORCE_MCP79_A9, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
130*560012aaSzrj { ATA_NFORCE_MCP79_AA, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
131*560012aaSzrj { ATA_NFORCE_MCP79_AB, 0, NVAHCI, 0, ATA_SA300, "nForce MCP79" },
132*560012aaSzrj { ATA_NFORCE_MCP89_A0, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
133*560012aaSzrj { ATA_NFORCE_MCP89_A1, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
134*560012aaSzrj { ATA_NFORCE_MCP89_A2, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
135*560012aaSzrj { ATA_NFORCE_MCP89_A3, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
136*560012aaSzrj { ATA_NFORCE_MCP89_A4, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
137*560012aaSzrj { ATA_NFORCE_MCP89_A5, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
138*560012aaSzrj { ATA_NFORCE_MCP89_A6, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
139*560012aaSzrj { ATA_NFORCE_MCP89_A7, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
140*560012aaSzrj { ATA_NFORCE_MCP89_A8, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
141*560012aaSzrj { ATA_NFORCE_MCP89_A9, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
142*560012aaSzrj { ATA_NFORCE_MCP89_AA, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
143*560012aaSzrj { ATA_NFORCE_MCP89_AB, 0, NVAHCI, 0, ATA_SA300, "nForce MCP89" },
144a1917f14Szrj { 0, 0, 0, 0, 0, 0}} ;
145a1917f14Szrj
14659503772Szrj if (pci_get_vendor(dev) != ATA_NVIDIA_ID)
147a1917f14Szrj return ENXIO;
148a1917f14Szrj
14959503772Szrj if (!(ctlr->chip = ata_match_chip(dev, ids)))
15059503772Szrj return ENXIO;
15159503772Szrj
15259503772Szrj ata_set_desc(dev);
153*560012aaSzrj if (ctlr->chip->cfg1 & NVAHCI)
154*560012aaSzrj ctlr->chipinit = ata_ahci_chipinit;
155*560012aaSzrj else
156a1917f14Szrj ctlr->chipinit = ata_nvidia_chipinit;
157a1917f14Szrj return 0;
158a1917f14Szrj }
159a1917f14Szrj
160a1917f14Szrj static int
ata_nvidia_chipinit(device_t dev)161a1917f14Szrj ata_nvidia_chipinit(device_t dev)
162a1917f14Szrj {
163a1917f14Szrj struct ata_pci_controller *ctlr = device_get_softc(dev);
164a1917f14Szrj
16543156ad7Szrj if (ata_setup_interrupt(dev, ata_generic_intr))
166a1917f14Szrj return ENXIO;
167a1917f14Szrj
168a1917f14Szrj if (ctlr->chip->max_dma >= ATA_SA150) {
169a1917f14Szrj if (pci_read_config(dev, PCIR_BAR(5), 1) & 1)
170a1917f14Szrj ctlr->r_type2 = SYS_RES_IOPORT;
171a1917f14Szrj else
172a1917f14Szrj ctlr->r_type2 = SYS_RES_MEMORY;
173a1917f14Szrj ctlr->r_rid2 = PCIR_BAR(5);
174a1917f14Szrj if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
175a1917f14Szrj &ctlr->r_rid2, RF_ACTIVE))) {
176d0fd322fSzrj int offset = ctlr->chip->cfg1 & NV4 ? 0x0440 : 0x0010;
177a1917f14Szrj
178a1917f14Szrj ctlr->allocate = ata_nvidia_allocate;
179a1917f14Szrj ctlr->reset = ata_nvidia_reset;
180a1917f14Szrj
181a1917f14Szrj /* enable control access */
182a1917f14Szrj pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) | 0x04,1);
183*560012aaSzrj /* MCP55 seems to need some time to allow r_res2 read. */
184*560012aaSzrj DELAY(10);
185d0fd322fSzrj if (ctlr->chip->cfg1 & NVQ) {
186a1917f14Szrj /* clear interrupt status */
187a1917f14Szrj ATA_OUTL(ctlr->r_res2, offset, 0x00ff00ff);
188a1917f14Szrj
189a1917f14Szrj /* enable device and PHY state change interrupts */
190a1917f14Szrj ATA_OUTL(ctlr->r_res2, offset + 4, 0x000d000d);
191a1917f14Szrj
192a1917f14Szrj /* disable NCQ support */
193a1917f14Szrj ATA_OUTL(ctlr->r_res2, 0x0400,
194a1917f14Szrj ATA_INL(ctlr->r_res2, 0x0400) & 0xfffffff9);
195a1917f14Szrj }
196a1917f14Szrj else {
197a1917f14Szrj /* clear interrupt status */
198a1917f14Szrj ATA_OUTB(ctlr->r_res2, offset, 0xff);
199a1917f14Szrj
200a1917f14Szrj /* enable device and PHY state change interrupts */
201a1917f14Szrj ATA_OUTB(ctlr->r_res2, offset + 1, 0xdd);
202a1917f14Szrj }
203a1917f14Szrj
204a1917f14Szrj /* enable PCI interrupt */
205a1917f14Szrj pci_write_config(dev, PCIR_COMMAND,
206a1917f14Szrj pci_read_config(dev, PCIR_COMMAND, 2) & ~0x0400,2);
207a1917f14Szrj
208a1917f14Szrj }
209a1917f14Szrj ctlr->setmode = ata_sata_setmode;
210a1917f14Szrj }
211a1917f14Szrj else {
212a1917f14Szrj /* disable prefetch, postwrite */
213a1917f14Szrj pci_write_config(dev, 0x51, pci_read_config(dev, 0x51, 1) & 0x0f, 1);
2144b582042Szrj ctlr->setmode = ata_nvidia_setmode;
215a1917f14Szrj }
216a1917f14Szrj return 0;
217a1917f14Szrj }
218a1917f14Szrj
219a1917f14Szrj static int
ata_nvidia_allocate(device_t dev)220a1917f14Szrj ata_nvidia_allocate(device_t dev)
221a1917f14Szrj {
222a1917f14Szrj struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
223a1917f14Szrj struct ata_channel *ch = device_get_softc(dev);
224a1917f14Szrj
225a1917f14Szrj /* setup the usual register normal pci style */
226a1917f14Szrj if (ata_pci_allocate(dev))
227a1917f14Szrj return ENXIO;
228a1917f14Szrj
229a1917f14Szrj ch->r_io[ATA_SSTATUS].res = ctlr->r_res2;
230a1917f14Szrj ch->r_io[ATA_SSTATUS].offset = (ch->unit << 6);
231a1917f14Szrj ch->r_io[ATA_SERROR].res = ctlr->r_res2;
232a1917f14Szrj ch->r_io[ATA_SERROR].offset = 0x04 + (ch->unit << 6);
233a1917f14Szrj ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
234a1917f14Szrj ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << 6);
235a1917f14Szrj
236a1917f14Szrj ch->hw.status = ata_nvidia_status;
237a1917f14Szrj ch->flags |= ATA_NO_SLAVE;
238a1917f14Szrj
239a1917f14Szrj return 0;
240a1917f14Szrj }
241a1917f14Szrj
242a1917f14Szrj static int
ata_nvidia_status(device_t dev)243a1917f14Szrj ata_nvidia_status(device_t dev)
244a1917f14Szrj {
245a1917f14Szrj struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
246a1917f14Szrj struct ata_channel *ch = device_get_softc(dev);
247d0fd322fSzrj int offset = ctlr->chip->cfg1 & NV4 ? 0x0440 : 0x0010;
248d0fd322fSzrj int shift = ch->unit << (ctlr->chip->cfg1 & NVQ ? 4 : 2);
249a1917f14Szrj u_int32_t istatus;
250a1917f14Szrj
251a1917f14Szrj /* get interrupt status */
252d0fd322fSzrj if (ctlr->chip->cfg1 & NVQ)
253a1917f14Szrj istatus = ATA_INL(ctlr->r_res2, offset);
254a1917f14Szrj else
255a1917f14Szrj istatus = ATA_INB(ctlr->r_res2, offset);
256a1917f14Szrj
257a1917f14Szrj /* do we have any PHY events ? */
258a1917f14Szrj if (istatus & (0x0c << shift))
259a1917f14Szrj ata_sata_phy_check_events(dev);
260a1917f14Szrj
261a1917f14Szrj /* clear interrupt(s) */
262d0fd322fSzrj if (ctlr->chip->cfg1 & NVQ)
263a1917f14Szrj ATA_OUTL(ctlr->r_res2, offset, (0x0f << shift) | 0x00f000f0);
264a1917f14Szrj else
265a1917f14Szrj ATA_OUTB(ctlr->r_res2, offset, (0x0f << shift));
266a1917f14Szrj
267a1917f14Szrj /* do we have any device action ? */
268a1917f14Szrj return (istatus & (0x01 << shift));
269a1917f14Szrj }
270a1917f14Szrj
271a1917f14Szrj static void
ata_nvidia_reset(device_t dev)272a1917f14Szrj ata_nvidia_reset(device_t dev)
273a1917f14Szrj {
274a1917f14Szrj if (ata_sata_phy_reset(dev))
275a1917f14Szrj ata_generic_reset(dev);
276a1917f14Szrj }
2774b582042Szrj
2784b582042Szrj static void
ata_nvidia_setmode(device_t dev,int mode)2794b582042Szrj ata_nvidia_setmode(device_t dev, int mode)
2804b582042Szrj {
2814b582042Szrj device_t gparent = GRANDPARENT(dev);
2824b582042Szrj struct ata_pci_controller *ctlr = device_get_softc(gparent);
2834b582042Szrj struct ata_channel *ch = device_get_softc(device_get_parent(dev));
2844b582042Szrj struct ata_device *atadev = device_get_softc(dev);
2852458a87aSzrj int devno = (ch->unit << 1) + atadev->unit;
2864b582042Szrj int error;
28759503772Szrj static const uint8_t timings[] =
28859503772Szrj { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
28959503772Szrj 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
29059503772Szrj static const uint8_t modes[] =
29159503772Szrj { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
29259503772Szrj int reg = 0x63 - devno;
2934b582042Szrj
2944b582042Szrj mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
2954b582042Szrj mode = ata_check_80pin(dev, mode);
2964b582042Szrj
2974b582042Szrj error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
2984b582042Szrj if (bootverbose)
2994b582042Szrj device_printf(dev, "%ssetting %s on %s chip\n",
3004b582042Szrj (error) ? "FAILURE " : "", ata_mode2str(mode),
3014b582042Szrj ctlr->chip->text);
3024b582042Szrj if (!error) {
3034b582042Szrj pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1);
3044b582042Szrj if (mode >= ATA_UDMA0)
3054b582042Szrj pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1);
3064b582042Szrj else
3074b582042Szrj pci_write_config(gparent, reg, 0x8b, 1);
3084b582042Szrj atadev->mode = mode;
3094b582042Szrj }
3104b582042Szrj }
311