Home | History | Annotate | Download | only in mpc85xx
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright 2010-2011 Freescale Semiconductor, Inc.
      4  */
      5 
      6 #include <config.h>
      7 #include <common.h>
      8 #include <asm/io.h>
      9 #include <asm/immap_85xx.h>
     10 #include <asm/fsl_serdes.h>
     11 
     12 typedef struct serdes_85xx {
     13 	u32	srdscr0;	/* 0x00 - SRDS Control Register 0 */
     14 	u32	srdscr1;	/* 0x04 - SRDS Control Register 1 */
     15 	u32	srdscr2;	/* 0x08 - SRDS Control Register 2 */
     16 	u32	srdscr3;	/* 0x0C - SRDS Control Register 3 */
     17 	u32	srdscr4;	/* 0x10 - SRDS Control Register 4 */
     18 } serdes_85xx_t;
     19 #define FSL_SRDSCR3_EIC0(x)	(((x) & 0x1f) << 8)
     20 #define FSL_SRDSCR3_EIC0_MASK	FSL_SRDSCR3_EIC0(0x1f)
     21 #define FSL_SRDSCR3_EIC1(x)	(((x) & 0x1f) << 0)
     22 #define FSL_SRDSCR3_EIC1_MASK	FSL_SRDSCR3_EIC1(0x1f)
     23 #define FSL_SRDSCR4_EIC2(x)	(((x) & 0x1f) << 8)
     24 #define FSL_SRDSCR4_EIC2_MASK	FSL_SRDSCR4_EIC2(0x1f)
     25 #define FSL_SRDSCR4_EIC3(x)	(((x) & 0x1f) << 0)
     26 #define FSL_SRDSCR4_EIC3_MASK	FSL_SRDSCR4_EIC3(0x1f)
     27 #define EIC_PCIE	0x13
     28 #define EIC_SGMII	0x04
     29 
     30 #define SRDS1_MAX_LANES		4
     31 
     32 static u32 serdes1_prtcl_map;
     33 
     34 static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = {
     35 	[0x0] = {PCIE1, NONE, NONE, NONE},
     36 	[0x6] = {PCIE1, PCIE1, PCIE1, PCIE1},
     37 	[0xe] = {PCIE1, PCIE2, SGMII_TSEC2, SGMII_TSEC3},
     38 	[0xf] = {PCIE1, PCIE1, SGMII_TSEC2, SGMII_TSEC3},
     39 };
     40 
     41 int is_serdes_configured(enum srds_prtcl prtcl)
     42 {
     43 	if (!(serdes1_prtcl_map & (1 << NONE)))
     44 		fsl_serdes_init();
     45 
     46 	return (1 << prtcl) & serdes1_prtcl_map;
     47 }
     48 
     49 void fsl_serdes_init(void)
     50 {
     51 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
     52 	serdes_85xx_t *serdes = (void *)CONFIG_SYS_MPC85xx_SERDES1_ADDR;
     53 
     54 	u32 pordevsr = in_be32(&gur->pordevsr);
     55 	u32 srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >>
     56 				MPC85xx_PORDEVSR_IO_SEL_SHIFT;
     57 	int lane;
     58 	u32 mask, val;
     59 
     60 	if (serdes1_prtcl_map & (1 << NONE))
     61 		return;
     62 
     63 	debug("PORDEVSR[IO_SEL_SRDS] = %x\n", srds_cfg);
     64 
     65 	if (srds_cfg >= ARRAY_SIZE(serdes1_cfg_tbl)) {
     66 		printf("Invalid PORDEVSR[IO_SEL_SRDS] = %d\n", srds_cfg);
     67 		return;
     68 	}
     69 
     70 	for (lane = 0; lane < SRDS1_MAX_LANES; lane++) {
     71 		enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds_cfg][lane];
     72 		serdes1_prtcl_map |= (1 << lane_prtcl);
     73 	}
     74 
     75 	/* Set the first bit to indicate serdes has been initialized */
     76 	serdes1_prtcl_map |= (1 << NONE);
     77 
     78 	/* Init SERDES Receiver electrical idle detection control for PCIe */
     79 
     80 	/* Lane 0 is always PCIe 1 */
     81 	mask = FSL_SRDSCR3_EIC0_MASK;
     82 	val = FSL_SRDSCR3_EIC0(EIC_PCIE);
     83 
     84 	/* Lane 1 */
     85 	if ((serdes1_cfg_tbl[srds_cfg][1] == PCIE1) ||
     86 	    (serdes1_cfg_tbl[srds_cfg][1] == PCIE2)) {
     87 		mask |= FSL_SRDSCR3_EIC1_MASK;
     88 		val |= FSL_SRDSCR3_EIC1(EIC_PCIE);
     89 	}
     90 
     91 	/* Handle lanes 0 & 1 */
     92 	clrsetbits_be32(&serdes->srdscr3, mask, val);
     93 
     94 	/* Handle lanes 2 & 3 */
     95 	if (srds_cfg == 0x6) {
     96 		mask = FSL_SRDSCR4_EIC2_MASK | FSL_SRDSCR4_EIC3_MASK;
     97 		val = FSL_SRDSCR4_EIC2(EIC_PCIE) | FSL_SRDSCR4_EIC3(EIC_PCIE);
     98 		clrsetbits_be32(&serdes->srdscr4, mask, val);
     99 	}
    100 
    101 	/* 100 ms delay */
    102 	udelay(100000);
    103 }
    104