diff options
Diffstat (limited to 'src/southbridge')
-rw-r--r-- | src/southbridge/intel/lynxpoint/chip.h | 4 | ||||
-rw-r--r-- | src/southbridge/intel/lynxpoint/sata.c | 252 |
2 files changed, 84 insertions, 172 deletions
diff --git a/src/southbridge/intel/lynxpoint/chip.h b/src/southbridge/intel/lynxpoint/chip.h index 40d0460419..89bbb1ce0c 100644 --- a/src/southbridge/intel/lynxpoint/chip.h +++ b/src/southbridge/intel/lynxpoint/chip.h @@ -38,9 +38,7 @@ struct southbridge_intel_lynxpoint_config { uint32_t gpe0_en_4; uint32_t alt_gp_smi_en; - /* IDE configuration */ - uint32_t ide_legacy_combined; - uint32_t sata_ahci; + /* SATA configuration */ uint8_t sata_port_map; uint32_t sata_port0_gen3_tx; uint32_t sata_port1_gen3_tx; diff --git a/src/southbridge/intel/lynxpoint/sata.c b/src/southbridge/intel/lynxpoint/sata.c index e1a2fa5a57..c9c7f2cadb 100644 --- a/src/southbridge/intel/lynxpoint/sata.c +++ b/src/southbridge/intel/lynxpoint/sata.c @@ -29,6 +29,9 @@ static void sata_init(struct device *dev) { u32 reg32; u16 reg16; + + u32 *abar; + /* Get the chip configuration */ config_t *config = dev->chip_info; @@ -44,170 +47,87 @@ static void sata_init(struct device *dev) /* Enable memory space decoding for ABAR */ pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO); - if (config->ide_legacy_combined) { - printk(BIOS_DEBUG, "SATA: Controller in combined mode.\n"); - - /* No AHCI: clear AHCI base */ - pci_write_config32(dev, 0x24, 0); - - /* And without AHCI BAR no memory decoding */ - pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MEMORY); - - pci_write_config8(dev, 0x09, 0x80); - - /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | - IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | - IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | - IDE_PPE0 | IDE_IE0 | IDE_TIME0); - - /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0200); - - /* Set IDE I/O Configuration */ - reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; - pci_write_config32(dev, IDE_CONFIG, reg32); - - /* Port enable */ - reg16 = pci_read_config16(dev, 0x92); - reg16 &= ~0x3f; - reg16 |= config->sata_port_map; - pci_write_config16(dev, 0x92, reg16); - - /* SATA Initialization register */ - pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183); - } else if (config->sata_ahci) { - u32 *abar; - - printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n"); - - /* Set Interrupt Line */ - /* Interrupt Pin is set by D31IP.PIP */ - pci_write_config8(dev, INTR_LN, 0x0a); - - /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | - IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | - IDE_PPE0 | IDE_IE0 | IDE_TIME0); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | - IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS); - - /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0001); - - /* Set IDE I/O Configuration */ - reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; - pci_write_config32(dev, IDE_CONFIG, reg32); - - /* for AHCI, Port Enable is managed in memory mapped space */ - reg16 = pci_read_config16(dev, 0x92); - reg16 &= ~0x3f; - reg16 |= 0x8000 | config->sata_port_map; - pci_write_config16(dev, 0x92, reg16); - udelay(2); - - /* Setup register 98h */ - reg32 = pci_read_config16(dev, 0x98); - reg32 |= 1 << 19; /* BWG step 6 */ - reg32 |= 1 << 22; /* BWG step 5 */ - reg32 &= ~(0x3f << 7); - reg32 |= 0x04 << 7; /* BWG step 7 */ - reg32 |= 1 << 20; /* BWG step 8 */ - reg32 &= ~(0x03 << 5); - reg32 |= 1 << 5; /* BWG step 9 */ - reg32 |= 1 << 18; /* BWG step 10 */ - reg32 |= 1 << 29; /* BWG step 11 */ - if (pch_is_lp()) { - reg32 &= ~((1 << 31) | (1 << 30)); - reg32 |= 1 << 23; - reg32 |= 1 << 24; /* Disable listen mode (hotplug) */ - } - pci_write_config32(dev, 0x98, reg32); - - /* Setup register 9Ch: Disable alternate ID and BWG step 12 */ - pci_write_config16(dev, 0x9c, 1 << 5); - - /* SATA Initialization register */ - reg32 = 0x183; - reg32 |= (config->sata_port_map ^ 0x3f) << 24; - reg32 |= (config->sata_devslp_mux & 1) << 15; - pci_write_config32(dev, 0x94, reg32); - - /* Initialize AHCI memory-mapped space */ - abar = (u32 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5); - printk(BIOS_DEBUG, "ABAR: %p\n", abar); - /* CAP (HBA Capabilities) : enable power management */ - reg32 = read32(abar + 0x00); - reg32 |= 0x0c006000; // set PSC+SSC+SALP+SSS - reg32 &= ~0x00020060; // clear SXS+EMS+PMS - if (pch_is_lp()) - reg32 |= (1 << 18); // SAM: SATA AHCI MODE ONLY - write32(abar + 0x00, reg32); - /* PI (Ports implemented) */ - write32(abar + 0x03, config->sata_port_map); - (void)read32(abar + 0x03); /* Read back 1 */ - (void)read32(abar + 0x03); /* Read back 2 */ - /* CAP2 (HBA Capabilities Extended)*/ - reg32 = read32(abar + 0x09); - /* Enable DEVSLP */ - if (pch_is_lp()) { - if (config->sata_devslp_disable) - reg32 &= ~(1 << 3); - else - reg32 |= (1 << 5)|(1 << 4)|(1 << 3)|(1 << 2); - } else { - reg32 &= ~0x00000002; - } - write32(abar + 0x09, reg32); + printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n"); + + /* Set Interrupt Line */ + /* Interrupt Pin is set by D31IP.PIP */ + pci_write_config8(dev, INTR_LN, 0x0a); + + /* Set timings */ + pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | + IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | + IDE_PPE0 | IDE_IE0 | IDE_TIME0); + pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | + IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS); + + /* Sync DMA */ + pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0); + pci_write_config16(dev, IDE_SDMA_TIM, 0x0001); + + /* Set IDE I/O Configuration */ + reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; + pci_write_config32(dev, IDE_CONFIG, reg32); + + /* for AHCI, Port Enable is managed in memory mapped space */ + reg16 = pci_read_config16(dev, 0x92); + reg16 &= ~0x3f; + reg16 |= 0x8000 | config->sata_port_map; + pci_write_config16(dev, 0x92, reg16); + udelay(2); + + /* Setup register 98h */ + reg32 = pci_read_config16(dev, 0x98); + reg32 |= 1 << 19; /* BWG step 6 */ + reg32 |= 1 << 22; /* BWG step 5 */ + reg32 &= ~(0x3f << 7); + reg32 |= 0x04 << 7; /* BWG step 7 */ + reg32 |= 1 << 20; /* BWG step 8 */ + reg32 &= ~(0x03 << 5); + reg32 |= 1 << 5; /* BWG step 9 */ + reg32 |= 1 << 18; /* BWG step 10 */ + reg32 |= 1 << 29; /* BWG step 11 */ + if (pch_is_lp()) { + reg32 &= ~((1 << 31) | (1 << 30)); + reg32 |= 1 << 23; + reg32 |= 1 << 24; /* Disable listen mode (hotplug) */ + } + pci_write_config32(dev, 0x98, reg32); + + /* Setup register 9Ch: Disable alternate ID and BWG step 12 */ + pci_write_config16(dev, 0x9c, 1 << 5); + + /* SATA Initialization register */ + reg32 = 0x183; + reg32 |= (config->sata_port_map ^ 0x3f) << 24; + reg32 |= (config->sata_devslp_mux & 1) << 15; + pci_write_config32(dev, 0x94, reg32); + + /* Initialize AHCI memory-mapped space */ + abar = (u32 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5); + printk(BIOS_DEBUG, "ABAR: %p\n", abar); + /* CAP (HBA Capabilities) : enable power management */ + reg32 = read32(abar + 0x00); + reg32 |= 0x0c006000; // set PSC+SSC+SALP+SSS + reg32 &= ~0x00020060; // clear SXS+EMS+PMS + if (pch_is_lp()) + reg32 |= (1 << 18); // SAM: SATA AHCI MODE ONLY + write32(abar + 0x00, reg32); + /* PI (Ports implemented) */ + write32(abar + 0x03, config->sata_port_map); + (void)read32(abar + 0x03); /* Read back 1 */ + (void)read32(abar + 0x03); /* Read back 2 */ + /* CAP2 (HBA Capabilities Extended)*/ + reg32 = read32(abar + 0x09); + /* Enable DEVSLP */ + if (pch_is_lp()) { + if (config->sata_devslp_disable) + reg32 &= ~(1 << 3); + else + reg32 |= (1 << 5)|(1 << 4)|(1 << 3)|(1 << 2); } else { - printk(BIOS_DEBUG, "SATA: Controller in plain mode.\n"); - - /* No AHCI: clear AHCI base */ - pci_write_config32(dev, 0x24, 0); - - /* And without AHCI BAR no memory decoding */ - pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MEMORY); - - /* - * Native mode capable on both primary and secondary (0xa) - * or'ed with enabled (0x50) = 0xf - * - * FIXME: Does not match the code. - */ - pci_write_config8(dev, 0x09, 0x8f); - - /* Set Interrupt Line */ - /* Interrupt Pin is set by D31IP.PIP */ - pci_write_config8(dev, INTR_LN, 0xff); - - /* Set timings */ - pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE | - IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS | - IDE_PPE0 | IDE_IE0 | IDE_TIME0); - pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE | - IDE_SITRE | IDE_ISP_3_CLOCKS | - IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0); - - /* Sync DMA */ - pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0); - pci_write_config16(dev, IDE_SDMA_TIM, 0x0201); - - /* Set IDE I/O Configuration */ - reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; - pci_write_config32(dev, IDE_CONFIG, reg32); - - /* Port enable */ - reg16 = pci_read_config16(dev, 0x92); - reg16 &= ~0x3f; - reg16 |= config->sata_port_map; - pci_write_config16(dev, 0x92, reg16); - - /* SATA Initialization register */ - pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183); + reg32 &= ~0x00000002; } + write32(abar + 0x09, reg32); /* Set Gen3 Transmitter settings if needed */ if (config->sata_port0_gen3_tx) @@ -290,7 +210,6 @@ static void sata_enable(struct device *dev) { /* Get the chip configuration */ config_t *config = dev->chip_info; - u16 map = 0; if (!config) return; @@ -299,12 +218,7 @@ static void sata_enable(struct device *dev) * Set SATA controller mode early so the resource allocator can * properly assign IO/Memory resources for the controller. */ - if (config->sata_ahci) - map = 0x0060; - - map |= (config->sata_port_map ^ 0x3f) << 8; - - pci_write_config16(dev, 0x90, map); + pci_write_config16(dev, 0x90, 0x0060 | (config->sata_port_map ^ 0x3f) << 8); } static struct device_operations sata_ops = { |