diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2018-12-15 23:46:48 +0100 |
---|---|---|
committer | Nico Huber <nico.h@gmx.de> | 2019-01-08 14:29:13 +0000 |
commit | 6267f5dd11aa43fd0bd84f84192db4ddaffa8575 (patch) | |
tree | 75ee8cc7fce69523e4fde510ec3330823807a40a /src/southbridge/intel/i82801gx | |
parent | 79a7ad6dda8a5a4272b6a59cef750af2f2585dc2 (diff) |
sb/intel/i82801gx: Autodisable functions based on devicetree
This removes the need to synchronize the devicetree and the romstage
writing to FD.
Change-Id: I83576599538a02d295fe00b35826f98d8c97d1cf
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/30244
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/southbridge/intel/i82801gx')
-rw-r--r-- | src/southbridge/intel/i82801gx/i82801gx.c | 80 | ||||
-rw-r--r-- | src/southbridge/intel/i82801gx/i82801gx.h | 15 |
2 files changed, 83 insertions, 12 deletions
diff --git a/src/southbridge/intel/i82801gx/i82801gx.c b/src/southbridge/intel/i82801gx/i82801gx.c index eb0583feed..a93d913a6d 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.c +++ b/src/southbridge/intel/i82801gx/i82801gx.c @@ -20,22 +20,86 @@ #include "i82801gx.h" #include "sata.h" +static void ich_hide_devfn(unsigned int devfn) +{ + switch (devfn) { + case PCI_DEVFN(27, 0): /* HD Audio Controller */ + RCBA32_OR(FD, FD_HDAUD); + break; + case PCI_DEVFN(28, 0): /* PCI Express Root Port 1 */ + case PCI_DEVFN(28, 1): /* PCI Express Root Port 2 */ + case PCI_DEVFN(28, 2): /* PCI Express Root Port 3 */ + case PCI_DEVFN(28, 3): /* PCI Express Root Port 4 */ + case PCI_DEVFN(28, 4): /* PCI Express Root Port 5 */ + case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */ + RCBA32_OR(FD, ICH_DISABLE_PCIE(PCI_FUNC(devfn))); + break; + case PCI_DEVFN(29, 0): /* UHCI #1 */ + case PCI_DEVFN(29, 1): /* UHCI #2 */ + case PCI_DEVFN(29, 2): /* UHCI #3 */ + case PCI_DEVFN(29, 3): /* UHCI #4 */ + RCBA32_OR(FD, ICH_DISABLE_UHCI(PCI_FUNC(devfn))); + break; + case PCI_DEVFN(29, 7): /* EHCI #1 */ + RCBA32_OR(FD, FD_EHCI); + break; + case PCI_DEVFN(30, 2): /* AC Audio */ + RCBA32_OR(FD, FD_ACAUD); + break; + case PCI_DEVFN(30, 3): /* AC Modem */ + RCBA32_OR(FD, FD_ACMOD); + break; + case PCI_DEVFN(31, 0): /* LPC */ + RCBA32_OR(FD, FD_LPCB); + break; + case PCI_DEVFN(31, 1): /* PATA #1 */ + RCBA32_OR(FD, FD_PATA); + break; + case PCI_DEVFN(31, 2): /* SATA #1 */ + RCBA32_OR(FD, FD_SATA); + break; + case PCI_DEVFN(31, 3): /* SMBUS */ + RCBA32_OR(FD, FD_SMBUS); + break; + } +} + void i82801gx_enable(struct device *dev) { u32 reg32; - /* Enable SERR */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 |= PCI_COMMAND_SERR; - pci_write_config32(dev, PCI_COMMAND, reg32); + if (!dev->enabled) { + printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev)); + + /* Ensure memory, io, and bus master are all disabled */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | PCI_COMMAND_IO); + pci_write_config32(dev, PCI_COMMAND, reg32); - if (dev->path.pci.devfn == PCI_DEVFN(31, 2)) { - printk(BIOS_DEBUG, "Set SATA mode early\n"); - sata_enable(dev); + /* Hide this device if possible */ + ich_hide_devfn(dev->path.pci.devfn); + } else { + /* Enable SERR */ + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_SERR; + pci_write_config32(dev, PCI_COMMAND, reg32); + + if (dev->path.pci.devfn == PCI_DEVFN(31, 2)) { + printk(BIOS_DEBUG, "Set SATA mode early\n"); + sata_enable(dev); + } } } +static void i82801gx_init(void *chip_info) +{ + /* Disable performance counter */ + RCBA32_OR(FD, 1); +} + struct chip_operations southbridge_intel_i82801gx_ops = { CHIP_NAME("Intel ICH7/ICH7-M (82801Gx) Series Southbridge") - .enable_dev = i82801gx_enable, + .enable_dev = i82801gx_enable, + .init = i82801gx_init, }; diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index 29c8736552..9fd9fd6273 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -68,6 +68,8 @@ int southbridge_detect_s3_resume(void); #define SEE (1 << 1) #define PERE (1 << 0) +#define ICH_PCIE_DEV_SLOT 28 + /* PCI Configuration Space (D31:F0): LPC */ #define SERIRQ_CNTL 0x64 @@ -227,6 +229,13 @@ int southbridge_detect_s3_resume(void); #define RPC 0x0224 /* 32bit */ #define RPFN 0x0238 /* 32bit */ +/* Get the function number assigned to a Root Port */ +#define RPFN_FNGET(reg, port) (((reg) >> ((port) * 4)) & 7) +/* Set the function number for a Root Port */ +#define RPFN_FNSET(port, func) (((func) & 7) << ((port) * 4)) +/* Root Port function number mask */ +#define RPFN_FNMASK(port) (7 << ((port) * 4)) + #define TRSR 0x1e00 /* 8bit */ #define TRCR 0x1e10 /* 64bit */ #define TWDR 0x1e18 /* 64bit */ @@ -269,16 +278,14 @@ int southbridge_detect_s3_resume(void); #define FD_PCIE3 (1 << 18) #define FD_PCIE2 (1 << 17) #define FD_PCIE1 (1 << 16) +#define ICH_DISABLE_PCIE(x) (1 << (16 + (x))) #define FD_EHCI (1 << 15) #define FD_LPCB (1 << 14) /* UHCI must be disabled from 4 downwards. * If UHCI controllers get disabled, EHCI * must know about it, too! */ -#define FD_UHCI4 (1 << 11) -#define FD_UHCI34 ((1 << 10) | FD_UHCI4) -#define FD_UHCI234 ((1 << 9) | FD_UHCI3) -#define FD_UHCI1234 ((1 << 8) | FD_UHCI2) +#define ICH_DISABLE_UHCI(x) (1 << (8 + (x))) #define FD_INTLAN (1 << 7) #define FD_ACMOD (1 << 6) |