xref: /linux/arch/arm/common/krait-l2-accessors.c (revision 3eb66e91a25497065c5322b1268cbc3953642227)
1*36d68f64SStephen Boyd // SPDX-License-Identifier: GPL-2.0
2*36d68f64SStephen Boyd // Copyright (c) 2018, The Linux Foundation. All rights reserved.
3*36d68f64SStephen Boyd 
4*36d68f64SStephen Boyd #include <linux/spinlock.h>
5*36d68f64SStephen Boyd #include <linux/export.h>
6*36d68f64SStephen Boyd 
7*36d68f64SStephen Boyd #include <asm/barrier.h>
8*36d68f64SStephen Boyd #include <asm/krait-l2-accessors.h>
9*36d68f64SStephen Boyd 
10*36d68f64SStephen Boyd static DEFINE_RAW_SPINLOCK(krait_l2_lock);
11*36d68f64SStephen Boyd 
krait_set_l2_indirect_reg(u32 addr,u32 val)12*36d68f64SStephen Boyd void krait_set_l2_indirect_reg(u32 addr, u32 val)
13*36d68f64SStephen Boyd {
14*36d68f64SStephen Boyd 	unsigned long flags;
15*36d68f64SStephen Boyd 
16*36d68f64SStephen Boyd 	raw_spin_lock_irqsave(&krait_l2_lock, flags);
17*36d68f64SStephen Boyd 	/*
18*36d68f64SStephen Boyd 	 * Select the L2 window by poking l2cpselr, then write to the window
19*36d68f64SStephen Boyd 	 * via l2cpdr.
20*36d68f64SStephen Boyd 	 */
21*36d68f64SStephen Boyd 	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
22*36d68f64SStephen Boyd 	isb();
23*36d68f64SStephen Boyd 	asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
24*36d68f64SStephen Boyd 	isb();
25*36d68f64SStephen Boyd 
26*36d68f64SStephen Boyd 	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
27*36d68f64SStephen Boyd }
28*36d68f64SStephen Boyd EXPORT_SYMBOL(krait_set_l2_indirect_reg);
29*36d68f64SStephen Boyd 
krait_get_l2_indirect_reg(u32 addr)30*36d68f64SStephen Boyd u32 krait_get_l2_indirect_reg(u32 addr)
31*36d68f64SStephen Boyd {
32*36d68f64SStephen Boyd 	u32 val;
33*36d68f64SStephen Boyd 	unsigned long flags;
34*36d68f64SStephen Boyd 
35*36d68f64SStephen Boyd 	raw_spin_lock_irqsave(&krait_l2_lock, flags);
36*36d68f64SStephen Boyd 	/*
37*36d68f64SStephen Boyd 	 * Select the L2 window by poking l2cpselr, then read from the window
38*36d68f64SStephen Boyd 	 * via l2cpdr.
39*36d68f64SStephen Boyd 	 */
40*36d68f64SStephen Boyd 	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
41*36d68f64SStephen Boyd 	isb();
42*36d68f64SStephen Boyd 	asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
43*36d68f64SStephen Boyd 
44*36d68f64SStephen Boyd 	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
45*36d68f64SStephen Boyd 
46*36d68f64SStephen Boyd 	return val;
47*36d68f64SStephen Boyd }
48*36d68f64SStephen Boyd EXPORT_SYMBOL(krait_get_l2_indirect_reg);
49