1/*-
2 * Copyright (C) 2008 Semihalf, Rafal Jaworowski
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 11 unchanged lines hidden (view full) ---
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/powerpc/mpc85xx/mpc85xx.c 292903 2015-12-30 03:43:25Z jhibbits $");
29
30#include "opt_platform.h"
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/lock.h>
34#include <sys/mutex.h>
35#include <sys/reboot.h>
36#include <sys/rman.h>
37
38#include <vm/vm.h>
39#include <vm/vm_param.h>
40#include <vm/pmap.h>
41
42#include <machine/cpu.h>
43#include <machine/cpufunc.h>
44#include <machine/machdep.h>
45#include <machine/pio.h>
46#include <machine/spr.h>
47
48#include <dev/fdt/fdt_common.h>
49
50#include <dev/fdt/fdt_common.h>
51#include <dev/ofw/ofw_bus.h>
52#include <dev/ofw/ofw_bus_subr.h>
53#include <dev/ofw/openfirm.h>
54
55#include <powerpc/mpc85xx/mpc85xx.h>
56
57
58/*
59 * MPC85xx system specific routines
60 */
61
62uint32_t
--- 189 unchanged lines hidden (view full) ---
252 }
253 if (rv == 0) {
254 *trgt_mem = trgt;
255 *trgt_io = trgt;
256 }
257 return (rv);
258}
259
260static void
261l3cache_inval(void)
262{
263
264 /* Flash invalidate the CPC and clear all the locks */
265 ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_FI |
266 OCP85XX_CPC_CSR0_LFC);
267 while (ccsr_read4(OCP85XX_CPC_CSR0) & (OCP85XX_CPC_CSR0_FI |
268 OCP85XX_CPC_CSR0_LFC))
269 ;
270}
271
272static void
273l3cache_enable(void)
274{
275
276 ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_CE |
277 OCP85XX_CPC_CSR0_PE);
278 /* Read back to sync write */
279 ccsr_read4(OCP85XX_CPC_CSR0);
280}
281
282void
283mpc85xx_enable_l3_cache(void)
284{
285 uint32_t csr, size, ver;
286
287 /* Enable L3 CoreNet Platform Cache (CPC) */
288 ver = SVR_VER(mfspr(SPR_SVR));
289 if (ver == SVR_P2041 || ver == SVR_P2041E || ver == SVR_P3041 ||
290 ver == SVR_P3041E || ver == SVR_P5020 || ver == SVR_P5020E) {
291 csr = ccsr_read4(OCP85XX_CPC_CSR0);
292 if ((csr & OCP85XX_CPC_CSR0_CE) == 0) {
293 l3cache_inval();
294 l3cache_enable();
295 }
296
297 csr = ccsr_read4(OCP85XX_CPC_CSR0);
298 if ((boothowto & RB_VERBOSE) != 0 ||
299 (csr & OCP85XX_CPC_CSR0_CE) == 0) {
300 size = OCP85XX_CPC_CFG0_SZ_K(ccsr_read4(OCP85XX_CPC_CFG0));
301 printf("L3 Corenet Platform Cache: %d KB %sabled\n",
302 size, (csr & OCP85XX_CPC_CSR0_CE) == 0 ?
303 "dis" : "en");
304 }
305 }
306}
307
308static void
309mpc85xx_dataloss_erratum_spr976(void)
310{
311 uint32_t svr = SVR_VER(mfspr(SPR_SVR));
312
313 /* Ignore whether it's the E variant */
314 svr &= ~0x8;
315
316 if (svr != SVR_P3041 && svr != SVR_P4040 &&
317 svr != SVR_P4080 && svr != SVR_P5020)
318 return;
319
320 mb();
321 isync();
322 mtspr(976, (mfspr(976) & ~0x1f8) | 0x48);
323 isync();
324}
325
326static vm_offset_t
327mpc85xx_map_dcsr(void)
328{
329 phandle_t node;
330 u_long b, s;
331 int err;
332
333 /*
334 * Try to access the dcsr node directly i.e. through /aliases/.
335 */
336 if ((node = OF_finddevice("dcsr")) != -1)
337 if (fdt_is_compatible_strict(node, "fsl,dcsr"))
338 goto moveon;
339 /*
340 * Find the node the long way.
341 */
342 if ((node = OF_finddevice("/")) == -1)
343 return (ENXIO);
344
345 if ((node = ofw_bus_find_compatible(node, "fsl,dcsr")) == 0)
346 return (ENXIO);
347
348moveon:
349 err = fdt_get_range(node, 0, &b, &s);
350
351 if (err != 0)
352 return (err);
353
354#ifdef QORIQ_DPAA
355 law_enable(OCP85XX_TGTIF_DCSR, b, 0x400000);
356#endif
357 return pmap_early_io_map(b, 0x400000);
358}
359
360
361
362void
363mpc85xx_fix_errata(vm_offset_t va_ccsr)
364{
365 uint32_t svr = SVR_VER(mfspr(SPR_SVR));
366 vm_offset_t va_dcsr;
367
368 /* Ignore whether it's the E variant */
369 svr &= ~0x8;
370
371 if (svr != SVR_P3041 && svr != SVR_P4040 &&
372 svr != SVR_P4080 && svr != SVR_P5020)
373 return;
374
375 if (mfmsr() & PSL_EE)
376 return;
377
378 /*
379 * dcsr region need to be mapped thus patch can refer to.
380 * Align dcsr right after ccsbar.
381 */
382 va_dcsr = mpc85xx_map_dcsr();
383 if (va_dcsr == 0)
384 goto err;
385
386 /*
387 * As A004510 errata specify, special purpose register 976
388 * SPR976[56:60] = 6'b001001 must be set. e500mc core reference manual
389 * does not document SPR976 register.
390 */
391 mpc85xx_dataloss_erratum_spr976();
392
393 /*
394 * Specific settings in the CCF and core platform cache (CPC)
395 * are required to reconfigure the CoreNet coherency fabric.
396 * The register settings that should be updated are described
397 * in errata and relay on base address, offset and updated value.
398 * Special conditions must be used to update these registers correctly.
399 */
400 dataloss_erratum_access(va_dcsr + 0xb0e08, 0xe0201800);
401 dataloss_erratum_access(va_dcsr + 0xb0e18, 0xe0201800);
402 dataloss_erratum_access(va_dcsr + 0xb0e38, 0xe0400000);
403 dataloss_erratum_access(va_dcsr + 0xb0008, 0x00900000);
404 dataloss_erratum_access(va_dcsr + 0xb0e40, 0xe00a0000);
405
406 switch (svr) {
407 case SVR_P5020:
408 dataloss_erratum_access(va_ccsr + 0x18600, 0xc0000000);
409 break;
410 case SVR_P4040:
411 case SVR_P4080:
412 dataloss_erratum_access(va_ccsr + 0x18600, 0xff000000);
413 break;
414 case SVR_P3041:
415 dataloss_erratum_access(va_ccsr + 0x18600, 0xf0000000);
416 }
417 dataloss_erratum_access(va_ccsr + 0x10f00, 0x415e5000);
418 dataloss_erratum_access(va_ccsr + 0x11f00, 0x415e5000);
419
420err:
421 return;
422}
2 * Copyright (C) 2008 Semihalf, Rafal Jaworowski
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 11 unchanged lines hidden (view full) ---
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/powerpc/mpc85xx/mpc85xx.c 292903 2015-12-30 03:43:25Z jhibbits $");
29
30#include "opt_platform.h"
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/lock.h>
34#include <sys/mutex.h>
35#include <sys/reboot.h>
36#include <sys/rman.h>
37
38#include <vm/vm.h>
39#include <vm/vm_param.h>
40#include <vm/pmap.h>
41
42#include <machine/cpu.h>
43#include <machine/cpufunc.h>
44#include <machine/machdep.h>
45#include <machine/pio.h>
46#include <machine/spr.h>
47
48#include <dev/fdt/fdt_common.h>
49
50#include <dev/fdt/fdt_common.h>
51#include <dev/ofw/ofw_bus.h>
52#include <dev/ofw/ofw_bus_subr.h>
53#include <dev/ofw/openfirm.h>
54
55#include <powerpc/mpc85xx/mpc85xx.h>
56
57
58/*
59 * MPC85xx system specific routines
60 */
61
62uint32_t
--- 189 unchanged lines hidden (view full) ---
252 }
253 if (rv == 0) {
254 *trgt_mem = trgt;
255 *trgt_io = trgt;
256 }
257 return (rv);
258}
259
260static void
261l3cache_inval(void)
262{
263
264 /* Flash invalidate the CPC and clear all the locks */
265 ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_FI |
266 OCP85XX_CPC_CSR0_LFC);
267 while (ccsr_read4(OCP85XX_CPC_CSR0) & (OCP85XX_CPC_CSR0_FI |
268 OCP85XX_CPC_CSR0_LFC))
269 ;
270}
271
272static void
273l3cache_enable(void)
274{
275
276 ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_CE |
277 OCP85XX_CPC_CSR0_PE);
278 /* Read back to sync write */
279 ccsr_read4(OCP85XX_CPC_CSR0);
280}
281
282void
283mpc85xx_enable_l3_cache(void)
284{
285 uint32_t csr, size, ver;
286
287 /* Enable L3 CoreNet Platform Cache (CPC) */
288 ver = SVR_VER(mfspr(SPR_SVR));
289 if (ver == SVR_P2041 || ver == SVR_P2041E || ver == SVR_P3041 ||
290 ver == SVR_P3041E || ver == SVR_P5020 || ver == SVR_P5020E) {
291 csr = ccsr_read4(OCP85XX_CPC_CSR0);
292 if ((csr & OCP85XX_CPC_CSR0_CE) == 0) {
293 l3cache_inval();
294 l3cache_enable();
295 }
296
297 csr = ccsr_read4(OCP85XX_CPC_CSR0);
298 if ((boothowto & RB_VERBOSE) != 0 ||
299 (csr & OCP85XX_CPC_CSR0_CE) == 0) {
300 size = OCP85XX_CPC_CFG0_SZ_K(ccsr_read4(OCP85XX_CPC_CFG0));
301 printf("L3 Corenet Platform Cache: %d KB %sabled\n",
302 size, (csr & OCP85XX_CPC_CSR0_CE) == 0 ?
303 "dis" : "en");
304 }
305 }
306}
307
308static void
309mpc85xx_dataloss_erratum_spr976(void)
310{
311 uint32_t svr = SVR_VER(mfspr(SPR_SVR));
312
313 /* Ignore whether it's the E variant */
314 svr &= ~0x8;
315
316 if (svr != SVR_P3041 && svr != SVR_P4040 &&
317 svr != SVR_P4080 && svr != SVR_P5020)
318 return;
319
320 mb();
321 isync();
322 mtspr(976, (mfspr(976) & ~0x1f8) | 0x48);
323 isync();
324}
325
326static vm_offset_t
327mpc85xx_map_dcsr(void)
328{
329 phandle_t node;
330 u_long b, s;
331 int err;
332
333 /*
334 * Try to access the dcsr node directly i.e. through /aliases/.
335 */
336 if ((node = OF_finddevice("dcsr")) != -1)
337 if (fdt_is_compatible_strict(node, "fsl,dcsr"))
338 goto moveon;
339 /*
340 * Find the node the long way.
341 */
342 if ((node = OF_finddevice("/")) == -1)
343 return (ENXIO);
344
345 if ((node = ofw_bus_find_compatible(node, "fsl,dcsr")) == 0)
346 return (ENXIO);
347
348moveon:
349 err = fdt_get_range(node, 0, &b, &s);
350
351 if (err != 0)
352 return (err);
353
354#ifdef QORIQ_DPAA
355 law_enable(OCP85XX_TGTIF_DCSR, b, 0x400000);
356#endif
357 return pmap_early_io_map(b, 0x400000);
358}
359
360
361
362void
363mpc85xx_fix_errata(vm_offset_t va_ccsr)
364{
365 uint32_t svr = SVR_VER(mfspr(SPR_SVR));
366 vm_offset_t va_dcsr;
367
368 /* Ignore whether it's the E variant */
369 svr &= ~0x8;
370
371 if (svr != SVR_P3041 && svr != SVR_P4040 &&
372 svr != SVR_P4080 && svr != SVR_P5020)
373 return;
374
375 if (mfmsr() & PSL_EE)
376 return;
377
378 /*
379 * dcsr region need to be mapped thus patch can refer to.
380 * Align dcsr right after ccsbar.
381 */
382 va_dcsr = mpc85xx_map_dcsr();
383 if (va_dcsr == 0)
384 goto err;
385
386 /*
387 * As A004510 errata specify, special purpose register 976
388 * SPR976[56:60] = 6'b001001 must be set. e500mc core reference manual
389 * does not document SPR976 register.
390 */
391 mpc85xx_dataloss_erratum_spr976();
392
393 /*
394 * Specific settings in the CCF and core platform cache (CPC)
395 * are required to reconfigure the CoreNet coherency fabric.
396 * The register settings that should be updated are described
397 * in errata and relay on base address, offset and updated value.
398 * Special conditions must be used to update these registers correctly.
399 */
400 dataloss_erratum_access(va_dcsr + 0xb0e08, 0xe0201800);
401 dataloss_erratum_access(va_dcsr + 0xb0e18, 0xe0201800);
402 dataloss_erratum_access(va_dcsr + 0xb0e38, 0xe0400000);
403 dataloss_erratum_access(va_dcsr + 0xb0008, 0x00900000);
404 dataloss_erratum_access(va_dcsr + 0xb0e40, 0xe00a0000);
405
406 switch (svr) {
407 case SVR_P5020:
408 dataloss_erratum_access(va_ccsr + 0x18600, 0xc0000000);
409 break;
410 case SVR_P4040:
411 case SVR_P4080:
412 dataloss_erratum_access(va_ccsr + 0x18600, 0xff000000);
413 break;
414 case SVR_P3041:
415 dataloss_erratum_access(va_ccsr + 0x18600, 0xf0000000);
416 }
417 dataloss_erratum_access(va_ccsr + 0x10f00, 0x415e5000);
418 dataloss_erratum_access(va_ccsr + 0x11f00, 0x415e5000);
419
420err:
421 return;
422}