1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2552a848eSStefano Babic /* 3552a848eSStefano Babic * Copyright 2015 Freescale Semiconductor, Inc. 4552a848eSStefano Babic */ 5552a848eSStefano Babic 6552a848eSStefano Babic #include <common.h> 7552a848eSStefano Babic #include <asm/armv7.h> 8552a848eSStefano Babic #include <asm/pl310.h> 9552a848eSStefano Babic #include <asm/io.h> 10552a848eSStefano Babic #include <asm/mach-imx/sys_proto.h> 11552a848eSStefano Babic 12552a848eSStefano Babic #ifndef CONFIG_SYS_DCACHE_OFF 13552a848eSStefano Babic void enable_caches(void) 14552a848eSStefano Babic { 15552a848eSStefano Babic #if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) 16552a848eSStefano Babic enum dcache_option option = DCACHE_WRITETHROUGH; 17552a848eSStefano Babic #else 18552a848eSStefano Babic enum dcache_option option = DCACHE_WRITEBACK; 19552a848eSStefano Babic #endif 20552a848eSStefano Babic /* Avoid random hang when download by usb */ 21552a848eSStefano Babic invalidate_dcache_all(); 22552a848eSStefano Babic 23552a848eSStefano Babic /* Enable D-cache. I-cache is already enabled in start.S */ 24552a848eSStefano Babic dcache_enable(); 25552a848eSStefano Babic 26552a848eSStefano Babic /* Enable caching on OCRAM and ROM */ 27552a848eSStefano Babic mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, 28552a848eSStefano Babic ROMCP_ARB_END_ADDR, 29552a848eSStefano Babic option); 30552a848eSStefano Babic mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, 31552a848eSStefano Babic IRAM_SIZE, 32552a848eSStefano Babic option); 33552a848eSStefano Babic } 34552a848eSStefano Babic #endif 35552a848eSStefano Babic 36552a848eSStefano Babic #ifndef CONFIG_SYS_L2CACHE_OFF 37552a848eSStefano Babic #ifdef CONFIG_SYS_L2_PL310 38552a848eSStefano Babic #define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002 39552a848eSStefano Babic void v7_outer_cache_enable(void) 40552a848eSStefano Babic { 41552a848eSStefano Babic struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE; 42552a848eSStefano Babic struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; 43552a848eSStefano Babic unsigned int val; 44552a848eSStefano Babic 45552a848eSStefano Babic 46552a848eSStefano Babic /* 47552a848eSStefano Babic * Must disable the L2 before changing the latency parameters 48552a848eSStefano Babic * and auxiliary control register. 49552a848eSStefano Babic */ 50552a848eSStefano Babic clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 51552a848eSStefano Babic 52552a848eSStefano Babic /* 53552a848eSStefano Babic * Set bit 22 in the auxiliary control register. If this bit 54552a848eSStefano Babic * is cleared, PL310 treats Normal Shared Non-cacheable 55552a848eSStefano Babic * accesses as Cacheable no-allocate. 56552a848eSStefano Babic */ 57552a848eSStefano Babic setbits_le32(&pl310->pl310_aux_ctrl, L310_SHARED_ATT_OVERRIDE_ENABLE); 58552a848eSStefano Babic 59552a848eSStefano Babic if (is_mx6sl() || is_mx6sll()) { 60552a848eSStefano Babic val = readl(&iomux->gpr[11]); 61552a848eSStefano Babic if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) { 62552a848eSStefano Babic /* L2 cache configured as OCRAM, reset it */ 63552a848eSStefano Babic val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM; 64552a848eSStefano Babic writel(val, &iomux->gpr[11]); 65552a848eSStefano Babic } 66552a848eSStefano Babic } 67552a848eSStefano Babic 68552a848eSStefano Babic writel(0x132, &pl310->pl310_tag_latency_ctrl); 69552a848eSStefano Babic writel(0x132, &pl310->pl310_data_latency_ctrl); 70552a848eSStefano Babic 71552a848eSStefano Babic val = readl(&pl310->pl310_prefetch_ctrl); 72552a848eSStefano Babic 73552a848eSStefano Babic /* Turn on the L2 I/D prefetch */ 74552a848eSStefano Babic val |= 0x30000000; 75552a848eSStefano Babic 76552a848eSStefano Babic /* 77552a848eSStefano Babic * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0 78552a848eSStefano Babic * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2 79552a848eSStefano Babic * But according to ARM PL310 errata: 752271 80552a848eSStefano Babic * ID: 752271: Double linefill feature can cause data corruption 81552a848eSStefano Babic * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2 82552a848eSStefano Babic * Workaround: The only workaround to this erratum is to disable the 83552a848eSStefano Babic * double linefill feature. This is the default behavior. 84552a848eSStefano Babic */ 85552a848eSStefano Babic 86552a848eSStefano Babic #ifndef CONFIG_MX6Q 87552a848eSStefano Babic val |= 0x40800000; 88552a848eSStefano Babic #endif 89552a848eSStefano Babic writel(val, &pl310->pl310_prefetch_ctrl); 90552a848eSStefano Babic 91552a848eSStefano Babic val = readl(&pl310->pl310_power_ctrl); 92552a848eSStefano Babic val |= L2X0_DYNAMIC_CLK_GATING_EN; 93552a848eSStefano Babic val |= L2X0_STNDBY_MODE_EN; 94552a848eSStefano Babic writel(val, &pl310->pl310_power_ctrl); 95552a848eSStefano Babic 96552a848eSStefano Babic setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 97552a848eSStefano Babic } 98552a848eSStefano Babic 99552a848eSStefano Babic void v7_outer_cache_disable(void) 100552a848eSStefano Babic { 101552a848eSStefano Babic struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE; 102552a848eSStefano Babic 103552a848eSStefano Babic clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); 104552a848eSStefano Babic } 105552a848eSStefano Babic #endif /* !CONFIG_SYS_L2_PL310 */ 106552a848eSStefano Babic #endif /* !CONFIG_SYS_L2CACHE_OFF */ 107