[U-Boot] imx: Check the PL310 version for applying errata
diff mbox series

Message ID 1546853345-24351-1-git-send-email-ye.li@nxp.com
State Accepted
Commit d8bbf362f3dc87326597217b8bab083516cf534f
Delegated to: Stefano Babic
Headers show
Series
  • [U-Boot] imx: Check the PL310 version for applying errata
Related show

Commit Message

Ye Li Jan. 7, 2019, 9:29 a.m. UTC
Apply errata based on PL310 version instead of compile
time. Also set Prefetch offset to 15, since it improves
memcpy performance by 35%. Don't enable Incr double
Linefill enable since it adversely affects memcpy
performance by about 32MB/s and reads by 90MB/s. Tested
with 4K to 16MB sized src and dst aligned buffer.

Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
---
 arch/arm/include/asm/pl310.h |  5 +++++
 arch/arm/mach-imx/cache.c    | 18 ++++++++++--------
 2 files changed, 15 insertions(+), 8 deletions(-)

Comments

Stefano Babic Jan. 28, 2019, 2:39 p.m. UTC | #1
Hi Ye,

On 07/01/19 10:29, Ye Li wrote:
> Apply errata based on PL310 version instead of compile
> time. Also set Prefetch offset to 15, since it improves
> memcpy performance by 35%. Don't enable Incr double
> Linefill enable since it adversely affects memcpy
> performance by about 32MB/s and reads by 90MB/s. Tested
> with 4K to 16MB sized src and dst aligned buffer.
> 
> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
> Signed-off-by: Ye Li <ye.li@nxp.com>
> ---
>  arch/arm/include/asm/pl310.h |  5 +++++
>  arch/arm/mach-imx/cache.c    | 18 ++++++++++--------
>  2 files changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/include/asm/pl310.h b/arch/arm/include/asm/pl310.h
> index 3624362..b83978b 100644
> --- a/arch/arm/include/asm/pl310.h
> +++ b/arch/arm/include/asm/pl310.h
> @@ -19,6 +19,11 @@
>  #define L310_AUX_CTRL_DATA_PREFETCH_MASK	(1 << 28)
>  #define L310_AUX_CTRL_INST_PREFETCH_MASK	(1 << 29)
>  
> +#define L2X0_CACHE_ID_PART_MASK     (0xf << 6)
> +#define L2X0_CACHE_ID_PART_L310     (3 << 6)
> +#define L2X0_CACHE_ID_RTL_MASK          0x3f
> +#define L2X0_CACHE_ID_RTL_R3P2          0x8
> +
>  struct pl310_regs {
>  	u32 pl310_cache_id;
>  	u32 pl310_cache_type;
> diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c
> index 82257f3..75e1f54 100644
> --- a/arch/arm/mach-imx/cache.c
> +++ b/arch/arm/mach-imx/cache.c
> @@ -82,7 +82,7 @@ void v7_outer_cache_enable(void)
>  {
>  	struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
>  	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
> -	unsigned int val;
> +	unsigned int val, cache_id;
>  
>  
>  	/*
> @@ -112,22 +112,24 @@ void v7_outer_cache_enable(void)
>  
>  	val = readl(&pl310->pl310_prefetch_ctrl);
>  
> -	/* Turn on the L2 I/D prefetch */
> -	val |= 0x30000000;
> +	/* Turn on the L2 I/D prefetch, double linefill */
> +	/* Set prefetch offset with any value except 23 as per errata 765569 */
> +	val |= 0x7000000f;
>  
>  	/*
>  	 * 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
> +	 * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL/SX/DQP
> +	 * 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
> +	cache_id = readl(&pl310->pl310_cache_id);
> +	if (((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310)
> +	    && ((cache_id & L2X0_CACHE_ID_RTL_MASK) < L2X0_CACHE_ID_RTL_R3P2))
> +		val &= ~(1 << 30);

Very good idea !

Reviewd-by: Stefano Babic <sbabic@denc.de>

Best regards,
Stefano Babic

>  	writel(val, &pl310->pl310_prefetch_ctrl);
>  
>  	val = readl(&pl310->pl310_power_ctrl);
>

Patch
diff mbox series

diff --git a/arch/arm/include/asm/pl310.h b/arch/arm/include/asm/pl310.h
index 3624362..b83978b 100644
--- a/arch/arm/include/asm/pl310.h
+++ b/arch/arm/include/asm/pl310.h
@@ -19,6 +19,11 @@ 
 #define L310_AUX_CTRL_DATA_PREFETCH_MASK	(1 << 28)
 #define L310_AUX_CTRL_INST_PREFETCH_MASK	(1 << 29)
 
+#define L2X0_CACHE_ID_PART_MASK     (0xf << 6)
+#define L2X0_CACHE_ID_PART_L310     (3 << 6)
+#define L2X0_CACHE_ID_RTL_MASK          0x3f
+#define L2X0_CACHE_ID_RTL_R3P2          0x8
+
 struct pl310_regs {
 	u32 pl310_cache_id;
 	u32 pl310_cache_type;
diff --git a/arch/arm/mach-imx/cache.c b/arch/arm/mach-imx/cache.c
index 82257f3..75e1f54 100644
--- a/arch/arm/mach-imx/cache.c
+++ b/arch/arm/mach-imx/cache.c
@@ -82,7 +82,7 @@  void v7_outer_cache_enable(void)
 {
 	struct pl310_regs *const pl310 = (struct pl310_regs *)L2_PL310_BASE;
 	struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
-	unsigned int val;
+	unsigned int val, cache_id;
 
 
 	/*
@@ -112,22 +112,24 @@  void v7_outer_cache_enable(void)
 
 	val = readl(&pl310->pl310_prefetch_ctrl);
 
-	/* Turn on the L2 I/D prefetch */
-	val |= 0x30000000;
+	/* Turn on the L2 I/D prefetch, double linefill */
+	/* Set prefetch offset with any value except 23 as per errata 765569 */
+	val |= 0x7000000f;
 
 	/*
 	 * 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
+	 * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL/SX/DQP
+	 * 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
+	cache_id = readl(&pl310->pl310_cache_id);
+	if (((cache_id & L2X0_CACHE_ID_PART_MASK) == L2X0_CACHE_ID_PART_L310)
+	    && ((cache_id & L2X0_CACHE_ID_RTL_MASK) < L2X0_CACHE_ID_RTL_R3P2))
+		val &= ~(1 << 30);
 	writel(val, &pl310->pl310_prefetch_ctrl);
 
 	val = readl(&pl310->pl310_power_ctrl);