diff --git a/src/soc/nvidia/tegra/gpio.c b/src/soc/nvidia/tegra/gpio.c index f834cd2b37..06153203b7 100644 --- a/src/soc/nvidia/tegra/gpio.c +++ b/src/soc/nvidia/tegra/gpio.c @@ -26,25 +26,25 @@ #include "gpio.h" #include "pinmux.h" -void __gpio_input(int gpio_index, int pinmux_index, u32 pull) +void __gpio_input(gpio_t gpio, u32 pull) { u32 pinmux_config = PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | pull; - gpio_set_int_enable(gpio_index, 0); - gpio_set_out_enable(gpio_index, 0); - gpio_set_mode(gpio_index, GPIO_MODE_GPIO); - pinmux_set_config(pinmux_index, pinmux_config); + gpio_set_int_enable(gpio, 0); + gpio_set_out_enable(gpio, 0); + gpio_set_mode(gpio, GPIO_MODE_GPIO); + pinmux_set_config(gpio >> GPIO_PINMUX_SHIFT, pinmux_config); } -void __gpio_output(int gpio_index, int pinmux_index, int value) +void gpio_output(gpio_t gpio, int value) { /* TODO: Set OPEN_DRAIN based on what pin it is? */ - gpio_set_int_enable(gpio_index, 0); - gpio_set_out_value(gpio_index, value); - gpio_set_out_enable(gpio_index, 1); - gpio_set_mode(gpio_index, GPIO_MODE_GPIO); - pinmux_set_config(pinmux_index, PINMUX_PULL_NONE); + gpio_set_int_enable(gpio, 0); + gpio_set_out_value(gpio, value); + gpio_set_out_enable(gpio, 1); + gpio_set_mode(gpio, GPIO_MODE_GPIO); + pinmux_set_config(gpio >> GPIO_PINMUX_SHIFT, PINMUX_PULL_NONE); } enum { @@ -104,120 +104,127 @@ static void gpio_write_port(int index, size_t offset, u32 mask, u32 value) } } -void gpio_set_mode(int gpio_index, enum gpio_mode mode) +void gpio_set_mode(gpio_t gpio, enum gpio_mode mode) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, config), + int bit = gpio % GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, config), 1 << bit, mode ? (1 << bit) : 0); } -int gpio_get_mode(int gpio_index) +int gpio_get_mode(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, config)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, config)); return (port & (1 << bit)) != 0; } -void gpio_set_lock(int gpio_index) +void gpio_set_lock(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, config), + int bit = gpio % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, config), 1 << bit, 1 << bit); } -int gpio_get_lock(int gpio_index) +int gpio_get_lock(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, config)); + int bit = gpio % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, config)); return (port & (1 << bit)) != 0; } -void gpio_set_out_enable(int gpio_index, int enable) +void gpio_set_out_enable(gpio_t gpio, int enable) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, out_enable), + int bit = gpio % GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, out_enable), 1 << bit, enable ? (1 << bit) : 0); } -int gpio_get_out_enable(int gpio_index) +int gpio_get_out_enable(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, out_enable)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, out_enable)); return (port & (1 << bit)) != 0; } -void gpio_set_out_value(int gpio_index, int value) +void gpio_set_out_value(gpio_t gpio, int value) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, out_value), + int bit = gpio % GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, out_value), 1 << bit, value ? (1 << bit) : 0); } -int gpio_get_out_value(int gpio_index) +int gpio_get_out_value(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, out_value)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, out_value)); return (port & (1 << bit)) != 0; } -int gpio_get_in_value(int gpio_index) +int gpio_get_in_value(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, in_value)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, in_value)); return (port & (1 << bit)) != 0; } -int gpio_get_int_status(int gpio_index) +int gpio_get_int_status(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, int_status)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, int_status)); return (port & (1 << bit)) != 0; } -void gpio_set_int_enable(int gpio_index, int enable) +void gpio_set_int_enable(gpio_t gpio, int enable) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, int_enable), + int bit = gpio % GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, int_enable), 1 << bit, enable ? (1 << bit) : 0); } -int gpio_get_int_enable(int gpio_index) +int gpio_get_int_enable(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, int_enable)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, int_enable)); return (port & (1 << bit)) != 0; } -void gpio_set_int_level(int gpio_index, int high_rise, int edge, int delta) +void gpio_set_int_level(gpio_t gpio, int high_rise, int edge, int delta) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; + int bit = gpio % GPIO_GPIOS_PER_PORT; u32 value = (high_rise ? (0x000001 << bit) : 0) | (edge ? (0x000100 << bit) : 0) | - (delta ? (0x010000 << bit) : 0); - gpio_write_port(gpio_index, offsetof(struct gpio_bank, config), + (delta ? (0x010000 << bit) : 0); + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, config), 0x010101 << bit, value); } -void gpio_get_int_level(int gpio_index, int *high_rise, int *edge, int *delta) +void gpio_get_int_level(gpio_t gpio, int *high_rise, int *edge, int *delta) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - u32 port = gpio_read_port(gpio_index, - offsetof(struct gpio_bank, int_level)); + int bit = gpio % GPIO_GPIOS_PER_PORT; + u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, int_level)); *high_rise = ((port & (0x000001 << bit)) != 0); *edge = ((port & (0x000100 << bit)) != 0); *delta = ((port & (0x010000 << bit)) != 0); } -void gpio_set_int_clear(int gpio_index) +void gpio_set_int_clear(gpio_t gpio) { - int bit = gpio_index % GPIO_GPIOS_PER_PORT; - gpio_write_port(gpio_index, offsetof(struct gpio_bank, int_clear), + int bit = gpio % GPIO_GPIOS_PER_PORT; + gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1), + offsetof(struct gpio_bank, int_clear), 1 << bit, 1 << bit); } diff --git a/src/soc/nvidia/tegra/gpio.h b/src/soc/nvidia/tegra/gpio.h index 71a552e870..546ea05030 100644 --- a/src/soc/nvidia/tegra/gpio.h +++ b/src/soc/nvidia/tegra/gpio.h @@ -22,20 +22,34 @@ #include +#include "pinmux.h" + +/* Wrapper type for GPIOs. Always use GPIO() macro to generate. */ +typedef u32 gpio_t; + +#define GPIO_PINMUX_SHIFT 16 +#define GPIO(name) ((gpio_t)(GPIO_##name##_INDEX | \ + (PINMUX_GPIO_##name << GPIO_PINMUX_SHIFT))) + /* Higher level function wrappers for common GPIO configurations. */ -#define gpio_input(gpio_enum) __gpio_input(gpio_enum, \ - PINMUX_##gpio_enum, PINMUX_PULL_NONE) -#define gpio_input_pulldown(gpio_enum) __gpio_input(gpio_enum, \ - PINMUX_##gpio_enum, PINMUX_PULL_DOWN) -#define gpio_input_pullup(gpio_enum) __gpio_input(gpio_enum, \ - PINMUX_##gpio_enum, PINMUX_PULL_UP) +void gpio_output(gpio_t gpio, int value); +void __gpio_input(gpio_t gpio, u32 pull); -#define gpio_output(gpio_enum, value) __gpio_output(gpio_enum, \ - PINMUX_##gpio_enum, value) +static inline void gpio_input(gpio_t gpio) +{ + __gpio_input(gpio, PINMUX_PULL_NONE); +} -void __gpio_input(int gpio_index, int pinmux_index, u32 pull); -void __gpio_output(int gpio_index, int pinmux_index, int value); +static inline void gpio_input_pulldown(gpio_t gpio) +{ + __gpio_input(gpio, PINMUX_PULL_DOWN); +} + +static inline void gpio_input_pullup(gpio_t gpio) +{ + __gpio_input(gpio, PINMUX_PULL_UP); +} /* Functions to modify specific GPIO control values. */ @@ -43,29 +57,29 @@ enum gpio_mode { GPIO_MODE_SPIO = 0, GPIO_MODE_GPIO = 1 }; -void gpio_set_mode(int gpio_index, enum gpio_mode); -int gpio_get_mode(int gpio_index); +void gpio_set_mode(gpio_t gpio, enum gpio_mode); +int gpio_get_mode(gpio_t gpio); // Lock a GPIO with extreme caution since they can't be unlocked. -void gpio_set_lock(int gpio_index); -int gpio_get_lock(int gpio_index); +void gpio_set_lock(gpio_t gpio); +int gpio_get_lock(gpio_t gpio); -void gpio_set_out_enable(int gpio_index, int enable); -int gpio_get_out_enable(int gpio_index); +void gpio_set_out_enable(gpio_t gpio, int enable); +int gpio_get_out_enable(gpio_t gpio); -void gpio_set_out_value(int gpio_index, int value); -int gpio_get_out_value(int gpio_index); +void gpio_set_out_value(gpio_t gpio, int value); +int gpio_get_out_value(gpio_t gpio); -int gpio_get_in_value(int gpio_index); +int gpio_get_in_value(gpio_t gpio); -int gpio_get_int_status(int gpio_index); +int gpio_get_int_status(gpio_t gpio); -void gpio_set_int_enable(int gpio_index, int enable); -int gpio_get_int_enable(int gpio_index); +void gpio_set_int_enable(gpio_t gpio, int enable); +int gpio_get_int_enable(gpio_t gpio); -void gpio_set_int_level(int gpio_index, int high_rise, int edge, int delta); -void gpio_get_int_level(int gpio_index, int *high_rise, int *edge, int *delta); +void gpio_set_int_level(gpio_t gpio, int high_rise, int edge, int delta); +void gpio_get_int_level(gpio_t gpio, int *high_rise, int *edge, int *delta); -void gpio_set_int_clear(int gpio_index); +void gpio_set_int_clear(gpio_t gpio); #endif /* __SOC_NVIDIA_TEGRA_GPIO_H__ */ diff --git a/src/soc/nvidia/tegra124/gpio.h b/src/soc/nvidia/tegra124/gpio.h index 64e5fad0d9..f7d1c3006a 100644 --- a/src/soc/nvidia/tegra124/gpio.h +++ b/src/soc/nvidia/tegra124/gpio.h @@ -23,13 +23,14 @@ #include #include -#include "pinmux.h" /* for pinmux constants in GPIO macros */ +#include "pinmux.h" /* for pinmux constants in GPIO macro */ /* GPIO index constants. */ #define GPIO_PORT_CONSTANTS(port) \ - GPIO_##port##0, GPIO_##port##1, GPIO_##port##2, GPIO_##port##3, \ - GPIO_##port##4, GPIO_##port##5, GPIO_##port##6, GPIO_##port##7 + GPIO_##port##0_INDEX, GPIO_##port##1_INDEX, GPIO_##port##2_INDEX, \ + GPIO_##port##3_INDEX, GPIO_##port##4_INDEX, GPIO_##port##5_INDEX, \ + GPIO_##port##6_INDEX, GPIO_##port##7_INDEX enum { GPIO_PORT_CONSTANTS(A),