0011-s0ix-amd.patch 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. From 3a7422993f0471af14c1a92493659fe2196e1619 Mon Sep 17 00:00:00 2001
  2. From: Mario Limonciello <mario.limonciello@amd.com>
  3. Date: Wed, 12 May 2021 17:15:14 -0500
  4. Subject: [PATCH] ACPI: processor idle: Fix up C-state latency if not ordered
  5. Generally, the C-state latency is provided by the _CST method or
  6. FADT, but some OEM platforms using AMD Picasso, Renoir, Van Gogh,
  7. and Cezanne set the C2 latency greater than C3's which causes the
  8. C2 state to be skipped.
  9. That will block the core entering PC6, which prevents S0ix working
  10. properly on Linux systems.
  11. In other operating systems, the latency values are not validated and
  12. this does not cause problems by skipping states.
  13. To avoid this issue on Linux, detect when latencies are not an
  14. arithmetic progression and sort them.
  15. Link: https://gitlab.freedesktop.org/agd5f/linux/-/commit/026d186e4592c1ee9c1cb44295912d0294508725
  16. Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1230#note_712174
  17. Suggested-by: Prike Liang <Prike.Liang@amd.com>
  18. Suggested-by: Alex Deucher <alexander.deucher@amd.com>
  19. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
  20. [ rjw: Subject and changelog edits ]
  21. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  22. Patchset: s0ix-amd
  23. ---
  24. drivers/acpi/processor_idle.c | 40 +++++++++++++++++++++++++++++++++++
  25. 1 file changed, 40 insertions(+)
  26. diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
  27. index 4e2d76b8b697..6790df5a2462 100644
  28. --- a/drivers/acpi/processor_idle.c
  29. +++ b/drivers/acpi/processor_idle.c
  30. @@ -16,6 +16,7 @@
  31. #include <linux/acpi.h>
  32. #include <linux/dmi.h>
  33. #include <linux/sched.h> /* need_resched() */
  34. +#include <linux/sort.h>
  35. #include <linux/tick.h>
  36. #include <linux/cpuidle.h>
  37. #include <linux/cpu.h>
  38. @@ -388,10 +389,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
  39. return;
  40. }
  41. +static int acpi_cst_latency_cmp(const void *a, const void *b)
  42. +{
  43. + const struct acpi_processor_cx *x = a, *y = b;
  44. +
  45. + if (!(x->valid && y->valid))
  46. + return 0;
  47. + if (x->latency > y->latency)
  48. + return 1;
  49. + if (x->latency < y->latency)
  50. + return -1;
  51. + return 0;
  52. +}
  53. +static void acpi_cst_latency_swap(void *a, void *b, int n)
  54. +{
  55. + struct acpi_processor_cx *x = a, *y = b;
  56. + u32 tmp;
  57. +
  58. + if (!(x->valid && y->valid))
  59. + return;
  60. + tmp = x->latency;
  61. + x->latency = y->latency;
  62. + y->latency = tmp;
  63. +}
  64. +
  65. static int acpi_processor_power_verify(struct acpi_processor *pr)
  66. {
  67. unsigned int i;
  68. unsigned int working = 0;
  69. + unsigned int last_latency = 0;
  70. + unsigned int last_type = 0;
  71. + bool buggy_latency = false;
  72. pr->power.timer_broadcast_on_state = INT_MAX;
  73. @@ -415,12 +443,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
  74. }
  75. if (!cx->valid)
  76. continue;
  77. + if (cx->type >= last_type && cx->latency < last_latency)
  78. + buggy_latency = true;
  79. + last_latency = cx->latency;
  80. + last_type = cx->type;
  81. lapic_timer_check_state(i, pr, cx);
  82. tsc_check_state(cx->type);
  83. working++;
  84. }
  85. + if (buggy_latency) {
  86. + pr_notice("FW issue: working around C-state latencies out of order\n");
  87. + sort(&pr->power.states[1], max_cstate,
  88. + sizeof(struct acpi_processor_cx),
  89. + acpi_cst_latency_cmp,
  90. + acpi_cst_latency_swap);
  91. + }
  92. +
  93. lapic_timer_propagate_broadcast(pr);
  94. return (working);
  95. --
  96. 2.32.0
  97. From 07ee2c4f1c48d74d7971dd017df43edd95582898 Mon Sep 17 00:00:00 2001
  98. From: Marcin Bachry <hegel666@gmail.com>
  99. Date: Tue, 16 Mar 2021 15:28:51 -0400
  100. Subject: [PATCH] PCI: quirks: Quirk PCI d3hot delay for AMD xhci
  101. Renoir needs a similar delay.
  102. Signed-off-by: Marcin Bachry <hegel666@gmail.com>
  103. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  104. Patchset: s0ix-amd
  105. ---
  106. drivers/pci/quirks.c | 3 +++
  107. 1 file changed, 3 insertions(+)
  108. diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
  109. index 7bf76bca888d..8e70605666d4 100644
  110. --- a/drivers/pci/quirks.c
  111. +++ b/drivers/pci/quirks.c
  112. @@ -1904,6 +1904,9 @@ static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev)
  113. }
  114. DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot);
  115. DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot);
  116. +/* Renoir XHCI requires longer delay when transitioning from D0 to
  117. + * D3hot */
  118. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1639, quirk_ryzen_xhci_d3hot);
  119. #ifdef CONFIG_X86_IO_APIC
  120. static int dmi_disable_ioapicreroute(const struct dmi_system_id *d)
  121. --
  122. 2.32.0
  123. From 5dd9cee2331182d21222220425e1f4d354f4342f Mon Sep 17 00:00:00 2001
  124. From: Mario Limonciello <mario.limonciello@amd.com>
  125. Date: Fri, 28 May 2021 11:02:34 -0500
  126. Subject: [PATCH] nvme-pci: look for StorageD3Enable on companion ACPI device
  127. instead
  128. The documentation around the StorageD3Enable property hints that it
  129. should be made on the PCI device. This is where newer AMD systems set
  130. the property and it's required for S0i3 support.
  131. So rather than look for nodes of the root port only present on Intel
  132. systems, switch to the companion ACPI device for all systems.
  133. David Box from Intel indicated this should work on Intel as well.
  134. Link: https://lore.kernel.org/linux-nvme/YK6gmAWqaRmvpJXb@google.com/T/#m900552229fa455867ee29c33b854845fce80ba70
  135. Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
  136. Fixes: df4f9bc4fb9c ("nvme-pci: add support for ACPI StorageD3Enable property")
  137. Suggested-by: Liang Prike <Prike.Liang@amd.com>
  138. Acked-by: Raul E Rangel <rrangel@chromium.org>
  139. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
  140. Reviewed-by: David E. Box <david.e.box@linux.intel.com>
  141. Signed-off-by: Christoph Hellwig <hch@lst.de>
  142. Patchset: s0ix-amd
  143. ---
  144. drivers/nvme/host/pci.c | 24 +-----------------------
  145. 1 file changed, 1 insertion(+), 23 deletions(-)
  146. diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
  147. index c92a15c3fbc5..60c1c83e03fa 100644
  148. --- a/drivers/nvme/host/pci.c
  149. +++ b/drivers/nvme/host/pci.c
  150. @@ -2834,10 +2834,7 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
  151. #ifdef CONFIG_ACPI
  152. static bool nvme_acpi_storage_d3(struct pci_dev *dev)
  153. {
  154. - struct acpi_device *adev;
  155. - struct pci_dev *root;
  156. - acpi_handle handle;
  157. - acpi_status status;
  158. + struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
  159. u8 val;
  160. /*
  161. @@ -2845,28 +2842,9 @@ static bool nvme_acpi_storage_d3(struct pci_dev *dev)
  162. * must use D3 to support deep platform power savings during
  163. * suspend-to-idle.
  164. */
  165. - root = pcie_find_root_port(dev);
  166. - if (!root)
  167. - return false;
  168. - adev = ACPI_COMPANION(&root->dev);
  169. if (!adev)
  170. return false;
  171. -
  172. - /*
  173. - * The property is defined in the PXSX device for South complex ports
  174. - * and in the PEGP device for North complex ports.
  175. - */
  176. - status = acpi_get_handle(adev->handle, "PXSX", &handle);
  177. - if (ACPI_FAILURE(status)) {
  178. - status = acpi_get_handle(adev->handle, "PEGP", &handle);
  179. - if (ACPI_FAILURE(status))
  180. - return false;
  181. - }
  182. -
  183. - if (acpi_bus_get_device(handle, &adev))
  184. - return false;
  185. -
  186. if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
  187. &val))
  188. return false;
  189. --
  190. 2.32.0
  191. From c5039db994a0f6de250b3039bd94d2e610f66ab7 Mon Sep 17 00:00:00 2001
  192. From: Mario Limonciello <mario.limonciello@amd.com>
  193. Date: Wed, 9 Jun 2021 13:40:17 -0500
  194. Subject: [PATCH] ACPI: Check StorageD3Enable _DSD property in ACPI code
  195. Although first implemented for NVME, this check may be usable by
  196. other drivers as well. Microsoft's specification explicitly mentions
  197. that is may be usable by SATA and AHCI devices. Google also indicates
  198. that they have used this with SDHCI in a downstream kernel tree that
  199. a user can plug a storage device into.
  200. Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
  201. Suggested-by: Keith Busch <kbusch@kernel.org>
  202. CC: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
  203. CC: Alexander Deucher <Alexander.Deucher@amd.com>
  204. CC: Rafael J. Wysocki <rjw@rjwysocki.net>
  205. CC: Prike Liang <prike.liang@amd.com>
  206. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
  207. Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  208. Signed-off-by: Christoph Hellwig <hch@lst.de>
  209. Patchset: s0ix-amd
  210. ---
  211. drivers/acpi/device_pm.c | 29 +++++++++++++++++++++++++++++
  212. drivers/nvme/host/pci.c | 28 +---------------------------
  213. include/linux/acpi.h | 5 +++++
  214. 3 files changed, 35 insertions(+), 27 deletions(-)
  215. diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
  216. index 58876248b192..1e278785c7db 100644
  217. --- a/drivers/acpi/device_pm.c
  218. +++ b/drivers/acpi/device_pm.c
  219. @@ -1337,4 +1337,33 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
  220. return 1;
  221. }
  222. EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
  223. +
  224. +/**
  225. + * acpi_storage_d3 - Check if D3 should be used in the suspend path
  226. + * @dev: Device to check
  227. + *
  228. + * Return %true if the platform firmware wants @dev to be programmed
  229. + * into D3hot or D3cold (if supported) in the suspend path, or %false
  230. + * when there is no specific preference. On some platforms, if this
  231. + * hint is ignored, @dev may remain unresponsive after suspending the
  232. + * platform as a whole.
  233. + *
  234. + * Although the property has storage in the name it actually is
  235. + * applied to the PCIe slot and plugging in a non-storage device the
  236. + * same platform restrictions will likely apply.
  237. + */
  238. +bool acpi_storage_d3(struct device *dev)
  239. +{
  240. + struct acpi_device *adev = ACPI_COMPANION(dev);
  241. + u8 val;
  242. +
  243. + if (!adev)
  244. + return false;
  245. + if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
  246. + &val))
  247. + return false;
  248. + return val == 1;
  249. +}
  250. +EXPORT_SYMBOL_GPL(acpi_storage_d3);
  251. +
  252. #endif /* CONFIG_PM */
  253. diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
  254. index 60c1c83e03fa..8593161d4da0 100644
  255. --- a/drivers/nvme/host/pci.c
  256. +++ b/drivers/nvme/host/pci.c
  257. @@ -2831,32 +2831,6 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
  258. return 0;
  259. }
  260. -#ifdef CONFIG_ACPI
  261. -static bool nvme_acpi_storage_d3(struct pci_dev *dev)
  262. -{
  263. - struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
  264. - u8 val;
  265. -
  266. - /*
  267. - * Look for _DSD property specifying that the storage device on the port
  268. - * must use D3 to support deep platform power savings during
  269. - * suspend-to-idle.
  270. - */
  271. -
  272. - if (!adev)
  273. - return false;
  274. - if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
  275. - &val))
  276. - return false;
  277. - return val == 1;
  278. -}
  279. -#else
  280. -static inline bool nvme_acpi_storage_d3(struct pci_dev *dev)
  281. -{
  282. - return false;
  283. -}
  284. -#endif /* CONFIG_ACPI */
  285. -
  286. static void nvme_async_probe(void *data, async_cookie_t cookie)
  287. {
  288. struct nvme_dev *dev = data;
  289. @@ -2906,7 +2880,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  290. quirks |= check_vendor_combination_bug(pdev);
  291. - if (!noacpi && nvme_acpi_storage_d3(pdev)) {
  292. + if (!noacpi && acpi_storage_d3(&pdev->dev)) {
  293. /*
  294. * Some systems use a bios work around to ask for D3 on
  295. * platforms that support kernel managed suspend.
  296. diff --git a/include/linux/acpi.h b/include/linux/acpi.h
  297. index 07a0044397e1..1997fc6589b9 100644
  298. --- a/include/linux/acpi.h
  299. +++ b/include/linux/acpi.h
  300. @@ -1001,6 +1001,7 @@ int acpi_dev_resume(struct device *dev);
  301. int acpi_subsys_runtime_suspend(struct device *dev);
  302. int acpi_subsys_runtime_resume(struct device *dev);
  303. int acpi_dev_pm_attach(struct device *dev, bool power_on);
  304. +bool acpi_storage_d3(struct device *dev);
  305. #else
  306. static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
  307. static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
  308. @@ -1008,6 +1009,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
  309. {
  310. return 0;
  311. }
  312. +static inline bool acpi_storage_d3(struct device *dev)
  313. +{
  314. + return false;
  315. +}
  316. #endif
  317. #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
  318. --
  319. 2.32.0
  320. From f130be1f855c90db03b7926a87a3f53ebcfb9e81 Mon Sep 17 00:00:00 2001
  321. From: Mario Limonciello <mario.limonciello@amd.com>
  322. Date: Wed, 9 Jun 2021 13:40:18 -0500
  323. Subject: [PATCH] ACPI: Add quirks for AMD Renoir/Lucienne CPUs to force the D3
  324. hint
  325. AMD systems from Renoir and Lucienne require that the NVME controller
  326. is put into D3 over a Modern Standby / suspend-to-idle
  327. cycle. This is "typically" accomplished using the `StorageD3Enable`
  328. property in the _DSD, but this property was introduced after many
  329. of these systems launched and most OEM systems don't have it in
  330. their BIOS.
  331. On AMD Renoir without these drives going into D3 over suspend-to-idle
  332. the resume will fail with the NVME controller being reset and a trace
  333. like this in the kernel logs:
  334. ```
  335. [ 83.556118] nvme nvme0: I/O 161 QID 2 timeout, aborting
  336. [ 83.556178] nvme nvme0: I/O 162 QID 2 timeout, aborting
  337. [ 83.556187] nvme nvme0: I/O 163 QID 2 timeout, aborting
  338. [ 83.556196] nvme nvme0: I/O 164 QID 2 timeout, aborting
  339. [ 95.332114] nvme nvme0: I/O 25 QID 0 timeout, reset controller
  340. [ 95.332843] nvme nvme0: Abort status: 0x371
  341. [ 95.332852] nvme nvme0: Abort status: 0x371
  342. [ 95.332856] nvme nvme0: Abort status: 0x371
  343. [ 95.332859] nvme nvme0: Abort status: 0x371
  344. [ 95.332909] PM: dpm_run_callback(): pci_pm_resume+0x0/0xe0 returns -16
  345. [ 95.332936] nvme 0000:03:00.0: PM: failed to resume async: error -16
  346. ```
  347. The Microsoft documentation for StorageD3Enable mentioned that Windows has
  348. a hardcoded allowlist for D3 support, which was used for these platforms.
  349. Introduce quirks to hardcode them for Linux as well.
  350. As this property is now "standardized", OEM systems using AMD Cezanne and
  351. newer APU's have adopted this property, and quirks like this should not be
  352. necessary.
  353. CC: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
  354. CC: Alexander Deucher <Alexander.Deucher@amd.com>
  355. CC: Prike Liang <prike.liang@amd.com>
  356. Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
  357. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
  358. Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  359. Tested-by: Julian Sikorski <belegdol@gmail.com>
  360. Signed-off-by: Christoph Hellwig <hch@lst.de>
  361. Patchset: s0ix-amd
  362. ---
  363. drivers/acpi/device_pm.c | 3 +++
  364. drivers/acpi/internal.h | 9 +++++++++
  365. drivers/acpi/x86/utils.c | 25 +++++++++++++++++++++++++
  366. 3 files changed, 37 insertions(+)
  367. diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
  368. index 1e278785c7db..28f629a3d95c 100644
  369. --- a/drivers/acpi/device_pm.c
  370. +++ b/drivers/acpi/device_pm.c
  371. @@ -1357,6 +1357,9 @@ bool acpi_storage_d3(struct device *dev)
  372. struct acpi_device *adev = ACPI_COMPANION(dev);
  373. u8 val;
  374. + if (force_storage_d3())
  375. + return true;
  376. +
  377. if (!adev)
  378. return false;
  379. if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
  380. diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
  381. index cb8f70842249..96471be3f0c8 100644
  382. --- a/drivers/acpi/internal.h
  383. +++ b/drivers/acpi/internal.h
  384. @@ -236,6 +236,15 @@ static inline int suspend_nvs_save(void) { return 0; }
  385. static inline void suspend_nvs_restore(void) {}
  386. #endif
  387. +#ifdef CONFIG_X86
  388. +bool force_storage_d3(void);
  389. +#else
  390. +static inline bool force_storage_d3(void)
  391. +{
  392. + return false;
  393. +}
  394. +#endif
  395. +
  396. /*--------------------------------------------------------------------------
  397. Device properties
  398. -------------------------------------------------------------------------- */
  399. diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
  400. index bdc1ba00aee9..5298bb4d81fe 100644
  401. --- a/drivers/acpi/x86/utils.c
  402. +++ b/drivers/acpi/x86/utils.c
  403. @@ -135,3 +135,28 @@ bool acpi_device_always_present(struct acpi_device *adev)
  404. return ret;
  405. }
  406. +
  407. +/*
  408. + * AMD systems from Renoir and Lucienne *require* that the NVME controller
  409. + * is put into D3 over a Modern Standby / suspend-to-idle cycle.
  410. + *
  411. + * This is "typically" accomplished using the `StorageD3Enable`
  412. + * property in the _DSD that is checked via the `acpi_storage_d3` function
  413. + * but this property was introduced after many of these systems launched
  414. + * and most OEM systems don't have it in their BIOS.
  415. + *
  416. + * The Microsoft documentation for StorageD3Enable mentioned that Windows has
  417. + * a hardcoded allowlist for D3 support, which was used for these platforms.
  418. + *
  419. + * This allows quirking on Linux in a similar fashion.
  420. + */
  421. +const struct x86_cpu_id storage_d3_cpu_ids[] = {
  422. + X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */
  423. + X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */
  424. + {}
  425. +};
  426. +
  427. +bool force_storage_d3(void)
  428. +{
  429. + return x86_match_cpu(storage_d3_cpu_ids);
  430. +}
  431. --
  432. 2.32.0
  433. From 82b63c1e1ee410922d54592397aadc2ba9738915 Mon Sep 17 00:00:00 2001
  434. From: Alex Deucher <alexander.deucher@amd.com>
  435. Date: Wed, 5 May 2021 09:20:32 -0400
  436. Subject: [PATCH] ACPI: PM: s2idle: Add missing LPS0 functions for AMD
  437. These are supposedly not required for AMD platforms,
  438. but at least some HP laptops seem to require it to
  439. properly turn off the keyboard backlight.
  440. Based on a patch from Marcin Bachry <hegel666@gmail.com>.
  441. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1230
  442. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  443. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  444. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  445. Patchset: s0ix-amd
  446. ---
  447. drivers/acpi/x86/s2idle.c | 4 ++++
  448. 1 file changed, 4 insertions(+)
  449. diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
  450. index 2b69536cdccb..2d7ddb8a8cb6 100644
  451. --- a/drivers/acpi/x86/s2idle.c
  452. +++ b/drivers/acpi/x86/s2idle.c
  453. @@ -42,6 +42,8 @@ static const struct acpi_device_id lps0_device_ids[] = {
  454. /* AMD */
  455. #define ACPI_LPS0_DSM_UUID_AMD "e3f32452-febc-43ce-9039-932122d37721"
  456. +#define ACPI_LPS0_ENTRY_AMD 2
  457. +#define ACPI_LPS0_EXIT_AMD 3
  458. #define ACPI_LPS0_SCREEN_OFF_AMD 4
  459. #define ACPI_LPS0_SCREEN_ON_AMD 5
  460. @@ -408,6 +410,7 @@ int acpi_s2idle_prepare_late(void)
  461. if (acpi_s2idle_vendor_amd()) {
  462. acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD);
  463. + acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD);
  464. } else {
  465. acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF);
  466. acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY);
  467. @@ -422,6 +425,7 @@ void acpi_s2idle_restore_early(void)
  468. return;
  469. if (acpi_s2idle_vendor_amd()) {
  470. + acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD);
  471. acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD);
  472. } else {
  473. acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT);
  474. --
  475. 2.32.0
  476. From 7d78ab3e4a44be78c5ef67a1b49632084527656f Mon Sep 17 00:00:00 2001
  477. From: Alex Deucher <alexander.deucher@amd.com>
  478. Date: Wed, 17 Mar 2021 10:38:42 -0400
  479. Subject: [PATCH] platform/x86: force LPS0 functions for AMD
  480. ACPI_LPS0_ENTRY_AMD/ACPI_LPS0_EXIT_AMD are supposedly not
  481. required for AMD platforms, and on some platforms they are
  482. not even listed in the function mask but at least some HP
  483. laptops seem to require it to properly support s0ix.
  484. Based on a patch from Marcin Bachry <hegel666@gmail.com>.
  485. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1230
  486. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  487. Cc: Marcin Bachry <hegel666@gmail.com>
  488. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  489. Patchset: s0ix-amd
  490. ---
  491. drivers/acpi/x86/s2idle.c | 7 +++++++
  492. 1 file changed, 7 insertions(+)
  493. diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
  494. index 2d7ddb8a8cb6..482e6b23b21a 100644
  495. --- a/drivers/acpi/x86/s2idle.c
  496. +++ b/drivers/acpi/x86/s2idle.c
  497. @@ -368,6 +368,13 @@ static int lps0_device_attach(struct acpi_device *adev,
  498. ACPI_FREE(out_obj);
  499. + /*
  500. + * Some HP laptops require ACPI_LPS0_ENTRY_AMD/ACPI_LPS0_EXIT_AMD for proper
  501. + * S0ix, but don't set the function mask correctly. Fix that up here.
  502. + */
  503. + if (acpi_s2idle_vendor_amd())
  504. + lps0_dsm_func_mask |= (1 << ACPI_LPS0_ENTRY_AMD) | (1 << ACPI_LPS0_EXIT_AMD);
  505. +
  506. acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n",
  507. lps0_dsm_func_mask);
  508. --
  509. 2.32.0
  510. From 47c6565338ddb199d82a5407f04986eb20e4a28a Mon Sep 17 00:00:00 2001
  511. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  512. Date: Thu, 17 Jun 2021 17:00:35 +0530
  513. Subject: [PATCH] platform/x86: amd-pmc: Fix command completion code
  514. The protocol to submit a job request to SMU is to wait for
  515. AMD_PMC_REGISTER_RESPONSE to return 1,meaning SMU is ready to take
  516. requests. PMC driver has to make sure that the response code is always
  517. AMD_PMC_RESULT_OK before making any command submissions.
  518. Also, when we submit a message to SMU, we have to wait until it processes
  519. the request. Adding a read_poll_timeout() check as this was missing in
  520. the existing code.
  521. Fixes: 156ec4731cb2 ("platform/x86: amd-pmc: Add AMD platform support for S2Idle")
  522. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  523. Reviewed-by: Hans de Goede <hdegoede@redhat.com>
  524. Patchset: s0ix-amd
  525. ---
  526. drivers/platform/x86/amd-pmc.c | 10 +++++++++-
  527. 1 file changed, 9 insertions(+), 1 deletion(-)
  528. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  529. index 0b5578a8a449..535e431f98a8 100644
  530. --- a/drivers/platform/x86/amd-pmc.c
  531. +++ b/drivers/platform/x86/amd-pmc.c
  532. @@ -140,7 +140,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  533. /* Wait until we get a valid response */
  534. rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
  535. - val, val > 0, PMC_MSG_DELAY_MIN_US,
  536. + val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
  537. PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
  538. if (rc) {
  539. dev_err(dev->dev, "failed to talk to SMU\n");
  540. @@ -156,6 +156,14 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  541. /* Write message ID to message ID register */
  542. msg = (dev->cpu_id == AMD_CPU_ID_RN) ? MSG_OS_HINT_RN : MSG_OS_HINT_PCO;
  543. amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg);
  544. + /* Wait until we get a valid response */
  545. + rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
  546. + val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
  547. + PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
  548. + if (rc) {
  549. + dev_err(dev->dev, "SMU response timed out\n");
  550. + return rc;
  551. + }
  552. return 0;
  553. }
  554. --
  555. 2.32.0
  556. From 95350e7ba7dc7866ede307c58f45296d3d8df5c1 Mon Sep 17 00:00:00 2001
  557. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  558. Date: Thu, 17 Jun 2021 17:00:36 +0530
  559. Subject: [PATCH] platform/x86: amd-pmc: Fix SMU firmware reporting mechanism
  560. It was lately understood that the current mechanism available in the
  561. driver to get SMU firmware info works only on internal SMU builds and
  562. there is a separate way to get all the SMU logging counters (addressed
  563. in the next patch). Hence remove all the smu info shown via debugfs as it
  564. is no more useful.
  565. Also, use dump registers routine only at one place i.e. after the command
  566. submission to SMU is done.
  567. Fixes: 156ec4731cb2 ("platform/x86: amd-pmc: Add AMD platform support for S2Idle")
  568. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  569. Patchset: s0ix-amd
  570. ---
  571. drivers/platform/x86/amd-pmc.c | 15 +--------------
  572. 1 file changed, 1 insertion(+), 14 deletions(-)
  573. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  574. index 535e431f98a8..d32f0a0eeb9f 100644
  575. --- a/drivers/platform/x86/amd-pmc.c
  576. +++ b/drivers/platform/x86/amd-pmc.c
  577. @@ -52,7 +52,6 @@
  578. #define AMD_CPU_ID_PCO AMD_CPU_ID_RV
  579. #define AMD_CPU_ID_CZN AMD_CPU_ID_RN
  580. -#define AMD_SMU_FW_VERSION 0x0
  581. #define PMC_MSG_DELAY_MIN_US 100
  582. #define RESPONSE_REGISTER_LOOP_MAX 200
  583. @@ -88,11 +87,6 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
  584. #ifdef CONFIG_DEBUG_FS
  585. static int smu_fw_info_show(struct seq_file *s, void *unused)
  586. {
  587. - struct amd_pmc_dev *dev = s->private;
  588. - u32 value;
  589. -
  590. - value = ioread32(dev->smu_base + AMD_SMU_FW_VERSION);
  591. - seq_printf(s, "SMU FW Info: %x\n", value);
  592. return 0;
  593. }
  594. DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
  595. @@ -164,6 +158,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  596. dev_err(dev->dev, "SMU response timed out\n");
  597. return rc;
  598. }
  599. + amd_pmc_dump_registers(dev);
  600. return 0;
  601. }
  602. @@ -176,7 +171,6 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
  603. if (rc)
  604. dev_err(pdev->dev, "suspend failed\n");
  605. - amd_pmc_dump_registers(pdev);
  606. return 0;
  607. }
  608. @@ -189,7 +183,6 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
  609. if (rc)
  610. dev_err(pdev->dev, "resume failed\n");
  611. - amd_pmc_dump_registers(pdev);
  612. return 0;
  613. }
  614. @@ -256,17 +249,11 @@ static int amd_pmc_probe(struct platform_device *pdev)
  615. pci_dev_put(rdev);
  616. base_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
  617. - dev->smu_base = devm_ioremap(dev->dev, base_addr, AMD_PMC_MAPPING_SIZE);
  618. - if (!dev->smu_base)
  619. - return -ENOMEM;
  620. -
  621. dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET,
  622. AMD_PMC_MAPPING_SIZE);
  623. if (!dev->regbase)
  624. return -ENOMEM;
  625. - amd_pmc_dump_registers(dev);
  626. -
  627. platform_set_drvdata(pdev, dev);
  628. amd_pmc_dbgfs_register(dev);
  629. return 0;
  630. --
  631. 2.32.0
  632. From 3c26a54d62e99ed2ce8a87f556d82db14722e80c Mon Sep 17 00:00:00 2001
  633. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  634. Date: Thu, 17 Jun 2021 17:00:37 +0530
  635. Subject: [PATCH] platform/x86: amd-pmc: Add support for logging SMU metrics
  636. SMU provides a way to dump the s0ix debug statistics in the form of a
  637. metrics table via a of set special mailbox commands.
  638. Add support to the driver which can send these commands to SMU and expose
  639. the information received via debugfs. The information contains the s0ix
  640. entry/exit, active time of each IP block etc.
  641. As a side note, SMU subsystem logging is not supported on Picasso based
  642. SoC's.
  643. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  644. Patchset: s0ix-amd
  645. ---
  646. drivers/platform/x86/amd-pmc.c | 148 +++++++++++++++++++++++++++++++--
  647. 1 file changed, 140 insertions(+), 8 deletions(-)
  648. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  649. index d32f0a0eeb9f..b5249fdeb95f 100644
  650. --- a/drivers/platform/x86/amd-pmc.c
  651. +++ b/drivers/platform/x86/amd-pmc.c
  652. @@ -46,6 +46,14 @@
  653. #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
  654. #define AMD_PMC_RESULT_FAILED 0xFF
  655. +/* SMU Message Definations */
  656. +#define SMU_MSG_GETSMUVERSION 0x02
  657. +#define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
  658. +#define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05
  659. +#define SMU_MSG_LOG_START 0x06
  660. +#define SMU_MSG_LOG_RESET 0x07
  661. +#define SMU_MSG_LOG_DUMP_DATA 0x08
  662. +#define SMU_MSG_GET_SUP_CONSTRAINTS 0x09
  663. /* List of supported CPU ids */
  664. #define AMD_CPU_ID_RV 0x15D0
  665. #define AMD_CPU_ID_RN 0x1630
  666. @@ -55,17 +63,42 @@
  667. #define PMC_MSG_DELAY_MIN_US 100
  668. #define RESPONSE_REGISTER_LOOP_MAX 200
  669. +#define SOC_SUBSYSTEM_IP_MAX 12
  670. +#define DELAY_MIN_US 2000
  671. +#define DELAY_MAX_US 3000
  672. enum amd_pmc_def {
  673. MSG_TEST = 0x01,
  674. MSG_OS_HINT_PCO,
  675. MSG_OS_HINT_RN,
  676. };
  677. +struct amd_pmc_bit_map {
  678. + const char *name;
  679. + u32 bit_mask;
  680. +};
  681. +
  682. +static const struct amd_pmc_bit_map soc15_ip_blk[] = {
  683. + {"DISPLAY", BIT(0)},
  684. + {"CPU", BIT(1)},
  685. + {"GFX", BIT(2)},
  686. + {"VDD", BIT(3)},
  687. + {"ACP", BIT(4)},
  688. + {"VCN", BIT(5)},
  689. + {"ISP", BIT(6)},
  690. + {"NBIO", BIT(7)},
  691. + {"DF", BIT(8)},
  692. + {"USB0", BIT(9)},
  693. + {"USB1", BIT(10)},
  694. + {"LAPIC", BIT(11)},
  695. + {}
  696. +};
  697. +
  698. struct amd_pmc_dev {
  699. void __iomem *regbase;
  700. - void __iomem *smu_base;
  701. + void __iomem *smu_virt_addr;
  702. u32 base_addr;
  703. u32 cpu_id;
  704. + u32 active_ips;
  705. struct device *dev;
  706. #if IS_ENABLED(CONFIG_DEBUG_FS)
  707. struct dentry *dbgfs_dir;
  708. @@ -73,6 +106,7 @@ struct amd_pmc_dev {
  709. };
  710. static struct amd_pmc_dev pmc;
  711. +static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret);
  712. static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
  713. {
  714. @@ -84,9 +118,50 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
  715. iowrite32(val, dev->regbase + reg_offset);
  716. }
  717. +struct smu_metrics {
  718. + u32 table_version;
  719. + u32 hint_count;
  720. + u32 s0i3_cyclecount;
  721. + u32 timein_s0i2;
  722. + u64 timeentering_s0i3_lastcapture;
  723. + u64 timeentering_s0i3_totaltime;
  724. + u64 timeto_resume_to_os_lastcapture;
  725. + u64 timeto_resume_to_os_totaltime;
  726. + u64 timein_s0i3_lastcapture;
  727. + u64 timein_s0i3_totaltime;
  728. + u64 timein_swdrips_lastcapture;
  729. + u64 timein_swdrips_totaltime;
  730. + u64 timecondition_notmet_lastcapture[SOC_SUBSYSTEM_IP_MAX];
  731. + u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX];
  732. +} __packed;
  733. +
  734. #ifdef CONFIG_DEBUG_FS
  735. static int smu_fw_info_show(struct seq_file *s, void *unused)
  736. {
  737. + struct amd_pmc_dev *dev = s->private;
  738. + struct smu_metrics table;
  739. + u32 value;
  740. + int idx;
  741. +
  742. + if (dev->cpu_id == AMD_CPU_ID_PCO)
  743. + return -EINVAL;
  744. +
  745. + memcpy_fromio(&table, dev->smu_virt_addr, sizeof(struct smu_metrics));
  746. +
  747. + seq_puts(s, "\n=== SMU Statistics ===\n");
  748. + seq_printf(s, "Table Version: %d\n", table.table_version);
  749. + seq_printf(s, "Hint Count: %d\n", table.hint_count);
  750. + seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount);
  751. + seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
  752. + seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
  753. +
  754. + seq_puts(s, "\n=== Active time (in us) ===\n");
  755. + for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
  756. + if (soc15_ip_blk[idx].bit_mask & dev->active_ips)
  757. + seq_printf(s, "%-8s : %lld\n", soc15_ip_blk[idx].name,
  758. + table.timecondition_notmet_lastcapture[idx]);
  759. + }
  760. +
  761. return 0;
  762. }
  763. DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
  764. @@ -112,6 +187,32 @@ static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
  765. }
  766. #endif /* CONFIG_DEBUG_FS */
  767. +static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
  768. +{
  769. + u32 phys_addr_low, phys_addr_hi;
  770. + u64 smu_phys_addr;
  771. +
  772. + if (dev->cpu_id == AMD_CPU_ID_PCO)
  773. + return -EINVAL;
  774. +
  775. + /* Get Active devices list from SMU */
  776. + amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, 1);
  777. +
  778. + /* Get dram address */
  779. + amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, 1);
  780. + amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, 1);
  781. + smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
  782. +
  783. + dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr, sizeof(struct smu_metrics));
  784. + if (!dev->smu_virt_addr)
  785. + return -ENOMEM;
  786. +
  787. + /* Start the logging */
  788. + amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, 0);
  789. +
  790. + return 0;
  791. +}
  792. +
  793. static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
  794. {
  795. u32 value;
  796. @@ -126,10 +227,9 @@ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
  797. dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value);
  798. }
  799. -static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  800. +static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret)
  801. {
  802. int rc;
  803. - u8 msg;
  804. u32 val;
  805. /* Wait until we get a valid response */
  806. @@ -148,8 +248,8 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  807. amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set);
  808. /* Write message ID to message ID register */
  809. - msg = (dev->cpu_id == AMD_CPU_ID_RN) ? MSG_OS_HINT_RN : MSG_OS_HINT_PCO;
  810. amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg);
  811. +
  812. /* Wait until we get a valid response */
  813. rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
  814. val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
  815. @@ -158,16 +258,40 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
  816. dev_err(dev->dev, "SMU response timed out\n");
  817. return rc;
  818. }
  819. +
  820. + if (ret) {
  821. + /* PMFW may take longer time to return back the data */
  822. + usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US);
  823. + *data = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_ARGUMENT);
  824. + }
  825. +
  826. amd_pmc_dump_registers(dev);
  827. return 0;
  828. }
  829. +static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
  830. +{
  831. + switch (dev->cpu_id) {
  832. + case AMD_CPU_ID_PCO:
  833. + return MSG_OS_HINT_PCO;
  834. + case AMD_CPU_ID_RN:
  835. + return MSG_OS_HINT_RN;
  836. + }
  837. + return -EINVAL;
  838. +}
  839. +
  840. static int __maybe_unused amd_pmc_suspend(struct device *dev)
  841. {
  842. struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
  843. int rc;
  844. + u8 msg;
  845. +
  846. + /* Reset and Start SMU logging - to monitor the s0i3 stats */
  847. + amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0);
  848. + amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0);
  849. - rc = amd_pmc_send_cmd(pdev, 1);
  850. + msg = amd_pmc_get_os_hint(pdev);
  851. + rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0);
  852. if (rc)
  853. dev_err(pdev->dev, "suspend failed\n");
  854. @@ -178,8 +302,13 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
  855. {
  856. struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
  857. int rc;
  858. + u8 msg;
  859. +
  860. + /* Let SMU know that we are looking for stats */
  861. + amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
  862. - rc = amd_pmc_send_cmd(pdev, 0);
  863. + msg = amd_pmc_get_os_hint(pdev);
  864. + rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0);
  865. if (rc)
  866. dev_err(pdev->dev, "resume failed\n");
  867. @@ -202,8 +331,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
  868. {
  869. struct amd_pmc_dev *dev = &pmc;
  870. struct pci_dev *rdev;
  871. - u32 base_addr_lo;
  872. - u32 base_addr_hi;
  873. + u32 base_addr_lo, base_addr_hi;
  874. u64 base_addr;
  875. int err;
  876. u32 val;
  877. @@ -254,6 +382,10 @@ static int amd_pmc_probe(struct platform_device *pdev)
  878. if (!dev->regbase)
  879. return -ENOMEM;
  880. + /* Use SMU to get the s0i3 debug stats */
  881. + err = amd_pmc_setup_smu_logging(dev);
  882. + if (err)
  883. + dev_err(dev->dev, "SMU debugging info not supported on this platform\n");
  884. platform_set_drvdata(pdev, dev);
  885. amd_pmc_dbgfs_register(dev);
  886. return 0;
  887. --
  888. 2.32.0
  889. From c0b1001ec46fd2912b7d2882f22973bfe309520f Mon Sep 17 00:00:00 2001
  890. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  891. Date: Thu, 17 Jun 2021 17:00:38 +0530
  892. Subject: [PATCH] platform/x86: amd-pmc: Add support for logging s0ix counters
  893. Even the FCH SSC registers provides certain level of information
  894. about the s0ix entry and exit times which comes handy when the SMU
  895. fails to report the statistics via the mailbox communication.
  896. This information is captured via a new debugfs file "s0ix_stats".
  897. A non-zero entry in this counters would mean that the system entered
  898. the s0ix state.
  899. If s0ix entry time and exit time don't change during suspend to idle,
  900. the silicon has not entered the deepest state.
  901. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  902. Patchset: s0ix-amd
  903. ---
  904. drivers/platform/x86/amd-pmc.c | 46 ++++++++++++++++++++++++++++++++--
  905. 1 file changed, 44 insertions(+), 2 deletions(-)
  906. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  907. index b5249fdeb95f..b6ad290c9a86 100644
  908. --- a/drivers/platform/x86/amd-pmc.c
  909. +++ b/drivers/platform/x86/amd-pmc.c
  910. @@ -46,6 +46,15 @@
  911. #define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
  912. #define AMD_PMC_RESULT_FAILED 0xFF
  913. +/* FCH SSC Registers */
  914. +#define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30
  915. +#define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34
  916. +#define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38
  917. +#define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C
  918. +#define FCH_SSC_MAPPING_SIZE 0x800
  919. +#define FCH_BASE_PHY_ADDR_LOW 0xFED81100
  920. +#define FCH_BASE_PHY_ADDR_HIGH 0x00000000
  921. +
  922. /* SMU Message Definations */
  923. #define SMU_MSG_GETSMUVERSION 0x02
  924. #define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
  925. @@ -96,6 +105,7 @@ static const struct amd_pmc_bit_map soc15_ip_blk[] = {
  926. struct amd_pmc_dev {
  927. void __iomem *regbase;
  928. void __iomem *smu_virt_addr;
  929. + void __iomem *fch_virt_addr;
  930. u32 base_addr;
  931. u32 cpu_id;
  932. u32 active_ips;
  933. @@ -140,7 +150,6 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
  934. {
  935. struct amd_pmc_dev *dev = s->private;
  936. struct smu_metrics table;
  937. - u32 value;
  938. int idx;
  939. if (dev->cpu_id == AMD_CPU_ID_PCO)
  940. @@ -166,6 +175,29 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
  941. }
  942. DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
  943. +static int s0ix_stats_show(struct seq_file *s, void *unused)
  944. +{
  945. + struct amd_pmc_dev *dev = s->private;
  946. + u64 entry_time, exit_time, residency;
  947. +
  948. + entry_time = ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_H_OFFSET);
  949. + entry_time = entry_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_L_OFFSET);
  950. +
  951. + exit_time = ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_H_OFFSET);
  952. + exit_time = exit_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_L_OFFSET);
  953. +
  954. + /* It's in 48MHz. We need to convert it to unit of 100ns */
  955. + residency = (exit_time - entry_time) * 10 / 48;
  956. +
  957. + seq_puts(s, "=== S0ix statistics ===\n");
  958. + seq_printf(s, "S0ix Entry Time: %lld\n", entry_time);
  959. + seq_printf(s, "S0ix Exit Time: %lld\n", exit_time);
  960. + seq_printf(s, "Residency Time: %lld\n", residency);
  961. +
  962. + return 0;
  963. +}
  964. +DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
  965. +
  966. static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
  967. {
  968. debugfs_remove_recursive(dev->dbgfs_dir);
  969. @@ -176,6 +208,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
  970. dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL);
  971. debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev,
  972. &smu_fw_info_fops);
  973. + debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
  974. + &s0ix_stats_fops);
  975. }
  976. #else
  977. static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
  978. @@ -332,7 +366,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
  979. struct amd_pmc_dev *dev = &pmc;
  980. struct pci_dev *rdev;
  981. u32 base_addr_lo, base_addr_hi;
  982. - u64 base_addr;
  983. + u64 base_addr, fch_phys_addr;
  984. int err;
  985. u32 val;
  986. @@ -382,6 +416,14 @@ static int amd_pmc_probe(struct platform_device *pdev)
  987. if (!dev->regbase)
  988. return -ENOMEM;
  989. + /* Use FCH registers to get the S0ix stats */
  990. + base_addr_lo = FCH_BASE_PHY_ADDR_LOW;
  991. + base_addr_hi = FCH_BASE_PHY_ADDR_HIGH;
  992. + fch_phys_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
  993. + dev->fch_virt_addr = devm_ioremap(dev->dev, fch_phys_addr, FCH_SSC_MAPPING_SIZE);
  994. + if (!dev->fch_virt_addr)
  995. + return -ENOMEM;
  996. +
  997. /* Use SMU to get the s0i3 debug stats */
  998. err = amd_pmc_setup_smu_logging(dev);
  999. if (err)
  1000. --
  1001. 2.32.0
  1002. From c1e5e94f1bf15f1b70ae991bcabab92d9e9150a5 Mon Sep 17 00:00:00 2001
  1003. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  1004. Date: Thu, 17 Jun 2021 17:00:39 +0530
  1005. Subject: [PATCH] platform/x86: amd-pmc: Add support for ACPI ID AMDI0006
  1006. Some newer BIOSes have added another ACPI ID for the uPEP device.
  1007. SMU statistics behave identically on this device.
  1008. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  1009. Patchset: s0ix-amd
  1010. ---
  1011. drivers/platform/x86/amd-pmc.c | 1 +
  1012. 1 file changed, 1 insertion(+)
  1013. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  1014. index b6ad290c9a86..2a73fe0deaf3 100644
  1015. --- a/drivers/platform/x86/amd-pmc.c
  1016. +++ b/drivers/platform/x86/amd-pmc.c
  1017. @@ -443,6 +443,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
  1018. static const struct acpi_device_id amd_pmc_acpi_ids[] = {
  1019. {"AMDI0005", 0},
  1020. + {"AMDI0006", 0},
  1021. {"AMD0004", 0},
  1022. {"AMD0005", 0},
  1023. { }
  1024. --
  1025. 2.32.0
  1026. From 31b773122734f73887807b6f8b1d7e2229b5af8b Mon Sep 17 00:00:00 2001
  1027. From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  1028. Date: Thu, 17 Jun 2021 17:00:40 +0530
  1029. Subject: [PATCH] platform/x86: amd-pmc: Add new acpi id for future PMC
  1030. controllers
  1031. The upcoming PMC controller would have a newer acpi id, add that to
  1032. the supported acpid device list.
  1033. Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
  1034. Patchset: s0ix-amd
  1035. ---
  1036. drivers/platform/x86/amd-pmc.c | 4 ++++
  1037. 1 file changed, 4 insertions(+)
  1038. diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
  1039. index 2a73fe0deaf3..5a2be598fc2e 100644
  1040. --- a/drivers/platform/x86/amd-pmc.c
  1041. +++ b/drivers/platform/x86/amd-pmc.c
  1042. @@ -68,6 +68,7 @@
  1043. #define AMD_CPU_ID_RN 0x1630
  1044. #define AMD_CPU_ID_PCO AMD_CPU_ID_RV
  1045. #define AMD_CPU_ID_CZN AMD_CPU_ID_RN
  1046. +#define AMD_CPU_ID_YC 0x14B5
  1047. #define PMC_MSG_DELAY_MIN_US 100
  1048. #define RESPONSE_REGISTER_LOOP_MAX 200
  1049. @@ -309,6 +310,7 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
  1050. case AMD_CPU_ID_PCO:
  1051. return MSG_OS_HINT_PCO;
  1052. case AMD_CPU_ID_RN:
  1053. + case AMD_CPU_ID_YC:
  1054. return MSG_OS_HINT_RN;
  1055. }
  1056. return -EINVAL;
  1057. @@ -354,6 +356,7 @@ static const struct dev_pm_ops amd_pmc_pm_ops = {
  1058. };
  1059. static const struct pci_device_id pmc_pci_ids[] = {
  1060. + { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) },
  1061. { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) },
  1062. { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) },
  1063. { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) },
  1064. @@ -444,6 +447,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
  1065. static const struct acpi_device_id amd_pmc_acpi_ids[] = {
  1066. {"AMDI0005", 0},
  1067. {"AMDI0006", 0},
  1068. + {"AMDI0007", 0},
  1069. {"AMD0004", 0},
  1070. {"AMD0005", 0},
  1071. { }
  1072. --
  1073. 2.32.0
  1074. From 7001c6c1a202585885a14575aa8f731f60714c5c Mon Sep 17 00:00:00 2001
  1075. From: Pratik Vishwakarma <Pratik.Vishwakarma@amd.com>
  1076. Date: Thu, 17 Jun 2021 11:42:08 -0500
  1077. Subject: [PATCH] ACPI: PM: s2idle: Use correct revision id
  1078. AMD spec mentions only revision 0. With this change,
  1079. device constraint list is populated properly.
  1080. Signed-off-by: Pratik Vishwakarma <Pratik.Vishwakarma@amd.com>
  1081. Patchset: s0ix-amd
  1082. ---
  1083. drivers/acpi/x86/s2idle.c | 2 +-
  1084. 1 file changed, 1 insertion(+), 1 deletion(-)
  1085. diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
  1086. index 482e6b23b21a..4339e6da0dd6 100644
  1087. --- a/drivers/acpi/x86/s2idle.c
  1088. +++ b/drivers/acpi/x86/s2idle.c
  1089. @@ -96,7 +96,7 @@ static void lpi_device_get_constraints_amd(void)
  1090. int i, j, k;
  1091. out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
  1092. - 1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
  1093. + rev_id, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
  1094. NULL, ACPI_TYPE_PACKAGE);
  1095. if (!out_obj)
  1096. --
  1097. 2.32.0