cpuidle-powernv.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * cpuidle-powernv - idle state cpuidle driver.
  3. * Adapted from drivers/cpuidle/cpuidle-pseries
  4. *
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9. #include <linux/moduleparam.h>
  10. #include <linux/cpuidle.h>
  11. #include <linux/cpu.h>
  12. #include <linux/notifier.h>
  13. #include <linux/clockchips.h>
  14. #include <linux/of.h>
  15. #include <linux/slab.h>
  16. #include <asm/machdep.h>
  17. #include <asm/firmware.h>
  18. #include <asm/opal.h>
  19. #include <asm/runlatch.h>
  20. #define POWERNV_THRESHOLD_LATENCY_NS 200000
  21. static struct cpuidle_driver powernv_idle_driver = {
  22. .name = "powernv_idle",
  23. .owner = THIS_MODULE,
  24. };
  25. static int max_idle_state;
  26. static struct cpuidle_state *cpuidle_state_table;
  27. static u64 stop_psscr_table[CPUIDLE_STATE_MAX];
  28. static u64 snooze_timeout;
  29. static bool snooze_timeout_en;
  30. static int snooze_loop(struct cpuidle_device *dev,
  31. struct cpuidle_driver *drv,
  32. int index)
  33. {
  34. u64 snooze_exit_time;
  35. local_irq_enable();
  36. set_thread_flag(TIF_POLLING_NRFLAG);
  37. snooze_exit_time = get_tb() + snooze_timeout;
  38. ppc64_runlatch_off();
  39. while (!need_resched()) {
  40. HMT_low();
  41. HMT_very_low();
  42. if (snooze_timeout_en && get_tb() > snooze_exit_time)
  43. break;
  44. }
  45. HMT_medium();
  46. ppc64_runlatch_on();
  47. clear_thread_flag(TIF_POLLING_NRFLAG);
  48. smp_mb();
  49. return index;
  50. }
  51. static int nap_loop(struct cpuidle_device *dev,
  52. struct cpuidle_driver *drv,
  53. int index)
  54. {
  55. ppc64_runlatch_off();
  56. power7_idle();
  57. ppc64_runlatch_on();
  58. return index;
  59. }
  60. /* Register for fastsleep only in oneshot mode of broadcast */
  61. #ifdef CONFIG_TICK_ONESHOT
  62. static int fastsleep_loop(struct cpuidle_device *dev,
  63. struct cpuidle_driver *drv,
  64. int index)
  65. {
  66. unsigned long old_lpcr = mfspr(SPRN_LPCR);
  67. unsigned long new_lpcr;
  68. if (unlikely(system_state < SYSTEM_RUNNING))
  69. return index;
  70. new_lpcr = old_lpcr;
  71. /* Do not exit powersave upon decrementer as we've setup the timer
  72. * offload.
  73. */
  74. new_lpcr &= ~LPCR_PECE1;
  75. mtspr(SPRN_LPCR, new_lpcr);
  76. power7_sleep();
  77. mtspr(SPRN_LPCR, old_lpcr);
  78. return index;
  79. }
  80. #endif
  81. static int stop_loop(struct cpuidle_device *dev,
  82. struct cpuidle_driver *drv,
  83. int index)
  84. {
  85. ppc64_runlatch_off();
  86. power9_idle_stop(stop_psscr_table[index]);
  87. ppc64_runlatch_on();
  88. return index;
  89. }
  90. /*
  91. * States for dedicated partition case.
  92. */
  93. static struct cpuidle_state powernv_states[CPUIDLE_STATE_MAX] = {
  94. { /* Snooze */
  95. .name = "snooze",
  96. .desc = "snooze",
  97. .exit_latency = 0,
  98. .target_residency = 0,
  99. .enter = snooze_loop },
  100. };
  101. static int powernv_cpuidle_cpu_online(unsigned int cpu)
  102. {
  103. struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
  104. if (dev && cpuidle_get_driver()) {
  105. cpuidle_pause_and_lock();
  106. cpuidle_enable_device(dev);
  107. cpuidle_resume_and_unlock();
  108. }
  109. return 0;
  110. }
  111. static int powernv_cpuidle_cpu_dead(unsigned int cpu)
  112. {
  113. struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
  114. if (dev && cpuidle_get_driver()) {
  115. cpuidle_pause_and_lock();
  116. cpuidle_disable_device(dev);
  117. cpuidle_resume_and_unlock();
  118. }
  119. return 0;
  120. }
  121. /*
  122. * powernv_cpuidle_driver_init()
  123. */
  124. static int powernv_cpuidle_driver_init(void)
  125. {
  126. int idle_state;
  127. struct cpuidle_driver *drv = &powernv_idle_driver;
  128. drv->state_count = 0;
  129. for (idle_state = 0; idle_state < max_idle_state; ++idle_state) {
  130. /* Is the state not enabled? */
  131. if (cpuidle_state_table[idle_state].enter == NULL)
  132. continue;
  133. drv->states[drv->state_count] = /* structure copy */
  134. cpuidle_state_table[idle_state];
  135. drv->state_count += 1;
  136. }
  137. return 0;
  138. }
  139. static int powernv_add_idle_states(void)
  140. {
  141. struct device_node *power_mgt;
  142. int nr_idle_states = 1; /* Snooze */
  143. int dt_idle_states;
  144. u32 latency_ns[CPUIDLE_STATE_MAX];
  145. u32 residency_ns[CPUIDLE_STATE_MAX];
  146. u32 flags[CPUIDLE_STATE_MAX];
  147. u64 psscr_val[CPUIDLE_STATE_MAX];
  148. const char *names[CPUIDLE_STATE_MAX];
  149. int i, rc;
  150. /* Currently we have snooze statically defined */
  151. power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
  152. if (!power_mgt) {
  153. pr_warn("opal: PowerMgmt Node not found\n");
  154. goto out;
  155. }
  156. /* Read values of any property to determine the num of idle states */
  157. dt_idle_states = of_property_count_u32_elems(power_mgt, "ibm,cpu-idle-state-flags");
  158. if (dt_idle_states < 0) {
  159. pr_warn("cpuidle-powernv: no idle states found in the DT\n");
  160. goto out;
  161. }
  162. /*
  163. * Since snooze is used as first idle state, max idle states allowed is
  164. * CPUIDLE_STATE_MAX -1
  165. */
  166. if (dt_idle_states > CPUIDLE_STATE_MAX - 1) {
  167. pr_warn("cpuidle-powernv: discovered idle states more than allowed");
  168. dt_idle_states = CPUIDLE_STATE_MAX - 1;
  169. }
  170. if (of_property_read_u32_array(power_mgt,
  171. "ibm,cpu-idle-state-flags", flags, dt_idle_states)) {
  172. pr_warn("cpuidle-powernv : missing ibm,cpu-idle-state-flags in DT\n");
  173. goto out;
  174. }
  175. if (of_property_read_u32_array(power_mgt,
  176. "ibm,cpu-idle-state-latencies-ns", latency_ns,
  177. dt_idle_states)) {
  178. pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n");
  179. goto out;
  180. }
  181. if (of_property_read_string_array(power_mgt,
  182. "ibm,cpu-idle-state-names", names, dt_idle_states) < 0) {
  183. pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-names in DT\n");
  184. goto out;
  185. }
  186. /*
  187. * If the idle states use stop instruction, probe for psscr values
  188. * which are necessary to specify required stop level.
  189. */
  190. if (flags[0] & (OPAL_PM_STOP_INST_FAST | OPAL_PM_STOP_INST_DEEP))
  191. if (of_property_read_u64_array(power_mgt,
  192. "ibm,cpu-idle-state-psscr", psscr_val, dt_idle_states)) {
  193. pr_warn("cpuidle-powernv: missing ibm,cpu-idle-states-psscr in DT\n");
  194. goto out;
  195. }
  196. rc = of_property_read_u32_array(power_mgt,
  197. "ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states);
  198. for (i = 0; i < dt_idle_states; i++) {
  199. /*
  200. * If an idle state has exit latency beyond
  201. * POWERNV_THRESHOLD_LATENCY_NS then don't use it
  202. * in cpu-idle.
  203. */
  204. if (latency_ns[i] > POWERNV_THRESHOLD_LATENCY_NS)
  205. continue;
  206. /*
  207. * Cpuidle accepts exit_latency and target_residency in us.
  208. * Use default target_residency values if f/w does not expose it.
  209. */
  210. if (flags[i] & OPAL_PM_NAP_ENABLED) {
  211. /* Add NAP state */
  212. strcpy(powernv_states[nr_idle_states].name, "Nap");
  213. strcpy(powernv_states[nr_idle_states].desc, "Nap");
  214. powernv_states[nr_idle_states].flags = 0;
  215. powernv_states[nr_idle_states].target_residency = 100;
  216. powernv_states[nr_idle_states].enter = nap_loop;
  217. } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) &&
  218. !(flags[i] & OPAL_PM_TIMEBASE_STOP)) {
  219. strncpy(powernv_states[nr_idle_states].name,
  220. names[i], CPUIDLE_NAME_LEN);
  221. strncpy(powernv_states[nr_idle_states].desc,
  222. names[i], CPUIDLE_NAME_LEN);
  223. powernv_states[nr_idle_states].flags = 0;
  224. powernv_states[nr_idle_states].enter = stop_loop;
  225. stop_psscr_table[nr_idle_states] = psscr_val[i];
  226. }
  227. /*
  228. * All cpuidle states with CPUIDLE_FLAG_TIMER_STOP set must come
  229. * within this config dependency check.
  230. */
  231. #ifdef CONFIG_TICK_ONESHOT
  232. if (flags[i] & OPAL_PM_SLEEP_ENABLED ||
  233. flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) {
  234. /* Add FASTSLEEP state */
  235. strcpy(powernv_states[nr_idle_states].name, "FastSleep");
  236. strcpy(powernv_states[nr_idle_states].desc, "FastSleep");
  237. powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP;
  238. powernv_states[nr_idle_states].target_residency = 300000;
  239. powernv_states[nr_idle_states].enter = fastsleep_loop;
  240. } else if ((flags[i] & OPAL_PM_STOP_INST_DEEP) &&
  241. (flags[i] & OPAL_PM_TIMEBASE_STOP)) {
  242. strncpy(powernv_states[nr_idle_states].name,
  243. names[i], CPUIDLE_NAME_LEN);
  244. strncpy(powernv_states[nr_idle_states].desc,
  245. names[i], CPUIDLE_NAME_LEN);
  246. powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP;
  247. powernv_states[nr_idle_states].enter = stop_loop;
  248. stop_psscr_table[nr_idle_states] = psscr_val[i];
  249. }
  250. #endif
  251. powernv_states[nr_idle_states].exit_latency =
  252. ((unsigned int)latency_ns[i]) / 1000;
  253. if (!rc) {
  254. powernv_states[nr_idle_states].target_residency =
  255. ((unsigned int)residency_ns[i]) / 1000;
  256. }
  257. nr_idle_states++;
  258. }
  259. out:
  260. return nr_idle_states;
  261. }
  262. /*
  263. * powernv_idle_probe()
  264. * Choose state table for shared versus dedicated partition
  265. */
  266. static int powernv_idle_probe(void)
  267. {
  268. if (cpuidle_disable != IDLE_NO_OVERRIDE)
  269. return -ENODEV;
  270. if (firmware_has_feature(FW_FEATURE_OPAL)) {
  271. cpuidle_state_table = powernv_states;
  272. /* Device tree can indicate more idle states */
  273. max_idle_state = powernv_add_idle_states();
  274. if (max_idle_state > 1) {
  275. snooze_timeout_en = true;
  276. snooze_timeout = powernv_states[1].target_residency *
  277. tb_ticks_per_usec;
  278. }
  279. } else
  280. return -ENODEV;
  281. return 0;
  282. }
  283. static int __init powernv_processor_idle_init(void)
  284. {
  285. int retval;
  286. retval = powernv_idle_probe();
  287. if (retval)
  288. return retval;
  289. powernv_cpuidle_driver_init();
  290. retval = cpuidle_register(&powernv_idle_driver, NULL);
  291. if (retval) {
  292. printk(KERN_DEBUG "Registration of powernv driver failed.\n");
  293. return retval;
  294. }
  295. retval = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
  296. "cpuidle/powernv:online",
  297. powernv_cpuidle_cpu_online, NULL);
  298. WARN_ON(retval < 0);
  299. retval = cpuhp_setup_state_nocalls(CPUHP_CPUIDLE_DEAD,
  300. "cpuidle/powernv:dead", NULL,
  301. powernv_cpuidle_cpu_dead);
  302. WARN_ON(retval < 0);
  303. printk(KERN_DEBUG "powernv_idle_driver registered\n");
  304. return 0;
  305. }
  306. device_initcall(powernv_processor_idle_init);