Sorry. please ignore this email. RP On Mon, Nov 28, 2016 at 11:08:59PM -0800, linux...@us.ibm.com wrote: > From: Shreyas B. Prabhu <shre...@linux.vnet.ibm.com> > > POWER ISA v3 defines a new idle processor core mechanism. In summary, > a) new instruction named stop is added. > b) new per thread SPR named PSSCR is added which controls the behavior > of stop instruction. > > Supported idle states and value to be written to PSSCR register to enter > any idle state is exposed via ibm,cpu-idle-state-names and > ibm,cpu-idle-state-psscr respectively. To enter an idle state, > platform provided power_stop() needs to be invoked with the appropriate > PSSCR value. > > This patch adds support for this new mechanism in cpuidle powernv driver. > > Cc: Rafael J. Wysocki <rafael.j.wyso...@intel.com> > Cc: Daniel Lezcano <daniel.lezc...@linaro.org> > Cc: Rob Herring <robh...@kernel.org> > Cc: Lorenzo Pieralisi <lorenzo.pieral...@arm.com> > Cc: linux...@vger.kernel.org > Cc: Michael Ellerman <m...@ellerman.id.au> > Cc: Paul Mackerras <pau...@ozlabs.org> > Cc: linuxppc-dev@lists.ozlabs.org > Reviewed-by: Gautham R. Shenoy <e...@linux.vnet.ibm.com> > Signed-off-by: Shreyas B. Prabhu <shre...@linux.vnet.ibm.com> > Signed-off-by: Michael Ellerman <m...@ellerman.id.au> > Signed-off-by: Ram Pai <linux...@us.ibm.com> > (cherry-picked from 3005c597ba46480b42e1fea3512c408f1830b816) > --- > drivers/cpuidle/cpuidle-powernv.c | 61 > +++++++++++++++++++++++++++++++++++++ > 1 files changed, 61 insertions(+), 0 deletions(-) > > diff --git a/drivers/cpuidle/cpuidle-powernv.c > b/drivers/cpuidle/cpuidle-powernv.c > index bdf8dae..cab1b4b 100644 > --- a/drivers/cpuidle/cpuidle-powernv.c > +++ b/drivers/cpuidle/cpuidle-powernv.c > @@ -20,6 +20,8 @@ > #include <asm/opal.h> > #include <asm/runlatch.h> > > +#define POWERNV_THRESHOLD_LATENCY_NS 200000 > + > struct cpuidle_driver powernv_idle_driver = { > .name = "powernv_idle", > .owner = THIS_MODULE, > @@ -27,6 +29,9 @@ struct cpuidle_driver powernv_idle_driver = { > > static int max_idle_state; > static struct cpuidle_state *cpuidle_state_table; > + > +static u64 stop_psscr_table[CPUIDLE_STATE_MAX]; > + > static u64 snooze_timeout; > static bool snooze_timeout_en; > > @@ -91,6 +96,17 @@ static int fastsleep_loop(struct cpuidle_device *dev, > return index; > } > #endif > + > +static int stop_loop(struct cpuidle_device *dev, > + struct cpuidle_driver *drv, > + int index) > +{ > + ppc64_runlatch_off(); > + power9_idle_stop(stop_psscr_table[index]); > + ppc64_runlatch_on(); > + return index; > +} > + > /* > * States for dedicated partition case. > */ > @@ -170,6 +186,8 @@ static int powernv_add_idle_states(void) > u32 latency_ns[CPUIDLE_STATE_MAX]; > u32 residency_ns[CPUIDLE_STATE_MAX]; > u32 flags[CPUIDLE_STATE_MAX]; > + u64 psscr_val[CPUIDLE_STATE_MAX]; > + const char *names[CPUIDLE_STATE_MAX]; > int i, rc; > > /* Currently we have snooze statically defined */ > @@ -208,12 +226,35 @@ static int powernv_add_idle_states(void) > pr_warn("cpuidle-powernv: missing > ibm,cpu-idle-state-latencies-ns in DT\n"); > goto out; > } > + if (of_property_read_string_array(power_mgt, > + "ibm,cpu-idle-state-names", names, dt_idle_states) < 0) { > + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-names in > DT\n"); > + goto out; > + } > + > + /* > + * If the idle states use stop instruction, probe for psscr values > + * which are necessary to specify required stop level. > + */ > + if (flags[0] & (OPAL_PM_STOP_INST_FAST | OPAL_PM_STOP_INST_DEEP)) > + if (of_property_read_u64_array(power_mgt, > + "ibm,cpu-idle-state-psscr", psscr_val, dt_idle_states)) { > + pr_warn("cpuidle-powernv: missing > ibm,cpu-idle-states-psscr in DT\n"); > + goto out; > + } > > rc = of_property_read_u32_array(power_mgt, > "ibm,cpu-idle-state-residency-ns", residency_ns, > dt_idle_states); > > > for (i = 0; i < dt_idle_states; i++) { > + /* > + * If an idle state has exit latency beyond > + * POWERNV_THRESHOLD_LATENCY_NS then don't use it > + * in cpu-idle. > + */ > + if (latency_ns[i] > POWERNV_THRESHOLD_LATENCY_NS) > + continue; > > /* > * Cpuidle accepts exit_latency and target_residency in us. > @@ -226,6 +267,16 @@ static int powernv_add_idle_states(void) > powernv_states[nr_idle_states].flags = > CPUIDLE_FLAG_TIME_VALID; > powernv_states[nr_idle_states].target_residency = 100; > powernv_states[nr_idle_states].enter = nap_loop; > + } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) && > + !(flags[i] & OPAL_PM_TIMEBASE_STOP)) { > + strncpy(powernv_states[nr_idle_states].name, > + names[i], CPUIDLE_NAME_LEN); > + strncpy(powernv_states[nr_idle_states].desc, > + names[i], CPUIDLE_NAME_LEN); > + powernv_states[nr_idle_states].flags = 0; > + > + powernv_states[nr_idle_states].enter = stop_loop; > + stop_psscr_table[nr_idle_states] = psscr_val[i]; > } > > /* > @@ -242,6 +293,16 @@ static int powernv_add_idle_states(void) > CPUIDLE_FLAG_TIME_VALID | > CPUIDLE_FLAG_TIMER_STOP; > powernv_states[nr_idle_states].target_residency = > 300000; > powernv_states[nr_idle_states].enter = fastsleep_loop; > + } else if ((flags[i] & OPAL_PM_STOP_INST_DEEP) && > + (flags[i] & OPAL_PM_TIMEBASE_STOP)) { > + strncpy(powernv_states[nr_idle_states].name, > + names[i], CPUIDLE_NAME_LEN); > + strncpy(powernv_states[nr_idle_states].desc, > + names[i], CPUIDLE_NAME_LEN); > + > + powernv_states[nr_idle_states].flags = > CPUIDLE_FLAG_TIMER_STOP; > + powernv_states[nr_idle_states].enter = stop_loop; > + stop_psscr_table[nr_idle_states] = psscr_val[i]; > } > #endif > powernv_states[nr_idle_states].exit_latency = > -- > 1.7.1
-- Ram Pai