Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99c6bb39 authored by Nicolas Pitre's avatar Nicolas Pitre
Browse files

[ARM] Feroceon: small cleanups to L2 cache code



- Make sure that coprocessor instructions for range ops are contiguous
  and not reordered.

- s/invalidate_and_disable_dcache/flush_and_disable_dcache/

- Don't re-enable I/D caches if they were not enabled initially.

- Change some masks to shifts for better generated code.

Signed-off-by: default avatarNicolas Pitre <nico@marvell.com>
Acked-by: default avatarLennert Buytenhek <buytenh@marvell.com>
parent 92a5de80
Loading
Loading
Loading
Loading
+25 −17
Original line number Original line Diff line number Diff line
@@ -48,11 +48,12 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
	 * L2 is PIPT and range operations only do a TLB lookup on
	 * L2 is PIPT and range operations only do a TLB lookup on
	 * the start address.
	 * the start address.
	 */
	 */
	BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
	BUG_ON((start ^ end) >> PAGE_SHIFT);


	raw_local_irq_save(flags);
	raw_local_irq_save(flags);
	__asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start));
	__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
	__asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end));
		"mcr p15, 1, %1, c15, c9, 5"
		: : "r" (start), "r" (end));
	raw_local_irq_restore(flags);
	raw_local_irq_restore(flags);
}
}


@@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
	 * L2 is PIPT and range operations only do a TLB lookup on
	 * L2 is PIPT and range operations only do a TLB lookup on
	 * the start address.
	 * the start address.
	 */
	 */
	BUG_ON((start ^ end) & ~(PAGE_SIZE - 1));
	BUG_ON((start ^ end) >> PAGE_SHIFT);


	raw_local_irq_save(flags);
	raw_local_irq_save(flags);
	__asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start));
	__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
	__asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end));
		"mcr p15, 1, %1, c15, c11, 5"
		: : "r" (start), "r" (end));
	raw_local_irq_restore(flags);
	raw_local_irq_restore(flags);
}
}


@@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end)
 * time.  These are necessary because the L2 cache can only be enabled
 * time.  These are necessary because the L2 cache can only be enabled
 * or disabled while the L1 Dcache and Icache are both disabled.
 * or disabled while the L1 Dcache and Icache are both disabled.
 */
 */
static void __init invalidate_and_disable_dcache(void)
static int __init flush_and_disable_dcache(void)
{
{
	u32 cr;
	u32 cr;


@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void)
		flush_cache_all();
		flush_cache_all();
		set_cr(cr & ~CR_C);
		set_cr(cr & ~CR_C);
		raw_local_irq_restore(flags);
		raw_local_irq_restore(flags);
		return 1;
	}
	}
	return 0;
}
}


static void __init enable_dcache(void)
static void __init enable_dcache(void)
@@ -225,7 +229,6 @@ static void __init enable_dcache(void)
	u32 cr;
	u32 cr;


	cr = get_cr();
	cr = get_cr();
	if (!(cr & CR_C))
	set_cr(cr | CR_C);
	set_cr(cr | CR_C);
}
}


@@ -233,10 +236,10 @@ static void __init __invalidate_icache(void)
{
{
	int dummy;
	int dummy;


	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy));
	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
}
}


static void __init invalidate_and_disable_icache(void)
static int __init invalidate_and_disable_icache(void)
{
{
	u32 cr;
	u32 cr;


@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void)
	if (cr & CR_I) {
	if (cr & CR_I) {
		set_cr(cr & ~CR_I);
		set_cr(cr & ~CR_I);
		__invalidate_icache();
		__invalidate_icache();
		return 1;
	}
	}
	return 0;
}
}


static void __init enable_icache(void)
static void __init enable_icache(void)
@@ -252,7 +257,6 @@ static void __init enable_icache(void)
	u32 cr;
	u32 cr;


	cr = get_cr();
	cr = get_cr();
	if (!(cr & CR_I))
	set_cr(cr | CR_I);
	set_cr(cr | CR_I);
}
}


@@ -291,12 +295,16 @@ static void __init enable_l2(void)


	u = read_extra_features();
	u = read_extra_features();
	if (!(u & 0x00400000)) {
	if (!(u & 0x00400000)) {
		int i, d;

		printk(KERN_INFO "Feroceon L2: Enabling L2\n");
		printk(KERN_INFO "Feroceon L2: Enabling L2\n");


		invalidate_and_disable_dcache();
		d = flush_and_disable_dcache();
		invalidate_and_disable_icache();
		i = invalidate_and_disable_icache();
		write_extra_features(u | 0x00400000);
		write_extra_features(u | 0x00400000);
		if (i)
			enable_icache();
			enable_icache();
		if (d)
			enable_dcache();
			enable_dcache();
	}
	}
}
}