blob: d74efcd21208051d2e66aeab0b7ffb0c41a2bc93 [file] [log] [blame]
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
4 * Jean-Jacques Hiblot <jjhiblot@ti.com>
5 */
6
7#include <common.h>
8#include <clk-uclass.h>
9#include <dm.h>
10#include <dm/device_compat.h>
11#include <asm/gpio.h>
12#include <dm/lists.h>
13#include <dm/device-internal.h>
14#include <regmap.h>
15#include <reset-uclass.h>
16#include <dt-bindings/phy/phy.h>
17
18#include <dt-bindings/phy/phy-ti.h>
19
20#define WIZ_MAX_INPUT_CLOCKS 4
21/* To include mux clocks, divider clocks and gate clocks */
22#define WIZ_MAX_OUTPUT_CLOCKS 32
23
24#define WIZ_MAX_LANES 4
25#define WIZ_MUX_NUM_CLOCKS 3
26#define WIZ_DIV_NUM_CLOCKS_16G 2
27#define WIZ_DIV_NUM_CLOCKS_10G 1
28
29#define WIZ_SERDES_CTRL 0x404
30#define WIZ_SERDES_TOP_CTRL 0x408
31#define WIZ_SERDES_RST 0x40c
32#define WIZ_SERDES_TYPEC 0x410
33#define WIZ_LANECTL(n) (0x480 + (0x40 * (n)))
34#define WIZ_LANEDIV(n) (0x484 + (0x40 * (n)))
35
36#define WIZ_MAX_LANES 4
37#define WIZ_MUX_NUM_CLOCKS 3
38#define WIZ_DIV_NUM_CLOCKS_16G 2
39#define WIZ_DIV_NUM_CLOCKS_10G 1
40
41#define WIZ_SERDES_TYPEC_LN10_SWAP BIT(30)
42
43enum wiz_lane_standard_mode {
44 LANE_MODE_GEN1,
45 LANE_MODE_GEN2,
46 LANE_MODE_GEN3,
47 LANE_MODE_GEN4,
48};
49
50enum wiz_refclk_mux_sel {
51 PLL0_REFCLK,
52 PLL1_REFCLK,
53 REFCLK_DIG,
54};
55
56enum wiz_refclk_div_sel {
57 CMN_REFCLK,
58 CMN_REFCLK1,
59};
60
61enum wiz_clock_input {
62 WIZ_CORE_REFCLK,
63 WIZ_EXT_REFCLK,
64 WIZ_CORE_REFCLK1,
65 WIZ_EXT_REFCLK1,
66};
67
68static const struct reg_field por_en = REG_FIELD(WIZ_SERDES_CTRL, 31, 31);
69static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31);
70static const struct reg_field pll1_refclk_mux_sel =
71 REG_FIELD(WIZ_SERDES_RST, 29, 29);
72static const struct reg_field pll0_refclk_mux_sel =
73 REG_FIELD(WIZ_SERDES_RST, 28, 28);
74static const struct reg_field refclk_dig_sel_16g =
75 REG_FIELD(WIZ_SERDES_RST, 24, 25);
76static const struct reg_field refclk_dig_sel_10g =
77 REG_FIELD(WIZ_SERDES_RST, 24, 24);
78static const struct reg_field pma_cmn_refclk_int_mode =
79 REG_FIELD(WIZ_SERDES_TOP_CTRL, 28, 29);
80static const struct reg_field pma_cmn_refclk_mode =
81 REG_FIELD(WIZ_SERDES_TOP_CTRL, 30, 31);
82static const struct reg_field pma_cmn_refclk_dig_div =
83 REG_FIELD(WIZ_SERDES_TOP_CTRL, 26, 27);
84static const struct reg_field pma_cmn_refclk1_dig_div =
85 REG_FIELD(WIZ_SERDES_TOP_CTRL, 24, 25);
86
87static const struct reg_field p_enable[WIZ_MAX_LANES] = {
88 REG_FIELD(WIZ_LANECTL(0), 30, 31),
89 REG_FIELD(WIZ_LANECTL(1), 30, 31),
90 REG_FIELD(WIZ_LANECTL(2), 30, 31),
91 REG_FIELD(WIZ_LANECTL(3), 30, 31),
92};
93
94enum p_enable { P_ENABLE = 2, P_ENABLE_FORCE = 1, P_ENABLE_DISABLE = 0 };
95
96static const struct reg_field p_align[WIZ_MAX_LANES] = {
97 REG_FIELD(WIZ_LANECTL(0), 29, 29),
98 REG_FIELD(WIZ_LANECTL(1), 29, 29),
99 REG_FIELD(WIZ_LANECTL(2), 29, 29),
100 REG_FIELD(WIZ_LANECTL(3), 29, 29),
101};
102
103static const struct reg_field p_raw_auto_start[WIZ_MAX_LANES] = {
104 REG_FIELD(WIZ_LANECTL(0), 28, 28),
105 REG_FIELD(WIZ_LANECTL(1), 28, 28),
106 REG_FIELD(WIZ_LANECTL(2), 28, 28),
107 REG_FIELD(WIZ_LANECTL(3), 28, 28),
108};
109
110static const struct reg_field p_standard_mode[WIZ_MAX_LANES] = {
111 REG_FIELD(WIZ_LANECTL(0), 24, 25),
112 REG_FIELD(WIZ_LANECTL(1), 24, 25),
113 REG_FIELD(WIZ_LANECTL(2), 24, 25),
114 REG_FIELD(WIZ_LANECTL(3), 24, 25),
115};
116
117static const struct reg_field p0_fullrt_div[WIZ_MAX_LANES] = {
118 REG_FIELD(WIZ_LANECTL(0), 22, 23),
119 REG_FIELD(WIZ_LANECTL(1), 22, 23),
120 REG_FIELD(WIZ_LANECTL(2), 22, 23),
121 REG_FIELD(WIZ_LANECTL(3), 22, 23),
122};
123
124static const struct reg_field p_mac_div_sel0[WIZ_MAX_LANES] = {
125 REG_FIELD(WIZ_LANEDIV(0), 16, 22),
126 REG_FIELD(WIZ_LANEDIV(1), 16, 22),
127 REG_FIELD(WIZ_LANEDIV(2), 16, 22),
128 REG_FIELD(WIZ_LANEDIV(3), 16, 22),
129};
130
131static const struct reg_field p_mac_div_sel1[WIZ_MAX_LANES] = {
132 REG_FIELD(WIZ_LANEDIV(0), 0, 8),
133 REG_FIELD(WIZ_LANEDIV(1), 0, 8),
134 REG_FIELD(WIZ_LANEDIV(2), 0, 8),
135 REG_FIELD(WIZ_LANEDIV(3), 0, 8),
136};
137
138struct wiz_clk_mux_sel {
139 enum wiz_refclk_mux_sel mux_sel;
140 u32 table[WIZ_MAX_INPUT_CLOCKS];
141 const char *node_name;
142 u32 num_parents;
143 u32 parents[WIZ_MAX_INPUT_CLOCKS];
144};
145
146struct wiz_clk_div_sel {
147 enum wiz_refclk_div_sel div_sel;
148 const char *node_name;
149};
150
151static struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
152 {
153 /*
154 * Mux value to be configured for each of the input clocks
155 * in the order populated in device tree
156 */
157 .num_parents = 2,
158 .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
159 .mux_sel = PLL0_REFCLK,
160 .table = { 1, 0 },
161 .node_name = "pll0-refclk",
162 },
163 {
164 .num_parents = 2,
165 .parents = { WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK1 },
166 .mux_sel = PLL1_REFCLK,
167 .table = { 1, 0 },
168 .node_name = "pll1-refclk",
169 },
170 {
171 .num_parents = 4,
172 .parents = { WIZ_CORE_REFCLK, WIZ_CORE_REFCLK1, WIZ_EXT_REFCLK, WIZ_EXT_REFCLK1 },
173 .mux_sel = REFCLK_DIG,
174 .table = { 1, 3, 0, 2 },
175 .node_name = "refclk-dig",
176 },
177};
178
179static struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
180 {
181 /*
182 * Mux value to be configured for each of the input clocks
183 * in the order populated in device tree
184 */
185 .num_parents = 2,
186 .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
187 .mux_sel = PLL0_REFCLK,
188 .table = { 1, 0 },
189 .node_name = "pll0-refclk",
190 },
191 {
192 .num_parents = 2,
193 .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
194 .mux_sel = PLL1_REFCLK,
195 .table = { 1, 0 },
196 .node_name = "pll1-refclk",
197 },
198 {
199 .num_parents = 2,
200 .parents = { WIZ_CORE_REFCLK, WIZ_EXT_REFCLK },
201 .mux_sel = REFCLK_DIG,
202 .table = { 1, 0 },
203 .node_name = "refclk-dig",
204 },
205};
206
207static struct wiz_clk_div_sel clk_div_sel[] = {
208 {
209 .div_sel = CMN_REFCLK,
210 .node_name = "cmn-refclk-dig-div",
211 },
212 {
213 .div_sel = CMN_REFCLK1,
214 .node_name = "cmn-refclk1-dig-div",
215 },
216};
217
218enum wiz_type {
219 J721E_WIZ_16G,
220 J721E_WIZ_10G,
221 AM64_WIZ_10G,
222};
223
224#define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */
225#define WIZ_TYPEC_DIR_DEBOUNCE_MAX 1000
226
227struct wiz {
228 struct regmap *regmap;
229 enum wiz_type type;
230 struct wiz_clk_mux_sel *clk_mux_sel;
231 struct wiz_clk_div_sel *clk_div_sel;
232 unsigned int clk_div_sel_num;
233 struct regmap_field *por_en;
234 struct regmap_field *phy_reset_n;
235 struct regmap_field *phy_en_refclk;
236 struct regmap_field *p_enable[WIZ_MAX_LANES];
237 struct regmap_field *p_align[WIZ_MAX_LANES];
238 struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
239 struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
240 struct regmap_field *p_mac_div_sel0[WIZ_MAX_LANES];
241 struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES];
242 struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES];
243 struct regmap_field *pma_cmn_refclk_int_mode;
244 struct regmap_field *pma_cmn_refclk_mode;
245 struct regmap_field *pma_cmn_refclk_dig_div;
246 struct regmap_field *pma_cmn_refclk1_dig_div;
247 struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G];
248 struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS];
249
250 struct udevice *dev;
251 u32 num_lanes;
252 struct gpio_desc *gpio_typec_dir;
253 u32 lane_phy_type[WIZ_MAX_LANES];
254 struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS];
255 unsigned int id;
256};
257
258struct wiz_div_clk {
259 struct clk parent_clk;
260 struct wiz *wiz;
261};
262
263struct wiz_mux_clk {
264 struct clk parent_clks[4];
265 struct wiz *wiz;
266};
267
268struct wiz_clk {
269 struct wiz *wiz;
270};
271
272struct wiz_reset {
273 struct wiz *wiz;
274};
275
276static ulong wiz_div_clk_get_rate(struct clk *clk)
277{
278 struct udevice *dev = clk->dev;
279 struct wiz_div_clk *priv = dev_get_priv(dev);
280 struct wiz_clk_div_sel *data = dev_get_plat(dev);
281 struct wiz *wiz = priv->wiz;
282 ulong parent_rate = clk_get_rate(&priv->parent_clk);
283 u32 val;
284
285 regmap_field_read(wiz->div_sel_field[data->div_sel], &val);
286
287 return parent_rate >> val;
288}
289
290static ulong wiz_div_clk_set_rate(struct clk *clk, ulong rate)
291{
292 struct udevice *dev = clk->dev;
293 struct wiz_div_clk *priv = dev_get_priv(dev);
294 struct wiz_clk_div_sel *data = dev_get_plat(dev);
295 struct wiz *wiz = priv->wiz;
296 ulong parent_rate = clk_get_rate(&priv->parent_clk);
297 u32 div = parent_rate / rate;
298
299 div = __ffs(div);
300 regmap_field_write(wiz->div_sel_field[data->div_sel], div);
301
302 return parent_rate >> div;
303}
304
305const struct clk_ops wiz_div_clk_ops = {
306 .get_rate = wiz_div_clk_get_rate,
307 .set_rate = wiz_div_clk_set_rate,
308};
309
310int wiz_div_clk_probe(struct udevice *dev)
311{
312 struct wiz_div_clk *priv = dev_get_priv(dev);
313 struct clk parent_clk;
314 int rc;
315
316 rc = clk_get_by_index(dev, 0, &parent_clk);
317 if (rc) {
318 dev_err(dev, "unable to get parent clock. ret %d\n", rc);
319 return rc;
320 }
321 priv->parent_clk = parent_clk;
322 priv->wiz = dev_get_priv(dev->parent);
323 return 0;
324}
325
326U_BOOT_DRIVER(wiz_div_clk) = {
327 .name = "wiz_div_clk",
328 .id = UCLASS_CLK,
329 .priv_auto = sizeof(struct wiz_div_clk),
330 .ops = &wiz_div_clk_ops,
331 .probe = wiz_div_clk_probe,
332};
333
334static int wiz_clk_mux_set_parent(struct clk *clk, struct clk *parent)
335{
336 struct udevice *dev = clk->dev;
337 struct wiz_mux_clk *priv = dev_get_priv(dev);
338 struct wiz_clk_mux_sel *data = dev_get_plat(dev);
339 struct wiz *wiz = priv->wiz;
340 int i;
341
342 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++)
343 if (parent->dev == priv->parent_clks[i].dev)
344 break;
345
346 if (i == ARRAY_SIZE(priv->parent_clks))
347 return -EINVAL;
348
349 regmap_field_write(wiz->mux_sel_field[data->mux_sel], data->table[i]);
350 return 0;
351}
352
353static int wiz_clk_xlate(struct clk *clk, struct ofnode_phandle_args *args)
354{
355 struct udevice *dev = clk->dev;
356 struct wiz_mux_clk *priv = dev_get_priv(dev);
357 struct wiz *wiz = priv->wiz;
358
359 clk->id = wiz->id;
360
361 return 0;
362}
363
364static const struct clk_ops wiz_clk_mux_ops = {
365 .set_parent = wiz_clk_mux_set_parent,
366 .of_xlate = wiz_clk_xlate,
367};
368
369int wiz_mux_clk_probe(struct udevice *dev)
370{
371 struct wiz_mux_clk *priv = dev_get_priv(dev);
372 int rc;
373 int i;
374
375 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++) {
376 rc = clk_get_by_index(dev, i, &priv->parent_clks[i]);
377 if (rc)
378 priv->parent_clks[i].dev = NULL;
379 }
380 priv->wiz = dev_get_priv(dev->parent);
381 return 0;
382}
383
384U_BOOT_DRIVER(wiz_mux_clk) = {
385 .name = "wiz_mux_clk",
386 .id = UCLASS_CLK,
387 .priv_auto = sizeof(struct wiz_mux_clk),
388 .ops = &wiz_clk_mux_ops,
389 .probe = wiz_mux_clk_probe,
390};
391
392static int wiz_clk_set_parent(struct clk *clk, struct clk *parent)
393{
394 struct udevice *dev = clk->dev;
395 struct wiz_clk *priv = dev_get_priv(dev);
396 const struct wiz_clk_mux_sel *mux_sel;
397 struct wiz *wiz = priv->wiz;
398 int num_parents;
399 int i, j, id;
400
401 id = clk->id >> 10;
402
403 /* set_parent is applicable only for MUX clocks */
404 if (id > TI_WIZ_REFCLK_DIG)
405 return 0;
406
407 for (i = 0; i < WIZ_MAX_INPUT_CLOCKS; i++)
408 if (wiz->input_clks[i]->dev == parent->dev)
409 break;
410
411 if (i == WIZ_MAX_INPUT_CLOCKS)
412 return -EINVAL;
413
414 mux_sel = &wiz->clk_mux_sel[id];
415 num_parents = mux_sel->num_parents;
416 for (j = 0; j < num_parents; j++)
417 if (mux_sel->parents[j] == i)
418 break;
419
420 if (j == num_parents)
421 return -EINVAL;
422
423 regmap_field_write(wiz->mux_sel_field[id], mux_sel->table[j]);
424
425 return 0;
426}
427
428static int wiz_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
429{
430 struct udevice *dev = clk->dev;
431 struct wiz_clk *priv = dev_get_priv(dev);
432 struct wiz *wiz = priv->wiz;
433
434 clk->id = args->args[0] << 10 | wiz->id;
435
436 return 0;
437}
438
439static const struct clk_ops wiz_clk_ops = {
440 .set_parent = wiz_clk_set_parent,
441 .of_xlate = wiz_clk_of_xlate,
442};
443
444int wiz_clk_probe(struct udevice *dev)
445{
446 struct wiz_clk *priv = dev_get_priv(dev);
447
448 priv->wiz = dev_get_priv(dev->parent);
449
450 return 0;
451}
452
453U_BOOT_DRIVER(wiz_clk) = {
454 .name = "wiz_clk",
455 .id = UCLASS_CLK,
456 .priv_auto = sizeof(struct wiz_clk),
457 .ops = &wiz_clk_ops,
458 .probe = wiz_clk_probe,
459};
460
461static int wiz_reset_request(struct reset_ctl *reset_ctl)
462{
463 return 0;
464}
465
466static int wiz_reset_free(struct reset_ctl *reset_ctl)
467{
468 return 0;
469}
470
471static int wiz_reset_assert(struct reset_ctl *reset_ctl)
472{
473 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
474 struct wiz *wiz = priv->wiz;
475 int ret;
476 int id = reset_ctl->id;
477
478 if (id == 0) {
479 ret = regmap_field_write(wiz->phy_reset_n, false);
480 return ret;
481 }
482
483 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE);
484 return ret;
485}
486
487static int wiz_phy_fullrt_div(struct wiz *wiz, int lane)
488{
489 if (wiz->type != AM64_WIZ_10G)
490 return 0;
491
492 if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE)
493 return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1);
494
495 return 0;
496}
497
498static int wiz_reset_deassert(struct reset_ctl *reset_ctl)
499{
500 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
501 struct wiz *wiz = priv->wiz;
502 int ret;
503 int id = reset_ctl->id;
504
505 ret = wiz_phy_fullrt_div(wiz, id - 1);
506 if (ret)
507 return ret;
508
509 /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
510 if (id == 0 && wiz->gpio_typec_dir) {
511 if (dm_gpio_get_value(wiz->gpio_typec_dir)) {
512 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
513 WIZ_SERDES_TYPEC_LN10_SWAP,
514 WIZ_SERDES_TYPEC_LN10_SWAP);
515 } else {
516 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
517 WIZ_SERDES_TYPEC_LN10_SWAP, 0);
518 }
519 }
520
521 if (id == 0) {
522 ret = regmap_field_write(wiz->phy_reset_n, true);
523 return ret;
524 }
525
526 if (wiz->lane_phy_type[id - 1] == PHY_TYPE_PCIE)
527 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
528 else
529 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE);
530
531 return ret;
532}
533
534static struct reset_ops wiz_reset_ops = {
535 .request = wiz_reset_request,
536 .rfree = wiz_reset_free,
537 .rst_assert = wiz_reset_assert,
538 .rst_deassert = wiz_reset_deassert,
539};
540
541int wiz_reset_probe(struct udevice *dev)
542{
543 struct wiz_reset *priv = dev_get_priv(dev);
544
545 priv->wiz = dev_get_priv(dev->parent);
546
547 return 0;
548}
549
550U_BOOT_DRIVER(wiz_reset) = {
551 .name = "wiz-reset",
552 .id = UCLASS_RESET,
553 .probe = wiz_reset_probe,
554 .ops = &wiz_reset_ops,
555 .flags = DM_FLAG_LEAVE_PD_ON,
556};
557
558static int wiz_reset(struct wiz *wiz)
559{
560 int ret;
561
562 ret = regmap_field_write(wiz->por_en, 0x1);
563 if (ret)
564 return ret;
565
566 mdelay(1);
567
568 ret = regmap_field_write(wiz->por_en, 0x0);
569 if (ret)
570 return ret;
571
572 return 0;
573}
574
575static int wiz_p_mac_div_sel(struct wiz *wiz)
576{
577 u32 num_lanes = wiz->num_lanes;
578 int ret;
579 int i;
580
581 for (i = 0; i < num_lanes; i++) {
582 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
583 ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1);
584 if (ret)
585 return ret;
586
587 ret = regmap_field_write(wiz->p_mac_div_sel1[i], 2);
588 if (ret)
589 return ret;
590 }
591 }
592
593 return 0;
594}
595
596static int wiz_mode_select(struct wiz *wiz)
597{
598 u32 num_lanes = wiz->num_lanes;
599 int ret;
600 int i;
601
602 for (i = 0; i < num_lanes; i++) {
603 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
604 ret = regmap_field_write(wiz->p_standard_mode[i],
605 LANE_MODE_GEN2);
606 if (ret)
607 return ret;
608 }
609 }
610
611 return 0;
612}
613
614static int wiz_init_raw_interface(struct wiz *wiz, bool enable)
615{
616 u32 num_lanes = wiz->num_lanes;
617 int i;
618 int ret;
619
620 for (i = 0; i < num_lanes; i++) {
621 ret = regmap_field_write(wiz->p_align[i], enable);
622 if (ret)
623 return ret;
624
625 ret = regmap_field_write(wiz->p_raw_auto_start[i], enable);
626 if (ret)
627 return ret;
628 }
629
630 return 0;
631}
632
633static int wiz_init(struct wiz *wiz)
634{
635 struct udevice *dev = wiz->dev;
636 int ret;
637
638 ret = wiz_reset(wiz);
639 if (ret) {
640 dev_err(dev, "WIZ reset failed\n");
641 return ret;
642 }
643
644 ret = wiz_mode_select(wiz);
645 if (ret) {
646 dev_err(dev, "WIZ mode select failed\n");
647 return ret;
648 }
649
650 ret = wiz_p_mac_div_sel(wiz);
651 if (ret) {
652 dev_err(dev, "Configuring P0 MAC DIV SEL failed\n");
653 return ret;
654 }
655
656 ret = wiz_init_raw_interface(wiz, true);
657 if (ret) {
658 dev_err(dev, "WIZ interface initialization failed\n");
659 return ret;
660 }
661
662 return 0;
663}
664
665static int wiz_regfield_init(struct wiz *wiz)
666{
667 struct regmap *regmap = wiz->regmap;
668 int num_lanes = wiz->num_lanes;
669 struct udevice *dev = wiz->dev;
670 enum wiz_type type;
671 int i;
672
673 wiz->por_en = devm_regmap_field_alloc(dev, regmap, por_en);
674 if (IS_ERR(wiz->por_en)) {
675 dev_err(dev, "POR_EN reg field init failed\n");
676 return PTR_ERR(wiz->por_en);
677 }
678
679 wiz->phy_reset_n = devm_regmap_field_alloc(dev, regmap,
680 phy_reset_n);
681 if (IS_ERR(wiz->phy_reset_n)) {
682 dev_err(dev, "PHY_RESET_N reg field init failed\n");
683 return PTR_ERR(wiz->phy_reset_n);
684 }
685
686 wiz->pma_cmn_refclk_int_mode =
687 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_int_mode);
688 if (IS_ERR(wiz->pma_cmn_refclk_int_mode)) {
689 dev_err(dev, "PMA_CMN_REFCLK_INT_MODE reg field init failed\n");
690 return PTR_ERR(wiz->pma_cmn_refclk_int_mode);
691 }
692
693 wiz->pma_cmn_refclk_mode =
694 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode);
695 if (IS_ERR(wiz->pma_cmn_refclk_mode)) {
696 dev_err(dev, "PMA_CMN_REFCLK_MODE reg field init failed\n");
697 return PTR_ERR(wiz->pma_cmn_refclk_mode);
698 }
699
700 wiz->div_sel_field[CMN_REFCLK] =
701 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_dig_div);
702 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK])) {
703 dev_err(dev, "PMA_CMN_REFCLK_DIG_DIV reg field init failed\n");
704 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK]);
705 }
706
707 wiz->div_sel_field[CMN_REFCLK1] =
708 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk1_dig_div);
709 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK1])) {
710 dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
711 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK1]);
712 }
713
714 wiz->mux_sel_field[PLL0_REFCLK] =
715 devm_regmap_field_alloc(dev, regmap, pll0_refclk_mux_sel);
716 if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) {
717 dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n");
718 return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]);
719 }
720
721 wiz->mux_sel_field[PLL1_REFCLK] =
722 devm_regmap_field_alloc(dev, regmap, pll1_refclk_mux_sel);
723 if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) {
724 dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n");
725 return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]);
726 }
727
728 type = dev_get_driver_data(dev);
729 if (type == J721E_WIZ_10G || type == AM64_WIZ_10G)
730 wiz->mux_sel_field[REFCLK_DIG] =
731 devm_regmap_field_alloc(dev, regmap,
732 refclk_dig_sel_10g);
733 else
734 wiz->mux_sel_field[REFCLK_DIG] =
735 devm_regmap_field_alloc(dev, regmap,
736 refclk_dig_sel_16g);
737 if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) {
738 dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
739 return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]);
740 }
741
742 for (i = 0; i < num_lanes; i++) {
743 wiz->p_enable[i] = devm_regmap_field_alloc(dev, regmap,
744 p_enable[i]);
745 if (IS_ERR(wiz->p_enable[i])) {
746 dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
747 return PTR_ERR(wiz->p_enable[i]);
748 }
749
750 wiz->p_align[i] = devm_regmap_field_alloc(dev, regmap,
751 p_align[i]);
752 if (IS_ERR(wiz->p_align[i])) {
753 dev_err(dev, "P%d_ALIGN reg field init failed\n", i);
754 return PTR_ERR(wiz->p_align[i]);
755 }
756
757 wiz->p_raw_auto_start[i] =
758 devm_regmap_field_alloc(dev, regmap, p_raw_auto_start[i]);
759 if (IS_ERR(wiz->p_raw_auto_start[i])) {
760 dev_err(dev, "P%d_RAW_AUTO_START reg field init fail\n",
761 i);
762 return PTR_ERR(wiz->p_raw_auto_start[i]);
763 }
764
765 wiz->p_standard_mode[i] =
766 devm_regmap_field_alloc(dev, regmap, p_standard_mode[i]);
767 if (IS_ERR(wiz->p_standard_mode[i])) {
768 dev_err(dev, "P%d_STANDARD_MODE reg field init fail\n",
769 i);
770 return PTR_ERR(wiz->p_standard_mode[i]);
771 }
772
773 wiz->p0_fullrt_div[i] = devm_regmap_field_alloc(dev, regmap, p0_fullrt_div[i]);
774 if (IS_ERR(wiz->p0_fullrt_div[i])) {
775 dev_err(dev, "P%d_FULLRT_DIV reg field init failed\n", i);
776 return PTR_ERR(wiz->p0_fullrt_div[i]);
777 }
778
779 wiz->p_mac_div_sel0[i] =
780 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel0[i]);
781 if (IS_ERR(wiz->p_mac_div_sel0[i])) {
782 dev_err(dev, "P%d_MAC_DIV_SEL0 reg field init fail\n",
783 i);
784 return PTR_ERR(wiz->p_mac_div_sel0[i]);
785 }
786
787 wiz->p_mac_div_sel1[i] =
788 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel1[i]);
789 if (IS_ERR(wiz->p_mac_div_sel1[i])) {
790 dev_err(dev, "P%d_MAC_DIV_SEL1 reg field init fail\n",
791 i);
792 return PTR_ERR(wiz->p_mac_div_sel1[i]);
793 }
794 }
795
796 return 0;
797}
798
799static int wiz_clock_init(struct wiz *wiz)
800{
801 struct udevice *dev = wiz->dev;
802 unsigned long rate;
803 struct clk *clk;
804 int ret;
805
806 clk = devm_clk_get(dev, "core_ref_clk");
807 if (IS_ERR(clk)) {
808 dev_err(dev, "core_ref_clk clock not found\n");
809 ret = PTR_ERR(clk);
810 return ret;
811 }
812 wiz->input_clks[WIZ_CORE_REFCLK] = clk;
813 /* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */
814 wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
815
816 rate = clk_get_rate(clk);
817 if (rate >= 100000000)
818 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
819 else
820 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
821
822 clk = devm_clk_get(dev, "ext_ref_clk");
823 if (IS_ERR(clk)) {
824 dev_err(dev, "ext_ref_clk clock not found\n");
825 ret = PTR_ERR(clk);
826 return ret;
827 }
828
829 wiz->input_clks[WIZ_EXT_REFCLK] = clk;
830 /* Initialize EXT_REFCLK1 to the same clock reference to maintain old DT compatibility */
831 wiz->input_clks[WIZ_EXT_REFCLK1] = clk;
832
833 rate = clk_get_rate(clk);
834 if (rate >= 100000000)
835 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
836 else
837 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
838
839 return 0;
840}
841
842static ofnode get_child_by_name(struct udevice *dev, const char *name)
843{
844 int l = strlen(name);
845 ofnode node = dev_read_first_subnode(dev);
846
847 while (ofnode_valid(node)) {
848 const char *child_name = ofnode_get_name(node);
849
850 if (!strncmp(child_name, name, l)) {
851 if (child_name[l] == '\0' || child_name[l] == '@')
852 return node;
853 }
854 node = dev_read_next_subnode(node);
855 }
856 return node;
857}
858
859static int j721e_wiz_bind_clocks(struct wiz *wiz)
860{
861 struct udevice *dev = wiz->dev;
862 struct driver *wiz_clk_drv;
863 int i, rc;
864
865 wiz_clk_drv = lists_driver_lookup_name("wiz_clk");
866 if (!wiz_clk_drv) {
867 dev_err(dev, "Cannot find driver 'wiz_clk'\n");
868 return -ENOENT;
869 }
870
871 for (i = 0; i < WIZ_DIV_NUM_CLOCKS_10G; i++) {
872 rc = device_bind(dev, wiz_clk_drv, clk_div_sel[i].node_name,
873 &clk_div_sel[i], dev_ofnode(dev), NULL);
874 if (rc) {
875 dev_err(dev, "cannot bind driver for clock %s\n",
876 clk_div_sel[i].node_name);
877 }
878 }
879
880 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
881 rc = device_bind(dev, wiz_clk_drv, clk_mux_sel_10g[i].node_name,
882 &clk_mux_sel_10g[i], dev_ofnode(dev), NULL);
883 if (rc) {
884 dev_err(dev, "cannot bind driver for clock %s\n",
885 clk_mux_sel_10g[i].node_name);
886 }
887 }
888
889 return 0;
890}
891
892static int j721e_wiz_bind_of_clocks(struct wiz *wiz)
893{
894 struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
895 struct udevice *dev = wiz->dev;
896 enum wiz_type type = wiz->type;
897 struct driver *div_clk_drv;
898 struct driver *mux_clk_drv;
899 ofnode node;
900 int i, rc;
901
902 if (type == AM64_WIZ_10G)
903 return j721e_wiz_bind_clocks(wiz);
904
905 div_clk_drv = lists_driver_lookup_name("wiz_div_clk");
906 if (!div_clk_drv) {
907 dev_err(dev, "Cannot find driver 'wiz_div_clk'\n");
908 return -ENOENT;
909 }
910
911 mux_clk_drv = lists_driver_lookup_name("wiz_mux_clk");
912 if (!mux_clk_drv) {
913 dev_err(dev, "Cannot find driver 'wiz_mux_clk'\n");
914 return -ENOENT;
915 }
916
917 for (i = 0; i < wiz->clk_div_sel_num; i++) {
918 node = get_child_by_name(dev, clk_div_sel[i].node_name);
919 if (!ofnode_valid(node)) {
920 dev_err(dev, "cannot find node for clock %s\n",
921 clk_div_sel[i].node_name);
922 continue;
923 }
924 rc = device_bind(dev, div_clk_drv, clk_div_sel[i].node_name,
925 &clk_div_sel[i], node, NULL);
926 if (rc) {
927 dev_err(dev, "cannot bind driver for clock %s\n",
928 clk_div_sel[i].node_name);
929 }
930 }
931
932 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
933 node = get_child_by_name(dev, clk_mux_sel[i].node_name);
934 if (!ofnode_valid(node)) {
935 dev_err(dev, "cannot find node for clock %s\n",
936 clk_mux_sel[i].node_name);
937 continue;
938 }
939 rc = device_bind(dev, mux_clk_drv, clk_mux_sel[i].node_name,
940 &clk_mux_sel[i], node, NULL);
941 if (rc) {
942 dev_err(dev, "cannot bind driver for clock %s\n",
943 clk_mux_sel[i].node_name);
944 }
945 }
946
947 return 0;
948}
949
950static int j721e_wiz_bind_reset(struct udevice *dev)
951{
952 int rc;
953 struct driver *drv;
954
955 drv = lists_driver_lookup_name("wiz-reset");
956 if (!drv) {
957 dev_err(dev, "Cannot find driver 'wiz-reset'\n");
958 return -ENOENT;
959 }
960
961 rc = device_bind(dev, drv, "wiz-reset", NULL, dev_ofnode(dev), NULL);
962 if (rc) {
963 dev_err(dev, "cannot bind driver for wiz-reset\n");
964 return rc;
965 }
966
967 return 0;
968}
969
970static int j721e_wiz_bind(struct udevice *dev)
971{
972 dm_scan_fdt_dev(dev);
973
974 return 0;
975}
976
977static int wiz_get_lane_phy_types(struct udevice *dev, struct wiz *wiz)
978{
979 ofnode child, serdes;
980
981 serdes = get_child_by_name(dev, "serdes");
982 if (!ofnode_valid(serdes)) {
983 dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__);
984 return -EINVAL;
985 }
986
987 ofnode_for_each_subnode(child, serdes) {
988 u32 reg, num_lanes = 1, phy_type = PHY_NONE;
989 int ret, i;
990
991 ret = ofnode_read_u32(child, "reg", &reg);
992 if (ret) {
993 dev_err(dev, "%s: Reading \"reg\" from failed: %d\n",
994 __func__, ret);
995 return ret;
996 }
997 ofnode_read_u32(child, "cdns,num-lanes", &num_lanes);
998 ofnode_read_u32(child, "cdns,phy-type", &phy_type);
999
1000 dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__,
1001 reg, reg + num_lanes - 1, phy_type);
1002
1003 for (i = reg; i < reg + num_lanes; i++)
1004 wiz->lane_phy_type[i] = phy_type;
1005 }
1006
1007 return 0;
1008}
1009
1010static int j721e_wiz_probe(struct udevice *dev)
1011{
1012 struct wiz *wiz = dev_get_priv(dev);
1013 struct ofnode_phandle_args args;
1014 unsigned int val;
1015 int rc, i;
1016 ofnode node;
1017 struct regmap *regmap;
1018 u32 num_lanes;
1019
1020 node = get_child_by_name(dev, "serdes");
1021
1022 if (!ofnode_valid(node)) {
1023 dev_err(dev, "Failed to get SERDES child DT node\n");
1024 return -ENODEV;
1025 }
1026
1027 rc = regmap_init_mem(node, &regmap);
1028 if (rc) {
1029 dev_err(dev, "Failed to get memory resource\n");
1030 return rc;
1031 }
1032 rc = dev_read_u32(dev, "num-lanes", &num_lanes);
1033 if (rc) {
1034 dev_err(dev, "Failed to read num-lanes property\n");
1035 goto err_addr_to_resource;
1036 }
1037
1038 if (num_lanes > WIZ_MAX_LANES) {
1039 dev_err(dev, "Cannot support %d lanes\n", num_lanes);
1040 goto err_addr_to_resource;
1041 }
1042
1043 wiz->gpio_typec_dir = devm_gpiod_get_optional(dev, "typec-dir",
1044 GPIOD_IS_IN);
1045 if (IS_ERR(wiz->gpio_typec_dir)) {
1046 rc = PTR_ERR(wiz->gpio_typec_dir);
1047 dev_err(dev, "Failed to request typec-dir gpio: %d\n", rc);
1048 goto err_addr_to_resource;
1049 }
1050
1051 rc = dev_read_phandle_with_args(dev, "power-domains", "#power-domain-cells", 0, 0, &args);
1052 if (rc) {
1053 dev_err(dev, "Failed to get power domain: %d\n", rc);
1054 goto err_addr_to_resource;
1055 }
1056
1057 wiz->id = args.args[0];
1058 wiz->regmap = regmap;
1059 wiz->num_lanes = num_lanes;
1060 wiz->dev = dev;
1061 wiz->clk_div_sel = clk_div_sel;
1062 wiz->type = dev_get_driver_data(dev);
1063 if (wiz->type == J721E_WIZ_10G || wiz->type == AM64_WIZ_10G) {
1064 wiz->clk_mux_sel = clk_mux_sel_10g;
1065 wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G;
1066 } else {
1067 wiz->clk_mux_sel = clk_mux_sel_16g;
1068 wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_16G;
1069 }
1070
1071 rc = wiz_get_lane_phy_types(dev, wiz);
1072 if (rc) {
1073 dev_err(dev, "Failed to get lane PHY types\n");
1074 goto err_addr_to_resource;
1075 }
1076
1077 rc = wiz_regfield_init(wiz);
1078 if (rc) {
1079 dev_err(dev, "Failed to initialize regfields\n");
1080 goto err_addr_to_resource;
1081 }
1082
1083 for (i = 0; i < wiz->num_lanes; i++) {
1084 regmap_field_read(wiz->p_enable[i], &val);
1085 if (val & (P_ENABLE | P_ENABLE_FORCE)) {
1086 dev_err(dev, "SERDES already configured\n");
1087 rc = -EBUSY;
1088 goto err_addr_to_resource;
1089 }
1090 }
1091
1092 rc = j721e_wiz_bind_of_clocks(wiz);
1093 if (rc) {
1094 dev_err(dev, "Failed to bind clocks\n");
1095 goto err_addr_to_resource;
1096 }
1097
1098 rc = j721e_wiz_bind_reset(dev);
1099 if (rc) {
1100 dev_err(dev, "Failed to bind reset\n");
1101 goto err_addr_to_resource;
1102 }
1103
1104 rc = wiz_clock_init(wiz);
1105 if (rc) {
1106 dev_warn(dev, "Failed to initialize clocks\n");
1107 goto err_addr_to_resource;
1108 }
1109
1110 rc = wiz_init(wiz);
1111 if (rc) {
1112 dev_err(dev, "WIZ initialization failed\n");
1113 goto err_addr_to_resource;
1114 }
1115
1116 return 0;
1117
1118err_addr_to_resource:
1119 free(regmap);
1120
1121 return rc;
1122}
1123
1124static int j721e_wiz_remove(struct udevice *dev)
1125{
1126 struct wiz *wiz = dev_get_priv(dev);
1127
1128 if (wiz->regmap)
1129 free(wiz->regmap);
1130
1131 return 0;
1132}
1133
1134static const struct udevice_id j721e_wiz_ids[] = {
1135 {
1136 .compatible = "ti,j721e-wiz-16g", .data = J721E_WIZ_16G,
1137 },
1138 {
1139 .compatible = "ti,j721e-wiz-10g", .data = J721E_WIZ_10G,
1140 },
1141 {
1142 .compatible = "ti,am64-wiz-10g", .data = AM64_WIZ_10G,
1143 },
1144 {}
1145};
1146
1147U_BOOT_DRIVER(phy_j721e_wiz) = {
1148 .name = "phy-j721e-wiz",
1149 .id = UCLASS_NOP,
1150 .of_match = j721e_wiz_ids,
1151 .bind = j721e_wiz_bind,
1152 .probe = j721e_wiz_probe,
1153 .remove = j721e_wiz_remove,
1154 .priv_auto = sizeof(struct wiz),
1155 .flags = DM_FLAG_LEAVE_PD_ON,
1156};