summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorFabio Estevam <fabio.estevam@freescale.com>2014-01-29 17:39:49 -0200
committerStefano Babic <sbabic@denx.de>2014-02-11 11:24:12 +0100
commit6d73c23410cd0f8a54227dd0361fb8b9eadcb4b2 (patch)
tree6e1b31648037762e47c487b94a271c14789d5c69 /arch/arm
parent4702c62dce3e2e2648ae3c8d002202211de8c92a (diff)
mx6: Enable L2 cache support
Add L2 cache support and enable it by default. Configure the L2 cache in the same way as done by FSL kernel: http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/arch/arm/mach-mx6/mm.c?h=imx_3.0.35_4.1.0 Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com> Acked-by: Dirk Behme <dirk.behme@gmail.com> Acked-by: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c58
-rw-r--r--arch/arm/include/asm/arch-mx6/imx-regs.h1
-rw-r--r--arch/arm/include/asm/pl310.h21
3 files changed, 80 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 4c5c367221..172527987d 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -8,6 +8,8 @@
*/
#include <common.h>
+#include <asm/armv7.h>
+#include <asm/pl310.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
@@ -375,3 +377,59 @@ void imx_setup_hdmi(void)
writel(reg, &mxc_ccm->chsccdr);
}
#endif
+
+#ifndef CONFIG_SYS_L2CACHE_OFF
+#define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
+void v7_outer_cache_enable(void)
+{
+ struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
+ unsigned int val;
+
+#if defined CONFIG_MX6SL
+ struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+ val = readl(&iomux->gpr[11]);
+ if (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM) {
+ /* L2 cache configured as OCRAM, reset it */
+ val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
+ writel(val, &iomux->gpr[11]);
+ }
+#endif
+
+ writel(0x132, &pl310->pl310_tag_latency_ctrl);
+ writel(0x132, &pl310->pl310_data_latency_ctrl);
+
+ val = readl(&pl310->pl310_prefetch_ctrl);
+
+ /* Turn on the L2 I/D prefetch */
+ val |= 0x30000000;
+
+ /*
+ * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
+ * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
+ * But according to ARM PL310 errata: 752271
+ * ID: 752271: Double linefill feature can cause data corruption
+ * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
+ * Workaround: The only workaround to this erratum is to disable the
+ * double linefill feature. This is the default behavior.
+ */
+
+#ifndef CONFIG_MX6Q
+ val |= 0x40800000;
+#endif
+ writel(val, &pl310->pl310_prefetch_ctrl);
+
+ val = readl(&pl310->pl310_power_ctrl);
+ val |= L2X0_DYNAMIC_CLK_GATING_EN;
+ val |= L2X0_STNDBY_MODE_EN;
+ writel(val, &pl310->pl310_power_ctrl);
+
+ setbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+}
+
+void v7_outer_cache_disable(void)
+{
+ struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
+
+ clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN);
+}
+#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index f2ad6e9ad3..c2d210a0f3 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -53,6 +53,7 @@
#define GLOBAL_TIMER_BASE_ADDR 0x00A00200
#define PRIVATE_TIMERS_WD_BASE_ADDR 0x00A00600
#define IC_DISTRIBUTOR_BASE_ADDR 0x00A01000
+#define L2_PL310_BASE 0x00A02000
#define GPV0_BASE_ADDR 0x00B00000
#define GPV1_BASE_ADDR 0x00C00000
#define PCIE_ARB_BASE_ADDR 0x01000000
diff --git a/arch/arm/include/asm/pl310.h b/arch/arm/include/asm/pl310.h
index f41ad8c559..ddc245bfd5 100644
--- a/arch/arm/include/asm/pl310.h
+++ b/arch/arm/include/asm/pl310.h
@@ -12,6 +12,9 @@
/* Register bit fields */
#define PL310_AUX_CTRL_ASSOCIATIVITY_MASK (1 << 16)
+#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
+#define L2X0_STNDBY_MODE_EN (1 << 0)
+#define L2X0_CTRL_EN 1
struct pl310_regs {
u32 pl310_cache_id;
@@ -47,6 +50,24 @@ struct pl310_regs {
u32 pad9[1];
u32 pl310_clean_inv_line_idx;
u32 pl310_clean_inv_way;
+ u32 pad10[64];
+ u32 pl310_lockdown_dbase;
+ u32 pl310_lockdown_ibase;
+ u32 pad11[190];
+ u32 pl310_addr_filter_start;
+ u32 pl310_addr_filter_end;
+ u32 pad12[190];
+ u32 pl310_test_operation;
+ u32 pad13[3];
+ u32 pl310_line_data;
+ u32 pad14[7];
+ u32 pl310_line_tag;
+ u32 pad15[3];
+ u32 pl310_debug_ctrl;
+ u32 pad16[7];
+ u32 pl310_prefetch_ctrl;
+ u32 pad17[7];
+ u32 pl310_power_ctrl;
};
void pl310_inval_all(void);