1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   *	IDE tuning and bus mastering support for the CS5510/CS5520
4   *	chipsets
5   *
6   *	The CS5510/CS5520 are slightly unusual devices. Unlike the
7   *	typical IDE controllers they do bus mastering with the drive in
8   *	PIO mode and smarter silicon.
9   *
10   *	The practical upshot of this is that we must always tune the
11   *	drive for the right PIO mode and ignore the drive bus mastering DMA
12   *	information. Also to confuse matters further we can do DMA on PIO only
13   *	drives.
14   *
15   *	DMA on the 5510 also requires we disable_hlt() during DMA on early
16   *	revisions.
17   *
18   *	*** This driver is strictly experimental ***
19   *
20   *	(c) Copyright Red Hat Inc 2002
21   *
22   * Documentation:
23   *	Not publicly available.
24   */
25  #include <linux/kernel.h>
26  #include <linux/module.h>
27  #include <linux/pci.h>
28  #include <linux/blkdev.h>
29  #include <linux/delay.h>
30  #include <scsi/scsi_host.h>
31  #include <linux/libata.h>
32  
33  #define DRV_NAME	"pata_cs5520"
34  #define DRV_VERSION	"0.6.6"
35  
36  struct pio_clocks
37  {
38  	int address;
39  	int assert;
40  	int recovery;
41  };
42  
43  static const struct pio_clocks cs5520_pio_clocks[]={
44  	{3, 6, 11},
45  	{2, 5, 6},
46  	{1, 4, 3},
47  	{1, 3, 2},
48  	{1, 2, 1}
49  };
50  
51  /**
52   *	cs5520_set_timings	-	program PIO timings
53   *	@ap: ATA port
54   *	@adev: ATA device
55   *	@pio: PIO ID
56   *
57   *	Program the PIO mode timings for the controller according to the pio
58   *	clocking table.
59   */
60  
cs5520_set_timings(struct ata_port * ap,struct ata_device * adev,int pio)61  static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio)
62  {
63  	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
64  	int slave = adev->devno;
65  
66  	pio -= XFER_PIO_0;
67  
68  	/* Channel command timing */
69  	pci_write_config_byte(pdev, 0x62 + ap->port_no,
70  				(cs5520_pio_clocks[pio].recovery << 4) |
71  				(cs5520_pio_clocks[pio].assert));
72  	/* FIXME: should these use address ? */
73  	/* Read command timing */
74  	pci_write_config_byte(pdev, 0x64 +  4*ap->port_no + slave,
75  				(cs5520_pio_clocks[pio].recovery << 4) |
76  				(cs5520_pio_clocks[pio].assert));
77  	/* Write command timing */
78  	pci_write_config_byte(pdev, 0x66 +  4*ap->port_no + slave,
79  				(cs5520_pio_clocks[pio].recovery << 4) |
80  				(cs5520_pio_clocks[pio].assert));
81  }
82  
83  /**
84   *	cs5520_set_piomode	-	program PIO timings
85   *	@ap: ATA port
86   *	@adev: ATA device
87   *
88   *	Program the PIO mode timings for the controller according to the pio
89   *	clocking table.
90   */
91  
cs5520_set_piomode(struct ata_port * ap,struct ata_device * adev)92  static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
93  {
94  	cs5520_set_timings(ap, adev, adev->pio_mode);
95  }
96  
97  static const struct scsi_host_template cs5520_sht = {
98  	ATA_BASE_SHT(DRV_NAME),
99  	.sg_tablesize		= LIBATA_DUMB_MAX_PRD,
100  	.dma_boundary		= ATA_DMA_BOUNDARY,
101  };
102  
103  static struct ata_port_operations cs5520_port_ops = {
104  	.inherits		= &ata_bmdma_port_ops,
105  	.qc_prep		= ata_bmdma_dumb_qc_prep,
106  	.cable_detect		= ata_cable_40wire,
107  	.set_piomode		= cs5520_set_piomode,
108  };
109  
cs5520_init_one(struct pci_dev * pdev,const struct pci_device_id * id)110  static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
111  {
112  	static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
113  	static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
114  	struct ata_port_info pi = {
115  		.flags		= ATA_FLAG_SLAVE_POSS,
116  		.pio_mask	= ATA_PIO4,
117  		.port_ops	= &cs5520_port_ops,
118  	};
119  	const struct ata_port_info *ppi[2];
120  	u8 pcicfg;
121  	void __iomem *iomap[5];
122  	struct ata_host *host;
123  	struct ata_ioports *ioaddr;
124  	int i, rc;
125  
126  	rc = pcim_enable_device(pdev);
127  	if (rc)
128  		return rc;
129  
130  	/* IDE port enable bits */
131  	pci_read_config_byte(pdev, 0x60, &pcicfg);
132  
133  	/* Check if the ATA ports are enabled */
134  	if ((pcicfg & 3) == 0)
135  		return -ENODEV;
136  
137  	ppi[0] = ppi[1] = &ata_dummy_port_info;
138  	if (pcicfg & 1)
139  		ppi[0] = &pi;
140  	if (pcicfg & 2)
141  		ppi[1] = &pi;
142  
143  	if ((pcicfg & 0x40) == 0) {
144  		dev_warn(&pdev->dev, "DMA mode disabled. Enabling.\n");
145  		pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
146  	}
147  
148  	pi.mwdma_mask = id->driver_data;
149  
150  	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
151  	if (!host)
152  		return -ENOMEM;
153  
154  	if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
155  		dev_err(&pdev->dev, "unable to configure DMA mask.\n");
156  		return -ENODEV;
157  	}
158  
159  	/* Map IO ports and initialize host accordingly */
160  	iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
161  	iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
162  	iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
163  	iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
164  	iomap[4] = pcim_iomap(pdev, 2, 0);
165  
166  	if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
167  		return -ENOMEM;
168  
169  	ioaddr = &host->ports[0]->ioaddr;
170  	ioaddr->cmd_addr = iomap[0];
171  	ioaddr->ctl_addr = iomap[1];
172  	ioaddr->altstatus_addr = iomap[1];
173  	ioaddr->bmdma_addr = iomap[4];
174  	ata_sff_std_ports(ioaddr);
175  
176  	ata_port_desc(host->ports[0],
177  		      "cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
178  	ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");
179  
180  	ioaddr = &host->ports[1]->ioaddr;
181  	ioaddr->cmd_addr = iomap[2];
182  	ioaddr->ctl_addr = iomap[3];
183  	ioaddr->altstatus_addr = iomap[3];
184  	ioaddr->bmdma_addr = iomap[4] + 8;
185  	ata_sff_std_ports(ioaddr);
186  
187  	ata_port_desc(host->ports[1],
188  		      "cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
189  	ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");
190  
191  	/* activate the host */
192  	pci_set_master(pdev);
193  	rc = ata_host_start(host);
194  	if (rc)
195  		return rc;
196  
197  	for (i = 0; i < 2; i++) {
198  		static const int irq[] = { 14, 15 };
199  		struct ata_port *ap = host->ports[i];
200  
201  		if (ata_port_is_dummy(ap))
202  			continue;
203  
204  		rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
205  				      ata_bmdma_interrupt, 0, DRV_NAME, host);
206  		if (rc)
207  			return rc;
208  
209  		ata_port_desc_misc(ap, irq[i]);
210  	}
211  
212  	return ata_host_register(host, &cs5520_sht);
213  }
214  
215  #ifdef CONFIG_PM_SLEEP
216  /**
217   *	cs5520_reinit_one	-	device resume
218   *	@pdev: PCI device
219   *
220   *	Do any reconfiguration work needed by a resume from RAM. We need
221   *	to restore DMA mode support on BIOSen which disabled it
222   */
223  
cs5520_reinit_one(struct pci_dev * pdev)224  static int cs5520_reinit_one(struct pci_dev *pdev)
225  {
226  	struct ata_host *host = pci_get_drvdata(pdev);
227  	u8 pcicfg;
228  	int rc;
229  
230  	rc = ata_pci_device_do_resume(pdev);
231  	if (rc)
232  		return rc;
233  
234  	pci_read_config_byte(pdev, 0x60, &pcicfg);
235  	if ((pcicfg & 0x40) == 0)
236  		pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
237  
238  	ata_host_resume(host);
239  	return 0;
240  }
241  
242  /**
243   *	cs5520_pci_device_suspend	-	device suspend
244   *	@pdev: PCI device
245   *	@mesg: PM event message
246   *
247   *	We have to cut and waste bits from the standard method because
248   *	the 5520 is a bit odd and not just a pure ATA device. As a result
249   *	we must not disable it. The needed code is short and this avoids
250   *	chip specific mess in the core code.
251   */
252  
cs5520_pci_device_suspend(struct pci_dev * pdev,pm_message_t mesg)253  static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
254  {
255  	struct ata_host *host = pci_get_drvdata(pdev);
256  
257  	ata_host_suspend(host, mesg);
258  
259  	pci_save_state(pdev);
260  	return 0;
261  }
262  #endif /* CONFIG_PM_SLEEP */
263  
264  /* For now keep DMA off. We can set it for all but A rev CS5510 once the
265     core ATA code can handle it */
266  
267  static const struct pci_device_id pata_cs5520[] = {
268  	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
269  	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
270  
271  	{ },
272  };
273  
274  static struct pci_driver cs5520_pci_driver = {
275  	.name 		= DRV_NAME,
276  	.id_table	= pata_cs5520,
277  	.probe 		= cs5520_init_one,
278  	.remove		= ata_pci_remove_one,
279  #ifdef CONFIG_PM_SLEEP
280  	.suspend	= cs5520_pci_device_suspend,
281  	.resume		= cs5520_reinit_one,
282  #endif
283  };
284  
285  module_pci_driver(cs5520_pci_driver);
286  
287  MODULE_AUTHOR("Alan Cox");
288  MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520");
289  MODULE_LICENSE("GPL");
290  MODULE_DEVICE_TABLE(pci, pata_cs5520);
291  MODULE_VERSION(DRV_VERSION);
292