From nobody Wed Dec 17 06:04:20 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9D3DC4167B for ; Thu, 9 Nov 2023 10:26:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233638AbjKIK0G (ORCPT ); Thu, 9 Nov 2023 05:26:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233286AbjKIKZz (ORCPT ); Thu, 9 Nov 2023 05:25:55 -0500 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33BE4258D for ; Thu, 9 Nov 2023 02:25:53 -0800 (PST) Received: from IcarusMOD.eternityproject.eu (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: kholk11) by madras.collabora.co.uk (Postfix) with ESMTPSA id 289C766074B0; Thu, 9 Nov 2023 10:25:51 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1699525552; bh=2GPFBJNW5GRbawHFbqCBL3Rkx8B9UBWyRsGfJmve0+U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UUd9lFROc6P2jd9yR9cBXg5Qok/3p+glg+eiU6FCVEERqbPtX9FhTSbS+U1tT0LB7 VaoUBkyDKRFo3IV3jCBe24hPg+geJ/rLWK6ZtS9nYSkirtiS1iHH1sMT3lYnIIsKRH pFocHO3HRi8vQUwGSo2dZ60g/CwVTs/2nPLB3Hzx2874rlg1TPwLwGJ7npYXqlSw3Z y8J8Dy7X+oZoMrFOso34RpmFAM9cmRxM4UmIaRcsSUCVXw/moA60N40hwbgaiQsDCX cYuFPX1wHUUyCtXTZIamvsmViWKlHjFD2T5WglwsT/hitW3Htd/ztJJmX4bR6j4EQQ KkdnmQQOcQ86g== From: AngeloGioacchino Del Regno To: boris.brezillon@collabora.com Cc: robh@kernel.org, steven.price@arm.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, airlied@gmail.com, daniel@ffwll.ch, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, wenst@chromium.org, AngeloGioacchino Del Regno , kernel@collabora.com Subject: [PATCH v3 3/6] drm/panfrost: Implement ability to turn on/off GPU clocks in suspend Date: Thu, 9 Nov 2023 11:25:40 +0100 Message-ID: <20231109102543.42971-4-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231109102543.42971-1-angelogioacchino.delregno@collabora.com> References: <20231109102543.42971-1-angelogioacchino.delregno@collabora.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently, the GPU is being internally powered off for runtime suspend and turned back on for runtime resume through commands sent to it, but note that the GPU doesn't need to be clocked during the poweroff state, hence it is possible to save some power on selected platforms. Add suspend and resume handlers for full system sleep and then add a new panfrost_gpu_pm enumeration and a pm_features variable in the panfrost_compatible structure: BIT(GPU_PM_CLK_DIS) will be used to enable this power saving technique only on SoCs that are able to safely use it. Note that this was implemented only for the system sleep case and not for runtime PM because testing on one of my MediaTek platforms showed issues when turning on and off clocks aggressively (in PM runtime) resulting in a full system lockup. Doing this only for full system sleep never showed issues during my testing by suspending and resuming the system continuously for more than 100 cycles. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Steven Price --- drivers/gpu/drm/panfrost/panfrost_device.c | 61 ++++++++++++++++++++-- drivers/gpu/drm/panfrost/panfrost_device.h | 11 ++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/p= anfrost/panfrost_device.c index 28f7046e1b1a..b4ddbc3b8069 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -403,7 +403,7 @@ void panfrost_device_reset(struct panfrost_device *pfde= v) panfrost_job_enable_interrupts(pfdev); } =20 -static int panfrost_device_resume(struct device *dev) +static int panfrost_device_runtime_resume(struct device *dev) { struct panfrost_device *pfdev =3D dev_get_drvdata(dev); =20 @@ -413,7 +413,7 @@ static int panfrost_device_resume(struct device *dev) return 0; } =20 -static int panfrost_device_suspend(struct device *dev) +static int panfrost_device_runtime_suspend(struct device *dev) { struct panfrost_device *pfdev =3D dev_get_drvdata(dev); =20 @@ -426,5 +426,58 @@ static int panfrost_device_suspend(struct device *dev) return 0; } =20 -EXPORT_GPL_RUNTIME_DEV_PM_OPS(panfrost_pm_ops, panfrost_device_suspend, - panfrost_device_resume, NULL); +static int panfrost_device_resume(struct device *dev) +{ + struct panfrost_device *pfdev =3D dev_get_drvdata(dev); + int ret; + + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { + ret =3D clk_enable(pfdev->clock); + if (ret) + return ret; + + if (pfdev->bus_clock) { + ret =3D clk_enable(pfdev->bus_clock); + if (ret) + goto err_bus_clk; + } + } + + ret =3D pm_runtime_force_resume(dev); + if (ret) + goto err_resume; + + return 0; + +err_resume: + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS) && pfdev->bus_clock) + clk_disable(pfdev->bus_clock); +err_bus_clk: + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) + clk_disable(pfdev->clock); + return ret; +} + +static int panfrost_device_suspend(struct device *dev) +{ + struct panfrost_device *pfdev =3D dev_get_drvdata(dev); + int ret; + + ret =3D pm_runtime_force_suspend(dev); + if (ret) + return ret; + + if (pfdev->comp->pm_features & BIT(GPU_PM_CLK_DIS)) { + if (pfdev->bus_clock) + clk_disable(pfdev->bus_clock); + + clk_disable(pfdev->clock); + } + + return 0; +} + +EXPORT_GPL_DEV_PM_OPS(panfrost_pm_ops) =3D { + RUNTIME_PM_OPS(panfrost_device_runtime_suspend, panfrost_device_runtime_r= esume, NULL) + SYSTEM_SLEEP_PM_OPS(panfrost_device_suspend, panfrost_device_resume) +}; diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/p= anfrost/panfrost_device.h index 1ef38f60d5dc..d7f179eb8ea3 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -25,6 +25,14 @@ struct panfrost_perfcnt; #define NUM_JOB_SLOTS 3 #define MAX_PM_DOMAINS 5 =20 +/** + * enum panfrost_gpu_pm - Supported kernel power management features + * @GPU_PM_CLK_DIS: Allow disabling clocks during system suspend + */ +enum panfrost_gpu_pm { + GPU_PM_CLK_DIS, +}; + struct panfrost_features { u16 id; u16 revision; @@ -75,6 +83,9 @@ struct panfrost_compatible { =20 /* Vendor implementation quirks callback */ void (*vendor_quirk)(struct panfrost_device *pfdev); + + /* Allowed PM features */ + u8 pm_features; }; =20 struct panfrost_device { --=20 2.42.0