| #include <console/console.h> |
| #include <device/device.h> |
| #include <device/pci.h> |
| #include <device/pci_ops.h> |
| #include <device/pci_ids.h> |
| #include "chip.h" |
| |
| static void ide_init(struct device *dev) |
| { |
| struct southbridge_via_vt8231_config *conf = (struct southbridge_via_vt8231_config *)dev->chip_info; |
| unsigned char enables; |
| |
| if (!conf->enable_native_ide) { |
| // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI |
| // interrupts. Using PCI ints confuses linux for some reason. |
| /* Setting reg 0x42 here does not work. It is set in mainboard/romstage.c |
| * It probably can only be changed while the IDE is disabled |
| * or it is possibly a timing issue. Ben Hewson 29 Apr 2007. |
| */ |
| |
| /* |
| printk(BIOS_INFO, "%s: enabling compatibility IDE addresses\n", __func__); |
| enables = pci_read_config8(dev, 0x42); |
| printk(BIOS_DEBUG, "enables in reg 0x42 0x%x\n", enables); |
| enables &= ~0xc0; // compatability mode |
| pci_write_config8(dev, 0x42, enables); |
| enables = pci_read_config8(dev, 0x42); |
| printk(BIOS_DEBUG, "enables in reg 0x42 read back as 0x%x\n", enables); |
| */ |
| } |
| |
| enables = pci_read_config8(dev, 0x40); |
| printk(BIOS_DEBUG, "enables in reg 0x40 0x%x\n", enables); |
| enables |= 3; |
| pci_write_config8(dev, 0x40, enables); |
| enables = pci_read_config8(dev, 0x40); |
| printk(BIOS_DEBUG, "enables in reg 0x40 read back as 0x%x\n", enables); |
| |
| // Enable prefetch buffers |
| enables = pci_read_config8(dev, 0x41); |
| enables |= 0xf0; |
| pci_write_config8(dev, 0x41, enables); |
| |
| // Lower thresholds (cause award does it) |
| enables = pci_read_config8(dev, 0x43); |
| enables &= ~0x0f; |
| enables |= 0x05; |
| pci_write_config8(dev, 0x43, enables); |
| |
| // PIO read prefetch counter (cause award does it) |
| pci_write_config8(dev, 0x44, 0x18); |
| |
| // Use memory read multiple |
| pci_write_config8(dev, 0x45, 0x1c); |
| |
| // address decoding. |
| // we want "flexible", i.e. 1f0-1f7 etc. or native PCI |
| // kevinh@ispiri.com - the standard linux drivers seem ass slow when |
| // used in native mode - I've changed back to classic |
| enables = pci_read_config8(dev, 0x9); |
| printk(BIOS_DEBUG, "enables in reg 0x9 0x%x\n", enables); |
| // by the book, set the low-order nibble to 0xa. |
| if (conf->enable_native_ide) { |
| enables &= ~0xf; |
| // cf/cg silicon needs an 'f' here. |
| enables |= 0xf; |
| } else { |
| enables &= ~0x5; |
| } |
| |
| pci_write_config8(dev, 0x9, enables); |
| enables = pci_read_config8(dev, 0x9); |
| printk(BIOS_DEBUG, "enables in reg 0x9 read back as 0x%x\n", enables); |
| |
| // standard bios sets master bit. |
| enables = pci_read_config8(dev, 0x4); |
| printk(BIOS_DEBUG, "command in reg 0x4 0x%x\n", enables); |
| enables |= 7; |
| |
| // No need for stepping - kevinh@ispiri.com |
| enables &= ~0x80; |
| |
| pci_write_config8(dev, 0x4, enables); |
| enables = pci_read_config8(dev, 0x4); |
| printk(BIOS_DEBUG, "command in reg 0x4 reads back as 0x%x\n", enables); |
| |
| if (!conf->enable_native_ide) { |
| // Use compatability mode - per award bios |
| pci_write_config32(dev, 0x10, 0x0); |
| pci_write_config32(dev, 0x14, 0x0); |
| pci_write_config32(dev, 0x18, 0x0); |
| pci_write_config32(dev, 0x1c, 0x0); |
| |
| // Force interrupts to use compat mode - just like Award bios |
| pci_write_config8(dev, 0x3d, 00); |
| pci_write_config8(dev, 0x3c, 0xff); |
| } |
| } |
| |
| static struct device_operations ide_ops = { |
| .read_resources = pci_dev_read_resources, |
| .set_resources = pci_dev_set_resources, |
| .enable_resources = pci_dev_enable_resources, |
| .init = ide_init, |
| .enable = 0, |
| .ops_pci = 0, |
| }; |
| |
| static const struct pci_driver northbridge_driver __pci_driver = { |
| .ops = &ide_ops, |
| .vendor = PCI_VENDOR_ID_VIA, |
| .device = PCI_DEVICE_ID_VIA_82C586_1, |
| }; |