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

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-meson/platsmp.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-meson/platsmp.c (Architecture sparc) and /arch/m68k/mach-meson/platsmp.c (Architecture m68k)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  * Copyright (C) 2015 Carlo Caione <carlo@endl    
  4  * Copyright (C) 2017 Martin Blumenstingl <mar    
  5  */                                               
  6                                                   
  7 #include <linux/delay.h>                          
  8 #include <linux/init.h>                           
  9 #include <linux/io.h>                             
 10 #include <linux/of.h>                             
 11 #include <linux/of_address.h>                     
 12 #include <linux/regmap.h>                         
 13 #include <linux/reset.h>                          
 14 #include <linux/smp.h>                            
 15 #include <linux/mfd/syscon.h>                     
 16                                                   
 17 #include <asm/cacheflush.h>                       
 18 #include <asm/cp15.h>                             
 19 #include <asm/smp_scu.h>                          
 20 #include <asm/smp_plat.h>                         
 21                                                   
 22 #define MESON_SMP_SRAM_CPU_CTRL_REG               
 23 #define MESON_SMP_SRAM_CPU_CTRL_ADDR_REG(c)       
 24                                                   
 25 #define MESON_CPU_AO_RTI_PWR_A9_CNTL0             
 26 #define MESON_CPU_AO_RTI_PWR_A9_CNTL1             
 27 #define MESON_CPU_AO_RTI_PWR_A9_MEM_PD0           
 28                                                   
 29 #define MESON_CPU_PWR_A9_CNTL0_M(c)               
 30 #define MESON_CPU_PWR_A9_CNTL1_M(c)               
 31 #define MESON_CPU_PWR_A9_MEM_PD0_M(c)             
 32 #define MESON_CPU_PWR_A9_CNTL1_ST(c)              
 33                                                   
 34 static void __iomem *sram_base;                   
 35 static void __iomem *scu_base;                    
 36 static struct regmap *pmu;                        
 37                                                   
 38 static struct reset_control *meson_smp_get_cor    
 39 {                                                 
 40         struct device_node *np = of_get_cpu_no    
 41                                                   
 42         return of_reset_control_get_exclusive(    
 43 }                                                 
 44                                                   
 45 static void meson_smp_set_cpu_ctrl(int cpu, bo    
 46 {                                                 
 47         u32 val = readl(sram_base + MESON_SMP_    
 48                                                   
 49         if (on_off)                               
 50                 val |= BIT(cpu);                  
 51         else                                      
 52                 val &= ~BIT(cpu);                 
 53                                                   
 54         /* keep bit 0 always enabled */           
 55         val |= BIT(0);                            
 56                                                   
 57         writel(val, sram_base + MESON_SMP_SRAM    
 58 }                                                 
 59                                                   
 60 static void __init meson_smp_prepare_cpus(cons    
 61                                           cons    
 62                                           cons    
 63 {                                                 
 64         static struct device_node *node;          
 65                                                   
 66         /* SMP SRAM */                            
 67         node = of_find_compatible_node(NULL, N    
 68         if (!node) {                              
 69                 pr_err("Missing SRAM node\n");    
 70                 return;                           
 71         }                                         
 72                                                   
 73         sram_base = of_iomap(node, 0);            
 74         of_node_put(node);                        
 75         if (!sram_base) {                         
 76                 pr_err("Couldn't map SRAM regi    
 77                 return;                           
 78         }                                         
 79                                                   
 80         /* PMU */                                 
 81         pmu = syscon_regmap_lookup_by_compatib    
 82         if (IS_ERR(pmu)) {                        
 83                 pr_err("Couldn't map PMU regis    
 84                 return;                           
 85         }                                         
 86                                                   
 87         /* SCU */                                 
 88         node = of_find_compatible_node(NULL, N    
 89         if (!node) {                              
 90                 pr_err("Missing SCU node\n");     
 91                 return;                           
 92         }                                         
 93                                                   
 94         scu_base = of_iomap(node, 0);             
 95         of_node_put(node);                        
 96         if (!scu_base) {                          
 97                 pr_err("Couldn't map SCU regis    
 98                 return;                           
 99         }                                         
100                                                   
101         scu_enable(scu_base);                     
102 }                                                 
103                                                   
104 static void __init meson8b_smp_prepare_cpus(un    
105 {                                                 
106         meson_smp_prepare_cpus("arm,cortex-a5-    
107                                "amlogic,meson8    
108 }                                                 
109                                                   
110 static void __init meson8_smp_prepare_cpus(uns    
111 {                                                 
112         meson_smp_prepare_cpus("arm,cortex-a9-    
113                                "amlogic,meson8    
114 }                                                 
115                                                   
116 static void meson_smp_begin_secondary_boot(uns    
117 {                                                 
118         /*                                        
119          * Set the entry point before powering    
120          * is needed if the CPU is in "warm" s    
121          * system without power-cycling, or wh    
122          * then taking it online again.           
123          */                                       
124         writel(__pa_symbol(secondary_startup),    
125                sram_base + MESON_SMP_SRAM_CPU_    
126                                                   
127         /*                                        
128          * SCU Power on CPU (needs to be done     
129          * otherwise the secondary CPU will no    
130          */                                       
131         scu_cpu_power_enable(scu_base, cpu);      
132 }                                                 
133                                                   
134 static int meson_smp_finalize_secondary_boot(u    
135 {                                                 
136         unsigned long timeout;                    
137                                                   
138         timeout = jiffies + (10 * HZ);            
139         while (readl(sram_base + MESON_SMP_SRA    
140                 if (!time_before(jiffies, time    
141                         pr_err("Timeout while     
142                                cpu);              
143                         return -ETIMEDOUT;        
144                 }                                 
145         }                                         
146                                                   
147         writel(__pa_symbol(secondary_startup),    
148                sram_base + MESON_SMP_SRAM_CPU_    
149                                                   
150         meson_smp_set_cpu_ctrl(cpu, true);        
151                                                   
152         return 0;                                 
153 }                                                 
154                                                   
155 static int meson8_smp_boot_secondary(unsigned     
156                                      struct ta    
157 {                                                 
158         struct reset_control *rstc;               
159         int ret;                                  
160                                                   
161         rstc = meson_smp_get_core_reset(cpu);     
162         if (IS_ERR(rstc)) {                       
163                 pr_err("Couldn't get the reset    
164                 return PTR_ERR(rstc);             
165         }                                         
166                                                   
167         meson_smp_begin_secondary_boot(cpu);      
168                                                   
169         /* Reset enable */                        
170         ret = reset_control_assert(rstc);         
171         if (ret) {                                
172                 pr_err("Failed to assert CPU%d    
173                 goto out;                         
174         }                                         
175                                                   
176         /* CPU power ON */                        
177         ret = regmap_update_bits(pmu, MESON_CP    
178                                  MESON_CPU_PWR    
179         if (ret < 0) {                            
180                 pr_err("Couldn't wake up CPU%d    
181                 goto out;                         
182         }                                         
183                                                   
184         udelay(10);                               
185                                                   
186         /* Isolation disable */                   
187         ret = regmap_update_bits(pmu, MESON_CP    
188                                  0);              
189         if (ret < 0) {                            
190                 pr_err("Error when disabling i    
191                 goto out;                         
192         }                                         
193                                                   
194         /* Reset disable */                       
195         ret = reset_control_deassert(rstc);       
196         if (ret) {                                
197                 pr_err("Failed to de-assert CP    
198                 goto out;                         
199         }                                         
200                                                   
201         ret = meson_smp_finalize_secondary_boo    
202         if (ret)                                  
203                 goto out;                         
204                                                   
205 out:                                              
206         reset_control_put(rstc);                  
207                                                   
208         return 0;                                 
209 }                                                 
210                                                   
211 static int meson8b_smp_boot_secondary(unsigned    
212                                      struct ta    
213 {                                                 
214         struct reset_control *rstc;               
215         int ret;                                  
216         u32 val;                                  
217                                                   
218         rstc = meson_smp_get_core_reset(cpu);     
219         if (IS_ERR(rstc)) {                       
220                 pr_err("Couldn't get the reset    
221                 return PTR_ERR(rstc);             
222         }                                         
223                                                   
224         meson_smp_begin_secondary_boot(cpu);      
225                                                   
226         /* CPU power UP */                        
227         ret = regmap_update_bits(pmu, MESON_CP    
228                                  MESON_CPU_PWR    
229         if (ret < 0) {                            
230                 pr_err("Couldn't power up CPU%    
231                 goto out;                         
232         }                                         
233                                                   
234         udelay(5);                                
235                                                   
236         /* Reset enable */                        
237         ret = reset_control_assert(rstc);         
238         if (ret) {                                
239                 pr_err("Failed to assert CPU%d    
240                 goto out;                         
241         }                                         
242                                                   
243         /* Memory power UP */                     
244         ret = regmap_update_bits(pmu, MESON_CP    
245                                  MESON_CPU_PWR    
246         if (ret < 0) {                            
247                 pr_err("Couldn't power up the     
248                 goto out;                         
249         }                                         
250                                                   
251         /* Wake up CPU */                         
252         ret = regmap_update_bits(pmu, MESON_CP    
253                                  MESON_CPU_PWR    
254         if (ret < 0) {                            
255                 pr_err("Couldn't wake up CPU%d    
256                 goto out;                         
257         }                                         
258                                                   
259         udelay(10);                               
260                                                   
261         ret = regmap_read_poll_timeout(pmu, ME    
262                                        val & M    
263                                        10, 100    
264         if (ret) {                                
265                 pr_err("Timeout while polling     
266                 goto out;                         
267         }                                         
268                                                   
269         /* Isolation disable */                   
270         ret = regmap_update_bits(pmu, MESON_CP    
271                                  0);              
272         if (ret < 0) {                            
273                 pr_err("Error when disabling i    
274                 goto out;                         
275         }                                         
276                                                   
277         /* Reset disable */                       
278         ret = reset_control_deassert(rstc);       
279         if (ret) {                                
280                 pr_err("Failed to de-assert CP    
281                 goto out;                         
282         }                                         
283                                                   
284         ret = meson_smp_finalize_secondary_boo    
285         if (ret)                                  
286                 goto out;                         
287                                                   
288 out:                                              
289         reset_control_put(rstc);                  
290                                                   
291         return 0;                                 
292 }                                                 
293                                                   
294 #ifdef CONFIG_HOTPLUG_CPU                         
295 static void meson8_smp_cpu_die(unsigned int cp    
296 {                                                 
297         meson_smp_set_cpu_ctrl(cpu, false);       
298                                                   
299         v7_exit_coherency_flush(louis);           
300                                                   
301         scu_power_mode(scu_base, SCU_PM_POWERO    
302                                                   
303         dsb();                                    
304         wfi();                                    
305                                                   
306         /* we should never get here */            
307         WARN_ON(1);                               
308 }                                                 
309                                                   
310 static int meson8_smp_cpu_kill(unsigned int cp    
311 {                                                 
312         int ret, power_mode;                      
313         unsigned long timeout;                    
314                                                   
315         timeout = jiffies + (50 * HZ);            
316         do {                                      
317                 power_mode = scu_get_cpu_power    
318                                                   
319                 if (power_mode == SCU_PM_POWER    
320                         break;                    
321                                                   
322                 usleep_range(10000, 15000);       
323         } while (time_before(jiffies, timeout)    
324                                                   
325         if (power_mode != SCU_PM_POWEROFF) {      
326                 pr_err("Error while waiting fo    
327                        cpu);                      
328                 return -ETIMEDOUT;                
329         }                                         
330                                                   
331         msleep(30);                               
332                                                   
333         /* Isolation enable */                    
334         ret = regmap_update_bits(pmu, MESON_CP    
335                                  0x3);            
336         if (ret < 0) {                            
337                 pr_err("Error when enabling is    
338                 return ret;                       
339         }                                         
340                                                   
341         udelay(10);                               
342                                                   
343         /* CPU power OFF */                       
344         ret = regmap_update_bits(pmu, MESON_CP    
345                                  MESON_CPU_PWR    
346         if (ret < 0) {                            
347                 pr_err("Couldn't change sleep     
348                 return ret;                       
349         }                                         
350                                                   
351         return 1;                                 
352 }                                                 
353                                                   
354 static int meson8b_smp_cpu_kill(unsigned int c    
355 {                                                 
356         int ret, power_mode, count = 5000;        
357                                                   
358         do {                                      
359                 power_mode = scu_get_cpu_power    
360                                                   
361                 if (power_mode == SCU_PM_POWER    
362                         break;                    
363                                                   
364                 udelay(10);                       
365         } while (++count);                        
366                                                   
367         if (power_mode != SCU_PM_POWEROFF) {      
368                 pr_err("Error while waiting fo    
369                        cpu);                      
370                 return -ETIMEDOUT;                
371         }                                         
372                                                   
373         udelay(10);                               
374                                                   
375         /* CPU power DOWN */                      
376         ret = regmap_update_bits(pmu, MESON_CP    
377                                  MESON_CPU_PWR    
378         if (ret < 0) {                            
379                 pr_err("Couldn't power down CP    
380                 return ret;                       
381         }                                         
382                                                   
383         /* Isolation enable */                    
384         ret = regmap_update_bits(pmu, MESON_CP    
385                                  0x3);            
386         if (ret < 0) {                            
387                 pr_err("Error when enabling is    
388                 return ret;                       
389         }                                         
390                                                   
391         udelay(10);                               
392                                                   
393         /* Sleep status */                        
394         ret = regmap_update_bits(pmu, MESON_CP    
395                                  MESON_CPU_PWR    
396         if (ret < 0) {                            
397                 pr_err("Couldn't change sleep     
398                 return ret;                       
399         }                                         
400                                                   
401         /* Memory power DOWN */                   
402         ret = regmap_update_bits(pmu, MESON_CP    
403                                  MESON_CPU_PWR    
404         if (ret < 0) {                            
405                 pr_err("Couldn't power down th    
406                 return ret;                       
407         }                                         
408                                                   
409         return 1;                                 
410 }                                                 
411 #endif                                            
412                                                   
413 static struct smp_operations meson8_smp_ops __    
414         .smp_prepare_cpus       = meson8_smp_p    
415         .smp_boot_secondary     = meson8_smp_b    
416 #ifdef CONFIG_HOTPLUG_CPU                         
417         .cpu_die                = meson8_smp_c    
418         .cpu_kill               = meson8_smp_c    
419 #endif                                            
420 };                                                
421                                                   
422 static struct smp_operations meson8b_smp_ops _    
423         .smp_prepare_cpus       = meson8b_smp_    
424         .smp_boot_secondary     = meson8b_smp_    
425 #ifdef CONFIG_HOTPLUG_CPU                         
426         .cpu_die                = meson8_smp_c    
427         .cpu_kill               = meson8b_smp_    
428 #endif                                            
429 };                                                
430                                                   
431 CPU_METHOD_OF_DECLARE(meson8_smp, "amlogic,mes    
432 CPU_METHOD_OF_DECLARE(meson8b_smp, "amlogic,me    
433                                                   

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