[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, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_IN, &reg,
> +					  &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, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
> +					  &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, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
> +					  &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, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
> +					  &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, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
> +					  &bit);
>  	if (ret)
>  		return ret;
>  
>  	clrbits_le32(priv->reg_gpio + reg, BIT(bit));
>  
> -	ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_OUT, &reg, &bit);
> +	ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
> +					  &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, &reg, &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, &reg, &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