cmd_errata.c 10.0 KB
Newer Older
1
/*
2
 * Copyright 2010-2011 Freescale Semiconductor, Inc.
3
 *
4
 * SPDX-License-Identifier:	GPL-2.0+
5 6 7 8 9
 */

#include <common.h>
#include <command.h>
#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 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
/*
 * This work-around is implemented in PBI, so just check to see if the
 * work-around was actually applied.  To do this, we check for specific data
 * at specific addresses in DCSR.
 *
 * Array offsets[] contains a list of offsets within DCSR.  According to the
 * erratum document, the value at each offset should be 2.
 */
static void check_erratum_a4849(uint32_t svr)
{
	void __iomem *dcsr = (void *)CONFIG_SYS_DCSRBAR + 0xb0000;
	unsigned int i;

#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
	static const uint8_t offsets[] = {
		0x50, 0x54, 0x58, 0x90, 0x94, 0x98
	};
#endif
#ifdef CONFIG_PPC_P4080
	static const uint8_t offsets[] = {
		0x60, 0x64, 0x68, 0x6c, 0xa0, 0xa4, 0xa8, 0xac
	};
#endif
	uint32_t x108; /* The value that should be at offset 0x108 */

	for (i = 0; i < ARRAY_SIZE(offsets); i++) {
		if (in_be32(dcsr + offsets[i]) != 2) {
			printf("Work-around for Erratum A004849 is not enabled\n");
			return;
		}
	}

#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
	x108 = 0x12;
#endif

#ifdef CONFIG_PPC_P4080
	/*
	 * For P4080, the erratum document says that the value at offset 0x108
	 * should be 0x12 on rev2, or 0x1c on rev3.
	 */
	if (SVR_MAJ(svr) == 2)
		x108 = 0x12;
	if (SVR_MAJ(svr) == 3)
		x108 = 0x1c;
#endif

	if (in_be32(dcsr + 0x108) != x108) {
		printf("Work-around for Erratum A004849 is not enabled\n");
		return;
	}

	/* Everything matches, so the erratum work-around was applied */

	printf("Work-around for Erratum A004849 enabled\n");
}
#endif

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
/*
 * This work-around is implemented in PBI, so just check to see if the
 * work-around was actually applied.  To do this, we check for specific data
 * at specific addresses in the SerDes register block.
 *
 * The work-around says that for each SerDes lane, write BnTTLCRy0 =
 * 0x1B00_0001, Register 2 = 0x0088_0000, and Register 3 = 0x4000_0000.

 */
static void check_erratum_a4580(uint32_t svr)
{
	const serdes_corenet_t __iomem *srds_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	unsigned int lane;

	for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
		if (serdes_lane_enabled(lane)) {
			const struct serdes_lane __iomem *srds_lane =
				&srds_regs->lane[serdes_get_lane_idx(lane)];

			/*
			 * Verify that the values we were supposed to write in
			 * the PBI are actually there.  Also, the lower 15
			 * bits of res4[3] should be the same as the upper 15
			 * bits of res4[1].
			 */
			if ((in_be32(&srds_lane->ttlcr0) != 0x1b000001) ||
			    (in_be32(&srds_lane->res4[1]) != 0x880000) ||
			    (in_be32(&srds_lane->res4[3]) != 0x40000044)) {
				printf("Work-around for Erratum A004580 is "
				       "not enabled\n");
				return;
			}
		}
	}

	/* Everything matches, so the erratum work-around was applied */

	printf("Work-around for Erratum A004580 enabled\n");
}
#endif

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
/*
 * This workaround can be implemented in PBI, or by u-boot.
 */
static void check_erratum_a007212(void)
{
	u32 __iomem *plldgdcr = (void *)(CONFIG_SYS_DCSRBAR + 0x21c20);

	if (in_be32(plldgdcr) & 0x1fe) {
		/* check if PLL ratio is set by workaround */
		puts("Work-around for Erratum A007212 enabled\n");
	}
}
#endif

132 133
static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
134 135 136
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
	extern int enable_cpu_a011_workaround;
#endif
137 138 139 140 141 142 143 144 145 146 147 148
	__maybe_unused u32 svr = get_svr();

#if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
	if (IS_SVR_REV(svr, 1, 0)) {
		switch (SVR_SOC_VER(svr)) {
		case SVR_P1013:
		case SVR_P1022:
			puts("Work-around for Erratum SATA A001 enabled\n");
		}
	}
#endif

149 150 151
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8)
	puts("Work-around for Erratum SERDES8 enabled\n");
#endif
152 153 154
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9)
	puts("Work-around for Erratum SERDES9 enabled\n");
#endif
155 156 157
#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES_A005)
	puts("Work-around for Erratum SERDES-A005 enabled\n");
#endif
158
#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22)
159 160
	if (SVR_MAJ(svr) < 3)
		puts("Work-around for Erratum CPU22 enabled\n");
161
#endif
162 163 164 165
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
	/*
	 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
	 * 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 170
		puts("Work-around for Erratum CPU-A011 enabled\n");
#endif
171 172 173
#if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999)
	puts("Work-around for Erratum CPU-A003999 enabled\n");
#endif
174
#if defined(CONFIG_SYS_FSL_ERRATUM_DDR_A003474)
175
	puts("Work-around for Erratum DDR-A003474 enabled\n");
176
#endif
177 178
#if defined(CONFIG_SYS_FSL_ERRATUM_DDR_MSYNC_IN)
	puts("Work-around for DDR MSYNC_IN Erratum enabled\n");
179 180 181
#endif
#if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC111)
	puts("Work-around for Erratum ESDHC111 enabled\n");
182
#endif
183 184 185
#ifdef CONFIG_SYS_FSL_ERRATUM_A004468
	puts("Work-around for Erratum A004468 enabled\n");
#endif
186 187
#if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC135)
	puts("Work-around for Erratum ESDHC135 enabled\n");
188
#endif
189 190 191
#if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC13)
	if (SVR_MAJ(svr) < 3)
		puts("Work-around for Erratum ESDHC13 enabled\n");
192
#endif
193 194 195
#if defined(CONFIG_SYS_FSL_ERRATUM_ESDHC_A001)
	puts("Work-around for Erratum ESDHC-A001 enabled\n");
#endif
196 197 198
#ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A002
	puts("Work-around for Erratum CPC-A002 enabled\n");
#endif
199 200 201
#ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A003
	puts("Work-around for Erratum CPC-A003 enabled\n");
#endif
202 203 204
#ifdef CONFIG_SYS_FSL_ERRATUM_ELBC_A001
	puts("Work-around for Erratum ELBC-A001 enabled\n");
#endif
205 206 207
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
	puts("Work-around for Erratum DDR-A003 enabled\n");
#endif
208 209
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115
	puts("Work-around for Erratum DDR115 enabled\n");
210 211 212 213
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
	puts("Work-around for Erratum DDR111 enabled\n");
	puts("Work-around for Erratum DDR134 enabled\n");
214 215 216
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769
	puts("Work-around for Erratum IFC-A002769 enabled\n");
217 218 219
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549
	puts("Work-around for Erratum P1010-A003549 enabled\n");
220 221 222
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A003399
	puts("Work-around for Erratum IFC A-003399 enabled\n");
223 224 225 226
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120
	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
		puts("Work-around for Erratum NMG DDR120 enabled\n");
227 228 229
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103
	puts("Work-around for Erratum NMG_LBC103 enabled\n");
230 231 232 233
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129
	if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0))
		puts("Work-around for Erratum NMG ETSEC129 enabled\n");
234
#endif
235 236 237
#ifdef CONFIG_SYS_FSL_ERRATUM_A004508
	puts("Work-around for Erratum A004508 enabled\n");
#endif
238 239
#ifdef CONFIG_SYS_FSL_ERRATUM_A004510
	puts("Work-around for Erratum A004510 enabled\n");
240 241 242
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
	puts("Work-around for Erratum SRIO-A004034 enabled\n");
243 244 245
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A_004934
	puts("Work-around for Erratum A004934 enabled\n");
246
#endif
247 248 249 250
#ifdef CONFIG_SYS_FSL_ERRATUM_A005871
	if (IS_SVR_REV(svr, 1, 0))
		puts("Work-around for Erratum A005871 enabled\n");
#endif
251 252 253 254 255 256 257 258
#ifdef CONFIG_SYS_FSL_ERRATUM_A006475
	if (SVR_MAJ(get_svr()) == 1)
		puts("Work-around for Erratum A006475 enabled\n");
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A006384
	if (SVR_MAJ(get_svr()) == 1)
		puts("Work-around for Erratum A006384 enabled\n");
#endif
259 260 261
#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
	/* This work-around is implemented in PBI, so just check for it */
	check_erratum_a4849(svr);
262 263 264 265
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
	/* This work-around is implemented in PBI, so just check for it */
	check_erratum_a4580(svr);
266 267 268
#endif
#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
	puts("Work-around for Erratum PCIe-A003 enabled\n");
269 270 271
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_USB14
	puts("Work-around for Erratum USB14 enabled\n");
272
#endif
273
#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
274 275
	if (has_erratum_a007186())
		puts("Work-around for Erratum A007186 enabled\n");
276
#endif
277 278
#ifdef CONFIG_SYS_FSL_ERRATUM_A006593
	puts("Work-around for Erratum A006593 enabled\n");
279
#endif
280 281 282 283
#ifdef CONFIG_SYS_FSL_ERRATUM_A006379
	if (has_erratum_a006379())
		puts("Work-around for Erratum A006379 enabled\n");
#endif
284 285 286 287
#ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
	if (IS_SVR_REV(svr, 1, 0))
		puts("Work-around for Erratum A003571 enabled\n");
#endif
288 289
#ifdef CONFIG_SYS_FSL_ERRATUM_A005812
	puts("Work-around for Erratum A-005812 enabled\n");
290
#endif
291 292 293
#ifdef CONFIG_SYS_FSL_ERRATUM_A005125
	puts("Work-around for Erratum A005125 enabled\n");
#endif
294 295 296 297
#ifdef CONFIG_SYS_FSL_ERRATUM_A007075
	if (has_erratum_a007075())
		puts("Work-around for Erratum A007075 enabled\n");
#endif
298 299 300 301
#ifdef CONFIG_SYS_FSL_ERRATUM_A007798
	if (has_erratum_a007798())
		puts("Work-around for Erratum A007798 enabled\n");
#endif
302 303 304 305
#ifdef CONFIG_SYS_FSL_ERRATUM_A004477
	if (has_erratum_a004477())
		puts("Work-around for Erratum A004477 enabled\n");
#endif
306 307 308 309
#ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
	if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
	    (SVR_REV(svr) <= CONFIG_SYS_FSL_A004447_SVR_REV))
		puts("Work-around for Erratum I2C-A004447 enabled\n");
310 311 312 313
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
	if (has_erratum_a006261())
		puts("Work-around for Erratum A006261 enabled\n");
314
#endif
315 316 317
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
	check_erratum_a007212();
#endif
318 319 320
#ifdef CONFIG_SYS_FSL_ERRATUM_A005434
	puts("Work-around for Erratum A-005434 enabled\n");
#endif
321 322
#if defined(CONFIG_SYS_FSL_ERRATUM_A008044) && \
	defined(CONFIG_A008044_WORKAROUND)
323 324
	if (IS_SVR_REV(svr, 1, 0))
		puts("Work-around for Erratum A-008044 enabled\n");
325
#endif
326 327 328 329
#if defined(CONFIG_SYS_FSL_B4860QDS_XFI_ERR) && defined(CONFIG_B4860QDS)
	puts("Work-around for Erratum XFI on B4860QDS enabled\n");
#endif

330 331 332 333 334 335 336 337
	return 0;
}

U_BOOT_CMD(
	errata, 1, 0,	do_errata,
	"Report errata workarounds",
	""
);