]>
Commit | Line | Data |
---|---|---|
4e53b500 PE |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Copyright (C) 2014-2018 Renesas Electronics Europe Limited | |
4 | * | |
5 | * Phil Edworthy <phil.edworthy@renesas.com> | |
6 | * Based on a driver originally written by Michel Pollet at Renesas. | |
7 | */ | |
8 | ||
9 | #include <dt-bindings/pinctrl/rzn1-pinctrl.h> | |
10 | #include <linux/clk.h> | |
11 | #include <linux/device.h> | |
12 | #include <linux/io.h> | |
13 | #include <linux/module.h> | |
14 | #include <linux/of.h> | |
15 | #include <linux/pinctrl/pinconf-generic.h> | |
16 | #include <linux/pinctrl/pinctrl.h> | |
17 | #include <linux/pinctrl/pinmux.h> | |
18 | #include <linux/platform_device.h> | |
19 | #include <linux/slab.h> | |
20 | #include "core.h" | |
21 | #include "pinconf.h" | |
22 | #include "pinctrl-utils.h" | |
23 | ||
24 | /* Field positions and masks in the pinmux registers */ | |
25 | #define RZN1_L1_PIN_DRIVE_STRENGTH 10 | |
26 | #define RZN1_L1_PIN_DRIVE_STRENGTH_4MA 0 | |
27 | #define RZN1_L1_PIN_DRIVE_STRENGTH_6MA 1 | |
28 | #define RZN1_L1_PIN_DRIVE_STRENGTH_8MA 2 | |
29 | #define RZN1_L1_PIN_DRIVE_STRENGTH_12MA 3 | |
30 | #define RZN1_L1_PIN_PULL 8 | |
31 | #define RZN1_L1_PIN_PULL_NONE 0 | |
32 | #define RZN1_L1_PIN_PULL_UP 1 | |
33 | #define RZN1_L1_PIN_PULL_DOWN 3 | |
34 | #define RZN1_L1_FUNCTION 0 | |
35 | #define RZN1_L1_FUNC_MASK 0xf | |
36 | #define RZN1_L1_FUNCTION_L2 0xf | |
37 | ||
38 | /* | |
39 | * The hardware manual describes two levels of multiplexing, but it's more | |
40 | * logical to think of the hardware as three levels, with level 3 consisting of | |
41 | * the multiplexing for Ethernet MDIO signals. | |
42 | * | |
43 | * Level 1 functions go from 0 to 9, with level 1 function '15' (0xf) specifying | |
44 | * that level 2 functions are used instead. Level 2 has a lot more options, | |
45 | * going from 0 to 61. Level 3 allows selection of MDIO functions which can be | |
46 | * floating, or one of seven internal peripherals. Unfortunately, there are two | |
47 | * level 2 functions that can select MDIO, and two MDIO channels so we have four | |
48 | * sets of level 3 functions. | |
49 | * | |
50 | * For this driver, we've compounded the numbers together, so: | |
51 | * 0 to 9 is level 1 | |
52 | * 10 to 71 is 10 + level 2 number | |
53 | * 72 to 79 is 72 + MDIO0 source for level 2 MDIO function. | |
54 | * 80 to 87 is 80 + MDIO0 source for level 2 MDIO_E1 function. | |
55 | * 88 to 95 is 88 + MDIO1 source for level 2 MDIO function. | |
56 | * 96 to 103 is 96 + MDIO1 source for level 2 MDIO_E1 function. | |
57 | * Examples: | |
58 | * Function 28 corresponds UART0 | |
59 | * Function 73 corresponds to MDIO0 to GMAC0 | |
60 | * | |
61 | * There are 170 configurable pins (called PL_GPIO in the datasheet). | |
62 | */ | |
63 | ||
64 | /* | |
65 | * Structure detailing the HW registers on the RZ/N1 devices. | |
66 | * Both the Level 1 mux registers and Level 2 mux registers have the same | |
67 | * structure. The only difference is that Level 2 has additional MDIO registers | |
68 | * at the end. | |
69 | */ | |
70 | struct rzn1_pinctrl_regs { | |
71 | u32 conf[170]; | |
72 | u32 pad0[86]; | |
73 | u32 status_protect; /* 0x400 */ | |
74 | /* MDIO mux registers, level2 only */ | |
75 | u32 l2_mdio[2]; | |
76 | }; | |
77 | ||
78 | /** | |
79 | * struct rzn1_pmx_func - describes rzn1 pinmux functions | |
80 | * @name: the name of this specific function | |
81 | * @groups: corresponding pin groups | |
82 | * @num_groups: the number of groups | |
83 | */ | |
84 | struct rzn1_pmx_func { | |
85 | const char *name; | |
86 | const char **groups; | |
87 | unsigned int num_groups; | |
88 | }; | |
89 | ||
90 | /** | |
91 | * struct rzn1_pin_group - describes an rzn1 pin group | |
92 | * @name: the name of this specific pin group | |
93 | * @func: the name of the function selected by this group | |
94 | * @npins: the number of pins in this group array, i.e. the number of | |
95 | * elements in .pins so we can iterate over that array | |
96 | * @pins: array of pins. Needed due to pinctrl_ops.get_group_pins() | |
97 | * @pin_ids: array of pin_ids, i.e. the value used to select the mux | |
98 | */ | |
99 | struct rzn1_pin_group { | |
100 | const char *name; | |
101 | const char *func; | |
102 | unsigned int npins; | |
103 | unsigned int *pins; | |
104 | u8 *pin_ids; | |
105 | }; | |
106 | ||
107 | struct rzn1_pinctrl { | |
108 | struct device *dev; | |
109 | struct clk *clk; | |
110 | struct pinctrl_dev *pctl; | |
111 | struct rzn1_pinctrl_regs __iomem *lev1; | |
112 | struct rzn1_pinctrl_regs __iomem *lev2; | |
113 | u32 lev1_protect_phys; | |
114 | u32 lev2_protect_phys; | |
8deaaa46 | 115 | int mdio_func[2]; |
4e53b500 PE |
116 | |
117 | struct rzn1_pin_group *groups; | |
118 | unsigned int ngroups; | |
119 | ||
120 | struct rzn1_pmx_func *functions; | |
121 | unsigned int nfunctions; | |
122 | }; | |
123 | ||
124 | #define RZN1_PINS_PROP "pinmux" | |
125 | ||
126 | #define RZN1_PIN(pin) PINCTRL_PIN(pin, "pl_gpio"#pin) | |
127 | ||
128 | static const struct pinctrl_pin_desc rzn1_pins[] = { | |
129 | RZN1_PIN(0), RZN1_PIN(1), RZN1_PIN(2), RZN1_PIN(3), RZN1_PIN(4), | |
130 | RZN1_PIN(5), RZN1_PIN(6), RZN1_PIN(7), RZN1_PIN(8), RZN1_PIN(9), | |
131 | RZN1_PIN(10), RZN1_PIN(11), RZN1_PIN(12), RZN1_PIN(13), RZN1_PIN(14), | |
132 | RZN1_PIN(15), RZN1_PIN(16), RZN1_PIN(17), RZN1_PIN(18), RZN1_PIN(19), | |
133 | RZN1_PIN(20), RZN1_PIN(21), RZN1_PIN(22), RZN1_PIN(23), RZN1_PIN(24), | |
134 | RZN1_PIN(25), RZN1_PIN(26), RZN1_PIN(27), RZN1_PIN(28), RZN1_PIN(29), | |
135 | RZN1_PIN(30), RZN1_PIN(31), RZN1_PIN(32), RZN1_PIN(33), RZN1_PIN(34), | |
136 | RZN1_PIN(35), RZN1_PIN(36), RZN1_PIN(37), RZN1_PIN(38), RZN1_PIN(39), | |
137 | RZN1_PIN(40), RZN1_PIN(41), RZN1_PIN(42), RZN1_PIN(43), RZN1_PIN(44), | |
138 | RZN1_PIN(45), RZN1_PIN(46), RZN1_PIN(47), RZN1_PIN(48), RZN1_PIN(49), | |
139 | RZN1_PIN(50), RZN1_PIN(51), RZN1_PIN(52), RZN1_PIN(53), RZN1_PIN(54), | |
140 | RZN1_PIN(55), RZN1_PIN(56), RZN1_PIN(57), RZN1_PIN(58), RZN1_PIN(59), | |
141 | RZN1_PIN(60), RZN1_PIN(61), RZN1_PIN(62), RZN1_PIN(63), RZN1_PIN(64), | |
142 | RZN1_PIN(65), RZN1_PIN(66), RZN1_PIN(67), RZN1_PIN(68), RZN1_PIN(69), | |
143 | RZN1_PIN(70), RZN1_PIN(71), RZN1_PIN(72), RZN1_PIN(73), RZN1_PIN(74), | |
144 | RZN1_PIN(75), RZN1_PIN(76), RZN1_PIN(77), RZN1_PIN(78), RZN1_PIN(79), | |
145 | RZN1_PIN(80), RZN1_PIN(81), RZN1_PIN(82), RZN1_PIN(83), RZN1_PIN(84), | |
146 | RZN1_PIN(85), RZN1_PIN(86), RZN1_PIN(87), RZN1_PIN(88), RZN1_PIN(89), | |
147 | RZN1_PIN(90), RZN1_PIN(91), RZN1_PIN(92), RZN1_PIN(93), RZN1_PIN(94), | |
148 | RZN1_PIN(95), RZN1_PIN(96), RZN1_PIN(97), RZN1_PIN(98), RZN1_PIN(99), | |
149 | RZN1_PIN(100), RZN1_PIN(101), RZN1_PIN(102), RZN1_PIN(103), | |
150 | RZN1_PIN(104), RZN1_PIN(105), RZN1_PIN(106), RZN1_PIN(107), | |
151 | RZN1_PIN(108), RZN1_PIN(109), RZN1_PIN(110), RZN1_PIN(111), | |
152 | RZN1_PIN(112), RZN1_PIN(113), RZN1_PIN(114), RZN1_PIN(115), | |
153 | RZN1_PIN(116), RZN1_PIN(117), RZN1_PIN(118), RZN1_PIN(119), | |
154 | RZN1_PIN(120), RZN1_PIN(121), RZN1_PIN(122), RZN1_PIN(123), | |
155 | RZN1_PIN(124), RZN1_PIN(125), RZN1_PIN(126), RZN1_PIN(127), | |
156 | RZN1_PIN(128), RZN1_PIN(129), RZN1_PIN(130), RZN1_PIN(131), | |
157 | RZN1_PIN(132), RZN1_PIN(133), RZN1_PIN(134), RZN1_PIN(135), | |
158 | RZN1_PIN(136), RZN1_PIN(137), RZN1_PIN(138), RZN1_PIN(139), | |
159 | RZN1_PIN(140), RZN1_PIN(141), RZN1_PIN(142), RZN1_PIN(143), | |
160 | RZN1_PIN(144), RZN1_PIN(145), RZN1_PIN(146), RZN1_PIN(147), | |
161 | RZN1_PIN(148), RZN1_PIN(149), RZN1_PIN(150), RZN1_PIN(151), | |
162 | RZN1_PIN(152), RZN1_PIN(153), RZN1_PIN(154), RZN1_PIN(155), | |
163 | RZN1_PIN(156), RZN1_PIN(157), RZN1_PIN(158), RZN1_PIN(159), | |
164 | RZN1_PIN(160), RZN1_PIN(161), RZN1_PIN(162), RZN1_PIN(163), | |
165 | RZN1_PIN(164), RZN1_PIN(165), RZN1_PIN(166), RZN1_PIN(167), | |
166 | RZN1_PIN(168), RZN1_PIN(169), | |
167 | }; | |
168 | ||
169 | enum { | |
170 | LOCK_LEVEL1 = 0x1, | |
171 | LOCK_LEVEL2 = 0x2, | |
172 | LOCK_ALL = LOCK_LEVEL1 | LOCK_LEVEL2, | |
173 | }; | |
174 | ||
175 | static void rzn1_hw_set_lock(struct rzn1_pinctrl *ipctl, u8 lock, u8 value) | |
176 | { | |
177 | /* | |
178 | * The pinmux configuration is locked by writing the physical address of | |
179 | * the status_protect register to itself. It is unlocked by writing the | |
180 | * address | 1. | |
181 | */ | |
182 | if (lock & LOCK_LEVEL1) { | |
183 | u32 val = ipctl->lev1_protect_phys | !(value & LOCK_LEVEL1); | |
184 | ||
185 | writel(val, &ipctl->lev1->status_protect); | |
186 | } | |
187 | ||
188 | if (lock & LOCK_LEVEL2) { | |
189 | u32 val = ipctl->lev2_protect_phys | !(value & LOCK_LEVEL2); | |
190 | ||
191 | writel(val, &ipctl->lev2->status_protect); | |
192 | } | |
193 | } | |
194 | ||
195 | static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl *ipctl, int mdio, | |
196 | u32 func) | |
197 | { | |
198 | if (ipctl->mdio_func[mdio] >= 0 && ipctl->mdio_func[mdio] != func) | |
199 | dev_warn(ipctl->dev, "conflicting setting for mdio%d!\n", mdio); | |
200 | ipctl->mdio_func[mdio] = func; | |
201 | ||
202 | dev_dbg(ipctl->dev, "setting mdio%d to %u\n", mdio, func); | |
203 | ||
204 | writel(func, &ipctl->lev2->l2_mdio[mdio]); | |
205 | } | |
206 | ||
207 | /* | |
208 | * Using a composite pin description, set the hardware pinmux registers | |
209 | * with the corresponding values. | |
210 | * Make sure to unlock write protection and reset it afterward. | |
211 | * | |
212 | * NOTE: There is no protection for potential concurrency, it is assumed these | |
213 | * calls are serialized already. | |
214 | */ | |
215 | static int rzn1_set_hw_pin_func(struct rzn1_pinctrl *ipctl, unsigned int pin, | |
216 | u32 pin_config, u8 use_locks) | |
217 | { | |
218 | u32 l1_cache; | |
219 | u32 l2_cache; | |
220 | u32 l1; | |
221 | u32 l2; | |
222 | ||
223 | /* Level 3 MDIO multiplexing */ | |
224 | if (pin_config >= RZN1_FUNC_MDIO0_HIGHZ && | |
225 | pin_config <= RZN1_FUNC_MDIO1_E1_SWITCH) { | |
226 | int mdio_channel; | |
227 | u32 mdio_func; | |
228 | ||
229 | if (pin_config <= RZN1_FUNC_MDIO1_HIGHZ) | |
230 | mdio_channel = 0; | |
231 | else | |
232 | mdio_channel = 1; | |
233 | ||
234 | /* Get MDIO func, and convert the func to the level 2 number */ | |
235 | if (pin_config <= RZN1_FUNC_MDIO0_SWITCH) { | |
236 | mdio_func = pin_config - RZN1_FUNC_MDIO0_HIGHZ; | |
237 | pin_config = RZN1_FUNC_ETH_MDIO; | |
238 | } else if (pin_config <= RZN1_FUNC_MDIO0_E1_SWITCH) { | |
239 | mdio_func = pin_config - RZN1_FUNC_MDIO0_E1_HIGHZ; | |
240 | pin_config = RZN1_FUNC_ETH_MDIO_E1; | |
241 | } else if (pin_config <= RZN1_FUNC_MDIO1_SWITCH) { | |
242 | mdio_func = pin_config - RZN1_FUNC_MDIO1_HIGHZ; | |
243 | pin_config = RZN1_FUNC_ETH_MDIO; | |
244 | } else { | |
245 | mdio_func = pin_config - RZN1_FUNC_MDIO1_E1_HIGHZ; | |
246 | pin_config = RZN1_FUNC_ETH_MDIO_E1; | |
247 | } | |
248 | rzn1_pinctrl_mdio_select(ipctl, mdio_channel, mdio_func); | |
249 | } | |
250 | ||
251 | /* Note here, we do not allow anything past the MDIO Mux values */ | |
252 | if (pin >= ARRAY_SIZE(ipctl->lev1->conf) || | |
253 | pin_config >= RZN1_FUNC_MDIO0_HIGHZ) | |
254 | return -EINVAL; | |
255 | ||
256 | l1 = readl(&ipctl->lev1->conf[pin]); | |
257 | l1_cache = l1; | |
258 | l2 = readl(&ipctl->lev2->conf[pin]); | |
259 | l2_cache = l2; | |
260 | ||
261 | dev_dbg(ipctl->dev, "setting func for pin %u to %u\n", pin, pin_config); | |
262 | ||
263 | l1 &= ~(RZN1_L1_FUNC_MASK << RZN1_L1_FUNCTION); | |
264 | ||
265 | if (pin_config < RZN1_FUNC_L2_OFFSET) { | |
266 | l1 |= (pin_config << RZN1_L1_FUNCTION); | |
267 | } else { | |
268 | l1 |= (RZN1_L1_FUNCTION_L2 << RZN1_L1_FUNCTION); | |
269 | ||
270 | l2 = pin_config - RZN1_FUNC_L2_OFFSET; | |
271 | } | |
272 | ||
273 | /* If either configuration changes, we update both anyway */ | |
274 | if (l1 != l1_cache || l2 != l2_cache) { | |
275 | writel(l1, &ipctl->lev1->conf[pin]); | |
276 | writel(l2, &ipctl->lev2->conf[pin]); | |
277 | } | |
278 | ||
279 | return 0; | |
280 | } | |
281 | ||
282 | static const struct rzn1_pin_group *rzn1_pinctrl_find_group_by_name( | |
283 | const struct rzn1_pinctrl *ipctl, const char *name) | |
284 | { | |
285 | unsigned int i; | |
286 | ||
287 | for (i = 0; i < ipctl->ngroups; i++) { | |
288 | if (!strcmp(ipctl->groups[i].name, name)) | |
289 | return &ipctl->groups[i]; | |
290 | } | |
291 | ||
292 | return NULL; | |
293 | } | |
294 | ||
295 | static int rzn1_get_groups_count(struct pinctrl_dev *pctldev) | |
296 | { | |
297 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
298 | ||
299 | return ipctl->ngroups; | |
300 | } | |
301 | ||
302 | static const char *rzn1_get_group_name(struct pinctrl_dev *pctldev, | |
303 | unsigned int selector) | |
304 | { | |
305 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
306 | ||
307 | return ipctl->groups[selector].name; | |
308 | } | |
309 | ||
310 | static int rzn1_get_group_pins(struct pinctrl_dev *pctldev, | |
311 | unsigned int selector, const unsigned int **pins, | |
312 | unsigned int *npins) | |
313 | { | |
314 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
315 | ||
316 | if (selector >= ipctl->ngroups) | |
317 | return -EINVAL; | |
318 | ||
319 | *pins = ipctl->groups[selector].pins; | |
320 | *npins = ipctl->groups[selector].npins; | |
321 | ||
322 | return 0; | |
323 | } | |
324 | ||
325 | /* | |
326 | * This function is called for each pinctl 'Function' node. | |
327 | * Sub-nodes can be used to describe multiple 'Groups' for the 'Function' | |
328 | * If there aren't any sub-nodes, the 'Group' is essentially the 'Function'. | |
329 | * Each 'Group' uses pinmux = <...> to detail the pins and data used to select | |
330 | * the functionality. Each 'Group' has optional pin configurations that apply | |
331 | * to all pins in the 'Group'. | |
332 | */ | |
333 | static int rzn1_dt_node_to_map_one(struct pinctrl_dev *pctldev, | |
334 | struct device_node *np, | |
335 | struct pinctrl_map **map, | |
336 | unsigned int *num_maps) | |
337 | { | |
338 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
339 | const struct rzn1_pin_group *grp; | |
340 | unsigned long *configs = NULL; | |
341 | unsigned int reserved_maps = *num_maps; | |
342 | unsigned int num_configs = 0; | |
343 | unsigned int reserve = 1; | |
344 | int ret; | |
345 | ||
346 | dev_dbg(ipctl->dev, "processing node %pOF\n", np); | |
347 | ||
348 | grp = rzn1_pinctrl_find_group_by_name(ipctl, np->name); | |
349 | if (!grp) { | |
350 | dev_err(ipctl->dev, "unable to find group for node %pOF\n", np); | |
351 | ||
352 | return -EINVAL; | |
353 | } | |
354 | ||
355 | /* Get the group's pin configuration */ | |
356 | ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, | |
357 | &num_configs); | |
358 | if (ret < 0) { | |
359 | dev_err(ipctl->dev, "%pOF: could not parse property\n", np); | |
360 | ||
361 | return ret; | |
362 | } | |
363 | ||
364 | if (num_configs) | |
365 | reserve++; | |
366 | ||
367 | /* Increase the number of maps to cover this group */ | |
368 | ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, num_maps, | |
369 | reserve); | |
370 | if (ret < 0) | |
371 | goto out; | |
372 | ||
373 | /* Associate the group with the function */ | |
374 | ret = pinctrl_utils_add_map_mux(pctldev, map, &reserved_maps, num_maps, | |
375 | grp->name, grp->func); | |
376 | if (ret < 0) | |
377 | goto out; | |
378 | ||
379 | if (num_configs) { | |
380 | /* Associate the group's pin configuration with the group */ | |
381 | ret = pinctrl_utils_add_map_configs(pctldev, map, | |
382 | &reserved_maps, num_maps, grp->name, | |
383 | configs, num_configs, | |
384 | PIN_MAP_TYPE_CONFIGS_GROUP); | |
385 | if (ret < 0) | |
386 | goto out; | |
387 | } | |
388 | ||
389 | dev_dbg(pctldev->dev, "maps: function %s group %s (%d pins)\n", | |
390 | grp->func, grp->name, grp->npins); | |
391 | ||
392 | out: | |
393 | kfree(configs); | |
394 | ||
395 | return ret; | |
396 | } | |
397 | ||
398 | static int rzn1_dt_node_to_map(struct pinctrl_dev *pctldev, | |
399 | struct device_node *np, | |
400 | struct pinctrl_map **map, | |
401 | unsigned int *num_maps) | |
402 | { | |
403 | struct device_node *child; | |
404 | int ret; | |
405 | ||
406 | *map = NULL; | |
407 | *num_maps = 0; | |
408 | ||
409 | ret = rzn1_dt_node_to_map_one(pctldev, np, map, num_maps); | |
410 | if (ret < 0) | |
411 | return ret; | |
412 | ||
413 | for_each_child_of_node(np, child) { | |
414 | ret = rzn1_dt_node_to_map_one(pctldev, child, map, num_maps); | |
415 | if (ret < 0) | |
416 | return ret; | |
417 | } | |
418 | ||
419 | return 0; | |
420 | } | |
421 | ||
422 | static const struct pinctrl_ops rzn1_pctrl_ops = { | |
423 | .get_groups_count = rzn1_get_groups_count, | |
424 | .get_group_name = rzn1_get_group_name, | |
425 | .get_group_pins = rzn1_get_group_pins, | |
426 | .dt_node_to_map = rzn1_dt_node_to_map, | |
427 | .dt_free_map = pinctrl_utils_free_map, | |
428 | }; | |
429 | ||
430 | static int rzn1_pmx_get_funcs_count(struct pinctrl_dev *pctldev) | |
431 | { | |
432 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
433 | ||
434 | return ipctl->nfunctions; | |
435 | } | |
436 | ||
437 | static const char *rzn1_pmx_get_func_name(struct pinctrl_dev *pctldev, | |
438 | unsigned int selector) | |
439 | { | |
440 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
441 | ||
442 | return ipctl->functions[selector].name; | |
443 | } | |
444 | ||
445 | static int rzn1_pmx_get_groups(struct pinctrl_dev *pctldev, | |
446 | unsigned int selector, | |
447 | const char * const **groups, | |
448 | unsigned int * const num_groups) | |
449 | { | |
450 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
451 | ||
452 | *groups = ipctl->functions[selector].groups; | |
453 | *num_groups = ipctl->functions[selector].num_groups; | |
454 | ||
455 | return 0; | |
456 | } | |
457 | ||
458 | static int rzn1_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, | |
459 | unsigned int group) | |
460 | { | |
461 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
462 | struct rzn1_pin_group *grp = &ipctl->groups[group]; | |
463 | unsigned int i, grp_pins = grp->npins; | |
464 | ||
465 | dev_dbg(ipctl->dev, "set mux %s(%d) group %s(%d)\n", | |
466 | ipctl->functions[selector].name, selector, grp->name, group); | |
467 | ||
468 | rzn1_hw_set_lock(ipctl, LOCK_ALL, LOCK_ALL); | |
469 | for (i = 0; i < grp_pins; i++) | |
470 | rzn1_set_hw_pin_func(ipctl, grp->pins[i], grp->pin_ids[i], 0); | |
471 | rzn1_hw_set_lock(ipctl, LOCK_ALL, 0); | |
472 | ||
473 | return 0; | |
474 | } | |
475 | ||
476 | static const struct pinmux_ops rzn1_pmx_ops = { | |
477 | .get_functions_count = rzn1_pmx_get_funcs_count, | |
478 | .get_function_name = rzn1_pmx_get_func_name, | |
479 | .get_function_groups = rzn1_pmx_get_groups, | |
480 | .set_mux = rzn1_set_mux, | |
481 | }; | |
482 | ||
483 | static int rzn1_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, | |
484 | unsigned long *config) | |
485 | { | |
486 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
487 | enum pin_config_param param = pinconf_to_config_param(*config); | |
488 | const u32 reg_drive[4] = { 4, 6, 8, 12 }; | |
489 | u32 pull, drive, l1mux; | |
490 | u32 l1, l2, arg = 0; | |
491 | ||
492 | if (pin >= ARRAY_SIZE(ipctl->lev1->conf)) | |
493 | return -EINVAL; | |
494 | ||
495 | l1 = readl(&ipctl->lev1->conf[pin]); | |
496 | ||
497 | l1mux = l1 & RZN1_L1_FUNC_MASK; | |
498 | pull = (l1 >> RZN1_L1_PIN_PULL) & 0x3; | |
499 | drive = (l1 >> RZN1_L1_PIN_DRIVE_STRENGTH) & 0x3; | |
500 | ||
501 | switch (param) { | |
502 | case PIN_CONFIG_BIAS_PULL_UP: | |
503 | if (pull != RZN1_L1_PIN_PULL_UP) | |
504 | return -EINVAL; | |
505 | break; | |
506 | case PIN_CONFIG_BIAS_PULL_DOWN: | |
507 | if (pull != RZN1_L1_PIN_PULL_DOWN) | |
508 | return -EINVAL; | |
509 | break; | |
510 | case PIN_CONFIG_BIAS_DISABLE: | |
511 | if (pull != RZN1_L1_PIN_PULL_NONE) | |
512 | return -EINVAL; | |
513 | break; | |
514 | case PIN_CONFIG_DRIVE_STRENGTH: | |
515 | arg = reg_drive[drive]; | |
516 | break; | |
517 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | |
518 | l2 = readl(&ipctl->lev2->conf[pin]); | |
519 | if (l1mux == RZN1_L1_FUNCTION_L2) { | |
520 | if (l2 != 0) | |
521 | return -EINVAL; | |
522 | } else if (l1mux != RZN1_FUNC_HIGHZ) { | |
523 | return -EINVAL; | |
524 | } | |
525 | break; | |
526 | default: | |
527 | return -ENOTSUPP; | |
528 | } | |
529 | ||
530 | *config = pinconf_to_config_packed(param, arg); | |
531 | ||
532 | return 0; | |
533 | } | |
534 | ||
535 | static int rzn1_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |
536 | unsigned long *configs, unsigned int num_configs) | |
537 | { | |
538 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
539 | enum pin_config_param param; | |
540 | unsigned int i; | |
541 | u32 l1, l1_cache; | |
542 | u32 drv; | |
543 | u32 arg; | |
544 | ||
545 | if (pin >= ARRAY_SIZE(ipctl->lev1->conf)) | |
546 | return -EINVAL; | |
547 | ||
548 | l1 = readl(&ipctl->lev1->conf[pin]); | |
549 | l1_cache = l1; | |
550 | ||
551 | for (i = 0; i < num_configs; i++) { | |
552 | param = pinconf_to_config_param(configs[i]); | |
553 | arg = pinconf_to_config_argument(configs[i]); | |
554 | ||
555 | switch (param) { | |
556 | case PIN_CONFIG_BIAS_PULL_UP: | |
557 | dev_dbg(ipctl->dev, "set pin %d pull up\n", pin); | |
558 | l1 &= ~(0x3 << RZN1_L1_PIN_PULL); | |
559 | l1 |= (RZN1_L1_PIN_PULL_UP << RZN1_L1_PIN_PULL); | |
560 | break; | |
561 | case PIN_CONFIG_BIAS_PULL_DOWN: | |
562 | dev_dbg(ipctl->dev, "set pin %d pull down\n", pin); | |
563 | l1 &= ~(0x3 << RZN1_L1_PIN_PULL); | |
564 | l1 |= (RZN1_L1_PIN_PULL_DOWN << RZN1_L1_PIN_PULL); | |
565 | break; | |
566 | case PIN_CONFIG_BIAS_DISABLE: | |
567 | dev_dbg(ipctl->dev, "set pin %d bias off\n", pin); | |
568 | l1 &= ~(0x3 << RZN1_L1_PIN_PULL); | |
569 | l1 |= (RZN1_L1_PIN_PULL_NONE << RZN1_L1_PIN_PULL); | |
570 | break; | |
571 | case PIN_CONFIG_DRIVE_STRENGTH: | |
572 | dev_dbg(ipctl->dev, "set pin %d drv %umA\n", pin, arg); | |
573 | switch (arg) { | |
574 | case 4: | |
575 | drv = RZN1_L1_PIN_DRIVE_STRENGTH_4MA; | |
576 | break; | |
577 | case 6: | |
578 | drv = RZN1_L1_PIN_DRIVE_STRENGTH_6MA; | |
579 | break; | |
580 | case 8: | |
581 | drv = RZN1_L1_PIN_DRIVE_STRENGTH_8MA; | |
582 | break; | |
583 | case 12: | |
584 | drv = RZN1_L1_PIN_DRIVE_STRENGTH_12MA; | |
585 | break; | |
586 | default: | |
587 | dev_err(ipctl->dev, | |
588 | "Drive strength %umA not supported\n", | |
589 | arg); | |
590 | ||
591 | return -EINVAL; | |
592 | } | |
593 | ||
594 | l1 &= ~(0x3 << RZN1_L1_PIN_DRIVE_STRENGTH); | |
595 | l1 |= (drv << RZN1_L1_PIN_DRIVE_STRENGTH); | |
596 | break; | |
597 | ||
598 | case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: | |
599 | dev_dbg(ipctl->dev, "set pin %d High-Z\n", pin); | |
600 | l1 &= ~RZN1_L1_FUNC_MASK; | |
601 | l1 |= RZN1_FUNC_HIGHZ; | |
602 | break; | |
603 | default: | |
604 | return -ENOTSUPP; | |
605 | } | |
606 | } | |
607 | ||
608 | if (l1 != l1_cache) { | |
609 | rzn1_hw_set_lock(ipctl, LOCK_LEVEL1, LOCK_LEVEL1); | |
610 | writel(l1, &ipctl->lev1->conf[pin]); | |
611 | rzn1_hw_set_lock(ipctl, LOCK_LEVEL1, 0); | |
612 | } | |
613 | ||
614 | return 0; | |
615 | } | |
616 | ||
617 | static int rzn1_pinconf_group_get(struct pinctrl_dev *pctldev, | |
618 | unsigned int selector, | |
619 | unsigned long *config) | |
620 | { | |
621 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
622 | struct rzn1_pin_group *grp = &ipctl->groups[selector]; | |
623 | unsigned long old = 0; | |
624 | unsigned int i; | |
625 | ||
626 | dev_dbg(ipctl->dev, "group get %s selector:%u\n", grp->name, selector); | |
627 | ||
628 | for (i = 0; i < grp->npins; i++) { | |
629 | if (rzn1_pinconf_get(pctldev, grp->pins[i], config)) | |
630 | return -ENOTSUPP; | |
631 | ||
632 | /* configs do not match between two pins */ | |
633 | if (i && (old != *config)) | |
634 | return -ENOTSUPP; | |
635 | ||
636 | old = *config; | |
637 | } | |
638 | ||
639 | return 0; | |
640 | } | |
641 | ||
642 | static int rzn1_pinconf_group_set(struct pinctrl_dev *pctldev, | |
643 | unsigned int selector, | |
644 | unsigned long *configs, | |
645 | unsigned int num_configs) | |
646 | { | |
647 | struct rzn1_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); | |
648 | struct rzn1_pin_group *grp = &ipctl->groups[selector]; | |
649 | unsigned int i; | |
650 | int ret; | |
651 | ||
652 | dev_dbg(ipctl->dev, "group set %s selector:%u configs:%p/%d\n", | |
653 | grp->name, selector, configs, num_configs); | |
654 | ||
655 | for (i = 0; i < grp->npins; i++) { | |
656 | unsigned int pin = grp->pins[i]; | |
657 | ||
658 | ret = rzn1_pinconf_set(pctldev, pin, configs, num_configs); | |
659 | if (ret) | |
660 | return ret; | |
661 | } | |
662 | ||
663 | return 0; | |
664 | } | |
665 | ||
666 | static const struct pinconf_ops rzn1_pinconf_ops = { | |
667 | .is_generic = true, | |
668 | .pin_config_get = rzn1_pinconf_get, | |
669 | .pin_config_set = rzn1_pinconf_set, | |
670 | .pin_config_group_get = rzn1_pinconf_group_get, | |
671 | .pin_config_group_set = rzn1_pinconf_group_set, | |
672 | .pin_config_config_dbg_show = pinconf_generic_dump_config, | |
673 | }; | |
674 | ||
675 | static struct pinctrl_desc rzn1_pinctrl_desc = { | |
676 | .pctlops = &rzn1_pctrl_ops, | |
677 | .pmxops = &rzn1_pmx_ops, | |
678 | .confops = &rzn1_pinconf_ops, | |
679 | .owner = THIS_MODULE, | |
680 | }; | |
681 | ||
682 | static int rzn1_pinctrl_parse_groups(struct device_node *np, | |
683 | struct rzn1_pin_group *grp, | |
684 | struct rzn1_pinctrl *ipctl) | |
685 | { | |
686 | const __be32 *list; | |
687 | unsigned int i; | |
688 | int size; | |
689 | ||
690 | dev_dbg(ipctl->dev, "%s: %s\n", __func__, np->name); | |
691 | ||
692 | /* Initialise group */ | |
693 | grp->name = np->name; | |
694 | ||
695 | /* | |
696 | * The binding format is | |
697 | * pinmux = <PIN_FUNC_ID CONFIG ...>, | |
698 | * do sanity check and calculate pins number | |
699 | */ | |
700 | list = of_get_property(np, RZN1_PINS_PROP, &size); | |
701 | if (!list) { | |
702 | dev_err(ipctl->dev, | |
703 | "no " RZN1_PINS_PROP " property in node %pOF\n", np); | |
704 | ||
705 | return -EINVAL; | |
706 | } | |
707 | ||
708 | if (!size) { | |
709 | dev_err(ipctl->dev, "Invalid " RZN1_PINS_PROP " in node %pOF\n", | |
710 | np); | |
711 | ||
712 | return -EINVAL; | |
713 | } | |
714 | ||
715 | grp->npins = size / sizeof(list[0]); | |
716 | grp->pin_ids = devm_kmalloc_array(ipctl->dev, | |
717 | grp->npins, sizeof(grp->pin_ids[0]), | |
718 | GFP_KERNEL); | |
719 | grp->pins = devm_kmalloc_array(ipctl->dev, | |
720 | grp->npins, sizeof(grp->pins[0]), | |
721 | GFP_KERNEL); | |
722 | if (!grp->pin_ids || !grp->pins) | |
723 | return -ENOMEM; | |
724 | ||
725 | for (i = 0; i < grp->npins; i++) { | |
726 | u32 pin_id = be32_to_cpu(*list++); | |
727 | ||
728 | grp->pins[i] = pin_id & 0xff; | |
729 | grp->pin_ids[i] = (pin_id >> 8) & 0x7f; | |
730 | } | |
731 | ||
732 | return grp->npins; | |
733 | } | |
734 | ||
735 | static int rzn1_pinctrl_count_function_groups(struct device_node *np) | |
736 | { | |
737 | struct device_node *child; | |
738 | int count = 0; | |
739 | ||
740 | if (of_property_count_u32_elems(np, RZN1_PINS_PROP) > 0) | |
741 | count++; | |
742 | ||
743 | for_each_child_of_node(np, child) { | |
744 | if (of_property_count_u32_elems(child, RZN1_PINS_PROP) > 0) | |
745 | count++; | |
746 | } | |
747 | ||
748 | return count; | |
749 | } | |
750 | ||
751 | static int rzn1_pinctrl_parse_functions(struct device_node *np, | |
752 | struct rzn1_pinctrl *ipctl, | |
753 | unsigned int index) | |
754 | { | |
755 | struct rzn1_pmx_func *func; | |
756 | struct rzn1_pin_group *grp; | |
757 | struct device_node *child; | |
758 | unsigned int i = 0; | |
759 | int ret; | |
760 | ||
761 | func = &ipctl->functions[index]; | |
762 | ||
763 | /* Initialise function */ | |
764 | func->name = np->name; | |
765 | func->num_groups = rzn1_pinctrl_count_function_groups(np); | |
766 | if (func->num_groups == 0) { | |
767 | dev_err(ipctl->dev, "no groups defined in %pOF\n", np); | |
768 | return -EINVAL; | |
769 | } | |
770 | dev_dbg(ipctl->dev, "function %s has %d groups\n", | |
771 | np->name, func->num_groups); | |
772 | ||
773 | func->groups = devm_kmalloc_array(ipctl->dev, | |
774 | func->num_groups, sizeof(char *), | |
775 | GFP_KERNEL); | |
776 | if (!func->groups) | |
777 | return -ENOMEM; | |
778 | ||
779 | if (of_property_count_u32_elems(np, RZN1_PINS_PROP) > 0) { | |
780 | func->groups[i] = np->name; | |
781 | grp = &ipctl->groups[ipctl->ngroups]; | |
782 | grp->func = func->name; | |
783 | ret = rzn1_pinctrl_parse_groups(np, grp, ipctl); | |
784 | if (ret < 0) | |
785 | return ret; | |
786 | i++; | |
787 | ipctl->ngroups++; | |
788 | } | |
789 | ||
790 | for_each_child_of_node(np, child) { | |
791 | func->groups[i] = child->name; | |
792 | grp = &ipctl->groups[ipctl->ngroups]; | |
793 | grp->func = func->name; | |
794 | ret = rzn1_pinctrl_parse_groups(child, grp, ipctl); | |
795 | if (ret < 0) | |
796 | return ret; | |
797 | i++; | |
798 | ipctl->ngroups++; | |
799 | } | |
800 | ||
801 | dev_dbg(ipctl->dev, "function %s parsed %u/%u groups\n", | |
802 | np->name, i, func->num_groups); | |
803 | ||
804 | return 0; | |
805 | } | |
806 | ||
807 | static int rzn1_pinctrl_probe_dt(struct platform_device *pdev, | |
808 | struct rzn1_pinctrl *ipctl) | |
809 | { | |
810 | struct device_node *np = pdev->dev.of_node; | |
811 | struct device_node *child; | |
812 | unsigned int maxgroups = 0; | |
4e53b500 | 813 | unsigned int i = 0; |
3f3327db | 814 | int nfuncs = 0; |
4e53b500 PE |
815 | int ret; |
816 | ||
817 | nfuncs = of_get_child_count(np); | |
818 | if (nfuncs <= 0) | |
819 | return 0; | |
820 | ||
821 | ipctl->nfunctions = nfuncs; | |
822 | ipctl->functions = devm_kmalloc_array(&pdev->dev, nfuncs, | |
823 | sizeof(*ipctl->functions), | |
824 | GFP_KERNEL); | |
825 | if (!ipctl->functions) | |
826 | return -ENOMEM; | |
827 | ||
828 | ipctl->ngroups = 0; | |
829 | for_each_child_of_node(np, child) | |
830 | maxgroups += rzn1_pinctrl_count_function_groups(child); | |
831 | ||
832 | ipctl->groups = devm_kmalloc_array(&pdev->dev, | |
833 | maxgroups, | |
834 | sizeof(*ipctl->groups), | |
835 | GFP_KERNEL); | |
836 | if (!ipctl->groups) | |
837 | return -ENOMEM; | |
838 | ||
839 | for_each_child_of_node(np, child) { | |
840 | ret = rzn1_pinctrl_parse_functions(child, ipctl, i++); | |
841 | if (ret < 0) | |
842 | return ret; | |
843 | } | |
844 | ||
845 | return 0; | |
846 | } | |
847 | ||
848 | static int rzn1_pinctrl_probe(struct platform_device *pdev) | |
849 | { | |
850 | struct rzn1_pinctrl *ipctl; | |
851 | struct resource *res; | |
852 | int ret; | |
853 | ||
854 | /* Create state holders etc for this driver */ | |
855 | ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL); | |
856 | if (!ipctl) | |
857 | return -ENOMEM; | |
858 | ||
859 | ipctl->mdio_func[0] = -1; | |
860 | ipctl->mdio_func[1] = -1; | |
861 | ||
862 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
863 | ipctl->lev1_protect_phys = (u32)res->start + 0x400; | |
864 | ipctl->lev1 = devm_ioremap_resource(&pdev->dev, res); | |
865 | if (IS_ERR(ipctl->lev1)) | |
866 | return PTR_ERR(ipctl->lev1); | |
867 | ||
868 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | |
869 | ipctl->lev2_protect_phys = (u32)res->start + 0x400; | |
870 | ipctl->lev2 = devm_ioremap_resource(&pdev->dev, res); | |
871 | if (IS_ERR(ipctl->lev2)) | |
872 | return PTR_ERR(ipctl->lev2); | |
873 | ||
874 | ipctl->clk = devm_clk_get(&pdev->dev, NULL); | |
875 | if (IS_ERR(ipctl->clk)) | |
876 | return PTR_ERR(ipctl->clk); | |
877 | ret = clk_prepare_enable(ipctl->clk); | |
878 | if (ret) | |
879 | return ret; | |
880 | ||
881 | ipctl->dev = &pdev->dev; | |
882 | rzn1_pinctrl_desc.name = dev_name(&pdev->dev); | |
883 | rzn1_pinctrl_desc.pins = rzn1_pins; | |
884 | rzn1_pinctrl_desc.npins = ARRAY_SIZE(rzn1_pins); | |
885 | ||
886 | ret = rzn1_pinctrl_probe_dt(pdev, ipctl); | |
887 | if (ret) { | |
888 | dev_err(&pdev->dev, "fail to probe dt properties\n"); | |
889 | goto err_clk; | |
890 | } | |
891 | ||
892 | platform_set_drvdata(pdev, ipctl); | |
893 | ||
894 | ret = devm_pinctrl_register_and_init(&pdev->dev, &rzn1_pinctrl_desc, | |
895 | ipctl, &ipctl->pctl); | |
896 | if (ret) { | |
897 | dev_err(&pdev->dev, "could not register rzn1 pinctrl driver\n"); | |
898 | goto err_clk; | |
899 | } | |
900 | ||
901 | ret = pinctrl_enable(ipctl->pctl); | |
902 | if (ret) | |
903 | goto err_clk; | |
904 | ||
905 | dev_info(&pdev->dev, "probed\n"); | |
906 | ||
907 | return 0; | |
908 | ||
909 | err_clk: | |
910 | clk_disable_unprepare(ipctl->clk); | |
911 | ||
912 | return ret; | |
913 | } | |
914 | ||
915 | static int rzn1_pinctrl_remove(struct platform_device *pdev) | |
916 | { | |
917 | struct rzn1_pinctrl *ipctl = platform_get_drvdata(pdev); | |
918 | ||
919 | clk_disable_unprepare(ipctl->clk); | |
920 | ||
921 | return 0; | |
922 | } | |
923 | ||
924 | static const struct of_device_id rzn1_pinctrl_match[] = { | |
925 | { .compatible = "renesas,rzn1-pinctrl", }, | |
926 | {} | |
927 | }; | |
928 | MODULE_DEVICE_TABLE(of, rzn1_pinctrl_match); | |
929 | ||
930 | static struct platform_driver rzn1_pinctrl_driver = { | |
931 | .probe = rzn1_pinctrl_probe, | |
932 | .remove = rzn1_pinctrl_remove, | |
933 | .driver = { | |
934 | .name = "rzn1-pinctrl", | |
4e53b500 PE |
935 | .of_match_table = rzn1_pinctrl_match, |
936 | }, | |
937 | }; | |
938 | ||
939 | static int __init _pinctrl_drv_register(void) | |
940 | { | |
941 | return platform_driver_register(&rzn1_pinctrl_driver); | |
942 | } | |
943 | subsys_initcall(_pinctrl_drv_register); | |
944 | ||
945 | MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>"); | |
946 | MODULE_DESCRIPTION("Renesas RZ/N1 pinctrl driver"); | |
947 | MODULE_LICENSE("GPL v2"); |