From nobody Thu Oct 2 00:54:17 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFF482D94B7; Thu, 25 Sep 2025 14:31:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810693; cv=none; b=n+lv990XGsEFg5iiD0Vn7JrAmo15IyA4QZAizzWUhszh+LznQFqGQOwDqgmgOqr34q5Za2gyU8XxzqTruu+fR9teeIVKSvcpN2RWg4cHLiXmtRG6D6BytlMh0r8ydtLzBjorbHvEgySxKeG+u4DxiheYFv3ZPvwnhdVcMFo6Ku4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810693; c=relaxed/simple; bh=3fkmVe49ZqkNZbH1Ddxixn6eJb+ThovqAzK3HkVrxFs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tCt0ccgQH81Q5GgsCuaiYSyAfC1bRb55NS6384d092H4wNVRyErV3bSWMjWV8dQTIEgzLxIxtbib9OaSlyzvywk09HA9y+2cyBUi7I4TtFygH6aioGJzx8RzpS4Q7BydKQdR3gThA2ok0ZD/MIDg7nQ3AXypzz1n1RdOpSbUeXE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=nwiWN0H5; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="nwiWN0H5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758810690; bh=3fkmVe49ZqkNZbH1Ddxixn6eJb+ThovqAzK3HkVrxFs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nwiWN0H5lhiw9Rka8oEhxPOK0qcEqmntHsIVnB/MfUgYc85hSxMu5ExsMAZZTzhlK tUR/4A7Nl5gJlPgwOQ+rRH5kPudgeq6s4RFwDCPdAI9+br3K/6MDX+XousJKWvoGuE Yp2XNgLnD747g7hOG4lboL0sGUpUYsmj6dxpu4X3RLieLYpueFwHnK3UGHUf0q71D9 geDUCVc7PeQ7gCWeYFdLUctZVGcxzpMcZ+yG6GdVTYvMt+YylQoSlhkFNYDNr5V9si EP+CZNvngFF+T4tb9NdnS+Tpll/RV5v/lHu2/wnpTKZZFfl3b4dqXxGqsMDD2Y5ts4 LsFDD0u4MCHRw== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (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 bali.collaboradmins.com (Postfix) with ESMTPSA id 81DAF17E1389; Thu, 25 Sep 2025 16:31:29 +0200 (CEST) From: AngeloGioacchino Del Regno To: ulf.hansson@linaro.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, nfraprado@collabora.com, fshao@chromium.org, y.oudjana@protonmail.com, wenst@chromium.org, mandyjh.liu@mediatek.com, mbrugger@suse.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, kernel@collabora.com Subject: [PATCH v2 1/5] dt-bindings: power: Add support for MT8196 power controllers Date: Thu, 25 Sep 2025 16:31:12 +0200 Message-ID: <20250925143122.39796-2-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> References: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add support for the power controllers found in the MediaTek MT8196 Chromebook SoC. This chip has three power controllers, two of which located in the SCP subsystems (where one can be directly controlled and the other can be controlled only through the HW Voter IP), and one located in the Multimedia HFRP subsystem, controllable only through the HW Voter IP. Acked-by: Rob Herring (Arm) Reviewed-by: N=C3=ADcolas F. R. A. Prado Signed-off-by: AngeloGioacchino Del Regno --- .../power/mediatek,power-controller.yaml | 4 ++ .../dt-bindings/power/mediatek,mt8196-power.h | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/dt-bindings/power/mediatek,mt8196-power.h diff --git a/Documentation/devicetree/bindings/power/mediatek,power-control= ler.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controlle= r.yaml index 500d98921581..f8a13928f615 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -33,6 +33,9 @@ properties: - mediatek,mt8188-power-controller - mediatek,mt8192-power-controller - mediatek,mt8195-power-controller + - mediatek,mt8196-hwv-hfrp-power-controller + - mediatek,mt8196-hwv-scp-power-controller + - mediatek,mt8196-power-controller - mediatek,mt8365-power-controller =20 '#power-domain-cells': @@ -157,6 +160,7 @@ allOf: contains: enum: - mediatek,mt8183-power-controller + - mediatek,mt8196-power-controller then: properties: access-controllers: diff --git a/include/dt-bindings/power/mediatek,mt8196-power.h b/include/dt= -bindings/power/mediatek,mt8196-power.h new file mode 100644 index 000000000000..c12f0fe8f4c1 --- /dev/null +++ b/include/dt-bindings/power/mediatek,mt8196-power.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (c) 2025 Collabora Ltd + * AngeloGioacchino Del Regno + */ + +#ifndef _DT_BINDINGS_POWER_MT8196_POWER_H +#define _DT_BINDINGS_POWER_MT8196_POWER_H + +/* SCPSYS Secure Power Manager - Direct Control */ +#define MT8196_POWER_DOMAIN_MD 0 +#define MT8196_POWER_DOMAIN_CONN 1 +#define MT8196_POWER_DOMAIN_SSUSB_P0 2 +#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0 3 +#define MT8196_POWER_DOMAIN_SSUSB_P1 4 +#define MT8196_POWER_DOMAIN_SSUSB_P23 5 +#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2 6 +#define MT8196_POWER_DOMAIN_PEXTP_MAC0 7 +#define MT8196_POWER_DOMAIN_PEXTP_MAC1 8 +#define MT8196_POWER_DOMAIN_PEXTP_MAC2 9 +#define MT8196_POWER_DOMAIN_PEXTP_PHY0 10 +#define MT8196_POWER_DOMAIN_PEXTP_PHY1 11 +#define MT8196_POWER_DOMAIN_PEXTP_PHY2 12 +#define MT8196_POWER_DOMAIN_AUDIO 13 +#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT 14 +#define MT8196_POWER_DOMAIN_ADSP_INFRA 15 +#define MT8196_POWER_DOMAIN_ADSP_AO 16 + +/* SCPSYS Secure Power Manager - HW Voter */ +#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT 0 +#define MT8196_POWER_DOMAIN_SSR 1 + +/* HFRPSYS MultiMedia Power Control (MMPC) - HW Voter */ +#define MT8196_POWER_DOMAIN_VDE0 0 +#define MT8196_POWER_DOMAIN_VDE1 1 +#define MT8196_POWER_DOMAIN_VDE_VCORE0 2 +#define MT8196_POWER_DOMAIN_VEN0 3 +#define MT8196_POWER_DOMAIN_VEN1 4 +#define MT8196_POWER_DOMAIN_VEN2 5 +#define MT8196_POWER_DOMAIN_DISP_VCORE 6 +#define MT8196_POWER_DOMAIN_DIS0_DORMANT 7 +#define MT8196_POWER_DOMAIN_DIS1_DORMANT 8 +#define MT8196_POWER_DOMAIN_OVL0_DORMANT 9 +#define MT8196_POWER_DOMAIN_OVL1_DORMANT 10 +#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT 11 +#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT 12 +#define MT8196_POWER_DOMAIN_MML0_SHUTDOWN 13 +#define MT8196_POWER_DOMAIN_MML1_SHUTDOWN 14 +#define MT8196_POWER_DOMAIN_MM_INFRA0 15 +#define MT8196_POWER_DOMAIN_MM_INFRA1 16 +#define MT8196_POWER_DOMAIN_MM_INFRA_AO 17 +#define MT8196_POWER_DOMAIN_CSI_BS_RX 18 +#define MT8196_POWER_DOMAIN_CSI_LS_RX 19 +#define MT8196_POWER_DOMAIN_DSI_PHY0 20 +#define MT8196_POWER_DOMAIN_DSI_PHY1 21 +#define MT8196_POWER_DOMAIN_DSI_PHY2 22 + +#endif /* _DT_BINDINGS_POWER_MT8196_POWER_H */ --=20 2.51.0 From nobody Thu Oct 2 00:54:17 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 668E32D9EEF; Thu, 25 Sep 2025 14:31:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810695; cv=none; b=Gcf+cj42LyFkTbh64tqKVqSS19jz9RP9peRZd/EBCOOLKZVe5yhKxUWeAJKR1zdUIvlqhlSV/j5+G+i6uoFl8nJ3hYT/FYuPrXAQN2Zaso2ZhRXsz6EkQD8fSkhSbWz+w/IsmuqaJ5k3J3agcCFd0PP5g4ilXFB8b1Qms1BwtME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810695; c=relaxed/simple; bh=ebL8FTWZUNTdcwrQm+9iuytO+mIF/plomFywLzhK17Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L81ucHnMImrFRuFhmghDrL6xYN784nxfSaNlo0R+FSFObyiYNkHwMoVM6wF/UYILyKp/C4JEgErfK6SrWDOrPLnGtxJSb/ouAj3GnWRsoqNt6oePyn7d+K/yMnOPDrvROCkdV+BLM3eyf1bTYgrNHK6O9wMYVZQM9QU/EtdaKrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=IwreccCJ; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="IwreccCJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758810690; bh=ebL8FTWZUNTdcwrQm+9iuytO+mIF/plomFywLzhK17Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IwreccCJdPjZBCHYtFWer/bSQKrh5JAWM6qjvljkPJHwmRjCqUXdmv7kXnhwl3wXT KWfH1CXsu6LDzmZ6uRgWWsTxNQ0ge6HTtP7dkM5zayh9wC97wvxJk68s+n7LWJMZ20 rU8dZMEEXZQq/6VfWdrPXUI+wkB3loP2Kk/qHL5mTkFm7Kk5cYh9SuQU23SIBewLNY KBjBBXR+kbQTl+ruWusVXgXFMkn+ujPzEOG+QJm2qmmIKWY0YCd39YG/VpwhFvJeua 3OC8rYQeMn6aiPpfI765PXVOSZKdLcSHomck719SJh7wnCl6KK3aQrLoP9W2KmEaEO OX+N6V0hMc0Nw== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (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 bali.collaboradmins.com (Postfix) with ESMTPSA id 4C33217E13C1; Thu, 25 Sep 2025 16:31:30 +0200 (CEST) From: AngeloGioacchino Del Regno To: ulf.hansson@linaro.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, nfraprado@collabora.com, fshao@chromium.org, y.oudjana@protonmail.com, wenst@chromium.org, mandyjh.liu@mediatek.com, mbrugger@suse.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, kernel@collabora.com Subject: [PATCH v2 2/5] pmdomain: mediatek: Add support for Hardware Voter power domains Date: Thu, 25 Sep 2025 16:31:13 +0200 Message-ID: <20250925143122.39796-3-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> References: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable New generation SoCs like MT8196/MT6991 feature a new type of power domains, managed by a Hardware Voter (HWV) helper (through a SoC internal fixed-function MCU): this is used to collect votes from both the AP and the various other remote processors present in the SoC and transparently power on/off various power domains, avoiding unpowered access of registers in various internal IPs from all of the integrated remote processors (or from the AP...!). Add a new power domain type and differentiate between the old SCPSYS_MTCMOS_TYPE_DIRECT_CTL - where power domains are controlled directly by and exclusively from the Application Processor, and the new SCPSYS_MTCMOS_TYPE_HW_VOTER, where the power domains are voted through the HWV. With the two needing different handling, check the power domain type and assign a different power_{off,on} callback for pm_genpd: for this specific reason, also move the check for the SCPD cap MTK_SCPD_KEEP_DEFAULT_OFF after the assignment, and use the assigned power_on function instead of calling scpsys_power_on() directly to make that work for both HW_VOTER and DIRECT_CTL. Reviewed-by: N=C3=ADcolas F. R. A. Prado Signed-off-by: AngeloGioacchino Del Regno --- drivers/pmdomain/mediatek/mtk-pm-domains.c | 247 ++++++++++++++++++--- drivers/pmdomain/mediatek/mtk-pm-domains.h | 45 +++- 2 files changed, 266 insertions(+), 26 deletions(-) diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/= mediatek/mtk-pm-domains.c index 0ebe7379b94e..36767f740f57 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -31,6 +31,12 @@ #define MTK_POLL_DELAY_US 10 #define MTK_POLL_TIMEOUT USEC_PER_SEC =20 +#define MTK_HWV_POLL_DELAY_US 5 +#define MTK_HWV_POLL_TIMEOUT (300 * USEC_PER_MSEC) + +#define MTK_HWV_PREPARE_DELAY_US 1 +#define MTK_HWV_PREPARE_TIMEOUT (3 * USEC_PER_MSEC) + #define PWR_RST_B_BIT BIT(0) #define PWR_ISO_BIT BIT(1) #define PWR_ON_BIT BIT(2) @@ -48,6 +54,7 @@ struct scpsys_domain { struct generic_pm_domain genpd; const struct scpsys_domain_data *data; + const struct scpsys_hwv_domain_data *hwv_data; struct scpsys *scpsys; int num_clks; struct clk_bulk_data *clks; @@ -83,6 +90,32 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd) return status && status2; } =20 +static bool scpsys_hwv_domain_is_disable_done(struct scpsys_domain *pd) +{ + const struct scpsys_hwv_domain_data *hwv =3D pd->hwv_data; + u32 regs[2] =3D { hwv->done, hwv->clr_sta }; + u32 val[2]; + u32 mask =3D BIT(hwv->setclr_bit); + + regmap_multi_reg_read(pd->scpsys->base, regs, val, 2); + + /* Disable is done when the bit is set in DONE, cleared in CLR_STA */ + return (val[0] & mask) && !(val[1] & mask); +} + +static bool scpsys_hwv_domain_is_enable_done(struct scpsys_domain *pd) +{ + const struct scpsys_hwv_domain_data *hwv =3D pd->hwv_data; + u32 regs[3] =3D { hwv->done, hwv->en, hwv->set_sta }; + u32 val[3]; + u32 mask =3D BIT(hwv->setclr_bit); + + regmap_multi_reg_read(pd->scpsys->base, regs, val, 3); + + /* Enable is done when the bit is set in DONE and EN, cleared in SET_STA = */ + return (val[0] & mask) && (val[1] & mask) && !(val[2] & mask); +} + static int scpsys_sram_enable(struct scpsys_domain *pd) { u32 expected_ack, pdn_ack =3D pd->data->sram_pdn_ack_bits; @@ -250,6 +283,137 @@ static int scpsys_regulator_disable(struct regulator = *supply) return supply ? regulator_disable(supply) : 0; } =20 +static int scpsys_hwv_power_on(struct generic_pm_domain *genpd) +{ + struct scpsys_domain *pd =3D container_of(genpd, struct scpsys_domain, ge= npd); + const struct scpsys_hwv_domain_data *hwv =3D pd->hwv_data; + struct scpsys *scpsys =3D pd->scpsys; + u32 val; + int ret; + + ret =3D scpsys_regulator_enable(pd->supply); + if (ret) + return ret; + + ret =3D clk_bulk_prepare_enable(pd->num_clks, pd->clks); + if (ret) + goto err_reg; + + /* For HWV the subsys clocks refer to the HWV low power subsystem */ + ret =3D clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks); + if (ret) + goto err_disable_clks; + + /* Make sure the HW Voter is idle and able to accept commands */ + ret =3D regmap_read_poll_timeout_atomic(scpsys->base, hwv->done, val, + val & BIT(hwv->setclr_bit), + MTK_HWV_POLL_DELAY_US, + MTK_HWV_POLL_TIMEOUT); + if (ret) { + dev_err(scpsys->dev, "Failed to power on: HW Voter busy.\n"); + goto err_disable_subsys_clks; + } + + /* + * Instruct the HWV to power on the MTCMOS (power domain): after that, + * the same bit will be unset immediately by the hardware. + */ + regmap_write(scpsys->base, hwv->set, BIT(hwv->setclr_bit)); + + /* + * Wait until the HWV sets the bit again, signalling that its internal + * state machine was started and it now processing the vote command. + */ + ret =3D regmap_read_poll_timeout_atomic(scpsys->base, hwv->set, val, + val & BIT(hwv->setclr_bit), + MTK_HWV_PREPARE_DELAY_US, + MTK_HWV_PREPARE_TIMEOUT); + if (ret) { + dev_err(scpsys->dev, "Failed to power on: HW Voter not starting.\n"); + goto err_disable_subsys_clks; + } + + /* Wait for ACK, signalling that the MTCMOS was enabled */ + ret =3D readx_poll_timeout_atomic(scpsys_hwv_domain_is_enable_done, pd, v= al, val, + MTK_HWV_POLL_DELAY_US, MTK_HWV_POLL_TIMEOUT); + if (ret) { + dev_err(scpsys->dev, "Failed to power on: HW Voter ACK timeout.\n"); + goto err_disable_subsys_clks; + } + + /* It's done! Disable the HWV low power subsystem clocks */ + clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); + + return 0; + +err_disable_subsys_clks: + clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); +err_disable_clks: + clk_bulk_disable_unprepare(pd->num_clks, pd->clks); +err_reg: + scpsys_regulator_disable(pd->supply); + return ret; +}; + +static int scpsys_hwv_power_off(struct generic_pm_domain *genpd) +{ + struct scpsys_domain *pd =3D container_of(genpd, struct scpsys_domain, ge= npd); + const struct scpsys_hwv_domain_data *hwv =3D pd->hwv_data; + struct scpsys *scpsys =3D pd->scpsys; + u32 val; + int ret; + + ret =3D clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks); + if (ret) + return ret; + + /* Make sure the HW Voter is idle and able to accept commands */ + ret =3D regmap_read_poll_timeout_atomic(scpsys->base, hwv->done, val, + val & BIT(hwv->setclr_bit), + MTK_HWV_POLL_DELAY_US, + MTK_HWV_POLL_TIMEOUT); + if (ret) + goto err_disable_subsys_clks; + + + /* + * Instruct the HWV to power off the MTCMOS (power domain): differently + * from poweron, the bit will be kept set. + */ + regmap_write(scpsys->base, hwv->clr, BIT(hwv->setclr_bit)); + + /* + * Wait until the HWV clears the bit, signalling that its internal + * state machine was started and it now processing the clear command. + */ + ret =3D regmap_read_poll_timeout_atomic(scpsys->base, hwv->clr, val, + !(val & BIT(hwv->setclr_bit)), + MTK_HWV_PREPARE_DELAY_US, + MTK_HWV_PREPARE_TIMEOUT); + if (ret) + goto err_disable_subsys_clks; + + /* Poweroff needs 100us for the HW to stabilize */ + udelay(100); + + /* Wait for ACK, signalling that the MTCMOS was disabled */ + ret =3D readx_poll_timeout_atomic(scpsys_hwv_domain_is_disable_done, pd, = val, val, + MTK_HWV_POLL_DELAY_US, MTK_HWV_POLL_TIMEOUT); + if (ret) + goto err_disable_subsys_clks; + + clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); + clk_bulk_disable_unprepare(pd->num_clks, pd->clks); + + scpsys_regulator_disable(pd->supply); + + return 0; + +err_disable_subsys_clks: + clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); + return ret; +}; + static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd) { struct scpsys *scpsys =3D pd->scpsys; @@ -514,6 +678,7 @@ static struct generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct dev= ice_node *node) { const struct scpsys_domain_data *domain_data; + const struct scpsys_hwv_domain_data *hwv_domain_data; struct scpsys_domain *pd; struct property *prop; const char *clk_name; @@ -529,14 +694,33 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsy= s *scpsys, struct device_no return ERR_PTR(-EINVAL); } =20 - if (id >=3D scpsys->soc_data->num_domains) { - dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id); - return ERR_PTR(-EINVAL); - } + switch (scpsys->soc_data->type) { + case SCPSYS_MTCMOS_TYPE_DIRECT_CTL: + if (id >=3D scpsys->soc_data->num_domains) { + dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id); + return ERR_PTR(-EINVAL); + } + + domain_data =3D &scpsys->soc_data->domains_data[id]; + hwv_domain_data =3D NULL; =20 - domain_data =3D &scpsys->soc_data->domains_data[id]; - if (domain_data->sta_mask =3D=3D 0) { - dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id); + if (domain_data->sta_mask =3D=3D 0) { + dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id); + return ERR_PTR(-EINVAL); + } + + break; + case SCPSYS_MTCMOS_TYPE_HW_VOTER: + if (id >=3D scpsys->soc_data->num_hwv_domains) { + dev_err(scpsys->dev, "%pOF: invalid HWV domain id %d\n", node, id); + return ERR_PTR(-EINVAL); + } + + domain_data =3D NULL; + hwv_domain_data =3D &scpsys->soc_data->hwv_domains_data[id]; + + break; + default: return ERR_PTR(-EINVAL); } =20 @@ -545,6 +729,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys = *scpsys, struct device_no return ERR_PTR(-ENOMEM); =20 pd->data =3D domain_data; + pd->hwv_data =3D hwv_domain_data; pd->scpsys =3D scpsys; =20 if (MTK_SCPD_CAPS(pd, MTK_SCPD_DOMAIN_SUPPLY)) { @@ -604,6 +789,31 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys= *scpsys, struct device_no pd->subsys_clks[i].clk =3D clk; } =20 + if (scpsys->domains[id]) { + ret =3D -EINVAL; + dev_err(scpsys->dev, + "power domain with id %d already exists, check your device-tree\n", id); + goto err_put_subsys_clocks; + } + + if (pd->data && pd->data->name) + pd->genpd.name =3D pd->data->name; + else if (pd->hwv_data && pd->hwv_data->name) + pd->genpd.name =3D pd->hwv_data->name; + else + pd->genpd.name =3D node->name; + + if (scpsys->soc_data->type =3D=3D SCPSYS_MTCMOS_TYPE_DIRECT_CTL) { + pd->genpd.power_off =3D scpsys_power_off; + pd->genpd.power_on =3D scpsys_power_on; + } else { + pd->genpd.power_off =3D scpsys_hwv_power_off; + pd->genpd.power_on =3D scpsys_hwv_power_on; + + /* HW-Voter code can be invoked in atomic context */ + pd->genpd.flags |=3D GENPD_FLAG_IRQ_SAFE; + } + /* * Initially turn on all domains to make the domains usable * with !CONFIG_PM and to get the hardware in sync with the @@ -615,7 +825,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys = *scpsys, struct device_no dev_warn(scpsys->dev, "%pOF: A default off power domain has been ON\n", node); } else { - ret =3D scpsys_power_on(&pd->genpd); + ret =3D pd->genpd.power_on(&pd->genpd); if (ret < 0) { dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret= ); goto err_put_subsys_clocks; @@ -625,21 +835,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys= *scpsys, struct device_no pd->genpd.flags |=3D GENPD_FLAG_ALWAYS_ON; } =20 - if (scpsys->domains[id]) { - ret =3D -EINVAL; - dev_err(scpsys->dev, - "power domain with id %d already exists, check your device-tree\n", id); - goto err_put_subsys_clocks; - } - - if (!pd->data->name) - pd->genpd.name =3D node->name; - else - pd->genpd.name =3D pd->data->name; - - pd->genpd.power_off =3D scpsys_power_off; - pd->genpd.power_on =3D scpsys_power_on; - if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP)) pd->genpd.flags |=3D GENPD_FLAG_ACTIVE_WAKEUP; =20 @@ -934,7 +1129,7 @@ static int scpsys_probe(struct platform_device *pdev) struct device_node *node; struct device *parent; struct scpsys *scpsys; - int ret; + int num_domains, ret; =20 soc =3D of_device_get_match_data(&pdev->dev); if (!soc) { @@ -942,7 +1137,9 @@ static int scpsys_probe(struct platform_device *pdev) return -EINVAL; } =20 - scpsys =3D devm_kzalloc(dev, struct_size(scpsys, domains, soc->num_domain= s), GFP_KERNEL); + num_domains =3D soc->num_domains + soc->num_hwv_domains; + + scpsys =3D devm_kzalloc(dev, struct_size(scpsys, domains, num_domains), G= FP_KERNEL); if (!scpsys) return -ENOMEM; =20 diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/= mediatek/mtk-pm-domains.h index b2e3dee03831..df4bf013709b 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.h +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h @@ -16,7 +16,9 @@ #define MTK_SCPD_SRAM_PDN_INVERTED BIT(9) #define MTK_SCPD_MODEM_PWRSEQ BIT(10) #define MTK_SCPD_SKIP_RESET_B BIT(11) -#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) +#define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data ? \ + (_scpd)->data->caps & (_x) : \ + (_scpd)->hwv_data->caps & (_x)) =20 #define SPM_VDE_PWR_CON 0x0210 #define SPM_MFG_PWR_CON 0x0214 @@ -124,6 +126,18 @@ enum scpsys_rtff_type { SCPSYS_RTFF_TYPE_MAX }; =20 +/** + * enum scpsys_mtcmos_type - Type of power domain controller + * @SCPSYS_MTCMOS_TYPE_DIRECT_CTL: Power domains are controlled with direc= t access + * @SCPSYS_MTCMOS_TYPE_HW_VOTER: Hardware-assisted voted power domain co= ntrol + * @SCPSYS_MTCMOS_TYPE_MAX: Number of supported power domain types + */ +enum scpsys_mtcmos_type { + SCPSYS_MTCMOS_TYPE_DIRECT_CTL =3D 0, + SCPSYS_MTCMOS_TYPE_HW_VOTER, + SCPSYS_MTCMOS_TYPE_MAX +}; + /** * struct scpsys_domain_data - scp domain data for power on/off flow * @name: The name of the power domain. @@ -152,11 +166,40 @@ struct scpsys_domain_data { int pwr_sta2nd_offs; }; =20 +/** + * struct scpsys_hwv_domain_data - Hardware Voter power domain data + * @name: Name of the power domain + * @set: Offset of the HWV SET register + * @clr: Offset of the HWV CLEAR register + * @done: Offset of the HWV DONE register + * @en: Offset of the HWV ENABLE register + * @set_sta: Offset of the HWV SET STATUS register + * @clr_sta: Offset of the HWV CLEAR STATUS register + * @setclr_bit: The SET/CLR bit to enable/disable the power domain + * @sta_bit: The SET/CLR STA bit to check for on/off ACK + * @caps: The flag for active wake-up action + */ +struct scpsys_hwv_domain_data { + const char *name; + u16 set; + u16 clr; + u16 done; + u16 en; + u16 set_sta; + u16 clr_sta; + u8 setclr_bit; + u8 sta_bit; + u16 caps; +}; + struct scpsys_soc_data { const struct scpsys_domain_data *domains_data; int num_domains; + const struct scpsys_hwv_domain_data *hwv_domains_data; + int num_hwv_domains; enum scpsys_bus_prot_block *bus_prot_blocks; int num_bus_prot_blocks; + enum scpsys_mtcmos_type type; }; =20 #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */ --=20 2.51.0 From nobody Thu Oct 2 00:54:17 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 669572D9EF3; Thu, 25 Sep 2025 14:31:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810695; cv=none; b=WX68l7Lt5ImdjVFNpD5yR8gnKZdESPh/vpCGGvKgINb2ykpDVUvIlc7a+SUa6vBW1NvmNq4IvjgRUNQyHebk4ydGrVEDeBAR0H6m8JnGkYMEJqo/rw9WUHyjeAGyWlcx5mV8iSBiQ/4219JMzuQSzRoQKmBth712vDVwavn0XjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810695; c=relaxed/simple; bh=kdhQOSWTYVrgxbYGEy8Sxj3IquAPonEI1tpFJXN2e1s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=byi0RpZhcLcXdByvh6cAVOOzcEVy97kJxeJ+voHMntmgvnO7K3V4afBEFymV6yMqVuZm0sEmwUFxUG71sgYJ2MgnRdub3yif1/nA1cHp+RiOWGjMC7mCPdL/1E6nKpA0v4lnOuWKLg1VAaukXmXGvK/3ONLjZT8x73bYbTkkEY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=EEq2Edtg; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="EEq2Edtg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758810691; bh=kdhQOSWTYVrgxbYGEy8Sxj3IquAPonEI1tpFJXN2e1s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EEq2EdtgxduBCYInjMo9FrZ0ixsEOk0HBrORtIIHw7b7lc8Ja7bTHwGSfBQNT9GtP Ndo0iRuVFMlSFwuPsgrDT2Rr4v6Gc5JmqWwfu7Tj/zxw3+rDsmwMNyM9pNBUaV1Buv Q9g7h+0iOsD3XO8OfmuCIWsJ1zqbGb5MHB23SyBMeDa4ZoEfPF3TdUqbjrR0yJKENB hqXpcu0WZJpA3Kfa2kpo1DPX6QIc5n+OG2SIzOkWdh8q10Z6MEXqPugIRYM08dzrTk qipsnBNAOxtBDsHm4Kj97ehhNKiM7DaBrptVWWvi0lP7zYreP9q+apZqXs1Mnx0POi P5Xky+ELgrdcw== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (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 bali.collaboradmins.com (Postfix) with ESMTPSA id 1582617E13CD; Thu, 25 Sep 2025 16:31:31 +0200 (CEST) From: AngeloGioacchino Del Regno To: ulf.hansson@linaro.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, nfraprado@collabora.com, fshao@chromium.org, y.oudjana@protonmail.com, wenst@chromium.org, mandyjh.liu@mediatek.com, mbrugger@suse.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, kernel@collabora.com Subject: [PATCH v2 3/5] pmdomain: mediatek: Add support for secure HWCCF infra power on Date: Thu, 25 Sep 2025 16:31:14 +0200 Message-ID: <20250925143122.39796-4-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> References: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Some SoCs, like the MediaTek Dimensity 9400 (MT6991), have granular power controls and will disable power to the infracfg to save power when the platform is in deeper sleep states (or when no IP in the the infracfg macro-block is in use). These chips also cannot control the infracfg power states directly via AP register writes as those are protected by the secure world. Add a new MTK_SCPD_INFRA_PWR_CTL cap and, if present, make a call to the secure world to poweron the infracfg block, as the HWV IP resides in there, when executing HWV domains power sequences. Reviewed-by: N=C3=ADcolas F. R. A. Prado Signed-off-by: AngeloGioacchino Del Regno --- drivers/pmdomain/mediatek/mtk-pm-domains.c | 40 ++++++++++++++++++++-- drivers/pmdomain/mediatek/mtk-pm-domains.h | 1 + 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/= mediatek/mtk-pm-domains.c index 36767f740f57..f400b0c6b5fd 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include "mt6735-pm-domains.h" #include "mt6795-pm-domains.h" @@ -51,6 +52,8 @@ #define PWR_RTFF_SAVE_FLAG BIT(27) #define PWR_RTFF_UFS_CLK_DIS BIT(28) =20 +#define MTK_SIP_KERNEL_HWCCF_CONTROL MTK_SIP_SMC_CMD(0x540) + struct scpsys_domain { struct generic_pm_domain genpd; const struct scpsys_domain_data *data; @@ -116,6 +119,15 @@ static bool scpsys_hwv_domain_is_enable_done(struct sc= psys_domain *pd) return (val[0] & mask) && (val[1] & mask) && !(val[2] & mask); } =20 +static int scpsys_sec_infra_power_on(bool on) +{ + struct arm_smccc_res res; + unsigned long cmd =3D on ? 1 : 0; + + arm_smccc_smc(MTK_SIP_KERNEL_HWCCF_CONTROL, cmd, 0, 0, 0, 0, 0, 0, &res); + return res.a0; +} + static int scpsys_sram_enable(struct scpsys_domain *pd) { u32 expected_ack, pdn_ack =3D pd->data->sram_pdn_ack_bits; @@ -291,9 +303,15 @@ static int scpsys_hwv_power_on(struct generic_pm_domai= n *genpd) u32 val; int ret; =20 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) { + ret =3D scpsys_sec_infra_power_on(true); + if (ret) + return ret; + } + ret =3D scpsys_regulator_enable(pd->supply); if (ret) - return ret; + goto err_infra; =20 ret =3D clk_bulk_prepare_enable(pd->num_clks, pd->clks); if (ret) @@ -344,6 +362,9 @@ static int scpsys_hwv_power_on(struct generic_pm_domain= *genpd) /* It's done! Disable the HWV low power subsystem clocks */ clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); =20 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) + scpsys_sec_infra_power_on(false); + return 0; =20 err_disable_subsys_clks: @@ -352,6 +373,9 @@ static int scpsys_hwv_power_on(struct generic_pm_domain= *genpd) clk_bulk_disable_unprepare(pd->num_clks, pd->clks); err_reg: scpsys_regulator_disable(pd->supply); +err_infra: + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) + scpsys_sec_infra_power_on(false); return ret; }; =20 @@ -363,9 +387,15 @@ static int scpsys_hwv_power_off(struct generic_pm_doma= in *genpd) u32 val; int ret; =20 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) { + ret =3D scpsys_sec_infra_power_on(true); + if (ret) + return ret; + } + ret =3D clk_bulk_prepare_enable(pd->num_subsys_clks, pd->subsys_clks); if (ret) - return ret; + goto err_infra; =20 /* Make sure the HW Voter is idle and able to accept commands */ ret =3D regmap_read_poll_timeout_atomic(scpsys->base, hwv->done, val, @@ -407,10 +437,16 @@ static int scpsys_hwv_power_off(struct generic_pm_dom= ain *genpd) =20 scpsys_regulator_disable(pd->supply); =20 + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) + scpsys_sec_infra_power_on(false); + return 0; =20 err_disable_subsys_clks: clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); +err_infra: + if (MTK_SCPD_CAPS(pd, MTK_SCPD_INFRA_PWR_CTL)) + scpsys_sec_infra_power_on(false); return ret; }; =20 diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/= mediatek/mtk-pm-domains.h index df4bf013709b..36adcfca80c6 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.h +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h @@ -16,6 +16,7 @@ #define MTK_SCPD_SRAM_PDN_INVERTED BIT(9) #define MTK_SCPD_MODEM_PWRSEQ BIT(10) #define MTK_SCPD_SKIP_RESET_B BIT(11) +#define MTK_SCPD_INFRA_PWR_CTL BIT(12) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data ? \ (_scpd)->data->caps & (_x) : \ (_scpd)->hwv_data->caps & (_x)) --=20 2.51.0 From nobody Thu Oct 2 00:54:17 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E4112DC353; Thu, 25 Sep 2025 14:31:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810696; cv=none; b=mxOJLnsiTouOT/IFOvXha4/GFYYVCWfeNqNqt9q5DKHrZ7xC5bvV2+FGZvGUSuJazaC6E2j6TTeb/1AL5IqBCOmzgVK9C5etlMWkyCMSCPvDRHr5nYROcvfxToNDEwC7zoZ5oOlH+Gh6NgBeqcFdEA3ya4COjjOTi8payKo9KDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810696; c=relaxed/simple; bh=/znEDOpCCt5yuHnPOnm5XVsVGFaByYXeLMMEMygmgrA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NVV4sEtVRUihuPjOxLmsLSfNHNgqkRHPjroAnWfwDo0KunkNn/ggXKWby8Vx8Gv37OuiMu1V528AEuzKveINZpjQkxv0/Qxg5USSHmZonj0OmSKKIQnOA1+DmP4YoKrlttq4e2H7pKUwhbg1HO+mVGE7jlsG7yPm9Mj9GxU0+WE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=fo2vlmX4; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="fo2vlmX4" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758810692; bh=/znEDOpCCt5yuHnPOnm5XVsVGFaByYXeLMMEMygmgrA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fo2vlmX46QmZZrMk8OjxvTPtLfzgotboREWzFXjrmIl/XCOREkkQ2jPE2gp0X+yr+ f7D6bwNsEC0ttqJev8X0PDuQdCHlCl7K5C1RuVk9/v0Vxicys7QeTL2PKmKuJRHGYh lIcWJxtkvfjhQKJ9oya0PP7K9KZA6zEMOamoFG3Hbela6EBEMy2EpDQXMRTCbghlQZ 8Fdlv1xT5sO+97XmtdWjo7WigAdtrB6MiYbzvnYIXvkRGdcDrDSsHnHfXzMCvRXxoh RvXvAbtSjPY5Dk0WjSFbb6FrnvXqkjlPPX3pTkeWtt3Cmd2gjwlZbvPlLAr2ei6LTv INnDaXE77+qNA== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (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 bali.collaboradmins.com (Postfix) with ESMTPSA id D3E4F17E13D5; Thu, 25 Sep 2025 16:31:31 +0200 (CEST) From: AngeloGioacchino Del Regno To: ulf.hansson@linaro.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, nfraprado@collabora.com, fshao@chromium.org, y.oudjana@protonmail.com, wenst@chromium.org, mandyjh.liu@mediatek.com, mbrugger@suse.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, kernel@collabora.com Subject: [PATCH v2 4/5] pmdomain: mediatek: Add support for MT8196 SCPSYS power domains Date: Thu, 25 Sep 2025 16:31:15 +0200 Message-ID: <20250925143122.39796-5-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> References: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a new SPM bus protection block and add support for both the direct control and HW Voter control SCPSYS power domains found in the MT8196 and MT6991 SoCs. Reviewed-by: N=C3=ADcolas F. R. A. Prado Signed-off-by: AngeloGioacchino Del Regno --- drivers/pmdomain/mediatek/mt8196-pm-domains.h | 386 ++++++++++++++++++ drivers/pmdomain/mediatek/mtk-pm-domains.c | 18 +- drivers/pmdomain/mediatek/mtk-pm-domains.h | 3 + 3 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 drivers/pmdomain/mediatek/mt8196-pm-domains.h diff --git a/drivers/pmdomain/mediatek/mt8196-pm-domains.h b/drivers/pmdoma= in/mediatek/mt8196-pm-domains.h new file mode 100644 index 000000000000..ce8d594c46f8 --- /dev/null +++ b/drivers/pmdomain/mediatek/mt8196-pm-domains.h @@ -0,0 +1,386 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Collabora Ltd + * AngeloGioacchino Del Regno + */ + +#ifndef __SOC_MEDIATEK_MT8196_PM_DOMAINS_H +#define __SOC_MEDIATEK_MT8196_PM_DOMAINS_H + +#include "mtk-pm-domains.h" +#include + +/* + * MT8196 and MT6991 power domain support + */ + +/* INFRA TOP_AXI registers */ +#define MT8196_TOP_AXI_PROT_EN_SET 0x4 +#define MT8196_TOP_AXI_PROT_EN_CLR 0x8 +#define MT8196_TOP_AXI_PROT_EN_STA 0xc + #define MT8196_TOP_AXI_PROT_EN_SLEEP0_MD BIT(29) + +#define MT8196_TOP_AXI_PROT_EN_1_SET 0x24 +#define MT8196_TOP_AXI_PROT_EN_1_CLR 0x28 +#define MT8196_TOP_AXI_PROT_EN_1_STA 0x2c + #define MT8196_TOP_AXI_PROT_EN_1_SLEEP1_MD BIT(0) + +/* SPM BUS_PROTECT registers */ +#define MT8196_SPM_BUS_PROTECT_CON_SET 0xdc +#define MT8196_SPM_BUS_PROTECT_CON_CLR 0xe0 +#define MT8196_SPM_BUS_PROTECT_RDY 0x208 + #define MT8196_SPM_PROT_EN_BUS_CONN BIT(1) + #define MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0 BIT(6) + #define MT8196_SPM_PROT_EN_BUS_SSUSB_P0 BIT(7) + #define MT8196_SPM_PROT_EN_BUS_SSUSB_P1 BIT(8) + #define MT8196_SPM_PROT_EN_BUS_SSUSB_P23 BIT(9) + #define MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2 BIT(10) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0 BIT(13) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1 BIT(14) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2 BIT(15) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0 BIT(16) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1 BIT(17) + #define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2 BIT(18) + #define MT8196_SPM_PROT_EN_BUS_AUDIO BIT(19) + #define MT8196_SPM_PROT_EN_BUS_ADSP_TOP BIT(21) + #define MT8196_SPM_PROT_EN_BUS_ADSP_INFRA BIT(22) + #define MT8196_SPM_PROT_EN_BUS_ADSP_AO BIT(23) + #define MT8196_SPM_PROT_EN_BUS_MM_PROC BIT(24) + +/* PWR_CON registers */ +#define MT8196_PWR_ACK BIT(30) +#define MT8196_PWR_ACK_2ND BIT(31) + +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8196[] =3D { + BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SPM +}; + +static const struct scpsys_domain_data scpsys_domain_data_mt8196[] =3D { + [MT8196_POWER_DOMAIN_MD] =3D { + .name =3D "md", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe00, + .pwr_sta_offs =3D 0xe00, + .pwr_sta2nd_offs =3D 0xe00, + .ext_buck_iso_offs =3D 0xefc, + .ext_buck_iso_mask =3D GENMASK(1, 0), + .bp_cfg =3D { + BUS_PROT_WR_IGN(INFRA, MT8196_TOP_AXI_PROT_EN_SLEEP0_MD, + MT8196_TOP_AXI_PROT_EN_SET, + MT8196_TOP_AXI_PROT_EN_CLR, + MT8196_TOP_AXI_PROT_EN_STA), + BUS_PROT_WR_IGN(INFRA, MT8196_TOP_AXI_PROT_EN_1_SLEEP1_MD, + MT8196_TOP_AXI_PROT_EN_1_SET, + MT8196_TOP_AXI_PROT_EN_1_CLR, + MT8196_TOP_AXI_PROT_EN_1_STA), + }, + .caps =3D MTK_SCPD_MODEM_PWRSEQ | MTK_SCPD_EXT_BUCK_ISO | + MTK_SCPD_SKIP_RESET_B | MTK_SCPD_KEEP_DEFAULT_OFF, + }, + [MT8196_POWER_DOMAIN_CONN] =3D { + .name =3D "conn", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe04, + .pwr_sta_offs =3D 0xe04, + .pwr_sta2nd_offs =3D 0xe04, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_CONN, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_KEEP_DEFAULT_OFF, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0] =3D { + .name =3D "ssusb-dp-phy-p0", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe18, + .pwr_sta_offs =3D 0xe18, + .pwr_sta2nd_offs =3D 0xe18, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_ALWAYS_ON, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_SSUSB_P0] =3D { + .name =3D "ssusb-p0", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe1c, + .pwr_sta_offs =3D 0xe1c, + .pwr_sta2nd_offs =3D 0xe1c, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P0, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_ALWAYS_ON, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_SSUSB_P1] =3D { + .name =3D "ssusb-p1", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe20, + .pwr_sta_offs =3D 0xe20, + .pwr_sta2nd_offs =3D 0xe20, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P1, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_ALWAYS_ON, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_SSUSB_P23] =3D { + .name =3D "ssusb-p23", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe24, + .pwr_sta_offs =3D 0xe24, + .pwr_sta2nd_offs =3D 0xe24, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_P23, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_KEEP_DEFAULT_OFF, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_SSUSB_PHY_P2] =3D { + .name =3D "ssusb-phy-p2", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe28, + .pwr_sta_offs =3D 0xe28, + .pwr_sta2nd_offs =3D 0xe28, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_KEEP_DEFAULT_OFF, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC0] =3D { + .name =3D "pextp-mac0", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe34, + .pwr_sta_offs =3D 0xe34, + .pwr_sta2nd_offs =3D 0xe34, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC1] =3D { + .name =3D "pextp-mac1", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe38, + .pwr_sta_offs =3D 0xe38, + .pwr_sta2nd_offs =3D 0xe38, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_PEXTP_MAC2] =3D { + .name =3D "pextp-mac2", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe3c, + .pwr_sta_offs =3D 0xe3c, + .pwr_sta2nd_offs =3D 0xe3c, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY0] =3D { + .name =3D "pextp-phy0", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe40, + .pwr_sta_offs =3D 0xe40, + .pwr_sta2nd_offs =3D 0xe40, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY1] =3D { + .name =3D "pextp-phy1", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe44, + .pwr_sta_offs =3D 0xe44, + .pwr_sta2nd_offs =3D 0xe44, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_PEXTP_PHY2] =3D { + .name =3D "pextp-phy2", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe48, + .pwr_sta_offs =3D 0xe48, + .pwr_sta2nd_offs =3D 0xe48, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_PCIE_PHY, + }, + [MT8196_POWER_DOMAIN_AUDIO] =3D { + .name =3D "audio", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe4c, + .pwr_sta_offs =3D 0xe4c, + .pwr_sta2nd_offs =3D 0xe4c, + .sram_pdn_bits =3D BIT(8), + .sram_pdn_ack_bits =3D BIT(12), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_AUDIO, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT] =3D { + .name =3D "adsp-top-dormant", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe54, + .pwr_sta_offs =3D 0xe54, + .pwr_sta2nd_offs =3D 0xe54, + /* Note: This is not managing powerdown (pdn), but sleep instead (slp) */ + .sram_pdn_bits =3D BIT(9), + .sram_pdn_ack_bits =3D BIT(13), + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_TOP, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_SRAM_ISO | MTK_SCPD_SRAM_PDN_INVERTED, + }, + [MT8196_POWER_DOMAIN_ADSP_INFRA] =3D { + .name =3D "adsp-infra", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe58, + .pwr_sta_offs =3D 0xe58, + .pwr_sta2nd_offs =3D 0xe58, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_INFRA, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_ALWAYS_ON, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, + [MT8196_POWER_DOMAIN_ADSP_AO] =3D { + .name =3D "adsp-ao", + .sta_mask =3D MT8196_PWR_ACK, + .sta2nd_mask =3D MT8196_PWR_ACK_2ND, + .ctl_offs =3D 0xe5c, + .pwr_sta_offs =3D 0xe5c, + .pwr_sta2nd_offs =3D 0xe5c, + .bp_cfg =3D { + BUS_PROT_WR_IGN(SPM, MT8196_SPM_PROT_EN_BUS_ADSP_AO, + MT8196_SPM_BUS_PROTECT_CON_SET, + MT8196_SPM_BUS_PROTECT_CON_CLR, + MT8196_SPM_BUS_PROTECT_RDY), + }, + .caps =3D MTK_SCPD_ALWAYS_ON, + .rtff_type =3D SCPSYS_RTFF_TYPE_GENERIC, + }, +}; + +static const struct scpsys_hwv_domain_data scpsys_hwv_domain_data_mt8196[]= =3D { + [MT8196_POWER_DOMAIN_MM_PROC_DORMANT] =3D { + .name =3D "mm-proc-dormant", + .set =3D 0x0218, + .clr =3D 0x021c, + .done =3D 0x141c, + .en =3D 0x1410, + .set_sta =3D 0x146c, + .clr_sta =3D 0x1470, + .setclr_bit =3D 0, + .caps =3D MTK_SCPD_ALWAYS_ON, + }, + [MT8196_POWER_DOMAIN_SSR] =3D { + .name =3D "ssrsys", + .set =3D 0x0218, + .clr =3D 0x021c, + .done =3D 0x141c, + .en =3D 0x1410, + .set_sta =3D 0x146c, + .clr_sta =3D 0x1470, + .setclr_bit =3D 1, + }, +}; + +static const struct scpsys_soc_data mt8196_scpsys_data =3D { + .domains_data =3D scpsys_domain_data_mt8196, + .num_domains =3D ARRAY_SIZE(scpsys_domain_data_mt8196), + .bus_prot_blocks =3D scpsys_bus_prot_blocks_mt8196, + .num_bus_prot_blocks =3D ARRAY_SIZE(scpsys_bus_prot_blocks_mt8196), + .type =3D SCPSYS_MTCMOS_TYPE_DIRECT_CTL, +}; + +static const struct scpsys_soc_data mt8196_scpsys_hwv_data =3D { + .hwv_domains_data =3D scpsys_hwv_domain_data_mt8196, + .num_hwv_domains =3D ARRAY_SIZE(scpsys_hwv_domain_data_mt8196), + .type =3D SCPSYS_MTCMOS_TYPE_HW_VOTER, +}; + +#endif /* __SOC_MEDIATEK_MT8196_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/= mediatek/mtk-pm-domains.c index f400b0c6b5fd..18f0b9b960d9 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -27,6 +27,7 @@ #include "mt8188-pm-domains.h" #include "mt8192-pm-domains.h" #include "mt8195-pm-domains.h" +#include "mt8196-pm-domains.h" #include "mt8365-pm-domains.h" =20 #define MTK_POLL_DELAY_US 10 @@ -81,13 +82,16 @@ struct scpsys { static bool scpsys_domain_is_on(struct scpsys_domain *pd) { struct scpsys *scpsys =3D pd->scpsys; - u32 status, status2; + u32 mask =3D pd->data->sta_mask; + u32 status, status2, mask2; + + mask2 =3D pd->data->sta2nd_mask ? pd->data->sta2nd_mask : mask; =20 regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status); - status &=3D pd->data->sta_mask; + status &=3D mask; =20 regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2); - status2 &=3D pd->data->sta_mask; + status2 &=3D mask2; =20 /* A domain is on when both status bits are set. */ return status && status2; @@ -1150,6 +1154,14 @@ static const struct of_device_id scpsys_of_match[] = =3D { .compatible =3D "mediatek,mt8195-power-controller", .data =3D &mt8195_scpsys_data, }, + { + .compatible =3D "mediatek,mt8196-power-controller", + .data =3D &mt8196_scpsys_data, + }, + { + .compatible =3D "mediatek,mt8196-hwv-scp-power-controller", + .data =3D &mt8196_scpsys_hwv_data, + }, { .compatible =3D "mediatek,mt8365-power-controller", .data =3D &mt8365_scpsys_data, diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/= mediatek/mtk-pm-domains.h index 36adcfca80c6..f608e6ec4744 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.h +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h @@ -62,6 +62,7 @@ enum scpsys_bus_prot_block { BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_INFRA_NAO, BUS_PROT_BLOCK_SMI, + BUS_PROT_BLOCK_SPM, BUS_PROT_BLOCK_COUNT, }; =20 @@ -143,6 +144,7 @@ enum scpsys_mtcmos_type { * struct scpsys_domain_data - scp domain data for power on/off flow * @name: The name of the power domain. * @sta_mask: The mask for power on/off status bit. + * @sta2nd_mask: The mask for second power on/off status bit. * @ctl_offs: The offset for main power control register. * @sram_pdn_bits: The mask for sram power control bits. * @sram_pdn_ack_bits: The mask for sram power control acked bits. @@ -155,6 +157,7 @@ enum scpsys_mtcmos_type { struct scpsys_domain_data { const char *name; u32 sta_mask; + u32 sta2nd_mask; int ctl_offs; u32 sram_pdn_bits; u32 sram_pdn_ack_bits; --=20 2.51.0 From nobody Thu Oct 2 00:54:17 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBD832DC77B; Thu, 25 Sep 2025 14:31:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810696; cv=none; b=lHdvYckmyocCqFjLtNSP5EttJBMAIeW+sY3ix7D3koQ1+A9fPBTgwGVkCyXaYVsh1j2O2SlaPQ8scDMj1YPuwncZ0wZH09cv/N9e4W1fEH4MAyRu489xbG/uOTWYLZirSezVmh5B2wk3H7VxIQ3ZRnirddDSjEx0JXSrAab7Kb4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758810696; c=relaxed/simple; bh=Z2etouC0e/MupXGZRqvPNjZ+eDUkxJ7q4FAYyzxRnbk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P5FmtUzUPqOOksT2Mu690JNLF/crFF+PILGsvxaC5qKBHFhrNZ5sU8py/7WNrVKVNWiSvjzgTakTuGmoPiG54HUyk4+WDkMvpv0v/jGKh907yF+YLnnDGU1y1c6axYAuHp8dnTvEaQU1xE5X2WvBqeKCH+zOLSvdYhmwq54MsOg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=NobN07bN; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="NobN07bN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758810693; bh=Z2etouC0e/MupXGZRqvPNjZ+eDUkxJ7q4FAYyzxRnbk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NobN07bNPhtZDfAE2nl12FeQcoOPv+RSZ15qU+YcnirjSx8jEIkW013s/v8el7PCk hEtjtjwxbLhFR/Hjxp8kAVtoiCbjOySaOzpv4Oh7iJhty53Ca4rIwtg3x0Eq8iI2JQ L1AvRjOzQBaq3IYb1W1vCQy1NbgXvnqcEy793HZXI56lo2kMl3hqHs+XJxGEshJS2L HWopjBGYeS5Hj29zFsmJYQHidUrSlzH0WH8gZHnUtk33fiIJ3RvxQ980CONTQ/Ve3N 6GD4cQhdQv1+0Dk+eDp1efbZq/rTzDuZtHhODG+Za5GgTDnohuuyGd7x9CttLTGaMP /N/eLkzpOyvGg== Received: from IcarusMOD.eternityproject.eu (2-237-20-237.ip236.fastwebnet.it [2.237.20.237]) (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 bali.collaboradmins.com (Postfix) with ESMTPSA id 9CE7F17E14FB; Thu, 25 Sep 2025 16:31:32 +0200 (CEST) From: AngeloGioacchino Del Regno To: ulf.hansson@linaro.org Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, matthias.bgg@gmail.com, angelogioacchino.delregno@collabora.com, nfraprado@collabora.com, fshao@chromium.org, y.oudjana@protonmail.com, wenst@chromium.org, mandyjh.liu@mediatek.com, mbrugger@suse.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, kernel@collabora.com Subject: [PATCH v2 5/5] pmdomain: mediatek: Add support for MT8196 HFRPSYS power domains Date: Thu, 25 Sep 2025 16:31:16 +0200 Message-ID: <20250925143122.39796-6-angelogioacchino.delregno@collabora.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> References: <20250925143122.39796-1-angelogioacchino.delregno@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add support for the HFRPSYS Multimedia power domains found in the MediaTek MT8196 Chromebook SoC. Those power domains are all managed by the Hardware Voter MCU. Reviewed-by: N=C3=ADcolas F. R. A. Prado Signed-off-by: AngeloGioacchino Del Regno --- drivers/pmdomain/mediatek/mt8196-pm-domains.h | 239 ++++++++++++++++++ drivers/pmdomain/mediatek/mtk-pm-domains.c | 4 + 2 files changed, 243 insertions(+) diff --git a/drivers/pmdomain/mediatek/mt8196-pm-domains.h b/drivers/pmdoma= in/mediatek/mt8196-pm-domains.h index ce8d594c46f8..2e4b28720659 100644 --- a/drivers/pmdomain/mediatek/mt8196-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8196-pm-domains.h @@ -369,6 +369,239 @@ static const struct scpsys_hwv_domain_data scpsys_hwv= _domain_data_mt8196[] =3D { }, }; =20 +static const struct scpsys_hwv_domain_data hfrpsys_hwv_domain_data_mt8196[= ] =3D { + [MT8196_POWER_DOMAIN_VDE0] =3D { + .name =3D "vde0", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 7, + }, + [MT8196_POWER_DOMAIN_VDE1] =3D { + .name =3D "vde1", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 8, + }, + [MT8196_POWER_DOMAIN_VDE_VCORE0] =3D { + .name =3D "vde-vcore0", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 9, + }, + [MT8196_POWER_DOMAIN_VEN0] =3D { + .name =3D "ven0", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 10, + }, + [MT8196_POWER_DOMAIN_VEN1] =3D { + .name =3D "ven1", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 11, + }, + [MT8196_POWER_DOMAIN_VEN2] =3D { + .name =3D "ven2", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 12, + }, + [MT8196_POWER_DOMAIN_DISP_VCORE] =3D { + .name =3D "disp-vcore", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 24, + }, + [MT8196_POWER_DOMAIN_DIS0_DORMANT] =3D { + .name =3D "dis0-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 25, + }, + [MT8196_POWER_DOMAIN_DIS1_DORMANT] =3D { + .name =3D "dis1-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 26, + }, + [MT8196_POWER_DOMAIN_OVL0_DORMANT] =3D { + .name =3D "ovl0-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 27, + }, + [MT8196_POWER_DOMAIN_OVL1_DORMANT] =3D { + .name =3D "ovl1-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 28, + }, + [MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT] =3D { + .name =3D "disp-edptx-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 29, + }, + [MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT] =3D { + .name =3D "disp-dptx-dormant", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 30, + }, + [MT8196_POWER_DOMAIN_MML0_SHUTDOWN] =3D { + .name =3D "mml0-shutdown", + .set =3D 0x0218, + .clr =3D 0x021C, + .done =3D 0x141C, + .en =3D 0x1410, + .set_sta =3D 0x146C, + .clr_sta =3D 0x1470, + .setclr_bit =3D 31, + }, + [MT8196_POWER_DOMAIN_MML1_SHUTDOWN] =3D { + .name =3D "mml1-shutdown", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 0, + }, + [MT8196_POWER_DOMAIN_MM_INFRA0] =3D { + .name =3D "mm-infra0", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 1, + }, + [MT8196_POWER_DOMAIN_MM_INFRA1] =3D { + .name =3D "mm-infra1", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 2, + }, + [MT8196_POWER_DOMAIN_MM_INFRA_AO] =3D { + .name =3D "mm-infra-ao", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 3, + }, + [MT8196_POWER_DOMAIN_CSI_BS_RX] =3D { + .name =3D "csi-bs-rx", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 5, + }, + [MT8196_POWER_DOMAIN_CSI_LS_RX] =3D { + .name =3D "csi-ls-rx", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 6, + }, + [MT8196_POWER_DOMAIN_DSI_PHY0] =3D { + .name =3D "dsi-phy0", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 7, + }, + [MT8196_POWER_DOMAIN_DSI_PHY1] =3D { + .name =3D "dsi-phy1", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 8, + }, + [MT8196_POWER_DOMAIN_DSI_PHY2] =3D { + .name =3D "dsi-phy2", + .set =3D 0x0220, + .clr =3D 0x0224, + .done =3D 0x142C, + .en =3D 0x1420, + .set_sta =3D 0x1474, + .clr_sta =3D 0x1478, + .setclr_bit =3D 9, + }, +}; + static const struct scpsys_soc_data mt8196_scpsys_data =3D { .domains_data =3D scpsys_domain_data_mt8196, .num_domains =3D ARRAY_SIZE(scpsys_domain_data_mt8196), @@ -383,4 +616,10 @@ static const struct scpsys_soc_data mt8196_scpsys_hwv_= data =3D { .type =3D SCPSYS_MTCMOS_TYPE_HW_VOTER, }; =20 +static const struct scpsys_soc_data mt8196_hfrpsys_hwv_data =3D { + .hwv_domains_data =3D hfrpsys_hwv_domain_data_mt8196, + .num_hwv_domains =3D ARRAY_SIZE(hfrpsys_hwv_domain_data_mt8196), + .type =3D SCPSYS_MTCMOS_TYPE_HW_VOTER, +}; + #endif /* __SOC_MEDIATEK_MT8196_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/= mediatek/mtk-pm-domains.c index 18f0b9b960d9..ac144ab8fce0 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -1158,6 +1158,10 @@ static const struct of_device_id scpsys_of_match[] = =3D { .compatible =3D "mediatek,mt8196-power-controller", .data =3D &mt8196_scpsys_data, }, + { + .compatible =3D "mediatek,mt8196-hwv-hfrp-power-controller", + .data =3D &mt8196_hfrpsys_hwv_data, + }, { .compatible =3D "mediatek,mt8196-hwv-scp-power-controller", .data =3D &mt8196_scpsys_hwv_data, --=20 2.51.0