blob: fb6b6cf3fff21283152339ed476584f8e7963766 [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
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700224struct wiz_data {
225 enum wiz_type type;
226 const struct reg_field *pll0_refclk_mux_sel;
227 const struct reg_field *pll1_refclk_mux_sel;
228 const struct reg_field *refclk_dig_sel;
229 const struct reg_field *pma_cmn_refclk1_dig_div;
230 const struct wiz_clk_mux_sel *clk_mux_sel;
231 unsigned int clk_div_sel_num;
232};
233
234static const struct wiz_data j721e_16g_data = {
235 .type = J721E_WIZ_16G,
236 .pll0_refclk_mux_sel = &pll0_refclk_mux_sel,
237 .pll1_refclk_mux_sel = &pll1_refclk_mux_sel,
238 .refclk_dig_sel = &refclk_dig_sel_16g,
239 .pma_cmn_refclk1_dig_div = &pma_cmn_refclk1_dig_div,
240 .clk_mux_sel = clk_mux_sel_16g,
241 .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_16G,
242};
243
244static const struct wiz_data j721e_10g_data = {
245 .type = J721E_WIZ_10G,
246 .pll0_refclk_mux_sel = &pll0_refclk_mux_sel,
247 .pll1_refclk_mux_sel = &pll1_refclk_mux_sel,
248 .refclk_dig_sel = &refclk_dig_sel_10g,
249 .clk_mux_sel = clk_mux_sel_10g,
250 .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G,
251};
252
253static struct wiz_data am64_10g_data = {
254 .type = AM64_WIZ_10G,
255 .pll0_refclk_mux_sel = &pll0_refclk_mux_sel,
256 .pll1_refclk_mux_sel = &pll1_refclk_mux_sel,
257 .refclk_dig_sel = &refclk_dig_sel_10g,
258 .clk_mux_sel = clk_mux_sel_10g,
259 .clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G,
260};
261
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530262#define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */
263#define WIZ_TYPEC_DIR_DEBOUNCE_MAX 1000
264
265struct wiz {
266 struct regmap *regmap;
267 enum wiz_type type;
268 struct wiz_clk_mux_sel *clk_mux_sel;
269 struct wiz_clk_div_sel *clk_div_sel;
270 unsigned int clk_div_sel_num;
271 struct regmap_field *por_en;
272 struct regmap_field *phy_reset_n;
273 struct regmap_field *phy_en_refclk;
274 struct regmap_field *p_enable[WIZ_MAX_LANES];
275 struct regmap_field *p_align[WIZ_MAX_LANES];
276 struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
277 struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
278 struct regmap_field *p_mac_div_sel0[WIZ_MAX_LANES];
279 struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES];
280 struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES];
281 struct regmap_field *pma_cmn_refclk_int_mode;
282 struct regmap_field *pma_cmn_refclk_mode;
283 struct regmap_field *pma_cmn_refclk_dig_div;
284 struct regmap_field *pma_cmn_refclk1_dig_div;
285 struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G];
286 struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS];
287
288 struct udevice *dev;
289 u32 num_lanes;
290 struct gpio_desc *gpio_typec_dir;
291 u32 lane_phy_type[WIZ_MAX_LANES];
292 struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS];
293 unsigned int id;
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700294 const struct wiz_data *data;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530295};
296
297struct wiz_div_clk {
298 struct clk parent_clk;
299 struct wiz *wiz;
300};
301
302struct wiz_mux_clk {
303 struct clk parent_clks[4];
304 struct wiz *wiz;
305};
306
307struct wiz_clk {
308 struct wiz *wiz;
309};
310
311struct wiz_reset {
312 struct wiz *wiz;
313};
314
315static ulong wiz_div_clk_get_rate(struct clk *clk)
316{
317 struct udevice *dev = clk->dev;
318 struct wiz_div_clk *priv = dev_get_priv(dev);
319 struct wiz_clk_div_sel *data = dev_get_plat(dev);
320 struct wiz *wiz = priv->wiz;
321 ulong parent_rate = clk_get_rate(&priv->parent_clk);
322 u32 val;
323
324 regmap_field_read(wiz->div_sel_field[data->div_sel], &val);
325
326 return parent_rate >> val;
327}
328
329static ulong wiz_div_clk_set_rate(struct clk *clk, ulong rate)
330{
331 struct udevice *dev = clk->dev;
332 struct wiz_div_clk *priv = dev_get_priv(dev);
333 struct wiz_clk_div_sel *data = dev_get_plat(dev);
334 struct wiz *wiz = priv->wiz;
335 ulong parent_rate = clk_get_rate(&priv->parent_clk);
336 u32 div = parent_rate / rate;
337
338 div = __ffs(div);
339 regmap_field_write(wiz->div_sel_field[data->div_sel], div);
340
341 return parent_rate >> div;
342}
343
344const struct clk_ops wiz_div_clk_ops = {
345 .get_rate = wiz_div_clk_get_rate,
346 .set_rate = wiz_div_clk_set_rate,
347};
348
349int wiz_div_clk_probe(struct udevice *dev)
350{
351 struct wiz_div_clk *priv = dev_get_priv(dev);
352 struct clk parent_clk;
353 int rc;
354
355 rc = clk_get_by_index(dev, 0, &parent_clk);
356 if (rc) {
357 dev_err(dev, "unable to get parent clock. ret %d\n", rc);
358 return rc;
359 }
360 priv->parent_clk = parent_clk;
361 priv->wiz = dev_get_priv(dev->parent);
362 return 0;
363}
364
365U_BOOT_DRIVER(wiz_div_clk) = {
366 .name = "wiz_div_clk",
367 .id = UCLASS_CLK,
368 .priv_auto = sizeof(struct wiz_div_clk),
369 .ops = &wiz_div_clk_ops,
370 .probe = wiz_div_clk_probe,
371};
372
373static int wiz_clk_mux_set_parent(struct clk *clk, struct clk *parent)
374{
375 struct udevice *dev = clk->dev;
376 struct wiz_mux_clk *priv = dev_get_priv(dev);
377 struct wiz_clk_mux_sel *data = dev_get_plat(dev);
378 struct wiz *wiz = priv->wiz;
379 int i;
380
381 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++)
382 if (parent->dev == priv->parent_clks[i].dev)
383 break;
384
385 if (i == ARRAY_SIZE(priv->parent_clks))
386 return -EINVAL;
387
388 regmap_field_write(wiz->mux_sel_field[data->mux_sel], data->table[i]);
389 return 0;
390}
391
392static int wiz_clk_xlate(struct clk *clk, struct ofnode_phandle_args *args)
393{
394 struct udevice *dev = clk->dev;
395 struct wiz_mux_clk *priv = dev_get_priv(dev);
396 struct wiz *wiz = priv->wiz;
397
398 clk->id = wiz->id;
399
400 return 0;
401}
402
403static const struct clk_ops wiz_clk_mux_ops = {
404 .set_parent = wiz_clk_mux_set_parent,
405 .of_xlate = wiz_clk_xlate,
406};
407
408int wiz_mux_clk_probe(struct udevice *dev)
409{
410 struct wiz_mux_clk *priv = dev_get_priv(dev);
411 int rc;
412 int i;
413
414 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++) {
415 rc = clk_get_by_index(dev, i, &priv->parent_clks[i]);
416 if (rc)
417 priv->parent_clks[i].dev = NULL;
418 }
419 priv->wiz = dev_get_priv(dev->parent);
420 return 0;
421}
422
423U_BOOT_DRIVER(wiz_mux_clk) = {
424 .name = "wiz_mux_clk",
425 .id = UCLASS_CLK,
426 .priv_auto = sizeof(struct wiz_mux_clk),
427 .ops = &wiz_clk_mux_ops,
428 .probe = wiz_mux_clk_probe,
429};
430
431static int wiz_clk_set_parent(struct clk *clk, struct clk *parent)
432{
433 struct udevice *dev = clk->dev;
434 struct wiz_clk *priv = dev_get_priv(dev);
435 const struct wiz_clk_mux_sel *mux_sel;
436 struct wiz *wiz = priv->wiz;
437 int num_parents;
438 int i, j, id;
439
440 id = clk->id >> 10;
441
442 /* set_parent is applicable only for MUX clocks */
443 if (id > TI_WIZ_REFCLK_DIG)
444 return 0;
445
446 for (i = 0; i < WIZ_MAX_INPUT_CLOCKS; i++)
447 if (wiz->input_clks[i]->dev == parent->dev)
448 break;
449
450 if (i == WIZ_MAX_INPUT_CLOCKS)
451 return -EINVAL;
452
453 mux_sel = &wiz->clk_mux_sel[id];
454 num_parents = mux_sel->num_parents;
455 for (j = 0; j < num_parents; j++)
456 if (mux_sel->parents[j] == i)
457 break;
458
459 if (j == num_parents)
460 return -EINVAL;
461
462 regmap_field_write(wiz->mux_sel_field[id], mux_sel->table[j]);
463
464 return 0;
465}
466
467static int wiz_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
468{
469 struct udevice *dev = clk->dev;
470 struct wiz_clk *priv = dev_get_priv(dev);
471 struct wiz *wiz = priv->wiz;
472
473 clk->id = args->args[0] << 10 | wiz->id;
474
475 return 0;
476}
477
478static const struct clk_ops wiz_clk_ops = {
479 .set_parent = wiz_clk_set_parent,
480 .of_xlate = wiz_clk_of_xlate,
481};
482
483int wiz_clk_probe(struct udevice *dev)
484{
485 struct wiz_clk *priv = dev_get_priv(dev);
486
487 priv->wiz = dev_get_priv(dev->parent);
488
489 return 0;
490}
491
492U_BOOT_DRIVER(wiz_clk) = {
493 .name = "wiz_clk",
494 .id = UCLASS_CLK,
495 .priv_auto = sizeof(struct wiz_clk),
496 .ops = &wiz_clk_ops,
497 .probe = wiz_clk_probe,
498};
499
500static int wiz_reset_request(struct reset_ctl *reset_ctl)
501{
502 return 0;
503}
504
505static int wiz_reset_free(struct reset_ctl *reset_ctl)
506{
507 return 0;
508}
509
510static int wiz_reset_assert(struct reset_ctl *reset_ctl)
511{
512 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
513 struct wiz *wiz = priv->wiz;
514 int ret;
515 int id = reset_ctl->id;
516
517 if (id == 0) {
518 ret = regmap_field_write(wiz->phy_reset_n, false);
519 return ret;
520 }
521
522 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE);
523 return ret;
524}
525
526static int wiz_phy_fullrt_div(struct wiz *wiz, int lane)
527{
528 if (wiz->type != AM64_WIZ_10G)
529 return 0;
530
531 if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE)
532 return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1);
533
534 return 0;
535}
536
537static int wiz_reset_deassert(struct reset_ctl *reset_ctl)
538{
539 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
540 struct wiz *wiz = priv->wiz;
541 int ret;
542 int id = reset_ctl->id;
543
544 ret = wiz_phy_fullrt_div(wiz, id - 1);
545 if (ret)
546 return ret;
547
548 /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
549 if (id == 0 && wiz->gpio_typec_dir) {
550 if (dm_gpio_get_value(wiz->gpio_typec_dir)) {
551 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
552 WIZ_SERDES_TYPEC_LN10_SWAP,
553 WIZ_SERDES_TYPEC_LN10_SWAP);
554 } else {
555 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
556 WIZ_SERDES_TYPEC_LN10_SWAP, 0);
557 }
558 }
559
560 if (id == 0) {
561 ret = regmap_field_write(wiz->phy_reset_n, true);
562 return ret;
563 }
564
Aswath Govindrajueaf8b512022-01-28 13:41:37 +0530565 if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP)
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530566 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
567 else
568 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE);
569
570 return ret;
571}
572
573static struct reset_ops wiz_reset_ops = {
574 .request = wiz_reset_request,
575 .rfree = wiz_reset_free,
576 .rst_assert = wiz_reset_assert,
577 .rst_deassert = wiz_reset_deassert,
578};
579
580int wiz_reset_probe(struct udevice *dev)
581{
582 struct wiz_reset *priv = dev_get_priv(dev);
583
584 priv->wiz = dev_get_priv(dev->parent);
585
586 return 0;
587}
588
589U_BOOT_DRIVER(wiz_reset) = {
590 .name = "wiz-reset",
591 .id = UCLASS_RESET,
592 .probe = wiz_reset_probe,
593 .ops = &wiz_reset_ops,
594 .flags = DM_FLAG_LEAVE_PD_ON,
595};
596
597static int wiz_reset(struct wiz *wiz)
598{
599 int ret;
600
601 ret = regmap_field_write(wiz->por_en, 0x1);
602 if (ret)
603 return ret;
604
605 mdelay(1);
606
607 ret = regmap_field_write(wiz->por_en, 0x0);
608 if (ret)
609 return ret;
610
611 return 0;
612}
613
614static int wiz_p_mac_div_sel(struct wiz *wiz)
615{
616 u32 num_lanes = wiz->num_lanes;
617 int ret;
618 int i;
619
620 for (i = 0; i < num_lanes; i++) {
621 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
622 ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1);
623 if (ret)
624 return ret;
625
626 ret = regmap_field_write(wiz->p_mac_div_sel1[i], 2);
627 if (ret)
628 return ret;
629 }
630 }
631
632 return 0;
633}
634
635static int wiz_mode_select(struct wiz *wiz)
636{
637 u32 num_lanes = wiz->num_lanes;
638 int ret;
639 int i;
640
641 for (i = 0; i < num_lanes; i++) {
642 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
643 ret = regmap_field_write(wiz->p_standard_mode[i],
644 LANE_MODE_GEN2);
645 if (ret)
646 return ret;
647 }
648 }
649
650 return 0;
651}
652
653static int wiz_init_raw_interface(struct wiz *wiz, bool enable)
654{
655 u32 num_lanes = wiz->num_lanes;
656 int i;
657 int ret;
658
659 for (i = 0; i < num_lanes; i++) {
660 ret = regmap_field_write(wiz->p_align[i], enable);
661 if (ret)
662 return ret;
663
664 ret = regmap_field_write(wiz->p_raw_auto_start[i], enable);
665 if (ret)
666 return ret;
667 }
668
669 return 0;
670}
671
672static int wiz_init(struct wiz *wiz)
673{
674 struct udevice *dev = wiz->dev;
675 int ret;
676
677 ret = wiz_reset(wiz);
678 if (ret) {
679 dev_err(dev, "WIZ reset failed\n");
680 return ret;
681 }
682
683 ret = wiz_mode_select(wiz);
684 if (ret) {
685 dev_err(dev, "WIZ mode select failed\n");
686 return ret;
687 }
688
689 ret = wiz_p_mac_div_sel(wiz);
690 if (ret) {
691 dev_err(dev, "Configuring P0 MAC DIV SEL failed\n");
692 return ret;
693 }
694
695 ret = wiz_init_raw_interface(wiz, true);
696 if (ret) {
697 dev_err(dev, "WIZ interface initialization failed\n");
698 return ret;
699 }
700
701 return 0;
702}
703
704static int wiz_regfield_init(struct wiz *wiz)
705{
706 struct regmap *regmap = wiz->regmap;
707 int num_lanes = wiz->num_lanes;
708 struct udevice *dev = wiz->dev;
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700709 const struct wiz_data *data = wiz->data;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530710 int i;
711
712 wiz->por_en = devm_regmap_field_alloc(dev, regmap, por_en);
713 if (IS_ERR(wiz->por_en)) {
714 dev_err(dev, "POR_EN reg field init failed\n");
715 return PTR_ERR(wiz->por_en);
716 }
717
718 wiz->phy_reset_n = devm_regmap_field_alloc(dev, regmap,
719 phy_reset_n);
720 if (IS_ERR(wiz->phy_reset_n)) {
721 dev_err(dev, "PHY_RESET_N reg field init failed\n");
722 return PTR_ERR(wiz->phy_reset_n);
723 }
724
725 wiz->pma_cmn_refclk_int_mode =
726 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_int_mode);
727 if (IS_ERR(wiz->pma_cmn_refclk_int_mode)) {
728 dev_err(dev, "PMA_CMN_REFCLK_INT_MODE reg field init failed\n");
729 return PTR_ERR(wiz->pma_cmn_refclk_int_mode);
730 }
731
732 wiz->pma_cmn_refclk_mode =
733 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode);
734 if (IS_ERR(wiz->pma_cmn_refclk_mode)) {
735 dev_err(dev, "PMA_CMN_REFCLK_MODE reg field init failed\n");
736 return PTR_ERR(wiz->pma_cmn_refclk_mode);
737 }
738
739 wiz->div_sel_field[CMN_REFCLK] =
740 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_dig_div);
741 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK])) {
742 dev_err(dev, "PMA_CMN_REFCLK_DIG_DIV reg field init failed\n");
743 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK]);
744 }
745
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700746 if (data->pma_cmn_refclk1_dig_div) {
747 wiz->div_sel_field[CMN_REFCLK1] =
748 devm_regmap_field_alloc(dev, regmap, *data->pma_cmn_refclk1_dig_div);
749 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK1])) {
750 dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
751 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK1]);
752 }
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530753 }
754
755 wiz->mux_sel_field[PLL0_REFCLK] =
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700756 devm_regmap_field_alloc(dev, regmap, *data->pll0_refclk_mux_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530757 if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) {
758 dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n");
759 return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]);
760 }
761
762 wiz->mux_sel_field[PLL1_REFCLK] =
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700763 devm_regmap_field_alloc(dev, regmap, *data->pll1_refclk_mux_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530764 if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) {
765 dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n");
766 return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]);
767 }
768
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700769 wiz->mux_sel_field[REFCLK_DIG] =
770 devm_regmap_field_alloc(dev, regmap, *data->refclk_dig_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530771 if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) {
772 dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
773 return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]);
774 }
775
776 for (i = 0; i < num_lanes; i++) {
777 wiz->p_enable[i] = devm_regmap_field_alloc(dev, regmap,
778 p_enable[i]);
779 if (IS_ERR(wiz->p_enable[i])) {
780 dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
781 return PTR_ERR(wiz->p_enable[i]);
782 }
783
784 wiz->p_align[i] = devm_regmap_field_alloc(dev, regmap,
785 p_align[i]);
786 if (IS_ERR(wiz->p_align[i])) {
787 dev_err(dev, "P%d_ALIGN reg field init failed\n", i);
788 return PTR_ERR(wiz->p_align[i]);
789 }
790
791 wiz->p_raw_auto_start[i] =
792 devm_regmap_field_alloc(dev, regmap, p_raw_auto_start[i]);
793 if (IS_ERR(wiz->p_raw_auto_start[i])) {
794 dev_err(dev, "P%d_RAW_AUTO_START reg field init fail\n",
795 i);
796 return PTR_ERR(wiz->p_raw_auto_start[i]);
797 }
798
799 wiz->p_standard_mode[i] =
800 devm_regmap_field_alloc(dev, regmap, p_standard_mode[i]);
801 if (IS_ERR(wiz->p_standard_mode[i])) {
802 dev_err(dev, "P%d_STANDARD_MODE reg field init fail\n",
803 i);
804 return PTR_ERR(wiz->p_standard_mode[i]);
805 }
806
807 wiz->p0_fullrt_div[i] = devm_regmap_field_alloc(dev, regmap, p0_fullrt_div[i]);
808 if (IS_ERR(wiz->p0_fullrt_div[i])) {
809 dev_err(dev, "P%d_FULLRT_DIV reg field init failed\n", i);
810 return PTR_ERR(wiz->p0_fullrt_div[i]);
811 }
812
813 wiz->p_mac_div_sel0[i] =
814 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel0[i]);
815 if (IS_ERR(wiz->p_mac_div_sel0[i])) {
816 dev_err(dev, "P%d_MAC_DIV_SEL0 reg field init fail\n",
817 i);
818 return PTR_ERR(wiz->p_mac_div_sel0[i]);
819 }
820
821 wiz->p_mac_div_sel1[i] =
822 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel1[i]);
823 if (IS_ERR(wiz->p_mac_div_sel1[i])) {
824 dev_err(dev, "P%d_MAC_DIV_SEL1 reg field init fail\n",
825 i);
826 return PTR_ERR(wiz->p_mac_div_sel1[i]);
827 }
828 }
829
830 return 0;
831}
832
833static int wiz_clock_init(struct wiz *wiz)
834{
835 struct udevice *dev = wiz->dev;
836 unsigned long rate;
837 struct clk *clk;
838 int ret;
839
840 clk = devm_clk_get(dev, "core_ref_clk");
841 if (IS_ERR(clk)) {
842 dev_err(dev, "core_ref_clk clock not found\n");
843 ret = PTR_ERR(clk);
844 return ret;
845 }
846 wiz->input_clks[WIZ_CORE_REFCLK] = clk;
847 /* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */
848 wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
849
850 rate = clk_get_rate(clk);
851 if (rate >= 100000000)
852 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
853 else
854 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
855
856 clk = devm_clk_get(dev, "ext_ref_clk");
857 if (IS_ERR(clk)) {
858 dev_err(dev, "ext_ref_clk clock not found\n");
859 ret = PTR_ERR(clk);
860 return ret;
861 }
862
863 wiz->input_clks[WIZ_EXT_REFCLK] = clk;
864 /* Initialize EXT_REFCLK1 to the same clock reference to maintain old DT compatibility */
865 wiz->input_clks[WIZ_EXT_REFCLK1] = clk;
866
867 rate = clk_get_rate(clk);
868 if (rate >= 100000000)
869 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
870 else
871 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
872
873 return 0;
874}
875
876static ofnode get_child_by_name(struct udevice *dev, const char *name)
877{
878 int l = strlen(name);
879 ofnode node = dev_read_first_subnode(dev);
880
881 while (ofnode_valid(node)) {
882 const char *child_name = ofnode_get_name(node);
883
884 if (!strncmp(child_name, name, l)) {
885 if (child_name[l] == '\0' || child_name[l] == '@')
886 return node;
887 }
888 node = dev_read_next_subnode(node);
889 }
890 return node;
891}
892
893static int j721e_wiz_bind_clocks(struct wiz *wiz)
894{
895 struct udevice *dev = wiz->dev;
896 struct driver *wiz_clk_drv;
897 int i, rc;
898
899 wiz_clk_drv = lists_driver_lookup_name("wiz_clk");
900 if (!wiz_clk_drv) {
901 dev_err(dev, "Cannot find driver 'wiz_clk'\n");
902 return -ENOENT;
903 }
904
905 for (i = 0; i < WIZ_DIV_NUM_CLOCKS_10G; i++) {
906 rc = device_bind(dev, wiz_clk_drv, clk_div_sel[i].node_name,
907 &clk_div_sel[i], dev_ofnode(dev), NULL);
908 if (rc) {
909 dev_err(dev, "cannot bind driver for clock %s\n",
910 clk_div_sel[i].node_name);
911 }
912 }
913
914 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
915 rc = device_bind(dev, wiz_clk_drv, clk_mux_sel_10g[i].node_name,
916 &clk_mux_sel_10g[i], dev_ofnode(dev), NULL);
917 if (rc) {
918 dev_err(dev, "cannot bind driver for clock %s\n",
919 clk_mux_sel_10g[i].node_name);
920 }
921 }
922
923 return 0;
924}
925
926static int j721e_wiz_bind_of_clocks(struct wiz *wiz)
927{
928 struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
929 struct udevice *dev = wiz->dev;
930 enum wiz_type type = wiz->type;
931 struct driver *div_clk_drv;
932 struct driver *mux_clk_drv;
933 ofnode node;
934 int i, rc;
935
936 if (type == AM64_WIZ_10G)
937 return j721e_wiz_bind_clocks(wiz);
938
939 div_clk_drv = lists_driver_lookup_name("wiz_div_clk");
940 if (!div_clk_drv) {
941 dev_err(dev, "Cannot find driver 'wiz_div_clk'\n");
942 return -ENOENT;
943 }
944
945 mux_clk_drv = lists_driver_lookup_name("wiz_mux_clk");
946 if (!mux_clk_drv) {
947 dev_err(dev, "Cannot find driver 'wiz_mux_clk'\n");
948 return -ENOENT;
949 }
950
951 for (i = 0; i < wiz->clk_div_sel_num; i++) {
952 node = get_child_by_name(dev, clk_div_sel[i].node_name);
953 if (!ofnode_valid(node)) {
954 dev_err(dev, "cannot find node for clock %s\n",
955 clk_div_sel[i].node_name);
956 continue;
957 }
958 rc = device_bind(dev, div_clk_drv, clk_div_sel[i].node_name,
959 &clk_div_sel[i], node, NULL);
960 if (rc) {
961 dev_err(dev, "cannot bind driver for clock %s\n",
962 clk_div_sel[i].node_name);
963 }
964 }
965
966 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
967 node = get_child_by_name(dev, clk_mux_sel[i].node_name);
968 if (!ofnode_valid(node)) {
969 dev_err(dev, "cannot find node for clock %s\n",
970 clk_mux_sel[i].node_name);
971 continue;
972 }
973 rc = device_bind(dev, mux_clk_drv, clk_mux_sel[i].node_name,
974 &clk_mux_sel[i], node, NULL);
975 if (rc) {
976 dev_err(dev, "cannot bind driver for clock %s\n",
977 clk_mux_sel[i].node_name);
978 }
979 }
980
981 return 0;
982}
983
984static int j721e_wiz_bind_reset(struct udevice *dev)
985{
986 int rc;
987 struct driver *drv;
988
989 drv = lists_driver_lookup_name("wiz-reset");
990 if (!drv) {
991 dev_err(dev, "Cannot find driver 'wiz-reset'\n");
992 return -ENOENT;
993 }
994
995 rc = device_bind(dev, drv, "wiz-reset", NULL, dev_ofnode(dev), NULL);
996 if (rc) {
997 dev_err(dev, "cannot bind driver for wiz-reset\n");
998 return rc;
999 }
1000
1001 return 0;
1002}
1003
1004static int j721e_wiz_bind(struct udevice *dev)
1005{
1006 dm_scan_fdt_dev(dev);
1007
1008 return 0;
1009}
1010
1011static int wiz_get_lane_phy_types(struct udevice *dev, struct wiz *wiz)
1012{
1013 ofnode child, serdes;
1014
1015 serdes = get_child_by_name(dev, "serdes");
1016 if (!ofnode_valid(serdes)) {
1017 dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__);
1018 return -EINVAL;
1019 }
1020
1021 ofnode_for_each_subnode(child, serdes) {
1022 u32 reg, num_lanes = 1, phy_type = PHY_NONE;
1023 int ret, i;
1024
1025 ret = ofnode_read_u32(child, "reg", &reg);
1026 if (ret) {
1027 dev_err(dev, "%s: Reading \"reg\" from failed: %d\n",
1028 __func__, ret);
1029 return ret;
1030 }
1031 ofnode_read_u32(child, "cdns,num-lanes", &num_lanes);
1032 ofnode_read_u32(child, "cdns,phy-type", &phy_type);
1033
1034 dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__,
1035 reg, reg + num_lanes - 1, phy_type);
1036
1037 for (i = reg; i < reg + num_lanes; i++)
1038 wiz->lane_phy_type[i] = phy_type;
1039 }
1040
1041 return 0;
1042}
1043
1044static int j721e_wiz_probe(struct udevice *dev)
1045{
1046 struct wiz *wiz = dev_get_priv(dev);
1047 struct ofnode_phandle_args args;
1048 unsigned int val;
1049 int rc, i;
1050 ofnode node;
1051 struct regmap *regmap;
1052 u32 num_lanes;
1053
1054 node = get_child_by_name(dev, "serdes");
1055
1056 if (!ofnode_valid(node)) {
1057 dev_err(dev, "Failed to get SERDES child DT node\n");
1058 return -ENODEV;
1059 }
1060
1061 rc = regmap_init_mem(node, &regmap);
1062 if (rc) {
1063 dev_err(dev, "Failed to get memory resource\n");
1064 return rc;
1065 }
1066 rc = dev_read_u32(dev, "num-lanes", &num_lanes);
1067 if (rc) {
1068 dev_err(dev, "Failed to read num-lanes property\n");
1069 goto err_addr_to_resource;
1070 }
1071
1072 if (num_lanes > WIZ_MAX_LANES) {
1073 dev_err(dev, "Cannot support %d lanes\n", num_lanes);
1074 goto err_addr_to_resource;
1075 }
1076
1077 wiz->gpio_typec_dir = devm_gpiod_get_optional(dev, "typec-dir",
1078 GPIOD_IS_IN);
1079 if (IS_ERR(wiz->gpio_typec_dir)) {
1080 rc = PTR_ERR(wiz->gpio_typec_dir);
1081 dev_err(dev, "Failed to request typec-dir gpio: %d\n", rc);
1082 goto err_addr_to_resource;
1083 }
1084
1085 rc = dev_read_phandle_with_args(dev, "power-domains", "#power-domain-cells", 0, 0, &args);
1086 if (rc) {
1087 dev_err(dev, "Failed to get power domain: %d\n", rc);
1088 goto err_addr_to_resource;
1089 }
1090
1091 wiz->id = args.args[0];
1092 wiz->regmap = regmap;
1093 wiz->num_lanes = num_lanes;
1094 wiz->dev = dev;
1095 wiz->clk_div_sel = clk_div_sel;
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001096
1097 wiz->data = (struct wiz_data *)dev_get_driver_data(dev);
1098 wiz->type = wiz->data->type;
1099
1100 wiz->clk_mux_sel = (struct wiz_clk_mux_sel *)wiz->data->clk_mux_sel;
1101 wiz->clk_div_sel_num = wiz->data->clk_div_sel_num;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301102
1103 rc = wiz_get_lane_phy_types(dev, wiz);
1104 if (rc) {
1105 dev_err(dev, "Failed to get lane PHY types\n");
1106 goto err_addr_to_resource;
1107 }
1108
1109 rc = wiz_regfield_init(wiz);
1110 if (rc) {
1111 dev_err(dev, "Failed to initialize regfields\n");
1112 goto err_addr_to_resource;
1113 }
1114
1115 for (i = 0; i < wiz->num_lanes; i++) {
1116 regmap_field_read(wiz->p_enable[i], &val);
1117 if (val & (P_ENABLE | P_ENABLE_FORCE)) {
1118 dev_err(dev, "SERDES already configured\n");
1119 rc = -EBUSY;
1120 goto err_addr_to_resource;
1121 }
1122 }
1123
1124 rc = j721e_wiz_bind_of_clocks(wiz);
1125 if (rc) {
1126 dev_err(dev, "Failed to bind clocks\n");
1127 goto err_addr_to_resource;
1128 }
1129
1130 rc = j721e_wiz_bind_reset(dev);
1131 if (rc) {
1132 dev_err(dev, "Failed to bind reset\n");
1133 goto err_addr_to_resource;
1134 }
1135
1136 rc = wiz_clock_init(wiz);
1137 if (rc) {
1138 dev_warn(dev, "Failed to initialize clocks\n");
1139 goto err_addr_to_resource;
1140 }
1141
1142 rc = wiz_init(wiz);
1143 if (rc) {
1144 dev_err(dev, "WIZ initialization failed\n");
1145 goto err_addr_to_resource;
1146 }
1147
1148 return 0;
1149
1150err_addr_to_resource:
1151 free(regmap);
1152
1153 return rc;
1154}
1155
1156static int j721e_wiz_remove(struct udevice *dev)
1157{
1158 struct wiz *wiz = dev_get_priv(dev);
1159
1160 if (wiz->regmap)
1161 free(wiz->regmap);
1162
1163 return 0;
1164}
1165
1166static const struct udevice_id j721e_wiz_ids[] = {
1167 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001168 .compatible = "ti,j721e-wiz-16g", .data = (ulong)&j721e_16g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301169 },
1170 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001171 .compatible = "ti,j721e-wiz-10g", .data = (ulong)&j721e_10g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301172 },
1173 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001174 .compatible = "ti,am64-wiz-10g", .data = (ulong)&am64_10g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301175 },
1176 {}
1177};
1178
1179U_BOOT_DRIVER(phy_j721e_wiz) = {
1180 .name = "phy-j721e-wiz",
1181 .id = UCLASS_NOP,
1182 .of_match = j721e_wiz_ids,
1183 .bind = j721e_wiz_bind,
1184 .probe = j721e_wiz_probe,
1185 .remove = j721e_wiz_remove,
1186 .priv_auto = sizeof(struct wiz),
1187 .flags = DM_FLAG_LEAVE_PD_ON,
1188};