summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-12-17 19:43:32 +0000
committerkettenis <kettenis@openbsd.org>2020-12-17 19:43:32 +0000
commitb055cb5ca82fbca5d190eb0776b4b7613cb0912b (patch)
tree909a2d470c923e5a73c02eb3512ebe06f00f5475
parentFix some issues with referencing named ACPI nodes from Packages. (diff)
downloadwireguard-openbsd-b055cb5ca82fbca5d190eb0776b4b7613cb0912b.tar.xz
wireguard-openbsd-b055cb5ca82fbca5d190eb0776b4b7613cb0912b.zip
Add support for the "Always On" GPIOs.
-rw-r--r--sys/dev/fdt/amlpinctrl.c261
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);
}