xref: /OK3568_Linux_fs/kernel/drivers/ata/pata_cmd64x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * pata_cmd64x.c 	- CMD64x PATA for new ATA layer
4*4882a593Smuzhiyun  *			  (C) 2005 Red Hat Inc
5*4882a593Smuzhiyun  *			  Alan Cox <alan@lxorguk.ukuu.org.uk>
6*4882a593Smuzhiyun  *			  (C) 2009-2010 Bartlomiej Zolnierkiewicz
7*4882a593Smuzhiyun  *			  (C) 2012 MontaVista Software, LLC <source@mvista.com>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Based upon
10*4882a593Smuzhiyun  * linux/drivers/ide/pci/cmd64x.c		Version 1.30	Sept 10, 2002
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
13*4882a593Smuzhiyun  *           Note, this driver is not used at all on other systems because
14*4882a593Smuzhiyun  *           there the "BIOS" has done all of the following already.
15*4882a593Smuzhiyun  *           Due to massive hardware bugs, UltraDMA is only supported
16*4882a593Smuzhiyun  *           on the 646U2 and not on the 646U.
17*4882a593Smuzhiyun  *
18*4882a593Smuzhiyun  * Copyright (C) 1998		Eddie C. Dost  (ecd@skynet.be)
19*4882a593Smuzhiyun  * Copyright (C) 1998		David S. Miller (davem@redhat.com)
20*4882a593Smuzhiyun  *
21*4882a593Smuzhiyun  * Copyright (C) 1999-2002	Andre Hedrick <andre@linux-ide.org>
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * TODO
24*4882a593Smuzhiyun  *	Testing work
25*4882a593Smuzhiyun  */
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include <linux/kernel.h>
28*4882a593Smuzhiyun #include <linux/module.h>
29*4882a593Smuzhiyun #include <linux/pci.h>
30*4882a593Smuzhiyun #include <linux/blkdev.h>
31*4882a593Smuzhiyun #include <linux/delay.h>
32*4882a593Smuzhiyun #include <scsi/scsi_host.h>
33*4882a593Smuzhiyun #include <linux/libata.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define DRV_NAME "pata_cmd64x"
36*4882a593Smuzhiyun #define DRV_VERSION "0.2.18"
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun  * CMD64x specific registers definition.
40*4882a593Smuzhiyun  */
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun enum {
43*4882a593Smuzhiyun 	CFR 		= 0x50,
44*4882a593Smuzhiyun 		CFR_INTR_CH0  = 0x04,
45*4882a593Smuzhiyun 	CNTRL		= 0x51,
46*4882a593Smuzhiyun 		CNTRL_CH0     = 0x04,
47*4882a593Smuzhiyun 		CNTRL_CH1     = 0x08,
48*4882a593Smuzhiyun 	CMDTIM 		= 0x52,
49*4882a593Smuzhiyun 	ARTTIM0 	= 0x53,
50*4882a593Smuzhiyun 	DRWTIM0 	= 0x54,
51*4882a593Smuzhiyun 	ARTTIM1 	= 0x55,
52*4882a593Smuzhiyun 	DRWTIM1 	= 0x56,
53*4882a593Smuzhiyun 	ARTTIM23 	= 0x57,
54*4882a593Smuzhiyun 		ARTTIM23_DIS_RA2  = 0x04,
55*4882a593Smuzhiyun 		ARTTIM23_DIS_RA3  = 0x08,
56*4882a593Smuzhiyun 		ARTTIM23_INTR_CH1 = 0x10,
57*4882a593Smuzhiyun 	DRWTIM2 	= 0x58,
58*4882a593Smuzhiyun 	BRST 		= 0x59,
59*4882a593Smuzhiyun 	DRWTIM3 	= 0x5b,
60*4882a593Smuzhiyun 	BMIDECR0	= 0x70,
61*4882a593Smuzhiyun 	MRDMODE		= 0x71,
62*4882a593Smuzhiyun 		MRDMODE_INTR_CH0 = 0x04,
63*4882a593Smuzhiyun 		MRDMODE_INTR_CH1 = 0x08,
64*4882a593Smuzhiyun 	BMIDESR0	= 0x72,
65*4882a593Smuzhiyun 	UDIDETCR0	= 0x73,
66*4882a593Smuzhiyun 	DTPR0		= 0x74,
67*4882a593Smuzhiyun 	BMIDECR1	= 0x78,
68*4882a593Smuzhiyun 	BMIDECSR	= 0x79,
69*4882a593Smuzhiyun 	UDIDETCR1	= 0x7B,
70*4882a593Smuzhiyun 	DTPR1		= 0x7C
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
cmd648_cable_detect(struct ata_port * ap)73*4882a593Smuzhiyun static int cmd648_cable_detect(struct ata_port *ap)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
76*4882a593Smuzhiyun 	u8 r;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	/* Check cable detect bits */
79*4882a593Smuzhiyun 	pci_read_config_byte(pdev, BMIDECSR, &r);
80*4882a593Smuzhiyun 	if (r & (1 << ap->port_no))
81*4882a593Smuzhiyun 		return ATA_CBL_PATA80;
82*4882a593Smuzhiyun 	return ATA_CBL_PATA40;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun /**
86*4882a593Smuzhiyun  *	cmd64x_set_timing	-	set PIO and MWDMA timing
87*4882a593Smuzhiyun  *	@ap: ATA interface
88*4882a593Smuzhiyun  *	@adev: ATA device
89*4882a593Smuzhiyun  *	@mode: mode
90*4882a593Smuzhiyun  *
91*4882a593Smuzhiyun  *	Called to do the PIO and MWDMA mode setup.
92*4882a593Smuzhiyun  */
93*4882a593Smuzhiyun 
cmd64x_set_timing(struct ata_port * ap,struct ata_device * adev,u8 mode)94*4882a593Smuzhiyun static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 mode)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
97*4882a593Smuzhiyun 	struct ata_timing t;
98*4882a593Smuzhiyun 	const unsigned long T = 1000000 / 33;
99*4882a593Smuzhiyun 	const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	u8 reg;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	/* Port layout is not logical so use a table */
104*4882a593Smuzhiyun 	const u8 arttim_port[2][2] = {
105*4882a593Smuzhiyun 		{ ARTTIM0, ARTTIM1 },
106*4882a593Smuzhiyun 		{ ARTTIM23, ARTTIM23 }
107*4882a593Smuzhiyun 	};
108*4882a593Smuzhiyun 	const u8 drwtim_port[2][2] = {
109*4882a593Smuzhiyun 		{ DRWTIM0, DRWTIM1 },
110*4882a593Smuzhiyun 		{ DRWTIM2, DRWTIM3 }
111*4882a593Smuzhiyun 	};
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	int arttim = arttim_port[ap->port_no][adev->devno];
114*4882a593Smuzhiyun 	int drwtim = drwtim_port[ap->port_no][adev->devno];
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* ata_timing_compute is smart and will produce timings for MWDMA
117*4882a593Smuzhiyun 	   that don't violate the drives PIO capabilities. */
118*4882a593Smuzhiyun 	if (ata_timing_compute(adev, mode, &t, T, 0) < 0) {
119*4882a593Smuzhiyun 		printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
120*4882a593Smuzhiyun 		return;
121*4882a593Smuzhiyun 	}
122*4882a593Smuzhiyun 	if (ap->port_no) {
123*4882a593Smuzhiyun 		/* Slave has shared address setup */
124*4882a593Smuzhiyun 		struct ata_device *pair = ata_dev_pair(adev);
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 		if (pair) {
127*4882a593Smuzhiyun 			struct ata_timing tp;
128*4882a593Smuzhiyun 			ata_timing_compute(pair, pair->pio_mode, &tp, T, 0);
129*4882a593Smuzhiyun 			ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
130*4882a593Smuzhiyun 		}
131*4882a593Smuzhiyun 	}
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	printk(KERN_DEBUG DRV_NAME ": active %d recovery %d setup %d.\n",
134*4882a593Smuzhiyun 		t.active, t.recover, t.setup);
135*4882a593Smuzhiyun 	if (t.recover > 16) {
136*4882a593Smuzhiyun 		t.active += t.recover - 16;
137*4882a593Smuzhiyun 		t.recover = 16;
138*4882a593Smuzhiyun 	}
139*4882a593Smuzhiyun 	if (t.active > 16)
140*4882a593Smuzhiyun 		t.active = 16;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/* Now convert the clocks into values we can actually stuff into
143*4882a593Smuzhiyun 	   the chip */
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if (t.recover == 16)
146*4882a593Smuzhiyun 		t.recover = 0;
147*4882a593Smuzhiyun 	else if (t.recover > 1)
148*4882a593Smuzhiyun 		t.recover--;
149*4882a593Smuzhiyun 	else
150*4882a593Smuzhiyun 		t.recover = 15;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	if (t.setup > 4)
153*4882a593Smuzhiyun 		t.setup = 0xC0;
154*4882a593Smuzhiyun 	else
155*4882a593Smuzhiyun 		t.setup = setup_data[t.setup];
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	t.active &= 0x0F;	/* 0 = 16 */
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	/* Load setup timing */
160*4882a593Smuzhiyun 	pci_read_config_byte(pdev, arttim, &reg);
161*4882a593Smuzhiyun 	reg &= 0x3F;
162*4882a593Smuzhiyun 	reg |= t.setup;
163*4882a593Smuzhiyun 	pci_write_config_byte(pdev, arttim, reg);
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* Load active/recovery */
166*4882a593Smuzhiyun 	pci_write_config_byte(pdev, drwtim, (t.active << 4) | t.recover);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun /**
170*4882a593Smuzhiyun  *	cmd64x_set_piomode	-	set initial PIO mode data
171*4882a593Smuzhiyun  *	@ap: ATA interface
172*4882a593Smuzhiyun  *	@adev: ATA device
173*4882a593Smuzhiyun  *
174*4882a593Smuzhiyun  *	Used when configuring the devices ot set the PIO timings. All the
175*4882a593Smuzhiyun  *	actual work is done by the PIO/MWDMA setting helper
176*4882a593Smuzhiyun  */
177*4882a593Smuzhiyun 
cmd64x_set_piomode(struct ata_port * ap,struct ata_device * adev)178*4882a593Smuzhiyun static void cmd64x_set_piomode(struct ata_port *ap, struct ata_device *adev)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	cmd64x_set_timing(ap, adev, adev->pio_mode);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun /**
184*4882a593Smuzhiyun  *	cmd64x_set_dmamode	-	set initial DMA mode data
185*4882a593Smuzhiyun  *	@ap: ATA interface
186*4882a593Smuzhiyun  *	@adev: ATA device
187*4882a593Smuzhiyun  *
188*4882a593Smuzhiyun  *	Called to do the DMA mode setup.
189*4882a593Smuzhiyun  */
190*4882a593Smuzhiyun 
cmd64x_set_dmamode(struct ata_port * ap,struct ata_device * adev)191*4882a593Smuzhiyun static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	static const u8 udma_data[] = {
194*4882a593Smuzhiyun 		0x30, 0x20, 0x10, 0x20, 0x10, 0x00
195*4882a593Smuzhiyun 	};
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
198*4882a593Smuzhiyun 	u8 regU, regD;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	int pciU = UDIDETCR0 + 8 * ap->port_no;
201*4882a593Smuzhiyun 	int pciD = BMIDESR0 + 8 * ap->port_no;
202*4882a593Smuzhiyun 	int shift = 2 * adev->devno;
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	pci_read_config_byte(pdev, pciD, &regD);
205*4882a593Smuzhiyun 	pci_read_config_byte(pdev, pciU, &regU);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	/* DMA bits off */
208*4882a593Smuzhiyun 	regD &= ~(0x20 << adev->devno);
209*4882a593Smuzhiyun 	/* DMA control bits */
210*4882a593Smuzhiyun 	regU &= ~(0x30 << shift);
211*4882a593Smuzhiyun 	/* DMA timing bits */
212*4882a593Smuzhiyun 	regU &= ~(0x05 << adev->devno);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	if (adev->dma_mode >= XFER_UDMA_0) {
215*4882a593Smuzhiyun 		/* Merge the timing value */
216*4882a593Smuzhiyun 		regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
217*4882a593Smuzhiyun 		/* Merge the control bits */
218*4882a593Smuzhiyun 		regU |= 1 << adev->devno; /* UDMA on */
219*4882a593Smuzhiyun 		if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
220*4882a593Smuzhiyun 			regU |= 4 << adev->devno;
221*4882a593Smuzhiyun 	} else {
222*4882a593Smuzhiyun 		regU &= ~ (1 << adev->devno);	/* UDMA off */
223*4882a593Smuzhiyun 		cmd64x_set_timing(ap, adev, adev->dma_mode);
224*4882a593Smuzhiyun 	}
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	regD |= 0x20 << adev->devno;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	pci_write_config_byte(pdev, pciU, regU);
229*4882a593Smuzhiyun 	pci_write_config_byte(pdev, pciD, regD);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun /**
233*4882a593Smuzhiyun  *	cmd64x_sff_irq_check	-	check IDE interrupt
234*4882a593Smuzhiyun  *	@ap: ATA interface
235*4882a593Smuzhiyun  *
236*4882a593Smuzhiyun  *	Check IDE interrupt in CFR/ARTTIM23 registers.
237*4882a593Smuzhiyun  */
238*4882a593Smuzhiyun 
cmd64x_sff_irq_check(struct ata_port * ap)239*4882a593Smuzhiyun static bool cmd64x_sff_irq_check(struct ata_port *ap)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
242*4882a593Smuzhiyun 	int irq_mask = ap->port_no ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
243*4882a593Smuzhiyun 	int irq_reg  = ap->port_no ? ARTTIM23 : CFR;
244*4882a593Smuzhiyun 	u8 irq_stat;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	/* NOTE: reading the register should clear the interrupt */
247*4882a593Smuzhiyun 	pci_read_config_byte(pdev, irq_reg, &irq_stat);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	return irq_stat & irq_mask;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun /**
253*4882a593Smuzhiyun  *	cmd64x_sff_irq_clear	-	clear IDE interrupt
254*4882a593Smuzhiyun  *	@ap: ATA interface
255*4882a593Smuzhiyun  *
256*4882a593Smuzhiyun  *	Clear IDE interrupt in CFR/ARTTIM23 and DMA status registers.
257*4882a593Smuzhiyun  */
258*4882a593Smuzhiyun 
cmd64x_sff_irq_clear(struct ata_port * ap)259*4882a593Smuzhiyun static void cmd64x_sff_irq_clear(struct ata_port *ap)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
262*4882a593Smuzhiyun 	int irq_reg = ap->port_no ? ARTTIM23 : CFR;
263*4882a593Smuzhiyun 	u8 irq_stat;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	ata_bmdma_irq_clear(ap);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	/* Reading the register should be enough to clear the interrupt */
268*4882a593Smuzhiyun 	pci_read_config_byte(pdev, irq_reg, &irq_stat);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /**
272*4882a593Smuzhiyun  *	cmd648_sff_irq_check	-	check IDE interrupt
273*4882a593Smuzhiyun  *	@ap: ATA interface
274*4882a593Smuzhiyun  *
275*4882a593Smuzhiyun  *	Check IDE interrupt in MRDMODE register.
276*4882a593Smuzhiyun  */
277*4882a593Smuzhiyun 
cmd648_sff_irq_check(struct ata_port * ap)278*4882a593Smuzhiyun static bool cmd648_sff_irq_check(struct ata_port *ap)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
281*4882a593Smuzhiyun 	unsigned long base = pci_resource_start(pdev, 4);
282*4882a593Smuzhiyun 	int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
283*4882a593Smuzhiyun 	u8 mrdmode = inb(base + 1);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	return mrdmode & irq_mask;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun /**
289*4882a593Smuzhiyun  *	cmd648_sff_irq_clear	-	clear IDE interrupt
290*4882a593Smuzhiyun  *	@ap: ATA interface
291*4882a593Smuzhiyun  *
292*4882a593Smuzhiyun  *	Clear IDE interrupt in MRDMODE and DMA status registers.
293*4882a593Smuzhiyun  */
294*4882a593Smuzhiyun 
cmd648_sff_irq_clear(struct ata_port * ap)295*4882a593Smuzhiyun static void cmd648_sff_irq_clear(struct ata_port *ap)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
298*4882a593Smuzhiyun 	unsigned long base = pci_resource_start(pdev, 4);
299*4882a593Smuzhiyun 	int irq_mask = ap->port_no ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
300*4882a593Smuzhiyun 	u8 mrdmode;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	ata_bmdma_irq_clear(ap);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* Clear this port's interrupt bit (leaving the other port alone) */
305*4882a593Smuzhiyun 	mrdmode  = inb(base + 1);
306*4882a593Smuzhiyun 	mrdmode &= ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1);
307*4882a593Smuzhiyun 	outb(mrdmode | irq_mask, base + 1);
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /**
311*4882a593Smuzhiyun  *	cmd646r1_bmdma_stop	-	DMA stop callback
312*4882a593Smuzhiyun  *	@qc: Command in progress
313*4882a593Smuzhiyun  *
314*4882a593Smuzhiyun  *	Stub for now while investigating the r1 quirk in the old driver.
315*4882a593Smuzhiyun  */
316*4882a593Smuzhiyun 
cmd646r1_bmdma_stop(struct ata_queued_cmd * qc)317*4882a593Smuzhiyun static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	ata_bmdma_stop(qc);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun static struct scsi_host_template cmd64x_sht = {
323*4882a593Smuzhiyun 	ATA_BMDMA_SHT(DRV_NAME),
324*4882a593Smuzhiyun };
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun static const struct ata_port_operations cmd64x_base_ops = {
327*4882a593Smuzhiyun 	.inherits	= &ata_bmdma_port_ops,
328*4882a593Smuzhiyun 	.set_piomode	= cmd64x_set_piomode,
329*4882a593Smuzhiyun 	.set_dmamode	= cmd64x_set_dmamode,
330*4882a593Smuzhiyun };
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun static struct ata_port_operations cmd64x_port_ops = {
333*4882a593Smuzhiyun 	.inherits	= &cmd64x_base_ops,
334*4882a593Smuzhiyun 	.sff_irq_check	= cmd64x_sff_irq_check,
335*4882a593Smuzhiyun 	.sff_irq_clear	= cmd64x_sff_irq_clear,
336*4882a593Smuzhiyun 	.cable_detect	= ata_cable_40wire,
337*4882a593Smuzhiyun };
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun static struct ata_port_operations cmd646r1_port_ops = {
340*4882a593Smuzhiyun 	.inherits	= &cmd64x_base_ops,
341*4882a593Smuzhiyun 	.sff_irq_check	= cmd64x_sff_irq_check,
342*4882a593Smuzhiyun 	.sff_irq_clear	= cmd64x_sff_irq_clear,
343*4882a593Smuzhiyun 	.bmdma_stop	= cmd646r1_bmdma_stop,
344*4882a593Smuzhiyun 	.cable_detect	= ata_cable_40wire,
345*4882a593Smuzhiyun };
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun static struct ata_port_operations cmd646r3_port_ops = {
348*4882a593Smuzhiyun 	.inherits	= &cmd64x_base_ops,
349*4882a593Smuzhiyun 	.sff_irq_check	= cmd648_sff_irq_check,
350*4882a593Smuzhiyun 	.sff_irq_clear	= cmd648_sff_irq_clear,
351*4882a593Smuzhiyun 	.cable_detect	= ata_cable_40wire,
352*4882a593Smuzhiyun };
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun static struct ata_port_operations cmd648_port_ops = {
355*4882a593Smuzhiyun 	.inherits	= &cmd64x_base_ops,
356*4882a593Smuzhiyun 	.sff_irq_check	= cmd648_sff_irq_check,
357*4882a593Smuzhiyun 	.sff_irq_clear	= cmd648_sff_irq_clear,
358*4882a593Smuzhiyun 	.cable_detect	= cmd648_cable_detect,
359*4882a593Smuzhiyun };
360*4882a593Smuzhiyun 
cmd64x_fixup(struct pci_dev * pdev)361*4882a593Smuzhiyun static void cmd64x_fixup(struct pci_dev *pdev)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun 	u8 mrdmode;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
366*4882a593Smuzhiyun 	pci_read_config_byte(pdev, MRDMODE, &mrdmode);
367*4882a593Smuzhiyun 	mrdmode &= ~0x30;	/* IRQ set up */
368*4882a593Smuzhiyun 	mrdmode |= 0x02;	/* Memory read line enable */
369*4882a593Smuzhiyun 	pci_write_config_byte(pdev, MRDMODE, mrdmode);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	/* PPC specific fixup copied from old driver */
372*4882a593Smuzhiyun #ifdef CONFIG_PPC
373*4882a593Smuzhiyun 	pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
374*4882a593Smuzhiyun #endif
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun 
cmd64x_init_one(struct pci_dev * pdev,const struct pci_device_id * id)377*4882a593Smuzhiyun static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun 	static const struct ata_port_info cmd_info[7] = {
380*4882a593Smuzhiyun 		{	/* CMD 643 - no UDMA */
381*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
382*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
383*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
384*4882a593Smuzhiyun 			.port_ops = &cmd64x_port_ops
385*4882a593Smuzhiyun 		},
386*4882a593Smuzhiyun 		{	/* CMD 646 with broken UDMA */
387*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
388*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
389*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
390*4882a593Smuzhiyun 			.port_ops = &cmd64x_port_ops
391*4882a593Smuzhiyun 		},
392*4882a593Smuzhiyun 		{	/* CMD 646U with broken UDMA */
393*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
394*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
395*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
396*4882a593Smuzhiyun 			.port_ops = &cmd646r3_port_ops
397*4882a593Smuzhiyun 		},
398*4882a593Smuzhiyun 		{	/* CMD 646U2 with working UDMA */
399*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
400*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
401*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
402*4882a593Smuzhiyun 			.udma_mask = ATA_UDMA2,
403*4882a593Smuzhiyun 			.port_ops = &cmd646r3_port_ops
404*4882a593Smuzhiyun 		},
405*4882a593Smuzhiyun 		{	/* CMD 646 rev 1  */
406*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
407*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
408*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
409*4882a593Smuzhiyun 			.port_ops = &cmd646r1_port_ops
410*4882a593Smuzhiyun 		},
411*4882a593Smuzhiyun 		{	/* CMD 648 */
412*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
413*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
414*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
415*4882a593Smuzhiyun 			.udma_mask = ATA_UDMA4,
416*4882a593Smuzhiyun 			.port_ops = &cmd648_port_ops
417*4882a593Smuzhiyun 		},
418*4882a593Smuzhiyun 		{	/* CMD 649 */
419*4882a593Smuzhiyun 			.flags = ATA_FLAG_SLAVE_POSS,
420*4882a593Smuzhiyun 			.pio_mask = ATA_PIO4,
421*4882a593Smuzhiyun 			.mwdma_mask = ATA_MWDMA2,
422*4882a593Smuzhiyun 			.udma_mask = ATA_UDMA5,
423*4882a593Smuzhiyun 			.port_ops = &cmd648_port_ops
424*4882a593Smuzhiyun 		}
425*4882a593Smuzhiyun 	};
426*4882a593Smuzhiyun 	const struct ata_port_info *ppi[] = {
427*4882a593Smuzhiyun 		&cmd_info[id->driver_data],
428*4882a593Smuzhiyun 		&cmd_info[id->driver_data],
429*4882a593Smuzhiyun 		NULL
430*4882a593Smuzhiyun 	};
431*4882a593Smuzhiyun 	u8 reg;
432*4882a593Smuzhiyun 	int rc;
433*4882a593Smuzhiyun 	struct pci_dev *bridge = pdev->bus->self;
434*4882a593Smuzhiyun 	/* mobility split bridges don't report enabled ports correctly */
435*4882a593Smuzhiyun 	int port_ok = !(bridge && bridge->vendor ==
436*4882a593Smuzhiyun 			PCI_VENDOR_ID_MOBILITY_ELECTRONICS);
437*4882a593Smuzhiyun 	/* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */
438*4882a593Smuzhiyun 	int cntrl_ch0_ok = (id->driver_data != 0);
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	rc = pcim_enable_device(pdev);
441*4882a593Smuzhiyun 	if (rc)
442*4882a593Smuzhiyun 		return rc;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	if (id->driver_data == 0)	/* 643 */
445*4882a593Smuzhiyun 		ata_pci_bmdma_clear_simplex(pdev);
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	if (pdev->device == PCI_DEVICE_ID_CMD_646)
448*4882a593Smuzhiyun 		switch (pdev->revision) {
449*4882a593Smuzhiyun 		/* UDMA works since rev 5 */
450*4882a593Smuzhiyun 		default:
451*4882a593Smuzhiyun 			ppi[0] = &cmd_info[3];
452*4882a593Smuzhiyun 			ppi[1] = &cmd_info[3];
453*4882a593Smuzhiyun 			break;
454*4882a593Smuzhiyun 		/* Interrupts in MRDMODE since rev 3 */
455*4882a593Smuzhiyun 		case 3:
456*4882a593Smuzhiyun 		case 4:
457*4882a593Smuzhiyun 			ppi[0] = &cmd_info[2];
458*4882a593Smuzhiyun 			ppi[1] = &cmd_info[2];
459*4882a593Smuzhiyun 			break;
460*4882a593Smuzhiyun 		/* Rev 1 with other problems? */
461*4882a593Smuzhiyun 		case 1:
462*4882a593Smuzhiyun 			ppi[0] = &cmd_info[4];
463*4882a593Smuzhiyun 			ppi[1] = &cmd_info[4];
464*4882a593Smuzhiyun 			fallthrough;
465*4882a593Smuzhiyun 		/* Early revs have no CNTRL_CH0 */
466*4882a593Smuzhiyun 		case 2:
467*4882a593Smuzhiyun 		case 0:
468*4882a593Smuzhiyun 			cntrl_ch0_ok = 0;
469*4882a593Smuzhiyun 			break;
470*4882a593Smuzhiyun 		}
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	cmd64x_fixup(pdev);
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	/* check for enabled ports */
475*4882a593Smuzhiyun 	pci_read_config_byte(pdev, CNTRL, &reg);
476*4882a593Smuzhiyun 	if (!port_ok)
477*4882a593Smuzhiyun 		dev_notice(&pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n");
478*4882a593Smuzhiyun 	if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) {
479*4882a593Smuzhiyun 		dev_notice(&pdev->dev, "Primary port is disabled\n");
480*4882a593Smuzhiyun 		ppi[0] = &ata_dummy_port_info;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	}
483*4882a593Smuzhiyun 	if (port_ok && !(reg & CNTRL_CH1)) {
484*4882a593Smuzhiyun 		dev_notice(&pdev->dev, "Secondary port is disabled\n");
485*4882a593Smuzhiyun 		ppi[1] = &ata_dummy_port_info;
486*4882a593Smuzhiyun 	}
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
cmd64x_reinit_one(struct pci_dev * pdev)492*4882a593Smuzhiyun static int cmd64x_reinit_one(struct pci_dev *pdev)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun 	struct ata_host *host = pci_get_drvdata(pdev);
495*4882a593Smuzhiyun 	int rc;
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	rc = ata_pci_device_do_resume(pdev);
498*4882a593Smuzhiyun 	if (rc)
499*4882a593Smuzhiyun 		return rc;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	cmd64x_fixup(pdev);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	ata_host_resume(host);
504*4882a593Smuzhiyun 	return 0;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun #endif
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun static const struct pci_device_id cmd64x[] = {
509*4882a593Smuzhiyun 	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
510*4882a593Smuzhiyun 	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
511*4882a593Smuzhiyun 	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 5 },
512*4882a593Smuzhiyun 	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 6 },
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	{ },
515*4882a593Smuzhiyun };
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun static struct pci_driver cmd64x_pci_driver = {
518*4882a593Smuzhiyun 	.name 		= DRV_NAME,
519*4882a593Smuzhiyun 	.id_table	= cmd64x,
520*4882a593Smuzhiyun 	.probe 		= cmd64x_init_one,
521*4882a593Smuzhiyun 	.remove		= ata_pci_remove_one,
522*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
523*4882a593Smuzhiyun 	.suspend	= ata_pci_device_suspend,
524*4882a593Smuzhiyun 	.resume		= cmd64x_reinit_one,
525*4882a593Smuzhiyun #endif
526*4882a593Smuzhiyun };
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun module_pci_driver(cmd64x_pci_driver);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun MODULE_AUTHOR("Alan Cox");
531*4882a593Smuzhiyun MODULE_DESCRIPTION("low-level driver for CMD64x series PATA controllers");
532*4882a593Smuzhiyun MODULE_LICENSE("GPL");
533*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, cmd64x);
534*4882a593Smuzhiyun MODULE_VERSION(DRV_VERSION);
535