History

Merge tag 'pmdomain-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm

Pull pmdomain updates from Ulf Hansson: - amlogic: Add support for S6/S7/S7D power-domains controller - imx: Add support for i.MX91 power-domains - marvell: Add support for PXA1908 power-domains - mediatek: - Add support for modem power sequence - Add support for RTFF Hardware in MT8196/MT6991 - qcom: Align power-domain definitions for rpmpd - rockchip: Default to use power-domain support - thead: Create auxiliary device along with a corresponding reset driver - ti: Synchronize on/off state with HW-state for ti-sci power-domains * tag 'pmdomain-v6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (25 commits) pmdomain: thead: Fix error pointer vs NULL bug in th1520_pd_reboot_init() pmdomain: thead: create auxiliary device for rebooting driver: reset: th1520-aon: add driver for poweroff/reboot via AON FW pmdomain: mediatek: airoha: convert from round_rate() to determine_rate() pmdomain: rockchip: enable ROCKCHIP_PM_DOMAINS with ARCH_ROCKCHIP pmdomain: marvell: Add PXA1908 power domains dt-bindings: clock: marvell,pxa1908: Add syscon compatible to apmu pmdomain: ti-sci: Set PD on/off state according to the HW state pmdomain: amlogic: Add support for S6 S7 S7D power domains controller dt-bindings: power: add Amlogic S6 S7 S7D power domains pmdomain: mediatek: Convert all SoCs to new style regmap retrieval pmdomain: mediatek: Add support for RTFF Hardware in MT8196/MT6991 pmdomain: mediatek: Add support for modem power sequences pmdomain: mediatek: Move ctl sequences out of power_on/off functions pmdomain: mediatek: Handle SoCs with inverted SRAM power-down bits pmdomain: mediatek: Refactor bus protection regmaps retrieval dt-bindings: power: mediatek: Document access-controllers property pmdomain: remove unneeded 'fast_io' parameter in regmap_config pmdomain: imx93-blk-ctrl: mask DSI and PXP PD domain register on i.MX91 pmdomain: imx93-blk-ctrl: use ARRAY_SIZE() instead of hardcode number ...

Linus Torvalds committed 1 year ago

Commit e93bcba2 parents ea1c6c5 bbc311038 files · +1592 −468Browse files

Unified · Split

38 files
  1. Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml +24 −6
  2. Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml +3 −0
  3. Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +37 −0
  4. Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml +47 −12
  5. MAINTAINERS +3 −0
  6. drivers/pmdomain/Kconfig +1 −0
  7. drivers/pmdomain/Makefile +1 −0
  8. drivers/pmdomain/amlogic/meson-secure-pwrc.c +95 −0
  9. drivers/pmdomain/imx/gpc.c +0 −1
  10. drivers/pmdomain/imx/imx93-blk-ctrl.c +21 −2
  11. drivers/pmdomain/marvell/Kconfig +18 −0
  12. drivers/pmdomain/marvell/Makefile +3 −0
  13. drivers/pmdomain/marvell/pxa1908-power-controller.c +274 −0
  14. drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c +4 −4
  15. drivers/pmdomain/mediatek/mt6795-pm-domains.h +5 −0
  16. drivers/pmdomain/mediatek/mt8167-pm-domains.h +5 −0
  17. drivers/pmdomain/mediatek/mt8173-pm-domains.h +5 −0
  18. drivers/pmdomain/mediatek/mt8183-pm-domains.h +5 −0
  19. drivers/pmdomain/mediatek/mt8186-pm-domains.h +5 −0
  20. drivers/pmdomain/mediatek/mt8188-pm-domains.h +6 −0
  21. drivers/pmdomain/mediatek/mt8192-pm-domains.h +5 −0
  22. drivers/pmdomain/mediatek/mt8195-pm-domains.h +5 −0
  23. drivers/pmdomain/mediatek/mt8365-pm-domains.h +9 −5
  24. drivers/pmdomain/mediatek/mtk-pm-domains.c +335 −64
  25. drivers/pmdomain/mediatek/mtk-pm-domains.h +56 −18
  26. drivers/pmdomain/qcom/rpmpd.c +56 −56
  27. drivers/pmdomain/rockchip/Kconfig +1 −0
  28. drivers/pmdomain/thead/th1520-pm-domains.c +16 −0
  29. drivers/pmdomain/ti/ti_sci_pm_domains.c +23 −1
  30. drivers/power/reset/Kconfig +7 −0
  31. drivers/power/reset/Makefile +1 −0
  32. drivers/power/reset/th1520-aon-reboot.c +98 −0
  33. include/dt-bindings/power/amlogic,s6-pwrc.h +29 −0
  34. include/dt-bindings/power/amlogic,s7-pwrc.h +20 −0
  35. include/dt-bindings/power/amlogic,s7d-pwrc.h +27 −0
  36. include/dt-bindings/power/marvell,pxa1908-power.h +17 −0
  37. include/dt-bindings/power/qcom,rpmhpd.h +233 −0
  38. include/dt-bindings/power/qcom-rpmpd.h +92 −299
Documentation/devicetree/bindings/clock/marvell,pxa1908.yaml+24−6
@@ -19,11 +19,14 @@ description: | · 18 unmodified lines
1919
2020 properties:
2121 compatible:
22− enum:
23− - marvell,pxa1908-apbc
24− - marvell,pxa1908-apbcp
25− - marvell,pxa1908-mpmu
26− - marvell,pxa1908-apmu
22+ oneOf:
23+ - enum:
24+ - marvell,pxa1908-apbc
25+ - marvell,pxa1908-apbcp
26+ - marvell,pxa1908-mpmu
27+ - items:
28+ - const: marvell,pxa1908-apmu
29+ - const: syscon
2730
2831 reg:
2932 maxItems: 1
@@ -31,6 +34,9 @@ properties: · 1 unmodified line
3134 '#clock-cells':
3235 const: 1
3336
37+ '#power-domain-cells':
38+ const: 1
39+
3440 required:
3541 - compatible
3642 - reg
@@ -38,11 +44,23 @@ required: · 1 unmodified line
3844
3945 additionalProperties: false
4046
47+if:
48+ not:
49+ properties:
50+ compatible:
51+ contains:
52+ const: marvell,pxa1908-apmu
53+
54+then:
55+ properties:
56+ '#power-domain-cells': false
57+
4158 examples:
4259 # APMU block:
4360 - |
4461 clock-controller@d4282800 {
45− compatible = "marvell,pxa1908-apmu";
62+ compatible = "marvell,pxa1908-apmu", "syscon";
4663 reg = <0xd4282800 0x400>;
4764 #clock-cells = <1>;
65+ #power-domain-cells = <1>;
4866 };
Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml+3−0
@@ -24,6 +24,9 @@ properties: · 23 unmodified lines
2424 - amlogic,a5-pwrc
2525 - amlogic,c3-pwrc
2626 - amlogic,t7-pwrc
27+ - amlogic,s6-pwrc
28+ - amlogic,s7-pwrc
29+ - amlogic,s7d-pwrc
2730
2831 "#power-domain-cells":
2932 const: 1
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml+37−0
@@ -44,6 +44,15 @@ properties: · 43 unmodified lines
4444 '#size-cells':
4545 const: 0
4646
47+ access-controllers:
48+ description:
49+ A number of phandles to external blocks to set and clear the required
50+ bits to enable or disable bus protection, necessary to avoid any bus
51+ faults while enabling or disabling a power domain.
52+ For example, this may hold phandles to INFRACFG and SMI.
53+ minItems: 1
54+ maxItems: 3
55+
4756 patternProperties:
4857 "^power-domain@[0-9a-f]+$":
4958 $ref: "#/$defs/power-domain-node"
@@ -123,14 +132,17 @@ $defs: · 73 unmodified lines
123132 mediatek,infracfg:
124133 $ref: /schemas/types.yaml#/definitions/phandle
125134 description: phandle to the device containing the INFRACFG register range.
135+ deprecated: true
126136
127137 mediatek,infracfg-nao:
128138 $ref: /schemas/types.yaml#/definitions/phandle
129139 description: phandle to the device containing the INFRACFG-NAO register range.
140+ deprecated: true
130141
131142 mediatek,smi:
132143 $ref: /schemas/types.yaml#/definitions/phandle
133144 description: phandle to the device containing the SMI register range.
145+ deprecated: true
134146
135147 required:
136148 - reg
@@ -138,6 +150,31 @@ $defs: · 1 unmodified line
138150 required:
139151 - compatible
140152
153+allOf:
154+ - if:
155+ properties:
156+ compatible:
157+ contains:
158+ enum:
159+ - mediatek,mt8183-power-controller
160+ then:
161+ properties:
162+ access-controllers:
163+ minItems: 2
164+ maxItems: 2
165+
166+ - if:
167+ properties:
168+ compatible:
169+ contains:
170+ enum:
171+ - mediatek,mt8365-power-controller
172+ then:
173+ properties:
174+ access-controllers:
175+ minItems: 3
176+ maxItems: 3
177+
141178 additionalProperties: false
142179
143180 examples:
Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml+47−12
@@ -18,7 +18,9 @@ description: · 17 unmodified lines
1818 properties:
1919 compatible:
2020 items:
21− - const: fsl,imx93-media-blk-ctrl
21+ - enum:
22+ - fsl,imx91-media-blk-ctrl
23+ - fsl,imx93-media-blk-ctrl
2224 - const: syscon
2325
2426 reg:
@@ -31,21 +33,54 @@ properties: · 6 unmodified lines
3133 maxItems: 1
3234
3335 clocks:
36+ minItems: 8
3437 maxItems: 10
3538
3639 clock-names:
37− items:
38− - const: apb
39− - const: axi
40− - const: nic
41− - const: disp
42− - const: cam
43− - const: pxp
44− - const: lcdif
45− - const: isi
46− - const: csi
47− - const: dsi
40+ minItems: 8
41+ maxItems: 10
4842
43+allOf:
44+ - if:
45+ properties:
46+ compatible:
47+ contains:
48+ const: fsl,imx91-media-blk-ctrl
49+ then:
50+ properties:
51+ clocks:
52+ maxItems: 8
53+ clock-names:
54+ items:
55+ - const: apb
56+ - const: axi
57+ - const: nic
58+ - const: disp
59+ - const: cam
60+ - const: lcdif
61+ - const: isi
62+ - const: csi
63+ - if:
64+ properties:
65+ compatible:
66+ contains:
67+ const: fsl,imx93-media-blk-ctrl
68+ then:
69+ properties:
70+ clocks:
71+ minItems: 10
72+ clock-names:
73+ items:
74+ - const: apb
75+ - const: axi
76+ - const: nic
77+ - const: disp
78+ - const: cam
79+ - const: pxp
80+ - const: lcdif
81+ - const: isi
82+ - const: csi
83+ - const: dsi
4984 required:
5085 - compatible
5186 - reg
MAINTAINERS+3−0
@@ -2880,7 +2880,9 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) · 2879 unmodified lines
28802880 S: Maintained
28812881 F: arch/arm64/boot/dts/marvell/mmp/
28822882 F: drivers/clk/mmp/clk-pxa1908*.c
2883+F: drivers/pmdomain/marvell/
28832884 F: include/dt-bindings/clock/marvell,pxa1908.h
2885+F: include/dt-bindings/power/marvell,pxa1908-power.h
28842886
28852887 ARM/Mediatek RTC DRIVER
28862888 M: Eddie Huang <eddie.huang@mediatek.com>
@@ -21863,6 +21865,7 @@ F: drivers/mailbox/mailbox-th1520.c · 18976 unmodified lines
2186321865 F: drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
2186421866 F: drivers/pinctrl/pinctrl-th1520.c
2186521867 F: drivers/pmdomain/thead/
21868+F: drivers/power/reset/th1520-aon-reboot.c
2186621869 F: drivers/power/sequencing/pwrseq-thead-gpu.c
2186721870 F: drivers/reset/reset-th1520.c
2186821871 F: include/dt-bindings/clock/thead,th1520-clk-ap.h
drivers/pmdomain/Kconfig+1−0
@@ -7,6 +7,7 @@ source "drivers/pmdomain/apple/Kconfig" · 6 unmodified lines
77 source "drivers/pmdomain/arm/Kconfig"
88 source "drivers/pmdomain/bcm/Kconfig"
99 source "drivers/pmdomain/imx/Kconfig"
10+source "drivers/pmdomain/marvell/Kconfig"
1011 source "drivers/pmdomain/mediatek/Kconfig"
1112 source "drivers/pmdomain/qcom/Kconfig"
1213 source "drivers/pmdomain/renesas/Kconfig"
drivers/pmdomain/Makefile+1−0
@@ -5,6 +5,7 @@ obj-y += apple/ · 4 unmodified lines
55 obj-y += arm/
66 obj-y += bcm/
77 obj-y += imx/
8+obj-y += marvell/
89 obj-y += mediatek/
910 obj-y += qcom/
1011 obj-y += renesas/
drivers/pmdomain/amlogic/meson-secure-pwrc.c+95−0
@@ -16,6 +16,9 @@ · 15 unmodified lines
1616 #include <dt-bindings/power/amlogic,t7-pwrc.h>
1717 #include <dt-bindings/power/amlogic,a4-pwrc.h>
1818 #include <dt-bindings/power/amlogic,a5-pwrc.h>
19+#include <dt-bindings/power/amlogic,s6-pwrc.h>
20+#include <dt-bindings/power/amlogic,s7-pwrc.h>
21+#include <dt-bindings/power/amlogic,s7d-pwrc.h>
1922 #include <linux/arm-smccc.h>
2023 #include <linux/firmware/meson/meson_sm.h>
2124 #include <linux/module.h>
@@ -201,6 +204,71 @@ static const struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = { · 179 unmodified lines
201204 SEC_PD(S4_AUDIO, 0),
202205 };
203206
207+static const struct meson_secure_pwrc_domain_desc s6_pwrc_domains[] = {
208+ SEC_PD(S6_DSPA, 0),
209+ SEC_PD(S6_DOS_HEVC, 0),
210+ SEC_PD(S6_DOS_VDEC, 0),
211+ SEC_PD(S6_VPU_HDMI, 0),
212+ SEC_PD(S6_U2DRD, 0),
213+ SEC_PD(S6_U3DRD, 0),
214+ SEC_PD(S6_SD_EMMC_C, 0),
215+ SEC_PD(S6_GE2D, 0),
216+ SEC_PD(S6_AMFC, 0),
217+ SEC_PD(S6_VC9000E, 0),
218+ SEC_PD(S6_DEWARP, 0),
219+ SEC_PD(S6_VICP, 0),
220+ SEC_PD(S6_SD_EMMC_A, 0),
221+ SEC_PD(S6_SD_EMMC_B, 0),
222+ /* ETH is for ethernet online wakeup, and should be always on */
223+ SEC_PD(S6_ETH, GENPD_FLAG_ALWAYS_ON),
224+ SEC_PD(S6_PCIE, 0),
225+ SEC_PD(S6_NNA_4T, 0),
226+ SEC_PD(S6_AUDIO, 0),
227+ SEC_PD(S6_AUCPU, 0),
228+ SEC_PD(S6_ADAPT, 0),
229+};
230+
231+static const struct meson_secure_pwrc_domain_desc s7_pwrc_domains[] = {
232+ SEC_PD(S7_DOS_HEVC, 0),
233+ SEC_PD(S7_DOS_VDEC, 0),
234+ SEC_PD(S7_VPU_HDMI, 0),
235+ SEC_PD(S7_USB_COMB, 0),
236+ SEC_PD(S7_SD_EMMC_C, 0),
237+ SEC_PD(S7_GE2D, 0),
238+ SEC_PD(S7_SD_EMMC_A, 0),
239+ SEC_PD(S7_SD_EMMC_B, 0),
240+ /* ETH is for ethernet online wakeup, and should be always on */
241+ SEC_PD(S7_ETH, GENPD_FLAG_ALWAYS_ON),
242+ SEC_PD(S7_AUCPU, 0),
243+ SEC_PD(S7_AUDIO, 0),
244+};
245+
246+static const struct meson_secure_pwrc_domain_desc s7d_pwrc_domains[] = {
247+ SEC_PD(S7D_DOS_HCODEC, 0),
248+ SEC_PD(S7D_DOS_HEVC, 0),
249+ SEC_PD(S7D_DOS_VDEC, 0),
250+ SEC_PD(S7D_VPU_HDMI, 0),
251+ SEC_PD(S7D_USB_U2DRD, 0),
252+ SEC_PD(S7D_USB_U2H, 0),
253+ SEC_PD(S7D_SSD_EMMC_C, 0),
254+ SEC_PD(S7D_GE2D, 0),
255+ SEC_PD(S7D_AMFC, 0),
256+ SEC_PD(S7D_EMMC_A, 0),
257+ SEC_PD(S7D_EMMC_B, 0),
258+ /* ETH is for ethernet online wakeup, and should be always on */
259+ SEC_PD(S7D_ETH, GENPD_FLAG_ALWAYS_ON),
260+ SEC_PD(S7D_AUCPU, 0),
261+ SEC_PD(S7D_AUDIO, 0),
262+ /* SRAMA is used as ATF runtime memory, and should be always on */
263+ SEC_PD(S7D_SRAMA, GENPD_FLAG_ALWAYS_ON),
264+ /* DMC0 is for DDR PHY ana/dig and DMC, and should be always on */
265+ SEC_PD(S7D_DMC0, GENPD_FLAG_ALWAYS_ON),
266+ /* DMC1 is for DDR PHY ana/dig and DMC, and should be always on */
267+ SEC_PD(S7D_DMC1, GENPD_FLAG_ALWAYS_ON),
268+ /* DDR should be always on */
269+ SEC_PD(S7D_DDR, GENPD_FLAG_ALWAYS_ON),
270+};
271+
204272 static const struct meson_secure_pwrc_domain_desc t7_pwrc_domains[] = {
205273 SEC_PD(T7_DSPA, 0),
206274 SEC_PD(T7_DSPB, 0),
@@ -367,6 +435,21 @@ static const struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = { · 160 unmodified lines
367435 .count = ARRAY_SIZE(s4_pwrc_domains),
368436 };
369437
438+static const struct meson_secure_pwrc_domain_data amlogic_secure_s6_pwrc_data = {
439+ .domains = s6_pwrc_domains,
440+ .count = ARRAY_SIZE(s6_pwrc_domains),
441+};
442+
443+static const struct meson_secure_pwrc_domain_data amlogic_secure_s7_pwrc_data = {
444+ .domains = s7_pwrc_domains,
445+ .count = ARRAY_SIZE(s7_pwrc_domains),
446+};
447+
448+static const struct meson_secure_pwrc_domain_data amlogic_secure_s7d_pwrc_data = {
449+ .domains = s7d_pwrc_domains,
450+ .count = ARRAY_SIZE(s7d_pwrc_domains),
451+};
452+
370453 static const struct meson_secure_pwrc_domain_data amlogic_secure_t7_pwrc_data = {
371454 .domains = t7_pwrc_domains,
372455 .count = ARRAY_SIZE(t7_pwrc_domains),
@@ -393,6 +476,18 @@ static const struct of_device_id meson_secure_pwrc_match_table[] = { · 20 unmodified lines
393476 .compatible = "amlogic,meson-s4-pwrc",
394477 .data = &meson_secure_s4_pwrc_data,
395478 },
479+ {
480+ .compatible = "amlogic,s6-pwrc",
481+ .data = &amlogic_secure_s6_pwrc_data,
482+ },
483+ {
484+ .compatible = "amlogic,s7-pwrc",
485+ .data = &amlogic_secure_s7_pwrc_data,
486+ },
487+ {
488+ .compatible = "amlogic,s7d-pwrc",
489+ .data = &amlogic_secure_s7d_pwrc_data,
490+ },
396491 {
397492 .compatible = "amlogic,t7-pwrc",
398493 .data = &amlogic_secure_t7_pwrc_data,
drivers/pmdomain/imx/gpc.c+0−1
@@ -343,7 +343,6 @@ static const struct regmap_config imx_gpc_regmap_config = { · 342 unmodified lines
343343 .rd_table = &access_table,
344344 .wr_table = &access_table,
345345 .max_register = 0x2ac,
346− .fast_io = true,
347346 };
348347
349348 static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
drivers/pmdomain/imx/imx93-blk-ctrl.c+21−2
@@ -86,6 +86,7 @@ struct imx93_blk_ctrl_domain { · 85 unmodified lines
8686
8787 struct imx93_blk_ctrl_data {
8888 const struct imx93_blk_ctrl_domain_data *domains;
89+ u32 skip_mask;
8990 int num_domains;
9091 const char * const *clk_names;
9192 int num_clks;
@@ -250,6 +251,8 @@ static int imx93_blk_ctrl_probe(struct platform_device *pdev) · 158 unmodified lines
250251 int j;
251252
252253 domain->data = data;
254+ if (bc_data->skip_mask & BIT(i))
255+ continue;
253256
254257 for (j = 0; j < data->num_clks; j++)
255258 domain->clks[j].id = data->clk_names[j];
@@ -418,16 +421,32 @@ static const struct regmap_access_table imx93_media_blk_ctl_access_table = { · 162 unmodified lines
418421 .n_yes_ranges = ARRAY_SIZE(imx93_media_blk_ctl_yes_ranges),
419422 };
420423
424+static const char * const media_blk_clk_names[] = {
425+ "axi", "apb", "nic"
426+};
427+
428+static const struct imx93_blk_ctrl_data imx91_media_blk_ctl_dev_data = {
429+ .domains = imx93_media_blk_ctl_domain_data,
430+ .skip_mask = BIT(IMX93_MEDIABLK_PD_MIPI_DSI) | BIT(IMX93_MEDIABLK_PD_PXP),
431+ .num_domains = ARRAY_SIZE(imx93_media_blk_ctl_domain_data),
432+ .clk_names = media_blk_clk_names,
433+ .num_clks = ARRAY_SIZE(media_blk_clk_names),
434+ .reg_access_table = &imx93_media_blk_ctl_access_table,
435+};
436+
421437 static const struct imx93_blk_ctrl_data imx93_media_blk_ctl_dev_data = {
422438 .domains = imx93_media_blk_ctl_domain_data,
423439 .num_domains = ARRAY_SIZE(imx93_media_blk_ctl_domain_data),
424− .clk_names = (const char *[]){ "axi", "apb", "nic", },
425− .num_clks = 3,
440+ .clk_names = media_blk_clk_names,
441+ .num_clks = ARRAY_SIZE(media_blk_clk_names),
426442 .reg_access_table = &imx93_media_blk_ctl_access_table,
427443 };
428444
429445 static const struct of_device_id imx93_blk_ctrl_of_match[] = {
430446 {
447+ .compatible = "fsl,imx91-media-blk-ctrl",
448+ .data = &imx91_media_blk_ctl_dev_data
449+ }, {
431450 .compatible = "fsl,imx93-media-blk-ctrl",
432451 .data = &imx93_media_blk_ctl_dev_data
433452 }, {
drivers/pmdomain/marvell/Kconfig+18−0
@@ -0,0 +1,18 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+menu "Marvell PM Domains"
4+ depends on ARCH_MMP || COMPILE_TEST
5+
6+config PXA1908_PM_DOMAINS
7+ tristate "Marvell PXA1908 power domains"
8+ depends on OF
9+ depends on PM
10+ default y if ARCH_MMP && ARM64
11+ select AUXILIARY_BUS
12+ select MFD_SYSCON
13+ select PM_GENERIC_DOMAINS
14+ select PM_GENERIC_DOMAINS_OF
15+ help
16+ Say Y here to enable support for Marvell PXA1908's power domanis.
17+
18+endmenu
drivers/pmdomain/marvell/Makefile+3−0
@@ -0,0 +1,3 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+
3+obj-$(CONFIG_PXA1908_PM_DOMAINS) += pxa1908-power-controller.o
drivers/pmdomain/marvell/pxa1908-power-controller.c+274−0
@@ -0,0 +1,274 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright 2025 Duje Mihanović <duje@dujemihanovic.xyz>
4+ */
5+
6+#include <linux/auxiliary_bus.h>
7+#include <linux/container_of.h>
8+#include <linux/dev_printk.h>
9+#include <linux/device.h>
10+#include <linux/mfd/syscon.h>
11+#include <linux/mod_devicetable.h>
12+#include <linux/module.h>
13+#include <linux/pm_domain.h>
14+#include <linux/regmap.h>
15+
16+#include <dt-bindings/power/marvell,pxa1908-power.h>
17+
18+/* VPU, GPU, ISP */
19+#define APMU_PWR_CTRL_REG 0xd8
20+#define APMU_PWR_BLK_TMR_REG 0xdc
21+#define APMU_PWR_STATUS_REG 0xf0
22+
23+/* DSI */
24+#define APMU_DEBUG 0x88
25+#define DSI_PHY_DVM_MASK BIT(31)
26+
27+#define POWER_ON_LATENCY_US 300
28+#define POWER_OFF_LATENCY_US 20
29+#define POWER_POLL_TIMEOUT_US (25 * USEC_PER_MSEC)
30+#define POWER_POLL_SLEEP_US 6
31+
32+#define NR_DOMAINS 5
33+
34+#define to_pxa1908_pd(_genpd) container_of(_genpd, struct pxa1908_pd, genpd)
35+
36+struct pxa1908_pd_ctrl {
37+ struct generic_pm_domain *domains[NR_DOMAINS];
38+ struct genpd_onecell_data onecell_data;
39+ struct regmap *base;
40+ struct device *dev;
41+};
42+
43+struct pxa1908_pd_data {
44+ u32 reg_clk_res_ctrl;
45+ u32 pwr_state;
46+ u32 hw_mode;
47+ bool keep_on;
48+ int id;
49+};
50+
51+struct pxa1908_pd {
52+ const struct pxa1908_pd_data data;
53+ struct pxa1908_pd_ctrl *ctrl;
54+ struct generic_pm_domain genpd;
55+ bool initialized;
56+};
57+
58+static inline bool pxa1908_pd_is_on(struct pxa1908_pd *pd)
59+{
60+ struct pxa1908_pd_ctrl *ctrl = pd->ctrl;
61+
62+ return pd->data.id != PXA1908_POWER_DOMAIN_DSI
63+ ? regmap_test_bits(ctrl->base, APMU_PWR_STATUS_REG, pd->data.pwr_state)
64+ : regmap_test_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK);
65+}
66+
67+static int pxa1908_pd_power_on(struct generic_pm_domain *genpd)
68+{
69+ struct pxa1908_pd *pd = to_pxa1908_pd(genpd);
70+ const struct pxa1908_pd_data *data = &pd->data;
71+ struct pxa1908_pd_ctrl *ctrl = pd->ctrl;
72+ unsigned int status;
73+ int ret = 0;
74+
75+ regmap_set_bits(ctrl->base, data->reg_clk_res_ctrl, data->hw_mode);
76+ if (data->id != PXA1908_POWER_DOMAIN_ISP)
77+ regmap_write(ctrl->base, APMU_PWR_BLK_TMR_REG, 0x20001fff);
78+ regmap_set_bits(ctrl->base, APMU_PWR_CTRL_REG, data->pwr_state);
79+
80+ ret = regmap_read_poll_timeout(ctrl->base, APMU_PWR_STATUS_REG, status,
81+ status & data->pwr_state, POWER_POLL_SLEEP_US,
82+ POWER_ON_LATENCY_US + POWER_POLL_TIMEOUT_US);
83+ if (ret == -ETIMEDOUT)
84+ dev_err(ctrl->dev, "timed out powering on domain '%s'\n", pd->genpd.name);
85+
86+ return ret;
87+}
88+
89+static int pxa1908_pd_power_off(struct generic_pm_domain *genpd)
90+{
91+ struct pxa1908_pd *pd = to_pxa1908_pd(genpd);
92+ const struct pxa1908_pd_data *data = &pd->data;
93+ struct pxa1908_pd_ctrl *ctrl = pd->ctrl;
94+ unsigned int status;
95+ int ret;
96+
97+ regmap_clear_bits(ctrl->base, APMU_PWR_CTRL_REG, data->pwr_state);
98+
99+ ret = regmap_read_poll_timeout(ctrl->base, APMU_PWR_STATUS_REG, status,
100+ !(status & data->pwr_state), POWER_POLL_SLEEP_US,
101+ POWER_OFF_LATENCY_US + POWER_POLL_TIMEOUT_US);
102+ if (ret == -ETIMEDOUT) {
103+ dev_err(ctrl->dev, "timed out powering off domain '%s'\n", pd->genpd.name);
104+ return ret;
105+ }
106+
107+ return regmap_clear_bits(ctrl->base, data->reg_clk_res_ctrl, data->hw_mode);
108+}
109+
110+static inline int pxa1908_dsi_power_on(struct generic_pm_domain *genpd)
111+{
112+ struct pxa1908_pd *pd = to_pxa1908_pd(genpd);
113+ struct pxa1908_pd_ctrl *ctrl = pd->ctrl;
114+
115+ return regmap_set_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK);
116+}
117+
118+static inline int pxa1908_dsi_power_off(struct generic_pm_domain *genpd)
119+{
120+ struct pxa1908_pd *pd = to_pxa1908_pd(genpd);
121+ struct pxa1908_pd_ctrl *ctrl = pd->ctrl;
122+
123+ return regmap_clear_bits(ctrl->base, APMU_DEBUG, DSI_PHY_DVM_MASK);
124+}
125+
126+#define DOMAIN(_id, _name, ctrl, mode, state) \
127+ [_id] = { \
128+ .data = { \
129+ .reg_clk_res_ctrl = ctrl, \
130+ .hw_mode = BIT(mode), \
131+ .pwr_state = BIT(state), \
132+ .id = _id, \
133+ }, \
134+ .genpd = { \
135+ .name = _name, \
136+ .power_on = pxa1908_pd_power_on, \
137+ .power_off = pxa1908_pd_power_off, \
138+ }, \
139+ }
140+
141+static struct pxa1908_pd domains[NR_DOMAINS] = {
142+ DOMAIN(PXA1908_POWER_DOMAIN_VPU, "vpu", 0xa4, 19, 2),
143+ DOMAIN(PXA1908_POWER_DOMAIN_GPU, "gpu", 0xcc, 11, 0),
144+ DOMAIN(PXA1908_POWER_DOMAIN_GPU2D, "gpu2d", 0xf4, 11, 6),
145+ DOMAIN(PXA1908_POWER_DOMAIN_ISP, "isp", 0x38, 15, 4),
146+ [PXA1908_POWER_DOMAIN_DSI] = {
147+ .genpd = {
148+ .name = "dsi",
149+ .power_on = pxa1908_dsi_power_on,
150+ .power_off = pxa1908_dsi_power_off,
151+ /*
152+ * TODO: There is no DSI driver written yet and until then we probably
153+ * don't want to power off the DSI PHY ever.
154+ */
155+ .flags = GENPD_FLAG_ALWAYS_ON,
156+ },
157+ .data = {
158+ /* See above. */
159+ .keep_on = true,
160+ },
161+ },
162+};
163+
164+static void pxa1908_pd_remove(struct auxiliary_device *auxdev)
165+{
166+ struct pxa1908_pd *pd;
167+ int ret;
168+
169+ for (int i = NR_DOMAINS - 1; i >= 0; i--) {
170+ pd = &domains[i];
171+
172+ if (!pd->initialized)
173+ continue;
174+
175+ if (pxa1908_pd_is_on(pd) && !pd->data.keep_on)
176+ pxa1908_pd_power_off(&pd->genpd);
177+
178+ ret = pm_genpd_remove(&pd->genpd);
179+ if (ret)
180+ dev_err(&auxdev->dev, "failed to remove domain '%s': %d\n",
181+ pd->genpd.name, ret);
182+ }
183+}
184+
185+static int
186+pxa1908_pd_init(struct pxa1908_pd_ctrl *ctrl, int id, struct device *dev)
187+{
188+ struct pxa1908_pd *pd = &domains[id];
189+ int ret;
190+
191+ ctrl->domains[id] = &pd->genpd;
192+
193+ pd->ctrl = ctrl;
194+
195+ /* Make sure the state of the hardware is synced with the domain table above. */
196+ if (pd->data.keep_on) {
197+ ret = pd->genpd.power_on(&pd->genpd);
198+ if (ret)
199+ return dev_err_probe(dev, ret, "failed to power on domain '%s'\n",
200+ pd->genpd.name);
201+ } else {
202+ if (pxa1908_pd_is_on(pd)) {
203+ dev_warn(dev,
204+ "domain '%s' is on despite being default off; powering off\n",
205+ pd->genpd.name);
206+
207+ ret = pd->genpd.power_off(&pd->genpd);
208+ if (ret)
209+ return dev_err_probe(dev, ret,
210+ "failed to power off domain '%s'\n",
211+ pd->genpd.name);
212+ }
213+ }
214+
215+ ret = pm_genpd_init(&pd->genpd, NULL, !pd->data.keep_on);
216+ if (ret)
217+ return dev_err_probe(dev, ret, "domain '%s' failed to initialize\n",
218+ pd->genpd.name);
219+
220+ pd->initialized = true;
221+
222+ return 0;
223+}
224+
225+static int
226+pxa1908_pd_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *aux_id)
227+{
228+ struct pxa1908_pd_ctrl *ctrl;
229+ struct device *dev = &auxdev->dev;
230+ int ret;
231+
232+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
233+ if (!ctrl)
234+ return -ENOMEM;
235+
236+ auxiliary_set_drvdata(auxdev, ctrl);
237+
238+ ctrl->base = syscon_node_to_regmap(dev->parent->of_node);
239+ if (IS_ERR(ctrl->base))
240+ return dev_err_probe(dev, PTR_ERR(ctrl->base), "no regmap available\n");
241+
242+ ctrl->dev = dev;
243+ ctrl->onecell_data.domains = ctrl->domains;
244+ ctrl->onecell_data.num_domains = NR_DOMAINS;
245+
246+ for (int i = 0; i < NR_DOMAINS; i++) {
247+ ret = pxa1908_pd_init(ctrl, i, dev);
248+ if (ret)
249+ goto err;
250+ }
251+
252+ return of_genpd_add_provider_onecell(dev->parent->of_node, &ctrl->onecell_data);
253+
254+err:
255+ pxa1908_pd_remove(auxdev);
256+ return ret;
257+}
258+
259+static const struct auxiliary_device_id pxa1908_pd_id[] = {
260+ { .name = "clk_pxa1908_apmu.power" },
261+ { }
262+};
263+MODULE_DEVICE_TABLE(auxiliary, pxa1908_pd_id);
264+
265+static struct auxiliary_driver pxa1908_pd_driver = {
266+ .probe = pxa1908_pd_probe,
267+ .remove = pxa1908_pd_remove,
268+ .id_table = pxa1908_pd_id,
269+};
270+module_auxiliary_driver(pxa1908_pd_driver);
271+
272+MODULE_AUTHOR("Duje Mihanović <duje@dujemihanovic.xyz>");
273+MODULE_DESCRIPTION("Marvell PXA1908 power domain driver");
274+MODULE_LICENSE("GPL");
drivers/pmdomain/mediatek/airoha-cpu-pmdomain.c+4−4
@@ -21,10 +21,10 @@ struct airoha_cpu_pmdomain_priv { · 20 unmodified lines
2121 struct generic_pm_domain pd;
2222 };
2323
24−static long airoha_cpu_pmdomain_clk_round(struct clk_hw *hw, unsigned long rate,
25− unsigned long *parent_rate)
24+static int airoha_cpu_pmdomain_clk_determine_rate(struct clk_hw *hw,
25+ struct clk_rate_request *req)
2626 {
27− return rate;
27+ return 0;
2828 }
2929
3030 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) · 17 unmodified lines
4848 static const struct clk_ops airoha_cpu_pmdomain_clk_ops = {
4949 .recalc_rate = airoha_cpu_pmdomain_clk_get,
5050 .is_enabled = airoha_cpu_pmdomain_clk_is_enabled,
51− .round_rate = airoha_cpu_pmdomain_clk_round,
51+ .determine_rate = airoha_cpu_pmdomain_clk_determine_rate,
5252 };
5353
5454 static int airoha_cpu_pmdomain_set_performance_state(struct generic_pm_domain *domain,
drivers/pmdomain/mediatek/mt6795-pm-domains.h+5−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
99 /*
1010 * MT6795 power domain support
1111 */
12+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt6795[] = {
13+ BUS_PROT_BLOCK_INFRA
14+};
1215
1316 static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = {
1417 [MT6795_POWER_DOMAIN_VDEC] = {
@@ -107,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt6795[] = { · 92 unmodified lines
107110 static const struct scpsys_soc_data mt6795_scpsys_data = {
108111 .domains_data = scpsys_domain_data_mt6795,
109112 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt6795),
113+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt6795,
114+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt6795),
110115 };
111116
112117 #endif /* __SOC_MEDIATEK_MT6795_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8167-pm-domains.h+5−0
@@ -12,6 +12,9 @@ · 11 unmodified lines
1212 /*
1313 * MT8167 power domain support
1414 */
15+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8167[] = {
16+ BUS_PROT_BLOCK_INFRA
17+};
1518
1619 static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
1720 [MT8167_POWER_DOMAIN_MM] = {
@@ -99,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 81 unmodified lines
99102 static const struct scpsys_soc_data mt8167_scpsys_data = {
100103 .domains_data = scpsys_domain_data_mt8167,
101104 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
105+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8167,
106+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8167),
102107 };
103108
104109 #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8173-pm-domains.h+5−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
99 /*
1010 * MT8173 power domain support
1111 */
12+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8173[] = {
13+ BUS_PROT_BLOCK_INFRA
14+};
1215
1316 static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
1417 [MT8173_POWER_DOMAIN_VDEC] = {
@@ -118,6 +121,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 103 unmodified lines
118121 static const struct scpsys_soc_data mt8173_scpsys_data = {
119122 .domains_data = scpsys_domain_data_mt8173,
120123 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
124+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8173,
125+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8173),
121126 };
122127
123128 #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8183-pm-domains.h+5−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
99 /*
1010 * MT8183 power domain support
1111 */
12+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8183[] = {
13+ BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SMI
14+};
1215
1316 static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
1417 [MT8183_POWER_DOMAIN_AUDIO] = {
@@ -290,6 +293,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 275 unmodified lines
290293 static const struct scpsys_soc_data mt8183_scpsys_data = {
291294 .domains_data = scpsys_domain_data_mt8183,
292295 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
296+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8183,
297+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8183),
293298 };
294299
295300 #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8186-pm-domains.h+5−0
@@ -13,6 +13,9 @@ · 12 unmodified lines
1313 /*
1414 * MT8186 power domain support
1515 */
16+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8186[] = {
17+ BUS_PROT_BLOCK_INFRA
18+};
1619
1720 static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
1821 [MT8186_POWER_DOMAIN_MFG0] = {
@@ -361,6 +364,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = { · 342 unmodified lines
361364 static const struct scpsys_soc_data mt8186_scpsys_data = {
362365 .domains_data = scpsys_domain_data_mt8186,
363366 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8186),
367+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8186,
368+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8186),
364369 };
365370
366371 #endif /* __SOC_MEDIATEK_MT8186_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8188-pm-domains.h+6−0
@@ -14,6 +14,10 @@ · 13 unmodified lines
1414 * MT8188 power domain support
1515 */
1616
17+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8188[] = {
18+ BUS_PROT_BLOCK_INFRA
19+};
20+
1721 static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
1822 [MT8188_POWER_DOMAIN_MFG0] = {
1923 .name = "mfg0",
@@ -685,6 +689,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = { · 665 unmodified lines
685689 static const struct scpsys_soc_data mt8188_scpsys_data = {
686690 .domains_data = scpsys_domain_data_mt8188,
687691 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8188),
692+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8188,
693+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8188),
688694 };
689695
690696 #endif /* __SOC_MEDIATEK_MT8188_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8192-pm-domains.h+5−0
@@ -9,6 +9,9 @@ · 8 unmodified lines
99 /*
1010 * MT8192 power domain support
1111 */
12+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8192[] = {
13+ BUS_PROT_BLOCK_INFRA
14+};
1215
1316 static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
1417 [MT8192_POWER_DOMAIN_AUDIO] = {
@@ -380,6 +383,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 365 unmodified lines
380383 static const struct scpsys_soc_data mt8192_scpsys_data = {
381384 .domains_data = scpsys_domain_data_mt8192,
382385 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
386+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8192,
387+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8192),
383388 };
384389
385390 #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8195-pm-domains.h+5−0
@@ -13,6 +13,9 @@ · 12 unmodified lines
1313 /*
1414 * MT8195 power domain support
1515 */
16+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8195[] = {
17+ BUS_PROT_BLOCK_INFRA
18+};
1619
1720 static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
1821 [MT8195_POWER_DOMAIN_PCIE_MAC_P0] = {
@@ -662,6 +665,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = { · 643 unmodified lines
662665 static const struct scpsys_soc_data mt8195_scpsys_data = {
663666 .domains_data = scpsys_domain_data_mt8195,
664667 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195),
668+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8195,
669+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8195),
665670 };
666671
667672 #endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mt8365-pm-domains.h+9−5
@@ -29,11 +29,13 @@ · 28 unmodified lines
2929 MT8365_SMI_COMMON_CLAMP_EN)
3030
3131 #define MT8365_BUS_PROT_WAY_EN(_set_mask, _set, _sta_mask, _sta) \
32− _BUS_PROT(_set_mask, _set, _set, _sta_mask, _sta, \
33− BUS_PROT_COMPONENT_INFRA | \
34− BUS_PROT_STA_COMPONENT_INFRA_NAO | \
35− BUS_PROT_INVERTED | \
36− BUS_PROT_REG_UPDATE)
32+ _BUS_PROT_STA(INFRA, INFRA_NAO, _set_mask, _set, _set, \
33+ _sta_mask, _sta, \
34+ BUS_PROT_INVERTED | BUS_PROT_REG_UPDATE)
35+
36+static enum scpsys_bus_prot_block scpsys_bus_prot_blocks_mt8365[] = {
37+ BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_INFRA_NAO, BUS_PROT_BLOCK_SMI
38+};
3739
3840 static const struct scpsys_domain_data scpsys_domain_data_mt8365[] = {
3941 [MT8365_POWER_DOMAIN_MM] = {
@@ -192,6 +194,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8365[] = { · 152 unmodified lines
192194 static const struct scpsys_soc_data mt8365_scpsys_data = {
193195 .domains_data = scpsys_domain_data_mt8365,
194196 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8365),
197+ .bus_prot_blocks = scpsys_bus_prot_blocks_mt8365,
198+ .num_bus_prot_blocks = ARRAY_SIZE(scpsys_bus_prot_blocks_mt8365),
195199 };
196200
197201 #endif /* __SOC_MEDIATEK_MT8365_PM_DOMAINS_H */
drivers/pmdomain/mediatek/mtk-pm-domains.c+335−64
@@ -39,6 +39,12 @@ · 38 unmodified lines
3939 #define PWR_SRAM_CLKISO_BIT BIT(5)
4040 #define PWR_SRAM_ISOINT_B_BIT BIT(6)
4141
42+#define PWR_RTFF_SAVE BIT(24)
43+#define PWR_RTFF_NRESTORE BIT(25)
44+#define PWR_RTFF_CLK_DIS BIT(26)
45+#define PWR_RTFF_SAVE_FLAG BIT(27)
46+#define PWR_RTFF_UFS_CLK_DIS BIT(28)
47+
4248 struct scpsys_domain {
4349 struct generic_pm_domain genpd;
4450 const struct scpsys_domain_data *data;
@@ -47,9 +53,6 @@ struct scpsys_domain { · 2 unmodified lines
4753 struct clk_bulk_data *clks;
4854 int num_subsys_clks;
4955 struct clk_bulk_data *subsys_clks;
50− struct regmap *infracfg_nao;
51− struct regmap *infracfg;
52− struct regmap *smi;
5356 struct regulator *supply;
5457 };
5558
@@ -57,6 +60,8 @@ struct scpsys { · 1 unmodified line
5760 struct device *dev;
5861 struct regmap *base;
5962 const struct scpsys_soc_data *soc_data;
63+ u8 bus_prot_index[BUS_PROT_BLOCK_COUNT];
64+ struct regmap **bus_prot;
6065 struct genpd_onecell_data pd_data;
6166 struct generic_pm_domain *domains[];
6267 };
@@ -80,16 +85,23 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd) · 17 unmodified lines
8085
8186 static int scpsys_sram_enable(struct scpsys_domain *pd)
8287 {
83− u32 pdn_ack = pd->data->sram_pdn_ack_bits;
88+ u32 expected_ack, pdn_ack = pd->data->sram_pdn_ack_bits;
8489 struct scpsys *scpsys = pd->scpsys;
8590 unsigned int tmp;
8691 int ret;
8792
88− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
93+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_PDN_INVERTED)) {
94+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
95+ expected_ack = pdn_ack;
96+ } else {
97+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
98+ expected_ack = 0;
99+ }
89100
90101 /* Either wait until SRAM_PDN_ACK all 1 or 0 */
91102 ret = regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp,
92− (tmp & pdn_ack) == 0, MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
103+ (tmp & pdn_ack) == expected_ack,
104+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
93105 if (ret < 0)
94106 return ret;
95107
@@ -104,7 +116,7 @@ static int scpsys_sram_enable(struct scpsys_domain *pd) · 8 unmodified lines
104116
105117 static int scpsys_sram_disable(struct scpsys_domain *pd)
106118 {
107− u32 pdn_ack = pd->data->sram_pdn_ack_bits;
119+ u32 expected_ack, pdn_ack = pd->data->sram_pdn_ack_bits;
108120 struct scpsys *scpsys = pd->scpsys;
109121 unsigned int tmp;
110122
@@ -114,30 +126,36 @@ static int scpsys_sram_disable(struct scpsys_domain *pd) · 3 unmodified lines
114126 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT);
115127 }
116128
117− regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
129+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_SRAM_PDN_INVERTED)) {
130+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
131+ expected_ack = 0;
132+ } else {
133+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits);
134+ expected_ack = pdn_ack;
135+ }
118136
119137 /* Either wait until SRAM_PDN_ACK all 1 or 0 */
120138 return regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp,
121− (tmp & pdn_ack) == pdn_ack, MTK_POLL_DELAY_US,
122− MTK_POLL_TIMEOUT);
139+ (tmp & pdn_ack) == expected_ack,
140+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
123141 }
124142
125143 static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
126144 const struct scpsys_bus_prot_data *bpd)
127145 {
128− if (bpd->flags & BUS_PROT_COMPONENT_SMI)
129− return pd->smi;
130− else
131− return pd->infracfg;
146+ struct scpsys *scpsys = pd->scpsys;
147+ unsigned short block_idx = scpsys->bus_prot_index[bpd->bus_prot_block];
148+
149+ return scpsys->bus_prot[block_idx];
132150 }
133151
134152 static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
135153 const struct scpsys_bus_prot_data *bpd)
136154 {
137− if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
138− return pd->infracfg_nao;
139− else
140− return scpsys_bus_protect_get_regmap(pd, bpd);
155+ struct scpsys *scpsys = pd->scpsys;
156+ int block_idx = scpsys->bus_prot_index[bpd->bus_prot_sta_block];
157+
158+ return scpsys->bus_prot[block_idx];
141159 }
142160
143161 static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
@@ -149,7 +167,7 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd, · 5 unmodified lines
149167 u32 expected_ack;
150168 u32 val;
151169
152− expected_ack = (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO ? sta_mask : 0);
170+ expected_ack = (bpd->bus_prot_sta_block == BUS_PROT_BLOCK_INFRA_NAO ? sta_mask : 0);
153171
154172 if (bpd->flags & BUS_PROT_REG_UPDATE)
155173 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) · 76 unmodified lines
232250 return supply ? regulator_disable(supply) : 0;
233251 }
234252
253+static int scpsys_ctl_pwrseq_on(struct scpsys_domain *pd)
254+{
255+ struct scpsys *scpsys = pd->scpsys;
256+ bool do_rtff_nrestore, tmp;
257+ int ret;
258+
259+ /* subsys power on */
260+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
261+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
262+
263+ /* wait until PWR_ACK = 1 */
264+ ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US,
265+ MTK_POLL_TIMEOUT);
266+ if (ret < 0)
267+ return ret;
268+
269+ if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY)
270+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
271+
272+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
273+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
274+
275+ /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */
276+ if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY)
277+ udelay(5);
278+
279+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
280+
281+ /*
282+ * RTFF HW state may be modified by secure world or remote processors.
283+ *
284+ * With the only exception of STOR_UFS, which always needs save/restore,
285+ * check if this power domain's RTFF is already on before trying to do
286+ * the NRESTORE procedure, otherwise the system will lock up.
287+ */
288+ switch (pd->data->rtff_type) {
289+ case SCPSYS_RTFF_TYPE_GENERIC:
290+ case SCPSYS_RTFF_TYPE_PCIE_PHY:
291+ {
292+ u32 ctl_status;
293+
294+ regmap_read(scpsys->base, pd->data->ctl_offs, &ctl_status);
295+ do_rtff_nrestore = ctl_status & PWR_RTFF_SAVE_FLAG;
296+ break;
297+ }
298+ case SCPSYS_RTFF_TYPE_STOR_UFS:
299+ /* STOR_UFS always needs NRESTORE */
300+ do_rtff_nrestore = true;
301+ break;
302+ default:
303+ do_rtff_nrestore = false;
304+ break;
305+ }
306+
307+ /* Return early if RTFF NRESTORE shall not be done */
308+ if (!do_rtff_nrestore)
309+ return 0;
310+
311+ switch (pd->data->rtff_type) {
312+ case SCPSYS_RTFF_TYPE_GENERIC:
313+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG);
314+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
315+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
316+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
317+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
318+ break;
319+ case SCPSYS_RTFF_TYPE_PCIE_PHY:
320+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG);
321+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
322+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
323+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
324+ break;
325+ case SCPSYS_RTFF_TYPE_STOR_UFS:
326+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS);
327+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
328+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_NRESTORE);
329+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS);
330+ break;
331+ default:
332+ break;
333+ }
334+
335+ return 0;
336+}
337+
338+static void scpsys_ctl_pwrseq_off(struct scpsys_domain *pd)
339+{
340+ struct scpsys *scpsys = pd->scpsys;
341+
342+ switch (pd->data->rtff_type) {
343+ case SCPSYS_RTFF_TYPE_GENERIC:
344+ case SCPSYS_RTFF_TYPE_PCIE_PHY:
345+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
346+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE);
347+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE);
348+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_CLK_DIS);
349+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE_FLAG);
350+ break;
351+ case SCPSYS_RTFF_TYPE_STOR_UFS:
352+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS);
353+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE);
354+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_SAVE);
355+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RTFF_UFS_CLK_DIS);
356+ break;
357+ default:
358+ break;
359+ }
360+
361+ /* subsys power off */
362+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
363+
364+ /* Wait for RTFF HW to sync buck isolation state if this is PCIe PHY RTFF */
365+ if (pd->data->rtff_type == SCPSYS_RTFF_TYPE_PCIE_PHY)
366+ udelay(1);
367+
368+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
369+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
370+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
371+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
372+}
373+
374+static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd)
375+{
376+ struct scpsys *scpsys = pd->scpsys;
377+ bool tmp;
378+ int ret;
379+
380+ if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B))
381+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
382+
383+ regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
384+
385+ /* wait until PWR_ACK = 1 */
386+ ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US,
387+ MTK_POLL_TIMEOUT);
388+ if (ret < 0)
389+ return ret;
390+
391+ return 0;
392+}
393+
394+static void scpsys_modem_pwrseq_off(struct scpsys_domain *pd)
395+{
396+ struct scpsys *scpsys = pd->scpsys;
397+
398+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
399+
400+ if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B))
401+ regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
402+}
403+
235404 static int scpsys_power_on(struct generic_pm_domain *genpd)
236405 {
237406 struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
238407 struct scpsys *scpsys = pd->scpsys;
239− bool tmp;
240408 int ret;
241409
242410 ret = scpsys_regulator_enable(pd->supply);
@@ -251,20 +419,14 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) · 8 unmodified lines
251419 regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs,
252420 pd->data->ext_buck_iso_mask);
253421
254− /* subsys power on */
255− regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
256− regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
422+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
423+ ret = scpsys_modem_pwrseq_on(pd);
424+ else
425+ ret = scpsys_ctl_pwrseq_on(pd);
257426
258− /* wait until PWR_ACK = 1 */
259− ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US,
260− MTK_POLL_TIMEOUT);
261− if (ret < 0)
427+ if (ret)
262428 goto err_pwr_ack;
263429
264− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
265− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
266− regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
267−
268430 /*
269431 * In few Mediatek platforms(e.g. MT6779), the bus protect policy is
270432 * 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) · 59 unmodified lines
330492
331493 clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
332494
333− /* subsys power off */
334− regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
335− regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
336− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
337− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
338− regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
495+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
496+ scpsys_modem_pwrseq_off(pd);
497+ else
498+ scpsys_ctl_pwrseq_off(pd);
339499
340500 /* wait until PWR_ACK = 0 */
341501 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 · 13 unmodified lines
355515 {
356516 const struct scpsys_domain_data *domain_data;
357517 struct scpsys_domain *pd;
358− struct device_node *smi_node;
359518 struct property *prop;
360519 const char *clk_name;
361520 int i, ret, num_clks;
@@ -396,32 +555,6 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no · 34 unmodified lines
396555 node);
397556 }
398557
399− pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg");
400− if (IS_ERR(pd->infracfg))
401− return dev_err_cast_probe(scpsys->dev, pd->infracfg,
402− "%pOF: failed to get infracfg regmap\n",
403− node);
404−
405− smi_node = of_parse_phandle(node, "mediatek,smi", 0);
406− if (smi_node) {
407− pd->smi = device_node_to_regmap(smi_node);
408− of_node_put(smi_node);
409− if (IS_ERR(pd->smi))
410− return dev_err_cast_probe(scpsys->dev, pd->smi,
411− "%pOF: failed to get SMI regmap\n",
412− node);
413− }
414−
415− if (MTK_SCPD_CAPS(pd, MTK_SCPD_HAS_INFRA_NAO)) {
416− pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao");
417− if (IS_ERR(pd->infracfg_nao))
418− return dev_err_cast_probe(scpsys->dev, pd->infracfg_nao,
419− "%pOF: failed to get infracfg-nao regmap\n",
420− node);
421− } else {
422− pd->infracfg_nao = NULL;
423− }
424−
425558 num_clks = of_clk_get_parent_count(node);
426559 if (num_clks > 0) {
427560 /* Calculate number of subsys_clks */
@@ -615,6 +748,136 @@ static void scpsys_domain_cleanup(struct scpsys *scpsys) · 187 unmodified lines
615748 }
616749 }
617750
751+static int scpsys_get_bus_protection_legacy(struct device *dev, struct scpsys *scpsys)
752+{
753+ const u8 bp_blocks[3] = {
754+ BUS_PROT_BLOCK_INFRA, BUS_PROT_BLOCK_SMI, BUS_PROT_BLOCK_INFRA_NAO
755+ };
756+ struct device_node *np = dev->of_node;
757+ struct device_node *node, *smi_np;
758+ int num_regmaps = 0, i, j;
759+ struct regmap *regmap[3];
760+
761+ /*
762+ * Legacy code retrieves a maximum of three bus protection handles:
763+ * some may be optional, or may not be, so the array of bp blocks
764+ * that is normally passed in as platform data must be dynamically
765+ * built in this case.
766+ *
767+ * Here, try to retrieve all of the regmaps that the legacy code
768+ * supported and then count the number of the ones that are present,
769+ * this makes it then possible to allocate the array of bus_prot
770+ * regmaps and convert all to the new style handling.
771+ */
772+ node = of_find_node_with_property(np, "mediatek,infracfg");
773+ if (node) {
774+ regmap[0] = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg");
775+ of_node_put(node);
776+ num_regmaps++;
777+ if (IS_ERR(regmap[0]))
778+ return dev_err_probe(dev, PTR_ERR(regmap[0]),
779+ "%pOF: failed to get infracfg regmap\n",
780+ node);
781+ } else {
782+ regmap[0] = NULL;
783+ }
784+
785+ node = of_find_node_with_property(np, "mediatek,smi");
786+ if (node) {
787+ smi_np = of_parse_phandle(node, "mediatek,smi", 0);
788+ of_node_put(node);
789+ if (!smi_np)
790+ return -ENODEV;
791+
792+ regmap[1] = device_node_to_regmap(smi_np);
793+ num_regmaps++;
794+ of_node_put(smi_np);
795+ if (IS_ERR(regmap[1]))
796+ return dev_err_probe(dev, PTR_ERR(regmap[1]),
797+ "%pOF: failed to get SMI regmap\n",
798+ node);
799+ } else {
800+ regmap[1] = NULL;
801+ }
802+
803+ node = of_find_node_with_property(np, "mediatek,infracfg-nao");
804+ if (node) {
805+ regmap[2] = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao");
806+ num_regmaps++;
807+ of_node_put(node);
808+ if (IS_ERR(regmap[2]))
809+ return dev_err_probe(dev, PTR_ERR(regmap[2]),
810+ "%pOF: failed to get infracfg regmap\n",
811+ node);
812+ } else {
813+ regmap[2] = NULL;
814+ }
815+
816+ scpsys->bus_prot = devm_kmalloc_array(dev, num_regmaps,
817+ sizeof(*scpsys->bus_prot), GFP_KERNEL);
818+ if (!scpsys->bus_prot)
819+ return -ENOMEM;
820+
821+ for (i = 0, j = 0; i < ARRAY_SIZE(bp_blocks); i++) {
822+ enum scpsys_bus_prot_block bp_type;
823+
824+ if (!regmap[i])
825+ continue;
826+
827+ bp_type = bp_blocks[i];
828+ scpsys->bus_prot_index[bp_type] = j;
829+ scpsys->bus_prot[j] = regmap[i];
830+
831+ j++;
832+ }
833+
834+ return 0;
835+}
836+
837+static int scpsys_get_bus_protection(struct device *dev, struct scpsys *scpsys)
838+{
839+ const struct scpsys_soc_data *soc = scpsys->soc_data;
840+ struct device_node *np = dev->of_node;
841+ int i, num_handles;
842+
843+ num_handles = of_count_phandle_with_args(np, "access-controllers", NULL);
844+ if (num_handles < 0 || num_handles != soc->num_bus_prot_blocks)
845+ return dev_err_probe(dev, -EINVAL,
846+ "Cannot get access controllers: expected %u, got %d\n",
847+ soc->num_bus_prot_blocks, num_handles);
848+
849+ scpsys->bus_prot = devm_kmalloc_array(dev, soc->num_bus_prot_blocks,
850+ sizeof(*scpsys->bus_prot), GFP_KERNEL);
851+ if (!scpsys->bus_prot)
852+ return -ENOMEM;
853+
854+ for (i = 0; i < soc->num_bus_prot_blocks; i++) {
855+ enum scpsys_bus_prot_block bp_type;
856+ struct device_node *node;
857+
858+ node = of_parse_phandle(np, "access-controllers", i);
859+ if (!node)
860+ return -EINVAL;
861+
862+ /*
863+ * Index the bus protection regmaps so that we don't have to
864+ * find the right one by type with a loop at every execution
865+ * of power sequence(s).
866+ */
867+ bp_type = soc->bus_prot_blocks[i];
868+ scpsys->bus_prot_index[bp_type] = i;
869+
870+ scpsys->bus_prot[i] = device_node_to_regmap(node);
871+ of_node_put(node);
872+ if (IS_ERR_OR_NULL(scpsys->bus_prot[i]))
873+ return dev_err_probe(dev, scpsys->bus_prot[i] ?
874+ PTR_ERR(scpsys->bus_prot[i]) : -ENXIO,
875+ "Cannot get regmap for access controller %d\n", i);
876+ }
877+
878+ return 0;
879+}
880+
618881 static const struct of_device_id scpsys_of_match[] = {
619882 {
620883 .compatible = "mediatek,mt6735-power-controller",
@@ -701,6 +964,14 @@ static int scpsys_probe(struct platform_device *pdev) · 80 unmodified lines
701964 return PTR_ERR(scpsys->base);
702965 }
703966
967+ if (of_find_property(np, "access-controllers", NULL))
968+ ret = scpsys_get_bus_protection(dev, scpsys);
969+ else
970+ ret = scpsys_get_bus_protection_legacy(dev, scpsys);
971+
972+ if (ret)
973+ return ret;
974+
704975 ret = -ENODEV;
705976 for_each_available_child_of_node(np, node) {
706977 struct generic_pm_domain *domain;
drivers/pmdomain/mediatek/mtk-pm-domains.h+56−18
@@ -13,6 +13,9 @@ · 12 unmodified lines
1313 #define MTK_SCPD_EXT_BUCK_ISO BIT(6)
1414 #define MTK_SCPD_HAS_INFRA_NAO BIT(7)
1515 #define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8)
16+#define MTK_SCPD_SRAM_PDN_INVERTED BIT(9)
17+#define MTK_SCPD_MODEM_PWRSEQ BIT(10)
18+#define MTK_SCPD_SKIP_RESET_B BIT(11)
1619 #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
1720
1821 #define SPM_VDE_PWR_CON 0x0210
@@ -50,30 +53,43 @@ enum scpsys_bus_prot_flags { · 31 unmodified lines
5053 BUS_PROT_REG_UPDATE = BIT(1),
5154 BUS_PROT_IGNORE_CLR_ACK = BIT(2),
5255 BUS_PROT_INVERTED = BIT(3),
53− BUS_PROT_COMPONENT_INFRA = BIT(4),
54− BUS_PROT_COMPONENT_SMI = BIT(5),
55− BUS_PROT_STA_COMPONENT_INFRA_NAO = BIT(6),
5656 };
5757
58−#define _BUS_PROT(_set_clr_mask, _set, _clr, _sta_mask, _sta, _flags) { \
59− .bus_prot_set_clr_mask = (_set_clr_mask), \
60− .bus_prot_set = _set, \
61− .bus_prot_clr = _clr, \
62− .bus_prot_sta_mask = (_sta_mask), \
63− .bus_prot_sta = _sta, \
64− .flags = _flags \
58+enum scpsys_bus_prot_block {
59+ BUS_PROT_BLOCK_INFRA,
60+ BUS_PROT_BLOCK_INFRA_NAO,
61+ BUS_PROT_BLOCK_SMI,
62+ BUS_PROT_BLOCK_COUNT,
63+};
64+
65+#define _BUS_PROT_STA(_hwip, _sta_hwip, _set_clr_mask, _set, _clr, \
66+ _sta_mask, _sta, _flags) \
67+ { \
68+ .bus_prot_block = BUS_PROT_BLOCK_##_hwip, \
69+ .bus_prot_sta_block = BUS_PROT_BLOCK_##_sta_hwip, \
70+ .bus_prot_set_clr_mask = (_set_clr_mask), \
71+ .bus_prot_set = _set, \
72+ .bus_prot_clr = _clr, \
73+ .bus_prot_sta_mask = (_sta_mask), \
74+ .bus_prot_sta = _sta, \
75+ .flags = _flags \
6576 }
6677
67−#define BUS_PROT_WR(_hwip, _mask, _set, _clr, _sta) \
68− _BUS_PROT(_mask, _set, _clr, _mask, _sta, BUS_PROT_COMPONENT_##_hwip)
78+#define _BUS_PROT(_hwip, _set_clr_mask, _set, _clr, _sta_mask, \
79+ _sta, _flags) \
80+ _BUS_PROT_STA(_hwip, _hwip, _set_clr_mask, _set, _clr, \
81+ _sta_mask, _sta, _flags)
6982
70−#define BUS_PROT_WR_IGN(_hwip, _mask, _set, _clr, _sta) \
71− _BUS_PROT(_mask, _set, _clr, _mask, _sta, \
72− BUS_PROT_COMPONENT_##_hwip | BUS_PROT_IGNORE_CLR_ACK)
83+#define BUS_PROT_WR(_hwip, _mask, _set, _clr, _sta) \
84+ _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, 0)
7385
74−#define BUS_PROT_UPDATE(_hwip, _mask, _set, _clr, _sta) \
75− _BUS_PROT(_mask, _set, _clr, _mask, _sta, \
76− BUS_PROT_COMPONENT_##_hwip | BUS_PROT_REG_UPDATE)
86+#define BUS_PROT_WR_IGN(_hwip, _mask, _set, _clr, _sta) \
87+ _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, \
88+ BUS_PROT_IGNORE_CLR_ACK)
89+
90+#define BUS_PROT_UPDATE(_hwip, _mask, _set, _clr, _sta) \
91+ _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta, \
92+ BUS_PROT_REG_UPDATE)
7793
7894 #define BUS_PROT_INFRA_UPDATE_TOPAXI(_mask) \
7995 BUS_PROT_UPDATE(INFRA, _mask, \
@@ -82,6 +98,8 @@ enum scpsys_bus_prot_flags { · 2 unmodified lines
8298 INFRA_TOPAXI_PROTECTSTA1)
8399
84100 struct scpsys_bus_prot_data {
101+ u8 bus_prot_block;
102+ u8 bus_prot_sta_block;
85103 u32 bus_prot_set_clr_mask;
86104 u32 bus_prot_set;
87105 u32 bus_prot_clr;
@@ -90,6 +108,22 @@ struct scpsys_bus_prot_data { · 2 unmodified lines
90108 u8 flags;
91109 };
92110
111+/**
112+ * enum scpsys_rtff_type - Type of RTFF Hardware for power domain
113+ * @SCPSYS_RTFF_NONE: RTFF HW not present or domain not RTFF managed
114+ * @SCPSYS_RTFF_TYPE_GENERIC: Non-CPU, peripheral-generic RTFF HW
115+ * @SCPSYS_RTFF_TYPE_PCIE_PHY: PCI-Express PHY specific RTFF HW
116+ * @SCPSYS_RTFF_TYPE_STOR_UFS: Storage (UFS) specific RTFF HW
117+ * @SCPSYS_RTFF_TYPE_MAX: Number of supported RTFF HW Types
118+ */
119+enum scpsys_rtff_type {
120+ SCPSYS_RTFF_NONE = 0,
121+ SCPSYS_RTFF_TYPE_GENERIC,
122+ SCPSYS_RTFF_TYPE_PCIE_PHY,
123+ SCPSYS_RTFF_TYPE_STOR_UFS,
124+ SCPSYS_RTFF_TYPE_MAX
125+};
126+
93127 /**
94128 * struct scpsys_domain_data - scp domain data for power on/off flow
95129 * @name: The name of the power domain.
@@ -100,6 +134,7 @@ struct scpsys_bus_prot_data { · 4 unmodified lines
100134 * @ext_buck_iso_offs: The offset for external buck isolation
101135 * @ext_buck_iso_mask: The mask for external buck isolation
102136 * @caps: The flag for active wake-up action.
137+ * @rtff_type: The power domain RTFF HW type
103138 * @bp_cfg: bus protection configuration for any subsystem
104139 */
105140 struct scpsys_domain_data {
@@ -111,6 +146,7 @@ struct scpsys_domain_data { · 5 unmodified lines
111146 int ext_buck_iso_offs;
112147 u32 ext_buck_iso_mask;
113148 u16 caps;
149+ enum scpsys_rtff_type rtff_type;
114150 const struct scpsys_bus_prot_data bp_cfg[SPM_MAX_BUS_PROT_DATA];
115151 int pwr_sta_offs;
116152 int pwr_sta2nd_offs;
@@ -119,6 +155,8 @@ struct scpsys_domain_data { · 2 unmodified lines
119155 struct scpsys_soc_data {
120156 const struct scpsys_domain_data *domains_data;
121157 int num_domains;
158+ enum scpsys_bus_prot_block *bus_prot_blocks;
159+ int num_bus_prot_blocks;
122160 };
123161
124162 #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
drivers/pmdomain/qcom/rpmpd.c+56−56
@@ -631,12 +631,12 @@ static struct rpmpd ssc_mx_rwsm0_vfl = { · 630 unmodified lines
631631 };
632632
633633 static struct rpmpd *mdm9607_rpmpds[] = {
634− [MDM9607_VDDCX] = &cx_s3a_lvl,
635− [MDM9607_VDDCX_AO] = &cx_s3a_lvl_ao,
636− [MDM9607_VDDCX_VFL] = &cx_s3a_vfl,
637− [MDM9607_VDDMX] = &mx_l12a_lvl,
638− [MDM9607_VDDMX_AO] = &mx_l12a_lvl_ao,
639− [MDM9607_VDDMX_VFL] = &mx_l12a_vfl,
634+ [RPMPD_VDDCX] = &cx_s3a_lvl,
635+ [RPMPD_VDDCX_AO] = &cx_s3a_lvl_ao,
636+ [RPMPD_VDDCX_VFL] = &cx_s3a_vfl,
637+ [RPMPD_VDDMX] = &mx_l12a_lvl,
638+ [RPMPD_VDDMX_AO] = &mx_l12a_lvl_ao,
639+ [RPMPD_VDDMX_VFL] = &mx_l12a_vfl,
640640 };
641641
642642 static const struct rpmpd_desc mdm9607_desc = {
@@ -646,9 +646,9 @@ static const struct rpmpd_desc mdm9607_desc = { · 3 unmodified lines
646646 };
647647
648648 static struct rpmpd *msm8226_rpmpds[] = {
649− [MSM8226_VDDCX] = &cx_s1a_corner,
650− [MSM8226_VDDCX_AO] = &cx_s1a_corner_ao,
651− [MSM8226_VDDCX_VFC] = &cx_s1a_vfc,
649+ [RPMPD_VDDCX] = &cx_s1a_corner,
650+ [RPMPD_VDDCX_AO] = &cx_s1a_corner_ao,
651+ [RPMPD_VDDCX_VFC] = &cx_s1a_vfc,
652652 };
653653
654654 static const struct rpmpd_desc msm8226_desc = {
@@ -675,11 +675,11 @@ static const struct rpmpd_desc msm8939_desc = { · 20 unmodified lines
675675 };
676676
677677 static struct rpmpd *msm8916_rpmpds[] = {
678− [MSM8916_VDDCX] = &cx_s1a_corner,
679− [MSM8916_VDDCX_AO] = &cx_s1a_corner_ao,
680− [MSM8916_VDDCX_VFC] = &cx_s1a_vfc,
681− [MSM8916_VDDMX] = &mx_l3a_corner,
682− [MSM8916_VDDMX_AO] = &mx_l3a_corner_ao,
678+ [RPMPD_VDDCX] = &cx_s1a_corner,
679+ [RPMPD_VDDCX_AO] = &cx_s1a_corner_ao,
680+ [RPMPD_VDDCX_VFC] = &cx_s1a_vfc,
681+ [RPMPD_VDDMX] = &mx_l3a_corner,
682+ [RPMPD_VDDMX_AO] = &mx_l3a_corner_ao,
683683 };
684684
685685 static const struct rpmpd_desc msm8916_desc = {
@@ -689,11 +689,11 @@ static const struct rpmpd_desc msm8916_desc = { · 3 unmodified lines
689689 };
690690
691691 static struct rpmpd *msm8917_rpmpds[] = {
692− [MSM8917_VDDCX] = &cx_s2a_lvl,
693− [MSM8917_VDDCX_AO] = &cx_s2a_lvl_ao,
694− [MSM8917_VDDCX_VFL] = &cx_s2a_vfl,
695− [MSM8917_VDDMX] = &mx_l3a_lvl,
696− [MSM8917_VDDMX_AO] = &mx_l3a_lvl_ao,
692+ [RPMPD_VDDCX] = &cx_s2a_lvl,
693+ [RPMPD_VDDCX_AO] = &cx_s2a_lvl_ao,
694+ [RPMPD_VDDCX_VFL] = &cx_s2a_vfl,
695+ [RPMPD_VDDMX] = &mx_l3a_lvl,
696+ [RPMPD_VDDMX_AO] = &mx_l3a_lvl_ao,
697697 };
698698
699699 static const struct rpmpd_desc msm8917_desc = {
@@ -747,12 +747,12 @@ static const struct rpmpd_desc msm8974pro_pma8084_desc = { · 47 unmodified lines
747747 };
748748
749749 static struct rpmpd *msm8976_rpmpds[] = {
750− [MSM8976_VDDCX] = &cx_s2a_lvl,
751− [MSM8976_VDDCX_AO] = &cx_s2a_lvl_ao,
752− [MSM8976_VDDCX_VFL] = &cx_rwsc2_vfl,
753− [MSM8976_VDDMX] = &mx_s6a_lvl,
754− [MSM8976_VDDMX_AO] = &mx_s6a_lvl_ao,
755− [MSM8976_VDDMX_VFL] = &mx_rwsm6_vfl,
750+ [RPMPD_VDDCX] = &cx_s2a_lvl,
751+ [RPMPD_VDDCX_AO] = &cx_s2a_lvl_ao,
752+ [RPMPD_VDDCX_VFL] = &cx_rwsc2_vfl,
753+ [RPMPD_VDDMX] = &mx_s6a_lvl,
754+ [RPMPD_VDDMX_AO] = &mx_s6a_lvl_ao,
755+ [RPMPD_VDDMX_VFL] = &mx_rwsm6_vfl,
756756 };
757757
758758 static const struct rpmpd_desc msm8976_desc = {
@@ -796,16 +796,16 @@ static const struct rpmpd_desc msm8996_desc = { · 37 unmodified lines
796796 };
797797
798798 static struct rpmpd *msm8998_rpmpds[] = {
799− [MSM8998_VDDCX] = &cx_rwcx0_lvl,
800− [MSM8998_VDDCX_AO] = &cx_rwcx0_lvl_ao,
801− [MSM8998_VDDCX_VFL] = &cx_rwcx0_vfl,
802− [MSM8998_VDDMX] = &mx_rwmx0_lvl,
803− [MSM8998_VDDMX_AO] = &mx_rwmx0_lvl_ao,
804− [MSM8998_VDDMX_VFL] = &mx_rwmx0_vfl,
805− [MSM8998_SSCCX] = &ssc_cx_rwsc0_lvl,
806− [MSM8998_SSCCX_VFL] = &ssc_cx_rwsc0_vfl,
807− [MSM8998_SSCMX] = &ssc_mx_rwsm0_lvl,
808− [MSM8998_SSCMX_VFL] = &ssc_mx_rwsm0_vfl,
799+ [RPMPD_VDDCX] = &cx_rwcx0_lvl,
800+ [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao,
801+ [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl,
802+ [RPMPD_VDDMX] = &mx_rwmx0_lvl,
803+ [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao,
804+ [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl,
805+ [RPMPD_SSCCX] = &ssc_cx_rwsc0_lvl,
806+ [RPMPD_SSCCX_VFL] = &ssc_cx_rwsc0_vfl,
807+ [RPMPD_SSCMX] = &ssc_mx_rwsm0_lvl,
808+ [RPMPD_SSCMX_VFL] = &ssc_mx_rwsm0_vfl,
809809 };
810810
811811 static const struct rpmpd_desc msm8998_desc = {
@@ -831,11 +831,11 @@ static const struct rpmpd_desc qcs404_desc = { · 19 unmodified lines
831831 };
832832
833833 static struct rpmpd *qm215_rpmpds[] = {
834− [QM215_VDDCX] = &cx_s1a_lvl,
835− [QM215_VDDCX_AO] = &cx_s1a_lvl_ao,
836− [QM215_VDDCX_VFL] = &cx_s1a_vfl,
837− [QM215_VDDMX] = &mx_l2a_lvl,
838− [QM215_VDDMX_AO] = &mx_l2a_lvl_ao,
834+ [RPMPD_VDDCX] = &cx_s1a_lvl,
835+ [RPMPD_VDDCX_AO] = &cx_s1a_lvl_ao,
836+ [RPMPD_VDDCX_VFL] = &cx_s1a_vfl,
837+ [RPMPD_VDDMX] = &mx_l2a_lvl,
838+ [RPMPD_VDDMX_AO] = &mx_l2a_lvl_ao,
839839 };
840840
841841 static const struct rpmpd_desc qm215_desc = {
@@ -845,16 +845,16 @@ static const struct rpmpd_desc qm215_desc = { · 3 unmodified lines
845845 };
846846
847847 static struct rpmpd *sdm660_rpmpds[] = {
848− [SDM660_VDDCX] = &cx_rwcx0_lvl,
849− [SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao,
850− [SDM660_VDDCX_VFL] = &cx_rwcx0_vfl,
851− [SDM660_VDDMX] = &mx_rwmx0_lvl,
852− [SDM660_VDDMX_AO] = &mx_rwmx0_lvl_ao,
853− [SDM660_VDDMX_VFL] = &mx_rwmx0_vfl,
854− [SDM660_SSCCX] = &ssc_cx_rwlc0_lvl,
855− [SDM660_SSCCX_VFL] = &ssc_cx_rwlc0_vfl,
856− [SDM660_SSCMX] = &ssc_mx_rwlm0_lvl,
857− [SDM660_SSCMX_VFL] = &ssc_mx_rwlm0_vfl,
848+ [RPMPD_VDDCX] = &cx_rwcx0_lvl,
849+ [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao,
850+ [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl,
851+ [RPMPD_VDDMX] = &mx_rwmx0_lvl,
852+ [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao,
853+ [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl,
854+ [RPMPD_SSCCX] = &ssc_cx_rwlc0_lvl,
855+ [RPMPD_SSCCX_VFL] = &ssc_cx_rwlc0_vfl,
856+ [RPMPD_SSCMX] = &ssc_mx_rwlm0_lvl,
857+ [RPMPD_SSCMX_VFL] = &ssc_mx_rwlm0_vfl,
858858 };
859859
860860 static const struct rpmpd_desc sdm660_desc = {
@@ -881,12 +881,12 @@ static const struct rpmpd_desc sm6115_desc = { · 20 unmodified lines
881881 };
882882
883883 static struct rpmpd *sm6125_rpmpds[] = {
884− [SM6125_VDDCX] = &cx_rwcx0_lvl,
885− [SM6125_VDDCX_AO] = &cx_rwcx0_lvl_ao,
886− [SM6125_VDDCX_VFL] = &cx_rwcx0_vfl,
887− [SM6125_VDDMX] = &mx_rwmx0_lvl,
888− [SM6125_VDDMX_AO] = &mx_rwmx0_lvl_ao,
889− [SM6125_VDDMX_VFL] = &mx_rwmx0_vfl,
884+ [RPMPD_VDDCX] = &cx_rwcx0_lvl,
885+ [RPMPD_VDDCX_AO] = &cx_rwcx0_lvl_ao,
886+ [RPMPD_VDDCX_VFL] = &cx_rwcx0_vfl,
887+ [RPMPD_VDDMX] = &mx_rwmx0_lvl,
888+ [RPMPD_VDDMX_AO] = &mx_rwmx0_lvl_ao,
889+ [RPMPD_VDDMX_VFL] = &mx_rwmx0_vfl,
890890 };
891891
892892 static const struct rpmpd_desc sm6125_desc = {
drivers/pmdomain/rockchip/Kconfig+1−0
@@ -3,6 +3,7 @@ if ARCH_ROCKCHIP || COMPILE_TEST · 2 unmodified lines
33
44 config ROCKCHIP_PM_DOMAINS
55 bool "Rockchip generic power domain"
6+ default ARCH_ROCKCHIP
67 depends on PM
78 depends on HAVE_ARM_SMCCC_DISCOVERY
89 depends on REGULATOR
drivers/pmdomain/thead/th1520-pm-domains.c+16−0
@@ -173,6 +173,18 @@ static int th1520_pd_pwrseq_gpu_init(struct device *dev) · 172 unmodified lines
173173 adev);
174174 }
175175
176+static int th1520_pd_reboot_init(struct device *dev,
177+ struct th1520_aon_chan *aon_chan)
178+{
179+ struct auxiliary_device *adev;
180+
181+ adev = devm_auxiliary_device_create(dev, "reboot", aon_chan);
182+ if (!adev)
183+ return -ENODEV;
184+
185+ return 0;
186+}
187+
176188 static int th1520_pd_probe(struct platform_device *pdev)
177189 {
178190 struct generic_pm_domain **domains;
@@ -235,6 +247,10 @@ static int th1520_pd_probe(struct platform_device *pdev) · 56 unmodified lines
235247 if (ret)
236248 goto err_clean_provider;
237249
250+ ret = th1520_pd_reboot_init(dev, aon_chan);
251+ if (ret)
252+ goto err_clean_provider;
253+
238254 return 0;
239255
240256 err_clean_provider:
drivers/pmdomain/ti/ti_sci_pm_domains.c+23−1
@@ -200,6 +200,23 @@ static bool ti_sci_pm_idx_exists(struct ti_sci_genpd_provider *pd_provider, u32 · 199 unmodified lines
200200 return false;
201201 }
202202
203+static bool ti_sci_pm_pd_is_on(struct ti_sci_genpd_provider *pd_provider,
204+ int pd_idx)
205+{
206+ bool is_on;
207+ int ret;
208+
209+ if (!pd_provider->ti_sci->ops.dev_ops.is_on)
210+ return false;
211+
212+ ret = pd_provider->ti_sci->ops.dev_ops.is_on(pd_provider->ti_sci,
213+ pd_idx, NULL, &is_on);
214+ if (ret)
215+ return false;
216+
217+ return is_on;
218+}
219+
203220 static int ti_sci_pm_domain_probe(struct platform_device *pdev)
204221 {
205222 struct device *dev = &pdev->dev;
@@ -231,6 +248,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) · 25 unmodified lines
231248 index, &args)) {
232249
233250 if (args.args_count >= 1 && args.np == dev->of_node) {
251+ bool is_on;
252+
234253 of_node_put(args.np);
235254 if (args.args[0] > max_id) {
236255 max_id = args.args[0];
@@ -264,7 +283,10 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) · 27 unmodified lines
264283 pd_provider->ti_sci->ops.pm_ops.set_latency_constraint)
265284 pd->pd.domain.ops.suspend = ti_sci_pd_suspend;
266285
267− pm_genpd_init(&pd->pd, NULL, true);
286+ is_on = ti_sci_pm_pd_is_on(pd_provider,
287+ pd->idx);
288+
289+ pm_genpd_init(&pd->pd, NULL, !is_on);
268290
269291 list_add(&pd->node, &pd_provider->pd_list);
270292 } else {
drivers/power/reset/Kconfig+7−0
@@ -225,6 +225,13 @@ config POWER_RESET_ST · 224 unmodified lines
225225 help
226226 Reset support for STMicroelectronics boards.
227227
228+config POWER_RESET_TH1520_AON
229+ tristate "T-Head TH1520 AON firmware poweroff and reset driver"
230+ depends on TH1520_PM_DOMAINS
231+ help
232+ This driver supports power-off and reset operations for T-Head
233+ TH1520 SoCs running the AON firmware.
234+
228235 config POWER_RESET_TORADEX_EC
229236 tristate "Toradex Embedded Controller power-off and reset driver"
230237 depends on ARCH_MXC || COMPILE_TEST
drivers/power/reset/Makefile+1−0
@@ -25,6 +25,7 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o · 24 unmodified lines
2525 obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o
2626 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
2727 obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o
28+obj-$(CONFIG_POWER_RESET_TH1520_AON) += th1520-aon-reboot.o
2829 obj-$(CONFIG_POWER_RESET_TORADEX_EC) += tdx-ec-poweroff.o
2930 obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o
3031 obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
drivers/power/reset/th1520-aon-reboot.c+98−0
@@ -0,0 +1,98 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * T-HEAD TH1520 AON Firmware Reboot Driver
4+ *
5+ * Copyright (c) 2025 Icenowy Zheng <uwu@icenowy.me>
6+ */
7+
8+#include <linux/auxiliary_bus.h>
9+#include <linux/firmware/thead/thead,th1520-aon.h>
10+#include <linux/module.h>
11+#include <linux/notifier.h>
12+#include <linux/of.h>
13+#include <linux/reboot.h>
14+#include <linux/slab.h>
15+
16+#define TH1520_AON_REBOOT_PRIORITY 200
17+
18+struct th1520_aon_msg_empty_body {
19+ struct th1520_aon_rpc_msg_hdr hdr;
20+ u16 reserved[12];
21+} __packed __aligned(1);
22+
23+static int th1520_aon_pwroff_handler(struct sys_off_data *data)
24+{
25+ struct th1520_aon_chan *aon_chan = data->cb_data;
26+ struct th1520_aon_msg_empty_body msg = {};
27+
28+ msg.hdr.svc = TH1520_AON_RPC_SVC_WDG;
29+ msg.hdr.func = TH1520_AON_WDG_FUNC_POWER_OFF;
30+ msg.hdr.size = TH1520_AON_RPC_MSG_NUM;
31+
32+ th1520_aon_call_rpc(aon_chan, &msg);
33+
34+ return NOTIFY_DONE;
35+}
36+
37+static int th1520_aon_restart_handler(struct sys_off_data *data)
38+{
39+ struct th1520_aon_chan *aon_chan = data->cb_data;
40+ struct th1520_aon_msg_empty_body msg = {};
41+
42+ msg.hdr.svc = TH1520_AON_RPC_SVC_WDG;
43+ msg.hdr.func = TH1520_AON_WDG_FUNC_RESTART;
44+ msg.hdr.size = TH1520_AON_RPC_MSG_NUM;
45+
46+ th1520_aon_call_rpc(aon_chan, &msg);
47+
48+ return NOTIFY_DONE;
49+}
50+
51+static int th1520_aon_reboot_probe(struct auxiliary_device *adev,
52+ const struct auxiliary_device_id *id)
53+{
54+ struct device *dev = &adev->dev;
55+ int ret;
56+
57+ /* Expect struct th1520_aon_chan to be passed via platform_data */
58+ ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
59+ TH1520_AON_REBOOT_PRIORITY,
60+ th1520_aon_pwroff_handler,
61+ adev->dev.platform_data);
62+
63+ if (ret) {
64+ dev_err(dev, "Failed to register power off handler\n");
65+ return ret;
66+ }
67+
68+ ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART,
69+ TH1520_AON_REBOOT_PRIORITY,
70+ th1520_aon_restart_handler,
71+ adev->dev.platform_data);
72+
73+ if (ret) {
74+ dev_err(dev, "Failed to register restart handler\n");
75+ return ret;
76+ }
77+
78+ return 0;
79+}
80+
81+static const struct auxiliary_device_id th1520_aon_reboot_id_table[] = {
82+ { .name = "th1520_pm_domains.reboot" },
83+ {},
84+};
85+MODULE_DEVICE_TABLE(auxiliary, th1520_aon_reboot_id_table);
86+
87+static struct auxiliary_driver th1520_aon_reboot_driver = {
88+ .driver = {
89+ .name = "th1520-aon-reboot",
90+ },
91+ .probe = th1520_aon_reboot_probe,
92+ .id_table = th1520_aon_reboot_id_table,
93+};
94+module_auxiliary_driver(th1520_aon_reboot_driver);
95+
96+MODULE_AUTHOR("Icenowy Zheng <uwu@icenowy.me>");
97+MODULE_DESCRIPTION("T-HEAD TH1520 AON-firmware-based reboot driver");
98+MODULE_LICENSE("GPL");
include/dt-bindings/power/amlogic,s6-pwrc.h+29−0
@@ -0,0 +1,29 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
2+/*
3+ * Copyright (C) 2025 Amlogic, Inc. All rights reserved
4+ */
5+#ifndef _DT_BINDINGS_AMLOGIC_S6_POWER_H
6+#define _DT_BINDINGS_AMLOGIC_S6_POWER_H
7+
8+#define PWRC_S6_DSPA_ID 0
9+#define PWRC_S6_DOS_HEVC_ID 1
10+#define PWRC_S6_DOS_VDEC_ID 2
11+#define PWRC_S6_VPU_HDMI_ID 3
12+#define PWRC_S6_U2DRD_ID 4
13+#define PWRC_S6_U3DRD_ID 5
14+#define PWRC_S6_SD_EMMC_C_ID 6
15+#define PWRC_S6_GE2D_ID 7
16+#define PWRC_S6_AMFC_ID 8
17+#define PWRC_S6_VC9000E_ID 9
18+#define PWRC_S6_DEWARP_ID 10
19+#define PWRC_S6_VICP_ID 11
20+#define PWRC_S6_SD_EMMC_A_ID 12
21+#define PWRC_S6_SD_EMMC_B_ID 13
22+#define PWRC_S6_ETH_ID 14
23+#define PWRC_S6_PCIE_ID 15
24+#define PWRC_S6_NNA_4T_ID 16
25+#define PWRC_S6_AUDIO_ID 17
26+#define PWRC_S6_AUCPU_ID 18
27+#define PWRC_S6_ADAPT_ID 19
28+
29+#endif
include/dt-bindings/power/amlogic,s7-pwrc.h+20−0
@@ -0,0 +1,20 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
2+/*
3+ * Copyright (C) 2025 Amlogic, Inc. All rights reserved
4+ */
5+#ifndef _DT_BINDINGS_AMLOGIC_S7_POWER_H
6+#define _DT_BINDINGS_AMLOGIC_S7_POWER_H
7+
8+#define PWRC_S7_DOS_HEVC_ID 0
9+#define PWRC_S7_DOS_VDEC_ID 1
10+#define PWRC_S7_VPU_HDMI_ID 2
11+#define PWRC_S7_USB_COMB_ID 3
12+#define PWRC_S7_SD_EMMC_C_ID 4
13+#define PWRC_S7_GE2D_ID 5
14+#define PWRC_S7_SD_EMMC_A_ID 6
15+#define PWRC_S7_SD_EMMC_B_ID 7
16+#define PWRC_S7_ETH_ID 8
17+#define PWRC_S7_AUCPU_ID 9
18+#define PWRC_S7_AUDIO_ID 10
19+
20+#endif
include/dt-bindings/power/amlogic,s7d-pwrc.h+27−0
@@ -0,0 +1,27 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
2+/*
3+ * Copyright (C) 2025 Amlogic, Inc. All rights reserved
4+ */
5+#ifndef _DT_BINDINGS_AMLOGIC_S7D_POWER_H
6+#define _DT_BINDINGS_AMLOGIC_S7D_POWER_H
7+
8+#define PWRC_S7D_DOS_HCODEC_ID 0
9+#define PWRC_S7D_DOS_HEVC_ID 1
10+#define PWRC_S7D_DOS_VDEC_ID 2
11+#define PWRC_S7D_VPU_HDMI_ID 3
12+#define PWRC_S7D_USB_U2DRD_ID 4
13+#define PWRC_S7D_USB_U2H_ID 5
14+#define PWRC_S7D_SSD_EMMC_C_ID 6
15+#define PWRC_S7D_GE2D_ID 7
16+#define PWRC_S7D_AMFC_ID 8
17+#define PWRC_S7D_EMMC_A_ID 9
18+#define PWRC_S7D_EMMC_B_ID 10
19+#define PWRC_S7D_ETH_ID 11
20+#define PWRC_S7D_AUCPU_ID 12
21+#define PWRC_S7D_AUDIO_ID 13
22+#define PWRC_S7D_SRAMA_ID 14
23+#define PWRC_S7D_DMC0_ID 15
24+#define PWRC_S7D_DMC1_ID 16
25+#define PWRC_S7D_DDR_ID 17
26+
27+#endif
include/dt-bindings/power/marvell,pxa1908-power.h+17−0
@@ -0,0 +1,17 @@
1+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
2+/*
3+ * Marvell PXA1908 power domains
4+ *
5+ * Copyright 2025, Duje Mihanović <duje@dujemihanovic.xyz>
6+ */
7+
8+#ifndef __DTS_MARVELL_PXA1908_POWER_H
9+#define __DTS_MARVELL_PXA1908_POWER_H
10+
11+#define PXA1908_POWER_DOMAIN_VPU 0
12+#define PXA1908_POWER_DOMAIN_GPU 1
13+#define PXA1908_POWER_DOMAIN_GPU2D 2
14+#define PXA1908_POWER_DOMAIN_DSI 3
15+#define PXA1908_POWER_DOMAIN_ISP 4
16+
17+#endif
include/dt-bindings/power/qcom,rpmhpd.h+233−0
@@ -29,4 +29,237 @@ · 28 unmodified lines
2929 #define RPMHPD_NSP2 19
3030 #define RPMHPD_GMXC 20
3131
32+/* RPMh Power Domain performance levels */
33+#define RPMH_REGULATOR_LEVEL_RETENTION 16
34+#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
35+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
36+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
37+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
38+#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
39+#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
40+#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
41+#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
42+#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
43+#define RPMH_REGULATOR_LEVEL_SVS 128
44+#define RPMH_REGULATOR_LEVEL_SVS_L0 144
45+#define RPMH_REGULATOR_LEVEL_SVS_L1 192
46+#define RPMH_REGULATOR_LEVEL_SVS_L2 224
47+#define RPMH_REGULATOR_LEVEL_NOM 256
48+#define RPMH_REGULATOR_LEVEL_NOM_L0 288
49+#define RPMH_REGULATOR_LEVEL_NOM_L1 320
50+#define RPMH_REGULATOR_LEVEL_NOM_L2 336
51+#define RPMH_REGULATOR_LEVEL_TURBO 384
52+#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
53+#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
54+#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
55+#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
56+#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
57+#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
58+#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
59+#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
60+
61+/*
62+ * Platform-specific power domain bindings. Don't add new entries here, use
63+ * RPMHPD_* above.
64+ */
65+
66+/* SA8775P Power Domain Indexes */
67+#define SA8775P_CX 0
68+#define SA8775P_CX_AO 1
69+#define SA8775P_DDR 2
70+#define SA8775P_EBI 3
71+#define SA8775P_GFX 4
72+#define SA8775P_LCX 5
73+#define SA8775P_LMX 6
74+#define SA8775P_MMCX 7
75+#define SA8775P_MMCX_AO 8
76+#define SA8775P_MSS 9
77+#define SA8775P_MX 10
78+#define SA8775P_MX_AO 11
79+#define SA8775P_MXC 12
80+#define SA8775P_MXC_AO 13
81+#define SA8775P_NSP0 14
82+#define SA8775P_NSP1 15
83+#define SA8775P_XO 16
84+
85+/* SDM670 Power Domain Indexes */
86+#define SDM670_MX 0
87+#define SDM670_MX_AO 1
88+#define SDM670_CX 2
89+#define SDM670_CX_AO 3
90+#define SDM670_LMX 4
91+#define SDM670_LCX 5
92+#define SDM670_GFX 6
93+#define SDM670_MSS 7
94+
95+/* SDM845 Power Domain Indexes */
96+#define SDM845_EBI 0
97+#define SDM845_MX 1
98+#define SDM845_MX_AO 2
99+#define SDM845_CX 3
100+#define SDM845_CX_AO 4
101+#define SDM845_LMX 5
102+#define SDM845_LCX 6
103+#define SDM845_GFX 7
104+#define SDM845_MSS 8
105+
106+/* SDX55 Power Domain Indexes */
107+#define SDX55_MSS 0
108+#define SDX55_MX 1
109+#define SDX55_CX 2
110+
111+/* SDX65 Power Domain Indexes */
112+#define SDX65_MSS 0
113+#define SDX65_MX 1
114+#define SDX65_MX_AO 2
115+#define SDX65_CX 3
116+#define SDX65_CX_AO 4
117+#define SDX65_MXC 5
118+
119+/* SM6350 Power Domain Indexes */
120+#define SM6350_CX 0
121+#define SM6350_GFX 1
122+#define SM6350_LCX 2
123+#define SM6350_LMX 3
124+#define SM6350_MSS 4
125+#define SM6350_MX 5
126+
127+/* SM8150 Power Domain Indexes */
128+#define SM8150_MSS 0
129+#define SM8150_EBI 1
130+#define SM8150_LMX 2
131+#define SM8150_LCX 3
132+#define SM8150_GFX 4
133+#define SM8150_MX 5
134+#define SM8150_MX_AO 6
135+#define SM8150_CX 7
136+#define SM8150_CX_AO 8
137+#define SM8150_MMCX 9
138+#define SM8150_MMCX_AO 10
139+
140+/* SA8155P is a special case, kept for backwards compatibility */
141+#define SA8155P_CX SM8150_CX
142+#define SA8155P_CX_AO SM8150_CX_AO
143+#define SA8155P_EBI SM8150_EBI
144+#define SA8155P_GFX SM8150_GFX
145+#define SA8155P_MSS SM8150_MSS
146+#define SA8155P_MX SM8150_MX
147+#define SA8155P_MX_AO SM8150_MX_AO
148+
149+/* SM8250 Power Domain Indexes */
150+#define SM8250_CX 0
151+#define SM8250_CX_AO 1
152+#define SM8250_EBI 2
153+#define SM8250_GFX 3
154+#define SM8250_LCX 4
155+#define SM8250_LMX 5
156+#define SM8250_MMCX 6
157+#define SM8250_MMCX_AO 7
158+#define SM8250_MX 8
159+#define SM8250_MX_AO 9
160+
161+/* SM8350 Power Domain Indexes */
162+#define SM8350_CX 0
163+#define SM8350_CX_AO 1
164+#define SM8350_EBI 2
165+#define SM8350_GFX 3
166+#define SM8350_LCX 4
167+#define SM8350_LMX 5
168+#define SM8350_MMCX 6
169+#define SM8350_MMCX_AO 7
170+#define SM8350_MX 8
171+#define SM8350_MX_AO 9
172+#define SM8350_MXC 10
173+#define SM8350_MXC_AO 11
174+#define SM8350_MSS 12
175+
176+/* SM8450 Power Domain Indexes */
177+#define SM8450_CX 0
178+#define SM8450_CX_AO 1
179+#define SM8450_EBI 2
180+#define SM8450_GFX 3
181+#define SM8450_LCX 4
182+#define SM8450_LMX 5
183+#define SM8450_MMCX 6
184+#define SM8450_MMCX_AO 7
185+#define SM8450_MX 8
186+#define SM8450_MX_AO 9
187+#define SM8450_MXC 10
188+#define SM8450_MXC_AO 11
189+#define SM8450_MSS 12
190+
191+/* SM8550 Power Domain Indexes */
192+#define SM8550_CX 0
193+#define SM8550_CX_AO 1
194+#define SM8550_EBI 2
195+#define SM8550_GFX 3
196+#define SM8550_LCX 4
197+#define SM8550_LMX 5
198+#define SM8550_MMCX 6
199+#define SM8550_MMCX_AO 7
200+#define SM8550_MX 8
201+#define SM8550_MX_AO 9
202+#define SM8550_MXC 10
203+#define SM8550_MXC_AO 11
204+#define SM8550_MSS 12
205+#define SM8550_NSP 13
206+
207+/* QDU1000/QRU1000 Power Domain Indexes */
208+#define QDU1000_EBI 0
209+#define QDU1000_MSS 1
210+#define QDU1000_CX 2
211+#define QDU1000_MX 3
212+
213+/* SC7180 Power Domain Indexes */
214+#define SC7180_CX 0
215+#define SC7180_CX_AO 1
216+#define SC7180_GFX 2
217+#define SC7180_MX 3
218+#define SC7180_MX_AO 4
219+#define SC7180_LMX 5
220+#define SC7180_LCX 6
221+#define SC7180_MSS 7
222+
223+/* SC7280 Power Domain Indexes */
224+#define SC7280_CX 0
225+#define SC7280_CX_AO 1
226+#define SC7280_EBI 2
227+#define SC7280_GFX 3
228+#define SC7280_MX 4
229+#define SC7280_MX_AO 5
230+#define SC7280_LMX 6
231+#define SC7280_LCX 7
232+#define SC7280_MSS 8
233+
234+/* SC8180X Power Domain Indexes */
235+#define SC8180X_CX 0
236+#define SC8180X_CX_AO 1
237+#define SC8180X_EBI 2
238+#define SC8180X_GFX 3
239+#define SC8180X_LCX 4
240+#define SC8180X_LMX 5
241+#define SC8180X_MMCX 6
242+#define SC8180X_MMCX_AO 7
243+#define SC8180X_MSS 8
244+#define SC8180X_MX 9
245+#define SC8180X_MX_AO 10
246+
247+/* SC8280XP Power Domain Indexes */
248+#define SC8280XP_CX 0
249+#define SC8280XP_CX_AO 1
250+#define SC8280XP_DDR 2
251+#define SC8280XP_EBI 3
252+#define SC8280XP_GFX 4
253+#define SC8280XP_LCX 5
254+#define SC8280XP_LMX 6
255+#define SC8280XP_MMCX 7
256+#define SC8280XP_MMCX_AO 8
257+#define SC8280XP_MSS 9
258+#define SC8280XP_MX 10
259+#define SC8280XP_MXC 12
260+#define SC8280XP_MX_AO 11
261+#define SC8280XP_NSP 13
262+#define SC8280XP_QPHY 14
263+#define SC8280XP_XO 15
264+
32265 #endif
include/dt-bindings/power/qcom-rpmpd.h+92−299
@@ -4,258 +4,39 @@ · 3 unmodified lines
44 #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
55 #define _DT_BINDINGS_POWER_QCOM_RPMPD_H
66
7−/* SA8775P Power Domain Indexes */
8−#define SA8775P_CX 0
9−#define SA8775P_CX_AO 1
10−#define SA8775P_DDR 2
11−#define SA8775P_EBI 3
12−#define SA8775P_GFX 4
13−#define SA8775P_LCX 5
14−#define SA8775P_LMX 6
15−#define SA8775P_MMCX 7
16−#define SA8775P_MMCX_AO 8
17−#define SA8775P_MSS 9
18−#define SA8775P_MX 10
19−#define SA8775P_MX_AO 11
20−#define SA8775P_MXC 12
21−#define SA8775P_MXC_AO 13
22−#define SA8775P_NSP0 14
23−#define SA8775P_NSP1 15
24−#define SA8775P_XO 16
25−
26−/* SDM670 Power Domain Indexes */
27−#define SDM670_MX 0
28−#define SDM670_MX_AO 1
29−#define SDM670_CX 2
30−#define SDM670_CX_AO 3
31−#define SDM670_LMX 4
32−#define SDM670_LCX 5
33−#define SDM670_GFX 6
34−#define SDM670_MSS 7
35−
36−/* SDM845 Power Domain Indexes */
37−#define SDM845_EBI 0
38−#define SDM845_MX 1
39−#define SDM845_MX_AO 2
40−#define SDM845_CX 3
41−#define SDM845_CX_AO 4
42−#define SDM845_LMX 5
43−#define SDM845_LCX 6
44−#define SDM845_GFX 7
45−#define SDM845_MSS 8
46−
47−/* SDX55 Power Domain Indexes */
48−#define SDX55_MSS 0
49−#define SDX55_MX 1
50−#define SDX55_CX 2
51−
52−/* SDX65 Power Domain Indexes */
53−#define SDX65_MSS 0
54−#define SDX65_MX 1
55−#define SDX65_MX_AO 2
56−#define SDX65_CX 3
57−#define SDX65_CX_AO 4
58−#define SDX65_MXC 5
59−
60−/* SM6350 Power Domain Indexes */
61−#define SM6350_CX 0
62−#define SM6350_GFX 1
63−#define SM6350_LCX 2
64−#define SM6350_LMX 3
65−#define SM6350_MSS 4
66−#define SM6350_MX 5
67−
68−/* SM6375 Power Domain Indexes */
69−#define SM6375_VDDCX 0
70−#define SM6375_VDDCX_AO 1
71−#define SM6375_VDDCX_VFL 2
72−#define SM6375_VDDMX 3
73−#define SM6375_VDDMX_AO 4
74−#define SM6375_VDDMX_VFL 5
75−#define SM6375_VDDGX 6
76−#define SM6375_VDDGX_AO 7
77−#define SM6375_VDD_LPI_CX 8
78−#define SM6375_VDD_LPI_MX 9
79−
80−/* SM8150 Power Domain Indexes */
81−#define SM8150_MSS 0
82−#define SM8150_EBI 1
83−#define SM8150_LMX 2
84−#define SM8150_LCX 3
85−#define SM8150_GFX 4
86−#define SM8150_MX 5
87−#define SM8150_MX_AO 6
88−#define SM8150_CX 7
89−#define SM8150_CX_AO 8
90−#define SM8150_MMCX 9
91−#define SM8150_MMCX_AO 10
92−
93−/* SA8155P is a special case, kept for backwards compatibility */
94−#define SA8155P_CX SM8150_CX
95−#define SA8155P_CX_AO SM8150_CX_AO
96−#define SA8155P_EBI SM8150_EBI
97−#define SA8155P_GFX SM8150_GFX
98−#define SA8155P_MSS SM8150_MSS
99−#define SA8155P_MX SM8150_MX
100−#define SA8155P_MX_AO SM8150_MX_AO
101−
102−/* SM8250 Power Domain Indexes */
103−#define SM8250_CX 0
104−#define SM8250_CX_AO 1
105−#define SM8250_EBI 2
106−#define SM8250_GFX 3
107−#define SM8250_LCX 4
108−#define SM8250_LMX 5
109−#define SM8250_MMCX 6
110−#define SM8250_MMCX_AO 7
111−#define SM8250_MX 8
112−#define SM8250_MX_AO 9
113−
114−/* SM8350 Power Domain Indexes */
115−#define SM8350_CX 0
116−#define SM8350_CX_AO 1
117−#define SM8350_EBI 2
118−#define SM8350_GFX 3
119−#define SM8350_LCX 4
120−#define SM8350_LMX 5
121−#define SM8350_MMCX 6
122−#define SM8350_MMCX_AO 7
123−#define SM8350_MX 8
124−#define SM8350_MX_AO 9
125−#define SM8350_MXC 10
126−#define SM8350_MXC_AO 11
127−#define SM8350_MSS 12
128−
129−/* SM8450 Power Domain Indexes */
130−#define SM8450_CX 0
131−#define SM8450_CX_AO 1
132−#define SM8450_EBI 2
133−#define SM8450_GFX 3
134−#define SM8450_LCX 4
135−#define SM8450_LMX 5
136−#define SM8450_MMCX 6
137−#define SM8450_MMCX_AO 7
138−#define SM8450_MX 8
139−#define SM8450_MX_AO 9
140−#define SM8450_MXC 10
141−#define SM8450_MXC_AO 11
142−#define SM8450_MSS 12
143−
144−/* SM8550 Power Domain Indexes */
145−#define SM8550_CX 0
146−#define SM8550_CX_AO 1
147−#define SM8550_EBI 2
148−#define SM8550_GFX 3
149−#define SM8550_LCX 4
150−#define SM8550_LMX 5
151−#define SM8550_MMCX 6
152−#define SM8550_MMCX_AO 7
153−#define SM8550_MX 8
154−#define SM8550_MX_AO 9
155−#define SM8550_MXC 10
156−#define SM8550_MXC_AO 11
157−#define SM8550_MSS 12
158−#define SM8550_NSP 13
159−
160−/* QDU1000/QRU1000 Power Domain Indexes */
161−#define QDU1000_EBI 0
162−#define QDU1000_MSS 1
163−#define QDU1000_CX 2
164−#define QDU1000_MX 3
165−
166−/* SC7180 Power Domain Indexes */
167−#define SC7180_CX 0
168−#define SC7180_CX_AO 1
169−#define SC7180_GFX 2
170−#define SC7180_MX 3
171−#define SC7180_MX_AO 4
172−#define SC7180_LMX 5
173−#define SC7180_LCX 6
174−#define SC7180_MSS 7
175−
176−/* SC7280 Power Domain Indexes */
177−#define SC7280_CX 0
178−#define SC7280_CX_AO 1
179−#define SC7280_EBI 2
180−#define SC7280_GFX 3
181−#define SC7280_MX 4
182−#define SC7280_MX_AO 5
183−#define SC7280_LMX 6
184−#define SC7280_LCX 7
185−#define SC7280_MSS 8
186−
187−/* SC8180X Power Domain Indexes */
188−#define SC8180X_CX 0
189−#define SC8180X_CX_AO 1
190−#define SC8180X_EBI 2
191−#define SC8180X_GFX 3
192−#define SC8180X_LCX 4
193−#define SC8180X_LMX 5
194−#define SC8180X_MMCX 6
195−#define SC8180X_MMCX_AO 7
196−#define SC8180X_MSS 8
197−#define SC8180X_MX 9
198−#define SC8180X_MX_AO 10
199−
200−/* SC8280XP Power Domain Indexes */
201−#define SC8280XP_CX 0
202−#define SC8280XP_CX_AO 1
203−#define SC8280XP_DDR 2
204−#define SC8280XP_EBI 3
205−#define SC8280XP_GFX 4
206−#define SC8280XP_LCX 5
207−#define SC8280XP_LMX 6
208−#define SC8280XP_MMCX 7
209−#define SC8280XP_MMCX_AO 8
210−#define SC8280XP_MSS 9
211−#define SC8280XP_MX 10
212−#define SC8280XP_MXC 12
213−#define SC8280XP_MX_AO 11
214−#define SC8280XP_NSP 13
215−#define SC8280XP_QPHY 14
216−#define SC8280XP_XO 15
217−
218−/* SDM845 Power Domain performance levels */
219−#define RPMH_REGULATOR_LEVEL_RETENTION 16
220−#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
221−#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
222−#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
223−#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
224−#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
225−#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
226−#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
227−#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
228−#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
229−#define RPMH_REGULATOR_LEVEL_SVS 128
230−#define RPMH_REGULATOR_LEVEL_SVS_L0 144
231−#define RPMH_REGULATOR_LEVEL_SVS_L1 192
232−#define RPMH_REGULATOR_LEVEL_SVS_L2 224
233−#define RPMH_REGULATOR_LEVEL_NOM 256
234−#define RPMH_REGULATOR_LEVEL_NOM_L0 288
235−#define RPMH_REGULATOR_LEVEL_NOM_L1 320
236−#define RPMH_REGULATOR_LEVEL_NOM_L2 336
237−#define RPMH_REGULATOR_LEVEL_TURBO 384
238−#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
239−#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
240−#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
241−#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
242−#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
243−#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
244−#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
245−#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
7+#include <dt-bindings/power/qcom,rpmhpd.h>
8+
9+/* Generic RPM Power Domain Indexes */
10+#define RPMPD_VDDCX 0
11+#define RPMPD_VDDCX_AO 1
12+/* VFC and VFL are mutually exclusive and can not be present on the same platform */
13+#define RPMPD_VDDCX_VFC 2
14+#define RPMPD_VDDCX_VFL 2
15+#define RPMPD_VDDMX 3
16+#define RPMPD_VDDMX_AO 4
17+#define RPMPD_VDDMX_VFL 5
18+#define RPMPD_SSCCX 6
19+#define RPMPD_SSCCX_VFL 7
20+#define RPMPD_SSCMX 8
21+#define RPMPD_SSCMX_VFL 9
22+
23+/*
24+ * Platform-specific power domain bindings. Don't add new entries here, use
25+ * RPMPD_* above.
26+ */
24627
24728 /* MDM9607 Power Domains */
248−#define MDM9607_VDDCX 0
249−#define MDM9607_VDDCX_AO 1
250−#define MDM9607_VDDCX_VFL 2
251−#define MDM9607_VDDMX 3
252−#define MDM9607_VDDMX_AO 4
253−#define MDM9607_VDDMX_VFL 5
29+#define MDM9607_VDDCX RPMPD_VDDCX
30+#define MDM9607_VDDCX_AO RPMPD_VDDCX_AO
31+#define MDM9607_VDDCX_VFL RPMPD_VDDCX_VFL
32+#define MDM9607_VDDMX RPMPD_VDDMX
33+#define MDM9607_VDDMX_AO RPMPD_VDDMX_AO
34+#define MDM9607_VDDMX_VFL RPMPD_VDDMX_VFL
25435
25536 /* MSM8226 Power Domain Indexes */
256−#define MSM8226_VDDCX 0
257−#define MSM8226_VDDCX_AO 1
258−#define MSM8226_VDDCX_VFC 2
37+#define MSM8226_VDDCX RPMPD_VDDCX
38+#define MSM8226_VDDCX_AO RPMPD_VDDCX_AO
39+#define MSM8226_VDDCX_VFC RPMPD_VDDCX_VFC
25940
26041 /* MSM8939 Power Domains */
26142 #define MSM8939_VDDMDCX 0
@@ -268,11 +49,11 @@ · 6 unmodified lines
26849 #define MSM8939_VDDMX_AO 7
26950
27051 /* MSM8916 Power Domain Indexes */
271−#define MSM8916_VDDCX 0
272−#define MSM8916_VDDCX_AO 1
273−#define MSM8916_VDDCX_VFC 2
274−#define MSM8916_VDDMX 3
275−#define MSM8916_VDDMX_AO 4
52+#define MSM8916_VDDCX RPMPD_VDDCX
53+#define MSM8916_VDDCX_AO RPMPD_VDDCX_AO
54+#define MSM8916_VDDCX_VFC RPMPD_VDDCX_VFC
55+#define MSM8916_VDDMX RPMPD_VDDMX
56+#define MSM8916_VDDMX_AO RPMPD_VDDMX_AO
27657
27758 /* MSM8909 Power Domain Indexes */
27859 #define MSM8909_VDDCX MSM8916_VDDCX
@@ -282,11 +63,11 @@ · 3 unmodified lines
28263 #define MSM8909_VDDMX_AO MSM8916_VDDMX_AO
28364
28465 /* MSM8917 Power Domain Indexes */
285−#define MSM8917_VDDCX 0
286−#define MSM8917_VDDCX_AO 1
287−#define MSM8917_VDDCX_VFL 2
288−#define MSM8917_VDDMX 3
289−#define MSM8917_VDDMX_AO 4
66+#define MSM8917_VDDCX RPMPD_VDDCX
67+#define MSM8917_VDDCX_AO RPMPD_VDDCX_AO
68+#define MSM8917_VDDCX_VFL RPMPD_VDDCX_VFL
69+#define MSM8917_VDDMX RPMPD_VDDMX
70+#define MSM8917_VDDMX_AO RPMPD_VDDMX_AO
29071
29172 /* MSM8937 Power Domain Indexes */
29273 #define MSM8937_VDDCX MSM8917_VDDCX
@@ -319,12 +100,12 @@ · 26 unmodified lines
319100 #define MSM8974_VDDGFX_VFC 4
320101
321102 /* MSM8976 Power Domain Indexes */
322−#define MSM8976_VDDCX 0
323−#define MSM8976_VDDCX_AO 1
324−#define MSM8976_VDDCX_VFL 2
325−#define MSM8976_VDDMX 3
326−#define MSM8976_VDDMX_AO 4
327−#define MSM8976_VDDMX_VFL 5
103+#define MSM8976_VDDCX RPMPD_VDDCX
104+#define MSM8976_VDDCX_AO RPMPD_VDDCX_AO
105+#define MSM8976_VDDCX_VFL RPMPD_VDDCX_VFL
106+#define MSM8976_VDDMX RPMPD_VDDMX
107+#define MSM8976_VDDMX_AO RPMPD_VDDMX_AO
108+#define MSM8976_VDDMX_VFL RPMPD_VDDMX_VFL
328109
329110 /* MSM8994 Power Domain Indexes */
330111 #define MSM8994_VDDCX 0
@@ -345,16 +126,26 @@ · 14 unmodified lines
345126 #define MSM8996_VDDSSCX_VFC 6
346127
347128 /* MSM8998 Power Domain Indexes */
348−#define MSM8998_VDDCX 0
349−#define MSM8998_VDDCX_AO 1
350−#define MSM8998_VDDCX_VFL 2
351−#define MSM8998_VDDMX 3
352−#define MSM8998_VDDMX_AO 4
353−#define MSM8998_VDDMX_VFL 5
354−#define MSM8998_SSCCX 6
355−#define MSM8998_SSCCX_VFL 7
356−#define MSM8998_SSCMX 8
357−#define MSM8998_SSCMX_VFL 9
129+#define MSM8998_VDDCX RPMPD_VDDCX
130+#define MSM8998_VDDCX_AO RPMPD_VDDCX_AO
131+#define MSM8998_VDDCX_VFL RPMPD_VDDCX_VFL
132+#define MSM8998_VDDMX RPMPD_VDDMX
133+#define MSM8998_VDDMX_AO RPMPD_VDDMX_AO
134+#define MSM8998_VDDMX_VFL RPMPD_VDDMX_VFL
135+#define MSM8998_SSCCX RPMPD_SSCCX
136+#define MSM8998_SSCCX_VFL RPMPD_SSCCX_VFL
137+#define MSM8998_SSCMX RPMPD_SSCMX
138+#define MSM8998_SSCMX_VFL RPMPD_SSCMX_VFL
139+
140+/* QCM2290 Power Domains */
141+#define QCM2290_VDDCX 0
142+#define QCM2290_VDDCX_AO 1
143+#define QCM2290_VDDCX_VFL 2
144+#define QCM2290_VDDMX 3
145+#define QCM2290_VDDMX_AO 4
146+#define QCM2290_VDDMX_VFL 5
147+#define QCM2290_VDD_LPI_CX 6
148+#define QCM2290_VDD_LPI_MX 7
358149
359150 /* QCS404 Power Domains */
360151 #define QCS404_VDDMX 0
@@ -366,16 +157,16 @@ · 5 unmodified lines
366157 #define QCS404_LPIMX_VFL 6
367158
368159 /* SDM660 Power Domains */
369−#define SDM660_VDDCX 0
370−#define SDM660_VDDCX_AO 1
371−#define SDM660_VDDCX_VFL 2
372−#define SDM660_VDDMX 3
373−#define SDM660_VDDMX_AO 4
374−#define SDM660_VDDMX_VFL 5
375−#define SDM660_SSCCX 6
376−#define SDM660_SSCCX_VFL 7
377−#define SDM660_SSCMX 8
378−#define SDM660_SSCMX_VFL 9
160+#define SDM660_VDDCX RPMPD_VDDCX
161+#define SDM660_VDDCX_AO RPMPD_VDDCX_AO
162+#define SDM660_VDDCX_VFL RPMPD_VDDCX_VFL
163+#define SDM660_VDDMX RPMPD_VDDMX
164+#define SDM660_VDDMX_AO RPMPD_VDDMX_AO
165+#define SDM660_VDDMX_VFL RPMPD_VDDMX_VFL
166+#define SDM660_SSCCX RPMPD_SSCCX
167+#define SDM660_SSCCX_VFL RPMPD_SSCCX_VFL
168+#define SDM660_SSCMX RPMPD_SSCMX
169+#define SDM660_SSCMX_VFL RPMPD_SSCMX_VFL
379170
380171 /* SM6115 Power Domains */
381172 #define SM6115_VDDCX 0
@@ -388,22 +179,24 @@ · 6 unmodified lines
388179 #define SM6115_VDD_LPI_MX 7
389180
390181 /* SM6125 Power Domains */
391−#define SM6125_VDDCX 0
392−#define SM6125_VDDCX_AO 1
393−#define SM6125_VDDCX_VFL 2
394−#define SM6125_VDDMX 3
395−#define SM6125_VDDMX_AO 4
396−#define SM6125_VDDMX_VFL 5
182+#define SM6125_VDDCX RPMPD_VDDCX
183+#define SM6125_VDDCX_AO RPMPD_VDDCX_AO
184+#define SM6125_VDDCX_VFL RPMPD_VDDCX_VFL
185+#define SM6125_VDDMX RPMPD_VDDMX
186+#define SM6125_VDDMX_AO RPMPD_VDDMX_AO
187+#define SM6125_VDDMX_VFL RPMPD_VDDMX_VFL
397188
398−/* QCM2290 Power Domains */
399−#define QCM2290_VDDCX 0
400−#define QCM2290_VDDCX_AO 1
401−#define QCM2290_VDDCX_VFL 2
402−#define QCM2290_VDDMX 3
403−#define QCM2290_VDDMX_AO 4
404−#define QCM2290_VDDMX_VFL 5
405−#define QCM2290_VDD_LPI_CX 6
406−#define QCM2290_VDD_LPI_MX 7
189+/* SM6375 Power Domain Indexes */
190+#define SM6375_VDDCX 0
191+#define SM6375_VDDCX_AO 1
192+#define SM6375_VDDCX_VFL 2
193+#define SM6375_VDDMX 3
194+#define SM6375_VDDMX_AO 4
195+#define SM6375_VDDMX_VFL 5
196+#define SM6375_VDDGX 6
197+#define SM6375_VDDGX_AO 7
198+#define SM6375_VDD_LPI_CX 8
199+#define SM6375_VDD_LPI_MX 9
407200
408201 /* RPM SMD Power Domain performance levels */
409202 #define RPM_SMD_LEVEL_RETENTION 16

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t