summaryrefslogtreecommitdiff
path: root/target/linux/realtek/files-5.10/drivers/clk/realtek/clk-rtl838x-sram.S
blob: 527436bbab48b005734f37356adfebe23c05fa36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Realtek RTL838X SRAM clock setters
 * Copyright (C) 2022 Markus Stockhausen <markus.stockhausen@gmx.de>
 */

#include <dt-bindings/clock/rtl83xx-clk.h>

#include "clk-rtl83xx.h"

#define rGLB	$t0
#define rCTR	$t1
#define rMSK	$t2
#define rSLP	$t3
#define rTMP	$t4

.set	noreorder

.globl	rtcl_838x_dram_start
rtcl_838x_dram_start:

/*
 * Functions start here and should avoid access to normal memory. REMARK! Do not forget about
 * stack pointer and dirty caches that might interfere.
 */

.globl	rtcl_838x_dram_set_rate
.ent	rtcl_838x_dram_set_rate
rtcl_838x_dram_set_rate:

#ifdef CONFIG_RTL838X

	li	rCTR, RTL_SW_CORE_BASE
	addiu	rGLB, rCTR, RTL838X_PLL_GLB_CTRL
	ori	rTMP, $0, CLK_CPU
	beq	$a0, rTMP, pre_cpu
	ori	rTMP, $0, CLK_MEM
	beq	$a0, rTMP, pre_mem
	nop
pre_lxb:
	ori	rSLP, $0, RTL838X_GLB_CTRL_LXB_PLL_READY_MASK
	addiu	rCTR, rCTR, RTL838X_PLL_LXB_CTRL0
	b	main_set
	ori	rMSK, $0, RTL838X_GLB_CTRL_EN_LXB_PLL_MASK
pre_mem:
	/* simple 64K data cache flush to avoid unexpected memory access */
	li	rMSK, RTL_SRAM_BASE
	li	rTMP, 2048
pre_flush:
	lw	$0, 0(rMSK)
	addiu	rMSK, rMSK, 32
	addiu	rTMP, rTMP, -1
	bne	rTMP, $0, pre_flush
	lw	$0, -4(rMSK)

	ori	rSLP, $0, RTL838X_GLB_CTRL_MEM_PLL_READY_MASK
	addiu	rCTR, rCTR, RTL838X_PLL_MEM_CTRL0
	b	main_set
	ori	rMSK, $0, RTL838X_GLB_CTRL_EN_MEM_PLL_MASK
pre_cpu:
	/* switch CPU to LXB clock */
	ori	rMSK, $0, RTL838X_GLB_CTRL_CPU_PLL_SC_MUX_MASK
	nor	rMSK, rMSK, $0
	sync
	lw	rTMP, 0(rGLB)
	and	rTMP, rTMP, rMSK
	sw	rTMP, 0(rGLB)
	sync

	ori	rSLP, $0, RTL838X_GLB_CTRL_CPU_PLL_READY_MASK
	addiu	rCTR, rCTR, RTL838X_PLL_CPU_CTRL0
	ori	rMSK, $0, RTL838X_GLB_CTRL_EN_CPU_PLL_MASK
main_set:
	/* disable PLL */
	nor	rMSK, rMSK, 0
	sync
	lw	rTMP, 0(rGLB)
	sync
	and	rTMP, rTMP, rMSK
	sync
	sw	rTMP, 0(rGLB)

	/* set new PLL values */
	sync
	sw	$a1, 0(rCTR)
	sw	$a2, 4(rCTR)
	sync

	/* enable PLL (will reset it and clear ready status) */
	nor	rMSK, rMSK, 0
	sync
	lw	rTMP, 0(rGLB)
	sync
	or	rTMP, rTMP, rMSK
	sync
	sw	rTMP, 0(rGLB)

	/* wait for PLL to become ready */
wait_ready:
	lw	rTMP, 0(rGLB)
	and	rTMP, rTMP, rSLP
	bne	rTMP, $0, wait_ready
	sync

	/* branch to post processing */
	ori	rTMP, $0, CLK_CPU
	beq	$a0, rTMP, post_cpu
	ori	rTMP, $0, CLK_MEM
	beq	$a0, rTMP, post_mem
	nop
post_lxb:
	jr	$ra
	nop
post_mem:
	jr	$ra
	nop
post_cpu:
	/* stabilize clock to avoid crash, empirically determined */
	ori	rSLP, $0, 0x3000
wait_cpu:
	bnez	rSLP, wait_cpu
	addiu	rSLP, rSLP, -1

	/* switch CPU to PLL clock */
	ori	rMSK, $0, RTL838X_GLB_CTRL_CPU_PLL_SC_MUX_MASK
	sync
	lw	rTMP, 0(rGLB)
	or	rTMP, rTMP, rMSK
	sw	rTMP, 0(rGLB)
	sync
	jr	$ra
	nop

#else /* !CONFIG_RTL838X */

	jr	$ra
	nop

#endif

.end	rtcl_838x_dram_set_rate

/*
 * End marker. Do not delete.
 */
	.word RTL_SRAM_MARKER
.globl	rtcl_838x_dram_size
rtcl_838x_dram_size:
	.word .-rtcl_838x_dram_start