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

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-mvebu/pm.c

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-mvebu/pm.c (Architecture i386) and /arch/sparc64/mach-mvebu/pm.c (Architecture sparc64)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  * Suspend/resume support. Currently supportin    
  4  *                                                
  5  * Copyright (C) 2014 Marvell                     
  6  *                                                
  7  * Thomas Petazzoni <thomas.petazzoni@free-ele    
  8  */                                               
  9                                                   
 10 #include <linux/cpu_pm.h>                         
 11 #include <linux/delay.h>                          
 12 #include <linux/gpio.h>                           
 13 #include <linux/io.h>                             
 14 #include <linux/kernel.h>                         
 15 #include <linux/mbus.h>                           
 16 #include <linux/of_address.h>                     
 17 #include <linux/suspend.h>                        
 18 #include <asm/cacheflush.h>                       
 19 #include <asm/outercache.h>                       
 20 #include <asm/suspend.h>                          
 21                                                   
 22 #include "coherency.h"                            
 23 #include "common.h"                               
 24 #include "pmsu.h"                                 
 25                                                   
 26 #define SDRAM_CONFIG_OFFS                  0x0    
 27 #define  SDRAM_CONFIG_SR_MODE_BIT          BIT    
 28 #define SDRAM_OPERATION_OFFS               0x1    
 29 #define  SDRAM_OPERATION_SELF_REFRESH      0x7    
 30 #define SDRAM_DLB_EVICTION_OFFS            0x3    
 31 #define  SDRAM_DLB_EVICTION_THRESHOLD_MASK 0xf    
 32                                                   
 33 static void (*mvebu_board_pm_enter)(void __iom    
 34 static void __iomem *sdram_ctrl;                  
 35                                                   
 36 static int mvebu_pm_powerdown(unsigned long da    
 37 {                                                 
 38         u32 reg, srcmd;                           
 39                                                   
 40         flush_cache_all();                        
 41         outer_flush_all();                        
 42                                                   
 43         /*                                        
 44          * Issue a Data Synchronization Barrie    
 45          * that all state saving has been comp    
 46          */                                       
 47         dsb();                                    
 48                                                   
 49         /* Flush the DLB and wait ~7 usec */      
 50         reg = readl(sdram_ctrl + SDRAM_DLB_EVI    
 51         reg &= ~SDRAM_DLB_EVICTION_THRESHOLD_M    
 52         writel(reg, sdram_ctrl + SDRAM_DLB_EVI    
 53                                                   
 54         udelay(7);                                
 55                                                   
 56         /* Set DRAM in battery backup mode */     
 57         reg = readl(sdram_ctrl + SDRAM_CONFIG_    
 58         reg &= ~SDRAM_CONFIG_SR_MODE_BIT;         
 59         writel(reg, sdram_ctrl + SDRAM_CONFIG_    
 60                                                   
 61         /* Prepare to go to self-refresh */       
 62                                                   
 63         srcmd = readl(sdram_ctrl + SDRAM_OPERA    
 64         srcmd &= ~0x1F;                           
 65         srcmd |= SDRAM_OPERATION_SELF_REFRESH;    
 66                                                   
 67         mvebu_board_pm_enter(sdram_ctrl + SDRA    
 68                                                   
 69         return 0;                                 
 70 }                                                 
 71                                                   
 72 #define BOOT_INFO_ADDR      0x3000                
 73 #define BOOT_MAGIC_WORD     0xdeadb002            
 74 #define BOOT_MAGIC_LIST_END 0xffffffff            
 75                                                   
 76 /*                                                
 77  * Those registers are accessed before switchi    
 78  * base, which is why we hardcode the 0xd00000    
 79  * used by the SoC out of reset.                  
 80  */                                               
 81 #define MBUS_WINDOW_12_CTRL       0xd00200b0      
 82 #define MBUS_INTERNAL_REG_ADDRESS 0xd0020080      
 83                                                   
 84 #define SDRAM_WIN_BASE_REG(x)   (0x20180 + (0x    
 85 #define SDRAM_WIN_CTRL_REG(x)   (0x20184 + (0x    
 86                                                   
 87 static phys_addr_t mvebu_internal_reg_base(voi    
 88 {                                                 
 89         struct device_node *np;                   
 90         __be32 in_addr[2];                        
 91                                                   
 92         np = of_find_node_by_name(NULL, "inter    
 93         BUG_ON(!np);                              
 94                                                   
 95         /*                                        
 96          * Ask the DT what is the internal reg    
 97          * platform. In the mvebu-mbus DT bind    
 98          * corresponds to the internal registe    
 99          */                                       
100         in_addr[0] = cpu_to_be32(0xf0010000);     
101         in_addr[1] = 0x0;                         
102                                                   
103         return of_translate_address(np, in_add    
104 }                                                 
105                                                   
106 static void mvebu_pm_store_armadaxp_bootinfo(u    
107 {                                                 
108         phys_addr_t resume_pc;                    
109                                                   
110         resume_pc = __pa_symbol(armada_370_xp_    
111                                                   
112         /*                                        
113          * The bootloader expects the first tw    
114          * value (BOOT_MAGIC_WORD), followed b    
115          * resume code to jump to. Then, it ex    
116          * (address, value) pairs, which can b    
117          * value of certain registers. This se    
118          * BOOT_MAGIC_LIST_END magic value.       
119          */                                       
120                                                   
121         writel(BOOT_MAGIC_WORD, store_addr++);    
122         writel(resume_pc, store_addr++);          
123                                                   
124         /*                                        
125          * Some platforms remap their internal    
126          * to 0xf1000000. However, out of rese    
127          * 0xf0000000 and ends at 0xf7ffffff,     
128          * the internal registers. Therefore,     
129          */                                       
130         writel(MBUS_WINDOW_12_CTRL, store_addr    
131         writel(0x0, store_addr++);                
132                                                   
133         /*                                        
134          * Set the internal register base addr    
135          * expected by Linux, as read from the    
136          */                                       
137         writel(MBUS_INTERNAL_REG_ADDRESS, stor    
138         writel(mvebu_internal_reg_base(), stor    
139                                                   
140         /*                                        
141          * Ask the mvebu-mbus driver to store     
142          * configuration, which has to be rest    
143          * before re-entering the kernel on re    
144          */                                       
145         store_addr += mvebu_mbus_save_cpu_targ    
146                                                   
147         writel(BOOT_MAGIC_LIST_END, store_addr    
148 }                                                 
149                                                   
150 static int mvebu_pm_store_bootinfo(void)          
151 {                                                 
152         u32 *store_addr;                          
153                                                   
154         store_addr = phys_to_virt(BOOT_INFO_AD    
155                                                   
156         if (of_machine_is_compatible("marvell,    
157                 mvebu_pm_store_armadaxp_bootin    
158         else                                      
159                 return -ENODEV;                   
160                                                   
161         return 0;                                 
162 }                                                 
163                                                   
164 static int mvebu_enter_suspend(void)              
165 {                                                 
166         int ret;                                  
167                                                   
168         ret = mvebu_pm_store_bootinfo();          
169         if (ret)                                  
170                 return ret;                       
171                                                   
172         cpu_pm_enter();                           
173                                                   
174         cpu_suspend(0, mvebu_pm_powerdown);       
175                                                   
176         outer_resume();                           
177                                                   
178         mvebu_v7_pmsu_idle_exit();                
179                                                   
180         set_cpu_coherent();                       
181                                                   
182         cpu_pm_exit();                            
183         return 0;                                 
184 }                                                 
185                                                   
186 static int mvebu_pm_enter(suspend_state_t stat    
187 {                                                 
188         switch (state) {                          
189         case PM_SUSPEND_STANDBY:                  
190                 cpu_do_idle();                    
191                 break;                            
192         case PM_SUSPEND_MEM:                      
193                 pr_warn("Entering suspend to R    
194                 return mvebu_enter_suspend();     
195         default:                                  
196                 return -EINVAL;                   
197         }                                         
198         return 0;                                 
199 }                                                 
200                                                   
201 static int mvebu_pm_valid(suspend_state_t stat    
202 {                                                 
203         if (state == PM_SUSPEND_STANDBY)          
204                 return 1;                         
205                                                   
206         if (state == PM_SUSPEND_MEM && mvebu_b    
207                 return 1;                         
208                                                   
209         return 0;                                 
210 }                                                 
211                                                   
212 static const struct platform_suspend_ops mvebu    
213         .enter = mvebu_pm_enter,                  
214         .valid = mvebu_pm_valid,                  
215 };                                                
216                                                   
217 static int __init mvebu_pm_init(void)             
218 {                                                 
219         if (!of_machine_is_compatible("marvell    
220             !of_machine_is_compatible("marvell    
221             !of_machine_is_compatible("marvell    
222             !of_machine_is_compatible("marvell    
223                 return -ENODEV;                   
224                                                   
225         suspend_set_ops(&mvebu_pm_ops);           
226                                                   
227         return 0;                                 
228 }                                                 
229                                                   
230                                                   
231 late_initcall(mvebu_pm_init);                     
232                                                   
233 int __init mvebu_pm_suspend_init(void (*board_    
234                                                   
235 {                                                 
236         struct device_node *np;                   
237         struct resource res;                      
238                                                   
239         np = of_find_compatible_node(NULL, NUL    
240                                      "marvell,    
241         if (!np)                                  
242                 return -ENODEV;                   
243                                                   
244         if (of_address_to_resource(np, 0, &res    
245                 of_node_put(np);                  
246                 return -ENODEV;                   
247         }                                         
248                                                   
249         if (!request_mem_region(res.start, res    
250                                 np->full_name)    
251                 of_node_put(np);                  
252                 return -EBUSY;                    
253         }                                         
254                                                   
255         sdram_ctrl = ioremap(res.start, resour    
256         if (!sdram_ctrl) {                        
257                 release_mem_region(res.start,     
258                 of_node_put(np);                  
259                 return -ENOMEM;                   
260         }                                         
261                                                   
262         of_node_put(np);                          
263                                                   
264         mvebu_board_pm_enter = board_pm_enter;    
265                                                   
266         return 0;                                 
267 }                                                 
268                                                   

~ [ 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