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