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

ARM: Add Krait L2 register accessor functions

Krait CPUs have a handful of L2 cache controller registers that
live behind a cp15 based indirection register. First you program
the indirection register (l2cpselr) to point the L2 'window'
register (l2cpdr) at what you want to read/write. Then you
read/write the 'window' register to do what you want. The
l2cpselr register is not banked per-cpu so we must lock around
accesses to it to prevent other CPUs from re-pointing l2cpdr
underneath us.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
Tested-by: Craig Tatlor <ctatlor97@gmail.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Stephen Boyd and committed by
Stephen Boyd
36d68f64 5b394b2d

+61
+3
arch/arm/common/Kconfig
··· 7 7 bool 8 8 select ZONE_DMA 9 9 10 + config KRAIT_L2_ACCESSORS 11 + bool 12 + 10 13 config SHARP_LOCOMO 11 14 bool 12 15
+1
arch/arm/common/Makefile
··· 7 7 8 8 obj-$(CONFIG_SA1111) += sa1111.o 9 9 obj-$(CONFIG_DMABOUNCE) += dmabounce.o 10 + obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o 10 11 obj-$(CONFIG_SHARP_LOCOMO) += locomo.o 11 12 obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o 12 13 obj-$(CONFIG_SHARP_SCOOP) += scoop.o
+48
arch/arm/common/krait-l2-accessors.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2018, The Linux Foundation. All rights reserved. 3 + 4 + #include <linux/spinlock.h> 5 + #include <linux/export.h> 6 + 7 + #include <asm/barrier.h> 8 + #include <asm/krait-l2-accessors.h> 9 + 10 + static DEFINE_RAW_SPINLOCK(krait_l2_lock); 11 + 12 + void krait_set_l2_indirect_reg(u32 addr, u32 val) 13 + { 14 + unsigned long flags; 15 + 16 + raw_spin_lock_irqsave(&krait_l2_lock, flags); 17 + /* 18 + * Select the L2 window by poking l2cpselr, then write to the window 19 + * via l2cpdr. 20 + */ 21 + asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr)); 22 + isb(); 23 + asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val)); 24 + isb(); 25 + 26 + raw_spin_unlock_irqrestore(&krait_l2_lock, flags); 27 + } 28 + EXPORT_SYMBOL(krait_set_l2_indirect_reg); 29 + 30 + u32 krait_get_l2_indirect_reg(u32 addr) 31 + { 32 + u32 val; 33 + unsigned long flags; 34 + 35 + raw_spin_lock_irqsave(&krait_l2_lock, flags); 36 + /* 37 + * Select the L2 window by poking l2cpselr, then read from the window 38 + * via l2cpdr. 39 + */ 40 + asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr)); 41 + isb(); 42 + asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val)); 43 + 44 + raw_spin_unlock_irqrestore(&krait_l2_lock, flags); 45 + 46 + return val; 47 + } 48 + EXPORT_SYMBOL(krait_get_l2_indirect_reg);
+9
arch/arm/include/asm/krait-l2-accessors.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __ASMARM_KRAIT_L2_ACCESSORS_H 4 + #define __ASMARM_KRAIT_L2_ACCESSORS_H 5 + 6 + extern void krait_set_l2_indirect_reg(u32 addr, u32 val); 7 + extern u32 krait_get_l2_indirect_reg(u32 addr); 8 + 9 + #endif