xref: /openbmc/linux/drivers/ata/pata_hpt37x.c (revision 669a5db4)
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
11669a5db4SJeff Garzik  *
12669a5db4SJeff Garzik  * TODO
13669a5db4SJeff Garzik  *	PLL mode
14669a5db4SJeff Garzik  *	Look into engine reset on timeout errors. Should not be
15669a5db4SJeff Garzik  *		required.
16669a5db4SJeff Garzik  */
17669a5db4SJeff Garzik 
18669a5db4SJeff Garzik #include <linux/kernel.h>
19669a5db4SJeff Garzik #include <linux/module.h>
20669a5db4SJeff Garzik #include <linux/pci.h>
21669a5db4SJeff Garzik #include <linux/init.h>
22669a5db4SJeff Garzik #include <linux/blkdev.h>
23669a5db4SJeff Garzik #include <linux/delay.h>
24669a5db4SJeff Garzik #include <scsi/scsi_host.h>
25669a5db4SJeff Garzik #include <linux/libata.h>
26669a5db4SJeff Garzik 
27669a5db4SJeff Garzik #define DRV_NAME	"pata_hpt37x"
28669a5db4SJeff Garzik #define DRV_VERSION	"0.5"
29669a5db4SJeff Garzik 
30669a5db4SJeff Garzik struct hpt_clock {
31669a5db4SJeff Garzik 	u8	xfer_speed;
32669a5db4SJeff Garzik 	u32	timing;
33669a5db4SJeff Garzik };
34669a5db4SJeff Garzik 
35669a5db4SJeff Garzik struct hpt_chip {
36669a5db4SJeff Garzik 	const char *name;
37669a5db4SJeff Garzik 	unsigned int base;
38669a5db4SJeff Garzik 	struct hpt_clock const *clocks[4];
39669a5db4SJeff Garzik };
40669a5db4SJeff Garzik 
41669a5db4SJeff Garzik /* key for bus clock timings
42669a5db4SJeff Garzik  * bit
43669a5db4SJeff Garzik  * 0:3    data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW
44669a5db4SJeff Garzik  *        DMA. cycles = value + 1
45669a5db4SJeff Garzik  * 4:8    data_low_time. active time of DIOW_/DIOR_ for PIO and MW
46669a5db4SJeff Garzik  *        DMA. cycles = value + 1
47669a5db4SJeff Garzik  * 9:12   cmd_high_time. inactive time of DIOW_/DIOR_ during task file
48669a5db4SJeff Garzik  *        register access.
49669a5db4SJeff Garzik  * 13:17  cmd_low_time. active time of DIOW_/DIOR_ during task file
50669a5db4SJeff Garzik  *        register access.
51669a5db4SJeff Garzik  * 18:21  udma_cycle_time. clock freq and clock cycles for UDMA xfer.
52669a5db4SJeff Garzik  *        during task file register access.
53669a5db4SJeff Garzik  * 22:24  pre_high_time. time to initialize 1st cycle for PIO and MW DMA
54669a5db4SJeff Garzik  *        xfer.
55669a5db4SJeff Garzik  * 25:27  cmd_pre_high_time. time to initialize 1st PIO cycle for task
56669a5db4SJeff Garzik  *        register access.
57669a5db4SJeff Garzik  * 28     UDMA enable
58669a5db4SJeff Garzik  * 29     DMA enable
59669a5db4SJeff Garzik  * 30     PIO_MST enable. if set, the chip is in bus master mode during
60669a5db4SJeff Garzik  *        PIO.
61669a5db4SJeff Garzik  * 31     FIFO enable.
62669a5db4SJeff Garzik  */
63669a5db4SJeff Garzik 
64669a5db4SJeff Garzik /* from highpoint documentation. these are old values */
65669a5db4SJeff Garzik static const struct hpt_clock hpt370_timings_33[] = {
66669a5db4SJeff Garzik /*	{	XFER_UDMA_5,	0x1A85F442,	0x16454e31	}, */
67669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x16454e31	},
68669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x16454e31	},
69669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x166d4e31	},
70669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x16494e31	},
71669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x164d4e31	},
72669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x16514e31	},
73669a5db4SJeff Garzik 
74669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x26514e21	},
75669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x26514e33	},
76669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x26514e97	},
77669a5db4SJeff Garzik 
78669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x06514e21	},
79669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x06514e22	},
80669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x06514e33	},
81669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x06914e43	},
82669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x06914e57	},
83669a5db4SJeff Garzik 	{	0,		0x06514e57	}
84669a5db4SJeff Garzik };
85669a5db4SJeff Garzik 
86669a5db4SJeff Garzik static const struct hpt_clock hpt370_timings_66[] = {
87669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x14846231	},
88669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x14886231	},
89669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x148c6231	},
90669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x148c6231	},
91669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x14906231	},
92669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x14986231	},
93669a5db4SJeff Garzik 
94669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x26514e21	},
95669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x26514e33	},
96669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x26514e97	},
97669a5db4SJeff Garzik 
98669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x06514e21	},
99669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x06514e22	},
100669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x06514e33	},
101669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x06914e43	},
102669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x06914e57	},
103669a5db4SJeff Garzik 	{	0,		0x06514e57	}
104669a5db4SJeff Garzik };
105669a5db4SJeff Garzik 
106669a5db4SJeff Garzik /* these are the current (4 sep 2001) timings from highpoint */
107669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_33[] = {
108669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x12446231	},
109669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x12446231	},
110669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x126c6231	},
111669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x12486231	},
112669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x124c6233	},
113669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x12506297	},
114669a5db4SJeff Garzik 
115669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x22406c31	},
116669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x22406c33	},
117669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x22406c97	},
118669a5db4SJeff Garzik 
119669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x06414e31	},
120669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x06414e42	},
121669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x06414e53	},
122669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x06814e93	},
123669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x06814ea7	},
124669a5db4SJeff Garzik 	{	0,		0x06814ea7	}
125669a5db4SJeff Garzik };
126669a5db4SJeff Garzik 
127669a5db4SJeff Garzik /* 2x 33MHz timings */
128669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_66[] = {
129669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x1488e673	},
130669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x1488e673	},
131669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x1498e673	},
132669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x1490e673	},
133669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x1498e677	},
134669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x14a0e73f	},
135669a5db4SJeff Garzik 
136669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x2480fa73	},
137669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x2480fa77	},
138669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x2480fb3f	},
139669a5db4SJeff Garzik 
140669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0c82be73	},
141669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0c82be95	},
142669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0c82beb7	},
143669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0d02bf37	},
144669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0d02bf5f	},
145669a5db4SJeff Garzik 	{	0,		0x0d02bf5f	}
146669a5db4SJeff Garzik };
147669a5db4SJeff Garzik 
148669a5db4SJeff Garzik static const struct hpt_clock hpt370a_timings_50[] = {
149669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x12848242	},
150669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x12ac8242	},
151669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x128c8242	},
152669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x120c8242	},
153669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x12148254	},
154669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x121882ea	},
155669a5db4SJeff Garzik 
156669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x22808242	},
157669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x22808254	},
158669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x228082ea	},
159669a5db4SJeff Garzik 
160669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0a81f442	},
161669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0a81f443	},
162669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0a81f454	},
163669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0ac1f465	},
164669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0ac1f48a	},
165669a5db4SJeff Garzik 	{	0,		0x0ac1f48a	}
166669a5db4SJeff Garzik };
167669a5db4SJeff Garzik 
168669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_33[] = {
169669a5db4SJeff Garzik 	{	XFER_UDMA_6,	0x1c81dc62	},
170669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x1c6ddc62	},
171669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x1c8ddc62	},
172669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x1c8edc62	},	/* checkme */
173669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x1c91dc62	},
174669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x1c9adc62	},	/* checkme */
175669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x1c82dc62	},	/* checkme */
176669a5db4SJeff Garzik 
177669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x2c829262	},
178669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x2c829266	},	/* checkme */
179669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x2c82922e	},	/* checkme */
180669a5db4SJeff Garzik 
181669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0c829c62	},
182669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0c829c84	},
183669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0c829ca6	},
184669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0d029d26	},
185669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0d029d5e	},
186669a5db4SJeff Garzik 	{	0,		0x0d029d5e	}
187669a5db4SJeff Garzik };
188669a5db4SJeff Garzik 
189669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_50[] = {
190669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x12848242	},
191669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x12ac8242	},
192669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x128c8242	},
193669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x120c8242	},
194669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x12148254	},
195669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x121882ea	},
196669a5db4SJeff Garzik 
197669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x22808242	},
198669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x22808254	},
199669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x228082ea	},
200669a5db4SJeff Garzik 
201669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0a81f442	},
202669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0a81f443	},
203669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0a81f454	},
204669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0ac1f465	},
205669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0ac1f48a	},
206669a5db4SJeff Garzik 	{	0,		0x0a81f443	}
207669a5db4SJeff Garzik };
208669a5db4SJeff Garzik 
209669a5db4SJeff Garzik static const struct hpt_clock hpt372_timings_66[] = {
210669a5db4SJeff Garzik 	{	XFER_UDMA_6,	0x1c869c62	},
211669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x1cae9c62	},
212669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x1c8a9c62	},
213669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x1c8e9c62	},
214669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x1c929c62	},
215669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x1c9a9c62	},
216669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x1c829c62	},
217669a5db4SJeff Garzik 
218669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x2c829c62	},
219669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x2c829c66	},
220669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x2c829d2e	},
221669a5db4SJeff Garzik 
222669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0c829c62	},
223669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0c829c84	},
224669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0c829ca6	},
225669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0d029d26	},
226669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0d029d5e	},
227669a5db4SJeff Garzik 	{	0,		0x0d029d26	}
228669a5db4SJeff Garzik };
229669a5db4SJeff Garzik 
230669a5db4SJeff Garzik static const struct hpt_clock hpt374_timings_33[] = {
231669a5db4SJeff Garzik 	{	XFER_UDMA_6,	0x12808242	},
232669a5db4SJeff Garzik 	{	XFER_UDMA_5,	0x12848242	},
233669a5db4SJeff Garzik 	{	XFER_UDMA_4,	0x12ac8242	},
234669a5db4SJeff Garzik 	{	XFER_UDMA_3,	0x128c8242	},
235669a5db4SJeff Garzik 	{	XFER_UDMA_2,	0x120c8242	},
236669a5db4SJeff Garzik 	{	XFER_UDMA_1,	0x12148254	},
237669a5db4SJeff Garzik 	{	XFER_UDMA_0,	0x121882ea	},
238669a5db4SJeff Garzik 
239669a5db4SJeff Garzik 	{	XFER_MW_DMA_2,	0x22808242	},
240669a5db4SJeff Garzik 	{	XFER_MW_DMA_1,	0x22808254	},
241669a5db4SJeff Garzik 	{	XFER_MW_DMA_0,	0x228082ea	},
242669a5db4SJeff Garzik 
243669a5db4SJeff Garzik 	{	XFER_PIO_4,	0x0a81f442	},
244669a5db4SJeff Garzik 	{	XFER_PIO_3,	0x0a81f443	},
245669a5db4SJeff Garzik 	{	XFER_PIO_2,	0x0a81f454	},
246669a5db4SJeff Garzik 	{	XFER_PIO_1,	0x0ac1f465	},
247669a5db4SJeff Garzik 	{	XFER_PIO_0,	0x0ac1f48a	},
248669a5db4SJeff Garzik 	{	0,		0x06814e93	}
249669a5db4SJeff Garzik };
250669a5db4SJeff Garzik 
251669a5db4SJeff Garzik static const struct hpt_chip hpt370 = {
252669a5db4SJeff Garzik 	"HPT370",
253669a5db4SJeff Garzik 	48,
254669a5db4SJeff Garzik 	{
255669a5db4SJeff Garzik 		hpt370_timings_33,
256669a5db4SJeff Garzik 		NULL,
257669a5db4SJeff Garzik 		NULL,
258669a5db4SJeff Garzik 		hpt370_timings_66
259669a5db4SJeff Garzik 	}
260669a5db4SJeff Garzik };
261669a5db4SJeff Garzik 
262669a5db4SJeff Garzik static const struct hpt_chip hpt370a = {
263669a5db4SJeff Garzik 	"HPT370A",
264669a5db4SJeff Garzik 	48,
265669a5db4SJeff Garzik 	{
266669a5db4SJeff Garzik 		hpt370a_timings_33,
267669a5db4SJeff Garzik 		NULL,
268669a5db4SJeff Garzik 		hpt370a_timings_50,
269669a5db4SJeff Garzik 		hpt370a_timings_66
270669a5db4SJeff Garzik 	}
271669a5db4SJeff Garzik };
272669a5db4SJeff Garzik 
273669a5db4SJeff Garzik static const struct hpt_chip hpt372 = {
274669a5db4SJeff Garzik 	"HPT372",
275669a5db4SJeff Garzik 	55,
276669a5db4SJeff Garzik 	{
277669a5db4SJeff Garzik 		hpt372_timings_33,
278669a5db4SJeff Garzik 		NULL,
279669a5db4SJeff Garzik 		hpt372_timings_50,
280669a5db4SJeff Garzik 		hpt372_timings_66
281669a5db4SJeff Garzik 	}
282669a5db4SJeff Garzik };
283669a5db4SJeff Garzik 
284669a5db4SJeff Garzik static const struct hpt_chip hpt302 = {
285669a5db4SJeff Garzik 	"HPT302",
286669a5db4SJeff Garzik 	66,
287669a5db4SJeff Garzik 	{
288669a5db4SJeff Garzik 		hpt372_timings_33,
289669a5db4SJeff Garzik 		NULL,
290669a5db4SJeff Garzik 		hpt372_timings_50,
291669a5db4SJeff Garzik 		hpt372_timings_66
292669a5db4SJeff Garzik 	}
293669a5db4SJeff Garzik };
294669a5db4SJeff Garzik 
295669a5db4SJeff Garzik static const struct hpt_chip hpt371 = {
296669a5db4SJeff Garzik 	"HPT371",
297669a5db4SJeff Garzik 	66,
298669a5db4SJeff Garzik 	{
299669a5db4SJeff Garzik 		hpt372_timings_33,
300669a5db4SJeff Garzik 		NULL,
301669a5db4SJeff Garzik 		hpt372_timings_50,
302669a5db4SJeff Garzik 		hpt372_timings_66
303669a5db4SJeff Garzik 	}
304669a5db4SJeff Garzik };
305669a5db4SJeff Garzik 
306669a5db4SJeff Garzik static const struct hpt_chip hpt372a = {
307669a5db4SJeff Garzik 	"HPT372A",
308669a5db4SJeff Garzik 	66,
309669a5db4SJeff Garzik 	{
310669a5db4SJeff Garzik 		hpt372_timings_33,
311669a5db4SJeff Garzik 		NULL,
312669a5db4SJeff Garzik 		hpt372_timings_50,
313669a5db4SJeff Garzik 		hpt372_timings_66
314669a5db4SJeff Garzik 	}
315669a5db4SJeff Garzik };
316669a5db4SJeff Garzik 
317669a5db4SJeff Garzik static const struct hpt_chip hpt374 = {
318669a5db4SJeff Garzik 	"HPT374",
319669a5db4SJeff Garzik 	48,
320669a5db4SJeff Garzik 	{
321669a5db4SJeff Garzik 		hpt374_timings_33,
322669a5db4SJeff Garzik 		NULL,
323669a5db4SJeff Garzik 		NULL,
324669a5db4SJeff Garzik 		NULL
325669a5db4SJeff Garzik 	}
326669a5db4SJeff Garzik };
327669a5db4SJeff Garzik 
328669a5db4SJeff Garzik /**
329669a5db4SJeff Garzik  *	hpt37x_find_mode	-	reset the hpt37x bus
330669a5db4SJeff Garzik  *	@ap: ATA port
331669a5db4SJeff Garzik  *	@speed: transfer mode
332669a5db4SJeff Garzik  *
333669a5db4SJeff Garzik  *	Return the 32bit register programming information for this channel
334669a5db4SJeff Garzik  *	that matches the speed provided.
335669a5db4SJeff Garzik  */
336669a5db4SJeff Garzik 
337669a5db4SJeff Garzik static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
338669a5db4SJeff Garzik {
339669a5db4SJeff Garzik 	struct hpt_clock *clocks = ap->host->private_data;
340669a5db4SJeff Garzik 
341669a5db4SJeff Garzik 	while(clocks->xfer_speed) {
342669a5db4SJeff Garzik 		if (clocks->xfer_speed == speed)
343669a5db4SJeff Garzik 			return clocks->timing;
344669a5db4SJeff Garzik 		clocks++;
345669a5db4SJeff Garzik 	}
346669a5db4SJeff Garzik 	BUG();
347669a5db4SJeff Garzik 	return 0xffffffffU;	/* silence compiler warning */
348669a5db4SJeff Garzik }
349669a5db4SJeff Garzik 
350669a5db4SJeff Garzik static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
351669a5db4SJeff Garzik {
352669a5db4SJeff Garzik 	unsigned char model_num[40];
353669a5db4SJeff Garzik 	char *s;
354669a5db4SJeff Garzik 	unsigned int len;
355669a5db4SJeff Garzik 	int i = 0;
356669a5db4SJeff Garzik 
357669a5db4SJeff Garzik 	ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
358669a5db4SJeff Garzik 			  sizeof(model_num));
359669a5db4SJeff Garzik 	s = &model_num[0];
360669a5db4SJeff Garzik 	len = strnlen(s, sizeof(model_num));
361669a5db4SJeff Garzik 
362669a5db4SJeff Garzik 	/* ATAPI specifies that empty space is blank-filled; remove blanks */
363669a5db4SJeff Garzik 	while ((len > 0) && (s[len - 1] == ' ')) {
364669a5db4SJeff Garzik 		len--;
365669a5db4SJeff Garzik 		s[len] = 0;
366669a5db4SJeff Garzik 	}
367669a5db4SJeff Garzik 
368669a5db4SJeff Garzik 	while(list[i] != NULL) {
369669a5db4SJeff Garzik 		if (!strncmp(list[i], s, len)) {
370669a5db4SJeff Garzik 			printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
371669a5db4SJeff Garzik 				modestr, list[i]);
372669a5db4SJeff Garzik 			return 1;
373669a5db4SJeff Garzik 		}
374669a5db4SJeff Garzik 		i++;
375669a5db4SJeff Garzik 	}
376669a5db4SJeff Garzik 	return 0;
377669a5db4SJeff Garzik }
378669a5db4SJeff Garzik 
379669a5db4SJeff Garzik static const char *bad_ata33[] = {
380669a5db4SJeff Garzik 	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2",
381669a5db4SJeff Garzik 	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
382669a5db4SJeff Garzik 	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
383669a5db4SJeff Garzik 	"Maxtor 90510D4",
384669a5db4SJeff Garzik 	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
385669a5db4SJeff Garzik 	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
386669a5db4SJeff Garzik 	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
387669a5db4SJeff Garzik 	NULL
388669a5db4SJeff Garzik };
389669a5db4SJeff Garzik 
390669a5db4SJeff Garzik static const char *bad_ata100_5[] = {
391669a5db4SJeff Garzik 	"IBM-DTLA-307075",
392669a5db4SJeff Garzik 	"IBM-DTLA-307060",
393669a5db4SJeff Garzik 	"IBM-DTLA-307045",
394669a5db4SJeff Garzik 	"IBM-DTLA-307030",
395669a5db4SJeff Garzik 	"IBM-DTLA-307020",
396669a5db4SJeff Garzik 	"IBM-DTLA-307015",
397669a5db4SJeff Garzik 	"IBM-DTLA-305040",
398669a5db4SJeff Garzik 	"IBM-DTLA-305030",
399669a5db4SJeff Garzik 	"IBM-DTLA-305020",
400669a5db4SJeff Garzik 	"IC35L010AVER07-0",
401669a5db4SJeff Garzik 	"IC35L020AVER07-0",
402669a5db4SJeff Garzik 	"IC35L030AVER07-0",
403669a5db4SJeff Garzik 	"IC35L040AVER07-0",
404669a5db4SJeff Garzik 	"IC35L060AVER07-0",
405669a5db4SJeff Garzik 	"WDC AC310200R",
406669a5db4SJeff Garzik 	NULL
407669a5db4SJeff Garzik };
408669a5db4SJeff Garzik 
409669a5db4SJeff Garzik /**
410669a5db4SJeff Garzik  *	hpt370_filter	-	mode selection filter
411669a5db4SJeff Garzik  *	@ap: ATA interface
412669a5db4SJeff Garzik  *	@adev: ATA device
413669a5db4SJeff Garzik  *
414669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
415669a5db4SJeff Garzik  */
416669a5db4SJeff Garzik 
417669a5db4SJeff Garzik static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
418669a5db4SJeff Garzik {
419669a5db4SJeff Garzik 	if (adev->class != ATA_DEV_ATA) {
420669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
421669a5db4SJeff Garzik 			mask &= ~ATA_MASK_UDMA;
422669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
423669a5db4SJeff Garzik 			mask &= ~(0x1F << ATA_SHIFT_UDMA);
424669a5db4SJeff Garzik 	}
425669a5db4SJeff Garzik 	return ata_pci_default_filter(ap, adev, mask);
426669a5db4SJeff Garzik }
427669a5db4SJeff Garzik 
428669a5db4SJeff Garzik /**
429669a5db4SJeff Garzik  *	hpt370a_filter	-	mode selection filter
430669a5db4SJeff Garzik  *	@ap: ATA interface
431669a5db4SJeff Garzik  *	@adev: ATA device
432669a5db4SJeff Garzik  *
433669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
434669a5db4SJeff Garzik  */
435669a5db4SJeff Garzik 
436669a5db4SJeff Garzik static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
437669a5db4SJeff Garzik {
438669a5db4SJeff Garzik 	if (adev->class != ATA_DEV_ATA) {
439669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
440669a5db4SJeff Garzik 			mask &= ~ (0x1F << ATA_SHIFT_UDMA);
441669a5db4SJeff Garzik 	}
442669a5db4SJeff Garzik 	return ata_pci_default_filter(ap, adev, mask);
443669a5db4SJeff Garzik }
444669a5db4SJeff Garzik 
445669a5db4SJeff Garzik /**
446669a5db4SJeff Garzik  *	hpt37x_pre_reset	-	reset the hpt37x bus
447669a5db4SJeff Garzik  *	@ap: ATA port to reset
448669a5db4SJeff Garzik  *
449669a5db4SJeff Garzik  *	Perform the initial reset handling for the 370/372 and 374 func 0
450669a5db4SJeff Garzik  */
451669a5db4SJeff Garzik 
452669a5db4SJeff Garzik static int hpt37x_pre_reset(struct ata_port *ap)
453669a5db4SJeff Garzik {
454669a5db4SJeff Garzik 	u8 scr2, ata66;
455669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
456669a5db4SJeff Garzik 
457669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5B, &scr2);
458669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
459669a5db4SJeff Garzik 	/* Cable register now active */
460669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
461669a5db4SJeff Garzik 	/* Restore state */
462669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2);
463669a5db4SJeff Garzik 
464669a5db4SJeff Garzik 	if (ata66 & (1 << ap->port_no))
465669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
466669a5db4SJeff Garzik 	else
467669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
468669a5db4SJeff Garzik 
469669a5db4SJeff Garzik 	/* Reset the state machine */
470669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x50, 0x37);
471669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x54, 0x37);
472669a5db4SJeff Garzik 	udelay(100);
473669a5db4SJeff Garzik 
474669a5db4SJeff Garzik 	return ata_std_prereset(ap);
475669a5db4SJeff Garzik }
476669a5db4SJeff Garzik 
477669a5db4SJeff Garzik /**
478669a5db4SJeff Garzik  *	hpt37x_error_handler	-	reset the hpt374
479669a5db4SJeff Garzik  *	@ap: ATA port to reset
480669a5db4SJeff Garzik  *
481669a5db4SJeff Garzik  *	Perform probe for HPT37x, except for HPT374 channel 2
482669a5db4SJeff Garzik  */
483669a5db4SJeff Garzik 
484669a5db4SJeff Garzik static void hpt37x_error_handler(struct ata_port *ap)
485669a5db4SJeff Garzik {
486669a5db4SJeff Garzik 	ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
487669a5db4SJeff Garzik }
488669a5db4SJeff Garzik 
489669a5db4SJeff Garzik static int hpt374_pre_reset(struct ata_port *ap)
490669a5db4SJeff Garzik {
491669a5db4SJeff Garzik 	u16 mcr3, mcr6;
492669a5db4SJeff Garzik 	u8 ata66;
493669a5db4SJeff Garzik 
494669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
495669a5db4SJeff Garzik 	/* Do the extra channel work */
496669a5db4SJeff Garzik 	pci_read_config_word(pdev, 0x52, &mcr3);
497669a5db4SJeff Garzik 	pci_read_config_word(pdev, 0x56, &mcr6);
498669a5db4SJeff Garzik 	/* Set bit 15 of 0x52 to enable TCBLID as input
499669a5db4SJeff Garzik 	   Set bit 15 of 0x56 to enable FCBLID as input
500669a5db4SJeff Garzik 	 */
501669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x52, mcr3 | 0x8000);
502669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x56, mcr6 | 0x8000);
503669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
504669a5db4SJeff Garzik 	/* Reset TCBLID/FCBLID to output */
505669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x52, mcr3);
506669a5db4SJeff Garzik 	pci_write_config_word(pdev, 0x56, mcr6);
507669a5db4SJeff Garzik 
508669a5db4SJeff Garzik 	if (ata66 & (1 << ap->port_no))
509669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA40;
510669a5db4SJeff Garzik 	else
511669a5db4SJeff Garzik 		ap->cbl = ATA_CBL_PATA80;
512669a5db4SJeff Garzik 
513669a5db4SJeff Garzik 	/* Reset the state machine */
514669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x50, 0x37);
515669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x54, 0x37);
516669a5db4SJeff Garzik 	udelay(100);
517669a5db4SJeff Garzik 
518669a5db4SJeff Garzik 	return ata_std_prereset(ap);
519669a5db4SJeff Garzik }
520669a5db4SJeff Garzik 
521669a5db4SJeff Garzik /**
522669a5db4SJeff Garzik  *	hpt374_error_handler	-	reset the hpt374
523669a5db4SJeff Garzik  *	@classes:
524669a5db4SJeff Garzik  *
525669a5db4SJeff Garzik  *	The 374 cable detect is a little different due to the extra
526669a5db4SJeff Garzik  *	channels. The function 0 channels work like usual but function 1
527669a5db4SJeff Garzik  *	is special
528669a5db4SJeff Garzik  */
529669a5db4SJeff Garzik 
530669a5db4SJeff Garzik static void hpt374_error_handler(struct ata_port *ap)
531669a5db4SJeff Garzik {
532669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
533669a5db4SJeff Garzik 
534669a5db4SJeff Garzik 	if (!(PCI_FUNC(pdev->devfn) & 1))
535669a5db4SJeff Garzik 		hpt37x_error_handler(ap);
536669a5db4SJeff Garzik 	else
537669a5db4SJeff Garzik 		ata_bmdma_drive_eh(ap, hpt374_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
538669a5db4SJeff Garzik }
539669a5db4SJeff Garzik 
540669a5db4SJeff Garzik /**
541669a5db4SJeff Garzik  *	hpt370_set_piomode		-	PIO setup
542669a5db4SJeff Garzik  *	@ap: ATA interface
543669a5db4SJeff Garzik  *	@adev: device on the interface
544669a5db4SJeff Garzik  *
545669a5db4SJeff Garzik  *	Perform PIO mode setup.
546669a5db4SJeff Garzik  */
547669a5db4SJeff Garzik 
548669a5db4SJeff Garzik static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev)
549669a5db4SJeff Garzik {
550669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
551669a5db4SJeff Garzik 	u32 addr1, addr2;
552669a5db4SJeff Garzik 	u32 reg;
553669a5db4SJeff Garzik 	u32 mode;
554669a5db4SJeff Garzik 	u8 fast;
555669a5db4SJeff Garzik 
556669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
557669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
558669a5db4SJeff Garzik 
559669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
560669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
561669a5db4SJeff Garzik 	fast &= ~0x02;
562669a5db4SJeff Garzik 	fast |= 0x01;
563669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
564669a5db4SJeff Garzik 
565669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
566669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
567669a5db4SJeff Garzik 	mode &= ~0x8000000;	/* No FIFO in PIO */
568669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
569669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
570669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
571669a5db4SJeff Garzik }
572669a5db4SJeff Garzik 
573669a5db4SJeff Garzik /**
574669a5db4SJeff Garzik  *	hpt370_set_dmamode		-	DMA timing setup
575669a5db4SJeff Garzik  *	@ap: ATA interface
576669a5db4SJeff Garzik  *	@adev: Device being configured
577669a5db4SJeff Garzik  *
578669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
579669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
580669a5db4SJeff Garzik  */
581669a5db4SJeff Garzik 
582669a5db4SJeff Garzik static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev)
583669a5db4SJeff Garzik {
584669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
585669a5db4SJeff Garzik 	u32 addr1, addr2;
586669a5db4SJeff Garzik 	u32 reg;
587669a5db4SJeff Garzik 	u32 mode;
588669a5db4SJeff Garzik 	u8 fast;
589669a5db4SJeff Garzik 
590669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
591669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
592669a5db4SJeff Garzik 
593669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
594669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
595669a5db4SJeff Garzik 	fast &= ~0x02;
596669a5db4SJeff Garzik 	fast |= 0x01;
597669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
598669a5db4SJeff Garzik 
599669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
600669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
601669a5db4SJeff Garzik 	mode |= 0x8000000;	/* FIFO in MWDMA or UDMA */
602669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
603669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
604669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
605669a5db4SJeff Garzik }
606669a5db4SJeff Garzik 
607669a5db4SJeff Garzik /**
608669a5db4SJeff Garzik  *	hpt370_bmdma_start		-	DMA engine begin
609669a5db4SJeff Garzik  *	@qc: ATA command
610669a5db4SJeff Garzik  *
611669a5db4SJeff Garzik  *	The 370 and 370A want us to reset the DMA engine each time we
612669a5db4SJeff Garzik  *	use it. The 372 and later are fine.
613669a5db4SJeff Garzik  */
614669a5db4SJeff Garzik 
615669a5db4SJeff Garzik static void hpt370_bmdma_start(struct ata_queued_cmd *qc)
616669a5db4SJeff Garzik {
617669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
618669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
619669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
620669a5db4SJeff Garzik 	udelay(10);
621669a5db4SJeff Garzik 	ata_bmdma_start(qc);
622669a5db4SJeff Garzik }
623669a5db4SJeff Garzik 
624669a5db4SJeff Garzik /**
625669a5db4SJeff Garzik  *	hpt370_bmdma_end		-	DMA engine stop
626669a5db4SJeff Garzik  *	@qc: ATA command
627669a5db4SJeff Garzik  *
628669a5db4SJeff Garzik  *	Work around the HPT370 DMA engine.
629669a5db4SJeff Garzik  */
630669a5db4SJeff Garzik 
631669a5db4SJeff Garzik static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
632669a5db4SJeff Garzik {
633669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
634669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
635669a5db4SJeff Garzik 	u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2);
636669a5db4SJeff Garzik 	u8 dma_cmd;
637669a5db4SJeff Garzik 	unsigned long bmdma = ap->ioaddr.bmdma_addr;
638669a5db4SJeff Garzik 
639669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
640669a5db4SJeff Garzik 		udelay(20);
641669a5db4SJeff Garzik 		dma_stat = inb(bmdma + 2);
642669a5db4SJeff Garzik 	}
643669a5db4SJeff Garzik 	if (dma_stat & 0x01) {
644669a5db4SJeff Garzik 		/* Clear the engine */
645669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
646669a5db4SJeff Garzik 		udelay(10);
647669a5db4SJeff Garzik 		/* Stop DMA */
648669a5db4SJeff Garzik 		dma_cmd = inb(bmdma );
649669a5db4SJeff Garzik 		outb(dma_cmd & 0xFE, bmdma);
650669a5db4SJeff Garzik 		/* Clear Error */
651669a5db4SJeff Garzik 		dma_stat = inb(bmdma + 2);
652669a5db4SJeff Garzik 		outb(dma_stat | 0x06 , bmdma + 2);
653669a5db4SJeff Garzik 		/* Clear the engine */
654669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
655669a5db4SJeff Garzik 		udelay(10);
656669a5db4SJeff Garzik 	}
657669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
658669a5db4SJeff Garzik }
659669a5db4SJeff Garzik 
660669a5db4SJeff Garzik /**
661669a5db4SJeff Garzik  *	hpt372_set_piomode		-	PIO setup
662669a5db4SJeff Garzik  *	@ap: ATA interface
663669a5db4SJeff Garzik  *	@adev: device on the interface
664669a5db4SJeff Garzik  *
665669a5db4SJeff Garzik  *	Perform PIO mode setup.
666669a5db4SJeff Garzik  */
667669a5db4SJeff Garzik 
668669a5db4SJeff Garzik static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev)
669669a5db4SJeff Garzik {
670669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
671669a5db4SJeff Garzik 	u32 addr1, addr2;
672669a5db4SJeff Garzik 	u32 reg;
673669a5db4SJeff Garzik 	u32 mode;
674669a5db4SJeff Garzik 	u8 fast;
675669a5db4SJeff Garzik 
676669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
677669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
678669a5db4SJeff Garzik 
679669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
680669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
681669a5db4SJeff Garzik 	fast &= ~0x07;
682669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
683669a5db4SJeff Garzik 
684669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
685669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->pio_mode);
686669a5db4SJeff Garzik 
687669a5db4SJeff Garzik 	printk("Find mode for %d reports %X\n", adev->pio_mode, mode);
688669a5db4SJeff Garzik 	mode &= ~0x80000000;	/* No FIFO in PIO */
689669a5db4SJeff Garzik 	mode &= ~0x30070000;	/* Leave config bits alone */
690669a5db4SJeff Garzik 	reg &= 0x30070000;	/* Strip timing bits */
691669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
692669a5db4SJeff Garzik }
693669a5db4SJeff Garzik 
694669a5db4SJeff Garzik /**
695669a5db4SJeff Garzik  *	hpt372_set_dmamode		-	DMA timing setup
696669a5db4SJeff Garzik  *	@ap: ATA interface
697669a5db4SJeff Garzik  *	@adev: Device being configured
698669a5db4SJeff Garzik  *
699669a5db4SJeff Garzik  *	Set up the channel for MWDMA or UDMA modes. Much the same as with
700669a5db4SJeff Garzik  *	PIO, load the mode number and then set MWDMA or UDMA flag.
701669a5db4SJeff Garzik  */
702669a5db4SJeff Garzik 
703669a5db4SJeff Garzik static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev)
704669a5db4SJeff Garzik {
705669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
706669a5db4SJeff Garzik 	u32 addr1, addr2;
707669a5db4SJeff Garzik 	u32 reg;
708669a5db4SJeff Garzik 	u32 mode;
709669a5db4SJeff Garzik 	u8 fast;
710669a5db4SJeff Garzik 
711669a5db4SJeff Garzik 	addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
712669a5db4SJeff Garzik 	addr2 = 0x51 + 4 * ap->port_no;
713669a5db4SJeff Garzik 
714669a5db4SJeff Garzik 	/* Fast interrupt prediction disable, hold off interrupt disable */
715669a5db4SJeff Garzik 	pci_read_config_byte(pdev, addr2, &fast);
716669a5db4SJeff Garzik 	fast &= ~0x07;
717669a5db4SJeff Garzik 	pci_write_config_byte(pdev, addr2, fast);
718669a5db4SJeff Garzik 
719669a5db4SJeff Garzik 	pci_read_config_dword(pdev, addr1, &reg);
720669a5db4SJeff Garzik 	mode = hpt37x_find_mode(ap, adev->dma_mode);
721669a5db4SJeff Garzik 	printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode);
722669a5db4SJeff Garzik 	mode &= ~0xC0000000;	/* Leave config bits alone */
723669a5db4SJeff Garzik 	mode |= 0x80000000;	/* FIFO in MWDMA or UDMA */
724669a5db4SJeff Garzik 	reg &= 0xC0000000;	/* Strip timing bits */
725669a5db4SJeff Garzik 	pci_write_config_dword(pdev, addr1, reg | mode);
726669a5db4SJeff Garzik }
727669a5db4SJeff Garzik 
728669a5db4SJeff Garzik /**
729669a5db4SJeff Garzik  *	hpt37x_bmdma_end		-	DMA engine stop
730669a5db4SJeff Garzik  *	@qc: ATA command
731669a5db4SJeff Garzik  *
732669a5db4SJeff Garzik  *	Clean up after the HPT372 and later DMA engine
733669a5db4SJeff Garzik  */
734669a5db4SJeff Garzik 
735669a5db4SJeff Garzik static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
736669a5db4SJeff Garzik {
737669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
738669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
739669a5db4SJeff Garzik 	int mscreg = 0x50 + 2 * ap->port_no;
740669a5db4SJeff Garzik 	u8 bwsr_stat, msc_stat;
741669a5db4SJeff Garzik 
742669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
743669a5db4SJeff Garzik 	pci_read_config_byte(pdev, mscreg, &msc_stat);
744669a5db4SJeff Garzik 	if (bwsr_stat & (1 << ap->port_no))
745669a5db4SJeff Garzik 		pci_write_config_byte(pdev, mscreg, msc_stat | 0x30);
746669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
747669a5db4SJeff Garzik }
748669a5db4SJeff Garzik 
749669a5db4SJeff Garzik 
750669a5db4SJeff Garzik static struct scsi_host_template hpt37x_sht = {
751669a5db4SJeff Garzik 	.module			= THIS_MODULE,
752669a5db4SJeff Garzik 	.name			= DRV_NAME,
753669a5db4SJeff Garzik 	.ioctl			= ata_scsi_ioctl,
754669a5db4SJeff Garzik 	.queuecommand		= ata_scsi_queuecmd,
755669a5db4SJeff Garzik 	.can_queue		= ATA_DEF_QUEUE,
756669a5db4SJeff Garzik 	.this_id		= ATA_SHT_THIS_ID,
757669a5db4SJeff Garzik 	.sg_tablesize		= LIBATA_MAX_PRD,
758669a5db4SJeff Garzik 	.max_sectors		= ATA_MAX_SECTORS,
759669a5db4SJeff Garzik 	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
760669a5db4SJeff Garzik 	.emulated		= ATA_SHT_EMULATED,
761669a5db4SJeff Garzik 	.use_clustering		= ATA_SHT_USE_CLUSTERING,
762669a5db4SJeff Garzik 	.proc_name		= DRV_NAME,
763669a5db4SJeff Garzik 	.dma_boundary		= ATA_DMA_BOUNDARY,
764669a5db4SJeff Garzik 	.slave_configure	= ata_scsi_slave_config,
765669a5db4SJeff Garzik 	.bios_param		= ata_std_bios_param,
766669a5db4SJeff Garzik };
767669a5db4SJeff Garzik 
768669a5db4SJeff Garzik /*
769669a5db4SJeff Garzik  *	Configuration for HPT370
770669a5db4SJeff Garzik  */
771669a5db4SJeff Garzik 
772669a5db4SJeff Garzik static struct ata_port_operations hpt370_port_ops = {
773669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
774669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
775669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
776669a5db4SJeff Garzik 	.mode_filter	= hpt370_filter,
777669a5db4SJeff Garzik 
778669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
779669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
780669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
781669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
782669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
783669a5db4SJeff Garzik 
784669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
785669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
786669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
787669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
788669a5db4SJeff Garzik 
789669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
790669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
791669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
792669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
793669a5db4SJeff Garzik 
794669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
795669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
796669a5db4SJeff Garzik 	.eng_timeout	= ata_eng_timeout,
797669a5db4SJeff Garzik 	.data_xfer	= ata_pio_data_xfer,
798669a5db4SJeff Garzik 
799669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
800669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
801669a5db4SJeff Garzik 
802669a5db4SJeff Garzik 	.port_start	= ata_port_start,
803669a5db4SJeff Garzik 	.port_stop	= ata_port_stop,
804669a5db4SJeff Garzik 	.host_stop	= ata_host_stop
805669a5db4SJeff Garzik };
806669a5db4SJeff Garzik 
807669a5db4SJeff Garzik /*
808669a5db4SJeff Garzik  *	Configuration for HPT370A. Close to 370 but less filters
809669a5db4SJeff Garzik  */
810669a5db4SJeff Garzik 
811669a5db4SJeff Garzik static struct ata_port_operations hpt370a_port_ops = {
812669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
813669a5db4SJeff Garzik 	.set_piomode	= hpt370_set_piomode,
814669a5db4SJeff Garzik 	.set_dmamode	= hpt370_set_dmamode,
815669a5db4SJeff Garzik 	.mode_filter	= hpt370a_filter,
816669a5db4SJeff Garzik 
817669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
818669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
819669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
820669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
821669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
822669a5db4SJeff Garzik 
823669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
824669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
825669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
826669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
827669a5db4SJeff Garzik 
828669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
829669a5db4SJeff Garzik 	.bmdma_start 	= hpt370_bmdma_start,
830669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
831669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
832669a5db4SJeff Garzik 
833669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
834669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
835669a5db4SJeff Garzik 	.eng_timeout	= ata_eng_timeout,
836669a5db4SJeff Garzik 	.data_xfer	= ata_pio_data_xfer,
837669a5db4SJeff Garzik 
838669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
839669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
840669a5db4SJeff Garzik 
841669a5db4SJeff Garzik 	.port_start	= ata_port_start,
842669a5db4SJeff Garzik 	.port_stop	= ata_port_stop,
843669a5db4SJeff Garzik 	.host_stop	= ata_host_stop
844669a5db4SJeff Garzik };
845669a5db4SJeff Garzik 
846669a5db4SJeff Garzik /*
847669a5db4SJeff Garzik  *	Configuration for HPT372, HPT371, HPT302. Slightly different PIO
848669a5db4SJeff Garzik  *	and DMA mode setting functionality.
849669a5db4SJeff Garzik  */
850669a5db4SJeff Garzik 
851669a5db4SJeff Garzik static struct ata_port_operations hpt372_port_ops = {
852669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
853669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
854669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
855669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
856669a5db4SJeff Garzik 
857669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
858669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
859669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
860669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
861669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
862669a5db4SJeff Garzik 
863669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
864669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
865669a5db4SJeff Garzik 	.error_handler	= hpt37x_error_handler,
866669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
867669a5db4SJeff Garzik 
868669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
869669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
870669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
871669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
872669a5db4SJeff Garzik 
873669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
874669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
875669a5db4SJeff Garzik 	.eng_timeout	= ata_eng_timeout,
876669a5db4SJeff Garzik 	.data_xfer	= ata_pio_data_xfer,
877669a5db4SJeff Garzik 
878669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
879669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
880669a5db4SJeff Garzik 
881669a5db4SJeff Garzik 	.port_start	= ata_port_start,
882669a5db4SJeff Garzik 	.port_stop	= ata_port_stop,
883669a5db4SJeff Garzik 	.host_stop	= ata_host_stop
884669a5db4SJeff Garzik };
885669a5db4SJeff Garzik 
886669a5db4SJeff Garzik /*
887669a5db4SJeff Garzik  *	Configuration for HPT374. Mode setting works like 372 and friends
888669a5db4SJeff Garzik  *	but we have a different cable detection procedure.
889669a5db4SJeff Garzik  */
890669a5db4SJeff Garzik 
891669a5db4SJeff Garzik static struct ata_port_operations hpt374_port_ops = {
892669a5db4SJeff Garzik 	.port_disable	= ata_port_disable,
893669a5db4SJeff Garzik 	.set_piomode	= hpt372_set_piomode,
894669a5db4SJeff Garzik 	.set_dmamode	= hpt372_set_dmamode,
895669a5db4SJeff Garzik 	.mode_filter	= ata_pci_default_filter,
896669a5db4SJeff Garzik 
897669a5db4SJeff Garzik 	.tf_load	= ata_tf_load,
898669a5db4SJeff Garzik 	.tf_read	= ata_tf_read,
899669a5db4SJeff Garzik 	.check_status 	= ata_check_status,
900669a5db4SJeff Garzik 	.exec_command	= ata_exec_command,
901669a5db4SJeff Garzik 	.dev_select 	= ata_std_dev_select,
902669a5db4SJeff Garzik 
903669a5db4SJeff Garzik 	.freeze		= ata_bmdma_freeze,
904669a5db4SJeff Garzik 	.thaw		= ata_bmdma_thaw,
905669a5db4SJeff Garzik 	.error_handler	= hpt374_error_handler,
906669a5db4SJeff Garzik 	.post_internal_cmd = ata_bmdma_post_internal_cmd,
907669a5db4SJeff Garzik 
908669a5db4SJeff Garzik 	.bmdma_setup 	= ata_bmdma_setup,
909669a5db4SJeff Garzik 	.bmdma_start 	= ata_bmdma_start,
910669a5db4SJeff Garzik 	.bmdma_stop	= hpt37x_bmdma_stop,
911669a5db4SJeff Garzik 	.bmdma_status 	= ata_bmdma_status,
912669a5db4SJeff Garzik 
913669a5db4SJeff Garzik 	.qc_prep 	= ata_qc_prep,
914669a5db4SJeff Garzik 	.qc_issue	= ata_qc_issue_prot,
915669a5db4SJeff Garzik 	.eng_timeout	= ata_eng_timeout,
916669a5db4SJeff Garzik 	.data_xfer	= ata_pio_data_xfer,
917669a5db4SJeff Garzik 
918669a5db4SJeff Garzik 	.irq_handler	= ata_interrupt,
919669a5db4SJeff Garzik 	.irq_clear	= ata_bmdma_irq_clear,
920669a5db4SJeff Garzik 
921669a5db4SJeff Garzik 	.port_start	= ata_port_start,
922669a5db4SJeff Garzik 	.port_stop	= ata_port_stop,
923669a5db4SJeff Garzik 	.host_stop	= ata_host_stop
924669a5db4SJeff Garzik };
925669a5db4SJeff Garzik 
926669a5db4SJeff Garzik /**
927669a5db4SJeff Garzik  *	htp37x_clock_slot	-	Turn timing to PC clock entry
928669a5db4SJeff Garzik  *	@freq: Reported frequency timing
929669a5db4SJeff Garzik  *	@base: Base timing
930669a5db4SJeff Garzik  *
931669a5db4SJeff Garzik  *	Turn the timing data intoa clock slot (0 for 33, 1 for 40, 2 for 50
932669a5db4SJeff Garzik  *	and 3 for 66Mhz)
933669a5db4SJeff Garzik  */
934669a5db4SJeff Garzik 
935669a5db4SJeff Garzik static int hpt37x_clock_slot(unsigned int freq, unsigned int base)
936669a5db4SJeff Garzik {
937669a5db4SJeff Garzik 	unsigned int f = (base * freq) / 192;	/* Mhz */
938669a5db4SJeff Garzik 	if (f < 40)
939669a5db4SJeff Garzik 		return 0;	/* 33Mhz slot */
940669a5db4SJeff Garzik 	if (f < 45)
941669a5db4SJeff Garzik 		return 1;	/* 40Mhz slot */
942669a5db4SJeff Garzik 	if (f < 55)
943669a5db4SJeff Garzik 		return 2;	/* 50Mhz slot */
944669a5db4SJeff Garzik 	return 3;		/* 60Mhz slot */
945669a5db4SJeff Garzik }
946669a5db4SJeff Garzik 
947669a5db4SJeff Garzik /**
948669a5db4SJeff Garzik  *	hpt37x_calibrate_dpll		-	Calibrate the DPLL loop
949669a5db4SJeff Garzik  *	@dev: PCI device
950669a5db4SJeff Garzik  *
951669a5db4SJeff Garzik  *	Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this
952669a5db4SJeff Garzik  *	succeeds
953669a5db4SJeff Garzik  */
954669a5db4SJeff Garzik 
955669a5db4SJeff Garzik static int hpt37x_calibrate_dpll(struct pci_dev *dev)
956669a5db4SJeff Garzik {
957669a5db4SJeff Garzik 	u8 reg5b;
958669a5db4SJeff Garzik 	u32 reg5c;
959669a5db4SJeff Garzik 	int tries;
960669a5db4SJeff Garzik 
961669a5db4SJeff Garzik 	for(tries = 0; tries < 0x5000; tries++) {
962669a5db4SJeff Garzik 		udelay(50);
963669a5db4SJeff Garzik 		pci_read_config_byte(dev, 0x5b, &reg5b);
964669a5db4SJeff Garzik 		if (reg5b & 0x80) {
965669a5db4SJeff Garzik 			/* See if it stays set */
966669a5db4SJeff Garzik 			for(tries = 0; tries < 0x1000; tries ++) {
967669a5db4SJeff Garzik 				pci_read_config_byte(dev, 0x5b, &reg5b);
968669a5db4SJeff Garzik 				/* Failed ? */
969669a5db4SJeff Garzik 				if ((reg5b & 0x80) == 0)
970669a5db4SJeff Garzik 					return 0;
971669a5db4SJeff Garzik 			}
972669a5db4SJeff Garzik 			/* Turn off tuning, we have the DPLL set */
973669a5db4SJeff Garzik 			pci_read_config_dword(dev, 0x5c, &reg5c);
974669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5c, reg5c & ~ 0x100);
975669a5db4SJeff Garzik 			return 1;
976669a5db4SJeff Garzik 		}
977669a5db4SJeff Garzik 	}
978669a5db4SJeff Garzik 	/* Never went stable */
979669a5db4SJeff Garzik 	return 0;
980669a5db4SJeff Garzik }
981669a5db4SJeff Garzik /**
982669a5db4SJeff Garzik  *	hpt37x_init_one		-	Initialise an HPT37X/302
983669a5db4SJeff Garzik  *	@dev: PCI device
984669a5db4SJeff Garzik  *	@id: Entry in match table
985669a5db4SJeff Garzik  *
986669a5db4SJeff Garzik  *	Initialise an HPT37x device. There are some interesting complications
987669a5db4SJeff Garzik  *	here. Firstly the chip may report 366 and be one of several variants.
988669a5db4SJeff Garzik  *	Secondly all the timings depend on the clock for the chip which we must
989669a5db4SJeff Garzik  *	detect and look up
990669a5db4SJeff Garzik  *
991669a5db4SJeff Garzik  *	This is the known chip mappings. It may be missing a couple of later
992669a5db4SJeff Garzik  *	releases.
993669a5db4SJeff Garzik  *
994669a5db4SJeff Garzik  *	Chip version		PCI		Rev	Notes
995669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	0	Other driver
996669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	1	Other driver
997669a5db4SJeff Garzik  *	HPT368			4 (HPT366)	2	Other driver
998669a5db4SJeff Garzik  *	HPT370			4 (HPT366)	3	UDMA100
999669a5db4SJeff Garzik  *	HPT370A			4 (HPT366)	4	UDMA100
1000669a5db4SJeff Garzik  *	HPT372			4 (HPT366)	5	UDMA133 (1)
1001669a5db4SJeff Garzik  *	HPT372N			4 (HPT366)	6	Other driver
1002669a5db4SJeff Garzik  *	HPT372A			5 (HPT372)	1	UDMA133 (1)
1003669a5db4SJeff Garzik  *	HPT372N			5 (HPT372)	2	Other driver
1004669a5db4SJeff Garzik  *	HPT302			6 (HPT302)	1	UDMA133
1005669a5db4SJeff Garzik  *	HPT302N			6 (HPT302)	2	Other driver
1006669a5db4SJeff Garzik  *	HPT371			7 (HPT371)	*	UDMA133
1007669a5db4SJeff Garzik  *	HPT374			8 (HPT374)	*	UDMA133 4 channel
1008669a5db4SJeff Garzik  *	HPT372N			9 (HPT372N)	*	Other driver
1009669a5db4SJeff Garzik  *
1010669a5db4SJeff Garzik  *	(1) UDMA133 support depends on the bus clock
1011669a5db4SJeff Garzik  */
1012669a5db4SJeff Garzik 
1013669a5db4SJeff Garzik static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
1014669a5db4SJeff Garzik {
1015669a5db4SJeff Garzik 	/* HPT370 - UDMA100 */
1016669a5db4SJeff Garzik 	static struct ata_port_info info_hpt370 = {
1017669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
1018669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
1019669a5db4SJeff Garzik 		.pio_mask = 0x1f,
1020669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
1021669a5db4SJeff Garzik 		.udma_mask = 0x3f,
1022669a5db4SJeff Garzik 		.port_ops = &hpt370_port_ops
1023669a5db4SJeff Garzik 	};
1024669a5db4SJeff Garzik 	/* HPT370A - UDMA100 */
1025669a5db4SJeff Garzik 	static struct ata_port_info info_hpt370a = {
1026669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
1027669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
1028669a5db4SJeff Garzik 		.pio_mask = 0x1f,
1029669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
1030669a5db4SJeff Garzik 		.udma_mask = 0x3f,
1031669a5db4SJeff Garzik 		.port_ops = &hpt370a_port_ops
1032669a5db4SJeff Garzik 	};
1033669a5db4SJeff Garzik 	/* HPT371, 372 and friends - UDMA133 */
1034669a5db4SJeff Garzik 	static struct ata_port_info info_hpt372 = {
1035669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
1036669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
1037669a5db4SJeff Garzik 		.pio_mask = 0x1f,
1038669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
1039669a5db4SJeff Garzik 		.udma_mask = 0x7f,
1040669a5db4SJeff Garzik 		.port_ops = &hpt372_port_ops
1041669a5db4SJeff Garzik 	};
1042669a5db4SJeff Garzik 	/* HPT371, 372 and friends - UDMA100 at 50MHz clock */
1043669a5db4SJeff Garzik 	static struct ata_port_info info_hpt372_50 = {
1044669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
1045669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
1046669a5db4SJeff Garzik 		.pio_mask = 0x1f,
1047669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
1048669a5db4SJeff Garzik 		.udma_mask = 0x3f,
1049669a5db4SJeff Garzik 		.port_ops = &hpt372_port_ops
1050669a5db4SJeff Garzik 	};
1051669a5db4SJeff Garzik 	/* HPT374 - UDMA133 */
1052669a5db4SJeff Garzik 	static struct ata_port_info info_hpt374 = {
1053669a5db4SJeff Garzik 		.sht = &hpt37x_sht,
1054669a5db4SJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
1055669a5db4SJeff Garzik 		.pio_mask = 0x1f,
1056669a5db4SJeff Garzik 		.mwdma_mask = 0x07,
1057669a5db4SJeff Garzik 		.udma_mask = 0x7f,
1058669a5db4SJeff Garzik 		.port_ops = &hpt374_port_ops
1059669a5db4SJeff Garzik 	};
1060669a5db4SJeff Garzik 
1061669a5db4SJeff Garzik 	static const int MHz[4] = { 33, 40, 50, 66 };
1062669a5db4SJeff Garzik 
1063669a5db4SJeff Garzik 	struct ata_port_info *port_info[2];
1064669a5db4SJeff Garzik 	struct ata_port_info *port;
1065669a5db4SJeff Garzik 
1066669a5db4SJeff Garzik 	u8 irqmask;
1067669a5db4SJeff Garzik 	u32 class_rev;
1068669a5db4SJeff Garzik 	u32 freq;
1069669a5db4SJeff Garzik 
1070669a5db4SJeff Garzik 	const struct hpt_chip *chip_table;
1071669a5db4SJeff Garzik 	int clock_slot;
1072669a5db4SJeff Garzik 
1073669a5db4SJeff Garzik 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
1074669a5db4SJeff Garzik 	class_rev &= 0xFF;
1075669a5db4SJeff Garzik 
1076669a5db4SJeff Garzik 	if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
1077669a5db4SJeff Garzik 		/* May be a later chip in disguise. Check */
1078669a5db4SJeff Garzik 		/* Older chips are in the HPT366 driver. Ignore them */
1079669a5db4SJeff Garzik 		if (class_rev < 3)
1080669a5db4SJeff Garzik 			return -ENODEV;
1081669a5db4SJeff Garzik 		/* N series chips have their own driver. Ignore */
1082669a5db4SJeff Garzik 		if (class_rev == 6)
1083669a5db4SJeff Garzik 			return -ENODEV;
1084669a5db4SJeff Garzik 
1085669a5db4SJeff Garzik 		switch(class_rev) {
1086669a5db4SJeff Garzik 			case 3:
1087669a5db4SJeff Garzik 				port = &info_hpt370;
1088669a5db4SJeff Garzik 				chip_table = &hpt370;
1089669a5db4SJeff Garzik 				break;
1090669a5db4SJeff Garzik 			case 4:
1091669a5db4SJeff Garzik 				port = &info_hpt370a;
1092669a5db4SJeff Garzik 				chip_table = &hpt370a;
1093669a5db4SJeff Garzik 				break;
1094669a5db4SJeff Garzik 			case 5:
1095669a5db4SJeff Garzik 				port = &info_hpt372;
1096669a5db4SJeff Garzik 				chip_table = &hpt372;
1097669a5db4SJeff Garzik 				break;
1098669a5db4SJeff Garzik 			default:
1099669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype please report (%d).\n", class_rev);
1100669a5db4SJeff Garzik 				return -ENODEV;
1101669a5db4SJeff Garzik 		}
1102669a5db4SJeff Garzik 	} else {
1103669a5db4SJeff Garzik 		switch(dev->device) {
1104669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT372:
1105669a5db4SJeff Garzik 				/* 372N if rev >= 2*/
1106669a5db4SJeff Garzik 				if (class_rev >= 2)
1107669a5db4SJeff Garzik 					return -ENODEV;
1108669a5db4SJeff Garzik 				port = &info_hpt372;
1109669a5db4SJeff Garzik 				chip_table = &hpt372a;
1110669a5db4SJeff Garzik 				break;
1111669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT302:
1112669a5db4SJeff Garzik 				/* 302N if rev > 1 */
1113669a5db4SJeff Garzik 				if (class_rev > 1)
1114669a5db4SJeff Garzik 					return -ENODEV;
1115669a5db4SJeff Garzik 				port = &info_hpt372;
1116669a5db4SJeff Garzik 				/* Check this */
1117669a5db4SJeff Garzik 				chip_table = &hpt302;
1118669a5db4SJeff Garzik 				break;
1119669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT371:
1120669a5db4SJeff Garzik 				port = &info_hpt372;
1121669a5db4SJeff Garzik 				chip_table = &hpt371;
1122669a5db4SJeff Garzik 				break;
1123669a5db4SJeff Garzik 			case PCI_DEVICE_ID_TTI_HPT374:
1124669a5db4SJeff Garzik 				chip_table = &hpt374;
1125669a5db4SJeff Garzik 				port = &info_hpt374;
1126669a5db4SJeff Garzik 				break;
1127669a5db4SJeff Garzik 			default:
1128669a5db4SJeff Garzik 				printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device);
1129669a5db4SJeff Garzik 				return -ENODEV;
1130669a5db4SJeff Garzik 		}
1131669a5db4SJeff Garzik 	}
1132669a5db4SJeff Garzik 	/* Ok so this is a chip we support */
1133669a5db4SJeff Garzik 
1134669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
1135669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
1136669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
1137669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
1138669a5db4SJeff Garzik 
1139669a5db4SJeff Garzik 	pci_read_config_byte(dev, 0x5A, &irqmask);
1140669a5db4SJeff Garzik 	irqmask &= ~0x10;
1141669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5a, irqmask);
1142669a5db4SJeff Garzik 
1143669a5db4SJeff Garzik 	/*
1144669a5db4SJeff Garzik 	 * default to pci clock. make sure MA15/16 are set to output
1145669a5db4SJeff Garzik 	 * to prevent drives having problems with 40-pin cables. Needed
1146669a5db4SJeff Garzik 	 * for some drives such as IBM-DTLA which will not enter ready
1147669a5db4SJeff Garzik 	 * state on reset when PDIAG is a input.
1148669a5db4SJeff Garzik 	 */
1149669a5db4SJeff Garzik 
1150669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5b, 0x23);
1151669a5db4SJeff Garzik 
1152669a5db4SJeff Garzik 	pci_read_config_dword(dev, 0x70, &freq);
1153669a5db4SJeff Garzik 	if ((freq >> 12) != 0xABCDE) {
1154669a5db4SJeff Garzik 		int i;
1155669a5db4SJeff Garzik 		u8 sr;
1156669a5db4SJeff Garzik 		u32 total = 0;
1157669a5db4SJeff Garzik 
1158669a5db4SJeff Garzik 		printk(KERN_WARNING "pata_hpt37x: BIOS has not set timing clocks.\n");
1159669a5db4SJeff Garzik 
1160669a5db4SJeff Garzik 		/* This is the process the HPT371 BIOS is reported to use */
1161669a5db4SJeff Garzik 		for(i = 0; i < 128; i++) {
1162669a5db4SJeff Garzik 			pci_read_config_byte(dev, 0x78, &sr);
1163669a5db4SJeff Garzik 			total += sr;
1164669a5db4SJeff Garzik 			udelay(15);
1165669a5db4SJeff Garzik 		}
1166669a5db4SJeff Garzik 		freq = total / 128;
1167669a5db4SJeff Garzik 	}
1168669a5db4SJeff Garzik 	freq &= 0x1FF;
1169669a5db4SJeff Garzik 
1170669a5db4SJeff Garzik 	/*
1171669a5db4SJeff Garzik 	 *	Turn the frequency check into a band and then find a timing
1172669a5db4SJeff Garzik 	 *	table to match it.
1173669a5db4SJeff Garzik 	 */
1174669a5db4SJeff Garzik 
1175669a5db4SJeff Garzik 	clock_slot = hpt37x_clock_slot(freq, chip_table->base);
1176669a5db4SJeff Garzik 	if (chip_table->clocks[clock_slot] == NULL) {
1177669a5db4SJeff Garzik 		/*
1178669a5db4SJeff Garzik 		 *	We need to try PLL mode instead
1179669a5db4SJeff Garzik 		 */
1180669a5db4SJeff Garzik 		unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192;
1181669a5db4SJeff Garzik 		unsigned int f_high = f_low + 2;
1182669a5db4SJeff Garzik 		int adjust;
1183669a5db4SJeff Garzik 
1184669a5db4SJeff Garzik 		for(adjust = 0; adjust < 8; adjust++) {
1185669a5db4SJeff Garzik 			if (hpt37x_calibrate_dpll(dev))
1186669a5db4SJeff Garzik 				break;
1187669a5db4SJeff Garzik 			/* See if it'll settle at a fractionally different clock */
1188669a5db4SJeff Garzik 			if ((adjust & 3) == 3) {
1189669a5db4SJeff Garzik 				f_low --;
1190669a5db4SJeff Garzik 				f_high ++;
1191669a5db4SJeff Garzik 			}
1192669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
1193669a5db4SJeff Garzik 		}
1194669a5db4SJeff Garzik 		if (adjust == 8) {
1195669a5db4SJeff Garzik 			printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
1196669a5db4SJeff Garzik 			return -ENODEV;
1197669a5db4SJeff Garzik 		}
1198669a5db4SJeff Garzik 		/* Check if this works for all cases */
1199669a5db4SJeff Garzik 		port->private_data = (void *)hpt370_timings_66;
1200669a5db4SJeff Garzik 
1201669a5db4SJeff Garzik 		printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
1202669a5db4SJeff Garzik 	} else {
1203669a5db4SJeff Garzik 		port->private_data = (void *)chip_table->clocks[clock_slot];
1204669a5db4SJeff Garzik 		/*
1205669a5db4SJeff Garzik 		 *	Perform a final fixup. The 371 and 372 clock determines
1206669a5db4SJeff Garzik 		 *	if UDMA133 is available.
1207669a5db4SJeff Garzik 		 */
1208669a5db4SJeff Garzik 
1209669a5db4SJeff Garzik 		if (clock_slot == 2 && chip_table == &hpt372) {	/* 50Mhz */
1210669a5db4SJeff Garzik 			printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n");
1211669a5db4SJeff Garzik 			if (port == &info_hpt372)
1212669a5db4SJeff Garzik 				port = &info_hpt372_50;
1213669a5db4SJeff Garzik 			else BUG();
1214669a5db4SJeff Garzik 		}
1215669a5db4SJeff Garzik 		printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
1216669a5db4SJeff Garzik 	}
1217669a5db4SJeff Garzik 	port_info[0] = port_info[1] = port;
1218669a5db4SJeff Garzik 	/* Now kick off ATA set up */
1219669a5db4SJeff Garzik 	return ata_pci_init_one(dev, port_info, 2);
1220669a5db4SJeff Garzik }
1221669a5db4SJeff Garzik 
1222669a5db4SJeff Garzik static struct pci_device_id hpt37x[] = {
1223669a5db4SJeff Garzik 	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366), },
1224669a5db4SJeff Garzik 	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371), },
1225669a5db4SJeff Garzik 	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372), },
1226669a5db4SJeff Garzik 	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374), },
1227669a5db4SJeff Garzik 	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302), },
1228669a5db4SJeff Garzik 	{ 0, },
1229669a5db4SJeff Garzik };
1230669a5db4SJeff Garzik 
1231669a5db4SJeff Garzik static struct pci_driver hpt37x_pci_driver = {
1232669a5db4SJeff Garzik         .name 		= DRV_NAME,
1233669a5db4SJeff Garzik 	.id_table	= hpt37x,
1234669a5db4SJeff Garzik 	.probe 		= hpt37x_init_one,
1235669a5db4SJeff Garzik 	.remove		= ata_pci_remove_one
1236669a5db4SJeff Garzik };
1237669a5db4SJeff Garzik 
1238669a5db4SJeff Garzik static int __init hpt37x_init(void)
1239669a5db4SJeff Garzik {
1240669a5db4SJeff Garzik 	return pci_register_driver(&hpt37x_pci_driver);
1241669a5db4SJeff Garzik }
1242669a5db4SJeff Garzik 
1243669a5db4SJeff Garzik 
1244669a5db4SJeff Garzik static void __exit hpt37x_exit(void)
1245669a5db4SJeff Garzik {
1246669a5db4SJeff Garzik 	pci_unregister_driver(&hpt37x_pci_driver);
1247669a5db4SJeff Garzik }
1248669a5db4SJeff Garzik 
1249669a5db4SJeff Garzik 
1250669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
1251669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
1252669a5db4SJeff Garzik MODULE_LICENSE("GPL");
1253669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, hpt37x);
1254669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
1255669a5db4SJeff Garzik 
1256669a5db4SJeff Garzik module_init(hpt37x_init);
1257669a5db4SJeff Garzik module_exit(hpt37x_exit);
1258