^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * IDE tuning and bus mastering support for the CS5510/CS5520
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * chipsets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * The CS5510/CS5520 are slightly unusual devices. Unlike the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * typical IDE controllers they do bus mastering with the drive in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * PIO mode and smarter silicon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The practical upshot of this is that we must always tune the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * drive for the right PIO mode. We must also ignore all the blacklists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * and the drive bus mastering DMA information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * *** This driver is strictly experimental ***
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * (c) Copyright Red Hat Inc 2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * under the terms of the GNU General Public License as published by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Free Software Foundation; either version 2, or (at your option) any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * For the avoidance of doubt the "preferred form" of this code is one which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * is in an open non patent encumbered format. Where cryptographic key signing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * forms part of the process of creating an executable the information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * including keys needed to generate an equivalently functional executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * are deemed to be part of the source code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/ide.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DRV_NAME "cs5520"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct pio_clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int assert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int recovery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static struct pio_clocks cs5520_pio_clocks[]={
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {3, 6, 11},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {2, 5, 6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {1, 4, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {1, 3, 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {1, 2, 1}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static void cs5520_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct pci_dev *pdev = to_pci_dev(hwif->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int controller = drive->dn > 1 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const u8 pio = drive->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* 8bit CAT/CRT - 8bit command timing for channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) pci_write_config_byte(pdev, 0x62 + controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) (cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* 0x64 - 16bit Primary, 0x68 - 16bit Secondary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* FIXME: should these use address ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Data read timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) (cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Write command timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) (cs5520_pio_clocks[pio].recovery << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) (cs5520_pio_clocks[pio].assert));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static void cs5520_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) printk(KERN_ERR "cs55x0: bad ide timing.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) drive->pio_mode = XFER_PIO_0 + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) cs5520_set_pio_mode(hwif, drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static const struct ide_port_ops cs5520_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .set_pio_mode = cs5520_set_pio_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .set_dma_mode = cs5520_set_dma_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct ide_port_info cyrix_chipset = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .port_ops = &cs5520_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_CS5520,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .pio_mask = ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * The 5510/5520 are a bit weird. They don't quite set up the way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * the PCI helper layer expects so we must do much of the set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * work longhand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const struct ide_port_info *d = &cyrix_chipset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct ide_hw hw[2], *hws[] = { NULL, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ide_setup_pci_noise(dev, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* We must not grab the entire device, it has 'ISA' space in its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * BARS too and we will freak out other bits of the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (pci_enable_device_io(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pci_set_master(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (dma_set_mask(&dev->dev, DMA_BIT_MASK(32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) printk(KERN_WARNING "%s: No suitable DMA available.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) d->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Now the chipset is configured we can let the core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * do all the device setup for us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) hw[0].irq = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) hw[1].irq = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ide_host_add(d, hws, 2, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const struct pci_device_id cs5520_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static struct pci_driver cs5520_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .name = "Cyrix_IDE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .id_table = cs5520_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .probe = cs5520_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .suspend = ide_pci_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .resume = ide_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static int __init cs5520_ide_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ide_pci_register_driver(&cs5520_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) module_init(cs5520_ide_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) MODULE_AUTHOR("Alan Cox");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) MODULE_LICENSE("GPL");