1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * pata_cmd640.c - CMD640 PCI PATA for new ATA layer
4*4882a593Smuzhiyun * (C) 2007 Red Hat Inc
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Based upon
7*4882a593Smuzhiyun * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Copyright (C) 1995-1996 Linus Torvalds & authors (see driver)
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * This drives only the PCI version of the controller. If you have a
12*4882a593Smuzhiyun * VLB one then we have enough docs to support it but you can write
13*4882a593Smuzhiyun * your own code.
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/module.h>
18*4882a593Smuzhiyun #include <linux/pci.h>
19*4882a593Smuzhiyun #include <linux/blkdev.h>
20*4882a593Smuzhiyun #include <linux/delay.h>
21*4882a593Smuzhiyun #include <linux/gfp.h>
22*4882a593Smuzhiyun #include <scsi/scsi_host.h>
23*4882a593Smuzhiyun #include <linux/libata.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #define DRV_NAME "pata_cmd640"
26*4882a593Smuzhiyun #define DRV_VERSION "0.0.5"
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun struct cmd640_reg {
29*4882a593Smuzhiyun int last;
30*4882a593Smuzhiyun u8 reg58[ATA_MAX_DEVICES];
31*4882a593Smuzhiyun };
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun enum {
34*4882a593Smuzhiyun CFR = 0x50,
35*4882a593Smuzhiyun CNTRL = 0x51,
36*4882a593Smuzhiyun CMDTIM = 0x52,
37*4882a593Smuzhiyun ARTIM0 = 0x53,
38*4882a593Smuzhiyun DRWTIM0 = 0x54,
39*4882a593Smuzhiyun ARTIM23 = 0x57,
40*4882a593Smuzhiyun DRWTIM23 = 0x58,
41*4882a593Smuzhiyun BRST = 0x59
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /**
45*4882a593Smuzhiyun * cmd640_set_piomode - set initial PIO mode data
46*4882a593Smuzhiyun * @ap: ATA port
47*4882a593Smuzhiyun * @adev: ATA device
48*4882a593Smuzhiyun *
49*4882a593Smuzhiyun * Called to do the PIO mode setup.
50*4882a593Smuzhiyun */
51*4882a593Smuzhiyun
cmd640_set_piomode(struct ata_port * ap,struct ata_device * adev)52*4882a593Smuzhiyun static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun struct cmd640_reg *timing = ap->private_data;
55*4882a593Smuzhiyun struct pci_dev *pdev = to_pci_dev(ap->host->dev);
56*4882a593Smuzhiyun struct ata_timing t;
57*4882a593Smuzhiyun const unsigned long T = 1000000 / 33;
58*4882a593Smuzhiyun const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
59*4882a593Smuzhiyun u8 reg;
60*4882a593Smuzhiyun int arttim = ARTIM0 + 2 * adev->devno;
61*4882a593Smuzhiyun struct ata_device *pair = ata_dev_pair(adev);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
64*4882a593Smuzhiyun printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
65*4882a593Smuzhiyun return;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* The second channel has shared timings and the setup timing is
69*4882a593Smuzhiyun messy to switch to merge it for worst case */
70*4882a593Smuzhiyun if (ap->port_no && pair) {
71*4882a593Smuzhiyun struct ata_timing p;
72*4882a593Smuzhiyun ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
73*4882a593Smuzhiyun ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* Make the timings fit */
77*4882a593Smuzhiyun if (t.recover > 16) {
78*4882a593Smuzhiyun t.active += t.recover - 16;
79*4882a593Smuzhiyun t.recover = 16;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun if (t.active > 16)
82*4882a593Smuzhiyun t.active = 16;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /* Now convert the clocks into values we can actually stuff into
85*4882a593Smuzhiyun the chip */
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (t.recover > 1)
88*4882a593Smuzhiyun t.recover--; /* 640B only */
89*4882a593Smuzhiyun else
90*4882a593Smuzhiyun t.recover = 15;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun if (t.setup > 4)
93*4882a593Smuzhiyun t.setup = 0xC0;
94*4882a593Smuzhiyun else
95*4882a593Smuzhiyun t.setup = setup_data[t.setup];
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun if (ap->port_no == 0) {
98*4882a593Smuzhiyun t.active &= 0x0F; /* 0 = 16 */
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /* Load setup timing */
101*4882a593Smuzhiyun pci_read_config_byte(pdev, arttim, ®);
102*4882a593Smuzhiyun reg &= 0x3F;
103*4882a593Smuzhiyun reg |= t.setup;
104*4882a593Smuzhiyun pci_write_config_byte(pdev, arttim, reg);
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /* Load active/recovery */
107*4882a593Smuzhiyun pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
108*4882a593Smuzhiyun } else {
109*4882a593Smuzhiyun /* Save the shared timings for channel, they will be loaded
110*4882a593Smuzhiyun by qc_issue. Reloading the setup time is expensive so we
111*4882a593Smuzhiyun keep a merged one loaded */
112*4882a593Smuzhiyun pci_read_config_byte(pdev, ARTIM23, ®);
113*4882a593Smuzhiyun reg &= 0x3F;
114*4882a593Smuzhiyun reg |= t.setup;
115*4882a593Smuzhiyun pci_write_config_byte(pdev, ARTIM23, reg);
116*4882a593Smuzhiyun timing->reg58[adev->devno] = (t.active << 4) | t.recover;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun /**
122*4882a593Smuzhiyun * cmd640_qc_issue - command preparation hook
123*4882a593Smuzhiyun * @qc: Command to be issued
124*4882a593Smuzhiyun *
125*4882a593Smuzhiyun * Channel 1 has shared timings. We must reprogram the
126*4882a593Smuzhiyun * clock each drive 2/3 switch we do.
127*4882a593Smuzhiyun */
128*4882a593Smuzhiyun
cmd640_qc_issue(struct ata_queued_cmd * qc)129*4882a593Smuzhiyun static unsigned int cmd640_qc_issue(struct ata_queued_cmd *qc)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun struct ata_port *ap = qc->ap;
132*4882a593Smuzhiyun struct ata_device *adev = qc->dev;
133*4882a593Smuzhiyun struct pci_dev *pdev = to_pci_dev(ap->host->dev);
134*4882a593Smuzhiyun struct cmd640_reg *timing = ap->private_data;
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun if (ap->port_no != 0 && adev->devno != timing->last) {
137*4882a593Smuzhiyun pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
138*4882a593Smuzhiyun timing->last = adev->devno;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun return ata_sff_qc_issue(qc);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun /**
144*4882a593Smuzhiyun * cmd640_port_start - port setup
145*4882a593Smuzhiyun * @ap: ATA port being set up
146*4882a593Smuzhiyun *
147*4882a593Smuzhiyun * The CMD640 needs to maintain private data structures so we
148*4882a593Smuzhiyun * allocate space here.
149*4882a593Smuzhiyun */
150*4882a593Smuzhiyun
cmd640_port_start(struct ata_port * ap)151*4882a593Smuzhiyun static int cmd640_port_start(struct ata_port *ap)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun struct pci_dev *pdev = to_pci_dev(ap->host->dev);
154*4882a593Smuzhiyun struct cmd640_reg *timing;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
157*4882a593Smuzhiyun if (timing == NULL)
158*4882a593Smuzhiyun return -ENOMEM;
159*4882a593Smuzhiyun timing->last = -1; /* Force a load */
160*4882a593Smuzhiyun ap->private_data = timing;
161*4882a593Smuzhiyun return 0;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
cmd640_sff_irq_check(struct ata_port * ap)164*4882a593Smuzhiyun static bool cmd640_sff_irq_check(struct ata_port *ap)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun struct pci_dev *pdev = to_pci_dev(ap->host->dev);
167*4882a593Smuzhiyun int irq_reg = ap->port_no ? ARTIM23 : CFR;
168*4882a593Smuzhiyun u8 irq_stat, irq_mask = ap->port_no ? 0x10 : 0x04;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun pci_read_config_byte(pdev, irq_reg, &irq_stat);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun return irq_stat & irq_mask;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun static struct scsi_host_template cmd640_sht = {
176*4882a593Smuzhiyun ATA_PIO_SHT(DRV_NAME),
177*4882a593Smuzhiyun };
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun static struct ata_port_operations cmd640_port_ops = {
180*4882a593Smuzhiyun .inherits = &ata_sff_port_ops,
181*4882a593Smuzhiyun /* In theory xfer_noirq is not needed once we kill the prefetcher */
182*4882a593Smuzhiyun .sff_data_xfer = ata_sff_data_xfer32,
183*4882a593Smuzhiyun .sff_irq_check = cmd640_sff_irq_check,
184*4882a593Smuzhiyun .qc_issue = cmd640_qc_issue,
185*4882a593Smuzhiyun .cable_detect = ata_cable_40wire,
186*4882a593Smuzhiyun .set_piomode = cmd640_set_piomode,
187*4882a593Smuzhiyun .port_start = cmd640_port_start,
188*4882a593Smuzhiyun };
189*4882a593Smuzhiyun
cmd640_hardware_init(struct pci_dev * pdev)190*4882a593Smuzhiyun static void cmd640_hardware_init(struct pci_dev *pdev)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun u8 ctrl;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* CMD640 detected, commiserations */
195*4882a593Smuzhiyun pci_write_config_byte(pdev, 0x5B, 0x00);
196*4882a593Smuzhiyun /* PIO0 command cycles */
197*4882a593Smuzhiyun pci_write_config_byte(pdev, CMDTIM, 0);
198*4882a593Smuzhiyun /* 512 byte bursts (sector) */
199*4882a593Smuzhiyun pci_write_config_byte(pdev, BRST, 0x40);
200*4882a593Smuzhiyun /*
201*4882a593Smuzhiyun * A reporter a long time ago
202*4882a593Smuzhiyun * Had problems with the data fifo
203*4882a593Smuzhiyun * So don't run the risk
204*4882a593Smuzhiyun * Of putting crap on the disk
205*4882a593Smuzhiyun * For its better just to go slow
206*4882a593Smuzhiyun */
207*4882a593Smuzhiyun /* Do channel 0 */
208*4882a593Smuzhiyun pci_read_config_byte(pdev, CNTRL, &ctrl);
209*4882a593Smuzhiyun pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
210*4882a593Smuzhiyun /* Ditto for channel 1 */
211*4882a593Smuzhiyun pci_read_config_byte(pdev, ARTIM23, &ctrl);
212*4882a593Smuzhiyun ctrl |= 0x0C;
213*4882a593Smuzhiyun pci_write_config_byte(pdev, ARTIM23, ctrl);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
cmd640_init_one(struct pci_dev * pdev,const struct pci_device_id * id)216*4882a593Smuzhiyun static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun static const struct ata_port_info info = {
219*4882a593Smuzhiyun .flags = ATA_FLAG_SLAVE_POSS,
220*4882a593Smuzhiyun .pio_mask = ATA_PIO4,
221*4882a593Smuzhiyun .port_ops = &cmd640_port_ops
222*4882a593Smuzhiyun };
223*4882a593Smuzhiyun const struct ata_port_info *ppi[] = { &info, NULL };
224*4882a593Smuzhiyun int rc;
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun rc = pcim_enable_device(pdev);
227*4882a593Smuzhiyun if (rc)
228*4882a593Smuzhiyun return rc;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun cmd640_hardware_init(pdev);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL, 0);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
cmd640_reinit_one(struct pci_dev * pdev)236*4882a593Smuzhiyun static int cmd640_reinit_one(struct pci_dev *pdev)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun struct ata_host *host = pci_get_drvdata(pdev);
239*4882a593Smuzhiyun int rc;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun rc = ata_pci_device_do_resume(pdev);
242*4882a593Smuzhiyun if (rc)
243*4882a593Smuzhiyun return rc;
244*4882a593Smuzhiyun cmd640_hardware_init(pdev);
245*4882a593Smuzhiyun ata_host_resume(host);
246*4882a593Smuzhiyun return 0;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun #endif
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun static const struct pci_device_id cmd640[] = {
251*4882a593Smuzhiyun { PCI_VDEVICE(CMD, 0x640), 0 },
252*4882a593Smuzhiyun { },
253*4882a593Smuzhiyun };
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun static struct pci_driver cmd640_pci_driver = {
256*4882a593Smuzhiyun .name = DRV_NAME,
257*4882a593Smuzhiyun .id_table = cmd640,
258*4882a593Smuzhiyun .probe = cmd640_init_one,
259*4882a593Smuzhiyun .remove = ata_pci_remove_one,
260*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
261*4882a593Smuzhiyun .suspend = ata_pci_device_suspend,
262*4882a593Smuzhiyun .resume = cmd640_reinit_one,
263*4882a593Smuzhiyun #endif
264*4882a593Smuzhiyun };
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun module_pci_driver(cmd640_pci_driver);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun MODULE_AUTHOR("Alan Cox");
269*4882a593Smuzhiyun MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers");
270*4882a593Smuzhiyun MODULE_LICENSE("GPL");
271*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, cmd640);
272*4882a593Smuzhiyun MODULE_VERSION(DRV_VERSION);
273