diff --git a/src/soc/intel/broadwell/gpio.c b/src/soc/intel/broadwell/gpio.c index d522d63c24..92699d28bb 100644 --- a/src/soc/intel/broadwell/gpio.c +++ b/src/soc/intel/broadwell/gpio.c @@ -22,27 +22,16 @@ #include #include #include - -#include "pch.h" -#include "lp_gpio.h" - -static u16 get_gpio_base(void) -{ -#if defined(__PRE_RAM__) || defined(__SMM__) - return pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc; -#else - return pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), - GPIO_BASE) & 0xfffc; -#endif -} - +#include +#include +#include /* * 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) +static int gpio_to_pirq(int gpio) { switch (gpio) { case 8: return 0; /* PIRQI */ @@ -65,10 +54,57 @@ static int lp_gpio_to_pirq(int gpio) }; } -void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[]) +void init_one_gpio(int gpio_num, struct gpio_config *config) { - u16 gpio_base = get_gpio_base(); - const struct pch_lp_gpio_map *config; + u32 owner, route, irqen, reset; + int set, bit; + + if (gpio_num > MAX_GPIO_NUMBER || !config) + return; + + outl(config->conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); + outl(config->conf1, GPIO_BASE_ADDRESS + GPIO_CONFIG1(gpio_num)); + + /* Determine set and bit based on GPIO number */ + set = gpio_num >> 5; + bit = gpio_num % 32; + + /* Save settings from current GPIO config */ + owner = inl(GPIO_BASE_ADDRESS + GPIO_OWNER(set)); + route = inl(GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); + irqen = inl(GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); + reset = inl(GPIO_BASE_ADDRESS + GPIO_RESET(set)); + + owner |= config->owner << bit; + route |= config->route << bit; + irqen |= config->irqen << bit; + reset |= config->reset << bit; + + outl(owner, GPIO_BASE_ADDRESS + GPIO_OWNER(set)); + outl(route, GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); + outl(irqen, GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); + outl(reset, GPIO_BASE_ADDRESS + GPIO_RESET(set)); + + if (set == 0) { + u32 blink = inl(GPIO_BASE_ADDRESS + GPIO_BLINK); + blink |= config->blink << bit; + outl(blink, GPIO_BASE_ADDRESS + GPIO_BLINK); + } + + /* PIRQ to IO-APIC map */ + if (config->pirq == GPIO_PIRQ_APIC_ROUTE) { + u32 pirq2apic = inl(GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); + set = gpio_to_pirq(gpio_num); + if (set >= 0) { + pirq2apic |= 1 << set; + outl(pirq2apic, GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); + } + } +} + +void init_gpios(const struct gpio_config config[]) +{ + const struct gpio_config *entry; u32 owner[3] = {0}; u32 route[3] = {0}; u32 irqen[3] = {0}; @@ -77,54 +113,52 @@ void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[]) u16 pirq2apic = 0; int set, bit, gpio = 0; - for (config = map; config->conf0 != GPIO_LIST_END; config++, gpio++) { + for (entry = config; entry->conf0 != GPIO_LIST_END; entry++, gpio++) { if (gpio > MAX_GPIO_NUMBER) break; /* Setup Configuration registers 1 and 2 */ - outl(config->conf0, gpio_base + GPIO_CONFIG0(gpio)); - outl(config->conf1, gpio_base + GPIO_CONFIG1(gpio)); + outl(entry->conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio)); + outl(entry->conf1, GPIO_BASE_ADDRESS + GPIO_CONFIG1(gpio)); /* Determine set and bit based on GPIO number */ set = gpio >> 5; bit = gpio % 32; /* Apply settings to set specific bits */ - owner[set] |= config->owner << bit; - route[set] |= config->route << bit; - irqen[set] |= config->irqen << bit; - reset[set] |= config->reset << bit; + owner[set] |= entry->owner << bit; + route[set] |= entry->route << bit; + irqen[set] |= entry->irqen << bit; + reset[set] |= entry->reset << bit; if (set == 0) - blink |= config->blink << bit; + blink |= entry->blink << bit; /* PIRQ to IO-APIC map */ - if (config->pirq == GPIO_PIRQ_APIC_ROUTE) { - set = lp_gpio_to_pirq(gpio); + if (entry->pirq == GPIO_PIRQ_APIC_ROUTE) { + set = gpio_to_pirq(gpio); if (set >= 0) pirq2apic |= 1 << set; } } for (set = 0; set <= 2; set++) { - outl(owner[set], gpio_base + GPIO_OWNER(set)); - outl(route[set], gpio_base + GPIO_ROUTE(set)); - outl(irqen[set], gpio_base + GPIO_IRQ_IE(set)); - outl(reset[set], gpio_base + GPIO_RESET(set)); + outl(owner[set], GPIO_BASE_ADDRESS + GPIO_OWNER(set)); + outl(route[set], GPIO_BASE_ADDRESS + GPIO_ROUTE(set)); + outl(irqen[set], GPIO_BASE_ADDRESS + GPIO_IRQ_IE(set)); + outl(reset[set], GPIO_BASE_ADDRESS + GPIO_RESET(set)); } - outl(blink, gpio_base + GPIO_BLINK); - outl(pirq2apic, gpio_base + GPIO_PIRQ_APIC_EN); + outl(blink, GPIO_BASE_ADDRESS + GPIO_BLINK); + outl(pirq2apic, GPIO_BASE_ADDRESS + GPIO_PIRQ_APIC_EN); } int get_gpio(int gpio_num) { - u16 gpio_base = get_gpio_base(); - if (gpio_num > MAX_GPIO_NUMBER) return 0; - return !!(inl(gpio_base + GPIO_CONFIG0(gpio_num)) & GPI_LEVEL); + return !!(inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)) & GPI_LEVEL); } /* @@ -148,21 +182,18 @@ unsigned get_gpios(const int *gpio_num_array) void set_gpio(int gpio_num, int value) { - u16 gpio_base = get_gpio_base(); u32 conf0; if (gpio_num > MAX_GPIO_NUMBER) return; - conf0 = inl(gpio_base + GPIO_CONFIG0(gpio_num)); + conf0 = inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); conf0 &= ~GPO_LEVEL_MASK; conf0 |= value << GPO_LEVEL_SHIFT; - outl(conf0, gpio_base + GPIO_CONFIG0(gpio_num)); + outl(conf0, GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)); } int gpio_is_native(int gpio_num) { - u16 gpio_base = get_gpio_base(); - - return !(inl(gpio_base + GPIO_CONFIG0(gpio_num)) & 1); + return !(inl(GPIO_BASE_ADDRESS + GPIO_CONFIG0(gpio_num)) & 1); }