blob: 23397175d3407e79a307e0db39e29c68dee4ea8f [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,
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
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530310#define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */
311#define WIZ_TYPEC_DIR_DEBOUNCE_MAX 1000
312
313struct wiz {
314 struct regmap *regmap;
315 enum wiz_type type;
316 struct wiz_clk_mux_sel *clk_mux_sel;
317 struct wiz_clk_div_sel *clk_div_sel;
318 unsigned int clk_div_sel_num;
319 struct regmap_field *por_en;
320 struct regmap_field *phy_reset_n;
321 struct regmap_field *phy_en_refclk;
322 struct regmap_field *p_enable[WIZ_MAX_LANES];
323 struct regmap_field *p_align[WIZ_MAX_LANES];
324 struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
325 struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
326 struct regmap_field *p_mac_div_sel0[WIZ_MAX_LANES];
327 struct regmap_field *p_mac_div_sel1[WIZ_MAX_LANES];
328 struct regmap_field *p0_fullrt_div[WIZ_MAX_LANES];
329 struct regmap_field *pma_cmn_refclk_int_mode;
Matt Ranostayb7c6fbb2022-10-05 13:51:30 -0700330 struct regmap_field *pma_cmn_refclk1_int_mode;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530331 struct regmap_field *pma_cmn_refclk_mode;
332 struct regmap_field *pma_cmn_refclk_dig_div;
333 struct regmap_field *pma_cmn_refclk1_dig_div;
334 struct regmap_field *div_sel_field[WIZ_DIV_NUM_CLOCKS_16G];
335 struct regmap_field *mux_sel_field[WIZ_MUX_NUM_CLOCKS];
336
337 struct udevice *dev;
338 u32 num_lanes;
339 struct gpio_desc *gpio_typec_dir;
340 u32 lane_phy_type[WIZ_MAX_LANES];
Sinthu Rajac5df75f2023-03-13 18:12:23 +0530341 u32 master_lane_num[WIZ_MAX_LANES];
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530342 struct clk *input_clks[WIZ_MAX_INPUT_CLOCKS];
343 unsigned int id;
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700344 const struct wiz_data *data;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530345};
346
347struct wiz_div_clk {
348 struct clk parent_clk;
349 struct wiz *wiz;
350};
351
352struct wiz_mux_clk {
353 struct clk parent_clks[4];
354 struct wiz *wiz;
355};
356
357struct wiz_clk {
358 struct wiz *wiz;
359};
360
361struct wiz_reset {
362 struct wiz *wiz;
363};
364
365static ulong wiz_div_clk_get_rate(struct clk *clk)
366{
367 struct udevice *dev = clk->dev;
368 struct wiz_div_clk *priv = dev_get_priv(dev);
369 struct wiz_clk_div_sel *data = dev_get_plat(dev);
370 struct wiz *wiz = priv->wiz;
371 ulong parent_rate = clk_get_rate(&priv->parent_clk);
372 u32 val;
373
374 regmap_field_read(wiz->div_sel_field[data->div_sel], &val);
375
376 return parent_rate >> val;
377}
378
379static ulong wiz_div_clk_set_rate(struct clk *clk, ulong rate)
380{
381 struct udevice *dev = clk->dev;
382 struct wiz_div_clk *priv = dev_get_priv(dev);
383 struct wiz_clk_div_sel *data = dev_get_plat(dev);
384 struct wiz *wiz = priv->wiz;
385 ulong parent_rate = clk_get_rate(&priv->parent_clk);
386 u32 div = parent_rate / rate;
387
388 div = __ffs(div);
389 regmap_field_write(wiz->div_sel_field[data->div_sel], div);
390
391 return parent_rate >> div;
392}
393
394const struct clk_ops wiz_div_clk_ops = {
395 .get_rate = wiz_div_clk_get_rate,
396 .set_rate = wiz_div_clk_set_rate,
397};
398
399int wiz_div_clk_probe(struct udevice *dev)
400{
401 struct wiz_div_clk *priv = dev_get_priv(dev);
402 struct clk parent_clk;
403 int rc;
404
405 rc = clk_get_by_index(dev, 0, &parent_clk);
406 if (rc) {
407 dev_err(dev, "unable to get parent clock. ret %d\n", rc);
408 return rc;
409 }
410 priv->parent_clk = parent_clk;
411 priv->wiz = dev_get_priv(dev->parent);
412 return 0;
413}
414
415U_BOOT_DRIVER(wiz_div_clk) = {
416 .name = "wiz_div_clk",
417 .id = UCLASS_CLK,
418 .priv_auto = sizeof(struct wiz_div_clk),
419 .ops = &wiz_div_clk_ops,
420 .probe = wiz_div_clk_probe,
421};
422
423static int wiz_clk_mux_set_parent(struct clk *clk, struct clk *parent)
424{
425 struct udevice *dev = clk->dev;
426 struct wiz_mux_clk *priv = dev_get_priv(dev);
427 struct wiz_clk_mux_sel *data = dev_get_plat(dev);
428 struct wiz *wiz = priv->wiz;
429 int i;
430
431 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++)
432 if (parent->dev == priv->parent_clks[i].dev)
433 break;
434
435 if (i == ARRAY_SIZE(priv->parent_clks))
436 return -EINVAL;
437
438 regmap_field_write(wiz->mux_sel_field[data->mux_sel], data->table[i]);
439 return 0;
440}
441
442static int wiz_clk_xlate(struct clk *clk, struct ofnode_phandle_args *args)
443{
444 struct udevice *dev = clk->dev;
445 struct wiz_mux_clk *priv = dev_get_priv(dev);
446 struct wiz *wiz = priv->wiz;
447
448 clk->id = wiz->id;
449
450 return 0;
451}
452
453static const struct clk_ops wiz_clk_mux_ops = {
454 .set_parent = wiz_clk_mux_set_parent,
455 .of_xlate = wiz_clk_xlate,
456};
457
458int wiz_mux_clk_probe(struct udevice *dev)
459{
460 struct wiz_mux_clk *priv = dev_get_priv(dev);
461 int rc;
462 int i;
463
464 for (i = 0; i < ARRAY_SIZE(priv->parent_clks); i++) {
465 rc = clk_get_by_index(dev, i, &priv->parent_clks[i]);
466 if (rc)
467 priv->parent_clks[i].dev = NULL;
468 }
469 priv->wiz = dev_get_priv(dev->parent);
470 return 0;
471}
472
473U_BOOT_DRIVER(wiz_mux_clk) = {
474 .name = "wiz_mux_clk",
475 .id = UCLASS_CLK,
476 .priv_auto = sizeof(struct wiz_mux_clk),
477 .ops = &wiz_clk_mux_ops,
478 .probe = wiz_mux_clk_probe,
479};
480
481static int wiz_clk_set_parent(struct clk *clk, struct clk *parent)
482{
483 struct udevice *dev = clk->dev;
484 struct wiz_clk *priv = dev_get_priv(dev);
485 const struct wiz_clk_mux_sel *mux_sel;
486 struct wiz *wiz = priv->wiz;
487 int num_parents;
488 int i, j, id;
489
490 id = clk->id >> 10;
491
492 /* set_parent is applicable only for MUX clocks */
493 if (id > TI_WIZ_REFCLK_DIG)
494 return 0;
495
496 for (i = 0; i < WIZ_MAX_INPUT_CLOCKS; i++)
497 if (wiz->input_clks[i]->dev == parent->dev)
498 break;
499
500 if (i == WIZ_MAX_INPUT_CLOCKS)
501 return -EINVAL;
502
503 mux_sel = &wiz->clk_mux_sel[id];
504 num_parents = mux_sel->num_parents;
505 for (j = 0; j < num_parents; j++)
506 if (mux_sel->parents[j] == i)
507 break;
508
509 if (j == num_parents)
510 return -EINVAL;
511
512 regmap_field_write(wiz->mux_sel_field[id], mux_sel->table[j]);
513
514 return 0;
515}
516
517static int wiz_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
518{
519 struct udevice *dev = clk->dev;
520 struct wiz_clk *priv = dev_get_priv(dev);
521 struct wiz *wiz = priv->wiz;
522
523 clk->id = args->args[0] << 10 | wiz->id;
524
525 return 0;
526}
527
528static const struct clk_ops wiz_clk_ops = {
529 .set_parent = wiz_clk_set_parent,
530 .of_xlate = wiz_clk_of_xlate,
531};
532
533int wiz_clk_probe(struct udevice *dev)
534{
535 struct wiz_clk *priv = dev_get_priv(dev);
536
537 priv->wiz = dev_get_priv(dev->parent);
538
539 return 0;
540}
541
542U_BOOT_DRIVER(wiz_clk) = {
543 .name = "wiz_clk",
544 .id = UCLASS_CLK,
545 .priv_auto = sizeof(struct wiz_clk),
546 .ops = &wiz_clk_ops,
547 .probe = wiz_clk_probe,
548};
549
550static int wiz_reset_request(struct reset_ctl *reset_ctl)
551{
552 return 0;
553}
554
555static int wiz_reset_free(struct reset_ctl *reset_ctl)
556{
557 return 0;
558}
559
560static int wiz_reset_assert(struct reset_ctl *reset_ctl)
561{
562 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
563 struct wiz *wiz = priv->wiz;
564 int ret;
565 int id = reset_ctl->id;
566
567 if (id == 0) {
568 ret = regmap_field_write(wiz->phy_reset_n, false);
569 return ret;
570 }
571
572 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE);
573 return ret;
574}
575
576static int wiz_phy_fullrt_div(struct wiz *wiz, int lane)
577{
578 if (wiz->type != AM64_WIZ_10G)
579 return 0;
580
581 if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE)
582 return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1);
583
584 return 0;
585}
586
587static int wiz_reset_deassert(struct reset_ctl *reset_ctl)
588{
589 struct wiz_reset *priv = dev_get_priv(reset_ctl->dev);
590 struct wiz *wiz = priv->wiz;
591 int ret;
592 int id = reset_ctl->id;
593
594 ret = wiz_phy_fullrt_div(wiz, id - 1);
595 if (ret)
596 return ret;
597
598 /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
Sinthu Rajac5df75f2023-03-13 18:12:23 +0530599 if (id == 0) {
600 if (wiz->gpio_typec_dir) {
601 if (dm_gpio_get_value(wiz->gpio_typec_dir)) {
602 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
603 WIZ_SERDES_TYPEC_LN10_SWAP,
604 WIZ_SERDES_TYPEC_LN10_SWAP);
605 } else {
606 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
607 WIZ_SERDES_TYPEC_LN10_SWAP, 0);
608 }
609 }
610 } else {
611 /* if no typec-dir gpio was specified and PHY type is
612 * USB3 with master lane number is '0', set LN10 SWAP
613 * bit to '1'
614 */
615 u32 num_lanes = wiz->num_lanes;
616 int i;
617
618 for (i = 0; i < num_lanes; i++) {
Sinthu Rajadae83a42023-03-13 18:12:24 +0530619 if (wiz->lane_phy_type[i] == PHY_TYPE_USB3) {
620 switch (wiz->master_lane_num[i]) {
621 case LANE0:
Sinthu Rajac5df75f2023-03-13 18:12:23 +0530622 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
623 WIZ_SERDES_TYPEC_LN10_SWAP,
624 WIZ_SERDES_TYPEC_LN10_SWAP);
Sinthu Rajadae83a42023-03-13 18:12:24 +0530625 break;
626 case LANE2:
627 regmap_update_bits(wiz->regmap, WIZ_SERDES_TYPEC,
628 WIZ_SERDES_TYPEC_LN23_SWAP,
629 WIZ_SERDES_TYPEC_LN23_SWAP);
630 break;
631 default:
632 break;
633 }
634 }
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530635 }
636 }
637
638 if (id == 0) {
639 ret = regmap_field_write(wiz->phy_reset_n, true);
640 return ret;
641 }
642
Aswath Govindrajueaf8b512022-01-28 13:41:37 +0530643 if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP)
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530644 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
645 else
646 ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE);
647
648 return ret;
649}
650
651static struct reset_ops wiz_reset_ops = {
652 .request = wiz_reset_request,
653 .rfree = wiz_reset_free,
654 .rst_assert = wiz_reset_assert,
655 .rst_deassert = wiz_reset_deassert,
656};
657
658int wiz_reset_probe(struct udevice *dev)
659{
660 struct wiz_reset *priv = dev_get_priv(dev);
661
662 priv->wiz = dev_get_priv(dev->parent);
663
664 return 0;
665}
666
667U_BOOT_DRIVER(wiz_reset) = {
668 .name = "wiz-reset",
669 .id = UCLASS_RESET,
670 .probe = wiz_reset_probe,
671 .ops = &wiz_reset_ops,
672 .flags = DM_FLAG_LEAVE_PD_ON,
673};
674
675static int wiz_reset(struct wiz *wiz)
676{
677 int ret;
678
679 ret = regmap_field_write(wiz->por_en, 0x1);
680 if (ret)
681 return ret;
682
683 mdelay(1);
684
685 ret = regmap_field_write(wiz->por_en, 0x0);
686 if (ret)
687 return ret;
688
689 return 0;
690}
691
692static int wiz_p_mac_div_sel(struct wiz *wiz)
693{
694 u32 num_lanes = wiz->num_lanes;
695 int ret;
696 int i;
697
698 for (i = 0; i < num_lanes; i++) {
699 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
700 ret = regmap_field_write(wiz->p_mac_div_sel0[i], 1);
701 if (ret)
702 return ret;
703
704 ret = regmap_field_write(wiz->p_mac_div_sel1[i], 2);
705 if (ret)
706 return ret;
707 }
708 }
709
710 return 0;
711}
712
713static int wiz_mode_select(struct wiz *wiz)
714{
715 u32 num_lanes = wiz->num_lanes;
716 int ret;
717 int i;
718
719 for (i = 0; i < num_lanes; i++) {
720 if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) {
721 ret = regmap_field_write(wiz->p_standard_mode[i],
722 LANE_MODE_GEN2);
723 if (ret)
724 return ret;
725 }
726 }
727
728 return 0;
729}
730
731static int wiz_init_raw_interface(struct wiz *wiz, bool enable)
732{
733 u32 num_lanes = wiz->num_lanes;
734 int i;
735 int ret;
736
737 for (i = 0; i < num_lanes; i++) {
738 ret = regmap_field_write(wiz->p_align[i], enable);
739 if (ret)
740 return ret;
741
742 ret = regmap_field_write(wiz->p_raw_auto_start[i], enable);
743 if (ret)
744 return ret;
745 }
746
747 return 0;
748}
749
750static int wiz_init(struct wiz *wiz)
751{
752 struct udevice *dev = wiz->dev;
753 int ret;
754
755 ret = wiz_reset(wiz);
756 if (ret) {
757 dev_err(dev, "WIZ reset failed\n");
758 return ret;
759 }
760
761 ret = wiz_mode_select(wiz);
762 if (ret) {
763 dev_err(dev, "WIZ mode select failed\n");
764 return ret;
765 }
766
767 ret = wiz_p_mac_div_sel(wiz);
768 if (ret) {
769 dev_err(dev, "Configuring P0 MAC DIV SEL failed\n");
770 return ret;
771 }
772
773 ret = wiz_init_raw_interface(wiz, true);
774 if (ret) {
775 dev_err(dev, "WIZ interface initialization failed\n");
776 return ret;
777 }
778
779 return 0;
780}
781
782static int wiz_regfield_init(struct wiz *wiz)
783{
784 struct regmap *regmap = wiz->regmap;
785 int num_lanes = wiz->num_lanes;
786 struct udevice *dev = wiz->dev;
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700787 const struct wiz_data *data = wiz->data;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530788 int i;
789
790 wiz->por_en = devm_regmap_field_alloc(dev, regmap, por_en);
791 if (IS_ERR(wiz->por_en)) {
792 dev_err(dev, "POR_EN reg field init failed\n");
793 return PTR_ERR(wiz->por_en);
794 }
795
796 wiz->phy_reset_n = devm_regmap_field_alloc(dev, regmap,
797 phy_reset_n);
798 if (IS_ERR(wiz->phy_reset_n)) {
799 dev_err(dev, "PHY_RESET_N reg field init failed\n");
800 return PTR_ERR(wiz->phy_reset_n);
801 }
802
803 wiz->pma_cmn_refclk_int_mode =
804 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_int_mode);
805 if (IS_ERR(wiz->pma_cmn_refclk_int_mode)) {
806 dev_err(dev, "PMA_CMN_REFCLK_INT_MODE reg field init failed\n");
807 return PTR_ERR(wiz->pma_cmn_refclk_int_mode);
808 }
809
Matt Ranostayb7c6fbb2022-10-05 13:51:30 -0700810 if (data->pma_cmn_refclk1_int_mode) {
811 wiz->pma_cmn_refclk1_int_mode =
812 devm_regmap_field_alloc(dev, regmap, *data->pma_cmn_refclk1_int_mode);
813 if (IS_ERR(wiz->pma_cmn_refclk1_int_mode)) {
814 dev_err(dev, "PMA_CMN_REFCLK1_INT_MODE reg field init failed\n");
815 return PTR_ERR(wiz->pma_cmn_refclk1_int_mode);
816 }
817 }
818
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530819 wiz->pma_cmn_refclk_mode =
820 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode);
821 if (IS_ERR(wiz->pma_cmn_refclk_mode)) {
822 dev_err(dev, "PMA_CMN_REFCLK_MODE reg field init failed\n");
823 return PTR_ERR(wiz->pma_cmn_refclk_mode);
824 }
825
826 wiz->div_sel_field[CMN_REFCLK] =
827 devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_dig_div);
828 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK])) {
829 dev_err(dev, "PMA_CMN_REFCLK_DIG_DIV reg field init failed\n");
830 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK]);
831 }
832
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700833 if (data->pma_cmn_refclk1_dig_div) {
834 wiz->div_sel_field[CMN_REFCLK1] =
835 devm_regmap_field_alloc(dev, regmap, *data->pma_cmn_refclk1_dig_div);
836 if (IS_ERR(wiz->div_sel_field[CMN_REFCLK1])) {
837 dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
838 return PTR_ERR(wiz->div_sel_field[CMN_REFCLK1]);
839 }
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530840 }
841
842 wiz->mux_sel_field[PLL0_REFCLK] =
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700843 devm_regmap_field_alloc(dev, regmap, *data->pll0_refclk_mux_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530844 if (IS_ERR(wiz->mux_sel_field[PLL0_REFCLK])) {
845 dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n");
846 return PTR_ERR(wiz->mux_sel_field[PLL0_REFCLK]);
847 }
848
849 wiz->mux_sel_field[PLL1_REFCLK] =
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700850 devm_regmap_field_alloc(dev, regmap, *data->pll1_refclk_mux_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530851 if (IS_ERR(wiz->mux_sel_field[PLL1_REFCLK])) {
852 dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n");
853 return PTR_ERR(wiz->mux_sel_field[PLL1_REFCLK]);
854 }
855
Matt Ranostay6d255cc2022-07-07 23:41:52 -0700856 wiz->mux_sel_field[REFCLK_DIG] =
857 devm_regmap_field_alloc(dev, regmap, *data->refclk_dig_sel);
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530858 if (IS_ERR(wiz->mux_sel_field[REFCLK_DIG])) {
859 dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
860 return PTR_ERR(wiz->mux_sel_field[REFCLK_DIG]);
861 }
862
863 for (i = 0; i < num_lanes; i++) {
864 wiz->p_enable[i] = devm_regmap_field_alloc(dev, regmap,
865 p_enable[i]);
866 if (IS_ERR(wiz->p_enable[i])) {
867 dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
868 return PTR_ERR(wiz->p_enable[i]);
869 }
870
871 wiz->p_align[i] = devm_regmap_field_alloc(dev, regmap,
872 p_align[i]);
873 if (IS_ERR(wiz->p_align[i])) {
874 dev_err(dev, "P%d_ALIGN reg field init failed\n", i);
875 return PTR_ERR(wiz->p_align[i]);
876 }
877
878 wiz->p_raw_auto_start[i] =
879 devm_regmap_field_alloc(dev, regmap, p_raw_auto_start[i]);
880 if (IS_ERR(wiz->p_raw_auto_start[i])) {
881 dev_err(dev, "P%d_RAW_AUTO_START reg field init fail\n",
882 i);
883 return PTR_ERR(wiz->p_raw_auto_start[i]);
884 }
885
886 wiz->p_standard_mode[i] =
887 devm_regmap_field_alloc(dev, regmap, p_standard_mode[i]);
888 if (IS_ERR(wiz->p_standard_mode[i])) {
889 dev_err(dev, "P%d_STANDARD_MODE reg field init fail\n",
890 i);
891 return PTR_ERR(wiz->p_standard_mode[i]);
892 }
893
894 wiz->p0_fullrt_div[i] = devm_regmap_field_alloc(dev, regmap, p0_fullrt_div[i]);
895 if (IS_ERR(wiz->p0_fullrt_div[i])) {
896 dev_err(dev, "P%d_FULLRT_DIV reg field init failed\n", i);
897 return PTR_ERR(wiz->p0_fullrt_div[i]);
898 }
899
900 wiz->p_mac_div_sel0[i] =
901 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel0[i]);
902 if (IS_ERR(wiz->p_mac_div_sel0[i])) {
903 dev_err(dev, "P%d_MAC_DIV_SEL0 reg field init fail\n",
904 i);
905 return PTR_ERR(wiz->p_mac_div_sel0[i]);
906 }
907
908 wiz->p_mac_div_sel1[i] =
909 devm_regmap_field_alloc(dev, regmap, p_mac_div_sel1[i]);
910 if (IS_ERR(wiz->p_mac_div_sel1[i])) {
911 dev_err(dev, "P%d_MAC_DIV_SEL1 reg field init fail\n",
912 i);
913 return PTR_ERR(wiz->p_mac_div_sel1[i]);
914 }
915 }
916
917 return 0;
918}
919
920static int wiz_clock_init(struct wiz *wiz)
921{
922 struct udevice *dev = wiz->dev;
923 unsigned long rate;
924 struct clk *clk;
925 int ret;
926
927 clk = devm_clk_get(dev, "core_ref_clk");
928 if (IS_ERR(clk)) {
929 dev_err(dev, "core_ref_clk clock not found\n");
930 ret = PTR_ERR(clk);
931 return ret;
932 }
933 wiz->input_clks[WIZ_CORE_REFCLK] = clk;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530934
935 rate = clk_get_rate(clk);
936 if (rate >= 100000000)
937 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
938 else
939 regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
940
Matt Ranostayb7c6fbb2022-10-05 13:51:30 -0700941 if (wiz->data->pma_cmn_refclk1_int_mode) {
942 clk = devm_clk_get(dev, "core_ref1_clk");
943 if (IS_ERR(clk)) {
944 dev_err(dev, "core_ref1_clk clock not found\n");
945 ret = PTR_ERR(clk);
946 return ret;
947 }
948 wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
949
950 rate = clk_get_rate(clk);
951 if (rate >= 100000000)
952 regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x1);
953 else
954 regmap_field_write(wiz->pma_cmn_refclk1_int_mode, 0x3);
955 } else {
956 /* Initialize CORE_REFCLK1 to the same clock reference to maintain old DT compatibility */
957 wiz->input_clks[WIZ_CORE_REFCLK1] = clk;
958 }
959
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +0530960 clk = devm_clk_get(dev, "ext_ref_clk");
961 if (IS_ERR(clk)) {
962 dev_err(dev, "ext_ref_clk clock not found\n");
963 ret = PTR_ERR(clk);
964 return ret;
965 }
966
967 wiz->input_clks[WIZ_EXT_REFCLK] = clk;
968 /* Initialize EXT_REFCLK1 to the same clock reference to maintain old DT compatibility */
969 wiz->input_clks[WIZ_EXT_REFCLK1] = clk;
970
971 rate = clk_get_rate(clk);
972 if (rate >= 100000000)
973 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
974 else
975 regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
976
977 return 0;
978}
979
980static ofnode get_child_by_name(struct udevice *dev, const char *name)
981{
982 int l = strlen(name);
983 ofnode node = dev_read_first_subnode(dev);
984
985 while (ofnode_valid(node)) {
986 const char *child_name = ofnode_get_name(node);
987
988 if (!strncmp(child_name, name, l)) {
989 if (child_name[l] == '\0' || child_name[l] == '@')
990 return node;
991 }
992 node = dev_read_next_subnode(node);
993 }
994 return node;
995}
996
997static int j721e_wiz_bind_clocks(struct wiz *wiz)
998{
999 struct udevice *dev = wiz->dev;
1000 struct driver *wiz_clk_drv;
1001 int i, rc;
1002
1003 wiz_clk_drv = lists_driver_lookup_name("wiz_clk");
1004 if (!wiz_clk_drv) {
1005 dev_err(dev, "Cannot find driver 'wiz_clk'\n");
1006 return -ENOENT;
1007 }
1008
1009 for (i = 0; i < WIZ_DIV_NUM_CLOCKS_10G; i++) {
1010 rc = device_bind(dev, wiz_clk_drv, clk_div_sel[i].node_name,
1011 &clk_div_sel[i], dev_ofnode(dev), NULL);
1012 if (rc) {
1013 dev_err(dev, "cannot bind driver for clock %s\n",
1014 clk_div_sel[i].node_name);
1015 }
1016 }
1017
1018 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
1019 rc = device_bind(dev, wiz_clk_drv, clk_mux_sel_10g[i].node_name,
1020 &clk_mux_sel_10g[i], dev_ofnode(dev), NULL);
1021 if (rc) {
1022 dev_err(dev, "cannot bind driver for clock %s\n",
1023 clk_mux_sel_10g[i].node_name);
1024 }
1025 }
1026
1027 return 0;
1028}
1029
1030static int j721e_wiz_bind_of_clocks(struct wiz *wiz)
1031{
1032 struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
1033 struct udevice *dev = wiz->dev;
1034 enum wiz_type type = wiz->type;
1035 struct driver *div_clk_drv;
1036 struct driver *mux_clk_drv;
1037 ofnode node;
1038 int i, rc;
1039
Matt Ranostayb7c6fbb2022-10-05 13:51:30 -07001040 if (type == AM64_WIZ_10G || type == J784S4_WIZ_10G)
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301041 return j721e_wiz_bind_clocks(wiz);
1042
1043 div_clk_drv = lists_driver_lookup_name("wiz_div_clk");
1044 if (!div_clk_drv) {
1045 dev_err(dev, "Cannot find driver 'wiz_div_clk'\n");
1046 return -ENOENT;
1047 }
1048
1049 mux_clk_drv = lists_driver_lookup_name("wiz_mux_clk");
1050 if (!mux_clk_drv) {
1051 dev_err(dev, "Cannot find driver 'wiz_mux_clk'\n");
1052 return -ENOENT;
1053 }
1054
1055 for (i = 0; i < wiz->clk_div_sel_num; i++) {
1056 node = get_child_by_name(dev, clk_div_sel[i].node_name);
1057 if (!ofnode_valid(node)) {
1058 dev_err(dev, "cannot find node for clock %s\n",
1059 clk_div_sel[i].node_name);
1060 continue;
1061 }
1062 rc = device_bind(dev, div_clk_drv, clk_div_sel[i].node_name,
1063 &clk_div_sel[i], node, NULL);
1064 if (rc) {
1065 dev_err(dev, "cannot bind driver for clock %s\n",
1066 clk_div_sel[i].node_name);
1067 }
1068 }
1069
1070 for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
1071 node = get_child_by_name(dev, clk_mux_sel[i].node_name);
1072 if (!ofnode_valid(node)) {
1073 dev_err(dev, "cannot find node for clock %s\n",
1074 clk_mux_sel[i].node_name);
1075 continue;
1076 }
1077 rc = device_bind(dev, mux_clk_drv, clk_mux_sel[i].node_name,
1078 &clk_mux_sel[i], node, NULL);
1079 if (rc) {
1080 dev_err(dev, "cannot bind driver for clock %s\n",
1081 clk_mux_sel[i].node_name);
1082 }
1083 }
1084
1085 return 0;
1086}
1087
1088static int j721e_wiz_bind_reset(struct udevice *dev)
1089{
1090 int rc;
1091 struct driver *drv;
1092
1093 drv = lists_driver_lookup_name("wiz-reset");
1094 if (!drv) {
1095 dev_err(dev, "Cannot find driver 'wiz-reset'\n");
1096 return -ENOENT;
1097 }
1098
1099 rc = device_bind(dev, drv, "wiz-reset", NULL, dev_ofnode(dev), NULL);
1100 if (rc) {
1101 dev_err(dev, "cannot bind driver for wiz-reset\n");
1102 return rc;
1103 }
1104
1105 return 0;
1106}
1107
1108static int j721e_wiz_bind(struct udevice *dev)
1109{
1110 dm_scan_fdt_dev(dev);
1111
1112 return 0;
1113}
1114
1115static int wiz_get_lane_phy_types(struct udevice *dev, struct wiz *wiz)
1116{
1117 ofnode child, serdes;
1118
1119 serdes = get_child_by_name(dev, "serdes");
1120 if (!ofnode_valid(serdes)) {
1121 dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__);
1122 return -EINVAL;
1123 }
1124
1125 ofnode_for_each_subnode(child, serdes) {
1126 u32 reg, num_lanes = 1, phy_type = PHY_NONE;
1127 int ret, i;
1128
1129 ret = ofnode_read_u32(child, "reg", &reg);
1130 if (ret) {
1131 dev_err(dev, "%s: Reading \"reg\" from failed: %d\n",
1132 __func__, ret);
1133 return ret;
1134 }
1135 ofnode_read_u32(child, "cdns,num-lanes", &num_lanes);
1136 ofnode_read_u32(child, "cdns,phy-type", &phy_type);
1137
1138 dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__,
1139 reg, reg + num_lanes - 1, phy_type);
1140
Sinthu Rajac5df75f2023-03-13 18:12:23 +05301141 for (i = reg; i < reg + num_lanes; i++) {
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301142 wiz->lane_phy_type[i] = phy_type;
Sinthu Rajac5df75f2023-03-13 18:12:23 +05301143 wiz->master_lane_num[i] = reg;
1144 }
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301145 }
1146
1147 return 0;
1148}
1149
1150static int j721e_wiz_probe(struct udevice *dev)
1151{
1152 struct wiz *wiz = dev_get_priv(dev);
1153 struct ofnode_phandle_args args;
1154 unsigned int val;
1155 int rc, i;
1156 ofnode node;
1157 struct regmap *regmap;
1158 u32 num_lanes;
1159
1160 node = get_child_by_name(dev, "serdes");
1161
1162 if (!ofnode_valid(node)) {
1163 dev_err(dev, "Failed to get SERDES child DT node\n");
1164 return -ENODEV;
1165 }
1166
1167 rc = regmap_init_mem(node, &regmap);
1168 if (rc) {
1169 dev_err(dev, "Failed to get memory resource\n");
1170 return rc;
1171 }
1172 rc = dev_read_u32(dev, "num-lanes", &num_lanes);
1173 if (rc) {
1174 dev_err(dev, "Failed to read num-lanes property\n");
1175 goto err_addr_to_resource;
1176 }
1177
1178 if (num_lanes > WIZ_MAX_LANES) {
1179 dev_err(dev, "Cannot support %d lanes\n", num_lanes);
1180 goto err_addr_to_resource;
1181 }
1182
1183 wiz->gpio_typec_dir = devm_gpiod_get_optional(dev, "typec-dir",
1184 GPIOD_IS_IN);
1185 if (IS_ERR(wiz->gpio_typec_dir)) {
1186 rc = PTR_ERR(wiz->gpio_typec_dir);
1187 dev_err(dev, "Failed to request typec-dir gpio: %d\n", rc);
1188 goto err_addr_to_resource;
1189 }
1190
1191 rc = dev_read_phandle_with_args(dev, "power-domains", "#power-domain-cells", 0, 0, &args);
1192 if (rc) {
1193 dev_err(dev, "Failed to get power domain: %d\n", rc);
1194 goto err_addr_to_resource;
1195 }
1196
1197 wiz->id = args.args[0];
1198 wiz->regmap = regmap;
1199 wiz->num_lanes = num_lanes;
1200 wiz->dev = dev;
1201 wiz->clk_div_sel = clk_div_sel;
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001202
1203 wiz->data = (struct wiz_data *)dev_get_driver_data(dev);
1204 wiz->type = wiz->data->type;
1205
1206 wiz->clk_mux_sel = (struct wiz_clk_mux_sel *)wiz->data->clk_mux_sel;
1207 wiz->clk_div_sel_num = wiz->data->clk_div_sel_num;
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301208
1209 rc = wiz_get_lane_phy_types(dev, wiz);
1210 if (rc) {
1211 dev_err(dev, "Failed to get lane PHY types\n");
1212 goto err_addr_to_resource;
1213 }
1214
1215 rc = wiz_regfield_init(wiz);
1216 if (rc) {
1217 dev_err(dev, "Failed to initialize regfields\n");
1218 goto err_addr_to_resource;
1219 }
1220
1221 for (i = 0; i < wiz->num_lanes; i++) {
1222 regmap_field_read(wiz->p_enable[i], &val);
1223 if (val & (P_ENABLE | P_ENABLE_FORCE)) {
1224 dev_err(dev, "SERDES already configured\n");
1225 rc = -EBUSY;
1226 goto err_addr_to_resource;
1227 }
1228 }
1229
1230 rc = j721e_wiz_bind_of_clocks(wiz);
1231 if (rc) {
1232 dev_err(dev, "Failed to bind clocks\n");
1233 goto err_addr_to_resource;
1234 }
1235
1236 rc = j721e_wiz_bind_reset(dev);
1237 if (rc) {
1238 dev_err(dev, "Failed to bind reset\n");
1239 goto err_addr_to_resource;
1240 }
1241
1242 rc = wiz_clock_init(wiz);
1243 if (rc) {
1244 dev_warn(dev, "Failed to initialize clocks\n");
1245 goto err_addr_to_resource;
1246 }
1247
1248 rc = wiz_init(wiz);
1249 if (rc) {
1250 dev_err(dev, "WIZ initialization failed\n");
1251 goto err_addr_to_resource;
1252 }
1253
1254 return 0;
1255
1256err_addr_to_resource:
1257 free(regmap);
1258
1259 return rc;
1260}
1261
1262static int j721e_wiz_remove(struct udevice *dev)
1263{
1264 struct wiz *wiz = dev_get_priv(dev);
1265
1266 if (wiz->regmap)
1267 free(wiz->regmap);
1268
1269 return 0;
1270}
1271
1272static const struct udevice_id j721e_wiz_ids[] = {
1273 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001274 .compatible = "ti,j721e-wiz-16g", .data = (ulong)&j721e_16g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301275 },
1276 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001277 .compatible = "ti,j721e-wiz-10g", .data = (ulong)&j721e_10g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301278 },
1279 {
Matt Ranostay6d255cc2022-07-07 23:41:52 -07001280 .compatible = "ti,am64-wiz-10g", .data = (ulong)&am64_10g_data,
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301281 },
Matt Ranostayb7c6fbb2022-10-05 13:51:30 -07001282 {
1283 .compatible = "ti,j784s4-wiz-10g", .data = (ulong)&j784s4_wiz_10g,
1284 },
Jean-Jacques Hiblot065788e2021-07-21 21:28:38 +05301285 {}
1286};
1287
1288U_BOOT_DRIVER(phy_j721e_wiz) = {
1289 .name = "phy-j721e-wiz",
1290 .id = UCLASS_NOP,
1291 .of_match = j721e_wiz_ids,
1292 .bind = j721e_wiz_bind,
1293 .probe = j721e_wiz_probe,
1294 .remove = j721e_wiz_remove,
1295 .priv_auto = sizeof(struct wiz),
1296 .flags = DM_FLAG_LEAVE_PD_ON,
1297};