2 * Copyright 2014-2015 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <linux/errno.h>
10 #include <asm/arch/fsl_serdes.h>
11 #include <asm/arch/soc.h>
12 #include <fsl-mc/ldpaa_wriop.h>
14 #ifdef CONFIG_SYS_FSL_SRDS_1
15 static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
17 #ifdef CONFIG_SYS_FSL_SRDS_2
18 static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
21 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
22 int xfi_dpmac[XFI8 + 1];
23 int sgmii_dpmac[SGMII16 + 1];
26 __weak void wriop_init_dpmac_qsgmii(int sd, int lane_prtcl)
32 *The return value of this func is the serdes protocol used.
33 *Typically this function is called number of times depending
34 *upon the number of serdes blocks in the Silicon.
35 *Zero is used to denote that no serdes was enabled,
36 *this is the case when golden RCW was used where DPAA2 bring was
37 *intentionally removed to achieve boot to prompt
40 __weak int serdes_get_number(int serdes, int cfg)
45 int is_serdes_configured(enum srds_prtcl device)
49 #ifdef CONFIG_SYS_FSL_SRDS_1
50 if (!serdes1_prtcl_map[NONE])
53 ret |= serdes1_prtcl_map[device];
55 #ifdef CONFIG_SYS_FSL_SRDS_2
56 if (!serdes2_prtcl_map[NONE])
59 ret |= serdes2_prtcl_map[device];
65 int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
67 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
72 #ifdef CONFIG_SYS_FSL_SRDS_1
74 cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
75 cfg &= FSL_CHASSIS3_SRDS1_PRTCL_MASK;
76 cfg >>= FSL_CHASSIS3_SRDS1_PRTCL_SHIFT;
79 #ifdef CONFIG_SYS_FSL_SRDS_2
81 cfg = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
82 cfg &= FSL_CHASSIS3_SRDS2_PRTCL_MASK;
83 cfg >>= FSL_CHASSIS3_SRDS2_PRTCL_SHIFT;
87 printf("invalid SerDes%d\n", sd);
91 cfg = serdes_get_number(sd, cfg);
93 /* Is serdes enabled at all? */
97 for (i = 0; i < SRDS_MAX_LANES; i++) {
98 if (serdes_get_prtcl(sd, cfg, i) == device)
105 void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32 sd_prctl_mask,
106 u32 sd_prctl_shift, u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
108 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
112 if (serdes_prtcl_map[NONE])
115 memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
117 cfg = gur_in32(&gur->rcwsr[rcwsr - 1]) & sd_prctl_mask;
118 cfg >>= sd_prctl_shift;
120 cfg = serdes_get_number(sd, cfg);
121 printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
123 if (!is_serdes_prtcl_valid(sd, cfg))
124 printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
126 for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
127 enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
128 if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
129 debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
131 serdes_prtcl_map[lane_prtcl] = 1;
132 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
133 switch (lane_prtcl) {
138 wriop_init_dpmac_qsgmii(sd, (int)lane_prtcl);
141 if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
143 xfi_dpmac[lane_prtcl],
146 if (lane_prtcl >= SGMII1 &&
147 lane_prtcl <= SGMII16)
148 wriop_init_dpmac(sd, sgmii_dpmac[
157 /* Set the first element to indicate serdes has been initialized */
158 serdes_prtcl_map[NONE] = 1;
161 __weak int get_serdes_volt(void)
166 __weak int set_serdes_volt(int svdd)
171 #define LNAGCR0_RT_RSTB 0x00600000
173 #define RSTCTL_RESET_MASK 0x000000E0
175 #define RSTCTL_RSTREQ 0x80000000
176 #define RSTCTL_RST_DONE 0x40000000
177 #define RSTCTL_RSTERR 0x20000000
179 #define RSTCTL_SDEN 0x00000020
180 #define RSTCTL_SDRST_B 0x00000040
181 #define RSTCTL_PLLRST_B 0x00000080
183 #define TCALCR_CALRST_B 0x08000000
185 struct serdes_prctl_info {
191 struct serdes_prctl_info srds_prctl_info[] = {
192 #ifdef CONFIG_SYS_FSL_SRDS_1
194 .mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK,
195 .shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT
199 #ifdef CONFIG_SYS_FSL_SRDS_2
201 .mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK,
202 .shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT
208 static int get_serdes_prctl_info_idx(u32 serdes_id)
211 struct serdes_prctl_info *srds_info;
213 /* loop until NULL ENTRY defined by .id=0 */
214 for (srds_info = srds_prctl_info; srds_info->id != 0;
215 srds_info++, pos++) {
216 if (srds_info->id == serdes_id)
223 static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg,
224 struct ccsr_serdes __iomem *serdes_base,
230 pos = get_serdes_prctl_info_idx(serdes_id);
232 printf("invalid serdes_id %d\n", serdes_id);
236 cfg_tmp = cfg & srds_prctl_info[pos].mask;
237 cfg_tmp >>= srds_prctl_info[pos].shift;
239 for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
241 setbits_le32(&serdes_base->lane[i].gcr0,
244 clrbits_le32(&serdes_base->lane[i].gcr0,
249 static void do_pll_reset(u32 cfg,
250 struct ccsr_serdes __iomem *serdes_base)
254 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
255 clrbits_le32(&serdes_base->bank[i].rstctl,
259 setbits_le32(&serdes_base->bank[i].rstctl,
265 static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base)
267 clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
268 clrbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
271 static void do_rx_tx_cal_reset_comp(u32 cfg, int i,
272 struct ccsr_serdes __iomem *serdes_base)
274 if (!(cfg == 0x3 && i == 1)) {
276 setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
277 setbits_le32(&serdes_base->srdstcalcr, TCALCR_CALRST_B);
282 static void do_pll_reset_done(u32 cfg,
283 struct ccsr_serdes __iomem *serdes_base)
288 for (i = 0; i < 2; i++) {
289 reg = in_le32(&serdes_base->bank[i].pllcr0);
290 if (!(cfg & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
291 setbits_le32(&serdes_base->bank[i].rstctl,
297 static void do_serdes_enable(u32 cfg,
298 struct ccsr_serdes __iomem *serdes_base)
302 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
303 setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_SDEN);
306 setbits_le32(&serdes_base->bank[i].rstctl, RSTCTL_PLLRST_B);
308 /* Take the Rx/Tx calibration out of reset */
309 do_rx_tx_cal_reset_comp(cfg, i, serdes_base);
313 static void do_pll_lock(u32 cfg,
314 struct ccsr_serdes __iomem *serdes_base)
319 for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
320 /* if the PLL is not locked, set RST_ERR */
321 reg = in_le32(&serdes_base->bank[i].pllcr0);
322 if (!((reg >> 23) & 0x1)) {
323 setbits_le32(&serdes_base->bank[i].rstctl,
327 setbits_le32(&serdes_base->bank[i].rstctl,
334 int setup_serdes_volt(u32 svdd)
336 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
337 struct ccsr_serdes __iomem *serdes1_base =
338 (void *)CONFIG_SYS_FSL_LSCH3_SERDES_ADDR;
339 u32 cfg_rcwsrds1 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS1_REGSR - 1]);
340 #ifdef CONFIG_SYS_FSL_SRDS_2
341 struct ccsr_serdes __iomem *serdes2_base =
342 (void *)(CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + 0x10000);
343 u32 cfg_rcwsrds2 = gur_in32(&gur->rcwsr[FSL_CHASSIS3_SRDS2_REGSR - 1]);
346 int svdd_cur, svdd_tar;
349 /* Only support switch SVDD to 900mV */
353 /* Scale up to the LTC resolution is 1/4096V */
354 svdd = (svdd * 4096) / 1000;
357 svdd_cur = get_serdes_volt();
361 debug("%s: current SVDD: %x; target SVDD: %x\n",
362 __func__, svdd_cur, svdd_tar);
363 if (svdd_cur == svdd_tar)
366 /* Put the all enabled lanes in reset */
367 #ifdef CONFIG_SYS_FSL_SRDS_1
368 do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, false);
371 #ifdef CONFIG_SYS_FSL_SRDS_2
372 do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, false);
375 /* Put the all enabled PLL in reset */
376 #ifdef CONFIG_SYS_FSL_SRDS_1
377 cfg_tmp = cfg_rcwsrds1 & 0x3;
378 do_pll_reset(cfg_tmp, serdes1_base);
381 #ifdef CONFIG_SYS_FSL_SRDS_2
382 cfg_tmp = cfg_rcwsrds1 & 0xC;
384 do_pll_reset(cfg_tmp, serdes2_base);
387 /* Put the Rx/Tx calibration into reset */
388 #ifdef CONFIG_SYS_FSL_SRDS_1
389 do_rx_tx_cal_reset(serdes1_base);
392 #ifdef CONFIG_SYS_FSL_SRDS_2
393 do_rx_tx_cal_reset(serdes2_base);
396 ret = set_serdes_volt(svdd);
398 printf("could not change SVDD\n");
402 /* For each PLL that’s not disabled via RCW enable the SERDES */
403 #ifdef CONFIG_SYS_FSL_SRDS_1
404 cfg_tmp = cfg_rcwsrds1 & 0x3;
405 do_serdes_enable(cfg_tmp, serdes1_base);
407 #ifdef CONFIG_SYS_FSL_SRDS_2
408 cfg_tmp = cfg_rcwsrds1 & 0xC;
410 do_serdes_enable(cfg_tmp, serdes2_base);
413 /* Wait for at at least 625us, ensure the PLLs being reset are locked */
416 #ifdef CONFIG_SYS_FSL_SRDS_1
417 cfg_tmp = cfg_rcwsrds1 & 0x3;
418 do_pll_lock(cfg_tmp, serdes1_base);
421 #ifdef CONFIG_SYS_FSL_SRDS_2
422 cfg_tmp = cfg_rcwsrds1 & 0xC;
424 do_pll_lock(cfg_tmp, serdes2_base);
426 /* Take the all enabled lanes out of reset */
427 #ifdef CONFIG_SYS_FSL_SRDS_1
428 do_enabled_lanes_reset(1, cfg_rcwsrds1, serdes1_base, true);
430 #ifdef CONFIG_SYS_FSL_SRDS_2
431 do_enabled_lanes_reset(2, cfg_rcwsrds2, serdes2_base, true);
434 /* For each PLL being reset, and achieved PLL lock set RST_DONE */
435 #ifdef CONFIG_SYS_FSL_SRDS_1
436 cfg_tmp = cfg_rcwsrds1 & 0x3;
437 do_pll_reset_done(cfg_tmp, serdes1_base);
439 #ifdef CONFIG_SYS_FSL_SRDS_2
440 cfg_tmp = cfg_rcwsrds1 & 0xC;
442 do_pll_reset_done(cfg_tmp, serdes2_base);
448 void fsl_serdes_init(void)
450 #if defined(CONFIG_FSL_MC_ENET) && !defined(CONFIG_SPL_BUILD)
453 for (i = XFI1, j = 1; i <= XFI8; i++, j++)
456 for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
460 #ifdef CONFIG_SYS_FSL_SRDS_1
461 serdes_init(FSL_SRDS_1,
462 CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
463 FSL_CHASSIS3_SRDS1_REGSR,
464 FSL_CHASSIS3_SRDS1_PRTCL_MASK,
465 FSL_CHASSIS3_SRDS1_PRTCL_SHIFT,
468 #ifdef CONFIG_SYS_FSL_SRDS_2
469 serdes_init(FSL_SRDS_2,
470 CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
471 FSL_CHASSIS3_SRDS2_REGSR,
472 FSL_CHASSIS3_SRDS2_PRTCL_MASK,
473 FSL_CHASSIS3_SRDS2_PRTCL_SHIFT,