Message ID | 1391024389-4531-1-git-send-email-festevam@gmail.com |
---|---|
State | Accepted |
Delegated to: | Stefano Babic |
Headers | show |
Am 29.01.2014 20:39, schrieb Fabio Estevam: > From: Fabio Estevam <fabio.estevam@freescale.com> > > 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> Thanks Dirk > --- > Changes since v3: > - Enable l2 cache using the same method as the kernel > Changes since v2: > - Add L2_PL310_BASE definition in imx_regs.h > Changes since v1: > - Fx typo in commit log > > arch/arm/cpu/armv7/mx6/soc.c | 58 ++++++++++++++++++++++++++++++++ > arch/arm/include/asm/arch-mx6/imx-regs.h | 1 + > arch/arm/include/asm/pl310.h | 21 ++++++++++++ > include/configs/mx6_common.h | 5 +++ > 4 files changed, 85 insertions(+) > > diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c > index 0208cba..396bba5 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> > @@ -336,3 +338,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 f2ad6e9..c2d210a 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 f41ad8c..d4526af 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); > diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h > index 514d634..eb107d3 100644 > --- a/include/configs/mx6_common.h > +++ b/include/configs/mx6_common.h > @@ -22,4 +22,9 @@ > #define CONFIG_ARM_ERRATA_751472 > #define CONFIG_BOARD_POSTCLK_INIT > > +#ifndef CONFIG_SYS_L2CACHE_OFF > +#define CONFIG_SYS_L2_PL310 > +#define CONFIG_SYS_PL310_BASE L2_PL310_BASE > +#endif > + > #endif >
Hi Fabio, On 29/01/2014 20:39, Fabio Estevam wrote: > From: Fabio Estevam <fabio.estevam@freescale.com> > > 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> > --- > Changes since v3: > - Enable l2 cache using the same method as the kernel > Changes since v2: > - Add L2_PL310_BASE definition in imx_regs.h > Changes since v1: > - Fx typo in commit log > > arch/arm/cpu/armv7/mx6/soc.c | 58 ++++++++++++++++++++++++++++++++ > arch/arm/include/asm/arch-mx6/imx-regs.h | 1 + > arch/arm/include/asm/pl310.h | 21 ++++++++++++ > include/configs/mx6_common.h | 5 +++ > 4 files changed, 85 insertions(+) > > diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c > index 0208cba..396bba5 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> > @@ -336,3 +338,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 f2ad6e9..c2d210a 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 f41ad8c..d4526af 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); > diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h > index 514d634..eb107d3 100644 > --- a/include/configs/mx6_common.h > +++ b/include/configs/mx6_common.h > @@ -22,4 +22,9 @@ > #define CONFIG_ARM_ERRATA_751472 > #define CONFIG_BOARD_POSTCLK_INIT > > +#ifndef CONFIG_SYS_L2CACHE_OFF > +#define CONFIG_SYS_L2_PL310 > +#define CONFIG_SYS_PL310_BASE L2_PL310_BASE > +#endif > + > #endif Put in my queue for merging. Acked-by: Stefano Babic <sbabic@denx.de> Best regards, Stefano
On 29/01/2014 20:39, Fabio Estevam wrote: > From: Fabio Estevam <fabio.estevam@freescale.com> > > 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> > --- Applied to u-boot-imx, thanks ! Best regards, Stefano Babic
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 0208cba..396bba5 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> @@ -336,3 +338,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 f2ad6e9..c2d210a 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 f41ad8c..d4526af 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); diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index 514d634..eb107d3 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -22,4 +22,9 @@ #define CONFIG_ARM_ERRATA_751472 #define CONFIG_BOARD_POSTCLK_INIT +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE L2_PL310_BASE +#endif + #endif