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 <[email protected]>
> ---
>  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
_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to