All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/4] ARC: read pae_exist bit from MMU BCR
@ 2018-01-16 16:20 Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 2/4] ARC: ARCv2: CACHE: fix work without IOC Eugeniy Paltsev
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eugeniy Paltsev @ 2018-01-16 16:20 UTC (permalink / raw)
  To: u-boot

ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
only if PAE exists in current HW. So we had to check pae_exist bit
before using them.

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
---
 arch/arc/include/asm/arcregs.h |  3 +++
 arch/arc/lib/cache.c           | 28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index ba1f7ba..53e83c7 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -65,6 +65,9 @@
 #define ARC_AUX_SLC_FLDL	0x912
 #define ARC_BCR_CLUSTER		0xcf
 
+/* MMU Management regs */
+#define ARC_AUX_MMU_BCR		0x06f
+
 /* IO coherency related auxiliary registers */
 #define ARC_AUX_IO_COH_ENABLE	0x500
 #define ARC_AUX_IO_COH_PARTIAL	0x501
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 1073e15..0a41dc4 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -41,6 +41,32 @@ bool icache_exists __section(".data") = false;
 int slc_line_sz __section(".data");
 bool slc_exists __section(".data") = false;
 bool ioc_exists __section(".data") = false;
+bool pae_exists __section(".data") = false;
+
+void read_decode_mmu_bcr(void)
+{
+	/* TODO: should we compare mmu version from BCR and from CONFIG? */
+#if (CONFIG_ARC_MMU_VER >= 4)
+	u32 tmp;
+
+	tmp = read_aux_reg(ARC_AUX_MMU_BCR);
+
+	struct bcr_mmu_4 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1,
+		     n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3;
+#else
+	/*           DTLB      ITLB      JES        JE         JA      */
+	unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2,
+		     pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8;
+#endif /* CONFIG_CPU_BIG_ENDIAN */
+	} *mmu4;
+
+	mmu4 = (struct bcr_mmu_4 *)&tmp;
+
+	pae_exists = !!mmu4->pae;
+#endif /* (CONFIG_ARC_MMU_VER >= 4) */
+}
 
 static unsigned int __before_slc_op(const int op)
 {
@@ -244,6 +270,8 @@ void cache_init(void)
 		write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
 
 	}
+
+	read_decode_mmu_bcr();
 #endif
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [U-Boot] [PATCH 2/4] ARC: ARCv2: CACHE: fix work without IOC
  2018-01-16 16:20 [U-Boot] [PATCH 1/4] ARC: read pae_exist bit from MMU BCR Eugeniy Paltsev
@ 2018-01-16 16:20 ` Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 3/4] ARC: CACHE: disable IOC by default Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 4/4] ARC: CACHE: fix style violations Eugeniy Paltsev
  2 siblings, 0 replies; 4+ messages in thread
From: Eugeniy Paltsev @ 2018-01-16 16:20 UTC (permalink / raw)
  To: u-boot

Previous slc_line_op implementation is broken. It was never tested/used
as we use u-boot with IOC enabled. So if we disable IOC we will
get a lot of errors while using DMA peripherals.
Fix it by replacingi broken slc_line_op with slc region operations (which
are used in linux kernel)

Main changes:
 * Replace __slc_line_op (per line operations) by __slc_rgn_op
   (region operations) Implementation from 4.14 linux kernel.
 * Rework __slc_entire_op to get rid of __after_slc_op and
   __before_slc_op functions. Implementation from 4.14 linux kernel
   with flush fix (flush only instead of flush-n-inv when OP_FLUSH is
   used)
 * Add SLC invalidation to invalidate_icache_all function.
 * Add (start >= end) check to invalidate_dcache_range and
   flush_dcache_range as some buggy drivers pass region start == end.

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
---
 arch/arc/include/asm/arcregs.h |   4 +
 arch/arc/lib/cache.c           | 167 +++++++++++++++++++++++------------------
 2 files changed, 97 insertions(+), 74 deletions(-)

diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 53e83c7..67f4163 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -63,6 +63,10 @@
 #define ARC_AUX_SLC_INVALIDATE	0x905
 #define ARC_AUX_SLC_IVDL	0x910
 #define ARC_AUX_SLC_FLDL	0x912
+#define ARC_AUX_SLC_RGN_START	0x914
+#define ARC_AUX_SLC_RGN_START1	0x915
+#define ARC_AUX_SLC_RGN_END	0x916
+#define ARC_AUX_SLC_RGN_END1	0x917
 #define ARC_BCR_CLUSTER		0xcf
 
 /* MMU Management regs */
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 0a41dc4..a6bbe3c 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -20,12 +20,17 @@
 #define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
 #define DC_CTRL_FLUSH_STATUS	(1 << 8)
 #define CACHE_VER_NUM_MASK	0xF
-#define SLC_CTRL_SB		(1 << 2)
 
 #define OP_INV		0x1
 #define OP_FLUSH	0x2
 #define OP_INV_IC	0x3
 
+/* Bit val in SLC_CONTROL */
+#define SLC_CTRL_DIS		0x001
+#define SLC_CTRL_IM		0x040
+#define SLC_CTRL_BUSY		0x100
+#define SLC_CTRL_RGN_OP_INV	0x200
+
 /*
  * By default that variable will fall into .bss section.
  * But .bss section is not relocated and so it will be initilized before
@@ -68,87 +73,88 @@ void read_decode_mmu_bcr(void)
 #endif /* (CONFIG_ARC_MMU_VER >= 4) */
 }
 
-static unsigned int __before_slc_op(const int op)
+static void __slc_entire_op(const int op)
 {
-	unsigned int reg = reg;
+	unsigned int ctrl;
 
-	if (op == OP_INV) {
-		/*
-		 * IM is set by default and implies Flush-n-inv
-		 * Clear it here for vanilla inv
-		 */
-		reg = read_aux_reg(ARC_AUX_SLC_CTRL);
-		write_aux_reg(ARC_AUX_SLC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
-	}
+	ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
 
-	return reg;
-}
-
-static void __after_slc_op(const int op, unsigned int reg)
-{
-	if (op & OP_FLUSH) {	/* flush / flush-n-inv both wait */
-		/*
-		 * Make sure "busy" bit reports correct status,
-		 * see STAR 9001165532
-		 */
-		read_aux_reg(ARC_AUX_SLC_CTRL);
-		while (read_aux_reg(ARC_AUX_SLC_CTRL) &
-		       DC_CTRL_FLUSH_STATUS)
-			;
-	}
-
-	/* Switch back to default Invalidate mode */
-	if (op == OP_INV)
-		write_aux_reg(ARC_AUX_SLC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
-}
-
-static inline void __slc_line_loop(unsigned long paddr, unsigned long sz,
-				   const int op)
-{
-	unsigned int aux_cmd;
-	int num_lines;
+	if (!(op & OP_FLUSH))		/* i.e. OP_INV */
+		ctrl &= ~SLC_CTRL_IM;	/* clear IM: Disable flush before Inv */
+	else
+		ctrl |= SLC_CTRL_IM;
 
-#define SLC_LINE_MASK	(~(slc_line_sz - 1))
+	write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
 
-	aux_cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL;
+	if (op & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
+		write_aux_reg(ARC_AUX_SLC_INVALIDATE, 0x1);
+	else
+		write_aux_reg(ARC_AUX_SLC_FLUSH, 0x1);
 
-	sz += paddr & ~SLC_LINE_MASK;
-	paddr &= SLC_LINE_MASK;
+	/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+	read_aux_reg(ARC_AUX_SLC_CTRL);
 
-	num_lines = DIV_ROUND_UP(sz, slc_line_sz);
+	/* Important to wait for flush to complete */
+	while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
+}
 
-	while (num_lines-- > 0) {
-		write_aux_reg(aux_cmd, paddr);
-		paddr += slc_line_sz;
-	}
+static void slc_upper_region_init(void)
+{
+	/*
+	 * ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1 are always == 0
+	 * as we don't use PAE40.
+	 */
+	write_aux_reg(ARC_AUX_SLC_RGN_END1, 0);
+	write_aux_reg(ARC_AUX_SLC_RGN_START1, 0);
 }
 
-static inline void __slc_entire_op(const int cacheop)
+static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
 {
-	int aux;
-	unsigned int ctrl_reg = __before_slc_op(cacheop);
+	unsigned int ctrl;
+	unsigned long end;
+
+	/*
+	 * The Region Flush operation is specified by CTRL.RGN_OP[11..9]
+	 *  - b'000 (default) is Flush,
+	 *  - b'001 is Invalidate if CTRL.IM == 0
+	 *  - b'001 is Flush-n-Invalidate if CTRL.IM == 1
+	 */
+	ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
+
+	/* Don't rely on default value of IM bit */
+	if (!(op & OP_FLUSH))		/* i.e. OP_INV */
+		ctrl &= ~SLC_CTRL_IM;	/* clear IM: Disable flush before Inv */
+	else
+		ctrl |= SLC_CTRL_IM;
 
-	if (cacheop & OP_INV)	/* Inv or flush-n-inv use same cmd reg */
-		aux = ARC_AUX_SLC_INVALIDATE;
+	if (op & OP_INV)
+		ctrl |= SLC_CTRL_RGN_OP_INV;	/* Inv or flush-n-inv */
 	else
-		aux = ARC_AUX_SLC_FLUSH;
+		ctrl &= ~SLC_CTRL_RGN_OP_INV;
 
-	write_aux_reg(aux, 0x1);
+	write_aux_reg(ARC_AUX_SLC_CTRL, ctrl);
 
-	__after_slc_op(cacheop, ctrl_reg);
-}
+	/*
+	 * Lower bits are ignored, no need to clip
+	 * END needs to be setup before START (latter triggers the operation)
+	 * END can't be same as START, so add (l2_line_sz - 1) to sz
+	 */
+	end = paddr + sz + slc_line_sz - 1;
 
-static inline void __slc_line_op(unsigned long paddr, unsigned long sz,
-				 const int cacheop)
-{
-	unsigned int ctrl_reg = __before_slc_op(cacheop);
-	__slc_line_loop(paddr, sz, cacheop);
-	__after_slc_op(cacheop, ctrl_reg);
+	/*
+	 * Upper addresses (ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1)
+	 * are always == 0 as we don't use PAE40, so we only setup lower ones
+	 * (ARC_AUX_SLC_RGN_END and ARC_AUX_SLC_RGN_START)
+	 */
+	write_aux_reg(ARC_AUX_SLC_RGN_END, end);
+	write_aux_reg(ARC_AUX_SLC_RGN_START, paddr);
+
+	/* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */
+	read_aux_reg(ARC_AUX_SLC_CTRL);
+
+	while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
 }
-#else
-#define __slc_entire_op(cacheop)
-#define __slc_line_op(paddr, sz, cacheop)
-#endif
+#endif /* CONFIG_ISA_ARCV2 */
 
 #ifdef CONFIG_ISA_ARCV2
 static void read_decode_cache_bcr_arcv2(void)
@@ -272,7 +278,15 @@ void cache_init(void)
 	}
 
 	read_decode_mmu_bcr();
-#endif
+
+	/*
+	 * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
+	 * only if PAE exists in current HW. So we had to check pae_exist
+	 * before using them.
+	 */
+	if (slc_exists && pae_exists)
+		slc_upper_region_init();
+#endif /* CONFIG_ISA_ARCV2 */
 }
 
 int icache_status(void)
@@ -300,7 +314,6 @@ void icache_disable(void)
 			      IC_CTRL_CACHE_DISABLE);
 }
 
-#ifndef CONFIG_SYS_DCACHE_OFF
 void invalidate_icache_all(void)
 {
 	/* Any write to IC_IVIC register triggers invalidation of entire I$ */
@@ -315,12 +328,12 @@ void invalidate_icache_all(void)
 		__builtin_arc_nop();
 		read_aux_reg(ARC_AUX_IC_CTRL);	/* blocks */
 	}
-}
-#else
-void invalidate_icache_all(void)
-{
-}
+
+#ifdef CONFIG_ISA_ARCV2
+	if (slc_exists)
+		__slc_entire_op(OP_INV);
 #endif
+}
 
 int dcache_status(void)
 {
@@ -447,6 +460,9 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
 
 void invalidate_dcache_range(unsigned long start, unsigned long end)
 {
+	if (start >= end)
+		return;
+
 #ifdef CONFIG_ISA_ARCV2
 	if (!ioc_exists)
 #endif
@@ -454,12 +470,15 @@ void invalidate_dcache_range(unsigned long start, unsigned long end)
 
 #ifdef CONFIG_ISA_ARCV2
 	if (slc_exists && !ioc_exists)
-		__slc_line_op(start, end - start, OP_INV);
+		__slc_rgn_op(start, end - start, OP_INV);
 #endif
 }
 
 void flush_dcache_range(unsigned long start, unsigned long end)
 {
+	if (start >= end)
+		return;
+
 #ifdef CONFIG_ISA_ARCV2
 	if (!ioc_exists)
 #endif
@@ -467,7 +486,7 @@ void flush_dcache_range(unsigned long start, unsigned long end)
 
 #ifdef CONFIG_ISA_ARCV2
 	if (slc_exists && !ioc_exists)
-		__slc_line_op(start, end - start, OP_FLUSH);
+		__slc_rgn_op(start, end - start, OP_FLUSH);
 #endif
 }
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [U-Boot] [PATCH 3/4] ARC: CACHE: disable IOC by default
  2018-01-16 16:20 [U-Boot] [PATCH 1/4] ARC: read pae_exist bit from MMU BCR Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 2/4] ARC: ARCv2: CACHE: fix work without IOC Eugeniy Paltsev
@ 2018-01-16 16:20 ` Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 4/4] ARC: CACHE: fix style violations Eugeniy Paltsev
  2 siblings, 0 replies; 4+ messages in thread
From: Eugeniy Paltsev @ 2018-01-16 16:20 UTC (permalink / raw)
  To: u-boot

Disable IOC by default with option to enable it.
We don't want to enable IOC in u-boot by default as we want
keep IOC HW at same state as after reset when we launching linux.

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
---
 arch/arc/lib/cache.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index a6bbe3c..d17948d 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -48,6 +48,9 @@ bool slc_exists __section(".data") = false;
 bool ioc_exists __section(".data") = false;
 bool pae_exists __section(".data") = false;
 
+/* To force enable IOC set ioc_enable to 'true' */
+bool ioc_enable __section(".data") = false;
+
 void read_decode_mmu_bcr(void)
 {
 	/* TODO: should we compare mmu version from BCR and from CONFIG? */
@@ -200,7 +203,7 @@ static void read_decode_cache_bcr_arcv2(void)
 	} cbcr;
 
 	cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
-	if (cbcr.fields.c)
+	if (cbcr.fields.c && ioc_enable)
 		ioc_exists = true;
 }
 #endif
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [U-Boot] [PATCH 4/4] ARC: CACHE: fix style violations
  2018-01-16 16:20 [U-Boot] [PATCH 1/4] ARC: read pae_exist bit from MMU BCR Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 2/4] ARC: ARCv2: CACHE: fix work without IOC Eugeniy Paltsev
  2018-01-16 16:20 ` [U-Boot] [PATCH 3/4] ARC: CACHE: disable IOC by default Eugeniy Paltsev
@ 2018-01-16 16:20 ` Eugeniy Paltsev
  2 siblings, 0 replies; 4+ messages in thread
From: Eugeniy Paltsev @ 2018-01-16 16:20 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
---
 arch/arc/lib/cache.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index d17948d..04f1d9d 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -13,12 +13,12 @@
 #include <asm/cache.h>
 
 /* Bit values in IC_CTRL */
-#define IC_CTRL_CACHE_DISABLE	(1 << 0)
+#define IC_CTRL_CACHE_DISABLE	BIT(0)
 
 /* Bit values in DC_CTRL */
-#define DC_CTRL_CACHE_DISABLE	(1 << 0)
-#define DC_CTRL_INV_MODE_FLUSH	(1 << 6)
-#define DC_CTRL_FLUSH_STATUS	(1 << 8)
+#define DC_CTRL_CACHE_DISABLE	BIT(0)
+#define DC_CTRL_INV_MODE_FLUSH	BIT(6)
+#define DC_CTRL_FLUSH_STATUS	BIT(8)
 #define CACHE_VER_NUM_MASK	0xF
 
 #define OP_INV		0x1
@@ -232,7 +232,7 @@ void read_decode_cache_bcr(void)
 	}
 
 	dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
-	if (dbcr.fields.ver){
+	if (dbcr.fields.ver) {
 		dcache_exists = true;
 		l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
 		if (!dc_line_sz)
@@ -267,8 +267,7 @@ void cache_init(void)
 		 * so setting 0x11 implies 512M, 0x12 implies 1G...
 		 */
 		write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE,
-			      order_base_2(ap_size/1024) - 2);
-
+			      order_base_2(ap_size / 1024) - 2);
 
 		/* IOC Aperture start must be aligned to the size of the aperture */
 		if (ap_base % ap_size != 0)
@@ -277,7 +276,6 @@ void cache_init(void)
 		write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, ap_base >> 12);
 		write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
 		write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
-
 	}
 
 	read_decode_mmu_bcr();
@@ -426,8 +424,7 @@ static unsigned int __before_dc_op(const int op)
 static void __after_dc_op(const int op, unsigned int reg)
 {
 	if (op & OP_FLUSH)	/* flush / flush-n-inv both wait */
-		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
-			;
+		while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
 
 	/* Switch back to default Invalidate mode */
 	if (op == OP_INV)
@@ -453,6 +450,7 @@ static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
 				const int cacheop)
 {
 	unsigned int ctrl_reg = __before_dc_op(cacheop);
+
 	__cache_line_loop(paddr, sz, cacheop);
 	__after_dc_op(cacheop, ctrl_reg);
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-01-16 16:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-16 16:20 [U-Boot] [PATCH 1/4] ARC: read pae_exist bit from MMU BCR Eugeniy Paltsev
2018-01-16 16:20 ` [U-Boot] [PATCH 2/4] ARC: ARCv2: CACHE: fix work without IOC Eugeniy Paltsev
2018-01-16 16:20 ` [U-Boot] [PATCH 3/4] ARC: CACHE: disable IOC by default Eugeniy Paltsev
2018-01-16 16:20 ` [U-Boot] [PATCH 4/4] ARC: CACHE: fix style violations Eugeniy Paltsev

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.