183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
25dc626f8SMasahiro Yamada /*
34e3d8406SMasahiro Yamada * Copyright (C) 2015-2016 Socionext Inc.
44e3d8406SMasahiro Yamada * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
55dc626f8SMasahiro Yamada */
65dc626f8SMasahiro Yamada
76a6b9d5dSMasahiro Yamada #include <common.h>
89d922450SSimon Glass #include <dm.h>
95dc626f8SMasahiro Yamada #include <linux/io.h>
105dc626f8SMasahiro Yamada #include <linux/err.h>
11f73cfb4dSMasahiro Yamada #include <linux/kernel.h>
12510454dbSMasahiro Yamada #include <linux/sizes.h>
135dc626f8SMasahiro Yamada #include <dm/pinctrl.h>
145dc626f8SMasahiro Yamada
155dc626f8SMasahiro Yamada #include "pinctrl-uniphier.h"
165dc626f8SMasahiro Yamada
17cdc7e3cbSMasahiro Yamada #define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
18cdc7e3cbSMasahiro Yamada #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
19*150997a4SMasahiro Yamada #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x1800
20*150997a4SMasahiro Yamada #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900
21*150997a4SMasahiro Yamada #define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980
226a6b9d5dSMasahiro Yamada #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
23cdc7e3cbSMasahiro Yamada #define UNIPHIER_PINCTRL_IECTRL 0x1d00
24cdc7e3cbSMasahiro Yamada
2564c1cc4cSMasahiro Yamada static const char *uniphier_pinctrl_dummy_name = "_dummy";
2664c1cc4cSMasahiro Yamada
uniphier_pinctrl_get_pins_count(struct udevice * dev)27603fd9eaSMasahiro Yamada static int uniphier_pinctrl_get_pins_count(struct udevice *dev)
28603fd9eaSMasahiro Yamada {
29603fd9eaSMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
30603fd9eaSMasahiro Yamada const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
31603fd9eaSMasahiro Yamada int pins_count = priv->socdata->pins_count;
32603fd9eaSMasahiro Yamada
33603fd9eaSMasahiro Yamada /*
34603fd9eaSMasahiro Yamada * We do not list all pins in the pin table to save memory footprint.
35603fd9eaSMasahiro Yamada * Report the max pin number + 1 to fake the framework.
36603fd9eaSMasahiro Yamada */
37603fd9eaSMasahiro Yamada return pins[pins_count - 1].number + 1;
38603fd9eaSMasahiro Yamada }
39603fd9eaSMasahiro Yamada
uniphier_pinctrl_get_pin_name(struct udevice * dev,unsigned int selector)40603fd9eaSMasahiro Yamada static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev,
41603fd9eaSMasahiro Yamada unsigned int selector)
42603fd9eaSMasahiro Yamada {
43603fd9eaSMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
44603fd9eaSMasahiro Yamada const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
45603fd9eaSMasahiro Yamada int pins_count = priv->socdata->pins_count;
46603fd9eaSMasahiro Yamada int i;
47603fd9eaSMasahiro Yamada
48603fd9eaSMasahiro Yamada for (i = 0; i < pins_count; i++)
49603fd9eaSMasahiro Yamada if (pins[i].number == selector)
50603fd9eaSMasahiro Yamada return pins[i].name;
51603fd9eaSMasahiro Yamada
52603fd9eaSMasahiro Yamada return uniphier_pinctrl_dummy_name;
53603fd9eaSMasahiro Yamada }
54603fd9eaSMasahiro Yamada
uniphier_pinctrl_get_groups_count(struct udevice * dev)555dc626f8SMasahiro Yamada static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
565dc626f8SMasahiro Yamada {
575dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
585dc626f8SMasahiro Yamada
595dc626f8SMasahiro Yamada return priv->socdata->groups_count;
605dc626f8SMasahiro Yamada }
615dc626f8SMasahiro Yamada
uniphier_pinctrl_get_group_name(struct udevice * dev,unsigned selector)625dc626f8SMasahiro Yamada static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
635dc626f8SMasahiro Yamada unsigned selector)
645dc626f8SMasahiro Yamada {
655dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
665dc626f8SMasahiro Yamada
6764c1cc4cSMasahiro Yamada if (!priv->socdata->groups[selector].name)
6864c1cc4cSMasahiro Yamada return uniphier_pinctrl_dummy_name;
6964c1cc4cSMasahiro Yamada
705dc626f8SMasahiro Yamada return priv->socdata->groups[selector].name;
715dc626f8SMasahiro Yamada }
725dc626f8SMasahiro Yamada
uniphier_pinmux_get_functions_count(struct udevice * dev)735dc626f8SMasahiro Yamada static int uniphier_pinmux_get_functions_count(struct udevice *dev)
745dc626f8SMasahiro Yamada {
755dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
765dc626f8SMasahiro Yamada
775dc626f8SMasahiro Yamada return priv->socdata->functions_count;
785dc626f8SMasahiro Yamada }
795dc626f8SMasahiro Yamada
uniphier_pinmux_get_function_name(struct udevice * dev,unsigned selector)805dc626f8SMasahiro Yamada static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
815dc626f8SMasahiro Yamada unsigned selector)
825dc626f8SMasahiro Yamada {
835dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
845dc626f8SMasahiro Yamada
8564c1cc4cSMasahiro Yamada if (!priv->socdata->functions[selector])
8664c1cc4cSMasahiro Yamada return uniphier_pinctrl_dummy_name;
8764c1cc4cSMasahiro Yamada
885dc626f8SMasahiro Yamada return priv->socdata->functions[selector];
895dc626f8SMasahiro Yamada }
905dc626f8SMasahiro Yamada
uniphier_pinconf_input_enable_perpin(struct udevice * dev,unsigned int pin,int enable)916a6b9d5dSMasahiro Yamada static int uniphier_pinconf_input_enable_perpin(struct udevice *dev,
926a6b9d5dSMasahiro Yamada unsigned int pin, int enable)
933b05b5f0SMasahiro Yamada {
943b05b5f0SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
953b05b5f0SMasahiro Yamada unsigned reg;
963b05b5f0SMasahiro Yamada u32 mask, tmp;
973b05b5f0SMasahiro Yamada
983b05b5f0SMasahiro Yamada reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4;
993b05b5f0SMasahiro Yamada mask = BIT(pin % 32);
1003b05b5f0SMasahiro Yamada
1013b05b5f0SMasahiro Yamada tmp = readl(priv->base + reg);
1026a6b9d5dSMasahiro Yamada if (enable)
1033b05b5f0SMasahiro Yamada tmp |= mask;
1046a6b9d5dSMasahiro Yamada else
1056a6b9d5dSMasahiro Yamada tmp &= ~mask;
1063b05b5f0SMasahiro Yamada writel(tmp, priv->base + reg);
1076a6b9d5dSMasahiro Yamada
1086a6b9d5dSMasahiro Yamada return 0;
1093b05b5f0SMasahiro Yamada }
1103b05b5f0SMasahiro Yamada
uniphier_pinconf_input_enable_legacy(struct udevice * dev,unsigned int pin,int enable)1116a6b9d5dSMasahiro Yamada static int uniphier_pinconf_input_enable_legacy(struct udevice *dev,
1126a6b9d5dSMasahiro Yamada unsigned int pin, int enable)
1135dc626f8SMasahiro Yamada {
1145dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
1155dc626f8SMasahiro Yamada
1166a6b9d5dSMasahiro Yamada /*
1176a6b9d5dSMasahiro Yamada * Multiple pins share one input enable, per-pin disabling is
1186a6b9d5dSMasahiro Yamada * impossible.
1196a6b9d5dSMasahiro Yamada */
1206a6b9d5dSMasahiro Yamada if (!enable)
1216a6b9d5dSMasahiro Yamada return -EINVAL;
1226a6b9d5dSMasahiro Yamada
123f73cfb4dSMasahiro Yamada /* Set all bits instead of having a bunch of pin data */
124f73cfb4dSMasahiro Yamada writel(U32_MAX, priv->base + UNIPHIER_PINCTRL_IECTRL);
1256a6b9d5dSMasahiro Yamada
1266a6b9d5dSMasahiro Yamada return 0;
1275dc626f8SMasahiro Yamada }
1285dc626f8SMasahiro Yamada
uniphier_pinconf_input_enable(struct udevice * dev,unsigned int pin,int enable)1296a6b9d5dSMasahiro Yamada static int uniphier_pinconf_input_enable(struct udevice *dev,
1306a6b9d5dSMasahiro Yamada unsigned int pin, int enable)
1313b05b5f0SMasahiro Yamada {
1323b05b5f0SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
1333b05b5f0SMasahiro Yamada
1343b05b5f0SMasahiro Yamada if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
1356a6b9d5dSMasahiro Yamada return uniphier_pinconf_input_enable_perpin(dev, pin, enable);
1363b05b5f0SMasahiro Yamada else
1376a6b9d5dSMasahiro Yamada return uniphier_pinconf_input_enable_legacy(dev, pin, enable);
1383b05b5f0SMasahiro Yamada }
1393b05b5f0SMasahiro Yamada
1406a6b9d5dSMasahiro Yamada #if CONFIG_IS_ENABLED(PINCONF)
1416a6b9d5dSMasahiro Yamada
1426a6b9d5dSMasahiro Yamada static const struct pinconf_param uniphier_pinconf_params[] = {
1436a6b9d5dSMasahiro Yamada { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
1446a6b9d5dSMasahiro Yamada { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
1456a6b9d5dSMasahiro Yamada { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
1466a6b9d5dSMasahiro Yamada { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
147*150997a4SMasahiro Yamada { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
1486a6b9d5dSMasahiro Yamada { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
1496a6b9d5dSMasahiro Yamada { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
1506a6b9d5dSMasahiro Yamada };
1516a6b9d5dSMasahiro Yamada
152*150997a4SMasahiro Yamada static const struct uniphier_pinctrl_pin *
uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv * priv,unsigned int pin)153*150997a4SMasahiro Yamada uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin)
154*150997a4SMasahiro Yamada {
155*150997a4SMasahiro Yamada const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
156*150997a4SMasahiro Yamada int pins_count = priv->socdata->pins_count;
157*150997a4SMasahiro Yamada int i;
158*150997a4SMasahiro Yamada
159*150997a4SMasahiro Yamada for (i = 0; i < pins_count; i++)
160*150997a4SMasahiro Yamada if (pins[i].number == pin)
161*150997a4SMasahiro Yamada return &pins[i];
162*150997a4SMasahiro Yamada
163*150997a4SMasahiro Yamada return NULL;
164*150997a4SMasahiro Yamada }
165*150997a4SMasahiro Yamada
uniphier_pinconf_bias_set(struct udevice * dev,unsigned int pin,unsigned int param,unsigned int arg)1666a6b9d5dSMasahiro Yamada static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
1676a6b9d5dSMasahiro Yamada unsigned int param, unsigned int arg)
1686a6b9d5dSMasahiro Yamada {
1696a6b9d5dSMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
1706a6b9d5dSMasahiro Yamada unsigned int enable = 1;
1716a6b9d5dSMasahiro Yamada unsigned int reg;
1726a6b9d5dSMasahiro Yamada u32 mask, tmp;
1736a6b9d5dSMasahiro Yamada
1746a6b9d5dSMasahiro Yamada if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE))
1756a6b9d5dSMasahiro Yamada return -ENOTSUPP;
1766a6b9d5dSMasahiro Yamada
1776a6b9d5dSMasahiro Yamada switch (param) {
1786a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_DISABLE:
1796a6b9d5dSMasahiro Yamada enable = 0;
1806a6b9d5dSMasahiro Yamada break;
1816a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_UP:
1826a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_DOWN:
1836a6b9d5dSMasahiro Yamada if (arg == 0) /* total bias is not supported */
1846a6b9d5dSMasahiro Yamada return -EINVAL;
1856a6b9d5dSMasahiro Yamada break;
1866a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
1876a6b9d5dSMasahiro Yamada if (arg == 0) /* configuration ignored */
1886a6b9d5dSMasahiro Yamada return 0;
1896a6b9d5dSMasahiro Yamada default:
1906a6b9d5dSMasahiro Yamada BUG();
1916a6b9d5dSMasahiro Yamada }
1926a6b9d5dSMasahiro Yamada
1936a6b9d5dSMasahiro Yamada reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4;
1946a6b9d5dSMasahiro Yamada mask = BIT(pin % 32);
1956a6b9d5dSMasahiro Yamada
1966a6b9d5dSMasahiro Yamada tmp = readl(priv->base + reg);
1976a6b9d5dSMasahiro Yamada if (enable)
1986a6b9d5dSMasahiro Yamada tmp |= mask;
1996a6b9d5dSMasahiro Yamada else
2006a6b9d5dSMasahiro Yamada tmp &= ~mask;
2016a6b9d5dSMasahiro Yamada writel(tmp, priv->base + reg);
2026a6b9d5dSMasahiro Yamada
2036a6b9d5dSMasahiro Yamada return 0;
2046a6b9d5dSMasahiro Yamada }
2056a6b9d5dSMasahiro Yamada
206*150997a4SMasahiro Yamada static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = {
207*150997a4SMasahiro Yamada 4, 8,
208*150997a4SMasahiro Yamada };
209*150997a4SMasahiro Yamada
210*150997a4SMasahiro Yamada static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = {
211*150997a4SMasahiro Yamada 8, 12, 16, 20,
212*150997a4SMasahiro Yamada };
213*150997a4SMasahiro Yamada
214*150997a4SMasahiro Yamada static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = {
215*150997a4SMasahiro Yamada 4, 5, 7, 9, 11, 12, 14, 16,
216*150997a4SMasahiro Yamada };
217*150997a4SMasahiro Yamada
uniphier_pinconf_drive_set(struct udevice * dev,unsigned int pin,unsigned int strength)218*150997a4SMasahiro Yamada static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin,
219*150997a4SMasahiro Yamada unsigned int strength)
220*150997a4SMasahiro Yamada {
221*150997a4SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
222*150997a4SMasahiro Yamada const struct uniphier_pinctrl_pin *desc;
223*150997a4SMasahiro Yamada const unsigned int *strengths;
224*150997a4SMasahiro Yamada unsigned int base, stride, width, drvctrl, reg, shift;
225*150997a4SMasahiro Yamada u32 val, mask, tmp;
226*150997a4SMasahiro Yamada
227*150997a4SMasahiro Yamada desc = uniphier_pinctrl_pin_get(priv, pin);
228*150997a4SMasahiro Yamada if (WARN_ON(!desc))
229*150997a4SMasahiro Yamada return -EINVAL;
230*150997a4SMasahiro Yamada
231*150997a4SMasahiro Yamada switch (uniphier_pin_get_drv_type(desc->data)) {
232*150997a4SMasahiro Yamada case UNIPHIER_PIN_DRV_1BIT:
233*150997a4SMasahiro Yamada strengths = uniphier_pinconf_drv_strengths_1bit;
234*150997a4SMasahiro Yamada base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
235*150997a4SMasahiro Yamada stride = 1;
236*150997a4SMasahiro Yamada width = 1;
237*150997a4SMasahiro Yamada break;
238*150997a4SMasahiro Yamada case UNIPHIER_PIN_DRV_2BIT:
239*150997a4SMasahiro Yamada strengths = uniphier_pinconf_drv_strengths_2bit;
240*150997a4SMasahiro Yamada base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
241*150997a4SMasahiro Yamada stride = 2;
242*150997a4SMasahiro Yamada width = 2;
243*150997a4SMasahiro Yamada break;
244*150997a4SMasahiro Yamada case UNIPHIER_PIN_DRV_3BIT:
245*150997a4SMasahiro Yamada strengths = uniphier_pinconf_drv_strengths_3bit;
246*150997a4SMasahiro Yamada base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
247*150997a4SMasahiro Yamada stride = 4;
248*150997a4SMasahiro Yamada width = 3;
249*150997a4SMasahiro Yamada break;
250*150997a4SMasahiro Yamada default:
251*150997a4SMasahiro Yamada /* drive strength control is not supported for this pin */
252*150997a4SMasahiro Yamada return -EINVAL;
253*150997a4SMasahiro Yamada }
254*150997a4SMasahiro Yamada
255*150997a4SMasahiro Yamada drvctrl = uniphier_pin_get_drvctrl(desc->data);
256*150997a4SMasahiro Yamada drvctrl *= stride;
257*150997a4SMasahiro Yamada
258*150997a4SMasahiro Yamada reg = base + drvctrl / 32 * 4;
259*150997a4SMasahiro Yamada shift = drvctrl % 32;
260*150997a4SMasahiro Yamada mask = (1U << width) - 1;
261*150997a4SMasahiro Yamada
262*150997a4SMasahiro Yamada for (val = 0; val <= mask; val++) {
263*150997a4SMasahiro Yamada if (strengths[val] > strength)
264*150997a4SMasahiro Yamada break;
265*150997a4SMasahiro Yamada }
266*150997a4SMasahiro Yamada
267*150997a4SMasahiro Yamada if (val == 0) {
268*150997a4SMasahiro Yamada dev_err(dev, "unsupported drive strength %u mA for pin %s\n",
269*150997a4SMasahiro Yamada strength, desc->name);
270*150997a4SMasahiro Yamada return -EINVAL;
271*150997a4SMasahiro Yamada }
272*150997a4SMasahiro Yamada
273*150997a4SMasahiro Yamada if (!mask)
274*150997a4SMasahiro Yamada return 0;
275*150997a4SMasahiro Yamada
276*150997a4SMasahiro Yamada val--;
277*150997a4SMasahiro Yamada
278*150997a4SMasahiro Yamada tmp = readl(priv->base + reg);
279*150997a4SMasahiro Yamada tmp &= ~(mask << shift);
280*150997a4SMasahiro Yamada tmp |= (mask & val) << shift;
281*150997a4SMasahiro Yamada writel(tmp, priv->base + reg);
282*150997a4SMasahiro Yamada
283*150997a4SMasahiro Yamada return 0;
284*150997a4SMasahiro Yamada }
285*150997a4SMasahiro Yamada
uniphier_pinconf_set(struct udevice * dev,unsigned int pin,unsigned int param,unsigned int arg)286603fd9eaSMasahiro Yamada static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin,
2876a6b9d5dSMasahiro Yamada unsigned int param, unsigned int arg)
2886a6b9d5dSMasahiro Yamada {
2896a6b9d5dSMasahiro Yamada int ret;
2906a6b9d5dSMasahiro Yamada
2916a6b9d5dSMasahiro Yamada switch (param) {
2926a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_DISABLE:
2936a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_UP:
2946a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_DOWN:
2956a6b9d5dSMasahiro Yamada case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
2966a6b9d5dSMasahiro Yamada ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
2976a6b9d5dSMasahiro Yamada break;
298*150997a4SMasahiro Yamada case PIN_CONFIG_DRIVE_STRENGTH:
299*150997a4SMasahiro Yamada ret = uniphier_pinconf_drive_set(dev, pin, arg);
300*150997a4SMasahiro Yamada break;
3016a6b9d5dSMasahiro Yamada case PIN_CONFIG_INPUT_ENABLE:
3026a6b9d5dSMasahiro Yamada ret = uniphier_pinconf_input_enable(dev, pin, arg);
3036a6b9d5dSMasahiro Yamada break;
3046a6b9d5dSMasahiro Yamada default:
3057629d0b9SMasahiro Yamada dev_err(dev, "unsupported configuration parameter %u\n", param);
3066a6b9d5dSMasahiro Yamada return -EINVAL;
3076a6b9d5dSMasahiro Yamada }
3086a6b9d5dSMasahiro Yamada
3096a6b9d5dSMasahiro Yamada return ret;
3106a6b9d5dSMasahiro Yamada }
3116a6b9d5dSMasahiro Yamada
uniphier_pinconf_group_set(struct udevice * dev,unsigned int group_selector,unsigned int param,unsigned int arg)3126a6b9d5dSMasahiro Yamada static int uniphier_pinconf_group_set(struct udevice *dev,
3136a6b9d5dSMasahiro Yamada unsigned int group_selector,
3146a6b9d5dSMasahiro Yamada unsigned int param, unsigned int arg)
3156a6b9d5dSMasahiro Yamada {
3166a6b9d5dSMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
3176a6b9d5dSMasahiro Yamada const struct uniphier_pinctrl_group *grp =
3186a6b9d5dSMasahiro Yamada &priv->socdata->groups[group_selector];
3196a6b9d5dSMasahiro Yamada int i, ret;
3206a6b9d5dSMasahiro Yamada
3216a6b9d5dSMasahiro Yamada for (i = 0; i < grp->num_pins; i++) {
322603fd9eaSMasahiro Yamada ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg);
3236a6b9d5dSMasahiro Yamada if (ret)
3246a6b9d5dSMasahiro Yamada return ret;
3256a6b9d5dSMasahiro Yamada }
3266a6b9d5dSMasahiro Yamada
3276a6b9d5dSMasahiro Yamada return 0;
3286a6b9d5dSMasahiro Yamada }
3296a6b9d5dSMasahiro Yamada
3306a6b9d5dSMasahiro Yamada #endif /* CONFIG_IS_ENABLED(PINCONF) */
3316a6b9d5dSMasahiro Yamada
uniphier_pinmux_set_one(struct udevice * dev,unsigned pin,int muxval)3325dc626f8SMasahiro Yamada static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
3335e25b9d5SMasahiro Yamada int muxval)
3345dc626f8SMasahiro Yamada {
3355dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
336bbb11980SMasahiro Yamada unsigned reg, reg_end, shift, mask;
337bbb11980SMasahiro Yamada unsigned mux_bits = 8;
338bbb11980SMasahiro Yamada unsigned reg_stride = 4;
339bbb11980SMasahiro Yamada bool load_pinctrl = false;
3405dc626f8SMasahiro Yamada u32 tmp;
3415dc626f8SMasahiro Yamada
342fdd15b6aSMasahiro Yamada /* some pins need input-enabling */
3436a6b9d5dSMasahiro Yamada uniphier_pinconf_input_enable(dev, pin, 1);
344fdd15b6aSMasahiro Yamada
3455e25b9d5SMasahiro Yamada if (muxval < 0)
3465e25b9d5SMasahiro Yamada return; /* dedicated pin; nothing to do for pin-mux */
3475e25b9d5SMasahiro Yamada
348bbb11980SMasahiro Yamada if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_MUX_4BIT)
349bbb11980SMasahiro Yamada mux_bits = 4;
350bbb11980SMasahiro Yamada
3518cc92b99SMasahiro Yamada if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
3528cc92b99SMasahiro Yamada /*
3538cc92b99SMasahiro Yamada * Mode offset bit
3548cc92b99SMasahiro Yamada * Normal 4 * n shift+3:shift
3558cc92b99SMasahiro Yamada * Debug 4 * n shift+7:shift+4
3568cc92b99SMasahiro Yamada */
357bbb11980SMasahiro Yamada mux_bits /= 2;
3588cc92b99SMasahiro Yamada reg_stride = 8;
3598cc92b99SMasahiro Yamada load_pinctrl = true;
3608cc92b99SMasahiro Yamada }
3618cc92b99SMasahiro Yamada
3625dc626f8SMasahiro Yamada reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
3635dc626f8SMasahiro Yamada reg_end = reg + reg_stride;
3645dc626f8SMasahiro Yamada shift = pin * mux_bits % 32;
3655dc626f8SMasahiro Yamada mask = (1U << mux_bits) - 1;
3665dc626f8SMasahiro Yamada
3675dc626f8SMasahiro Yamada /*
3685dc626f8SMasahiro Yamada * If reg_stride is greater than 4, the MSB of each pinsel shall be
3695dc626f8SMasahiro Yamada * stored in the offset+4.
3705dc626f8SMasahiro Yamada */
3715dc626f8SMasahiro Yamada for (; reg < reg_end; reg += 4) {
3725dc626f8SMasahiro Yamada tmp = readl(priv->base + reg);
3735dc626f8SMasahiro Yamada tmp &= ~(mask << shift);
3745dc626f8SMasahiro Yamada tmp |= (mask & muxval) << shift;
3755dc626f8SMasahiro Yamada writel(tmp, priv->base + reg);
3765dc626f8SMasahiro Yamada
3775dc626f8SMasahiro Yamada muxval >>= mux_bits;
3785dc626f8SMasahiro Yamada }
3795dc626f8SMasahiro Yamada
3808cc92b99SMasahiro Yamada if (load_pinctrl)
3815dc626f8SMasahiro Yamada writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX);
3825dc626f8SMasahiro Yamada }
3835dc626f8SMasahiro Yamada
uniphier_pinmux_group_set(struct udevice * dev,unsigned group_selector,unsigned func_selector)3845dc626f8SMasahiro Yamada static int uniphier_pinmux_group_set(struct udevice *dev,
3855dc626f8SMasahiro Yamada unsigned group_selector,
3865dc626f8SMasahiro Yamada unsigned func_selector)
3875dc626f8SMasahiro Yamada {
3885dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
3895dc626f8SMasahiro Yamada const struct uniphier_pinctrl_group *grp =
3905dc626f8SMasahiro Yamada &priv->socdata->groups[group_selector];
3915dc626f8SMasahiro Yamada int i;
3925dc626f8SMasahiro Yamada
3935dc626f8SMasahiro Yamada for (i = 0; i < grp->num_pins; i++)
3945dc626f8SMasahiro Yamada uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]);
3955dc626f8SMasahiro Yamada
3965dc626f8SMasahiro Yamada return 0;
3975dc626f8SMasahiro Yamada }
3985dc626f8SMasahiro Yamada
3995dc626f8SMasahiro Yamada const struct pinctrl_ops uniphier_pinctrl_ops = {
400603fd9eaSMasahiro Yamada .get_pins_count = uniphier_pinctrl_get_pins_count,
401603fd9eaSMasahiro Yamada .get_pin_name = uniphier_pinctrl_get_pin_name,
4025dc626f8SMasahiro Yamada .get_groups_count = uniphier_pinctrl_get_groups_count,
4035dc626f8SMasahiro Yamada .get_group_name = uniphier_pinctrl_get_group_name,
4045dc626f8SMasahiro Yamada .get_functions_count = uniphier_pinmux_get_functions_count,
4055dc626f8SMasahiro Yamada .get_function_name = uniphier_pinmux_get_function_name,
4065dc626f8SMasahiro Yamada .pinmux_group_set = uniphier_pinmux_group_set,
4076a6b9d5dSMasahiro Yamada #if CONFIG_IS_ENABLED(PINCONF)
4086a6b9d5dSMasahiro Yamada .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
4096a6b9d5dSMasahiro Yamada .pinconf_params = uniphier_pinconf_params,
410603fd9eaSMasahiro Yamada .pinconf_set = uniphier_pinconf_set,
4116a6b9d5dSMasahiro Yamada .pinconf_group_set = uniphier_pinconf_group_set,
4126a6b9d5dSMasahiro Yamada #endif
4135dc626f8SMasahiro Yamada .set_state = pinctrl_generic_set_state,
4145dc626f8SMasahiro Yamada };
4155dc626f8SMasahiro Yamada
uniphier_pinctrl_probe(struct udevice * dev,struct uniphier_pinctrl_socdata * socdata)4165dc626f8SMasahiro Yamada int uniphier_pinctrl_probe(struct udevice *dev,
4175dc626f8SMasahiro Yamada struct uniphier_pinctrl_socdata *socdata)
4185dc626f8SMasahiro Yamada {
4195dc626f8SMasahiro Yamada struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
4205dc626f8SMasahiro Yamada fdt_addr_t addr;
4215dc626f8SMasahiro Yamada
422a821c4afSSimon Glass addr = devfdt_get_addr(dev->parent);
4235dc626f8SMasahiro Yamada if (addr == FDT_ADDR_T_NONE)
4245dc626f8SMasahiro Yamada return -EINVAL;
4255dc626f8SMasahiro Yamada
4264e3d8406SMasahiro Yamada priv->base = devm_ioremap(dev, addr, SZ_4K);
4275dc626f8SMasahiro Yamada if (!priv->base)
4285dc626f8SMasahiro Yamada return -ENOMEM;
4295dc626f8SMasahiro Yamada
4305dc626f8SMasahiro Yamada priv->socdata = socdata;
4315dc626f8SMasahiro Yamada
4325dc626f8SMasahiro Yamada return 0;
4335dc626f8SMasahiro Yamada }
434