static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct ata_device *pair = ata_dev_pair(adev); int pio = adev->pio_mode - XFER_PIO_0; int dma = adev->dma_mode - XFER_MW_DMA_0; void __iomem *regio = ap->ioaddr.cmd_addr; u8 addr; static const u8 addr_timing[2][5] = { { 0x30, 0x20, 0x20, 0x10, 0x10 }, { 0x20, 0x20, 0x10, 0x10, 0x10 } }; static const u8 data_rec_timing[2][5] = { { 0x59, 0x46, 0x30, 0x20, 0x20 }, { 0x46, 0x32, 0x20, 0x20, 0x10 } }; static const u8 dma_data_rec_timing[2][3] = { { 0x76, 0x20, 0x20 }, { 0x54, 0x20, 0x10 } }; optidma_unlock(ap); if (mode >= XFER_MW_DMA_0) addr = 0; else addr = addr_timing[pci_clock][pio]; if (pair) { u8 pair_addr; if (pair->dma_mode) pair_addr = 0; else pair_addr = addr_timing[pci_clock][pair->pio_mode - XFER_PIO_0]; if (pair_addr > addr) addr = pair_addr; } iowrite8(adev->devno, regio + MISC_REG); if (mode < XFER_MW_DMA_0) { iowrite8(data_rec_timing[pci_clock][pio], regio + READ_REG); iowrite8(data_rec_timing[pci_clock][pio], regio + WRITE_REG); } else if (mode < XFER_UDMA_0) { iowrite8(dma_data_rec_timing[pci_clock][dma], regio + READ_REG); iowrite8(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG); } iowrite8(addr | adev->devno, regio + MISC_REG); iowrite8(0x85, regio + CNTRL_REG); optidma_lock(ap); }
static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct ata_device *pair = ata_dev_pair(adev); int pio = adev->pio_mode - XFER_PIO_0; int dma = adev->dma_mode - XFER_MW_DMA_0; void __iomem *regio = ap->ioaddr.cmd_addr; u8 addr; /* Address table precomputed with a DCLK of 2 */ static const u8 addr_timing[2][5] = { { 0x30, 0x20, 0x20, 0x10, 0x10 }, { 0x20, 0x20, 0x10, 0x10, 0x10 } }; static const u8 data_rec_timing[2][5] = { { 0x59, 0x46, 0x30, 0x20, 0x20 }, { 0x46, 0x32, 0x20, 0x20, 0x10 } }; static const u8 dma_data_rec_timing[2][3] = { { 0x76, 0x20, 0x20 }, { 0x54, 0x20, 0x10 } }; /* Switch from IDE to control mode */ optidma_unlock(ap); /* * As with many controllers the address setup time is shared * and must suit both devices if present. FIXME: Check if we * need to look at slowest of PIO/DMA mode of either device */ if (mode >= XFER_MW_DMA_0) addr = 0; else addr = addr_timing[pci_clock][pio]; if (pair) { u8 pair_addr; /* Hardware constraint */ if (pair->dma_mode) pair_addr = 0; else pair_addr = addr_timing[pci_clock][pair->pio_mode - XFER_PIO_0]; if (pair_addr > addr) addr = pair_addr; } /* Commence primary programming sequence */ /* First we load the device number into the timing select */ iowrite8(adev->devno, regio + MISC_REG); /* Now we load the data timings into read data/write data */ if (mode < XFER_MW_DMA_0) { iowrite8(data_rec_timing[pci_clock][pio], regio + READ_REG); iowrite8(data_rec_timing[pci_clock][pio], regio + WRITE_REG); } else if (mode < XFER_UDMA_0) { iowrite8(dma_data_rec_timing[pci_clock][dma], regio + READ_REG); iowrite8(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG); } /* Finally we load the address setup into the misc register */ iowrite8(addr | adev->devno, regio + MISC_REG); /* Programming sequence complete, timing 0 dev 0, timing 1 dev 1 */ iowrite8(0x85, regio + CNTRL_REG); /* Switch back to IDE mode */ optidma_lock(ap); /* Note: at this point our programming is incomplete. We are not supposed to program PCI 0x43 "things we hacked onto the chip" until we've done both sets of PIO/DMA timings */ }