diff options
author | Aneesh V <aneesh@ti.com> | 2011-06-16 23:30:53 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2011-07-04 10:55:25 +0200 |
commit | 45bf05854bc94ed8bae9e9114292895b990327ea (patch) | |
tree | 1bc119e00d0dd4a58b36df51cc07768a950352a0 | |
parent | 8b457fa828971ac036b15e98e65d99b6354c5496 (diff) | |
download | u-boot-imx-45bf05854bc94ed8bae9e9114292895b990327ea.zip u-boot-imx-45bf05854bc94ed8bae9e9114292895b990327ea.tar.gz u-boot-imx-45bf05854bc94ed8bae9e9114292895b990327ea.tar.bz2 |
armv7: adapt omap3 to the new cache maintenance framework
adapt omap3 to the new layered cache maintenance framework
Signed-off-by: Aneesh V <aneesh@ti.com>
-rw-r--r-- | arch/arm/cpu/armv7/omap3/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap3/board.c | 136 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap3/cache.S | 263 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/omap3/lowlevel_init.S | 32 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap3/omap3.h | 20 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-omap3/sys_proto.h | 10 |
6 files changed, 176 insertions, 286 deletions
diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile index 7164d50..522bcd2 100644 --- a/arch/arm/cpu/armv7/omap3/Makefile +++ b/arch/arm/cpu/armv7/omap3/Makefile @@ -26,7 +26,6 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -SOBJS += cache.o COBJS += board.o COBJS += clock.o diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 6c2a132..98519a9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -37,8 +37,12 @@ #include <asm/arch/sys_proto.h> #include <asm/arch/mem.h> #include <asm/cache.h> +#include <asm/armv7.h> +/* Declarations */ extern omap3_sysinfo sysinfo; +static void omap3_setup_aux_cr(void); +static void omap3_invalidate_l2_cache_secure(void); /****************************************************************************** * Routine: delay @@ -166,27 +170,13 @@ void s_init(void) try_unlock_memory(); - /* - * Right now flushing at low MPU speed. - * Need to move after clock init - */ - invalidate_dcache(get_device_type()); -#ifndef CONFIG_ICACHE_OFF - icache_enable(); -#endif + /* Errata workarounds */ + omap3_setup_aux_cr(); -#ifdef CONFIG_L2_OFF - l2_cache_disable(); -#else - l2_cache_enable(); +#ifndef CONFIG_SYS_L2CACHE_OFF + /* Invalidate L2-cache from secure mode */ + omap3_invalidate_l2_cache_secure(); #endif - /* - * Writing to AuxCR in U-boot using SMI for GP DEV - * Currently SMI in Kernel on ES2 devices seems to have an issue - * Once that is resolved, we can postpone this config to kernel - */ - if (get_device_type() == GP_DEVICE) - setup_auxcr(); set_muxconf_regs(); delay(100); @@ -292,3 +282,111 @@ int checkboard (void) return 0; } #endif /* CONFIG_DISPLAY_BOARDINFO */ + +static void omap3_emu_romcode_call(u32 service_id, u32 *parameters) +{ + u32 i, num_params = *parameters; + u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA; + + /* + * copy the parameters to an un-cached area to avoid coherency + * issues + */ + for (i = 0; i < num_params; i++) { + __raw_writel(*parameters, sram_scratch_space); + parameters++; + sram_scratch_space++; + } + + /* Now make the PPA call */ + do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA); +} + +static void omap3_update_aux_cr_secure(u32 set_bits, u32 clear_bits) +{ + u32 acr; + + /* Read ACR */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); + acr &= ~clear_bits; + acr |= set_bits; + + if (get_device_type() == GP_DEVICE) { + omap3_gp_romcode_call(OMAP3_GP_ROMCODE_API_WRITE_ACR, + acr); + } else { + struct emu_hal_params emu_romcode_params; + emu_romcode_params.num_params = 1; + emu_romcode_params.param1 = acr; + omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR, + (u32 *)&emu_romcode_params); + } +} + +static void omap3_update_aux_cr(u32 set_bits, u32 clear_bits) +{ + u32 acr; + + /* Read ACR */ + asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); + acr &= ~clear_bits; + acr |= set_bits; + + /* Write ACR - affects non-secure banked bits */ + asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (acr)); +} + +static void omap3_setup_aux_cr(void) +{ + /* Workaround for Cortex-A8 errata: #454179 #430973 + * Set "IBE" bit + * Set "Disable Brach Size Mispredicts" bit + * Workaround for erratum #621766 + * Enable L1NEON bit + * ACR |= (IBE | DBSM | L1NEON) => ACR |= 0xE0 + */ + omap3_update_aux_cr_secure(0xE0, 0); +} + +#ifndef CONFIG_SYS_L2CACHE_OFF +/* Invalidate the entire L2 cache from secure mode */ +static void omap3_invalidate_l2_cache_secure(void) +{ + if (get_device_type() == GP_DEVICE) { + omap3_gp_romcode_call(OMAP3_GP_ROMCODE_API_L2_INVAL, + 0); + } else { + struct emu_hal_params emu_romcode_params; + emu_romcode_params.num_params = 1; + emu_romcode_params.param1 = 0; + omap3_emu_romcode_call(OMAP3_EMU_HAL_API_L2_INVAL, + (u32 *)&emu_romcode_params); + } +} + +void v7_outer_cache_enable(void) +{ + /* Set L2EN */ + omap3_update_aux_cr_secure(0x2, 0); + + /* + * On some revisions L2EN bit is banked on some revisions it's not + * No harm in setting both banked bits(in fact this is required + * by an erratum) + */ + omap3_update_aux_cr(0x2, 0); +} + +void v7_outer_cache_disable(void) +{ + /* Clear L2EN */ + omap3_update_aux_cr_secure(0, 0x2); + + /* + * On some revisions L2EN bit is banked on some revisions it's not + * No harm in clearing both banked bits(in fact this is required + * by an erratum) + */ + omap3_update_aux_cr(0, 0x2); +} +#endif diff --git a/arch/arm/cpu/armv7/omap3/cache.S b/arch/arm/cpu/armv7/omap3/cache.S deleted file mode 100644 index cda87ba..0000000 --- a/arch/arm/cpu/armv7/omap3/cache.S +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (c) 2009 Wind River Systems, Inc. - * Tom Rix <Tom.Rix@windriver.com> - * - * This file is based on and replaces the existing cache.c file - * The copyrights for the cache.c file are: - * - * (C) Copyright 2008 Texas Insturments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.de> - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <asm/arch/omap3.h> - -/* - * omap3 cache code - */ - -.align 5 -.global invalidate_dcache -.global l2_cache_enable -.global l2_cache_disable -.global setup_auxcr - -/* - * invalidate_dcache() - * - * Invalidate the whole D-cache. - * - * Corrupted registers: r0-r5, r7, r9-r11 - * - * - mm - mm_struct describing address space - */ -invalidate_dcache: - stmfd r13!, {r0 - r5, r7, r9 - r12, r14} - - mov r7, r0 @ take a backup of device type - cmp r0, #0x3 @ check if the device type is - @ GP - moveq r12, #0x1 @ set up to invalide L2 -smi: .word 0x01600070 @ Call SMI monitor (smieq) - cmp r7, #0x3 @ compare again in case its - @ lost - beq finished_inval @ if GP device, inval done - @ above - - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished_inval @ if loc is 0, then no need to - @ clean - mov r10, #0 @ start clean at cache level 0 -inval_loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache - @ level - mov r1, r0, lsr r2 @ extract cache type bits from - @ clidr - and r1, r1, #7 @ mask of the bits for current - @ cache only - cmp r1, #2 @ see what cache we have at - @ this level - blt skip_inval @ skip if no cache, or just - @ i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mov r2, #0 @ operand for mcr SBZ - mcr p15, 0, r2, c7, c5, 4 @ flush prefetch buffer to - @ sych the new cssr&csidr, - @ with armv7 this is 'isb', - @ but we compile with armv5 - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the - @ cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the - @ way size - clz r5, r4 @ find bit position of way - @ size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the - @ index size -inval_loop2: - mov r9, r4 @ create working copy of max - @ way size -inval_loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number - @ into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge inval_loop3 - subs r7, r7, #1 @ decrement the index - bge inval_loop2 -skip_inval: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt inval_loop1 -finished_inval: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level - @ in cssr - mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, - @ with armv7 this is 'isb', - @ but we compile with armv5 - - ldmfd r13!, {r0 - r5, r7, r9 - r12, pc} - -l2_cache_set: - stmfd r13!, {r4 - r6, lr} - mov r5, r0 - bl get_cpu_rev - mov r4, r0 - bl get_cpu_family - @ ES2 onwards we can disable/enable L2 ourselves - cmp r0, #CPU_OMAP34XX - cmpeq r4, #CPU_3XX_ES10 - mrc 15, 0, r0, cr1, cr0, 1 - bic r0, r0, #2 - orr r0, r0, r5, lsl #1 - mcreq 15, 0, r0, cr1, cr0, 1 - @ GP Device ROM code API usage here - @ r12 = AUXCR Write function and r0 value - mov ip, #3 - @ SMCNE instruction to call ROM Code API - .word 0x11600070 - ldmfd r13!, {r4 - r6, pc} - -l2_cache_enable: - mov r0, #1 - b l2_cache_set - -l2_cache_disable: - mov r0, #0 - b l2_cache_set - -/****************************************************************************** - * Routine: setup_auxcr() - * Description: Write to AuxCR desired value using SMI. - * general use. - *****************************************************************************/ -setup_auxcr: - mrc p15, 0, r0, c0, c0, 0 @ read main ID register - and r2, r0, #0x00f00000 @ variant - and r3, r0, #0x0000000f @ revision - orr r1, r3, r2, lsr #20-4 @ combine variant and revision - mov r12, #0x3 - mrc p15, 0, r0, c1, c0, 1 - orr r0, r0, #0x10 @ Enable ASA - @ Enable L1NEON on pre-r2p1 (erratum 621766 workaround) - cmp r1, #0x21 - orrlt r0, r0, #1 << 5 - .word 0xE1600070 @ SMC - mov r12, #0x2 - mrc p15, 1, r0, c9, c0, 2 - @ Set PLD_FWD bit in L2AUXCR on pre-r2p1 (erratum 725233 workaround) - cmp r1, #0x21 - orrlt r0, r0, #1 << 27 - .word 0xE1600070 @ SMC - bx lr - -.align 5 -.global v7_flush_dcache_all -.global v7_flush_cache_all - -/* - * v7_flush_dcache_all() - * - * Flush the whole D-cache. - * - * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) - * - * - mm - mm_struct describing address space - */ -v7_flush_dcache_all: -# dmb @ ensure ordering with previous memory accesses - mrc p15, 1, r0, c0, c0, 1 @ read clidr - ands r3, r0, #0x7000000 @ extract loc from clidr - mov r3, r3, lsr #23 @ left align loc bit field - beq finished @ if loc is 0, then no need to clean - mov r10, #0 @ start clean at cache level 0 -loop1: - add r2, r10, r10, lsr #1 @ work out 3x current cache level - mov r1, r0, lsr r2 @ extract cache type bits from clidr - and r1, r1, #7 @ mask of the bits for current cache only - cmp r1, #2 @ see what cache we have at this level - blt skip @ skip if no cache, or just i-cache - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr - mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, - @ with armv7 this is 'isb', - @ but we compile with armv5 - mrc p15, 1, r1, c0, c0, 0 @ read the new csidr - and r2, r1, #7 @ extract the length of the cache lines - add r2, r2, #4 @ add 4 (line length offset) - ldr r4, =0x3ff - ands r4, r4, r1, lsr #3 @ find maximum number on the way size - clz r5, r4 @ find bit position of way size increment - ldr r7, =0x7fff - ands r7, r7, r1, lsr #13 @ extract max number of the index size -loop2: - mov r9, r4 @ create working copy of max way size -loop3: - orr r11, r10, r9, lsl r5 @ factor way and cache number into r11 - orr r11, r11, r7, lsl r2 @ factor index number into r11 - mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way - subs r9, r9, #1 @ decrement the way - bge loop3 - subs r7, r7, #1 @ decrement the index - bge loop2 -skip: - add r10, r10, #2 @ increment cache number - cmp r3, r10 - bgt loop1 -finished: - mov r10, #0 @ swith back to cache level 0 - mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr -# dsb - mcr p15, 0, r10, c7, c5, 4 @ flush prefetch buffer, - @ with armv7 this is 'isb', - @ but we compile with armv5 - mov pc, lr - -/* - * v7_flush_cache_all() - * - * Flush the entire cache system. - * The data cache flush is now achieved using atomic clean / invalidates - * working outwards from L1 cache. This is done using Set/Way based cache - * maintainance instructions. - * The instruction cache can still be invalidated back to the point of - * unification in a single instruction. - * - */ -v7_flush_cache_all: - stmfd sp!, {r0-r7, r9-r11, lr} - bl v7_flush_dcache_all - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate - ldmfd sp!, {r0-r7, r9-r11, lr} - mov pc, lr diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S index 1458072..67e8ceb 100644 --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S @@ -35,6 +35,38 @@ _TEXT_BASE: .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ +.global omap3_gp_romcode_call +omap3_gp_romcode_call: + PUSH {r4-r12, lr} @ Save all registers from ROM code! + MOV r12, r0 @ Copy the Service ID in R12 + MOV r0, r1 @ Copy parameter to R0 + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c10, 5 @ DMB + .word 0xe1600070 @ SMC #0 to enter monitor - hand assembled + @ because we use -march=armv5 + POP {r4-r12, pc} + +/* + * Funtion for making PPA HAL API calls in secure devices + * Input: + * R0 - Service ID + * R1 - paramer list + */ +.global do_omap3_emu_romcode_call +do_omap3_emu_romcode_call: + PUSH {r4-r12, lr} @ Save all registers from ROM code! + MOV r12, r0 @ Copy the Secure Service ID in R12 + MOV r3, r1 @ Copy the pointer to va_list in R3 + MOV r1, #0 @ Process ID - 0 + MOV r2, #OMAP3_EMU_HAL_START_HAL_CRITICAL @ Copy the pointer + @ to va_list in R3 + MOV r6, #0xFF @ Indicate new Task call + mcr p15, 0, r0, c7, c10, 4 @ DSB + mcr p15, 0, r0, c7, c10, 5 @ DMB + .word 0xe1600071 @ SMC #1 to call PPA service - hand assembled + @ because we use -march=armv5 + POP {r4-r12, pc} + #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_NAND_BOOT) /************************************************************************** * cpy_clk_code: relocates clock code into SRAM where its safer to execute diff --git a/arch/arm/include/asm/arch-omap3/omap3.h b/arch/arm/include/asm/arch-omap3/omap3.h index cc2b541..d9d49da 100644 --- a/arch/arm/include/asm/arch-omap3/omap3.h +++ b/arch/arm/include/asm/arch-omap3/omap3.h @@ -159,8 +159,14 @@ struct gpio { #define SRAM_VECT_CODE (SRAM_OFFSET0 | SRAM_OFFSET1 | \ SRAM_OFFSET2) +#define OMAP3_PUBLIC_SRAM_BASE 0x40208000 /* Works for GP & EMU */ +#define OMAP3_PUBLIC_SRAM_END 0x40210000 + #define LOW_LEVEL_SRAM_STACK 0x4020FFFC +/* scratch area - accessible on both EMU and GP */ +#define OMAP3_PUBLIC_SRAM_SCRATCH_AREA OMAP3_PUBLIC_SRAM_BASE + #define DEBUG_LED1 149 /* gpio */ #define DEBUG_LED2 150 /* gpio */ @@ -227,4 +233,18 @@ struct gpio { #define OMAP3730 0x0c00 +/* + * ROM code API related flags + */ +#define OMAP3_GP_ROMCODE_API_L2_INVAL 1 +#define OMAP3_GP_ROMCODE_API_WRITE_ACR 3 + +/* + * EMU device PPA HAL related flags + */ +#define OMAP3_EMU_HAL_API_L2_INVAL 40 +#define OMAP3_EMU_HAL_API_WRITE_ACR 42 + +#define OMAP3_EMU_HAL_START_HAL_CRITICAL 4 + #endif diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h index 4a28ba1..995e7cb 100644 --- a/arch/arm/include/asm/arch-omap3/sys_proto.h +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h @@ -27,6 +27,11 @@ typedef struct { char *nand_string; } omap3_sysinfo; +struct emu_hal_params { + u32 num_params; + u32 param1; +}; + void prcm_init(void); void per_clocks_enable(void); @@ -53,9 +58,7 @@ u32 is_running_in_sdram(void); u32 is_running_in_sram(void); u32 is_running_in_flash(void); u32 get_device_type(void); -void l2cache_enable(void); void secureworld_exit(void); -void setup_auxcr(void); void try_unlock_memory(void); u32 get_boot_type(void); void invalidate_dcache(u32); @@ -66,5 +69,6 @@ void make_cs1_contiguous(void); void omap_nand_switch_ecc(int); void power_init_r(void); void dieid_num_r(void); - +void do_omap3_emu_romcode_call(u32 service_id, u32 parameters); +void omap3_gp_romcode_call(u32 service_id, u32 parameter); #endif |