- pinctrl: meson-gx: fix GPIO_TEST_N and GPIOCLK_ groups

- pinctrl: meson-gxbb: add hdmi related pins to fix HDMI on GXBB
 - pinctrl: meson: add support for getting pinmux status
 - pinctrl: meson-g12a: add support for drive-strength-microamp property
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJdARHoAAoJEHfc29rIyEnRT/oP/1SXqPLazLQapLPr82nFh5f3
 Wf/YxmzWscpWFsS3eyOuIpitIY4d461UWRR3i855uY0TFfoJlt1doIsJWyMy5fTm
 XLUSoZrSzWPPfdcdXyVfQ3LvA/+r67hfxq0CQjABpCMa/ewn9hV8lPp7Yuz3ZxRm
 xZQi52j/9idl6i0z17wPHef2bbgskZW56eYG9BJxmHDNIboJlaEOF0vwNb9SenfL
 uWOSPSEL7MbKm3c1EtDo1KPilU2des0MOxrrkM/kLpMyoOnGwML/GQuRdKUzGhFC
 CHoP74WCWvoyJtlqDizhYdXHkT15Kg1HZyegbp/vw8u52Ol1R5eSXZxp82VlP7Zm
 KPvC2tL6RIbx4+uGD3abwsY3nEAne4IRB9Kj0EaX4nKu/nZpKo44qbzPLBUpGFF8
 kD28/vrOlXqunYQIwon/1lQ3yfzceXqe2f60KZz7chv3u5c23xOpiWx1ptGetKHm
 kiJtRofb+6HsiGJPRny7DS1/6zPzKLe1gJdWs5ZSOCm2nl0Nd1YMCe0J444lgk1m
 iEbT5K9GjEV8g4BpQdFGCWy89pb4whUwFxz8+AYykqfEJSG6xjCW2Wp8N1Sfk1VF
 1CKMd93c+39BwxJTDyQlp+2zi4wOZnIuQ080tzk1hMh2CzZ/ZWjiXquidZI12uw+
 vRopJDiqYGX30TnHMhCm
 =QA+5
 -----END PGP SIGNATURE-----

Merge tag 'u-boot-amlogic-20190612' of git://git.denx.de/u-boot-amlogic

- pinctrl: meson-gx: fix GPIO_TEST_N and GPIOCLK_ groups
- pinctrl: meson-gxbb: add hdmi related pins to fix HDMI on GXBB
- pinctrl: meson: add support for getting pinmux status
- pinctrl: meson-g12a: add support for drive-strength-microamp property
This commit is contained in:
Tom Rini 2019-06-12 15:28:34 -04:00
commit 698bc1f2e9
8 changed files with 234 additions and 28 deletions

View file

@ -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, &reg, &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,

View file

@ -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[] = {

View file

@ -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 = {

View file

@ -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[] = {

View file

@ -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[] = {

View file

@ -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, &reg, &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;

View file

@ -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,7 +110,8 @@ struct meson_bank {
.num_groups = ARRAY_SIZE(fn ## _groups), \
}
#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
#define BANK_DS(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib, \
dsr, dsb) \
{ \
.name = n, \
.first = f, \
@ -110,9 +122,13 @@ struct meson_bank {
[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)
extern const struct pinctrl_ops meson_pinctrl_ops;
@ -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);

View file

@ -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,