From 36fa5b80843d836518eb89f46747e80ed6b5d96f Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Tue, 28 Oct 2014 23:43:20 +0100 Subject: [PATCH] i82801ix,bd82x6x,ibexpeak: rewrite expresscard hotplug This implementation is more compact, unified and works with windows as well. Tested under windows and under Debian GNU/Linux. Change-Id: I585dec12e17e22d829baa3f2dc7aecc174f9d3b5 Signed-off-by: Vladimir Serbinenko Reviewed-on: http://review.coreboot.org/7296 Reviewed-by: Edward O'Callaghan Reviewed-by: Nicolas Reinecke Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t520/acpi/gpe.asl | 13 -- src/mainboard/lenovo/t520/devicetree.cb | 2 + src/mainboard/lenovo/t520/dsdt.asl | 4 - src/mainboard/lenovo/t520/mainboard.c | 8 - src/mainboard/lenovo/t530/acpi/gpe.asl | 13 -- src/mainboard/lenovo/t530/devicetree.cb | 2 + src/mainboard/lenovo/t530/dsdt.asl | 4 - src/mainboard/lenovo/t530/mainboard.c | 8 - src/mainboard/lenovo/x200/acpi/gpe.asl | 14 -- src/mainboard/lenovo/x200/devicetree.cb | 1 + src/mainboard/lenovo/x200/dsdt.asl | 1 - src/mainboard/lenovo/x200/romstage.c | 8 - src/mainboard/lenovo/x201/acpi/gpe.asl | 14 -- src/mainboard/lenovo/x201/devicetree.cb | 2 + src/mainboard/lenovo/x201/dsdt.asl | 1 - src/mainboard/lenovo/x201/mainboard.c | 8 - src/mainboard/lenovo/x220/acpi/gpe.asl | 13 -- src/mainboard/lenovo/x220/devicetree.cb | 2 + src/mainboard/lenovo/x220/dsdt.asl | 4 - src/mainboard/lenovo/x220/mainboard.c | 8 - src/mainboard/lenovo/x230/acpi/gpe.asl | 13 -- src/mainboard/lenovo/x230/devicetree.cb | 2 + src/mainboard/lenovo/x230/dsdt.asl | 4 - src/mainboard/lenovo/x230/mainboard.c | 8 - src/southbridge/intel/bd82x6x/Makefile.inc | 1 + src/southbridge/intel/bd82x6x/acpi/pcie.asl | 21 --- src/southbridge/intel/bd82x6x/chip.h | 2 + src/southbridge/intel/bd82x6x/lpc.c | 10 ++ src/southbridge/intel/bd82x6x/pcie.c | 15 ++ src/southbridge/intel/common/pciehp.c | 175 +++++++++++++++++++ src/southbridge/intel/common/pciehp.h | 2 + src/southbridge/intel/i82801ix/Makefile.inc | 1 + src/southbridge/intel/i82801ix/acpi/pcie.asl | 11 -- src/southbridge/intel/i82801ix/chip.h | 2 + src/southbridge/intel/i82801ix/lpc.c | 10 ++ src/southbridge/intel/i82801ix/pcie.c | 28 ++- src/southbridge/intel/ibexpeak/Makefile.inc | 1 + src/southbridge/intel/ibexpeak/lpc.c | 10 ++ 38 files changed, 267 insertions(+), 179 deletions(-) delete mode 100644 src/mainboard/lenovo/t520/acpi/gpe.asl delete mode 100644 src/mainboard/lenovo/t530/acpi/gpe.asl delete mode 100644 src/mainboard/lenovo/x220/acpi/gpe.asl delete mode 100644 src/mainboard/lenovo/x230/acpi/gpe.asl create mode 100644 src/southbridge/intel/common/pciehp.c create mode 100644 src/southbridge/intel/common/pciehp.h diff --git a/src/mainboard/lenovo/t520/acpi/gpe.asl b/src/mainboard/lenovo/t520/acpi/gpe.asl deleted file mode 100644 index 80bee71109..0000000000 --- a/src/mainboard/lenovo/t520/acpi/gpe.asl +++ /dev/null @@ -1,13 +0,0 @@ - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP04.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP04.HPCS) - If (\_SB.PCI0.RP04.PDC) - { - Store (0x01, \_SB.PCI0.RP04.PDC) - Notify (\_SB.PCI0.RP04, 0x00) - } - } - } diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb index d347e8246d..065261a8c0 100644 --- a/src/mainboard/lenovo/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/devicetree.cb @@ -76,6 +76,8 @@ chip northbridge/intel/sandybridge register "c2_latency" = "101" # c2 not supported register "p_cnt_throttling_supported" = "1" + register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }" + device pci 16.0 on end # Management Engine Interface 1 device pci 16.1 off end device pci 16.2 off end diff --git a/src/mainboard/lenovo/t520/dsdt.asl b/src/mainboard/lenovo/t520/dsdt.asl index b6b4b332b5..85e2b4f9e0 100644 --- a/src/mainboard/lenovo/t520/dsdt.asl +++ b/src/mainboard/lenovo/t520/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP04_IS_EXPRESSCARD 1 #define EC_LENOVO_H8_ME_WORKAROUND 1 #define HAVE_LCD_SCREEN 1 @@ -42,9 +41,6 @@ DefinitionBlock( // global NVS and variables #include - // General Purpose Events - //#include "acpi/gpe.asl" - #include Scope (\_SB) { diff --git a/src/mainboard/lenovo/t520/mainboard.c b/src/mainboard/lenovo/t520/mainboard.c index 387bbe0558..582ef8166d 100644 --- a/src/mainboard/lenovo/t520/mainboard.c +++ b/src/mainboard/lenovo/t520/mainboard.c @@ -53,14 +53,6 @@ static void mainboard_init(device_t dev) RCBA32(0x38c0) = 0x00000007; pc_keyboard_init(); - - /* Enable expresscard hotplug events. */ - pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0xd8, - pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), 0xd8) - | (1 << 30)); - pci_write_config16(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0x42, 0x142); } /* mainboard_enable is executed as first thing after diff --git a/src/mainboard/lenovo/t530/acpi/gpe.asl b/src/mainboard/lenovo/t530/acpi/gpe.asl deleted file mode 100644 index eb489d5c4e..0000000000 --- a/src/mainboard/lenovo/t530/acpi/gpe.asl +++ /dev/null @@ -1,13 +0,0 @@ - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP03.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP03.HPCS) - If (\_SB.PCI0.RP03.PDC) - { - Store (0x01, \_SB.PCI0.RP03.PDC) - Notify (\_SB.PCI0.RP03, 0x00) - } - } - } diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb index 397bb9f5ed..ec3913c5f6 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -75,6 +75,8 @@ chip northbridge/intel/sandybridge register "c2_latency" = "101" # c2 not supported register "p_cnt_throttling_supported" = "1" + register "pcie_hotplug_map" = "{ 0, 0, 1, 0, 0, 0, 0, 0 }" + device pci 14.0 on end # USB 3.0 Controller device pci 16.0 on end # Management Engine Interface 1 device pci 16.1 off end # Management Engine Interface 2 diff --git a/src/mainboard/lenovo/t530/dsdt.asl b/src/mainboard/lenovo/t530/dsdt.asl index c73f795074..85e2b4f9e0 100644 --- a/src/mainboard/lenovo/t530/dsdt.asl +++ b/src/mainboard/lenovo/t530/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP03_IS_EXPRESSCARD 1 #define EC_LENOVO_H8_ME_WORKAROUND 1 #define HAVE_LCD_SCREEN 1 @@ -42,9 +41,6 @@ DefinitionBlock( // global NVS and variables #include - // General Purpose Events - //#include "acpi/gpe.asl" - #include Scope (\_SB) { diff --git a/src/mainboard/lenovo/t530/mainboard.c b/src/mainboard/lenovo/t530/mainboard.c index f8c9daee35..14e19604b8 100644 --- a/src/mainboard/lenovo/t530/mainboard.c +++ b/src/mainboard/lenovo/t530/mainboard.c @@ -56,14 +56,6 @@ static void mainboard_init(device_t dev) connected to anything and hence we don't init it. */ pc_keyboard_init(); - - /* Enable expresscard hotplug events. */ - pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), - 0xd8, - pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), 0xd8) - | (1 << 30)); - pci_write_config16(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), - 0x42, 0x142); } // mainboard_enable is executed as first thing after diff --git a/src/mainboard/lenovo/x200/acpi/gpe.asl b/src/mainboard/lenovo/x200/acpi/gpe.asl index cc6075f223..3120cafe2f 100644 --- a/src/mainboard/lenovo/x200/acpi/gpe.asl +++ b/src/mainboard/lenovo/x200/acpi/gpe.asl @@ -26,18 +26,4 @@ Scope (\_GPE) /* Read EC register to clear wake status */ Store(\_SB.PCI0.LPCB.EC.WAKE, Local0) } - - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP04.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP04.HPCS) - If (\_SB.PCI0.RP04.PDC) - { - Store (0x01, \_SB.PCI0.RP04.PDC) - Notify (\_SB.PCI0.RP04, 0x00) - } - } - } } diff --git a/src/mainboard/lenovo/x200/devicetree.cb b/src/mainboard/lenovo/x200/devicetree.cb index 376273a3f2..acc6c3a742 100644 --- a/src/mainboard/lenovo/x200/devicetree.cb +++ b/src/mainboard/lenovo/x200/devicetree.cb @@ -71,6 +71,7 @@ chip northbridge/intel/gm45 # Set power limits to 10 * 10^0 watts. # Maybe we should set less for Mini PCIe. register "pcie_power_limits" = "{ { 10, 0 }, { 10, 0 }, { 0, 0 }, { 10, 0 }, { 0, 0 }, { 0, 0 } }" + register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }" chip drivers/generic/ioapic register "have_isa_interrupts" = "1" diff --git a/src/mainboard/lenovo/x200/dsdt.asl b/src/mainboard/lenovo/x200/dsdt.asl index eb6ce6dc95..0409e66437 100644 --- a/src/mainboard/lenovo/x200/dsdt.asl +++ b/src/mainboard/lenovo/x200/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP04_IS_EXPRESSCARD 1 #define DISPLAY_DEVICE_2_IS_LCD_SCREEN 1 DefinitionBlock( diff --git a/src/mainboard/lenovo/x200/romstage.c b/src/mainboard/lenovo/x200/romstage.c index dcb4e16415..1c0668fb99 100644 --- a/src/mainboard/lenovo/x200/romstage.c +++ b/src/mainboard/lenovo/x200/romstage.c @@ -77,14 +77,6 @@ void main(unsigned long bist) int cbmem_initted; u16 reg16; - /* Enable expresscard hotplug events. */ - pci_write_config32(PCI_DEV (0, 0x1c, 3), - 0xd8, - pci_read_config32(PCI_DEV (0, 0x1c, 3), 0xd8) - | (1 << 30)); - pci_write_config16(PCI_DEV (0, 0x1c, 3), - 0x42, 0x141); - /* basic northbridge setup, including MMCONF BAR */ gm45_early_init(); diff --git a/src/mainboard/lenovo/x201/acpi/gpe.asl b/src/mainboard/lenovo/x201/acpi/gpe.asl index 2f0ee16695..b160b5015f 100644 --- a/src/mainboard/lenovo/x201/acpi/gpe.asl +++ b/src/mainboard/lenovo/x201/acpi/gpe.asl @@ -27,18 +27,4 @@ Scope (\_GPE) /* Read EC register to clear wake status */ Store(\_SB.PCI0.LPCB.EC.WAKE, Local0) } - - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP04.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP04.HPCS) - If (\_SB.PCI0.RP04.PDC) - { - Store (0x01, \_SB.PCI0.RP04.PDC) - Notify (\_SB.PCI0.RP04, 0x00) - } - } - } } diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb index 3005077979..614245cba9 100644 --- a/src/mainboard/lenovo/x201/devicetree.cb +++ b/src/mainboard/lenovo/x201/devicetree.cb @@ -122,6 +122,8 @@ chip northbridge/intel/nehalem register "c2_latency" = "1" register "docking_supported" = "1" + register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }" + device pci 16.2 on # IDE/SATA subsystemid 0x17aa 0x2161 end diff --git a/src/mainboard/lenovo/x201/dsdt.asl b/src/mainboard/lenovo/x201/dsdt.asl index 62616a8bf5..5265a91fa1 100644 --- a/src/mainboard/lenovo/x201/dsdt.asl +++ b/src/mainboard/lenovo/x201/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP04_IS_EXPRESSCARD 1 #define EC_LENOVO_H8_ME_WORKAROUND 1 #define HAVE_LCD_SCREEN 1 diff --git a/src/mainboard/lenovo/x201/mainboard.c b/src/mainboard/lenovo/x201/mainboard.c index 5b76be2734..a58d41505c 100644 --- a/src/mainboard/lenovo/x201/mainboard.c +++ b/src/mainboard/lenovo/x201/mainboard.c @@ -102,14 +102,6 @@ static void mainboard_init(device_t dev) connected to anything and hence we don't init it. */ pc_keyboard_init(); - - /* Enable expresscard hotplug events. */ - pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0xd8, - pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), 0xd8) - | (1 << 30)); - pci_write_config16(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0x42, 0x142); } static void fill_ssdt(void) diff --git a/src/mainboard/lenovo/x220/acpi/gpe.asl b/src/mainboard/lenovo/x220/acpi/gpe.asl deleted file mode 100644 index 80bee71109..0000000000 --- a/src/mainboard/lenovo/x220/acpi/gpe.asl +++ /dev/null @@ -1,13 +0,0 @@ - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP04.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP04.HPCS) - If (\_SB.PCI0.RP04.PDC) - { - Store (0x01, \_SB.PCI0.RP04.PDC) - Notify (\_SB.PCI0.RP04, 0x00) - } - } - } diff --git a/src/mainboard/lenovo/x220/devicetree.cb b/src/mainboard/lenovo/x220/devicetree.cb index 3edbb87a08..c1bea43e99 100644 --- a/src/mainboard/lenovo/x220/devicetree.cb +++ b/src/mainboard/lenovo/x220/devicetree.cb @@ -74,6 +74,8 @@ chip northbridge/intel/sandybridge register "gen2_dec" = "0x0c15e1" register "gen4_dec" = "0x0c06a1" + register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }" + # Enable zero-based linear PCIe root port functions register "pcie_port_coalesce" = "1" diff --git a/src/mainboard/lenovo/x220/dsdt.asl b/src/mainboard/lenovo/x220/dsdt.asl index b6b4b332b5..85e2b4f9e0 100644 --- a/src/mainboard/lenovo/x220/dsdt.asl +++ b/src/mainboard/lenovo/x220/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP04_IS_EXPRESSCARD 1 #define EC_LENOVO_H8_ME_WORKAROUND 1 #define HAVE_LCD_SCREEN 1 @@ -42,9 +41,6 @@ DefinitionBlock( // global NVS and variables #include - // General Purpose Events - //#include "acpi/gpe.asl" - #include Scope (\_SB) { diff --git a/src/mainboard/lenovo/x220/mainboard.c b/src/mainboard/lenovo/x220/mainboard.c index 00e7991250..2fdc204e4e 100644 --- a/src/mainboard/lenovo/x220/mainboard.c +++ b/src/mainboard/lenovo/x220/mainboard.c @@ -59,14 +59,6 @@ static void mainboard_init(device_t dev) connected to anything and hence we don't init it. */ pc_keyboard_init(); - - /* Enable expresscard hotplug events. */ - pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0xd8, - pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), 0xd8) - | (1 << 30)); - pci_write_config16(dev_find_slot(0, PCI_DEVFN(0x1c, 3)), - 0x42, 0x142); } // mainboard_enable is executed as first thing after diff --git a/src/mainboard/lenovo/x230/acpi/gpe.asl b/src/mainboard/lenovo/x230/acpi/gpe.asl deleted file mode 100644 index eb489d5c4e..0000000000 --- a/src/mainboard/lenovo/x230/acpi/gpe.asl +++ /dev/null @@ -1,13 +0,0 @@ - Method (_L01, 0, NotSerialized) - { - If (\_SB.PCI0.RP03.HPCS) - { - Sleep (100) - Store (0x01, \_SB.PCI0.RP03.HPCS) - If (\_SB.PCI0.RP03.PDC) - { - Store (0x01, \_SB.PCI0.RP03.PDC) - Notify (\_SB.PCI0.RP03, 0x00) - } - } - } diff --git a/src/mainboard/lenovo/x230/devicetree.cb b/src/mainboard/lenovo/x230/devicetree.cb index 256586bf40..c44a2b7a1a 100644 --- a/src/mainboard/lenovo/x230/devicetree.cb +++ b/src/mainboard/lenovo/x230/devicetree.cb @@ -74,6 +74,8 @@ chip northbridge/intel/sandybridge register "gen2_dec" = "0x0c15e1" register "gen4_dec" = "0x0c06a1" + register "pcie_hotplug_map" = "{ 0, 0, 1, 0, 0, 0, 0, 0 }" + # Enable zero-based linear PCIe root port functions register "pcie_port_coalesce" = "1" register "c2_latency" = "101" # c2 not supported diff --git a/src/mainboard/lenovo/x230/dsdt.asl b/src/mainboard/lenovo/x230/dsdt.asl index c73f795074..85e2b4f9e0 100644 --- a/src/mainboard/lenovo/x230/dsdt.asl +++ b/src/mainboard/lenovo/x230/dsdt.asl @@ -23,7 +23,6 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 -#define RP03_IS_EXPRESSCARD 1 #define EC_LENOVO_H8_ME_WORKAROUND 1 #define HAVE_LCD_SCREEN 1 @@ -42,9 +41,6 @@ DefinitionBlock( // global NVS and variables #include - // General Purpose Events - //#include "acpi/gpe.asl" - #include Scope (\_SB) { diff --git a/src/mainboard/lenovo/x230/mainboard.c b/src/mainboard/lenovo/x230/mainboard.c index a060015843..da0aa65a0a 100644 --- a/src/mainboard/lenovo/x230/mainboard.c +++ b/src/mainboard/lenovo/x230/mainboard.c @@ -60,14 +60,6 @@ static void mainboard_init(device_t dev) connected to anything and hence we don't init it. */ pc_keyboard_init(); - - /* Enable expresscard hotplug events. */ - pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), - 0xd8, - pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), 0xd8) - | (1 << 30)); - pci_write_config16(dev_find_slot(0, PCI_DEVFN(0x1c, 2)), - 0x42, 0x142); } // mainboard_enable is executed as first thing after diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index 3d33edcd13..621a74341c 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -33,6 +33,7 @@ ramstage-y += usb_xhci.c ramstage-y += me.c ramstage-y += me_8.x.c ramstage-y += smbus.c +ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c diff --git a/src/southbridge/intel/bd82x6x/acpi/pcie.asl b/src/southbridge/intel/bd82x6x/acpi/pcie.asl index 14ae449e7e..934cf782e9 100644 --- a/src/southbridge/intel/bd82x6x/acpi/pcie.asl +++ b/src/southbridge/intel/bd82x6x/acpi/pcie.asl @@ -155,16 +155,6 @@ Device (RP03) { Return (IRQM (RPPN)) } -#ifdef RP03_IS_EXPRESSCARD - Device (SLOT) - { - Name (_ADR, 0x00) - Method (_RMV, 0, NotSerialized) - { - Return (0x01) - } - } -#endif } Device (RP04) @@ -177,17 +167,6 @@ Device (RP04) { Return (IRQM (RPPN)) } - -#ifdef RP04_IS_EXPRESSCARD - Device (SLOT) - { - Name (_ADR, 0x00) - Method (_RMV, 0, NotSerialized) - { - Return (0x01) - } - } -#endif } Device (RP05) diff --git a/src/southbridge/intel/bd82x6x/chip.h b/src/southbridge/intel/bd82x6x/chip.h index e5da531e75..d4adfd5c9f 100644 --- a/src/southbridge/intel/bd82x6x/chip.h +++ b/src/southbridge/intel/bd82x6x/chip.h @@ -100,6 +100,8 @@ struct southbridge_intel_bd82x6x_config { int p_cnt_throttling_supported; int c2_latency; int docking_supported; + + uint8_t pcie_hotplug_map[8]; }; #endif /* SOUTHBRIDGE_INTEL_BD82X6X_CHIP_H */ diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c index 80d6284629..3c559462ee 100644 --- a/src/southbridge/intel/bd82x6x/lpc.c +++ b/src/southbridge/intel/bd82x6x/lpc.c @@ -38,6 +38,7 @@ #include #include "pch.h" #include "nvs.h" +#include #define NMI_OFF 0 @@ -838,6 +839,14 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } +static void southbridge_fill_ssdt(void) +{ + device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0)); + config_t *chip = dev->chip_info; + + intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8); +} + static struct pci_operations pci_ops = { .set_subsystem = set_subsystem, }; @@ -848,6 +857,7 @@ static struct device_operations device_ops = { .enable_resources = pch_lpc_enable_resources, .write_acpi_tables = acpi_write_hpet, .acpi_inject_dsdt_generator = southbridge_inject_dsdt, + .acpi_fill_ssdt_generator = southbridge_fill_ssdt, .init = lpc_init, .enable = pch_lpc_enable, .scan_bus = scan_static_bus, diff --git a/src/southbridge/intel/bd82x6x/pcie.c b/src/southbridge/intel/bd82x6x/pcie.c index fadb43ff2b..4769dd53d0 100644 --- a/src/southbridge/intel/bd82x6x/pcie.c +++ b/src/southbridge/intel/bd82x6x/pcie.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "pch.h" static void pch_pcie_pm_early(struct device *dev) @@ -218,6 +219,7 @@ static void pci_init(struct device *dev) { u16 reg16; u32 reg32; + struct southbridge_intel_bd82x6x_config *config = dev->chip_info; printk(BIOS_DEBUG, "Initializing PCH PCIe bridge.\n"); @@ -255,6 +257,14 @@ static void pci_init(struct device *dev) reg16 = pci_read_config16(dev, 0x1e); //reg16 |= 0xf900; pci_write_config16(dev, 0x1e, reg16); + + /* Enable expresscard hotplug events. */ + if (config->pcie_hotplug_map[PCI_FUNC(dev->path.pci.devfn)]) { + pci_write_config32(dev, 0xd8, + pci_read_config32(dev, 0xd8) + | (1 << 30)); + pci_write_config16(dev, 0x42, 0x142); + } } static void pch_pcie_enable(device_t dev) @@ -266,10 +276,15 @@ static void pch_pcie_enable(device_t dev) static unsigned int pch_pciexp_scan_bridge(device_t dev, unsigned int max) { unsigned int ret; + struct southbridge_intel_bd82x6x_config *config = dev->chip_info; /* Normal PCIe Scan */ ret = pciexp_scan_bridge(dev, max); + if (config->pcie_hotplug_map[PCI_FUNC(dev->path.pci.devfn)]) { + intel_acpi_pcie_hotplug_scan_slot(dev->link_list); + } + /* Late Power Management init after bridge device enumeration */ pch_pcie_pm_late(dev); diff --git a/src/southbridge/intel/common/pciehp.c b/src/southbridge/intel/common/pciehp.c new file mode 100644 index 0000000000..5327c13923 --- /dev/null +++ b/src/southbridge/intel/common/pciehp.c @@ -0,0 +1,175 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "pciehp.h" + +void intel_acpi_pcie_hotplug_generator(u8 *hotplug_map, int port_number) +{ + int port; + int have_hotplug = 0; + + for (port = 0; port < port_number; port++) { + if (hotplug_map[port]) { + have_hotplug = 1; + } + } + + if (!have_hotplug) { + return; + } + + for (port = 0; port < port_number; port++) { + if (hotplug_map[port]) { + char scope_name[] = "\\_SB.PCI0.RP0x"; + scope_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port; + acpigen_write_scope(scope_name); + + /* + Device (SLOT) + { + Name (_ADR, 0x00) + Method (_RMV, 0, NotSerialized) + { + Return (0x01) + } + } + */ + + acpigen_write_device("SLOT"); + + acpigen_write_name_byte("_ADR", 0x00); + + acpigen_write_method("_RMV", 0); + /* ReturnOp */ + acpigen_emit_byte (0xa4); + /* One */ + acpigen_emit_byte (0x01); + acpigen_pop_len(); + acpigen_pop_len(); + acpigen_pop_len(); + } + } + + /* Method (_L01, 0, NotSerialized) + { + If (\_SB.PCI0.RP04.HPCS) + { + Sleep (100) + Store (0x01, \_SB.PCI0.RP04.HPCS) + If (\_SB.PCI0.RP04.PDC) + { + Store (0x01, \_SB.PCI0.RP04.PDC) + Notify (\_SB.PCI0.RP04, 0x00) + } + } + } + + */ + acpigen_write_scope("\\_GPE"); + acpigen_write_method("_L01", 0); + for (port = 0; port < port_number; port++) { + if (hotplug_map[port]) { + char reg_name[] = "\\_SB.PCI0.RP0x.HPCS"; + reg_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port; + acpigen_emit_byte(0xa0); /* IfOp. */ + acpigen_write_len_f(); + acpigen_emit_namestring(reg_name); + + /* Sleep (100) */ + acpigen_emit_byte(0x5b); /* SleepOp. */ + acpigen_emit_byte(0x22); + acpigen_write_byte(100); + + /* Store (0x01, \_SB.PCI0.RP04.HPCS) */ + acpigen_emit_byte(0x70); + acpigen_emit_byte(0x01); + acpigen_emit_namestring(reg_name); + + memcpy(reg_name + sizeof("\\_SB.PCI0.RP0x.") - 1, "PDC", 4); + + /* If (\_SB.PCI0.RP04.PDC) */ + acpigen_emit_byte(0xa0); /* IfOp. */ + acpigen_write_len_f(); + acpigen_emit_namestring(reg_name); + + /* Store (0x01, \_SB.PCI0.RP04.PDC) */ + acpigen_emit_byte(0x70); + acpigen_emit_byte(0x01); + acpigen_emit_namestring(reg_name); + + reg_name[sizeof("\\_SB.PCI0.RP0x") - 1] = '\0'; + + /* Notify(\_SB.PCI0.RP04, 0x00) */ + acpigen_emit_byte(0x86); + acpigen_emit_namestring(reg_name); + acpigen_emit_byte(0x00); + acpigen_pop_len(); + acpigen_pop_len(); + } + } + acpigen_pop_len(); + acpigen_pop_len(); + +} + +static void slot_dev_read_resources(struct device *dev) +{ + struct resource *resource; + + resource = new_resource(dev, 0x10); + resource->size = 1 << 23; + resource->align = 22; + resource->gran = 22; + resource->limit = 0xffffffff; + resource->flags |= IORESOURCE_MEM; + + resource = new_resource(dev, 0x14); + resource->size = 1 << 23; + resource->align = 22; + resource->gran = 22; + resource->limit = 0xffffffff; + resource->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; + + resource = new_resource(dev, 0x18); + resource->size = 1 << 12; + resource->align = 12; + resource->gran = 12; + resource->limit = 0xffff; + resource->flags |= IORESOURCE_IO; +} + +static struct device_operations slot_dev_ops = { + .read_resources = slot_dev_read_resources, +}; + +/* Add a dummy device to reserve I/O space for hotpluggable devices. */ +void intel_acpi_pcie_hotplug_scan_slot(struct bus *bus) +{ + struct device *slot; + struct device_path slot_path = { .type = DEVICE_PATH_NONE }; + slot = alloc_dev(bus, &slot_path); + slot->ops = &slot_dev_ops; +} diff --git a/src/southbridge/intel/common/pciehp.h b/src/southbridge/intel/common/pciehp.h new file mode 100644 index 0000000000..7bf47f35a0 --- /dev/null +++ b/src/southbridge/intel/common/pciehp.h @@ -0,0 +1,2 @@ +void intel_acpi_pcie_hotplug_generator(u8 *hotplug_map, int port_number); +void intel_acpi_pcie_hotplug_scan_slot(struct bus *bus); diff --git a/src/southbridge/intel/i82801ix/Makefile.inc b/src/southbridge/intel/i82801ix/Makefile.inc index 4117263ee7..a6580c4208 100644 --- a/src/southbridge/intel/i82801ix/Makefile.inc +++ b/src/southbridge/intel/i82801ix/Makefile.inc @@ -27,6 +27,7 @@ ramstage-y += sata.c ramstage-y += hdaudio.c ramstage-y += thermal.c ramstage-y += smbus.c +ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c diff --git a/src/southbridge/intel/i82801ix/acpi/pcie.asl b/src/southbridge/intel/i82801ix/acpi/pcie.asl index f02ad021c6..9233e5fa59 100644 --- a/src/southbridge/intel/i82801ix/acpi/pcie.asl +++ b/src/southbridge/intel/i82801ix/acpi/pcie.asl @@ -127,17 +127,6 @@ Device (RP04) } } - -#ifdef RP04_IS_EXPRESSCARD - Device (SLOT) - { - Name (_ADR, 0x00) - Method (_RMV, 0, NotSerialized) - { - Return (0x01) - } - } -#endif } diff --git a/src/southbridge/intel/i82801ix/chip.h b/src/southbridge/intel/i82801ix/chip.h index 5e1221d28b..b8b58a684b 100644 --- a/src/southbridge/intel/i82801ix/chip.h +++ b/src/southbridge/intel/i82801ix/chip.h @@ -88,6 +88,8 @@ struct southbridge_intel_i82801ix_config { uint8_t value : 8; uint8_t scale : 2; } pcie_power_limits[6]; + + uint8_t pcie_hotplug_map[8]; }; #endif /* SOUTHBRIDGE_INTEL_I82801IX_CHIP_H */ diff --git a/src/southbridge/intel/i82801ix/lpc.c b/src/southbridge/intel/i82801ix/lpc.c index dc2cfe8ed7..e12c724c2d 100644 --- a/src/southbridge/intel/i82801ix/lpc.c +++ b/src/southbridge/intel/i82801ix/lpc.c @@ -36,6 +36,7 @@ #include #include "i82801ix.h" #include "nvs.h" +#include #define NMI_OFF 0 @@ -555,6 +556,14 @@ static void southbridge_inject_dsdt(void) acpigen_pop_len(); } } + +static void southbridge_fill_ssdt(void) +{ + device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0)); + config_t *chip = dev->chip_info; + + intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8); +} #endif static struct pci_operations pci_ops = { @@ -568,6 +577,7 @@ static struct device_operations device_ops = { #if IS_ENABLED(CONFIG_PER_DEVICE_ACPI_TABLES) .acpi_inject_dsdt_generator = southbridge_inject_dsdt, .write_acpi_tables = acpi_write_hpet, + .acpi_fill_ssdt_generator = southbridge_fill_ssdt, #endif .init = lpc_init, .scan_bus = scan_static_bus, diff --git a/src/southbridge/intel/i82801ix/pcie.c b/src/southbridge/intel/i82801ix/pcie.c index 2022dac3e7..7583715add 100644 --- a/src/southbridge/intel/i82801ix/pcie.c +++ b/src/southbridge/intel/i82801ix/pcie.c @@ -24,11 +24,14 @@ #include #include #include +#include +#include "chip.h" static void pci_init(struct device *dev) { u16 reg16; u32 reg32; + struct southbridge_intel_i82801ix_config *config = dev->chip_info; printk(BIOS_DEBUG, "Initializing ICH9 PCIe root port.\n"); @@ -85,6 +88,14 @@ static void pci_init(struct device *dev) reg32 |= (1 << 1); pci_write_config32(dev, 0xe8, reg32); } + + /* Enable expresscard hotplug events. */ + if (config->pcie_hotplug_map[PCI_FUNC(dev->path.pci.devfn)]) { + pci_write_config32(dev, 0xd8, + pci_read_config32(dev, 0xd8) + | (1 << 30)); + pci_write_config16(dev, 0x42, 0x142); + } } static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -99,6 +110,21 @@ static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device) } } +static unsigned int pch_pciexp_scan_bridge(device_t dev, unsigned int max) +{ + unsigned int ret; + struct southbridge_intel_i82801ix_config *config = dev->chip_info; + + /* Normal PCIe Scan */ + ret = pciexp_scan_bridge(dev, max); + + if (config->pcie_hotplug_map[PCI_FUNC(dev->path.pci.devfn)]) { + intel_acpi_pcie_hotplug_scan_slot(dev->link_list); + } + + return ret; +} + static struct pci_operations pci_ops = { .set_subsystem = pcie_set_subsystem, }; @@ -108,7 +134,7 @@ static struct device_operations device_ops = { .set_resources = pci_dev_set_resources, .enable_resources = pci_bus_enable_resources, .init = pci_init, - .scan_bus = pciexp_scan_bridge, + .scan_bus = pch_pciexp_scan_bridge, .ops_pci = &pci_ops, }; diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index 24cbe454a1..2db758a056 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -33,6 +33,7 @@ ramstage-y += me.c ramstage-y += ../bd82x6x/me_8.x.c ramstage-y += smbus.c ramstage-y += thermal.c +ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c diff --git a/src/southbridge/intel/ibexpeak/lpc.c b/src/southbridge/intel/ibexpeak/lpc.c index c094ead557..03b40495e1 100644 --- a/src/southbridge/intel/ibexpeak/lpc.c +++ b/src/southbridge/intel/ibexpeak/lpc.c @@ -38,6 +38,7 @@ #include #include "pch.h" #include "nvs.h" +#include #define NMI_OFF 0 @@ -821,6 +822,14 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } +static void southbridge_fill_ssdt(void) +{ + device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0)); + config_t *chip = dev->chip_info; + + intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8); +} + static struct pci_operations pci_ops = { .set_subsystem = set_subsystem, }; @@ -830,6 +839,7 @@ static struct device_operations device_ops = { .set_resources = pci_dev_set_resources, .enable_resources = pch_lpc_enable_resources, .acpi_inject_dsdt_generator = southbridge_inject_dsdt, + .acpi_fill_ssdt_generator = southbridge_fill_ssdt, .write_acpi_tables = acpi_write_hpet, .init = lpc_init, .enable = pch_lpc_enable,