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