~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-imx/suspend-imx6.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/mach-imx/suspend-imx6.S (Version linux-6.12-rc7) and /arch/ppc/mach-imx/suspend-imx6.S (Version linux-5.0.21)


  1 /* SPDX-License-Identifier: GPL-2.0-or-later *    
  2 /*                                                
  3  * Copyright 2014 Freescale Semiconductor, Inc    
  4  */                                               
  5                                                   
  6 #include <linux/linkage.h>                        
  7 #include <asm/assembler.h>                        
  8 #include <asm/asm-offsets.h>                      
  9 #include <asm/hardware/cache-l2x0.h>              
 10 #include "hardware.h"                             
 11                                                   
 12 .arch armv7-a                                     
 13                                                   
 14 /*                                                
 15  * ==================== low level suspend ====    
 16  *                                                
 17  * Better to follow below rules to use ARM reg    
 18  * r0: pm_info structure address;                 
 19  * r1 ~ r4: for saving pm_info members;           
 20  * r5 ~ r10: free registers;                      
 21  * r11: io base address.                          
 22  *                                                
 23  * suspend ocram space layout:                    
 24  * ======================== high address =====    
 25  *                              .                 
 26  *                              .                 
 27  *                              .                 
 28  *                              ^                 
 29  *                              ^                 
 30  *                              ^                 
 31  *                      imx6_suspend code         
 32  *              PM_INFO structure(imx6_cpu_pm_    
 33  * ======================== low address ======    
 34  */                                               
 35                                                   
 36 /*                                                
 37  * Below offsets are based on struct imx6_cpu_    
 38  * which defined in arch/arm/mach-imx/pm-imx6q    
 39  * structure contains necessary pm info for lo    
 40  * suspend related code.                          
 41  */                                               
 42 #define PM_INFO_PBASE_OFFSET                      
 43 #define PM_INFO_RESUME_ADDR_OFFSET                
 44 #define PM_INFO_DDR_TYPE_OFFSET                   
 45 #define PM_INFO_PM_INFO_SIZE_OFFSET               
 46 #define PM_INFO_MX6Q_MMDC_P_OFFSET                
 47 #define PM_INFO_MX6Q_MMDC_V_OFFSET                
 48 #define PM_INFO_MX6Q_SRC_P_OFFSET                 
 49 #define PM_INFO_MX6Q_SRC_V_OFFSET                 
 50 #define PM_INFO_MX6Q_IOMUXC_P_OFFSET              
 51 #define PM_INFO_MX6Q_IOMUXC_V_OFFSET              
 52 #define PM_INFO_MX6Q_CCM_P_OFFSET                 
 53 #define PM_INFO_MX6Q_CCM_V_OFFSET                 
 54 #define PM_INFO_MX6Q_GPC_P_OFFSET                 
 55 #define PM_INFO_MX6Q_GPC_V_OFFSET                 
 56 #define PM_INFO_MX6Q_L2_P_OFFSET                  
 57 #define PM_INFO_MX6Q_L2_V_OFFSET                  
 58 #define PM_INFO_MMDC_IO_NUM_OFFSET                
 59 #define PM_INFO_MMDC_IO_VAL_OFFSET                
 60                                                   
 61 #define MX6Q_SRC_GPR1   0x20                      
 62 #define MX6Q_SRC_GPR2   0x24                      
 63 #define MX6Q_MMDC_MAPSR 0x404                     
 64 #define MX6Q_MMDC_MPDGCTRL0     0x83c             
 65 #define MX6Q_GPC_IMR1   0x08                      
 66 #define MX6Q_GPC_IMR2   0x0c                      
 67 #define MX6Q_GPC_IMR3   0x10                      
 68 #define MX6Q_GPC_IMR4   0x14                      
 69 #define MX6Q_CCM_CCR    0x0                       
 70                                                   
 71         .align 3                                  
 72         .arm                                      
 73                                                   
 74         .macro  sync_l2_cache                     
 75                                                   
 76         /* sync L2 cache to drain L2's buffers    
 77 #ifdef CONFIG_CACHE_L2X0                          
 78         ldr     r11, [r0, #PM_INFO_MX6Q_L2_V_O    
 79         teq     r11, #0                           
 80         beq     6f                                
 81         mov     r6, #0x0                          
 82         str     r6, [r11, #L2X0_CACHE_SYNC]       
 83 1:                                                
 84         ldr     r6, [r11, #L2X0_CACHE_SYNC]       
 85         ands    r6, r6, #0x1                      
 86         bne     1b                                
 87 6:                                                
 88 #endif                                            
 89                                                   
 90         .endm                                     
 91                                                   
 92         .macro  resume_mmdc                       
 93                                                   
 94         /* restore MMDC IO */                     
 95         cmp     r5, #0x0                          
 96         ldreq   r11, [r0, #PM_INFO_MX6Q_IOMUXC    
 97         ldrne   r11, [r0, #PM_INFO_MX6Q_IOMUXC    
 98                                                   
 99         ldr     r6, [r0, #PM_INFO_MMDC_IO_NUM_    
100         ldr     r7, =PM_INFO_MMDC_IO_VAL_OFFSE    
101         add     r7, r7, r0                        
102 1:                                                
103         ldr     r8, [r7], #0x4                    
104         ldr     r9, [r7], #0x4                    
105         str     r9, [r11, r8]                     
106         subs    r6, r6, #0x1                      
107         bne     1b                                
108                                                   
109         cmp     r5, #0x0                          
110         ldreq   r11, [r0, #PM_INFO_MX6Q_MMDC_V    
111         ldrne   r11, [r0, #PM_INFO_MX6Q_MMDC_P    
112                                                   
113         cmp     r3, #IMX_DDR_TYPE_LPDDR2          
114         bne     4f                                
115                                                   
116         /* reset read FIFO, RST_RD_FIFO */        
117         ldr     r7, =MX6Q_MMDC_MPDGCTRL0          
118         ldr     r6, [r11, r7]                     
119         orr     r6, r6, #(1 << 31)                
120         str     r6, [r11, r7]                     
121 2:                                                
122         ldr     r6, [r11, r7]                     
123         ands    r6, r6, #(1 << 31)                
124         bne     2b                                
125                                                   
126         /* reset FIFO a second time */            
127         ldr     r6, [r11, r7]                     
128         orr     r6, r6, #(1 << 31)                
129         str     r6, [r11, r7]                     
130 3:                                                
131         ldr     r6, [r11, r7]                     
132         ands    r6, r6, #(1 << 31)                
133         bne     3b                                
134 4:                                                
135         /* let DDR out of self-refresh */         
136         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
137         bic     r7, r7, #(1 << 21)                
138         str     r7, [r11, #MX6Q_MMDC_MAPSR]       
139 5:                                                
140         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
141         ands    r7, r7, #(1 << 25)                
142         bne     5b                                
143                                                   
144         /* enable DDR auto power saving */        
145         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
146         bic     r7, r7, #0x1                      
147         str     r7, [r11, #MX6Q_MMDC_MAPSR]       
148                                                   
149         .endm                                     
150                                                   
151 ENTRY(imx6_suspend)                               
152         ldr     r1, [r0, #PM_INFO_PBASE_OFFSET    
153         ldr     r2, [r0, #PM_INFO_RESUME_ADDR_    
154         ldr     r3, [r0, #PM_INFO_DDR_TYPE_OFF    
155         ldr     r4, [r0, #PM_INFO_PM_INFO_SIZE    
156                                                   
157         /*                                        
158          * counting the resume address in iram    
159          * to set it in SRC register.             
160          */                                       
161         ldr     r6, =imx6_suspend                 
162         ldr     r7, =resume                       
163         sub     r7, r7, r6                        
164         add     r8, r1, r4                        
165         add     r9, r8, r7                        
166                                                   
167         /*                                        
168          * make sure TLB contain the addr we w    
169          * as we will access them after MMDC I    
170          */                                       
171                                                   
172         ldr     r11, [r0, #PM_INFO_MX6Q_CCM_V_    
173         ldr     r6, [r11, #0x0]                   
174         ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_    
175         ldr     r6, [r11, #0x0]                   
176         ldr     r11, [r0, #PM_INFO_MX6Q_IOMUXC    
177         ldr     r6, [r11, #0x0]                   
178                                                   
179         /* use r11 to store the IO address */     
180         ldr     r11, [r0, #PM_INFO_MX6Q_SRC_V_    
181         /* store physical resume addr and pm_i    
182         str     r9, [r11, #MX6Q_SRC_GPR1]         
183         str     r1, [r11, #MX6Q_SRC_GPR2]         
184                                                   
185         /* need to sync L2 cache before DSM. *    
186         sync_l2_cache                             
187                                                   
188         ldr     r11, [r0, #PM_INFO_MX6Q_MMDC_V    
189         /*                                        
190          * put DDR explicitly into self-refres    
191          * disable automatic power savings.       
192          */                                       
193         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
194         orr     r7, r7, #0x1                      
195         str     r7, [r11, #MX6Q_MMDC_MAPSR]       
196                                                   
197         /* make the DDR explicitly enter self-    
198         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
199         orr     r7, r7, #(1 << 21)                
200         str     r7, [r11, #MX6Q_MMDC_MAPSR]       
201                                                   
202 poll_dvfs_set:                                    
203         ldr     r7, [r11, #MX6Q_MMDC_MAPSR]       
204         ands    r7, r7, #(1 << 25)                
205         beq     poll_dvfs_set                     
206                                                   
207         ldr     r11, [r0, #PM_INFO_MX6Q_IOMUXC    
208         ldr     r6, =0x0                          
209         ldr     r7, [r0, #PM_INFO_MMDC_IO_NUM_    
210         ldr     r8, =PM_INFO_MMDC_IO_VAL_OFFSE    
211         add     r8, r8, r0                        
212         /* LPDDR2's last 3 IOs need special se    
213         cmp     r3, #IMX_DDR_TYPE_LPDDR2          
214         subeq   r7, r7, #0x3                      
215 set_mmdc_io_lpm:                                  
216         ldr     r9, [r8], #0x8                    
217         str     r6, [r11, r9]                     
218         subs    r7, r7, #0x1                      
219         bne     set_mmdc_io_lpm                   
220                                                   
221         cmp     r3, #IMX_DDR_TYPE_LPDDR2          
222         bne     set_mmdc_io_lpm_done              
223         ldr     r6, =0x1000                       
224         ldr     r9, [r8], #0x8                    
225         str     r6, [r11, r9]                     
226         ldr     r9, [r8], #0x8                    
227         str     r6, [r11, r9]                     
228         ldr     r6, =0x80000                      
229         ldr     r9, [r8]                          
230         str     r6, [r11, r9]                     
231 set_mmdc_io_lpm_done:                             
232                                                   
233         /*                                        
234          * mask all GPC interrupts before         
235          * enabling the RBC counters to           
236          * avoid the counter starting too         
237          * early if an interupt is already        
238          * pending.                               
239          */                                       
240         ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_    
241         ldr     r6, [r11, #MX6Q_GPC_IMR1]         
242         ldr     r7, [r11, #MX6Q_GPC_IMR2]         
243         ldr     r8, [r11, #MX6Q_GPC_IMR3]         
244         ldr     r9, [r11, #MX6Q_GPC_IMR4]         
245                                                   
246         ldr     r10, =0xffffffff                  
247         str     r10, [r11, #MX6Q_GPC_IMR1]        
248         str     r10, [r11, #MX6Q_GPC_IMR2]        
249         str     r10, [r11, #MX6Q_GPC_IMR3]        
250         str     r10, [r11, #MX6Q_GPC_IMR4]        
251                                                   
252         /*                                        
253          * enable the RBC bypass counter here     
254          * to hold off the interrupts. RBC cou    
255          * = 32 (1ms), Minimum RBC delay shoul    
256          * 400us for the analog LDOs to power     
257          */                                       
258         ldr     r11, [r0, #PM_INFO_MX6Q_CCM_V_    
259         ldr     r10, [r11, #MX6Q_CCM_CCR]         
260         bic     r10, r10, #(0x3f << 21)           
261         orr     r10, r10, #(0x20 << 21)           
262         str     r10, [r11, #MX6Q_CCM_CCR]         
263                                                   
264         /* enable the counter. */                 
265         ldr     r10, [r11, #MX6Q_CCM_CCR]         
266         orr     r10, r10, #(0x1 << 27)            
267         str     r10, [r11, #MX6Q_CCM_CCR]         
268                                                   
269         /* unmask all the GPC interrupts. */      
270         ldr     r11, [r0, #PM_INFO_MX6Q_GPC_V_    
271         str     r6, [r11, #MX6Q_GPC_IMR1]         
272         str     r7, [r11, #MX6Q_GPC_IMR2]         
273         str     r8, [r11, #MX6Q_GPC_IMR3]         
274         str     r9, [r11, #MX6Q_GPC_IMR4]         
275                                                   
276         /*                                        
277          * now delay for a short while (3usec)    
278          * ARM is at 1GHz at this point           
279          * so a short loop should be enough.      
280          * this delay is required to ensure th    
281          * the RBC counter can start counting     
282          * case an interrupt is already pendin    
283          * or in case an interrupt arrives jus    
284          * as ARM is about to assert DSM_reque    
285          */                                       
286         ldr     r6, =2000                         
287 rbc_loop:                                         
288         subs    r6, r6, #0x1                      
289         bne     rbc_loop                          
290                                                   
291         /* Zzz, enter stop mode */                
292         wfi                                       
293         nop                                       
294         nop                                       
295         nop                                       
296         nop                                       
297                                                   
298         /*                                        
299          * run to here means there is pending     
300          * wakeup source, system should auto      
301          * resume, we need to restore MMDC IO     
302          */                                       
303         mov     r5, #0x0                          
304         resume_mmdc                               
305                                                   
306         /* return to suspend finish */            
307         ret     lr                                
308                                                   
309 resume:                                           
310         /* invalidate L1 I-cache first */         
311         mov     r6, #0x0                          
312         mcr     p15, 0, r6, c7, c5, 0             
313         mcr     p15, 0, r6, c7, c5, 6             
314         /* enable the Icache and branch predic    
315         mov     r6, #0x1800                       
316         mcr     p15, 0, r6, c1, c0, 0             
317         isb                                       
318                                                   
319         /* get physical resume address from pm    
320         ldr     lr, [r0, #PM_INFO_RESUME_ADDR_    
321         /* clear core0's entry and parameter *    
322         ldr     r11, [r0, #PM_INFO_MX6Q_SRC_P_    
323         mov     r7, #0x0                          
324         str     r7, [r11, #MX6Q_SRC_GPR1]         
325         str     r7, [r11, #MX6Q_SRC_GPR2]         
326                                                   
327         ldr     r3, [r0, #PM_INFO_DDR_TYPE_OFF    
328         mov     r5, #0x1                          
329         resume_mmdc                               
330                                                   
331         ret     lr                                
332 ENDPROC(imx6_suspend)                             
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php