summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/southbridge/intel/lynxpoint/lp_gpio.c38
-rw-r--r--src/southbridge/intel/lynxpoint/lp_gpio.h11
-rw-r--r--src/southbridge/intel/lynxpoint/lpc.c5
3 files changed, 54 insertions, 0 deletions
diff --git a/src/southbridge/intel/lynxpoint/lp_gpio.c b/src/southbridge/intel/lynxpoint/lp_gpio.c
index b90e5ba4b8..7d1a28d73c 100644
--- a/src/southbridge/intel/lynxpoint/lp_gpio.c
+++ b/src/southbridge/intel/lynxpoint/lp_gpio.c
@@ -36,6 +36,35 @@ static u16 get_gpio_base(void)
#endif
}
+
+/*
+ * This function will return a number that indicates which PIRQ
+ * this GPIO maps to. If this is not a PIRQ capable GPIO then
+ * it will return -1. The GPIO to PIRQ mapping is not linear.
+ */
+static int lp_gpio_to_pirq(int gpio)
+{
+ switch (gpio) {
+ case 8: return 0; /* PIRQI */
+ case 9: return 1; /* PIRQJ */
+ case 10: return 2; /* PIRQK */
+ case 13: return 3; /* PIRQL */
+ case 14: return 4; /* PIRQM */
+ case 45: return 5; /* PIRQN */
+ case 46: return 6; /* PIRQO */
+ case 47: return 7; /* PIRQP */
+ case 48: return 8; /* PIRQQ */
+ case 49: return 9; /* PIRQR */
+ case 50: return 10; /* PIRQS */
+ case 51: return 11; /* PIRQT */
+ case 52: return 12; /* PIRQU */
+ case 53: return 13; /* PIRQV */
+ case 54: return 14; /* PIRQW */
+ case 55: return 15; /* PIRQX */
+ default: return -1;
+ };
+}
+
void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
{
u16 gpio_base = get_gpio_base();
@@ -45,6 +74,7 @@ void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
u32 irqen[3] = {0};
u32 reset[3] = {0};
u32 blink = 0;
+ u16 pirq2apic = 0;
int set, bit, gpio = 0;
for (config = map; config->conf0 != GPIO_LIST_END; config++, gpio++) {
@@ -67,6 +97,13 @@ void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
if (set == 0)
blink |= config->blink << bit;
+
+ /* PIRQ to IO-APIC map */
+ if (config->pirq == GPIO_PIRQ_APIC_ROUTE) {
+ set = lp_gpio_to_pirq(gpio);
+ if (set >= 0)
+ pirq2apic |= 1 << set;
+ }
}
for (set = 0; set <= 2; set++) {
@@ -77,6 +114,7 @@ void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
}
outl(blink, gpio_base + GPIO_BLINK);
+ outl(pirq2apic, gpio_base + GPIO_PIRQ_APIC_EN);
}
int get_gpio(int gpio_num)
diff --git a/src/southbridge/intel/lynxpoint/lp_gpio.h b/src/southbridge/intel/lynxpoint/lp_gpio.h
index d9927dc975..f1b2717423 100644
--- a/src/southbridge/intel/lynxpoint/lp_gpio.h
+++ b/src/southbridge/intel/lynxpoint/lp_gpio.h
@@ -93,6 +93,11 @@
#define GPIO_RESET_PWROK 0
#define GPIO_RESET_RSMRST 1
+/* pirq route to io-apic */
+
+#define GPIO_PIRQ_APIC_MASK 0
+#define GPIO_PIRQ_APIC_ROUTE 1
+
#define LP_GPIO_END \
{ .conf0 = GPIO_LIST_END }
@@ -128,6 +133,11 @@
.owner = GPIO_OWNER_GPIO, \
.irqen = GPIO_IRQ_ENABLE }
+#define LP_GPIO_PIRQ \
+ { .conf0 = GPIO_MODE_GPIO | GPIO_DIR_INPUT, \
+ .owner = GPIO_OWNER_GPIO, \
+ .pirq = GPIO_PIRQ_APIC_ROUTE }
+
#define LP_GPIO_OUT_HIGH \
{ .conf0 = GPIO_MODE_GPIO | GPIO_DIR_OUTPUT | GPO_LEVEL_HIGH, \
.owner = GPIO_OWNER_GPIO, \
@@ -147,6 +157,7 @@ struct pch_lp_gpio_map {
u8 irqen;
u8 reset;
u8 blink;
+ u8 pirq;
} __attribute__ ((packed));
/* Configure GPIOs with mainboard provided settings */
diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c
index 33d74f1903..ff50476a62 100644
--- a/src/southbridge/intel/lynxpoint/lpc.c
+++ b/src/southbridge/intel/lynxpoint/lpc.c
@@ -59,6 +59,11 @@ static void pch_enable_ioapic(struct device *dev)
/* affirm full set of redirection table entries ("write once") */
reg32 = io_apic_read(IO_APIC_ADDR, 0x01);
+ if (pch_is_lp()) {
+ /* PCH-LP has 39 redirection entries */
+ reg32 &= ~0x00ff0000;
+ reg32 |= 0x00270000;
+ }
io_apic_write(IO_APIC_ADDR, 0x01, reg32);
/*