lynxpoint: Add new GPIO interface for Lynxpoint-LP
The low power variant of the chipset introduces a completely new interface to the GPIOs. This is a 1KB region and so needs to be moved as well so it does not conflict with other IO regions. Also expose the gpio_get functions to ramstage and move the prototypes to pch.h so they can be used for both GPIO interfaces. Change-Id: I20bc18669525af16de8cdf99f0ccfa9612be63ad Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: http://review.coreboot.org/2648 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marc.jones@se-eng.com>
This commit is contained in:
parent
51254049b9
commit
045f153a4f
|
@ -45,10 +45,18 @@ smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
|
|||
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
|
||||
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c
|
||||
|
||||
romstage-y += early_usb.c early_smbus.c early_me.c me_status.c gpio.c
|
||||
romstage-y += early_usb.c early_smbus.c early_me.c me_status.c
|
||||
romstage-$(CONFIG_USBDEBUG) += usb_debug.c
|
||||
romstage-y += reset.c early_spi.c
|
||||
|
||||
ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y)
|
||||
romstage-y += lp_gpio.c
|
||||
ramstage-y += lp_gpio.c
|
||||
else
|
||||
romstage-y += gpio.c
|
||||
ramstage-y += gpio.c
|
||||
endif
|
||||
|
||||
lynxpoint_add_me: $(obj)/coreboot.pre $(IFDTOOL)
|
||||
printf " DD Adding Intel Firmware Descriptor\n"
|
||||
dd if=3rdparty/mainboard/$(MAINBOARDDIR)/descriptor.bin \
|
||||
|
|
|
@ -194,7 +194,22 @@ Device (LPCB)
|
|||
IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
|
||||
//IO (Decode16, 0x800, 0x800, 0x1, 0x10) // ACPI I/O trap
|
||||
IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80) // ICH7-M ACPI
|
||||
IO (Decode16, DEFAULT_GPIOBASE, DEFAULT_GPIOBASE, 0x1, 0x40) // ICH7-M GPIO
|
||||
|
||||
#if CONFIG_INTEL_LYNXPOINT_LP
|
||||
// LynxPoint LP GPIO is 1KB
|
||||
IO (Decode16, DEFAULT_GPIOBASE,
|
||||
DEFAULT_GPIOBASE, 0x1, 0xff)
|
||||
IO (Decode16, Add(DEFAULT_GPIOBASE, 0x100),
|
||||
Add(DEFAULT_GPIOBASE, 0x100), 0x1, 0xff)
|
||||
IO (Decode16, Add(DEFAULT_GPIOBASE, 0x200),
|
||||
Add(DEFAULT_GPIOBASE, 0x200), 0x1, 0xff)
|
||||
IO (Decode16, Add(DEFAULT_GPIOBASE, 0x300),
|
||||
Add(DEFAULT_GPIOBASE, 0x300), 0x1, 0xff)
|
||||
#else
|
||||
// LynxPoint GPIO is 128 bytes
|
||||
IO (Decode16, DEFAULT_GPIOBASE,
|
||||
DEFAULT_GPIOBASE, 0x1, DEFAULT_GPIOSIZE)
|
||||
#endif
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,32 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <arch/io.h>
|
||||
|
||||
#ifdef __PRE_RAM__
|
||||
#include <arch/romcc_io.h>
|
||||
#else
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#endif
|
||||
|
||||
#include "pch.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#define MAX_GPIO_NUMBER 75 /* zero based */
|
||||
|
||||
static u16 get_gpio_base(void)
|
||||
{
|
||||
#ifdef __PRE_RAM__
|
||||
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
|
||||
}
|
||||
|
||||
void setup_pch_gpios(const struct pch_gpio_map *gpio)
|
||||
{
|
||||
u16 gpiobase = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
|
||||
u16 gpiobase = get_gpio_base();
|
||||
|
||||
/* GPIO Set 1 */
|
||||
if (gpio->set1.level)
|
||||
|
@ -69,7 +85,7 @@ void setup_pch_gpios(const struct pch_gpio_map *gpio)
|
|||
int get_gpio(int gpio_num)
|
||||
{
|
||||
static const int gpio_reg_offsets[] = {0xc, 0x38, 0x48};
|
||||
u16 gpio_base = pci_read_config16(PCH_LPC_DEV, GPIO_BASE) & 0xfffc;
|
||||
u16 gpio_base = get_gpio_base();
|
||||
int index, bit;
|
||||
|
||||
if (gpio_num > MAX_GPIO_NUMBER)
|
||||
|
|
|
@ -20,6 +20,22 @@
|
|||
#ifndef INTEL_LYNXPOINT_GPIO_H
|
||||
#define INTEL_LYNXPOINT_GPIO_H
|
||||
|
||||
/* ICH7 GPIOBASE */
|
||||
#define GPIO_USE_SEL 0x00
|
||||
#define GP_IO_SEL 0x04
|
||||
#define GP_LVL 0x0c
|
||||
#define GPO_BLINK 0x18
|
||||
#define GPI_INV 0x2c
|
||||
#define GPIO_USE_SEL2 0x30
|
||||
#define GP_IO_SEL2 0x34
|
||||
#define GP_LVL2 0x38
|
||||
#define GPIO_USE_SEL3 0x40
|
||||
#define GP_IO_SEL3 0x44
|
||||
#define GP_LVL3 0x48
|
||||
#define GP_RST_SEL1 0x60
|
||||
#define GP_RST_SEL2 0x64
|
||||
#define GP_RST_SEL3 0x68
|
||||
|
||||
#define GPIO_MODE_NATIVE 0
|
||||
#define GPIO_MODE_GPIO 1
|
||||
#define GPIO_MODE_NONE 1
|
||||
|
@ -150,12 +166,4 @@ struct pch_gpio_map {
|
|||
/* Configure GPIOs with mainboard provided settings */
|
||||
void setup_pch_gpios(const struct pch_gpio_map *gpio);
|
||||
|
||||
/* get GPIO pin value */
|
||||
int get_gpio(int gpio_num);
|
||||
/*
|
||||
* get a number comprised of multiple GPIO values. gpio_num_array points to
|
||||
* the array of gpio pin numbers to scan, terminated by -1.
|
||||
*/
|
||||
unsigned get_gpios(const int *gpio_num_array);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
#include <arch/io.h>
|
||||
#ifdef __PRE_RAM__
|
||||
#include <arch/romcc_io.h>
|
||||
#else
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#endif
|
||||
|
||||
#include "pch.h"
|
||||
#include "lp_gpio.h"
|
||||
|
||||
static u16 get_gpio_base(void)
|
||||
{
|
||||
#ifdef __PRE_RAM__
|
||||
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
|
||||
}
|
||||
|
||||
void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[])
|
||||
{
|
||||
u16 gpio_base = get_gpio_base();
|
||||
const struct pch_lp_gpio_map *config;
|
||||
u32 owner[3] = {0};
|
||||
u32 route[3] = {0};
|
||||
u32 irqen[3] = {0};
|
||||
u32 reset[3] = {0};
|
||||
u32 blink = 0;
|
||||
int set, bit;
|
||||
|
||||
for (config = map; config->gpio != GPIO_LIST_END; config++) {
|
||||
if (config->gpio > MAX_GPIO_NUMBER)
|
||||
continue;
|
||||
|
||||
/* Setup Configuration registers 1 and 2 */
|
||||
outl(config->conf0, gpio_base + GPIO_CONFIG0(config->gpio));
|
||||
outl(config->conf1, gpio_base + GPIO_CONFIG1(config->gpio));
|
||||
|
||||
/* Determine set and bit based on GPIO number */
|
||||
set = config->gpio >> 5;
|
||||
bit = config->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;
|
||||
|
||||
if (set == 0)
|
||||
blink |= config->blink << bit;
|
||||
}
|
||||
|
||||
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(blink, gpio_base + GPIO_BLINK);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* get a number comprised of multiple GPIO values. gpio_num_array points to
|
||||
* the array of gpio pin numbers to scan, terminated by -1.
|
||||
*/
|
||||
unsigned get_gpios(const int *gpio_num_array)
|
||||
{
|
||||
int gpio;
|
||||
unsigned bitmask = 1;
|
||||
unsigned vector = 0;
|
||||
|
||||
while (bitmask &&
|
||||
((gpio = *gpio_num_array++) != -1)) {
|
||||
if (get_gpio(gpio))
|
||||
vector |= bitmask;
|
||||
bitmask <<= 1;
|
||||
}
|
||||
return vector;
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 Google Inc. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef INTEL_LYNXPOINT_LP_GPIO_H
|
||||
#define INTEL_LYNXPOINT_LP_GPIO_H
|
||||
|
||||
/* LynxPoint LP GPIOBASE Registers */
|
||||
#define GPIO_OWNER(set) (0x00 + ((set) * 4))
|
||||
#define GPIO_PIRQ_APIC_EN 0x10
|
||||
#define GPIO_BLINK 0x18
|
||||
#define GPIO_SER_BLINK 0x1c
|
||||
#define GPIO_SER_BLINK_CS 0x20
|
||||
#define GPIO_SER_BLINK_DATA 0x24
|
||||
#define GPIO_ROUTE(set) (0x30 + ((set) * 4))
|
||||
#define GPIO_ALT_GPI_SMI_STS 0x50
|
||||
#define GPIO_ALT_GPI_SMI_EN 0x54
|
||||
#define GPIO_RESET(set) (0x60 + ((set) * 4))
|
||||
#define GPIO_GLOBAL_CONFIG 0x7c
|
||||
#define GPIO_IRQ_IS(set) (0x80 + ((set) * 4))
|
||||
#define GPIO_IRQ_IE(set) (0x90 + ((set) * 4))
|
||||
#define GPIO_CONFIG0(gpio) (0x100 + ((gpio) * 8))
|
||||
#define GPIO_CONFIG1(gpio) (0x104 + ((gpio) * 8))
|
||||
|
||||
#define MAX_GPIO_NUMBER 94 /* zero based */
|
||||
#define GPIO_LIST_END 0xff
|
||||
|
||||
/* conf0 */
|
||||
|
||||
#define GPIO_MODE_NATIVE (0 << 0)
|
||||
#define GPIO_MODE_GPIO (1 << 0)
|
||||
|
||||
#define GPIO_DIR_OUTPUT (0 << 2)
|
||||
#define GPIO_DIR_INPUT (1 << 2)
|
||||
|
||||
#define GPIO_NO_INVERT (0 << 3)
|
||||
#define GPIO_INVERT (1 << 3)
|
||||
|
||||
#define GPIO_IRQ_EDGE (0 << 4)
|
||||
#define GPIO_IRQ_LEVEL (1 << 4)
|
||||
|
||||
#define GPI_LEVEL (1 << 30)
|
||||
|
||||
#define GPO_LEVEL_LOW (0 << 31)
|
||||
#define GPO_LEVEL_HIGH (1 << 31)
|
||||
|
||||
/* conf1 */
|
||||
|
||||
#define GPIO_PULL_NONE (0 << 0)
|
||||
#define GPIO_PULL_DOWN (1 << 0)
|
||||
#define GPIO_PULL_UP (2 << 0)
|
||||
|
||||
#define GPIO_SENSE_ENABLE (0 << 2)
|
||||
#define GPIO_SENSE_DISABLE (1 << 2)
|
||||
|
||||
/* owner */
|
||||
|
||||
#define GPIO_OWNER_ACPI 0
|
||||
#define GPIO_OWNER_GPIO 1
|
||||
|
||||
/* route */
|
||||
|
||||
#define GPIO_ROUTE_SCI 0
|
||||
#define GPIO_ROUTE_SMI 1
|
||||
|
||||
/* irqen */
|
||||
|
||||
#define GPIO_IRQ_DISABLE 0
|
||||
#define GPIO_IRQ_ENABLE 1
|
||||
|
||||
/* blink */
|
||||
|
||||
#define GPO_NO_BLINK 0
|
||||
#define GPO_BLINK 1
|
||||
|
||||
/* reset */
|
||||
|
||||
#define GPIO_RESET_PWROK 0
|
||||
#define GPIO_RESET_RSMRST 1
|
||||
|
||||
struct pch_lp_gpio_map {
|
||||
u8 gpio;
|
||||
u32 conf0;
|
||||
u32 conf1;
|
||||
u8 owner;
|
||||
u8 route;
|
||||
u8 irqen;
|
||||
u8 reset;
|
||||
u8 blink;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Configure GPIOs with mainboard provided settings */
|
||||
void setup_pch_lp_gpios(const struct pch_lp_gpio_map map[]);
|
||||
|
||||
#endif
|
|
@ -561,13 +561,20 @@ static void pch_lpc_read_resources(device_t dev)
|
|||
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
|
||||
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
|
||||
/* GPIOBASE */
|
||||
res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
|
||||
res->base = DEFAULT_GPIOBASE;
|
||||
res->size = DEFAULT_GPIOSIZE;
|
||||
res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
|
||||
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
|
||||
res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
|
||||
res->base = 0xff800000;
|
||||
res->size = 0x00800000; /* 8 MB for flash */
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
|
||||
IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
|
||||
res = new_resource(dev, 3); /* IOAPIC */
|
||||
res = new_resource(dev, io_index++); /* IOAPIC */
|
||||
res->base = IO_APIC_ADDR;
|
||||
res->size = 0x00001000;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
|
|
|
@ -63,10 +63,16 @@
|
|||
*/
|
||||
#define SMBUS_IO_BASE 0x0400
|
||||
#define SMBUS_SLAVE_ADDR 0x24
|
||||
/* TODO Make sure these don't get changed by stage2 */
|
||||
#define DEFAULT_GPIOBASE 0x0480
|
||||
#define DEFAULT_PMBASE 0x0500
|
||||
|
||||
#if CONFIG_INTEL_LYNXPOINT_LP
|
||||
#define DEFAULT_GPIOBASE 0x1000
|
||||
#define DEFAULT_GPIOSIZE 0x400
|
||||
#else
|
||||
#define DEFAULT_GPIOBASE 0x480
|
||||
#define DEFAULT_GPIOSIZE 0x80
|
||||
#endif
|
||||
|
||||
#define HPET_ADDR 0xfed00000
|
||||
#define DEFAULT_RCBA 0xfed1c000
|
||||
|
||||
|
@ -97,6 +103,15 @@ void enable_usb_bar(void);
|
|||
int smbus_read_byte(unsigned device, unsigned address);
|
||||
int early_spi_read(u32 offset, u32 size, u8 *buffer);
|
||||
#endif
|
||||
/*
|
||||
* get GPIO pin value
|
||||
*/
|
||||
int get_gpio(int gpio_num);
|
||||
/*
|
||||
* get a number comprised of multiple GPIO values. gpio_num_array points to
|
||||
* the array of gpio pin numbers to scan, terminated by -1.
|
||||
*/
|
||||
unsigned get_gpios(const int *gpio_num_array);
|
||||
#endif
|
||||
|
||||
#define MAINBOARD_POWER_OFF 0
|
||||
|
@ -438,22 +453,6 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer);
|
|||
#define PCH_DISABLE_MEI1 (1 << 1)
|
||||
#define PCH_ENABLE_DBDF (1 << 0)
|
||||
|
||||
/* ICH7 GPIOBASE */
|
||||
#define GPIO_USE_SEL 0x00
|
||||
#define GP_IO_SEL 0x04
|
||||
#define GP_LVL 0x0c
|
||||
#define GPO_BLINK 0x18
|
||||
#define GPI_INV 0x2c
|
||||
#define GPIO_USE_SEL2 0x30
|
||||
#define GP_IO_SEL2 0x34
|
||||
#define GP_LVL2 0x38
|
||||
#define GPIO_USE_SEL3 0x40
|
||||
#define GP_IO_SEL3 0x44
|
||||
#define GP_LVL3 0x48
|
||||
#define GP_RST_SEL1 0x60
|
||||
#define GP_RST_SEL2 0x64
|
||||
#define GP_RST_SEL3 0x68
|
||||
|
||||
/* ICH7 PMBASE */
|
||||
#define PM1_STS 0x00
|
||||
#define WAK_STS (1 << 15)
|
||||
|
|
Loading…
Reference in New Issue