diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c index f23b188f2f..b5d74068c5 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c @@ -93,10 +93,56 @@ static int meson_axg_pinmux_group_set(struct udevice *dev, return 0; } +static int meson_axg_pinmux_get(struct udevice *dev, unsigned int selector, + char *buf, int size) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + struct meson_pmx_axg_data *pmx_data; + struct meson_pmx_group *group; + struct meson_pmx_bank *bank; + unsigned int offset; + unsigned int func; + unsigned int reg; + int ret, i, j; + + selector += priv->data->pin_base; + + ret = meson_axg_pmx_get_bank(dev, selector, &bank); + if (ret) { + snprintf(buf, size, "Unhandled"); + return 0; + } + + meson_axg_pmx_calc_reg_and_offset(bank, selector, ®, &offset); + + func = (readl(priv->reg_mux + (reg << 2)) >> offset) & 0xf; + + for (i = 0; i < priv->data->num_groups; i++) { + group = &priv->data->groups[i]; + pmx_data = (struct meson_pmx_axg_data *)group->data; + + if (pmx_data->func != func) + continue; + + for (j = 0; j < group->num_pins; j++) { + if (group->pins[j] == selector) { + snprintf(buf, size, "%s (%x)", + group->name, func); + return 0; + } + } + } + + snprintf(buf, size, "Unknown (%x)", func); + + return 0; +} + const struct pinconf_param meson_axg_pinconf_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 }, + { "drive-strength-microamp", PIN_CONFIG_DRIVE_STRENGTH_UA, 0 }, }; const struct pinctrl_ops meson_axg_pinctrl_ops = { @@ -110,6 +156,9 @@ const struct pinctrl_ops meson_axg_pinctrl_ops = { .pinconf_num_params = ARRAY_SIZE(meson_axg_pinconf_params), .pinconf_set = meson_pinconf_set, .pinconf_group_set = meson_pinconf_group_set, + .get_pin_name = meson_pinctrl_get_pin_name, + .get_pins_count = meson_pinctrl_get_pins_count, + .get_pin_muxing = meson_axg_pinmux_get, }; static int meson_axg_gpio_request(struct udevice *dev, diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c index 9cc2b9d52b..115e8b5616 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c +++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c @@ -1204,19 +1204,19 @@ static struct meson_pmx_func meson_g12a_aobus_functions[] = { }; static struct meson_bank meson_g12a_periphs_banks[] = { - /* name first last pullen pull dir out in */ - BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0), - BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_8, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0), - BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0), - BANK("C", PIN(GPIOC_0, EE_OFF), PIN(GPIOC_7, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0), - BANK("A", PIN(GPIOA_0, EE_OFF), PIN(GPIOA_15, EE_OFF), 5, 0, 5, 0, 16, 0, 17, 0, 18, 0), - BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_19, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0), + /* name first last pullen pull dir out in ds*/ + BANK_DS("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 4, 0, 4, 0, 12, 0, 13, 0, 14, 0, 5, 0), + BANK_DS("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_8, EE_OFF), 3, 0, 3, 0, 9, 0, 10, 0, 11, 0, 4, 0), + BANK_DS("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0), + BANK_DS("C", PIN(GPIOC_0, EE_OFF), PIN(GPIOC_7, EE_OFF), 1, 0, 1, 0, 3, 0, 4, 0, 5, 0, 1, 0), + BANK_DS("A", PIN(GPIOA_0, EE_OFF), PIN(GPIOA_15, EE_OFF), 5, 0, 5, 0, 16, 0, 17, 0, 18, 0, 6, 0), + BANK_DS("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_19, EE_OFF), 2, 0, 2, 0, 6, 0, 7, 0, 8, 0, 2, 0), }; static struct meson_bank meson_g12a_aobus_banks[] = { - /* name first last pullen pull dir out in */ - BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_11, 0), 3, 0, 2, 0, 0, 0, 4, 0, 1, 0), - BANK("E", PIN(GPIOE_0, 0), PIN(GPIOE_2, 0), 3, 16, 2, 16, 0, 16, 4, 16, 1, 16), + /* name first last pullen pull dir out in ds*/ + BANK_DS("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_11, 0), 3, 0, 2, 0, 0, 0, 4, 0, 1, 0, 0, 0), + BANK_DS("E", PIN(GPIOE_0, 0), PIN(GPIOE_2, 0), 3, 16, 2, 16, 0, 16, 4, 16, 1, 16, 1, 0), }; static struct meson_pmx_bank meson_g12a_periphs_pmx_banks[] = { diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c index cf72576b6c..b37b517fe5 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c @@ -72,6 +72,47 @@ static int meson_gx_pinmux_group_set(struct udevice *dev, return 0; } +static int meson_gx_pinmux_get(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + struct meson_pmx_group *group; + struct meson_gx_pmx_data *pmx_data; + void __iomem *addr; + int i, j, pos = 0; + unsigned int pin; + u32 reg; + + pin = selector + priv->data->pin_base; + + for (i = 0; i < priv->data->num_groups; i++) { + group = &priv->data->groups[i]; + pmx_data = (struct meson_gx_pmx_data *)group->data; + if (pmx_data->is_gpio) + continue; + + for (j = 0; j < group->num_pins; j++) { + if (group->pins[j] == pin) { + /* We have found a group using the pin */ + addr = priv->reg_mux + pmx_data->reg * 4; + reg = readl(addr) & BIT(pmx_data->bit); + if (reg) { + pos += snprintf(buf + pos, size - pos, + "%s ", group->name) - 1; + return 0; + } + } + } + } + + /* Fallback, must be used as GPIO */ + snprintf(buf, size, "%s or Unknown", + priv->data->groups[selector].name); + + return 0; +} + const struct pinconf_param meson_gx_pinconf_params[] = { { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, @@ -89,6 +130,9 @@ const struct pinctrl_ops meson_gx_pinctrl_ops = { .pinconf_num_params = ARRAY_SIZE(meson_gx_pinconf_params), .pinconf_set = meson_pinconf_set, .pinconf_group_set = meson_pinconf_group_set, + .get_pin_name = meson_pinctrl_get_pin_name, + .get_pins_count = meson_pinctrl_get_pins_count, + .get_pin_muxing = meson_gx_pinmux_get, }; static const struct dm_gpio_ops meson_gx_gpio_ops = { diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index 22e8b055d7..9e2e151164 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -61,6 +61,10 @@ static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) }; static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) }; static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) }; +static const unsigned int hdmi_hpd_pins[] = { PIN(GPIOH_0, EE_OFF) }; +static const unsigned int hdmi_sda_pins[] = { PIN(GPIOH_1, EE_OFF) }; +static const unsigned int hdmi_scl_pins[] = { PIN(GPIOH_2, EE_OFF) }; + static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) }; static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) }; static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) }; @@ -144,6 +148,7 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = { GPIO_GROUP(GPIODV_15, EE_OFF), GPIO_GROUP(GPIODV_16, EE_OFF), GPIO_GROUP(GPIODV_17, EE_OFF), + GPIO_GROUP(GPIODV_18, EE_OFF), GPIO_GROUP(GPIODV_19, EE_OFF), GPIO_GROUP(GPIODV_20, EE_OFF), GPIO_GROUP(GPIODV_21, EE_OFF), @@ -203,8 +208,6 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = { GPIO_GROUP(GPIOCLK_2, EE_OFF), GPIO_GROUP(GPIOCLK_3, EE_OFF), - GPIO_GROUP(GPIO_TEST_N, EE_OFF), - /* Bank X */ GROUP(uart_tx_a, 4, 13), GROUP(uart_rx_a, 4, 12), @@ -233,6 +236,11 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = { GROUP(eth_txd2, 6, 3), GROUP(eth_txd3, 6, 2), + /* Bank H */ + GROUP(hdmi_hpd, 1, 26), + GROUP(hdmi_sda, 1, 25), + GROUP(hdmi_scl, 1, 24), + /* Bank DV */ GROUP(uart_tx_b, 2, 29), GROUP(uart_rx_b, 2, 28), @@ -270,6 +278,8 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = { GPIO_GROUP(GPIOAO_12, 0), GPIO_GROUP(GPIOAO_13, 0), + GPIO_GROUP(GPIO_TEST_N, 0), + /* bank AO */ GROUP(uart_tx_ao_b, 0, 26), GROUP(uart_rx_ao_b, 0, 25), @@ -318,6 +328,8 @@ static const char * const gpio_periphs_groups[] = { "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19", "GPIOX_20", "GPIOX_21", "GPIOX_22", + + "GPIOCLK_0", "GPIOCLK_1", "GPIOCLK_2", "GPIOCLK_3", }; static const char * const emmc_groups[] = { @@ -348,6 +360,14 @@ static const char * const eth_groups[] = { "eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3", }; +static const char * const hdmi_hpd_groups[] = { + "hdmi_hpd", +}; + +static const char * const hdmi_i2c_groups[] = { + "hdmi_sda", "hdmi_scl", +}; + static const char * const gpio_aobus_groups[] = { "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", @@ -380,6 +400,8 @@ static struct meson_pmx_func meson_gxbb_periphs_functions[] = { FUNCTION(uart_b), FUNCTION(uart_c), FUNCTION(eth), + FUNCTION(hdmi_hpd), + FUNCTION(hdmi_i2c), }; static struct meson_pmx_func meson_gxbb_aobus_functions[] = { diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c index 1819eee4d0..5acc21b9c2 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c @@ -254,6 +254,7 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = { GPIO_GROUP(GPIODV_15, EE_OFF), GPIO_GROUP(GPIODV_16, EE_OFF), GPIO_GROUP(GPIODV_17, EE_OFF), + GPIO_GROUP(GPIODV_18, EE_OFF), GPIO_GROUP(GPIODV_19, EE_OFF), GPIO_GROUP(GPIODV_20, EE_OFF), GPIO_GROUP(GPIODV_21, EE_OFF), @@ -289,8 +290,6 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = { GPIO_GROUP(GPIOCLK_0, EE_OFF), GPIO_GROUP(GPIOCLK_1, EE_OFF), - GPIO_GROUP(GPIO_TEST_N, 0), - /* Bank X */ GROUP(sdio_d0, 5, 31), GROUP(sdio_d1, 5, 30), @@ -415,6 +414,8 @@ static struct meson_pmx_group meson_gxl_aobus_groups[] = { GPIO_GROUP(GPIOAO_8, 0), GPIO_GROUP(GPIOAO_9, 0), + GPIO_GROUP(GPIO_TEST_N, 0), + /* bank AO */ GROUP(uart_tx_ao_b_0, 0, 26), GROUP(uart_rx_ao_b_1, 0, 25), @@ -471,6 +472,7 @@ static const char * const gpio_periphs_groups[] = { "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", + "GPIOCLK_0", "GPIOCLK_1", }; static const char * const emmc_groups[] = { diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 8735418c5b..f664d76b54 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; static const char *meson_pinctrl_dummy_name = "_dummy"; +static char pin_name[PINNAME_SIZE]; + int meson_pinctrl_get_groups_count(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); @@ -38,6 +40,28 @@ const char *meson_pinctrl_get_group_name(struct udevice *dev, return priv->data->groups[selector].name; } +int meson_pinctrl_get_pins_count(struct udevice *dev) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + + return priv->data->num_pins; +} + +const char *meson_pinctrl_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + + if (selector > priv->data->num_pins || + selector > priv->data->funcs[0].num_groups) + snprintf(pin_name, PINNAME_SIZE, "Error"); + else + snprintf(pin_name, PINNAME_SIZE, "%s", + priv->data->funcs[0].groups[selector]); + + return pin_name; +} + int meson_pinmux_get_functions_count(struct udevice *dev) { struct meson_pinctrl *priv = dev_get_priv(dev); @@ -198,6 +222,47 @@ static int meson_pinconf_bias_set(struct udevice *dev, unsigned int pin, return 0; } +static int meson_pinconf_drive_strength_set(struct udevice *dev, + unsigned int pin, + unsigned int drive_strength_ua) +{ + struct meson_pinctrl *priv = dev_get_priv(dev); + unsigned int offset = pin - priv->data->pin_base; + unsigned int reg, bit; + unsigned int ds_val; + int ret; + + if (!priv->reg_ds) { + dev_err(dev, "drive-strength-microamp not supported\n"); + return -ENOTSUPP; + } + + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DS, ®, &bit); + if (ret) + return ret; + + bit = bit << 1; + + if (drive_strength_ua <= 500) { + ds_val = MESON_PINCONF_DRV_500UA; + } else if (drive_strength_ua <= 2500) { + ds_val = MESON_PINCONF_DRV_2500UA; + } else if (drive_strength_ua <= 3000) { + ds_val = MESON_PINCONF_DRV_3000UA; + } else if (drive_strength_ua <= 4000) { + ds_val = MESON_PINCONF_DRV_4000UA; + } else { + dev_warn(dev, + "pin %u: invalid drive-strength-microamp : %d , default to 4mA\n", + pin, drive_strength_ua); + ds_val = MESON_PINCONF_DRV_4000UA; + } + + clrsetbits_le32(priv->reg_ds + reg, 0x3 << bit, ds_val << bit); + + return 0; +} + int meson_pinconf_set(struct udevice *dev, unsigned int pin, unsigned int param, unsigned int arg) { @@ -209,7 +274,9 @@ int meson_pinconf_set(struct udevice *dev, unsigned int pin, case PIN_CONFIG_BIAS_PULL_DOWN: ret = meson_pinconf_bias_set(dev, pin, param); break; - + case PIN_CONFIG_DRIVE_STRENGTH_UA: + ret = meson_pinconf_drive_strength_set(dev, pin, arg); + break; default: dev_err(dev, "unsupported configuration parameter %u\n", param); return -EINVAL; diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index b3683e2073..98010cdaf9 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -58,6 +58,16 @@ struct meson_reg_desc { unsigned int bit; }; +/** + * enum meson_pinconf_drv - value of drive-strength supported + */ +enum meson_pinconf_drv { + MESON_PINCONF_DRV_500UA, + MESON_PINCONF_DRV_2500UA, + MESON_PINCONF_DRV_3000UA, + MESON_PINCONF_DRV_4000UA, +}; + /** * enum meson_reg_type - type of registers encoded in @meson_reg_desc */ @@ -67,6 +77,7 @@ enum meson_reg_type { REG_DIR, REG_OUT, REG_IN, + REG_DS, NUM_REG, }; @@ -99,19 +110,24 @@ struct meson_bank { .num_groups = ARRAY_SIZE(fn ## _groups), \ } -#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ - { \ - .name = n, \ - .first = f, \ - .last = l, \ - .regs = { \ - [REG_PULLEN] = { per, peb }, \ - [REG_PULL] = { pr, pb }, \ - [REG_DIR] = { dr, db }, \ - [REG_OUT] = { or, ob }, \ - [REG_IN] = { ir, ib }, \ - }, \ - } +#define BANK_DS(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib, \ + dsr, dsb) \ + { \ + .name = n, \ + .first = f, \ + .last = l, \ + .regs = { \ + [REG_PULLEN] = {per, peb}, \ + [REG_PULL] = {pr, pb}, \ + [REG_DIR] = {dr, db}, \ + [REG_OUT] = { or, ob}, \ + [REG_IN] = {ir, ib}, \ + [REG_DS] = {dsr, dsb}, \ + }, \ + } + +#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \ + BANK_DS(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib, 0, 0) #define MESON_PIN(x, b) PINCTRL_PIN(PIN(x, b), #x) @@ -120,6 +136,9 @@ extern const struct pinctrl_ops meson_pinctrl_ops; int meson_pinctrl_get_groups_count(struct udevice *dev); const char *meson_pinctrl_get_group_name(struct udevice *dev, unsigned int selector); +int meson_pinctrl_get_pins_count(struct udevice *dev); +const char *meson_pinctrl_get_pin_name(struct udevice *dev, + unsigned int selector); int meson_pinmux_get_functions_count(struct udevice *dev); const char *meson_pinmux_get_function_name(struct udevice *dev, unsigned int selector); diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h index e7b8ad9078..3eca34fbf7 100644 --- a/include/dm/pinctrl.h +++ b/include/dm/pinctrl.h @@ -225,6 +225,8 @@ struct pinctrl_ops { * push-pull mode, the argument is ignored. * @PIN_CONFIG_DRIVE_STRENGTH: the pin will sink or source at most the current * passed as argument. The argument is in mA. + * @PIN_CONFIG_DRIVE_STRENGTH_UA: the pin will sink or source at most the current + * passed as argument. The argument is in uA. * @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode, * which means it will wait for signals to settle when reading inputs. The * argument gives the debounce time in usecs. Setting the @@ -281,6 +283,7 @@ enum pin_config_param { PIN_CONFIG_DRIVE_OPEN_SOURCE, PIN_CONFIG_DRIVE_PUSH_PULL, PIN_CONFIG_DRIVE_STRENGTH, + PIN_CONFIG_DRIVE_STRENGTH_UA, PIN_CONFIG_INPUT_DEBOUNCE, PIN_CONFIG_INPUT_ENABLE, PIN_CONFIG_INPUT_SCHMITT,