1026 lines
34 KiB
Diff
1026 lines
34 KiB
Diff
|
From cbc2f5f6667fddb72517156c071609069252848a Mon Sep 17 00:00:00 2001
|
||
|
From: Sachi King <nakato@nakato.io>
|
||
|
Date: Sat, 29 May 2021 22:27:25 +1000
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Add device HID for AMD PMC
|
||
|
|
||
|
The Surface Laptop 4 appears to have used AMD0005 for the PMC instead of
|
||
|
the AMDI0005 which would match the ACPI ID Registry.
|
||
|
|
||
|
AMD appears to have previously used "AMD" in a number of IDs in the past,
|
||
|
and AMD is not allocated to any other entity as an ID, so adding this ID
|
||
|
should not cause any harm.
|
||
|
|
||
|
Signed-off-by: Sachi King <nakato@nakato.io>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 1 +
|
||
|
1 file changed, 1 insertion(+)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index b9da58ee9b1e..0b5578a8a449 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -275,6 +275,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
|
||
|
static const struct acpi_device_id amd_pmc_acpi_ids[] = {
|
||
|
{"AMDI0005", 0},
|
||
|
{"AMD0004", 0},
|
||
|
+ {"AMD0005", 0},
|
||
|
{ }
|
||
|
};
|
||
|
MODULE_DEVICE_TABLE(acpi, amd_pmc_acpi_ids);
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 03247c72b0f1471c51d6680950bcff545f20251c Mon Sep 17 00:00:00 2001
|
||
|
From: Marcin Bachry <hegel666@gmail.com>
|
||
|
Date: Tue, 16 Mar 2021 15:28:51 -0400
|
||
|
Subject: [PATCH] PCI: quirks: Quirk PCI d3hot delay for AMD xhci
|
||
|
|
||
|
Renoir needs a similar delay.
|
||
|
|
||
|
Signed-off-by: Marcin Bachry <hegel666@gmail.com>
|
||
|
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/pci/quirks.c | 3 +++
|
||
|
1 file changed, 3 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
|
||
|
index 6d74386eadc2..446f8f7b0ee4 100644
|
||
|
--- a/drivers/pci/quirks.c
|
||
|
+++ b/drivers/pci/quirks.c
|
||
|
@@ -1900,6 +1900,9 @@ static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev)
|
||
|
}
|
||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot);
|
||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot);
|
||
|
+/* Renoir XHCI requires longer delay when transitioning from D0 to
|
||
|
+ * D3hot */
|
||
|
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1639, quirk_ryzen_xhci_d3hot);
|
||
|
|
||
|
#ifdef CONFIG_X86_IO_APIC
|
||
|
static int dmi_disable_ioapicreroute(const struct dmi_system_id *d)
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From e47b481ce800b5ea83120fce8350eb8051f3fe8e Mon Sep 17 00:00:00 2001
|
||
|
From: Mario Limonciello <mario.limonciello@amd.com>
|
||
|
Date: Wed, 9 Jun 2021 13:40:17 -0500
|
||
|
Subject: [PATCH] ACPI: Check StorageD3Enable _DSD property in ACPI code
|
||
|
|
||
|
Although first implemented for NVME, this check may be usable by
|
||
|
other drivers as well. Microsoft's specification explicitly mentions
|
||
|
that is may be usable by SATA and AHCI devices. Google also indicates
|
||
|
that they have used this with SDHCI in a downstream kernel tree that
|
||
|
a user can plug a storage device into.
|
||
|
|
||
|
Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
|
||
|
Suggested-by: Keith Busch <kbusch@kernel.org>
|
||
|
CC: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
|
||
|
CC: Alexander Deucher <Alexander.Deucher@amd.com>
|
||
|
CC: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||
|
CC: Prike Liang <prike.liang@amd.com>
|
||
|
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
||
|
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||
|
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/acpi/device_pm.c | 29 +++++++++++++++++++++++++++++
|
||
|
drivers/nvme/host/pci.c | 28 +---------------------------
|
||
|
include/linux/acpi.h | 5 +++++
|
||
|
3 files changed, 35 insertions(+), 27 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
|
||
|
index 9d2d3b9bb8b5..b20ae93415f0 100644
|
||
|
--- a/drivers/acpi/device_pm.c
|
||
|
+++ b/drivers/acpi/device_pm.c
|
||
|
@@ -1338,4 +1338,33 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||
|
return 1;
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(acpi_dev_pm_attach);
|
||
|
+
|
||
|
+/**
|
||
|
+ * acpi_storage_d3 - Check if D3 should be used in the suspend path
|
||
|
+ * @dev: Device to check
|
||
|
+ *
|
||
|
+ * Return %true if the platform firmware wants @dev to be programmed
|
||
|
+ * into D3hot or D3cold (if supported) in the suspend path, or %false
|
||
|
+ * when there is no specific preference. On some platforms, if this
|
||
|
+ * hint is ignored, @dev may remain unresponsive after suspending the
|
||
|
+ * platform as a whole.
|
||
|
+ *
|
||
|
+ * Although the property has storage in the name it actually is
|
||
|
+ * applied to the PCIe slot and plugging in a non-storage device the
|
||
|
+ * same platform restrictions will likely apply.
|
||
|
+ */
|
||
|
+bool acpi_storage_d3(struct device *dev)
|
||
|
+{
|
||
|
+ struct acpi_device *adev = ACPI_COMPANION(dev);
|
||
|
+ u8 val;
|
||
|
+
|
||
|
+ if (!adev)
|
||
|
+ return false;
|
||
|
+ if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
|
||
|
+ &val))
|
||
|
+ return false;
|
||
|
+ return val == 1;
|
||
|
+}
|
||
|
+EXPORT_SYMBOL_GPL(acpi_storage_d3);
|
||
|
+
|
||
|
#endif /* CONFIG_PM */
|
||
|
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
|
||
|
index 42ad75ff1348..5a72bdf5ad03 100644
|
||
|
--- a/drivers/nvme/host/pci.c
|
||
|
+++ b/drivers/nvme/host/pci.c
|
||
|
@@ -2828,32 +2828,6 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-#ifdef CONFIG_ACPI
|
||
|
-static bool nvme_acpi_storage_d3(struct pci_dev *dev)
|
||
|
-{
|
||
|
- struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
|
||
|
- u8 val;
|
||
|
-
|
||
|
- /*
|
||
|
- * Look for _DSD property specifying that the storage device on the port
|
||
|
- * must use D3 to support deep platform power savings during
|
||
|
- * suspend-to-idle.
|
||
|
- */
|
||
|
-
|
||
|
- if (!adev)
|
||
|
- return false;
|
||
|
- if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
|
||
|
- &val))
|
||
|
- return false;
|
||
|
- return val == 1;
|
||
|
-}
|
||
|
-#else
|
||
|
-static inline bool nvme_acpi_storage_d3(struct pci_dev *dev)
|
||
|
-{
|
||
|
- return false;
|
||
|
-}
|
||
|
-#endif /* CONFIG_ACPI */
|
||
|
-
|
||
|
static void nvme_async_probe(void *data, async_cookie_t cookie)
|
||
|
{
|
||
|
struct nvme_dev *dev = data;
|
||
|
@@ -2903,7 +2877,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||
|
|
||
|
quirks |= check_vendor_combination_bug(pdev);
|
||
|
|
||
|
- if (!noacpi && nvme_acpi_storage_d3(pdev)) {
|
||
|
+ if (!noacpi && acpi_storage_d3(&pdev->dev)) {
|
||
|
/*
|
||
|
* Some systems use a bios work around to ask for D3 on
|
||
|
* platforms that support kernel managed suspend.
|
||
|
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
|
||
|
index e8ba7063c000..66c43abef4a4 100644
|
||
|
--- a/include/linux/acpi.h
|
||
|
+++ b/include/linux/acpi.h
|
||
|
@@ -1006,6 +1006,7 @@ int acpi_dev_resume(struct device *dev);
|
||
|
int acpi_subsys_runtime_suspend(struct device *dev);
|
||
|
int acpi_subsys_runtime_resume(struct device *dev);
|
||
|
int acpi_dev_pm_attach(struct device *dev, bool power_on);
|
||
|
+bool acpi_storage_d3(struct device *dev);
|
||
|
#else
|
||
|
static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; }
|
||
|
static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; }
|
||
|
@@ -1013,6 +1014,10 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
+static inline bool acpi_storage_d3(struct device *dev)
|
||
|
+{
|
||
|
+ return false;
|
||
|
+}
|
||
|
#endif
|
||
|
|
||
|
#if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From cbece4688721474e9f061d68532f1fee59dd705f Mon Sep 17 00:00:00 2001
|
||
|
From: Mario Limonciello <mario.limonciello@amd.com>
|
||
|
Date: Wed, 9 Jun 2021 13:40:18 -0500
|
||
|
Subject: [PATCH] ACPI: Add quirks for AMD Renoir/Lucienne CPUs to force the D3
|
||
|
hint
|
||
|
|
||
|
AMD systems from Renoir and Lucienne require that the NVME controller
|
||
|
is put into D3 over a Modern Standby / suspend-to-idle
|
||
|
cycle. This is "typically" accomplished using the `StorageD3Enable`
|
||
|
property in the _DSD, but this property was introduced after many
|
||
|
of these systems launched and most OEM systems don't have it in
|
||
|
their BIOS.
|
||
|
|
||
|
On AMD Renoir without these drives going into D3 over suspend-to-idle
|
||
|
the resume will fail with the NVME controller being reset and a trace
|
||
|
like this in the kernel logs:
|
||
|
```
|
||
|
[ 83.556118] nvme nvme0: I/O 161 QID 2 timeout, aborting
|
||
|
[ 83.556178] nvme nvme0: I/O 162 QID 2 timeout, aborting
|
||
|
[ 83.556187] nvme nvme0: I/O 163 QID 2 timeout, aborting
|
||
|
[ 83.556196] nvme nvme0: I/O 164 QID 2 timeout, aborting
|
||
|
[ 95.332114] nvme nvme0: I/O 25 QID 0 timeout, reset controller
|
||
|
[ 95.332843] nvme nvme0: Abort status: 0x371
|
||
|
[ 95.332852] nvme nvme0: Abort status: 0x371
|
||
|
[ 95.332856] nvme nvme0: Abort status: 0x371
|
||
|
[ 95.332859] nvme nvme0: Abort status: 0x371
|
||
|
[ 95.332909] PM: dpm_run_callback(): pci_pm_resume+0x0/0xe0 returns -16
|
||
|
[ 95.332936] nvme 0000:03:00.0: PM: failed to resume async: error -16
|
||
|
```
|
||
|
|
||
|
The Microsoft documentation for StorageD3Enable mentioned that Windows has
|
||
|
a hardcoded allowlist for D3 support, which was used for these platforms.
|
||
|
Introduce quirks to hardcode them for Linux as well.
|
||
|
|
||
|
As this property is now "standardized", OEM systems using AMD Cezanne and
|
||
|
newer APU's have adopted this property, and quirks like this should not be
|
||
|
necessary.
|
||
|
|
||
|
CC: Shyam-sundar S-k <Shyam-sundar.S-k@amd.com>
|
||
|
CC: Alexander Deucher <Alexander.Deucher@amd.com>
|
||
|
CC: Prike Liang <prike.liang@amd.com>
|
||
|
Link: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/power-management-for-storage-hardware-devices-intro
|
||
|
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
||
|
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||
|
Tested-by: Julian Sikorski <belegdol@gmail.com>
|
||
|
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/acpi/device_pm.c | 3 +++
|
||
|
drivers/acpi/internal.h | 9 +++++++++
|
||
|
drivers/acpi/x86/utils.c | 25 +++++++++++++++++++++++++
|
||
|
3 files changed, 37 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
|
||
|
index b20ae93415f0..0cfdef2fc3ad 100644
|
||
|
--- a/drivers/acpi/device_pm.c
|
||
|
+++ b/drivers/acpi/device_pm.c
|
||
|
@@ -1358,6 +1358,9 @@ bool acpi_storage_d3(struct device *dev)
|
||
|
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||
|
u8 val;
|
||
|
|
||
|
+ if (force_storage_d3())
|
||
|
+ return true;
|
||
|
+
|
||
|
if (!adev)
|
||
|
return false;
|
||
|
if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable",
|
||
|
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
|
||
|
index e21611c9a170..7ac01b03ba67 100644
|
||
|
--- a/drivers/acpi/internal.h
|
||
|
+++ b/drivers/acpi/internal.h
|
||
|
@@ -236,6 +236,15 @@ static inline int suspend_nvs_save(void) { return 0; }
|
||
|
static inline void suspend_nvs_restore(void) {}
|
||
|
#endif
|
||
|
|
||
|
+#ifdef CONFIG_X86
|
||
|
+bool force_storage_d3(void);
|
||
|
+#else
|
||
|
+static inline bool force_storage_d3(void)
|
||
|
+{
|
||
|
+ return false;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
/*--------------------------------------------------------------------------
|
||
|
Device properties
|
||
|
-------------------------------------------------------------------------- */
|
||
|
diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
|
||
|
index bdc1ba00aee9..5298bb4d81fe 100644
|
||
|
--- a/drivers/acpi/x86/utils.c
|
||
|
+++ b/drivers/acpi/x86/utils.c
|
||
|
@@ -135,3 +135,28 @@ bool acpi_device_always_present(struct acpi_device *adev)
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
+
|
||
|
+/*
|
||
|
+ * AMD systems from Renoir and Lucienne *require* that the NVME controller
|
||
|
+ * is put into D3 over a Modern Standby / suspend-to-idle cycle.
|
||
|
+ *
|
||
|
+ * This is "typically" accomplished using the `StorageD3Enable`
|
||
|
+ * property in the _DSD that is checked via the `acpi_storage_d3` function
|
||
|
+ * but this property was introduced after many of these systems launched
|
||
|
+ * and most OEM systems don't have it in their BIOS.
|
||
|
+ *
|
||
|
+ * The Microsoft documentation for StorageD3Enable mentioned that Windows has
|
||
|
+ * a hardcoded allowlist for D3 support, which was used for these platforms.
|
||
|
+ *
|
||
|
+ * This allows quirking on Linux in a similar fashion.
|
||
|
+ */
|
||
|
+const struct x86_cpu_id storage_d3_cpu_ids[] = {
|
||
|
+ X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL), /* Renoir */
|
||
|
+ X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL), /* Lucienne */
|
||
|
+ {}
|
||
|
+};
|
||
|
+
|
||
|
+bool force_storage_d3(void)
|
||
|
+{
|
||
|
+ return x86_match_cpu(storage_d3_cpu_ids);
|
||
|
+}
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 538e90326aba5ad0322797144b4fc601115e6359 Mon Sep 17 00:00:00 2001
|
||
|
From: Alex Deucher <alexander.deucher@amd.com>
|
||
|
Date: Wed, 17 Mar 2021 10:38:42 -0400
|
||
|
Subject: [PATCH] platform/x86: force LPS0 functions for AMD
|
||
|
|
||
|
ACPI_LPS0_ENTRY_AMD/ACPI_LPS0_EXIT_AMD are supposedly not
|
||
|
required for AMD platforms, and on some platforms they are
|
||
|
not even listed in the function mask but at least some HP
|
||
|
laptops seem to require it to properly support s0ix.
|
||
|
|
||
|
Based on a patch from Marcin Bachry <hegel666@gmail.com>.
|
||
|
|
||
|
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1230
|
||
|
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||
|
Cc: Marcin Bachry <hegel666@gmail.com>
|
||
|
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/acpi/x86/s2idle.c | 7 +++++++
|
||
|
1 file changed, 7 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
|
||
|
index 2d7ddb8a8cb6..482e6b23b21a 100644
|
||
|
--- a/drivers/acpi/x86/s2idle.c
|
||
|
+++ b/drivers/acpi/x86/s2idle.c
|
||
|
@@ -368,6 +368,13 @@ static int lps0_device_attach(struct acpi_device *adev,
|
||
|
|
||
|
ACPI_FREE(out_obj);
|
||
|
|
||
|
+ /*
|
||
|
+ * Some HP laptops require ACPI_LPS0_ENTRY_AMD/ACPI_LPS0_EXIT_AMD for proper
|
||
|
+ * S0ix, but don't set the function mask correctly. Fix that up here.
|
||
|
+ */
|
||
|
+ if (acpi_s2idle_vendor_amd())
|
||
|
+ lps0_dsm_func_mask |= (1 << ACPI_LPS0_ENTRY_AMD) | (1 << ACPI_LPS0_EXIT_AMD);
|
||
|
+
|
||
|
acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n",
|
||
|
lps0_dsm_func_mask);
|
||
|
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From a91022f9251f063ca3f7f1a73af614b5b646a43e Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:35 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Fix command completion code
|
||
|
|
||
|
The protocol to submit a job request to SMU is to wait for
|
||
|
AMD_PMC_REGISTER_RESPONSE to return 1,meaning SMU is ready to take
|
||
|
requests. PMC driver has to make sure that the response code is always
|
||
|
AMD_PMC_RESULT_OK before making any command submissions.
|
||
|
|
||
|
Also, when we submit a message to SMU, we have to wait until it processes
|
||
|
the request. Adding a read_poll_timeout() check as this was missing in
|
||
|
the existing code.
|
||
|
|
||
|
Fixes: 156ec4731cb2 ("platform/x86: amd-pmc: Add AMD platform support for S2Idle")
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 10 +++++++++-
|
||
|
1 file changed, 9 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index 0b5578a8a449..535e431f98a8 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -140,7 +140,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
|
||
|
/* Wait until we get a valid response */
|
||
|
rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
|
||
|
- val, val > 0, PMC_MSG_DELAY_MIN_US,
|
||
|
+ val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
|
||
|
PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
|
||
|
if (rc) {
|
||
|
dev_err(dev->dev, "failed to talk to SMU\n");
|
||
|
@@ -156,6 +156,14 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
/* Write message ID to message ID register */
|
||
|
msg = (dev->cpu_id == AMD_CPU_ID_RN) ? MSG_OS_HINT_RN : MSG_OS_HINT_PCO;
|
||
|
amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg);
|
||
|
+ /* Wait until we get a valid response */
|
||
|
+ rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
|
||
|
+ val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
|
||
|
+ PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
|
||
|
+ if (rc) {
|
||
|
+ dev_err(dev->dev, "SMU response timed out\n");
|
||
|
+ return rc;
|
||
|
+ }
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 77f498db905e555187750157bd8db2430f7d1f74 Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:36 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Fix SMU firmware reporting mechanism
|
||
|
|
||
|
It was lately understood that the current mechanism available in the
|
||
|
driver to get SMU firmware info works only on internal SMU builds and
|
||
|
there is a separate way to get all the SMU logging counters (addressed
|
||
|
in the next patch). Hence remove all the smu info shown via debugfs as it
|
||
|
is no more useful.
|
||
|
|
||
|
Also, use dump registers routine only at one place i.e. after the command
|
||
|
submission to SMU is done.
|
||
|
|
||
|
Fixes: 156ec4731cb2 ("platform/x86: amd-pmc: Add AMD platform support for S2Idle")
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 15 +--------------
|
||
|
1 file changed, 1 insertion(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index 535e431f98a8..d32f0a0eeb9f 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -52,7 +52,6 @@
|
||
|
#define AMD_CPU_ID_PCO AMD_CPU_ID_RV
|
||
|
#define AMD_CPU_ID_CZN AMD_CPU_ID_RN
|
||
|
|
||
|
-#define AMD_SMU_FW_VERSION 0x0
|
||
|
#define PMC_MSG_DELAY_MIN_US 100
|
||
|
#define RESPONSE_REGISTER_LOOP_MAX 200
|
||
|
|
||
|
@@ -88,11 +87,6 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
|
||
|
#ifdef CONFIG_DEBUG_FS
|
||
|
static int smu_fw_info_show(struct seq_file *s, void *unused)
|
||
|
{
|
||
|
- struct amd_pmc_dev *dev = s->private;
|
||
|
- u32 value;
|
||
|
-
|
||
|
- value = ioread32(dev->smu_base + AMD_SMU_FW_VERSION);
|
||
|
- seq_printf(s, "SMU FW Info: %x\n", value);
|
||
|
return 0;
|
||
|
}
|
||
|
DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
|
||
|
@@ -164,6 +158,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
dev_err(dev->dev, "SMU response timed out\n");
|
||
|
return rc;
|
||
|
}
|
||
|
+ amd_pmc_dump_registers(dev);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -176,7 +171,6 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
|
||
|
if (rc)
|
||
|
dev_err(pdev->dev, "suspend failed\n");
|
||
|
|
||
|
- amd_pmc_dump_registers(pdev);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -189,7 +183,6 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
|
||
|
if (rc)
|
||
|
dev_err(pdev->dev, "resume failed\n");
|
||
|
|
||
|
- amd_pmc_dump_registers(pdev);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
@@ -256,17 +249,11 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||
|
pci_dev_put(rdev);
|
||
|
base_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
|
||
|
|
||
|
- dev->smu_base = devm_ioremap(dev->dev, base_addr, AMD_PMC_MAPPING_SIZE);
|
||
|
- if (!dev->smu_base)
|
||
|
- return -ENOMEM;
|
||
|
-
|
||
|
dev->regbase = devm_ioremap(dev->dev, base_addr + AMD_PMC_BASE_ADDR_OFFSET,
|
||
|
AMD_PMC_MAPPING_SIZE);
|
||
|
if (!dev->regbase)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
- amd_pmc_dump_registers(dev);
|
||
|
-
|
||
|
platform_set_drvdata(pdev, dev);
|
||
|
amd_pmc_dbgfs_register(dev);
|
||
|
return 0;
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From e711eb6e913357e1184ad8c7e23e1c3f2ede7494 Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:37 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Add support for logging SMU metrics
|
||
|
|
||
|
SMU provides a way to dump the s0ix debug statistics in the form of a
|
||
|
metrics table via a of set special mailbox commands.
|
||
|
|
||
|
Add support to the driver which can send these commands to SMU and expose
|
||
|
the information received via debugfs. The information contains the s0ix
|
||
|
entry/exit, active time of each IP block etc.
|
||
|
|
||
|
As a side note, SMU subsystem logging is not supported on Picasso based
|
||
|
SoC's.
|
||
|
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 148 +++++++++++++++++++++++++++++++--
|
||
|
1 file changed, 140 insertions(+), 8 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index d32f0a0eeb9f..b5249fdeb95f 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -46,6 +46,14 @@
|
||
|
#define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
|
||
|
#define AMD_PMC_RESULT_FAILED 0xFF
|
||
|
|
||
|
+/* SMU Message Definations */
|
||
|
+#define SMU_MSG_GETSMUVERSION 0x02
|
||
|
+#define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
|
||
|
+#define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05
|
||
|
+#define SMU_MSG_LOG_START 0x06
|
||
|
+#define SMU_MSG_LOG_RESET 0x07
|
||
|
+#define SMU_MSG_LOG_DUMP_DATA 0x08
|
||
|
+#define SMU_MSG_GET_SUP_CONSTRAINTS 0x09
|
||
|
/* List of supported CPU ids */
|
||
|
#define AMD_CPU_ID_RV 0x15D0
|
||
|
#define AMD_CPU_ID_RN 0x1630
|
||
|
@@ -55,17 +63,42 @@
|
||
|
#define PMC_MSG_DELAY_MIN_US 100
|
||
|
#define RESPONSE_REGISTER_LOOP_MAX 200
|
||
|
|
||
|
+#define SOC_SUBSYSTEM_IP_MAX 12
|
||
|
+#define DELAY_MIN_US 2000
|
||
|
+#define DELAY_MAX_US 3000
|
||
|
enum amd_pmc_def {
|
||
|
MSG_TEST = 0x01,
|
||
|
MSG_OS_HINT_PCO,
|
||
|
MSG_OS_HINT_RN,
|
||
|
};
|
||
|
|
||
|
+struct amd_pmc_bit_map {
|
||
|
+ const char *name;
|
||
|
+ u32 bit_mask;
|
||
|
+};
|
||
|
+
|
||
|
+static const struct amd_pmc_bit_map soc15_ip_blk[] = {
|
||
|
+ {"DISPLAY", BIT(0)},
|
||
|
+ {"CPU", BIT(1)},
|
||
|
+ {"GFX", BIT(2)},
|
||
|
+ {"VDD", BIT(3)},
|
||
|
+ {"ACP", BIT(4)},
|
||
|
+ {"VCN", BIT(5)},
|
||
|
+ {"ISP", BIT(6)},
|
||
|
+ {"NBIO", BIT(7)},
|
||
|
+ {"DF", BIT(8)},
|
||
|
+ {"USB0", BIT(9)},
|
||
|
+ {"USB1", BIT(10)},
|
||
|
+ {"LAPIC", BIT(11)},
|
||
|
+ {}
|
||
|
+};
|
||
|
+
|
||
|
struct amd_pmc_dev {
|
||
|
void __iomem *regbase;
|
||
|
- void __iomem *smu_base;
|
||
|
+ void __iomem *smu_virt_addr;
|
||
|
u32 base_addr;
|
||
|
u32 cpu_id;
|
||
|
+ u32 active_ips;
|
||
|
struct device *dev;
|
||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||
|
struct dentry *dbgfs_dir;
|
||
|
@@ -73,6 +106,7 @@ struct amd_pmc_dev {
|
||
|
};
|
||
|
|
||
|
static struct amd_pmc_dev pmc;
|
||
|
+static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret);
|
||
|
|
||
|
static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
|
||
|
{
|
||
|
@@ -84,9 +118,50 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
|
||
|
iowrite32(val, dev->regbase + reg_offset);
|
||
|
}
|
||
|
|
||
|
+struct smu_metrics {
|
||
|
+ u32 table_version;
|
||
|
+ u32 hint_count;
|
||
|
+ u32 s0i3_cyclecount;
|
||
|
+ u32 timein_s0i2;
|
||
|
+ u64 timeentering_s0i3_lastcapture;
|
||
|
+ u64 timeentering_s0i3_totaltime;
|
||
|
+ u64 timeto_resume_to_os_lastcapture;
|
||
|
+ u64 timeto_resume_to_os_totaltime;
|
||
|
+ u64 timein_s0i3_lastcapture;
|
||
|
+ u64 timein_s0i3_totaltime;
|
||
|
+ u64 timein_swdrips_lastcapture;
|
||
|
+ u64 timein_swdrips_totaltime;
|
||
|
+ u64 timecondition_notmet_lastcapture[SOC_SUBSYSTEM_IP_MAX];
|
||
|
+ u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX];
|
||
|
+} __packed;
|
||
|
+
|
||
|
#ifdef CONFIG_DEBUG_FS
|
||
|
static int smu_fw_info_show(struct seq_file *s, void *unused)
|
||
|
{
|
||
|
+ struct amd_pmc_dev *dev = s->private;
|
||
|
+ struct smu_metrics table;
|
||
|
+ u32 value;
|
||
|
+ int idx;
|
||
|
+
|
||
|
+ if (dev->cpu_id == AMD_CPU_ID_PCO)
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ memcpy_fromio(&table, dev->smu_virt_addr, sizeof(struct smu_metrics));
|
||
|
+
|
||
|
+ seq_puts(s, "\n=== SMU Statistics ===\n");
|
||
|
+ seq_printf(s, "Table Version: %d\n", table.table_version);
|
||
|
+ seq_printf(s, "Hint Count: %d\n", table.hint_count);
|
||
|
+ seq_printf(s, "S0i3 Cycle Count: %d\n", table.s0i3_cyclecount);
|
||
|
+ seq_printf(s, "Time (in us) to S0i3: %lld\n", table.timeentering_s0i3_lastcapture);
|
||
|
+ seq_printf(s, "Time (in us) in S0i3: %lld\n", table.timein_s0i3_lastcapture);
|
||
|
+
|
||
|
+ seq_puts(s, "\n=== Active time (in us) ===\n");
|
||
|
+ for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
|
||
|
+ if (soc15_ip_blk[idx].bit_mask & dev->active_ips)
|
||
|
+ seq_printf(s, "%-8s : %lld\n", soc15_ip_blk[idx].name,
|
||
|
+ table.timecondition_notmet_lastcapture[idx]);
|
||
|
+ }
|
||
|
+
|
||
|
return 0;
|
||
|
}
|
||
|
DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
|
||
|
@@ -112,6 +187,32 @@ static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
|
||
|
}
|
||
|
#endif /* CONFIG_DEBUG_FS */
|
||
|
|
||
|
+static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
|
||
|
+{
|
||
|
+ u32 phys_addr_low, phys_addr_hi;
|
||
|
+ u64 smu_phys_addr;
|
||
|
+
|
||
|
+ if (dev->cpu_id == AMD_CPU_ID_PCO)
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ /* Get Active devices list from SMU */
|
||
|
+ amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, 1);
|
||
|
+
|
||
|
+ /* Get dram address */
|
||
|
+ amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, 1);
|
||
|
+ amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, 1);
|
||
|
+ smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
|
||
|
+
|
||
|
+ dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr, sizeof(struct smu_metrics));
|
||
|
+ if (!dev->smu_virt_addr)
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
+ /* Start the logging */
|
||
|
+ amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, 0);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
|
||
|
{
|
||
|
u32 value;
|
||
|
@@ -126,10 +227,9 @@ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
|
||
|
dev_dbg(dev->dev, "AMD_PMC_REGISTER_MESSAGE:%x\n", value);
|
||
|
}
|
||
|
|
||
|
-static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
+static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg, bool ret)
|
||
|
{
|
||
|
int rc;
|
||
|
- u8 msg;
|
||
|
u32 val;
|
||
|
|
||
|
/* Wait until we get a valid response */
|
||
|
@@ -148,8 +248,8 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set);
|
||
|
|
||
|
/* Write message ID to message ID register */
|
||
|
- msg = (dev->cpu_id == AMD_CPU_ID_RN) ? MSG_OS_HINT_RN : MSG_OS_HINT_PCO;
|
||
|
amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg);
|
||
|
+
|
||
|
/* Wait until we get a valid response */
|
||
|
rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
|
||
|
val, val == AMD_PMC_RESULT_OK, PMC_MSG_DELAY_MIN_US,
|
||
|
@@ -158,16 +258,40 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set)
|
||
|
dev_err(dev->dev, "SMU response timed out\n");
|
||
|
return rc;
|
||
|
}
|
||
|
+
|
||
|
+ if (ret) {
|
||
|
+ /* PMFW may take longer time to return back the data */
|
||
|
+ usleep_range(DELAY_MIN_US, 10 * DELAY_MAX_US);
|
||
|
+ *data = amd_pmc_reg_read(dev, AMD_PMC_REGISTER_ARGUMENT);
|
||
|
+ }
|
||
|
+
|
||
|
amd_pmc_dump_registers(dev);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
|
||
|
+{
|
||
|
+ switch (dev->cpu_id) {
|
||
|
+ case AMD_CPU_ID_PCO:
|
||
|
+ return MSG_OS_HINT_PCO;
|
||
|
+ case AMD_CPU_ID_RN:
|
||
|
+ return MSG_OS_HINT_RN;
|
||
|
+ }
|
||
|
+ return -EINVAL;
|
||
|
+}
|
||
|
+
|
||
|
static int __maybe_unused amd_pmc_suspend(struct device *dev)
|
||
|
{
|
||
|
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
||
|
int rc;
|
||
|
+ u8 msg;
|
||
|
+
|
||
|
+ /* Reset and Start SMU logging - to monitor the s0i3 stats */
|
||
|
+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_RESET, 0);
|
||
|
+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_START, 0);
|
||
|
|
||
|
- rc = amd_pmc_send_cmd(pdev, 1);
|
||
|
+ msg = amd_pmc_get_os_hint(pdev);
|
||
|
+ rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0);
|
||
|
if (rc)
|
||
|
dev_err(pdev->dev, "suspend failed\n");
|
||
|
|
||
|
@@ -178,8 +302,13 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
|
||
|
{
|
||
|
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
||
|
int rc;
|
||
|
+ u8 msg;
|
||
|
+
|
||
|
+ /* Let SMU know that we are looking for stats */
|
||
|
+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
|
||
|
|
||
|
- rc = amd_pmc_send_cmd(pdev, 0);
|
||
|
+ msg = amd_pmc_get_os_hint(pdev);
|
||
|
+ rc = amd_pmc_send_cmd(pdev, 0, NULL, msg, 0);
|
||
|
if (rc)
|
||
|
dev_err(pdev->dev, "resume failed\n");
|
||
|
|
||
|
@@ -202,8 +331,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||
|
{
|
||
|
struct amd_pmc_dev *dev = &pmc;
|
||
|
struct pci_dev *rdev;
|
||
|
- u32 base_addr_lo;
|
||
|
- u32 base_addr_hi;
|
||
|
+ u32 base_addr_lo, base_addr_hi;
|
||
|
u64 base_addr;
|
||
|
int err;
|
||
|
u32 val;
|
||
|
@@ -254,6 +382,10 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||
|
if (!dev->regbase)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
+ /* Use SMU to get the s0i3 debug stats */
|
||
|
+ err = amd_pmc_setup_smu_logging(dev);
|
||
|
+ if (err)
|
||
|
+ dev_err(dev->dev, "SMU debugging info not supported on this platform\n");
|
||
|
platform_set_drvdata(pdev, dev);
|
||
|
amd_pmc_dbgfs_register(dev);
|
||
|
return 0;
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 88a2ccda674ec50c98a946f0801fdaa93628c280 Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:38 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Add support for logging s0ix counters
|
||
|
|
||
|
Even the FCH SSC registers provides certain level of information
|
||
|
about the s0ix entry and exit times which comes handy when the SMU
|
||
|
fails to report the statistics via the mailbox communication.
|
||
|
|
||
|
This information is captured via a new debugfs file "s0ix_stats".
|
||
|
A non-zero entry in this counters would mean that the system entered
|
||
|
the s0ix state.
|
||
|
|
||
|
If s0ix entry time and exit time don't change during suspend to idle,
|
||
|
the silicon has not entered the deepest state.
|
||
|
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 46 ++++++++++++++++++++++++++++++++--
|
||
|
1 file changed, 44 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index b5249fdeb95f..b6ad290c9a86 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -46,6 +46,15 @@
|
||
|
#define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
|
||
|
#define AMD_PMC_RESULT_FAILED 0xFF
|
||
|
|
||
|
+/* FCH SSC Registers */
|
||
|
+#define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30
|
||
|
+#define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34
|
||
|
+#define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38
|
||
|
+#define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C
|
||
|
+#define FCH_SSC_MAPPING_SIZE 0x800
|
||
|
+#define FCH_BASE_PHY_ADDR_LOW 0xFED81100
|
||
|
+#define FCH_BASE_PHY_ADDR_HIGH 0x00000000
|
||
|
+
|
||
|
/* SMU Message Definations */
|
||
|
#define SMU_MSG_GETSMUVERSION 0x02
|
||
|
#define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
|
||
|
@@ -96,6 +105,7 @@ static const struct amd_pmc_bit_map soc15_ip_blk[] = {
|
||
|
struct amd_pmc_dev {
|
||
|
void __iomem *regbase;
|
||
|
void __iomem *smu_virt_addr;
|
||
|
+ void __iomem *fch_virt_addr;
|
||
|
u32 base_addr;
|
||
|
u32 cpu_id;
|
||
|
u32 active_ips;
|
||
|
@@ -140,7 +150,6 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
|
||
|
{
|
||
|
struct amd_pmc_dev *dev = s->private;
|
||
|
struct smu_metrics table;
|
||
|
- u32 value;
|
||
|
int idx;
|
||
|
|
||
|
if (dev->cpu_id == AMD_CPU_ID_PCO)
|
||
|
@@ -166,6 +175,29 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
|
||
|
}
|
||
|
DEFINE_SHOW_ATTRIBUTE(smu_fw_info);
|
||
|
|
||
|
+static int s0ix_stats_show(struct seq_file *s, void *unused)
|
||
|
+{
|
||
|
+ struct amd_pmc_dev *dev = s->private;
|
||
|
+ u64 entry_time, exit_time, residency;
|
||
|
+
|
||
|
+ entry_time = ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_H_OFFSET);
|
||
|
+ entry_time = entry_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_ENTRY_TIME_L_OFFSET);
|
||
|
+
|
||
|
+ exit_time = ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_H_OFFSET);
|
||
|
+ exit_time = exit_time << 32 | ioread32(dev->fch_virt_addr + FCH_S0I3_EXIT_TIME_L_OFFSET);
|
||
|
+
|
||
|
+ /* It's in 48MHz. We need to convert it to unit of 100ns */
|
||
|
+ residency = (exit_time - entry_time) * 10 / 48;
|
||
|
+
|
||
|
+ seq_puts(s, "=== S0ix statistics ===\n");
|
||
|
+ seq_printf(s, "S0ix Entry Time: %lld\n", entry_time);
|
||
|
+ seq_printf(s, "S0ix Exit Time: %lld\n", exit_time);
|
||
|
+ seq_printf(s, "Residency Time: %lld\n", residency);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
|
||
|
+
|
||
|
static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
|
||
|
{
|
||
|
debugfs_remove_recursive(dev->dbgfs_dir);
|
||
|
@@ -176,6 +208,8 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
|
||
|
dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL);
|
||
|
debugfs_create_file("smu_fw_info", 0644, dev->dbgfs_dir, dev,
|
||
|
&smu_fw_info_fops);
|
||
|
+ debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
|
||
|
+ &s0ix_stats_fops);
|
||
|
}
|
||
|
#else
|
||
|
static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
|
||
|
@@ -332,7 +366,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||
|
struct amd_pmc_dev *dev = &pmc;
|
||
|
struct pci_dev *rdev;
|
||
|
u32 base_addr_lo, base_addr_hi;
|
||
|
- u64 base_addr;
|
||
|
+ u64 base_addr, fch_phys_addr;
|
||
|
int err;
|
||
|
u32 val;
|
||
|
|
||
|
@@ -382,6 +416,14 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||
|
if (!dev->regbase)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
+ /* Use FCH registers to get the S0ix stats */
|
||
|
+ base_addr_lo = FCH_BASE_PHY_ADDR_LOW;
|
||
|
+ base_addr_hi = FCH_BASE_PHY_ADDR_HIGH;
|
||
|
+ fch_phys_addr = ((u64)base_addr_hi << 32 | base_addr_lo);
|
||
|
+ dev->fch_virt_addr = devm_ioremap(dev->dev, fch_phys_addr, FCH_SSC_MAPPING_SIZE);
|
||
|
+ if (!dev->fch_virt_addr)
|
||
|
+ return -ENOMEM;
|
||
|
+
|
||
|
/* Use SMU to get the s0i3 debug stats */
|
||
|
err = amd_pmc_setup_smu_logging(dev);
|
||
|
if (err)
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 58dde84a288df2fc20ff2827a6b16b10e7eaff08 Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:39 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Add support for ACPI ID AMDI0006
|
||
|
|
||
|
Some newer BIOSes have added another ACPI ID for the uPEP device.
|
||
|
SMU statistics behave identically on this device.
|
||
|
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 1 +
|
||
|
1 file changed, 1 insertion(+)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index b6ad290c9a86..2a73fe0deaf3 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -443,6 +443,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
|
||
|
|
||
|
static const struct acpi_device_id amd_pmc_acpi_ids[] = {
|
||
|
{"AMDI0005", 0},
|
||
|
+ {"AMDI0006", 0},
|
||
|
{"AMD0004", 0},
|
||
|
{"AMD0005", 0},
|
||
|
{ }
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 0e20c11aebedea83412eedc37da665f096d9c12d Mon Sep 17 00:00:00 2001
|
||
|
From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 17:00:40 +0530
|
||
|
Subject: [PATCH] platform/x86: amd-pmc: Add new acpi id for future PMC
|
||
|
controllers
|
||
|
|
||
|
The upcoming PMC controller would have a newer acpi id, add that to
|
||
|
the supported acpid device list.
|
||
|
|
||
|
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/platform/x86/amd-pmc.c | 4 ++++
|
||
|
1 file changed, 4 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
|
||
|
index 2a73fe0deaf3..5a2be598fc2e 100644
|
||
|
--- a/drivers/platform/x86/amd-pmc.c
|
||
|
+++ b/drivers/platform/x86/amd-pmc.c
|
||
|
@@ -68,6 +68,7 @@
|
||
|
#define AMD_CPU_ID_RN 0x1630
|
||
|
#define AMD_CPU_ID_PCO AMD_CPU_ID_RV
|
||
|
#define AMD_CPU_ID_CZN AMD_CPU_ID_RN
|
||
|
+#define AMD_CPU_ID_YC 0x14B5
|
||
|
|
||
|
#define PMC_MSG_DELAY_MIN_US 100
|
||
|
#define RESPONSE_REGISTER_LOOP_MAX 200
|
||
|
@@ -309,6 +310,7 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
|
||
|
case AMD_CPU_ID_PCO:
|
||
|
return MSG_OS_HINT_PCO;
|
||
|
case AMD_CPU_ID_RN:
|
||
|
+ case AMD_CPU_ID_YC:
|
||
|
return MSG_OS_HINT_RN;
|
||
|
}
|
||
|
return -EINVAL;
|
||
|
@@ -354,6 +356,7 @@ static const struct dev_pm_ops amd_pmc_pm_ops = {
|
||
|
};
|
||
|
|
||
|
static const struct pci_device_id pmc_pci_ids[] = {
|
||
|
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_YC) },
|
||
|
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_CZN) },
|
||
|
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RN) },
|
||
|
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) },
|
||
|
@@ -444,6 +447,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
|
||
|
static const struct acpi_device_id amd_pmc_acpi_ids[] = {
|
||
|
{"AMDI0005", 0},
|
||
|
{"AMDI0006", 0},
|
||
|
+ {"AMDI0007", 0},
|
||
|
{"AMD0004", 0},
|
||
|
{"AMD0005", 0},
|
||
|
{ }
|
||
|
--
|
||
|
2.32.0
|
||
|
|
||
|
From 3020f6c4637a7fecb94866eb633719898308e07b Mon Sep 17 00:00:00 2001
|
||
|
From: Pratik Vishwakarma <Pratik.Vishwakarma@amd.com>
|
||
|
Date: Thu, 17 Jun 2021 11:42:08 -0500
|
||
|
Subject: [PATCH] ACPI: PM: s2idle: Use correct revision id
|
||
|
|
||
|
AMD spec mentions only revision 0. With this change,
|
||
|
device constraint list is populated properly.
|
||
|
|
||
|
Signed-off-by: Pratik Vishwakarma <Pratik.Vishwakarma@amd.com>
|
||
|
Patchset: amd-s0ix
|
||
|
---
|
||
|
drivers/acpi/x86/s2idle.c | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
|
||
|
index 482e6b23b21a..4339e6da0dd6 100644
|
||
|
--- a/drivers/acpi/x86/s2idle.c
|
||
|
+++ b/drivers/acpi/x86/s2idle.c
|
||
|
@@ -96,7 +96,7 @@ static void lpi_device_get_constraints_amd(void)
|
||
|
int i, j, k;
|
||
|
|
||
|
out_obj = acpi_evaluate_dsm_typed(lps0_device_handle, &lps0_dsm_guid,
|
||
|
- 1, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
|
||
|
+ rev_id, ACPI_LPS0_GET_DEVICE_CONSTRAINTS,
|
||
|
NULL, ACPI_TYPE_PACKAGE);
|
||
|
|
||
|
if (!out_obj)
|
||
|
--
|
||
|
2.32.0
|
||
|
|