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