[U-Boot] [PATCH u-boot] pinctrl: meson: add pinconf support
Neil Armstrong
narmstrong at baylibre.com
Mon Jan 14 16:12:00 UTC 2019
Hi Jerome,
On 04/01/2019 15:44, Jerome Brunet wrote:
> Adding pinconf support is necessary to enable boot from SPI
> without breaking the eMMC. When booting from SPI, the ROM code
> leave pull downs on the eMMC pad.
>
> We need to set pinconf provided in DT to solve this
>
> Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
> ---
> drivers/pinctrl/meson/Kconfig | 1 +
> drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c | 10 ++
> drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c | 10 ++
> drivers/pinctrl/meson/pinctrl-meson.c | 101 ++++++++++++++++--
> drivers/pinctrl/meson/pinctrl-meson.h | 8 ++
> 5 files changed, 123 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
> index ee820a57a0e0..162642d7289b 100644
> --- a/drivers/pinctrl/meson/Kconfig
> +++ b/drivers/pinctrl/meson/Kconfig
> @@ -2,6 +2,7 @@ if ARCH_MESON
>
> config PINCTRL_MESON
> select PINCTRL_GENERIC
> + select PINCONF
> bool
>
> config PINCTRL_MESON_GX_PMX
> diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
> index c82413d08f34..f9065723eea9 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
> @@ -93,6 +93,12 @@ static int meson_axg_pinmux_group_set(struct udevice *dev,
> 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 },
> +};
> +
> const struct pinctrl_ops meson_axg_pinctrl_ops = {
> .get_groups_count = meson_pinctrl_get_groups_count,
> .get_group_name = meson_pinctrl_get_group_name,
> @@ -100,6 +106,10 @@ const struct pinctrl_ops meson_axg_pinctrl_ops = {
> .get_function_name = meson_pinmux_get_function_name,
> .pinmux_group_set = meson_axg_pinmux_group_set,
> .set_state = pinctrl_generic_set_state,
> + .pinconf_params = meson_axg_pinconf_params
> + .pinconf_num_params = ARRAY_SIZE(meson_axg_pinconf_params),
> + .pinconf_set = meson_pinconf_set,
> + .pinconf_group_set = meson_pinconf_group_set,
> };
>
> static int meson_axg_gpio_request(struct udevice *dev,
> diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
> index fc1538ea719e..cf72576b6ce2 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
> @@ -72,6 +72,12 @@ static int meson_gx_pinmux_group_set(struct udevice *dev,
> 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 },
> + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
> +};
> +
> const struct pinctrl_ops meson_gx_pinctrl_ops = {
> .get_groups_count = meson_pinctrl_get_groups_count,
> .get_group_name = meson_pinctrl_get_group_name,
> @@ -79,6 +85,10 @@ const struct pinctrl_ops meson_gx_pinctrl_ops = {
> .get_function_name = meson_pinmux_get_function_name,
> .pinmux_group_set = meson_gx_pinmux_group_set,
> .set_state = pinctrl_generic_set_state,
> + .pinconf_params = meson_gx_pinconf_params,
> + .pinconf_num_params = ARRAY_SIZE(meson_gx_pinconf_params),
> + .pinconf_set = meson_pinconf_set,
> + .pinconf_group_set = meson_pinconf_group_set,
> };
>
> static const struct dm_gpio_ops meson_gx_gpio_ops = {
> diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
> index b539749752c8..fa3d78858a9e 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson.c
> @@ -57,7 +57,7 @@ static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
> enum meson_reg_type reg_type,
> unsigned int *reg, unsigned int *bit)
> {
> - struct meson_pinctrl *priv = dev_get_priv(dev->parent);
> + struct meson_pinctrl *priv = dev_get_priv(dev);
> struct meson_bank *bank = NULL;
> struct meson_reg_desc *desc;
> unsigned int pin;
> @@ -89,7 +89,8 @@ int meson_gpio_get(struct udevice *dev, unsigned int offset)
> unsigned int reg, bit;
> int ret;
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_IN, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_IN, ®,
> + &bit);
> if (ret)
> return ret;
>
> @@ -102,7 +103,8 @@ int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
> unsigned int reg, bit;
> int ret;
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, ®,
> + &bit);
> if (ret)
> return ret;
>
> @@ -117,7 +119,8 @@ int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
> unsigned int reg, bit, val;
> int ret;
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, ®,
> + &bit);
> if (ret)
> return ret;
>
> @@ -132,7 +135,8 @@ int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
> unsigned int reg, bit;
> int ret;
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, ®,
> + &bit);
> if (ret)
> return ret;
>
> @@ -148,13 +152,15 @@ int meson_gpio_direction_output(struct udevice *dev,
> unsigned int reg, bit;
> int ret;
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DIR, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, ®,
> + &bit);
> if (ret)
> return ret;
>
> clrbits_le32(priv->reg_gpio + reg, BIT(bit));
>
> - ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, ®, &bit);
> + ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, ®,
> + &bit);
> if (ret)
> return ret;
>
> @@ -163,6 +169,72 @@ int meson_gpio_direction_output(struct udevice *dev,
> return 0;
> }
>
> +static int meson_pinconf_bias_set(struct udevice *dev, unsigned int pin,
> + unsigned int param)
> +{
> + struct meson_pinctrl *priv = dev_get_priv(dev);
> + unsigned int offset = pin - priv->data->pin_base;
> + unsigned int reg, bit;
> + int ret;
> +
> + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULLEN, ®, &bit);
> + if (ret)
> + return ret;
> +
> + if (param == PIN_CONFIG_BIAS_DISABLE) {
> + clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 0);
> + return 0;
> + }
> +
> + /* othewise, enable the bias and select level */
> + clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 1);
> + ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULL, ®, &bit);
> + if (ret)
> + return ret;
> +
> + clrsetbits_le32(priv->reg_pull + reg, BIT(bit),
> + param == PIN_CONFIG_BIAS_PULL_UP);
> +
> + return 0;
> +}
> +
> +int meson_pinconf_set(struct udevice *dev, unsigned int pin,
> + unsigned int param, unsigned int arg)
> +{
> + int ret;
> +
> + switch (param) {
> + case PIN_CONFIG_BIAS_DISABLE:
> + case PIN_CONFIG_BIAS_PULL_UP:
> + case PIN_CONFIG_BIAS_PULL_DOWN:
> + ret = meson_pinconf_bias_set(dev, pin, param);
> + break;
> +
> + default:
> + dev_err(dev, "unsupported configuration parameter %u\n", param);
> + return -EINVAL;
> + }
> +
> + return ret;
> +}
> +
> +int meson_pinconf_group_set(struct udevice *dev,
> + unsigned int group_selector,
> + unsigned int param, unsigned int arg)
> +{
> + struct meson_pinctrl *priv = dev_get_priv(dev);
> + struct meson_pmx_group *grp = &priv->data->groups[group_selector];
> + int i, ret;
> +
> + for (i = 0; i < grp->num_pins; i++) {
> + ret = meson_pinconf_set(dev, grp->pins[i], param, arg);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> int meson_gpio_probe(struct udevice *dev)
> {
> struct meson_pinctrl *priv = dev_get_priv(dev->parent);
> @@ -240,6 +312,21 @@ int meson_pinctrl_probe(struct udevice *dev)
> return -EINVAL;
> }
> priv->reg_gpio = (void __iomem *)addr;
> +
> + addr = parse_address(gpio, "pull", na, ns);
> + if (addr == FDT_ADDR_T_NONE) {
> + debug("pull address not found\n");
> + return -EINVAL;
> + }
> + priv->reg_pull = (void __iomem *)addr;
> +
> + addr = parse_address(gpio, "pull-enable", na, ns);
> + /* Use pull region if pull-enable one is not present */
> + if (addr == FDT_ADDR_T_NONE)
> + priv->reg_pullen = priv->reg_pull;
> + else
> + priv->reg_pullen = (void __iomem *)addr;
> +
> priv->data = (struct meson_pinctrl_data *)dev_get_driver_data(dev);
>
> /* Lookup GPIO driver */
> diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
> index bdee721fc007..28085a7495d4 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson.h
> +++ b/drivers/pinctrl/meson/pinctrl-meson.h
> @@ -39,6 +39,8 @@ struct meson_pinctrl {
> struct meson_pinctrl_data *data;
> void __iomem *reg_mux;
> void __iomem *reg_gpio;
> + void __iomem *reg_pull;
> + void __iomem *reg_pullen;
> };
>
> /**
> @@ -130,4 +132,10 @@ int meson_gpio_direction_output(struct udevice *dev, unsigned int offset,
> int value);
> int meson_gpio_probe(struct udevice *dev);
>
> +int meson_pinconf_set(struct udevice *dev, unsigned int pin,
> + unsigned int param, unsigned int arg);
> +int meson_pinconf_group_set(struct udevice *dev,
> + unsigned int group_selector,
> + unsigned int param, unsigned int arg);
> +
> #endif /* __PINCTRL_MESON_H__ */
>
Looks good to me,
Applied to u-boot-amlogic
Neil
More information about the U-Boot
mailing list