1 From f147cf49ef39f5e87d5df9ef1fab52683bc75c63 Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Sat, 2 Dec 2017 12:23:09 +0100
4 Subject: [PATCH 11/31] pinctrl: gemini: Support drive strength setting
6 The Gemini pin controller can set drive strength for a few
7 select groups of pins (not individually). Implement this
8 for GMAC0 and 1 (ethernet ports), IDE and PCI.
10 Cc: devicetree@vger.kernel.org
11 Reviewed-by: Rob Herring <robh@kernel.org>
12 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
14 .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 3 +
15 drivers/pinctrl/pinctrl-gemini.c | 81 ++++++++++++++++++++++
16 2 files changed, 84 insertions(+)
18 --- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
19 +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
20 @@ -17,6 +17,9 @@ and generic pin config nodes.
22 Supported configurations:
23 - skew-delay is supported on the Ethernet pins
24 +- drive-strength with 4, 8, 12 or 16 mA as argument is supported for
25 + entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp"
30 --- a/drivers/pinctrl/pinctrl-gemini.c
31 +++ b/drivers/pinctrl/pinctrl-gemini.c
32 @@ -67,6 +67,9 @@ struct gemini_pmx {
33 * elements in .pins so we can iterate over that array
34 * @mask: bits to clear to enable this when doing pin muxing
35 * @value: bits to set to enable this when doing pin muxing
36 + * @driving_mask: bitmask for the IO Pad driving register for this
37 + * group, if it supports altering the driving strength of
40 struct gemini_pin_group {
42 @@ -74,12 +77,14 @@ struct gemini_pin_group {
43 const unsigned int num_pins;
49 /* Some straight-forward control registers */
50 #define GLOBAL_WORD_ID 0x00
51 #define GLOBAL_STATUS 0x04
52 #define GLOBAL_STATUS_FLPIN BIT(20)
53 +#define GLOBAL_IODRIVE 0x10
54 #define GLOBAL_GMAC_CTRL_SKEW 0x1c
55 #define GLOBAL_GMAC0_DATA_SKEW 0x20
56 #define GLOBAL_GMAC1_DATA_SKEW 0x24
57 @@ -741,6 +746,7 @@ static const struct gemini_pin_group gem
58 /* Conflict with all flash usage */
59 .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
60 PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
61 + .driving_mask = GENMASK(21, 20),
65 @@ -756,6 +762,7 @@ static const struct gemini_pin_group gem
66 .name = "gmii_gmac0_grp",
67 .pins = gmii_gmac0_3512_pins,
68 .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins),
69 + .driving_mask = GENMASK(17, 16),
72 .name = "gmii_gmac1_grp",
73 @@ -763,6 +770,7 @@ static const struct gemini_pin_group gem
74 .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins),
75 /* Bring out RGMII on the GMAC1 pins */
76 .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
77 + .driving_mask = GENMASK(19, 18),
81 @@ -770,6 +778,7 @@ static const struct gemini_pin_group gem
82 .num_pins = ARRAY_SIZE(pci_3512_pins),
83 /* Conflict only with GPIO2 */
84 .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
85 + .driving_mask = GENMASK(23, 22),
89 @@ -1686,6 +1695,7 @@ static const struct gemini_pin_group gem
90 /* Conflict with all flash usage */
91 .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
92 PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
93 + .driving_mask = GENMASK(21, 20),
97 @@ -1701,6 +1711,7 @@ static const struct gemini_pin_group gem
98 .name = "gmii_gmac0_grp",
99 .pins = gmii_gmac0_3516_pins,
100 .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins),
101 + .driving_mask = GENMASK(17, 16),
104 .name = "gmii_gmac1_grp",
105 @@ -1708,6 +1719,7 @@ static const struct gemini_pin_group gem
106 .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins),
107 /* Bring out RGMII on the GMAC1 pins */
108 .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
109 + .driving_mask = GENMASK(19, 18),
113 @@ -1715,6 +1727,7 @@ static const struct gemini_pin_group gem
114 .num_pins = ARRAY_SIZE(pci_3516_pins),
115 /* Conflict only with GPIO2 */
116 .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
117 + .driving_mask = GENMASK(23, 22),
121 @@ -2423,9 +2436,77 @@ static int gemini_pinconf_set(struct pin
125 +static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev,
127 + unsigned long *configs,
128 + unsigned num_configs)
130 + struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
131 + const struct gemini_pin_group *grp = NULL;
132 + enum pin_config_param param;
138 + grp = &gemini_3512_pin_groups[selector];
140 + grp = &gemini_3516_pin_groups[selector];
142 + /* First figure out if this group supports configs */
143 + if (!grp->driving_mask) {
144 + dev_err(pmx->dev, "pin config group \"%s\" does "
145 + "not support drive strength setting\n",
150 + for (i = 0; i < num_configs; i++) {
151 + param = pinconf_to_config_param(configs[i]);
152 + arg = pinconf_to_config_argument(configs[i]);
155 + case PIN_CONFIG_DRIVE_STRENGTH:
171 + "invalid drive strength %d mA\n",
175 + val <<= (ffs(grp->driving_mask) - 1);
176 + regmap_update_bits(pmx->map, GLOBAL_IODRIVE,
180 + "set group %s to %d mA drive strength mask %08x val %08x\n",
181 + grp->name, arg, grp->driving_mask, val);
184 + dev_err(pmx->dev, "invalid config param %04x\n", param);
192 static const struct pinconf_ops gemini_pinconf_ops = {
193 .pin_config_get = gemini_pinconf_get,
194 .pin_config_set = gemini_pinconf_set,
195 + .pin_config_group_set = gemini_pinconf_group_set,