Loading arch/arm/include/asm/hardware/cache-l2x0.h +6 −3 Original line number Diff line number Diff line Loading @@ -21,9 +21,6 @@ #define __ASM_ARM_HARDWARE_L2X0_H #define L2X0_CACHE_ID 0x000 #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) #define L2X0_CACHE_TYPE 0x004 #define L2X0_CTRL 0x100 #define L2X0_AUX_CTRL 0x104 Loading Loading @@ -58,6 +55,12 @@ #define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1) #define L2X0_STNDBY_MODE_EN (1 << 0) /* Registers shifts and masks */ #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) #define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); #endif Loading arch/arm/include/asm/outercache.h +24 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ struct outer_cache_fns { void (*inv_range)(unsigned long, unsigned long); void (*clean_range)(unsigned long, unsigned long); void (*flush_range)(unsigned long, unsigned long); void (*flush_all)(void); void (*inv_all)(void); void (*disable)(void); #ifdef CONFIG_OUTER_CACHE_SYNC void (*sync)(void); #endif Loading @@ -50,6 +53,24 @@ static inline void outer_flush_range(unsigned long start, unsigned long end) outer_cache.flush_range(start, end); } static inline void outer_flush_all(void) { if (outer_cache.flush_all) outer_cache.flush_all(); } static inline void outer_inv_all(void) { if (outer_cache.inv_all) outer_cache.inv_all(); } static inline void outer_disable(void) { if (outer_cache.disable) outer_cache.disable(); } #else static inline void outer_inv_range(unsigned long start, unsigned long end) Loading @@ -58,6 +79,9 @@ static inline void outer_clean_range(unsigned long start, unsigned long end) { } static inline void outer_flush_range(unsigned long start, unsigned long end) { } static inline void outer_flush_all(void) { } static inline void outer_inv_all(void) { } static inline void outer_disable(void) { } #endif Loading arch/arm/kernel/machine_kexec.c +3 −0 Original line number Diff line number Diff line Loading @@ -78,7 +78,10 @@ void machine_kexec(struct kimage *image) local_fiq_disable(); setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ flush_cache_all(); outer_flush_all(); outer_disable(); cpu_proc_fin(); outer_inv_all(); flush_cache_all(); cpu_reset(reboot_code_buffer_phys); } arch/arm/mach-omap2/omap4-common.c +13 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,13 @@ void __init gic_init_irq(void) } #ifdef CONFIG_CACHE_L2X0 static void omap4_l2x0_disable(void) { /* Disable PL310 L2 Cache controller */ omap_smc1(0x102, 0x0); } static int __init omap_l2_cache_init(void) { /* Loading @@ -70,6 +77,12 @@ static int __init omap_l2_cache_init(void) else l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff); /* * Override default outer_cache.disable with a OMAP4 * specific one */ outer_cache.disable = omap4_l2x0_disable; return 0; } early_initcall(omap_l2_cache_init); Loading arch/arm/mach-ux500/cpu.c +45 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> Loading Loading @@ -71,6 +72,46 @@ void __init ux500_init_irq(void) } #ifdef CONFIG_CACHE_L2X0 static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) { /* wait for the operation to complete */ while (readl(reg) & mask) ; } static inline void ux500_cache_sync(void) { void __iomem *base = __io_address(UX500_L2CC_BASE); writel(0, base + L2X0_CACHE_SYNC); ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); } /* * The L2 cache cannot be turned off in the non-secure world. * Dummy until a secure service is in place. */ static void ux500_l2x0_disable(void) { } /* * This is only called when doing a kexec, just after turning off the L2 * and L1 cache, and it is surrounded by a spinlock in the generic version. * However, we're not really turning off the L2 cache right now and the * PL310 does not support exclusive accesses (used to implement the spinlock). * So, the invalidation needs to be done without the spinlock. */ static void ux500_l2x0_inv_all(void) { void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE); uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ /* invalidate all ways */ writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); ux500_cache_sync(); } static int ux500_l2x0_init(void) { void __iomem *l2x0_base; Loading @@ -80,6 +121,10 @@ static int ux500_l2x0_init(void) /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); /* Override invalidate function */ outer_cache.disable = ux500_l2x0_disable; outer_cache.inv_all = ux500_l2x0_inv_all; return 0; } early_initcall(ux500_l2x0_init); Loading Loading
arch/arm/include/asm/hardware/cache-l2x0.h +6 −3 Original line number Diff line number Diff line Loading @@ -21,9 +21,6 @@ #define __ASM_ARM_HARDWARE_L2X0_H #define L2X0_CACHE_ID 0x000 #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) #define L2X0_CACHE_TYPE 0x004 #define L2X0_CTRL 0x100 #define L2X0_AUX_CTRL 0x104 Loading Loading @@ -58,6 +55,12 @@ #define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1) #define L2X0_STNDBY_MODE_EN (1 << 0) /* Registers shifts and masks */ #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) #define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x3 << 17) #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); #endif Loading
arch/arm/include/asm/outercache.h +24 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ struct outer_cache_fns { void (*inv_range)(unsigned long, unsigned long); void (*clean_range)(unsigned long, unsigned long); void (*flush_range)(unsigned long, unsigned long); void (*flush_all)(void); void (*inv_all)(void); void (*disable)(void); #ifdef CONFIG_OUTER_CACHE_SYNC void (*sync)(void); #endif Loading @@ -50,6 +53,24 @@ static inline void outer_flush_range(unsigned long start, unsigned long end) outer_cache.flush_range(start, end); } static inline void outer_flush_all(void) { if (outer_cache.flush_all) outer_cache.flush_all(); } static inline void outer_inv_all(void) { if (outer_cache.inv_all) outer_cache.inv_all(); } static inline void outer_disable(void) { if (outer_cache.disable) outer_cache.disable(); } #else static inline void outer_inv_range(unsigned long start, unsigned long end) Loading @@ -58,6 +79,9 @@ static inline void outer_clean_range(unsigned long start, unsigned long end) { } static inline void outer_flush_range(unsigned long start, unsigned long end) { } static inline void outer_flush_all(void) { } static inline void outer_inv_all(void) { } static inline void outer_disable(void) { } #endif Loading
arch/arm/kernel/machine_kexec.c +3 −0 Original line number Diff line number Diff line Loading @@ -78,7 +78,10 @@ void machine_kexec(struct kimage *image) local_fiq_disable(); setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ flush_cache_all(); outer_flush_all(); outer_disable(); cpu_proc_fin(); outer_inv_all(); flush_cache_all(); cpu_reset(reboot_code_buffer_phys); }
arch/arm/mach-omap2/omap4-common.c +13 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,13 @@ void __init gic_init_irq(void) } #ifdef CONFIG_CACHE_L2X0 static void omap4_l2x0_disable(void) { /* Disable PL310 L2 Cache controller */ omap_smc1(0x102, 0x0); } static int __init omap_l2_cache_init(void) { /* Loading @@ -70,6 +77,12 @@ static int __init omap_l2_cache_init(void) else l2x0_init(l2cache_base, 0x0e070000, 0xc0000fff); /* * Override default outer_cache.disable with a OMAP4 * specific one */ outer_cache.disable = omap4_l2x0_disable; return 0; } early_initcall(omap_l2_cache_init); Loading
arch/arm/mach-ux500/cpu.c +45 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <asm/cacheflush.h> #include <asm/hardware/cache-l2x0.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> Loading Loading @@ -71,6 +72,46 @@ void __init ux500_init_irq(void) } #ifdef CONFIG_CACHE_L2X0 static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) { /* wait for the operation to complete */ while (readl(reg) & mask) ; } static inline void ux500_cache_sync(void) { void __iomem *base = __io_address(UX500_L2CC_BASE); writel(0, base + L2X0_CACHE_SYNC); ux500_cache_wait(base + L2X0_CACHE_SYNC, 1); } /* * The L2 cache cannot be turned off in the non-secure world. * Dummy until a secure service is in place. */ static void ux500_l2x0_disable(void) { } /* * This is only called when doing a kexec, just after turning off the L2 * and L1 cache, and it is surrounded by a spinlock in the generic version. * However, we're not really turning off the L2 cache right now and the * PL310 does not support exclusive accesses (used to implement the spinlock). * So, the invalidation needs to be done without the spinlock. */ static void ux500_l2x0_inv_all(void) { void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE); uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ /* invalidate all ways */ writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); ux500_cache_sync(); } static int ux500_l2x0_init(void) { void __iomem *l2x0_base; Loading @@ -80,6 +121,10 @@ static int ux500_l2x0_init(void) /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); /* Override invalidate function */ outer_cache.disable = ux500_l2x0_disable; outer_cache.inv_all = ux500_l2x0_inv_all; return 0; } early_initcall(ux500_l2x0_init); Loading