Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  IDE tuning and bus mastering support for the CS5510/CS5520
0004  *  chipsets
0005  *
0006  *  The CS5510/CS5520 are slightly unusual devices. Unlike the
0007  *  typical IDE controllers they do bus mastering with the drive in
0008  *  PIO mode and smarter silicon.
0009  *
0010  *  The practical upshot of this is that we must always tune the
0011  *  drive for the right PIO mode. We must also ignore all the blacklists
0012  *  and the drive bus mastering DMA information. Also to confuse matters
0013  *  further we can do DMA on PIO only drives.
0014  *
0015  *  DMA on the 5510 also requires we disable_hlt() during DMA on early
0016  *  revisions.
0017  *
0018  *  *** This driver is strictly experimental ***
0019  *
0020  *  (c) Copyright Red Hat Inc 2002
0021  *
0022  * Documentation:
0023  *  Not publicly available.
0024  */
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/pci.h>
0028 #include <linux/blkdev.h>
0029 #include <linux/delay.h>
0030 #include <scsi/scsi_host.h>
0031 #include <linux/libata.h>
0032 
0033 #define DRV_NAME    "pata_cs5520"
0034 #define DRV_VERSION "0.6.6"
0035 
0036 struct pio_clocks
0037 {
0038     int address;
0039     int assert;
0040     int recovery;
0041 };
0042 
0043 static const struct pio_clocks cs5520_pio_clocks[]={
0044     {3, 6, 11},
0045     {2, 5, 6},
0046     {1, 4, 3},
0047     {1, 3, 2},
0048     {1, 2, 1}
0049 };
0050 
0051 /**
0052  *  cs5520_set_timings  -   program PIO timings
0053  *  @ap: ATA port
0054  *  @adev: ATA device
0055  *  @pio: PIO ID
0056  *
0057  *  Program the PIO mode timings for the controller according to the pio
0058  *  clocking table.
0059  */
0060 
0061 static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int pio)
0062 {
0063     struct pci_dev *pdev = to_pci_dev(ap->host->dev);
0064     int slave = adev->devno;
0065 
0066     pio -= XFER_PIO_0;
0067 
0068     /* Channel command timing */
0069     pci_write_config_byte(pdev, 0x62 + ap->port_no,
0070                 (cs5520_pio_clocks[pio].recovery << 4) |
0071                 (cs5520_pio_clocks[pio].assert));
0072     /* FIXME: should these use address ? */
0073     /* Read command timing */
0074     pci_write_config_byte(pdev, 0x64 +  4*ap->port_no + slave,
0075                 (cs5520_pio_clocks[pio].recovery << 4) |
0076                 (cs5520_pio_clocks[pio].assert));
0077     /* Write command timing */
0078     pci_write_config_byte(pdev, 0x66 +  4*ap->port_no + slave,
0079                 (cs5520_pio_clocks[pio].recovery << 4) |
0080                 (cs5520_pio_clocks[pio].assert));
0081 }
0082 
0083 /**
0084  *  cs5520_set_piomode  -   program PIO timings
0085  *  @ap: ATA port
0086  *  @adev: ATA device
0087  *
0088  *  Program the PIO mode timings for the controller according to the pio
0089  *  clocking table.
0090  */
0091 
0092 static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
0093 {
0094     cs5520_set_timings(ap, adev, adev->pio_mode);
0095 }
0096 
0097 static struct scsi_host_template cs5520_sht = {
0098     ATA_BASE_SHT(DRV_NAME),
0099     .sg_tablesize       = LIBATA_DUMB_MAX_PRD,
0100     .dma_boundary       = ATA_DMA_BOUNDARY,
0101 };
0102 
0103 static struct ata_port_operations cs5520_port_ops = {
0104     .inherits       = &ata_bmdma_port_ops,
0105     .qc_prep        = ata_bmdma_dumb_qc_prep,
0106     .cable_detect       = ata_cable_40wire,
0107     .set_piomode        = cs5520_set_piomode,
0108 };
0109 
0110 static int cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
0111 {
0112     static const unsigned int cmd_port[] = { 0x1F0, 0x170 };
0113     static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
0114     struct ata_port_info pi = {
0115         .flags      = ATA_FLAG_SLAVE_POSS,
0116         .pio_mask   = ATA_PIO4,
0117         .port_ops   = &cs5520_port_ops,
0118     };
0119     const struct ata_port_info *ppi[2];
0120     u8 pcicfg;
0121     void __iomem *iomap[5];
0122     struct ata_host *host;
0123     struct ata_ioports *ioaddr;
0124     int i, rc;
0125 
0126     rc = pcim_enable_device(pdev);
0127     if (rc)
0128         return rc;
0129 
0130     /* IDE port enable bits */
0131     pci_read_config_byte(pdev, 0x60, &pcicfg);
0132 
0133     /* Check if the ATA ports are enabled */
0134     if ((pcicfg & 3) == 0)
0135         return -ENODEV;
0136 
0137     ppi[0] = ppi[1] = &ata_dummy_port_info;
0138     if (pcicfg & 1)
0139         ppi[0] = &pi;
0140     if (pcicfg & 2)
0141         ppi[1] = &pi;
0142 
0143     if ((pcicfg & 0x40) == 0) {
0144         dev_warn(&pdev->dev, "DMA mode disabled. Enabling.\n");
0145         pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
0146     }
0147 
0148     pi.mwdma_mask = id->driver_data;
0149 
0150     host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
0151     if (!host)
0152         return -ENOMEM;
0153 
0154     /* Perform set up for DMA */
0155     if (pci_enable_device_io(pdev)) {
0156         dev_err(&pdev->dev, "unable to configure BAR2.\n");
0157         return -ENODEV;
0158     }
0159 
0160     if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
0161         dev_err(&pdev->dev, "unable to configure DMA mask.\n");
0162         return -ENODEV;
0163     }
0164 
0165     /* Map IO ports and initialize host accordingly */
0166     iomap[0] = devm_ioport_map(&pdev->dev, cmd_port[0], 8);
0167     iomap[1] = devm_ioport_map(&pdev->dev, ctl_port[0], 1);
0168     iomap[2] = devm_ioport_map(&pdev->dev, cmd_port[1], 8);
0169     iomap[3] = devm_ioport_map(&pdev->dev, ctl_port[1], 1);
0170     iomap[4] = pcim_iomap(pdev, 2, 0);
0171 
0172     if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
0173         return -ENOMEM;
0174 
0175     ioaddr = &host->ports[0]->ioaddr;
0176     ioaddr->cmd_addr = iomap[0];
0177     ioaddr->ctl_addr = iomap[1];
0178     ioaddr->altstatus_addr = iomap[1];
0179     ioaddr->bmdma_addr = iomap[4];
0180     ata_sff_std_ports(ioaddr);
0181 
0182     ata_port_desc(host->ports[0],
0183               "cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
0184     ata_port_pbar_desc(host->ports[0], 4, 0, "bmdma");
0185 
0186     ioaddr = &host->ports[1]->ioaddr;
0187     ioaddr->cmd_addr = iomap[2];
0188     ioaddr->ctl_addr = iomap[3];
0189     ioaddr->altstatus_addr = iomap[3];
0190     ioaddr->bmdma_addr = iomap[4] + 8;
0191     ata_sff_std_ports(ioaddr);
0192 
0193     ata_port_desc(host->ports[1],
0194               "cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
0195     ata_port_pbar_desc(host->ports[1], 4, 8, "bmdma");
0196 
0197     /* activate the host */
0198     pci_set_master(pdev);
0199     rc = ata_host_start(host);
0200     if (rc)
0201         return rc;
0202 
0203     for (i = 0; i < 2; i++) {
0204         static const int irq[] = { 14, 15 };
0205         struct ata_port *ap = host->ports[i];
0206 
0207         if (ata_port_is_dummy(ap))
0208             continue;
0209 
0210         rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
0211                       ata_bmdma_interrupt, 0, DRV_NAME, host);
0212         if (rc)
0213             return rc;
0214 
0215         ata_port_desc(ap, "irq %d", irq[i]);
0216     }
0217 
0218     return ata_host_register(host, &cs5520_sht);
0219 }
0220 
0221 #ifdef CONFIG_PM_SLEEP
0222 /**
0223  *  cs5520_reinit_one   -   device resume
0224  *  @pdev: PCI device
0225  *
0226  *  Do any reconfiguration work needed by a resume from RAM. We need
0227  *  to restore DMA mode support on BIOSen which disabled it
0228  */
0229 
0230 static int cs5520_reinit_one(struct pci_dev *pdev)
0231 {
0232     struct ata_host *host = pci_get_drvdata(pdev);
0233     u8 pcicfg;
0234     int rc;
0235 
0236     rc = ata_pci_device_do_resume(pdev);
0237     if (rc)
0238         return rc;
0239 
0240     pci_read_config_byte(pdev, 0x60, &pcicfg);
0241     if ((pcicfg & 0x40) == 0)
0242         pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
0243 
0244     ata_host_resume(host);
0245     return 0;
0246 }
0247 
0248 /**
0249  *  cs5520_pci_device_suspend   -   device suspend
0250  *  @pdev: PCI device
0251  *  @mesg: PM event message
0252  *
0253  *  We have to cut and waste bits from the standard method because
0254  *  the 5520 is a bit odd and not just a pure ATA device. As a result
0255  *  we must not disable it. The needed code is short and this avoids
0256  *  chip specific mess in the core code.
0257  */
0258 
0259 static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
0260 {
0261     struct ata_host *host = pci_get_drvdata(pdev);
0262 
0263     ata_host_suspend(host, mesg);
0264 
0265     pci_save_state(pdev);
0266     return 0;
0267 }
0268 #endif /* CONFIG_PM_SLEEP */
0269 
0270 /* For now keep DMA off. We can set it for all but A rev CS5510 once the
0271    core ATA code can handle it */
0272 
0273 static const struct pci_device_id pata_cs5520[] = {
0274     { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
0275     { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
0276 
0277     { },
0278 };
0279 
0280 static struct pci_driver cs5520_pci_driver = {
0281     .name       = DRV_NAME,
0282     .id_table   = pata_cs5520,
0283     .probe      = cs5520_init_one,
0284     .remove     = ata_pci_remove_one,
0285 #ifdef CONFIG_PM_SLEEP
0286     .suspend    = cs5520_pci_device_suspend,
0287     .resume     = cs5520_reinit_one,
0288 #endif
0289 };
0290 
0291 module_pci_driver(cs5520_pci_driver);
0292 
0293 MODULE_AUTHOR("Alan Cox");
0294 MODULE_DESCRIPTION("low-level driver for Cyrix CS5510/5520");
0295 MODULE_LICENSE("GPL");
0296 MODULE_DEVICE_TABLE(pci, pata_cs5520);
0297 MODULE_VERSION(DRV_VERSION);