diff options
author | Scott B | 2021-11-19 16:47:59 -0800 |
---|---|---|
committer | Scott B | 2021-11-20 22:50:39 -0800 |
commit | 56212d137f3b19eefa757304c5454b61d256bc0b (patch) | |
tree | 1b579c5d22c707215d5bb4876e5f2cd94da5cc2c /9001-v5.15-s0ix-patch-2021-11-04.patch | |
parent | 453d4234b2e4140da70a9078bf12fea2b34680fa (diff) | |
download | aur-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.patch | 1032 |
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 - |