linux/arch/powerpc/kernel/cpu_setup_fsl_booke.S
<<
>>
Prefs
   1/*
   2 * This file contains low level CPU setup functions.
   3 * Kumar Gala <galak@kernel.crashing.org>
   4 * Copyright 2009 Freescale Semiconductor, Inc.
   5 *
   6 * Based on cpu_setup_6xx code by
   7 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License
  11 * as published by the Free Software Foundation; either version
  12 * 2 of the License, or (at your option) any later version.
  13 *
  14 */
  15
  16#include <asm/processor.h>
  17#include <asm/cputable.h>
  18#include <asm/ppc_asm.h>
  19#include <asm/mmu-book3e.h>
  20#include <asm/asm-offsets.h>
  21
  22_GLOBAL(__e500_icache_setup)
  23        mfspr   r0, SPRN_L1CSR1
  24        andi.   r3, r0, L1CSR1_ICE
  25        bnelr                           /* Already enabled */
  26        oris    r0, r0, L1CSR1_CPE@h
  27        ori     r0, r0, (L1CSR1_ICFI | L1CSR1_ICLFR |  L1CSR1_ICE)
  28        mtspr   SPRN_L1CSR1, r0         /* Enable I-Cache */
  29        isync
  30        blr
  31
  32_GLOBAL(__e500_dcache_setup)
  33        mfspr   r0, SPRN_L1CSR0
  34        andi.   r3, r0, L1CSR0_DCE
  35        bnelr                           /* Already enabled */
  36        msync
  37        isync
  38        li      r0, 0
  39        mtspr   SPRN_L1CSR0, r0         /* Disable */
  40        msync
  41        isync
  42        li      r0, (L1CSR0_DCFI | L1CSR0_CLFC)
  43        mtspr   SPRN_L1CSR0, r0         /* Invalidate */
  44        isync
  451:      mfspr   r0, SPRN_L1CSR0
  46        andi.   r3, r0, L1CSR0_CLFC
  47        bne+    1b                      /* Wait for lock bits reset */
  48        oris    r0, r0, L1CSR0_CPE@h
  49        ori     r0, r0, L1CSR0_DCE
  50        msync
  51        isync
  52        mtspr   SPRN_L1CSR0, r0         /* Enable */
  53        isync
  54        blr
  55
  56/*
  57 * FIXME - we haven't yet done testing to determine a reasonable default
  58 * value for PW20_WAIT_IDLE_BIT.
  59 */
  60#define PW20_WAIT_IDLE_BIT              50 /* 1ms, TB frequency is 41.66MHZ */
  61_GLOBAL(setup_pw20_idle)
  62        mfspr   r3, SPRN_PWRMGTCR0
  63
  64        /* Set PW20_WAIT bit, enable pw20 state*/
  65        ori     r3, r3, PWRMGTCR0_PW20_WAIT
  66        li      r11, PW20_WAIT_IDLE_BIT
  67
  68        /* Set Automatic PW20 Core Idle Count */
  69        rlwimi  r3, r11, PWRMGTCR0_PW20_ENT_SHIFT, PWRMGTCR0_PW20_ENT
  70
  71        mtspr   SPRN_PWRMGTCR0, r3
  72
  73        blr
  74
  75/*
  76 * FIXME - we haven't yet done testing to determine a reasonable default
  77 * value for AV_WAIT_IDLE_BIT.
  78 */
  79#define AV_WAIT_IDLE_BIT                50 /* 1ms, TB frequency is 41.66MHZ */
  80_GLOBAL(setup_altivec_idle)
  81        mfspr   r3, SPRN_PWRMGTCR0
  82
  83        /* Enable Altivec Idle */
  84        oris    r3, r3, PWRMGTCR0_AV_IDLE_PD_EN@h
  85        li      r11, AV_WAIT_IDLE_BIT
  86
  87        /* Set Automatic AltiVec Idle Count */
  88        rlwimi  r3, r11, PWRMGTCR0_AV_IDLE_CNT_SHIFT, PWRMGTCR0_AV_IDLE_CNT
  89
  90        mtspr   SPRN_PWRMGTCR0, r3
  91
  92        blr
  93
  94#ifdef CONFIG_PPC_E500MC
  95_GLOBAL(__setup_cpu_e6500)
  96        mflr    r6
  97#ifdef CONFIG_PPC64
  98        bl      setup_altivec_ivors
  99        /* Touch IVOR42 only if the CPU supports E.HV category */
 100        mfspr   r10,SPRN_MMUCFG
 101        rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
 102        beq     1f
 103        bl      setup_lrat_ivor
 1041:
 105#endif
 106        bl      setup_pw20_idle
 107        bl      setup_altivec_idle
 108        bl      __setup_cpu_e5500
 109        mtlr    r6
 110        blr
 111#endif /* CONFIG_PPC_E500MC */
 112
 113#ifdef CONFIG_PPC32
 114#ifdef CONFIG_E200
 115_GLOBAL(__setup_cpu_e200)
 116        /* enable dedicated debug exception handling resources (Debug APU) */
 117        mfspr   r3,SPRN_HID0
 118        ori     r3,r3,HID0_DAPUEN@l
 119        mtspr   SPRN_HID0,r3
 120        b       __setup_e200_ivors
 121#endif /* CONFIG_E200 */
 122
 123#ifdef CONFIG_E500
 124#ifndef CONFIG_PPC_E500MC
 125_GLOBAL(__setup_cpu_e500v1)
 126_GLOBAL(__setup_cpu_e500v2)
 127        mflr    r4
 128        bl      __e500_icache_setup
 129        bl      __e500_dcache_setup
 130        bl      __setup_e500_ivors
 131#if defined(CONFIG_FSL_RIO) || defined(CONFIG_FSL_PCI)
 132        /* Ensure that RFXE is set */
 133        mfspr   r3,SPRN_HID1
 134        oris    r3,r3,HID1_RFXE@h
 135        mtspr   SPRN_HID1,r3
 136#endif
 137        mtlr    r4
 138        blr
 139#else /* CONFIG_PPC_E500MC */
 140_GLOBAL(__setup_cpu_e500mc)
 141_GLOBAL(__setup_cpu_e5500)
 142        mflr    r5
 143        bl      __e500_icache_setup
 144        bl      __e500_dcache_setup
 145        bl      __setup_e500mc_ivors
 146        /*
 147         * We only want to touch IVOR38-41 if we're running on hardware
 148         * that supports category E.HV.  The architectural way to determine
 149         * this is MMUCFG[LPIDSIZE].
 150         */
 151        mfspr   r3, SPRN_MMUCFG
 152        rlwinm. r3, r3, 0, MMUCFG_LPIDSIZE
 153        beq     1f
 154        bl      __setup_ehv_ivors
 155        b       2f
 1561:
 157        lwz     r3, CPU_SPEC_FEATURES(r4)
 158        /* We need this check as cpu_setup is also called for
 159         * the secondary cores. So, if we have already cleared
 160         * the feature on the primary core, avoid doing it on the
 161         * secondary core.
 162         */
 163        andis.  r6, r3, CPU_FTR_EMB_HV@h
 164        beq     2f
 165        rlwinm  r3, r3, 0, ~CPU_FTR_EMB_HV
 166        stw     r3, CPU_SPEC_FEATURES(r4)
 1672:
 168        mtlr    r5
 169        blr
 170#endif /* CONFIG_PPC_E500MC */
 171#endif /* CONFIG_E500 */
 172#endif /* CONFIG_PPC32 */
 173
 174#ifdef CONFIG_PPC_BOOK3E_64
 175_GLOBAL(__restore_cpu_e6500)
 176        mflr    r5
 177        bl      setup_altivec_ivors
 178        /* Touch IVOR42 only if the CPU supports E.HV category */
 179        mfspr   r10,SPRN_MMUCFG
 180        rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
 181        beq     1f
 182        bl      setup_lrat_ivor
 1831:
 184        bl      setup_pw20_idle
 185        bl      setup_altivec_idle
 186        bl      __restore_cpu_e5500
 187        mtlr    r5
 188        blr
 189
 190_GLOBAL(__restore_cpu_e5500)
 191        mflr    r4
 192        bl      __e500_icache_setup
 193        bl      __e500_dcache_setup
 194        bl      __setup_base_ivors
 195        bl      setup_perfmon_ivor
 196        bl      setup_doorbell_ivors
 197        /*
 198         * We only want to touch IVOR38-41 if we're running on hardware
 199         * that supports category E.HV.  The architectural way to determine
 200         * this is MMUCFG[LPIDSIZE].
 201         */
 202        mfspr   r10,SPRN_MMUCFG
 203        rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
 204        beq     1f
 205        bl      setup_ehv_ivors
 2061:
 207        mtlr    r4
 208        blr
 209
 210_GLOBAL(__setup_cpu_e5500)
 211        mflr    r5
 212        bl      __e500_icache_setup
 213        bl      __e500_dcache_setup
 214        bl      __setup_base_ivors
 215        bl      setup_perfmon_ivor
 216        bl      setup_doorbell_ivors
 217        /*
 218         * We only want to touch IVOR38-41 if we're running on hardware
 219         * that supports category E.HV.  The architectural way to determine
 220         * this is MMUCFG[LPIDSIZE].
 221         */
 222        mfspr   r10,SPRN_MMUCFG
 223        rlwinm. r10,r10,0,MMUCFG_LPIDSIZE
 224        beq     1f
 225        bl      setup_ehv_ivors
 226        b       2f
 2271:
 228        ld      r10,CPU_SPEC_FEATURES(r4)
 229        LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV)
 230        andc    r10,r10,r9
 231        std     r10,CPU_SPEC_FEATURES(r4)
 2322:
 233        mtlr    r5
 234        blr
 235#endif
 236