xref: /openbmc/linux/drivers/ata/pata_hpt37x.c (revision 62877f6b)
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
11fcc2f69aSAlan Cox  * Portions Copyright (C) 2005-2006	MontaVista Software, Inc.
12669a5db4SJeff Garzik  *
13669a5db4SJeff Garzik  * TODO
14669a5db4SJeff Garzik  *	PLL mode
15669a5db4SJeff Garzik  *	Look into engine reset on timeout errors. Should not be
16669a5db4SJeff Garzik  *		required.
17669a5db4SJeff Garzik  */
18669a5db4SJeff Garzik 
19669a5db4SJeff Garzik #include <linux/kernel.h>
20669a5db4SJeff Garzik #include <linux/module.h>
21669a5db4SJeff Garzik #include <linux/pci.h>
22669a5db4SJeff Garzik #include <linux/init.h>
23669a5db4SJeff Garzik #include <linux/blkdev.h>
24669a5db4SJeff Garzik #include <linux/delay.h>
25669a5db4SJeff Garzik #include <scsi/scsi_host.h>
26669a5db4SJeff Garzik #include <linux/libata.h>
27669a5db4SJeff Garzik 
28669a5db4SJeff Garzik #define DRV_NAME	"pata_hpt37x"
29960c8a10SAlan Cox #define DRV_VERSION	"0.6.6"
30669a5db4SJeff Garzik 
31669a5db4SJeff Garzik struct hpt_clock {
32669a5db4SJeff Garzik 	u8	xfer_speed;
33669a5db4SJeff Garzik 	u32	timing;
34669a5db4SJeff Garzik };
35669a5db4SJeff Garzik 
36669a5db4SJeff Garzik struct hpt_chip {
37669a5db4SJeff Garzik 	const char *name;
38669a5db4SJeff Garzik 	unsigned int base;
39669a5db4SJeff Garzik 	struct hpt_clock const *clocks[4];
40669a5db4SJeff Garzik };
41669a5db4SJeff Garzik 
42669a5db4SJeff Garzik /* key for bus clock timings
43669a5db4SJeff Garzik  * bit
44669a5db4SJeff Garzik  * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
45669a5db4SJeff Garzik  *        DMA. cycles = value + 1
46669a5db4SJeff Garzik  * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
47669a5db4SJeff Garzik  *        DMA. cycles = value + 1
48669a5db4SJeff Garzik  * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
49669a5db4SJeff Garzik  *        register access.
50669a5db4SJeff Garzik  * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
51669a5db4SJeff Garzik  *        register access.
52669a5db4SJeff Garzik  * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
53669a5db4SJeff Garzik  *        during task file register access.
54669a5db4SJeff Garzik  * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
55669a5db4SJeff Garzik  *        xfer.
56669a5db4SJeff Garzik  * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
57669a5db4SJeff Garzik  *        register access.
58669a5db4SJeff Garzik  * 28     UDMA enable
59669a5db4SJeff Garzik  * 29     DMA enable
60669a5db4SJeff Garzik  * 30     PIO_MST enable. if set, the chip is in bus master mode during
61669a5db4SJeff Garzik  *        PIO.
62669a5db4SJeff Garzik  * 31     FIFO enable.
63669a5db4SJeff Garzik  */
64669a5db4SJeff Garzik 
65fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_33[] = {
66fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12446231 },	/* 0x12646231 ?? */
67669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12446231 },
68669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12446231 },
69669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x126c6231 },
70669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x12486231 },
71669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x124c6233 },
72669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x12506297 },
73669a5db4SJeff Garzik 
74669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22406c31 },
75669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22406c33 },
76669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x22406c97 },
77669a5db4SJeff Garzik 
78669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x06414e31 },
79669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x06414e42 },
80669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x06414e53 },
81669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x06814e93 },
82fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x06814ea7 }
83669a5db4SJeff Garzik };
84669a5db4SJeff Garzik 
85fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_50[] = {
86fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12848242 },
87669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12848242 },
88669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12ac8242 },
89669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x128c8242 },
90669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x120c8242 },
91669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x12148254 },
92669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x121882ea },
93669a5db4SJeff Garzik 
94669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22808242 },
95669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22808254 },
96669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x228082ea },
97669a5db4SJeff Garzik 
98669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0a81f442 },
99669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0a81f443 },
100669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0a81f454 },
101669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0ac1f465 },
102fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0ac1f48a }
103669a5db4SJeff Garzik };
104669a5db4SJeff Garzik 
105fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_66[] = {
106669a5db4SJeff Garzik 	{ XFER_UDMA_6,		0x1c869c62 },
107fcc2f69aSAlan Cox 	{ XFER_UDMA_5,		0x1cae9c62 },	/* 0x1c8a9c62 */
108669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x1c8a9c62 },
109669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x1c8e9c62 },
110669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x1c929c62 },
111669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x1c9a9c62 },
112669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x1c829c62 },
113669a5db4SJeff Garzik 
114669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x2c829c62 },
115669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x2c829c66 },
116669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x2c829d2e },
117669a5db4SJeff Garzik 
118669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0c829c62 },
119669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0c829c84 },
120669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0c829ca6 },
121669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0d029d26 },
122fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0d029d5e }
123669a5db4SJeff Garzik };
124669a5db4SJeff Garzik 
125669a5db4SJeff Garzik 
126669a5db4SJeff Garzik static const struct hpt_chip hpt370 = {
127669a5db4SJeff Garzik 	"HPT370",
128669a5db4SJeff Garzik 	48,
129669a5db4SJeff Garzik 	{
130fcc2f69aSAlan Cox 		hpt37x_timings_33,
131669a5db4SJeff Garzik 		NULL,
132669a5db4SJeff Garzik 		NULL,
133a4734468SAlan Cox 		NULL
134669a5db4SJeff Garzik 	}
135669a5db4SJeff Garzik };
136669a5db4SJeff Garzik 
137669a5db4SJeff Garzik static const struct hpt_chip hpt370a = {
138669a5db4SJeff Garzik 	"HPT370A",
139669a5db4SJeff Garzik 	48,
140669a5db4SJeff Garzik 	{
141fcc2f69aSAlan Cox 		hpt37x_timings_33,
142669a5db4SJeff Garzik 		NULL,
143fcc2f69aSAlan Cox 		hpt37x_timings_50,
144a4734468SAlan Cox 		NULL
145669a5db4SJeff Garzik 	}
146669a5db4SJeff Garzik };
147669a5db4SJeff Garzik 
148669a5db4SJeff Garzik static const struct hpt_chip hpt372 = {
149669a5db4SJeff Garzik 	"HPT372",
150669a5db4SJeff Garzik 	55,
151669a5db4SJeff Garzik 	{
152fcc2f69aSAlan Cox 		hpt37x_timings_33,
153669a5db4SJeff Garzik 		NULL,
154fcc2f69aSAlan Cox 		hpt37x_timings_50,
155fcc2f69aSAlan Cox 		hpt37x_timings_66
156669a5db4SJeff Garzik 	}
157669a5db4SJeff Garzik };
158669a5db4SJeff Garzik 
159669a5db4SJeff Garzik static const struct hpt_chip hpt302 = {
160669a5db4SJeff Garzik 	"HPT302",
161669a5db4SJeff Garzik 	66,
162669a5db4SJeff Garzik 	{
163fcc2f69aSAlan Cox 		hpt37x_timings_33,
164669a5db4SJeff Garzik 		NULL,
165fcc2f69aSAlan Cox 		hpt37x_timings_50,
166fcc2f69aSAlan Cox 		hpt37x_timings_66
167669a5db4SJeff Garzik 	}
168669a5db4SJeff Garzik };
169669a5db4SJeff Garzik 
170669a5db4SJeff Garzik static const struct hpt_chip hpt371 = {
171669a5db4SJeff Garzik 	"HPT371",
172669a5db4SJeff Garzik 	66,
173669a5db4SJeff Garzik 	{
174fcc2f69aSAlan Cox 		hpt37x_timings_33,
175669a5db4SJeff Garzik 		NULL,
176fcc2f69aSAlan Cox 		hpt37x_timings_50,
177fcc2f69aSAlan Cox 		hpt37x_timings_66
178669a5db4SJeff Garzik 	}
179669a5db4SJeff Garzik };
180669a5db4SJeff Garzik 
181669a5db4SJeff Garzik static const struct hpt_chip hpt372a = {
182669a5db4SJeff Garzik 	"HPT372A",
183669a5db4SJeff Garzik 	66,
184669a5db4SJeff Garzik 	{
185fcc2f69aSAlan Cox 		hpt37x_timings_33,
186669a5db4SJeff Garzik 		NULL,
187fcc2f69aSAlan Cox 		hpt37x_timings_50,
188fcc2f69aSAlan Cox 		hpt37x_timings_66
189669a5db4SJeff Garzik 	}
190669a5db4SJeff Garzik };
191669a5db4SJeff Garzik 
192669a5db4SJeff Garzik static const struct hpt_chip hpt374 = {
193669a5db4SJeff Garzik 	"HPT374",
194669a5db4SJeff Garzik 	48,
195669a5db4SJeff Garzik 	{
196fcc2f69aSAlan Cox 		hpt37x_timings_33,
197669a5db4SJeff Garzik 		NULL,
198669a5db4SJeff Garzik 		NULL,
199669a5db4SJeff Garzik 		NULL
200669a5db4SJeff Garzik 	}
201669a5db4SJeff Garzik };
202669a5db4SJeff Garzik 
203669a5db4SJeff Garzik /**
204669a5db4SJeff Garzik  *	hpt37x_find_mode	-	reset the hpt37x bus
205669a5db4SJeff Garzik  *	@ap: ATA port
206669a5db4SJeff Garzik  *	@speed: transfer mode
207669a5db4SJeff Garzik  *
208669a5db4SJeff Garzik  *	Return the 32bit register programming information for this channel
209669a5db4SJeff Garzik  *	that matches the speed provided.
210669a5db4SJeff Garzik  */
211669a5db4SJeff Garzik 
212669a5db4SJeff Garzik static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
213669a5db4SJeff Garzik {
214669a5db4SJeff Garzik 	struct hpt_clock *clocks = ap->host->private_data;
215669a5db4SJeff Garzik 
216669a5db4SJeff Garzik 	while(clocks->xfer_speed) {
217669a5db4SJeff Garzik 		if (clocks->xfer_speed == speed)
218669a5db4SJeff Garzik 			return clocks->timing;
219669a5db4SJeff Garzik 		clocks++;
220669a5db4SJeff Garzik 	}
221669a5db4SJeff Garzik 	BUG();
222669a5db4SJeff Garzik 	return 0xffffffffU;	/* silence compiler warning */
223669a5db4SJeff Garzik }
224669a5db4SJeff Garzik 
225669a5db4SJeff Garzik static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
226669a5db4SJeff Garzik {
2278bfa79fcSTejun Heo 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
228669a5db4SJeff Garzik 	int i = 0;
229669a5db4SJeff Garzik 
2308bfa79fcSTejun Heo 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
231669a5db4SJeff Garzik 
232669a5db4SJeff Garzik 	while (list[i] != NULL) {
2338bfa79fcSTejun Heo 		if (!strcmp(list[i], model_num)) {
234669a5db4SJeff Garzik 			printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
235669a5db4SJeff Garzik 				modestr, list[i]);
236669a5db4SJeff Garzik 			return 1;
237669a5db4SJeff Garzik 		}
238669a5db4SJeff Garzik 		i++;
239669a5db4SJeff Garzik 	}
240669a5db4SJeff Garzik 	return 0;
241669a5db4SJeff Garzik }
242669a5db4SJeff Garzik 
243669a5db4SJeff Garzik static const char *bad_ata33[] = {
244669a5db4SJeff Garzik 	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
245669a5db4SJeff Garzik 	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
246669a5db4SJeff Garzik 	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
247669a5db4SJeff Garzik 	"Maxtor 90510D4",
248669a5db4SJeff Garzik 	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
249669a5db4SJeff Garzik 	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
250669a5db4SJeff Garzik 	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
251669a5db4SJeff Garzik 	NULL
252669a5db4SJeff Garzik };
253669a5db4SJeff Garzik 
254669a5db4SJeff Garzik static const char *bad_ata100_5[] = {
255669a5db4SJeff Garzik 	"IBM-DTLA-307075",
256669a5db4SJeff Garzik 	"IBM-DTLA-307060",
257669a5db4SJeff Garzik 	"IBM-DTLA-307045",
258669a5db4SJeff Garzik 	"IBM-DTLA-307030",
259669a5db4SJeff Garzik 	"IBM-DTLA-307020",
260669a5db4SJeff Garzik 	"IBM-DTLA-307015",
261669a5db4SJeff Garzik 	"IBM-DTLA-305040",
262669a5db4SJeff Garzik 	"IBM-DTLA-305030",
263669a5db4SJeff Garzik 	"IBM-DTLA-305020",
264669a5db4SJeff Garzik 	"IC35L010AVER07-0",
265669a5db4SJeff Garzik 	"IC35L020AVER07-0",
266669a5db4SJeff Garzik 	"IC35L030AVER07-0",
267669a5db4SJeff Garzik 	"IC35L040AVER07-0",
268669a5db4SJeff Garzik 	"IC35L060AVER07-0",
269669a5db4SJeff Garzik 	"WDC AC310200R",
270669a5db4SJeff Garzik 	NULL
271669a5db4SJeff Garzik };
272669a5db4SJeff Garzik 
273669a5db4SJeff Garzik /**
274669a5db4SJeff Garzik  *	hpt370_filter	-	mode selection filter
275669a5db4SJeff Garzik  *	@adev: ATA device
276669a5db4SJeff Garzik  *
277669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
278669a5db4SJeff Garzik  */
279669a5db4SJeff Garzik 
280a76b62caSAlan Cox static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
281669a5db4SJeff Garzik {
2826929da44SAlan 	if (adev->class == ATA_DEV_ATA) {
283669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
284669a5db4SJeff Garzik 			mask &= ~ATA_MASK_UDMA;
285669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
286669a5db4SJeff Garzik 			mask &= ~(0x1F << ATA_SHIFT_UDMA);
287669a5db4SJeff Garzik 	}
288a76b62caSAlan Cox 	return ata_pci_default_filter(adev, mask);
289669a5db4SJeff Garzik }
290669a5db4SJeff Garzik 
291669a5db4SJeff Garzik /**
292669a5db4SJeff Garzik  *	hpt370a_filter	-	mode selection filter
293669a5db4SJeff Garzik  *	@adev: ATA device
294669a5db4SJeff Garzik  *
295669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
296669a5db4SJeff Garzik  */
297669a5db4SJeff Garzik 
298a76b62caSAlan Cox static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
299669a5db4SJeff Garzik {
300669a5db4SJeff Garzik 	if (adev->class != ATA_DEV_ATA) {
301669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
302669a5db4SJeff Garzik 			mask &= ~ (0x1F << ATA_SHIFT_UDMA);
303669a5db4SJeff Garzik 	}
304a76b62caSAlan Cox 	return ata_pci_default_filter(adev, mask);
305669a5db4SJeff Garzik }
306669a5db4SJeff Garzik 
307669a5db4SJeff Garzik /**
308669a5db4SJeff Garzik  *	hpt37x_pre_reset	-	reset the hpt37x bus
309669a5db4SJeff Garzik  *	@ap: ATA port to reset
310d4b2bab4STejun Heo  *	@deadline: deadline jiffies for the operation
311669a5db4SJeff Garzik  *
312669a5db4SJeff Garzik  *	Perform the initial reset handling for the 370/372 and 374 func 0
313669a5db4SJeff Garzik  */
314669a5db4SJeff Garzik 
315d4b2bab4STejun Heo static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)
316669a5db4SJeff Garzik {
317669a5db4SJeff Garzik 	u8 scr2, ata66;
318669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
319b5bf24b9SAlan Cox 	static const struct pci_bits hpt37x_enable_bits[] = {
320b5bf24b9SAlan Cox 		{ 0x50, 1, 0x04, 0x04 },
321b5bf24b9SAlan Cox 		{ 0x54, 1, 0x04, 0x04 }
322b5bf24b9SAlan Cox 	};
323b5bf24b9SAlan Cox 	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
324b5bf24b9SAlan Cox 		return -ENOENT;
325669a5db4SJeff Garzik 
326669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5B, &scr2);
327669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
328669a5db4SJeff Garzik 	/* Cable register now active */
329669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
330669a5db4SJeff Garzik 	/* Restore state */
331669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2);
332669a5db4SJeff Garzik 
333669a5db4SJeff Garzik 	if (ata66 & (1 << ap->port_no))
334669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
335669a5db4SJeff Garzik 	else
336669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
337669a5db4SJeff Garzik 
338669a5db4SJeff Garzik 	/* Reset the state machine */
339fcc2f69aSAlan Cox 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
340669a5db4SJeff Garzik 	udelay(100);
341669a5db4SJeff Garzik 
342d4b2bab4STejun Heo 	return ata_std_prereset(ap, deadline);
343669a5db4SJeff Garzik }
344669a5db4SJeff Garzik 
345669a5db4SJeff Garzik /**
346669a5db4SJeff Garzik  *	hpt37x_error_handler	-	reset the hpt374
347669a5db4SJeff Garzik  *	@ap: ATA port to reset
348669a5db4SJeff Garzik  *
349669a5db4SJeff Garzik  *	Perform probe for HPT37x, except for HPT374 channel 2
350669a5db4SJeff Garzik  */
351669a5db4SJeff Garzik 
352669a5db4SJeff Garzik static void hpt37x_error_handler(struct ata_port *ap)
353669a5db4SJeff Garzik {
354669a5db4SJeff Garzik 	ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
355669a5db4SJeff Garzik }
356669a5db4SJeff Garzik 
357d4b2bab4STejun Heo static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
358669a5db4SJeff Garzik {
359b5bf24b9SAlan Cox 	static const struct pci_bits hpt37x_enable_bits[] = {
360b5bf24b9SAlan Cox 		{ 0x50, 1, 0x04, 0x04 },
361b5bf24b9SAlan Cox 		{ 0x54, 1, 0x04, 0x04 }
362b5bf24b9SAlan Cox 	};
363669a5db4SJeff Garzik 	u16 mcr3, mcr6;
364669a5db4SJeff Garzik 	u8 ata66;
365669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
366b5bf24b9SAlan Cox 
367b5bf24b9SAlan Cox 	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
368b5bf24b9SAlan Cox 		return -ENOENT;
369b5bf24b9SAlan Cox 
370669a5db4SJeff Garzik 	/* Do the extra channel work */
371669a5db4SJeff Garzik 	pci_read_config_word(pdev, 0x52, &mcr3);
372669a5db4SJeff Garzik 	pci_read_config_word(pdev, 0x56, &mcr6);
373669a5db4SJeff Garzik 	/* Set bit 15 of 0x52 to enable TCBLID as input
374669a5db4SJeff Garzik 	   Set bit 15 of 0x56 to enable FCBLID as input
375669a5db4SJeff Garzik 	 */
376669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x52, mcr3 | 0x8000);
377669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x56, mcr6 | 0x8000);
378669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
379669a5db4SJeff Garzik 	/* Reset TCBLID/FCBLID to output */
380669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x52, mcr3);
381669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x56, mcr6);
382669a5db4SJeff Garzik 
383669a5db4SJeff Garzik 	if (ata66 & (1 << ap->port_no))
384669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
385669a5db4SJeff Garzik 	else
386669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
387669a5db4SJeff Garzik 
388669a5db4SJeff Garzik 	/* Reset the state machine */
389fcc2f69aSAlan Cox 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
390669a5db4SJeff Garzik 	udelay(100);
391669a5db4SJeff Garzik 
392d4b2bab4STejun Heo 	return ata_std_prereset(ap, deadline);
393669a5db4SJeff Garzik }
394669a5db4SJeff Garzik 
395669a5db4SJeff Garzik /**
396669a5db4SJeff Garzik  *	hpt374_error_handler	-	reset the hpt374
397669a5db4SJeff Garzik  *	@classes:
398669a5db4SJeff Garzik  *
399669a5db4SJeff Garzik  *	The 374 cable detect is a little different due to the extra
400669a5db4SJeff Garzik  *	channels. The function 0 channels work like usual but function 1
401669a5db4SJeff Garzik  *	is special
402669a5db4SJeff Garzik  */
403669a5db4SJeff Garzik 
404669a5db4SJeff Garzik static void hpt374_error_handler(struct ata_port *ap)
405669a5db4SJeff Garzik {
406669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
407669a5db4SJeff Garzik 
408669a5db4SJeff Garzik 	if (!(PCI_FUNC(pdev->devfn) & 1))
409669a5db4SJeff Garzik 		hpt37x_error_handler(ap);
410669a5db4SJeff Garzik 	else
411669a5db4SJeff Garzik 		ata_bmdma_drive_eh(ap, hpt374_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
412669a5db4SJeff Garzik }
413669a5db4SJeff Garzik 
414669a5db4SJeff Garzik /**
415669a5db4SJeff Garzik  *	hpt370_set_piomode		-	PIO setup
416669a5db4SJeff Garzik  *	@ap: ATA interface
417669a5db4SJeff Garzik  *	@adev: device on the interface
418669a5db4SJeff Garzik  *
419669a5db4SJeff Garzik  *	Perform PIO mode setup.
420669a5db4SJeff Garzik  */
421669a5db4SJeff Garzik 
422669a5db4SJeff Garzik static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
423669a5db4SJeff Garzik {
424669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
425669a5db4SJeff Garzik 	u32 addr1, addr2;
426669a5db4SJeff Garzik 	u32 reg;
427669a5db4SJeff Garzik 	u32 mode;
428669a5db4SJeff Garzik 	u8 fast;
429669a5db4SJeff Garzik 
430669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
431669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
432669a5db4SJeff Garzik 
433669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
434669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
435669a5db4SJeff Garzik 	fast &= ~0x02;
436669a5db4SJeff Garzik 	fast |= 0x01;
437669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
438669a5db4SJeff Garzik 
439669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
440669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
441669a5db4SJeff Garzik 	mode &= ~0x8000000;	/* No FIFO in PIO */
442669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
443669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
444669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
445669a5db4SJeff Garzik }
446669a5db4SJeff Garzik 
447669a5db4SJeff Garzik /**
448669a5db4SJeff Garzik  *	hpt370_set_dmamode		-	DMA timing setup
449669a5db4SJeff Garzik  *	@ap: ATA interface
450669a5db4SJeff Garzik  *	@adev: Device being configured
451669a5db4SJeff Garzik  *
452669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
453669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
454669a5db4SJeff Garzik  */
455669a5db4SJeff Garzik 
456669a5db4SJeff Garzik static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
457669a5db4SJeff Garzik {
458669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
459669a5db4SJeff Garzik 	u32 addr1, addr2;
460669a5db4SJeff Garzik 	u32 reg;
461669a5db4SJeff Garzik 	u32 mode;
462669a5db4SJeff Garzik 	u8 fast;
463669a5db4SJeff Garzik 
464669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
465669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
466669a5db4SJeff Garzik 
467669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
468669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
469669a5db4SJeff Garzik 	fast &= ~0x02;
470669a5db4SJeff Garzik 	fast |= 0x01;
471669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
472669a5db4SJeff Garzik 
473669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
474669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
475669a5db4SJeff Garzik 	mode |= 0x8000000;	/* FIFO in MWDMA or UDMA */
476669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
477669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
478669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
479669a5db4SJeff Garzik }
480669a5db4SJeff Garzik 
481669a5db4SJeff Garzik /**
482669a5db4SJeff Garzik  *	hpt370_bmdma_start		-	DMA engine begin
483669a5db4SJeff Garzik  *	@qc: ATA command
484669a5db4SJeff Garzik  *
485669a5db4SJeff Garzik  *	The 370 and 370A want us to reset the DMA engine each time we
486669a5db4SJeff Garzik  *	use it. The 372 and later are fine.
487669a5db4SJeff Garzik  */
488669a5db4SJeff Garzik 
489669a5db4SJeff Garzik static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
490669a5db4SJeff Garzik {
491669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
492669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
493669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
494669a5db4SJeff Garzik 	udelay(10);
495669a5db4SJeff Garzik 	ata_bmdma_start(qc);
496669a5db4SJeff Garzik }
497669a5db4SJeff Garzik 
498669a5db4SJeff Garzik /**
499669a5db4SJeff Garzik  *	hpt370_bmdma_end		-	DMA engine stop
500669a5db4SJeff Garzik  *	@qc: ATA command
501669a5db4SJeff Garzik  *
502669a5db4SJeff Garzik  *	Work around the HPT370 DMA engine.
503669a5db4SJeff Garzik  */
504669a5db4SJeff Garzik 
505669a5db4SJeff Garzik static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
506669a5db4SJeff Garzik {
507669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
508669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
5090d5ff566STejun Heo 	u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2);
510669a5db4SJeff Garzik 	u8 dma_cmd;
5110d5ff566STejun Heo 	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
512669a5db4SJeff Garzik 
513669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
514669a5db4SJeff Garzik 		udelay(20);
5150d5ff566STejun Heo 		dma_stat = ioread8(bmdma + 2);
516669a5db4SJeff Garzik 	}
517669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
518669a5db4SJeff Garzik 		/* Clear the engine */
519669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
520669a5db4SJeff Garzik 		udelay(10);
521669a5db4SJeff Garzik 		/* Stop DMA */
5220d5ff566STejun Heo 		dma_cmd = ioread8(bmdma );
5230d5ff566STejun Heo 		iowrite8(dma_cmd & 0xFE, bmdma);
524669a5db4SJeff Garzik 		/* Clear Error */
5250d5ff566STejun Heo 		dma_stat = ioread8(bmdma + 2);
5260d5ff566STejun Heo 		iowrite8(dma_stat | 0x06 , bmdma + 2);
527669a5db4SJeff Garzik 		/* Clear the engine */
528669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
529669a5db4SJeff Garzik 		udelay(10);
530669a5db4SJeff Garzik 	}
531669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
532669a5db4SJeff Garzik }
533669a5db4SJeff Garzik 
534669a5db4SJeff Garzik /**
535669a5db4SJeff Garzik  *	hpt372_set_piomode		-	PIO setup
536669a5db4SJeff Garzik  *	@ap: ATA interface
537669a5db4SJeff Garzik  *	@adev: device on the interface
538669a5db4SJeff Garzik  *
539669a5db4SJeff Garzik  *	Perform PIO mode setup.
540669a5db4SJeff Garzik  */
541669a5db4SJeff Garzik 
542669a5db4SJeff Garzik static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
543669a5db4SJeff Garzik {
544669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
545669a5db4SJeff Garzik 	u32 addr1, addr2;
546669a5db4SJeff Garzik 	u32 reg;
547669a5db4SJeff Garzik 	u32 mode;
548669a5db4SJeff Garzik 	u8 fast;
549669a5db4SJeff Garzik 
550669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
551669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
552669a5db4SJeff Garzik 
553669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
554669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
555669a5db4SJeff Garzik 	fast &= ~0x07;
556669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
557669a5db4SJeff Garzik 
558669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
559669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
560669a5db4SJeff Garzik 
561669a5db4SJeff Garzik 	printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
562669a5db4SJeff Garzik 	mode &= ~0x80000000;	/* No FIFO in PIO */
563669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
564669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
565669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
566669a5db4SJeff Garzik }
567669a5db4SJeff Garzik 
568669a5db4SJeff Garzik /**
569669a5db4SJeff Garzik  *	hpt372_set_dmamode		-	DMA timing setup
570669a5db4SJeff Garzik  *	@ap: ATA interface
571669a5db4SJeff Garzik  *	@adev: Device being configured
572669a5db4SJeff Garzik  *
573669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
574669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
575669a5db4SJeff Garzik  */
576669a5db4SJeff Garzik 
577669a5db4SJeff Garzik static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
578669a5db4SJeff Garzik {
579669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
580669a5db4SJeff Garzik 	u32 addr1, addr2;
581669a5db4SJeff Garzik 	u32 reg;
582669a5db4SJeff Garzik 	u32 mode;
583669a5db4SJeff Garzik 	u8 fast;
584669a5db4SJeff Garzik 
585669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
586669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
587669a5db4SJeff Garzik 
588669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
589669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
590669a5db4SJeff Garzik 	fast &= ~0x07;
591669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
592669a5db4SJeff Garzik 
593669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
594669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
595669a5db4SJeff Garzik 	printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
596669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
597669a5db4SJeff Garzik 	mode |= 0x80000000;	/* FIFO in MWDMA or UDMA */
598669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
599669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
600669a5db4SJeff Garzik }
601669a5db4SJeff Garzik 
602669a5db4SJeff Garzik /**
603669a5db4SJeff Garzik  *	hpt37x_bmdma_end		-	DMA engine stop
604669a5db4SJeff Garzik  *	@qc: ATA command
605669a5db4SJeff Garzik  *
606669a5db4SJeff Garzik  *	Clean up after the HPT372 and later DMA engine
607669a5db4SJeff Garzik  */
608669a5db4SJeff Garzik 
609669a5db4SJeff Garzik static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
610669a5db4SJeff Garzik {
611669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
612669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
6136929da44SAlan 	int mscreg = 0x50 + 4 * ap->port_no;
614669a5db4SJeff Garzik 	u8 bwsr_stat, msc_stat;
615669a5db4SJeff Garzik 
616669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
617669a5db4SJeff Garzik 	pci_read_config_byte(pdev, mscreg, &msc_stat);
618669a5db4SJeff Garzik 	if (bwsr_stat & (1 << ap->port_no))
619669a5db4SJeff Garzik 		pci_write_config_byte(pdev, mscreg, msc_stat | 0x30);
620669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
621669a5db4SJeff Garzik }
622669a5db4SJeff Garzik 
623669a5db4SJeff Garzik 
624669a5db4SJeff Garzik static struct scsi_host_template hpt37x_sht = {
625669a5db4SJeff Garzik 	.module			= THIS_MODULE,
626669a5db4SJeff Garzik 	.name			= DRV_NAME,
627669a5db4SJeff Garzik 	.ioctl			= ata_scsi_ioctl,
628669a5db4SJeff Garzik 	.queuecommand		= ata_scsi_queuecmd,
629669a5db4SJeff Garzik 	.can_queue		= ATA_DEF_QUEUE,
630669a5db4SJeff Garzik 	.this_id		= ATA_SHT_THIS_ID,
631669a5db4SJeff Garzik 	.sg_tablesize		= LIBATA_MAX_PRD,
632669a5db4SJeff Garzik 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
633669a5db4SJeff Garzik 	.emulated		= ATA_SHT_EMULATED,
634669a5db4SJeff Garzik 	.use_clustering		= ATA_SHT_USE_CLUSTERING,
635669a5db4SJeff Garzik 	.proc_name		= DRV_NAME,
636669a5db4SJeff Garzik 	.dma_boundary		= ATA_DMA_BOUNDARY,
637669a5db4SJeff Garzik 	.slave_configure	= ata_scsi_slave_config,
638afdfe899STejun Heo 	.slave_destroy		= ata_scsi_slave_destroy,
639669a5db4SJeff Garzik 	.bios_param		= ata_std_bios_param,
640669a5db4SJeff Garzik };
641669a5db4SJeff Garzik 
642669a5db4SJeff Garzik /*
643669a5db4SJeff Garzik  *	Configuration for HPT370
644669a5db4SJeff Garzik  */
645669a5db4SJeff Garzik 
646669a5db4SJeff Garzik static struct ata_port_operations hpt370_port_ops = {
647669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
648669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
649669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
650669a5db4SJeff Garzik 	.mode_filter	= hpt370_filter,
651669a5db4SJeff Garzik 
652669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
653669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
654669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
655669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
656669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
657669a5db4SJeff Garzik 
658669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
659669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
660669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
661669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
662669a5db4SJeff Garzik 
663669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
664669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
665669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
666669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
667669a5db4SJeff Garzik 
668669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
669669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
670bda30288SJeff Garzik 
6710d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
672669a5db4SJeff Garzik 
673669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
674669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
675246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
676246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
677669a5db4SJeff Garzik 
678669a5db4SJeff Garzik 	.port_start	= ata_port_start,
679669a5db4SJeff Garzik };
680669a5db4SJeff Garzik 
681669a5db4SJeff Garzik /*
682669a5db4SJeff Garzik  *	Configuration for HPT370A. Close to 370 but less filters
683669a5db4SJeff Garzik  */
684669a5db4SJeff Garzik 
685669a5db4SJeff Garzik static struct ata_port_operations hpt370a_port_ops = {
686669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
687669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
688669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
689669a5db4SJeff Garzik 	.mode_filter	= hpt370a_filter,
690669a5db4SJeff Garzik 
691669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
692669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
693669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
694669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
695669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
696669a5db4SJeff Garzik 
697669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
698669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
699669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
700669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
701669a5db4SJeff Garzik 
702669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
703669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
704669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
705669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
706669a5db4SJeff Garzik 
707669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
708669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
709bda30288SJeff Garzik 
7100d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
711669a5db4SJeff Garzik 
712669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
713669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
714246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
715246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
716669a5db4SJeff Garzik 
717669a5db4SJeff Garzik 	.port_start	= ata_port_start,
718669a5db4SJeff Garzik };
719669a5db4SJeff Garzik 
720669a5db4SJeff Garzik /*
721669a5db4SJeff Garzik  *	Configuration for HPT372, HPT371, HPT302. Slightly different PIO
722669a5db4SJeff Garzik  *	and DMA mode setting functionality.
723669a5db4SJeff Garzik  */
724669a5db4SJeff Garzik 
725669a5db4SJeff Garzik static struct ata_port_operations hpt372_port_ops = {
726669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
727669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
728669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
729669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
730669a5db4SJeff Garzik 
731669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
732669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
733669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
734669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
735669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
736669a5db4SJeff Garzik 
737669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
738669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
739669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
740669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
741669a5db4SJeff Garzik 
742669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
743669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
744669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
745669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
746669a5db4SJeff Garzik 
747669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
748669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
749bda30288SJeff Garzik 
7500d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
751669a5db4SJeff Garzik 
752669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
753669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
754246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
755246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
756669a5db4SJeff Garzik 
757669a5db4SJeff Garzik 	.port_start	= ata_port_start,
758669a5db4SJeff Garzik };
759669a5db4SJeff Garzik 
760669a5db4SJeff Garzik /*
761669a5db4SJeff Garzik  *	Configuration for HPT374. Mode setting works like 372 and friends
762669a5db4SJeff Garzik  *	but we have a different cable detection procedure.
763669a5db4SJeff Garzik  */
764669a5db4SJeff Garzik 
765669a5db4SJeff Garzik static struct ata_port_operations hpt374_port_ops = {
766669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
767669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
768669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
769669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
770669a5db4SJeff Garzik 
771669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
772669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
773669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
774669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
775669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
776669a5db4SJeff Garzik 
777669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
778669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
779669a5db4SJeff Garzik 	.error_handler	= hpt374_error_handler,
780669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
781669a5db4SJeff Garzik 
782669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
783669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
784669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
785669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
786669a5db4SJeff Garzik 
787669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
788669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
789bda30288SJeff Garzik 
7900d5ff566STejun Heo 	.data_xfer	= ata_data_xfer,
791669a5db4SJeff Garzik 
792669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
793669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
794246ce3b6SAkira Iguchi 	.irq_on		= ata_irq_on,
795246ce3b6SAkira Iguchi 	.irq_ack	= ata_irq_ack,
796669a5db4SJeff Garzik 
797669a5db4SJeff Garzik 	.port_start	= ata_port_start,
798669a5db4SJeff Garzik };
799669a5db4SJeff Garzik 
800669a5db4SJeff Garzik /**
801669a5db4SJeff Garzik  *	htp37x_clock_slot	-	Turn timing to PC clock entry
802669a5db4SJeff Garzik  *	@freq: Reported frequency timing
803669a5db4SJeff Garzik  *	@base: Base timing
804669a5db4SJeff Garzik  *
805669a5db4SJeff Garzik  *	Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50
806669a5db4SJeff Garzik  *	and 3 for 66Mhz)
807669a5db4SJeff Garzik  */
808669a5db4SJeff Garzik 
809669a5db4SJeff Garzik static int hpt37x_clock_slot(unsigned int freq, unsigned int base)
810669a5db4SJeff Garzik {
811669a5db4SJeff Garzik 	unsigned int f = (base * freq) / 192;	/* Mhz */
812669a5db4SJeff Garzik 	if (f < 40)
813669a5db4SJeff Garzik 		return 0;	/* 33Mhz slot */
814669a5db4SJeff Garzik 	if (f < 45)
815669a5db4SJeff Garzik 		return 1;	/* 40Mhz slot */
816669a5db4SJeff Garzik 	if (f < 55)
817669a5db4SJeff Garzik 		return 2;	/* 50Mhz slot */
818669a5db4SJeff Garzik 	return 3;		/* 60Mhz slot */
819669a5db4SJeff Garzik }
820669a5db4SJeff Garzik 
821669a5db4SJeff Garzik /**
822669a5db4SJeff Garzik  *	hpt37x_calibrate_dpll		-	Calibrate the DPLL loop
823669a5db4SJeff Garzik  *	@dev: PCI device
824669a5db4SJeff Garzik  *
825669a5db4SJeff Garzik  *	Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this
826669a5db4SJeff Garzik  *	succeeds
827669a5db4SJeff Garzik  */
828669a5db4SJeff Garzik 
829669a5db4SJeff Garzik static int hpt37x_calibrate_dpll(struct pci_dev *dev)
830669a5db4SJeff Garzik {
831669a5db4SJeff Garzik 	u8 reg5b;
832669a5db4SJeff Garzik 	u32 reg5c;
833669a5db4SJeff Garzik 	int tries;
834669a5db4SJeff Garzik 
835669a5db4SJeff Garzik 	for(tries = 0; tries < 0x5000; tries++) {
836669a5db4SJeff Garzik 		udelay(50);
837669a5db4SJeff Garzik 		pci_read_config_byte(dev, 0x5b, &reg5b);
838669a5db4SJeff Garzik 		if (reg5b & 0x80) {
839669a5db4SJeff Garzik 			/* See if it stays set */
840669a5db4SJeff Garzik 			for(tries = 0; tries < 0x1000; tries ++) {
841669a5db4SJeff Garzik 				pci_read_config_byte(dev, 0x5b, &reg5b);
842669a5db4SJeff Garzik 				/* Failed ? */
843669a5db4SJeff Garzik 				if ((reg5b & 0x80) == 0)
844669a5db4SJeff Garzik 					return 0;
845669a5db4SJeff Garzik 			}
846669a5db4SJeff Garzik 			/* Turn off tuning, we have the DPLL set */
847669a5db4SJeff Garzik 			pci_read_config_dword(dev, 0x5c, &reg5c);
848669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100);
849669a5db4SJeff Garzik 			return 1;
850669a5db4SJeff Garzik 		}
851669a5db4SJeff Garzik 	}
852669a5db4SJeff Garzik 	/* Never went stable */
853669a5db4SJeff Garzik 	return 0;
854669a5db4SJeff Garzik }
855669a5db4SJeff Garzik /**
856669a5db4SJeff Garzik  *	hpt37x_init_one		-	Initialise an HPT37X/302
857669a5db4SJeff Garzik  *	@dev: PCI device
858669a5db4SJeff Garzik  *	@id: Entry in match table
859669a5db4SJeff Garzik  *
860669a5db4SJeff Garzik  *	Initialise an HPT37x device. There are some interesting complications
861669a5db4SJeff Garzik  *	here. Firstly the chip may report 366 and be one of several variants.
862669a5db4SJeff Garzik  *	Secondly all the timings depend on the clock for the chip which we must
863669a5db4SJeff Garzik  *	detect and look up
864669a5db4SJeff Garzik  *
865669a5db4SJeff Garzik  *	This is the known chip mappings. It may be missing a couple of later
866669a5db4SJeff Garzik  *	releases.
867669a5db4SJeff Garzik  *
868669a5db4SJeff Garzik  *	Chip version		PCI		Rev	Notes
869669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	0	Other driver
870669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	1	Other driver
871669a5db4SJeff Garzik  *	HPT368			4 (HPT366)	2	Other driver
872669a5db4SJeff Garzik  *	HPT370			4 (HPT366)	3	UDMA100
873669a5db4SJeff Garzik  *	HPT370A			4 (HPT366)	4	UDMA100
874669a5db4SJeff Garzik  *	HPT372			4 (HPT366)	5	UDMA133 (1)
875669a5db4SJeff Garzik  *	HPT372N			4 (HPT366)	6	Other driver
876669a5db4SJeff Garzik  *	HPT372A			5 (HPT372)	1	UDMA133 (1)
877669a5db4SJeff Garzik  *	HPT372N			5 (HPT372)	2	Other driver
878669a5db4SJeff Garzik  *	HPT302			6 (HPT302)	1	UDMA133
879669a5db4SJeff Garzik  *	HPT302N			6 (HPT302)	2	Other driver
880669a5db4SJeff Garzik  *	HPT371			7 (HPT371)	*	UDMA133
881669a5db4SJeff Garzik  *	HPT374			8 (HPT374)	*	UDMA133 4 channel
882669a5db4SJeff Garzik  *	HPT372N			9 (HPT372N)	*	Other driver
883669a5db4SJeff Garzik  *
884669a5db4SJeff Garzik  *	(1) UDMA133 support depends on the bus clock
885669a5db4SJeff Garzik  */
886669a5db4SJeff Garzik 
887669a5db4SJeff Garzik static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
888669a5db4SJeff Garzik {
889669a5db4SJeff Garzik 	/* HPT370 - UDMA100 */
8901626aeb8STejun Heo 	static const struct ata_port_info info_hpt370 = {
891669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
892669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
893669a5db4SJeff Garzik 		.pio_mask = 0x1f,
894669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
895669a5db4SJeff Garzik 		.udma_mask = 0x3f,
896669a5db4SJeff Garzik 		.port_ops = &hpt370_port_ops
897669a5db4SJeff Garzik 	};
898669a5db4SJeff Garzik 	/* HPT370A - UDMA100 */
8991626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a = {
900669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
901669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
902669a5db4SJeff Garzik 		.pio_mask = 0x1f,
903669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
904669a5db4SJeff Garzik 		.udma_mask = 0x3f,
905669a5db4SJeff Garzik 		.port_ops = &hpt370a_port_ops
906669a5db4SJeff Garzik 	};
907fcc2f69aSAlan Cox 	/* HPT370 - UDMA100 */
9081626aeb8STejun Heo 	static const struct ata_port_info info_hpt370_33 = {
909fcc2f69aSAlan Cox 		.sht = &hpt37x_sht,
910fcc2f69aSAlan Cox 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
911fcc2f69aSAlan Cox 		.pio_mask = 0x1f,
912fcc2f69aSAlan Cox 		.mwdma_mask = 0x07,
913fcc2f69aSAlan Cox 		.udma_mask = 0x0f,
914fcc2f69aSAlan Cox 		.port_ops = &hpt370_port_ops
915fcc2f69aSAlan Cox 	};
916fcc2f69aSAlan Cox 	/* HPT370A - UDMA100 */
9171626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a_33 = {
918fcc2f69aSAlan Cox 		.sht = &hpt37x_sht,
919fcc2f69aSAlan Cox 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
920fcc2f69aSAlan Cox 		.pio_mask = 0x1f,
921fcc2f69aSAlan Cox 		.mwdma_mask = 0x07,
922fcc2f69aSAlan Cox 		.udma_mask = 0x0f,
923fcc2f69aSAlan Cox 		.port_ops = &hpt370a_port_ops
924fcc2f69aSAlan Cox 	};
925669a5db4SJeff Garzik 	/* HPT371, 372 and friends - UDMA133 */
9261626aeb8STejun Heo 	static const struct ata_port_info info_hpt372 = {
927669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
928669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
929669a5db4SJeff Garzik 		.pio_mask = 0x1f,
930669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
931669a5db4SJeff Garzik 		.udma_mask = 0x7f,
932669a5db4SJeff Garzik 		.port_ops = &hpt372_port_ops
933669a5db4SJeff Garzik 	};
93462877f6bSAlan Cox 	/* HPT374 - UDMA100 */
9351626aeb8STejun Heo 	static const struct ata_port_info info_hpt374 = {
936669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
937669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
938669a5db4SJeff Garzik 		.pio_mask = 0x1f,
939669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
94062877f6bSAlan Cox 		.udma_mask = 0x3f,
941669a5db4SJeff Garzik 		.port_ops = &hpt374_port_ops
942669a5db4SJeff Garzik 	};
943669a5db4SJeff Garzik 
944669a5db4SJeff Garzik 	static const int MHz[4] = { 33, 40, 50, 66 };
9451626aeb8STejun Heo 	const struct ata_port_info *port;
9461626aeb8STejun Heo 	void *private_data = NULL;
9471626aeb8STejun Heo 	struct ata_port_info port_info;
9481626aeb8STejun Heo 	const struct ata_port_info *ppi[] = { &port_info, NULL };
949669a5db4SJeff Garzik 
950669a5db4SJeff Garzik 	u8 irqmask;
951669a5db4SJeff Garzik 	u32 class_rev;
952fcc2f69aSAlan Cox 	u8 mcr1;
953669a5db4SJeff Garzik 	u32 freq;
954fcc2f69aSAlan Cox 	int prefer_dpll = 1;
955fcc2f69aSAlan Cox 
956fcc2f69aSAlan Cox 	unsigned long iobase = pci_resource_start(dev, 4);
957669a5db4SJeff Garzik 
958669a5db4SJeff Garzik 	const struct hpt_chip *chip_table;
959669a5db4SJeff Garzik 	int clock_slot;
960669a5db4SJeff Garzik 
961669a5db4SJeff Garzik 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
962669a5db4SJeff Garzik 	class_rev &= 0xFF;
963669a5db4SJeff Garzik 
964669a5db4SJeff Garzik 	if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
965669a5db4SJeff Garzik 		/* May be a later chip in disguise. Check */
966669a5db4SJeff Garzik 		/* Older chips are in the HPT366 driver. Ignore them */
967669a5db4SJeff Garzik 		if (class_rev < 3)
968669a5db4SJeff Garzik 			return -ENODEV;
969669a5db4SJeff Garzik 		/* N series chips have their own driver. Ignore */
970669a5db4SJeff Garzik 		if (class_rev == 6)
971669a5db4SJeff Garzik 			return -ENODEV;
972669a5db4SJeff Garzik 
973669a5db4SJeff Garzik 		switch(class_rev) {
974669a5db4SJeff Garzik 			case 3:
975669a5db4SJeff Garzik 				port = &info_hpt370;
976669a5db4SJeff Garzik 				chip_table = &hpt370;
977fcc2f69aSAlan Cox 				prefer_dpll = 0;
978669a5db4SJeff Garzik 				break;
979669a5db4SJeff Garzik 			case 4:
980669a5db4SJeff Garzik 				port = &info_hpt370a;
981669a5db4SJeff Garzik 				chip_table = &hpt370a;
982fcc2f69aSAlan Cox 				prefer_dpll = 0;
983669a5db4SJeff Garzik 				break;
984669a5db4SJeff Garzik 			case 5:
985669a5db4SJeff Garzik 				port = &info_hpt372;
986669a5db4SJeff Garzik 				chip_table = &hpt372;
987669a5db4SJeff Garzik 				break;
988669a5db4SJeff Garzik 			default:
989669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev);
990669a5db4SJeff Garzik 				return -ENODEV;
991669a5db4SJeff Garzik 		}
992669a5db4SJeff Garzik 	} else {
993669a5db4SJeff Garzik 		switch(dev->device) {
994669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT372:
995669a5db4SJeff Garzik 				/* 372N if rev >= 2*/
996669a5db4SJeff Garzik 				if (class_rev >= 2)
997669a5db4SJeff Garzik 					return -ENODEV;
998669a5db4SJeff Garzik 				port = &info_hpt372;
999669a5db4SJeff Garzik 				chip_table = &hpt372a;
1000669a5db4SJeff Garzik 				break;
1001669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT302:
1002669a5db4SJeff Garzik 				/* 302N if rev > 1 */
1003669a5db4SJeff Garzik 				if (class_rev > 1)
1004669a5db4SJeff Garzik 					return -ENODEV;
1005669a5db4SJeff Garzik 				port = &info_hpt372;
1006669a5db4SJeff Garzik 				/* Check this */
1007669a5db4SJeff Garzik 				chip_table = &hpt302;
1008669a5db4SJeff Garzik 				break;
1009669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT371:
1010fcc2f69aSAlan Cox 				if (class_rev > 1)
1011fcc2f69aSAlan Cox 					return -ENODEV;
1012669a5db4SJeff Garzik 				port = &info_hpt372;
1013669a5db4SJeff Garzik 				chip_table = &hpt371;
1014a4734468SAlan Cox 				/* Single channel device, master is not present
1015a4734468SAlan Cox 				   but the BIOS (or us for non x86) must mark it
1016fcc2f69aSAlan Cox 				   absent */
1017fcc2f69aSAlan Cox 				pci_read_config_byte(dev, 0x50, &mcr1);
1018fcc2f69aSAlan Cox 				mcr1 &= ~0x04;
1019fcc2f69aSAlan Cox 				pci_write_config_byte(dev, 0x50, mcr1);
1020669a5db4SJeff Garzik 				break;
1021669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT374:
1022669a5db4SJeff Garzik 				chip_table = &hpt374;
1023669a5db4SJeff Garzik 				port = &info_hpt374;
1024669a5db4SJeff Garzik 				break;
1025669a5db4SJeff Garzik 			default:
1026669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device);
1027669a5db4SJeff Garzik 				return -ENODEV;
1028669a5db4SJeff Garzik 		}
1029669a5db4SJeff Garzik 	}
1030669a5db4SJeff Garzik 	/* Ok so this is a chip we support */
1031669a5db4SJeff Garzik 
1032669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
1033669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
1034669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
1035669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
1036669a5db4SJeff Garzik 
1037669a5db4SJeff Garzik 	pci_read_config_byte(dev, 0x5A, &irqmask);
1038669a5db4SJeff Garzik 	irqmask &= ~0x10;
1039669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5a, irqmask);
1040669a5db4SJeff Garzik 
1041669a5db4SJeff Garzik 	/*
1042669a5db4SJeff Garzik 	 * default to pci clock. make sure MA15/16 are set to output
1043669a5db4SJeff Garzik 	 * to prevent drives having problems with 40-pin cables. Needed
1044669a5db4SJeff Garzik 	 * for some drives such as IBM-DTLA which will not enter ready
1045669a5db4SJeff Garzik 	 * state on reset when PDIAG is a input.
1046669a5db4SJeff Garzik 	 */
1047669a5db4SJeff Garzik 
1048669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5b, 0x23);
1049669a5db4SJeff Garzik 
1050fcc2f69aSAlan Cox 	/*
1051fcc2f69aSAlan Cox 	 * HighPoint does this for HPT372A.
1052fcc2f69aSAlan Cox 	 * NOTE: This register is only writeable via I/O space.
1053fcc2f69aSAlan Cox 	 */
1054fcc2f69aSAlan Cox 	if (chip_table == &hpt372a)
1055fcc2f69aSAlan Cox 		outb(0x0e, iobase + 0x9c);
1056fcc2f69aSAlan Cox 
1057fcc2f69aSAlan Cox 	/* Some devices do not let this value be accessed via PCI space
1058fcc2f69aSAlan Cox 	   according to the old driver */
1059fcc2f69aSAlan Cox 
1060fcc2f69aSAlan Cox 	freq = inl(iobase + 0x90);
1061669a5db4SJeff Garzik 	if ((freq >> 12) != 0xABCDE) {
1062669a5db4SJeff Garzik 		int i;
1063669a5db4SJeff Garzik 		u8 sr;
1064669a5db4SJeff Garzik 		u32 total = 0;
1065669a5db4SJeff Garzik 
1066669a5db4SJeff Garzik 		printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
1067669a5db4SJeff Garzik 
1068669a5db4SJeff Garzik 		/* This is the process the HPT371 BIOS is reported to use */
1069669a5db4SJeff Garzik 		for(i = 0; i < 128; i++) {
1070669a5db4SJeff Garzik 			pci_read_config_byte(dev, 0x78, &sr);
1071fcc2f69aSAlan Cox 			total += sr & 0x1FF;
1072669a5db4SJeff Garzik 			udelay(15);
1073669a5db4SJeff Garzik 		}
1074669a5db4SJeff Garzik 		freq = total / 128;
1075669a5db4SJeff Garzik 	}
1076669a5db4SJeff Garzik 	freq &= 0x1FF;
1077669a5db4SJeff Garzik 
1078669a5db4SJeff Garzik 	/*
1079669a5db4SJeff Garzik 	 *	Turn the frequency check into a band and then find a timing
1080669a5db4SJeff Garzik 	 *	table to match it.
1081669a5db4SJeff Garzik 	 */
1082669a5db4SJeff Garzik 
1083669a5db4SJeff Garzik 	clock_slot = hpt37x_clock_slot(freq, chip_table->base);
1084fcc2f69aSAlan Cox 	if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
1085669a5db4SJeff Garzik 		/*
1086669a5db4SJeff Garzik 		 *	We need to try PLL mode instead
1087fcc2f69aSAlan Cox 		 *
1088fcc2f69aSAlan Cox 		 *	For non UDMA133 capable devices we should
1089fcc2f69aSAlan Cox 		 *	use a 50MHz DPLL by choice
1090669a5db4SJeff Garzik 		 */
1091fcc2f69aSAlan Cox 		unsigned int f_low, f_high;
1092960c8a10SAlan Cox 		int dpll, adjust;
1093669a5db4SJeff Garzik 
1094960c8a10SAlan Cox 		/* Compute DPLL */
1095960c8a10SAlan Cox 		dpll = 2;
1096fcc2f69aSAlan Cox 		if (port->udma_mask & 0xE0)
1097960c8a10SAlan Cox 			dpll = 3;
1098fcc2f69aSAlan Cox 
1099960c8a10SAlan Cox 		f_low = (MHz[clock_slot] * 48) / MHz[dpll];
1100fcc2f69aSAlan Cox 		f_high = f_low + 2;
1101960c8a10SAlan Cox 		if (clock_slot > 1)
1102960c8a10SAlan Cox 			f_high += 2;
1103fcc2f69aSAlan Cox 
1104fcc2f69aSAlan Cox 		/* Select the DPLL clock. */
1105fcc2f69aSAlan Cox 		pci_write_config_byte(dev, 0x5b, 0x21);
1106960c8a10SAlan Cox 		pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
1107fcc2f69aSAlan Cox 
1108669a5db4SJeff Garzik 		for(adjust = 0; adjust < 8; adjust++) {
1109669a5db4SJeff Garzik 			if (hpt37x_calibrate_dpll(dev))
1110669a5db4SJeff Garzik 				break;
1111669a5db4SJeff Garzik 			/* See if it'll settle at a fractionally different clock */
1112669a5db4SJeff Garzik 			if ((adjust & 3) == 3) {
1113669a5db4SJeff Garzik 				f_low --;
1114669a5db4SJeff Garzik 				f_high ++;
1115669a5db4SJeff Garzik 			}
1116669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
1117669a5db4SJeff Garzik 		}
1118669a5db4SJeff Garzik 		if (adjust == 8) {
1119669a5db4SJeff Garzik 			printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
1120669a5db4SJeff Garzik 			return -ENODEV;
1121669a5db4SJeff Garzik 		}
1122960c8a10SAlan Cox 		if (dpll == 3)
11231626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_66;
1124fcc2f69aSAlan Cox 		else
11251626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_50;
1126669a5db4SJeff Garzik 
1127960c8a10SAlan Cox 		printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
1128669a5db4SJeff Garzik 	} else {
11291626aeb8STejun Heo 		private_data = (void *)chip_table->clocks[clock_slot];
1130669a5db4SJeff Garzik 		/*
1131a4734468SAlan Cox 		 *	Perform a final fixup. Note that we will have used the
1132a4734468SAlan Cox 		 *	DPLL on the HPT372 which means we don't have to worry
1133a4734468SAlan Cox 		 *	about lack of UDMA133 support on lower clocks
1134669a5db4SJeff Garzik  		 */
1135669a5db4SJeff Garzik 
1136fcc2f69aSAlan Cox 		if (clock_slot < 2 && port == &info_hpt370)
1137fcc2f69aSAlan Cox 			port = &info_hpt370_33;
1138fcc2f69aSAlan Cox 		if (clock_slot < 2 && port == &info_hpt370a)
1139fcc2f69aSAlan Cox 			port = &info_hpt370a_33;
1140669a5db4SJeff Garzik 		printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
1141669a5db4SJeff Garzik 	}
1142fcc2f69aSAlan Cox 
1143669a5db4SJeff Garzik 	/* Now kick off ATA set up */
11441626aeb8STejun Heo 	port_info = *port;
11451626aeb8STejun Heo 	port_info.private_data = private_data;
11461626aeb8STejun Heo 
11471626aeb8STejun Heo 	return ata_pci_init_one(dev, ppi);
1148669a5db4SJeff Garzik }
1149669a5db4SJeff Garzik 
11502d2744fcSJeff Garzik static const struct pci_device_id hpt37x[] = {
11512d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
11522d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
11532d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
11542d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), },
11552d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
11562d2744fcSJeff Garzik 
11572d2744fcSJeff Garzik 	{ },
1158669a5db4SJeff Garzik };
1159669a5db4SJeff Garzik 
1160669a5db4SJeff Garzik static struct pci_driver hpt37x_pci_driver = {
1161669a5db4SJeff Garzik 	.name 		= DRV_NAME,
1162669a5db4SJeff Garzik 	.id_table	= hpt37x,
1163669a5db4SJeff Garzik 	.probe 		= hpt37x_init_one,
1164669a5db4SJeff Garzik 	.remove		= ata_pci_remove_one
1165669a5db4SJeff Garzik };
1166669a5db4SJeff Garzik 
1167669a5db4SJeff Garzik static int __init hpt37x_init(void)
1168669a5db4SJeff Garzik {
1169669a5db4SJeff Garzik 	return pci_register_driver(&hpt37x_pci_driver);
1170669a5db4SJeff Garzik }
1171669a5db4SJeff Garzik 
1172669a5db4SJeff Garzik static void __exit hpt37x_exit(void)
1173669a5db4SJeff Garzik {
1174669a5db4SJeff Garzik 	pci_unregister_driver(&hpt37x_pci_driver);
1175669a5db4SJeff Garzik }
1176669a5db4SJeff Garzik 
1177669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
1178669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
1179669a5db4SJeff Garzik MODULE_LICENSE("GPL");
1180669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, hpt37x);
1181669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
1182669a5db4SJeff Garzik 
1183669a5db4SJeff Garzik module_init(hpt37x_init);
1184669a5db4SJeff Garzik module_exit(hpt37x_exit);
1185