pervasive.c (22b8c9f5baeb440a716ea760ff05290221565b4c) | pervasive.c (302eca184fb844670fb128c69e22a8a28bbce48a) |
---|---|
1/* 2 * CBE Pervasive Monitor and Debug 3 * 4 * (C) Copyright IBM Corporation 2005 5 * 6 * Authors: Maximino Aguilar (maguilar@us.ibm.com) 7 * Michael N. Day (mnday@us.ibm.com) 8 * --- 24 unchanged lines hidden (view full) --- 33#include <asm/machdep.h> 34#include <asm/prom.h> 35#include <asm/pgtable.h> 36#include <asm/reg.h> 37 38#include "pervasive.h" 39#include "cbe_regs.h" 40 | 1/* 2 * CBE Pervasive Monitor and Debug 3 * 4 * (C) Copyright IBM Corporation 2005 5 * 6 * Authors: Maximino Aguilar (maguilar@us.ibm.com) 7 * Michael N. Day (mnday@us.ibm.com) 8 * --- 24 unchanged lines hidden (view full) --- 33#include <asm/machdep.h> 34#include <asm/prom.h> 35#include <asm/pgtable.h> 36#include <asm/reg.h> 37 38#include "pervasive.h" 39#include "cbe_regs.h" 40 |
41static DEFINE_SPINLOCK(cbe_pervasive_lock); 42 43static void __init cbe_enable_pause_zero(void) | 41static void cbe_power_save(void) |
44{ | 42{ |
45 unsigned long thread_switch_control; 46 unsigned long temp_register; 47 struct cbe_pmd_regs __iomem *pregs; | 43 unsigned long ctrl, thread_switch_control; 44 ctrl = mfspr(SPRN_CTRLF); |
48 | 45 |
49 spin_lock_irq(&cbe_pervasive_lock); 50 pregs = cbe_get_cpu_pmd_regs(smp_processor_id()); 51 if (pregs == NULL) 52 goto out; 53 54 pr_debug("Power Management: CPU %d\n", smp_processor_id()); 55 56 /* Enable Pause(0) control bit */ 57 temp_register = in_be64(&pregs->pmcr); 58 59 out_be64(&pregs->pmcr, 60 temp_register | CBE_PMD_PAUSE_ZERO_CONTROL); 61 | |
62 /* Enable DEC and EE interrupt request */ 63 thread_switch_control = mfspr(SPRN_TSC_CELL); 64 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST; 65 | 46 /* Enable DEC and EE interrupt request */ 47 thread_switch_control = mfspr(SPRN_TSC_CELL); 48 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST; 49 |
66 switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { | 50 switch (ctrl & CTRL_CT) { |
67 case CTRL_CT0: 68 thread_switch_control |= TSC_CELL_DEC_ENABLE_0; 69 break; 70 case CTRL_CT1: 71 thread_switch_control |= TSC_CELL_DEC_ENABLE_1; 72 break; 73 default: 74 printk(KERN_WARNING "%s: unknown configuration\n", 75 __FUNCTION__); 76 break; 77 } | 51 case CTRL_CT0: 52 thread_switch_control |= TSC_CELL_DEC_ENABLE_0; 53 break; 54 case CTRL_CT1: 55 thread_switch_control |= TSC_CELL_DEC_ENABLE_1; 56 break; 57 default: 58 printk(KERN_WARNING "%s: unknown configuration\n", 59 __FUNCTION__); 60 break; 61 } |
78 | |
79 mtspr(SPRN_TSC_CELL, thread_switch_control); 80 | 62 mtspr(SPRN_TSC_CELL, thread_switch_control); 63 |
81out: 82 spin_unlock_irq(&cbe_pervasive_lock); 83} 84 85static void cbe_idle(void) 86{ 87 unsigned long ctrl; 88 89 /* Why do we do that on every idle ? Couldn't that be done once for 90 * all or do we lose the state some way ? Also, the pmcr 91 * register setting, that can't be set once at boot ? We really want 92 * to move that away in order to implement a simple powersave | 64 /* 65 * go into low thread priority, medium priority will be 66 * restored for us after wake-up. |
93 */ | 67 */ |
94 cbe_enable_pause_zero(); | 68 HMT_low(); |
95 | 69 |
96 while (1) { 97 if (!need_resched()) { 98 local_irq_disable(); 99 while (!need_resched()) { 100 /* go into low thread priority */ 101 HMT_low(); 102 103 /* 104 * atomically disable thread execution 105 * and runlatch. 106 * External and Decrementer exceptions 107 * are still handled when the thread 108 * is disabled but now enter in 109 * cbe_system_reset_exception() 110 */ 111 ctrl = mfspr(SPRN_CTRLF); 112 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); 113 mtspr(SPRN_CTRLT, ctrl); 114 } 115 /* restore thread prio */ 116 HMT_medium(); 117 local_irq_enable(); 118 } 119 120 /* 121 * turn runlatch on again before scheduling the 122 * process we just woke up 123 */ 124 ppc64_runlatch_on(); 125 126 preempt_enable_no_resched(); 127 schedule(); 128 preempt_disable(); 129 } | 70 /* 71 * atomically disable thread execution and runlatch. 72 * External and Decrementer exceptions are still handled when the 73 * thread is disabled but now enter in cbe_system_reset_exception() 74 */ 75 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); 76 mtspr(SPRN_CTRLT, ctrl); |
130} 131 132static int cbe_system_reset_exception(struct pt_regs *regs) 133{ 134 switch (regs->msr & SRR1_WAKEMASK) { 135 case SRR1_WAKEEE: 136 do_IRQ(regs); 137 break; --- 15 unchanged lines hidden (view full) --- 153 return 0; 154 } 155 /* everything handled */ 156 return 1; 157} 158 159void __init cbe_pervasive_init(void) 160{ | 77} 78 79static int cbe_system_reset_exception(struct pt_regs *regs) 80{ 81 switch (regs->msr & SRR1_WAKEMASK) { 82 case SRR1_WAKEEE: 83 do_IRQ(regs); 84 break; --- 15 unchanged lines hidden (view full) --- 100 return 0; 101 } 102 /* everything handled */ 103 return 1; 104} 105 106void __init cbe_pervasive_init(void) 107{ |
108 int cpu; |
|
161 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) 162 return; 163 | 109 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) 110 return; 111 |
164 ppc_md.idle_loop = cbe_idle; | 112 for_each_possible_cpu(cpu) { 113 struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu); 114 if (!regs) 115 continue; 116 117 /* Enable Pause(0) control bit */ 118 out_be64(®s->pmcr, in_be64(®s->pmcr) | 119 CBE_PMD_PAUSE_ZERO_CONTROL); 120 } 121 122 ppc_md.power_save = cbe_power_save; |
165 ppc_md.system_reset_exception = cbe_system_reset_exception; 166} | 123 ppc_md.system_reset_exception = cbe_system_reset_exception; 124} |