1 /* 2 * Copyright 2010-2011 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <linux/compiler.h> 10 #include <fsl_errata.h> 11 #include <asm/processor.h> 12 #include <fsl_usb.h> 13 #include "fsl_corenet_serdes.h" 14 15 #ifdef CONFIG_SYS_FSL_ERRATUM_A004849 16 /* 17 * This work-around is implemented in PBI, so just check to see if the 18 * work-around was actually applied. To do this, we check for specific data 19 * at specific addresses in DCSR. 20 * 21 * Array offsets[] contains a list of offsets within DCSR. According to the 22 * erratum document, the value at each offset should be 2. 23 */ 24 static void check_erratum_a4849(uint32_t svr) 25 { 26 void __iomem *dcsr = (void *)CONFIG_SYS_DCSRBAR + 0xb0000; 27 unsigned int i; 28 29 #if defined(CONFIG_ARCH_P2041) || defined(CONFIG_ARCH_P3041) 30 static const uint8_t offsets[] = { 31 0x50, 0x54, 0x58, 0x90, 0x94, 0x98 32 }; 33 #endif 34 #ifdef CONFIG_ARCH_P4080 35 static const uint8_t offsets[] = { 36 0x60, 0x64, 0x68, 0x6c, 0xa0, 0xa4, 0xa8, 0xac 37 }; 38 #endif 39 uint32_t x108; /* The value that should be at offset 0x108 */ 40 41 for (i = 0; i < ARRAY_SIZE(offsets); i++) { 42 if (in_be32(dcsr + offsets[i]) != 2) { 43 printf("Work-around for Erratum A004849 is not enabled\n"); 44 return; 45 } 46 } 47 48 #if defined(CONFIG_ARCH_P2041) || defined(CONFIG_ARCH_P3041) 49 x108 = 0x12; 50 #endif 51 52 #ifdef CONFIG_ARCH_P4080 53 /* 54 * For P4080, the erratum document says that the value at offset 0x108 55 * should be 0x12 on rev2, or 0x1c on rev3. 56 */ 57 if (SVR_MAJ(svr) == 2) 58 x108 = 0x12; 59 if (SVR_MAJ(svr) == 3) 60 x108 = 0x1c; 61 #endif 62 63 if (in_be32(dcsr + 0x108) != x108) { 64 printf("Work-around for Erratum A004849 is not enabled\n"); 65 return; 66 } 67 68 /* Everything matches, so the erratum work-around was applied */ 69 70 printf("Work-around for Erratum A004849 enabled\n"); 71 } 72 #endif 73 74 #ifdef CONFIG_SYS_FSL_ERRATUM_A004580 75 /* 76 * This work-around is implemented in PBI, so just check to see if the 77 * work-around was actually applied. To do this, we check for specific data 78 * at specific addresses in the SerDes register block. 79 * 80 * The work-around says that for each SerDes lane, write BnTTLCRy0 = 81 * 0x1B00_0001, Register 2 = 0x0088_0000, and Register 3 = 0x4000_0000. 82 83 */ 84 static void check_erratum_a4580(uint32_t svr) 85 { 86 const serdes_corenet_t __iomem *srds_regs = 87 (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; 88 unsigned int lane; 89 90 for (lane = 0; lane < SRDS_MAX_LANES; lane++) { 91 if (serdes_lane_enabled(lane)) { 92 const struct serdes_lane __iomem *srds_lane = 93 &srds_regs->lane[serdes_get_lane_idx(lane)]; 94 95 /* 96 * Verify that the values we were supposed to write in 97 * the PBI are actually there. Also, the lower 15 98 * bits of res4[3] should be the same as the upper 15 99 * bits of res4[1]. 100 */ 101 if ((in_be32(&srds_lane->ttlcr0) != 0x1b000001) || 102 (in_be32(&srds_lane->res4[1]) != 0x880000) || 103 (in_be32(&srds_lane->res4[3]) != 0x40000044)) { 104 printf("Work-around for Erratum A004580 is " 105 "not enabled\n"); 106 return; 107 } 108 } 109 } 110 111 /* Everything matches, so the erratum work-around was applied */ 112 113 printf("Work-around for Erratum A004580 enabled\n"); 114 } 115 #endif 116 117 #ifdef CONFIG_SYS_FSL_ERRATUM_A007212 118 /* 119 * This workaround can be implemented in PBI, or by u-boot. 120 */ 121 static void check_erratum_a007212(void) 122 { 123 u32 __iomem *plldgdcr = (void *)(CONFIG_SYS_DCSRBAR + 0x21c20); 124 125 if (in_be32(plldgdcr) & 0x1fe) { 126 /* check if PLL ratio is set by workaround */ 127 puts("Work-around for Erratum A007212 enabled\n"); 128 } 129 } 130 #endif 131 132 static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 133 { 134 #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 135 extern int enable_cpu_a011_workaround; 136 #endif 137 __maybe_unused u32 svr = get_svr(); 138 139 #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_SYS_FSL_ERRATUM_SATA_A001) 140 if (IS_SVR_REV(svr, 1, 0)) { 141 switch (SVR_SOC_VER(svr)) { 142 case SVR_P1013: 143 case SVR_P1022: 144 puts("Work-around for Erratum SATA A001 enabled\n"); 145 } 146 } 147 #endif 148 149 #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8) 150 puts("Work-around for Erratum SERDES8 enabled\n"); 151 #endif 152 #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) 153 puts("Work-around for Erratum SERDES9 enabled\n"); 154 #endif 155 #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES_A005) 156 puts("Work-around for Erratum SERDES-A005 enabled\n"); 157 #endif 158 #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) 159 if (SVR_MAJ(svr) < 3) 160 puts("Work-around for Erratum CPU22 enabled\n"); 161 #endif 162 #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 163 /* 164 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 165 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 166 * The SVR has been checked by cpu_init_r(). 167 */ 168 if (enable_cpu_a011_workaround) 169 puts("Work-around for Erratum CPU-A011 enabled\n"); 170 #endif 171 #if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999) 172 puts("Work-around for Erratum CPU-A003999 enabled\n"); 173 #endif 174 #if defined(CONFIG_SYS_FSL_ERRATUM_DDR_A003474) 175 puts("Work-around for Erratum DDR-A003474 enabled\n"); 176 #endif 177 #if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN) 178 puts("Work-around for DDR MSYNC_IN Erratum enabled\n"); 179 #endif 180 #if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC111) 181 puts("Work-around for Erratum ESDHC111 enabled\n"); 182 #endif 183 #ifdef CONFIG_SYS_FSL_ERRATUM_A004468 184 puts("Work-around for Erratum A004468 enabled\n"); 185 #endif 186 #if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC135) 187 puts("Work-around for Erratum ESDHC135 enabled\n"); 188 #endif 189 #if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC13) 190 if (SVR_MAJ(svr) < 3) 191 puts("Work-around for Erratum ESDHC13 enabled\n"); 192 #endif 193 #if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC_A001) 194 puts("Work-around for Erratum ESDHC-A001 enabled\n"); 195 #endif 196 #ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A002 197 puts("Work-around for Erratum CPC-A002 enabled\n"); 198 #endif 199 #ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A003 200 puts("Work-around for Erratum CPC-A003 enabled\n"); 201 #endif 202 #ifdef CONFIG_SYS_FSL_ERRATUM_ELBC_A001 203 puts("Work-around for Erratum ELBC-A001 enabled\n"); 204 #endif 205 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003 206 puts("Work-around for Erratum DDR-A003 enabled\n"); 207 #endif 208 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115 209 puts("Work-around for Erratum DDR115 enabled\n"); 210 #endif 211 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 212 puts("Work-around for Erratum DDR111 enabled\n"); 213 puts("Work-around for Erratum DDR134 enabled\n"); 214 #endif 215 #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769 216 puts("Work-around for Erratum IFC-A002769 enabled\n"); 217 #endif 218 #ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549 219 puts("Work-around for Erratum P1010-A003549 enabled\n"); 220 #endif 221 #ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399 222 puts("Work-around for Erratum IFC A-003399 enabled\n"); 223 #endif 224 #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 225 if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) 226 puts("Work-around for Erratum NMG DDR120 enabled\n"); 227 #endif 228 #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 229 puts("Work-around for Erratum NMG_LBC103 enabled\n"); 230 #endif 231 #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 232 if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) 233 puts("Work-around for Erratum NMG ETSEC129 enabled\n"); 234 #endif 235 #ifdef CONFIG_SYS_FSL_ERRATUM_A004508 236 puts("Work-around for Erratum A004508 enabled\n"); 237 #endif 238 #ifdef CONFIG_SYS_FSL_ERRATUM_A004510 239 puts("Work-around for Erratum A004510 enabled\n"); 240 #endif 241 #ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034 242 puts("Work-around for Erratum SRIO-A004034 enabled\n"); 243 #endif 244 #ifdef CONFIG_SYS_FSL_ERRATUM_A_004934 245 puts("Work-around for Erratum A004934 enabled\n"); 246 #endif 247 #ifdef CONFIG_SYS_FSL_ERRATUM_A005871 248 if (IS_SVR_REV(svr, 1, 0)) 249 puts("Work-around for Erratum A005871 enabled\n"); 250 #endif 251 #ifdef CONFIG_SYS_FSL_ERRATUM_A006475 252 if (SVR_MAJ(get_svr()) == 1) 253 puts("Work-around for Erratum A006475 enabled\n"); 254 #endif 255 #ifdef CONFIG_SYS_FSL_ERRATUM_A006384 256 if (SVR_MAJ(get_svr()) == 1) 257 puts("Work-around for Erratum A006384 enabled\n"); 258 #endif 259 #ifdef CONFIG_SYS_FSL_ERRATUM_A004849 260 /* This work-around is implemented in PBI, so just check for it */ 261 check_erratum_a4849(svr); 262 #endif 263 #ifdef CONFIG_SYS_FSL_ERRATUM_A004580 264 /* This work-around is implemented in PBI, so just check for it */ 265 check_erratum_a4580(svr); 266 #endif 267 #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003 268 puts("Work-around for Erratum PCIe-A003 enabled\n"); 269 #endif 270 #ifdef CONFIG_SYS_FSL_ERRATUM_USB14 271 puts("Work-around for Erratum USB14 enabled\n"); 272 #endif 273 #ifdef CONFIG_SYS_FSL_ERRATUM_A007186 274 if (has_erratum_a007186()) 275 puts("Work-around for Erratum A007186 enabled\n"); 276 #endif 277 #ifdef CONFIG_SYS_FSL_ERRATUM_A006593 278 puts("Work-around for Erratum A006593 enabled\n"); 279 #endif 280 #ifdef CONFIG_SYS_FSL_ERRATUM_A006379 281 if (has_erratum_a006379()) 282 puts("Work-around for Erratum A006379 enabled\n"); 283 #endif 284 #ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571 285 if (IS_SVR_REV(svr, 1, 0)) 286 puts("Work-around for Erratum A003571 enabled\n"); 287 #endif 288 #ifdef CONFIG_SYS_FSL_ERRATUM_A005812 289 puts("Work-around for Erratum A-005812 enabled\n"); 290 #endif 291 #ifdef CONFIG_SYS_FSL_ERRATUM_A005125 292 puts("Work-around for Erratum A005125 enabled\n"); 293 #endif 294 #ifdef CONFIG_SYS_FSL_ERRATUM_A007075 295 if (has_erratum_a007075()) 296 puts("Work-around for Erratum A007075 enabled\n"); 297 #endif 298 #ifdef CONFIG_SYS_FSL_ERRATUM_A007798 299 if (has_erratum_a007798()) 300 puts("Work-around for Erratum A007798 enabled\n"); 301 #endif 302 #ifdef CONFIG_SYS_FSL_ERRATUM_A004477 303 if (has_erratum_a004477()) 304 puts("Work-around for Erratum A004477 enabled\n"); 305 #endif 306 #ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447 307 if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) || 308 (SVR_REV(svr) <= CONFIG_SYS_FSL_A004447_SVR_REV)) 309 puts("Work-around for Erratum I2C-A004447 enabled\n"); 310 #endif 311 #ifdef CONFIG_SYS_FSL_ERRATUM_A006261 312 if (has_erratum_a006261()) 313 puts("Work-around for Erratum A006261 enabled\n"); 314 #endif 315 #ifdef CONFIG_SYS_FSL_ERRATUM_A007212 316 check_erratum_a007212(); 317 #endif 318 #ifdef CONFIG_SYS_FSL_ERRATUM_A005434 319 puts("Work-around for Erratum A-005434 enabled\n"); 320 #endif 321 #if defined(CONFIG_SYS_FSL_ERRATUM_A008044) && \ 322 defined(CONFIG_A008044_WORKAROUND) 323 if (IS_SVR_REV(svr, 1, 0)) 324 puts("Work-around for Erratum A-008044 enabled\n"); 325 #endif 326 #if defined(CONFIG_SYS_FSL_B4860QDS_XFI_ERR) && \ 327 (defined(CONFIG_TARGET_B4860QDS) || defined(CONFIG_TARGET_B4420QDS)) 328 puts("Work-around for Erratum XFI on B4860QDS enabled\n"); 329 #endif 330 #ifdef CONFIG_SYS_FSL_ERRATUM_A009663 331 puts("Work-around for Erratum A009663 enabled\n"); 332 #endif 333 334 return 0; 335 } 336 337 U_BOOT_CMD( 338 errata, 1, 0, do_errata, 339 "Report errata workarounds", 340 "" 341 ); 342