cstate.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2005 Intel Corporation
  4. * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
  5. * - Added _PDC for SMP C-states on Intel CPUs
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/export.h>
  9. #include <linux/init.h>
  10. #include <linux/acpi.h>
  11. #include <linux/cpu.h>
  12. #include <linux/sched.h>
  13. #include <acpi/processor.h>
  14. #include <asm/mwait.h>
  15. #include <asm/special_insns.h>
  16. /*
  17. * Initialize bm_flags based on the CPU cache properties
  18. * On SMP it depends on cache configuration
  19. * - When cache is not shared among all CPUs, we flush cache
  20. * before entering C3.
  21. * - When cache is shared among all CPUs, we use bm_check
  22. * mechanism as in UP case
  23. *
  24. * This routine is called only after all the CPUs are online
  25. */
  26. void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
  27. unsigned int cpu)
  28. {
  29. struct cpuinfo_x86 *c = &cpu_data(cpu);
  30. flags->bm_check = 0;
  31. if (num_online_cpus() == 1)
  32. flags->bm_check = 1;
  33. else if (c->x86_vendor == X86_VENDOR_INTEL) {
  34. /*
  35. * Today all MP CPUs that support C3 share cache.
  36. * And caches should not be flushed by software while
  37. * entering C3 type state.
  38. */
  39. flags->bm_check = 1;
  40. }
  41. /*
  42. * On all recent Intel platforms, ARB_DISABLE is a nop.
  43. * So, set bm_control to zero to indicate that ARB_DISABLE
  44. * is not required while entering C3 type state on
  45. * P4, Core and beyond CPUs
  46. */
  47. if (c->x86_vendor == X86_VENDOR_INTEL &&
  48. (c->x86 > 0xf || (c->x86 == 6 && c->x86_model >= 0x0f)))
  49. flags->bm_control = 0;
  50. if (c->x86_vendor == X86_VENDOR_CENTAUR) {
  51. if (c->x86 > 6 || (c->x86 == 6 && c->x86_model == 0x0f &&
  52. c->x86_stepping >= 0x0e)) {
  53. /*
  54. * For all recent Centaur CPUs, the ucode will make sure that each
  55. * core can keep cache coherence with each other while entering C3
  56. * type state. So, set bm_check to 1 to indicate that the kernel
  57. * doesn't need to execute a cache flush operation (WBINVD) when
  58. * entering C3 type state.
  59. */
  60. flags->bm_check = 1;
  61. /*
  62. * For all recent Centaur platforms, ARB_DISABLE is a nop.
  63. * Set bm_control to zero to indicate that ARB_DISABLE is
  64. * not required while entering C3 type state.
  65. */
  66. flags->bm_control = 0;
  67. }
  68. }
  69. if (c->x86_vendor == X86_VENDOR_ZHAOXIN) {
  70. /*
  71. * All Zhaoxin CPUs that support C3 share cache.
  72. * And caches should not be flushed by software while
  73. * entering C3 type state.
  74. */
  75. flags->bm_check = 1;
  76. /*
  77. * On all recent Zhaoxin platforms, ARB_DISABLE is a nop.
  78. * So, set bm_control to zero to indicate that ARB_DISABLE
  79. * is not required while entering C3 type state.
  80. */
  81. flags->bm_control = 0;
  82. }
  83. if (c->x86_vendor == X86_VENDOR_AMD && c->x86 >= 0x17) {
  84. /*
  85. * For all AMD Zen or newer CPUs that support C3, caches
  86. * should not be flushed by software while entering C3
  87. * type state. Set bm->check to 1 so that kernel doesn't
  88. * need to execute cache flush operation.
  89. */
  90. flags->bm_check = 1;
  91. /*
  92. * In current AMD C state implementation ARB_DIS is no longer
  93. * used. So set bm_control to zero to indicate ARB_DIS is not
  94. * required while entering C3 type state.
  95. */
  96. flags->bm_control = 0;
  97. }
  98. }
  99. EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
  100. /* The code below handles cstate entry with monitor-mwait pair on Intel*/
  101. struct cstate_entry {
  102. struct {
  103. unsigned int eax;
  104. unsigned int ecx;
  105. } states[ACPI_PROCESSOR_MAX_POWER];
  106. };
  107. static struct cstate_entry __percpu *cpu_cstate_entry; /* per CPU ptr */
  108. static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
  109. #define NATIVE_CSTATE_BEYOND_HALT (2)
  110. static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
  111. {
  112. struct acpi_processor_cx *cx = _cx;
  113. long retval;
  114. unsigned int eax, ebx, ecx, edx;
  115. unsigned int edx_part;
  116. unsigned int cstate_type; /* C-state type and not ACPI C-state type */
  117. unsigned int num_cstate_subtype;
  118. cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
  119. /* Check whether this particular cx_type (in CST) is supported or not */
  120. cstate_type = (((cx->address >> MWAIT_SUBSTATE_SIZE) &
  121. MWAIT_CSTATE_MASK) + 1) & MWAIT_CSTATE_MASK;
  122. edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
  123. num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
  124. retval = 0;
  125. /* If the HW does not support any sub-states in this C-state */
  126. if (num_cstate_subtype == 0) {
  127. pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n",
  128. cx->address, edx_part);
  129. retval = -1;
  130. goto out;
  131. }
  132. /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */
  133. if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
  134. !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) {
  135. retval = -1;
  136. goto out;
  137. }
  138. if (!mwait_supported[cstate_type]) {
  139. mwait_supported[cstate_type] = 1;
  140. printk(KERN_DEBUG
  141. "Monitor-Mwait will be used to enter C-%d state\n",
  142. cx->type);
  143. }
  144. snprintf(cx->desc,
  145. ACPI_CX_DESC_LEN, "ACPI FFH MWAIT 0x%x",
  146. cx->address);
  147. out:
  148. return retval;
  149. }
  150. int acpi_processor_ffh_cstate_probe(unsigned int cpu,
  151. struct acpi_processor_cx *cx, struct acpi_power_register *reg)
  152. {
  153. struct cstate_entry *percpu_entry;
  154. struct cpuinfo_x86 *c = &cpu_data(cpu);
  155. long retval;
  156. if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF)
  157. return -1;
  158. if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
  159. return -1;
  160. percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
  161. percpu_entry->states[cx->index].eax = 0;
  162. percpu_entry->states[cx->index].ecx = 0;
  163. /* Make sure we are running on right CPU */
  164. retval = call_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx,
  165. false);
  166. if (retval == 0) {
  167. /* Use the hint in CST */
  168. percpu_entry->states[cx->index].eax = cx->address;
  169. percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
  170. }
  171. /*
  172. * For _CST FFH on Intel, if GAS.access_size bit 1 is cleared,
  173. * then we should skip checking BM_STS for this C-state.
  174. * ref: "Intel Processor Vendor-Specific ACPI Interface Specification"
  175. */
  176. if ((c->x86_vendor == X86_VENDOR_INTEL) && !(reg->access_size & 0x2))
  177. cx->bm_sts_skip = 1;
  178. return retval;
  179. }
  180. EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
  181. void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
  182. {
  183. unsigned int cpu = smp_processor_id();
  184. struct cstate_entry *percpu_entry;
  185. percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
  186. mwait_idle_with_hints(percpu_entry->states[cx->index].eax,
  187. percpu_entry->states[cx->index].ecx);
  188. }
  189. EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter);
  190. static int __init ffh_cstate_init(void)
  191. {
  192. struct cpuinfo_x86 *c = &boot_cpu_data;
  193. if (c->x86_vendor != X86_VENDOR_INTEL &&
  194. c->x86_vendor != X86_VENDOR_AMD &&
  195. c->x86_vendor != X86_VENDOR_HYGON)
  196. return -1;
  197. cpu_cstate_entry = alloc_percpu(struct cstate_entry);
  198. return 0;
  199. }
  200. static void __exit ffh_cstate_exit(void)
  201. {
  202. free_percpu(cpu_cstate_entry);
  203. cpu_cstate_entry = NULL;
  204. }
  205. arch_initcall(ffh_cstate_init);
  206. __exitcall(ffh_cstate_exit);