xref: /openbmc/linux/arch/powerpc/kernel/cpu_setup_e500.S (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
13e731858SChristophe Leroy/* SPDX-License-Identifier: GPL-2.0-or-later */
23e731858SChristophe Leroy/*
33e731858SChristophe Leroy * This file contains low level CPU setup functions.
43e731858SChristophe Leroy * Kumar Gala <galak@kernel.crashing.org>
53e731858SChristophe Leroy * Copyright 2009 Freescale Semiconductor, Inc.
63e731858SChristophe Leroy *
73e731858SChristophe Leroy * Based on cpu_setup_6xx code by
83e731858SChristophe Leroy * Benjamin Herrenschmidt <benh@kernel.crashing.org>
93e731858SChristophe Leroy */
103e731858SChristophe Leroy
11*2da37761SChristophe Leroy#include <linux/linkage.h>
12*2da37761SChristophe Leroy
133e731858SChristophe Leroy#include <asm/page.h>
143e731858SChristophe Leroy#include <asm/processor.h>
153e731858SChristophe Leroy#include <asm/cputable.h>
163e731858SChristophe Leroy#include <asm/ppc_asm.h>
17aa5f59dfSChristophe Leroy#include <asm/nohash/mmu-e500.h>
183e731858SChristophe Leroy#include <asm/asm-offsets.h>
193e731858SChristophe Leroy#include <asm/mpc85xx.h>
203e731858SChristophe Leroy
213e731858SChristophe Leroy_GLOBAL(__e500_icache_setup)
223e731858SChristophe Leroy	mfspr	r0, SPRN_L1CSR1
233e731858SChristophe Leroy	andi.	r3, r0, L1CSR1_ICE
243e731858SChristophe Leroy	bnelr				/* Already enabled */
253e731858SChristophe Leroy	oris	r0, r0, L1CSR1_CPE@h
263e731858SChristophe Leroy	ori	r0, r0, (L1CSR1_ICFI | L1CSR1_ICLFR |  L1CSR1_ICE)
273e731858SChristophe Leroy	mtspr	SPRN_L1CSR1, r0		/* Enable I-Cache */
283e731858SChristophe Leroy	isync
293e731858SChristophe Leroy	blr
303e731858SChristophe Leroy
313e731858SChristophe Leroy_GLOBAL(__e500_dcache_setup)
323e731858SChristophe Leroy	mfspr	r0, SPRN_L1CSR0
333e731858SChristophe Leroy	andi.	r3, r0, L1CSR0_DCE
343e731858SChristophe Leroy	bnelr				/* Already enabled */
353e731858SChristophe Leroy	msync
363e731858SChristophe Leroy	isync
373e731858SChristophe Leroy	li	r0, 0
383e731858SChristophe Leroy	mtspr	SPRN_L1CSR0, r0		/* Disable */
393e731858SChristophe Leroy	msync
403e731858SChristophe Leroy	isync
413e731858SChristophe Leroy	li	r0, (L1CSR0_DCFI | L1CSR0_CLFC)
423e731858SChristophe Leroy	mtspr	SPRN_L1CSR0, r0		/* Invalidate */
433e731858SChristophe Leroy	isync
443e731858SChristophe Leroy1:	mfspr	r0, SPRN_L1CSR0
453e731858SChristophe Leroy	andi.	r3, r0, L1CSR0_CLFC
463e731858SChristophe Leroy	bne+	1b			/* Wait for lock bits reset */
473e731858SChristophe Leroy	oris	r0, r0, L1CSR0_CPE@h
483e731858SChristophe Leroy	ori	r0, r0, L1CSR0_DCE
493e731858SChristophe Leroy	msync
503e731858SChristophe Leroy	isync
513e731858SChristophe Leroy	mtspr	SPRN_L1CSR0, r0		/* Enable */
523e731858SChristophe Leroy	isync
533e731858SChristophe Leroy	blr
543e731858SChristophe Leroy
553e731858SChristophe Leroy/*
563e731858SChristophe Leroy * FIXME - we haven't yet done testing to determine a reasonable default
573e731858SChristophe Leroy * value for PW20_WAIT_IDLE_BIT.
583e731858SChristophe Leroy */
593e731858SChristophe Leroy#define PW20_WAIT_IDLE_BIT		50 /* 1ms, TB frequency is 41.66MHZ */
603e731858SChristophe Leroy_GLOBAL(setup_pw20_idle)
613e731858SChristophe Leroy	mfspr	r3, SPRN_PWRMGTCR0
623e731858SChristophe Leroy
633e731858SChristophe Leroy	/* Set PW20_WAIT bit, enable pw20 state*/
643e731858SChristophe Leroy	ori	r3, r3, PWRMGTCR0_PW20_WAIT
653e731858SChristophe Leroy	li	r11, PW20_WAIT_IDLE_BIT
663e731858SChristophe Leroy
673e731858SChristophe Leroy	/* Set Automatic PW20 Core Idle Count */
683e731858SChristophe Leroy	rlwimi	r3, r11, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT
693e731858SChristophe Leroy
703e731858SChristophe Leroy	mtspr	SPRN_PWRMGTCR0, r3
713e731858SChristophe Leroy
723e731858SChristophe Leroy	blr
733e731858SChristophe Leroy
743e731858SChristophe Leroy/*
753e731858SChristophe Leroy * FIXME - we haven't yet done testing to determine a reasonable default
763e731858SChristophe Leroy * value for AV_WAIT_IDLE_BIT.
773e731858SChristophe Leroy */
783e731858SChristophe Leroy#define AV_WAIT_IDLE_BIT		50 /* 1ms, TB frequency is 41.66MHZ */
793e731858SChristophe Leroy_GLOBAL(setup_altivec_idle)
803e731858SChristophe Leroy	mfspr	r3, SPRN_PWRMGTCR0
813e731858SChristophe Leroy
823e731858SChristophe Leroy	/* Enable Altivec Idle */
833e731858SChristophe Leroy	oris	r3, r3, PWRMGTCR0_AV_IDLE_PD_EN@h
843e731858SChristophe Leroy	li	r11, AV_WAIT_IDLE_BIT
853e731858SChristophe Leroy
863e731858SChristophe Leroy	/* Set Automatic AltiVec Idle Count */
873e731858SChristophe Leroy	rlwimi	r3, r11, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT
883e731858SChristophe Leroy
893e731858SChristophe Leroy	mtspr	SPRN_PWRMGTCR0, r3
903e731858SChristophe Leroy
913e731858SChristophe Leroy	blr
923e731858SChristophe Leroy
933e731858SChristophe Leroy#ifdef CONFIG_PPC_E500MC
943e731858SChristophe Leroy_GLOBAL(__setup_cpu_e6500)
953e731858SChristophe Leroy	mflr	r6
963e731858SChristophe Leroy#ifdef CONFIG_PPC64
973e731858SChristophe Leroy	bl	setup_altivec_ivors
983e731858SChristophe Leroy	/* Touch IVOR42 only if the CPU supports E.HV category */
993e731858SChristophe Leroy	mfspr	r10,SPRN_MMUCFG
1003e731858SChristophe Leroy	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
1013e731858SChristophe Leroy	beq	1f
1023e731858SChristophe Leroy	bl	setup_lrat_ivor
1033e731858SChristophe Leroy1:
1043e731858SChristophe Leroy#endif
1053e731858SChristophe Leroy	bl	setup_pw20_idle
1063e731858SChristophe Leroy	bl	setup_altivec_idle
1073e731858SChristophe Leroy	bl	__setup_cpu_e5500
1083e731858SChristophe Leroy	mtlr	r6
1093e731858SChristophe Leroy	blr
1103e731858SChristophe Leroy#endif /* CONFIG_PPC_E500MC */
1113e731858SChristophe Leroy
1123e731858SChristophe Leroy#ifdef CONFIG_PPC32
1133e731858SChristophe Leroy#ifdef CONFIG_PPC_E500
1143e731858SChristophe Leroy#ifndef CONFIG_PPC_E500MC
1153e731858SChristophe Leroy_GLOBAL(__setup_cpu_e500v1)
1163e731858SChristophe Leroy_GLOBAL(__setup_cpu_e500v2)
1173e731858SChristophe Leroy	mflr	r4
1183e731858SChristophe Leroy	bl	__e500_icache_setup
1193e731858SChristophe Leroy	bl	__e500_dcache_setup
1203e731858SChristophe Leroy	bl	__setup_e500_ivors
1213e731858SChristophe Leroy#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
1223e731858SChristophe Leroy	/* Ensure that RFXE is set */
1233e731858SChristophe Leroy	mfspr	r3,SPRN_HID1
1243e731858SChristophe Leroy	oris	r3,r3,HID1_RFXE@h
1253e731858SChristophe Leroy	mtspr	SPRN_HID1,r3
1263e731858SChristophe Leroy#endif
1273e731858SChristophe Leroy	mtlr	r4
1283e731858SChristophe Leroy	blr
1293e731858SChristophe Leroy#else /* CONFIG_PPC_E500MC */
1303e731858SChristophe Leroy_GLOBAL(__setup_cpu_e500mc)
1313e731858SChristophe Leroy_GLOBAL(__setup_cpu_e5500)
1323e731858SChristophe Leroy	mflr	r5
1333e731858SChristophe Leroy	bl	__e500_icache_setup
1343e731858SChristophe Leroy	bl	__e500_dcache_setup
1353e731858SChristophe Leroy	bl	__setup_e500mc_ivors
1363e731858SChristophe Leroy	/*
1373e731858SChristophe Leroy	 * We only want to touch IVOR38-41 if we're running on hardware
1383e731858SChristophe Leroy	 * that supports category E.HV.  The architectural way to determine
1393e731858SChristophe Leroy	 * this is MMUCFG[LPIDSIZE].
1403e731858SChristophe Leroy	 */
1413e731858SChristophe Leroy	mfspr	r3, SPRN_MMUCFG
1423e731858SChristophe Leroy	rlwinm.	r3, r3, 0, MMUCFG_LPIDSIZE
1433e731858SChristophe Leroy	beq	1f
1443e731858SChristophe Leroy	bl	__setup_ehv_ivors
1453e731858SChristophe Leroy	b	2f
1463e731858SChristophe Leroy1:
1473e731858SChristophe Leroy	lwz	r3, CPU_SPEC_FEATURES(r4)
1483e731858SChristophe Leroy	/* We need this check as cpu_setup is also called for
1493e731858SChristophe Leroy	 * the secondary cores. So, if we have already cleared
1503e731858SChristophe Leroy	 * the feature on the primary core, avoid doing it on the
1513e731858SChristophe Leroy	 * secondary core.
1523e731858SChristophe Leroy	 */
1533e731858SChristophe Leroy	andi.	r6, r3, CPU_FTR_EMB_HV
1543e731858SChristophe Leroy	beq	2f
1553e731858SChristophe Leroy	rlwinm	r3, r3, 0, ~CPU_FTR_EMB_HV
1563e731858SChristophe Leroy	stw	r3, CPU_SPEC_FEATURES(r4)
1573e731858SChristophe Leroy2:
1583e731858SChristophe Leroy	mtlr	r5
1593e731858SChristophe Leroy	blr
1603e731858SChristophe Leroy#endif /* CONFIG_PPC_E500MC */
1613e731858SChristophe Leroy#endif /* CONFIG_PPC_E500 */
1623e731858SChristophe Leroy#endif /* CONFIG_PPC32 */
1633e731858SChristophe Leroy
1643e731858SChristophe Leroy#ifdef CONFIG_PPC_BOOK3E_64
1653e731858SChristophe Leroy_GLOBAL(__restore_cpu_e6500)
1663e731858SChristophe Leroy	mflr	r5
1673e731858SChristophe Leroy	bl	setup_altivec_ivors
1683e731858SChristophe Leroy	/* Touch IVOR42 only if the CPU supports E.HV category */
1693e731858SChristophe Leroy	mfspr	r10,SPRN_MMUCFG
1703e731858SChristophe Leroy	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
1713e731858SChristophe Leroy	beq	1f
1723e731858SChristophe Leroy	bl	setup_lrat_ivor
1733e731858SChristophe Leroy1:
1743e731858SChristophe Leroy	bl	setup_pw20_idle
1753e731858SChristophe Leroy	bl	setup_altivec_idle
1763e731858SChristophe Leroy	bl	__restore_cpu_e5500
1773e731858SChristophe Leroy	mtlr	r5
1783e731858SChristophe Leroy	blr
1793e731858SChristophe Leroy
1803e731858SChristophe Leroy_GLOBAL(__restore_cpu_e5500)
1813e731858SChristophe Leroy	mflr	r4
1823e731858SChristophe Leroy	bl	__e500_icache_setup
1833e731858SChristophe Leroy	bl	__e500_dcache_setup
1843e731858SChristophe Leroy	bl	__setup_base_ivors
1853e731858SChristophe Leroy	bl	setup_perfmon_ivor
1863e731858SChristophe Leroy	bl	setup_doorbell_ivors
1873e731858SChristophe Leroy	/*
1883e731858SChristophe Leroy	 * We only want to touch IVOR38-41 if we're running on hardware
1893e731858SChristophe Leroy	 * that supports category E.HV.  The architectural way to determine
1903e731858SChristophe Leroy	 * this is MMUCFG[LPIDSIZE].
1913e731858SChristophe Leroy	 */
1923e731858SChristophe Leroy	mfspr	r10,SPRN_MMUCFG
1933e731858SChristophe Leroy	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
1943e731858SChristophe Leroy	beq	1f
1953e731858SChristophe Leroy	bl	setup_ehv_ivors
1963e731858SChristophe Leroy1:
1973e731858SChristophe Leroy	mtlr	r4
1983e731858SChristophe Leroy	blr
1993e731858SChristophe Leroy
2003e731858SChristophe Leroy_GLOBAL(__setup_cpu_e5500)
2013e731858SChristophe Leroy	mflr	r5
2023e731858SChristophe Leroy	bl	__e500_icache_setup
2033e731858SChristophe Leroy	bl	__e500_dcache_setup
2043e731858SChristophe Leroy	bl	__setup_base_ivors
2053e731858SChristophe Leroy	bl	setup_perfmon_ivor
2063e731858SChristophe Leroy	bl	setup_doorbell_ivors
2073e731858SChristophe Leroy	/*
2083e731858SChristophe Leroy	 * We only want to touch IVOR38-41 if we're running on hardware
2093e731858SChristophe Leroy	 * that supports category E.HV.  The architectural way to determine
2103e731858SChristophe Leroy	 * this is MMUCFG[LPIDSIZE].
2113e731858SChristophe Leroy	 */
2123e731858SChristophe Leroy	mfspr	r10,SPRN_MMUCFG
2133e731858SChristophe Leroy	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
2143e731858SChristophe Leroy	beq	1f
2153e731858SChristophe Leroy	bl	setup_ehv_ivors
2163e731858SChristophe Leroy	b	2f
2173e731858SChristophe Leroy1:
2183e731858SChristophe Leroy	ld	r10,CPU_SPEC_FEATURES(r4)
2193e731858SChristophe Leroy	LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV)
2203e731858SChristophe Leroy	andc	r10,r10,r9
2213e731858SChristophe Leroy	std	r10,CPU_SPEC_FEATURES(r4)
2223e731858SChristophe Leroy2:
2233e731858SChristophe Leroy	mtlr	r5
2243e731858SChristophe Leroy	blr
2253e731858SChristophe Leroy#endif
2263e731858SChristophe Leroy
2273e731858SChristophe Leroy/* flush L1 data cache, it can apply to e500v2, e500mc and e5500 */
2283e731858SChristophe Leroy_GLOBAL(flush_dcache_L1)
2293e731858SChristophe Leroy	mfmsr	r10
2303e731858SChristophe Leroy	wrteei	0
2313e731858SChristophe Leroy
2323e731858SChristophe Leroy	mfspr	r3,SPRN_L1CFG0
2333e731858SChristophe Leroy	rlwinm	r5,r3,9,3	/* Extract cache block size */
2343e731858SChristophe Leroy	twlgti	r5,1		/* Only 32 and 64 byte cache blocks
2353e731858SChristophe Leroy				 * are currently defined.
2363e731858SChristophe Leroy				 */
2373e731858SChristophe Leroy	li	r4,32
2383e731858SChristophe Leroy	subfic	r6,r5,2		/* r6 = log2(1KiB / cache block size) -
2393e731858SChristophe Leroy				 *      log2(number of ways)
2403e731858SChristophe Leroy				 */
2413e731858SChristophe Leroy	slw	r5,r4,r5	/* r5 = cache block size */
2423e731858SChristophe Leroy
2433e731858SChristophe Leroy	rlwinm	r7,r3,0,0xff	/* Extract number of KiB in the cache */
2443e731858SChristophe Leroy	mulli	r7,r7,13	/* An 8-way cache will require 13
2453e731858SChristophe Leroy				 * loads per set.
2463e731858SChristophe Leroy				 */
2473e731858SChristophe Leroy	slw	r7,r7,r6
2483e731858SChristophe Leroy
2493e731858SChristophe Leroy	/* save off HID0 and set DCFA */
2503e731858SChristophe Leroy	mfspr	r8,SPRN_HID0
2513e731858SChristophe Leroy	ori	r9,r8,HID0_DCFA@l
2523e731858SChristophe Leroy	mtspr	SPRN_HID0,r9
2533e731858SChristophe Leroy	isync
2543e731858SChristophe Leroy
2553e731858SChristophe Leroy	LOAD_REG_IMMEDIATE(r6, KERNELBASE)
2563e731858SChristophe Leroy	mr	r4, r6
2573e731858SChristophe Leroy	mtctr	r7
2583e731858SChristophe Leroy
2593e731858SChristophe Leroy1:	lwz	r3,0(r4)	/* Load... */
2603e731858SChristophe Leroy	add	r4,r4,r5
2613e731858SChristophe Leroy	bdnz	1b
2623e731858SChristophe Leroy
2633e731858SChristophe Leroy	msync
2643e731858SChristophe Leroy	mr	r4, r6
2653e731858SChristophe Leroy	mtctr	r7
2663e731858SChristophe Leroy
2673e731858SChristophe Leroy1:	dcbf	0,r4		/* ...and flush. */
2683e731858SChristophe Leroy	add	r4,r4,r5
2693e731858SChristophe Leroy	bdnz	1b
2703e731858SChristophe Leroy
2713e731858SChristophe Leroy	/* restore HID0 */
2723e731858SChristophe Leroy	mtspr	SPRN_HID0,r8
2733e731858SChristophe Leroy	isync
2743e731858SChristophe Leroy
2753e731858SChristophe Leroy	wrtee r10
2763e731858SChristophe Leroy
2773e731858SChristophe Leroy	blr
2783e731858SChristophe Leroy
279*2da37761SChristophe LeroySYM_FUNC_START_LOCAL(has_L2_cache)
2803e731858SChristophe Leroy	/* skip L2 cache on P2040/P2040E as they have no L2 cache */
2813e731858SChristophe Leroy	mfspr	r3, SPRN_SVR
2823e731858SChristophe Leroy	/* shift right by 8 bits and clear E bit of SVR */
2833e731858SChristophe Leroy	rlwinm	r4, r3, 24, ~0x800
2843e731858SChristophe Leroy
2853e731858SChristophe Leroy	lis	r3, SVR_P2040@h
2863e731858SChristophe Leroy	ori	r3, r3, SVR_P2040@l
2873e731858SChristophe Leroy	cmpw	r4, r3
2883e731858SChristophe Leroy	beq	1f
2893e731858SChristophe Leroy
2903e731858SChristophe Leroy	li	r3, 1
2913e731858SChristophe Leroy	blr
2923e731858SChristophe Leroy1:
2933e731858SChristophe Leroy	li	r3, 0
2943e731858SChristophe Leroy	blr
295*2da37761SChristophe LeroySYM_FUNC_END(has_L2_cache)
2963e731858SChristophe Leroy
2973e731858SChristophe Leroy/* flush backside L2 cache */
298*2da37761SChristophe LeroySYM_FUNC_START_LOCAL(flush_backside_L2_cache)
2993e731858SChristophe Leroy	mflr	r10
3003e731858SChristophe Leroy	bl	has_L2_cache
3013e731858SChristophe Leroy	mtlr	r10
3023e731858SChristophe Leroy	cmpwi	r3, 0
3033e731858SChristophe Leroy	beq	2f
3043e731858SChristophe Leroy
3053e731858SChristophe Leroy	/* Flush the L2 cache */
3063e731858SChristophe Leroy	mfspr	r3, SPRN_L2CSR0
3073e731858SChristophe Leroy	ori	r3, r3, L2CSR0_L2FL@l
3083e731858SChristophe Leroy	msync
3093e731858SChristophe Leroy	isync
3103e731858SChristophe Leroy	mtspr	SPRN_L2CSR0,r3
3113e731858SChristophe Leroy	isync
3123e731858SChristophe Leroy
3133e731858SChristophe Leroy	/* check if it is complete */
3143e731858SChristophe Leroy1:	mfspr	r3,SPRN_L2CSR0
3153e731858SChristophe Leroy	andi.	r3, r3, L2CSR0_L2FL@l
3163e731858SChristophe Leroy	bne	1b
3173e731858SChristophe Leroy2:
3183e731858SChristophe Leroy	blr
319*2da37761SChristophe LeroySYM_FUNC_END(flush_backside_L2_cache)
3203e731858SChristophe Leroy
3213e731858SChristophe Leroy_GLOBAL(cpu_down_flush_e500v2)
3223e731858SChristophe Leroy	mflr r0
3233e731858SChristophe Leroy	bl	flush_dcache_L1
3243e731858SChristophe Leroy	mtlr r0
3253e731858SChristophe Leroy	blr
3263e731858SChristophe Leroy
3273e731858SChristophe Leroy_GLOBAL(cpu_down_flush_e500mc)
3283e731858SChristophe Leroy_GLOBAL(cpu_down_flush_e5500)
3293e731858SChristophe Leroy	mflr r0
3303e731858SChristophe Leroy	bl	flush_dcache_L1
3313e731858SChristophe Leroy	bl	flush_backside_L2_cache
3323e731858SChristophe Leroy	mtlr r0
3333e731858SChristophe Leroy	blr
3343e731858SChristophe Leroy
3353e731858SChristophe Leroy/* L1 Data Cache of e6500 contains no modified data, no flush is required */
3363e731858SChristophe Leroy_GLOBAL(cpu_down_flush_e6500)
3373e731858SChristophe Leroy	blr
338