From b799eabc7ee3086a708297d2309ebfe0be9adb68 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 12 Aug 2021 20:09:43 -0500 Subject: sunxi: pinctrl: Create the driver skeleton Create a do-nothing driver for each sunxi pin controller variant. Since only one driver can automatically bind to a DT node, since the GPIO driver already requires a manual binding process, and since the pinctrl driver needs access to some of the same information, refactor the GPIO driver to be bound by the pinctrl driver. This commit should cause no functional change. Signed-off-by: Samuel Holland Signed-off-by: Andre Przywara --- drivers/gpio/sunxi_gpio.c | 130 +----------- drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/sunxi/Kconfig | 125 ++++++++++++ drivers/pinctrl/sunxi/Makefile | 3 + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 362 ++++++++++++++++++++++++++++++++++ 6 files changed, 494 insertions(+), 129 deletions(-) create mode 100644 drivers/pinctrl/sunxi/Kconfig create mode 100644 drivers/pinctrl/sunxi/Makefile create mode 100644 drivers/pinctrl/sunxi/pinctrl-sunxi.c (limited to 'drivers') diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 6c3c10862c4..1e85db179a6 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -16,15 +16,8 @@ #include #include #include -#include #include -struct sunxi_gpio_plat { - struct sunxi_gpio *regs; - const char *bank_name; /* Name of bank, e.g. "B" */ - int gpio_count; -}; - #if !CONFIG_IS_ENABLED(DM_GPIO) static int sunxi_gpio_output(u32 pin, u32 val) { @@ -211,28 +204,6 @@ static const struct dm_gpio_ops gpio_sunxi_ops = { .set_flags = sunxi_gpio_set_flags, }; -/** - * Returns the name of a GPIO bank - * - * GPIO banks are named A, B, C, ... - * - * @bank: Bank number (0, 1..n-1) - * Return: allocated string containing the name - */ -static char *gpio_bank_name(int bank) -{ - char *name; - - name = malloc(3); - if (name) { - name[0] = 'P'; - name[1] = 'A' + bank; - name[2] = '\0'; - } - - return name; -} - static int gpio_sunxi_probe(struct udevice *dev) { struct sunxi_gpio_plat *plat = dev_get_plat(dev); @@ -240,114 +211,17 @@ static int gpio_sunxi_probe(struct udevice *dev) /* Tell the uclass how many GPIOs we have */ if (plat) { - uc_priv->gpio_count = plat->gpio_count; + uc_priv->gpio_count = SUNXI_GPIOS_PER_BANK; uc_priv->bank_name = plat->bank_name; } return 0; } -struct sunxi_gpio_soc_data { - int start; - int no_banks; -}; - -/** - * We have a top-level GPIO device with no actual GPIOs. It has a child - * device for each Sunxi bank. - */ -static int gpio_sunxi_bind(struct udevice *parent) -{ - struct sunxi_gpio_soc_data *soc_data = - (struct sunxi_gpio_soc_data *)dev_get_driver_data(parent); - struct sunxi_gpio_plat *plat = dev_get_plat(parent); - struct sunxi_gpio_reg *ctlr; - int bank, ret; - - /* If this is a child device, there is nothing to do here */ - if (plat) - return 0; - - ctlr = dev_read_addr_ptr(parent); - for (bank = 0; bank < soc_data->no_banks; bank++) { - struct sunxi_gpio_plat *plat; - struct udevice *dev; - - plat = calloc(1, sizeof(*plat)); - if (!plat) - return -ENOMEM; - plat->regs = &ctlr->gpio_bank[bank]; - plat->bank_name = gpio_bank_name(soc_data->start + bank); - plat->gpio_count = SUNXI_GPIOS_PER_BANK; - - ret = device_bind(parent, parent->driver, plat->bank_name, plat, - dev_ofnode(parent), &dev); - if (ret) - return ret; - } - - return 0; -} - -static const struct sunxi_gpio_soc_data soc_data_a_all = { - .start = 0, - .no_banks = SUNXI_GPIO_BANKS, -}; - -static const struct sunxi_gpio_soc_data soc_data_l_1 = { - .start = 'L' - 'A', - .no_banks = 1, -}; - -static const struct sunxi_gpio_soc_data soc_data_l_2 = { - .start = 'L' - 'A', - .no_banks = 2, -}; - -static const struct sunxi_gpio_soc_data soc_data_l_3 = { - .start = 'L' - 'A', - .no_banks = 3, -}; - -#define ID(_compat_, _soc_data_) \ - { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ } - -static const struct udevice_id sunxi_gpio_ids[] = { - ID("allwinner,sun4i-a10-pinctrl", a_all), - ID("allwinner,sun5i-a10s-pinctrl", a_all), - ID("allwinner,sun5i-a13-pinctrl", a_all), - ID("allwinner,sun50i-h5-pinctrl", a_all), - ID("allwinner,sun6i-a31-pinctrl", a_all), - ID("allwinner,sun6i-a31s-pinctrl", a_all), - ID("allwinner,sun7i-a20-pinctrl", a_all), - ID("allwinner,sun8i-a23-pinctrl", a_all), - ID("allwinner,sun8i-a33-pinctrl", a_all), - ID("allwinner,sun8i-a83t-pinctrl", a_all), - ID("allwinner,sun8i-h3-pinctrl", a_all), - ID("allwinner,sun8i-r40-pinctrl", a_all), - ID("allwinner,sun8i-v3-pinctrl", a_all), - ID("allwinner,sun8i-v3s-pinctrl", a_all), - ID("allwinner,sun9i-a80-pinctrl", a_all), - ID("allwinner,sun50i-a64-pinctrl", a_all), - ID("allwinner,sun50i-h6-pinctrl", a_all), - ID("allwinner,sun50i-h616-pinctrl", a_all), - ID("allwinner,sun6i-a31-r-pinctrl", l_2), - ID("allwinner,sun8i-a23-r-pinctrl", l_1), - ID("allwinner,sun8i-a83t-r-pinctrl", l_1), - ID("allwinner,sun8i-h3-r-pinctrl", l_1), - ID("allwinner,sun9i-a80-r-pinctrl", l_3), - ID("allwinner,sun50i-a64-r-pinctrl", l_1), - ID("allwinner,sun50i-h6-r-pinctrl", l_2), - ID("allwinner,sun50i-h616-r-pinctrl", l_1), - { } -}; - U_BOOT_DRIVER(gpio_sunxi) = { .name = "gpio_sunxi", .id = UCLASS_GPIO, - .ops = &gpio_sunxi_ops, - .of_match = sunxi_gpio_ids, - .bind = gpio_sunxi_bind, .probe = gpio_sunxi_probe, + .ops = &gpio_sunxi_ops, }; #endif /* DM_GPIO */ diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 03946245c7d..6a640ba3a21 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -332,6 +332,7 @@ source "drivers/pinctrl/nexell/Kconfig" source "drivers/pinctrl/nxp/Kconfig" source "drivers/pinctrl/renesas/Kconfig" source "drivers/pinctrl/rockchip/Kconfig" +source "drivers/pinctrl/sunxi/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" endmenu diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index df37c32033f..32283ddd88d 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_PINCTRL_INTEL) += intel/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o - +obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig new file mode 100644 index 00000000000..96c2f35f3a5 --- /dev/null +++ b/drivers/pinctrl/sunxi/Kconfig @@ -0,0 +1,125 @@ +# SPDX-License-Identifier: GPL-2.0 + +if ARCH_SUNXI + +config PINCTRL_SUNXI + select PINCTRL_FULL + select PINCTRL_GENERIC + bool + +config PINCTRL_SUNIV_F1C100S + bool "Support for the Allwinner F1C100s PIO" + default MACH_SUNIV + select PINCTRL_SUNXI + +config PINCTRL_SUN4I_A10 + bool "Support for the Allwinner A10 PIO" + default MACH_SUN4I + select PINCTRL_SUNXI + +config PINCTRL_SUN5I_A13 + bool "Support for the Allwinner A10s/A13 PIO" + default MACH_SUN5I + select PINCTRL_SUNXI + +config PINCTRL_SUN6I_A31 + bool "Support for the Allwinner A31 PIO" + default MACH_SUN6I + select PINCTRL_SUNXI + +config PINCTRL_SUN6I_A31_R + bool "Support for the Allwinner A31 R-PIO" + default MACH_SUN6I + select PINCTRL_SUNXI + +config PINCTRL_SUN7I_A20 + bool "Support for the Allwinner A20/R40 PIO" + default MACH_SUN7I || MACH_SUN8I_R40 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_A23 + bool "Support for the Allwinner A23 PIO" + default MACH_SUN8I_A23 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_A23_R + bool "Support for the Allwinner A23/A33 R-PIO" + default MACH_SUN8I_A23 || MACH_SUN8I_A33 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_A33 + bool "Support for the Allwinner A33 PIO" + default MACH_SUN8I_A33 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_A83T + bool "Support for the Allwinner A83T PIO" + default MACH_SUN8I_A83T + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_A83T_R + bool "Support for the Allwinner A83T R-PIO" + default MACH_SUN8I_A83T + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_H3 + bool "Support for the Allwinner H3 PIO" + default MACH_SUN8I_H3 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_H3_R + bool "Support for the Allwinner H3/H5 R-PIO" + default MACH_SUN8I_H3 || MACH_SUN50I_H5 + select PINCTRL_SUNXI + +config PINCTRL_SUN8I_V3S + bool "Support for the Allwinner V3s PIO" + default MACH_SUN8I_V3S + select PINCTRL_SUNXI + +config PINCTRL_SUN9I_A80 + bool "Support for the Allwinner A80 PIO" + default MACH_SUN9I + select PINCTRL_SUNXI + +config PINCTRL_SUN9I_A80_R + bool "Support for the Allwinner A80 R-PIO" + default MACH_SUN9I + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_A64 + bool "Support for the Allwinner A64 PIO" + default MACH_SUN50I + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_A64_R + bool "Support for the Allwinner A64 R-PIO" + default MACH_SUN50I + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H5 + bool "Support for the Allwinner H5 PIO" + default MACH_SUN50I_H5 + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H6 + bool "Support for the Allwinner H6 PIO" + default MACH_SUN50I_H6 + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H6_R + bool "Support for the Allwinner H6 R-PIO" + default MACH_SUN50I_H6 + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H616 + bool "Support for the Allwinner H616 PIO" + default MACH_SUN50I_H616 + select PINCTRL_SUNXI + +config PINCTRL_SUN50I_H616_R + bool "Support for the Allwinner H616 R-PIO" + default MACH_SUN50I_H616 + select PINCTRL_SUNXI + +endif diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile new file mode 100644 index 00000000000..6a8c01f3729 --- /dev/null +++ b/drivers/pinctrl/sunxi/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += pinctrl-sunxi.o diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c new file mode 100644 index 00000000000..43bb1ec650a --- /dev/null +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include + +#include + +extern U_BOOT_DRIVER(gpio_sunxi); + +struct sunxi_pinctrl_desc { + u8 first_bank; + u8 num_banks; +}; + +struct sunxi_pinctrl_plat { + struct sunxi_gpio __iomem *base; +}; + +static const struct pinctrl_ops sunxi_pinctrl_ops = { + .set_state = pinctrl_generic_set_state, +}; + +static int sunxi_pinctrl_bind(struct udevice *dev) +{ + struct sunxi_pinctrl_plat *plat = dev_get_plat(dev); + struct sunxi_pinctrl_desc *desc; + struct sunxi_gpio_plat *gpio_plat; + struct udevice *gpio_dev; + int i, ret; + + desc = (void *)dev_get_driver_data(dev); + if (!desc) + return -EINVAL; + dev_set_priv(dev, desc); + + plat->base = dev_read_addr_ptr(dev); + + ret = device_bind_driver_to_node(dev, "gpio_sunxi", dev->name, + dev_ofnode(dev), &gpio_dev); + if (ret) + return ret; + + for (i = 0; i < desc->num_banks; ++i) { + gpio_plat = malloc(sizeof(*gpio_plat)); + if (!gpio_plat) + return -ENOMEM; + + gpio_plat->regs = plat->base + i; + gpio_plat->bank_name[0] = 'P'; + gpio_plat->bank_name[1] = 'A' + desc->first_bank + i; + gpio_plat->bank_name[2] = '\0'; + + ret = device_bind(gpio_dev, DM_DRIVER_REF(gpio_sunxi), + gpio_plat->bank_name, gpio_plat, + ofnode_null(), NULL); + if (ret) + return ret; + } + + return 0; +} + +static int sunxi_pinctrl_probe(struct udevice *dev) +{ + struct clk *apb_clk; + + apb_clk = devm_clk_get(dev, "apb"); + if (!IS_ERR(apb_clk)) + clk_enable(apb_clk); + + return 0; +} + +static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 6, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 9, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 7, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 2, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 9, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 1, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 1, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 7, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 1, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 7, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 3, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 1, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 7, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 8, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 2, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = { + .first_bank = SUNXI_GPIO_A, + .num_banks = 9, +}; + +static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = { + .first_bank = SUNXI_GPIO_L, + .num_banks = 1, +}; + +static const struct udevice_id sunxi_pinctrl_ids[] = { +#ifdef CONFIG_PINCTRL_SUNIV_F1C100S + { + .compatible = "allwinner,suniv-f1c100s-pinctrl", + .data = (ulong)&suniv_f1c100s_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN4I_A10 + { + .compatible = "allwinner,sun4i-a10-pinctrl", + .data = (ulong)&sun4i_a10_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN5I_A13 + { + .compatible = "allwinner,sun5i-a10s-pinctrl", + .data = (ulong)&sun5i_a13_pinctrl_desc, + }, + { + .compatible = "allwinner,sun5i-a13-pinctrl", + .data = (ulong)&sun5i_a13_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN6I_A31 + { + .compatible = "allwinner,sun6i-a31-pinctrl", + .data = (ulong)&sun6i_a31_pinctrl_desc, + }, + { + .compatible = "allwinner,sun6i-a31s-pinctrl", + .data = (ulong)&sun6i_a31_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN6I_A31_R + { + .compatible = "allwinner,sun6i-a31-r-pinctrl", + .data = (ulong)&sun6i_a31_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN7I_A20 + { + .compatible = "allwinner,sun7i-a20-pinctrl", + .data = (ulong)&sun7i_a20_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_A23 + { + .compatible = "allwinner,sun8i-a23-pinctrl", + .data = (ulong)&sun8i_a23_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_A23_R + { + .compatible = "allwinner,sun8i-a23-r-pinctrl", + .data = (ulong)&sun8i_a23_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_A33 + { + .compatible = "allwinner,sun8i-a33-pinctrl", + .data = (ulong)&sun8i_a33_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_A83T + { + .compatible = "allwinner,sun8i-a83t-pinctrl", + .data = (ulong)&sun8i_a83t_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_A83T_R + { + .compatible = "allwinner,sun8i-a83t-r-pinctrl", + .data = (ulong)&sun8i_a83t_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_H3 + { + .compatible = "allwinner,sun8i-h3-pinctrl", + .data = (ulong)&sun8i_h3_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_H3_R + { + .compatible = "allwinner,sun8i-h3-r-pinctrl", + .data = (ulong)&sun8i_h3_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN7I_A20 + { + .compatible = "allwinner,sun8i-r40-pinctrl", + .data = (ulong)&sun7i_a20_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN8I_V3S + { + .compatible = "allwinner,sun8i-v3-pinctrl", + .data = (ulong)&sun8i_v3s_pinctrl_desc, + }, + { + .compatible = "allwinner,sun8i-v3s-pinctrl", + .data = (ulong)&sun8i_v3s_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN9I_A80 + { + .compatible = "allwinner,sun9i-a80-pinctrl", + .data = (ulong)&sun9i_a80_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN9I_A80_R + { + .compatible = "allwinner,sun9i-a80-r-pinctrl", + .data = (ulong)&sun9i_a80_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_A64 + { + .compatible = "allwinner,sun50i-a64-pinctrl", + .data = (ulong)&sun50i_a64_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_A64_R + { + .compatible = "allwinner,sun50i-a64-r-pinctrl", + .data = (ulong)&sun50i_a64_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_H5 + { + .compatible = "allwinner,sun50i-h5-pinctrl", + .data = (ulong)&sun50i_h5_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_H6 + { + .compatible = "allwinner,sun50i-h6-pinctrl", + .data = (ulong)&sun50i_h6_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_H6_R + { + .compatible = "allwinner,sun50i-h6-r-pinctrl", + .data = (ulong)&sun50i_h6_r_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_H616 + { + .compatible = "allwinner,sun50i-h616-pinctrl", + .data = (ulong)&sun50i_h616_pinctrl_desc, + }, +#endif +#ifdef CONFIG_PINCTRL_SUN50I_H616_R + { + .compatible = "allwinner,sun50i-h616-r-pinctrl", + .data = (ulong)&sun50i_h616_r_pinctrl_desc, + }, +#endif + {} +}; + +U_BOOT_DRIVER(sunxi_pinctrl) = { + .name = "sunxi-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = sunxi_pinctrl_ids, + .bind = sunxi_pinctrl_bind, + .probe = sunxi_pinctrl_probe, + .plat_auto = sizeof(struct sunxi_pinctrl_plat), + .ops = &sunxi_pinctrl_ops, +}; -- cgit v1.3.1 From 29babfd92b25883ce45f294b8eeacc04113389e7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Mon, 16 Aug 2021 23:56:47 -0500 Subject: sunxi: pinctrl: Implement pin muxing functions Implement the operations to get pin and function names, and to set the mux for a pin. The pin count and pin names are calculated as if each bank has the maximum number of pins. Function names are simply the index into a list of { function name, mux value } pairs. We assume all pins associated with a function use the same mux value for that function. This is generally true within a group of pins on a single port, but generally false when some peripheral can be muxed to multiple ports. For example, A64 UART3 uses mux 3 on port D, and mux 2 on port H. But all of the port D pins use the same mux value, and so do all of the port H pins. This applies even when the pins for some function are not contiguous, and when the lower-numbered mux values are unused. A good example of both of these cases is SPI0 on most SoCs. This strategy saves a lot of space (which is especially important for SPL), but where the mux value for a certain function differs across ports, it forces us to choose a single port for that function at build time. Since almost all boards use the default (i.e. reference design) pin muxes[1], this is unlikely to be a problem. [1]: See commit dda9fa734f81 ("sunxi: Simplify MMC pinmux selection") Signed-off-by: Samuel Holland [Andre: add comment summarising the commit message] Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/Kconfig | 1 + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 237 ++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index 96c2f35f3a5..f4949f89e0d 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -5,6 +5,7 @@ if ARCH_SUNXI config PINCTRL_SUNXI select PINCTRL_FULL select PINCTRL_GENERIC + select PINMUX bool config PINCTRL_SUNIV_F1C100S diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 43bb1ec650a..fe6c46cdd5b 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -12,7 +12,24 @@ extern U_BOOT_DRIVER(gpio_sunxi); +/* + * This structure implements a simplified view of the possible pinmux settings: + * Each mux value is assumed to be the same for a given function, across the + * pins in each group (almost universally true, with same rare exceptions not + * relevant to U-Boot), but also across different ports (not true in many + * cases). We ignore the first problem, and work around the latter by just + * supporting one particular port for a each function. This works fine for all + * board configurations so far. If this would need to be revisited, we could + * add a "u8 port;" below and match that, with 0 encoding the "don't care" case. + */ +struct sunxi_pinctrl_function { + const char name[sizeof("gpio_out")]; + u8 mux; +}; + struct sunxi_pinctrl_desc { + const struct sunxi_pinctrl_function *functions; + u8 num_functions; u8 first_bank; u8 num_banks; }; @@ -21,7 +38,66 @@ struct sunxi_pinctrl_plat { struct sunxi_gpio __iomem *base; }; +static int sunxi_pinctrl_get_pins_count(struct udevice *dev) +{ + const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev); + + return desc->num_banks * SUNXI_GPIOS_PER_BANK; +} + +static const char *sunxi_pinctrl_get_pin_name(struct udevice *dev, + uint pin_selector) +{ + const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev); + static char pin_name[sizeof("PN31")]; + + snprintf(pin_name, sizeof(pin_name), "P%c%d", + pin_selector / SUNXI_GPIOS_PER_BANK + desc->first_bank + 'A', + pin_selector % SUNXI_GPIOS_PER_BANK); + + return pin_name; +} + +static int sunxi_pinctrl_get_functions_count(struct udevice *dev) +{ + const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev); + + return desc->num_functions; +} + +static const char *sunxi_pinctrl_get_function_name(struct udevice *dev, + uint func_selector) +{ + const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev); + + return desc->functions[func_selector].name; +} + +static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector, + uint func_selector) +{ + const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev); + struct sunxi_pinctrl_plat *plat = dev_get_plat(dev); + int bank = pin_selector / SUNXI_GPIOS_PER_BANK; + int pin = pin_selector % SUNXI_GPIOS_PER_BANK; + + debug("set mux: %-4s => %s (%d)\n", + sunxi_pinctrl_get_pin_name(dev, pin_selector), + sunxi_pinctrl_get_function_name(dev, func_selector), + desc->functions[func_selector].mux); + + sunxi_gpio_set_cfgbank(plat->base + bank, pin, + desc->functions[func_selector].mux); + + return 0; +} + static const struct pinctrl_ops sunxi_pinctrl_ops = { + .get_pins_count = sunxi_pinctrl_get_pins_count, + .get_pin_name = sunxi_pinctrl_get_pin_name, + .get_functions_count = sunxi_pinctrl_get_functions_count, + .get_function_name = sunxi_pinctrl_get_function_name, + .pinmux_set = sunxi_pinctrl_pinmux_set, .set_state = pinctrl_generic_set_state, }; @@ -76,117 +152,278 @@ static int sunxi_pinctrl_probe(struct udevice *dev) return 0; } +static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = { + .functions = suniv_f1c100s_pinctrl_functions, + .num_functions = ARRAY_SIZE(suniv_f1c100s_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 6, }; +static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = { + .functions = sun4i_a10_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun4i_a10_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 9, }; +static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = { + .functions = sun5i_a13_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun5i_a13_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 7, }; +static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = { + .functions = sun6i_a31_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun6i_a31_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun6i_a31_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = { + .functions = sun6i_a31_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun6i_a31_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 2, }; +static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = { + .functions = sun7i_a20_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun7i_a20_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 9, }; +static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = { + .functions = sun8i_a23_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_a23_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun8i_a23_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = { + .functions = sun8i_a23_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_a23_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 1, }; +static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = { + .functions = sun8i_a33_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_a33_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = { + .functions = sun8i_a83t_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_a83t_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun8i_a83t_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = { + .functions = sun8i_a83t_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_a83t_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 1, }; +static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = { + .functions = sun8i_h3_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_h3_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 7, }; +static const struct sunxi_pinctrl_function sun8i_h3_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = { + .functions = sun8i_h3_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_h3_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 1, }; +static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = { + .functions = sun8i_v3s_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun8i_v3s_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 7, }; +static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = { + .functions = sun9i_a80_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun9i_a80_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun9i_a80_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = { + .functions = sun9i_a80_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun9i_a80_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 3, }; +static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = { + .functions = sun50i_a64_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_a64_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = { + .functions = sun50i_a64_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_a64_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 1, }; +static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = { + .functions = sun50i_h5_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_h5_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 7, }; +static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = { + .functions = sun50i_h6_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_h6_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 8, }; +static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = { + .functions = sun50i_h6_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_h6_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 2, }; +static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = { + .functions = sun50i_h616_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_h616_pinctrl_functions), .first_bank = SUNXI_GPIO_A, .num_banks = 9, }; +static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = { + { "gpio_in", 0 }, + { "gpio_out", 1 }, +}; + static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = { + .functions = sun50i_h616_r_pinctrl_functions, + .num_functions = ARRAY_SIZE(sun50i_h616_r_pinctrl_functions), .first_bank = SUNXI_GPIO_L, .num_banks = 1, }; -- cgit v1.3.1 From d4b388244abfb7580a00967147fc5e45baf2f41f Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Tue, 17 Aug 2021 00:52:00 -0500 Subject: sunxi: pinctrl: Implement get_pin_muxing function The pinmux command uses this function to display pinmux status. Since the driver cannot map pin numbers to a list of supported functions, only functions which are common across all pins can be reported by name. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index fe6c46cdd5b..789cfbacbbc 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -92,6 +92,32 @@ static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector, return 0; } +static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector, + char *buf, int size) +{ + struct sunxi_pinctrl_plat *plat = dev_get_plat(dev); + int bank = pin_selector / SUNXI_GPIOS_PER_BANK; + int pin = pin_selector % SUNXI_GPIOS_PER_BANK; + int mux = sunxi_gpio_get_cfgbank(plat->base + bank, pin); + + switch (mux) { + case SUNXI_GPIO_INPUT: + strlcpy(buf, "gpio input", size); + break; + case SUNXI_GPIO_OUTPUT: + strlcpy(buf, "gpio output", size); + break; + case SUNXI_GPIO_DISABLE: + strlcpy(buf, "disabled", size); + break; + default: + snprintf(buf, size, "function %d", mux); + break; + } + + return 0; +} + static const struct pinctrl_ops sunxi_pinctrl_ops = { .get_pins_count = sunxi_pinctrl_get_pins_count, .get_pin_name = sunxi_pinctrl_get_pin_name, @@ -99,6 +125,7 @@ static const struct pinctrl_ops sunxi_pinctrl_ops = { .get_function_name = sunxi_pinctrl_get_function_name, .pinmux_set = sunxi_pinctrl_pinmux_set, .set_state = pinctrl_generic_set_state, + .get_pin_muxing = sunxi_pinctrl_get_pin_muxing, }; static int sunxi_pinctrl_bind(struct udevice *dev) -- cgit v1.3.1 From 50c195ee851b35264df4bb8089a459470da491b5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 21:10:47 -0500 Subject: sunxi: pinctrl: Implement pin configuration The sunxi pinctrl hardware has bias and drive control. Add driver support for configuring those options. Reviewed-by: Simon Glass Signed-off-by: Samuel Holland Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/Kconfig | 1 + drivers/pinctrl/sunxi/pinctrl-sunxi.c | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig index f4949f89e0d..77da90836b6 100644 --- a/drivers/pinctrl/sunxi/Kconfig +++ b/drivers/pinctrl/sunxi/Kconfig @@ -5,6 +5,7 @@ if ARCH_SUNXI config PINCTRL_SUNXI select PINCTRL_FULL select PINCTRL_GENERIC + select PINCONF select PINMUX bool diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 789cfbacbbc..ffb0375be32 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -92,6 +92,56 @@ static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector, return 0; } +static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 2 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 10 }, +}; + +static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat, + uint bank, uint pin, uint bias) +{ + struct sunxi_gpio *regs = &plat->base[bank]; + + sunxi_gpio_set_pull_bank(regs, pin, bias); + + return 0; +} + +static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat, + uint bank, uint pin, uint drive) +{ + struct sunxi_gpio *regs = &plat->base[bank]; + + if (drive < 10 || drive > 40) + return -EINVAL; + + /* Convert mA to the register value, rounding down. */ + sunxi_gpio_set_drv_bank(regs, pin, drive / 10 - 1); + + return 0; +} + +static int sunxi_pinctrl_pinconf_set(struct udevice *dev, uint pin_selector, + uint param, uint val) +{ + struct sunxi_pinctrl_plat *plat = dev_get_plat(dev); + int bank = pin_selector / SUNXI_GPIOS_PER_BANK; + int pin = pin_selector % SUNXI_GPIOS_PER_BANK; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + return sunxi_pinctrl_pinconf_set_pull(plat, bank, pin, val); + case PIN_CONFIG_DRIVE_STRENGTH: + return sunxi_pinctrl_pinconf_set_drive(plat, bank, pin, val); + } + + return -EINVAL; +} + static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector, char *buf, int size) { @@ -124,6 +174,9 @@ static const struct pinctrl_ops sunxi_pinctrl_ops = { .get_functions_count = sunxi_pinctrl_get_functions_count, .get_function_name = sunxi_pinctrl_get_function_name, .pinmux_set = sunxi_pinctrl_pinmux_set, + .pinconf_num_params = ARRAY_SIZE(sunxi_pinctrl_pinconf_params), + .pinconf_params = sunxi_pinctrl_pinconf_params, + .pinconf_set = sunxi_pinctrl_pinconf_set, .set_state = pinctrl_generic_set_state, .get_pin_muxing = sunxi_pinctrl_get_pin_muxing, }; -- cgit v1.3.1 From 470a7bdb61b7eaff62bac70819e7b8190eb48e6a Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 13:00:45 -0500 Subject: pinctrl: sunxi: Add UART pinmuxes This includes UART0 and R_UART (s_uart) on all supported platforms, plus the additional UART configurations from arch/arm/mach-sunxi/board.c. Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 98 +++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index ffb0375be32..4c638f1ec81 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -235,6 +235,11 @@ static int sunxi_pinctrl_probe(struct udevice *dev) static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 5 }, /* PE0-PE1 */ +#endif }; static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = { @@ -247,6 +252,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 4 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PB22-PB23 */ +#endif }; static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = { @@ -259,6 +269,12 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = { static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 4 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PB19-PB20 */ +#endif + { "uart1", 4 }, /* PG3-PG4 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = { @@ -271,6 +287,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = { static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PH20-PH21 */ +#endif }; static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = { @@ -283,6 +304,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = { static const struct sunxi_pinctrl_function sun6i_a31_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = { @@ -295,6 +317,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 4 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PB22-PB23 */ +#endif }; static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = { @@ -307,6 +334,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PB0-PB1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = { @@ -319,6 +351,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_a23_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = { @@ -331,6 +364,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 3 }, /* PB0-PB1 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PB0-PB1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = { @@ -343,6 +383,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PB9-PB10 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PB0-PB1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = { @@ -355,6 +402,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = static const struct sunxi_pinctrl_function sun8i_a83t_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = { @@ -367,6 +415,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PA4-PA5 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PA0-PA1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = { @@ -379,6 +434,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_h3_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = { @@ -391,6 +447,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 3 }, /* PB8-PB9 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PB0-PB1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = { @@ -403,6 +466,11 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = { static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 4 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PH12-PH13 */ +#endif }; static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = { @@ -415,6 +483,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = { static const struct sunxi_pinctrl_function sun9i_a80_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 3 }, /* PL0-PL1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = { @@ -427,6 +496,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 4 }, /* PB8-PB9 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PB0-PB1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = { @@ -439,6 +515,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = { @@ -451,6 +528,13 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PA4-PA5 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ + { "uart2", 2 }, /* PA0-PA1 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = { @@ -463,6 +547,12 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = { static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PH0-PH1 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = { @@ -475,6 +565,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = { static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = { @@ -487,6 +578,12 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, +#if IS_ENABLED(CONFIG_UART0_PORT_F) + { "uart0", 3 }, /* PF2-PF4 */ +#else + { "uart0", 2 }, /* PH0-PH1 */ +#endif + { "uart1", 2 }, /* PG6-PG7 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = { @@ -499,6 +596,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_uart", 2 }, /* PL2-PL3 */ }; static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = { -- cgit v1.3.1 From fcdbbd68d389e9696e707706917b72c21f9f946b Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 13:21:36 -0500 Subject: pinctrl: sunxi: Add sun4i EMAC pinmuxes Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 4c638f1ec81..ce7119931da 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -250,6 +250,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc }; static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { + { "emac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -267,6 +268,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = { }; static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { + { "emac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -315,6 +317,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = }; static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { + { "emac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) -- cgit v1.3.1 From 12bd00aafc5a0848d21dbc096b6481d62bba976c Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 13:22:41 -0500 Subject: net: sunxi_emac: Remove non-DM pin setup This is now handled automatically by the pinctrl driver. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 - drivers/net/sunxi_emac.c | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 773711b6a3f..e93c9e84c98 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -135,7 +135,6 @@ enum sunxi_gpio_number { #define SUNXI_GPIO_OUTPUT 1 #define SUNXI_GPIO_DISABLE 7 -#define SUNXI_GPA_EMAC 2 #define SUN6I_GPA_GMAC 2 #define SUN7I_GPA_GMAC 5 #define SUN8I_H3_GPA_UART0 2 diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 17ad88e732e..d15b0add7c9 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -17,7 +17,6 @@ #include #include #include -#include /* EMAC register */ struct emac_regs { @@ -511,15 +510,11 @@ static int sunxi_emac_board_setup(struct udevice *dev, struct sunxi_sramc_regs *sram = (struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE; struct emac_regs *regs = priv->regs; - int pin, ret; + int ret; /* Map SRAM to EMAC */ setbits_le32(&sram->ctrl1, 0x5 << 2); - /* Configure pin mux settings for MII Ethernet */ - for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++) - sunxi_gpio_set_cfgpin(pin, SUNXI_GPA_EMAC); - /* Set up clock gating */ ret = clk_enable(&priv->clk); if (ret) { -- cgit v1.3.1 From 7a93644c69f5d856951ae366d4123c44b068716c Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 13:13:52 -0500 Subject: pinctrl: sunxi: Add sunxi GMAC pinmuxes Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index ce7119931da..01627494f94 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -287,6 +287,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = { }; static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { + { "gmac", 2 }, /* PA0-PA27 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -318,6 +319,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "emac", 2 }, /* PA0-PA17 */ + { "gmac", 5 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -467,6 +469,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = { }; static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { + { "gmac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) -- cgit v1.3.1 From 37b3de432f2ddbcfcebb9bb2ca1d6e783da191f5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 13:34:29 -0500 Subject: pinctrl: sunxi: Add sun8i EMAC pinmuxes Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 01627494f94..01d658ea6e9 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -386,6 +386,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = { }; static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { + { "gmac", 4 }, /* PD2-PD23 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -418,6 +419,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc }; static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { + { "emac", 2 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -450,6 +452,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = }; static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { + { "emac", 4 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -500,6 +503,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = }; static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { + { "emac", 4 }, /* PD8-PD23 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -532,6 +536,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc }; static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { + { "emac", 2 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -551,6 +556,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = { }; static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { + { "emac", 5 }, /* PD0-PD20 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) @@ -582,6 +588,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = }; static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { + { "emac0", 2 }, /* PI0-PI16 */ { "gpio_in", 0 }, { "gpio_out", 1 }, #if IS_ENABLED(CONFIG_UART0_PORT_F) -- cgit v1.3.1 From ae022e8366a3173c57b3701e4269fa55094e0be7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 11:49:40 -0500 Subject: net: sun8i_emac: Remove non-DM pin setup This is now handled automatically by the pinctrl driver. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/net/sun8i_emac.c | 90 ------------------------------------------------ 1 file changed, 90 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 2e24d122141..b23faa228e0 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #define MDIO_CMD_MII_BUSY BIT(0) @@ -81,13 +80,6 @@ #define AHB_GATE_OFFSET_EPHY 0 -/* IO mux settings */ -#define SUN8I_IOMUX_H3 2 -#define SUN8I_IOMUX_R40 5 -#define SUN8I_IOMUX_H6 5 -#define SUN8I_IOMUX_H616 2 -#define SUN8I_IOMUX 4 - /* H3/A64 EMAC Register's offset */ #define EMAC_CTL0 0x00 #define EMAC_CTL0_FULL_DUPLEX BIT(0) @@ -519,85 +511,6 @@ static int sun8i_emac_eth_start(struct udevice *dev) return 0; } -static int parse_phy_pins(struct udevice *dev) -{ - int offset; - const char *pin_name; - int drive, pull = SUN4I_PINCTRL_NO_PULL, i; - u32 iomux; - - offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev), - "pinctrl-0"); - if (offset < 0) { - printf("WARNING: emac: cannot find pinctrl-0 node\n"); - return offset; - } - - drive = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0, - "drive-strength", ~0); - if (drive != ~0) { - if (drive <= 10) - drive = SUN4I_PINCTRL_10_MA; - else if (drive <= 20) - drive = SUN4I_PINCTRL_20_MA; - else if (drive <= 30) - drive = SUN4I_PINCTRL_30_MA; - else - drive = SUN4I_PINCTRL_40_MA; - } - - if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-up", NULL)) - pull = SUN4I_PINCTRL_PULL_UP; - else if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-down", NULL)) - pull = SUN4I_PINCTRL_PULL_DOWN; - - /* - * The GPIO pinmux value is an integration choice, so depends on the - * SoC, not the EMAC variant. - */ - if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5)) - iomux = SUN8I_IOMUX_H3; - else if (IS_ENABLED(CONFIG_MACH_SUN8I_R40)) - iomux = SUN8I_IOMUX_R40; - else if (IS_ENABLED(CONFIG_MACH_SUN50I_H6)) - iomux = SUN8I_IOMUX_H6; - else if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) - iomux = SUN8I_IOMUX_H616; - else if (IS_ENABLED(CONFIG_MACH_SUN8I_A83T)) - iomux = SUN8I_IOMUX; - else if (IS_ENABLED(CONFIG_MACH_SUN50I)) - iomux = SUN8I_IOMUX; - else - BUILD_BUG_ON_MSG(1, "missing pinmux value for Ethernet pins"); - - for (i = 0; ; i++) { - int pin; - - pin_name = fdt_stringlist_get(gd->fdt_blob, offset, - "pins", i, NULL); - if (!pin_name) - break; - - pin = sunxi_name_to_gpio(pin_name); - if (pin < 0) - continue; - - sunxi_gpio_set_cfgpin(pin, iomux); - - if (drive != ~0) - sunxi_gpio_set_drv(pin, drive); - if (pull != ~0) - sunxi_gpio_set_pull(pin, pull); - } - - if (!i) { - printf("WARNING: emac: cannot find pins property\n"); - return -2; - } - - return 0; -} - static int sun8i_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct emac_eth_dev *priv = dev_get_priv(dev); @@ -965,9 +878,6 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev) priv->interface = pdata->phy_interface; - if (!priv->use_internal_phy) - parse_phy_pins(dev); - sun8i_pdata->tx_delay_ps = fdtdec_get_int(gd->fdt_blob, node, "allwinner,tx-delay-ps", 0); if (sun8i_pdata->tx_delay_ps < 0 || sun8i_pdata->tx_delay_ps > 700) -- cgit v1.3.1 From 4c8f11d4afc799f78d8f6a82efcff618bed03f6c Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 15:17:32 -0500 Subject: pinctrl: sunxi: Add I2C pinmuxes Where multiple options were available, the one matching board.c and the device trees was chosen. Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland [Andre: fixup H5 I2C1 pinmux] Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 01d658ea6e9..d19cf27746a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -235,6 +235,8 @@ static int sunxi_pinctrl_probe(struct udevice *dev) static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 3 }, /* PE11-PE12 */ + { "i2c1", 3 }, /* PD5-PD6 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -253,6 +255,8 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { { "emac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PB0-PB1 */ + { "i2c1", 2 }, /* PB18-PB19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -271,6 +275,8 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "emac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PB0-PB1 */ + { "i2c1", 2 }, /* PB15-PB16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -290,6 +296,8 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "gmac", 2 }, /* PA0-PA27 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH14-PH15 */ + { "i2c1", 2 }, /* PH16-PH17 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -307,6 +315,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = { static const struct sunxi_pinctrl_function sun6i_a31_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 2 }, /* PL0-PL1 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -322,6 +331,8 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "gmac", 5 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PB0-PB1 */ + { "i2c1", 2 }, /* PB18-PB19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -339,6 +350,8 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH2-PH3 */ + { "i2c1", 2 }, /* PH4-PH5 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #endif @@ -356,6 +369,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_a23_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 3 }, /* PL0-PL1 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -369,6 +383,8 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH2-PH3 */ + { "i2c1", 2 }, /* PH4-PH5 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -389,6 +405,8 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "gmac", 4 }, /* PD2-PD23 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH0-PH1 */ + { "i2c1", 2 }, /* PH2-PH3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -408,6 +426,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = static const struct sunxi_pinctrl_function sun8i_a83t_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 2 }, /* PL8-PL9 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -422,6 +441,8 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "emac", 2 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PA11-PA12 */ + { "i2c1", 3 }, /* PA18-PA19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -441,6 +462,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = { static const struct sunxi_pinctrl_function sun8i_h3_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 2 }, /* PL0-PL1 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -455,6 +477,8 @@ static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { { "emac", 4 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PB6-PB7 */ + { "i2c1", 2 }, /* PB8-PB9 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -475,6 +499,8 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "gmac", 2 }, /* PA0-PA17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH0-PH1 */ + { "i2c1", 2 }, /* PH2-PH3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -492,6 +518,8 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = { static const struct sunxi_pinctrl_function sun9i_a80_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c0", 2 }, /* PN0-PN1 */ + { "s_i2c1", 3 }, /* PM8-PM9 */ { "s_uart", 3 }, /* PL0-PL1 */ }; @@ -506,6 +534,8 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "emac", 4 }, /* PD8-PD23 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PH0-PH1 */ + { "i2c1", 2 }, /* PH2-PH3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -525,6 +555,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 2 }, /* PL8-PL9 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -539,6 +570,8 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "emac", 2 }, /* PD0-PD17 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PA11-PA12 */ + { "i2c1", 3 }, /* PA18-PA19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -559,6 +592,8 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "emac", 5 }, /* PD0-PD20 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "i2c0", 2 }, /* PD25-PD26 */ + { "i2c1", 4 }, /* PH5-PH6 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -577,6 +612,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = { static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 3 }, /* PL0-PL1 */ { "s_uart", 2 }, /* PL2-PL3 */ }; @@ -609,6 +645,7 @@ static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = { { "gpio_in", 0 }, { "gpio_out", 1 }, + { "s_i2c", 3 }, /* PL0-PL1 */ { "s_uart", 2 }, /* PL2-PL3 */ }; -- cgit v1.3.1 From 923d89316ae6e48a4ce5abd4324c74aae38dddde Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 20 Oct 2021 23:01:29 -0500 Subject: i2c: sun6i_p2wi: Only do non-DM pin setup for non-DM I2C When the DM_I2C driver is loaded, the pin setup is done automatically from the device tree by the pinctrl driver. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/i2c/sun6i_p2wi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c index c9e1b3fcd5f..73b808b09bf 100644 --- a/drivers/i2c/sun6i_p2wi.c +++ b/drivers/i2c/sun6i_p2wi.c @@ -102,12 +102,6 @@ static int sun6i_p2wi_change_to_p2wi_mode(struct sunxi_p2wi_reg *base, static void sun6i_p2wi_init(struct sunxi_p2wi_reg *base) { - /* Enable p2wi and PIO clk, and de-assert their resets */ - prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI); - - sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK); - sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA); - /* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */ writel(P2WI_CTRL_RESET, &base->ctrl); sdelay(0x100); @@ -142,6 +136,12 @@ void p2wi_init(void) { struct sunxi_p2wi_reg *base = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; + /* Enable p2wi and PIO clk, and de-assert their resets */ + prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI); + + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA); + sun6i_p2wi_init(base); } #endif -- cgit v1.3.1 From af2ec35c4179620e2655f195ec0fd41e7a1ff784 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 20 Oct 2021 23:01:29 -0500 Subject: i2c: sun8i_rsb: Only do non-DM pin setup for non-DM I2C When the DM_I2C driver is loaded, the pin setup is done automatically from the device tree by the pinctrl driver. Clean up the code in the process: remove #ifdefs and recognize that the pin configuration is the same for all sun8i/sun50i SoCs, not just those which select CONFIG_MACH_SUN8I. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/i2c/sun8i_rsb.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c index 716b245a003..0dea8f7a923 100644 --- a/drivers/i2c/sun8i_rsb.c +++ b/drivers/i2c/sun8i_rsb.c @@ -95,27 +95,6 @@ static int sun8i_rsb_set_device_address(struct sunxi_rsb_reg *base, return sun8i_rsb_do_trans(base); } -static void sun8i_rsb_cfg_io(void) -{ -#ifdef CONFIG_MACH_SUN8I - sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); - sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); - sunxi_gpio_set_pull(SUNXI_GPL(0), 1); - sunxi_gpio_set_pull(SUNXI_GPL(1), 1); - sunxi_gpio_set_drv(SUNXI_GPL(0), 2); - sunxi_gpio_set_drv(SUNXI_GPL(1), 2); -#elif defined CONFIG_MACH_SUN9I - sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB); - sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB); - sunxi_gpio_set_pull(SUNXI_GPN(0), 1); - sunxi_gpio_set_pull(SUNXI_GPN(1), 1); - sunxi_gpio_set_drv(SUNXI_GPN(0), 2); - sunxi_gpio_set_drv(SUNXI_GPN(1), 2); -#else -#error unsupported MACH_SUNXI -#endif -} - static void sun8i_rsb_set_clk(struct sunxi_rsb_reg *base) { u32 div = 0; @@ -147,12 +126,6 @@ static int sun8i_rsb_set_device_mode(struct sunxi_rsb_reg *base) static int sun8i_rsb_init(struct sunxi_rsb_reg *base) { - /* Enable RSB and PIO clk, and de-assert their resets */ - prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); - - /* Setup external pins */ - sun8i_rsb_cfg_io(); - writel(RSB_CTRL_SOFT_RST, &base->ctrl); sun8i_rsb_set_clk(base); @@ -185,6 +158,25 @@ int rsb_init(void) { struct sunxi_rsb_reg *base = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + /* Enable RSB and PIO clk, and de-assert their resets */ + prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); + + if (IS_ENABLED(CONFIG_MACH_SUN9I)) { + sunxi_gpio_set_cfgpin(SUNXI_GPN(0), SUN9I_GPN_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPN(1), SUN9I_GPN_R_RSB); + sunxi_gpio_set_pull(SUNXI_GPN(0), 1); + sunxi_gpio_set_pull(SUNXI_GPN(1), 1); + sunxi_gpio_set_drv(SUNXI_GPN(0), 2); + sunxi_gpio_set_drv(SUNXI_GPN(1), 2); + } else { + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL_R_RSB); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL_R_RSB); + sunxi_gpio_set_pull(SUNXI_GPL(0), 1); + sunxi_gpio_set_pull(SUNXI_GPL(1), 1); + sunxi_gpio_set_drv(SUNXI_GPL(0), 2); + sunxi_gpio_set_drv(SUNXI_GPL(1), 2); + } + return sun8i_rsb_init(base); } #endif -- cgit v1.3.1 From 7570c54e46a76a853a1e3f89a7a3e9960e6a511b Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 16:51:03 -0500 Subject: pinctrl: sunxi: Add MMC pinmuxes Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 54 +++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index d19cf27746a..7e66c30f859 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -237,6 +237,8 @@ static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 3 }, /* PE11-PE12 */ { "i2c1", 3 }, /* PD5-PD6 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 3 }, /* PC0-PC2 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -257,6 +259,14 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PB0-PB1 */ { "i2c1", 2 }, /* PB18-PB19 */ + { "mmc0", 2 }, /* PF0-PF5 */ +#if IS_ENABLED(CONFIG_MMC1_PINS_PH) + { "mmc1", 5 }, /* PH22-PH27 */ +#else + { "mmc1", 4 }, /* PG0-PG5 */ +#endif + { "mmc2", 3 }, /* PC6-PC15 */ + { "mmc3", 2 }, /* PI4-PI9 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -277,6 +287,9 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PB0-PB1 */ { "i2c1", 2 }, /* PB15-PB16 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG3-PG8 */ + { "mmc2", 3 }, /* PC6-PC15 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -298,6 +311,10 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH14-PH15 */ { "i2c1", 2 }, /* PH16-PH17 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC6-PC15, PC24 */ + { "mmc3", 4 }, /* PC6-PC15, PC24 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -333,6 +350,13 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PB0-PB1 */ { "i2c1", 2 }, /* PB18-PB19 */ + { "mmc0", 2 }, /* PF0-PF5 */ +#if IS_ENABLED(CONFIG_MMC1_PINS_PH) + { "mmc1", 5 }, /* PH22-PH27 */ +#else + { "mmc1", 4 }, /* PG0-PG5 */ +#endif + { "mmc2", 3 }, /* PC5-PC15, PC24 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -352,6 +376,9 @@ static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH2-PH3 */ { "i2c1", 2 }, /* PH4-PH5 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC5-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #endif @@ -385,6 +412,9 @@ static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH2-PH3 */ { "i2c1", 2 }, /* PH4-PH5 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC5-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -407,6 +437,9 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH0-PH1 */ { "i2c1", 2 }, /* PH2-PH3 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC5-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -443,6 +476,9 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PA11-PA12 */ { "i2c1", 3 }, /* PA18-PA19 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC5-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -479,6 +515,9 @@ static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PB6-PB7 */ { "i2c1", 2 }, /* PB8-PB9 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 2 }, /* PC0-PC10 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -501,6 +540,9 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH0-PH1 */ { "i2c1", 2 }, /* PH2-PH3 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC6-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -536,6 +578,9 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PH0-PH1 */ { "i2c1", 2 }, /* PH2-PH3 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC1-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -572,6 +617,9 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PA11-PA12 */ { "i2c1", 3 }, /* PA18-PA19 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC1-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -594,6 +642,9 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "gpio_out", 1 }, { "i2c0", 2 }, /* PD25-PD26 */ { "i2c1", 4 }, /* PH5-PH6 */ + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC1-PC14 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -627,6 +678,9 @@ static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "emac0", 2 }, /* PI0-PI16 */ { "gpio_in", 0 }, { "gpio_out", 1 }, + { "mmc0", 2 }, /* PF0-PF5 */ + { "mmc1", 2 }, /* PG0-PG5 */ + { "mmc2", 3 }, /* PC0-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else -- cgit v1.3.1 From aa4823ce483f1c277775200846c5684697a4669a Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 15:52:52 -0500 Subject: pinctrl: sunxi: Add the A64 PWM pinmux This is the only possible mux setting for the A64's PWM peripheral. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 7e66c30f859..b8ca452e83a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -581,6 +581,7 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */ + { "pwm", 2 }, /* PD22 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else -- cgit v1.3.1 From 458e59da5d8dfc9da49601cb50688b7e71a1242d Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 11:50:51 -0500 Subject: pwm: sunxi: Remove non-DM pin setup This is now handled automatically by the pinctrl driver. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 - drivers/pwm/sunxi_pwm.c | 11 ----------- 2 files changed, 12 deletions(-) (limited to 'drivers') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index cf5afdac6a2..9f07d907e5a 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -159,7 +159,6 @@ enum sunxi_gpio_number { #define SUNXI_GPD_LCD0 2 #define SUNXI_GPD_LVDS0 3 -#define SUNXI_GPD_PWM 2 #define SUNIV_GPE_UART0 5 diff --git a/drivers/pwm/sunxi_pwm.c b/drivers/pwm/sunxi_pwm.c index e3d5ee456b0..bb1bec05ec3 100644 --- a/drivers/pwm/sunxi_pwm.c +++ b/drivers/pwm/sunxi_pwm.c @@ -13,7 +13,6 @@ #include #include #include -#include #include DECLARE_GLOBAL_DATA_PTR; @@ -45,14 +44,6 @@ static const u32 prescaler_table[] = { 1, /* 1111 */ }; -static int sunxi_pwm_config_pinmux(void) -{ -#ifdef CONFIG_MACH_SUN50I - sunxi_gpio_set_cfgpin(SUNXI_GPD(22), SUNXI_GPD_PWM); -#endif - return 0; -} - static int sunxi_pwm_set_invert(struct udevice *dev, uint channel, bool polarity) { @@ -137,8 +128,6 @@ static int sunxi_pwm_set_enable(struct udevice *dev, uint channel, bool enable) return 0; } - sunxi_pwm_config_pinmux(); - if (priv->invert) v &= ~SUNXI_PWM_CTRL_CH0_ACT_STA; else -- cgit v1.3.1 From 77834dcc5bafb3928d3caa02f676b43487eb36a4 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 17:05:35 -0500 Subject: pinctrl: sunxi: Add SPI0 pinmuxes Pin lists and mux values were taken from the Linux drivers. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index b8ca452e83a..9ce2bc1b3af 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -239,6 +239,7 @@ static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = { { "i2c1", 3 }, /* PD5-PD6 */ { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 3 }, /* PC0-PC2 */ + { "spi0", 2 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -267,6 +268,7 @@ static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = { #endif { "mmc2", 3 }, /* PC6-PC15 */ { "mmc3", 2 }, /* PI4-PI9 */ + { "spi0", 3 }, /* PC0-PC2, PC23 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -290,6 +292,7 @@ static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG3-PG8 */ { "mmc2", 3 }, /* PC6-PC15 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -315,6 +318,7 @@ static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = { { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC15, PC24 */ { "mmc3", 4 }, /* PC6-PC15, PC24 */ + { "spi0", 3 }, /* PC0-PC2, PC27 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -357,6 +361,7 @@ static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = { { "mmc1", 4 }, /* PG0-PG5 */ #endif { "mmc2", 3 }, /* PC5-PC15, PC24 */ + { "spi0", 3 }, /* PC0-PC2, PC23 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -379,6 +384,7 @@ static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #endif @@ -415,6 +421,7 @@ static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -440,6 +447,7 @@ static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -479,6 +487,7 @@ static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC5-PC16 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -518,6 +527,7 @@ static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 2 }, /* PC0-PC10 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -543,6 +553,7 @@ static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC6-PC16 */ + { "spi0", 3 }, /* PC0-PC2, PC19 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 4 }, /* PF2-PF4 */ #else @@ -582,6 +593,7 @@ static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = { { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */ { "pwm", 2 }, /* PD22 */ + { "spi0", 4 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -621,6 +633,7 @@ static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC16 */ + { "spi0", 3 }, /* PC0-PC3 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -646,6 +659,7 @@ static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC1-PC14 */ + { "spi0", 4 }, /* PC0-PC7 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else @@ -682,6 +696,7 @@ static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = { { "mmc0", 2 }, /* PF0-PF5 */ { "mmc1", 2 }, /* PG0-PG5 */ { "mmc2", 3 }, /* PC0-PC16 */ + { "spi0", 4 }, /* PC0-PC7, PC15-PC16 */ #if IS_ENABLED(CONFIG_UART0_PORT_F) { "uart0", 3 }, /* PF2-PF4 */ #else -- cgit v1.3.1 From f64233e9a54ae4b36b7fe4c739275005187f27b5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sat, 28 Aug 2021 11:50:28 -0500 Subject: spi: sun4i_spi: Remove non-DM pin setup This is now handled automatically by the pinctrl driver. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/spi/spi-sunxi.c | 84 ------------------------------------------------- 1 file changed, 84 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c index d62355ec6fb..b6cd7ddafad 100644 --- a/drivers/spi/spi-sunxi.c +++ b/drivers/spi/spi-sunxi.c @@ -32,7 +32,6 @@ #include #include -#include #include #include @@ -180,87 +179,6 @@ static void sun4i_spi_set_cs(struct udevice *bus, u8 cs, bool enable) writel(reg, SPI_REG(priv, SPI_TCR)); } -static int sun4i_spi_parse_pins(struct udevice *dev) -{ - const void *fdt = gd->fdt_blob; - const char *pin_name; - const fdt32_t *list; - u32 phandle; - int drive, pull = 0, pin, i; - int offset; - int size; - - list = fdt_getprop(fdt, dev_of_offset(dev), "pinctrl-0", &size); - if (!list) { - printf("WARNING: sun4i_spi: cannot find pinctrl-0 node\n"); - return -EINVAL; - } - - while (size) { - phandle = fdt32_to_cpu(*list++); - size -= sizeof(*list); - - offset = fdt_node_offset_by_phandle(fdt, phandle); - if (offset < 0) - return offset; - - drive = fdt_getprop_u32_default_node(fdt, offset, 0, - "drive-strength", 0); - if (drive) { - if (drive <= 10) - drive = 0; - else if (drive <= 20) - drive = 1; - else if (drive <= 30) - drive = 2; - else - drive = 3; - } else { - drive = fdt_getprop_u32_default_node(fdt, offset, 0, - "allwinner,drive", - 0); - drive = min(drive, 3); - } - - if (fdt_get_property(fdt, offset, "bias-disable", NULL)) - pull = 0; - else if (fdt_get_property(fdt, offset, "bias-pull-up", NULL)) - pull = 1; - else if (fdt_get_property(fdt, offset, "bias-pull-down", NULL)) - pull = 2; - else - pull = fdt_getprop_u32_default_node(fdt, offset, 0, - "allwinner,pull", - 0); - pull = min(pull, 2); - - for (i = 0; ; i++) { - pin_name = fdt_stringlist_get(fdt, offset, - "pins", i, NULL); - if (!pin_name) { - pin_name = fdt_stringlist_get(fdt, offset, - "allwinner,pins", - i, NULL); - if (!pin_name) - break; - } - - pin = sunxi_name_to_gpio(pin_name); - if (pin < 0) - break; - - if (IS_ENABLED(CONFIG_MACH_SUN50I) || - IS_ENABLED(CONFIG_SUN50I_GEN_H6)) - sunxi_gpio_set_cfgpin(pin, SUN50I_GPC_SPI0); - else - sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0); - sunxi_gpio_set_drv(pin, drive); - sunxi_gpio_set_pull(pin, pull); - } - } - return 0; -} - static inline int sun4i_spi_set_clock(struct udevice *dev, bool enable) { struct sun4i_spi_priv *priv = dev_get_priv(dev); @@ -507,8 +425,6 @@ static int sun4i_spi_probe(struct udevice *bus) return ret; } - sun4i_spi_parse_pins(bus); - priv->variant = plat->variant; priv->base = plat->base; priv->freq = plat->max_hz; -- cgit v1.3.1 From 48457f7ab031884d749e84440f4e5ae798e77c39 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 17 Mar 2022 23:52:33 -0500 Subject: i2c: sun6i_p2wi: Initialize chips in .child_pre_probe Chips attached to the P2WI bus require an initialization command before they can be used. (Specifically, this switches the chip from I2C mode to P2WI mode.) The driver does this in its .probe_chip hook, under the assumption that .probe_chip is called during child probe. This is not the case; .probe_chip is only called by dm_i2c_probe, which is intended for use by board-level code, not for chips with OF nodes. Since this initialization command must be run before a child chip can be used, do it before probing each child. Signed-off-by: Samuel Holland Acked-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/i2c/sun6i_p2wi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c index 73b808b09bf..064d82a6d1f 100644 --- a/drivers/i2c/sun6i_p2wi.c +++ b/drivers/i2c/sun6i_p2wi.c @@ -191,11 +191,12 @@ static int sun6i_p2wi_probe(struct udevice *bus) static int sun6i_p2wi_child_pre_probe(struct udevice *child) { struct dm_i2c_chip *chip = dev_get_parent_plat(child); + struct udevice *bus = child->parent; /* Ensure each transfer is for a single register. */ chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS; - return 0; + return sun6i_p2wi_probe_chip(bus, chip->chip_addr, 0); } static const struct dm_i2c_ops sun6i_p2wi_ops = { -- cgit v1.3.1 From 07c411346cb2493e4f59a8affbd35f5efc2ec736 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 17 Mar 2022 23:52:34 -0500 Subject: i2c: sun6i_p2wi: Add support for DM clocks and resets Currently, clock/reset setup for this device is handled by a platform-specific function and is intermixed with non-DM pinctrl setup. Use the devicetree to get clocks/resets, which disentagles it from the pinctrl setup in preparation for moving to DM_PINCTRL. Signed-off-by: Samuel Holland Reviewed-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/i2c/sun6i_p2wi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/sun6i_p2wi.c b/drivers/i2c/sun6i_p2wi.c index 064d82a6d1f..d221323295d 100644 --- a/drivers/i2c/sun6i_p2wi.c +++ b/drivers/i2c/sun6i_p2wi.c @@ -14,10 +14,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -180,9 +182,19 @@ static int sun6i_p2wi_probe_chip(struct udevice *bus, uint chip_addr, static int sun6i_p2wi_probe(struct udevice *bus) { struct sun6i_p2wi_priv *priv = dev_get_priv(bus); + struct reset_ctl *reset; + struct clk *clk; priv->base = dev_read_addr_ptr(bus); + reset = devm_reset_control_get(bus, NULL); + if (!IS_ERR(reset)) + reset_deassert(reset); + + clk = devm_clk_get(bus, NULL); + if (!IS_ERR(clk)) + clk_enable(clk); + sun6i_p2wi_init(priv->base); return 0; -- cgit v1.3.1 From c9dd3caae3119c9f77081b5c1ef42553b44ddf20 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 17 Mar 2022 23:52:35 -0500 Subject: i2c: sun8i_rsb: Initialize chips in .child_pre_probe Chips attached to the RSB bus require an initialization command before they can be used. (Specifically, this command programs the chip's runtime address.) The driver does this in its .probe_chip hook, under the assumption that .probe_chip is called during child probe. This is not the case; .probe_chip is only called by dm_i2c_probe, which is intended for use by board-level code, not for chips with OF nodes. Since this initialization command must be run before a child chip can be used, do it before probing each child. Signed-off-by: Samuel Holland Acked-by: Andre Przywara Signed-off-by: Andre Przywara --- drivers/i2c/sun8i_rsb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c index 0dea8f7a923..38d6e87577d 100644 --- a/drivers/i2c/sun8i_rsb.c +++ b/drivers/i2c/sun8i_rsb.c @@ -244,11 +244,12 @@ static int sun8i_rsb_probe(struct udevice *bus) static int sun8i_rsb_child_pre_probe(struct udevice *child) { struct dm_i2c_chip *chip = dev_get_parent_plat(child); + struct udevice *bus = child->parent; /* Ensure each transfer is for a single register. */ chip->flags |= DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS; - return 0; + return sun8i_rsb_probe_chip(bus, chip->chip_addr, 0); } static const struct dm_i2c_ops sun8i_rsb_ops = { -- cgit v1.3.1 From f5bfe1575078cea8de0fa4affb529b360a511094 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Thu, 17 Mar 2022 23:52:36 -0500 Subject: i2c: sun8i_rsb: Add support for DM clocks and resets Currently, clock/reset setup for this device is handled by a platform-specific function and is intermixed with non-DM pinctrl setup. Use the devicetree to get clocks/resets, which disentagles it from the pinctrl setup in preparation for moving to DM_PINCTRL. This also has the added benefit of picking the right clock/reset bits for H6 and new SoCs that have a rearranged PRCM MMIO space. Signed-off-by: Samuel Holland Signed-off-by: Andre Przywara --- drivers/i2c/sun8i_rsb.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/sun8i_rsb.c b/drivers/i2c/sun8i_rsb.c index 38d6e87577d..47fa05b6d1c 100644 --- a/drivers/i2c/sun8i_rsb.c +++ b/drivers/i2c/sun8i_rsb.c @@ -9,10 +9,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -235,9 +237,19 @@ static int sun8i_rsb_probe_chip(struct udevice *bus, uint chip_addr, static int sun8i_rsb_probe(struct udevice *bus) { struct sun8i_rsb_priv *priv = dev_get_priv(bus); + struct reset_ctl *reset; + struct clk *clk; priv->base = dev_read_addr_ptr(bus); + reset = devm_reset_control_get(bus, NULL); + if (!IS_ERR(reset)) + reset_deassert(reset); + + clk = devm_clk_get(bus, NULL); + if (!IS_ERR(clk)) + clk_enable(clk); + return sun8i_rsb_init(priv->base); } -- cgit v1.3.1