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