kernel: bump 4.14 to 4.14.144
[oweals/openwrt.git] / target / linux / gemini / patches-4.14 / 0006-pinctrl-gemini-Implement-clock-skew-delay-config.patch
1 From 43e8f011ddbb293e0a3394d0f39819ea2ead4a1b Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Sat, 28 Oct 2017 15:37:19 +0200
4 Subject: [PATCH 06/31] pinctrl: gemini: Implement clock skew/delay config
5
6 This enabled pin config on the Gemini driver and implements
7 pin skew/delay so that the ethernet pins clocking can be
8 properly configured.
9
10 Acked-by: Hans Ulli Kroll <ulli.kroll@googlemail.com>
11 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
12 ---
13  .../bindings/pinctrl/cortina,gemini-pinctrl.txt    |  10 +-
14  drivers/pinctrl/pinctrl-gemini.c                   | 178 ++++++++++++++++++++-
15  2 files changed, 182 insertions(+), 6 deletions(-)
16
17 --- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
18 +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
19 @@ -9,8 +9,14 @@ The pin controller node must be a subnod
20  Required properties:
21  - compatible: "cortina,gemini-pinctrl"
22  
23 -Subnodes of the pin controller contain pin control multiplexing set-up.
24 -Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes.
25 +Subnodes of the pin controller contain pin control multiplexing set-up
26 +and pin configuration of individual pins.
27 +
28 +Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes
29 +and generic pin config nodes.
30 +
31 +Supported configurations:
32 +- skew-delay is supported on the Ethernet pins
33  
34  Example:
35  
36 --- a/drivers/pinctrl/pinctrl-gemini.c
37 +++ b/drivers/pinctrl/pinctrl-gemini.c
38 @@ -24,6 +24,19 @@
39  #define DRIVER_NAME "pinctrl-gemini"
40  
41  /**
42 + * struct gemini_pin_conf - information about configuring a pin
43 + * @pin: the pin number
44 + * @reg: config register
45 + * @mask: the bits affecting the configuration of the pin
46 + */
47 +struct gemini_pin_conf {
48 +       unsigned int pin;
49 +       u32 reg;
50 +       u32 mask;
51 +};
52 +
53 +/**
54 + * struct gemini_pmx - state holder for the gemini pin controller
55   * @dev: a pointer back to containing device
56   * @virtbase: the offset to the controller in virtual memory
57   * @map: regmap to access registers
58 @@ -31,6 +44,8 @@
59   * @is_3516: whether the SoC/package is the 3516 variant
60   * @flash_pin: whether the flash pin (extended pins for parallel
61   * flash) is set
62 + * @confs: pin config information
63 + * @nconfs: number of pin config information items
64   */
65  struct gemini_pmx {
66         struct device *dev;
67 @@ -39,6 +54,8 @@ struct gemini_pmx {
68         bool is_3512;
69         bool is_3516;
70         bool flash_pin;
71 +       const struct gemini_pin_conf *confs;
72 +       unsigned int nconfs;
73  };
74  
75  /**
76 @@ -59,6 +76,13 @@ struct gemini_pin_group {
77         u32 value;
78  };
79  
80 +/* Some straight-forward control registers */
81 +#define GLOBAL_WORD_ID         0x00
82 +#define GLOBAL_STATUS          0x04
83 +#define GLOBAL_STATUS_FLPIN    BIT(20)
84 +#define GLOBAL_GMAC_CTRL_SKEW  0x1c
85 +#define GLOBAL_GMAC0_DATA_SKEW 0x20
86 +#define GLOBAL_GMAC1_DATA_SKEW 0x24
87  /*
88   * Global Miscellaneous Control Register
89   * This register controls all Gemini pad/pin multiplexing
90 @@ -71,9 +95,6 @@ struct gemini_pin_group {
91   *   DISABLED again. So you select a flash configuration once, and then
92   *   you are stuck with it.
93   */
94 -#define GLOBAL_WORD_ID         0x00
95 -#define GLOBAL_STATUS          0x04
96 -#define GLOBAL_STATUS_FLPIN    BIT(20)
97  #define GLOBAL_MISC_CTRL       0x30
98  #define TVC_CLK_PAD_ENABLE     BIT(20)
99  #define PCI_CLK_PAD_ENABLE     BIT(17)
100 @@ -1925,7 +1946,7 @@ static const struct pinctrl_ops gemini_p
101         .get_group_name = gemini_get_group_name,
102         .get_group_pins = gemini_get_group_pins,
103         .pin_dbg_show = gemini_pin_dbg_show,
104 -       .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
105 +       .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
106         .dt_free_map = pinconf_generic_dt_free_map,
107  };
108  
109 @@ -2203,10 +2224,155 @@ static const struct pinmux_ops gemini_pm
110         .set_mux = gemini_pmx_set_mux,
111  };
112  
113 +#define GEMINI_CFGPIN(_n, _r, _lb, _hb) {      \
114 +       .pin = _n,                              \
115 +       .reg = _r,                              \
116 +       .mask = GENMASK(_hb, _lb)               \
117 +}
118 +
119 +static const struct gemini_pin_conf gemini_confs_3512[] = {
120 +       GEMINI_CFGPIN(259, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */
121 +       GEMINI_CFGPIN(277, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */
122 +       GEMINI_CFGPIN(241, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */
123 +       GEMINI_CFGPIN(312, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */
124 +       GEMINI_CFGPIN(298, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */
125 +       GEMINI_CFGPIN(280, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */
126 +       GEMINI_CFGPIN(316, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */
127 +       GEMINI_CFGPIN(243, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */
128 +       GEMINI_CFGPIN(295, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */
129 +       GEMINI_CFGPIN(313, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */
130 +       GEMINI_CFGPIN(242, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */
131 +       GEMINI_CFGPIN(260, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */
132 +       GEMINI_CFGPIN(294, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */
133 +       GEMINI_CFGPIN(276, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */
134 +       GEMINI_CFGPIN(258, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */
135 +       GEMINI_CFGPIN(240, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */
136 +       GEMINI_CFGPIN(262, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */
137 +       GEMINI_CFGPIN(244, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */
138 +       GEMINI_CFGPIN(317, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */
139 +       GEMINI_CFGPIN(299, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */
140 +       GEMINI_CFGPIN(261, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */
141 +       GEMINI_CFGPIN(279, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */
142 +       GEMINI_CFGPIN(297, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */
143 +       GEMINI_CFGPIN(315, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */
144 +};
145 +
146 +static const struct gemini_pin_conf gemini_confs_3516[] = {
147 +       GEMINI_CFGPIN(347, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */
148 +       GEMINI_CFGPIN(386, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */
149 +       GEMINI_CFGPIN(307, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */
150 +       GEMINI_CFGPIN(327, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */
151 +       GEMINI_CFGPIN(309, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */
152 +       GEMINI_CFGPIN(390, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */
153 +       GEMINI_CFGPIN(370, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */
154 +       GEMINI_CFGPIN(350, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */
155 +       GEMINI_CFGPIN(367, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */
156 +       GEMINI_CFGPIN(348, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */
157 +       GEMINI_CFGPIN(387, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */
158 +       GEMINI_CFGPIN(328, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */
159 +       GEMINI_CFGPIN(306, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */
160 +       GEMINI_CFGPIN(325, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */
161 +       GEMINI_CFGPIN(346, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */
162 +       GEMINI_CFGPIN(326, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */
163 +       GEMINI_CFGPIN(391, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */
164 +       GEMINI_CFGPIN(351, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */
165 +       GEMINI_CFGPIN(310, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */
166 +       GEMINI_CFGPIN(371, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */
167 +       GEMINI_CFGPIN(329, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */
168 +       GEMINI_CFGPIN(389, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */
169 +       GEMINI_CFGPIN(369, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */
170 +       GEMINI_CFGPIN(308, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */
171 +};
172 +
173 +static const struct gemini_pin_conf *gemini_get_pin_conf(struct gemini_pmx *pmx,
174 +                                                        unsigned int pin)
175 +{
176 +       const struct gemini_pin_conf *retconf;
177 +       int i;
178 +
179 +       for (i = 0; i < pmx->nconfs; i++) {
180 +               retconf = &gemini_confs_3516[i];
181 +               if (retconf->pin == pin)
182 +                       return retconf;
183 +       }
184 +       return NULL;
185 +}
186 +
187 +static int gemini_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
188 +                             unsigned long *config)
189 +{
190 +       struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
191 +       enum pin_config_param param = pinconf_to_config_param(*config);
192 +       const struct gemini_pin_conf *conf;
193 +       u32 val;
194 +
195 +       switch (param) {
196 +       case PIN_CONFIG_SKEW_DELAY:
197 +               conf = gemini_get_pin_conf(pmx, pin);
198 +               if (!conf)
199 +                       return -ENOTSUPP;
200 +               regmap_read(pmx->map, conf->reg, &val);
201 +               val &= conf->mask;
202 +               val >>= (ffs(conf->mask) - 1);
203 +               *config = pinconf_to_config_packed(PIN_CONFIG_SKEW_DELAY, val);
204 +               break;
205 +       default:
206 +               return -ENOTSUPP;
207 +       }
208 +
209 +       return 0;
210 +}
211 +
212 +static int gemini_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
213 +                             unsigned long *configs, unsigned int num_configs)
214 +{
215 +       struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
216 +       const struct gemini_pin_conf *conf;
217 +       enum pin_config_param param;
218 +       u32 arg;
219 +       int ret = 0;
220 +       int i;
221 +
222 +       for (i = 0; i < num_configs; i++) {
223 +               param = pinconf_to_config_param(configs[i]);
224 +               arg = pinconf_to_config_argument(configs[i]);
225 +
226 +               switch (param) {
227 +               case PIN_CONFIG_SKEW_DELAY:
228 +                       if (arg > 0xf)
229 +                               return -EINVAL;
230 +                       conf = gemini_get_pin_conf(pmx, pin);
231 +                       if (!conf) {
232 +                               dev_err(pmx->dev,
233 +                                       "invalid pin for skew delay %d\n", pin);
234 +                               return -ENOTSUPP;
235 +                       }
236 +                       arg <<= (ffs(conf->mask) - 1);
237 +                       dev_dbg(pmx->dev,
238 +                               "set pin %d to skew delay mask %08x, val %08x\n",
239 +                               pin, conf->mask, arg);
240 +                       regmap_update_bits(pmx->map, conf->reg, conf->mask, arg);
241 +                       break;
242 +               default:
243 +                       dev_err(pmx->dev, "Invalid config param %04x\n", param);
244 +                       return -ENOTSUPP;
245 +               }
246 +       }
247 +
248 +       return ret;
249 +}
250 +
251 +static const struct pinconf_ops gemini_pinconf_ops = {
252 +       .pin_config_get = gemini_pinconf_get,
253 +       .pin_config_set = gemini_pinconf_set,
254 +       .is_generic = true,
255 +};
256 +
257  static struct pinctrl_desc gemini_pmx_desc = {
258         .name = DRIVER_NAME,
259         .pctlops = &gemini_pctrl_ops,
260         .pmxops = &gemini_pmx_ops,
261 +       .confops = &gemini_pinconf_ops,
262         .owner = THIS_MODULE,
263  };
264  
265 @@ -2249,11 +2415,15 @@ static int gemini_pmx_probe(struct platf
266         val &= 0xffff;
267         if (val == 0x3512) {
268                 pmx->is_3512 = true;
269 +               pmx->confs = gemini_confs_3512;
270 +               pmx->nconfs = ARRAY_SIZE(gemini_confs_3512);
271                 gemini_pmx_desc.pins = gemini_3512_pins;
272                 gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3512_pins);
273                 dev_info(dev, "detected 3512 chip variant\n");
274         } else if (val == 0x3516) {
275                 pmx->is_3516 = true;
276 +               pmx->confs = gemini_confs_3516;
277 +               pmx->nconfs = ARRAY_SIZE(gemini_confs_3516);
278                 gemini_pmx_desc.pins = gemini_3516_pins;
279                 gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3516_pins);
280                 dev_info(dev, "detected 3516 chip variant\n");