xref: /openbmc/linux/drivers/ata/pata_hpt37x.c (revision 25df73d9)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2669a5db4SJeff Garzik /*
3669a5db4SJeff Garzik  * Libata driver for the highpoint 37x and 30x UDMA66 ATA controllers.
4669a5db4SJeff Garzik  *
5669a5db4SJeff Garzik  * This driver is heavily based upon:
6669a5db4SJeff Garzik  *
7669a5db4SJeff Garzik  * linux/drivers/ide/pci/hpt366.c		Version 0.36	April 25, 2003
8669a5db4SJeff Garzik  *
9669a5db4SJeff Garzik  * Copyright (C) 1999-2003		Andre Hedrick <andre@linux-ide.org>
10669a5db4SJeff Garzik  * Portions Copyright (C) 2001	        Sun Microsystems, Inc.
11669a5db4SJeff Garzik  * Portions Copyright (C) 2003		Red Hat Inc
128e834c2eSSergei Shtylyov  * Portions Copyright (C) 2005-2010	MontaVista Software, Inc.
13669a5db4SJeff Garzik  *
14669a5db4SJeff Garzik  * TODO
15d44a65f7SSergei Shtylyov  *	Look into engine reset on timeout errors. Should not be	required.
16669a5db4SJeff Garzik  */
17669a5db4SJeff Garzik #include <linux/kernel.h>
18669a5db4SJeff Garzik #include <linux/module.h>
19669a5db4SJeff Garzik #include <linux/pci.h>
20669a5db4SJeff Garzik #include <linux/blkdev.h>
21669a5db4SJeff Garzik #include <linux/delay.h>
22669a5db4SJeff Garzik #include <scsi/scsi_host.h>
23669a5db4SJeff Garzik #include <linux/libata.h>
24669a5db4SJeff Garzik 
25669a5db4SJeff Garzik #define DRV_NAME	"pata_hpt37x"
2675b4d58cSSergey Shtylyov #define DRV_VERSION	"0.6.30"
27669a5db4SJeff Garzik 
28669a5db4SJeff Garzik struct hpt_clock {
29669a5db4SJeff Garzik 	u8	xfer_speed;
30669a5db4SJeff Garzik 	u32	timing;
31669a5db4SJeff Garzik };
32669a5db4SJeff Garzik 
33669a5db4SJeff Garzik struct hpt_chip {
34669a5db4SJeff Garzik 	const char *name;
35669a5db4SJeff Garzik 	unsigned int base;
36669a5db4SJeff Garzik 	struct hpt_clock const *clocks[4];
37669a5db4SJeff Garzik };
38669a5db4SJeff Garzik 
39669a5db4SJeff Garzik /* key for bus clock timings
40669a5db4SJeff Garzik  * bit
41fd5e62e2SSergei Shtylyov  * 0:3    data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA.
42fd5e62e2SSergei Shtylyov  *        cycles = value + 1
43fd5e62e2SSergei Shtylyov  * 4:8    data_low_time. Active time of DIOW_/DIOR_ for PIO and MW DMA.
44fd5e62e2SSergei Shtylyov  *        cycles = value + 1
45fd5e62e2SSergei Shtylyov  * 9:12   cmd_high_time. Inactive time of DIOW_/DIOR_ during task file
46669a5db4SJeff Garzik  *        register access.
47fd5e62e2SSergei Shtylyov  * 13:17  cmd_low_time. Active time of DIOW_/DIOR_ during task file
48669a5db4SJeff Garzik  *        register access.
49fd5e62e2SSergei Shtylyov  * 18:20  udma_cycle_time. Clock cycles for UDMA xfer.
50fd5e62e2SSergei Shtylyov  * 21     CLK frequency for UDMA: 0=ATA clock, 1=dual ATA clock.
51fd5e62e2SSergei Shtylyov  * 22:24  pre_high_time. Time to initialize 1st cycle for PIO and MW DMA xfer.
52fd5e62e2SSergei Shtylyov  * 25:27  cmd_pre_high_time. Time to initialize 1st PIO cycle for task file
53669a5db4SJeff Garzik  *        register access.
54fd5e62e2SSergei Shtylyov  * 28     UDMA enable.
55fd5e62e2SSergei Shtylyov  * 29     DMA  enable.
56fd5e62e2SSergei Shtylyov  * 30     PIO_MST enable. If set, the chip is in bus master mode during
57fd5e62e2SSergei Shtylyov  *        PIO xfer.
58fd5e62e2SSergei Shtylyov  * 31     FIFO enable. Only for PIO.
59669a5db4SJeff Garzik  */
60669a5db4SJeff Garzik 
61fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_33[] = {
62fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12446231 },	/* 0x12646231 ?? */
63669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12446231 },
64669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12446231 },
65669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x126c6231 },
66669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x12486231 },
67669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x124c6233 },
68669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x12506297 },
69669a5db4SJeff Garzik 
70669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22406c31 },
71669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22406c33 },
72669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x22406c97 },
73669a5db4SJeff Garzik 
74669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x06414e31 },
75669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x06414e42 },
76669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x06414e53 },
77669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x06814e93 },
78fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x06814ea7 }
79669a5db4SJeff Garzik };
80669a5db4SJeff Garzik 
81fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_50[] = {
82fcc2f69aSAlan Cox 	{ XFER_UDMA_6,		0x12848242 },
83669a5db4SJeff Garzik 	{ XFER_UDMA_5,		0x12848242 },
84669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x12ac8242 },
85669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x128c8242 },
86669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x120c8242 },
87669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x12148254 },
88669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x121882ea },
89669a5db4SJeff Garzik 
90669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x22808242 },
91669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x22808254 },
92669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x228082ea },
93669a5db4SJeff Garzik 
94669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0a81f442 },
95669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0a81f443 },
96669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0a81f454 },
97669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0ac1f465 },
98fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0ac1f48a }
99669a5db4SJeff Garzik };
100669a5db4SJeff Garzik 
101fcc2f69aSAlan Cox static struct hpt_clock hpt37x_timings_66[] = {
102669a5db4SJeff Garzik 	{ XFER_UDMA_6,		0x1c869c62 },
103fcc2f69aSAlan Cox 	{ XFER_UDMA_5,		0x1cae9c62 },	/* 0x1c8a9c62 */
104669a5db4SJeff Garzik 	{ XFER_UDMA_4,		0x1c8a9c62 },
105669a5db4SJeff Garzik 	{ XFER_UDMA_3,		0x1c8e9c62 },
106669a5db4SJeff Garzik 	{ XFER_UDMA_2,		0x1c929c62 },
107669a5db4SJeff Garzik 	{ XFER_UDMA_1,		0x1c9a9c62 },
108669a5db4SJeff Garzik 	{ XFER_UDMA_0,		0x1c829c62 },
109669a5db4SJeff Garzik 
110669a5db4SJeff Garzik 	{ XFER_MW_DMA_2,	0x2c829c62 },
111669a5db4SJeff Garzik 	{ XFER_MW_DMA_1,	0x2c829c66 },
112669a5db4SJeff Garzik 	{ XFER_MW_DMA_0,	0x2c829d2e },
113669a5db4SJeff Garzik 
114669a5db4SJeff Garzik 	{ XFER_PIO_4,		0x0c829c62 },
115669a5db4SJeff Garzik 	{ XFER_PIO_3,		0x0c829c84 },
116669a5db4SJeff Garzik 	{ XFER_PIO_2,		0x0c829ca6 },
117669a5db4SJeff Garzik 	{ XFER_PIO_1,		0x0d029d26 },
118fcc2f69aSAlan Cox 	{ XFER_PIO_0,		0x0d029d5e }
119669a5db4SJeff Garzik };
120669a5db4SJeff Garzik 
121669a5db4SJeff Garzik 
122669a5db4SJeff Garzik static const struct hpt_chip hpt370 = {
123669a5db4SJeff Garzik 	"HPT370",
124669a5db4SJeff Garzik 	48,
125669a5db4SJeff Garzik 	{
126fcc2f69aSAlan Cox 		hpt37x_timings_33,
127669a5db4SJeff Garzik 		NULL,
128669a5db4SJeff Garzik 		NULL,
129a4734468SAlan Cox 		NULL
130669a5db4SJeff Garzik 	}
131669a5db4SJeff Garzik };
132669a5db4SJeff Garzik 
133669a5db4SJeff Garzik static const struct hpt_chip hpt370a = {
134669a5db4SJeff Garzik 	"HPT370A",
135669a5db4SJeff Garzik 	48,
136669a5db4SJeff Garzik 	{
137fcc2f69aSAlan Cox 		hpt37x_timings_33,
138669a5db4SJeff Garzik 		NULL,
139fcc2f69aSAlan Cox 		hpt37x_timings_50,
140a4734468SAlan Cox 		NULL
141669a5db4SJeff Garzik 	}
142669a5db4SJeff Garzik };
143669a5db4SJeff Garzik 
144669a5db4SJeff Garzik static const struct hpt_chip hpt372 = {
145669a5db4SJeff Garzik 	"HPT372",
146669a5db4SJeff Garzik 	55,
147669a5db4SJeff Garzik 	{
148fcc2f69aSAlan Cox 		hpt37x_timings_33,
149669a5db4SJeff Garzik 		NULL,
150fcc2f69aSAlan Cox 		hpt37x_timings_50,
151fcc2f69aSAlan Cox 		hpt37x_timings_66
152669a5db4SJeff Garzik 	}
153669a5db4SJeff Garzik };
154669a5db4SJeff Garzik 
155669a5db4SJeff Garzik static const struct hpt_chip hpt302 = {
156669a5db4SJeff Garzik 	"HPT302",
157669a5db4SJeff Garzik 	66,
158669a5db4SJeff Garzik 	{
159fcc2f69aSAlan Cox 		hpt37x_timings_33,
160669a5db4SJeff Garzik 		NULL,
161fcc2f69aSAlan Cox 		hpt37x_timings_50,
162fcc2f69aSAlan Cox 		hpt37x_timings_66
163669a5db4SJeff Garzik 	}
164669a5db4SJeff Garzik };
165669a5db4SJeff Garzik 
166669a5db4SJeff Garzik static const struct hpt_chip hpt371 = {
167669a5db4SJeff Garzik 	"HPT371",
168669a5db4SJeff Garzik 	66,
169669a5db4SJeff Garzik 	{
170fcc2f69aSAlan Cox 		hpt37x_timings_33,
171669a5db4SJeff Garzik 		NULL,
172fcc2f69aSAlan Cox 		hpt37x_timings_50,
173fcc2f69aSAlan Cox 		hpt37x_timings_66
174669a5db4SJeff Garzik 	}
175669a5db4SJeff Garzik };
176669a5db4SJeff Garzik 
177669a5db4SJeff Garzik static const struct hpt_chip hpt372a = {
178669a5db4SJeff Garzik 	"HPT372A",
179669a5db4SJeff Garzik 	66,
180669a5db4SJeff Garzik 	{
181fcc2f69aSAlan Cox 		hpt37x_timings_33,
182669a5db4SJeff Garzik 		NULL,
183fcc2f69aSAlan Cox 		hpt37x_timings_50,
184fcc2f69aSAlan Cox 		hpt37x_timings_66
185669a5db4SJeff Garzik 	}
186669a5db4SJeff Garzik };
187669a5db4SJeff Garzik 
188669a5db4SJeff Garzik static const struct hpt_chip hpt374 = {
189669a5db4SJeff Garzik 	"HPT374",
190669a5db4SJeff Garzik 	48,
191669a5db4SJeff Garzik 	{
192fcc2f69aSAlan Cox 		hpt37x_timings_33,
193669a5db4SJeff Garzik 		NULL,
194669a5db4SJeff Garzik 		NULL,
195669a5db4SJeff Garzik 		NULL
196669a5db4SJeff Garzik 	}
197669a5db4SJeff Garzik };
198669a5db4SJeff Garzik 
199669a5db4SJeff Garzik /**
200669a5db4SJeff Garzik  *	hpt37x_find_mode	-	reset the hpt37x bus
201669a5db4SJeff Garzik  *	@ap: ATA port
202669a5db4SJeff Garzik  *	@speed: transfer mode
203669a5db4SJeff Garzik  *
204669a5db4SJeff Garzik  *	Return the 32bit register programming information for this channel
205669a5db4SJeff Garzik  *	that matches the speed provided.
206669a5db4SJeff Garzik  */
207669a5db4SJeff Garzik 
hpt37x_find_mode(struct ata_port * ap,int speed)208669a5db4SJeff Garzik static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
209669a5db4SJeff Garzik {
210669a5db4SJeff Garzik 	struct hpt_clock *clocks = ap->host->private_data;
211669a5db4SJeff Garzik 
212669a5db4SJeff Garzik 	while (clocks->xfer_speed) {
213669a5db4SJeff Garzik 		if (clocks->xfer_speed == speed)
214669a5db4SJeff Garzik 			return clocks->timing;
215669a5db4SJeff Garzik 		clocks++;
216669a5db4SJeff Garzik 	}
217669a5db4SJeff Garzik 	BUG();
218669a5db4SJeff Garzik 	return 0xffffffffU;	/* silence compiler warning */
219669a5db4SJeff Garzik }
220669a5db4SJeff Garzik 
hpt_dma_blacklisted(const struct ata_device * dev,char * modestr,const char * const list[])22149bfbd38SSergei Shtylyov static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
22249bfbd38SSergei Shtylyov 			       const char * const list[])
223669a5db4SJeff Garzik {
2248bfa79fcSTejun Heo 	unsigned char model_num[ATA_ID_PROD_LEN + 1];
225dc85ca57SAndy Shevchenko 	int i;
226669a5db4SJeff Garzik 
2278bfa79fcSTejun Heo 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
228669a5db4SJeff Garzik 
229dc85ca57SAndy Shevchenko 	i = match_string(list, -1, model_num);
230dc85ca57SAndy Shevchenko 	if (i >= 0) {
231f06c13aaSHannes Reinecke 		ata_dev_warn(dev, "%s is not supported for %s\n",
232f06c13aaSHannes Reinecke 			     modestr, list[i]);
233669a5db4SJeff Garzik 		return 1;
234669a5db4SJeff Garzik 	}
235669a5db4SJeff Garzik 	return 0;
236669a5db4SJeff Garzik }
237669a5db4SJeff Garzik 
23849bfbd38SSergei Shtylyov static const char * const bad_ata33[] = {
23949bfbd38SSergei Shtylyov 	"Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3",
24049bfbd38SSergei Shtylyov 	"Maxtor 90845U3", "Maxtor 90650U2",
24149bfbd38SSergei Shtylyov 	"Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5",
24249bfbd38SSergei Shtylyov 	"Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2",
24349bfbd38SSergei Shtylyov 	"Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6",
24449bfbd38SSergei Shtylyov 	"Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4",
245669a5db4SJeff Garzik 	"Maxtor 90510D4",
246669a5db4SJeff Garzik 	"Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2",
24749bfbd38SSergei Shtylyov 	"Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7",
24849bfbd38SSergei Shtylyov 	"Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4",
24949bfbd38SSergei Shtylyov 	"Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5",
25049bfbd38SSergei Shtylyov 	"Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2",
251669a5db4SJeff Garzik 	NULL
252669a5db4SJeff Garzik };
253669a5db4SJeff Garzik 
25449bfbd38SSergei Shtylyov static const char * const 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
276a51746f4SLee Jones  *	@mask: mode mask
277669a5db4SJeff Garzik  *
278669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
279669a5db4SJeff Garzik  */
280669a5db4SJeff Garzik 
hpt370_filter(struct ata_device * adev,unsigned int mask)281f0a6d77bSSergey Shtylyov static unsigned int hpt370_filter(struct ata_device *adev, unsigned int mask)
282669a5db4SJeff Garzik {
2836929da44SAlan 	if (adev->class == ATA_DEV_ATA) {
284669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
285669a5db4SJeff Garzik 			mask &= ~ATA_MASK_UDMA;
286669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
2876ddd6861SAlan Cox 			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
288669a5db4SJeff Garzik 	}
289c7087652STejun Heo 	return mask;
290669a5db4SJeff Garzik }
291669a5db4SJeff Garzik 
292669a5db4SJeff Garzik /**
293669a5db4SJeff Garzik  *	hpt370a_filter	-	mode selection filter
294669a5db4SJeff Garzik  *	@adev: ATA device
295a51746f4SLee Jones  *	@mask: mode mask
296669a5db4SJeff Garzik  *
297669a5db4SJeff Garzik  *	Block UDMA on devices that cause trouble with this controller.
298669a5db4SJeff Garzik  */
299669a5db4SJeff Garzik 
hpt370a_filter(struct ata_device * adev,unsigned int mask)300f0a6d77bSSergey Shtylyov static unsigned int hpt370a_filter(struct ata_device *adev, unsigned int mask)
301669a5db4SJeff Garzik {
30273946f9fSAlan Cox 	if (adev->class == ATA_DEV_ATA) {
303669a5db4SJeff Garzik 		if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
3046ddd6861SAlan Cox 			mask &= ~(0xE0 << ATA_SHIFT_UDMA);
305669a5db4SJeff Garzik 	}
306c7087652STejun Heo 	return mask;
307669a5db4SJeff Garzik }
308669a5db4SJeff Garzik 
309669a5db4SJeff Garzik /**
3108e834c2eSSergei Shtylyov  *	hpt372_filter	-	mode selection filter
3118e834c2eSSergei Shtylyov  *	@adev: ATA device
3128e834c2eSSergei Shtylyov  *	@mask: mode mask
3138e834c2eSSergei Shtylyov  *
3148e834c2eSSergei Shtylyov  *	The Marvell bridge chips used on the HighPoint SATA cards do not seem
3158e834c2eSSergei Shtylyov  *	to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
3168e834c2eSSergei Shtylyov  */
hpt372_filter(struct ata_device * adev,unsigned int mask)317f0a6d77bSSergey Shtylyov static unsigned int hpt372_filter(struct ata_device *adev, unsigned int mask)
3188e834c2eSSergei Shtylyov {
3198e834c2eSSergei Shtylyov 	if (ata_id_is_sata(adev->id))
3208e834c2eSSergei Shtylyov 		mask &= ~((0xE << ATA_SHIFT_UDMA) | ATA_MASK_MWDMA);
3218e834c2eSSergei Shtylyov 
3228e834c2eSSergei Shtylyov 	return mask;
3238e834c2eSSergei Shtylyov }
3248e834c2eSSergei Shtylyov 
3258e834c2eSSergei Shtylyov /**
3269e87be9eSBartlomiej Zolnierkiewicz  *	hpt37x_cable_detect	-	Detect the cable type
3279e87be9eSBartlomiej Zolnierkiewicz  *	@ap: ATA port to detect on
328669a5db4SJeff Garzik  *
3299e87be9eSBartlomiej Zolnierkiewicz  *	Return the cable type attached to this port
330669a5db4SJeff Garzik  */
331669a5db4SJeff Garzik 
hpt37x_cable_detect(struct ata_port * ap)3329e87be9eSBartlomiej Zolnierkiewicz static int hpt37x_cable_detect(struct ata_port *ap)
333669a5db4SJeff Garzik {
334669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
3359e87be9eSBartlomiej Zolnierkiewicz 	u8 scr2, ata66;
336669a5db4SJeff Garzik 
337669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5B, &scr2);
338669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
33910a9c969SBartlomiej Zolnierkiewicz 
34010a9c969SBartlomiej Zolnierkiewicz 	udelay(10); /* debounce */
34110a9c969SBartlomiej Zolnierkiewicz 
342669a5db4SJeff Garzik 	/* Cable register now active */
343669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x5A, &ata66);
344669a5db4SJeff Garzik 	/* Restore state */
345669a5db4SJeff Garzik 	pci_write_config_byte(pdev, 0x5B, scr2);
346669a5db4SJeff Garzik 
34722d5c760SAlan Cox 	if (ata66 & (2 >> ap->port_no))
3489e87be9eSBartlomiej Zolnierkiewicz 		return ATA_CBL_PATA40;
349669a5db4SJeff Garzik 	else
3509e87be9eSBartlomiej Zolnierkiewicz 		return ATA_CBL_PATA80;
3519e87be9eSBartlomiej Zolnierkiewicz }
3529e87be9eSBartlomiej Zolnierkiewicz 
3539e87be9eSBartlomiej Zolnierkiewicz /**
3549e87be9eSBartlomiej Zolnierkiewicz  *	hpt374_fn1_cable_detect	-	Detect the cable type
3559e87be9eSBartlomiej Zolnierkiewicz  *	@ap: ATA port to detect on
3569e87be9eSBartlomiej Zolnierkiewicz  *
3579e87be9eSBartlomiej Zolnierkiewicz  *	Return the cable type attached to this port
3589e87be9eSBartlomiej Zolnierkiewicz  */
3599e87be9eSBartlomiej Zolnierkiewicz 
hpt374_fn1_cable_detect(struct ata_port * ap)3609e87be9eSBartlomiej Zolnierkiewicz static int hpt374_fn1_cable_detect(struct ata_port *ap)
3619e87be9eSBartlomiej Zolnierkiewicz {
3629e87be9eSBartlomiej Zolnierkiewicz 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
3639e87be9eSBartlomiej Zolnierkiewicz 	unsigned int mcrbase = 0x50 + 4 * ap->port_no;
3649e87be9eSBartlomiej Zolnierkiewicz 	u16 mcr3;
3659e87be9eSBartlomiej Zolnierkiewicz 	u8 ata66;
3669e87be9eSBartlomiej Zolnierkiewicz 
3679e87be9eSBartlomiej Zolnierkiewicz 	/* Do the extra channel work */
3689e87be9eSBartlomiej Zolnierkiewicz 	pci_read_config_word(pdev, mcrbase + 2, &mcr3);
3699e87be9eSBartlomiej Zolnierkiewicz 	/* Set bit 15 of 0x52 to enable TCBLID as input */
3709e87be9eSBartlomiej Zolnierkiewicz 	pci_write_config_word(pdev, mcrbase + 2, mcr3 | 0x8000);
3719e87be9eSBartlomiej Zolnierkiewicz 	pci_read_config_byte(pdev, 0x5A, &ata66);
3729e87be9eSBartlomiej Zolnierkiewicz 	/* Reset TCBLID/FCBLID to output */
3739e87be9eSBartlomiej Zolnierkiewicz 	pci_write_config_word(pdev, mcrbase + 2, mcr3);
3749e87be9eSBartlomiej Zolnierkiewicz 
3759e87be9eSBartlomiej Zolnierkiewicz 	if (ata66 & (2 >> ap->port_no))
3769e87be9eSBartlomiej Zolnierkiewicz 		return ATA_CBL_PATA40;
3779e87be9eSBartlomiej Zolnierkiewicz 	else
3789e87be9eSBartlomiej Zolnierkiewicz 		return ATA_CBL_PATA80;
3799e87be9eSBartlomiej Zolnierkiewicz }
3809e87be9eSBartlomiej Zolnierkiewicz 
3819e87be9eSBartlomiej Zolnierkiewicz /**
3829e87be9eSBartlomiej Zolnierkiewicz  *	hpt37x_pre_reset	-	reset the hpt37x bus
3839e87be9eSBartlomiej Zolnierkiewicz  *	@link: ATA link to reset
3849e87be9eSBartlomiej Zolnierkiewicz  *	@deadline: deadline jiffies for the operation
3859e87be9eSBartlomiej Zolnierkiewicz  *
386ab81a505SBartlomiej Zolnierkiewicz  *	Perform the initial reset handling for the HPT37x.
3879e87be9eSBartlomiej Zolnierkiewicz  */
3889e87be9eSBartlomiej Zolnierkiewicz 
hpt37x_pre_reset(struct ata_link * link,unsigned long deadline)3899e87be9eSBartlomiej Zolnierkiewicz static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
3909e87be9eSBartlomiej Zolnierkiewicz {
3919e87be9eSBartlomiej Zolnierkiewicz 	struct ata_port *ap = link->ap;
3929e87be9eSBartlomiej Zolnierkiewicz 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
3939e87be9eSBartlomiej Zolnierkiewicz 	static const struct pci_bits hpt37x_enable_bits[] = {
3949e87be9eSBartlomiej Zolnierkiewicz 		{ 0x50, 1, 0x04, 0x04 },
3959e87be9eSBartlomiej Zolnierkiewicz 		{ 0x54, 1, 0x04, 0x04 }
3969e87be9eSBartlomiej Zolnierkiewicz 	};
3976110530bSSergey Shtylyov 	u8 mcr2;
39849bfbd38SSergei Shtylyov 
3999e87be9eSBartlomiej Zolnierkiewicz 	if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
4009e87be9eSBartlomiej Zolnierkiewicz 		return -ENOENT;
401669a5db4SJeff Garzik 
402669a5db4SJeff Garzik 	/* Reset the state machine */
403fcc2f69aSAlan Cox 	pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
404669a5db4SJeff Garzik 	udelay(100);
405669a5db4SJeff Garzik 
4066110530bSSergey Shtylyov 	/*
4076110530bSSergey Shtylyov 	 * Disable the "fast interrupt" prediction.  Don't hold off
4086110530bSSergey Shtylyov 	 * on interrupts. (== 0x01 despite what the docs say)
4096110530bSSergey Shtylyov 	 */
4106110530bSSergey Shtylyov 	pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2);
4116110530bSSergey Shtylyov 	/* Is it HPT370/A? */
4126110530bSSergey Shtylyov 	if (pdev->device == PCI_DEVICE_ID_TTI_HPT366 && pdev->revision < 5) {
4136110530bSSergey Shtylyov 		mcr2 &= ~0x02;
4146110530bSSergey Shtylyov 		mcr2 |= 0x01;
4156110530bSSergey Shtylyov 	} else {
4166110530bSSergey Shtylyov 		mcr2 &= ~0x07;
4176110530bSSergey Shtylyov 	}
4186110530bSSergey Shtylyov 	pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2);
4196110530bSSergey Shtylyov 
4209363c382STejun Heo 	return ata_sff_prereset(link, deadline);
421669a5db4SJeff Garzik }
422669a5db4SJeff Garzik 
hpt37x_set_mode(struct ata_port * ap,struct ata_device * adev,u8 mode)4239256766fSSergey Shtylyov static void hpt37x_set_mode(struct ata_port *ap, struct ata_device *adev,
4241a1b172bSSergei Shtylyov 			    u8 mode)
4251a1b172bSSergei Shtylyov {
4261a1b172bSSergei Shtylyov 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
4276110530bSSergey Shtylyov 	int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no);
4281a1b172bSSergei Shtylyov 	u32 reg, timing, mask;
4291a1b172bSSergei Shtylyov 
4301a1b172bSSergei Shtylyov 	/* Determine timing mask and find matching mode entry */
4311a1b172bSSergei Shtylyov 	if (mode < XFER_MW_DMA_0)
4321a1b172bSSergei Shtylyov 		mask = 0xcfc3ffff;
4331a1b172bSSergei Shtylyov 	else if (mode < XFER_UDMA_0)
4341a1b172bSSergei Shtylyov 		mask = 0x31c001ff;
4351a1b172bSSergei Shtylyov 	else
4361a1b172bSSergei Shtylyov 		mask = 0x303c0000;
4371a1b172bSSergei Shtylyov 
4381a1b172bSSergei Shtylyov 	timing = hpt37x_find_mode(ap, mode);
4391a1b172bSSergei Shtylyov 
4406110530bSSergey Shtylyov 	pci_read_config_dword(pdev, addr, &reg);
4411a1b172bSSergei Shtylyov 	reg = (reg & ~mask) | (timing & mask);
4426110530bSSergey Shtylyov 	pci_write_config_dword(pdev, addr, reg);
4431a1b172bSSergei Shtylyov }
444669a5db4SJeff Garzik /**
4459256766fSSergey Shtylyov  *	hpt37x_set_piomode		-	PIO setup
446669a5db4SJeff Garzik  *	@ap: ATA interface
447669a5db4SJeff Garzik  *	@adev: device on the interface
448669a5db4SJeff Garzik  *
449669a5db4SJeff Garzik  *	Perform PIO mode setup.
450669a5db4SJeff Garzik  */
451669a5db4SJeff Garzik 
hpt37x_set_piomode(struct ata_port * ap,struct ata_device * adev)4529256766fSSergey Shtylyov static void hpt37x_set_piomode(struct ata_port *ap, struct ata_device *adev)
453669a5db4SJeff Garzik {
4549256766fSSergey Shtylyov 	hpt37x_set_mode(ap, adev, adev->pio_mode);
455669a5db4SJeff Garzik }
456669a5db4SJeff Garzik 
457669a5db4SJeff Garzik /**
4589256766fSSergey Shtylyov  *	hpt37x_set_dmamode		-	DMA timing setup
459669a5db4SJeff Garzik  *	@ap: ATA interface
460669a5db4SJeff Garzik  *	@adev: Device being configured
461669a5db4SJeff Garzik  *
4621a1b172bSSergei Shtylyov  *	Set up the channel for MWDMA or UDMA modes.
463669a5db4SJeff Garzik  */
464669a5db4SJeff Garzik 
hpt37x_set_dmamode(struct ata_port * ap,struct ata_device * adev)4659256766fSSergey Shtylyov static void hpt37x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
466669a5db4SJeff Garzik {
4679256766fSSergey Shtylyov 	hpt37x_set_mode(ap, adev, adev->dma_mode);
468669a5db4SJeff Garzik }
469669a5db4SJeff Garzik 
470669a5db4SJeff Garzik /**
471a51746f4SLee Jones  *	hpt370_bmdma_stop		-	DMA engine stop
472669a5db4SJeff Garzik  *	@qc: ATA command
473669a5db4SJeff Garzik  *
474669a5db4SJeff Garzik  *	Work around the HPT370 DMA engine.
475669a5db4SJeff Garzik  */
476669a5db4SJeff Garzik 
hpt370_bmdma_stop(struct ata_queued_cmd * qc)477669a5db4SJeff Garzik static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
478669a5db4SJeff Garzik {
479669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
480669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
4810d5ff566STejun Heo 	void __iomem *bmdma = ap->ioaddr.bmdma_addr;
48256f46f8cSSergei Shtylyov 	u8 dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
48356f46f8cSSergei Shtylyov 	u8 dma_cmd;
484669a5db4SJeff Garzik 
48556f46f8cSSergei Shtylyov 	if (dma_stat & ATA_DMA_ACTIVE) {
486669a5db4SJeff Garzik 		udelay(20);
48756f46f8cSSergei Shtylyov 		dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
488669a5db4SJeff Garzik 	}
48956f46f8cSSergei Shtylyov 	if (dma_stat & ATA_DMA_ACTIVE) {
490669a5db4SJeff Garzik 		/* Clear the engine */
491669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
492669a5db4SJeff Garzik 		udelay(10);
493669a5db4SJeff Garzik 		/* Stop DMA */
49456f46f8cSSergei Shtylyov 		dma_cmd = ioread8(bmdma + ATA_DMA_CMD);
49556f46f8cSSergei Shtylyov 		iowrite8(dma_cmd & ~ATA_DMA_START, bmdma + ATA_DMA_CMD);
496669a5db4SJeff Garzik 		/* Clear Error */
49756f46f8cSSergei Shtylyov 		dma_stat = ioread8(bmdma + ATA_DMA_STATUS);
49856f46f8cSSergei Shtylyov 		iowrite8(dma_stat | ATA_DMA_INTR | ATA_DMA_ERR,
49956f46f8cSSergei Shtylyov 			 bmdma + ATA_DMA_STATUS);
500669a5db4SJeff Garzik 		/* Clear the engine */
501669a5db4SJeff Garzik 		pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
502669a5db4SJeff Garzik 		udelay(10);
503669a5db4SJeff Garzik 	}
504669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
505669a5db4SJeff Garzik }
506669a5db4SJeff Garzik 
507669a5db4SJeff Garzik /**
508a51746f4SLee Jones  *	hpt37x_bmdma_stop		-	DMA engine stop
509669a5db4SJeff Garzik  *	@qc: ATA command
510669a5db4SJeff Garzik  *
511669a5db4SJeff Garzik  *	Clean up after the HPT372 and later DMA engine
512669a5db4SJeff Garzik  */
513669a5db4SJeff Garzik 
hpt37x_bmdma_stop(struct ata_queued_cmd * qc)514669a5db4SJeff Garzik static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
515669a5db4SJeff Garzik {
516669a5db4SJeff Garzik 	struct ata_port *ap = qc->ap;
517669a5db4SJeff Garzik 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
5186929da44SAlan 	int mscreg = 0x50 + 4 * ap->port_no;
519669a5db4SJeff Garzik 	u8 bwsr_stat, msc_stat;
520669a5db4SJeff Garzik 
521669a5db4SJeff Garzik 	pci_read_config_byte(pdev, 0x6A, &bwsr_stat);
522669a5db4SJeff Garzik 	pci_read_config_byte(pdev, mscreg, &msc_stat);
523669a5db4SJeff Garzik 	if (bwsr_stat & (1 << ap->port_no))
524669a5db4SJeff Garzik 		pci_write_config_byte(pdev, mscreg, msc_stat | 0x30);
525669a5db4SJeff Garzik 	ata_bmdma_stop(qc);
526669a5db4SJeff Garzik }
527669a5db4SJeff Garzik 
528669a5db4SJeff Garzik 
529*25df73d9SBart Van Assche static const struct scsi_host_template hpt37x_sht = {
53068d1d07bSTejun Heo 	ATA_BMDMA_SHT(DRV_NAME),
531669a5db4SJeff Garzik };
532669a5db4SJeff Garzik 
533669a5db4SJeff Garzik /*
534669a5db4SJeff Garzik  *	Configuration for HPT370
535669a5db4SJeff Garzik  */
536669a5db4SJeff Garzik 
537669a5db4SJeff Garzik static struct ata_port_operations hpt370_port_ops = {
538029cfd6bSTejun Heo 	.inherits	= &ata_bmdma_port_ops,
539669a5db4SJeff Garzik 
540669a5db4SJeff Garzik 	.bmdma_stop	= hpt370_bmdma_stop,
541669a5db4SJeff Garzik 
542029cfd6bSTejun Heo 	.mode_filter	= hpt370_filter,
5439e87be9eSBartlomiej Zolnierkiewicz 	.cable_detect	= hpt37x_cable_detect,
5449256766fSSergey Shtylyov 	.set_piomode	= hpt37x_set_piomode,
5459256766fSSergey Shtylyov 	.set_dmamode	= hpt37x_set_dmamode,
546a1efdabaSTejun Heo 	.prereset	= hpt37x_pre_reset,
547669a5db4SJeff Garzik };
548669a5db4SJeff Garzik 
549669a5db4SJeff Garzik /*
550669a5db4SJeff Garzik  *	Configuration for HPT370A. Close to 370 but less filters
551669a5db4SJeff Garzik  */
552669a5db4SJeff Garzik 
553669a5db4SJeff Garzik static struct ata_port_operations hpt370a_port_ops = {
554029cfd6bSTejun Heo 	.inherits	= &hpt370_port_ops,
555669a5db4SJeff Garzik 	.mode_filter	= hpt370a_filter,
556669a5db4SJeff Garzik };
557669a5db4SJeff Garzik 
558669a5db4SJeff Garzik /*
5599256766fSSergey Shtylyov  *	Configuration for HPT371 and HPT302.
560669a5db4SJeff Garzik  */
561669a5db4SJeff Garzik 
5628e834c2eSSergei Shtylyov static struct ata_port_operations hpt302_port_ops = {
563029cfd6bSTejun Heo 	.inherits	= &ata_bmdma_port_ops,
564029cfd6bSTejun Heo 
565029cfd6bSTejun Heo 	.bmdma_stop	= hpt37x_bmdma_stop,
566029cfd6bSTejun Heo 
5679e87be9eSBartlomiej Zolnierkiewicz 	.cable_detect	= hpt37x_cable_detect,
5689256766fSSergey Shtylyov 	.set_piomode	= hpt37x_set_piomode,
5699256766fSSergey Shtylyov 	.set_dmamode	= hpt37x_set_dmamode,
570a1efdabaSTejun Heo 	.prereset	= hpt37x_pre_reset,
571669a5db4SJeff Garzik };
572669a5db4SJeff Garzik 
573669a5db4SJeff Garzik /*
5748e834c2eSSergei Shtylyov  *	Configuration for HPT372. Mode setting works like 371 and 302
5758e834c2eSSergei Shtylyov  *	but we have a mode filter.
5768e834c2eSSergei Shtylyov  */
5778e834c2eSSergei Shtylyov 
5788e834c2eSSergei Shtylyov static struct ata_port_operations hpt372_port_ops = {
5798e834c2eSSergei Shtylyov 	.inherits	= &hpt302_port_ops,
5808e834c2eSSergei Shtylyov 	.mode_filter	= hpt372_filter,
5818e834c2eSSergei Shtylyov };
5828e834c2eSSergei Shtylyov 
5838e834c2eSSergei Shtylyov /*
5848e834c2eSSergei Shtylyov  *	Configuration for HPT374. Mode setting and filtering works like 372
585a1efdabaSTejun Heo  *	but we have a different cable detection procedure for function 1.
586669a5db4SJeff Garzik  */
587669a5db4SJeff Garzik 
588a1efdabaSTejun Heo static struct ata_port_operations hpt374_fn1_port_ops = {
589029cfd6bSTejun Heo 	.inherits	= &hpt372_port_ops,
5909e87be9eSBartlomiej Zolnierkiewicz 	.cable_detect	= hpt374_fn1_cable_detect,
591669a5db4SJeff Garzik };
592669a5db4SJeff Garzik 
593669a5db4SJeff Garzik /**
594ad452d64SKrzysztof Halasa  *	hpt37x_clock_slot	-	Turn timing to PC clock entry
595305f8db7SSergey Shtylyov  *	@freq: Reported frequency in MHz
596669a5db4SJeff Garzik  *
597669a5db4SJeff Garzik  *	Turn the timing data into a clock slot (0 for 33, 1 for 40, 2 for 50
598669a5db4SJeff Garzik  *	and 3 for 66Mhz)
599669a5db4SJeff Garzik  */
600669a5db4SJeff Garzik 
hpt37x_clock_slot(unsigned int freq)601305f8db7SSergey Shtylyov static int hpt37x_clock_slot(unsigned int freq)
602669a5db4SJeff Garzik {
603305f8db7SSergey Shtylyov 	if (freq < 40)
604669a5db4SJeff Garzik 		return 0;	/* 33Mhz slot */
605305f8db7SSergey Shtylyov 	if (freq < 45)
606669a5db4SJeff Garzik 		return 1;	/* 40Mhz slot */
607305f8db7SSergey Shtylyov 	if (freq < 55)
608669a5db4SJeff Garzik 		return 2;	/* 50Mhz slot */
609669a5db4SJeff Garzik 	return 3;		/* 60Mhz slot */
610669a5db4SJeff Garzik }
611669a5db4SJeff Garzik 
612669a5db4SJeff Garzik /**
613669a5db4SJeff Garzik  *	hpt37x_calibrate_dpll		-	Calibrate the DPLL loop
614669a5db4SJeff Garzik  *	@dev: PCI device
615669a5db4SJeff Garzik  *
616669a5db4SJeff Garzik  *	Perform a calibration cycle on the HPT37x DPLL. Returns 1 if this
617669a5db4SJeff Garzik  *	succeeds
618669a5db4SJeff Garzik  */
619669a5db4SJeff Garzik 
hpt37x_calibrate_dpll(struct pci_dev * dev)620669a5db4SJeff Garzik static int hpt37x_calibrate_dpll(struct pci_dev *dev)
621669a5db4SJeff Garzik {
622669a5db4SJeff Garzik 	u8 reg5b;
623669a5db4SJeff Garzik 	u32 reg5c;
624669a5db4SJeff Garzik 	int tries;
625669a5db4SJeff Garzik 
626669a5db4SJeff Garzik 	for (tries = 0; tries < 0x5000; tries++) {
627669a5db4SJeff Garzik 		udelay(50);
628669a5db4SJeff Garzik 		pci_read_config_byte(dev, 0x5b, &reg5b);
629669a5db4SJeff Garzik 		if (reg5b & 0x80) {
630669a5db4SJeff Garzik 			/* See if it stays set */
631669a5db4SJeff Garzik 			for (tries = 0; tries < 0x1000; tries++) {
632669a5db4SJeff Garzik 				pci_read_config_byte(dev, 0x5b, &reg5b);
633669a5db4SJeff Garzik 				/* Failed ? */
634669a5db4SJeff Garzik 				if ((reg5b & 0x80) == 0)
635669a5db4SJeff Garzik 					return 0;
636669a5db4SJeff Garzik 			}
637669a5db4SJeff Garzik 			/* Turn off tuning, we have the DPLL set */
638669a5db4SJeff Garzik 			pci_read_config_dword(dev, 0x5c, &reg5c);
639669a5db4SJeff Garzik 			pci_write_config_dword(dev, 0x5c, reg5c & ~0x100);
640669a5db4SJeff Garzik 			return 1;
641669a5db4SJeff Garzik 		}
642669a5db4SJeff Garzik 	}
643669a5db4SJeff Garzik 	/* Never went stable */
644669a5db4SJeff Garzik 	return 0;
645669a5db4SJeff Garzik }
64673946f9fSAlan Cox 
hpt37x_pci_clock(struct pci_dev * pdev,unsigned int base)64796c34ac4SSergey Shtylyov static int hpt37x_pci_clock(struct pci_dev *pdev, unsigned int base)
64896c34ac4SSergey Shtylyov {
64996c34ac4SSergey Shtylyov 	unsigned int freq;
65096c34ac4SSergey Shtylyov 	u32 fcnt;
65196c34ac4SSergey Shtylyov 
65296c34ac4SSergey Shtylyov 	/*
65396c34ac4SSergey Shtylyov 	 * Some devices do not let this value be accessed via PCI space
65496c34ac4SSergey Shtylyov 	 * according to the old driver. In addition we must use the value
65596c34ac4SSergey Shtylyov 	 * from FN 0 on the HPT374.
65696c34ac4SSergey Shtylyov 	 */
65775b4d58cSSergey Shtylyov 	if (pdev->device == PCI_DEVICE_ID_TTI_HPT374 &&
65875b4d58cSSergey Shtylyov 	    (PCI_FUNC(pdev->devfn) & 1)) {
65975b4d58cSSergey Shtylyov 		struct pci_dev *pdev_fn0;
66075b4d58cSSergey Shtylyov 
66175b4d58cSSergey Shtylyov 		pdev_fn0 = pci_get_slot(pdev->bus, pdev->devfn - 1);
66275b4d58cSSergey Shtylyov 		/* Someone hot plugged the controller on us? */
66375b4d58cSSergey Shtylyov 		if (!pdev_fn0)
66496c34ac4SSergey Shtylyov 			return 0;
66575b4d58cSSergey Shtylyov 		fcnt = inl(pci_resource_start(pdev_fn0, 4) + 0x90);
66675b4d58cSSergey Shtylyov 		pci_dev_put(pdev_fn0);
66796c34ac4SSergey Shtylyov 	} else	{
66896c34ac4SSergey Shtylyov 		fcnt = inl(pci_resource_start(pdev, 4) + 0x90);
66996c34ac4SSergey Shtylyov 	}
67096c34ac4SSergey Shtylyov 
67196c34ac4SSergey Shtylyov 	if ((fcnt >> 12) != 0xABCDE) {
67296c34ac4SSergey Shtylyov 		u32 total = 0;
67396c34ac4SSergey Shtylyov 		int i;
67496c34ac4SSergey Shtylyov 		u16 sr;
67596c34ac4SSergey Shtylyov 
67696c34ac4SSergey Shtylyov 		dev_warn(&pdev->dev, "BIOS clock data not set\n");
67796c34ac4SSergey Shtylyov 
67896c34ac4SSergey Shtylyov 		/* This is the process the HPT371 BIOS is reported to use */
67996c34ac4SSergey Shtylyov 		for (i = 0; i < 128; i++) {
68096c34ac4SSergey Shtylyov 			pci_read_config_word(pdev, 0x78, &sr);
68196c34ac4SSergey Shtylyov 			total += sr & 0x1FF;
68296c34ac4SSergey Shtylyov 			udelay(15);
68396c34ac4SSergey Shtylyov 		}
68496c34ac4SSergey Shtylyov 		fcnt = total / 128;
68596c34ac4SSergey Shtylyov 	}
68696c34ac4SSergey Shtylyov 	fcnt &= 0x1FF;
68796c34ac4SSergey Shtylyov 
68896c34ac4SSergey Shtylyov 	freq = (fcnt * base) / 192;	/* in MHz */
68996c34ac4SSergey Shtylyov 
69096c34ac4SSergey Shtylyov 	/* Clamp to bands */
69196c34ac4SSergey Shtylyov 	if (freq < 40)
69296c34ac4SSergey Shtylyov 		return 33;
69396c34ac4SSergey Shtylyov 	if (freq < 45)
69496c34ac4SSergey Shtylyov 		return 40;
69596c34ac4SSergey Shtylyov 	if (freq < 55)
69696c34ac4SSergey Shtylyov 		return 50;
69796c34ac4SSergey Shtylyov 	return 66;
69896c34ac4SSergey Shtylyov }
69996c34ac4SSergey Shtylyov 
700669a5db4SJeff Garzik /**
701669a5db4SJeff Garzik  *	hpt37x_init_one		-	Initialise an HPT37X/302
702669a5db4SJeff Garzik  *	@dev: PCI device
703669a5db4SJeff Garzik  *	@id: Entry in match table
704669a5db4SJeff Garzik  *
705669a5db4SJeff Garzik  *	Initialise an HPT37x device. There are some interesting complications
706669a5db4SJeff Garzik  *	here. Firstly the chip may report 366 and be one of several variants.
707669a5db4SJeff Garzik  *	Secondly all the timings depend on the clock for the chip which we must
708669a5db4SJeff Garzik  *	detect and look up
709669a5db4SJeff Garzik  *
710669a5db4SJeff Garzik  *	This is the known chip mappings. It may be missing a couple of later
711669a5db4SJeff Garzik  *	releases.
712669a5db4SJeff Garzik  *
713669a5db4SJeff Garzik  *	Chip version		PCI		Rev	Notes
714669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	0	Other driver
715669a5db4SJeff Garzik  *	HPT366			4 (HPT366)	1	Other driver
716669a5db4SJeff Garzik  *	HPT368			4 (HPT366)	2	Other driver
717669a5db4SJeff Garzik  *	HPT370			4 (HPT366)	3	UDMA100
718669a5db4SJeff Garzik  *	HPT370A			4 (HPT366)	4	UDMA100
719669a5db4SJeff Garzik  *	HPT372			4 (HPT366)	5	UDMA133 (1)
720669a5db4SJeff Garzik  *	HPT372N			4 (HPT366)	6	Other driver
721669a5db4SJeff Garzik  *	HPT372A			5 (HPT372)	1	UDMA133 (1)
722669a5db4SJeff Garzik  *	HPT372N			5 (HPT372)	2	Other driver
723669a5db4SJeff Garzik  *	HPT302			6 (HPT302)	1	UDMA133
724669a5db4SJeff Garzik  *	HPT302N			6 (HPT302)	2	Other driver
725669a5db4SJeff Garzik  *	HPT371			7 (HPT371)	*	UDMA133
726669a5db4SJeff Garzik  *	HPT374			8 (HPT374)	*	UDMA133 4 channel
727669a5db4SJeff Garzik  *	HPT372N			9 (HPT372N)	*	Other driver
728669a5db4SJeff Garzik  *
729669a5db4SJeff Garzik  *	(1) UDMA133 support depends on the bus clock
730669a5db4SJeff Garzik  */
731669a5db4SJeff Garzik 
hpt37x_init_one(struct pci_dev * dev,const struct pci_device_id * id)732669a5db4SJeff Garzik static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
733669a5db4SJeff Garzik {
734669a5db4SJeff Garzik 	/* HPT370 - UDMA100 */
7351626aeb8STejun Heo 	static const struct ata_port_info info_hpt370 = {
7361d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
73714bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
73814bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
739bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
740669a5db4SJeff Garzik 		.port_ops = &hpt370_port_ops
741669a5db4SJeff Garzik 	};
742669a5db4SJeff Garzik 	/* HPT370A - UDMA100 */
7431626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a = {
7441d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
74514bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
74614bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
747bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
748669a5db4SJeff Garzik 		.port_ops = &hpt370a_port_ops
749669a5db4SJeff Garzik 	};
750fc2698d5SSergei Shtylyov 	/* HPT370 - UDMA66 */
7511626aeb8STejun Heo 	static const struct ata_port_info info_hpt370_33 = {
7521d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
75314bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
75414bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
755fc2698d5SSergei Shtylyov 		.udma_mask = ATA_UDMA4,
756fcc2f69aSAlan Cox 		.port_ops = &hpt370_port_ops
757fcc2f69aSAlan Cox 	};
758fc2698d5SSergei Shtylyov 	/* HPT370A - UDMA66 */
7591626aeb8STejun Heo 	static const struct ata_port_info info_hpt370a_33 = {
7601d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
76114bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
76214bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
763fc2698d5SSergei Shtylyov 		.udma_mask = ATA_UDMA4,
764fcc2f69aSAlan Cox 		.port_ops = &hpt370a_port_ops
765fcc2f69aSAlan Cox 	};
7668e834c2eSSergei Shtylyov 	/* HPT372 - UDMA133 */
7671626aeb8STejun Heo 	static const struct ata_port_info info_hpt372 = {
7681d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
76914bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
77014bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
771bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA6,
772669a5db4SJeff Garzik 		.port_ops = &hpt372_port_ops
773669a5db4SJeff Garzik 	};
7748e834c2eSSergei Shtylyov 	/* HPT371, 302 - UDMA133 */
7758e834c2eSSergei Shtylyov 	static const struct ata_port_info info_hpt302 = {
7768e834c2eSSergei Shtylyov 		.flags = ATA_FLAG_SLAVE_POSS,
7778e834c2eSSergei Shtylyov 		.pio_mask = ATA_PIO4,
7788e834c2eSSergei Shtylyov 		.mwdma_mask = ATA_MWDMA2,
7798e834c2eSSergei Shtylyov 		.udma_mask = ATA_UDMA6,
7808e834c2eSSergei Shtylyov 		.port_ops = &hpt302_port_ops
7818e834c2eSSergei Shtylyov 	};
782defed559SSergei Shtylyov 	/* HPT374 - UDMA100, function 1 uses different cable_detect method */
783a1efdabaSTejun Heo 	static const struct ata_port_info info_hpt374_fn0 = {
7841d2808fdSJeff Garzik 		.flags = ATA_FLAG_SLAVE_POSS,
78514bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
78614bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
787bf6263a8SJeff Garzik 		.udma_mask = ATA_UDMA5,
788a1efdabaSTejun Heo 		.port_ops = &hpt372_port_ops
789a1efdabaSTejun Heo 	};
790a1efdabaSTejun Heo 	static const struct ata_port_info info_hpt374_fn1 = {
791a1efdabaSTejun Heo 		.flags = ATA_FLAG_SLAVE_POSS,
79214bdef98SErik Inge Bolsø 		.pio_mask = ATA_PIO4,
79314bdef98SErik Inge Bolsø 		.mwdma_mask = ATA_MWDMA2,
794a1efdabaSTejun Heo 		.udma_mask = ATA_UDMA5,
795a1efdabaSTejun Heo 		.port_ops = &hpt374_fn1_port_ops
796669a5db4SJeff Garzik 	};
797669a5db4SJeff Garzik 
798669a5db4SJeff Garzik 	static const int MHz[4] = { 33, 40, 50, 66 };
7991626aeb8STejun Heo 	void *private_data = NULL;
800887125e3STejun Heo 	const struct ata_port_info *ppi[] = { NULL, NULL };
80189d3b360SSergei Shtylyov 	u8 rev = dev->revision;
802669a5db4SJeff Garzik 	u8 irqmask;
803fcc2f69aSAlan Cox 	u8 mcr1;
804305f8db7SSergey Shtylyov 	unsigned int freq; /* MHz */
805fcc2f69aSAlan Cox 	int prefer_dpll = 1;
806fcc2f69aSAlan Cox 
807fcc2f69aSAlan Cox 	unsigned long iobase = pci_resource_start(dev, 4);
808669a5db4SJeff Garzik 
809669a5db4SJeff Garzik 	const struct hpt_chip *chip_table;
810669a5db4SJeff Garzik 	int clock_slot;
811f08048e9STejun Heo 	int rc;
812f08048e9STejun Heo 
813f08048e9STejun Heo 	rc = pcim_enable_device(dev);
814f08048e9STejun Heo 	if (rc)
815f08048e9STejun Heo 		return rc;
816669a5db4SJeff Garzik 
817910f7bb1SSergei Shtylyov 	switch (dev->device) {
818910f7bb1SSergei Shtylyov 	case PCI_DEVICE_ID_TTI_HPT366:
819669a5db4SJeff Garzik 		/* May be a later chip in disguise. Check */
820669a5db4SJeff Garzik 		/* Older chips are in the HPT366 driver. Ignore them */
82189d3b360SSergei Shtylyov 		if (rev < 3)
822669a5db4SJeff Garzik 			return -ENODEV;
823669a5db4SJeff Garzik 		/* N series chips have their own driver. Ignore */
82489d3b360SSergei Shtylyov 		if (rev == 6)
825669a5db4SJeff Garzik 			return -ENODEV;
826669a5db4SJeff Garzik 
82789d3b360SSergei Shtylyov 		switch (rev) {
828669a5db4SJeff Garzik 		case 3:
829887125e3STejun Heo 			ppi[0] = &info_hpt370;
830669a5db4SJeff Garzik 			chip_table = &hpt370;
831fcc2f69aSAlan Cox 			prefer_dpll = 0;
832669a5db4SJeff Garzik 			break;
833669a5db4SJeff Garzik 		case 4:
834887125e3STejun Heo 			ppi[0] = &info_hpt370a;
835669a5db4SJeff Garzik 			chip_table = &hpt370a;
836fcc2f69aSAlan Cox 			prefer_dpll = 0;
837669a5db4SJeff Garzik 			break;
838669a5db4SJeff Garzik 		case 5:
839887125e3STejun Heo 			ppi[0] = &info_hpt372;
840669a5db4SJeff Garzik 			chip_table = &hpt372;
841669a5db4SJeff Garzik 			break;
842669a5db4SJeff Garzik 		default:
843f06c13aaSHannes Reinecke 			dev_err(&dev->dev,
844f06c13aaSHannes Reinecke 				"Unknown HPT366 subtype, please report (%d)\n",
8458d7b1c70SJoe Perches 			       rev);
846669a5db4SJeff Garzik 			return -ENODEV;
847669a5db4SJeff Garzik 		}
848910f7bb1SSergei Shtylyov 		break;
849669a5db4SJeff Garzik 	case PCI_DEVICE_ID_TTI_HPT372:
850669a5db4SJeff Garzik 		/* 372N if rev >= 2 */
85189d3b360SSergei Shtylyov 		if (rev >= 2)
852669a5db4SJeff Garzik 			return -ENODEV;
853887125e3STejun Heo 		ppi[0] = &info_hpt372;
854669a5db4SJeff Garzik 		chip_table = &hpt372a;
855669a5db4SJeff Garzik 		break;
856669a5db4SJeff Garzik 	case PCI_DEVICE_ID_TTI_HPT302:
857669a5db4SJeff Garzik 		/* 302N if rev > 1 */
85889d3b360SSergei Shtylyov 		if (rev > 1)
859669a5db4SJeff Garzik 			return -ENODEV;
8608e834c2eSSergei Shtylyov 		ppi[0] = &info_hpt302;
861669a5db4SJeff Garzik 		/* Check this */
862669a5db4SJeff Garzik 		chip_table = &hpt302;
863669a5db4SJeff Garzik 		break;
864669a5db4SJeff Garzik 	case PCI_DEVICE_ID_TTI_HPT371:
86589d3b360SSergei Shtylyov 		if (rev > 1)
866fcc2f69aSAlan Cox 			return -ENODEV;
8678e834c2eSSergei Shtylyov 		ppi[0] = &info_hpt302;
868669a5db4SJeff Garzik 		chip_table = &hpt371;
86949bfbd38SSergei Shtylyov 		/*
870910f7bb1SSergei Shtylyov 		 * Single channel device, master is not present but the BIOS
871910f7bb1SSergei Shtylyov 		 * (or us for non x86) must mark it absent
87249bfbd38SSergei Shtylyov 		 */
873fcc2f69aSAlan Cox 		pci_read_config_byte(dev, 0x50, &mcr1);
874fcc2f69aSAlan Cox 		mcr1 &= ~0x04;
875fcc2f69aSAlan Cox 		pci_write_config_byte(dev, 0x50, mcr1);
876669a5db4SJeff Garzik 		break;
877669a5db4SJeff Garzik 	case PCI_DEVICE_ID_TTI_HPT374:
878669a5db4SJeff Garzik 		chip_table = &hpt374;
879a1efdabaSTejun Heo 		if (!(PCI_FUNC(dev->devfn) & 1))
880a1efdabaSTejun Heo 			*ppi = &info_hpt374_fn0;
881a1efdabaSTejun Heo 		else
882a1efdabaSTejun Heo 			*ppi = &info_hpt374_fn1;
883669a5db4SJeff Garzik 		break;
884669a5db4SJeff Garzik 	default:
885f06c13aaSHannes Reinecke 		dev_err(&dev->dev, "PCI table is bogus, please report (%d)\n",
886f06c13aaSHannes Reinecke 			dev->device);
887669a5db4SJeff Garzik 		return -ENODEV;
888669a5db4SJeff Garzik 	}
889669a5db4SJeff Garzik 	/* Ok so this is a chip we support */
890669a5db4SJeff Garzik 
891669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
892669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
893669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
894669a5db4SJeff Garzik 	pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
895669a5db4SJeff Garzik 
896669a5db4SJeff Garzik 	pci_read_config_byte(dev, 0x5A, &irqmask);
897669a5db4SJeff Garzik 	irqmask &= ~0x10;
898669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5a, irqmask);
899669a5db4SJeff Garzik 
900669a5db4SJeff Garzik 	/*
9018d093e02SSergey Shtylyov 	 * HPT371 chips physically have only one channel, the secondary one,
9028d093e02SSergey Shtylyov 	 * but the primary channel registers do exist!  Go figure...
9038d093e02SSergey Shtylyov 	 * So,  we manually disable the non-existing channel here
9048d093e02SSergey Shtylyov 	 * (if the BIOS hasn't done this already).
9058d093e02SSergey Shtylyov 	 */
9068d093e02SSergey Shtylyov 	if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
9078d093e02SSergey Shtylyov 		u8 mcr1;
9088d093e02SSergey Shtylyov 
9098d093e02SSergey Shtylyov 		pci_read_config_byte(dev, 0x50, &mcr1);
9108d093e02SSergey Shtylyov 		mcr1 &= ~0x04;
9118d093e02SSergey Shtylyov 		pci_write_config_byte(dev, 0x50, mcr1);
9128d093e02SSergey Shtylyov 	}
9138d093e02SSergey Shtylyov 
9148d093e02SSergey Shtylyov 	/*
915669a5db4SJeff Garzik 	 * default to pci clock. make sure MA15/16 are set to output
916669a5db4SJeff Garzik 	 * to prevent drives having problems with 40-pin cables. Needed
917669a5db4SJeff Garzik 	 * for some drives such as IBM-DTLA which will not enter ready
918669a5db4SJeff Garzik 	 * state on reset when PDIAG is a input.
919669a5db4SJeff Garzik 	 */
920669a5db4SJeff Garzik 
921669a5db4SJeff Garzik 	pci_write_config_byte(dev, 0x5b, 0x23);
922669a5db4SJeff Garzik 
923fcc2f69aSAlan Cox 	/*
924fcc2f69aSAlan Cox 	 * HighPoint does this for HPT372A.
925fcc2f69aSAlan Cox 	 * NOTE: This register is only writeable via I/O space.
926fcc2f69aSAlan Cox 	 */
927fcc2f69aSAlan Cox 	if (chip_table == &hpt372a)
928fcc2f69aSAlan Cox 		outb(0x0e, iobase + 0x9c);
929fcc2f69aSAlan Cox 
93096c34ac4SSergey Shtylyov 	freq = hpt37x_pci_clock(dev, chip_table->base);
93196c34ac4SSergey Shtylyov 	if (!freq)
93273946f9fSAlan Cox 		return -ENODEV;
933669a5db4SJeff Garzik 
934669a5db4SJeff Garzik 	/*
935669a5db4SJeff Garzik 	 *	Turn the frequency check into a band and then find a timing
936669a5db4SJeff Garzik 	 *	table to match it.
937669a5db4SJeff Garzik 	 */
938669a5db4SJeff Garzik 
939305f8db7SSergey Shtylyov 	clock_slot = hpt37x_clock_slot(freq);
940fcc2f69aSAlan Cox 	if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
941669a5db4SJeff Garzik 		/*
942669a5db4SJeff Garzik 		 *	We need to try PLL mode instead
943fcc2f69aSAlan Cox 		 *
944fcc2f69aSAlan Cox 		 *	For non UDMA133 capable devices we should
945fcc2f69aSAlan Cox 		 *	use a 50MHz DPLL by choice
946669a5db4SJeff Garzik 		 */
947fcc2f69aSAlan Cox 		unsigned int f_low, f_high;
948960c8a10SAlan Cox 		int dpll, adjust;
949669a5db4SJeff Garzik 
950960c8a10SAlan Cox 		/* Compute DPLL */
951887125e3STejun Heo 		dpll = (ppi[0]->udma_mask & 0xC0) ? 3 : 2;
952fcc2f69aSAlan Cox 
953960c8a10SAlan Cox 		f_low = (MHz[clock_slot] * 48) / MHz[dpll];
954fcc2f69aSAlan Cox 		f_high = f_low + 2;
955960c8a10SAlan Cox 		if (clock_slot > 1)
956960c8a10SAlan Cox 			f_high += 2;
957fcc2f69aSAlan Cox 
958fcc2f69aSAlan Cox 		/* Select the DPLL clock. */
959fcc2f69aSAlan Cox 		pci_write_config_byte(dev, 0x5b, 0x21);
96049bfbd38SSergei Shtylyov 		pci_write_config_dword(dev, 0x5C,
96149bfbd38SSergei Shtylyov 				       (f_high << 16) | f_low | 0x100);
962fcc2f69aSAlan Cox 
963669a5db4SJeff Garzik 		for (adjust = 0; adjust < 8; adjust++) {
964669a5db4SJeff Garzik 			if (hpt37x_calibrate_dpll(dev))
965669a5db4SJeff Garzik 				break;
96649bfbd38SSergei Shtylyov 			/*
96749bfbd38SSergei Shtylyov 			 * See if it'll settle at a fractionally
96849bfbd38SSergei Shtylyov 			 * different clock
96949bfbd38SSergei Shtylyov 			 */
97064a81709SAlan Cox 			if (adjust & 1)
97164a81709SAlan Cox 				f_low -= adjust >> 1;
97264a81709SAlan Cox 			else
97364a81709SAlan Cox 				f_high += adjust >> 1;
97449bfbd38SSergei Shtylyov 			pci_write_config_dword(dev, 0x5C,
97549bfbd38SSergei Shtylyov 					       (f_high << 16) | f_low | 0x100);
976669a5db4SJeff Garzik 		}
977669a5db4SJeff Garzik 		if (adjust == 8) {
978f06c13aaSHannes Reinecke 			dev_err(&dev->dev, "DPLL did not stabilize!\n");
979669a5db4SJeff Garzik 			return -ENODEV;
980669a5db4SJeff Garzik 		}
981960c8a10SAlan Cox 		if (dpll == 3)
9821626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_66;
983fcc2f69aSAlan Cox 		else
9841626aeb8STejun Heo 			private_data = (void *)hpt37x_timings_50;
985669a5db4SJeff Garzik 
986f06c13aaSHannes Reinecke 		dev_info(&dev->dev, "bus clock %dMHz, using %dMHz DPLL\n",
98780b8987cSSergei Shtylyov 			MHz[clock_slot], MHz[dpll]);
988669a5db4SJeff Garzik 	} else {
9891626aeb8STejun Heo 		private_data = (void *)chip_table->clocks[clock_slot];
990669a5db4SJeff Garzik 		/*
991a4734468SAlan Cox 		 *	Perform a final fixup. Note that we will have used the
992a4734468SAlan Cox 		 *	DPLL on the HPT372 which means we don't have to worry
993a4734468SAlan Cox 		 *	about lack of UDMA133 support on lower clocks
994669a5db4SJeff Garzik 		 */
995669a5db4SJeff Garzik 
996887125e3STejun Heo 		if (clock_slot < 2 && ppi[0] == &info_hpt370)
997887125e3STejun Heo 			ppi[0] = &info_hpt370_33;
998887125e3STejun Heo 		if (clock_slot < 2 && ppi[0] == &info_hpt370a)
999887125e3STejun Heo 			ppi[0] = &info_hpt370a_33;
100040d69ba0SSergei Shtylyov 
1001f06c13aaSHannes Reinecke 		dev_info(&dev->dev, "%s using %dMHz bus clock\n",
100280b8987cSSergei Shtylyov 			chip_table->name, MHz[clock_slot]);
1003669a5db4SJeff Garzik 	}
1004fcc2f69aSAlan Cox 
1005669a5db4SJeff Garzik 	/* Now kick off ATA set up */
10061c5afdf7STejun Heo 	return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data, 0);
1007669a5db4SJeff Garzik }
1008669a5db4SJeff Garzik 
10092d2744fcSJeff Garzik static const struct pci_device_id hpt37x[] = {
10102d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
10112d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
10122d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
10132d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT374), },
10142d2744fcSJeff Garzik 	{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
10152d2744fcSJeff Garzik 
10162d2744fcSJeff Garzik 	{ },
1017669a5db4SJeff Garzik };
1018669a5db4SJeff Garzik 
1019669a5db4SJeff Garzik static struct pci_driver hpt37x_pci_driver = {
1020669a5db4SJeff Garzik 	.name		= DRV_NAME,
1021669a5db4SJeff Garzik 	.id_table	= hpt37x,
1022669a5db4SJeff Garzik 	.probe		= hpt37x_init_one,
1023669a5db4SJeff Garzik 	.remove		= ata_pci_remove_one
1024669a5db4SJeff Garzik };
1025669a5db4SJeff Garzik 
10262fc75da0SAxel Lin module_pci_driver(hpt37x_pci_driver);
1027669a5db4SJeff Garzik 
1028669a5db4SJeff Garzik MODULE_AUTHOR("Alan Cox");
1029669a5db4SJeff Garzik MODULE_DESCRIPTION("low-level driver for the Highpoint HPT37x/30x");
1030669a5db4SJeff Garzik MODULE_LICENSE("GPL");
1031669a5db4SJeff Garzik MODULE_DEVICE_TABLE(pci, hpt37x);
1032669a5db4SJeff Garzik MODULE_VERSION(DRV_VERSION);
1033