at91: add kernel support for sama7g5 soc
[openwrt/openwrt.git] / target / linux / at91 / patches-5.10 / 208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch
1 From 1bfd85d71703f80392a71043caf74f159bec97b8 Mon Sep 17 00:00:00 2001
2 From: Claudiu Beznea <claudiu.beznea@microchip.com>
3 Date: Thu, 15 Apr 2021 13:49:58 +0300
4 Subject: [PATCH 208/247] ARM: at91: pm: add self-refresh support for sama7g5
5
6 Add self-refresh support for SAMA7G5.
7
8 Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
9 Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
10 Link: https://lore.kernel.org/r/20210415105010.569620-13-claudiu.beznea@microchip.com
11 ---
12 arch/arm/mach-at91/pm.h | 2 +
13 arch/arm/mach-at91/pm_data-offsets.c | 2 +
14 arch/arm/mach-at91/pm_suspend.S | 199 +++++++++++++++++++++++++++
15 3 files changed, 203 insertions(+)
16
17 diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
18 index bfb260be371e..666474088d55 100644
19 --- a/arch/arm/mach-at91/pm.h
20 +++ b/arch/arm/mach-at91/pm.h
21 @@ -12,6 +12,7 @@
22 #include <linux/mfd/syscon/atmel-mc.h>
23 #include <soc/at91/at91sam9_ddrsdr.h>
24 #include <soc/at91/at91sam9_sdramc.h>
25 +#include <soc/at91/sama7-ddr.h>
26
27 #define AT91_MEMCTRL_MC 0
28 #define AT91_MEMCTRL_SDRAMC 1
29 @@ -27,6 +28,7 @@
30 struct at91_pm_data {
31 void __iomem *pmc;
32 void __iomem *ramc[2];
33 + void __iomem *ramc_phy;
34 unsigned long uhp_udp_mask;
35 unsigned int memctrl;
36 unsigned int mode;
37 diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c
38 index 82089ff258c0..40bd4e8fe40a 100644
39 --- a/arch/arm/mach-at91/pm_data-offsets.c
40 +++ b/arch/arm/mach-at91/pm_data-offsets.c
41 @@ -8,6 +8,8 @@ int main(void)
42 DEFINE(PM_DATA_PMC, offsetof(struct at91_pm_data, pmc));
43 DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0]));
44 DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1]));
45 + DEFINE(PM_DATA_RAMC_PHY, offsetof(struct at91_pm_data,
46 + ramc_phy));
47 DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl));
48 DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode));
49 DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc));
50 diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
51 index 7669b32d5257..84418120ba67 100644
52 --- a/arch/arm/mach-at91/pm_suspend.S
53 +++ b/arch/arm/mach-at91/pm_suspend.S
54 @@ -87,6 +87,200 @@ tmp3 .req r6
55
56 .arm
57
58 +#ifdef CONFIG_SOC_SAMA7
59 +/**
60 + * Enable self-refresh
61 + *
62 + * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7
63 + */
64 +.macro at91_sramc_self_refresh_ena
65 + ldr r2, .sramc_base
66 + ldr r3, .sramc_phy_base
67 + ldr r7, .pm_mode
68 +
69 + dsb
70 +
71 + /* Disable all AXI ports. */
72 + ldr tmp1, [r2, #UDDRC_PCTRL_0]
73 + bic tmp1, tmp1, #0x1
74 + str tmp1, [r2, #UDDRC_PCTRL_0]
75 +
76 + ldr tmp1, [r2, #UDDRC_PCTRL_1]
77 + bic tmp1, tmp1, #0x1
78 + str tmp1, [r2, #UDDRC_PCTRL_1]
79 +
80 + ldr tmp1, [r2, #UDDRC_PCTRL_2]
81 + bic tmp1, tmp1, #0x1
82 + str tmp1, [r2, #UDDRC_PCTRL_2]
83 +
84 + ldr tmp1, [r2, #UDDRC_PCTRL_3]
85 + bic tmp1, tmp1, #0x1
86 + str tmp1, [r2, #UDDRC_PCTRL_3]
87 +
88 + ldr tmp1, [r2, #UDDRC_PCTRL_4]
89 + bic tmp1, tmp1, #0x1
90 + str tmp1, [r2, #UDDRC_PCTRL_4]
91 +
92 +sr_ena_1:
93 + /* Wait for all ports to disable. */
94 + ldr tmp1, [r2, #UDDRC_PSTAT]
95 + ldr tmp2, =UDDRC_PSTAT_ALL_PORTS
96 + tst tmp1, tmp2
97 + bne sr_ena_1
98 +
99 + /* Switch to self-refresh. */
100 + ldr tmp1, [r2, #UDDRC_PWRCTL]
101 + orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
102 + str tmp1, [r2, #UDDRC_PWRCTL]
103 +
104 +sr_ena_2:
105 + /* Wait for self-refresh enter. */
106 + ldr tmp1, [r2, #UDDRC_STAT]
107 + bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK
108 + cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW
109 + bne sr_ena_2
110 +
111 + /* Put DDR PHY's DLL in bypass mode for non-backup modes. */
112 + cmp r7, #AT91_PM_BACKUP
113 + beq sr_ena_3
114 + ldr tmp1, [r3, #DDR3PHY_PIR]
115 + orr tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
116 + str tmp1, [r3, #DDR3PHY_PIR]
117 +
118 +sr_ena_3:
119 + /* Power down DDR PHY data receivers. */
120 + ldr tmp1, [r3, #DDR3PHY_DXCCR]
121 + orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
122 + str tmp1, [r3, #DDR3PHY_DXCCR]
123 +
124 + /* Power down ADDR/CMD IO. */
125 + ldr tmp1, [r3, #DDR3PHY_ACIOCR]
126 + orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
127 + orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
128 + orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
129 + str tmp1, [r3, #DDR3PHY_ACIOCR]
130 +
131 + /* Power down ODT. */
132 + ldr tmp1, [r3, #DDR3PHY_DSGCR]
133 + orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
134 + str tmp1, [r3, #DDR3PHY_DSGCR]
135 +.endm
136 +
137 +/**
138 + * Disable self-refresh
139 + *
140 + * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3
141 + */
142 +.macro at91_sramc_self_refresh_dis
143 + ldr r2, .sramc_base
144 + ldr r3, .sramc_phy_base
145 +
146 + /* Power up DDR PHY data receivers. */
147 + ldr tmp1, [r3, #DDR3PHY_DXCCR]
148 + bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR
149 + str tmp1, [r3, #DDR3PHY_DXCCR]
150 +
151 + /* Power up the output of CK and CS pins. */
152 + ldr tmp1, [r3, #DDR3PHY_ACIOCR]
153 + bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD
154 + bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0
155 + bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0
156 + str tmp1, [r3, #DDR3PHY_ACIOCR]
157 +
158 + /* Power up ODT. */
159 + ldr tmp1, [r3, #DDR3PHY_DSGCR]
160 + bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0
161 + str tmp1, [r3, #DDR3PHY_DSGCR]
162 +
163 + /* Take DDR PHY's DLL out of bypass mode. */
164 + ldr tmp1, [r3, #DDR3PHY_PIR]
165 + bic tmp1, tmp1, #DDR3PHY_PIR_DLLBYP
166 + str tmp1, [r3, #DDR3PHY_PIR]
167 +
168 + /* Enable quasi-dynamic programming. */
169 + mov tmp1, #0
170 + str tmp1, [r2, #UDDRC_SWCTRL]
171 +
172 + /* De-assert SDRAM initialization. */
173 + ldr tmp1, [r2, #UDDRC_DFIMISC]
174 + bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
175 + str tmp1, [r2, #UDDRC_DFIMISC]
176 +
177 + /* Quasi-dynamic programming done. */
178 + mov tmp1, #UDDRC_SWCTRL_SW_DONE
179 + str tmp1, [r2, #UDDRC_SWCTRL]
180 +
181 +sr_dis_1:
182 + ldr tmp1, [r2, #UDDRC_SWSTAT]
183 + tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
184 + beq sr_dis_1
185 +
186 + /* DLL soft-reset + DLL lock wait + ITM reset */
187 + mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \
188 + DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST)
189 + str tmp1, [r3, #DDR3PHY_PIR]
190 +
191 +sr_dis_4:
192 + /* Wait for it. */
193 + ldr tmp1, [r3, #DDR3PHY_PGSR]
194 + tst tmp1, #DDR3PHY_PGSR_IDONE
195 + beq sr_dis_4
196 +
197 + /* Enable quasi-dynamic programming. */
198 + mov tmp1, #0
199 + str tmp1, [r2, #UDDRC_SWCTRL]
200 +
201 + /* Assert PHY init complete enable signal. */
202 + ldr tmp1, [r2, #UDDRC_DFIMISC]
203 + orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN
204 + str tmp1, [r2, #UDDRC_DFIMISC]
205 +
206 + /* Programming is done. Set sw_done. */
207 + mov tmp1, #UDDRC_SWCTRL_SW_DONE
208 + str tmp1, [r2, #UDDRC_SWCTRL]
209 +
210 +sr_dis_5:
211 + /* Wait for it. */
212 + ldr tmp1, [r2, #UDDRC_SWSTAT]
213 + tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK
214 + beq sr_dis_5
215 +
216 + /* Trigger self-refresh exit. */
217 + ldr tmp1, [r2, #UDDRC_PWRCTL]
218 + bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
219 + str tmp1, [r2, #UDDRC_PWRCTL]
220 +
221 +sr_dis_6:
222 + /* Wait for self-refresh exit done. */
223 + ldr tmp1, [r2, #UDDRC_STAT]
224 + bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK
225 + cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL
226 + bne sr_dis_6
227 +
228 + /* Enable all AXI ports. */
229 + ldr tmp1, [r2, #UDDRC_PCTRL_0]
230 + orr tmp1, tmp1, #0x1
231 + str tmp1, [r2, #UDDRC_PCTRL_0]
232 +
233 + ldr tmp1, [r2, #UDDRC_PCTRL_1]
234 + orr tmp1, tmp1, #0x1
235 + str tmp1, [r2, #UDDRC_PCTRL_1]
236 +
237 + ldr tmp1, [r2, #UDDRC_PCTRL_2]
238 + orr tmp1, tmp1, #0x1
239 + str tmp1, [r2, #UDDRC_PCTRL_2]
240 +
241 + ldr tmp1, [r2, #UDDRC_PCTRL_3]
242 + orr tmp1, tmp1, #0x1
243 + str tmp1, [r2, #UDDRC_PCTRL_3]
244 +
245 + ldr tmp1, [r2, #UDDRC_PCTRL_4]
246 + orr tmp1, tmp1, #0x1
247 + str tmp1, [r2, #UDDRC_PCTRL_4]
248 +
249 + dsb
250 +.endm
251 +#else
252 /**
253 * Enable self-refresh
254 *
255 @@ -228,6 +422,7 @@ sdramc_exit_sf:
256
257 sr_dis_exit:
258 .endm
259 +#endif
260
261 .macro at91_pm_ulp0_mode
262 ldr pmc, .pmc_base
263 @@ -668,6 +863,8 @@ ENTRY(at91_pm_suspend_in_sram)
264 str tmp1, .sramc_base
265 ldr tmp1, [r0, #PM_DATA_RAMC1]
266 str tmp1, .sramc1_base
267 + ldr tmp1, [r0, #PM_DATA_RAMC_PHY]
268 + str tmp1, .sramc_phy_base
269 ldr tmp1, [r0, #PM_DATA_MEMCTRL]
270 str tmp1, .memtype
271 ldr tmp1, [r0, #PM_DATA_MODE]
272 @@ -721,6 +918,8 @@ ENDPROC(at91_pm_suspend_in_sram)
273 .word 0
274 .sramc1_base:
275 .word 0
276 +.sramc_phy_base:
277 + .word 0
278 .shdwc:
279 .word 0
280 .sfrbu:
281 --
282 2.32.0
283