diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/clk_meson.c | 6 | ||||
-rw-r--r-- | drivers/clk/clk_meson_axg.c | 316 | ||||
-rw-r--r-- | drivers/mmc/meson_gx_mmc.c | 1 | ||||
-rw-r--r-- | drivers/net/designware.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/meson/Kconfig | 18 | ||||
-rw-r--r-- | drivers/pinctrl/meson/Makefile | 3 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c | 125 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-axg.c | 979 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-axg.h | 66 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c | 97 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-gx.h | 48 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 6 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson-gxl.c | 6 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson.c | 109 | ||||
-rw-r--r-- | drivers/pinctrl/meson/pinctrl-meson.h | 37 |
16 files changed, 1695 insertions, 126 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index c128538..9acbb1a 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -9,8 +9,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o obj-y += imx/ obj-y += tegra/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ -obj-$(CONFIG_ARCH_MESON) += clk_meson.o obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +obj-$(CONFIG_ARCH_MESON) += clk_meson.o clk_meson_axg.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_ARCH_SOCFPGA) += altera/ obj-$(CONFIG_CLK_AT91) += at91/ diff --git a/drivers/clk/clk_meson.c b/drivers/clk/clk_meson.c index c448588..0df8b91 100644 --- a/drivers/clk/clk_meson.c +++ b/drivers/clk/clk_meson.c @@ -6,7 +6,7 @@ */ #include <common.h> -#include <asm/arch/clock.h> +#include <asm/arch/clock-gx.h> #include <asm/io.h> #include <clk-uclass.h> #include <div64.h> @@ -79,7 +79,7 @@ static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id, static ulong meson_mux_get_parent(struct clk *clk, unsigned long id); static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id); -struct meson_gate gates[] = { +static struct meson_gate gates[] = { /* Everything Else (EE) domain gates */ MESON_GATE(CLKID_DDR, HHI_GCLK_MPEG0, 0), MESON_GATE(CLKID_DOS, HHI_GCLK_MPEG0, 1), @@ -791,7 +791,7 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) return -ENOENT; } - printf("clock %lu has rate %lu\n", id, rate); + debug("clock %lu has rate %lu\n", id, rate); return rate; } diff --git a/drivers/clk/clk_meson_axg.c b/drivers/clk/clk_meson_axg.c new file mode 100644 index 0000000..32cbf75 --- /dev/null +++ b/drivers/clk/clk_meson_axg.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com> + * (C) Copyright 2018 - BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + */ + +#include <common.h> +#include <asm/arch/clock-axg.h> +#include <asm/io.h> +#include <clk-uclass.h> +#include <dm.h> +#include <regmap.h> +#include <syscon.h> +#include <div64.h> +#include <dt-bindings/clock/axg-clkc.h> +#include "clk_meson.h" + +#define XTAL_RATE 24000000 + +struct meson_clk { + struct regmap *map; +}; + +static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id); + +static struct meson_gate gates[] = { + /* Everything Else (EE) domain gates */ + MESON_GATE(CLKID_SPICC0, HHI_GCLK_MPEG0, 8), + MESON_GATE(CLKID_I2C, HHI_GCLK_MPEG0, 9), + MESON_GATE(CLKID_UART0, HHI_GCLK_MPEG0, 13), + MESON_GATE(CLKID_SPICC1, HHI_GCLK_MPEG0, 15), + MESON_GATE(CLKID_SD_EMMC_B, HHI_GCLK_MPEG0, 25), + MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26), + MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3), + MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16), + + /* Always On (AO) domain gates */ + MESON_GATE(CLKID_AO_I2C, HHI_GCLK_AO, 4), + + /* PLL Gates */ + /* CLKID_FCLK_DIV2 is critical for the SCPI Processor */ + MESON_GATE(CLKID_MPLL2, HHI_MPLL_CNTL9, 14), + /* CLKID_CLK81 is critical for the system */ + + /* Peripheral Gates */ + MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23), + MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7), +}; + +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT; + + gate = &gates[clk->id]; + + if (gate->reg == 0) + return 0; + + regmap_update_bits(priv->map, gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{ + return meson_set_gate(clk, false); +} + +static unsigned long meson_clk81_get_rate(struct clk *clk) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + unsigned long parent_rate; + uint reg; + int parents[] = { + -1, + -1, + CLKID_FCLK_DIV7, + CLKID_MPLL1, + CLKID_MPLL2, + CLKID_FCLK_DIV4, + CLKID_FCLK_DIV3, + CLKID_FCLK_DIV5 + }; + + /* mux */ + regmap_read(priv->map, HHI_MPEG_CLK_CNTL, ®); + reg = (reg >> 12) & 7; + + switch (reg) { + case 0: + parent_rate = XTAL_RATE; + break; + case 1: + return -ENOENT; + default: + parent_rate = meson_clk_get_rate_by_id(clk, parents[reg]); + } + + /* divider */ + regmap_read(priv->map, HHI_MPEG_CLK_CNTL, ®); + reg = reg & ((1 << 7) - 1); + + return parent_rate / reg; +} + +static long mpll_rate_from_params(unsigned long parent_rate, + unsigned long sdm, + unsigned long n2) +{ + unsigned long divisor = (SDM_DEN * n2) + sdm; + + if (n2 < N2_MIN) + return -EINVAL; + + return DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, divisor); +} + +static struct parm meson_mpll0_parm[3] = { + {HHI_MPLL_CNTL7, 0, 14}, /* psdm */ + {HHI_MPLL_CNTL7, 16, 9}, /* pn2 */ +}; + +static struct parm meson_mpll1_parm[3] = { + {HHI_MPLL_CNTL8, 0, 14}, /* psdm */ + {HHI_MPLL_CNTL8, 16, 9}, /* pn2 */ +}; + +static struct parm meson_mpll2_parm[3] = { + {HHI_MPLL_CNTL9, 0, 14}, /* psdm */ + {HHI_MPLL_CNTL9, 16, 9}, /* pn2 */ +}; + +/* + * MultiPhase Locked Loops are outputs from a PLL with additional frequency + * scaling capabilities. MPLL rates are calculated as: + * + * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384) + */ +static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct parm *psdm, *pn2; + unsigned long sdm, n2; + unsigned long parent_rate; + uint reg; + + switch (id) { + case CLKID_MPLL0: + psdm = &meson_mpll0_parm[0]; + pn2 = &meson_mpll0_parm[1]; + break; + case CLKID_MPLL1: + psdm = &meson_mpll1_parm[0]; + pn2 = &meson_mpll1_parm[1]; + break; + case CLKID_MPLL2: + psdm = &meson_mpll2_parm[0]; + pn2 = &meson_mpll2_parm[1]; + break; + default: + return -ENOENT; + } + + parent_rate = meson_clk_get_rate_by_id(clk, CLKID_FIXED_PLL); + if (IS_ERR_VALUE(parent_rate)) + return parent_rate; + + regmap_read(priv->map, psdm->reg_off, ®); + sdm = PARM_GET(psdm->width, psdm->shift, reg); + + regmap_read(priv->map, pn2->reg_off, ®); + n2 = PARM_GET(pn2->width, pn2->shift, reg); + + return mpll_rate_from_params(parent_rate, sdm, n2); +} + +static struct parm meson_fixed_pll_parm[3] = { + {HHI_MPLL_CNTL, 0, 9}, /* pm */ + {HHI_MPLL_CNTL, 9, 5}, /* pn */ + {HHI_MPLL_CNTL, 16, 2}, /* pod */ +}; + +static struct parm meson_sys_pll_parm[3] = { + {HHI_SYS_PLL_CNTL, 0, 9}, /* pm */ + {HHI_SYS_PLL_CNTL, 9, 5}, /* pn */ + {HHI_SYS_PLL_CNTL, 16, 2}, /* pod */ +}; + +static ulong meson_pll_get_rate(struct clk *clk, unsigned long id) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct parm *pm, *pn, *pod; + unsigned long parent_rate_mhz = XTAL_RATE / 1000000; + u16 n, m, od; + uint reg; + + switch (id) { + case CLKID_FIXED_PLL: + pm = &meson_fixed_pll_parm[0]; + pn = &meson_fixed_pll_parm[1]; + pod = &meson_fixed_pll_parm[2]; + break; + case CLKID_SYS_PLL: + pm = &meson_sys_pll_parm[0]; + pn = &meson_sys_pll_parm[1]; + pod = &meson_sys_pll_parm[2]; + break; + default: + return -ENOENT; + } + + regmap_read(priv->map, pn->reg_off, ®); + n = PARM_GET(pn->width, pn->shift, reg); + + regmap_read(priv->map, pm->reg_off, ®); + m = PARM_GET(pm->width, pm->shift, reg); + + regmap_read(priv->map, pod->reg_off, ®); + od = PARM_GET(pod->width, pod->shift, reg); + + return ((parent_rate_mhz * m / n) >> od) * 1000000; +} + +static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id) +{ + ulong rate; + + switch (id) { + case CLKID_FIXED_PLL: + case CLKID_SYS_PLL: + rate = meson_pll_get_rate(clk, id); + break; + case CLKID_FCLK_DIV2: + rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2; + break; + case CLKID_FCLK_DIV3: + rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3; + break; + case CLKID_FCLK_DIV4: + rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4; + break; + case CLKID_FCLK_DIV5: + rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5; + break; + case CLKID_FCLK_DIV7: + rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7; + break; + case CLKID_MPLL0: + case CLKID_MPLL1: + case CLKID_MPLL2: + rate = meson_mpll_get_rate(clk, id); + break; + case CLKID_CLK81: + rate = meson_clk81_get_rate(clk); + break; + default: + if (gates[id].reg != 0) { + /* a clock gate */ + rate = meson_clk81_get_rate(clk); + break; + } + return -ENOENT; + } + + debug("clock %lu has rate %lu\n", id, rate); + return rate; +} + +static ulong meson_clk_get_rate(struct clk *clk) +{ + return meson_clk_get_rate_by_id(clk, clk->id); +} + +static int meson_clk_probe(struct udevice *dev) +{ + struct meson_clk *priv = dev_get_priv(dev); + + priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node); + if (IS_ERR(priv->map)) + return PTR_ERR(priv->map); + + debug("meson-clk-axg: probed\n"); + + return 0; +} + +static struct clk_ops meson_clk_ops = { + .disable = meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, +}; + +static const struct udevice_id meson_clk_ids[] = { + { .compatible = "amlogic,axg-clkc" }, + { } +}; + +U_BOOT_DRIVER(meson_clk_axg) = { + .name = "meson_clk_axg", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto_alloc_size = sizeof(struct meson_clk), + .ops = &meson_clk_ops, + .probe = meson_clk_probe, +}; diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 332f1e1..767dfff 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -278,6 +278,7 @@ int meson_mmc_bind(struct udevice *dev) static const struct udevice_id meson_mmc_match[] = { { .compatible = "amlogic,meson-gx-mmc" }, + { .compatible = "amlogic,meson-axg-mmc" }, { /* sentinel */ } }; diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 19db0a8..4fa26ab 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -838,6 +838,8 @@ static const struct udevice_id designware_eth_ids[] = { { .compatible = "altr,socfpga-stmmac" }, { .compatible = "amlogic,meson6-dwmac" }, { .compatible = "amlogic,meson-gx-dwmac" }, + { .compatible = "amlogic,meson-gxbb-dwmac" }, + { .compatible = "amlogic,meson-axg-dwmac" }, { .compatible = "st,stm32-dwmac" }, { } }; diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig index 27ba890..ee820a5 100644 --- a/drivers/pinctrl/meson/Kconfig +++ b/drivers/pinctrl/meson/Kconfig @@ -1,15 +1,27 @@ if ARCH_MESON config PINCTRL_MESON - depends on PINCTRL_GENERIC + select PINCTRL_GENERIC + bool + +config PINCTRL_MESON_GX_PMX + select PINCTRL_MESON + bool + +config PINCTRL_MESON_AXG_PMX + select PINCTRL_MESON bool config PINCTRL_MESON_GXBB bool "Amlogic Meson GXBB SoC pinctrl driver" - select PINCTRL_MESON + select PINCTRL_MESON_GX_PMX config PINCTRL_MESON_GXL bool "Amlogic Meson GXL SoC pinctrl driver" - select PINCTRL_MESON + select PINCTRL_MESON_GX_PMX + +config PINCTRL_MESON_AXG + bool "Amlogic Meson AXG SoC pinctrl driver" + select PINCTRL_MESON_AXG_PMX endif diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile index 965092c..707287c 100644 --- a/drivers/pinctrl/meson/Makefile +++ b/drivers/pinctrl/meson/Makefile @@ -1,5 +1,8 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += pinctrl-meson.o +obj-$(CONFIG_PINCTRL_MESON_GX_PMX) += pinctrl-meson-gx-pmx.o +obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o +obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c new file mode 100644 index 0000000..c82413d --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Jerome Brunet <jbrunet@baylibre.com> + * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com> + */ + +#include <asm/gpio.h> +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/io.h> +#include "pinctrl-meson-axg.h" + +static int meson_axg_pmx_get_bank(struct udevice *dev, unsigned int pin, + struct meson_pmx_bank **bank) +{ + int i; + struct meson_pinctrl *priv = dev_get_priv(dev); + struct meson_axg_pmx_data *pmx = priv->data->pmx_data; + + for (i = 0; i < pmx->num_pmx_banks; i++) + if (pin >= pmx->pmx_banks[i].first && + pin <= pmx->pmx_banks[i].last) { + *bank = &pmx->pmx_banks[i]; + return 0; + } + + return -EINVAL; +} + +static int meson_axg_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank, + unsigned int pin, + unsigned int *reg, + unsigned int *offset) +{ + int shift; + + shift = pin - bank->first; + + *reg = bank->reg + (bank->offset + (shift << 2)) / 32; + *offset = (bank->offset + (shift << 2)) % 32; + + return 0; +} + +static int meson_axg_pmx_update_function(struct udevice *dev, + unsigned int pin, unsigned int func) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + struct meson_pmx_bank *bank; + unsigned int offset; + unsigned int reg; + unsigned int tmp; + int ret; + + ret = meson_axg_pmx_get_bank(dev, pin, &bank); + if (ret) + return ret; + + meson_axg_pmx_calc_reg_and_offset(bank, pin, ®, &offset); + + tmp = readl(priv->reg_mux + (reg << 2)); + tmp &= ~(0xf << offset); + tmp |= (func & 0xf) << offset; + writel(tmp, priv->reg_mux + (reg << 2)); + + return ret; +} + +static int meson_axg_pinmux_group_set(struct udevice *dev, + unsigned int group_selector, + unsigned int func_selector) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + const struct meson_pmx_group *group; + const struct meson_pmx_func *func; + struct meson_pmx_axg_data *pmx_data; + int i, ret; + + group = &priv->data->groups[group_selector]; + pmx_data = (struct meson_pmx_axg_data *)group->data; + func = &priv->data->funcs[func_selector]; + + debug("pinmux: set group %s func %s\n", group->name, func->name); + + for (i = 0; i < group->num_pins; i++) { + ret = meson_axg_pmx_update_function(dev, group->pins[i], + pmx_data->func); + if (ret) + return ret; + } + + return 0; +} + +const struct pinctrl_ops meson_axg_pinctrl_ops = { + .get_groups_count = meson_pinctrl_get_groups_count, + .get_group_name = meson_pinctrl_get_group_name, + .get_functions_count = meson_pinmux_get_functions_count, + .get_function_name = meson_pinmux_get_function_name, + .pinmux_group_set = meson_axg_pinmux_group_set, + .set_state = pinctrl_generic_set_state, +}; + +static int meson_axg_gpio_request(struct udevice *dev, + unsigned int offset, const char *label) +{ + return meson_axg_pmx_update_function(dev->parent, offset, 0); +} + +static const struct dm_gpio_ops meson_axg_gpio_ops = { + .request = meson_axg_gpio_request, + .set_value = meson_gpio_set, + .get_value = meson_gpio_get, + .get_function = meson_gpio_get_direction, + .direction_input = meson_gpio_direction_input, + .direction_output = meson_gpio_direction_output, +}; + +const struct driver meson_axg_gpio_driver = { + .name = "meson-axg-gpio", + .id = UCLASS_GPIO, + .probe = meson_gpio_probe, + .ops = &meson_axg_gpio_ops, +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c new file mode 100644 index 0000000..a54fbce --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c @@ -0,0 +1,979 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright (C) 2018 Neil Armstrong <narmstrong@baylibre.com> + * + * Based on code from Linux kernel: + * Copyright (c) 2017 Amlogic, Inc. All rights reserved. + * Author: Xingyu Chen <xingyu.chen@amlogic.com> + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <dt-bindings/gpio/meson-axg-gpio.h> + +#include "pinctrl-meson-axg.h" + +#define EE_OFF 14 + +/* emmc */ +static const unsigned int emmc_nand_d0_pins[] = {BOOT_0}; +static const unsigned int emmc_nand_d1_pins[] = {BOOT_1}; +static const unsigned int emmc_nand_d2_pins[] = {BOOT_2}; +static const unsigned int emmc_nand_d3_pins[] = {BOOT_3}; +static const unsigned int emmc_nand_d4_pins[] = {BOOT_4}; +static const unsigned int emmc_nand_d5_pins[] = {BOOT_5}; +static const unsigned int emmc_nand_d6_pins[] = {BOOT_6}; +static const unsigned int emmc_nand_d7_pins[] = {BOOT_7}; + +static const unsigned int emmc_clk_pins[] = {BOOT_8}; +static const unsigned int emmc_cmd_pins[] = {BOOT_10}; +static const unsigned int emmc_ds_pins[] = {BOOT_13}; + +/* nand */ +static const unsigned int nand_ce0_pins[] = {BOOT_8}; +static const unsigned int nand_ale_pins[] = {BOOT_9}; +static const unsigned int nand_cle_pins[] = {BOOT_10}; +static const unsigned int nand_wen_clk_pins[] = {BOOT_11}; +static const unsigned int nand_ren_wr_pins[] = {BOOT_12}; +static const unsigned int nand_rb0_pins[] = {BOOT_13}; + +/* nor */ +static const unsigned int nor_hold_pins[] = {BOOT_3}; +static const unsigned int nor_d_pins[] = {BOOT_4}; +static const unsigned int nor_q_pins[] = {BOOT_5}; +static const unsigned int nor_c_pins[] = {BOOT_6}; +static const unsigned int nor_wp_pins[] = {BOOT_9}; +static const unsigned int nor_cs_pins[] = {BOOT_14}; + +/* sdio */ +static const unsigned int sdio_d0_pins[] = {GPIOX_0}; +static const unsigned int sdio_d1_pins[] = {GPIOX_1}; +static const unsigned int sdio_d2_pins[] = {GPIOX_2}; +static const unsigned int sdio_d3_pins[] = {GPIOX_3}; +static const unsigned int sdio_clk_pins[] = {GPIOX_4}; +static const unsigned int sdio_cmd_pins[] = {GPIOX_5}; + +/* spi0 */ +static const unsigned int spi0_clk_pins[] = {GPIOZ_0}; +static const unsigned int spi0_mosi_pins[] = {GPIOZ_1}; +static const unsigned int spi0_miso_pins[] = {GPIOZ_2}; +static const unsigned int spi0_ss0_pins[] = {GPIOZ_3}; +static const unsigned int spi0_ss1_pins[] = {GPIOZ_4}; +static const unsigned int spi0_ss2_pins[] = {GPIOZ_5}; + +/* spi1 */ +static const unsigned int spi1_clk_x_pins[] = {GPIOX_19}; +static const unsigned int spi1_mosi_x_pins[] = {GPIOX_17}; +static const unsigned int spi1_miso_x_pins[] = {GPIOX_18}; +static const unsigned int spi1_ss0_x_pins[] = {GPIOX_16}; + +static const unsigned int spi1_clk_a_pins[] = {GPIOA_4}; +static const unsigned int spi1_mosi_a_pins[] = {GPIOA_2}; +static const unsigned int spi1_miso_a_pins[] = {GPIOA_3}; +static const unsigned int spi1_ss0_a_pins[] = {GPIOA_5}; +static const unsigned int spi1_ss1_pins[] = {GPIOA_6}; + +/* i2c0 */ +static const unsigned int i2c0_sck_pins[] = {GPIOZ_6}; +static const unsigned int i2c0_sda_pins[] = {GPIOZ_7}; + +/* i2c1 */ +static const unsigned int i2c1_sck_z_pins[] = {GPIOZ_8}; +static const unsigned int i2c1_sda_z_pins[] = {GPIOZ_9}; + +static const unsigned int i2c1_sck_x_pins[] = {GPIOX_16}; +static const unsigned int i2c1_sda_x_pins[] = {GPIOX_17}; + +/* i2c2 */ +static const unsigned int i2c2_sck_x_pins[] = {GPIOX_18}; +static const unsigned int i2c2_sda_x_pins[] = {GPIOX_19}; + +static const unsigned int i2c2_sda_a_pins[] = {GPIOA_17}; +static const unsigned int i2c2_sck_a_pins[] = {GPIOA_18}; + +/* i2c3 */ +static const unsigned int i2c3_sda_a6_pins[] = {GPIOA_6}; +static const unsigned int i2c3_sck_a7_pins[] = {GPIOA_7}; + +static const unsigned int i2c3_sda_a12_pins[] = {GPIOA_12}; +static const unsigned int i2c3_sck_a13_pins[] = {GPIOA_13}; + +static const unsigned int i2c3_sda_a19_pins[] = {GPIOA_19}; +static const unsigned int i2c3_sck_a20_pins[] = {GPIOA_20}; + +/* uart_a */ +static const unsigned int uart_rts_a_pins[] = {GPIOX_11}; +static const unsigned int uart_cts_a_pins[] = {GPIOX_10}; +static const unsigned int uart_tx_a_pins[] = {GPIOX_8}; +static const unsigned int uart_rx_a_pins[] = {GPIOX_9}; + +/* uart_b */ +static const unsigned int uart_rts_b_z_pins[] = {GPIOZ_0}; +static const unsigned int uart_cts_b_z_pins[] = {GPIOZ_1}; +static const unsigned int uart_tx_b_z_pins[] = {GPIOZ_2}; +static const unsigned int uart_rx_b_z_pins[] = {GPIOZ_3}; + +static const unsigned int uart_rts_b_x_pins[] = {GPIOX_18}; +static const unsigned int uart_cts_b_x_pins[] = {GPIOX_19}; +static const unsigned int uart_tx_b_x_pins[] = {GPIOX_16}; +static const unsigned int uart_rx_b_x_pins[] = {GPIOX_17}; + +/* uart_ao_b */ +static const unsigned int uart_ao_tx_b_z_pins[] = {GPIOZ_8}; +static const unsigned int uart_ao_rx_b_z_pins[] = {GPIOZ_9}; +static const unsigned int uart_ao_cts_b_z_pins[] = {GPIOZ_6}; +static const unsigned int uart_ao_rts_b_z_pins[] = {GPIOZ_7}; + +/* pwm_a */ +static const unsigned int pwm_a_z_pins[] = {GPIOZ_5}; + +static const unsigned int pwm_a_x18_pins[] = {GPIOX_18}; +static const unsigned int pwm_a_x20_pins[] = {GPIOX_20}; + +static const unsigned int pwm_a_a_pins[] = {GPIOA_14}; + +/* pwm_b */ +static const unsigned int pwm_b_z_pins[] = {GPIOZ_4}; + +static const unsigned int pwm_b_x_pins[] = {GPIOX_19}; + +static const unsigned int pwm_b_a_pins[] = {GPIOA_15}; + +/* pwm_c */ +static const unsigned int pwm_c_x10_pins[] = {GPIOX_10}; +static const unsigned int pwm_c_x17_pins[] = {GPIOX_17}; + +static const unsigned int pwm_c_a_pins[] = {GPIOA_16}; + +/* pwm_d */ +static const unsigned int pwm_d_x11_pins[] = {GPIOX_11}; +static const unsigned int pwm_d_x16_pins[] = {GPIOX_16}; + +/* pwm_vs */ +static const unsigned int pwm_vs_pins[] = {GPIOA_0}; + +/* spdif_in */ +static const unsigned int spdif_in_z_pins[] = {GPIOZ_4}; + +static const unsigned int spdif_in_a1_pins[] = {GPIOA_1}; +static const unsigned int spdif_in_a7_pins[] = {GPIOA_7}; +static const unsigned int spdif_in_a19_pins[] = {GPIOA_19}; +static const unsigned int spdif_in_a20_pins[] = {GPIOA_20}; + +/* spdif_out */ +static const unsigned int spdif_out_z_pins[] = {GPIOZ_5}; + +static const unsigned int spdif_out_a1_pins[] = {GPIOA_1}; +static const unsigned int spdif_out_a11_pins[] = {GPIOA_11}; +static const unsigned int spdif_out_a19_pins[] = {GPIOA_19}; +static const unsigned int spdif_out_a20_pins[] = {GPIOA_20}; + +/* jtag_ee */ +static const unsigned int jtag_tdo_x_pins[] = {GPIOX_0}; +static const unsigned int jtag_tdi_x_pins[] = {GPIOX_1}; +static const unsigned int jtag_clk_x_pins[] = {GPIOX_4}; +static const unsigned int jtag_tms_x_pins[] = {GPIOX_5}; + +/* eth */ +static const unsigned int eth_txd0_x_pins[] = {GPIOX_8}; +static const unsigned int eth_txd1_x_pins[] = {GPIOX_9}; +static const unsigned int eth_txen_x_pins[] = {GPIOX_10}; +static const unsigned int eth_rgmii_rx_clk_x_pins[] = {GPIOX_12}; +static const unsigned int eth_rxd0_x_pins[] = {GPIOX_13}; +static const unsigned int eth_rxd1_x_pins[] = {GPIOX_14}; +static const unsigned int eth_rx_dv_x_pins[] = {GPIOX_15}; +static const unsigned int eth_mdio_x_pins[] = {GPIOX_21}; +static const unsigned int eth_mdc_x_pins[] = {GPIOX_22}; + +static const unsigned int eth_txd0_y_pins[] = {GPIOY_10}; +static const unsigned int eth_txd1_y_pins[] = {GPIOY_11}; +static const unsigned int eth_txen_y_pins[] = {GPIOY_9}; +static const unsigned int eth_rgmii_rx_clk_y_pins[] = {GPIOY_2}; +static const unsigned int eth_rxd0_y_pins[] = {GPIOY_4}; +static const unsigned int eth_rxd1_y_pins[] = {GPIOY_5}; +static const unsigned int eth_rx_dv_y_pins[] = {GPIOY_3}; +static const unsigned int eth_mdio_y_pins[] = {GPIOY_0}; +static const unsigned int eth_mdc_y_pins[] = {GPIOY_1}; + +static const unsigned int eth_rxd2_rgmii_pins[] = {GPIOY_6}; +static const unsigned int eth_rxd3_rgmii_pins[] = {GPIOY_7}; +static const unsigned int eth_rgmii_tx_clk_pins[] = {GPIOY_8}; +static const unsigned int eth_txd2_rgmii_pins[] = {GPIOY_12}; +static const unsigned int eth_txd3_rgmii_pins[] = {GPIOY_13}; + +/* pdm */ +static const unsigned int pdm_dclk_a14_pins[] = {GPIOA_14}; +static const unsigned int pdm_dclk_a19_pins[] = {GPIOA_19}; +static const unsigned int pdm_din0_pins[] = {GPIOA_15}; +static const unsigned int pdm_din1_pins[] = {GPIOA_16}; +static const unsigned int pdm_din2_pins[] = {GPIOA_17}; +static const unsigned int pdm_din3_pins[] = {GPIOA_18}; + +/* mclk */ +static const unsigned int mclk_c_pins[] = {GPIOA_0}; +static const unsigned int mclk_b_pins[] = {GPIOA_1}; + +/* tdm */ +static const unsigned int tdma_sclk_pins[] = {GPIOX_12}; +static const unsigned int tdma_sclk_slv_pins[] = {GPIOX_12}; +static const unsigned int tdma_fs_pins[] = {GPIOX_13}; +static const unsigned int tdma_fs_slv_pins[] = {GPIOX_13}; +static const unsigned int tdma_din0_pins[] = {GPIOX_14}; +static const unsigned int tdma_dout0_x14_pins[] = {GPIOX_14}; +static const unsigned int tdma_dout0_x15_pins[] = {GPIOX_15}; +static const unsigned int tdma_dout1_pins[] = {GPIOX_15}; +static const unsigned int tdma_din1_pins[] = {GPIOX_15}; + +static const unsigned int tdmc_sclk_pins[] = {GPIOA_2}; +static const unsigned int tdmc_sclk_slv_pins[] = {GPIOA_2}; +static const unsigned int tdmc_fs_pins[] = {GPIOA_3}; +static const unsigned int tdmc_fs_slv_pins[] = {GPIOA_3}; +static const unsigned int tdmc_din0_pins[] = {GPIOA_4}; +static const unsigned int tdmc_dout0_pins[] = {GPIOA_4}; +static const unsigned int tdmc_din1_pins[] = {GPIOA_5}; +static const unsigned int tdmc_dout1_pins[] = {GPIOA_5}; +static const unsigned int tdmc_din2_pins[] = {GPIOA_6}; +static const unsigned int tdmc_dout2_pins[] = {GPIOA_6}; +static const unsigned int tdmc_din3_pins[] = {GPIOA_7}; +static const unsigned int tdmc_dout3_pins[] = {GPIOA_7}; + +static const unsigned int tdmb_sclk_pins[] = {GPIOA_8}; +static const unsigned int tdmb_sclk_slv_pins[] = {GPIOA_8}; +static const unsigned int tdmb_fs_pins[] = {GPIOA_9}; +static const unsigned int tdmb_fs_slv_pins[] = {GPIOA_9}; +static const unsigned int tdmb_din0_pins[] = {GPIOA_10}; +static const unsigned int tdmb_dout0_pins[] = {GPIOA_10}; +static const unsigned int tdmb_din1_pins[] = {GPIOA_11}; +static const unsigned int tdmb_dout1_pins[] = {GPIOA_11}; +static const unsigned int tdmb_din2_pins[] = {GPIOA_12}; +static const unsigned int tdmb_dout2_pins[] = {GPIOA_12}; +static const unsigned int tdmb_din3_pins[] = {GPIOA_13}; +static const unsigned int tdmb_dout3_pins[] = {GPIOA_13}; + +static struct meson_pmx_group meson_axg_periphs_groups[] = { + GPIO_GROUP(GPIOZ_0, EE_OFF), + GPIO_GROUP(GPIOZ_1, EE_OFF), + GPIO_GROUP(GPIOZ_2, EE_OFF), + GPIO_GROUP(GPIOZ_3, EE_OFF), + GPIO_GROUP(GPIOZ_4, EE_OFF), + GPIO_GROUP(GPIOZ_5, EE_OFF), + GPIO_GROUP(GPIOZ_6, EE_OFF), + GPIO_GROUP(GPIOZ_7, EE_OFF), + GPIO_GROUP(GPIOZ_8, EE_OFF), + GPIO_GROUP(GPIOZ_9, EE_OFF), + GPIO_GROUP(GPIOZ_10, EE_OFF), + + GPIO_GROUP(BOOT_0, EE_OFF), + GPIO_GROUP(BOOT_1, EE_OFF), + GPIO_GROUP(BOOT_2, EE_OFF), + GPIO_GROUP(BOOT_3, EE_OFF), + GPIO_GROUP(BOOT_4, EE_OFF), + GPIO_GROUP(BOOT_5, EE_OFF), + GPIO_GROUP(BOOT_6, EE_OFF), + GPIO_GROUP(BOOT_7, EE_OFF), + GPIO_GROUP(BOOT_8, EE_OFF), + GPIO_GROUP(BOOT_9, EE_OFF), + GPIO_GROUP(BOOT_10, EE_OFF), + GPIO_GROUP(BOOT_11, EE_OFF), + GPIO_GROUP(BOOT_12, EE_OFF), + GPIO_GROUP(BOOT_13, EE_OFF), + GPIO_GROUP(BOOT_14, EE_OFF), + + GPIO_GROUP(GPIOA_0, EE_OFF), + GPIO_GROUP(GPIOA_1, EE_OFF), + GPIO_GROUP(GPIOA_2, EE_OFF), + GPIO_GROUP(GPIOA_3, EE_OFF), + GPIO_GROUP(GPIOA_4, EE_OFF), + GPIO_GROUP(GPIOA_5, EE_OFF), + GPIO_GROUP(GPIOA_6, EE_OFF), + GPIO_GROUP(GPIOA_7, EE_OFF), + GPIO_GROUP(GPIOA_8, EE_OFF), + GPIO_GROUP(GPIOA_9, EE_OFF), + GPIO_GROUP(GPIOA_10, EE_OFF), + GPIO_GROUP(GPIOA_11, EE_OFF), + GPIO_GROUP(GPIOA_12, EE_OFF), + GPIO_GROUP(GPIOA_13, EE_OFF), + GPIO_GROUP(GPIOA_14, EE_OFF), + GPIO_GROUP(GPIOA_15, EE_OFF), + GPIO_GROUP(GPIOA_16, EE_OFF), + GPIO_GROUP(GPIOA_17, EE_OFF), + GPIO_GROUP(GPIOA_19, EE_OFF), + GPIO_GROUP(GPIOA_20, EE_OFF), + + GPIO_GROUP(GPIOX_0, EE_OFF), + GPIO_GROUP(GPIOX_1, EE_OFF), + GPIO_GROUP(GPIOX_2, EE_OFF), + GPIO_GROUP(GPIOX_3, EE_OFF), + GPIO_GROUP(GPIOX_4, EE_OFF), + GPIO_GROUP(GPIOX_5, EE_OFF), + GPIO_GROUP(GPIOX_6, EE_OFF), + GPIO_GROUP(GPIOX_7, EE_OFF), + GPIO_GROUP(GPIOX_8, EE_OFF), + GPIO_GROUP(GPIOX_9, EE_OFF), + GPIO_GROUP(GPIOX_10, EE_OFF), + GPIO_GROUP(GPIOX_11, EE_OFF), + GPIO_GROUP(GPIOX_12, EE_OFF), + GPIO_GROUP(GPIOX_13, EE_OFF), + GPIO_GROUP(GPIOX_14, EE_OFF), + GPIO_GROUP(GPIOX_15, EE_OFF), + GPIO_GROUP(GPIOX_16, EE_OFF), + GPIO_GROUP(GPIOX_17, EE_OFF), + GPIO_GROUP(GPIOX_18, EE_OFF), + GPIO_GROUP(GPIOX_19, EE_OFF), + GPIO_GROUP(GPIOX_20, EE_OFF), + GPIO_GROUP(GPIOX_21, EE_OFF), + GPIO_GROUP(GPIOX_22, EE_OFF), + + GPIO_GROUP(GPIOY_0, EE_OFF), + GPIO_GROUP(GPIOY_1, EE_OFF), + GPIO_GROUP(GPIOY_2, EE_OFF), + GPIO_GROUP(GPIOY_3, EE_OFF), + GPIO_GROUP(GPIOY_4, EE_OFF), + GPIO_GROUP(GPIOY_5, EE_OFF), + GPIO_GROUP(GPIOY_6, EE_OFF), + GPIO_GROUP(GPIOY_7, EE_OFF), + GPIO_GROUP(GPIOY_8, EE_OFF), + GPIO_GROUP(GPIOY_9, EE_OFF), + GPIO_GROUP(GPIOY_10, EE_OFF), + GPIO_GROUP(GPIOY_11, EE_OFF), + GPIO_GROUP(GPIOY_12, EE_OFF), + GPIO_GROUP(GPIOY_13, EE_OFF), + GPIO_GROUP(GPIOY_14, EE_OFF), + GPIO_GROUP(GPIOY_15, EE_OFF), + + /* bank BOOT */ + GROUP(emmc_nand_d0, 1), + GROUP(emmc_nand_d1, 1), + GROUP(emmc_nand_d2, 1), + GROUP(emmc_nand_d3, 1), + GROUP(emmc_nand_d4, 1), + GROUP(emmc_nand_d5, 1), + GROUP(emmc_nand_d6, 1), + GROUP(emmc_nand_d7, 1), + GROUP(emmc_clk, 1), + GROUP(emmc_cmd, 1), + GROUP(emmc_ds, 1), + GROUP(nand_ce0, 2), + GROUP(nand_ale, 2), + GROUP(nand_cle, 2), + GROUP(nand_wen_clk, 2), + GROUP(nand_ren_wr, 2), + GROUP(nand_rb0, 2), + GROUP(nor_hold, 3), + GROUP(nor_d, 3), + GROUP(nor_q, 3), + GROUP(nor_c, 3), + GROUP(nor_wp, 3), + GROUP(nor_cs, 3), + + /* bank GPIOZ */ + GROUP(spi0_clk, 1), + GROUP(spi0_mosi, 1), + GROUP(spi0_miso, 1), + GROUP(spi0_ss0, 1), + GROUP(spi0_ss1, 1), + GROUP(spi0_ss2, 1), + GROUP(i2c0_sck, 1), + GROUP(i2c0_sda, 1), + GROUP(i2c1_sck_z, 1), + GROUP(i2c1_sda_z, 1), + GROUP(uart_rts_b_z, 2), + GROUP(uart_cts_b_z, 2), + GROUP(uart_tx_b_z, 2), + GROUP(uart_rx_b_z, 2), + GROUP(pwm_a_z, 2), + GROUP(pwm_b_z, 2), + GROUP(spdif_in_z, 3), + GROUP(spdif_out_z, 3), + GROUP(uart_ao_tx_b_z, 2), + GROUP(uart_ao_rx_b_z, 2), + GROUP(uart_ao_cts_b_z, 2), + GROUP(uart_ao_rts_b_z, 2), + + /* bank GPIOX */ + GROUP(sdio_d0, 1), + GROUP(sdio_d1, 1), + GROUP(sdio_d2, 1), + GROUP(sdio_d3, 1), + GROUP(sdio_clk, 1), + GROUP(sdio_cmd, 1), + GROUP(i2c1_sck_x, 1), + GROUP(i2c1_sda_x, 1), + GROUP(i2c2_sck_x, 1), + GROUP(i2c2_sda_x, 1), + GROUP(uart_rts_a, 1), + GROUP(uart_cts_a, 1), + GROUP(uart_tx_a, 1), + GROUP(uart_rx_a, 1), + GROUP(uart_rts_b_x, 2), + GROUP(uart_cts_b_x, 2), + GROUP(uart_tx_b_x, 2), + GROUP(uart_rx_b_x, 2), + GROUP(jtag_tdo_x, 2), + GROUP(jtag_tdi_x, 2), + GROUP(jtag_clk_x, 2), + GROUP(jtag_tms_x, 2), + GROUP(spi1_clk_x, 4), + GROUP(spi1_mosi_x, 4), + GROUP(spi1_miso_x, 4), + GROUP(spi1_ss0_x, 4), + GROUP(pwm_a_x18, 3), + GROUP(pwm_a_x20, 1), + GROUP(pwm_b_x, 3), + GROUP(pwm_c_x10, 3), + GROUP(pwm_c_x17, 3), + GROUP(pwm_d_x11, 3), + GROUP(pwm_d_x16, 3), + GROUP(eth_txd0_x, 4), + GROUP(eth_txd1_x, 4), + GROUP(eth_txen_x, 4), + GROUP(eth_rgmii_rx_clk_x, 4), + GROUP(eth_rxd0_x, 4), + GROUP(eth_rxd1_x, 4), + GROUP(eth_rx_dv_x, 4), + GROUP(eth_mdio_x, 4), + GROUP(eth_mdc_x, 4), + GROUP(tdma_sclk, 1), + GROUP(tdma_sclk_slv, 2), + GROUP(tdma_fs, 1), + GROUP(tdma_fs_slv, 2), + GROUP(tdma_din0, 1), + GROUP(tdma_dout0_x14, 2), + GROUP(tdma_dout0_x15, 1), + GROUP(tdma_dout1, 2), + GROUP(tdma_din1, 3), + + /* bank GPIOY */ + GROUP(eth_txd0_y, 1), + GROUP(eth_txd1_y, 1), + GROUP(eth_txen_y, 1), + GROUP(eth_rgmii_rx_clk_y, 1), + GROUP(eth_rxd0_y, 1), + GROUP(eth_rxd1_y, 1), + GROUP(eth_rx_dv_y, 1), + GROUP(eth_mdio_y, 1), + GROUP(eth_mdc_y, 1), + GROUP(eth_rxd2_rgmii, 1), + GROUP(eth_rxd3_rgmii, 1), + GROUP(eth_rgmii_tx_clk, 1), + GROUP(eth_txd2_rgmii, 1), + GROUP(eth_txd3_rgmii, 1), + + /* bank GPIOA */ + GROUP(spdif_out_a1, 4), + GROUP(spdif_out_a11, 3), + GROUP(spdif_out_a19, 2), + GROUP(spdif_out_a20, 1), + GROUP(spdif_in_a1, 3), + GROUP(spdif_in_a7, 3), + GROUP(spdif_in_a19, 1), + GROUP(spdif_in_a20, 2), + GROUP(spi1_clk_a, 3), + GROUP(spi1_mosi_a, 3), + GROUP(spi1_miso_a, 3), + GROUP(spi1_ss0_a, 3), + GROUP(spi1_ss1, 3), + GROUP(pwm_a_a, 3), + GROUP(pwm_b_a, 3), + GROUP(pwm_c_a, 3), + GROUP(pwm_vs, 2), + GROUP(i2c2_sda_a, 3), + GROUP(i2c2_sck_a, 3), + GROUP(i2c3_sda_a6, 4), + GROUP(i2c3_sck_a7, 4), + GROUP(i2c3_sda_a12, 4), + GROUP(i2c3_sck_a13, 4), + GROUP(i2c3_sda_a19, 4), + GROUP(i2c3_sck_a20, 4), + GROUP(pdm_dclk_a14, 1), + GROUP(pdm_dclk_a19, 3), + GROUP(pdm_din0, 1), + GROUP(pdm_din1, 1), + GROUP(pdm_din2, 1), + GROUP(pdm_din3, 1), + GROUP(mclk_c, 1), + GROUP(mclk_b, 1), + GROUP(tdmc_sclk, 1), + GROUP(tdmc_sclk_slv, 2), + GROUP(tdmc_fs, 1), + GROUP(tdmc_fs_slv, 2), + GROUP(tdmc_din0, 2), + GROUP(tdmc_dout0, 1), + GROUP(tdmc_din1, 2), + GROUP(tdmc_dout1, 1), + GROUP(tdmc_din2, 2), + GROUP(tdmc_dout2, 1), + GROUP(tdmc_din3, 2), + GROUP(tdmc_dout3, 1), + GROUP(tdmb_sclk, 1), + GROUP(tdmb_sclk_slv, 2), + GROUP(tdmb_fs, 1), + GROUP(tdmb_fs_slv, 2), + GROUP(tdmb_din0, 2), + GROUP(tdmb_dout0, 1), + GROUP(tdmb_din1, 2), + GROUP(tdmb_dout1, 1), + GROUP(tdmb_din2, 2), + GROUP(tdmb_dout2, 1), + GROUP(tdmb_din3, 2), + GROUP(tdmb_dout3, 1), +}; + +/* uart_ao_a */ +static const unsigned int uart_ao_tx_a_pins[] = {GPIOAO_0}; +static const unsigned int uart_ao_rx_a_pins[] = {GPIOAO_1}; +static const unsigned int uart_ao_cts_a_pins[] = {GPIOAO_2}; +static const unsigned int uart_ao_rts_a_pins[] = {GPIOAO_3}; + +/* uart_ao_b */ +static const unsigned int uart_ao_tx_b_pins[] = {GPIOAO_4}; +static const unsigned int uart_ao_rx_b_pins[] = {GPIOAO_5}; +static const unsigned int uart_ao_cts_b_pins[] = {GPIOAO_2}; +static const unsigned int uart_ao_rts_b_pins[] = {GPIOAO_3}; + +/* i2c_ao */ +static const unsigned int i2c_ao_sck_4_pins[] = {GPIOAO_4}; +static const unsigned int i2c_ao_sda_5_pins[] = {GPIOAO_5}; +static const unsigned int i2c_ao_sck_8_pins[] = {GPIOAO_8}; +static const unsigned int i2c_ao_sda_9_pins[] = {GPIOAO_9}; +static const unsigned int i2c_ao_sck_10_pins[] = {GPIOAO_10}; +static const unsigned int i2c_ao_sda_11_pins[] = {GPIOAO_11}; + +/* i2c_ao_slave */ +static const unsigned int i2c_ao_slave_sck_pins[] = {GPIOAO_10}; +static const unsigned int i2c_ao_slave_sda_pins[] = {GPIOAO_11}; + +/* ir_in */ +static const unsigned int remote_input_ao_pins[] = {GPIOAO_6}; + +/* ir_out */ +static const unsigned int remote_out_ao_pins[] = {GPIOAO_7}; + +/* pwm_ao_a */ +static const unsigned int pwm_ao_a_pins[] = {GPIOAO_3}; + +/* pwm_ao_b */ +static const unsigned int pwm_ao_b_ao2_pins[] = {GPIOAO_2}; +static const unsigned int pwm_ao_b_ao12_pins[] = {GPIOAO_12}; + +/* pwm_ao_c */ +static const unsigned int pwm_ao_c_ao8_pins[] = {GPIOAO_8}; +static const unsigned int pwm_ao_c_ao13_pins[] = {GPIOAO_13}; + +/* pwm_ao_d */ +static const unsigned int pwm_ao_d_pins[] = {GPIOAO_9}; + +/* jtag_ao */ +static const unsigned int jtag_ao_tdi_pins[] = {GPIOAO_3}; +static const unsigned int jtag_ao_tdo_pins[] = {GPIOAO_4}; +static const unsigned int jtag_ao_clk_pins[] = {GPIOAO_5}; +static const unsigned int jtag_ao_tms_pins[] = {GPIOAO_7}; + +static struct meson_pmx_group meson_axg_aobus_groups[] = { + GPIO_GROUP(GPIOAO_0, 0), + GPIO_GROUP(GPIOAO_1, 0), + GPIO_GROUP(GPIOAO_2, 0), + GPIO_GROUP(GPIOAO_3, 0), + GPIO_GROUP(GPIOAO_4, 0), + GPIO_GROUP(GPIOAO_5, 0), + GPIO_GROUP(GPIOAO_6, 0), + GPIO_GROUP(GPIOAO_7, 0), + GPIO_GROUP(GPIOAO_8, 0), + GPIO_GROUP(GPIOAO_9, 0), + GPIO_GROUP(GPIOAO_10, 0), + GPIO_GROUP(GPIOAO_11, 0), + GPIO_GROUP(GPIOAO_12, 0), + GPIO_GROUP(GPIOAO_13, 0), + GPIO_GROUP(GPIO_TEST_N, 0), + + /* bank AO */ + GROUP(uart_ao_tx_a, 1), + GROUP(uart_ao_rx_a, 1), + GROUP(uart_ao_cts_a, 2), + GROUP(uart_ao_rts_a, 2), + GROUP(uart_ao_tx_b, 1), + GROUP(uart_ao_rx_b, 1), + GROUP(uart_ao_cts_b, 1), + GROUP(uart_ao_rts_b, 1), + GROUP(i2c_ao_sck_4, 2), + GROUP(i2c_ao_sda_5, 2), + GROUP(i2c_ao_sck_8, 2), + GROUP(i2c_ao_sda_9, 2), + GROUP(i2c_ao_sck_10, 2), + GROUP(i2c_ao_sda_11, 2), + GROUP(i2c_ao_slave_sck, 1), + GROUP(i2c_ao_slave_sda, 1), + GROUP(remote_input_ao, 1), + GROUP(remote_out_ao, 1), + GROUP(pwm_ao_a, 3), + GROUP(pwm_ao_b_ao2, 3), + GROUP(pwm_ao_b_ao12, 3), + GROUP(pwm_ao_c_ao8, 3), + GROUP(pwm_ao_c_ao13, 3), + GROUP(pwm_ao_d, 3), + GROUP(jtag_ao_tdi, 4), + GROUP(jtag_ao_tdo, 4), + GROUP(jtag_ao_clk, 4), + GROUP(jtag_ao_tms, 4), +}; + +static const char * const gpio_periphs_groups[] = { + "GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4", + "GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9", + "GPIOZ_10", + + "BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4", + "BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9", + "BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14", + + "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4", + "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9", + "GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14", + "GPIOA_15", "GPIOA_16", "GPIOA_17", "GPIOA_18", "GPIOA_19", + "GPIOA_20", + + "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4", + "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", + "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14", + "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19", + "GPIOX_20", "GPIOX_21", "GPIOX_22", + + "GPIOY_0", "GPIOY_1", "GPIOY_2", "GPIOY_3", "GPIOY_4", + "GPIOY_5", "GPIOY_6", "GPIOY_7", "GPIOY_8", "GPIOY_9", + "GPIOY_10", "GPIOY_11", "GPIOY_12", "GPIOY_13", "GPIOY_14", + "GPIOY_15", +}; + +static const char * const emmc_groups[] = { + "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", + "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5", + "emmc_nand_d6", "emmc_nand_d7", + "emmc_clk", "emmc_cmd", "emmc_ds", +}; + +static const char * const nand_groups[] = { + "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", + "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5", + "emmc_nand_d6", "emmc_nand_d7", + "nand_ce0", "nand_ale", "nand_cle", + "nand_wen_clk", "nand_ren_wr", "nand_rb0", +}; + +static const char * const nor_groups[] = { + "nor_d", "nor_q", "nor_c", "nor_cs", + "nor_hold", "nor_wp", +}; + +static const char * const sdio_groups[] = { + "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3", + "sdio_cmd", "sdio_clk", +}; + +static const char * const spi0_groups[] = { + "spi0_clk", "spi0_mosi", "spi0_miso", "spi0_ss0", + "spi0_ss1", "spi0_ss2" +}; + +static const char * const spi1_groups[] = { + "spi1_clk_x", "spi1_mosi_x", "spi1_miso_x", "spi1_ss0_x", + "spi1_clk_a", "spi1_mosi_a", "spi1_miso_a", "spi1_ss0_a", + "spi1_ss1" +}; + +static const char * const uart_a_groups[] = { + "uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a", +}; + +static const char * const uart_b_groups[] = { + "uart_tx_b_z", "uart_rx_b_z", "uart_cts_b_z", "uart_rts_b_z", + "uart_tx_b_x", "uart_rx_b_x", "uart_cts_b_x", "uart_rts_b_x", +}; + +static const char * const uart_ao_b_z_groups[] = { + "uart_ao_tx_b_z", "uart_ao_rx_b_z", + "uart_ao_cts_b_z", "uart_ao_rts_b_z", +}; + +static const char * const i2c0_groups[] = { + "i2c0_sck", "i2c0_sda", +}; + +static const char * const i2c1_groups[] = { + "i2c1_sck_z", "i2c1_sda_z", + "i2c1_sck_x", "i2c1_sda_x", +}; + +static const char * const i2c2_groups[] = { + "i2c2_sck_x", "i2c2_sda_x", + "i2c2_sda_a", "i2c2_sck_a", +}; + +static const char * const i2c3_groups[] = { + "i2c3_sda_a6", "i2c3_sck_a7", + "i2c3_sda_a12", "i2c3_sck_a13", + "i2c3_sda_a19", "i2c3_sck_a20", +}; + +static const char * const eth_groups[] = { + "eth_rxd2_rgmii", "eth_rxd3_rgmii", "eth_rgmii_tx_clk", + "eth_txd2_rgmii", "eth_txd3_rgmii", + "eth_txd0_x", "eth_txd1_x", "eth_txen_x", "eth_rgmii_rx_clk_x", + "eth_rxd0_x", "eth_rxd1_x", "eth_rx_dv_x", "eth_mdio_x", + "eth_mdc_x", + "eth_txd0_y", "eth_txd1_y", "eth_txen_y", "eth_rgmii_rx_clk_y", + "eth_rxd0_y", "eth_rxd1_y", "eth_rx_dv_y", "eth_mdio_y", + "eth_mdc_y", +}; + +static const char * const pwm_a_groups[] = { + "pwm_a_z", "pwm_a_x18", "pwm_a_x20", "pwm_a_a", +}; + +static const char * const pwm_b_groups[] = { + "pwm_b_z", "pwm_b_x", "pwm_b_a", +}; + +static const char * const pwm_c_groups[] = { + "pwm_c_x10", "pwm_c_x17", "pwm_c_a", +}; + +static const char * const pwm_d_groups[] = { + "pwm_d_x11", "pwm_d_x16", +}; + +static const char * const pwm_vs_groups[] = { + "pwm_vs", +}; + +static const char * const spdif_out_groups[] = { + "spdif_out_z", "spdif_out_a1", "spdif_out_a11", + "spdif_out_a19", "spdif_out_a20", +}; + +static const char * const spdif_in_groups[] = { + "spdif_in_z", "spdif_in_a1", "spdif_in_a7", + "spdif_in_a19", "spdif_in_a20", +}; + +static const char * const jtag_ee_groups[] = { + "jtag_tdo_x", "jtag_tdi_x", "jtag_clk_x", + "jtag_tms_x", +}; + +static const char * const pdm_groups[] = { + "pdm_din0", "pdm_din1", "pdm_din2", "pdm_din3", + "pdm_dclk_a14", "pdm_dclk_a19", +}; + +static const char * const gpio_aobus_groups[] = { + "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", + "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", + "GPIOAO_10", "GPIOAO_11", "GPIOAO_12", "GPIOAO_13", + "GPIO_TEST_N", +}; + +static const char * const uart_ao_a_groups[] = { + "uart_ao_tx_a", "uart_ao_rx_a", "uart_ao_cts_a", "uart_ao_rts_a", +}; + +static const char * const uart_ao_b_groups[] = { + "uart_ao_tx_b", "uart_ao_rx_b", "uart_ao_cts_b", "uart_ao_rts_b", +}; + +static const char * const i2c_ao_groups[] = { + "i2c_ao_sck_4", "i2c_ao_sda_5", + "i2c_ao_sck_8", "i2c_ao_sda_9", + "i2c_ao_sck_10", "i2c_ao_sda_11", +}; + +static const char * const i2c_ao_slave_groups[] = { + "i2c_ao_slave_sck", "i2c_ao_slave_sda", +}; + +static const char * const remote_input_ao_groups[] = { + "remote_input_ao", +}; + +static const char * const remote_out_ao_groups[] = { + "remote_out_ao", +}; + +static const char * const pwm_ao_a_groups[] = { + "pwm_ao_a", +}; + +static const char * const pwm_ao_b_groups[] = { + "pwm_ao_b_ao2", "pwm_ao_b_ao12", +}; + +static const char * const pwm_ao_c_groups[] = { + "pwm_ao_c_ao8", "pwm_ao_c_ao13", +}; + +static const char * const pwm_ao_d_groups[] = { + "pwm_ao_d", +}; + +static const char * const jtag_ao_groups[] = { + "jtag_ao_tdi", "jtag_ao_tdo", "jtag_ao_clk", "jtag_ao_tms", +}; + +static const char * const mclk_c_groups[] = { + "mclk_c", +}; + +static const char * const mclk_b_groups[] = { + "mclk_b", +}; + +static const char * const tdma_groups[] = { + "tdma_sclk", "tdma_sclk_slv", "tdma_fs", "tdma_fs_slv", + "tdma_din0", "tdma_dout0_x14", "tdma_dout0_x15", "tdma_dout1", + "tdma_din1", +}; + +static const char * const tdmc_groups[] = { + "tdmc_sclk", "tdmc_sclk_slv", "tdmc_fs", "tdmc_fs_slv", + "tdmc_din0", "tdmc_dout0", "tdmc_din1", "tdmc_dout1", + "tdmc_din2", "tdmc_dout2", "tdmc_din3", "tdmc_dout3", +}; + +static const char * const tdmb_groups[] = { + "tdmb_sclk", "tdmb_sclk_slv", "tdmb_fs", "tdmb_fs_slv", + "tdmb_din0", "tdmb_dout0", "tdmb_din1", "tdmb_dout1", + "tdmb_din2", "tdmb_dout2", "tdmb_din3", "tdmb_dout3", +}; + +static struct meson_pmx_func meson_axg_periphs_functions[] = { + FUNCTION(gpio_periphs), + FUNCTION(emmc), + FUNCTION(nor), + FUNCTION(spi0), + FUNCTION(spi1), + FUNCTION(sdio), + FUNCTION(nand), + FUNCTION(uart_a), + FUNCTION(uart_b), + FUNCTION(uart_ao_b_z), + FUNCTION(i2c0), + FUNCTION(i2c1), + FUNCTION(i2c2), + FUNCTION(i2c3), + FUNCTION(eth), + FUNCTION(pwm_a), + FUNCTION(pwm_b), + FUNCTION(pwm_c), + FUNCTION(pwm_d), + FUNCTION(pwm_vs), + FUNCTION(spdif_out), + FUNCTION(spdif_in), + FUNCTION(jtag_ee), + FUNCTION(pdm), + FUNCTION(mclk_b), + FUNCTION(mclk_c), + FUNCTION(tdma), + FUNCTION(tdmb), + FUNCTION(tdmc), +}; + +static struct meson_pmx_func meson_axg_aobus_functions[] = { + FUNCTION(gpio_aobus), + FUNCTION(uart_ao_a), + FUNCTION(uart_ao_b), + FUNCTION(i2c_ao), + FUNCTION(i2c_ao_slave), + FUNCTION(remote_input_ao), + FUNCTION(remote_out_ao), + FUNCTION(pwm_ao_a), + FUNCTION(pwm_ao_b), + FUNCTION(pwm_ao_c), + FUNCTION(pwm_ao_d), + FUNCTION(jtag_ao), +}; + +static struct meson_bank meson_axg_periphs_banks[] = { + /* name first last pullen pull dir out in */ + BANK("Z", GPIOZ_0, GPIOZ_10, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), + BANK("BOOT", BOOT_0, BOOT_14, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), + BANK("A", GPIOA_0, GPIOA_20, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), + BANK("X", GPIOX_0, GPIOX_22, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + BANK("Y", GPIOY_0, GPIOY_15, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), +}; + +static struct meson_bank meson_axg_aobus_banks[] = { + /* name first last pullen pull dir out in */ + BANK("AO", GPIOAO_0, GPIOAO_13, 0, 16, 0, 0, 0, 0, 0, 16, 1, 0), +}; + +static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = { + /* name first lask reg offset */ + BANK_PMX("Z", GPIOZ_0, GPIOZ_10, 0x2, 0), + BANK_PMX("BOOT", BOOT_0, BOOT_14, 0x0, 0), + BANK_PMX("A", GPIOA_0, GPIOA_20, 0xb, 0), + BANK_PMX("X", GPIOX_0, GPIOX_22, 0x4, 0), + BANK_PMX("Y", GPIOY_0, GPIOY_15, 0x8, 0), +}; + +static struct meson_axg_pmx_data meson_axg_periphs_pmx_banks_data = { + .pmx_banks = meson_axg_periphs_pmx_banks, + .num_pmx_banks = ARRAY_SIZE(meson_axg_periphs_pmx_banks), +}; + +static struct meson_pmx_bank meson_axg_aobus_pmx_banks[] = { + BANK_PMX("AO", GPIOAO_0, GPIOAO_13, 0x0, 0), +}; + +static struct meson_axg_pmx_data meson_axg_aobus_pmx_banks_data = { + .pmx_banks = meson_axg_aobus_pmx_banks, + .num_pmx_banks = ARRAY_SIZE(meson_axg_aobus_pmx_banks), +}; + +struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = { + .name = "periphs-banks", + .pin_base = 11, + .groups = meson_axg_periphs_groups, + .funcs = meson_axg_periphs_functions, + .banks = meson_axg_periphs_banks, + .num_pins = 100, + .num_groups = ARRAY_SIZE(meson_axg_periphs_groups), + .num_funcs = ARRAY_SIZE(meson_axg_periphs_functions), + .num_banks = ARRAY_SIZE(meson_axg_periphs_banks), + .gpio_driver = &meson_axg_gpio_driver, + .pmx_data = &meson_axg_periphs_pmx_banks_data, +}; + +struct meson_pinctrl_data meson_axg_aobus_pinctrl_data = { + .name = "aobus-banks", + .pin_base = 0, + .groups = meson_axg_aobus_groups, + .funcs = meson_axg_aobus_functions, + .banks = meson_axg_aobus_banks, + .num_pins = 14, + .num_groups = ARRAY_SIZE(meson_axg_aobus_groups), + .num_funcs = ARRAY_SIZE(meson_axg_aobus_functions), + .num_banks = ARRAY_SIZE(meson_axg_aobus_banks), + .gpio_driver = &meson_axg_gpio_driver, + .pmx_data = &meson_axg_aobus_pmx_banks_data, +}; + +static const struct udevice_id meson_axg_pinctrl_match[] = { + { + .compatible = "amlogic,meson-axg-periphs-pinctrl", + .data = (ulong)&meson_axg_periphs_pinctrl_data, + }, + { + .compatible = "amlogic,meson-axg-aobus-pinctrl", + .data = (ulong)&meson_axg_aobus_pinctrl_data, + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(meson_axg_pinctrl) = { + .name = "meson-axg-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = of_match_ptr(meson_axg_pinctrl_match), + .probe = meson_pinctrl_probe, + .priv_auto_alloc_size = sizeof(struct meson_pinctrl), + .ops = &meson_axg_pinctrl_ops, +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.h b/drivers/pinctrl/meson/pinctrl-meson-axg.h new file mode 100644 index 0000000..c8d2b3a --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-axg.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com> + * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com> + */ + +#ifndef __PINCTRL_MESON_AXG_H__ +#define __PINCTRL_MESON_AXG_H__ + +#include "pinctrl-meson.h" + +struct meson_pmx_bank { + const char *name; + unsigned int first; + unsigned int last; + unsigned int reg; + unsigned int offset; +}; + +struct meson_axg_pmx_data { + struct meson_pmx_bank *pmx_banks; + unsigned int num_pmx_banks; +}; + +#define BANK_PMX(n, f, l, r, o) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .reg = r, \ + .offset = o, \ + } + +struct meson_pmx_axg_data { + unsigned int func; +}; + +#define PMX_DATA(f) \ + { \ + .func = f, \ + } + +#define GROUP(grp, f) \ + { \ + .name = #grp, \ + .pins = grp ## _pins, \ + .num_pins = ARRAY_SIZE(grp ## _pins), \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(f), \ + }, \ + } + +#define GPIO_GROUP(gpio, b) \ + { \ + .name = #gpio, \ + .pins = (const unsigned int[]){ PIN(gpio, b) }, \ + .num_pins = 1, \ + .data = (const struct meson_pmx_axg_data[]){ \ + PMX_DATA(0), \ + }, \ + } + +extern const struct pinctrl_ops meson_axg_pinctrl_ops; +extern const struct driver meson_axg_gpio_driver; + +#endif /* __PINCTRL_MESON_AXG_H__ */ diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c new file mode 100644 index 0000000..fc1538e --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com> + */ + +#include <asm/gpio.h> +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/io.h> +#include "pinctrl-meson-gx.h" + +static void meson_gx_pinmux_disable_other_groups(struct meson_pinctrl *priv, + unsigned int pin, + int sel_group) +{ + struct meson_pmx_group *group; + struct meson_gx_pmx_data *pmx_data; + void __iomem *addr; + int i, j; + + for (i = 0; i < priv->data->num_groups; i++) { + group = &priv->data->groups[i]; + pmx_data = (struct meson_gx_pmx_data *)group->data; + if (pmx_data->is_gpio || i == sel_group) + continue; + + for (j = 0; j < group->num_pins; j++) { + if (group->pins[j] == pin) { + /* We have found a group using the pin */ + debug("pinmux: disabling %s\n", group->name); + addr = priv->reg_mux + pmx_data->reg * 4; + writel(readl(addr) & ~BIT(pmx_data->bit), addr); + } + } + } +} + +static int meson_gx_pinmux_group_set(struct udevice *dev, + unsigned int group_selector, + unsigned int func_selector) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + const struct meson_pmx_group *group; + const struct meson_pmx_func *func; + struct meson_gx_pmx_data *pmx_data; + void __iomem *addr; + int i; + + group = &priv->data->groups[group_selector]; + pmx_data = (struct meson_gx_pmx_data *)group->data; + func = &priv->data->funcs[func_selector]; + + debug("pinmux: set group %s func %s\n", group->name, func->name); + + /* + * Disable groups using the same pins. + * The selected group is not disabled to avoid glitches. + */ + for (i = 0; i < group->num_pins; i++) { + meson_gx_pinmux_disable_other_groups(priv, + group->pins[i], + group_selector); + } + + /* Function 0 (GPIO) doesn't need any additional setting */ + if (func_selector) { + addr = priv->reg_mux + pmx_data->reg * 4; + writel(readl(addr) | BIT(pmx_data->bit), addr); + } + + return 0; +} + +const struct pinctrl_ops meson_gx_pinctrl_ops = { + .get_groups_count = meson_pinctrl_get_groups_count, + .get_group_name = meson_pinctrl_get_group_name, + .get_functions_count = meson_pinmux_get_functions_count, + .get_function_name = meson_pinmux_get_function_name, + .pinmux_group_set = meson_gx_pinmux_group_set, + .set_state = pinctrl_generic_set_state, +}; + +static const struct dm_gpio_ops meson_gx_gpio_ops = { + .set_value = meson_gpio_set, + .get_value = meson_gpio_get, + .get_function = meson_gpio_get_direction, + .direction_input = meson_gpio_direction_input, + .direction_output = meson_gpio_direction_output, +}; + +const struct driver meson_gx_gpio_driver = { + .name = "meson-gx-gpio", + .id = UCLASS_GPIO, + .probe = meson_gpio_probe, + .ops = &meson_gx_gpio_ops, +}; diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx.h b/drivers/pinctrl/meson/pinctrl-meson-gx.h new file mode 100644 index 0000000..4c1aa1a --- /dev/null +++ b/drivers/pinctrl/meson/pinctrl-meson-gx.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> + * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com> + */ + +#ifndef __PINCTRL_MESON_GX_H__ +#define __PINCTRL_MESON_GX_H__ + +#include "pinctrl-meson.h" + +struct meson_gx_pmx_data { + bool is_gpio; + unsigned int reg; + unsigned int bit; +}; + +#define PMX_DATA(r, b, g) \ + { \ + .reg = r, \ + .bit = b, \ + .is_gpio = g, \ + } + +#define GROUP(grp, r, b) \ + { \ + .name = #grp, \ + .pins = grp ## _pins, \ + .num_pins = ARRAY_SIZE(grp ## _pins), \ + .data = (const struct meson_gx_pmx_data[]){ \ + PMX_DATA(r, b, false), \ + }, \ + } + +#define GPIO_GROUP(gpio, b) \ + { \ + .name = #gpio, \ + .pins = (const unsigned int[]){ PIN(gpio, b) }, \ + .num_pins = 1, \ + .data = (const struct meson_gx_pmx_data[]){ \ + PMX_DATA(0, 0, true), \ + }, \ + } + +extern const struct pinctrl_ops meson_gx_pinctrl_ops; +extern const struct driver meson_gx_gpio_driver; + +#endif /* __PINCTRL_MESON_GX_H__ */ diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index a8e47e3..22e8b05 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -11,7 +11,7 @@ #include <dm/pinctrl.h> #include <dt-bindings/gpio/meson-gxbb-gpio.h> -#include "pinctrl-meson.h" +#include "pinctrl-meson-gx.h" #define EE_OFF 15 @@ -417,6 +417,7 @@ struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = { .num_groups = ARRAY_SIZE(meson_gxbb_periphs_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_periphs_functions), .num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks), + .gpio_driver = &meson_gx_gpio_driver, }; struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { @@ -429,6 +430,7 @@ struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = { .num_groups = ARRAY_SIZE(meson_gxbb_aobus_groups), .num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions), .num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks), + .gpio_driver = &meson_gx_gpio_driver, }; static const struct udevice_id meson_gxbb_pinctrl_match[] = { @@ -449,5 +451,5 @@ U_BOOT_DRIVER(meson_gxbb_pinctrl) = { .of_match = of_match_ptr(meson_gxbb_pinctrl_match), .probe = meson_pinctrl_probe, .priv_auto_alloc_size = sizeof(struct meson_pinctrl), - .ops = &meson_pinctrl_ops, + .ops = &meson_gx_pinctrl_ops, }; diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c index ba6e353..1819eee 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c @@ -11,7 +11,7 @@ #include <dm/pinctrl.h> #include <dt-bindings/gpio/meson-gxl-gpio.h> -#include "pinctrl-meson.h" +#include "pinctrl-meson-gx.h" #define EE_OFF 11 @@ -699,6 +699,7 @@ struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = { .num_groups = ARRAY_SIZE(meson_gxl_periphs_groups), .num_funcs = ARRAY_SIZE(meson_gxl_periphs_functions), .num_banks = ARRAY_SIZE(meson_gxl_periphs_banks), + .gpio_driver = &meson_gx_gpio_driver, }; struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = { @@ -711,6 +712,7 @@ struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = { .num_groups = ARRAY_SIZE(meson_gxl_aobus_groups), .num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions), .num_banks = ARRAY_SIZE(meson_gxl_aobus_banks), + .gpio_driver = &meson_gx_gpio_driver, }; static const struct udevice_id meson_gxl_pinctrl_match[] = { @@ -731,5 +733,5 @@ U_BOOT_DRIVER(meson_gxl_pinctrl) = { .of_match = of_match_ptr(meson_gxl_pinctrl_match), .probe = meson_pinctrl_probe, .priv_auto_alloc_size = sizeof(struct meson_pinctrl), - .ops = &meson_pinctrl_ops, + .ops = &meson_gx_pinctrl_ops, }; diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 387c241..0bd6152 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -20,15 +20,15 @@ DECLARE_GLOBAL_DATA_PTR; static const char *meson_pinctrl_dummy_name = "_dummy"; -static int meson_pinctrl_get_groups_count(struct udevice *dev) +int meson_pinctrl_get_groups_count(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); return priv->data->num_groups; } -static const char *meson_pinctrl_get_group_name(struct udevice *dev, - unsigned selector) +const char *meson_pinctrl_get_group_name(struct udevice *dev, + unsigned int selector) { struct meson_pinctrl *priv = dev_get_priv(dev); @@ -38,87 +38,21 @@ static const char *meson_pinctrl_get_group_name(struct udevice *dev, return priv->data->groups[selector].name; } -static int meson_pinmux_get_functions_count(struct udevice *dev) +int meson_pinmux_get_functions_count(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); return priv->data->num_funcs; } -static const char *meson_pinmux_get_function_name(struct udevice *dev, - unsigned selector) +const char *meson_pinmux_get_function_name(struct udevice *dev, + unsigned int selector) { struct meson_pinctrl *priv = dev_get_priv(dev); return priv->data->funcs[selector].name; } -static void meson_pinmux_disable_other_groups(struct meson_pinctrl *priv, - unsigned int pin, int sel_group) -{ - struct meson_pmx_group *group; - void __iomem *addr; - int i, j; - - for (i = 0; i < priv->data->num_groups; i++) { - group = &priv->data->groups[i]; - if (group->is_gpio || i == sel_group) - continue; - - for (j = 0; j < group->num_pins; j++) { - if (group->pins[j] == pin) { - /* We have found a group using the pin */ - debug("pinmux: disabling %s\n", group->name); - addr = priv->reg_mux + group->reg * 4; - writel(readl(addr) & ~BIT(group->bit), addr); - } - } - } -} - -static int meson_pinmux_group_set(struct udevice *dev, - unsigned group_selector, - unsigned func_selector) -{ - struct meson_pinctrl *priv = dev_get_priv(dev); - const struct meson_pmx_group *group; - const struct meson_pmx_func *func; - void __iomem *addr; - int i; - - group = &priv->data->groups[group_selector]; - func = &priv->data->funcs[func_selector]; - - debug("pinmux: set group %s func %s\n", group->name, func->name); - - /* - * Disable groups using the same pins. - * The selected group is not disabled to avoid glitches. - */ - for (i = 0; i < group->num_pins; i++) { - meson_pinmux_disable_other_groups(priv, - group->pins[i], - group_selector); - } - - /* Function 0 (GPIO) doesn't need any additional setting */ - if (func_selector) { - addr = priv->reg_mux + group->reg * 4; - writel(readl(addr) | BIT(group->bit), addr); - } - - return 0; -} - -const struct pinctrl_ops meson_pinctrl_ops = { - .get_groups_count = meson_pinctrl_get_groups_count, - .get_group_name = meson_pinctrl_get_group_name, - .get_functions_count = meson_pinmux_get_functions_count, - .get_function_name = meson_pinmux_get_function_name, - .pinmux_group_set = meson_pinmux_group_set, - .set_state = pinctrl_generic_set_state, -}; - static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset, enum meson_reg_type reg_type, unsigned int *reg, unsigned int *bit) @@ -149,7 +83,7 @@ static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset, return 0; } -static int meson_gpio_get(struct udevice *dev, unsigned int offset) +int meson_gpio_get(struct udevice *dev, unsigned int offset) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); unsigned int reg, bit; @@ -162,7 +96,7 @@ static int meson_gpio_get(struct udevice *dev, unsigned int offset) return !!(readl(priv->reg_gpio + reg) & BIT(bit)); } -static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value) +int meson_gpio_set(struct udevice *dev, unsigned int offset, int value) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); unsigned int reg, bit; @@ -177,7 +111,7 @@ static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value) return 0; } -static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset) +int meson_gpio_get_direction(struct udevice *dev, unsigned int offset) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); unsigned int reg, bit, val; @@ -192,7 +126,7 @@ static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset) return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT; } -static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset) +int meson_gpio_direction_input(struct udevice *dev, unsigned int offset) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); unsigned int reg, bit; @@ -207,8 +141,8 @@ static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset) return 0; } -static int meson_gpio_direction_output(struct udevice *dev, - unsigned int offset, int value) +int meson_gpio_direction_output(struct udevice *dev, + unsigned int offset, int value) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); unsigned int reg, bit; @@ -229,7 +163,7 @@ static int meson_gpio_direction_output(struct udevice *dev, return 0; } -static int meson_gpio_probe(struct udevice *dev) +int meson_gpio_probe(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev->parent); struct gpio_dev_priv *uc_priv; @@ -241,21 +175,6 @@ static int meson_gpio_probe(struct udevice *dev) return 0; } -static const struct dm_gpio_ops meson_gpio_ops = { - .set_value = meson_gpio_set, - .get_value = meson_gpio_get, - .get_function = meson_gpio_get_direction, - .direction_input = meson_gpio_direction_input, - .direction_output = meson_gpio_direction_output, -}; - -static struct driver meson_gpio_driver = { - .name = "meson-gpio", - .id = UCLASS_GPIO, - .probe = meson_gpio_probe, - .ops = &meson_gpio_ops, -}; - static fdt_addr_t parse_address(int offset, const char *name, int na, int ns) { int index, len = 0; @@ -334,7 +253,7 @@ int meson_pinctrl_probe(struct udevice *dev) sprintf(name, "meson-gpio"); /* Create child device UCLASS_GPIO and bind it */ - device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev); + device_bind(dev, priv->data->gpio_driver, name, NULL, gpio, &gpio_dev); dev_set_of_offset(gpio_dev, gpio); return 0; diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index 6ec89ba..bdee721 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -12,9 +12,7 @@ struct meson_pmx_group { const char *name; const unsigned int *pins; unsigned int num_pins; - bool is_gpio; - unsigned int reg; - unsigned int bit; + const void *data; }; struct meson_pmx_func { @@ -33,6 +31,8 @@ struct meson_pinctrl_data { unsigned int num_groups; unsigned int num_funcs; unsigned int num_banks; + const struct driver *gpio_driver; + void *pmx_data; }; struct meson_pinctrl { @@ -89,23 +89,6 @@ struct meson_bank { #define PIN(x, b) (b + x) -#define GROUP(grp, r, b) \ - { \ - .name = #grp, \ - .pins = grp ## _pins, \ - .num_pins = ARRAY_SIZE(grp ## _pins), \ - .reg = r, \ - .bit = b, \ - } - -#define GPIO_GROUP(gpio, b) \ - { \ - .name = #gpio, \ - .pins = (const unsigned int[]){ PIN(gpio, b) }, \ - .num_pins = 1, \ - .is_gpio = true, \ - } - #define FUNCTION(fn) \ { \ .name = #fn, \ @@ -131,6 +114,20 @@ struct meson_bank { extern const struct pinctrl_ops meson_pinctrl_ops; +int meson_pinctrl_get_groups_count(struct udevice *dev); +const char *meson_pinctrl_get_group_name(struct udevice *dev, + unsigned int selector); +int meson_pinmux_get_functions_count(struct udevice *dev); +const char *meson_pinmux_get_function_name(struct udevice *dev, + unsigned int selector); int meson_pinctrl_probe(struct udevice *dev); +int meson_gpio_get(struct udevice *dev, unsigned int offset); +int meson_gpio_set(struct udevice *dev, unsigned int offset, int value); +int meson_gpio_get_direction(struct udevice *dev, unsigned int offset); +int meson_gpio_direction_input(struct udevice *dev, unsigned int offset); +int meson_gpio_direction_output(struct udevice *dev, unsigned int offset, + int value); +int meson_gpio_probe(struct udevice *dev); + #endif /* __PINCTRL_MESON_H__ */ |