Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: cns3xxx: Add support for L2 Cache Controller

CNS3xxx SOCs have L310-compatible cache controller, so let's use it.

With this patch benchmarking with 'gzip' shows that performance is
doubled, and I'm still able to boot full-fledged userland over NFS
(using PCIe NIC), so the support should be pretty robust.

p.s. While CNS3xxx reports that it has PL310, it still needs to wait
on cache line operations, so we should not select 'CACHE_PL310',
which is a micro-optimization that removes these waits for v7 CPUs.
Someday we'd better rename CACHE_PL310 Kconfig option into
NO_CACHE_WAIT or something less ambiguous.

Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>

+52 -1
+2
arch/arm/mach-cns3xxx/cns3420vb.c
··· 170 170 171 171 static void __init cns3420_init(void) 172 172 { 173 + cns3xxx_l2x0_init(); 174 + 173 175 platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs)); 174 176 175 177 cns3xxx_ahci_init();
+43
arch/arm/mach-cns3xxx/core.c
··· 16 16 #include <asm/mach/time.h> 17 17 #include <asm/mach/irq.h> 18 18 #include <asm/hardware/gic.h> 19 + #include <asm/hardware/cache-l2x0.h> 19 20 #include <mach/cns3xxx.h> 20 21 #include "core.h" 21 22 ··· 245 244 struct sys_timer cns3xxx_timer = { 246 245 .init = cns3xxx_timer_init, 247 246 }; 247 + 248 + #ifdef CONFIG_CACHE_L2X0 249 + 250 + void __init cns3xxx_l2x0_init(void) 251 + { 252 + void __iomem *base = ioremap(CNS3XXX_L2C_BASE, SZ_4K); 253 + u32 val; 254 + 255 + if (WARN_ON(!base)) 256 + return; 257 + 258 + /* 259 + * Tag RAM Control register 260 + * 261 + * bit[10:8] - 1 cycle of write accesses latency 262 + * bit[6:4] - 1 cycle of read accesses latency 263 + * bit[3:0] - 1 cycle of setup latency 264 + * 265 + * 1 cycle of latency for setup, read and write accesses 266 + */ 267 + val = readl(base + L2X0_TAG_LATENCY_CTRL); 268 + val &= 0xfffff888; 269 + writel(val, base + L2X0_TAG_LATENCY_CTRL); 270 + 271 + /* 272 + * Data RAM Control register 273 + * 274 + * bit[10:8] - 1 cycles of write accesses latency 275 + * bit[6:4] - 1 cycles of read accesses latency 276 + * bit[3:0] - 1 cycle of setup latency 277 + * 278 + * 1 cycle of latency for setup, read and write accesses 279 + */ 280 + val = readl(base + L2X0_DATA_LATENCY_CTRL); 281 + val &= 0xfffff888; 282 + writel(val, base + L2X0_DATA_LATENCY_CTRL); 283 + 284 + /* 32 KiB, 8-way, parity disable */ 285 + l2x0_init(base, 0x00540000, 0xfe000fff); 286 + } 287 + 288 + #endif /* CONFIG_CACHE_L2X0 */
+6
arch/arm/mach-cns3xxx/core.h
··· 13 13 14 14 extern struct sys_timer cns3xxx_timer; 15 15 16 + #ifdef CONFIG_CACHE_L2X0 17 + void __init cns3xxx_l2x0_init(void); 18 + #else 19 + static inline void cns3xxx_l2x0_init(void) {} 20 + #endif /* CONFIG_CACHE_L2X0 */ 21 + 16 22 void __init cns3xxx_map_io(void); 17 23 void __init cns3xxx_init_irq(void); 18 24 void cns3xxx_power_off(void);
+1 -1
arch/arm/mm/Kconfig
··· 821 821 depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ 822 822 REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \ 823 823 ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \ 824 - ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE 824 + ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || ARCH_CNS3XXX 825 825 default y 826 826 select OUTER_CACHE 827 827 select OUTER_CACHE_SYNC