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

