/* SPDX-License-Identifier: GPL-2.0-or-later */1/*2* This file contains low level CPU setup functions.3* Kumar Gala <[email protected]>4* Copyright 2009 Freescale Semiconductor, Inc.5*6* Based on cpu_setup_6xx code by7* Benjamin Herrenschmidt <[email protected]>8*/910#include <linux/linkage.h>1112#include <asm/page.h>13#include <asm/processor.h>14#include <asm/cputable.h>15#include <asm/ppc_asm.h>16#include <asm/nohash/mmu-e500.h>17#include <asm/asm-offsets.h>18#include <asm/mpc85xx.h>1920_GLOBAL(__e500_icache_setup)21mfspr r0, SPRN_L1CSR122andi. r3, r0, L1CSR1_ICE23bnelr /* Already enabled */24oris r0, r0, L1CSR1_CPE@h25ori r0, r0, (L1CSR1_ICFI | L1CSR1_ICLFR | L1CSR1_ICE)26mtspr SPRN_L1CSR1, r0 /* Enable I-Cache */27isync28blr2930_GLOBAL(__e500_dcache_setup)31mfspr r0, SPRN_L1CSR032andi. r3, r0, L1CSR0_DCE33bnelr /* Already enabled */34msync35isync36li r0, 037mtspr SPRN_L1CSR0, r0 /* Disable */38msync39isync40li r0, (L1CSR0_DCFI | L1CSR0_CLFC)41mtspr SPRN_L1CSR0, r0 /* Invalidate */42isync431: mfspr r0, SPRN_L1CSR044andi. r3, r0, L1CSR0_CLFC45bne+ 1b /* Wait for lock bits reset */46oris r0, r0, L1CSR0_CPE@h47ori r0, r0, L1CSR0_DCE48msync49isync50mtspr SPRN_L1CSR0, r0 /* Enable */51isync52blr5354/*55* FIXME - we haven't yet done testing to determine a reasonable default56* value for PW20_WAIT_IDLE_BIT.57*/58#define PW20_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */59_GLOBAL(setup_pw20_idle)60mfspr r3, SPRN_PWRMGTCR06162/* Set PW20_WAIT bit, enable pw20 state*/63ori r3, r3, PWRMGTCR0_PW20_WAIT64li r11, PW20_WAIT_IDLE_BIT6566/* Set Automatic PW20 Core Idle Count */67rlwimi r3, r11, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT6869mtspr SPRN_PWRMGTCR0, r37071blr7273/*74* FIXME - we haven't yet done testing to determine a reasonable default75* value for AV_WAIT_IDLE_BIT.76*/77#define AV_WAIT_IDLE_BIT 50 /* 1ms, TB frequency is 41.66MHZ */78_GLOBAL(setup_altivec_idle)79mfspr r3, SPRN_PWRMGTCR08081/* Enable Altivec Idle */82oris r3, r3, PWRMGTCR0_AV_IDLE_PD_EN@h83li r11, AV_WAIT_IDLE_BIT8485/* Set Automatic AltiVec Idle Count */86rlwimi r3, r11, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT8788mtspr SPRN_PWRMGTCR0, r38990blr9192#ifdef CONFIG_PPC_E500MC93_GLOBAL(__setup_cpu_e6500)94mflr r695#ifdef CONFIG_PPC6496bl setup_altivec_ivors97/* Touch IVOR42 only if the CPU supports E.HV category */98mfspr r10,SPRN_MMUCFG99rlwinm. r10,r10,0,MMUCFG_LPIDSIZE100beq 1f101bl setup_lrat_ivor1021:103#endif104bl setup_pw20_idle105bl setup_altivec_idle106bl __setup_cpu_e5500107mtlr r6108blr109#endif /* CONFIG_PPC_E500MC */110111#ifdef CONFIG_PPC32112#ifdef CONFIG_PPC_E500113#ifndef CONFIG_PPC_E500MC114_GLOBAL(__setup_cpu_e500v1)115_GLOBAL(__setup_cpu_e500v2)116mflr r4117bl __e500_icache_setup118bl __e500_dcache_setup119bl __setup_e500_ivors120#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)121/* Ensure that RFXE is set */122mfspr r3,SPRN_HID1123oris r3,r3,HID1_RFXE@h124mtspr SPRN_HID1,r3125#endif126mtlr r4127blr128#else /* CONFIG_PPC_E500MC */129_GLOBAL(__setup_cpu_e500mc)130_GLOBAL(__setup_cpu_e5500)131mflr r5132bl __e500_icache_setup133bl __e500_dcache_setup134bl __setup_e500mc_ivors135/*136* We only want to touch IVOR38-41 if we're running on hardware137* that supports category E.HV. The architectural way to determine138* this is MMUCFG[LPIDSIZE].139*/140mfspr r3, SPRN_MMUCFG141rlwinm. r3, r3, 0, MMUCFG_LPIDSIZE142beq 1f143bl __setup_ehv_ivors144b 2f1451:146lwz r3, CPU_SPEC_FEATURES(r4)147/* We need this check as cpu_setup is also called for148* the secondary cores. So, if we have already cleared149* the feature on the primary core, avoid doing it on the150* secondary core.151*/152andi. r6, r3, CPU_FTR_EMB_HV153beq 2f154rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV155stw r3, CPU_SPEC_FEATURES(r4)1562:157mtlr r5158blr159#endif /* CONFIG_PPC_E500MC */160#endif /* CONFIG_PPC_E500 */161#endif /* CONFIG_PPC32 */162163#ifdef CONFIG_PPC_BOOK3E_64164_GLOBAL(__restore_cpu_e6500)165mflr r5166bl setup_altivec_ivors167/* Touch IVOR42 only if the CPU supports E.HV category */168mfspr r10,SPRN_MMUCFG169rlwinm. r10,r10,0,MMUCFG_LPIDSIZE170beq 1f171bl setup_lrat_ivor1721:173bl setup_pw20_idle174bl setup_altivec_idle175bl __restore_cpu_e5500176mtlr r5177blr178179_GLOBAL(__restore_cpu_e5500)180mflr r4181bl __e500_icache_setup182bl __e500_dcache_setup183bl __setup_base_ivors184bl setup_perfmon_ivor185bl setup_doorbell_ivors186/*187* We only want to touch IVOR38-41 if we're running on hardware188* that supports category E.HV. The architectural way to determine189* this is MMUCFG[LPIDSIZE].190*/191mfspr r10,SPRN_MMUCFG192rlwinm. r10,r10,0,MMUCFG_LPIDSIZE193beq 1f194bl setup_ehv_ivors1951:196mtlr r4197blr198199_GLOBAL(__setup_cpu_e5500)200mflr r5201bl __e500_icache_setup202bl __e500_dcache_setup203bl __setup_base_ivors204bl setup_perfmon_ivor205bl setup_doorbell_ivors206/*207* We only want to touch IVOR38-41 if we're running on hardware208* that supports category E.HV. The architectural way to determine209* this is MMUCFG[LPIDSIZE].210*/211mfspr r10,SPRN_MMUCFG212rlwinm. r10,r10,0,MMUCFG_LPIDSIZE213beq 1f214bl setup_ehv_ivors215b 2f2161:217ld r10,CPU_SPEC_FEATURES(r4)218LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV)219andc r10,r10,r9220std r10,CPU_SPEC_FEATURES(r4)2212:222mtlr r5223blr224#endif225226/* flush L1 data cache, it can apply to e500v2, e500mc and e5500 */227_GLOBAL(flush_dcache_L1)228mfmsr r10229wrteei 0230231mfspr r3,SPRN_L1CFG0232rlwinm r5,r3,9,3 /* Extract cache block size */233twlgti r5,1 /* Only 32 and 64 byte cache blocks234* are currently defined.235*/236li r4,32237subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) -238* log2(number of ways)239*/240slw r5,r4,r5 /* r5 = cache block size */241242rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */243mulli r7,r7,13 /* An 8-way cache will require 13244* loads per set.245*/246slw r7,r7,r6247248/* save off HID0 and set DCFA */249mfspr r8,SPRN_HID0250ori r9,r8,HID0_DCFA@l251mtspr SPRN_HID0,r9252isync253254LOAD_REG_IMMEDIATE(r6, KERNELBASE)255mr r4, r6256mtctr r72572581: lwz r3,0(r4) /* Load... */259add r4,r4,r5260bdnz 1b261262msync263mr r4, r6264mtctr r72652661: dcbf 0,r4 /* ...and flush. */267add r4,r4,r5268bdnz 1b269270/* restore HID0 */271mtspr SPRN_HID0,r8272isync273274wrtee r10275276blr277278SYM_FUNC_START_LOCAL(has_L2_cache)279/* skip L2 cache on P2040/P2040E as they have no L2 cache */280mfspr r3, SPRN_SVR281/* shift right by 8 bits and clear E bit of SVR */282rlwinm r4, r3, 24, ~0x800283284lis r3, SVR_P2040@h285ori r3, r3, SVR_P2040@l286cmpw r4, r3287beq 1f288289li r3, 1290blr2911:292li r3, 0293blr294SYM_FUNC_END(has_L2_cache)295296/* flush backside L2 cache */297SYM_FUNC_START_LOCAL(flush_backside_L2_cache)298mflr r10299bl has_L2_cache300mtlr r10301cmpwi r3, 0302beq 2f303304/* Flush the L2 cache */305mfspr r3, SPRN_L2CSR0306ori r3, r3, L2CSR0_L2FL@l307msync308isync309mtspr SPRN_L2CSR0,r3310isync311312/* check if it is complete */3131: mfspr r3,SPRN_L2CSR0314andi. r3, r3, L2CSR0_L2FL@l315bne 1b3162:317blr318SYM_FUNC_END(flush_backside_L2_cache)319320_GLOBAL(cpu_down_flush_e500v2)321mflr r0322bl flush_dcache_L1323mtlr r0324blr325326_GLOBAL(cpu_down_flush_e500mc)327_GLOBAL(cpu_down_flush_e5500)328mflr r0329bl flush_dcache_L1330bl flush_backside_L2_cache331mtlr r0332blr333334/* L1 Data Cache of e6500 contains no modified data, no flush is required */335_GLOBAL(cpu_down_flush_e6500)336blr337338339