1 /* 2 * Copyright 2008,2010 Freescale Semiconductor, Inc. 3 * Dave Liu <daveliu@freescale.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <config.h> 9 #include <common.h> 10 #include <asm/io.h> 11 #include <asm/immap_85xx.h> 12 #include <asm/fsl_serdes.h> 13 14 /* PORDEVSR register */ 15 #define GUTS_PORDEVSR_OFFS 0xc 16 #define GUTS_PORDEVSR_SERDES2_IO_SEL 0x38000000 17 #define GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT 27 18 19 /* SerDes CR0 register */ 20 #define FSL_SRDSCR0_OFFS 0x0 21 #define FSL_SRDSCR0_TXEQA_MASK 0x00007000 22 #define FSL_SRDSCR0_TXEQA_SGMII 0x00004000 23 #define FSL_SRDSCR0_TXEQA_SATA 0x00001000 24 #define FSL_SRDSCR0_TXEQE_MASK 0x00000700 25 #define FSL_SRDSCR0_TXEQE_SGMII 0x00000400 26 #define FSL_SRDSCR0_TXEQE_SATA 0x00000100 27 28 /* SerDes CR1 register */ 29 #define FSL_SRDSCR1_OFFS 0x4 30 #define FSL_SRDSCR1_LANEA_MASK 0x80200000 31 #define FSL_SRDSCR1_LANEA_OFF 0x80200000 32 #define FSL_SRDSCR1_LANEE_MASK 0x08020000 33 #define FSL_SRDSCR1_LANEE_OFF 0x08020000 34 35 /* SerDes CR2 register */ 36 #define FSL_SRDSCR2_OFFS 0x8 37 #define FSL_SRDSCR2_EICA_MASK 0x00001f00 38 #define FSL_SRDSCR2_EICA_SGMII 0x00000400 39 #define FSL_SRDSCR2_EICA_SATA 0x00001400 40 #define FSL_SRDSCR2_EICE_MASK 0x0000001f 41 #define FSL_SRDSCR2_EICE_SGMII 0x00000004 42 #define FSL_SRDSCR2_EICE_SATA 0x00000014 43 44 /* SerDes CR3 register */ 45 #define FSL_SRDSCR3_OFFS 0xc 46 #define FSL_SRDSCR3_LANEA_MASK 0x3f000700 47 #define FSL_SRDSCR3_LANEA_SGMII 0x00000000 48 #define FSL_SRDSCR3_LANEA_SATA 0x15000500 49 #define FSL_SRDSCR3_LANEE_MASK 0x003f0007 50 #define FSL_SRDSCR3_LANEE_SGMII 0x00000000 51 #define FSL_SRDSCR3_LANEE_SATA 0x00150005 52 53 #define SRDS1_MAX_LANES 8 54 #define SRDS2_MAX_LANES 2 55 56 static u32 serdes1_prtcl_map, serdes2_prtcl_map; 57 58 static u8 serdes1_cfg_tbl[][SRDS1_MAX_LANES] = { 59 [0x2] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, NONE, NONE}, 60 [0x3] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1, PCIE1}, 61 [0x5] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2}, 62 [0x7] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE3, PCIE3}, 63 }; 64 65 static u8 serdes2_cfg_tbl[][SRDS2_MAX_LANES] = { 66 [0x1] = {SATA1, SATA2}, 67 [0x3] = {SATA1, NONE}, 68 [0x4] = {SGMII_TSEC1, SGMII_TSEC3}, 69 [0x6] = {SGMII_TSEC1, NONE}, 70 }; 71 72 int is_serdes_configured(enum srds_prtcl device) 73 { 74 int ret = (1 << device) & serdes1_prtcl_map; 75 76 if (ret) 77 return ret; 78 79 return (1 << device) & serdes2_prtcl_map; 80 } 81 82 void fsl_serdes_init(void) 83 { 84 void *guts = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 85 void *sd = (void *)CONFIG_SYS_MPC85xx_SERDES2_ADDR; 86 u32 pordevsr = in_be32(guts + GUTS_PORDEVSR_OFFS); 87 u32 srds1_io_sel, srds2_io_sel; 88 u32 tmp; 89 int lane; 90 91 srds1_io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 92 MPC85xx_PORDEVSR_IO_SEL_SHIFT; 93 94 /* parse the SRDS2_IO_SEL of PORDEVSR */ 95 srds2_io_sel = (pordevsr & GUTS_PORDEVSR_SERDES2_IO_SEL) 96 >> GUTS_PORDEVSR_SERDES2_IO_SEL_SHIFT; 97 98 debug("PORDEVSR[SRDS1_IO_SEL] = %x\n", srds1_io_sel); 99 debug("PORDEVSR[SRDS2_IO_SEL] = %x\n", srds2_io_sel); 100 101 switch (srds2_io_sel) { 102 case 1: /* Lane A - SATA1, Lane E - SATA2 */ 103 /* CR 0 */ 104 tmp = in_be32(sd + FSL_SRDSCR0_OFFS); 105 tmp &= ~FSL_SRDSCR0_TXEQA_MASK; 106 tmp |= FSL_SRDSCR0_TXEQA_SATA; 107 tmp &= ~FSL_SRDSCR0_TXEQE_MASK; 108 tmp |= FSL_SRDSCR0_TXEQE_SATA; 109 out_be32(sd + FSL_SRDSCR0_OFFS, tmp); 110 /* CR 1 */ 111 tmp = in_be32(sd + FSL_SRDSCR1_OFFS); 112 tmp &= ~FSL_SRDSCR1_LANEA_MASK; 113 tmp &= ~FSL_SRDSCR1_LANEE_MASK; 114 out_be32(sd + FSL_SRDSCR1_OFFS, tmp); 115 /* CR 2 */ 116 tmp = in_be32(sd + FSL_SRDSCR2_OFFS); 117 tmp &= ~FSL_SRDSCR2_EICA_MASK; 118 tmp |= FSL_SRDSCR2_EICA_SATA; 119 tmp &= ~FSL_SRDSCR2_EICE_MASK; 120 tmp |= FSL_SRDSCR2_EICE_SATA; 121 out_be32(sd + FSL_SRDSCR2_OFFS, tmp); 122 /* CR 3 */ 123 tmp = in_be32(sd + FSL_SRDSCR3_OFFS); 124 tmp &= ~FSL_SRDSCR3_LANEA_MASK; 125 tmp |= FSL_SRDSCR3_LANEA_SATA; 126 tmp &= ~FSL_SRDSCR3_LANEE_MASK; 127 tmp |= FSL_SRDSCR3_LANEE_SATA; 128 out_be32(sd + FSL_SRDSCR3_OFFS, tmp); 129 break; 130 case 3: /* Lane A - SATA1, Lane E - disabled */ 131 /* CR 0 */ 132 tmp = in_be32(sd + FSL_SRDSCR0_OFFS); 133 tmp &= ~FSL_SRDSCR0_TXEQA_MASK; 134 tmp |= FSL_SRDSCR0_TXEQA_SATA; 135 out_be32(sd + FSL_SRDSCR0_OFFS, tmp); 136 /* CR 1 */ 137 tmp = in_be32(sd + FSL_SRDSCR1_OFFS); 138 tmp &= ~FSL_SRDSCR1_LANEE_MASK; 139 tmp |= FSL_SRDSCR1_LANEE_OFF; 140 out_be32(sd + FSL_SRDSCR1_OFFS, tmp); 141 /* CR 2 */ 142 tmp = in_be32(sd + FSL_SRDSCR2_OFFS); 143 tmp &= ~FSL_SRDSCR2_EICA_MASK; 144 tmp |= FSL_SRDSCR2_EICA_SATA; 145 out_be32(sd + FSL_SRDSCR2_OFFS, tmp); 146 /* CR 3 */ 147 tmp = in_be32(sd + FSL_SRDSCR3_OFFS); 148 tmp &= ~FSL_SRDSCR3_LANEA_MASK; 149 tmp |= FSL_SRDSCR3_LANEA_SATA; 150 out_be32(sd + FSL_SRDSCR3_OFFS, tmp); 151 break; 152 case 4: /* Lane A - eTSEC1 SGMII, Lane E - eTSEC3 SGMII */ 153 /* CR 0 */ 154 tmp = in_be32(sd + FSL_SRDSCR0_OFFS); 155 tmp &= ~FSL_SRDSCR0_TXEQA_MASK; 156 tmp |= FSL_SRDSCR0_TXEQA_SGMII; 157 tmp &= ~FSL_SRDSCR0_TXEQE_MASK; 158 tmp |= FSL_SRDSCR0_TXEQE_SGMII; 159 out_be32(sd + FSL_SRDSCR0_OFFS, tmp); 160 /* CR 1 */ 161 tmp = in_be32(sd + FSL_SRDSCR1_OFFS); 162 tmp &= ~FSL_SRDSCR1_LANEA_MASK; 163 tmp &= ~FSL_SRDSCR1_LANEE_MASK; 164 out_be32(sd + FSL_SRDSCR1_OFFS, tmp); 165 /* CR 2 */ 166 tmp = in_be32(sd + FSL_SRDSCR2_OFFS); 167 tmp &= ~FSL_SRDSCR2_EICA_MASK; 168 tmp |= FSL_SRDSCR2_EICA_SGMII; 169 tmp &= ~FSL_SRDSCR2_EICE_MASK; 170 tmp |= FSL_SRDSCR2_EICE_SGMII; 171 out_be32(sd + FSL_SRDSCR2_OFFS, tmp); 172 /* CR 3 */ 173 tmp = in_be32(sd + FSL_SRDSCR3_OFFS); 174 tmp &= ~FSL_SRDSCR3_LANEA_MASK; 175 tmp |= FSL_SRDSCR3_LANEA_SGMII; 176 tmp &= ~FSL_SRDSCR3_LANEE_MASK; 177 tmp |= FSL_SRDSCR3_LANEE_SGMII; 178 out_be32(sd + FSL_SRDSCR3_OFFS, tmp); 179 break; 180 case 6: /* Lane A - eTSEC1 SGMII, Lane E - disabled */ 181 /* CR 0 */ 182 tmp = in_be32(sd + FSL_SRDSCR0_OFFS); 183 tmp &= ~FSL_SRDSCR0_TXEQA_MASK; 184 tmp |= FSL_SRDSCR0_TXEQA_SGMII; 185 out_be32(sd + FSL_SRDSCR0_OFFS, tmp); 186 /* CR 1 */ 187 tmp = in_be32(sd + FSL_SRDSCR1_OFFS); 188 tmp &= ~FSL_SRDSCR1_LANEE_MASK; 189 tmp |= FSL_SRDSCR1_LANEE_OFF; 190 out_be32(sd + FSL_SRDSCR1_OFFS, tmp); 191 /* CR 2 */ 192 tmp = in_be32(sd + FSL_SRDSCR2_OFFS); 193 tmp &= ~FSL_SRDSCR2_EICA_MASK; 194 tmp |= FSL_SRDSCR2_EICA_SGMII; 195 out_be32(sd + FSL_SRDSCR2_OFFS, tmp); 196 /* CR 3 */ 197 tmp = in_be32(sd + FSL_SRDSCR3_OFFS); 198 tmp &= ~FSL_SRDSCR3_LANEA_MASK; 199 tmp |= FSL_SRDSCR3_LANEA_SGMII; 200 out_be32(sd + FSL_SRDSCR3_OFFS, tmp); 201 break; 202 case 7: /* Lane A - disabled, Lane E - disabled */ 203 /* CR 1 */ 204 tmp = in_be32(sd + FSL_SRDSCR1_OFFS); 205 tmp &= ~FSL_SRDSCR1_LANEA_MASK; 206 tmp |= FSL_SRDSCR1_LANEA_OFF; 207 tmp &= ~FSL_SRDSCR1_LANEE_MASK; 208 tmp |= FSL_SRDSCR1_LANEE_OFF; 209 out_be32(sd + FSL_SRDSCR1_OFFS, tmp); 210 break; 211 default: 212 break; 213 } 214 215 if (srds1_io_sel >= ARRAY_SIZE(serdes1_cfg_tbl)) { 216 printf("Invalid PORDEVSR[SRDS1_IO_SEL] = %d\n", srds1_io_sel); 217 return; 218 } 219 for (lane = 0; lane < SRDS1_MAX_LANES; lane++) { 220 enum srds_prtcl lane_prtcl = serdes1_cfg_tbl[srds1_io_sel][lane]; 221 serdes1_prtcl_map |= (1 << lane_prtcl); 222 } 223 224 if (srds2_io_sel >= ARRAY_SIZE(serdes2_cfg_tbl)) { 225 printf("Invalid PORDEVSR[SRDS2_IO_SEL] = %d\n", srds2_io_sel); 226 return; 227 } 228 229 for (lane = 0; lane < SRDS2_MAX_LANES; lane++) { 230 enum srds_prtcl lane_prtcl = serdes2_cfg_tbl[srds2_io_sel][lane]; 231 serdes2_prtcl_map |= (1 << lane_prtcl); 232 } 233 } 234