sb/inte/common/gpio: Implement gpio_input() and gpio_output()
Implement the two functions defined as prototypes in gpio.h. Allows to drop custom SMI handler code and use the generic function from gpio.c instead. Change-Id: I795af83374118d3fc2b46837b1822205c966fda6 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/88508 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
55bed620a4
commit
c54fde5040
3 changed files with 80 additions and 86 deletions
|
|
@ -10,64 +10,25 @@
|
|||
#include <device/pci_def.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <northbridge/intel/sandybridge/sandybridge.h>
|
||||
#include <gpio.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <southbridge/intel/bd82x6x/me.h>
|
||||
#include <southbridge/intel/common/finalize.h>
|
||||
#include <southbridge/intel/common/gpio.h>
|
||||
#include <southbridge/intel/common/pmutil.h>
|
||||
#include <types.h>
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
static void southbridge_gate_memory_reset_real(int offset,
|
||||
u16 use, u16 io, u16 lvl)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
/* Make sure it is set as GPIO */
|
||||
reg32 = inl(use);
|
||||
if (!(reg32 & (1 << offset))) {
|
||||
reg32 |= (1 << offset);
|
||||
outl(reg32, use);
|
||||
}
|
||||
|
||||
/* Make sure it is set as output */
|
||||
reg32 = inl(io);
|
||||
if (reg32 & (1 << offset)) {
|
||||
reg32 &= ~(1 << offset);
|
||||
outl(reg32, io);
|
||||
}
|
||||
|
||||
/* Drive the output low */
|
||||
reg32 = inl(lvl);
|
||||
reg32 &= ~(1 << offset);
|
||||
outl(reg32, lvl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drive GPIO 60 low to gate memory reset in S3.
|
||||
* Drive reset gate GPIO low to gate memory reset in S3.
|
||||
*
|
||||
* Intel reference designs all use GPIO 60 but it is
|
||||
* not a requirement and boards could use a different pin.
|
||||
*/
|
||||
void southbridge_gate_memory_reset(void)
|
||||
{
|
||||
u16 gpiobase;
|
||||
|
||||
gpiobase = pci_read_config16(PCH_LPC_DEV, GPIOBASE) & 0xfffc;
|
||||
if (!gpiobase)
|
||||
return;
|
||||
|
||||
if (CONFIG_DRAM_RESET_GATE_GPIO >= 32)
|
||||
southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO - 32,
|
||||
gpiobase + GPIO_USE_SEL2,
|
||||
gpiobase + GP_IO_SEL2,
|
||||
gpiobase + GP_LVL2);
|
||||
else
|
||||
southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO,
|
||||
gpiobase + GPIO_USE_SEL,
|
||||
gpiobase + GP_IO_SEL,
|
||||
gpiobase + GP_LVL);
|
||||
gpio_output(CONFIG_DRAM_RESET_GATE_GPIO, 0);
|
||||
}
|
||||
|
||||
void southbridge_smi_monitor(void)
|
||||
|
|
|
|||
|
|
@ -146,7 +146,79 @@ int gpio_is_native(int gpio_num)
|
|||
return !(config & (1 << bit));
|
||||
}
|
||||
|
||||
void gpio_input(gpio_t gpio)
|
||||
static void gpio_set_gpio(gpio_t gpio_num)
|
||||
{
|
||||
// FIXME: Implement
|
||||
static const int gpio_use_reg_offsets[] = {
|
||||
GPIO_USE_SEL, GPIO_USE_SEL2, GPIO_USE_SEL3
|
||||
};
|
||||
u16 gpio_base = get_gpio_base();
|
||||
int index, bit;
|
||||
u32 config;
|
||||
|
||||
if (gpio_num > MAX_GPIO_NUMBER)
|
||||
return; /* Just ignore wrong gpio numbers. */
|
||||
|
||||
index = gpio_num / 32;
|
||||
bit = gpio_num % 32;
|
||||
|
||||
config = inl(gpio_base + gpio_use_reg_offsets[index]);
|
||||
if (config & (GPIO_MODE_GPIO << bit))
|
||||
return;
|
||||
|
||||
config |= GPIO_MODE_GPIO << bit;
|
||||
outl(gpio_base + gpio_use_reg_offsets[index], config);
|
||||
}
|
||||
|
||||
void gpio_input(gpio_t gpio_num)
|
||||
{
|
||||
static const int gpio_io_reg_offsets[] = {
|
||||
GP_IO_SEL, GP_IO_SEL2, GP_IO_SEL3
|
||||
};
|
||||
u16 gpio_base = get_gpio_base();
|
||||
int index, bit;
|
||||
u32 config;
|
||||
|
||||
if (gpio_num > MAX_GPIO_NUMBER)
|
||||
return; /* Just ignore wrong gpio numbers. */
|
||||
|
||||
gpio_set_gpio(gpio_num);
|
||||
|
||||
index = gpio_num / 32;
|
||||
bit = gpio_num % 32;
|
||||
|
||||
config = inl(gpio_base + gpio_io_reg_offsets[index]);
|
||||
if (((config >> bit) & 1) == GPIO_DIR_INPUT)
|
||||
return;
|
||||
|
||||
config |= 1 << bit;
|
||||
outl(gpio_base + gpio_io_reg_offsets[index], config);
|
||||
}
|
||||
|
||||
void gpio_output(gpio_t gpio_num, int value)
|
||||
{
|
||||
static const int gpio_io_reg_offsets[] = {
|
||||
GP_IO_SEL, GP_IO_SEL2, GP_IO_SEL3
|
||||
};
|
||||
u16 gpio_base = get_gpio_base();
|
||||
int index, bit;
|
||||
u32 config;
|
||||
|
||||
if (gpio_num > MAX_GPIO_NUMBER)
|
||||
return; /* Just ignore wrong gpio numbers. */
|
||||
|
||||
gpio_set_gpio(gpio_num);
|
||||
gpio_set(gpio_num, value);
|
||||
|
||||
index = gpio_num / 32;
|
||||
bit = gpio_num % 32;
|
||||
|
||||
config = inl(gpio_base + gpio_io_reg_offsets[index]);
|
||||
if (((config >> bit) & 1) == GPIO_DIR_OUTPUT)
|
||||
return;
|
||||
|
||||
config &= ~(1 << bit);
|
||||
outl(gpio_base + gpio_io_reg_offsets[index], config);
|
||||
|
||||
/* Set value again in case output register was gated */
|
||||
gpio_set(gpio_num, value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <device/pci_def.h>
|
||||
#include <cpu/intel/em64t101_save_state.h>
|
||||
#include <cpu/intel/model_2065x/model_2065x.h>
|
||||
#include <gpio.h>
|
||||
#include <southbridge/intel/common/finalize.h>
|
||||
#include <southbridge/intel/common/pmbase.h>
|
||||
#include <southbridge/intel/ibexpeak/me.h>
|
||||
|
|
@ -17,58 +18,18 @@
|
|||
* 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
|
||||
*/
|
||||
#include <northbridge/intel/ironlake/ironlake.h>
|
||||
#include <southbridge/intel/common/gpio.h>
|
||||
#include <southbridge/intel/common/pmutil.h>
|
||||
|
||||
static void southbridge_gate_memory_reset_real(int offset,
|
||||
u16 use, u16 io, u16 lvl)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
/* Make sure it is set as GPIO */
|
||||
reg32 = inl(use);
|
||||
if (!(reg32 & (1 << offset))) {
|
||||
reg32 |= (1 << offset);
|
||||
outl(reg32, use);
|
||||
}
|
||||
|
||||
/* Make sure it is set as output */
|
||||
reg32 = inl(io);
|
||||
if (reg32 & (1 << offset)) {
|
||||
reg32 &= ~(1 << offset);
|
||||
outl(reg32, io);
|
||||
}
|
||||
|
||||
/* Drive the output low */
|
||||
reg32 = inl(lvl);
|
||||
reg32 &= ~(1 << offset);
|
||||
outl(reg32, lvl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drive GPIO 60 low to gate memory reset in S3.
|
||||
* Drive reset gate GPIO low to gate memory reset in S3.
|
||||
*
|
||||
* Intel reference designs all use GPIO 60 but it is
|
||||
* not a requirement and boards could use a different pin.
|
||||
*/
|
||||
void southbridge_gate_memory_reset(void)
|
||||
{
|
||||
u16 gpiobase;
|
||||
|
||||
gpiobase = pci_read_config16(PCI_DEV(0, 0x1f, 0), GPIOBASE) & 0xfffc;
|
||||
if (!gpiobase)
|
||||
return;
|
||||
|
||||
if (CONFIG_DRAM_RESET_GATE_GPIO >= 32)
|
||||
southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO - 32,
|
||||
gpiobase + GPIO_USE_SEL2,
|
||||
gpiobase + GP_IO_SEL2,
|
||||
gpiobase + GP_LVL2);
|
||||
else
|
||||
southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO,
|
||||
gpiobase + GPIO_USE_SEL,
|
||||
gpiobase + GP_IO_SEL,
|
||||
gpiobase + GP_LVL);
|
||||
gpio_output(CONFIG_DRAM_RESET_GATE_GPIO, 0);
|
||||
}
|
||||
|
||||
void southbridge_smi_monitor(void)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue