diff options
author | 2020-12-17 19:43:32 +0000 | |
---|---|---|
committer | 2020-12-17 19:43:32 +0000 | |
commit | b055cb5ca82fbca5d190eb0776b4b7613cb0912b (patch) | |
tree | 909a2d470c923e5a73c02eb3512ebe06f00f5475 | |
parent | Fix some issues with referencing named ACPI nodes from Packages. (diff) | |
download | wireguard-openbsd-b055cb5ca82fbca5d190eb0776b4b7613cb0912b.tar.xz wireguard-openbsd-b055cb5ca82fbca5d190eb0776b4b7613cb0912b.zip |
Add support for the "Always On" GPIOs.
-rw-r--r-- | sys/dev/fdt/amlpinctrl.c | 261 |
1 files changed, 188 insertions, 73 deletions
diff --git a/sys/dev/fdt/amlpinctrl.c b/sys/dev/fdt/amlpinctrl.c index 046a7364441..644177e7e9f 100644 --- a/sys/dev/fdt/amlpinctrl.c +++ b/sys/dev/fdt/amlpinctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: amlpinctrl.c,v 1.5 2019/10/06 16:17:06 kettenis Exp $ */ +/* $OpenBSD: amlpinctrl.c,v 1.6 2020/12/17 19:43:32 kettenis Exp $ */ /* * Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org> * @@ -71,6 +71,12 @@ #define GPIOX_17 82 #define GPIOX_18 83 +#define GPIOAO_0 0 +#define GPIOAO_1 1 +#define GPIOAO_5 5 +#define GPIOE_0 12 +#define GPIOE_1 13 + #define PERIPHS_PIN_MUX_0 0xb0 #define PERIPHS_PIN_MUX_3 0xb3 #define PERIPHS_PIN_MUX_6 0xb6 @@ -78,11 +84,23 @@ #define PERIPHS_PIN_MUX_B 0xbb #define PERIPHS_PIN_MUX_D 0xbd #define PREG_PAD_GPIO0_EN_N 0x10 +#define PREG_PAD_GPIO0_O 0x11 +#define PREG_PAD_GPIO0_I 0x12 #define PREG_PAD_GPIO1_EN_N 0x13 +#define PREG_PAD_GPIO1_O 0x14 +#define PREG_PAD_GPIO1_I 0x15 #define PREG_PAD_GPIO2_EN_N 0x16 +#define PREG_PAD_GPIO2_O 0x16 +#define PREG_PAD_GPIO2_I 0x18 #define PREG_PAD_GPIO3_EN_N 0x19 +#define PREG_PAD_GPIO3_O 0x1a +#define PREG_PAD_GPIO3_I 0x1b #define PREG_PAD_GPIO4_EN_N 0x1c +#define PREG_PAD_GPIO4_O 0x1d +#define PREG_PAD_GPIO4_I 0x1e #define PREG_PAD_GPIO5_EN_N 0x20 +#define PREG_PAD_GPIO5_O 0x21 +#define PREG_PAD_GPIO5_I 0x22 #define PAD_PULL_UP_EN_0 0x48 #define PAD_PULL_UP_EN_1 0x49 #define PAD_PULL_UP_EN_2 0x4a @@ -102,13 +120,25 @@ #define PAD_DS_4A 0xd5 #define PAD_DS_5A 0xd6 +#define AO_RTI_PINMUX_0 0x05 +#define AO_RTI_PINMUX_1 0x06 +#define AO_PAD_DS_A 0x07 +#define AO_PAD_DS_B 0x08 +#define AO_GPIO_O_EN_N 0x09 +#define AO_GPIO_I 0x0a +#define AO_GPIO_O 0x0d +#define AO_RTI_PULL_UP 0x0b +#define AO_RTI_PULL_UP_EN 0x0c + struct aml_gpio_bank { uint8_t first_pin, num_pins; - uint8_t mux_reg; - uint8_t gpio_reg; - uint8_t pull_reg; - uint8_t pull_en_reg; - uint8_t ds_reg; + uint8_t mux_reg, mux_bit; + uint8_t dir_reg, dir_bit; + uint8_t in_reg, in_bit; + uint8_t out_reg, out_bit; + uint8_t pull_reg, pull_bit; + uint8_t pull_en_reg, pull_en_bit; + uint8_t ds_reg, ds_bit; }; struct aml_pin_group { @@ -120,40 +150,64 @@ struct aml_pin_group { struct aml_gpio_bank aml_g12a_gpio_banks[] = { /* BOOT */ - { BOOT_0, 16, PERIPHS_PIN_MUX_0 - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO0_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_0 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_0 - PAD_PULL_UP_EN_0, PAD_DS_0A - PAD_DS_0A }, + { BOOT_0, 16, + PERIPHS_PIN_MUX_0 - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO0_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO0_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO0_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_0 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_0 - PAD_PULL_UP_EN_0, 0, + PAD_DS_0A - PAD_DS_0A, 0 }, /* GPIOC */ - { GPIOC_0, 8, PERIPHS_PIN_MUX_9 - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO1_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_1 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_1 - PAD_PULL_UP_EN_0, PAD_DS_1A - PAD_DS_0A }, + { GPIOC_0, 8, + PERIPHS_PIN_MUX_9 - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO1_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO1_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO1_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_1 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_1 - PAD_PULL_UP_EN_0, 0, + PAD_DS_1A - PAD_DS_0A, 0 }, /* GPIOX */ - { GPIOX_0, 20, PERIPHS_PIN_MUX_3 - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO2_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_2 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_2 - PAD_PULL_UP_EN_0, PAD_DS_2A - PAD_DS_0A }, + { GPIOX_0, 20, + PERIPHS_PIN_MUX_3 - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO2_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO2_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO2_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_2 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_2 - PAD_PULL_UP_EN_0, 0, + PAD_DS_2A - PAD_DS_0A, 0 }, /* GPIOH */ - { GPIOH_0, 9, PERIPHS_PIN_MUX_B - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO3_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_3 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_3 - PAD_PULL_UP_EN_0, PAD_DS_3A - PAD_DS_0A }, + { GPIOH_0, 9, + PERIPHS_PIN_MUX_B - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO3_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO3_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO3_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_3 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_3 - PAD_PULL_UP_EN_0, 0, + PAD_DS_3A - PAD_DS_0A, 0 }, /* GPIOZ */ - { GPIOZ_0, 16, PERIPHS_PIN_MUX_6 - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO4_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_4 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_4 - PAD_PULL_UP_EN_0, PAD_DS_4A - PAD_DS_0A }, + { GPIOZ_0, 16, + PERIPHS_PIN_MUX_6 - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO4_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO4_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO4_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_4 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_4 - PAD_PULL_UP_EN_0, 0, + PAD_DS_4A - PAD_DS_0A, 0 }, /* GPIOA */ - { GPIOA_0, 16, PERIPHS_PIN_MUX_D - PERIPHS_PIN_MUX_0, - PREG_PAD_GPIO5_EN_N - PREG_PAD_GPIO0_EN_N, - PAD_PULL_UP_5 - PAD_PULL_UP_0, - PAD_PULL_UP_EN_5 - PAD_PULL_UP_EN_0, PAD_DS_5A - PAD_DS_0A }, + { GPIOA_0, 16, + PERIPHS_PIN_MUX_D - PERIPHS_PIN_MUX_0, 0, + PREG_PAD_GPIO5_EN_N - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO5_I - PREG_PAD_GPIO0_EN_N, 0, + PREG_PAD_GPIO5_O - PREG_PAD_GPIO0_EN_N, 0, + PAD_PULL_UP_5 - PAD_PULL_UP_0, 0, + PAD_PULL_UP_EN_5 - PAD_PULL_UP_EN_0, 0, + PAD_DS_5A - PAD_DS_0A, 0 }, { } }; @@ -213,6 +267,42 @@ struct aml_pin_group aml_g12a_pin_groups[] = { { } }; +struct aml_gpio_bank aml_g12a_ao_gpio_banks[] = { + /* GPIOAO */ + { GPIOAO_0, 12, + AO_RTI_PINMUX_0 - AO_RTI_PINMUX_0, 0, + AO_GPIO_O_EN_N - AO_GPIO_O_EN_N, 0, + AO_GPIO_I - AO_GPIO_O_EN_N, 0, + AO_GPIO_O - AO_GPIO_O_EN_N, 0, + AO_RTI_PULL_UP - AO_RTI_PULL_UP, 0, + AO_RTI_PULL_UP_EN - AO_RTI_PULL_UP_EN, 0, + AO_PAD_DS_A - AO_PAD_DS_A, 0 }, + + /* GPIOE */ + { GPIOE_0, 3, + AO_RTI_PINMUX_1 - AO_RTI_PINMUX_0, 16, + AO_GPIO_O_EN_N - AO_GPIO_O_EN_N, 16, + AO_GPIO_I - AO_GPIO_O_EN_N, 16, + AO_GPIO_O - AO_GPIO_O_EN_N, 16, + AO_RTI_PULL_UP - AO_RTI_PULL_UP, 16, + AO_RTI_PULL_UP_EN - AO_RTI_PULL_UP_EN, 16, + AO_PAD_DS_B - AO_PAD_DS_A, 0 }, + + { } +}; + +struct aml_pin_group aml_g12a_ao_pin_groups[] = { + /* GPIOAO */ + { "uart_ao_a_tx", GPIOAO_0, 1, "uart_ao_a" }, + { "uart_ao_a_rx", GPIOAO_1, 1, "uart_ao_a" }, + { "remote_ao_input", GPIOAO_5, 1, "remote_ao_input" }, + + /* GPIOE */ + { "pwm_ao_d_e", GPIOE_1, 3, "pwm_ao_d" }, + + { } +}; + struct amlpinctrl_softc { struct device sc_dev; bus_space_tag_t sc_iot; @@ -221,6 +311,7 @@ struct amlpinctrl_softc { bus_space_handle_t sc_pull_en_ioh; bus_space_handle_t sc_mux_ioh; bus_space_handle_t sc_ds_ioh; + int sc_nobias; struct aml_gpio_bank *sc_gpio_banks; struct aml_pin_group *sc_pin_groups; @@ -250,7 +341,8 @@ amlpinctrl_match(struct device *parent, void *match, void *aux) struct fdt_attach_args *faa = aux; int node = faa->fa_node; - return OF_is_compatible(node, "amlogic,meson-g12a-periphs-pinctrl"); + return (OF_is_compatible(node, "amlogic,meson-g12a-periphs-pinctrl") || + OF_is_compatible(node, "amlogic,meson-g12a-aobus-pinctrl")); } void @@ -285,6 +377,7 @@ amlpinctrl_attach(struct device *parent, struct device *self, void *aux) return; } + memset(&size, 0, sizeof(size)); OF_getpropintarray(child, "reg", reg, len); for (i = 0, cell = reg; i < len / line; i++) { addr[i] = cell[0]; @@ -298,31 +391,51 @@ amlpinctrl_attach(struct device *parent, struct device *self, void *aux) } sc->sc_iot = faa->fa_iot; - if (bus_space_map(sc->sc_iot, addr[0], size[0], 0, &sc->sc_gpio_ioh)) { + + i = OF_getindex(child, "gpio", "reg-names"); + if (i < 0 || i >= nitems(size) || size[i] == 0 || + bus_space_map(sc->sc_iot, addr[i], size[i], 0, &sc->sc_gpio_ioh)) { printf(": can't map gpio registers\n"); return; } - if (bus_space_map(sc->sc_iot, addr[1], size[1], 0, &sc->sc_pull_ioh)) { - printf(": can't map pull registers\n"); + i = OF_getindex(child, "mux", "reg-names"); + if (i < 0 || i >= nitems(size) || size[i] == 0 || + bus_space_map(sc->sc_iot, addr[i], size[i], 0, &sc->sc_mux_ioh)) { + printf(": can't map mux registers\n"); return; } - if (bus_space_map(sc->sc_iot, addr[2], size[2], 0, &sc->sc_pull_en_ioh)) { - printf(": can't map pull-enable registers\n"); + i = OF_getindex(child, "ds", "reg-names"); + if (i < 0 || i >= nitems(size) || size[i] == 0 || + bus_space_map(sc->sc_iot, addr[i], size[i], 0, &sc->sc_ds_ioh)) { + printf(": can't map ds registers\n"); return; } - if (bus_space_map(sc->sc_iot, addr[3], size[3], 0, &sc->sc_mux_ioh)) { - printf(": can't map mux registers\n"); + i = OF_getindex(child, "pull", "reg-names"); + if (i < 0) + sc->sc_nobias = 1; + else if (i >= nitems(size) || size[i] == 0 || + bus_space_map(sc->sc_iot, addr[i], size[i], 0, &sc->sc_pull_ioh)) { + printf(": can't map pull registers\n"); return; } - if (bus_space_map(sc->sc_iot, addr[4], size[4], 0, &sc->sc_ds_ioh)) { - printf(": can't map ds registers\n"); + i = OF_getindex(child, "pull-enable", "reg-names"); + if (i < 0) + sc->sc_nobias = 1; + else if (i >= nitems(size) || size[i] == 0 || + bus_space_map(sc->sc_iot, addr[i], size[i], 0, &sc->sc_pull_en_ioh)) { + printf(": can't map pull-enable registers\n"); return; } printf("\n"); - sc->sc_gpio_banks = aml_g12a_gpio_banks; - sc->sc_pin_groups = aml_g12a_pin_groups; + if (OF_is_compatible(node, "amlogic,meson-g12a-periphs-pinctrl")) { + sc->sc_gpio_banks = aml_g12a_gpio_banks; + sc->sc_pin_groups = aml_g12a_pin_groups; + } else { + sc->sc_gpio_banks = aml_g12a_ao_gpio_banks; + sc->sc_pin_groups = aml_g12a_ao_pin_groups; + } pinctrl_register(faa->fa_node, amlpinctrl_pinctrl, sc); @@ -389,27 +502,29 @@ amlpinctrl_config_func(struct amlpinctrl_softc *sc, const char *name, /* mux */ off = (bank->mux_reg + pin / 8) << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_mux_ioh, off); - reg &= ~(0xf << ((pin % 8) * 4)); - reg |= (group->func << ((pin % 8) * 4)); + reg &= ~(0xf << (((pin % 8) * 4) + bank->mux_bit)); + reg |= (group->func << (((pin % 8) * 4) + bank->mux_bit)); bus_space_write_4(sc->sc_iot, sc->sc_mux_ioh, off, reg); - - /* pull */ - off = bank->pull_reg << 2; - reg = bus_space_read_4(sc->sc_iot, sc->sc_pull_ioh, off); - if (bias == BIAS_PULL_UP) - reg |= (1 << pin); - else - reg &= ~(1 << pin); - bus_space_write_4(sc->sc_iot, sc->sc_pull_ioh, off, reg); - - /* pull-enable */ - off = bank->pull_en_reg << 2; - reg = bus_space_read_4(sc->sc_iot, sc->sc_pull_en_ioh, off); - if (bias != BIAS_DISABLE) - reg |= (1 << pin); - else - reg &= ~(1 << pin); - bus_space_write_4(sc->sc_iot, sc->sc_pull_en_ioh, off, reg); + + if (!sc->sc_nobias) { + /* pull */ + off = bank->pull_reg << 2; + reg = bus_space_read_4(sc->sc_iot, sc->sc_pull_ioh, off); + if (bias == BIAS_PULL_UP) + reg |= (1 << (pin + bank->pull_bit)); + else + reg &= ~(1 << (pin + bank->pull_bit)); + bus_space_write_4(sc->sc_iot, sc->sc_pull_ioh, off, reg); + + /* pull-enable */ + off = bank->pull_en_reg << 2; + reg = bus_space_read_4(sc->sc_iot, sc->sc_pull_en_ioh, off); + if (bias != BIAS_DISABLE) + reg |= (1 << (pin + bank->pull_en_bit)); + else + reg &= ~(1 << (pin + bank->pull_en_bit)); + bus_space_write_4(sc->sc_iot, sc->sc_pull_en_ioh, off, reg); + } if (ds < 0) return; @@ -429,8 +544,8 @@ amlpinctrl_config_func(struct amlpinctrl_softc *sc, const char *name, /* ds */ off = (bank->ds_reg + pin / 16) << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_ds_ioh, off); - reg &= ~(0x3 << ((pin % 16) * 2)); - reg |= (ds << ((pin % 16) * 2)); + reg &= ~(0x3 << (((pin % 16) * 2) + bank->ds_bit)); + reg |= (ds << (((pin % 16) * 2) + bank->ds_bit)); bus_space_write_4(sc->sc_iot, sc->sc_ds_ioh, off, reg); } @@ -507,16 +622,16 @@ amlpinctrl_config_pin(void *cookie, uint32_t *cells, int config) /* mux */ off = (bank->mux_reg + pin / 8) << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_mux_ioh, off); - reg &= ~(0xf << ((pin % 8) * 4)); + reg &= ~(0xf << (((pin % 8) * 4) + bank->mux_bit)); bus_space_write_4(sc->sc_iot, sc->sc_mux_ioh, off, reg); /* gpio */ - off = bank->gpio_reg << 2; + off = bank->dir_reg << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, off); if (config & GPIO_CONFIG_OUTPUT) - reg &= ~(1 << pin); + reg &= ~(1 << (pin + bank->dir_bit)); else - reg |= (1 << pin); + reg |= (1 << (pin + bank->dir_bit)); bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, off, reg); } @@ -540,9 +655,9 @@ amlpinctrl_get_pin(void *cookie, uint32_t *cells) pin = pin - bank->first_pin; /* gpio */ - off = (bank->gpio_reg + 2) << 2; + off = bank->in_reg << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, off); - val = (reg >> pin) & 1; + val = (reg >> (pin + bank->in_bit)) & 1; if (flags & GPIO_ACTIVE_LOW) val = !val; @@ -571,11 +686,11 @@ amlpinctrl_set_pin(void *cookie, uint32_t *cells, int val) pin = pin - bank->first_pin; /* gpio */ - off = (bank->gpio_reg + 1) << 2; + off = bank->out_reg << 2; reg = bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, off); if (val) - reg |= (1 << pin); + reg |= (1 << (pin + bank->out_bit)); else - reg &= ~(1 << pin); + reg &= ~(1 << (pin + bank->out_bit)); bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, off, reg); } |