kernel: bump 4.14 to 4.14.144
[oweals/openwrt.git] / target / linux / gemini / patches-4.14 / 0011-pinctrl-gemini-Support-drive-strength-setting.patch
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
5
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.
9
10 Cc: devicetree@vger.kernel.org
11 Reviewed-by: Rob Herring <robh@kernel.org>
12 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
13 ---
14  .../bindings/pinctrl/cortina,gemini-pinctrl.txt    |  3 +
15  drivers/pinctrl/pinctrl-gemini.c                   | 81 ++++++++++++++++++++++
16  2 files changed, 84 insertions(+)
17
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.
21  
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"
26 +  and "pcigrp".
27  
28  Example:
29  
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
38 + *     its lines.
39   */
40  struct gemini_pin_group {
41         const char *name;
42 @@ -74,12 +77,14 @@ struct gemini_pin_group {
43         const unsigned int num_pins;
44         u32 mask;
45         u32 value;
46 +       u32 driving_mask;
47  };
48  
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 @@ -738,6 +743,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),
62         },
63         {
64                 .name = "satagrp",
65 @@ -753,6 +759,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),
70         },
71         {
72                 .name = "gmii_gmac1_grp",
73 @@ -760,6 +767,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),
78         },
79         {
80                 .name = "pcigrp",
81 @@ -767,6 +775,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),
86         },
87         {
88                 .name = "lpcgrp",
89 @@ -1671,6 +1680,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),
94         },
95         {
96                 .name = "satagrp",
97 @@ -1686,6 +1696,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),
102         },
103         {
104                 .name = "gmii_gmac1_grp",
105 @@ -1693,6 +1704,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),
110         },
111         {
112                 .name = "pcigrp",
113 @@ -1700,6 +1712,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),
118         },
119         {
120                 .name = "lpcgrp",
121 @@ -2394,9 +2407,77 @@ static int gemini_pinconf_set(struct pin
122         return ret;
123  }
124  
125 +static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev,
126 +                                   unsigned selector,
127 +                                   unsigned long *configs,
128 +                                   unsigned num_configs)
129 +{
130 +       struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
131 +       const struct gemini_pin_group *grp = NULL;
132 +       enum pin_config_param param;
133 +       u32 arg;
134 +       u32 val;
135 +       int i;
136 +
137 +       if (pmx->is_3512)
138 +               grp = &gemini_3512_pin_groups[selector];
139 +       if (pmx->is_3516)
140 +               grp = &gemini_3516_pin_groups[selector];
141 +
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",
146 +                       grp->name);
147 +               return -EINVAL;
148 +       }
149 +
150 +       for (i = 0; i < num_configs; i++) {
151 +               param = pinconf_to_config_param(configs[i]);
152 +               arg = pinconf_to_config_argument(configs[i]);
153 +
154 +               switch (param) {
155 +               case PIN_CONFIG_DRIVE_STRENGTH:
156 +                       switch (arg) {
157 +                       case 4:
158 +                               val = 0;
159 +                               break;
160 +                       case 8:
161 +                               val = 1;
162 +                               break;
163 +                       case 12:
164 +                               val = 2;
165 +                               break;
166 +                       case 16:
167 +                               val = 3;
168 +                               break;
169 +                       default:
170 +                               dev_err(pmx->dev,
171 +                                       "invalid drive strength %d mA\n",
172 +                                       arg);
173 +                               return -ENOTSUPP;
174 +                       }
175 +                       val <<= (ffs(grp->driving_mask) - 1);
176 +                       regmap_update_bits(pmx->map, GLOBAL_IODRIVE,
177 +                                          grp->driving_mask,
178 +                                          val);
179 +                       dev_info(pmx->dev,
180 +                                "set group %s to %d mA drive strength mask %08x val %08x\n",
181 +                                grp->name, arg, grp->driving_mask, val);
182 +                       break;
183 +               default:
184 +                       dev_err(pmx->dev, "invalid config param %04x\n", param);
185 +                       return -ENOTSUPP;
186 +               }
187 +       }
188 +
189 +       return 0;
190 +}
191 +
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,
196         .is_generic = true,
197  };
198