u-boot/drivers/pinctrl/mtmips/pinctrl-mt7628.c
Simon Glass 41575d8e4c dm: treewide: Rename auto_alloc_size members to be shorter
This construct is quite long-winded. In earlier days it made some sense
since auto-allocation was a strange concept. But with driver model now
used pretty universally, we can shorten this to 'auto'. This reduces
verbosity and makes it easier to read.

Coincidentally it also ensures that every declaration is on one line,
thus making dtoc's job easier.

Signed-off-by: Simon Glass <sjg@chromium.org>
2020-12-13 08:00:25 -07:00

585 lines
14 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
*
* Author: Weijie Gao <weijie.gao@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 const struct mtmips_pmx_func ephy4_1_pad_grp[] = {
FUNC("digital", 0xf),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func ephy0_grp[] = {
FUNC("disable", 1),
FUNC("enable", 0),
};
static const struct mtmips_pmx_func rf_olt_grp[] = {
FUNC("enable", 1),
FUNC("disable", 0),
};
static const struct mtmips_pmx_func n9_eint_src_grp[] = {
FUNC("gpio", 1),
FUNC("utif", 0),
};
static const struct mtmips_pmx_func wlen_od_grp[] = {
FUNC("enable", 1),
FUNC("disable", 0),
};
static const struct mtmips_pmx_func ref_clko_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_clk_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_ws_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_sdo_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func i2s_sdi_grp[] = {
FUNC("digital", 1),
FUNC("analog", 0),
};
static const struct mtmips_pmx_func pwm1_grp[] = {
FUNC("sdxc d6", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("pwm1", 0),
};
static const struct mtmips_pmx_func pwm0_grp[] = {
FUNC("sdxc d7", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("pwm0", 0),
};
static const struct mtmips_pmx_func uart2_grp[] = {
FUNC("sdxc d5 d4", 3),
FUNC("pwm", 2),
FUNC("gpio", 1),
FUNC("uart2", 0),
};
static const struct mtmips_pmx_func uart1_grp[] = {
FUNC("sw_r", 3),
FUNC("pwm", 2),
FUNC("gpio", 1),
FUNC("uart1", 0),
};
static const struct mtmips_pmx_func i2c_grp[] = {
FUNC("-", 3),
FUNC("debug", 2),
FUNC("gpio", 1),
FUNC("i2c", 0),
};
static const struct mtmips_pmx_func refclk_grp[] = {
FUNC("gpio", 1),
FUNC("refclk", 0),
};
static const struct mtmips_pmx_func perst_grp[] = {
FUNC("gpio", 1),
FUNC("perst", 0),
};
static const struct mtmips_pmx_func esd_grp[] = {
FUNC("router", 1),
FUNC("iot", 0),
};
static const struct mtmips_pmx_func wdt_grp[] = {
FUNC("gpio", 1),
FUNC("wdt", 0),
};
static const struct mtmips_pmx_func spi_grp[] = {
FUNC("gpio", 1),
FUNC("spi", 0),
};
static const struct mtmips_pmx_func sd_mode_grp[] = {
FUNC("n9 jtag", 3),
FUNC("utif1", 2),
FUNC("gpio", 1),
FUNC("sdxc", 0),
};
static const struct mtmips_pmx_func uart0_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("uart0", 0),
};
static const struct mtmips_pmx_func i2s_grp[] = {
FUNC("antenna", 3),
FUNC("pcm", 2),
FUNC("gpio", 1),
FUNC("i2s", 0),
};
static const struct mtmips_pmx_func spi_cs1_grp[] = {
FUNC("-", 3),
FUNC("refclk", 2),
FUNC("gpio", 1),
FUNC("spi cs1", 0),
};
static const struct mtmips_pmx_func spis_grp[] = {
FUNC("pwm_uart2", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("spis", 0),
};
static const struct mtmips_pmx_func gpio0_grp[] = {
FUNC("perst", 3),
FUNC("refclk", 2),
FUNC("gpio", 1),
FUNC("gpio0", 0),
};
static const struct mtmips_pmx_func wled_a_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p0led_a_grp[] = {
FUNC("jtag", 3),
FUNC("rsvd", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p1led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p2led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p3led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p4led_a_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func wled_k_grp[] = {
FUNC("-", 3),
FUNC("-", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p0led_k_grp[] = {
FUNC("jtag", 3),
FUNC("rsvd", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p1led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p2led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p3led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const struct mtmips_pmx_func p4led_k_grp[] = {
FUNC("jtag", 3),
FUNC("utif", 2),
FUNC("gpio", 1),
FUNC("led", 0),
};
static const 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 const 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 = sizeof(struct mt7628_pinctrl_priv),
};