diff options
38 files changed, 1590 insertions, 468 deletions
diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml b/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml index 4e78933232b6..6f3a8578fe2a 100644 --- a/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml +++ b/Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml @@ -19,11 +19,14 @@ description: | properties: compatible: - enum: - - marvell,pxa1908-apbc - - marvell,pxa1908-apbcp - - marvell,pxa1908-mpmu - - marvell,pxa1908-apmu + oneOf: + - enum: + - marvell,pxa1908-apbc + - marvell,pxa1908-apbcp + - marvell,pxa1908-mpmu + - items: + - const: marvell,pxa1908-apmu + - const: syscon reg: maxItems: 1 @@ -31,6 +34,9 @@ properties: '#clock-cells': const: 1 + '#power-domain-cells': + const: 1 + required: - compatible - reg @@ -38,11 +44,23 @@ required: additionalProperties: false +if: + not: + properties: + compatible: + contains: + const: marvell,pxa1908-apmu + +then: + properties: + '#power-domain-cells': false + examples: # APMU block: - | clock-controller@d4282800 { - compatible = "marvell,pxa1908-apmu"; + compatible = "marvell,pxa1908-apmu", "syscon"; reg = <0xd4282800 0x400>; #clock-cells = <1>; + #power-domain-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml index 15d74138baa3..12b71688dd34 100644 --- a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml +++ b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml @@ -24,6 +24,9 @@ properties: - amlogic,a5-pwrc - amlogic,c3-pwrc - amlogic,t7-pwrc + - amlogic,s6-pwrc + - amlogic,s7-pwrc + - amlogic,s7d-pwrc "#power-domain-cells": const: 1 diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml index 9c7cc632abee..500d98921581 100644 --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml @@ -44,6 +44,15 @@ properties: '#size-cells': const: 0 + access-controllers: + description: + A number of phandles to external blocks to set and clear the required + bits to enable or disable bus protection, necessary to avoid any bus + faults while enabling or disabling a power domain. + For example, this may hold phandles to INFRACFG and SMI. + minItems: 1 + maxItems: 3 + patternProperties: "^power-domain@[0-9a-f]+$": $ref: "#/$defs/power-domain-node" @@ -123,14 +132,17 @@ $defs: mediatek,infracfg: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the INFRACFG register range. + deprecated: true mediatek,infracfg-nao: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the INFRACFG-NAO register range. + deprecated: true mediatek,smi: $ref: /schemas/types.yaml#/definitions/phandle description: phandle to the device containing the SMI register range. + deprecated: true required: - reg @@ -138,6 +150,31 @@ $defs: required: - compatible +allOf: + - if: + properties: + compatible: + contains: + enum: + - mediatek,mt8183-power-controller + then: + properties: + access-controllers: + minItems: 2 + maxItems: 2 + + - if: + properties: + compatible: + contains: + enum: + - mediatek,mt8365-power-controller + then: + properties: + access-controllers: + minItems: 3 + maxItems: 3 + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml index b3554e7f9e76..34aea58094e5 100644 --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml @@ -18,7 +18,9 @@ description: properties: compatible: items: - - const: fsl,imx93-media-blk-ctrl + - enum: + - fsl,imx91-media-blk-ctrl + - fsl,imx93-media-blk-ctrl - const: syscon reg: @@ -31,21 +33,54 @@ properties: maxItems: 1 clocks: + minItems: 8 maxItems: 10 clock-names: - items: - - const: apb - - const: axi - - const: nic - - const: disp - - const: cam - - const: pxp - - const: lcdif - - const: isi - - const: csi - - const: dsi + minItems: 8 + maxItems: 10 +allOf: + - if: + properties: + compatible: + contains: + const: fsl,imx91-media-blk-ctrl + then: + properties: + clocks: + maxItems: 8 + clock-names: + items: + - const: apb + - const: axi + - const: nic + - const: disp + - const: cam + - const: lcdif + - const: isi + - const: csi + - if: + properties: + compatible: + contains: + const: fsl,imx93-media-blk-ctrl + then: + properties: + clocks: + minItems: 10 + clock-names: + items: + - const: apb + - const: axi + - const: nic + - const: disp + - const: cam + - const: pxp + - const: lcdif + - const: isi + - const: csi + - const: dsi required: - compatible - reg diff --git a/MAINTAINERS b/MAINTAINERS index daf520a13bdf..a84bfa671dfd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2871,7 +2871,9 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm64/boot/dts/marvell/mmp/ F: drivers/clk/mmp/clk-pxa1908*.c +F: drivers/pmdomain/marvell/ F: include/dt-bindings/clock/marvell,pxa1908.h +F: include/dt-bindings/power/marvell,pxa1908-power.h ARM/Mediatek RTC DRIVER M: Eddie Huang <eddie.huang@mediatek.com> @@ -21730,6 +21732,7 @@ F: drivers/mailbox/mailbox-th1520.c F: drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c F: drivers/pinctrl/pinctrl-th1520.c F: drivers/pmdomain/thead/ +F: drivers/power/reset/th1520-aon-reboot.c F: drivers/power/sequencing/pwrseq-thead-gpu.c F: drivers/reset/reset-th1520.c F: include/dt-bindings/clock/thead,th1520-clk-ap.h diff --git a/drivers/pmdomain/Kconfig b/drivers/pmdomain/Kconfig index 91f04ace35d4..23076ae90e66 100644 --- a/drivers/pmdomain/Kconfig +++ b/drivers/pmdomain/Kconfig @@ -7,6 +7,7 @@ source "drivers/pmdomain/apple/Kconfig" source "drivers/pmdomain/arm/Kconfig" source "drivers/pmdomain/bcm/Kconfig" source "drivers/pmdomain/imx/Kconfig" +source "drivers/pmdomain/marvell/Kconfig" source "drivers/pmdomain/mediatek/Kconfig" source "drivers/pmdomain/qcom/Kconfig" source "drivers/pmdomain/renesas/Kconfig" diff --git a/drivers/pmdomain/Makefile b/drivers/pmdomain/Makefile index 7030f44a49df..ebc802f13eb9 100644 --- a/drivers/pmdomain/Makefile +++ b/drivers/pmdomain/Makefile @@ -5,6 +5,7 @@ obj-y += apple/ obj-y += arm/ obj-y += bcm/ obj-y += imx/ +obj-y += marvell/ obj-y += mediatek/ obj-y += qcom/ obj-y += renesas/ diff --git a/drivers/pmdomain/amlogic/meson-secure-pwrc.c b/drivers/pmdomain/amlogic/meson-secure-pwrc.c index e8bda60078c4..1d2f371d2d7f 100644 --- a/drivers/pmdomain/amlogic/meson-secure-pwrc.c +++ b/drivers/pmdomain/amlogic/meson-secure-pwrc.c @@ -16,6 +16,9 @@ #include <dt-bindings/power/amlogic,t7-pwrc.h> #include <dt-bindings/power/amlogic,a4-pwrc.h> #include <dt-bindings/power/amlogic,a5-pwrc.h> +#include <dt-bindings/power/amlogic,s6-pwrc.h> +#include <dt-bindings/power/amlogic,s7-pwrc.h> +#include <dt-bindings/power/amlogic,s7d-pwrc.h> #include <linux/arm-smccc.h> #include <linux/firmware/meson/meson_sm.h> #include <linux/module.h> @@ -201,6 +204,71 @@ static const struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = { SEC_PD(S4_AUDIO, 0), }; +static const struct meson_secure_pwrc_domain_desc s6_pwrc_domains[] = { + SEC_PD(S6_DSPA, 0), + SEC_PD(S6_DOS_HEVC, 0), + SEC_PD(S6_DOS_VDEC, 0), + SEC_PD(S6_VPU_HDMI, 0), + SEC_PD(S6_U2DRD, 0), + SEC_PD(S6_U3DRD, 0), + SEC_PD(S6_SD_EMMC_C, 0), + SEC_PD(S6_GE2D, 0), + SEC_PD(S6_AMFC, 0), + SEC_PD(S6_VC9000E, 0), + SEC_PD(S6_DEWARP, 0), + SEC_PD(S6_VICP, 0), + SEC_PD(S6_SD_EMMC_A, 0), + SEC_PD(S6_SD_EMMC_B, 0), + /* ETH is for ethernet online wakeup, and should be always on */ + SEC_PD(S6_ETH, GENPD_FLAG_ALWAYS_ON), + SEC_PD(S6_PCIE, 0), + SEC_PD(S6_NNA_4T, 0), + SEC_PD(S6_AUDIO, 0), + SEC_PD(S6_AUCPU, 0), + SEC_PD(S6_ADAPT, 0), +}; + +static const struct meson_secure_pwrc_domain_desc s7_pwrc_domains[] = { + SEC_PD(S7_DOS_HEVC, 0), + SEC_PD(S7_DOS_VDEC, 0), + SEC_PD(S7_VPU_HDMI, 0), + SEC_PD(S7_USB_COMB, 0), + SEC_PD(S7_SD_EMMC_C, 0), + SEC_PD(S7_GE2D, 0), + SEC_PD(S7_SD_EMMC_A, 0), + SEC_PD(S7_SD_EMMC_B, 0), + /* ETH is for ethernet online wakeup, and should be always on */ + SEC_PD(S7_ETH, GENPD_FLAG_ALWAYS_ON), + SEC_PD(S7_AUCPU, 0), + SEC_PD(S7_AUDIO, 0), +}; + +static const struct meson_secure_pwrc_domain_desc s7d_pwrc_domains[] = { + SEC_PD(S7D_DOS_HCODEC, 0), + SEC_PD(S7D_DOS_HEVC, 0), + SEC_PD(S7D_DOS_VDEC, 0), + SEC_PD(S7D_VPU_HDMI, 0), + SEC_PD(S7D_USB_U2DRD, 0), + SEC_PD(S7D_USB_U2H, 0), + SEC_PD(S7D_SSD_EMMC_C, 0), + SEC_PD(S7D_GE2D, 0), + SEC_PD(S7D_AMFC, 0), + SEC_PD(S7D_EMMC_A, 0), + SEC_PD(S7D_EMMC_B, 0), + /* ETH is for ethernet online wakeup, and should be always on */ + SEC_PD(S7D_ETH, GENPD_FLAG_ALWAYS_ON), + SEC_PD(S7D_AUCPU, 0), + SEC_PD(S7D_AUDIO, 0), + /* SRAMA is used as ATF runtime memory, and should be always on */ + SEC_PD(S7D_SRAMA, GENPD_FLAG_ALWAYS_ON), + /* DMC0 is for DDR PHY ana/dig and DMC, and should be always on */ + SEC_PD(S7D_DMC0, GENPD_FLAG_ALWAYS_ON), + /* DMC1 is for DDR PHY ana/dig and DMC, and should be always on */ + SEC_PD(S7D_DMC1, GENPD_FLAG_ALWAYS_ON), + /* DDR should be always on */ + SEC_PD(S7D_DDR, GENPD_FLAG_ALWAYS_ON), +}; + static const struct meson_secure_pwrc_domain_desc t7_pwrc_domains[] = { SEC_PD(T7_DSPA, 0), SEC_PD(T7_DSPB, 0), @@ -367,6 +435,21 @@ static const struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = { .count = ARRAY_SIZE(s4_pwrc_domains), }; +static const struct meson_secure_pwrc_domain_data amlogic_secure_s6_pwrc_data = { + .domains = s6_pwrc_domains, + .count = ARRAY_SIZE(s6_pwrc_domains), +}; + +static const struct meson_secure_pwrc_domain_data amlogic_secure_s7_pwrc_data = { + .domains = s7_pwrc_domains, + .count = ARRAY_SIZE(s7_pwrc_domains), +}; + +static const struct meson_secure_pwrc_domain_data amlogic_secure_s7d_pwrc_data = { + .domains = s7d_pwrc_domains, + .count = ARRAY_SIZE(s7d_pwrc_domains), +}; + static const struct meson_secure_pwrc_domain_data amlogic_secure_t7_pwrc_data = { .domains = t7_pwrc_domains, .count = ARRAY_SIZE(t7_pwrc_domains), @@ -394,6 +477,18 @@ static const struct of_device_id meson_secure_pwrc_match_table[] = { .data = &meson_secure_s4_pwrc_data, }, { + .compatible = "amlogic,s6-pwrc", + .data = &amlogic_secure_s6_pwrc_data, + }, + { + .compatible = "amlogic,s7-pwrc", + .data = &amlogic_secure_s7_pwrc_data, + }, + { + .compatible = "amlogic,s7d-pwrc", + .data = &amlogic_secure_s7d_pwrc_data, + }, + { .compatible = "amlogic,t7-pwrc", .data = &amlogic_secure_t7_pwrc_data, }, diff --git a/drivers/pmdomain/imx/gpc.c b/drivers/pmdomain/imx/gpc.c index f18c7e6e75dd..33991f3c6b55 100644 --- a/drivers/pmdomain/imx/gpc.c +++ b/drivers/pmdomain/imx/gpc.c @@ -343,7 +343,6 @@ static const struct regmap_config imx_gpc_regmap_config = { .rd_table = &access_table, .wr_table = &access_table, .max_register = 0x2ac, - .fast_io = true, }; static struct generic_pm_domain *imx_gpc_onecell_domains[] = { diff --git a/drivers/pmdomain/imx/imx93-blk-ctrl.c b/drivers/pmdomain/imx/imx93-blk-ctrl.c index 0e2ba8ec55d7..e094fe5a42bf 100644 --- a/drivers/pmdomain/imx/imx93-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx93-blk-ctrl.c @@ -86,6 +86,7 @@ struct imx93_blk_ctrl_domain { struct imx93_blk_ctrl_data { const struct imx93_blk_ctrl_domain_data *domains; + u32 skip_mask; int num_domains; const char * const *clk_names; int num_clks; @@ -250,6 +251,8 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev) int j; domain->data = data; + if (bc_data->skip_mask & BIT(i)) + continue; for (j = 0; j < data->num_clks; j++) domain->clks[j].id = data->clk_names[j]; @@ -418,16 +421,32 @@ static const struct regmap_access_table imx93_media_blk_ctl_access_table = { .n_yes_ranges = ARRAY_SIZE(imx93_media_blk_ctl_yes_ranges), }; +static const char * const media_blk_clk_names[] = { + "axi", "apb", "nic" +}; + +static const struct imx93_blk_ctrl_data imx91_media_blk_ctl_dev_data = { + .domains = imx93_media_blk_ctl_domain_data, + .skip_mask = BIT(IMX93_MEDIABLK_PD_MIPI_DSI) | BIT(IMX93_MEDIABLK_PD_PXP), + .num_domains = ARRAY_SIZE(imx93_media_blk_ctl_domain_data), + .clk_names = media_blk_clk_names, + .num_clks = ARRAY_SIZE(media_blk_clk_names), + .reg_access_table = &imx93_media_blk_ctl_access_table, +}; + static const struct imx93_blk_ctrl_data imx93_media_blk_ctl_dev_data = { .domains = imx93_media_blk_ctl_domain_data, .num_domains = ARRAY_SIZE(imx93_media_blk_ctl_domain_data), - .clk_names = (const char *[]){ "axi", "apb", "nic", }, - .num_clks = 3, + .clk_names = media_blk_clk_names, + .num_clks = ARRAY_SIZE(media_blk_clk_names), .reg_access_table = &imx93_media_blk_ctl_access_table, }; static const struct of_device_id imx93_blk_ctrl_of_match[] = { { + .compatible = "fsl,imx91-media-blk-ctrl", + .data = &imx91_media_blk_ctl_dev_data + }, { .compatible = "fsl,imx93-media-blk-ctrl", .data = &imx93_media_blk_ctl_dev_data }, { diff --git a/drivers/pmdomain/marvell/Kconfig b/drivers/pmdomain/marvell/Kconfig new file mode 100644 index 000000000000..6c4084c82667 --- /dev/null +++ b/drivers/pmdomain/marvell/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +menu "Marvell PM Domains" + depends on ARCH_MMP || COMPILE_TEST + +config PXA1908_PM_DOMAINS + tristate "Marvell PXA1908 power domains" + depends on OF + depends on PM + default y if ARCH_MMP && ARM64 + select AUXILIARY_BUS + select MFD_SYSCON + select PM_GENERIC_DOMAINS + select PM_GENERIC_DOMAINS_OF + help + Say Y here to enable support for Marvell PXA1908's power domanis. + +endmenu diff --git a/drivers/pmdomain/marvell/Makefile b/drivers/pmdomain/marvell/Makefile new file mode 100644 index 000000000000..22c25013f6c8 --- /dev/null +++ b/drivers/pmdomain/marvell/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_PXA1908_PM_DOMAINS) += pxa1908-power-controller.o diff --git a/drivers/pmdomain/marvell/pxa1908-power-controller.c b/drivers/pmdomain/marvell/pxa1908-power-controller.c new file mode 100644 index 000000000000..ff5e6e82d3f8 --- /dev/null +++ b/drivers/pmdomain/marvell/pxa1908-power-controller.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Duje Mihanović <duje@dujemihanovic.xyz> + */ + +#include <linux/auxiliary_bus.h> +#include <linux/container_of.h> +#include <linux/dev_printk.h> +#include <linux/device.h> +#include <linux/mfd/syscon.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/pm_domain.h> +#include <linux/regmap.h> + +#include <dt-bindings/power/marvell,pxa1908-power.h> + +/* VPU, GPU, ISP */ +#define APMU_PWR_CTRL_REG 0xd8 +#define APMU_PWR_BLK_TMR_REG 0xdc +#define APMU_PWR_STATUS_REG 0xf0 + +/* DSI */ +#define APMU_DEBUG 0x88 +#define DSI_PHY_DVM_MASK BIT(31) + +#define POWER_ON_LATENCY_US 300 +#define POWER_OFF_LATENCY_US 20 +#define POWER_POLL_TIMEOUT_US (25 * USEC_PER_MSEC) +#define POWER_POLL_SLEEP_US 6 + +#define NR_DOMAINS 5 + +#define to_pxa1908_pd(_genpd) container_of(_genpd, struct pxa1908_pd, genpd) + +struct pxa1908_pd_ctrl { + struct generic_pm_domain *domains[NR_DOMAINS]; + struct genpd_onecell_data onecell_data; + struct regmap *base; + struct device *dev; +}; + +struct pxa1908_pd_data { + u32 reg_clk_res_ctrl; + u32 pwr_state; + u32 hw_mode; + bool keep_on; + int id; +}; + +struct pxa1908_pd { + const struct pxa1908_pd_data data; + struct pxa1908_pd_ctrl *ctrl; + struct generic_pm_domain genpd; + bool initialized; +}; + +static inline bool pxa1908_pd_is_on(struct pxa1908_pd *pd) +{ + struct pxa1908_pd_ctrl *ctrl = pd->ctrl; + + return pd->data.id != PXA1908_POWER_DOMAIN_DSI + ? regmap_test_bits(ctrl->base, APMU_PWR_STATUS_REG, pd->data.pwr_state) + : regmap_test_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK); +} + +static int pxa1908_pd_power_on(struct generic_pm_domain *genpd) +{ + struct pxa1908_pd *pd = to_pxa1908_pd(genpd); + const struct pxa1908_pd_data *data = &pd->data; + struct pxa1908_pd_ctrl *ctrl = pd->ctrl; + unsigned int status; + int ret = 0; + + regmap_set_bits(ctrl->base, data->reg_clk_res_ctrl, data->hw_mode); + if (data->id != PXA1908_POWER_DOMAIN_ISP) + regmap_write(ctrl->base, APMU_PWR_BLK_TMR_REG, 0x20001fff); + regmap_set_bits(ctrl->base, APMU_PWR_CTRL_REG, data->pwr_state); + + ret = regmap_read_poll_timeout(ctrl->base, APMU_PWR_STATUS_REG, status, + status & data->pwr_state, POWER_POLL_SLEEP_US, + POWER_ON_LATENCY_US + POWER_POLL_TIMEOUT_US); + if (ret == -ETIMEDOUT) + dev_err(ctrl->dev, "timed out powering on domain '%s'\n", pd->genpd.name); + + return ret; +} + +static int pxa1908_pd_power_off(struct generic_pm_domain *genpd) +{ + struct pxa1908_pd *pd = to_pxa1908_pd(genpd); + const struct pxa1908_pd_data *data = &pd->data; + struct pxa1908_pd_ctrl *ctrl = pd->ctrl; + unsigned int status; + int ret; + + regmap_clear_bits(ctrl->base, APMU_PWR_CTRL_REG, data->pwr_state); + + ret = regmap_read_poll_timeout(ctrl->base, APMU_PWR_STATUS_REG, status, + !(status & data->pwr_state), POWER_POLL_SLEEP_US, + POWER_OFF_LATENCY_US + POWER_POLL_TIMEOUT_US); + if (ret == -ETIMEDOUT) { + dev_err(ctrl->dev, "timed out powering off domain '%s'\n", pd->genpd.name); + return ret; + } + + return regmap_clear_bits(ctrl->base, data->reg_clk_res_ctrl, data->hw_mode); +} + +static inline int pxa1908_dsi_power_on(struct generic_pm_domain *genpd) +{ + struct pxa1908_pd *pd = to_pxa1908_pd(genpd); + struct pxa1908_pd_ctrl *ctrl = pd->ctrl; + + return regmap_set_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK); +} + +static inline int pxa1908_dsi_power_off(struct generic_pm_domain *genpd) +{ + struct pxa1908_pd *pd = to_pxa1908_pd(genpd); + struct pxa1908_pd_ctrl *ctrl = pd->ctrl; + + return regmap_clear_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK); +} + +#define DOMAIN(_id, _name, ctrl, mode, state) \ + [_id] = { \ + .data = { \ + .reg_clk_res_ctrl = ctrl, \ + .hw_mode = BIT(mode), \ + .pwr_state = BIT(state), \ + .id = _id, \ + }, \ + .genpd = { \ + .name = _name, \ + .power_on = pxa1908_pd_power_on, \ + .power_off = pxa1908_pd_power_off, \ + }, \ + } + +static struct pxa1908_pd domains[NR_DOMAINS] = { + DOMAIN(PXA1908_POWER_DOMAIN_VPU, "vpu", 0xa4, 19, 2), + DOMAIN(PXA1908_POWER_DOMAIN_GPU, "gpu", 0xcc, 11, 0), + DOMAIN(PXA1908_POWER_DOMAIN_GPU2D, "gpu2d", 0xf4, 11, 6), + DOMAIN(PXA1908_POWER_DOMAIN_ISP, "isp", 0x38, 15, 4), + [PXA1908_POWER_DOMAIN_DSI] = { + .genpd = { + .name = "dsi", + .power_on = pxa1908_dsi_power_on, + .power_off = pxa1908_dsi_power_off, + /* + * TODO: There is no DSI driver written yet and until then we probably + * don't want to power off the DSI PHY ever. + */ + .flags = GENPD_FLAG_ALWAYS_ON, + }, + .data = { + /* See above. */ + .keep_on = true, + }, + }, +}; + +static void pxa1908_pd_remove(struct auxiliary_device *auxdev) +{ + struct pxa1908_pd *pd; + int ret; + + for (int i = NR_DOMAINS - 1; i >= 0; i--) { + pd = &domains[i]; + + if (!pd->initialized) + continue; + + if (pxa1908_pd_is_on(pd) && !pd->data.keep_on) + pxa1908_pd_power_off(&pd->genpd); + + ret = pm_genpd_remove(&pd->genpd); + if (ret) + dev_err(&auxdev->dev, "failed to remove domain '%s': %d\n", + pd->genpd.name, ret); + } +} + +static int +pxa1908_pd_init(struct pxa1908_pd_ctrl *ctrl, int id, struct device *dev) +{ + struct pxa1908_pd *pd = &domains[id]; + int ret; + + ctrl->domains[id] = &pd->genpd; + + pd->ctrl = ctrl; + + /* Make sure the state of the hardware is synced with the domain table above. */ + if (pd->data.keep_on) { + ret = pd->genpd.power_on(&pd->genpd); + if (ret) + return dev_err_probe(dev, ret, "failed to power on domain '%s'\n", + pd->genpd.name); + } else { + if (pxa1908_pd_is_on(pd)) { + dev_warn(dev, + "domain '%s' is on despite being default off; powering off\n", + pd->genpd.name); + + ret = pd->genpd.power_off(&pd->genpd); + if (ret) + return dev_err_probe(dev, ret, + "failed to power off domain '%s'\n", + pd->genpd.name); + } + } + + ret = pm_genpd_init(&pd->genpd, NULL, !pd->data.keep_on); + if (ret) + return dev_err_probe(dev, ret, "domain '%s' failed to initialize\n", + pd->genpd.name); + + pd->initialized = true; + + return 0; +} + +static int +pxa1908_pd_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *aux_id) +{ + struct pxa1908_pd_ctrl *ctrl; + struct device *dev = &auxdev->dev; + int ret; + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + auxiliary_set_drvdata(auxdev, ctrl); + + ctrl->base = syscon_node_to_regmap(dev->parent->of_node); + if (IS_ERR(ctrl->base)) + return dev_err_probe(dev, PTR_ERR(ctrl->base), "no regmap available\n"); + + ctrl->dev = dev; + ctrl->onecell_data.domains = ctrl->domains; + ctrl->onecell_data.num_domains = NR_DOMAINS; + + for (int i = 0; i < NR_DOMAINS; i++) { + ret = pxa1908_pd_init(ctrl, i, dev); + if (ret) + goto err; + } + + return of_genpd_add_provider_onecell(dev->parent->of_node, &ctrl->onecell_data); + +err: + pxa1908_pd_remove(auxdev); + return ret; +} + +static const struct auxiliary_device_id pxa1908_pd_id[] = { + { .name = "clk_pxa1908_apmu.power" }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, pxa1908_pd_id); + +static struct auxiliary_driver pxa1908_pd_driver = { + .probe = pxa1908_pd_probe, + .remove = pxa1908_pd_remove, + .id_table = pxa1908_pd_id, +}; +module_auxiliary_driver(pxa1908_pd_driver); + +MODULE_AUTHOR("Duje Mihanović <duje@dujemihanovic.xyz>"); +MODULE_DESCRIPTION("Marvell PXA1908 power domain driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c index 0fd88d2f9ac2..3b1d202f89dc 100644 --- a/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c +++ b/drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c @@ -21,10 +21,10 @@ struct airoha_cpu_pmdomain_priv { struct generic_pm_domain pd; }; -static long airoha_cpu_pmdomain_clk_round(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int airoha_cpu_pmdomain_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return rate; + return 0; } static unsigned long airoha_cpu_pmdomain_clk_get(struct clk_hw *hw, @@ -48,7 +48,7 @@ static int airoha_cpu_pmdomain_clk_is_enabled(struct clk_hw *hw) static const struct clk_ops airoha_cpu_pmdomain_clk_ops = { .recalc_rate = airoha_cpu_pmdomain_clk_get, .is_enabled = airoha_cpu_pmdomain_clk_is_enabled, - .round_rate = airoha_cpu_pmdomain_clk_round, + .determine_rate = airoha_cpu_pmdomain_clk_determine_rate, }; static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain, diff --git a/drivers/pmdomain/mediatek/mt6795-pm-domains.h b/drivers/pmdomain/mediatek/mt6795-pm-domains.h index a3f7785b04bd..dc8e9f8877ad 100644 --- a/drivers/pmdomain/mediatek/mt6795-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt6795-pm-domains.h @@ -9,6 +9,9 @@ /* * MT6795 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt6795[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = { [MT6795_POWER_DOMAIN_VDEC] = { @@ -107,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = { static const struct scpsys_soc_data mt6795_scpsys_data = { .domains_data = scpsys_domain_data_mt6795, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt6795), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt6795, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt6795), }; #endif /* __SOC_MEDIATEK_MT6795_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8167-pm-domains.h b/drivers/pmdomain/mediatek/mt8167-pm-domains.h index 8a0e898b79ab..f6ee48a711a1 100644 --- a/drivers/pmdomain/mediatek/mt8167-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8167-pm-domains.h @@ -12,6 +12,9 @@ /* * MT8167 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8167[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { [MT8167_POWER_DOMAIN_MM] = { @@ -99,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { static const struct scpsys_soc_data mt8167_scpsys_data = { .domains_data = scpsys_domain_data_mt8167, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8167, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8167), }; #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8173-pm-domains.h b/drivers/pmdomain/mediatek/mt8173-pm-domains.h index 7be0f47f5214..561a644b5d1c 100644 --- a/drivers/pmdomain/mediatek/mt8173-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8173-pm-domains.h @@ -9,6 +9,9 @@ /* * MT8173 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8173[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { [MT8173_POWER_DOMAIN_VDEC] = { @@ -118,6 +121,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { static const struct scpsys_soc_data mt8173_scpsys_data = { .domains_data = scpsys_domain_data_mt8173, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8173, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8173), }; #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8183-pm-domains.h b/drivers/pmdomain/mediatek/mt8183-pm-domains.h index c4c1b63d85b1..3742782a2702 100644 --- a/drivers/pmdomain/mediatek/mt8183-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8183-pm-domains.h @@ -9,6 +9,9 @@ /* * MT8183 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8183[] = { + BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SMI +}; static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { [MT8183_POWER_DOMAIN_AUDIO] = { @@ -290,6 +293,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { static const struct scpsys_soc_data mt8183_scpsys_data = { .domains_data = scpsys_domain_data_mt8183, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8183, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8183), }; #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8186-pm-domains.h b/drivers/pmdomain/mediatek/mt8186-pm-domains.h index cbac715c38fa..00b9861af7c9 100644 --- a/drivers/pmdomain/mediatek/mt8186-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8186-pm-domains.h @@ -13,6 +13,9 @@ /* * MT8186 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8186[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = { [MT8186_POWER_DOMAIN_MFG0] = { @@ -361,6 +364,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = { static const struct scpsys_soc_data mt8186_scpsys_data = { .domains_data = scpsys_domain_data_mt8186, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8186), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8186, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8186), }; #endif /* __SOC_MEDIATEK_MT8186_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h index 007235be9efe..3a989e83e9b7 100644 --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h @@ -14,6 +14,10 @@ * MT8188 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8188[] = { + BUS_PROT_BLOCK_INFRA +}; + static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { [MT8188_POWER_DOMAIN_MFG0] = { .name = "mfg0", @@ -685,6 +689,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { static const struct scpsys_soc_data mt8188_scpsys_data = { .domains_data = scpsys_domain_data_mt8188, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8188), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8188, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8188), }; #endif /* __SOC_MEDIATEK_MT8188_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8192-pm-domains.h b/drivers/pmdomain/mediatek/mt8192-pm-domains.h index 6f139eed3769..5d62fac5f682 100644 --- a/drivers/pmdomain/mediatek/mt8192-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8192-pm-domains.h @@ -9,6 +9,9 @@ /* * MT8192 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8192[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { [MT8192_POWER_DOMAIN_AUDIO] = { @@ -380,6 +383,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { static const struct scpsys_soc_data mt8192_scpsys_data = { .domains_data = scpsys_domain_data_mt8192, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8192, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8192), }; #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8195-pm-domains.h b/drivers/pmdomain/mediatek/mt8195-pm-domains.h index 414dfe82361f..1d3ca195ac75 100644 --- a/drivers/pmdomain/mediatek/mt8195-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8195-pm-domains.h @@ -13,6 +13,9 @@ /* * MT8195 power domain support */ +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8195[] = { + BUS_PROT_BLOCK_INFRA +}; static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = { [MT8195_POWER_DOMAIN_PCIE_MAC_P0] = { @@ -662,6 +665,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = { static const struct scpsys_soc_data mt8195_scpsys_data = { .domains_data = scpsys_domain_data_mt8195, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8195, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8195), }; #endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mt8365-pm-domains.h b/drivers/pmdomain/mediatek/mt8365-pm-domains.h index 3d83d49eaa7c..33265ab8ce76 100644 --- a/drivers/pmdomain/mediatek/mt8365-pm-domains.h +++ b/drivers/pmdomain/mediatek/mt8365-pm-domains.h @@ -29,11 +29,13 @@ MT8365_SMI_COMMON_CLAMP_EN) #define MT8365_BUS_PROT_WAY_EN(_set_mask, _set, _sta_mask, _sta) \ - _BUS_PROT(_set_mask, _set, _set, _sta_mask, _sta, \ - BUS_PROT_COMPONENT_INFRA | \ - BUS_PROT_STA_COMPONENT_INFRA_NAO | \ - BUS_PROT_INVERTED | \ - BUS_PROT_REG_UPDATE) + _BUS_PROT_STA(INFRA, INFRA_NAO, _set_mask, _set, _set, \ + _sta_mask, _sta, \ + BUS_PROT_INVERTED | BUS_PROT_REG_UPDATE) + +static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8365[] = { + BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_INFRA_NAO, BUS_PROT_BLOCK_SMI +}; static const struct scpsys_domain_data scpsys_domain_data_mt8365[] = { [MT8365_POWER_DOMAIN_MM] = { @@ -192,6 +194,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8365[] = { static const struct scpsys_soc_data mt8365_scpsys_data = { .domains_data = scpsys_domain_data_mt8365, .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8365), + .bus_prot_blocks = scpsys_bus_prot_blocks_mt8365, + .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8365), }; #endif /* __SOC_MEDIATEK_MT8365_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c index a58ed7e2d9a4..0ebe7379b94e 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c @@ -39,6 +39,12 @@ #define PWR_SRAM_CLKISO_BIT BIT(5) #define PWR_SRAM_ISOINT_B_BIT BIT(6) +#define PWR_RTFF_SAVE BIT(24) +#define PWR_RTFF_NRESTORE BIT(25) +#define PWR_RTFF_CLK_DIS BIT(26) +#define PWR_RTFF_SAVE_FLAG BIT(27) +#define PWR_RTFF_UFS_CLK_DIS BIT(28) + struct scpsys_domain { struct generic_pm_domain genpd; const struct scpsys_domain_data *data; @@ -47,9 +53,6 @@ struct scpsys_domain { struct clk_bulk_data *clks; int num_subsys_clks; struct clk_bulk_data *subsys_clks; - struct regmap *infracfg_nao; - struct regmap *infracfg; - struct regmap *smi; struct regulator *supply; }; @@ -57,6 +60,8 @@ struct scpsys { struct device *dev; struct regmap *base; const struct scpsys_soc_data *soc_data; + u8 bus_prot_index[BUS_PROT_BLOCK_COUNT]; + struct regmap **bus_prot; struct genpd_onecell_data pd_data; struct generic_pm_domain *domains[]; }; @@ -80,16 +85,23 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd) static int scpsys_sram_enable(struct scpsys_domain *pd) { - u32 pdn_ack = pd->data->sram_pdn_ack_bits; + u32 expected_ack, pdn_ack = pd->data->sram_pdn_ack_bits; struct scpsys *scpsys = pd->scpsys; unsigned int tmp; int ret; - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_PDN_INVERTED)) { + regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + expected_ack = pdn_ack; + } else { + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + expected_ack = 0; + } /* Either wait until SRAM_PDN_ACK all 1 or 0 */ ret = regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, - (tmp & pdn_ack) == 0, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); + (tmp & pdn_ack) == expected_ack, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret < 0) return ret; @@ -104,7 +116,7 @@ static int scpsys_sram_enable(struct scpsys_domain *pd) static int scpsys_sram_disable(struct scpsys_domain *pd) { - u32 pdn_ack = pd->data->sram_pdn_ack_bits; + u32 expected_ack, pdn_ack = pd->data->sram_pdn_ack_bits; struct scpsys *scpsys = pd->scpsys; unsigned int tmp; @@ -114,30 +126,36 @@ static int scpsys_sram_disable(struct scpsys_domain *pd) regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT); } - regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_PDN_INVERTED)) { + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + expected_ack = 0; + } else { + regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); + expected_ack = pdn_ack; + } /* Either wait until SRAM_PDN_ACK all 1 or 0 */ return regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, - (tmp & pdn_ack) == pdn_ack, MTK_POLL_DELAY_US, - MTK_POLL_TIMEOUT); + (tmp & pdn_ack) == expected_ack, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); } static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd, const struct scpsys_bus_prot_data *bpd) { - if (bpd->flags & BUS_PROT_COMPONENT_SMI) - return pd->smi; - else - return pd->infracfg; + struct scpsys *scpsys = pd->scpsys; + unsigned short block_idx = scpsys->bus_prot_index[bpd->bus_prot_block]; + + return scpsys->bus_prot[block_idx]; } static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd, const struct scpsys_bus_prot_data *bpd) { - if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO) - return pd->infracfg_nao; - else - return scpsys_bus_protect_get_regmap(pd, bpd); + struct scpsys *scpsys = pd->scpsys; + int block_idx = scpsys->bus_prot_index[bpd->bus_prot_sta_block]; + + return scpsys->bus_prot[block_idx]; } static int scpsys_bus_protect_clear(struct scpsys_domain *pd, @@ -149,7 +167,7 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd, u32 expected_ack; u32 val; - expected_ack = (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO ? sta_mask : 0); + expected_ack = (bpd->bus_prot_sta_block == BUS_PROT_BLOCK_INFRA_NAO ? sta_mask : 0); if (bpd->flags & BUS_PROT_REG_UPDATE) regmap_clear_bits(regmap, bpd->bus_prot_clr, bpd->bus_prot_set_clr_mask); @@ -232,11 +250,161 @@ static int scpsys_regulator_disable(struct regulator *supply) return supply ? regulator_disable(supply) : 0; } +static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd) +{ + struct scpsys *scpsys = pd->scpsys; + bool do_rtff_nrestore, tmp; + int ret; + + /* subsys power on */ + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); + + /* wait until PWR_ACK = 1 */ + ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US, + MTK_POLL_TIMEOUT); + if (ret < 0) + return ret; + + if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY) + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); + + /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */ + if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY) + udelay(5); + + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); + + /* + * RTFF HW state may be modified by secure world or remote processors. + * + * With the only exception of STOR_UFS, which always needs save/restore, + * check if this power domain's RTFF is already on before trying to do + * the NRESTORE procedure, otherwise the system will lock up. + */ + switch (pd->data->rtff_type) { + case SCPSYS_RTFF_TYPE_GENERIC: + case SCPSYS_RTFF_TYPE_PCIE_PHY: + { + u32 ctl_status; + + regmap_read(scpsys->base, pd->data->ctl_offs, &ctl_status); + do_rtff_nrestore = ctl_status & PWR_RTFF_SAVE_FLAG; + break; + } + case SCPSYS_RTFF_TYPE_STOR_UFS: + /* STOR_UFS always needs NRESTORE */ + do_rtff_nrestore = true; + break; + default: + do_rtff_nrestore = false; + break; + } + + /* Return early if RTFF NRESTORE shall not be done */ + if (!do_rtff_nrestore) + return 0; + + switch (pd->data->rtff_type) { + case SCPSYS_RTFF_TYPE_GENERIC: + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + break; + case SCPSYS_RTFF_TYPE_PCIE_PHY: + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + break; + case SCPSYS_RTFF_TYPE_STOR_UFS: + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS); + break; + default: + break; + } + + return 0; +} + +static void scpsys_ctl_pwrseq_off(struct scpsys_domain *pd) +{ + struct scpsys *scpsys = pd->scpsys; + + switch (pd->data->rtff_type) { + case SCPSYS_RTFF_TYPE_GENERIC: + case SCPSYS_RTFF_TYPE_PCIE_PHY: + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG); + break; + case SCPSYS_RTFF_TYPE_STOR_UFS: + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS); + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS); + break; + default: + break; + } + + /* subsys power off */ + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); + + /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */ + if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY) + udelay(1); + + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); +} + +static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd) +{ + struct scpsys *scpsys = pd->scpsys; + bool tmp; + int ret; + + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B)) + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); + + regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); + + /* wait until PWR_ACK = 1 */ + ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US, + MTK_POLL_TIMEOUT); + if (ret < 0) + return ret; + + return 0; +} + +static void scpsys_modem_pwrseq_off(struct scpsys_domain *pd) +{ + struct scpsys *scpsys = pd->scpsys; + + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); + + if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B)) + regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); +} + static int scpsys_power_on(struct generic_pm_domain *genpd) { struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); struct scpsys *scpsys = pd->scpsys; - bool tmp; int ret; ret = scpsys_regulator_enable(pd->supply); @@ -251,20 +419,14 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs, pd->data->ext_buck_iso_mask); - /* subsys power on */ - regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); - regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); + if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ)) + ret = scpsys_modem_pwrseq_on(pd); + else + ret = scpsys_ctl_pwrseq_on(pd); - /* wait until PWR_ACK = 1 */ - ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US, - MTK_POLL_TIMEOUT); - if (ret < 0) + if (ret) goto err_pwr_ack; - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); - regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); - /* * In few Mediatek platforms(e.g. MT6779), the bus protect policy is * stricter, which leads to bus protect release must be prior to bus @@ -330,12 +492,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); - /* subsys power off */ - regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); - regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); - regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); + if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ)) + scpsys_modem_pwrseq_off(pd); + else + scpsys_ctl_pwrseq_off(pd); /* wait until PWR_ACK = 0 */ ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US, @@ -355,7 +515,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no { const struct scpsys_domain_data *domain_data; struct scpsys_domain *pd; - struct device_node *smi_node; struct property *prop; const char *clk_name; int i, ret, num_clks; @@ -396,32 +555,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no node); } - pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg"); - if (IS_ERR(pd->infracfg)) - return dev_err_cast_probe(scpsys->dev, pd->infracfg, - "%pOF: failed to get infracfg regmap\n", - node); - - smi_node = of_parse_phandle(node, "mediatek,smi", 0); - if (smi_node) { - pd->smi = device_node_to_regmap(smi_node); - of_node_put(smi_node); - if (IS_ERR(pd->smi)) - return dev_err_cast_probe(scpsys->dev, pd->smi, - "%pOF: failed to get SMI regmap\n", - node); - } - - if (MTK_SCPD_CAPS(pd, MTK_SCPD_HAS_INFRA_NAO)) { - pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao"); - if (IS_ERR(pd->infracfg_nao)) - return dev_err_cast_probe(scpsys->dev, pd->infracfg_nao, - "%pOF: failed to get infracfg-nao regmap\n", - node); - } else { - pd->infracfg_nao = NULL; - } - num_clks = of_clk_get_parent_count(node); if (num_clks > 0) { /* Calculate number of subsys_clks */ @@ -615,6 +748,136 @@ static void scpsys_domain_cleanup(struct scpsys *scpsys) } } +static int scpsys_get_bus_protection_legacy(struct device *dev, struct scpsys *scpsys) +{ + const u8 bp_blocks[3] = { + BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SMI, BUS_PROT_BLOCK_INFRA_NAO + }; + struct device_node *np = dev->of_node; + struct device_node *node, *smi_np; + int num_regmaps = 0, i, j; + struct regmap *regmap[3]; + + /* + * Legacy code retrieves a maximum of three bus protection handles: + * some may be optional, or may not be, so the array of bp blocks + * that is normally passed in as platform data must be dynamically + * built in this case. + * + * Here, try to retrieve all of the regmaps that the legacy code + * supported and then count the number of the ones that are present, + * this makes it then possible to allocate the array of bus_prot + * regmaps and convert all to the new style handling. + */ + node = of_find_node_with_property(np, "mediatek,infracfg"); + if (node) { + regmap[0] = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg"); + of_node_put(node); + num_regmaps++; + if (IS_ERR(regmap[0])) + return dev_err_probe(dev, PTR_ERR(regmap[0]), + "%pOF: failed to get infracfg regmap\n", + node); + } else { + regmap[0] = NULL; + } + + node = of_find_node_with_property(np, "mediatek,smi"); + if (node) { + smi_np = of_parse_phandle(node, "mediatek,smi", 0); + of_node_put(node); + if (!smi_np) + return -ENODEV; + + regmap[1] = device_node_to_regmap(smi_np); + num_regmaps++; + of_node_put(smi_np); + if (IS_ERR(regmap[1])) + return dev_err_probe(dev, PTR_ERR(regmap[1]), + "%pOF: failed to get SMI regmap\n", + node); + } else { + regmap[1] = NULL; + } + + node = of_find_node_with_property(np, "mediatek,infracfg-nao"); + if (node) { + regmap[2] = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao"); + num_regmaps++; + of_node_put(node); + if (IS_ERR(regmap[2])) + return dev_err_probe(dev, PTR_ERR(regmap[2]), + "%pOF: failed to get infracfg regmap\n", + node); + } else { + regmap[2] = NULL; + } + + scpsys->bus_prot = devm_kmalloc_array(dev, num_regmaps, + sizeof(*scpsys->bus_prot), GFP_KERNEL); + if (!scpsys->bus_prot) + return -ENOMEM; + + for (i = 0, j = 0; i < ARRAY_SIZE(bp_blocks); i++) { + enum scpsys_bus_prot_block bp_type; + + if (!regmap[i]) + continue; + + bp_type = bp_blocks[i]; + scpsys->bus_prot_index[bp_type] = j; + scpsys->bus_prot[j] = regmap[i]; + + j++; + } + + return 0; +} + +static int scpsys_get_bus_protection(struct device *dev, struct scpsys *scpsys) +{ + const struct scpsys_soc_data *soc = scpsys->soc_data; + struct device_node *np = dev->of_node; + int i, num_handles; + + num_handles = of_count_phandle_with_args(np, "access-controllers", NULL); + if (num_handles < 0 || num_handles != soc->num_bus_prot_blocks) + return dev_err_probe(dev, -EINVAL, + "Cannot get access controllers: expected %u, got %d\n", + soc->num_bus_prot_blocks, num_handles); + + scpsys->bus_prot = devm_kmalloc_array(dev, soc->num_bus_prot_blocks, + sizeof(*scpsys->bus_prot), GFP_KERNEL); + if (!scpsys->bus_prot) + return -ENOMEM; + + for (i = 0; i < soc->num_bus_prot_blocks; i++) { + enum scpsys_bus_prot_block bp_type; + struct device_node *node; + + node = of_parse_phandle(np, "access-controllers", i); + if (!node) + return -EINVAL; + + /* + * Index the bus protection regmaps so that we don't have to + * find the right one by type with a loop at every execution + * of power sequence(s). + */ + bp_type = soc->bus_prot_blocks[i]; + scpsys->bus_prot_index[bp_type] = i; + + scpsys->bus_prot[i] = device_node_to_regmap(node); + of_node_put(node); + if (IS_ERR_OR_NULL(scpsys->bus_prot[i])) + return dev_err_probe(dev, scpsys->bus_prot[i] ? + PTR_ERR(scpsys->bus_prot[i]) : -ENXIO, + "Cannot get regmap for access controller %d\n", i); + } + + return 0; +} + static const struct of_device_id scpsys_of_match[] = { { .compatible = "mediatek,mt6735-power-controller", @@ -701,6 +964,14 @@ static int scpsys_probe(struct platform_device *pdev) return PTR_ERR(scpsys->base); } + if (of_find_property(np, "access-controllers", NULL)) + ret = scpsys_get_bus_protection(dev, scpsys); + else + ret = scpsys_get_bus_protection_legacy(dev, scpsys); + + if (ret) + return ret; + ret = -ENODEV; for_each_available_child_of_node(np, node) { struct generic_pm_domain *domain; diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h index 7085fa2976e9..b2e3dee03831 100644 --- a/drivers/pmdomain/mediatek/mtk-pm-domains.h +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h @@ -13,6 +13,9 @@ #define MTK_SCPD_EXT_BUCK_ISO BIT(6) #define MTK_SCPD_HAS_INFRA_NAO BIT(7) #define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8) +#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 SPM_VDE_PWR_CON 0x0210 @@ -50,30 +53,43 @@ enum scpsys_bus_prot_flags { BUS_PROT_REG_UPDATE = BIT(1), BUS_PROT_IGNORE_CLR_ACK = BIT(2), BUS_PROT_INVERTED = BIT(3), - BUS_PROT_COMPONENT_INFRA = BIT(4), - BUS_PROT_COMPONENT_SMI = BIT(5), - BUS_PROT_STA_COMPONENT_INFRA_NAO = BIT(6), }; -#define _BUS_PROT(_set_clr_mask, _set, _clr, _sta_mask, _sta, _flags) { \ - .bus_prot_set_clr_mask = (_set_clr_mask), \ - .bus_prot_set = _set, \ - .bus_prot_clr = _clr, \ - .bus_prot_sta_mask = (_sta_mask), \ - .bus_prot_sta = _sta, \ - .flags = _flags \ +enum scpsys_bus_prot_block { + BUS_PROT_BLOCK_INFRA, + BUS_PROT_BLOCK_INFRA_NAO, + BUS_PROT_BLOCK_SMI, + BUS_PROT_BLOCK_COUNT, +}; + +#define _BUS_PROT_STA(_hwip, _sta_hwip, _set_clr_mask, _set, _clr, \ + _sta_mask, _sta, _flags) \ + { \ + .bus_prot_block = BUS_PROT_BLOCK_##_hwip, \ + .bus_prot_sta_block = BUS_PROT_BLOCK_##_sta_hwip, \ + .bus_prot_set_clr_mask = (_set_clr_mask), \ + .bus_prot_set = _set, \ + .bus_prot_clr = _clr, \ + .bus_prot_sta_mask = (_sta_mask), \ + .bus_prot_sta = _sta, \ + .flags = _flags \ } -#define BUS_PROT_WR(_hwip, _mask, _set, _clr, _sta) \ - _BUS_PROT(_mask, _set, _clr, _mask, _sta, BUS_PROT_COMPONENT_##_hwip) +#define _BUS_PROT(_hwip, _set_clr_mask, _set, _clr, _sta_mask, \ + _sta, _flags) \ + _BUS_PROT_STA(_hwip, _hwip, _set_clr_mask, _set, _clr, \ + _sta_mask, _sta, _flags) -#define BUS_PROT_WR_IGN(_hwip, _mask, _set, _clr, _sta) \ - _BUS_PROT(_mask, _set, _clr, _mask, _sta, \ - BUS_PROT_COMPONENT_##_hwip | BUS_PROT_IGNORE_CLR_ACK) +#define BUS_PROT_WR(_hwip, _mask, _set, _clr, _sta) \ + _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, 0) -#define BUS_PROT_UPDATE(_hwip, _mask, _set, _clr, _sta) \ - _BUS_PROT(_mask, _set, _clr, _mask, _sta, \ - BUS_PROT_COMPONENT_##_hwip | BUS_PROT_REG_UPDATE) +#define BUS_PROT_WR_IGN(_hwip, _mask, _set, _clr, _sta) \ + _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, \ + BUS_PROT_IGNORE_CLR_ACK) + +#define BUS_PROT_UPDATE(_hwip, _mask, _set, _clr, _sta) \ + _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, \ + BUS_PROT_REG_UPDATE) #define BUS_PROT_INFRA_UPDATE_TOPAXI(_mask) \ BUS_PROT_UPDATE(INFRA, _mask, \ @@ -82,6 +98,8 @@ enum scpsys_bus_prot_flags { INFRA_TOPAXI_PROTECTSTA1) struct scpsys_bus_prot_data { + u8 bus_prot_block; + u8 bus_prot_sta_block; u32 bus_prot_set_clr_mask; u32 bus_prot_set; u32 bus_prot_clr; @@ -91,6 +109,22 @@ struct scpsys_bus_prot_data { }; /** + * enum scpsys_rtff_type - Type of RTFF Hardware for power domain + * @SCPSYS_RTFF_NONE: RTFF HW not present or domain not RTFF managed + * @SCPSYS_RTFF_TYPE_GENERIC: Non-CPU, peripheral-generic RTFF HW + * @SCPSYS_RTFF_TYPE_PCIE_PHY: PCI-Express PHY specific RTFF HW + * @SCPSYS_RTFF_TYPE_STOR_UFS: Storage (UFS) specific RTFF HW + * @SCPSYS_RTFF_TYPE_MAX: Number of supported RTFF HW Types + */ +enum scpsys_rtff_type { + SCPSYS_RTFF_NONE = 0, + SCPSYS_RTFF_TYPE_GENERIC, + SCPSYS_RTFF_TYPE_PCIE_PHY, + SCPSYS_RTFF_TYPE_STOR_UFS, + SCPSYS_RTFF_TYPE_MAX +}; + +/** * 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. @@ -100,6 +134,7 @@ struct scpsys_bus_prot_data { * @ext_buck_iso_offs: The offset for external buck isolation * @ext_buck_iso_mask: The mask for external buck isolation * @caps: The flag for active wake-up action. + * @rtff_type: The power domain RTFF HW type * @bp_cfg: bus protection configuration for any subsystem */ struct scpsys_domain_data { @@ -111,6 +146,7 @@ struct scpsys_domain_data { int ext_buck_iso_offs; u32 ext_buck_iso_mask; u16 caps; + enum scpsys_rtff_type rtff_type; const struct scpsys_bus_prot_data bp_cfg[SPM_MAX_BUS_PROT_DATA]; int pwr_sta_offs; int pwr_sta2nd_offs; @@ -119,6 +155,8 @@ struct scpsys_domain_data { struct scpsys_soc_data { const struct scpsys_domain_data *domains_data; int num_domains; + enum scpsys_bus_prot_block *bus_prot_blocks; + int num_bus_prot_blocks; }; #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */ diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c index 833c46944600..f8580ec0f737 100644 --- a/drivers/pmdomain/qcom/rpmpd.c +++ b/drivers/pmdomain/qcom/rpmpd.c @@ -631,12 +631,12 @@ static struct rpmpd ssc_mx_rwsm0_vfl = { }; static struct rpmpd *mdm9607_rpmpds[] = { - [MDM9607_VDDCX] = &cx_s3a_lvl, - [MDM9607_VDDCX_AO] = &cx_s3a_lvl_ao, - [MDM9607_VDDCX_VFL] = &cx_s3a_vfl, - [MDM9607_VDDMX] = &mx_l12a_lvl, - [MDM9607_VDDMX_AO] = &mx_l12a_lvl_ao, - [MDM9607_VDDMX_VFL] = &mx_l12a_vfl, + [RPMPD_VDDCX] = &cx_s3a_lvl, + [RPMPD_VDDCX_AO] = &cx_s3a_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_s3a_vfl, + [RPMPD_VDDMX] = &mx_l12a_lvl, + [RPMPD_VDDMX_AO] = &mx_l12a_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_l12a_vfl, }; static const struct rpmpd_desc mdm9607_desc = { @@ -646,9 +646,9 @@ static const struct rpmpd_desc mdm9607_desc = { }; static struct rpmpd *msm8226_rpmpds[] = { - [MSM8226_VDDCX] = &cx_s1a_corner, - [MSM8226_VDDCX_AO] = &cx_s1a_corner_ao, - [MSM8226_VDDCX_VFC] = &cx_s1a_vfc, + [RPMPD_VDDCX] = &cx_s1a_corner, + [RPMPD_VDDCX_AO] = &cx_s1a_corner_ao, + [RPMPD_VDDCX_VFC] = &cx_s1a_vfc, }; static const struct rpmpd_desc msm8226_desc = { @@ -675,11 +675,11 @@ static const struct rpmpd_desc msm8939_desc = { }; static struct rpmpd *msm8916_rpmpds[] = { - [MSM8916_VDDCX] = &cx_s1a_corner, - [MSM8916_VDDCX_AO] = &cx_s1a_corner_ao, - [MSM8916_VDDCX_VFC] = &cx_s1a_vfc, - [MSM8916_VDDMX] = &mx_l3a_corner, - [MSM8916_VDDMX_AO] = &mx_l3a_corner_ao, + [RPMPD_VDDCX] = &cx_s1a_corner, + [RPMPD_VDDCX_AO] = &cx_s1a_corner_ao, + [RPMPD_VDDCX_VFC] = &cx_s1a_vfc, + [RPMPD_VDDMX] = &mx_l3a_corner, + [RPMPD_VDDMX_AO] = &mx_l3a_corner_ao, }; static const struct rpmpd_desc msm8916_desc = { @@ -689,11 +689,11 @@ static const struct rpmpd_desc msm8916_desc = { }; static struct rpmpd *msm8917_rpmpds[] = { - [MSM8917_VDDCX] = &cx_s2a_lvl, - [MSM8917_VDDCX_AO] = &cx_s2a_lvl_ao, - [MSM8917_VDDCX_VFL] = &cx_s2a_vfl, - [MSM8917_VDDMX] = &mx_l3a_lvl, - [MSM8917_VDDMX_AO] = &mx_l3a_lvl_ao, + [RPMPD_VDDCX] = &cx_s2a_lvl, + [RPMPD_VDDCX_AO] = &cx_s2a_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_s2a_vfl, + [RPMPD_VDDMX] = &mx_l3a_lvl, + [RPMPD_VDDMX_AO] = &mx_l3a_lvl_ao, }; static const struct rpmpd_desc msm8917_desc = { @@ -747,12 +747,12 @@ static const struct rpmpd_desc msm8974pro_pma8084_desc = { }; static struct rpmpd *msm8976_rpmpds[] = { - [MSM8976_VDDCX] = &cx_s2a_lvl, - [MSM8976_VDDCX_AO] = &cx_s2a_lvl_ao, - [MSM8976_VDDCX_VFL] = &cx_rwsc2_vfl, - [MSM8976_VDDMX] = &mx_s6a_lvl, - [MSM8976_VDDMX_AO] = &mx_s6a_lvl_ao, - [MSM8976_VDDMX_VFL] = &mx_rwsm6_vfl, + [RPMPD_VDDCX] = &cx_s2a_lvl, + [RPMPD_VDDCX_AO] = &cx_s2a_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_rwsc2_vfl, + [RPMPD_VDDMX] = &mx_s6a_lvl, + [RPMPD_VDDMX_AO] = &mx_s6a_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_rwsm6_vfl, }; static const struct rpmpd_desc msm8976_desc = { @@ -796,16 +796,16 @@ static const struct rpmpd_desc msm8996_desc = { }; static struct rpmpd *msm8998_rpmpds[] = { - [MSM8998_VDDCX] = &cx_rwcx0_lvl, - [MSM8998_VDDCX_AO] = &cx_rwcx0_lvl_ao, - [MSM8998_VDDCX_VFL] = &cx_rwcx0_vfl, - [MSM8998_VDDMX] = &mx_rwmx0_lvl, - [MSM8998_VDDMX_AO] = &mx_rwmx0_lvl_ao, - [MSM8998_VDDMX_VFL] = &mx_rwmx0_vfl, - [MSM8998_SSCCX] = &ssc_cx_rwsc0_lvl, - [MSM8998_SSCCX_VFL] = &ssc_cx_rwsc0_vfl, - [MSM8998_SSCMX] = &ssc_mx_rwsm0_lvl, - [MSM8998_SSCMX_VFL] = &ssc_mx_rwsm0_vfl, + [RPMPD_VDDCX] = &cx_rwcx0_lvl, + [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl, + [RPMPD_VDDMX] = &mx_rwmx0_lvl, + [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl, + [RPMPD_SSCCX] = &ssc_cx_rwsc0_lvl, + [RPMPD_SSCCX_VFL] = &ssc_cx_rwsc0_vfl, + [RPMPD_SSCMX] = &ssc_mx_rwsm0_lvl, + [RPMPD_SSCMX_VFL] = &ssc_mx_rwsm0_vfl, }; static const struct rpmpd_desc msm8998_desc = { @@ -831,11 +831,11 @@ static const struct rpmpd_desc qcs404_desc = { }; static struct rpmpd *qm215_rpmpds[] = { - [QM215_VDDCX] = &cx_s1a_lvl, - [QM215_VDDCX_AO] = &cx_s1a_lvl_ao, - [QM215_VDDCX_VFL] = &cx_s1a_vfl, - [QM215_VDDMX] = &mx_l2a_lvl, - [QM215_VDDMX_AO] = &mx_l2a_lvl_ao, + [RPMPD_VDDCX] = &cx_s1a_lvl, + [RPMPD_VDDCX_AO] = &cx_s1a_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_s1a_vfl, + [RPMPD_VDDMX] = &mx_l2a_lvl, + [RPMPD_VDDMX_AO] = &mx_l2a_lvl_ao, }; static const struct rpmpd_desc qm215_desc = { @@ -845,16 +845,16 @@ static const struct rpmpd_desc qm215_desc = { }; static struct rpmpd *sdm660_rpmpds[] = { - [SDM660_VDDCX] = &cx_rwcx0_lvl, - [SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao, - [SDM660_VDDCX_VFL] = &cx_rwcx0_vfl, - [SDM660_VDDMX] = &mx_rwmx0_lvl, - [SDM660_VDDMX_AO] = &mx_rwmx0_lvl_ao, - [SDM660_VDDMX_VFL] = &mx_rwmx0_vfl, - [SDM660_SSCCX] = &ssc_cx_rwlc0_lvl, - [SDM660_SSCCX_VFL] = &ssc_cx_rwlc0_vfl, - [SDM660_SSCMX] = &ssc_mx_rwlm0_lvl, - [SDM660_SSCMX_VFL] = &ssc_mx_rwlm0_vfl, + [RPMPD_VDDCX] = &cx_rwcx0_lvl, + [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl, + [RPMPD_VDDMX] = &mx_rwmx0_lvl, + [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl, + [RPMPD_SSCCX] = &ssc_cx_rwlc0_lvl, + [RPMPD_SSCCX_VFL] = &ssc_cx_rwlc0_vfl, + [RPMPD_SSCMX] = &ssc_mx_rwlm0_lvl, + [RPMPD_SSCMX_VFL] = &ssc_mx_rwlm0_vfl, }; static const struct rpmpd_desc sdm660_desc = { @@ -881,12 +881,12 @@ static const struct rpmpd_desc sm6115_desc = { }; static struct rpmpd *sm6125_rpmpds[] = { - [SM6125_VDDCX] = &cx_rwcx0_lvl, - [SM6125_VDDCX_AO] = &cx_rwcx0_lvl_ao, - [SM6125_VDDCX_VFL] = &cx_rwcx0_vfl, - [SM6125_VDDMX] = &mx_rwmx0_lvl, - [SM6125_VDDMX_AO] = &mx_rwmx0_lvl_ao, - [SM6125_VDDMX_VFL] = &mx_rwmx0_vfl, + [RPMPD_VDDCX] = &cx_rwcx0_lvl, + [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao, + [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl, + [RPMPD_VDDMX] = &mx_rwmx0_lvl, + [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao, + [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl, }; static const struct rpmpd_desc sm6125_desc = { diff --git a/drivers/pmdomain/rockchip/Kconfig b/drivers/pmdomain/rockchip/Kconfig index 218d43186e5b..17f2e6fe86b6 100644 --- a/drivers/pmdomain/rockchip/Kconfig +++ b/drivers/pmdomain/rockchip/Kconfig @@ -3,6 +3,7 @@ if ARCH_ROCKCHIP || COMPILE_TEST config ROCKCHIP_PM_DOMAINS bool "Rockchip generic power domain" + default ARCH_ROCKCHIP depends on PM depends on HAVE_ARM_SMCCC_DISCOVERY depends on REGULATOR diff --git a/drivers/pmdomain/thead/th1520-pm-domains.c b/drivers/pmdomain/thead/th1520-pm-domains.c index 9040b698e7f7..5213994101a5 100644 --- a/drivers/pmdomain/thead/th1520-pm-domains.c +++ b/drivers/pmdomain/thead/th1520-pm-domains.c @@ -173,6 +173,16 @@ static int th1520_pd_pwrseq_gpu_init(struct device *dev) adev); } +static int th1520_pd_reboot_init(struct device *dev, + struct th1520_aon_chan *aon_chan) +{ + struct auxiliary_device *adev; + + adev = devm_auxiliary_device_create(dev, "reboot", aon_chan); + + return PTR_ERR_OR_ZERO(adev); +} + static int th1520_pd_probe(struct platform_device *pdev) { struct generic_pm_domain **domains; @@ -235,6 +245,10 @@ static int th1520_pd_probe(struct platform_device *pdev) if (ret) goto err_clean_provider; + ret = th1520_pd_reboot_init(dev, aon_chan); + if (ret) + goto err_clean_provider; + return 0; err_clean_provider: diff --git a/drivers/pmdomain/ti/ti_sci_pm_domains.c b/drivers/pmdomain/ti/ti_sci_pm_domains.c index 82df7e44250b..e5d1934f78d9 100644 --- a/drivers/pmdomain/ti/ti_sci_pm_domains.c +++ b/drivers/pmdomain/ti/ti_sci_pm_domains.c @@ -200,6 +200,23 @@ static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 return false; } +static bool ti_sci_pm_pd_is_on(struct ti_sci_genpd_provider *pd_provider, + int pd_idx) +{ + bool is_on; + int ret; + + if (!pd_provider->ti_sci->ops.dev_ops.is_on) + return false; + + ret = pd_provider->ti_sci->ops.dev_ops.is_on(pd_provider->ti_sci, + pd_idx, NULL, &is_on); + if (ret) + return false; + + return is_on; +} + static int ti_sci_pm_domain_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -231,6 +248,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) index, &args)) { if (args.args_count >= 1 && args.np == dev->of_node) { + bool is_on; + of_node_put(args.np); if (args.args[0] > max_id) { max_id = args.args[0]; @@ -264,7 +283,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) pd_provider->ti_sci->ops.pm_ops.set_latency_constraint) pd->pd.domain.ops.suspend = ti_sci_pd_suspend; - pm_genpd_init(&pd->pd, NULL, true); + is_on = ti_sci_pm_pd_is_on(pd_provider, + pd->idx); + + pm_genpd_init(&pd->pd, NULL, !is_on); list_add(&pd->node, &pd_provider->pd_list); } else { diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 77ea3129c708..8248895ca903 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -225,6 +225,13 @@ config POWER_RESET_ST help Reset support for STMicroelectronics boards. +config POWER_RESET_TH1520_AON + tristate "T-Head TH1520 AON firmware poweroff and reset driver" + depends on TH1520_PM_DOMAINS + help + This driver supports power-off and reset operations for T-Head + TH1520 SoCs running the AON firmware. + config POWER_RESET_TORADEX_EC tristate "Toradex Embedded Controller power-off and reset driver" depends on ARCH_MXC || COMPILE_TEST diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index b7c2b5940be9..51da87e05ce7 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o +obj-$(CONFIG_POWER_RESET_TH1520_AON) += th1520-aon-reboot.o obj-$(CONFIG_POWER_RESET_TORADEX_EC) += tdx-ec-poweroff.o obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o diff --git a/drivers/power/reset/th1520-aon-reboot.c b/drivers/power/reset/th1520-aon-reboot.c new file mode 100644 index 000000000000..ec249667a0ff --- /dev/null +++ b/drivers/power/reset/th1520-aon-reboot.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * T-HEAD TH1520 AON Firmware Reboot Driver + * + * Copyright (c) 2025 Icenowy Zheng <uwu@icenowy.me> + */ + +#include <linux/auxiliary_bus.h> +#include <linux/firmware/thead/thead,th1520-aon.h> +#include <linux/module.h> +#include <linux/notifier.h> +#include <linux/of.h> +#include <linux/reboot.h> +#include <linux/slab.h> + +#define TH1520_AON_REBOOT_PRIORITY 200 + +struct th1520_aon_msg_empty_body { + struct th1520_aon_rpc_msg_hdr hdr; + u16 reserved[12]; +} __packed __aligned(1); + +static int th1520_aon_pwroff_handler(struct sys_off_data *data) +{ + struct th1520_aon_chan *aon_chan = data->cb_data; + struct th1520_aon_msg_empty_body msg = {}; + + msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; + msg.hdr.func = TH1520_AON_WDG_FUNC_POWER_OFF; + msg.hdr.size = TH1520_AON_RPC_MSG_NUM; + + th1520_aon_call_rpc(aon_chan, &msg); + + return NOTIFY_DONE; +} + +static int th1520_aon_restart_handler(struct sys_off_data *data) +{ + struct th1520_aon_chan *aon_chan = data->cb_data; + struct th1520_aon_msg_empty_body msg = {}; + + msg.hdr.svc = TH1520_AON_RPC_SVC_WDG; + msg.hdr.func = TH1520_AON_WDG_FUNC_RESTART; + msg.hdr.size = TH1520_AON_RPC_MSG_NUM; + + th1520_aon_call_rpc(aon_chan, &msg); + + return NOTIFY_DONE; +} + +static int th1520_aon_reboot_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct device *dev = &adev->dev; + int ret; + + /* Expect struct th1520_aon_chan to be passed via platform_data */ + ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF, + TH1520_AON_REBOOT_PRIORITY, + th1520_aon_pwroff_handler, + adev->dev.platform_data); + + if (ret) { + dev_err(dev, "Failed to register power off handler\n"); + return ret; + } + + ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, + TH1520_AON_REBOOT_PRIORITY, + th1520_aon_restart_handler, + adev->dev.platform_data); + + if (ret) { + dev_err(dev, "Failed to register restart handler\n"); + return ret; + } + + return 0; +} + +static const struct auxiliary_device_id th1520_aon_reboot_id_table[] = { + { .name = "th1520_pm_domains.reboot" }, + {}, +}; +MODULE_DEVICE_TABLE(auxiliary, th1520_aon_reboot_id_table); + +static struct auxiliary_driver th1520_aon_reboot_driver = { + .driver = { + .name = "th1520-aon-reboot", + }, + .probe = th1520_aon_reboot_probe, + .id_table = th1520_aon_reboot_id_table, +}; +module_auxiliary_driver(th1520_aon_reboot_driver); + +MODULE_AUTHOR("Icenowy Zheng <uwu@icenowy.me>"); +MODULE_DESCRIPTION("T-HEAD TH1520 AON-firmware-based reboot driver"); +MODULE_LICENSE("GPL"); diff --git a/include/dt-bindings/power/amlogic,s6-pwrc.h b/include/dt-bindings/power/amlogic,s6-pwrc.h new file mode 100644 index 000000000000..2c005864ae73 --- /dev/null +++ b/include/dt-bindings/power/amlogic,s6-pwrc.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2025 Amlogic, Inc. All rights reserved + */ +#ifndef _DT_BINDINGS_AMLOGIC_S6_POWER_H +#define _DT_BINDINGS_AMLOGIC_S6_POWER_H + +#define PWRC_S6_DSPA_ID 0 +#define PWRC_S6_DOS_HEVC_ID 1 +#define PWRC_S6_DOS_VDEC_ID 2 +#define PWRC_S6_VPU_HDMI_ID 3 +#define PWRC_S6_U2DRD_ID 4 +#define PWRC_S6_U3DRD_ID 5 +#define PWRC_S6_SD_EMMC_C_ID 6 +#define PWRC_S6_GE2D_ID 7 +#define PWRC_S6_AMFC_ID 8 +#define PWRC_S6_VC9000E_ID 9 +#define PWRC_S6_DEWARP_ID 10 +#define PWRC_S6_VICP_ID 11 +#define PWRC_S6_SD_EMMC_A_ID 12 +#define PWRC_S6_SD_EMMC_B_ID 13 +#define PWRC_S6_ETH_ID 14 +#define PWRC_S6_PCIE_ID 15 +#define PWRC_S6_NNA_4T_ID 16 +#define PWRC_S6_AUDIO_ID 17 +#define PWRC_S6_AUCPU_ID 18 +#define PWRC_S6_ADAPT_ID 19 + +#endif diff --git a/include/dt-bindings/power/amlogic,s7-pwrc.h b/include/dt-bindings/power/amlogic,s7-pwrc.h new file mode 100644 index 000000000000..3f21d095f784 --- /dev/null +++ b/include/dt-bindings/power/amlogic,s7-pwrc.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2025 Amlogic, Inc. All rights reserved + */ +#ifndef _DT_BINDINGS_AMLOGIC_S7_POWER_H +#define _DT_BINDINGS_AMLOGIC_S7_POWER_H + +#define PWRC_S7_DOS_HEVC_ID 0 +#define PWRC_S7_DOS_VDEC_ID 1 +#define PWRC_S7_VPU_HDMI_ID 2 +#define PWRC_S7_USB_COMB_ID 3 +#define PWRC_S7_SD_EMMC_C_ID 4 +#define PWRC_S7_GE2D_ID 5 +#define PWRC_S7_SD_EMMC_A_ID 6 +#define PWRC_S7_SD_EMMC_B_ID 7 +#define PWRC_S7_ETH_ID 8 +#define PWRC_S7_AUCPU_ID 9 +#define PWRC_S7_AUDIO_ID 10 + +#endif diff --git a/include/dt-bindings/power/amlogic,s7d-pwrc.h b/include/dt-bindings/power/amlogic,s7d-pwrc.h new file mode 100644 index 000000000000..c6998553670a --- /dev/null +++ b/include/dt-bindings/power/amlogic,s7d-pwrc.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2025 Amlogic, Inc. All rights reserved + */ +#ifndef _DT_BINDINGS_AMLOGIC_S7D_POWER_H +#define _DT_BINDINGS_AMLOGIC_S7D_POWER_H + +#define PWRC_S7D_DOS_HCODEC_ID 0 +#define PWRC_S7D_DOS_HEVC_ID 1 +#define PWRC_S7D_DOS_VDEC_ID 2 +#define PWRC_S7D_VPU_HDMI_ID 3 +#define PWRC_S7D_USB_U2DRD_ID 4 +#define PWRC_S7D_USB_U2H_ID 5 +#define PWRC_S7D_SSD_EMMC_C_ID 6 +#define PWRC_S7D_GE2D_ID 7 +#define PWRC_S7D_AMFC_ID 8 +#define PWRC_S7D_EMMC_A_ID 9 +#define PWRC_S7D_EMMC_B_ID 10 +#define PWRC_S7D_ETH_ID 11 +#define PWRC_S7D_AUCPU_ID 12 +#define PWRC_S7D_AUDIO_ID 13 +#define PWRC_S7D_SRAMA_ID 14 +#define PWRC_S7D_DMC0_ID 15 +#define PWRC_S7D_DMC1_ID 16 +#define PWRC_S7D_DDR_ID 17 + +#endif diff --git a/include/dt-bindings/power/marvell,pxa1908-power.h b/include/dt-bindings/power/marvell,pxa1908-power.h new file mode 100644 index 000000000000..19b088351af1 --- /dev/null +++ b/include/dt-bindings/power/marvell,pxa1908-power.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Marvell PXA1908 power domains + * + * Copyright 2025, Duje Mihanović <duje@dujemihanovic.xyz> + */ + +#ifndef __DTS_MARVELL_PXA1908_POWER_H +#define __DTS_MARVELL_PXA1908_POWER_H + +#define PXA1908_POWER_DOMAIN_VPU 0 +#define PXA1908_POWER_DOMAIN_GPU 1 +#define PXA1908_POWER_DOMAIN_GPU2D 2 +#define PXA1908_POWER_DOMAIN_DSI 3 +#define PXA1908_POWER_DOMAIN_ISP 4 + +#endif diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h index e54ffa361451..73cceb88953f 100644 --- a/include/dt-bindings/power/qcom,rpmhpd.h +++ b/include/dt-bindings/power/qcom,rpmhpd.h @@ -29,4 +29,237 @@ #define RPMHPD_NSP2 19 #define RPMHPD_GMXC 20 +/* RPMh Power Domain performance levels */ +#define RPMH_REGULATOR_LEVEL_RETENTION 16 +#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 +#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 +#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96 +#define RPMH_REGULATOR_LEVEL_SVS 128 +#define RPMH_REGULATOR_LEVEL_SVS_L0 144 +#define RPMH_REGULATOR_LEVEL_SVS_L1 192 +#define RPMH_REGULATOR_LEVEL_SVS_L2 224 +#define RPMH_REGULATOR_LEVEL_NOM 256 +#define RPMH_REGULATOR_LEVEL_NOM_L0 288 +#define RPMH_REGULATOR_LEVEL_NOM_L1 320 +#define RPMH_REGULATOR_LEVEL_NOM_L2 336 +#define RPMH_REGULATOR_LEVEL_TURBO 384 +#define RPMH_REGULATOR_LEVEL_TURBO_L0 400 +#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 +#define RPMH_REGULATOR_LEVEL_TURBO_L2 432 +#define RPMH_REGULATOR_LEVEL_TURBO_L3 448 +#define RPMH_REGULATOR_LEVEL_TURBO_L4 452 +#define RPMH_REGULATOR_LEVEL_TURBO_L5 456 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 +#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 + +/* + * Platform-specific power domain bindings. Don't add new entries here, use + * RPMHPD_* above. + */ + +/* SA8775P Power Domain Indexes */ +#define SA8775P_CX 0 +#define SA8775P_CX_AO 1 +#define SA8775P_DDR 2 +#define SA8775P_EBI 3 +#define SA8775P_GFX 4 +#define SA8775P_LCX 5 +#define SA8775P_LMX 6 +#define SA8775P_MMCX 7 +#define SA8775P_MMCX_AO 8 +#define SA8775P_MSS 9 +#define SA8775P_MX 10 +#define SA8775P_MX_AO 11 +#define SA8775P_MXC 12 +#define SA8775P_MXC_AO 13 +#define SA8775P_NSP0 14 +#define SA8775P_NSP1 15 +#define SA8775P_XO 16 + +/* SDM670 Power Domain Indexes */ +#define SDM670_MX 0 +#define SDM670_MX_AO 1 +#define SDM670_CX 2 +#define SDM670_CX_AO 3 +#define SDM670_LMX 4 +#define SDM670_LCX 5 +#define SDM670_GFX 6 +#define SDM670_MSS 7 + +/* SDM845 Power Domain Indexes */ +#define SDM845_EBI 0 +#define SDM845_MX 1 +#define SDM845_MX_AO 2 +#define SDM845_CX 3 +#define SDM845_CX_AO 4 +#define SDM845_LMX 5 +#define SDM845_LCX 6 +#define SDM845_GFX 7 +#define SDM845_MSS 8 + +/* SDX55 Power Domain Indexes */ +#define SDX55_MSS 0 +#define SDX55_MX 1 +#define SDX55_CX 2 + +/* SDX65 Power Domain Indexes */ +#define SDX65_MSS 0 +#define SDX65_MX 1 +#define SDX65_MX_AO 2 +#define SDX65_CX 3 +#define SDX65_CX_AO 4 +#define SDX65_MXC 5 + +/* SM6350 Power Domain Indexes */ +#define SM6350_CX 0 +#define SM6350_GFX 1 +#define SM6350_LCX 2 +#define SM6350_LMX 3 +#define SM6350_MSS 4 +#define SM6350_MX 5 + +/* SM8150 Power Domain Indexes */ +#define SM8150_MSS 0 +#define SM8150_EBI 1 +#define SM8150_LMX 2 +#define SM8150_LCX 3 +#define SM8150_GFX 4 +#define SM8150_MX 5 +#define SM8150_MX_AO 6 +#define SM8150_CX 7 +#define SM8150_CX_AO 8 +#define SM8150_MMCX 9 +#define SM8150_MMCX_AO 10 + +/* SA8155P is a special case, kept for backwards compatibility */ +#define SA8155P_CX SM8150_CX +#define SA8155P_CX_AO SM8150_CX_AO +#define SA8155P_EBI SM8150_EBI +#define SA8155P_GFX SM8150_GFX +#define SA8155P_MSS SM8150_MSS +#define SA8155P_MX SM8150_MX +#define SA8155P_MX_AO SM8150_MX_AO + +/* SM8250 Power Domain Indexes */ +#define SM8250_CX 0 +#define SM8250_CX_AO 1 +#define SM8250_EBI 2 +#define SM8250_GFX 3 +#define SM8250_LCX 4 +#define SM8250_LMX 5 +#define SM8250_MMCX 6 +#define SM8250_MMCX_AO 7 +#define SM8250_MX 8 +#define SM8250_MX_AO 9 + +/* SM8350 Power Domain Indexes */ +#define SM8350_CX 0 +#define SM8350_CX_AO 1 +#define SM8350_EBI 2 +#define SM8350_GFX 3 +#define SM8350_LCX 4 +#define SM8350_LMX 5 +#define SM8350_MMCX 6 +#define SM8350_MMCX_AO 7 +#define SM8350_MX 8 +#define SM8350_MX_AO 9 +#define SM8350_MXC 10 +#define SM8350_MXC_AO 11 +#define SM8350_MSS 12 + +/* SM8450 Power Domain Indexes */ +#define SM8450_CX 0 +#define SM8450_CX_AO 1 +#define SM8450_EBI 2 +#define SM8450_GFX 3 +#define SM8450_LCX 4 +#define SM8450_LMX 5 +#define SM8450_MMCX 6 +#define SM8450_MMCX_AO 7 +#define SM8450_MX 8 +#define SM8450_MX_AO 9 +#define SM8450_MXC 10 +#define SM8450_MXC_AO 11 +#define SM8450_MSS 12 + +/* SM8550 Power Domain Indexes */ +#define SM8550_CX 0 +#define SM8550_CX_AO 1 +#define SM8550_EBI 2 +#define SM8550_GFX 3 +#define SM8550_LCX 4 +#define SM8550_LMX 5 +#define SM8550_MMCX 6 +#define SM8550_MMCX_AO 7 +#define SM8550_MX 8 +#define SM8550_MX_AO 9 +#define SM8550_MXC 10 +#define SM8550_MXC_AO 11 +#define SM8550_MSS 12 +#define SM8550_NSP 13 + +/* QDU1000/QRU1000 Power Domain Indexes */ +#define QDU1000_EBI 0 +#define QDU1000_MSS 1 +#define QDU1000_CX 2 +#define QDU1000_MX 3 + +/* SC7180 Power Domain Indexes */ +#define SC7180_CX 0 +#define SC7180_CX_AO 1 +#define SC7180_GFX 2 +#define SC7180_MX 3 +#define SC7180_MX_AO 4 +#define SC7180_LMX 5 +#define SC7180_LCX 6 +#define SC7180_MSS 7 + +/* SC7280 Power Domain Indexes */ +#define SC7280_CX 0 +#define SC7280_CX_AO 1 +#define SC7280_EBI 2 +#define SC7280_GFX 3 +#define SC7280_MX 4 +#define SC7280_MX_AO 5 +#define SC7280_LMX 6 +#define SC7280_LCX 7 +#define SC7280_MSS 8 + +/* SC8180X Power Domain Indexes */ +#define SC8180X_CX 0 +#define SC8180X_CX_AO 1 +#define SC8180X_EBI 2 +#define SC8180X_GFX 3 +#define SC8180X_LCX 4 +#define SC8180X_LMX 5 +#define SC8180X_MMCX 6 +#define SC8180X_MMCX_AO 7 +#define SC8180X_MSS 8 +#define SC8180X_MX 9 +#define SC8180X_MX_AO 10 + +/* SC8280XP Power Domain Indexes */ +#define SC8280XP_CX 0 +#define SC8280XP_CX_AO 1 +#define SC8280XP_DDR 2 +#define SC8280XP_EBI 3 +#define SC8280XP_GFX 4 +#define SC8280XP_LCX 5 +#define SC8280XP_LMX 6 +#define SC8280XP_MMCX 7 +#define SC8280XP_MMCX_AO 8 +#define SC8280XP_MSS 9 +#define SC8280XP_MX 10 +#define SC8280XP_MXC 12 +#define SC8280XP_MX_AO 11 +#define SC8280XP_NSP 13 +#define SC8280XP_QPHY 14 +#define SC8280XP_XO 15 + #endif diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h index f15bcee7c928..4371ac941f29 100644 --- a/include/dt-bindings/power/qcom-rpmpd.h +++ b/include/dt-bindings/power/qcom-rpmpd.h @@ -4,258 +4,39 @@ #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H #define _DT_BINDINGS_POWER_QCOM_RPMPD_H -/* SA8775P Power Domain Indexes */ -#define SA8775P_CX 0 -#define SA8775P_CX_AO 1 -#define SA8775P_DDR 2 -#define SA8775P_EBI 3 -#define SA8775P_GFX 4 -#define SA8775P_LCX 5 -#define SA8775P_LMX 6 -#define SA8775P_MMCX 7 -#define SA8775P_MMCX_AO 8 -#define SA8775P_MSS 9 -#define SA8775P_MX 10 -#define SA8775P_MX_AO 11 -#define SA8775P_MXC 12 -#define SA8775P_MXC_AO 13 -#define SA8775P_NSP0 14 -#define SA8775P_NSP1 15 -#define SA8775P_XO 16 - -/* SDM670 Power Domain Indexes */ -#define SDM670_MX 0 -#define SDM670_MX_AO 1 -#define SDM670_CX 2 -#define SDM670_CX_AO 3 -#define SDM670_LMX 4 -#define SDM670_LCX 5 -#define SDM670_GFX 6 -#define SDM670_MSS 7 - -/* SDM845 Power Domain Indexes */ -#define SDM845_EBI 0 -#define SDM845_MX 1 -#define SDM845_MX_AO 2 -#define SDM845_CX 3 -#define SDM845_CX_AO 4 -#define SDM845_LMX 5 -#define SDM845_LCX 6 -#define SDM845_GFX 7 -#define SDM845_MSS 8 - -/* SDX55 Power Domain Indexes */ -#define SDX55_MSS 0 -#define SDX55_MX 1 -#define SDX55_CX 2 - -/* SDX65 Power Domain Indexes */ -#define SDX65_MSS 0 -#define SDX65_MX 1 -#define SDX65_MX_AO 2 -#define SDX65_CX 3 -#define SDX65_CX_AO 4 -#define SDX65_MXC 5 - -/* SM6350 Power Domain Indexes */ -#define SM6350_CX 0 -#define SM6350_GFX 1 -#define SM6350_LCX 2 -#define SM6350_LMX 3 -#define SM6350_MSS 4 -#define SM6350_MX 5 - -/* SM6375 Power Domain Indexes */ -#define SM6375_VDDCX 0 -#define SM6375_VDDCX_AO 1 -#define SM6375_VDDCX_VFL 2 -#define SM6375_VDDMX 3 -#define SM6375_VDDMX_AO 4 -#define SM6375_VDDMX_VFL 5 -#define SM6375_VDDGX 6 -#define SM6375_VDDGX_AO 7 -#define SM6375_VDD_LPI_CX 8 -#define SM6375_VDD_LPI_MX 9 - -/* SM8150 Power Domain Indexes */ -#define SM8150_MSS 0 -#define SM8150_EBI 1 -#define SM8150_LMX 2 -#define SM8150_LCX 3 -#define SM8150_GFX 4 -#define SM8150_MX 5 -#define SM8150_MX_AO 6 -#define SM8150_CX 7 -#define SM8150_CX_AO 8 -#define SM8150_MMCX 9 -#define SM8150_MMCX_AO 10 - -/* SA8155P is a special case, kept for backwards compatibility */ -#define SA8155P_CX SM8150_CX -#define SA8155P_CX_AO SM8150_CX_AO -#define SA8155P_EBI SM8150_EBI -#define SA8155P_GFX SM8150_GFX -#define SA8155P_MSS SM8150_MSS -#define SA8155P_MX SM8150_MX -#define SA8155P_MX_AO SM8150_MX_AO - -/* SM8250 Power Domain Indexes */ -#define SM8250_CX 0 -#define SM8250_CX_AO 1 -#define SM8250_EBI 2 -#define SM8250_GFX 3 -#define SM8250_LCX 4 -#define SM8250_LMX 5 -#define SM8250_MMCX 6 -#define SM8250_MMCX_AO 7 -#define SM8250_MX 8 -#define SM8250_MX_AO 9 - -/* SM8350 Power Domain Indexes */ -#define SM8350_CX 0 -#define SM8350_CX_AO 1 -#define SM8350_EBI 2 -#define SM8350_GFX 3 -#define SM8350_LCX 4 -#define SM8350_LMX 5 -#define SM8350_MMCX 6 -#define SM8350_MMCX_AO 7 -#define SM8350_MX 8 -#define SM8350_MX_AO 9 -#define SM8350_MXC 10 -#define SM8350_MXC_AO 11 -#define SM8350_MSS 12 - -/* SM8450 Power Domain Indexes */ -#define SM8450_CX 0 -#define SM8450_CX_AO 1 -#define SM8450_EBI 2 -#define SM8450_GFX 3 -#define SM8450_LCX 4 -#define SM8450_LMX 5 -#define SM8450_MMCX 6 -#define SM8450_MMCX_AO 7 -#define SM8450_MX 8 -#define SM8450_MX_AO 9 -#define SM8450_MXC 10 -#define SM8450_MXC_AO 11 -#define SM8450_MSS 12 - -/* SM8550 Power Domain Indexes */ -#define SM8550_CX 0 -#define SM8550_CX_AO 1 -#define SM8550_EBI 2 -#define SM8550_GFX 3 -#define SM8550_LCX 4 -#define SM8550_LMX 5 -#define SM8550_MMCX 6 -#define SM8550_MMCX_AO 7 -#define SM8550_MX 8 -#define SM8550_MX_AO 9 -#define SM8550_MXC 10 -#define SM8550_MXC_AO 11 -#define SM8550_MSS 12 -#define SM8550_NSP 13 - -/* QDU1000/QRU1000 Power Domain Indexes */ -#define QDU1000_EBI 0 -#define QDU1000_MSS 1 -#define QDU1000_CX 2 -#define QDU1000_MX 3 - -/* SC7180 Power Domain Indexes */ -#define SC7180_CX 0 -#define SC7180_CX_AO 1 -#define SC7180_GFX 2 -#define SC7180_MX 3 -#define SC7180_MX_AO 4 -#define SC7180_LMX 5 -#define SC7180_LCX 6 -#define SC7180_MSS 7 - -/* SC7280 Power Domain Indexes */ -#define SC7280_CX 0 -#define SC7280_CX_AO 1 -#define SC7280_EBI 2 -#define SC7280_GFX 3 -#define SC7280_MX 4 -#define SC7280_MX_AO 5 -#define SC7280_LMX 6 -#define SC7280_LCX 7 -#define SC7280_MSS 8 - -/* SC8180X Power Domain Indexes */ -#define SC8180X_CX 0 -#define SC8180X_CX_AO 1 -#define SC8180X_EBI 2 -#define SC8180X_GFX 3 -#define SC8180X_LCX 4 -#define SC8180X_LMX 5 -#define SC8180X_MMCX 6 -#define SC8180X_MMCX_AO 7 -#define SC8180X_MSS 8 -#define SC8180X_MX 9 -#define SC8180X_MX_AO 10 - -/* SC8280XP Power Domain Indexes */ -#define SC8280XP_CX 0 -#define SC8280XP_CX_AO 1 -#define SC8280XP_DDR 2 -#define SC8280XP_EBI 3 -#define SC8280XP_GFX 4 -#define SC8280XP_LCX 5 -#define SC8280XP_LMX 6 -#define SC8280XP_MMCX 7 -#define SC8280XP_MMCX_AO 8 -#define SC8280XP_MSS 9 -#define SC8280XP_MX 10 -#define SC8280XP_MXC 12 -#define SC8280XP_MX_AO 11 -#define SC8280XP_NSP 13 -#define SC8280XP_QPHY 14 -#define SC8280XP_XO 15 - -/* SDM845 Power Domain performance levels */ -#define RPMH_REGULATOR_LEVEL_RETENTION 16 -#define RPMH_REGULATOR_LEVEL_MIN_SVS 48 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60 -#define RPMH_REGULATOR_LEVEL_LOW_SVS 64 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80 -#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96 -#define RPMH_REGULATOR_LEVEL_SVS 128 -#define RPMH_REGULATOR_LEVEL_SVS_L0 144 -#define RPMH_REGULATOR_LEVEL_SVS_L1 192 -#define RPMH_REGULATOR_LEVEL_SVS_L2 224 -#define RPMH_REGULATOR_LEVEL_NOM 256 -#define RPMH_REGULATOR_LEVEL_NOM_L0 288 -#define RPMH_REGULATOR_LEVEL_NOM_L1 320 -#define RPMH_REGULATOR_LEVEL_NOM_L2 336 -#define RPMH_REGULATOR_LEVEL_TURBO 384 -#define RPMH_REGULATOR_LEVEL_TURBO_L0 400 -#define RPMH_REGULATOR_LEVEL_TURBO_L1 416 -#define RPMH_REGULATOR_LEVEL_TURBO_L2 432 -#define RPMH_REGULATOR_LEVEL_TURBO_L3 448 -#define RPMH_REGULATOR_LEVEL_TURBO_L4 452 -#define RPMH_REGULATOR_LEVEL_TURBO_L5 456 -#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464 -#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480 +#include <dt-bindings/power/qcom,rpmhpd.h> + +/* Generic RPM Power Domain Indexes */ +#define RPMPD_VDDCX 0 +#define RPMPD_VDDCX_AO 1 +/* VFC and VFL are mutually exclusive and can not be present on the same platform */ +#define RPMPD_VDDCX_VFC 2 +#define RPMPD_VDDCX_VFL 2 +#define RPMPD_VDDMX 3 +#define RPMPD_VDDMX_AO 4 +#define RPMPD_VDDMX_VFL 5 +#define RPMPD_SSCCX 6 +#define RPMPD_SSCCX_VFL 7 +#define RPMPD_SSCMX 8 +#define RPMPD_SSCMX_VFL 9 + +/* + * Platform-specific power domain bindings. Don't add new entries here, use + * RPMPD_* above. + */ /* MDM9607 Power Domains */ -#define MDM9607_VDDCX 0 -#define MDM9607_VDDCX_AO 1 -#define MDM9607_VDDCX_VFL 2 -#define MDM9607_VDDMX 3 -#define MDM9607_VDDMX_AO 4 -#define MDM9607_VDDMX_VFL 5 +#define MDM9607_VDDCX RPMPD_VDDCX +#define MDM9607_VDDCX_AO RPMPD_VDDCX_AO +#define MDM9607_VDDCX_VFL RPMPD_VDDCX_VFL +#define MDM9607_VDDMX RPMPD_VDDMX +#define MDM9607_VDDMX_AO RPMPD_VDDMX_AO +#define MDM9607_VDDMX_VFL RPMPD_VDDMX_VFL /* MSM8226 Power Domain Indexes */ -#define MSM8226_VDDCX 0 -#define MSM8226_VDDCX_AO 1 -#define MSM8226_VDDCX_VFC 2 +#define MSM8226_VDDCX RPMPD_VDDCX +#define MSM8226_VDDCX_AO RPMPD_VDDCX_AO +#define MSM8226_VDDCX_VFC RPMPD_VDDCX_VFC /* MSM8939 Power Domains */ #define MSM8939_VDDMDCX 0 @@ -268,11 +49,11 @@ #define MSM8939_VDDMX_AO 7 /* MSM8916 Power Domain Indexes */ -#define MSM8916_VDDCX 0 -#define MSM8916_VDDCX_AO 1 -#define MSM8916_VDDCX_VFC 2 -#define MSM8916_VDDMX 3 -#define MSM8916_VDDMX_AO 4 +#define MSM8916_VDDCX RPMPD_VDDCX +#define MSM8916_VDDCX_AO RPMPD_VDDCX_AO +#define MSM8916_VDDCX_VFC RPMPD_VDDCX_VFC +#define MSM8916_VDDMX RPMPD_VDDMX +#define MSM8916_VDDMX_AO RPMPD_VDDMX_AO /* MSM8909 Power Domain Indexes */ #define MSM8909_VDDCX MSM8916_VDDCX @@ -282,11 +63,11 @@ #define MSM8909_VDDMX_AO MSM8916_VDDMX_AO /* MSM8917 Power Domain Indexes */ -#define MSM8917_VDDCX 0 -#define MSM8917_VDDCX_AO 1 -#define MSM8917_VDDCX_VFL 2 -#define MSM8917_VDDMX 3 -#define MSM8917_VDDMX_AO 4 +#define MSM8917_VDDCX RPMPD_VDDCX +#define MSM8917_VDDCX_AO RPMPD_VDDCX_AO +#define MSM8917_VDDCX_VFL RPMPD_VDDCX_VFL +#define MSM8917_VDDMX RPMPD_VDDMX +#define MSM8917_VDDMX_AO RPMPD_VDDMX_AO /* MSM8937 Power Domain Indexes */ #define MSM8937_VDDCX MSM8917_VDDCX @@ -319,12 +100,12 @@ #define MSM8974_VDDGFX_VFC 4 /* MSM8976 Power Domain Indexes */ -#define MSM8976_VDDCX 0 -#define MSM8976_VDDCX_AO 1 -#define MSM8976_VDDCX_VFL 2 -#define MSM8976_VDDMX 3 -#define MSM8976_VDDMX_AO 4 -#define MSM8976_VDDMX_VFL 5 +#define MSM8976_VDDCX RPMPD_VDDCX +#define MSM8976_VDDCX_AO RPMPD_VDDCX_AO +#define MSM8976_VDDCX_VFL RPMPD_VDDCX_VFL +#define MSM8976_VDDMX RPMPD_VDDMX +#define MSM8976_VDDMX_AO RPMPD_VDDMX_AO +#define MSM8976_VDDMX_VFL RPMPD_VDDMX_VFL /* MSM8994 Power Domain Indexes */ #define MSM8994_VDDCX 0 @@ -345,16 +126,26 @@ #define MSM8996_VDDSSCX_VFC 6 /* MSM8998 Power Domain Indexes */ -#define MSM8998_VDDCX 0 -#define MSM8998_VDDCX_AO 1 -#define MSM8998_VDDCX_VFL 2 -#define MSM8998_VDDMX 3 -#define MSM8998_VDDMX_AO 4 -#define MSM8998_VDDMX_VFL 5 -#define MSM8998_SSCCX 6 -#define MSM8998_SSCCX_VFL 7 -#define MSM8998_SSCMX 8 -#define MSM8998_SSCMX_VFL 9 +#define MSM8998_VDDCX RPMPD_VDDCX +#define MSM8998_VDDCX_AO RPMPD_VDDCX_AO +#define MSM8998_VDDCX_VFL RPMPD_VDDCX_VFL +#define MSM8998_VDDMX RPMPD_VDDMX +#define MSM8998_VDDMX_AO RPMPD_VDDMX_AO +#define MSM8998_VDDMX_VFL RPMPD_VDDMX_VFL +#define MSM8998_SSCCX RPMPD_SSCCX +#define MSM8998_SSCCX_VFL RPMPD_SSCCX_VFL +#define MSM8998_SSCMX RPMPD_SSCMX +#define MSM8998_SSCMX_VFL RPMPD_SSCMX_VFL + +/* QCM2290 Power Domains */ +#define QCM2290_VDDCX 0 +#define QCM2290_VDDCX_AO 1 +#define QCM2290_VDDCX_VFL 2 +#define QCM2290_VDDMX 3 +#define QCM2290_VDDMX_AO 4 +#define QCM2290_VDDMX_VFL 5 +#define QCM2290_VDD_LPI_CX 6 +#define QCM2290_VDD_LPI_MX 7 /* QCS404 Power Domains */ #define QCS404_VDDMX 0 @@ -366,16 +157,16 @@ #define QCS404_LPIMX_VFL 6 /* SDM660 Power Domains */ -#define SDM660_VDDCX 0 -#define SDM660_VDDCX_AO 1 -#define SDM660_VDDCX_VFL 2 -#define SDM660_VDDMX 3 -#define SDM660_VDDMX_AO 4 -#define SDM660_VDDMX_VFL 5 -#define SDM660_SSCCX 6 -#define SDM660_SSCCX_VFL 7 -#define SDM660_SSCMX 8 -#define SDM660_SSCMX_VFL 9 +#define SDM660_VDDCX RPMPD_VDDCX +#define SDM660_VDDCX_AO RPMPD_VDDCX_AO +#define SDM660_VDDCX_VFL RPMPD_VDDCX_VFL +#define SDM660_VDDMX RPMPD_VDDMX +#define SDM660_VDDMX_AO RPMPD_VDDMX_AO +#define SDM660_VDDMX_VFL RPMPD_VDDMX_VFL +#define SDM660_SSCCX RPMPD_SSCCX +#define SDM660_SSCCX_VFL RPMPD_SSCCX_VFL +#define SDM660_SSCMX RPMPD_SSCMX +#define SDM660_SSCMX_VFL RPMPD_SSCMX_VFL /* SM6115 Power Domains */ #define SM6115_VDDCX 0 @@ -388,22 +179,24 @@ #define SM6115_VDD_LPI_MX 7 /* SM6125 Power Domains */ -#define SM6125_VDDCX 0 -#define SM6125_VDDCX_AO 1 -#define SM6125_VDDCX_VFL 2 -#define SM6125_VDDMX 3 -#define SM6125_VDDMX_AO 4 -#define SM6125_VDDMX_VFL 5 +#define SM6125_VDDCX RPMPD_VDDCX +#define SM6125_VDDCX_AO RPMPD_VDDCX_AO +#define SM6125_VDDCX_VFL RPMPD_VDDCX_VFL +#define SM6125_VDDMX RPMPD_VDDMX +#define SM6125_VDDMX_AO RPMPD_VDDMX_AO +#define SM6125_VDDMX_VFL RPMPD_VDDMX_VFL -/* QCM2290 Power Domains */ -#define QCM2290_VDDCX 0 -#define QCM2290_VDDCX_AO 1 -#define QCM2290_VDDCX_VFL 2 -#define QCM2290_VDDMX 3 -#define QCM2290_VDDMX_AO 4 -#define QCM2290_VDDMX_VFL 5 -#define QCM2290_VDD_LPI_CX 6 -#define QCM2290_VDD_LPI_MX 7 +/* SM6375 Power Domain Indexes */ +#define SM6375_VDDCX 0 +#define SM6375_VDDCX_AO 1 +#define SM6375_VDDCX_VFL 2 +#define SM6375_VDDMX 3 +#define SM6375_VDDMX_AO 4 +#define SM6375_VDDMX_VFL 5 +#define SM6375_VDDGX 6 +#define SM6375_VDDGX_AO 7 +#define SM6375_VDD_LPI_CX 8 +#define SM6375_VDD_LPI_MX 9 /* RPM SMD Power Domain performance levels */ #define RPM_SMD_LEVEL_RETENTION 16 |