summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKerry Sheh <shekairui@gmail.com>2011-10-12 11:42:59 +0800
committerMarc Jones <marcj303@gmail.com>2011-10-12 07:43:48 +0200
commit0e6344e1cfe0bad409a4a0bfacbaa92a57440aa7 (patch)
tree7c9535f2cf718113f1d3f9cc57214c6925fa9b67
parent56ed40acb2d76c51c36e2ebbc12cf75b97225ade (diff)
SB800: Sata Enable bus master and enable ahci for AHCI/RAID mode
In order to make sure AHCI/RAID ROM works correctly For SB800_SATA_AHCI or SB800_SATA_RAID mode, SATA should enable bus master and the ahci also should be enabled. Change-Id: I9d9c557816d364d8373fe343860ad5fe45988200 Signed-off-by: Kerry She <kerry.she@amd.com> Signed-off-by: Kerry She <shekairui@gmail.com> Reviewed-on: http://review.coreboot.org/248 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marcj303@gmail.com>
-rw-r--r--src/include/device/pci_ids.h1
-rw-r--r--src/southbridge/amd/cimx/sb800/late.c55
2 files changed, 54 insertions, 2 deletions
diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h
index 390a42a66c..d16f85e4d7 100644
--- a/src/include/device/pci_ids.h
+++ b/src/include/device/pci_ids.h
@@ -15,6 +15,7 @@
#define PCI_CLASS_STORAGE_FLOPPY 0x0102
#define PCI_CLASS_STORAGE_IPI 0x0103
#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_SATA 0x0106
#define PCI_CLASS_STORAGE_OTHER 0x0180
#define PCI_BASE_CLASS_NETWORK 0x02
diff --git a/src/southbridge/amd/cimx/sb800/late.c b/src/southbridge/amd/cimx/sb800/late.c
index b78f1ce726..8c7abdba16 100644
--- a/src/southbridge/amd/cimx/sb800/late.c
+++ b/src/southbridge/amd/cimx/sb800/late.c
@@ -74,6 +74,46 @@ u32 sb800_callout_entry(u32 func, u32 data, void* config)
return ret;
}
+#define HOST_CAP 0x00 /* host capabilities */
+#define HOST_CTL 0x04 /* global host control */
+#define HOST_IRQ_STAT 0x08 /* interrupt status */
+#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
+
+#define HOST_CTL_AHCI_EN (1 << 31) /* AHCI enabled */
+static void ahci_raid_init(struct device *dev)
+{
+ u8 irq = 0;
+ u32 bar5, caps, ports, val;
+
+ val = pci_read_config16(dev, PCI_CLASS_DEVICE);
+ if (val == PCI_CLASS_STORAGE_SATA) {
+ printk(BIOS_DEBUG, "AHCI controller ");
+ } else if (val == PCI_CLASS_STORAGE_RAID) {
+ printk(BIOS_DEBUG, "RAID controller ");
+ } else {
+ printk(BIOS_WARNING, "device class:%x, neither in ahci or raid mode\n", val);
+ return;
+ }
+
+ irq = pci_read_config8(dev, PCI_INTERRUPT_LINE);
+ bar5 = pci_read_config32(dev, PCI_BASE_ADDRESS_5);
+ printk(BIOS_DEBUG, "IOMEM base: 0x%X, IRQ: 0x%X\n", bar5, irq);
+
+ caps = *(volatile u32 *)(bar5 + HOST_CAP);
+ caps = (caps & 0x1F) + 1;
+ ports= *(volatile u32 *)(bar5 + HOST_PORTS_IMPL);
+ printk(BIOS_DEBUG, "Number of Ports: 0x%x, Port implemented(bit map): 0x%x\n", caps, ports);
+
+ /* make sure ahci is enabled */
+ val = *(volatile u32 *)(bar5 + HOST_CTL);
+ if (!(val & HOST_CTL_AHCI_EN)) {
+ *(volatile u32 *)(bar5 + HOST_CTL) = val | HOST_CTL_AHCI_EN;
+ }
+
+ dev->command |= PCI_COMMAND_MASTER;
+ pci_write_config8(dev, PCI_COMMAND, dev->command);
+ printk(BIOS_DEBUG, "AHCI/RAID controller initialized\n");
+}
static struct pci_operations lops_pci = {
.set_subsystem = pci_dev_set_subsystem,
@@ -98,17 +138,28 @@ static struct device_operations sata_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
- .init = 0,
+ .init = ahci_raid_init,
.scan_bus = 0,
.ops_pci = &lops_pci,
};
-static const struct pci_driver sata_driver __pci_driver = {
+static const struct pci_driver ahci_driver __pci_driver = {
.ops = &sata_ops,
.vendor = PCI_VENDOR_ID_ATI,
.device = PCI_DEVICE_ID_ATI_SB800_SATA_AHCI,
};
+static const struct pci_driver raid_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB800_SATA_RAID,
+};
+static const struct pci_driver raid5_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB800_SATA_RAID5,
+};
+
#if CONFIG_USBDEBUG == 1
static void usb_set_resources(struct device *dev)
{