@@ -41,6 +41,15 @@ tmp2 .req r5
4141 beq 1b
4242 .endm
4343
44+ / *
45+ * Wait for main oscillator selection is done
46+ * /
47+ .macro wait_moscsels
48+ 1 : ldr tmp1 , [ pmc , #AT91_PMC_SR ]
49+ tst tmp1 , #AT91_PMC_MOSCSELS
50+ beq 1b
51+ .endm
52+
4453/ *
4554 * Wait until PLLA has locked.
4655 * /
@@ -112,19 +121,20 @@ ENTRY(at91_pm_suspend_in_sram)
112121 bl at91_sramc_self_refresh
113122
114123 ldr r0 , .pm_mode
115- cmp r0 , #AT91_PM_ULP0
116- beq ulp0_mode
124+ cmp r0 , #AT91_PM_STANDBY
125+ beq standby
117126 cmp r0 , #AT91_PM_BACKUP
118127 beq backup_mode
119128
129+ bl at91_ulp_mode
130+ b exit_suspend
131+
132+ standby:
120133 / * Wait for interrupt * /
121134 ldr pmc , .pmc_base
122135 at91_cpu_idle
123136 b exit_suspend
124137
125- ulp0_mode:
126- bl at91_ulp0_mode
127- b exit_suspend
128138backup_mode:
129139 bl at91_backup_mode
130140 b exit_suspend
@@ -151,7 +161,102 @@ ENTRY(at91_backup_mode)
151161 str tmp1 , [ r0 , # 0 ]
152162ENDPROC(at91_backup_mode)
153163
154- ENTRY(at91_ulp0_mode)
164+ .macro at91_pm_ulp0_mode
165+ ldr pmc , .pmc_base
166+
167+ / * Turn off the crystal oscillator * /
168+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
169+ bic tmp1 , tmp1 , #AT91_PMC_MOSCEN
170+ orr tmp1 , tmp1 , #AT91_PMC_KEY
171+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
172+
173+ / * Wait for interrupt * /
174+ at91_cpu_idle
175+
176+ / * Turn on the crystal oscillator * /
177+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
178+ orr tmp1 , tmp1 , #AT91_PMC_MOSCEN
179+ orr tmp1 , tmp1 , #AT91_PMC_KEY
180+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
181+
182+ wait_moscrdy
183+ .endm
184+
185+ / **
186+ * Note: This procedure only applies on the platform which uses
187+ * the external crystal oscillator as a main clock source.
188+ * /
189+ .macro at91_pm_ulp1_mode
190+ ldr pmc , .pmc_base
191+
192+ / * Switch the main clock source to 12 - MHz RC oscillator * /
193+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
194+ bic tmp1 , tmp1 , #AT91_PMC_MOSCSEL
195+ bic tmp1 , tmp1 , #AT91_PMC_KEY_MASK
196+ orr tmp1 , tmp1 , #AT91_PMC_KEY
197+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
198+
199+ wait_moscsels
200+
201+ / * Disable the crystal oscillator * /
202+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
203+ bic tmp1 , tmp1 , #AT91_PMC_MOSCEN
204+ bic tmp1 , tmp1 , #AT91_PMC_KEY_MASK
205+ orr tmp1 , tmp1 , #AT91_PMC_KEY
206+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
207+
208+ / * Switch the master clock source to main clock * /
209+ ldr tmp1 , [ pmc , #AT91_PMC_MCKR ]
210+ bic tmp1 , tmp1 , #AT91_PMC_CSS
211+ orr tmp1 , tmp1 , #AT91_PMC_CSS_MAIN
212+ str tmp1 , [ pmc , #AT91_PMC_MCKR ]
213+
214+ wait_mckrdy
215+
216+ / * Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR * /
217+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
218+ orr tmp1 , tmp1 , #AT91_PMC_WAITMODE
219+ bic tmp1 , tmp1 , #AT91_PMC_KEY_MASK
220+ orr tmp1 , tmp1 , #AT91_PMC_KEY
221+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
222+
223+ wait_mckrdy
224+
225+ / * Enable the crystal oscillator * /
226+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
227+ orr tmp1 , tmp1 , #AT91_PMC_MOSCEN
228+ bic tmp1 , tmp1 , #AT91_PMC_KEY_MASK
229+ orr tmp1 , tmp1 , #AT91_PMC_KEY
230+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
231+
232+ wait_moscrdy
233+
234+ / * Switch the master clock source to slow clock * /
235+ ldr tmp1 , [ pmc , #AT91_PMC_MCKR ]
236+ bic tmp1 , tmp1 , #AT91_PMC_CSS
237+ str tmp1 , [ pmc , #AT91_PMC_MCKR ]
238+
239+ wait_mckrdy
240+
241+ / * Switch main clock source to crystal oscillator * /
242+ ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
243+ orr tmp1 , tmp1 , #AT91_PMC_MOSCSEL
244+ bic tmp1 , tmp1 , #AT91_PMC_KEY_MASK
245+ orr tmp1 , tmp1 , #AT91_PMC_KEY
246+ str tmp1 , [ pmc , #AT91_CKGR_MOR ]
247+
248+ wait_moscsels
249+
250+ / * Switch the master clock source to main clock * /
251+ ldr tmp1 , [ pmc , #AT91_PMC_MCKR ]
252+ bic tmp1 , tmp1 , #AT91_PMC_CSS
253+ orr tmp1 , tmp1 , #AT91_PMC_CSS_MAIN
254+ str tmp1 , [ pmc , #AT91_PMC_MCKR ]
255+
256+ wait_mckrdy
257+ .endm
258+
259+ ENTRY(at91_ulp_mode)
155260 ldr pmc , .pmc_base
156261
157262 / * Save Master clock setting * /
@@ -174,22 +279,19 @@ ENTRY(at91_ulp0_mode)
174279 orr tmp1 , tmp1 , #( 1 << 29 ) / * bit 29 always set * /
175280 str tmp1 , [ pmc , #AT91_CKGR_PLLAR ]
176281
177- / * Turn off the main oscillator * /
178- ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
179- bic tmp1 , tmp1 , #AT91_PMC_MOSCEN
180- orr tmp1 , tmp1 , #AT91_PMC_KEY
181- str tmp1 , [ pmc , #AT91_CKGR_MOR ]
282+ ldr r0 , .pm_mode
283+ cmp r0 , #AT91_PM_ULP1
284+ beq ulp1_mode
182285
183- / * Wait for interrupt * /
184- at91_cpu_idle
286+ at91_pm_ulp0_mode
287+ b ulp_exit
185288
186- / * Turn on the main oscillator * /
187- ldr tmp1 , [ pmc , #AT91_CKGR_MOR ]
188- orr tmp1 , tmp1 , #AT91_PMC_MOSCEN
189- orr tmp1 , tmp1 , #AT91_PMC_KEY
190- str tmp1 , [ pmc , #AT91_CKGR_MOR ]
289+ ulp1_mode:
290+ at91_pm_ulp1_mode
291+ b ulp_exit
191292
192- wait_moscrdy
293+ ulp_exit:
294+ ldr pmc , .pmc_base
193295
194296 / * Restore PLLA setting * /
195297 ldr tmp1 , .saved_pllar
@@ -212,7 +314,7 @@ ENTRY(at91_ulp0_mode)
212314 wait_mckrdy
213315
214316 mov pc , lr
215- ENDPROC(at91_ulp0_mode )
317+ ENDPROC(at91_ulp_mode )
216318
217319/ *
218320 * void at91_sramc_self_refresh(unsigned int is_active)
0 commit comments