xref: /openbmc/linux/drivers/ata/pata_hpt37x.c (revision 6ddd6861)
1669a5db4SJeff Garzik /*
2669a5db4SJeff Garzik  * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers.
3669a5db4SJeff Garzik  *
4669a5db4SJeff Garzik  * This driver is heavily based upon:
5669a5db4SJeff Garzik  *
6669a5db4SJeff Garzik  * linux/drivers/ide/pci/hpt366.c		Version 0.36	April 25, 2003
7669a5db4SJeff Garzik  *
8669a5db4SJeff Garzik  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
9669a5db4SJeff Garzik  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
10669a5db4SJeff Garzik  * Portions Copyright (C) 2003		Red Hat Inc
11d44a65f7SSergei Shtylyov  * Portions Copyright (C) 2005-2007	MontaVista Software, Inc.
12669a5db4SJeff Garzik  *
13669a5db4SJeff Garzik  * TODO
14d44a65f7SSergei Shtylyov  *	Look into engine reset on timeout errors. Should not be	required.
15669a5db4SJeff Garzik  */
16669a5db4SJeff Garzik 
17669a5db4SJeff Garzik #include <linux/kernel.h>
18669a5db4SJeff Garzik #include <linux/module.h>
19669a5db4SJeff Garzik #include <linux/pci.h>
20669a5db4SJeff Garzik #include <linux/init.h>
21669a5db4SJeff Garzik #include <linux/blkdev.h>
22669a5db4SJeff Garzik #include <linux/delay.h>
23669a5db4SJeff Garzik #include <scsi/scsi_host.h>
24669a5db4SJeff Garzik #include <linux/libata.h>
25669a5db4SJeff Garzik 
26669a5db4SJeff Garzik #define DRV_NAME	"pata_hpt37x"
276ddd6861SAlan Cox #define DRV_VERSION	"0.6.11"
28669a5db4SJeff Garzik 
29669a5db4SJeff Garzik struct hpt_clock {
30669a5db4SJeff Garzik 	u8	xfer_speed;
31669a5db4SJeff Garzik 	u32	timing;
32669a5db4SJeff Garzik };
33669a5db4SJeff Garzik 
34669a5db4SJeff Garzik struct hpt_chip {
35669a5db4SJeff Garzik 	const char *name;
36669a5db4SJeff Garzik 	unsigned int base;
37669a5db4SJeff Garzik 	struct hpt_clock const *clocks[4];
38669a5db4SJeff Garzik };
39669a5db4SJeff Garzik 
40669a5db4SJeff Garzik /* key for bus clock timings
41669a5db4SJeff Garzik  * bit
42669a5db4SJeff Garzik  * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
43669a5db4SJeff Garzik  *        DMA. cycles = value + 1
44669a5db4SJeff Garzik  * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
45669a5db4SJeff Garzik  *        DMA. cycles = value + 1
46669a5db4SJeff Garzik  * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
47669a5db4SJeff Garzik  *        register access.
48669a5db4SJeff Garzik  * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
49669a5db4SJeff Garzik  *        register access.
50669a5db4SJeff Garzik  * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
51669a5db4SJeff Garzik  *        during task file register access.
52669a5db4SJeff Garzik  * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
53669a5db4SJeff Garzik  *        xfer.
54669a5db4SJeff Garzik  * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
55669a5db4SJeff Garzik  *        register access.
56669a5db4SJeff Garzik  * 28     UDMA enable
57669a5db4SJeff Garzik  * 29     DMA enable
58669a5db4SJeff Garzik  * 30     PIO_MST enable. if set, the chip is in bus master mode during
59669a5db4SJeff Garzik  *        PIO.
60669a5db4SJeff Garzik  * 31     FIFO enable.
61669a5db4SJeff Garzik  */
62669a5db4SJeff Garzik 
63fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_33[] = {
64fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12446231 },	/* 0x12646231 ?? */
65669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12446231 },
66669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12446231 },
67669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x126c6231 },
68669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x12486231 },
69669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x124c6233 },
70669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x12506297 },
71669a5db4SJeff Garzik 
72669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22406c31 },
73669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22406c33 },
74669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x22406c97 },
75669a5db4SJeff Garzik 
76669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x06414e31 },
77669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x06414e42 },
78669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x06414e53 },
79669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x06814e93 },
80fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x06814ea7 }
81669a5db4SJeff Garzik };
82669a5db4SJeff Garzik 
83fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_50[] = {
84fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12848242 },
85669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12848242 },
86669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12ac8242 },
87669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x128c8242 },
88669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x120c8242 },
89669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x12148254 },
90669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x121882ea },
91669a5db4SJeff Garzik 
92669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22808242 },
93669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22808254 },
94669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x228082ea },
95669a5db4SJeff Garzik 
96669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0a81f442 },
97669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0a81f443 },
98669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0a81f454 },
99669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0ac1f465 },
100fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0ac1f48a }
101669a5db4SJeff Garzik };
102669a5db4SJeff Garzik 
103fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_66[] = {
104669a5db4SJeff Garzik 	{ XFER_UDMA_6,		0x1c869c62 },
105fcc2f69aSAlan Cox 	{ XFER_UDMA_5,		0x1cae9c62 },	/* 0x1c8a9c62 */
106669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x1c8a9c62 },
107669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x1c8e9c62 },
108669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x1c929c62 },
109669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x1c9a9c62 },
110669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x1c829c62 },
111669a5db4SJeff Garzik 
112669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x2c829c62 },
113669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x2c829c66 },
114669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x2c829d2e },
115669a5db4SJeff Garzik 
116669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0c829c62 },
117669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0c829c84 },
118669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0c829ca6 },
119669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0d029d26 },
120fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0d029d5e }
121669a5db4SJeff Garzik };
122669a5db4SJeff Garzik 
123669a5db4SJeff Garzik 
124669a5db4SJeff Garzik static const struct hpt_chip hpt370 = {
125669a5db4SJeff Garzik 	"HPT370",
126669a5db4SJeff Garzik 	48,
127669a5db4SJeff Garzik 	{
128fcc2f69aSAlan Cox 		hpt37x_timings_33,
129669a5db4SJeff Garzik 		NULL,
130669a5db4SJeff Garzik 		NULL,
131a4734468SAlan Cox 		NULL
132669a5db4SJeff Garzik 	}
133669a5db4SJeff Garzik };
134669a5db4SJeff Garzik 
135669a5db4SJeff Garzik static const struct hpt_chip hpt370a = {
136669a5db4SJeff Garzik 	"HPT370A",
137669a5db4SJeff Garzik 	48,
138669a5db4SJeff Garzik 	{
139fcc2f69aSAlan Cox 		hpt37x_timings_33,
140669a5db4SJeff Garzik 		NULL,
141fcc2f69aSAlan Cox 		hpt37x_timings_50,
142a4734468SAlan Cox 		NULL
143669a5db4SJeff Garzik 	}
144669a5db4SJeff Garzik };
145669a5db4SJeff Garzik 
146669a5db4SJeff Garzik static const struct hpt_chip hpt372 = {
147669a5db4SJeff Garzik 	"HPT372",
148669a5db4SJeff Garzik 	55,
149669a5db4SJeff Garzik 	{
150fcc2f69aSAlan Cox 		hpt37x_timings_33,
151669a5db4SJeff Garzik 		NULL,
152fcc2f69aSAlan Cox 		hpt37x_timings_50,
153fcc2f69aSAlan Cox 		hpt37x_timings_66
154669a5db4SJeff Garzik 	}
155669a5db4SJeff Garzik };
156669a5db4SJeff Garzik 
157669a5db4SJeff Garzik static const struct hpt_chip hpt302 = {
158669a5db4SJeff Garzik 	"HPT302",
159669a5db4SJeff Garzik 	66,
160669a5db4SJeff Garzik 	{
161fcc2f69aSAlan Cox 		hpt37x_timings_33,
162669a5db4SJeff Garzik 		NULL,
163fcc2f69aSAlan Cox 		hpt37x_timings_50,
164fcc2f69aSAlan Cox 		hpt37x_timings_66
165669a5db4SJeff Garzik 	}
166669a5db4SJeff Garzik };
167669a5db4SJeff Garzik 
168669a5db4SJeff Garzik static const struct hpt_chip hpt371 = {
169669a5db4SJeff Garzik 	"HPT371",
170669a5db4SJeff Garzik 	66,
171669a5db4SJeff Garzik 	{
172fcc2f69aSAlan Cox 		hpt37x_timings_33,
173669a5db4SJeff Garzik 		NULL,
174fcc2f69aSAlan Cox 		hpt37x_timings_50,
175fcc2f69aSAlan Cox 		hpt37x_timings_66
176669a5db4SJeff Garzik 	}
177669a5db4SJeff Garzik };
178669a5db4SJeff Garzik 
179669a5db4SJeff Garzik static const struct hpt_chip hpt372a = {
180669a5db4SJeff Garzik 	"HPT372A",
181669a5db4SJeff Garzik 	66,
182669a5db4SJeff Garzik 	{
183fcc2f69aSAlan Cox 		hpt37x_timings_33,
184669a5db4SJeff Garzik 		NULL,
185fcc2f69aSAlan Cox 		hpt37x_timings_50,
186fcc2f69aSAlan Cox 		hpt37x_timings_66
187669a5db4SJeff Garzik 	}
188669a5db4SJeff Garzik };
189669a5db4SJeff Garzik 
190669a5db4SJeff Garzik static const struct hpt_chip hpt374 = {
191669a5db4SJeff Garzik 	"HPT374",
192669a5db4SJeff Garzik 	48,
193669a5db4SJeff Garzik 	{
194fcc2f69aSAlan Cox 		hpt37x_timings_33,
195669a5db4SJeff Garzik 		NULL,
196669a5db4SJeff Garzik 		NULL,
197669a5db4SJeff Garzik 		NULL
198669a5db4SJeff Garzik 	}
199669a5db4SJeff Garzik };
200669a5db4SJeff Garzik 
201669a5db4SJeff Garzik /**
202669a5db4SJeff Garzik  *	hpt37x_find_mode	-	reset the hpt37x bus
203669a5db4SJeff Garzik  *	@ap: ATA port
204669a5db4SJeff Garzik  *	@speed: transfer mode
205669a5db4SJeff Garzik  *
206669a5db4SJeff Garzik  *	Return the 32bit register programming information for this channel
207669a5db4SJeff Garzik  *	that matches the speed provided.
208669a5db4SJeff Garzik  */
209669a5db4SJeff Garzik 
210669a5db4SJeff Garzik static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
211669a5db4SJeff Garzik {
212669a5db4SJeff Garzik 	struct hpt_clock *clocks = ap->host->private_data;
213669a5db4SJeff Garzik 
214669a5db4SJeff Garzik 	while(clocks->xfer_speed) {
215669a5db4SJeff Garzik 		if (clocks->xfer_speed == speed)
216669a5db4SJeff Garzik 			return clocks->timing;
217669a5db4SJeff Garzik 		clocks++;
218669a5db4SJeff Garzik 	}
219669a5db4SJeff Garzik 	BUG();
220669a5db4SJeff Garzik 	return 0xffffffffU;	/* silence compiler warning */
221669a5db4SJeff Garzik }
222669a5db4SJeff Garzik 
223669a5db4SJeff Garzik static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
224669a5db4SJeff Garzik {
2258bfa79fcSTejun Heo 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
226669a5db4SJeff Garzik 	int i = 0;
227669a5db4SJeff Garzik 
2288bfa79fcSTejun Heo 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
229669a5db4SJeff Garzik 
230669a5db4SJeff Garzik 	while (list[i] != NULL) {
2318bfa79fcSTejun Heo 		if (!strcmp(list[i], model_num)) {
232669a5db4SJeff Garzik 			printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
233669a5db4SJeff Garzik 				modestr, list[i]);
234669a5db4SJeff Garzik 			return 1;
235669a5db4SJeff Garzik 		}
236669a5db4SJeff Garzik 		i++;
237669a5db4SJeff Garzik 	}
238669a5db4SJeff Garzik 	return 0;
239669a5db4SJeff Garzik }
240669a5db4SJeff Garzik 
241669a5db4SJeff Garzik static const char *bad_ata33[] = {
242669a5db4SJeff Garzik 	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
243669a5db4SJeff Garzik 	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
244669a5db4SJeff Garzik 	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
245669a5db4SJeff Garzik 	"Maxtor 90510D4",
246669a5db4SJeff Garzik 	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
247669a5db4SJeff Garzik 	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
248669a5db4SJeff Garzik 	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
249669a5db4SJeff Garzik 	NULL
250669a5db4SJeff Garzik };
251669a5db4SJeff Garzik 
252669a5db4SJeff Garzik static const char *bad_ata100_5[] = {
253669a5db4SJeff Garzik 	"IBM-DTLA-307075",
254669a5db4SJeff Garzik 	"IBM-DTLA-307060",
255669a5db4SJeff Garzik 	"IBM-DTLA-307045",
256669a5db4SJeff Garzik 	"IBM-DTLA-307030",
257669a5db4SJeff Garzik 	"IBM-DTLA-307020",
258669a5db4SJeff Garzik 	"IBM-DTLA-307015",
259669a5db4SJeff Garzik 	"IBM-DTLA-305040",
260669a5db4SJeff Garzik 	"IBM-DTLA-305030",
261669a5db4SJeff Garzik 	"IBM-DTLA-305020",
262669a5db4SJeff Garzik 	"IC35L010AVER07-0",
263669a5db4SJeff Garzik 	"IC35L020AVER07-0",
264669a5db4SJeff Garzik 	"IC35L030AVER07-0",
265669a5db4SJeff Garzik 	"IC35L040AVER07-0",
266669a5db4SJeff Garzik 	"IC35L060AVER07-0",
267669a5db4SJeff Garzik 	"WDC AC310200R",
268669a5db4SJeff Garzik 	NULL
269669a5db4SJeff Garzik };
270669a5db4SJeff Garzik 
271669a5db4SJeff Garzik /**
272669a5db4SJeff Garzik  *	hpt370_filter	-	mode selection filter
273669a5db4SJeff Garzik  *	@adev: ATA device
274669a5db4SJeff Garzik  *
275669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
276669a5db4SJeff Garzik  */
277669a5db4SJeff Garzik 
278a76b62caSAlan Cox static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
279669a5db4SJeff Garzik {
2806929da44SAlan 	if (adev->class == ATA_DEV_ATA) {
281669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
282669a5db4SJeff Garzik 			mask &= ~ATA_MASK_UDMA;
283669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
2846ddd6861SAlan Cox 			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
285669a5db4SJeff Garzik 	}
286a76b62caSAlan Cox 	return ata_pci_default_filter(adev, mask);
287669a5db4SJeff Garzik }
288669a5db4SJeff Garzik 
289669a5db4SJeff Garzik /**
290669a5db4SJeff Garzik  *	hpt370a_filter	-	mode selection filter
291669a5db4SJeff Garzik  *	@adev: ATA device
292669a5db4SJeff Garzik  *
293669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
294669a5db4SJeff Garzik  */
295669a5db4SJeff Garzik 
296a76b62caSAlan Cox static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
297669a5db4SJeff Garzik {
29873946f9fSAlan Cox 	if (adev->class == ATA_DEV_ATA) {
299669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
3006ddd6861SAlan Cox 			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
301669a5db4SJeff Garzik 	}
302a76b62caSAlan Cox 	return ata_pci_default_filter(adev, mask);
303669a5db4SJeff Garzik }
304669a5db4SJeff Garzik 
305669a5db4SJeff Garzik /**
306669a5db4SJeff Garzik  *	hpt37x_pre_reset	-	reset the hpt37x bus
307cc0680a5STejun Heo  *	@link: ATA link to reset
308d4b2bab4STejun Heo  *	@deadline: deadline jiffies for the operation
309669a5db4SJeff Garzik  *
310669a5db4SJeff Garzik  *	Perform the initial reset handling for the 370/372 and 374 func 0
311669a5db4SJeff Garzik  */
312669a5db4SJeff Garzik 
313cc0680a5STejun Heo static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
314669a5db4SJeff Garzik {
315669a5db4SJeff Garzik 	u8 scr2, ata66;
316cc0680a5STejun Heo 	struct ata_port *ap = link->ap;
317669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
318b5bf24b9SAlan Cox 	static const struct pci_bits hpt37x_enable_bits[] = {
319b5bf24b9SAlan Cox 		{ 0x50, 1, 0x04, 0x04 },
320b5bf24b9SAlan Cox 		{ 0x54, 1, 0x04, 0x04 }
321b5bf24b9SAlan Cox 	};
322b5bf24b9SAlan Cox 	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
323b5bf24b9SAlan Cox 		return -ENOENT;
324669a5db4SJeff Garzik 
325669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5B, &scr2);
326669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
327669a5db4SJeff Garzik 	/* Cable register now active */
328669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
329669a5db4SJeff Garzik 	/* Restore state */
330669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2);
331669a5db4SJeff Garzik 
33222d5c760SAlan Cox 	if (ata66 & (2 >> ap->port_no))
333669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
334669a5db4SJeff Garzik 	else
335669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
336669a5db4SJeff Garzik 
337669a5db4SJeff Garzik 	/* Reset the state machine */
338fcc2f69aSAlan Cox 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
339669a5db4SJeff Garzik 	udelay(100);
340669a5db4SJeff Garzik 
341cc0680a5STejun Heo 	return ata_std_prereset(link, deadline);
342669a5db4SJeff Garzik }
343669a5db4SJeff Garzik 
344669a5db4SJeff Garzik /**
345669a5db4SJeff Garzik  *	hpt37x_error_handler	-	reset the hpt374
346669a5db4SJeff Garzik  *	@ap: ATA port to reset
347669a5db4SJeff Garzik  *
348669a5db4SJeff Garzik  *	Perform probe for HPT37x, except for HPT374 channel 2
349669a5db4SJeff Garzik  */
350669a5db4SJeff Garzik 
351669a5db4SJeff Garzik static void hpt37x_error_handler(struct ata_port *ap)
352669a5db4SJeff Garzik {
353669a5db4SJeff Garzik 	ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
354669a5db4SJeff Garzik }
355669a5db4SJeff Garzik 
356cc0680a5STejun Heo static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline)
357669a5db4SJeff Garzik {
358b5bf24b9SAlan Cox 	static const struct pci_bits hpt37x_enable_bits[] = {
359b5bf24b9SAlan Cox 		{ 0x50, 1, 0x04, 0x04 },
360b5bf24b9SAlan Cox 		{ 0x54, 1, 0x04, 0x04 }
361b5bf24b9SAlan Cox 	};
36273946f9fSAlan Cox 	u16 mcr3;
363669a5db4SJeff Garzik 	u8 ata66;
364cc0680a5STejun Heo 	struct ata_port *ap = link->ap;
365669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
36673946f9fSAlan Cox 	unsigned int mcrbase = 0x50 + 4 * ap->port_no;
367b5bf24b9SAlan Cox 
368b5bf24b9SAlan Cox 	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
369b5bf24b9SAlan Cox 		return -ENOENT;
370b5bf24b9SAlan Cox 
371669a5db4SJeff Garzik 	/* Do the extra channel work */
37273946f9fSAlan Cox 	pci_read_config_word(pdev, mcrbase + 2, &mcr3);
373669a5db4SJeff Garzik 	/* Set bit 15 of 0x52 to enable TCBLID as input
374669a5db4SJeff Garzik 	 */
37573946f9fSAlan Cox 	pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000);
376669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
377669a5db4SJeff Garzik 	/* Reset TCBLID/FCBLID to output */
378f941b168SAlan Cox 	pci_write_config_word(pdev, mcrbase + 2, mcr3);
379669a5db4SJeff Garzik 
38073946f9fSAlan Cox 	if (ata66 & (2 >> ap->port_no))
381669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
382669a5db4SJeff Garzik 	else
383669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
384669a5db4SJeff Garzik 
385669a5db4SJeff Garzik 	/* Reset the state machine */
386fcc2f69aSAlan Cox 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
387669a5db4SJeff Garzik 	udelay(100);
388669a5db4SJeff Garzik 
389cc0680a5STejun Heo 	return ata_std_prereset(link, deadline);
390669a5db4SJeff Garzik }
391669a5db4SJeff Garzik 
392669a5db4SJeff Garzik /**
393669a5db4SJeff Garzik  *	hpt374_error_handler	-	reset the hpt374
394669a5db4SJeff Garzik  *	@classes:
395669a5db4SJeff Garzik  *
396669a5db4SJeff Garzik  *	The 374 cable detect is a little different due to the extra
397669a5db4SJeff Garzik  *	channels. The function 0 channels work like usual but function 1
398669a5db4SJeff Garzik  *	is special
399669a5db4SJeff Garzik  */
400669a5db4SJeff Garzik 
401669a5db4SJeff Garzik static void hpt374_error_handler(struct ata_port *ap)
402669a5db4SJeff Garzik {
403669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
404669a5db4SJeff Garzik 
405669a5db4SJeff Garzik 	if (!(PCI_FUNC(pdev->devfn) & 1))
406669a5db4SJeff Garzik 		hpt37x_error_handler(ap);
407669a5db4SJeff Garzik 	else
408669a5db4SJeff Garzik 		ata_bmdma_drive_eh(ap, hpt374_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
409669a5db4SJeff Garzik }
410669a5db4SJeff Garzik 
411669a5db4SJeff Garzik /**
412669a5db4SJeff Garzik  *	hpt370_set_piomode		-	PIO setup
413669a5db4SJeff Garzik  *	@ap: ATA interface
414669a5db4SJeff Garzik  *	@adev: device on the interface
415669a5db4SJeff Garzik  *
416669a5db4SJeff Garzik  *	Perform PIO mode setup.
417669a5db4SJeff Garzik  */
418669a5db4SJeff Garzik 
419669a5db4SJeff Garzik static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
420669a5db4SJeff Garzik {
421669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
422669a5db4SJeff Garzik 	u32 addr1, addr2;
423669a5db4SJeff Garzik 	u32 reg;
424669a5db4SJeff Garzik 	u32 mode;
425669a5db4SJeff Garzik 	u8 fast;
426669a5db4SJeff Garzik 
427669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
428669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
429669a5db4SJeff Garzik 
430669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
431669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
432669a5db4SJeff Garzik 	fast &= ~0x02;
433669a5db4SJeff Garzik 	fast |= 0x01;
434669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
435669a5db4SJeff Garzik 
436669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
437669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
438669a5db4SJeff Garzik 	mode &= ~0x8000000;	/* No FIFO in PIO */
439669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
440669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
441669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
442669a5db4SJeff Garzik }
443669a5db4SJeff Garzik 
444669a5db4SJeff Garzik /**
445669a5db4SJeff Garzik  *	hpt370_set_dmamode		-	DMA timing setup
446669a5db4SJeff Garzik  *	@ap: ATA interface
447669a5db4SJeff Garzik  *	@adev: Device being configured
448669a5db4SJeff Garzik  *
449669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
450669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
451669a5db4SJeff Garzik  */
452669a5db4SJeff Garzik 
453669a5db4SJeff Garzik static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
454669a5db4SJeff Garzik {
455669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
456669a5db4SJeff Garzik 	u32 addr1, addr2;
457669a5db4SJeff Garzik 	u32 reg;
458669a5db4SJeff Garzik 	u32 mode;
459669a5db4SJeff Garzik 	u8 fast;
460669a5db4SJeff Garzik 
461669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
462669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
463669a5db4SJeff Garzik 
464669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
465669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
466669a5db4SJeff Garzik 	fast &= ~0x02;
467669a5db4SJeff Garzik 	fast |= 0x01;
468669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
469669a5db4SJeff Garzik 
470669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
471669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
472669a5db4SJeff Garzik 	mode |= 0x8000000;	/* FIFO in MWDMA or UDMA */
473669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
474669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
475669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
476669a5db4SJeff Garzik }
477669a5db4SJeff Garzik 
478669a5db4SJeff Garzik /**
479669a5db4SJeff Garzik  *	hpt370_bmdma_start		-	DMA engine begin
480669a5db4SJeff Garzik  *	@qc: ATA command
481669a5db4SJeff Garzik  *
482669a5db4SJeff Garzik  *	The 370 and 370A want us to reset the DMA engine each time we
483669a5db4SJeff Garzik  *	use it. The 372 and later are fine.
484669a5db4SJeff Garzik  */
485669a5db4SJeff Garzik 
486669a5db4SJeff Garzik static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
487669a5db4SJeff Garzik {
488669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
489669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
490669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
491669a5db4SJeff Garzik 	udelay(10);
492669a5db4SJeff Garzik 	ata_bmdma_start(qc);
493669a5db4SJeff Garzik }
494669a5db4SJeff Garzik 
495669a5db4SJeff Garzik /**
496669a5db4SJeff Garzik  *	hpt370_bmdma_end		-	DMA engine stop
497669a5db4SJeff Garzik  *	@qc: ATA command
498669a5db4SJeff Garzik  *
499669a5db4SJeff Garzik  *	Work around the HPT370 DMA engine.
500669a5db4SJeff Garzik  */
501669a5db4SJeff Garzik 
502669a5db4SJeff Garzik static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
503669a5db4SJeff Garzik {
504669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
505669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
5060d5ff566STejun Heo 	u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2);
507669a5db4SJeff Garzik 	u8 dma_cmd;
5080d5ff566STejun Heo 	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
509669a5db4SJeff Garzik 
510669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
511669a5db4SJeff Garzik 		udelay(20);
5120d5ff566STejun Heo 		dma_stat = ioread8(bmdma + 2);
513669a5db4SJeff Garzik 	}
514669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
515669a5db4SJeff Garzik 		/* Clear the engine */
516669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
517669a5db4SJeff Garzik 		udelay(10);
518669a5db4SJeff Garzik 		/* Stop DMA */
5190d5ff566STejun Heo 		dma_cmd = ioread8(bmdma );
5200d5ff566STejun Heo 		iowrite8(dma_cmd & 0xFE, bmdma);
521669a5db4SJeff Garzik 		/* Clear Error */
5220d5ff566STejun Heo 		dma_stat = ioread8(bmdma + 2);
5230d5ff566STejun Heo 		iowrite8(dma_stat | 0x06 , bmdma + 2);
524669a5db4SJeff Garzik 		/* Clear the engine */
525669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
526669a5db4SJeff Garzik 		udelay(10);
527669a5db4SJeff Garzik 	}
528669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
529669a5db4SJeff Garzik }
530669a5db4SJeff Garzik 
531669a5db4SJeff Garzik /**
532669a5db4SJeff Garzik  *	hpt372_set_piomode		-	PIO setup
533669a5db4SJeff Garzik  *	@ap: ATA interface
534669a5db4SJeff Garzik  *	@adev: device on the interface
535669a5db4SJeff Garzik  *
536669a5db4SJeff Garzik  *	Perform PIO mode setup.
537669a5db4SJeff Garzik  */
538669a5db4SJeff Garzik 
539669a5db4SJeff Garzik static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
540669a5db4SJeff Garzik {
541669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
542669a5db4SJeff Garzik 	u32 addr1, addr2;
543669a5db4SJeff Garzik 	u32 reg;
544669a5db4SJeff Garzik 	u32 mode;
545669a5db4SJeff Garzik 	u8 fast;
546669a5db4SJeff Garzik 
547669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
548669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
549669a5db4SJeff Garzik 
550669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
551669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
552669a5db4SJeff Garzik 	fast &= ~0x07;
553669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
554669a5db4SJeff Garzik 
555669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
556669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
557669a5db4SJeff Garzik 
558669a5db4SJeff Garzik 	printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
559669a5db4SJeff Garzik 	mode &= ~0x80000000;	/* No FIFO in PIO */
560669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
561669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
562669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
563669a5db4SJeff Garzik }
564669a5db4SJeff Garzik 
565669a5db4SJeff Garzik /**
566669a5db4SJeff Garzik  *	hpt372_set_dmamode		-	DMA timing setup
567669a5db4SJeff Garzik  *	@ap: ATA interface
568669a5db4SJeff Garzik  *	@adev: Device being configured
569669a5db4SJeff Garzik  *
570669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
571669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
572669a5db4SJeff Garzik  */
573669a5db4SJeff Garzik 
574669a5db4SJeff Garzik static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
575669a5db4SJeff Garzik {
576669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
577669a5db4SJeff Garzik 	u32 addr1, addr2;
578669a5db4SJeff Garzik 	u32 reg;
579669a5db4SJeff Garzik 	u32 mode;
580669a5db4SJeff Garzik 	u8 fast;
581669a5db4SJeff Garzik 
582669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
583669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
584669a5db4SJeff Garzik 
585669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
586669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
587669a5db4SJeff Garzik 	fast &= ~0x07;
588669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
589669a5db4SJeff Garzik 
590669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
591669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
592669a5db4SJeff Garzik 	printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
593669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
594669a5db4SJeff Garzik 	mode |= 0x80000000;	/* FIFO in MWDMA or UDMA */
595669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
596669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
597669a5db4SJeff Garzik }
598669a5db4SJeff Garzik 
599669a5db4SJeff Garzik /**
600669a5db4SJeff Garzik  *	hpt37x_bmdma_end		-	DMA engine stop
601669a5db4SJeff Garzik  *	@qc: ATA command
602669a5db4SJeff Garzik  *
603669a5db4SJeff Garzik  *	Clean up after the HPT372 and later DMA engine
604669a5db4SJeff Garzik  */
605669a5db4SJeff Garzik 
606669a5db4SJeff Garzik static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
607669a5db4SJeff Garzik {
608669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
609669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
6106929da44SAlan 	int mscreg = 0x50 + 4 * ap->port_no;
611669a5db4SJeff Garzik 	u8 bwsr_stat, msc_stat;
612669a5db4SJeff Garzik 
613669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
614669a5db4SJeff Garzik 	pci_read_config_byte(pdev, mscreg, &msc_stat);
615669a5db4SJeff Garzik 	if (bwsr_stat & (1 << ap->port_no))
616669a5db4SJeff Garzik 		pci_write_config_byte(pdev, mscreg, msc_stat | 0x30);
617669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
618669a5db4SJeff Garzik }
619669a5db4SJeff Garzik 
620669a5db4SJeff Garzik 
621669a5db4SJeff Garzik static struct scsi_host_template hpt37x_sht = {
622669a5db4SJeff Garzik 	.module			= THIS_MODULE,
623669a5db4SJeff Garzik 	.name			= DRV_NAME,
624669a5db4SJeff Garzik 	.ioctl			= ata_scsi_ioctl,
625669a5db4SJeff Garzik 	.queuecommand		= ata_scsi_queuecmd,
626669a5db4SJeff Garzik 	.can_queue		= ATA_DEF_QUEUE,
627669a5db4SJeff Garzik 	.this_id		= ATA_SHT_THIS_ID,
628669a5db4SJeff Garzik 	.sg_tablesize		= LIBATA_MAX_PRD,
629669a5db4SJeff Garzik 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
630669a5db4SJeff Garzik 	.emulated		= ATA_SHT_EMULATED,
631669a5db4SJeff Garzik 	.use_clustering		= ATA_SHT_USE_CLUSTERING,
632669a5db4SJeff Garzik 	.proc_name		= DRV_NAME,
633669a5db4SJeff Garzik 	.dma_boundary		= ATA_DMA_BOUNDARY,
634669a5db4SJeff Garzik 	.slave_configure	= ata_scsi_slave_config,
635afdfe899STejun Heo 	.slave_destroy		= ata_scsi_slave_destroy,
636669a5db4SJeff Garzik 	.bios_param		= ata_std_bios_param,
637669a5db4SJeff Garzik };
638669a5db4SJeff Garzik 
639669a5db4SJeff Garzik /*
640669a5db4SJeff Garzik  *	Configuration for HPT370
641669a5db4SJeff Garzik  */
642669a5db4SJeff Garzik 
643669a5db4SJeff Garzik static struct ata_port_operations hpt370_port_ops = {
644669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
645669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
646669a5db4SJeff Garzik 	.mode_filter	= hpt370_filter,
647669a5db4SJeff Garzik 
648669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
649669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
650669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
651669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
652669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
653669a5db4SJeff Garzik 
654669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
655669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
656669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
657669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
658669a5db4SJeff Garzik 
659669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
660669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
661669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
662669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
663669a5db4SJeff Garzik 
664669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
665669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
666bda30288SJeff Garzik 
6670d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
668669a5db4SJeff Garzik 
669669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
670669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
671246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
672669a5db4SJeff Garzik 
67381ad1837SAlan Cox 	.port_start	= ata_sff_port_start,
674669a5db4SJeff Garzik };
675669a5db4SJeff Garzik 
676669a5db4SJeff Garzik /*
677669a5db4SJeff Garzik  *	Configuration for HPT370A. Close to 370 but less filters
678669a5db4SJeff Garzik  */
679669a5db4SJeff Garzik 
680669a5db4SJeff Garzik static struct ata_port_operations hpt370a_port_ops = {
681669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
682669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
683669a5db4SJeff Garzik 	.mode_filter	= hpt370a_filter,
684669a5db4SJeff Garzik 
685669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
686669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
687669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
688669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
689669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
690669a5db4SJeff Garzik 
691669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
692669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
693669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
694669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
695669a5db4SJeff Garzik 
696669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
697669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
698669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
699669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
700669a5db4SJeff Garzik 
701669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
702669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
703bda30288SJeff Garzik 
7040d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
705669a5db4SJeff Garzik 
706669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
707669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
708246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
709669a5db4SJeff Garzik 
71081ad1837SAlan Cox 	.port_start	= ata_sff_port_start,
711669a5db4SJeff Garzik };
712669a5db4SJeff Garzik 
713669a5db4SJeff Garzik /*
714669a5db4SJeff Garzik  *	Configuration for HPT372, HPT371, HPT302. Slightly different PIO
715669a5db4SJeff Garzik  *	and DMA mode setting functionality.
716669a5db4SJeff Garzik  */
717669a5db4SJeff Garzik 
718669a5db4SJeff Garzik static struct ata_port_operations hpt372_port_ops = {
719669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
720669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
721669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
722669a5db4SJeff Garzik 
723669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
724669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
725669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
726669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
727669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
728669a5db4SJeff Garzik 
729669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
730669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
731669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
732669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
733669a5db4SJeff Garzik 
734669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
735669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
736669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
737669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
738669a5db4SJeff Garzik 
739669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
740669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
741bda30288SJeff Garzik 
7420d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
743669a5db4SJeff Garzik 
744669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
745669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
746246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
747669a5db4SJeff Garzik 
74881ad1837SAlan Cox 	.port_start	= ata_sff_port_start,
749669a5db4SJeff Garzik };
750669a5db4SJeff Garzik 
751669a5db4SJeff Garzik /*
752669a5db4SJeff Garzik  *	Configuration for HPT374. Mode setting works like 372 and friends
753669a5db4SJeff Garzik  *	but we have a different cable detection procedure.
754669a5db4SJeff Garzik  */
755669a5db4SJeff Garzik 
756669a5db4SJeff Garzik static struct ata_port_operations hpt374_port_ops = {
757669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
758669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
759669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
760669a5db4SJeff Garzik 
761669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
762669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
763669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
764669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
765669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
766669a5db4SJeff Garzik 
767669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
768669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
769669a5db4SJeff Garzik 	.error_handler	= hpt374_error_handler,
770669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
771669a5db4SJeff Garzik 
772669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
773669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
774669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
775669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
776669a5db4SJeff Garzik 
777669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
778669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
779bda30288SJeff Garzik 
7800d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
781669a5db4SJeff Garzik 
782669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
783669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
784246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
785669a5db4SJeff Garzik 
78681ad1837SAlan Cox 	.port_start	= ata_sff_port_start,
787669a5db4SJeff Garzik };
788669a5db4SJeff Garzik 
789669a5db4SJeff Garzik /**
790669a5db4SJeff Garzik  *	htp37x_clock_slot	-	Turn timing to PC clock entry
791669a5db4SJeff Garzik  *	@freq: Reported frequency timing
792669a5db4SJeff Garzik  *	@base: Base timing
793669a5db4SJeff Garzik  *
794669a5db4SJeff Garzik  *	Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50
795669a5db4SJeff Garzik  *	and 3 for 66Mhz)
796669a5db4SJeff Garzik  */
797669a5db4SJeff Garzik 
798669a5db4SJeff Garzik static int hpt37x_clock_slot(unsigned int freq, unsigned int base)
799669a5db4SJeff Garzik {
800669a5db4SJeff Garzik 	unsigned int f = (base * freq) / 192;	/* Mhz */
801669a5db4SJeff Garzik 	if (f < 40)
802669a5db4SJeff Garzik 		return 0;	/* 33Mhz slot */
803669a5db4SJeff Garzik 	if (f < 45)
804669a5db4SJeff Garzik 		return 1;	/* 40Mhz slot */
805669a5db4SJeff Garzik 	if (f < 55)
806669a5db4SJeff Garzik 		return 2;	/* 50Mhz slot */
807669a5db4SJeff Garzik 	return 3;		/* 60Mhz slot */
808669a5db4SJeff Garzik }
809669a5db4SJeff Garzik 
810669a5db4SJeff Garzik /**
811669a5db4SJeff Garzik  *	hpt37x_calibrate_dpll		-	Calibrate the DPLL loop
812669a5db4SJeff Garzik  *	@dev: PCI device
813669a5db4SJeff Garzik  *
814669a5db4SJeff Garzik  *	Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this
815669a5db4SJeff Garzik  *	succeeds
816669a5db4SJeff Garzik  */
817669a5db4SJeff Garzik 
818669a5db4SJeff Garzik static int hpt37x_calibrate_dpll(struct pci_dev *dev)
819669a5db4SJeff Garzik {
820669a5db4SJeff Garzik 	u8 reg5b;
821669a5db4SJeff Garzik 	u32 reg5c;
822669a5db4SJeff Garzik 	int tries;
823669a5db4SJeff Garzik 
824669a5db4SJeff Garzik 	for(tries = 0; tries < 0x5000; tries++) {
825669a5db4SJeff Garzik 		udelay(50);
826669a5db4SJeff Garzik 		pci_read_config_byte(dev, 0x5b, &reg5b);
827669a5db4SJeff Garzik 		if (reg5b & 0x80) {
828669a5db4SJeff Garzik 			/* See if it stays set */
829669a5db4SJeff Garzik 			for(tries = 0; tries < 0x1000; tries ++) {
830669a5db4SJeff Garzik 				pci_read_config_byte(dev, 0x5b, &reg5b);
831669a5db4SJeff Garzik 				/* Failed ? */
832669a5db4SJeff Garzik 				if ((reg5b & 0x80) == 0)
833669a5db4SJeff Garzik 					return 0;
834669a5db4SJeff Garzik 			}
835669a5db4SJeff Garzik 			/* Turn off tuning, we have the DPLL set */
836669a5db4SJeff Garzik 			pci_read_config_dword(dev, 0x5c, &reg5c);
837669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100);
838669a5db4SJeff Garzik 			return 1;
839669a5db4SJeff Garzik 		}
840669a5db4SJeff Garzik 	}
841669a5db4SJeff Garzik 	/* Never went stable */
842669a5db4SJeff Garzik 	return 0;
843669a5db4SJeff Garzik }
84473946f9fSAlan Cox 
84573946f9fSAlan Cox static u32 hpt374_read_freq(struct pci_dev *pdev)
84673946f9fSAlan Cox {
84773946f9fSAlan Cox 	u32 freq;
84873946f9fSAlan Cox 	unsigned long io_base = pci_resource_start(pdev, 4);
84973946f9fSAlan Cox 	if (PCI_FUNC(pdev->devfn) & 1) {
85040f46f17SAndrew Morton 		struct pci_dev *pdev_0;
85140f46f17SAndrew Morton 
85240f46f17SAndrew Morton 		pdev_0 = pci_get_slot(pdev->bus, pdev->devfn - 1);
85373946f9fSAlan Cox 		/* Someone hot plugged the controller on us ? */
85473946f9fSAlan Cox 		if (pdev_0 == NULL)
85573946f9fSAlan Cox 			return 0;
85673946f9fSAlan Cox 		io_base = pci_resource_start(pdev_0, 4);
85773946f9fSAlan Cox 		freq = inl(io_base + 0x90);
85873946f9fSAlan Cox 		pci_dev_put(pdev_0);
85940f46f17SAndrew Morton 	} else
86073946f9fSAlan Cox 		freq = inl(io_base + 0x90);
86173946f9fSAlan Cox 	return freq;
86273946f9fSAlan Cox }
86373946f9fSAlan Cox 
864669a5db4SJeff Garzik /**
865669a5db4SJeff Garzik  *	hpt37x_init_one		-	Initialise an HPT37X/302
866669a5db4SJeff Garzik  *	@dev: PCI device
867669a5db4SJeff Garzik  *	@id: Entry in match table
868669a5db4SJeff Garzik  *
869669a5db4SJeff Garzik  *	Initialise an HPT37x device. There are some interesting complications
870669a5db4SJeff Garzik  *	here. Firstly the chip may report 366 and be one of several variants.
871669a5db4SJeff Garzik  *	Secondly all the timings depend on the clock for the chip which we must
872669a5db4SJeff Garzik  *	detect and look up
873669a5db4SJeff Garzik  *
874669a5db4SJeff Garzik  *	This is the known chip mappings. It may be missing a couple of later
875669a5db4SJeff Garzik  *	releases.
876669a5db4SJeff Garzik  *
877669a5db4SJeff Garzik  *	Chip version		PCI		Rev	Notes
878669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	0	Other driver
879669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	1	Other driver
880669a5db4SJeff Garzik  *	HPT368			4 (HPT366)	2	Other driver
881669a5db4SJeff Garzik  *	HPT370			4 (HPT366)	3	UDMA100
882669a5db4SJeff Garzik  *	HPT370A			4 (HPT366)	4	UDMA100
883669a5db4SJeff Garzik  *	HPT372			4 (HPT366)	5	UDMA133 (1)
884669a5db4SJeff Garzik  *	HPT372N			4 (HPT366)	6	Other driver
885669a5db4SJeff Garzik  *	HPT372A			5 (HPT372)	1	UDMA133 (1)
886669a5db4SJeff Garzik  *	HPT372N			5 (HPT372)	2	Other driver
887669a5db4SJeff Garzik  *	HPT302			6 (HPT302)	1	UDMA133
888669a5db4SJeff Garzik  *	HPT302N			6 (HPT302)	2	Other driver
889669a5db4SJeff Garzik  *	HPT371			7 (HPT371)	*	UDMA133
890669a5db4SJeff Garzik  *	HPT374			8 (HPT374)	*	UDMA133 4 channel
891669a5db4SJeff Garzik  *	HPT372N			9 (HPT372N)	*	Other driver
892669a5db4SJeff Garzik  *
893669a5db4SJeff Garzik  *	(1) UDMA133 support depends on the bus clock
894669a5db4SJeff Garzik  */
895669a5db4SJeff Garzik 
896669a5db4SJeff Garzik static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
897669a5db4SJeff Garzik {
898669a5db4SJeff Garzik 	/* HPT370 - UDMA100 */
8991626aeb8STejun Heo 	static const struct ata_port_info info_hpt370 = {
900669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
9011d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
902669a5db4SJeff Garzik 		.pio_mask = 0x1f,
903669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
904bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
905669a5db4SJeff Garzik 		.port_ops = &hpt370_port_ops
906669a5db4SJeff Garzik 	};
907669a5db4SJeff Garzik 	/* HPT370A - UDMA100 */
9081626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a = {
909669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
9101d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
911669a5db4SJeff Garzik 		.pio_mask = 0x1f,
912669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
913bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
914669a5db4SJeff Garzik 		.port_ops = &hpt370a_port_ops
915669a5db4SJeff Garzik 	};
916fcc2f69aSAlan Cox 	/* HPT370 - UDMA100 */
9171626aeb8STejun Heo 	static const struct ata_port_info info_hpt370_33 = {
918fcc2f69aSAlan Cox 		.sht = &hpt37x_sht,
9191d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
920fcc2f69aSAlan Cox 		.pio_mask = 0x1f,
921fcc2f69aSAlan Cox 		.mwdma_mask = 0x07,
92273946f9fSAlan Cox 		.udma_mask = ATA_UDMA5,
923fcc2f69aSAlan Cox 		.port_ops = &hpt370_port_ops
924fcc2f69aSAlan Cox 	};
925fcc2f69aSAlan Cox 	/* HPT370A - UDMA100 */
9261626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a_33 = {
927fcc2f69aSAlan Cox 		.sht = &hpt37x_sht,
9281d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
929fcc2f69aSAlan Cox 		.pio_mask = 0x1f,
930fcc2f69aSAlan Cox 		.mwdma_mask = 0x07,
93173946f9fSAlan Cox 		.udma_mask = ATA_UDMA5,
932fcc2f69aSAlan Cox 		.port_ops = &hpt370a_port_ops
933fcc2f69aSAlan Cox 	};
934669a5db4SJeff Garzik 	/* HPT371, 372 and friends - UDMA133 */
9351626aeb8STejun Heo 	static const struct ata_port_info info_hpt372 = {
936669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
9371d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
938669a5db4SJeff Garzik 		.pio_mask = 0x1f,
939669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
940bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA6,
941669a5db4SJeff Garzik 		.port_ops = &hpt372_port_ops
942669a5db4SJeff Garzik 	};
94362877f6bSAlan Cox 	/* HPT374 - UDMA100 */
9441626aeb8STejun Heo 	static const struct ata_port_info info_hpt374 = {
945669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
9461d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
947669a5db4SJeff Garzik 		.pio_mask = 0x1f,
948669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
949bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
950669a5db4SJeff Garzik 		.port_ops = &hpt374_port_ops
951669a5db4SJeff Garzik 	};
952669a5db4SJeff Garzik 
953669a5db4SJeff Garzik 	static const int MHz[4] = { 33, 40, 50, 66 };
9541626aeb8STejun Heo 	const struct ata_port_info *port;
9551626aeb8STejun Heo 	void *private_data = NULL;
9561626aeb8STejun Heo 	struct ata_port_info port_info;
9571626aeb8STejun Heo 	const struct ata_port_info *ppi[] = { &port_info, NULL };
958669a5db4SJeff Garzik 
959669a5db4SJeff Garzik 	u8 irqmask;
960669a5db4SJeff Garzik 	u32 class_rev;
961fcc2f69aSAlan Cox 	u8 mcr1;
962669a5db4SJeff Garzik 	u32 freq;
963fcc2f69aSAlan Cox 	int prefer_dpll = 1;
964fcc2f69aSAlan Cox 
965fcc2f69aSAlan Cox 	unsigned long iobase = pci_resource_start(dev, 4);
966669a5db4SJeff Garzik 
967669a5db4SJeff Garzik 	const struct hpt_chip *chip_table;
968669a5db4SJeff Garzik 	int clock_slot;
969669a5db4SJeff Garzik 
970669a5db4SJeff Garzik 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
971669a5db4SJeff Garzik 	class_rev &= 0xFF;
972669a5db4SJeff Garzik 
973669a5db4SJeff Garzik 	if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
974669a5db4SJeff Garzik 		/* May be a later chip in disguise. Check */
975669a5db4SJeff Garzik 		/* Older chips are in the HPT366 driver. Ignore them */
976669a5db4SJeff Garzik 		if (class_rev < 3)
977669a5db4SJeff Garzik 			return -ENODEV;
978669a5db4SJeff Garzik 		/* N series chips have their own driver. Ignore */
979669a5db4SJeff Garzik 		if (class_rev == 6)
980669a5db4SJeff Garzik 			return -ENODEV;
981669a5db4SJeff Garzik 
982669a5db4SJeff Garzik 		switch(class_rev) {
983669a5db4SJeff Garzik 			case 3:
984669a5db4SJeff Garzik 				port = &info_hpt370;
985669a5db4SJeff Garzik 				chip_table = &hpt370;
986fcc2f69aSAlan Cox 				prefer_dpll = 0;
987669a5db4SJeff Garzik 				break;
988669a5db4SJeff Garzik 			case 4:
989669a5db4SJeff Garzik 				port = &info_hpt370a;
990669a5db4SJeff Garzik 				chip_table = &hpt370a;
991fcc2f69aSAlan Cox 				prefer_dpll = 0;
992669a5db4SJeff Garzik 				break;
993669a5db4SJeff Garzik 			case 5:
994669a5db4SJeff Garzik 				port = &info_hpt372;
995669a5db4SJeff Garzik 				chip_table = &hpt372;
996669a5db4SJeff Garzik 				break;
997669a5db4SJeff Garzik 			default:
998669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev);
999669a5db4SJeff Garzik 				return -ENODEV;
1000669a5db4SJeff Garzik 		}
1001669a5db4SJeff Garzik 	} else {
1002669a5db4SJeff Garzik 		switch(dev->device) {
1003669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT372:
1004669a5db4SJeff Garzik 				/* 372N if rev >= 2*/
1005669a5db4SJeff Garzik 				if (class_rev >= 2)
1006669a5db4SJeff Garzik 					return -ENODEV;
1007669a5db4SJeff Garzik 				port = &info_hpt372;
1008669a5db4SJeff Garzik 				chip_table = &hpt372a;
1009669a5db4SJeff Garzik 				break;
1010669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT302:
1011669a5db4SJeff Garzik 				/* 302N if rev > 1 */
1012669a5db4SJeff Garzik 				if (class_rev > 1)
1013669a5db4SJeff Garzik 					return -ENODEV;
1014669a5db4SJeff Garzik 				port = &info_hpt372;
1015669a5db4SJeff Garzik 				/* Check this */
1016669a5db4SJeff Garzik 				chip_table = &hpt302;
1017669a5db4SJeff Garzik 				break;
1018669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT371:
1019fcc2f69aSAlan Cox 				if (class_rev > 1)
1020fcc2f69aSAlan Cox 					return -ENODEV;
1021669a5db4SJeff Garzik 				port = &info_hpt372;
1022669a5db4SJeff Garzik 				chip_table = &hpt371;
1023a4734468SAlan Cox 				/* Single channel device, master is not present
1024a4734468SAlan Cox 				   but the BIOS (or us for non x86) must mark it
1025fcc2f69aSAlan Cox 				   absent */
1026fcc2f69aSAlan Cox 				pci_read_config_byte(dev, 0x50, &mcr1);
1027fcc2f69aSAlan Cox 				mcr1 &= ~0x04;
1028fcc2f69aSAlan Cox 				pci_write_config_byte(dev, 0x50, mcr1);
1029669a5db4SJeff Garzik 				break;
1030669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT374:
1031669a5db4SJeff Garzik 				chip_table = &hpt374;
1032669a5db4SJeff Garzik 				port = &info_hpt374;
1033669a5db4SJeff Garzik 				break;
1034669a5db4SJeff Garzik 			default:
1035669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device);
1036669a5db4SJeff Garzik 				return -ENODEV;
1037669a5db4SJeff Garzik 		}
1038669a5db4SJeff Garzik 	}
1039669a5db4SJeff Garzik 	/* Ok so this is a chip we support */
1040669a5db4SJeff Garzik 
1041669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
1042669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
1043669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
1044669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
1045669a5db4SJeff Garzik 
1046669a5db4SJeff Garzik 	pci_read_config_byte(dev, 0x5A, &irqmask);
1047669a5db4SJeff Garzik 	irqmask &= ~0x10;
1048669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5a, irqmask);
1049669a5db4SJeff Garzik 
1050669a5db4SJeff Garzik 	/*
1051669a5db4SJeff Garzik 	 * default to pci clock. make sure MA15/16 are set to output
1052669a5db4SJeff Garzik 	 * to prevent drives having problems with 40-pin cables. Needed
1053669a5db4SJeff Garzik 	 * for some drives such as IBM-DTLA which will not enter ready
1054669a5db4SJeff Garzik 	 * state on reset when PDIAG is a input.
1055669a5db4SJeff Garzik 	 */
1056669a5db4SJeff Garzik 
1057669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5b, 0x23);
1058669a5db4SJeff Garzik 
1059fcc2f69aSAlan Cox 	/*
1060fcc2f69aSAlan Cox 	 * HighPoint does this for HPT372A.
1061fcc2f69aSAlan Cox 	 * NOTE: This register is only writeable via I/O space.
1062fcc2f69aSAlan Cox 	 */
1063fcc2f69aSAlan Cox 	if (chip_table == &hpt372a)
1064fcc2f69aSAlan Cox 		outb(0x0e, iobase + 0x9c);
1065fcc2f69aSAlan Cox 
1066fcc2f69aSAlan Cox 	/* Some devices do not let this value be accessed via PCI space
106773946f9fSAlan Cox 	   according to the old driver. In addition we must use the value
106873946f9fSAlan Cox 	   from FN 0 on the HPT374 */
1069fcc2f69aSAlan Cox 
107073946f9fSAlan Cox 	if (chip_table == &hpt374) {
107173946f9fSAlan Cox 		freq = hpt374_read_freq(dev);
107273946f9fSAlan Cox 		if (freq == 0)
107373946f9fSAlan Cox 			return -ENODEV;
107473946f9fSAlan Cox 	} else
1075fcc2f69aSAlan Cox 		freq = inl(iobase + 0x90);
107673946f9fSAlan Cox 
1077669a5db4SJeff Garzik 	if ((freq >> 12) != 0xABCDE) {
1078669a5db4SJeff Garzik 		int i;
1079669a5db4SJeff Garzik 		u8 sr;
1080669a5db4SJeff Garzik 		u32 total = 0;
1081669a5db4SJeff Garzik 
1082669a5db4SJeff Garzik 		printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
1083669a5db4SJeff Garzik 
1084669a5db4SJeff Garzik 		/* This is the process the HPT371 BIOS is reported to use */
1085669a5db4SJeff Garzik 		for(i = 0; i < 128; i++) {
1086669a5db4SJeff Garzik 			pci_read_config_byte(dev, 0x78, &sr);
1087fcc2f69aSAlan Cox 			total += sr & 0x1FF;
1088669a5db4SJeff Garzik 			udelay(15);
1089669a5db4SJeff Garzik 		}
1090669a5db4SJeff Garzik 		freq = total / 128;
1091669a5db4SJeff Garzik 	}
1092669a5db4SJeff Garzik 	freq &= 0x1FF;
1093669a5db4SJeff Garzik 
1094669a5db4SJeff Garzik 	/*
1095669a5db4SJeff Garzik 	 *	Turn the frequency check into a band and then find a timing
1096669a5db4SJeff Garzik 	 *	table to match it.
1097669a5db4SJeff Garzik 	 */
1098669a5db4SJeff Garzik 
1099669a5db4SJeff Garzik 	clock_slot = hpt37x_clock_slot(freq, chip_table->base);
1100fcc2f69aSAlan Cox 	if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
1101669a5db4SJeff Garzik 		/*
1102669a5db4SJeff Garzik 		 *	We need to try PLL mode instead
1103fcc2f69aSAlan Cox 		 *
1104fcc2f69aSAlan Cox 		 *	For non UDMA133 capable devices we should
1105fcc2f69aSAlan Cox 		 *	use a 50MHz DPLL by choice
1106669a5db4SJeff Garzik 		 */
1107fcc2f69aSAlan Cox 		unsigned int f_low, f_high;
1108960c8a10SAlan Cox 		int dpll, adjust;
1109669a5db4SJeff Garzik 
1110960c8a10SAlan Cox 		/* Compute DPLL */
1111d44a65f7SSergei Shtylyov 		dpll = (port->udma_mask & 0xC0) ? 3 : 2;
1112fcc2f69aSAlan Cox 
1113960c8a10SAlan Cox 		f_low = (MHz[clock_slot] * 48) / MHz[dpll];
1114fcc2f69aSAlan Cox 		f_high = f_low + 2;
1115960c8a10SAlan Cox 		if (clock_slot > 1)
1116960c8a10SAlan Cox 			f_high += 2;
1117fcc2f69aSAlan Cox 
1118fcc2f69aSAlan Cox 		/* Select the DPLL clock. */
1119fcc2f69aSAlan Cox 		pci_write_config_byte(dev, 0x5b, 0x21);
112064a81709SAlan Cox 		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
1121fcc2f69aSAlan Cox 
1122669a5db4SJeff Garzik 		for(adjust = 0; adjust < 8; adjust++) {
1123669a5db4SJeff Garzik 			if (hpt37x_calibrate_dpll(dev))
1124669a5db4SJeff Garzik 				break;
1125669a5db4SJeff Garzik 			/* See if it'll settle at a fractionally different clock */
112664a81709SAlan Cox 			if (adjust & 1)
112764a81709SAlan Cox 				f_low -= adjust >> 1;
112864a81709SAlan Cox 			else
112964a81709SAlan Cox 				f_high += adjust >> 1;
113064a81709SAlan Cox 			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
1131669a5db4SJeff Garzik 		}
1132669a5db4SJeff Garzik 		if (adjust == 8) {
113380b8987cSSergei Shtylyov 			printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
1134669a5db4SJeff Garzik 			return -ENODEV;
1135669a5db4SJeff Garzik 		}
1136960c8a10SAlan Cox 		if (dpll == 3)
11371626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_66;
1138fcc2f69aSAlan Cox 		else
11391626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_50;
1140669a5db4SJeff Garzik 
114180b8987cSSergei Shtylyov 		printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
114280b8987cSSergei Shtylyov 		       MHz[clock_slot], MHz[dpll]);
1143669a5db4SJeff Garzik 	} else {
11441626aeb8STejun Heo 		private_data = (void *)chip_table->clocks[clock_slot];
1145669a5db4SJeff Garzik 		/*
1146a4734468SAlan Cox 		 *	Perform a final fixup. Note that we will have used the
1147a4734468SAlan Cox 		 *	DPLL on the HPT372 which means we don't have to worry
1148a4734468SAlan Cox 		 *	about lack of UDMA133 support on lower clocks
1149669a5db4SJeff Garzik  		 */
1150669a5db4SJeff Garzik 
1151fcc2f69aSAlan Cox 		if (clock_slot < 2 && port == &info_hpt370)
1152fcc2f69aSAlan Cox 			port = &info_hpt370_33;
1153fcc2f69aSAlan Cox 		if (clock_slot < 2 && port == &info_hpt370a)
1154fcc2f69aSAlan Cox 			port = &info_hpt370a_33;
115580b8987cSSergei Shtylyov 		printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
115680b8987cSSergei Shtylyov 		       chip_table->name, MHz[clock_slot]);
1157669a5db4SJeff Garzik 	}
1158fcc2f69aSAlan Cox 
1159669a5db4SJeff Garzik 	/* Now kick off ATA set up */
11601626aeb8STejun Heo 	port_info = *port;
11611626aeb8STejun Heo 	port_info.private_data = private_data;
11621626aeb8STejun Heo 
11631626aeb8STejun Heo 	return ata_pci_init_one(dev, ppi);
1164669a5db4SJeff Garzik }
1165669a5db4SJeff Garzik 
11662d2744fcSJeff Garzik static const struct pci_device_id hpt37x[] = {
11672d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
11682d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
11692d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
11702d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), },
11712d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
11722d2744fcSJeff Garzik 
11732d2744fcSJeff Garzik 	{ },
1174669a5db4SJeff Garzik };
1175669a5db4SJeff Garzik 
1176669a5db4SJeff Garzik static struct pci_driver hpt37x_pci_driver = {
1177669a5db4SJeff Garzik 	.name 		= DRV_NAME,
1178669a5db4SJeff Garzik 	.id_table	= hpt37x,
1179669a5db4SJeff Garzik 	.probe 		= hpt37x_init_one,
1180669a5db4SJeff Garzik 	.remove		= ata_pci_remove_one
1181669a5db4SJeff Garzik };
1182669a5db4SJeff Garzik 
1183669a5db4SJeff Garzik static int __init hpt37x_init(void)
1184669a5db4SJeff Garzik {
1185669a5db4SJeff Garzik 	return pci_register_driver(&hpt37x_pci_driver);
1186669a5db4SJeff Garzik }
1187669a5db4SJeff Garzik 
1188669a5db4SJeff Garzik static void __exit hpt37x_exit(void)
1189669a5db4SJeff Garzik {
1190669a5db4SJeff Garzik 	pci_unregister_driver(&hpt37x_pci_driver);
1191669a5db4SJeff Garzik }
1192669a5db4SJeff Garzik 
1193669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
1194669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
1195669a5db4SJeff Garzik MODULE_LICENSE("GPL");
1196669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, hpt37x);
1197669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
1198669a5db4SJeff Garzik 
1199669a5db4SJeff Garzik module_init(hpt37x_init);
1200669a5db4SJeff Garzik module_exit(hpt37x_exit);
1201