xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv7/cache_v7_asm.S (revision 9bdfc3446f8b2772b1080079f34965f4e6ee2a54)
1c09d2905SHans de Goede/*
2c09d2905SHans de Goede * SPDX-License-Identifier:	GPL-2.0+
3c09d2905SHans de Goede */
4c09d2905SHans de Goede
5c09d2905SHans de Goede#include <config.h>
6c09d2905SHans de Goede#include <linux/linkage.h>
7c09d2905SHans de Goede#include <linux/sizes.h>
8c09d2905SHans de Goede#include <asm/system.h>
9c09d2905SHans de Goede
103a649407STom Rini#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD)
11c09d2905SHans de Goede#define ARM(x...)
12c09d2905SHans de Goede#define THUMB(x...)	x
13c09d2905SHans de Goede#else
14c09d2905SHans de Goede#define ARM(x...)	x
15c09d2905SHans de Goede#define THUMB(x...)
16c09d2905SHans de Goede#endif
17c09d2905SHans de Goede
18c09d2905SHans de Goede/*
19c09d2905SHans de Goede *	v7_flush_dcache_all()
20c09d2905SHans de Goede *
21c09d2905SHans de Goede *	Flush the whole D-cache.
22c09d2905SHans de Goede *
23c09d2905SHans de Goede *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
24c09d2905SHans de Goede *
25c09d2905SHans de Goede *	Note: copied from arch/arm/mm/cache-v7.S of Linux 4.4
26c09d2905SHans de Goede */
27c09d2905SHans de GoedeENTRY(__v7_flush_dcache_all)
28c09d2905SHans de Goede	dmb					@ ensure ordering with previous memory accesses
29c09d2905SHans de Goede	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
30c09d2905SHans de Goede	mov	r3, r0, lsr #23			@ move LoC into position
31c09d2905SHans de Goede	ands	r3, r3, #7 << 1			@ extract LoC*2 from clidr
32c09d2905SHans de Goede	beq	finished			@ if loc is 0, then no need to clean
33c09d2905SHans de Goedestart_flush_levels:
34c09d2905SHans de Goede	mov	r10, #0				@ start clean at cache level 0
35c09d2905SHans de Goedeflush_levels:
36c09d2905SHans de Goede	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
37c09d2905SHans de Goede	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
38c09d2905SHans de Goede	and	r1, r1, #7			@ mask of the bits for current cache only
39c09d2905SHans de Goede	cmp	r1, #2				@ see what cache we have at this level
40c09d2905SHans de Goede	blt	skip				@ skip if no cache, or just i-cache
41c09d2905SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
42c09d2905SHans de Goede	isb					@ isb to sych the new cssr&csidr
43c09d2905SHans de Goede	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
44c09d2905SHans de Goede	and	r2, r1, #7			@ extract the length of the cache lines
45c09d2905SHans de Goede	add	r2, r2, #4			@ add 4 (line length offset)
46c09d2905SHans de Goede	movw	r4, #0x3ff
47c09d2905SHans de Goede	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
48c09d2905SHans de Goede	clz	r5, r4				@ find bit position of way size increment
49c09d2905SHans de Goede	movw	r7, #0x7fff
50c09d2905SHans de Goede	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
51c09d2905SHans de Goedeloop1:
52c09d2905SHans de Goede	mov	r9, r7				@ create working copy of max index
53c09d2905SHans de Goedeloop2:
54c09d2905SHans de Goede ARM(	orr	r11, r10, r4, lsl r5	)	@ factor way and cache number into r11
55c09d2905SHans de Goede THUMB(	lsl	r6, r4, r5		)
56c09d2905SHans de Goede THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
57c09d2905SHans de Goede ARM(	orr	r11, r11, r9, lsl r2	)	@ factor index number into r11
58c09d2905SHans de Goede THUMB(	lsl	r6, r9, r2		)
59c09d2905SHans de Goede THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
60c09d2905SHans de Goede	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
61c09d2905SHans de Goede	subs	r9, r9, #1			@ decrement the index
62c09d2905SHans de Goede	bge	loop2
63c09d2905SHans de Goede	subs	r4, r4, #1			@ decrement the way
64c09d2905SHans de Goede	bge	loop1
65c09d2905SHans de Goedeskip:
66c09d2905SHans de Goede	add	r10, r10, #2			@ increment cache number
67c09d2905SHans de Goede	cmp	r3, r10
68*9bdfc344SJoseph Chen#ifdef CONFIG_ARM_ERRATA_814220
69*9bdfc344SJoseph Chen	dsb
70*9bdfc344SJoseph Chen#endif
71c09d2905SHans de Goede	bgt	flush_levels
72c09d2905SHans de Goedefinished:
73c09d2905SHans de Goede	mov	r10, #0				@ swith back to cache level 0
74c09d2905SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
75c09d2905SHans de Goede	dsb	st
76c09d2905SHans de Goede	isb
77c09d2905SHans de Goede	bx	lr
78c09d2905SHans de GoedeENDPROC(__v7_flush_dcache_all)
79c09d2905SHans de Goede
80c09d2905SHans de GoedeENTRY(v7_flush_dcache_all)
81c09d2905SHans de Goede ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
82c09d2905SHans de Goede THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
83c09d2905SHans de Goede	bl	__v7_flush_dcache_all
84c09d2905SHans de Goede ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
85c09d2905SHans de Goede THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
86c09d2905SHans de Goede	bx	lr
87c09d2905SHans de GoedeENDPROC(v7_flush_dcache_all)
88df120142SHans de Goede
89df120142SHans de Goede/*
90df120142SHans de Goede *	v7_invalidate_dcache_all()
91df120142SHans de Goede *
92df120142SHans de Goede *	Invalidate the whole D-cache.
93df120142SHans de Goede *
94df120142SHans de Goede *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
95df120142SHans de Goede *
96df120142SHans de Goede *	Note: copied from __v7_flush_dcache_all above with
97df120142SHans de Goede *	mcr     p15, 0, r11, c7, c14, 2
98df120142SHans de Goede *	Replaced with:
99df120142SHans de Goede *	mcr     p15, 0, r11, c7, c6, 2
100df120142SHans de Goede */
101df120142SHans de GoedeENTRY(__v7_invalidate_dcache_all)
102df120142SHans de Goede	dmb					@ ensure ordering with previous memory accesses
103df120142SHans de Goede	mrc	p15, 1, r0, c0, c0, 1		@ read clidr
104df120142SHans de Goede	mov	r3, r0, lsr #23			@ move LoC into position
105df120142SHans de Goede	ands	r3, r3, #7 << 1			@ extract LoC*2 from clidr
106df120142SHans de Goede	beq	inval_finished			@ if loc is 0, then no need to clean
107df120142SHans de Goede	mov	r10, #0				@ start clean at cache level 0
108df120142SHans de Goedeinval_levels:
109df120142SHans de Goede	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
110df120142SHans de Goede	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
111df120142SHans de Goede	and	r1, r1, #7			@ mask of the bits for current cache only
112df120142SHans de Goede	cmp	r1, #2				@ see what cache we have at this level
113df120142SHans de Goede	blt	inval_skip			@ skip if no cache, or just i-cache
114df120142SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
115df120142SHans de Goede	isb					@ isb to sych the new cssr&csidr
116df120142SHans de Goede	mrc	p15, 1, r1, c0, c0, 0		@ read the new csidr
117df120142SHans de Goede	and	r2, r1, #7			@ extract the length of the cache lines
118df120142SHans de Goede	add	r2, r2, #4			@ add 4 (line length offset)
119df120142SHans de Goede	movw	r4, #0x3ff
120df120142SHans de Goede	ands	r4, r4, r1, lsr #3		@ find maximum number on the way size
121df120142SHans de Goede	clz	r5, r4				@ find bit position of way size increment
122df120142SHans de Goede	movw	r7, #0x7fff
123df120142SHans de Goede	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
124df120142SHans de Goedeinval_loop1:
125df120142SHans de Goede	mov	r9, r7				@ create working copy of max index
126df120142SHans de Goedeinval_loop2:
127df120142SHans de Goede ARM(	orr	r11, r10, r4, lsl r5	)	@ factor way and cache number into r11
128df120142SHans de Goede THUMB(	lsl	r6, r4, r5		)
129df120142SHans de Goede THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
130df120142SHans de Goede ARM(	orr	r11, r11, r9, lsl r2	)	@ factor index number into r11
131df120142SHans de Goede THUMB(	lsl	r6, r9, r2		)
132df120142SHans de Goede THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
133df120142SHans de Goede	mcr	p15, 0, r11, c7, c6, 2		@ invalidate by set/way
134df120142SHans de Goede	subs	r9, r9, #1			@ decrement the index
135df120142SHans de Goede	bge	inval_loop2
136df120142SHans de Goede	subs	r4, r4, #1			@ decrement the way
137df120142SHans de Goede	bge	inval_loop1
138df120142SHans de Goedeinval_skip:
139df120142SHans de Goede	add	r10, r10, #2			@ increment cache number
140df120142SHans de Goede	cmp	r3, r10
141df120142SHans de Goede	bgt	inval_levels
142df120142SHans de Goedeinval_finished:
143df120142SHans de Goede	mov	r10, #0				@ swith back to cache level 0
144df120142SHans de Goede	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
145df120142SHans de Goede	dsb	st
146df120142SHans de Goede	isb
147df120142SHans de Goede	bx	lr
148df120142SHans de GoedeENDPROC(__v7_invalidate_dcache_all)
149df120142SHans de Goede
150df120142SHans de GoedeENTRY(v7_invalidate_dcache_all)
151df120142SHans de Goede ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
152df120142SHans de Goede THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
153df120142SHans de Goede	bl	__v7_invalidate_dcache_all
154df120142SHans de Goede ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
155df120142SHans de Goede THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
156df120142SHans de Goede	bx	lr
157df120142SHans de GoedeENDPROC(v7_invalidate_dcache_all)
158