Am 18.09.19 um 04:15 schrieb Weijie Gao: > This patch adds pinctrl support for mt7628, with a file for common pinmux > functions and a file for mt7628 which has additional support for pinconf. > > Signed-off-by: Weijie Gao <weijie....@mediatek.com> > --- > drivers/pinctrl/Kconfig | 1 + > drivers/pinctrl/Makefile | 1 + > drivers/pinctrl/mtmips/Kconfig | 13 + > drivers/pinctrl/mtmips/Makefile | 7 + > drivers/pinctrl/mtmips/pinctrl-mt7628.c | 585 ++++++++++++++++++ > .../pinctrl/mtmips/pinctrl-mtmips-common.c | 87 +++ > .../pinctrl/mtmips/pinctrl-mtmips-common.h | 53 ++ > 7 files changed, 747 insertions(+) > create mode 100644 drivers/pinctrl/mtmips/Kconfig > create mode 100644 drivers/pinctrl/mtmips/Makefile > create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7628.c > create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.c > create mode 100644 drivers/pinctrl/mtmips/pinctrl-mtmips-common.h > > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig > index a0ac167d14..1634dffb35 100644 > --- a/drivers/pinctrl/Kconfig > +++ b/drivers/pinctrl/Kconfig > @@ -244,6 +244,7 @@ source "drivers/pinctrl/exynos/Kconfig" > source "drivers/pinctrl/mediatek/Kconfig" > source "drivers/pinctrl/meson/Kconfig" > source "drivers/pinctrl/mscc/Kconfig" > +source "drivers/pinctrl/mtmips/Kconfig" > source "drivers/pinctrl/mvebu/Kconfig" > source "drivers/pinctrl/nxp/Kconfig" > source "drivers/pinctrl/renesas/Kconfig" > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile > index 4b080b74dc..ce0879a2b7 100644 > --- a/drivers/pinctrl/Makefile > +++ b/drivers/pinctrl/Makefile > @@ -9,6 +9,7 @@ obj-y += nxp/ > obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/ > obj-$(CONFIG_ARCH_ASPEED) += aspeed/ > obj-$(CONFIG_ARCH_ATH79) += ath79/ > +obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ > obj-$(CONFIG_ARCH_RMOBILE) += renesas/ > obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o > > diff --git a/drivers/pinctrl/mtmips/Kconfig b/drivers/pinctrl/mtmips/Kconfig > new file mode 100644 > index 0000000000..8482a38ebc > --- /dev/null > +++ b/drivers/pinctrl/mtmips/Kconfig > @@ -0,0 +1,13 @@ > + > +config PINCTRL_MTMIPS > + depends on ARCH_MTMIPS > + bool > + > +config PINCTRL_MT7628 > + bool "MediaTek MT7628 pin control driver" > + select PINCTRL_MTMIPS > + depends on SOC_MT7628 && PINCTRL_GENERIC > + help > + Support pin multiplexing control on MediaTek MT7628. > + The driver is controlled by a device tree node which contains > + the pin mux functions for each available pin groups. > diff --git a/drivers/pinctrl/mtmips/Makefile b/drivers/pinctrl/mtmips/Makefile > new file mode 100644 > index 0000000000..3ba5c0c66d > --- /dev/null > +++ b/drivers/pinctrl/mtmips/Makefile > @@ -0,0 +1,7 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +# Core > +obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o > + > +# SoC Drivers > +obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o > diff --git a/drivers/pinctrl/mtmips/pinctrl-mt7628.c > b/drivers/pinctrl/mtmips/pinctrl-mt7628.c > new file mode 100644 > index 0000000000..6883450a09 > --- /dev/null > +++ b/drivers/pinctrl/mtmips/pinctrl-mt7628.c > @@ -0,0 +1,585 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. > + * > + * Author: Weijie Gao <weijie....@mediatek.com> > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <linux/bitops.h> > +#include <linux/io.h> > + > +#include "pinctrl-mtmips-common.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#define AGPIO_OFS 0 > +#define GPIOMODE1_OFS 0x24 > +#define GPIOMODE2_OFS 0x28 > + > +#define EPHY4_1_PAD_SHIFT 17 > +#define EPHY4_1_PAD_MASK 0x0f > +#define EPHY0_SHIFT 16 > +#define RF_OLT_MODE_SHIFT 12 > +#define N9_EINT_SRC_SHIFT 9 > +#define WLED_OD_SHIFT 8 > +#define REF_CLKO_PAD_SHIFT 4 > +#define I2S_CLK_PAD_SHIFT 3 > +#define I2S_WS_PAD_SHIFT 2 > +#define I2S_SDO_PAD_SHIFT 1 > +#define I2S_SDI_PAD_SHIFT 0 > + > +#define GM4_MASK 3 > + > +#define P4LED_K_SHIFT 26 > +#define P3LED_K_SHIFT 24 > +#define P2LED_K_SHIFT 22 > +#define P1LED_K_SHIFT 20 > +#define P0LED_K_SHIFT 18 > +#define WLED_K_SHIFT 16 > +#define P4LED_A_SHIFT 10 > +#define P3LED_A_SHIFT 8 > +#define P2LED_A_SHIFT 6 > +#define P1LED_A_SHIFT 4 > +#define P0LED_A_SHIFT 2 > +#define WLED_A_SHIFT 0 > + > +#define PWM1_SHIFT 30 > +#define PWM0_SHIFT 28 > +#define UART2_SHIFT 26 > +#define UART1_SHIFT 24 > +#define I2C_SHIFT 20 > +#define REFCLK_SHIFT 18 > +#define PERST_SHIFT 16 > +#define ESD_SHIFT 15 > +#define WDT_SHIFT 14 > +#define SPI_SHIFT 12 > +#define SDMODE_SHIFT 10 > +#define UART0_SHIFT 8 > +#define I2S_SHIFT 6 > +#define SPI_CS1_SHIFT 4 > +#define SPIS_SHIFT 2 > +#define GPIO0_SHIFT 0 > + > +#define PAD_PU_G0_REG 0x00 > +#define PAD_PU_G1_REG 0x04 > +#define PAD_PD_G0_REG 0x10 > +#define PAD_PD_G1_REG 0x14 > +#define PAD_SR_G0_REG 0x20 > +#define PAD_SR_G1_REG 0x24 > +#define PAD_SMT_G0_REG 0x30 > +#define PAD_SMT_G1_REG 0x34 > +#define PAD_E2_G0_REG 0x40 > +#define PAD_E2_G1_REG 0x44 > +#define PAD_E4_G0_REG 0x50 > +#define PAD_E4_G1_REG 0x54 > +#define PAD_E8_G0_REG 0x60 > +#define PAD_E8_G1_REG 0x64 > + > +#define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1) > +#define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2) > + > +struct mt7628_pinctrl_priv { > + struct mtmips_pinctrl_priv mp; > + > + void __iomem *pcbase; > +}; > + > +#if CONFIG_IS_ENABLED(PINMUX) > +static struct mtmips_pmx_func ephy4_1_pad_grp[] = { > + FUNC("digital", 0xf), > + FUNC("analog", 0), > +};
all those structs could be made "const" > + > +static struct mtmips_pmx_func ephy0_grp[] = { > + FUNC("disable", 1), > + FUNC("enable", 0), > +}; > + > +static struct mtmips_pmx_func rf_olt_grp[] = { > + FUNC("enable", 1), > + FUNC("disable", 0), > +}; > + > +static struct mtmips_pmx_func n9_eint_src_grp[] = { > + FUNC("gpio", 1), > + FUNC("utif", 0), > +}; > + > +static struct mtmips_pmx_func wlen_od_grp[] = { > + FUNC("enable", 1), > + FUNC("disable", 0), > +}; > + > +static struct mtmips_pmx_func ref_clko_grp[] = { > + FUNC("digital", 1), > + FUNC("analog", 0), > +}; > + > +static struct mtmips_pmx_func i2s_clk_grp[] = { > + FUNC("digital", 1), > + FUNC("analog", 0), > +}; > + > +static struct mtmips_pmx_func i2s_ws_grp[] = { > + FUNC("digital", 1), > + FUNC("analog", 0), > +}; > + > +static struct mtmips_pmx_func i2s_sdo_grp[] = { > + FUNC("digital", 1), > + FUNC("analog", 0), > +}; > + > +static struct mtmips_pmx_func i2s_sdi_grp[] = { > + FUNC("digital", 1), > + FUNC("analog", 0), > +}; > + > +static struct mtmips_pmx_func pwm1_grp[] = { > + FUNC("sdxc d6", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("pwm1", 0), > +}; > + > +static struct mtmips_pmx_func pwm0_grp[] = { > + FUNC("sdxc d7", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("pwm0", 0), > +}; > + > +static struct mtmips_pmx_func uart2_grp[] = { > + FUNC("sdxc d5 d4", 3), > + FUNC("pwm", 2), > + FUNC("gpio", 1), > + FUNC("uart2", 0), > +}; > + > +static struct mtmips_pmx_func uart1_grp[] = { > + FUNC("sw_r", 3), > + FUNC("pwm", 2), > + FUNC("gpio", 1), > + FUNC("uart1", 0), > +}; > + > +static struct mtmips_pmx_func i2c_grp[] = { > + FUNC("-", 3), > + FUNC("debug", 2), > + FUNC("gpio", 1), > + FUNC("i2c", 0), > +}; > + > +static struct mtmips_pmx_func refclk_grp[] = { > + FUNC("gpio", 1), > + FUNC("refclk", 0), > +}; > + > +static struct mtmips_pmx_func perst_grp[] = { > + FUNC("gpio", 1), > + FUNC("perst", 0), > +}; > + > +static struct mtmips_pmx_func esd_grp[] = { > + FUNC("router", 1), > + FUNC("iot", 0), > +}; > + > +static struct mtmips_pmx_func wdt_grp[] = { > + FUNC("gpio", 1), > + FUNC("wdt", 0), > +}; > + > +static struct mtmips_pmx_func spi_grp[] = { > + FUNC("gpio", 1), > + FUNC("spi", 0), > +}; > + > +static struct mtmips_pmx_func sd_mode_grp[] = { > + FUNC("n9 jtag", 3), > + FUNC("utif1", 2), > + FUNC("gpio", 1), > + FUNC("sdxc", 0), > +}; > + > +static struct mtmips_pmx_func uart0_grp[] = { > + FUNC("-", 3), > + FUNC("-", 2), > + FUNC("gpio", 1), > + FUNC("uart0", 0), > +}; > + > +static struct mtmips_pmx_func i2s_grp[] = { > + FUNC("antenna", 3), > + FUNC("pcm", 2), > + FUNC("gpio", 1), > + FUNC("i2s", 0), > +}; > + > +static struct mtmips_pmx_func spi_cs1_grp[] = { > + FUNC("-", 3), > + FUNC("refclk", 2), > + FUNC("gpio", 1), > + FUNC("spi cs1", 0), > +}; > + > +static struct mtmips_pmx_func spis_grp[] = { > + FUNC("pwm_uart2", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("spis", 0), > +}; > + > +static struct mtmips_pmx_func gpio0_grp[] = { > + FUNC("perst", 3), > + FUNC("refclk", 2), > + FUNC("gpio", 1), > + FUNC("gpio0", 0), > +}; > + > +static struct mtmips_pmx_func wled_a_grp[] = { > + FUNC("-", 3), > + FUNC("-", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p0led_a_grp[] = { > + FUNC("jtag", 3), > + FUNC("rsvd", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p1led_a_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p2led_a_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p3led_a_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p4led_a_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func wled_k_grp[] = { > + FUNC("-", 3), > + FUNC("-", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p0led_k_grp[] = { > + FUNC("jtag", 3), > + FUNC("rsvd", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p1led_k_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p2led_k_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p3led_k_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_func p4led_k_grp[] = { > + FUNC("jtag", 3), > + FUNC("utif", 2), > + FUNC("gpio", 1), > + FUNC("led", 0), > +}; > + > +static struct mtmips_pmx_group mt7628_pinmux_data[] = { > + GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT, > + EPHY4_1_PAD_MASK), > + GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1), > + GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1), > + GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1), > + GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1), > + GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1), > + GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1), > + GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1), > + GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1), > + GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1), > + GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK), > + GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK), > + GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK), > + GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK), > + GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK), > + GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1), > + GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1), > + GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1), > + GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1), > + GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1), > + GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK), > + GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK), > + GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK), > + GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK), > + GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK), > + GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK), > + GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK), > + GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK), > + GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK), > + GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK), > + GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK), > + GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK), > + GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK), > + GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK), > + GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK), > + GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK), > + GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK), > + GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK), > +}; > + > +static int mt7628_get_groups_count(struct udevice *dev) > +{ > + return ARRAY_SIZE(mt7628_pinmux_data); > +} > + > +static const char *mt7628_get_group_name(struct udevice *dev, > + unsigned int selector) > +{ > + return mt7628_pinmux_data[selector].name; > +} > +#endif /* CONFIG_IS_ENABLED(PINMUX) */ > + > +#if CONFIG_IS_ENABLED(PINCONF) > +static const struct pinconf_param mt7628_conf_params[] = { > + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, > + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, > + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, > + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, > + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, > + { "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 }, > + { "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 }, > + { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, > +}; > + > +static const char *const mt7628_pins[] = { > + "i2s_sdi", > + "i2s_sdo", > + "i2s_ws", > + "i2s_clk", > + "i2s_sclk", > + "i2c_sd", > + "spi_cs1", > + "spi_clk", > + "spi_mosi", > + "spi_miso", > + "spi_cs0", > + "gpio0", > + "uart0_txd", > + "uart0_rxd", > + "spis_cs", > + "spis_clk", > + "spis_miso", > + "spis_mosi", > + "pwm_ch0", > + "pwm_ch1", > + "uart2_txd", > + "uart2_rxd", > + "sd_wp", > + "sd_cd", > + "sd_d1", > + "sd_d0", > + "sd_clk", > + "sd_cmd", > + "sd_d3", > + "sd_d2", > + "ephy_led4_k", > + "ephy_led3_k", > + "ephy_led2_k", > + "ephy_led1_k", > + "ephy_led0_k", > + "wled_k", > + "perst_n", > + "co_clko", > + "wdt", > + "ephy_led4_a", > + "ephy_led3_a", > + "ephy_led2_a", > + "ephy_led1_a", > + "ephy_led0_a", > + "wled_a", > + "uart1_txd", > + "uart1_rxd", > +}; > + > +static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8}; > +static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16}; > + > +static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit, > + const u32 tbl[], u32 reg_lo, u32 reg_hi) > +{ > + int i; > + > + for (i = 0; i < 4; i++) > + if (tbl[i] == val) > + break; > + > + if (i >= 4) > + return -EINVAL; > + > + clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit); > + clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit); > + > + return 0; > +} > + > +static int mt7628_get_pins_count(struct udevice *dev) > +{ > + return ARRAY_SIZE(mt7628_pins); > +} > + > +static const char *mt7628_get_pin_name(struct udevice *dev, > + unsigned int selector) > +{ > + return mt7628_pins[selector]; > +} > + > +static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector, > + unsigned int param, unsigned int argument) > +{ > + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); > + u32 offs, bit; > + int ret = 0; > + > + offs = (pin_selector / 32) * 4; > + bit = pin_selector % 32; > + > + switch (param) { > + case PIN_CONFIG_BIAS_DISABLE: > + clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); > + clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); > + break; > + case PIN_CONFIG_BIAS_PULL_UP: > + setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); > + clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); > + break; > + case PIN_CONFIG_BIAS_PULL_DOWN: > + clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit)); > + setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit)); > + break; > + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: > + clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG, > + BIT(bit), (!!argument) << bit); > + break; > + case PIN_CONFIG_DRIVE_STRENGTH_28: > + ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, > + bit, mt7628_drv_strength_28_tbl, > + PAD_E2_G0_REG, PAD_E4_G0_REG); > + break; > + case PIN_CONFIG_DRIVE_STRENGTH_4G: > + ret = mt7628_set_drv_strength(priv->pcbase + offs, argument, > + bit, mt7628_drv_strength_4g_tbl, > + PAD_E4_G0_REG, PAD_E8_G0_REG); > + break; > + case PIN_CONFIG_SLEW_RATE: > + clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG, > + BIT(bit), (!!argument) << bit); > + break; > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} > +#endif > + > +static int mt7628_pinctrl_probe(struct udevice *dev) > +{ > + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); > + int ret = 0; > + > +#if CONFIG_IS_ENABLED(PINMUX) > + ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data), > + mt7628_pinmux_data); > +#endif /* CONFIG_IS_ENABLED(PINMUX) */ > + > + return ret; > +} > + > +static int mt7628_pinctrl_ofdata_to_platdata(struct udevice *dev) > +{ > + struct mt7628_pinctrl_priv *priv = dev_get_priv(dev); > + > + priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0); > + > + if (!priv->mp.base) > + return -EINVAL; > + > + priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1); > + > + if (!priv->pcbase) > + return -EINVAL; > + > + return 0; > +} > + > +static struct pinctrl_ops mt7628_pinctrl_ops = { > +#if CONFIG_IS_ENABLED(PINMUX) > + .get_groups_count = mt7628_get_groups_count, > + .get_group_name = mt7628_get_group_name, > + .get_functions_count = mtmips_get_functions_count, > + .get_function_name = mtmips_get_function_name, > + .pinmux_group_set = mtmips_pinmux_group_set, > +#endif /* CONFIG_IS_ENABLED(PINMUX) */ > +#if CONFIG_IS_ENABLED(PINCONF) > + .pinconf_num_params = ARRAY_SIZE(mt7628_conf_params), > + .pinconf_params = mt7628_conf_params, > + .get_pins_count = mt7628_get_pins_count, > + .get_pin_name = mt7628_get_pin_name, > + .pinconf_set = mt7628_pinconf_set, > +#endif /* CONFIG_IS_ENABLED(PINCONF) */ > + .set_state = pinctrl_generic_set_state, > +}; > + > +static const struct udevice_id mt7628_pinctrl_ids[] = { > + { .compatible = "mediatek,mt7628-pinctrl" }, > + { } > +}; > + > +U_BOOT_DRIVER(mt7628_pinctrl) = { > + .name = "mt7628-pinctrl", > + .id = UCLASS_PINCTRL, > + .of_match = mt7628_pinctrl_ids, > + .ofdata_to_platdata = mt7628_pinctrl_ofdata_to_platdata, > + .ops = &mt7628_pinctrl_ops, > + .probe = mt7628_pinctrl_probe, > + .priv_auto_alloc_size = sizeof(struct mt7628_pinctrl_priv), > +}; > diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c > b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c > new file mode 100644 > index 0000000000..ee6a9d1fc8 > --- /dev/null > +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c > @@ -0,0 +1,87 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. > + * > + * Author: Weijie Gao <weijie....@mediatek.com> > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <linux/io.h> > + > +#include "pinctrl-mtmips-common.h" > + > +static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv, > + u32 reg, u32 shift, u32 mask, u32 value) > +{ > + u32 val; > + > + val = readl(priv->base + reg); > + val &= ~(mask << shift); > + val |= value << shift; > + writel(val, priv->base + reg); > +} > + > +int mtmips_get_functions_count(struct udevice *dev) > +{ > + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); > + > + return priv->nfuncs; > +} > + > +const char *mtmips_get_function_name(struct udevice *dev, unsigned int > selector) > +{ > + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); > + > + return priv->funcs[selector]->name; > +} > + > +int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector, > + unsigned int func_selector) > +{ > + struct mtmips_pinctrl_priv *priv = dev_get_priv(dev); > + const struct mtmips_pmx_group *grp = &priv->groups[group_selector]; > + const struct mtmips_pmx_func *func = priv->funcs[func_selector]; > + int i; > + > + if (!grp->nfuncs) > + return 0; > + > + for (i = 0; i < grp->nfuncs; i++) { > + if (!strcmp(grp->funcs[i].name, func->name)) { > + mtmips_pinctrl_reg_set(priv, grp->reg, grp->shift, > + grp->mask, grp->funcs[i].value); > + return 0; > + } > + } > + > + return -EINVAL; > +} > + > +int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups, > + const struct mtmips_pmx_group *groups) > +{ > + int i, j, n; > + > + priv->ngroups = ngroups; > + priv->groups = groups; > + > + priv->nfuncs = 0; > + > + for (i = 0; i < ngroups; i++) > + priv->nfuncs += groups[i].nfuncs; > + > + priv->funcs = malloc(priv->nfuncs * sizeof(*priv->funcs)); > + if (!priv->funcs) > + return -ENOMEM; > + > + n = 0; > + > + for (i = 0; i < ngroups; i++) { > + for (j = 0; j < groups[i].nfuncs; j++) > + priv->funcs[n++] = &groups[i].funcs[j]; > + } > + > + return 0; > +} > diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h > b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h > new file mode 100644 > index 0000000000..b51d8f009c > --- /dev/null > +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h > @@ -0,0 +1,53 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2019 MediaTek Inc. All Rights Reserved. > + * > + * Author: Weijie Gao <weijie....@mediatek.com> > + */ > + > +#ifndef _PINCTRL_MTMIPS_COMMON_H_ > +#define _PINCTRL_MTMIPS_COMMON_H_ > + > +#include <common.h> > + > +struct mtmips_pmx_func { > + const char *name; > + int value; > +}; > + > +struct mtmips_pmx_group { > + const char *name; > + > + u32 reg; > + u32 shift; > + char mask; > + > + int nfuncs; > + const struct mtmips_pmx_func *funcs; > +}; > + > +struct mtmips_pinctrl_priv { > + void __iomem *base; > + > + u32 ngroups; > + const struct mtmips_pmx_group *groups; > + > + u32 nfuncs; > + const struct mtmips_pmx_func **funcs; > +}; > + > +#define FUNC(name, value) { name, value } > + > +#define GRP(_name, _funcs, _reg, _shift, _mask) \ > + { .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \ > + .funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) } > + > +int mtmips_get_functions_count(struct udevice *dev); > +const char *mtmips_get_function_name(struct udevice *dev, > + unsigned int selector); > +int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector, > + unsigned int func_selector); > +int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups, > + const struct mtmips_pmx_group *groups); > + > +#endif /* _PINCTRL_MTMIPS_COMMON_H_ */ > -- - Daniel _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot