static u8 sil_pata_udma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc, mask = 0; base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A; scsc = sil_ioread8(dev, base); switch (scsc & 0x30) { case 0x10: mask = ATA_UDMA6; break; case 0x20: mask = ATA_UDMA6; break; case 0x00: mask = ATA_UDMA5; break; default: BUG(); } return mask; }
static u8 sil_pata_udma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long base = (unsigned long)hwif->hwif_data; u8 scsc, mask = 0; scsc = sil_ioread8(dev, base + (hwif->mmio ? 0x4A : 0x8A)); switch (scsc & 0x30) { case 0x10: /* 133 */ mask = ATA_UDMA6; break; case 0x20: /* 2xPCI */ mask = ATA_UDMA6; break; case 0x00: /* 100 */ mask = ATA_UDMA5; break; default: /* Disabled ? */ BUG(); } return mask; }
static u8 sil_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long addr = siimage_selreg(hwif, 0); u8 ata66 = sil_ioread8(dev, addr); return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40; }
static int sil_test_irq(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long addr = siimage_selreg(hwif, 1); u8 val = sil_ioread8(dev, addr); return (val & 8) ? 1 : 0; }
static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long base = (unsigned long)hwif->hwif_data; u16 ultra = 0, multi = 0; u8 mode = 0, unit = drive->dn & 1; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); unsigned long ma = siimage_seldev(drive, 0x08); unsigned long ua = siimage_seldev(drive, 0x0C); const u8 speed = drive->dma_mode; scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A)); mode = sil_ioread8 (dev, base + addr_mask); multi = sil_ioread16(dev, ma); ultra = sil_ioread16(dev, ua); mode &= ~(unit ? 0x30 : 0x03); ultra &= ~0x3F; scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; scsc = is_sata(hwif) ? 1 : scsc; if (speed >= XFER_UDMA_0) { multi = dma[2]; ultra |= scsc ? ultra6[speed - XFER_UDMA_0] : ultra5[speed - XFER_UDMA_0]; mode |= unit ? 0x30 : 0x03; } else { multi = dma[speed - XFER_MW_DMA_0]; mode |= unit ? 0x20 : 0x02; } sil_iowrite8 (dev, mode, base + addr_mask); sil_iowrite16(dev, multi, ma); sil_iowrite16(dev, ultra, ua); }
static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; struct pci_dev *dev = to_pci_dev(hwif->dev); ide_drive_t *pair = ide_get_pair_dev(drive); u32 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); unsigned long tfaddr = siimage_selreg(hwif, 0x02); unsigned long base = (unsigned long)hwif->hwif_data; const u8 pio = drive->pio_mode - XFER_PIO_0; u8 tf_pio = pio; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); u8 mode = 0; u8 unit = drive->dn & 1; if (pair) { u8 pair_pio = pair->pio_mode - XFER_PIO_0; if (pair_pio < tf_pio) tf_pio = pair_pio; } speedp = data_speed[pio]; speedt = tf_speed[tf_pio]; sil_iowrite16(dev, speedp, addr); sil_iowrite16(dev, speedt, tfaddr); speedp = sil_ioread16(dev, tfaddr - 2); speedp &= ~0x200; mode = sil_ioread8(dev, base + addr_mask); mode &= ~(unit ? 0x30 : 0x03); if (ide_pio_need_iordy(drive, pio)) { speedp |= 0x200; mode |= unit ? 0x10 : 0x01; } sil_iowrite16(dev, speedp, tfaddr - 2); sil_iowrite8(dev, mode, base + addr_mask); }
static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) { static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); ide_drive_t *pair = ide_get_paired_drive(drive); u32 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); unsigned long tfaddr = siimage_selreg(hwif, 0x02); unsigned long base = (unsigned long)hwif->hwif_data; u8 tf_pio = pio; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84) : (mmio ? 0xB4 : 0x80); u8 mode = 0; u8 unit = drive->select.b.unit; /* trim *taskfile* PIO to the slowest of the master/slave */ if (pair->present) { u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4); if (pair_pio < tf_pio) tf_pio = pair_pio; } /* cheat for now and use the docs */ speedp = data_speed[pio]; speedt = tf_speed[tf_pio]; sil_iowrite16(dev, speedp, addr); sil_iowrite16(dev, speedt, tfaddr); /* now set up IORDY */ speedp = sil_ioread16(dev, tfaddr - 2); speedp &= ~0x200; if (pio > 2) speedp |= 0x200; sil_iowrite16(dev, speedp, tfaddr - 2); mode = sil_ioread8(dev, base + addr_mask); mode &= ~(unit ? 0x30 : 0x03); mode |= unit ? 0x10 : 0x01; sil_iowrite8(dev, mode, base + addr_mask); }
static int init_chipset_siimage(struct pci_dev *dev) { struct ide_host *host = pci_get_drvdata(dev); void __iomem *ioaddr = host->host_priv; unsigned long base, scsc_addr; u8 rev = dev->revision, tmp; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255); if (ioaddr) pci_set_master(dev); base = (unsigned long)ioaddr; if (ioaddr && pdev_is_sata(dev)) { u32 tmp32, irq_mask; irq_mask = (1 << 22) | (1 << 23); tmp32 = readl(ioaddr + 0x48); if (tmp32 & irq_mask) { tmp32 &= ~irq_mask; writel(tmp32, ioaddr + 0x48); readl(ioaddr + 0x48); } writel(0, ioaddr + 0x148); writel(0, ioaddr + 0x1C8); } sil_iowrite8(dev, 0, base ? (base + 0xB4) : 0x80); sil_iowrite8(dev, 0, base ? (base + 0xF4) : 0x84); scsc_addr = base ? (base + 0x4A) : 0x8A; tmp = sil_ioread8(dev, scsc_addr); switch (tmp & 0x30) { case 0x00: sil_iowrite8(dev, tmp | 0x10, scsc_addr); break; case 0x30: sil_iowrite8(dev, tmp & ~0x20, scsc_addr); case 0x10: break; case 0x20: break; } tmp = sil_ioread8(dev, scsc_addr); sil_iowrite8 (dev, 0x72, base + 0xA1); sil_iowrite16(dev, 0x328A, base + 0xA2); sil_iowrite32(dev, 0x62DD62DD, base + 0xA4); sil_iowrite32(dev, 0x43924392, base + 0xA8); sil_iowrite32(dev, 0x40094009, base + 0xAC); sil_iowrite8 (dev, 0x72, base ? (base + 0xE1) : 0xB1); sil_iowrite16(dev, 0x328A, base ? (base + 0xE2) : 0xB2); sil_iowrite32(dev, 0x62DD62DD, base ? (base + 0xE4) : 0xB4); sil_iowrite32(dev, 0x43924392, base ? (base + 0xE8) : 0xB8); sil_iowrite32(dev, 0x40094009, base ? (base + 0xEC) : 0xBC); if (base && pdev_is_sata(dev)) { writel(0xFFFF0000, ioaddr + 0x108); writel(0xFFFF0000, ioaddr + 0x188); writel(0x00680000, ioaddr + 0x148); writel(0x00680000, ioaddr + 0x1C8); } if (!pdev_is_sata(dev)) { static const char *clk_str[] = { "== 100", "== 133", "== 2X PCI", "DISABLED!" }; tmp >>= 4; printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n", pci_name(dev), clk_str[tmp & 3]); } return 0; }
static int init_chipset_siimage(struct pci_dev *dev) { struct ide_host *host = pci_get_drvdata(dev); void __iomem *ioaddr = host->host_priv; unsigned long base, scsc_addr; u8 rev = dev->revision, tmp; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255); if (ioaddr) pci_set_master(dev); base = (unsigned long)ioaddr; if (ioaddr && pdev_is_sata(dev)) { u32 tmp32, irq_mask; /* make sure IDE0/1 interrupts are not masked */ irq_mask = (1 << 22) | (1 << 23); tmp32 = readl(ioaddr + 0x48); if (tmp32 & irq_mask) { tmp32 &= ~irq_mask; writel(tmp32, ioaddr + 0x48); readl(ioaddr + 0x48); /* flush */ } writel(0, ioaddr + 0x148); writel(0, ioaddr + 0x1C8); } sil_iowrite8(dev, 0, base ? (base + 0xB4) : 0x80); sil_iowrite8(dev, 0, base ? (base + 0xF4) : 0x84); scsc_addr = base ? (base + 0x4A) : 0x8A; tmp = sil_ioread8(dev, scsc_addr); switch (tmp & 0x30) { case 0x00: /* On 100 MHz clocking, try and switch to 133 MHz */ sil_iowrite8(dev, tmp | 0x10, scsc_addr); break; case 0x30: /* Clocking is disabled, attempt to force 133MHz clocking. */ sil_iowrite8(dev, tmp & ~0x20, scsc_addr); case 0x10: /* On 133Mhz clocking. */ break; case 0x20: /* On PCIx2 clocking. */ break; } tmp = sil_ioread8(dev, scsc_addr); sil_iowrite8 (dev, 0x72, base + 0xA1); sil_iowrite16(dev, 0x328A, base + 0xA2); sil_iowrite32(dev, 0x62DD62DD, base + 0xA4); sil_iowrite32(dev, 0x43924392, base + 0xA8); sil_iowrite32(dev, 0x40094009, base + 0xAC); sil_iowrite8 (dev, 0x72, base ? (base + 0xE1) : 0xB1); sil_iowrite16(dev, 0x328A, base ? (base + 0xE2) : 0xB2); sil_iowrite32(dev, 0x62DD62DD, base ? (base + 0xE4) : 0xB4); sil_iowrite32(dev, 0x43924392, base ? (base + 0xE8) : 0xB8); sil_iowrite32(dev, 0x40094009, base ? (base + 0xEC) : 0xBC); if (base && pdev_is_sata(dev)) { writel(0xFFFF0000, ioaddr + 0x108); writel(0xFFFF0000, ioaddr + 0x188); writel(0x00680000, ioaddr + 0x148); writel(0x00680000, ioaddr + 0x1C8); } /* report the clocking mode of the controller */ if (!pdev_is_sata(dev)) { static const char *clk_str[] = { "== 100", "== 133", "== 2X PCI", "DISABLED!" }; tmp >>= 4; printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n", pci_name(dev), clk_str[tmp & 3]); } return 0; }