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
10static DEFINE_RAW_SPINLOCK(krait_l2_lock);
11
12void 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}
28EXPORT_SYMBOL(krait_set_l2_indirect_reg);
29
30u32 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}
48EXPORT_SYMBOL(krait_get_l2_indirect_reg);
49