superio/nuvoton/nct5104d: add chip config option to reset GPIOs
Define a chip option to explicitly soft reset all enabled GPIOs to default state. TEST=boot FreeBSD 11.2 on PC Engines apu1, change GPIO configuration using nctgpio module and check whether GPIOs are reset after reboot Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Change-Id: Iae4205574800138402cbc95f4948167265a80d15 Reviewed-on: https://review.coreboot.org/c/coreboot/+/38850 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
parent
48409b8229
commit
65f05505a6
|
@ -41,6 +41,7 @@ chip northbridge/amd/agesa/family14/root_complex
|
||||||
device pci 14.3 on # LPC 0x439d
|
device pci 14.3 on # LPC 0x439d
|
||||||
chip superio/nuvoton/nct5104d
|
chip superio/nuvoton/nct5104d
|
||||||
register "irq_trigger_type" = "0"
|
register "irq_trigger_type" = "0"
|
||||||
|
register "reset_gpios" = "1"
|
||||||
device pnp 2e.0 off end
|
device pnp 2e.0 off end
|
||||||
device pnp 2e.2 on
|
device pnp 2e.2 on
|
||||||
io 0x60 = 0x3f8
|
io 0x60 = 0x3f8
|
||||||
|
|
|
@ -44,6 +44,7 @@ chip northbridge/amd/pi/00730F01/root_complex
|
||||||
device pci 14.3 on # LPC 0x439d
|
device pci 14.3 on # LPC 0x439d
|
||||||
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
||||||
register "irq_trigger_type" = "0"
|
register "irq_trigger_type" = "0"
|
||||||
|
register "reset_gpios" = "1"
|
||||||
device pnp 2e.0 off end
|
device pnp 2e.0 off end
|
||||||
device pnp 2e.2 on
|
device pnp 2e.2 on
|
||||||
io 0x60 = 0x3f8
|
io 0x60 = 0x3f8
|
||||||
|
|
|
@ -44,6 +44,7 @@ chip northbridge/amd/pi/00730F01/root_complex
|
||||||
device pci 14.3 on # LPC 0x439d
|
device pci 14.3 on # LPC 0x439d
|
||||||
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
||||||
register "irq_trigger_type" = "0"
|
register "irq_trigger_type" = "0"
|
||||||
|
register "reset_gpios" = "1"
|
||||||
device pnp 2e.0 off end
|
device pnp 2e.0 off end
|
||||||
device pnp 2e.2 on
|
device pnp 2e.2 on
|
||||||
io 0x60 = 0x3f8
|
io 0x60 = 0x3f8
|
||||||
|
|
|
@ -44,6 +44,7 @@ chip northbridge/amd/pi/00730F01/root_complex
|
||||||
device pci 14.3 on # LPC 0x439d
|
device pci 14.3 on # LPC 0x439d
|
||||||
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
chip superio/nuvoton/nct5104d # SIO NCT5104D
|
||||||
register "irq_trigger_type" = "0"
|
register "irq_trigger_type" = "0"
|
||||||
|
register "reset_gpios" = "1"
|
||||||
device pnp 2e.0 off end
|
device pnp 2e.0 off end
|
||||||
device pnp 2e.2 on
|
device pnp 2e.2 on
|
||||||
io 0x60 = 0x3f8
|
io 0x60 = 0x3f8
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
struct superio_nuvoton_nct5104d_config {
|
struct superio_nuvoton_nct5104d_config {
|
||||||
u8 irq_trigger_type;
|
u8 irq_trigger_type;
|
||||||
|
u8 reset_gpios;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/* This file is part of the coreboot project. */
|
/* This file is part of the coreboot project. */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/pnp.h>
|
#include <device/pnp.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
|
@ -98,42 +99,45 @@ static void route_pins_to_uart(struct device *dev, bool to_uart)
|
||||||
static void reset_gpio_default_in(struct device *dev)
|
static void reset_gpio_default_in(struct device *dev)
|
||||||
{
|
{
|
||||||
pnp_set_logical_device(dev);
|
pnp_set_logical_device(dev);
|
||||||
|
/*
|
||||||
/* Soft reset GPIOs to default state: IN */
|
* Soft reset GPIOs to default state: IN.
|
||||||
switch (dev->path.pnp.device) {
|
* The main GPIO LDN holds registers that configure the pins as output
|
||||||
case NCT5104D_GPIO0:
|
* or input. These registers are located at offset 0xE0 plus the GPIO
|
||||||
pnp_write_config(dev, NCT5104D_GPIO0_IO, 0xFF);
|
* bank number multiplied by 4: 0xE0 for GPIO0, 0xE4 for GPIO1 and
|
||||||
break;
|
* 0xF8 for GPIO6.
|
||||||
case NCT5104D_GPIO1:
|
*/
|
||||||
pnp_write_config(dev, NCT5104D_GPIO1_IO, 0xFF);
|
pnp_write_config(dev, NCT5104D_GPIO0_IO + (dev->path.pnp.device >> 8) * 4, 0xFF);
|
||||||
break;
|
|
||||||
case NCT5104D_GPIO6:
|
|
||||||
pnp_write_config(dev, NCT5104D_GPIO6_IO, 0xFF);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_gpio_default_od(struct device *dev)
|
static void reset_gpio_default_od(struct device *dev)
|
||||||
{
|
{
|
||||||
struct device *gpio0, *gpio1, *gpio6;
|
struct device *gpio0, *gpio1, *gpio6;
|
||||||
|
|
||||||
|
pnp_set_logical_device(dev);
|
||||||
|
|
||||||
gpio0 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO0);
|
gpio0 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO0);
|
||||||
gpio1 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO1);
|
gpio1 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO1);
|
||||||
gpio6 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO6);
|
gpio6 = dev_find_slot_pnp(dev->path.pnp.port, NCT5104D_GPIO6);
|
||||||
|
|
||||||
pnp_set_logical_device(dev);
|
/*
|
||||||
|
* Soft reset GPIOs to default state: Open-drain.
|
||||||
/* Soft reset GPIOs to default state: Open-drain */
|
* The NCT5104D_GPIO_PP_OD LDN holds registers (1 for each GPIO bank)
|
||||||
|
* that configure each GPIO pin to be open dain or push pull. System
|
||||||
|
* reset is known to not reset the values in this register. The
|
||||||
|
* registers are located at offsets begginign from 0xE0 plus GPIO bank
|
||||||
|
* number, i.e. 0xE0 for GPIO0, 0xE1 for GPIO1 and 0xE6 for GPIO6.
|
||||||
|
*/
|
||||||
if (gpio0 && gpio0->enabled)
|
if (gpio0 && gpio0->enabled)
|
||||||
pnp_write_config(dev, NCT5104D_GPIO0_PP_OD, 0xFF);
|
pnp_write_config(dev,
|
||||||
|
(gpio0->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
|
||||||
|
|
||||||
if (gpio1 && gpio1->enabled)
|
if (gpio1 && gpio1->enabled)
|
||||||
pnp_write_config(dev, NCT5104D_GPIO1_PP_OD, 0xFF);
|
pnp_write_config(dev,
|
||||||
|
(gpio1->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
|
||||||
|
|
||||||
if (gpio6 && gpio6->enabled)
|
if (gpio6 && gpio6->enabled)
|
||||||
pnp_write_config(dev, NCT5104D_GPIO6_PP_OD, 0xFF);
|
pnp_write_config(dev,
|
||||||
|
(gpio6->path.pnp.device >> 8) + NCT5104D_GPIO0_PP_OD, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_gpio_io_port(struct device *dev)
|
static void disable_gpio_io_port(struct device *dev)
|
||||||
|
@ -181,13 +185,14 @@ static void nct5104d_init(struct device *dev)
|
||||||
case NCT5104D_GPIO0:
|
case NCT5104D_GPIO0:
|
||||||
case NCT5104D_GPIO1:
|
case NCT5104D_GPIO1:
|
||||||
route_pins_to_uart(dev, false);
|
route_pins_to_uart(dev, false);
|
||||||
reset_gpio_default_in(dev);
|
/* FALLTHROUGH */
|
||||||
break;
|
|
||||||
case NCT5104D_GPIO6:
|
case NCT5104D_GPIO6:
|
||||||
reset_gpio_default_in(dev);
|
if (conf->reset_gpios)
|
||||||
|
reset_gpio_default_in(dev);
|
||||||
break;
|
break;
|
||||||
case NCT5104D_GPIO_PP_OD:
|
case NCT5104D_GPIO_PP_OD:
|
||||||
reset_gpio_default_od(dev);
|
if (conf->reset_gpios)
|
||||||
|
reset_gpio_default_od(dev);
|
||||||
break;
|
break;
|
||||||
case NCT5104D_GPIO_IO:
|
case NCT5104D_GPIO_IO:
|
||||||
disable_gpio_io_port(dev);
|
disable_gpio_io_port(dev);
|
||||||
|
|
Loading…
Reference in New Issue