L2 cache support for pxa16x

Siddarth Gore gores at marvell.com
Fri May 21 06:37:08 EDT 2010


On Fri, 2010-05-21 at 03:27 -0700, Eric Miao wrote:
> On Fri, May 21, 2010 at 5:44 PM, Siddarth Gore <gores at marvell.com> wrote:
> >
> > On Thu, 2010-05-20 at 07:06 -0700, Eric Miao wrote:
> > > On Thu, May 20, 2010 at 6:17 PM, Siddarth Gore <gores at marvell.com> wrote:
> > > > On Wed, 2010-05-12 at 03:11 -0700, Eric Miao wrote:
> > > >> On Wed, May 12, 2010 at 11:56 AM, Siddarth Gore <gores at marvell.com> wrote:
> > > >> > Hi Eric/Haojian,
> > > >> >
> > > >> > Can the Tauros2 support be used for pxa168 as well? The one difference I
> > > >> > can see is that L2 Enable is in control register instead of extra
> > > >> > feature register. But rest of the things look very similar to me.
> > > >> >
> > > >
> > > > I tried doing this. It works when I enable L2 before turning the MMU on,
> > > > i.e. in __mohawk_setup
> > > >
> > > > But when I do the following in tauros2_init(), the kernel crashes.
> > > > 1. flush and disable dcache
> > > > 2. invalidate and disable icache
> > > > 3. drain write buffer
> > > > 4. invalidate TLB
> > > > 5. invalidate L2
> > > > 6. enable L2
> > > > 7. enable icache
> > > > 8. enable dcache
> > > >
> > > > I think the right place to enable L2 is in tauros2_init, so any idea
> > > > what I am doing wrong here?
> > > >
> > >
> > > I believe that was the reason why I didn't put tauros2 support to pxa168
> > > at the first place. And enabling L2 after MMU is enabled is supposed to
> > > be unsafe, which is mentioned in xscale3 manual, though not sure if that's
> > > the case for pxa168 as well.
> > >
> > I did not find it mentioned anywhere in the mohawk (PJ1) datasheet. Also
> > any idea why is this unsafe? I clean and disable the L1 cache first so
> > all the page tables, etc. will be backed up in main memory before
> > turning L2 on. plus invalidate the entire L2, so all the fetches will
> > first go to main memory.
> >
> > other CPUs using tauros2 (also feroceon) turn L2 on after MMU, and they
> > work fine.
> >
> 
> Can you post here the changes you've made?

Please find them below. It works if I uncomment the last change in
proc-mohawk.S

-siddarth

diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index a2d307e..d047d8c 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -17,6 +17,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/nand.h>
 
+#include <asm/hardware/cache-tauros2.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/addr-map.h>
@@ -125,6 +126,7 @@ static struct pxa3xx_nand_platform_data
aspenite_nand_info = {
 
 static void __init common_init(void)
 {
+	tauros2_init();
 	mfp_config(ARRAY_AND_SIZE(common_pin_config));
 
 	/* on-chip devices */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5bd7c89..ededf5a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -769,7 +769,7 @@ config CACHE_L2X0
 
 config CACHE_TAUROS2
 	bool "Enable the Tauros2 L2 cache controller"
-	depends on ARCH_DOVE
+	depends on ARCH_DOVE || ARCH_MMP
 	default y
 	select OUTER_CACHE
 	help
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
index 5086865..d2d4545 100644
--- a/arch/arm/mm/cache-tauros2.c
+++ b/arch/arm/mm/cache-tauros2.c
@@ -48,6 +48,10 @@ static inline void tauros2_inv_pa(unsigned long addr)
 	__asm__("mcr p15, 1, %0, c7, c7, 3" : : "r" (addr));
 }
 
+static inline void tauros2_inv_all(void)
+{
+	__asm__("mcr p15, 1, %0, c7, c7, 0" : : "r" (0));
+}
 
 /*
  * Linux primitives.
@@ -168,6 +172,62 @@ static inline void __init write_actlr(u32 actlr)
 	__asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
 }
 
+static int __init flush_and_disable_dcache(void)
+{
+	u32 cr;
+
+	cr = get_cr();
+	if (cr & CR_C) {
+		unsigned long flags;
+
+		raw_local_irq_save(flags);
+		flush_cache_all();
+		set_cr(cr & ~CR_C);
+		raw_local_irq_restore(flags);
+		return 1;
+	}
+	return 0;
+}
+
+static void __init enable_dcache(void)
+{
+	u32 cr;
+
+	cr = get_cr();
+	set_cr(cr | CR_C);
+}
+
+static void __init __invalidate_icache(void)
+{
+	__asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+}
+
+static int __init invalidate_and_disable_icache(void)
+{
+	u32 cr;
+
+	cr = get_cr();
+	if (cr & CR_I) {
+		set_cr(cr & ~CR_I);
+		__invalidate_icache();
+		return 1;
+	}
+	return 0;
+}
+
+static void __init enable_icache(void)
+{
+	u32 cr;
+
+	cr = get_cr();
+	set_cr(cr | CR_I);
+}
+
+static void __init __invalidate_tlb(void)
+{
+	__asm__("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
+}
+
 void __init tauros2_init(void)
 {
 	extern int processor_id;
@@ -179,6 +239,25 @@ void __init tauros2_init(void)
 	if ((processor_id & 0xff0f0000) == 0x56050000) {
 		u32 feat;
 
+#ifdef CONFIG_CPU_MOHAWK
+		/*
+ 		 * for mohawk cpu, L2 enable bit is in control reg
+ 		 */
+#define	CR_L2 (1 << 26)
+		feat = get_cr();
+		if (!(feat & CR_L2)) {
+			printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+		
+			flush_and_disable_dcache();
+			invalidate_and_disable_icache();
+			dsb();
+			__invalidate_tlb();
+			tauros2_inv_all();
+			set_cr(feat | CR_L2);
+			enable_icache();
+			enable_dcache();
+		}
+#else
 		/*
 		 * v5 CPUs with Tauros2 have the L2 cache enable bit
 		 * located in the CPU Extra Features register.
@@ -188,6 +267,7 @@ void __init tauros2_init(void)
 			printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
 			write_extra_features(feat | 0x00400000);
 		}
+#endif
 
 		mode = "ARMv5";
 		outer_cache.inv_range = tauros2_inv_range;
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index caa3115..5f7d706 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -361,6 +361,7 @@ __mohawk_setup:
 	mrc	p15, 0, r0, c1, c0		@ get control register
 	bic	r0, r0, r5
 	orr	r0, r0, r6
+@	orr     r0, r0, #(1 << 26)              @ L2 enable - xscale/PJ41/PJ4
 	mov	pc, lr
 
 	.size	__mohawk_setup, . - __mohawk_setup




More information about the linux-arm-kernel mailing list