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