aboutsummarylogtreecommitdiffstats
path: root/9001-v5.15-s0ix-patch-2021-11-04.patch
diff options
context:
space:
mode:
authorScott B2021-11-19 16:47:59 -0800
committerScott B2021-11-20 22:50:39 -0800
commit56212d137f3b19eefa757304c5454b61d256bc0b (patch)
tree1b579c5d22c707215d5bb4876e5f2cd94da5cc2c /9001-v5.15-s0ix-patch-2021-11-04.patch
parent453d4234b2e4140da70a9078bf12fea2b34680fa (diff)
downloadaur-56212d137f3b19eefa757304c5454b61d256bc0b.tar.gz
s0ix: update patches
Diffstat (limited to '9001-v5.15-s0ix-patch-2021-11-04.patch')
-rw-r--r--9001-v5.15-s0ix-patch-2021-11-04.patch1032
1 files changed, 0 insertions, 1032 deletions
diff --git a/9001-v5.15-s0ix-patch-2021-11-04.patch b/9001-v5.15-s0ix-patch-2021-11-04.patch
deleted file mode 100644
index e355d4a73d85..000000000000
--- a/9001-v5.15-s0ix-patch-2021-11-04.patch
+++ /dev/null
@@ -1,1032 +0,0 @@
-From 453ac7e441998d9fbd48e56506bdd6f697f85736 Mon Sep 17 00:00:00 2001
-From: Scott B <arglebargle@arglebargle.dev>
-Date: Thu, 4 Nov 2021 20:03:10 -0700
-Subject: [PATCH] v5.15 s0ix patch 2021-11-04
-
-Squashed commit of the following:
-
-commit 6bdd54fa7d0770fcfdde3a969876ed54673cfdd5
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Tue Sep 28 11:00:40 2021 -0500
-
- platform/x86: amd-pmc: explicitly check for GFXOFF mask (!SEE NOTES!)
-
- NOTE: This patch needs manual merging due to prior changes, see
- "platform/x86: amd-pmc: Fix compilation when CONFIG_DEBUGFS is disabled"
- https://git.kernel.org/pdx86/platform-drivers-x86/c/40635cd32f0d83573a558dc30e9ba3469e769249
- and "platform/x86: amd-pmc: Add support for AMD Smart Trace Buffer"
-
- (This patch is for testing only and should not be upstreamed in
- this state)
-
- Explicitly check the value of GFXOFF before setting OS_HINT. If
- it's not valid, continue retrying to read it - for up to 2 seconds.
-
- If it's still not valid, abort the suspend routine.
-
- Possible outcomes:
- * If this makes all failed suspends "go away" 100% success -> there is
- a timing problem remaining in amdgpu as it pertains to when GFXOFF is
- set relative to when AMD_PMC sends OS_HINT
-
- There should be a message "gfxoff not asserted retrying"
- * If the suspend entry fails now with "gfxoff not asserted after 2000000us"
- -> GFXOFF is also a symptom and not the root cause of failed s0i3 entry
-
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
- Change-Id: Ic3a1ed188abad21f94c8dd82c2eeed43117b1dbe
-
-commit 4ccffecb1210fd7b38e1b584b35d00d52fe685dc
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Oct 28 17:09:35 2021 +0530
-
- platform/x86: amd-pmc: Add support for AMD Smart Trace Buffer (v5)
-
- STB (Smart Trace Buffer), is a debug trace buffer which is used to help
- isolate failures by analyzing the last feature that a system was running
- before hitting a failure. This nonintrusive way is always running in the
- background and trace is stored into the SoC.
-
- This patch provides mechanism to access the STB buffer using the read
- and write routines.
-
- Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
-
-commit c76c8b2d6497dcc828fbb5ca1c1a24b456feab52
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Oct 28 17:09:34 2021 +0530
-
- platform/x86: amd-pmc: Store the pci_dev instance inside struct amd_pmc_dev
-
- Store the root port information in amd_pmc_probe() so that the
- information can be used across multiple routines.
-
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
-
-commit eb36880e53d06c51941c8760e951e455d2b4dc92
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Oct 28 17:09:33 2021 +0530
-
- platform/x86: amd-pmc: Simplify error handling path
-
- Handle error-exits in the amd_pmc_probe() so that the code duplication
- is reduced.
-
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
-
-commit d7245e84b1abd655c34276c34b46e22786e196b0
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Sun Oct 31 20:48:53 2021 -0500
-
- pinctrl: amd: Fix wakeups when IRQ is shared with SCI (v7)
-
- On some Lenovo AMD Gen2 platforms the IRQ for the SCI and pinctrl drivers
- are shared. Due to how the s2idle loop handling works, this case needs
- an extra explicit check whether the interrupt was caused by SCI or by
- the GPIO controller.
-
- To fix this rework the existing IRQ handler function to function as a
- checker and an IRQ handler depending on the calling arguments.
-
- BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1738
- Reported-by: Joerie de Gram <j.de.gram@gmail.com>
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
- Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
-
-commit e63e24d5c814734ea52e21d85054ee98fa56fa0f
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Fri Oct 29 15:40:16 2021 -0500
-
- ACPI: Add stubs for wakeup handler functions
-
- The commit ddfd9dcf270c ("ACPI: PM: Add acpi_[un]register_wakeup_handler()")
- added new functions for drivers to use during the s2idle wakeup path, but
- didn't add stubs for when CONFIG_ACPI wasn't set.
-
- Add those stubs in for other drivers to be able to use.
-
- Fixes: ddfd9dcf270c ("ACPI: PM: Add acpi_[un]register_wakeup_handler()")
- Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 8f1609f26f32b629304f8fee5ff359c58e5eade0
-Author: Hans de Goede <hdegoede@redhat.com>
-Date: Tue Nov 2 16:32:56 2021 +0100
-
- platform/x86: amd-pmc: Make CONFIG_AMD_PMC depend on RTC_CLASS
-
- Since the "Add special handling for timer based S0i3 wakeup" changes
- the amd-pmc code now relies on symbols from the RTC-class code,
- add a dependency for this to Kconfig.
-
- Fixes: 59348401ebed ("platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup")
- Cc: Mario Limonciello <mario.limonciello@amd.com>
- Reported-by: Randy Dunlap <rdunlap@infradead.org>
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
- Acked-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 4016da45040d2625a8cf822bc02091ca16d36409
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Tue Oct 26 12:14:43 2021 -0500
-
- platform/x86: amd-pmc: Drop check for valid alarm time
-
- This is already checked when calling rtc_read_alarm.
-
- Suggested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit eac1b32f6cce4a8b416029fbaa0b9218353583fd
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Tue Oct 26 12:14:42 2021 -0500
-
- platform/x86: amd-pmc: Downgrade dev_info message to dev_dbg
-
- For the majority of users this information will not be informative
- as they've chosen to program the RTC before going to sleep.
-
- Suggested-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 6c12d3aba8789b49bc4b82d76e905e4d1a84bbb9
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Tue Oct 26 12:14:41 2021 -0500
-
- platform/x86: amd-pmc: fix compilation without CONFIG_RTC_SYSTOHC_DEVICE
-
- If the configuration hasn't specified this parameter the rest of the new
- RTC functionality should just be ignored.
-
- Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
- Suggested-by: Hans de Goede <hdegoede@redhat.com>
- Fixes: 59348401ebed ("platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup")
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 6ac4a98e4ca2b1dcb72e49de93211acb9f399f1e
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Wed Oct 20 11:29:46 2021 -0500
-
- platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup
-
- RTC based wakeup from s0i3 doesn't work properly on some Green Sardine
- platforms. Because of this, a newer SMU for Green Sardine has the ability
- to pass wakeup time as argument of the upper 16 bits of OS_HINT message.
-
- With older firmware setting the timer value in OS_HINT will cause firmware
- to reject the hint, so only run this path on:
- 1) Green Sardine
- 2) Minimum SMU FW
- 3) RTC alarm armed during s0i3 entry
-
- Using this method has some limitations that the s0i3 wakeup will need to
- be between 4 seconds and 18 hours, so check those boundary conditions as
- well and abort the suspend if RTC is armed for too short or too long of a
- duration.
-
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit b7f215dee5b17eb26ff39c09fcf5dcc3b55c5570
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Wed Oct 20 11:29:45 2021 -0500
-
- platform/x86: amd-pmc: adjust arguments for `amd_pmc_send_cmd`
-
- Currently the "argument" for the "message" is listed as a boolean
- value. This works well for the commands used currently, but an
- additional upcoming command will pass more data in the message.
-
- Expand it to be a full 32 bit value.
-
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit c738c0930b1e8edc8a0f3425de9342cea0b7bfc0
-Author: Scott B <arglebargle@arglebargle.dev>
-Date: Thu Oct 14 02:22:21 2021 -0700
-
- TEST: Replaces "don't wait to signal GFXOFF"
-
- replacement for 4df3adab896f843afe5bca5960fbca6ff2cc407e per lijo lazar
- see: https://gitlab.freedesktop.org/drm/amd/-/issues/1710#note_1102805
-
-commit 326ad78248530c566707ec74241d7f64d70199d1
-Author: Scott B <arglebargle@arglebargle.dev>
-Date: Thu Oct 14 02:16:16 2021 -0700
-
- Revert "drm/amdgpu: During s0ix don't wait to signal GFXOFF"
-
- This reverts commit 4df3adab896f843afe5bca5960fbca6ff2cc407e.
-
-commit bacdd913c9f333f1075bf8b8e26ca0fca0ba93a2
-Author: Hans de Goede <hdegoede@redhat.com>
-Date: Tue Sep 28 16:21:22 2021 +0200
-
- platform/x86: amd-pmc: Fix compilation when CONFIG_DEBUGFS is disabled
-
- The amd_pmc_get_smu_version() and amd_pmc_idlemask_read() functions are
- used in the probe / suspend/resume code, so they are also used when
- CONFIG_DEBUGFS is disabled, move them outside of the #ifdef CONFIG_DEBUGFS
- block.
-
- Note this purely moves the code to above the #ifdef CONFIG_DEBUGFS,
- the code is completely unchanged.
-
- Cc: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Cc: Sanket Goswami <Sanket.Goswami@amd.com>
- Reported-by: Nathan Chancellor <nathan@kernel.org>
- Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-
-commit c93d488a712caa8c08b11802bf02305f2a157199
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Fri Sep 24 12:32:06 2021 -0500
-
- ACPI: PM: s2idle: Don't report missing devices as failing constraints
-
- ACPI tables may have entries for devices that are not physically
- present but that can be connected. These devices shouldn't cause
- constraints checking to fail.
-
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
- Change-Id: I34f5ca978aab69ff0a0906191eec21649b19fe27
-
-commit d2b71a18d8ae450d26d2a475dc5bda28da09919e
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Tue Sep 21 17:30:20 2021 +0530
-
- platform/x86: amd-pmc: Add a message to print resume time info
-
- Add a message to print the resume time information obtained from the
- smu_metrics structure.
-
- Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
-
-commit d9eb018a52af1451a72389b76326f5246a67c543
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Tue Sep 21 17:29:10 2021 +0530
-
- platform/x86: amd-pmc: Send command to dump data after clearing OS_HINT
-
- It was reported that the resume stats received from the firmware are
- always zero. This happens because the SMU expects the driver to send the
- command to dump the log data after clearing the OS_HINT.
-
- Adjust the order of the commands sent to SMU.
-
- Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
-
-commit 4851b6540bd2fbae04435179be8f3ba2e46174f1
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Sep 16 18:11:30 2021 +0530
-
- platform/x86: amd-pmc: Check s0i3 cycle status
-
- As the PM firmware returns the status of the last s0i3 in the smu_metrics
- structure, the existing name "s0i3_cyclecount" seems to be a misnomer.
- Change it accordingly to "s0i3_last_entry_status".
-
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
- Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
-
-commit 053bd7d9cf67f78c37559ff3f63292065b788df9
-Author: Sanket Goswami <Sanket.Goswami@amd.com>
-Date: Thu Sep 16 18:10:02 2021 +0530
-
- platform/x86: amd-pmc: Export Idlemask values based on the APU
-
- IdleMask is the metric used by the PM firmware to know the status of each
- of the Hardware IP blocks monitored by the PM firmware.
-
- Knowing this value is key to get the information of s2idle suspend/resume
- status. This value is mapped to PMC scratch registers, retrieve them
- accordingly based on the CPU family and the underlying firmware support.
-
- Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
- Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
- Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
-
-commit 5ba1eb1a6352b5c835b8a876f0e924c561be7c3e
-Author: Mario Limonciello <mario.limonciello@amd.com>
-Date: Wed Sep 15 16:52:16 2021 -0500
-
- ACPI: processor idle: Allow playing dead in C3
-
- commit 1a022e3f1be1 ("idle, x86: Allow off-lined CPU to enter
- deeper C states") originally allowed offlined CPUs to play dead
- up to ACPI C2. Although this improves power consumption of offlined
- CPUs, it does not allow the CPUs to get into the deepest state
- on AMD platforms blocking s0i3 entry.
-
- BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1708
- Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
----
- drivers/acpi/processor_idle.c | 3 +-
- drivers/acpi/x86/s2idle.c | 6 +
- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 +-
- .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 2 +
- drivers/pinctrl/pinctrl-amd.c | 29 +-
- drivers/platform/x86/Kconfig | 2 +-
- drivers/platform/x86/amd-pmc.c | 322 ++++++++++++++++--
- include/linux/acpi.h | 9 +
- 8 files changed, 351 insertions(+), 36 deletions(-)
-
-diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
-index f37fba9e5ba0..9d378dc9e928 100644
---- a/drivers/acpi/processor_idle.c
-+++ b/drivers/acpi/processor_idle.c
-@@ -789,7 +789,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr)
- state->enter = acpi_idle_enter;
-
- state->flags = 0;
-- if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) {
-+ if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2
-+ || cx->type == ACPI_STATE_C3) {
- state->enter_dead = acpi_idle_play_dead;
- drv->safe_state_index = count;
- }
-diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
-index 1c48358b43ba..0b65d4623214 100644
---- a/drivers/acpi/x86/s2idle.c
-+++ b/drivers/acpi/x86/s2idle.c
-@@ -309,6 +309,12 @@ static void lpi_check_constraints(void)
- continue;
- }
-
-+ if (!acpi_get_first_physical_node(adev)) {
-+ acpi_handle_debug(handle, "LPI: Device is not physically present\n");
-+ lpi_constraints_table[i].handle = NULL;
-+ continue;
-+ }
-+
- if (adev->power.state < lpi_constraints_table[i].min_dstate)
- acpi_handle_info(handle,
- "LPI: Constraint not met; min power state:%s current power state:%s\n",
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-index 1916ec84dd71..e7f06bd0f0cd 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
-@@ -31,8 +31,6 @@
- /* delay 0.1 second to enable gfx off feature */
- #define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(100)
-
--#define GFX_OFF_NO_DELAY 0
--
- /*
- * GPU GFX IP block helpers function.
- */
-@@ -560,8 +558,6 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
-
- void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
- {
-- unsigned long delay = GFX_OFF_DELAY_ENABLE;
--
- if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
- return;
-
-@@ -577,14 +573,8 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
-
- adev->gfx.gfx_off_req_count--;
-
-- if (adev->gfx.gfx_off_req_count == 0 &&
-- !adev->gfx.gfx_off_state) {
-- /* If going to s2idle, no need to wait */
-- if (adev->in_s0ix)
-- delay = GFX_OFF_NO_DELAY;
-- schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
-- delay);
-- }
-+ if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
-+ schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
- } else {
- if (adev->gfx.gfx_off_req_count == 0) {
- cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
-diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
-index 145f13b8c977..25d9e5b22cd3 100644
---- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
-+++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
-@@ -1378,6 +1378,8 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
-
- static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
- {
-+ if (state == sGpuChangeState_D3Entry)
-+ smu_v12_0_gfx_off_control(smu, true);
-
- return 0;
- }
-diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
-index bae9d429b813..ecab9064a845 100644
---- a/drivers/pinctrl/pinctrl-amd.c
-+++ b/drivers/pinctrl/pinctrl-amd.c
-@@ -598,14 +598,14 @@ static struct irq_chip amd_gpio_irqchip = {
-
- #define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
-
--static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
-+static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
- {
- struct amd_gpio *gpio_dev = dev_id;
- struct gpio_chip *gc = &gpio_dev->gc;
-- irqreturn_t ret = IRQ_NONE;
- unsigned int i, irqnr;
- unsigned long flags;
- u32 __iomem *regs;
-+ bool ret = false;
- u32 regval;
- u64 status, mask;
-
-@@ -627,6 +627,14 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
- /* Each status bit covers four pins */
- for (i = 0; i < 4; i++) {
- regval = readl(regs + i);
-+ /* caused wake on resume context for shared IRQ */
-+ if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) {
-+ dev_dbg(&gpio_dev->pdev->dev,
-+ "Waking due to GPIO %d: 0x%x",
-+ irqnr + i, regval);
-+ return true;
-+ }
-+
- if (!(regval & PIN_IRQ_PENDING) ||
- !(regval & BIT(INTERRUPT_MASK_OFF)))
- continue;
-@@ -650,9 +658,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
- }
- writel(regval, regs + i);
- raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
-- ret = IRQ_HANDLED;
-+ ret = true;
- }
- }
-+ /* did not cause wake on resume context for shared IRQ */
-+ if (irq < 0)
-+ return false;
-
- /* Signal EOI to the GPIO unit */
- raw_spin_lock_irqsave(&gpio_dev->lock, flags);
-@@ -664,6 +675,16 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
- return ret;
- }
-
-+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
-+{
-+ return IRQ_RETVAL(do_amd_gpio_irq_handler(irq, dev_id));
-+}
-+
-+static bool __maybe_unused amd_gpio_check_wake(void *dev_id)
-+{
-+ return do_amd_gpio_irq_handler(-1, dev_id);
-+}
-+
- static int amd_get_groups_count(struct pinctrl_dev *pctldev)
- {
- struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
-@@ -1033,6 +1054,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
- goto out2;
-
- platform_set_drvdata(pdev, gpio_dev);
-+ acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
-
- dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
- return ret;
-@@ -1050,6 +1072,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
- gpio_dev = platform_get_drvdata(pdev);
-
- gpiochip_remove(&gpio_dev->gc);
-+ acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
-
- return 0;
- }
-diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
-index e21ea3d23e6f..4cc2782635ec 100644
---- a/drivers/platform/x86/Kconfig
-+++ b/drivers/platform/x86/Kconfig
-@@ -170,7 +170,7 @@ config ACER_WMI
-
- config AMD_PMC
- tristate "AMD SoC PMC driver"
-- depends on ACPI && PCI
-+ depends on ACPI && PCI && RTC_CLASS
- help
- The driver provides support for AMD Power Management Controller
- primarily responsible for S2Idle transactions that are driven from
-diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
-index fc95620101e8..2c1bebf972c1 100644
---- a/drivers/platform/x86/amd-pmc.c
-+++ b/drivers/platform/x86/amd-pmc.c
-@@ -17,9 +17,11 @@
- #include <linux/delay.h>
- #include <linux/io.h>
- #include <linux/iopoll.h>
-+#include <linux/limits.h>
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/platform_device.h>
-+#include <linux/rtc.h>
- #include <linux/suspend.h>
- #include <linux/seq_file.h>
- #include <linux/uaccess.h>
-@@ -29,6 +31,16 @@
- #define AMD_PMC_REGISTER_RESPONSE 0x980
- #define AMD_PMC_REGISTER_ARGUMENT 0x9BC
-
-+/* PMC Scratch Registers */
-+#define AMD_PMC_SCRATCH_REG_CZN 0x94
-+#define AMD_PMC_SCRATCH_REG_YC 0xD14
-+
-+/* STB Registers */
-+#define AMD_PMC_STB_INDEX_ADDRESS 0xF8
-+#define AMD_PMC_STB_INDEX_DATA 0xFC
-+#define AMD_PMC_STB_PMI_0 0x03E30600
-+#define AMD_PMC_STB_PREDEF 0xC6000001
-+
- /* Base address of SMU for mapping physical address to virtual address */
- #define AMD_PMC_SMU_INDEX_ADDRESS 0xB8
- #define AMD_PMC_SMU_INDEX_DATA 0xBC
-@@ -76,6 +88,10 @@
- #define SOC_SUBSYSTEM_IP_MAX 12
- #define DELAY_MIN_US 2000
- #define DELAY_MAX_US 3000
-+#define FIFO_SIZE 4096
-+
-+#define GFX_IDLE_MASK 0x00000080
-+
- enum amd_pmc_def {
- MSG_TEST = 0x01,
- MSG_OS_HINT_PCO,
-@@ -110,15 +126,26 @@ struct amd_pmc_dev {
- u32 base_addr;
- u32 cpu_id;
- u32 active_ips;
-+/* SMU version information */
-+ u16 major;
-+ u16 minor;
-+ u16 rev;
- struct device *dev;
-+ struct pci_dev *rdev;
- struct mutex lock; /* generic mutex lock */
- #if IS_ENABLED(CONFIG_DEBUG_FS)
- struct dentry *dbgfs_dir;
- #endif /* CONFIG_DEBUG_FS */
- };
-
-+static bool enable_stb;
-+module_param(enable_stb, bool, 0644);
-+MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
-+
- 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 int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
-+static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
-+static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
-
- static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
- {
-@@ -133,7 +160,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
- struct smu_metrics {
- u32 table_version;
- u32 hint_count;
-- u32 s0i3_cyclecount;
-+ u32 s0i3_last_entry_status;
- u32 timein_s0i2;
- u64 timeentering_s0i3_lastcapture;
- u64 timeentering_s0i3_totaltime;
-@@ -147,6 +174,99 @@ struct smu_metrics {
- u64 timecondition_notmet_totaltime[SOC_SUBSYSTEM_IP_MAX];
- } __packed;
-
-+static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
-+{
-+ int rc;
-+ u32 val;
-+
-+ rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, 1);
-+ if (rc)
-+ return rc;
-+
-+ dev->major = (val >> 16) & GENMASK(15, 0);
-+ dev->minor = (val >> 8) & GENMASK(7, 0);
-+ dev->rev = (val >> 0) & GENMASK(7, 0);
-+
-+ dev_dbg(dev->dev, "SMU version is %u.%u.%u\n", dev->major, dev->minor, dev->rev);
-+
-+ return 0;
-+}
-+
-+static int amd_pmc_stb_debugfs_open(struct inode *inode, struct file *filp)
-+{
-+ struct amd_pmc_dev *dev = filp->f_inode->i_private;
-+ u32 size = FIFO_SIZE * sizeof(u32);
-+ u32 *buf;
-+ int rc;
-+
-+ buf = kzalloc(size, GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ rc = amd_pmc_read_stb(dev, buf);
-+ if (rc)
-+ goto out;
-+
-+ filp->private_data = buf;
-+ return 0;
-+
-+out:
-+ kfree(buf);
-+ return rc;
-+}
-+
-+static ssize_t amd_pmc_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
-+ loff_t *pos)
-+{
-+ if (!filp->private_data)
-+ return -EINVAL;
-+
-+ return simple_read_from_buffer(buf, size, pos, filp->private_data,
-+ FIFO_SIZE * sizeof(u32));
-+}
-+
-+static int amd_pmc_stb_debugfs_release(struct inode *inode, struct file *filp)
-+{
-+ kfree(filp->private_data);
-+ filp->private_data = NULL;
-+
-+ return 0;
-+}
-+
-+const struct file_operations amd_pmc_stb_debugfs_fops = {
-+ .owner = THIS_MODULE,
-+ .open = amd_pmc_stb_debugfs_open,
-+ .read = amd_pmc_stb_debugfs_read,
-+ .release = amd_pmc_stb_debugfs_release,
-+};
-+
-+static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
-+ struct seq_file *s, u32 *val_out)
-+{
-+ u32 val;
-+
-+ switch (pdev->cpu_id) {
-+ case AMD_CPU_ID_CZN:
-+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_CZN);
-+ break;
-+ case AMD_CPU_ID_YC:
-+ val = amd_pmc_reg_read(pdev, AMD_PMC_SCRATCH_REG_YC);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ if (val_out)
-+ *val_out = val;
-+
-+ if (dev)
-+ dev_dbg(pdev->dev, "SMU idlemask s0i3: 0x%x\n", val);
-+
-+ if (s)
-+ seq_printf(s, "SMU idlemask : 0x%x\n", val);
-+
-+ return 0;
-+}
-+
- #ifdef CONFIG_DEBUG_FS
- static int smu_fw_info_show(struct seq_file *s, void *unused)
- {
-@@ -162,9 +282,12 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
- 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, "Last S0i3 Status: %s\n", table.s0i3_last_entry_status ? "Success" :
-+ "Unknown/Fail");
- 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_printf(s, "Time (in us) to resume from S0i3: %lld\n",
-+ table.timeto_resume_to_os_lastcapture);
-
- seq_puts(s, "\n=== Active time (in us) ===\n");
- for (idx = 0 ; idx < SOC_SUBSYSTEM_IP_MAX ; idx++) {
-@@ -201,6 +324,23 @@ static int s0ix_stats_show(struct seq_file *s, void *unused)
- }
- DEFINE_SHOW_ATTRIBUTE(s0ix_stats);
-
-+static int amd_pmc_idlemask_show(struct seq_file *s, void *unused)
-+{
-+ struct amd_pmc_dev *dev = s->private;
-+ int rc;
-+
-+ if (dev->major > 56 || (dev->major >= 55 && dev->minor >= 37)) {
-+ rc = amd_pmc_idlemask_read(dev, NULL, s, NULL);
-+ if (rc)
-+ return rc;
-+ } else {
-+ seq_puts(s, "Unsupported SMU version for Idlemask\n");
-+ }
-+
-+ return 0;
-+}
-+DEFINE_SHOW_ATTRIBUTE(amd_pmc_idlemask);
-+
- static void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
- {
- debugfs_remove_recursive(dev->dbgfs_dir);
-@@ -213,6 +353,12 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
- &smu_fw_info_fops);
- debugfs_create_file("s0ix_stats", 0644, dev->dbgfs_dir, dev,
- &s0ix_stats_fops);
-+ debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
-+ &amd_pmc_idlemask_fops);
-+ /* Enable STB only when the module_param is set */
-+ if (enable_stb)
-+ debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
-+ &amd_pmc_stb_debugfs_fops);
- }
- #else
- static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
-@@ -264,7 +410,7 @@ 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, u32 *data, u8 msg, bool ret)
-+static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
- {
- int rc;
- u32 val;
-@@ -283,7 +429,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg
- amd_pmc_reg_write(dev, AMD_PMC_REGISTER_RESPONSE, 0);
-
- /* Write argument into response register */
-- amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, set);
-+ amd_pmc_reg_write(dev, AMD_PMC_REGISTER_ARGUMENT, arg);
-
- /* Write message ID to message ID register */
- amd_pmc_reg_write(dev, AMD_PMC_REGISTER_MESSAGE, msg);
-@@ -339,21 +485,95 @@ static int amd_pmc_get_os_hint(struct amd_pmc_dev *dev)
- return -EINVAL;
- }
-
-+static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
-+{
-+ struct rtc_device *rtc_device;
-+ time64_t then, now, duration;
-+ struct rtc_wkalrm alarm;
-+ struct rtc_time tm;
-+ int rc;
-+
-+ if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
-+ return 0;
-+
-+ rtc_device = rtc_class_open("rtc0");
-+ if (!rtc_device)
-+ return 0;
-+ rc = rtc_read_alarm(rtc_device, &alarm);
-+ if (rc)
-+ return rc;
-+ if (!alarm.enabled) {
-+ dev_dbg(pdev->dev, "alarm not enabled\n");
-+ return 0;
-+ }
-+ rc = rtc_read_time(rtc_device, &tm);
-+ if (rc)
-+ return rc;
-+ then = rtc_tm_to_time64(&alarm.time);
-+ now = rtc_tm_to_time64(&tm);
-+ duration = then-now;
-+
-+ /* in the past */
-+ if (then < now)
-+ return 0;
-+
-+ /* will be stored in upper 16 bits of s0i3 hint argument,
-+ * so timer wakeup from s0i3 is limited to ~18 hours or less
-+ */
-+ if (duration <= 4 || duration > U16_MAX)
-+ return -EINVAL;
-+
-+ *arg |= (duration << 16);
-+ rc = rtc_alarm_irq_enable(rtc_device, 0);
-+ dev_dbg(pdev->dev, "wakeup timer programmed for %lld seconds\n", duration);
-+
-+ return rc;
-+}
-+
- static int __maybe_unused amd_pmc_suspend(struct device *dev)
- {
- struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
- int rc;
-+ u32 val = 0;
- u8 msg;
-+ u32 arg = 1;
-
- /* 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);
-
-+ /* Activate CZN specific RTC functionality */
-+ if (pdev->cpu_id == AMD_CPU_ID_CZN) {
-+ rc = amd_pmc_verify_czn_rtc(pdev, &arg);
-+ if (rc < 0)
-+ return rc;
-+ }
-+
-+ /* Dump the IdleMask before we send hint to SMU */
-+ amd_pmc_idlemask_read(pdev, dev, NULL, &val);
-+ if (!(val & GFX_IDLE_MASK)) {
-+ uint32_t i;
-+ dev_err(pdev->dev, "gfxoff not asserted, retrying\n");
-+ for (i = 0; i < PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX; i++) {
-+ udelay(PMC_MSG_DELAY_MIN_US);
-+ amd_pmc_idlemask_read(pdev, dev, NULL, &val);
-+ if (val & GFX_IDLE_MASK)
-+ break;
-+ }
-+ if (!(val & GFX_IDLE_MASK)) {
-+ dev_err(pdev->dev, "gfxoff not asserted after %dus\n",
-+ PMC_MSG_DELAY_MIN_US * RESPONSE_REGISTER_LOOP_MAX);
-+ return -EBUSY;
-+ }
-+ }
- msg = amd_pmc_get_os_hint(pdev);
-- rc = amd_pmc_send_cmd(pdev, 1, NULL, msg, 0);
-+ rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
- if (rc)
- dev_err(pdev->dev, "suspend failed\n");
-
-+ if (enable_stb)
-+ amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF);
-+
- return rc;
- }
-
-@@ -363,14 +583,21 @@ static int __maybe_unused amd_pmc_resume(struct device *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);
--
- 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");
-
-+ /* Let SMU know that we are looking for stats */
-+ amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
-+
-+ /* Dump the IdleMask to see the blockers */
-+ amd_pmc_idlemask_read(pdev, dev, NULL, NULL);
-+
-+ /* Write data incremented by 1 to distinguish in stb_read */
-+ if (enable_stb)
-+ amd_pmc_write_stb(pdev, AMD_PMC_STB_PREDEF + 1);
-+
- return 0;
- }
-
-@@ -387,6 +614,57 @@ static const struct pci_device_id pmc_pci_ids[] = {
- { }
- };
-
-+static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
-+{
-+ int rc;
-+
-+ rc = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
-+ if (rc) {
-+ dev_err(dev->dev, "failed to write addr in stb: 0x%X\n",
-+ AMD_PMC_STB_INDEX_ADDRESS);
-+ pci_dev_put(dev->rdev);
-+ return pcibios_err_to_errno(rc);
-+ }
-+
-+ rc = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, data);
-+ if (rc) {
-+ dev_err(dev->dev, "failed to write data in stb: 0x%X\n",
-+ AMD_PMC_STB_INDEX_DATA);
-+ pci_dev_put(dev->rdev);
-+ return pcibios_err_to_errno(rc);
-+ }
-+
-+ return 0;
-+}
-+
-+static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
-+{
-+ int i, err;
-+ u32 value;
-+
-+ err = pci_write_config_dword(dev->rdev, AMD_PMC_STB_INDEX_ADDRESS, AMD_PMC_STB_PMI_0);
-+ if (err) {
-+ dev_err(dev->dev, "error writing addr to stb: 0x%X\n",
-+ AMD_PMC_STB_INDEX_ADDRESS);
-+ pci_dev_put(dev->rdev);
-+ return pcibios_err_to_errno(err);
-+ }
-+
-+ for (i = 0; i < FIFO_SIZE; i++) {
-+ err = pci_read_config_dword(dev->rdev, AMD_PMC_STB_INDEX_DATA, &value);
-+ if (err) {
-+ dev_err(dev->dev, "error reading data from stb: 0x%X\n",
-+ AMD_PMC_STB_INDEX_DATA);
-+ pci_dev_put(dev->rdev);
-+ return pcibios_err_to_errno(err);
-+ }
-+
-+ *buf++ = value;
-+ }
-+
-+ return 0;
-+}
-+
- static int amd_pmc_probe(struct platform_device *pdev)
- {
- struct amd_pmc_dev *dev = &pmc;
-@@ -400,22 +678,23 @@ static int amd_pmc_probe(struct platform_device *pdev)
-
- rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
- if (!rdev || !pci_match_id(pmc_pci_ids, rdev)) {
-- pci_dev_put(rdev);
-- return -ENODEV;
-+ err = -ENODEV;
-+ goto err_pci_dev_put;
- }
-
- dev->cpu_id = rdev->device;
-+ dev->rdev = rdev;
- err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_LO);
- if (err) {
- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
-- pci_dev_put(rdev);
-- return pcibios_err_to_errno(err);
-+ err = pcibios_err_to_errno(err);
-+ goto err_pci_dev_put;
- }
-
- err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
- if (err) {
-- pci_dev_put(rdev);
-- return pcibios_err_to_errno(err);
-+ err = pcibios_err_to_errno(err);
-+ goto err_pci_dev_put;
- }
-
- base_addr_lo = val & AMD_PMC_BASE_ADDR_HI_MASK;
-@@ -423,14 +702,14 @@ static int amd_pmc_probe(struct platform_device *pdev)
- err = pci_write_config_dword(rdev, AMD_PMC_SMU_INDEX_ADDRESS, AMD_PMC_BASE_ADDR_HI);
- if (err) {
- dev_err(dev->dev, "error writing to 0x%x\n", AMD_PMC_SMU_INDEX_ADDRESS);
-- pci_dev_put(rdev);
-- return pcibios_err_to_errno(err);
-+ err = pcibios_err_to_errno(err);
-+ goto err_pci_dev_put;
- }
-
- err = pci_read_config_dword(rdev, AMD_PMC_SMU_INDEX_DATA, &val);
- if (err) {
-- pci_dev_put(rdev);
-- return pcibios_err_to_errno(err);
-+ err = pcibios_err_to_errno(err);
-+ goto err_pci_dev_put;
- }
-
- base_addr_hi = val & AMD_PMC_BASE_ADDR_LO_MASK;
-@@ -457,9 +736,14 @@ static int amd_pmc_probe(struct platform_device *pdev)
- if (err)
- dev_err(dev->dev, "SMU debugging info not supported on this platform\n");
-
-+ amd_pmc_get_smu_version(dev);
- platform_set_drvdata(pdev, dev);
- amd_pmc_dbgfs_register(dev);
- return 0;
-+
-+err_pci_dev_put:
-+ pci_dev_put(rdev);
-+ return err;
- }
-
- static int amd_pmc_remove(struct platform_device *pdev)
-diff --git a/include/linux/acpi.h b/include/linux/acpi.h
-index 974d497a897d..6224b1e32681 100644
---- a/include/linux/acpi.h
-+++ b/include/linux/acpi.h
-@@ -976,6 +976,15 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr)
- return -ENODEV;
- }
-
-+static inline int acpi_register_wakeup_handler(int wake_irq,
-+ bool (*wakeup)(void *context), void *context)
-+{
-+ return -ENXIO;
-+}
-+
-+static inline void acpi_unregister_wakeup_handler(
-+ bool (*wakeup)(void *context), void *context) { }
-+
- #endif /* !CONFIG_ACPI */
-
- #ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
---
-2.33.1
-