cd43dfaabd0b9da2a10421a1430243381b8c336b
[openwrt/staging/jow.git] / target / linux / realtek / files-5.15 / drivers / clk / realtek / clk-rtl839x-sram.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * Realtek RTL839X SRAM clock setters
4 * Copyright (C) 2022 Markus Stockhausen <markus.stockhausen@gmx.de>
5 */
6
7 #include <asm/mipsregs.h>
8 #include <dt-bindings/clock/rtl83xx-clk.h>
9
10 #include "clk-rtl83xx.h"
11
12 #define rGLB $t0
13 #define rCTR $t1
14 #define rMSK $t2
15 #define rSLP1 $t3
16 #define rSLP2 $t4
17 #define rSLP3 $t5
18 #define rTMP $t6
19 #define rCP0 $t7
20
21 .set noreorder
22
23 .globl rtcl_839x_dram_start
24 rtcl_839x_dram_start:
25
26 /*
27 * Functions start here and should avoid access to normal memory. REMARK! Do not forget about
28 * stack pointer and dirty caches that might interfere.
29 */
30
31 .globl rtcl_839x_dram_set_rate
32 .ent rtcl_839x_dram_set_rate
33 rtcl_839x_dram_set_rate:
34
35 #ifdef CONFIG_RTL839X
36
37 /* disable MIPS 34K branch and return prediction */
38 mfc0 rCP0, CP0_CONFIG, 7
39 ori rTMP, rCP0, 0xc
40 mtc0 rTMP, CP0_CONFIG, 7
41
42 li rCTR, RTL_SW_CORE_BASE
43 addiu rGLB, rCTR, RTL839X_PLL_GLB_CTRL
44 ori rTMP, $0, CLK_CPU
45 beq $a0, rTMP, pre_cpu
46 ori rTMP, $0, CLK_MEM
47 beq $a0, rTMP, pre_mem
48 nop
49 pre_lxb:
50 li rSLP1, 0x400000
51 li rSLP2, 0x400000
52 li rSLP3, 0x400000
53 addiu rCTR, rCTR, RTL839X_PLL_LXB_CTRL0
54 b main_set
55 ori rMSK, $0, RTL839X_GLB_CTRL_LXB_CLKSEL_MASK
56 pre_mem:
57 /* try to avoid memory access with simple 64K data cache flush */
58 li rMSK, RTL_SRAM_BASE
59 li rTMP, 2048
60 pre_flush:
61 lw $0, 0(rMSK)
62 addiu rMSK, rMSK, 32
63 addiu rTMP, rTMP, -1
64 bne rTMP, $0, pre_flush
65 lw $0, -4(rMSK)
66
67 li rSLP1, 0x10000
68 li rSLP2, 0x10000
69 li rSLP3, 0x10000
70 addiu rCTR, rCTR, RTL839X_PLL_MEM_CTRL0
71 b main_set
72 ori rMSK, $0, RTL839X_GLB_CTRL_MEM_CLKSEL_MASK
73 pre_cpu:
74 li rSLP1, 0x1000
75 li rSLP2, 0x1000
76 li rSLP3, 0x200
77 addiu rCTR, rCTR, RTL839X_PLL_CPU_CTRL0
78 ori rMSK, $0, RTL839X_GLB_CTRL_CPU_CLKSEL_MASK
79 main_set:
80 /* switch to fixed clock */
81 sync
82 lw rTMP, 0(rGLB)
83 sync
84 or rTMP, rTMP, rMSK
85 sync
86 sw rTMP, 0(rGLB)
87
88 /* wait until fixed clock in use */
89 or rTMP, rSLP1, $0
90 wait_fixclock:
91 bnez rTMP, wait_fixclock
92 addiu rTMP, rTMP, -1
93
94 /* set new PLL values */
95 sync
96 sw $a1, 0(rCTR)
97 sw $a2, 4(rCTR)
98 sync
99
100 /* wait for value takeover */
101 or rTMP, rSLP2, $0
102 wait_pll:
103 bnez rTMP, wait_pll
104 addiu rTMP, rTMP, -1
105
106 /* switch back to PLL clock*/
107 nor rMSK, rMSK, $0
108 sync
109 lw rTMP, 0(rGLB)
110 sync
111 and rTMP, rTMP, rMSK
112 sync
113 sw rTMP, 0(rGLB)
114
115 /* wait until PLL clock in use */
116 or rTMP, rSLP3, $0
117 wait_pllclock:
118 bnez rTMP, wait_pllclock
119 addiu rTMP, rTMP, -1
120
121 /* restore branch prediction */
122 mtc0 rCP0, CP0_CONFIG, 7
123 jr $ra
124 nop
125
126 #else /* !CONFIG_RTL839X */
127
128 jr $ra
129 nop
130
131 #endif
132
133 .end rtcl_839x_dram_set_rate
134
135 /*
136 * End marker. Do not delete.
137 */
138 .word RTL_SRAM_MARKER
139 .globl rtcl_839x_dram_size
140 rtcl_839x_dram_size:
141 .word .-rtcl_839x_dram_start
142