History

Merge tag 'arm-drivers-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM driver updates from Arnd Bergmann: "There are a few separately maintained driver subsystems that we merge through the SoC tree, notable changes are: - Memory controller updates, mainly for Tegra and Mediatek SoCs, and clarifications for the memory controller DT bindings - SCMI firmware interface updates, in particular a new transport based on OPTEE and support for atomic operations. - Cleanups to the TEE subsystem, refactoring its memory management For SoC specific drivers without a separate subsystem, changes include - Smaller updates and fixes for TI, AT91/SAMA5, Qualcomm and NXP Layerscape SoCs. - Driver support for Microchip SAMA5D29, Tesla FSD, Renesas RZ/G2L, and Qualcomm SM8450. - Better power management on Mediatek MT81xx, NXP i.MX8MQ and older NVIDIA Tegra chips" * tag 'arm-drivers-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (154 commits) ARM: spear: fix typos in comments soc/microchip: fix invalid free in mpfs_sys_controller_delete soc: s4: Add support for power domains controller dt-bindings: power: add Amlogic s4 power domains bindings ARM: at91: add support in soc driver for new SAMA5D29 soc: mediatek: mmsys: add sw0_rst_offset in mmsys driver data dt-bindings: memory: renesas,rpc-if: Document RZ/V2L SoC memory: emif: check the pointer temp in get_device_details() memory: emif: Add check for setup_interrupts dt-bindings: arm: mediatek: mmsys: add support for MT8186 dt-bindings: mediatek: add compatible for MT8186 pwrap soc: mediatek: pwrap: add pwrap driver for MT8186 SoC soc: mediatek: mmsys: add mmsys reset control for MT8186 soc: mediatek: mtk-infracfg: Disable ACP on MT8192 soc: ti: k3-socinfo: Add AM62x JTAG ID soc: mediatek: add MTK mutex support for MT8186 soc: mediatek: mmsys: add mt8186 mmsys routing table soc: mediatek: pm-domains: Add support for mt8186 dt-bindings: power: Add MT8186 power domains soc: mediatek: pm-domains: Add support for mt8195 ...

Linus Torvalds committed 4 years ago

Commit b4bc93b2 parents baaa68a 339ac71124 files · +7628 −1419Browse files

Unified · Split

124 files
  1. Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml +1 −0
  2. Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml +2 −0
  3. Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml +198 −0
  4. Documentation/devicetree/bindings/firmware/arm,scmi.yaml +75 −0
  5. Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml +135 −0
  6. Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml +17 −6
  7. Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml +157 −0
  8. Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml +263 −0
  9. Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt +0 −52
  10. Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt +0 −58
  11. Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt +0 −107
  12. Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml +113 −0
  13. Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt +0 −82
  14. Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml +15 −17
  15. Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml +10 −9
  16. Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml +2 −1
  17. Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml +1 −2
  18. Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml +2 −1
  19. Documentation/devicetree/bindings/power/mediatek,power-controller.yaml +3 −0
  20. Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +1 −0
  21. Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +16 −0
  22. Documentation/devicetree/bindings/soc/mediatek/pwrap.txt +1 −0
  23. arch/arm/mach-qcom/platsmp.c +1 −2
  24. arch/arm/mach-spear/spear13xx.c +1 −1
  25. drivers/bus/imx-weim.c +126 −9
  26. drivers/char/hw_random/optee-rng.c +3 −3
  27. drivers/clk/clk-scmi.c +60 −11
  28. drivers/clk/samsung/Kconfig +9 −0
  29. drivers/clk/samsung/Makefile +1 −0
  30. drivers/clk/samsung/clk-fsd.c +1803 −0
  31. drivers/clk/samsung/clk-pll.c +1 −0
  32. drivers/clk/samsung/clk-pll.h +1 −0
  33. drivers/cpuidle/cpuidle-qcom-spm.c +24 −4
  34. drivers/firmware/arm_scmi/Kconfig +56 −0
  35. drivers/firmware/arm_scmi/Makefile +8 −0
  36. drivers/firmware/arm_scmi/clock.c +28 −6
  37. drivers/firmware/arm_scmi/common.h +25 −1
  38. drivers/firmware/arm_scmi/driver.c +191 −43
  39. drivers/firmware/arm_scmi/mailbox.c +2 −1
  40. drivers/firmware/arm_scmi/optee.c +567 −0
  41. drivers/firmware/arm_scmi/smc.c +72 −26
  42. drivers/firmware/arm_scmi/virtio.c +517 −96
  43. drivers/firmware/imx/rm.c +45 −0
  44. drivers/firmware/imx/scu-pd.c +4 −0
  45. drivers/firmware/qcom_scm.c +119 −96
  46. drivers/firmware/qcom_scm.h +7 −0
  47. drivers/firmware/ti_sci.c +1 −1
  48. drivers/memory/brcmstb_dpfe.c +1 −1
  49. drivers/memory/emif.c +5 −3
  50. drivers/memory/fsl_ifc.c +9 −0
  51. drivers/memory/mtk-smi.c +53 −4
  52. drivers/memory/of_memory.c +19 −10
  53. drivers/memory/tegra/Kconfig +1 −0
  54. drivers/memory/tegra/tegra20-emc.c +1 −1
  55. drivers/memory/tegra/tegra210-emc-core.c +1 −1
  56. drivers/memory/tegra/tegra30-emc.c +121 −10
  57. drivers/remoteproc/qcom_q6v5_mss.c +4 −3
  58. drivers/remoteproc/qcom_q6v5_pas.c +33 −3
  59. drivers/soc/amlogic/meson-secure-pwrc.c +22 −0
  60. drivers/soc/atmel/soc.c +3 −0
  61. drivers/soc/atmel/soc.h +1 −0
  62. drivers/soc/imx/imx8m-blk-ctrl.c +66 −0
  63. drivers/soc/imx/soc-imx.c +0 −3
  64. drivers/soc/mediatek/mt8167-pm-domains.h +14 −2
  65. drivers/soc/mediatek/mt8173-pm-domains.h +20 −2
  66. drivers/soc/mediatek/mt8183-mmsys.h +2 −0
  67. drivers/soc/mediatek/mt8183-pm-domains.h +30 −2
  68. drivers/soc/mediatek/mt8186-mmsys.h +115 −0
  69. drivers/soc/mediatek/mt8186-pm-domains.h +344 −0
  70. drivers/soc/mediatek/mt8192-pm-domains.h +42 −2
  71. drivers/soc/mediatek/mt8195-pm-domains.h +613 −0
  72. drivers/soc/mediatek/mtk-infracfg.c +19 −0
  73. drivers/soc/mediatek/mtk-mmsys.c +16 −2
  74. drivers/soc/mediatek/mtk-mmsys.h +1 −2
  75. drivers/soc/mediatek/mtk-mutex.c +45 −0
  76. drivers/soc/mediatek/mtk-pm-domains.c +15 −2
  77. drivers/soc/mediatek/mtk-pm-domains.h +3 −5
  78. drivers/soc/mediatek/mtk-pmic-wrap.c +71 −0
  79. drivers/soc/microchip/mpfs-sys-controller.c +8 −5
  80. drivers/soc/qcom/apr.c +0 −1
  81. drivers/soc/qcom/llcc-qcom.c +91 −16
  82. drivers/soc/qcom/mdt_loader.c +151 −81
  83. drivers/soc/qcom/ocmem.c +1 −0
  84. drivers/soc/qcom/qcom_aoss.c +6 −2
  85. drivers/soc/qcom/rpmpd.c +20 −0
  86. drivers/soc/qcom/socinfo.c +12 −0
  87. drivers/soc/renesas/Kconfig +12 −0
  88. drivers/soc/renesas/renesas-soc.c +46 −22
  89. drivers/soc/tegra/fuse/fuse-tegra.c +21 −3
  90. drivers/soc/tegra/pmc.c +11 −5
  91. drivers/soc/ti/k3-ringacc.c +6 −9
  92. drivers/soc/ti/k3-socinfo.c +1 −0
  93. drivers/soc/ti/smartreflex.c +7 −6
  94. drivers/soc/ti/wkup_m3_ipc.c +2 −2
  95. drivers/tee/amdtee/call.c +1 −1
  96. drivers/tee/amdtee/shm_pool.c +16 −39
  97. drivers/tee/optee/Kconfig +0 −8
  98. drivers/tee/optee/call.c +1 −1
  99. drivers/tee/optee/core.c +17 −4
  100. drivers/tee/optee/device.c +2 −3
  101. drivers/tee/optee/ffa_abi.c +17 −46
  102. drivers/tee/optee/optee_private.h +5 −2
  103. drivers/tee/optee/smc_abi.c +37 −88
  104. drivers/tee/tee_core.c +2 −3
  105. drivers/tee/tee_private.h +4 −11
  106. drivers/tee/tee_shm.c +210 −110
  107. drivers/tee/tee_shm_pool.c +34 −128
  108. include/dt-bindings/clock/fsd-clk.h +150 −0
  109. include/dt-bindings/power/imx8mq-power.h +3 −0
  110. include/dt-bindings/power/meson-s4-power.h +19 −0
  111. include/dt-bindings/power/mt8186-power.h +32 −0
  112. include/dt-bindings/power/mt8195-power.h +46 −0
  113. include/dt-bindings/power/qcom-rpmpd.h +5 −0
  114. include/linux/firmware/imx/svc/rm.h +5 −0
  115. include/linux/qcom_scm.h +13 −3
  116. include/linux/scmi_protocol.h +15 −0
  117. include/linux/soc/mediatek/infracfg.h +133 −0
  118. include/linux/soc/qcom/llcc-qcom.h +7 −2
  119. include/linux/soc/qcom/mdt_loader.h +15 −2
  120. include/linux/soc/ti/ti_sci_protocol.h +1 −1
  121. include/linux/tee_drv.h +31 −107
  122. include/soc/tegra/bpmp-abi.h +1 −1
  123. include/trace/events/scmi.h +28 −0
  124. security/keys/trusted-keys/trusted_tee.c +9 −14
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml+1−0
@@ -29,6 +29,7 @@ properties: · 28 unmodified lines
2929 - mediatek,mt8167-mmsys
3030 - mediatek,mt8173-mmsys
3131 - mediatek,mt8183-mmsys
32+ - mediatek,mt8186-mmsys
3233 - mediatek,mt8192-mmsys
3334 - mediatek,mt8365-mmsys
3435 - const: syscon
Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml+2−0
@@ -27,6 +27,8 @@ properties: · 26 unmodified lines
2727 - qcom,sm6350-llcc
2828 - qcom,sm8150-llcc
2929 - qcom,sm8250-llcc
30+ - qcom,sm8350-llcc
31+ - qcom,sm8450-llcc
3032
3133 reg:
3234 items:
Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml+198−0
@@ -0,0 +1,198 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: Tesla FSD (Full Self-Driving) SoC clock controller
8+
9+maintainers:
10+ - Alim Akhtar <alim.akhtar@samsung.com>
11+ - linux-fsd@tesla.com
12+
13+description: |
14+ FSD clock controller consist of several clock management unit
15+ (CMU), which generates clocks for various inteernal SoC blocks.
16+ The root clock comes from external OSC clock (24 MHz).
17+
18+ All available clocks are defined as preprocessor macros in
19+ 'dt-bindings/clock/fsd-clk.h' header.
20+
21+properties:
22+ compatible:
23+ enum:
24+ - tesla,fsd-clock-cmu
25+ - tesla,fsd-clock-imem
26+ - tesla,fsd-clock-peric
27+ - tesla,fsd-clock-fsys0
28+ - tesla,fsd-clock-fsys1
29+ - tesla,fsd-clock-mfc
30+ - tesla,fsd-clock-cam_csi
31+
32+ clocks:
33+ minItems: 1
34+ maxItems: 6
35+
36+ clock-names:
37+ minItems: 1
38+ maxItems: 6
39+
40+ "#clock-cells":
41+ const: 1
42+
43+ reg:
44+ maxItems: 1
45+
46+allOf:
47+ - if:
48+ properties:
49+ compatible:
50+ contains:
51+ const: tesla,fsd-clock-cmu
52+ then:
53+ properties:
54+ clocks:
55+ items:
56+ - description: External reference clock (24 MHz)
57+ clock-names:
58+ items:
59+ - const: fin_pll
60+
61+ - if:
62+ properties:
63+ compatible:
64+ contains:
65+ const: tesla,fsd-clock-imem
66+ then:
67+ properties:
68+ clocks:
69+ items:
70+ - description: External reference clock (24 MHz)
71+ - description: IMEM TCU clock (from CMU_CMU)
72+ - description: IMEM bus clock (from CMU_CMU)
73+ - description: IMEM DMA clock (from CMU_CMU)
74+ clock-names:
75+ items:
76+ - const: fin_pll
77+ - const: dout_cmu_imem_tcuclk
78+ - const: dout_cmu_imem_aclk
79+ - const: dout_cmu_imem_dmaclk
80+
81+ - if:
82+ properties:
83+ compatible:
84+ contains:
85+ const: tesla,fsd-clock-peric
86+ then:
87+ properties:
88+ clocks:
89+ items:
90+ - description: External reference clock (24 MHz)
91+ - description: Shared0 PLL div4 clock (from CMU_CMU)
92+ - description: PERIC shared1 div36 clock (from CMU_CMU)
93+ - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
94+ - description: PERIC shared0 div20 clock (from CMU_CMU)
95+ - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
96+ clock-names:
97+ items:
98+ - const: fin_pll
99+ - const: dout_cmu_pll_shared0_div4
100+ - const: dout_cmu_peric_shared1div36
101+ - const: dout_cmu_peric_shared0div3_tbuclk
102+ - const: dout_cmu_peric_shared0div20
103+ - const: dout_cmu_peric_shared1div4_dmaclk
104+
105+ - if:
106+ properties:
107+ compatible:
108+ contains:
109+ const: tesla,fsd-clock-fsys0
110+ then:
111+ properties:
112+ clocks:
113+ items:
114+ - description: External reference clock (24 MHz)
115+ - description: Shared0 PLL div6 clock (from CMU_CMU)
116+ - description: FSYS0 shared1 div4 clock (from CMU_CMU)
117+ - description: FSYS0 shared0 div4 clock (from CMU_CMU)
118+ clock-names:
119+ items:
120+ - const: fin_pll
121+ - const: dout_cmu_pll_shared0_div6
122+ - const: dout_cmu_fsys0_shared1div4
123+ - const: dout_cmu_fsys0_shared0div4
124+
125+ - if:
126+ properties:
127+ compatible:
128+ contains:
129+ const: tesla,fsd-clock-fsys1
130+ then:
131+ properties:
132+ clocks:
133+ items:
134+ - description: External reference clock (24 MHz)
135+ - description: FSYS1 shared0 div8 clock (from CMU_CMU)
136+ - description: FSYS1 shared0 div4 clock (from CMU_CMU)
137+ clock-names:
138+ items:
139+ - const: fin_pll
140+ - const: dout_cmu_fsys1_shared0div8
141+ - const: dout_cmu_fsys1_shared0div4
142+
143+ - if:
144+ properties:
145+ compatible:
146+ contains:
147+ const: tesla,fsd-clock-mfc
148+ then:
149+ properties:
150+ clocks:
151+ items:
152+ - description: External reference clock (24 MHz)
153+ clock-names:
154+ items:
155+ - const: fin_pll
156+
157+ - if:
158+ properties:
159+ compatible:
160+ contains:
161+ const: tesla,fsd-clock-cam_csi
162+ then:
163+ properties:
164+ clocks:
165+ items:
166+ - description: External reference clock (24 MHz)
167+ clock-names:
168+ items:
169+ - const: fin_pll
170+
171+required:
172+ - compatible
173+ - "#clock-cells"
174+ - clocks
175+ - clock-names
176+ - reg
177+
178+additionalProperties: false
179+
180+examples:
181+ # Clock controller node for CMU_FSYS1
182+ - |
183+ #include <dt-bindings/clock/fsd-clk.h>
184+
185+ clock_fsys1: clock-controller@16810000 {
186+ compatible = "tesla,fsd-clock-fsys1";
187+ reg = <0x16810000 0x3000>;
188+ #clock-cells = <1>;
189+
190+ clocks = <&fin_pll>,
191+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
192+ <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
193+ clock-names = "fin_pll",
194+ "dout_cmu_fsys1_shared0div8",
195+ "dout_cmu_fsys1_shared0div4";
196+ };
197+
198+...
Documentation/devicetree/bindings/firmware/arm,scmi.yaml+75−0
@@ -38,6 +38,9 @@ properties: · 37 unmodified lines
3838 The virtio transport only supports a single device.
3939 items:
4040 - const: arm,scmi-virtio
41+ - description: SCMI compliant firmware with OP-TEE transport
42+ items:
43+ - const: linaro,scmi-optee
4144
4245 interrupts:
4346 description:
@@ -78,11 +81,24 @@ properties: · 34 unmodified lines
7881 '#size-cells':
7982 const: 0
8083
84+ atomic-threshold-us:
85+ description:
86+ An optional time value, expressed in microseconds, representing, on this
87+ platform, the threshold above which any SCMI command, advertised to have
88+ an higher-than-threshold execution latency, should not be considered for
89+ atomic mode of operation, even if requested.
90+ default: 0
91+
8192 arm,smc-id:
8293 $ref: /schemas/types.yaml#/definitions/uint32
8394 description:
8495 SMC id required when using smc or hvc transports
8596
97+ linaro,optee-channel-id:
98+ $ref: /schemas/types.yaml#/definitions/uint32
99+ description:
100+ Channel specifier required when using OP-TEE transport.
101+
86102 protocol@11:
87103 type: object
88104 properties:
@@ -195,6 +211,12 @@ patternProperties: · 106 unmodified lines
195211 minItems: 1
196212 maxItems: 2
197213
214+ linaro,optee-channel-id:
215+ $ref: /schemas/types.yaml#/definitions/uint32
216+ description:
217+ Channel specifier required when using OP-TEE transport and
218+ protocol has a dedicated communication channel.
219+
198220 required:
199221 - reg
200222
@@ -226,6 +248,16 @@ else: · 25 unmodified lines
226248 - arm,smc-id
227249 - shmem
228250
251+ else:
252+ if:
253+ properties:
254+ compatible:
255+ contains:
256+ const: linaro,scmi-optee
257+ then:
258+ required:
259+ - linaro,optee-channel-id
260+
229261 examples:
230262 - |
231263 firmware {
@@ -240,6 +272,8 @@ examples: · 8 unmodified lines
240272 #address-cells = <1>;
241273 #size-cells = <0>;
242274
275+ atomic-threshold-us = <10000>;
276+
243277 scmi_devpd: protocol@11 {
244278 reg = <0x11>;
245279 #power-domain-cells = <1>;
@@ -340,7 +374,48 @@ examples: · 94 unmodified lines
340374 reg = <0x11>;
341375 #power-domain-cells = <1>;
342376 };
377+ };
378+ };
379+
380+ - |
381+ firmware {
382+ scmi {
383+ compatible = "linaro,scmi-optee";
384+ linaro,optee-channel-id = <0>;
343385
386+ #address-cells = <1>;
387+ #size-cells = <0>;
388+
389+ scmi_dvfs1: protocol@13 {
390+ reg = <0x13>;
391+ linaro,optee-channel-id = <1>;
392+ shmem = <&cpu_optee_lpri0>;
393+ #clock-cells = <1>;
394+ };
395+
396+ scmi_clk0: protocol@14 {
397+ reg = <0x14>;
398+ #clock-cells = <1>;
399+ };
400+ };
401+ };
402+
403+ soc {
404+ #address-cells = <2>;
405+ #size-cells = <2>;
406+
407+ sram@51000000 {
408+ compatible = "mmio-sram";
409+ reg = <0x0 0x51000000 0x0 0x10000>;
410+
411+ #address-cells = <1>;
412+ #size-cells = <1>;
413+ ranges = <0 0x0 0x51000000 0x10000>;
414+
415+ cpu_optee_lpri0: optee-sram-section@0 {
416+ compatible = "arm,scmi-shmem";
417+ reg = <0x0 0x80>;
418+ };
344419 };
345420 };
346421
Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2-timings.yaml+135−0
@@ -0,0 +1,135 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr2-timings.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: LPDDR2 SDRAM AC timing parameters for a given speed-bin
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11+
12+properties:
13+ compatible:
14+ const: jedec,lpddr2-timings
15+
16+ max-freq:
17+ $ref: /schemas/types.yaml#/definitions/uint32
18+ description: |
19+ Maximum DDR clock frequency for the speed-bin, in Hz.
20+
21+ min-freq:
22+ $ref: /schemas/types.yaml#/definitions/uint32
23+ description: |
24+ Minimum DDR clock frequency for the speed-bin, in Hz.
25+
26+ tCKESR:
27+ $ref: /schemas/types.yaml#/definitions/uint32
28+ description: |
29+ CKE minimum pulse width during SELF REFRESH (low pulse width during
30+ SELF REFRESH) in pico seconds.
31+
32+ tDQSCK-max:
33+ $ref: /schemas/types.yaml#/definitions/uint32
34+ description: |
35+ DQS output data access time from CK_t/CK_c in pico seconds.
36+
37+ tDQSCK-max-derated:
38+ $ref: /schemas/types.yaml#/definitions/uint32
39+ description: |
40+ DQS output data access time from CK_t/CK_c, temperature de-rated, in pico
41+ seconds.
42+
43+ tFAW:
44+ $ref: /schemas/types.yaml#/definitions/uint32
45+ description: |
46+ Four-bank activate window in pico seconds.
47+
48+ tRAS-max-ns:
49+ description: |
50+ Row active time in nano seconds.
51+
52+ tRAS-min:
53+ $ref: /schemas/types.yaml#/definitions/uint32
54+ description: |
55+ Row active time in pico seconds.
56+
57+ tRCD:
58+ $ref: /schemas/types.yaml#/definitions/uint32
59+ description: |
60+ RAS-to-CAS delay in pico seconds.
61+
62+ tRPab:
63+ $ref: /schemas/types.yaml#/definitions/uint32
64+ description: |
65+ Row precharge time (all banks) in pico seconds.
66+
67+ tRRD:
68+ $ref: /schemas/types.yaml#/definitions/uint32
69+ description: |
70+ Active bank A to active bank B in pico seconds.
71+
72+ tRTP:
73+ $ref: /schemas/types.yaml#/definitions/uint32
74+ description: |
75+ Internal READ to PRECHARGE command delay in pico seconds.
76+
77+ tWR:
78+ $ref: /schemas/types.yaml#/definitions/uint32
79+ description: |
80+ WRITE recovery time in pico seconds.
81+
82+ tWTR:
83+ $ref: /schemas/types.yaml#/definitions/uint32
84+ description: |
85+ Internal WRITE-to-READ command delay in pico seconds.
86+
87+ tXP:
88+ $ref: /schemas/types.yaml#/definitions/uint32
89+ description: |
90+ Exit power-down to next valid command delay in pico seconds.
91+
92+ tZQCL:
93+ $ref: /schemas/types.yaml#/definitions/uint32
94+ description: |
95+ Long calibration time in pico seconds.
96+
97+ tZQCS:
98+ $ref: /schemas/types.yaml#/definitions/uint32
99+ description: |
100+ Short calibration time in pico seconds.
101+
102+ tZQinit:
103+ $ref: /schemas/types.yaml#/definitions/uint32
104+ description: |
105+ Initialization calibration time in pico seconds.
106+
107+required:
108+ - compatible
109+ - min-freq
110+ - max-freq
111+
112+additionalProperties: false
113+
114+examples:
115+ - |
116+ timings {
117+ compatible = "jedec,lpddr2-timings";
118+ min-freq = <10000000>;
119+ max-freq = <400000000>;
120+ tCKESR = <15000>;
121+ tDQSCK-max = <5500>;
122+ tFAW = <50000>;
123+ tRAS-max-ns = <70000>;
124+ tRAS-min = <42000>;
125+ tRPab = <21000>;
126+ tRCD = <18000>;
127+ tRRD = <10000>;
128+ tRTP = <7500>;
129+ tWR = <15000>;
130+ tWTR = <7500>;
131+ tXP = <7500>;
132+ tZQCL = <360000>;
133+ tZQCS = <90000>;
134+ tZQinit = <1000000>;
135+ };
Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr2.yaml+17−6
@@ -30,12 +30,26 @@ properties: · 29 unmodified lines
3030 maximum: 255
3131 description: |
3232 Revision 1 value of SDRAM chip. Obtained from device datasheet.
33+ Property is deprecated, use revision-id instead.
34+ deprecated: true
3335
3436 revision-id2:
3537 $ref: /schemas/types.yaml#/definitions/uint32
3638 maximum: 255
3739 description: |
3840 Revision 2 value of SDRAM chip. Obtained from device datasheet.
41+ Property is deprecated, use revision-id instead.
42+ deprecated: true
43+
44+ revision-id:
45+ $ref: /schemas/types.yaml#/definitions/uint32-array
46+ description: |
47+ Revision IDs read from Mode Register 6 and 7. One byte per uint32 cell (i.e. <MR6 MR7>).
48+ minItems: 2
49+ maxItems: 2
50+ items:
51+ minimum: 0
52+ maximum: 255
3953
4054 density:
4155 $ref: /schemas/types.yaml#/definitions/uint32
@@ -142,14 +156,12 @@ properties: · 100 unmodified lines
142156
143157 patternProperties:
144158 "^lpddr2-timings":
145− type: object
159+ $ref: jedec,lpddr2-timings.yaml
146160 description: |
147161 The lpddr2 node may have one or more child nodes of type "lpddr2-timings".
148162 "lpddr2-timings" provides AC timing parameters of the device for
149163 a given speed-bin. The user may provide the timings for as many
150− speed-bins as is required. Please see Documentation/devicetree/
151− bindings/memory-controllers/ddr/lpddr2-timings.txt for more information
152− on "lpddr2-timings".
164+ speed-bins as is required.
153165
154166 required:
155167 - compatible
@@ -164,8 +176,7 @@ examples: · 8 unmodified lines
164176 compatible = "elpida,ECB240ABACN", "jedec,lpddr2-s4";
165177 density = <2048>;
166178 io-width = <32>;
167− revision-id1 = <1>;
168− revision-id2 = <0>;
179+ revision-id = <1 0>;
169180
170181 tRPab-min-tck = <3>;
171182 tRCD-min-tck = <3>;
Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3-timings.yaml+157−0
@@ -0,0 +1,157 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3-timings.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: LPDDR3 SDRAM AC timing parameters for a given speed-bin
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11+
12+properties:
13+ compatible:
14+ const: jedec,lpddr3-timings
15+
16+ reg:
17+ maxItems: 1
18+ description: |
19+ Maximum DDR clock frequency for the speed-bin, in Hz.
20+ Property is deprecated, use max-freq.
21+ deprecated: true
22+
23+ max-freq:
24+ $ref: /schemas/types.yaml#/definitions/uint32
25+ description: |
26+ Maximum DDR clock frequency for the speed-bin, in Hz.
27+
28+ min-freq:
29+ $ref: /schemas/types.yaml#/definitions/uint32
30+ description: |
31+ Minimum DDR clock frequency for the speed-bin, in Hz.
32+
33+ tCKE:
34+ $ref: /schemas/types.yaml#/definitions/uint32
35+ description: |
36+ CKE minimum pulse width (HIGH and LOW pulse width) in pico seconds.
37+
38+ tCKESR:
39+ $ref: /schemas/types.yaml#/definitions/uint32
40+ description: |
41+ CKE minimum pulse width during SELF REFRESH (low pulse width during
42+ SELF REFRESH) in pico seconds.
43+
44+ tFAW:
45+ $ref: /schemas/types.yaml#/definitions/uint32
46+ description: |
47+ Four-bank activate window in pico seconds.
48+
49+ tMRD:
50+ $ref: /schemas/types.yaml#/definitions/uint32
51+ description: |
52+ Mode register set command delay in pico seconds.
53+
54+ tR2R-C2C:
55+ $ref: /schemas/types.yaml#/definitions/uint32
56+ description: |
57+ Additional READ-to-READ delay in chip-to-chip cases in pico seconds.
58+
59+ tRAS:
60+ $ref: /schemas/types.yaml#/definitions/uint32
61+ description: |
62+ Row active time in pico seconds.
63+
64+ tRC:
65+ $ref: /schemas/types.yaml#/definitions/uint32
66+ description: |
67+ ACTIVATE-to-ACTIVATE command period in pico seconds.
68+
69+ tRCD:
70+ $ref: /schemas/types.yaml#/definitions/uint32
71+ description: |
72+ RAS-to-CAS delay in pico seconds.
73+
74+ tRFC:
75+ $ref: /schemas/types.yaml#/definitions/uint32
76+ description: |
77+ Refresh Cycle time in pico seconds.
78+
79+ tRPab:
80+ $ref: /schemas/types.yaml#/definitions/uint32
81+ description: |
82+ Row precharge time (all banks) in pico seconds.
83+
84+ tRPpb:
85+ $ref: /schemas/types.yaml#/definitions/uint32
86+ description: |
87+ Row precharge time (single banks) in pico seconds.
88+
89+ tRRD:
90+ $ref: /schemas/types.yaml#/definitions/uint32
91+ description: |
92+ Active bank A to active bank B in pico seconds.
93+
94+ tRTP:
95+ $ref: /schemas/types.yaml#/definitions/uint32
96+ description: |
97+ Internal READ to PRECHARGE command delay in pico seconds.
98+
99+ tW2W-C2C:
100+ $ref: /schemas/types.yaml#/definitions/uint32
101+ description: |
102+ Additional WRITE-to-WRITE delay in chip-to-chip cases in pico seconds.
103+
104+ tWR:
105+ $ref: /schemas/types.yaml#/definitions/uint32
106+ description: |
107+ WRITE recovery time in pico seconds.
108+
109+ tWTR:
110+ $ref: /schemas/types.yaml#/definitions/uint32
111+ description: |
112+ Internal WRITE-to-READ command delay in pico seconds.
113+
114+ tXP:
115+ $ref: /schemas/types.yaml#/definitions/uint32
116+ description: |
117+ Exit power-down to next valid command delay in pico seconds.
118+
119+ tXSR:
120+ $ref: /schemas/types.yaml#/definitions/uint32
121+ description: |
122+ SELF REFRESH exit to next valid command delay in pico seconds.
123+
124+required:
125+ - compatible
126+ - min-freq
127+ - max-freq
128+
129+additionalProperties: false
130+
131+examples:
132+ - |
133+ lpddr3 {
134+ timings {
135+ compatible = "jedec,lpddr3-timings";
136+ max-freq = <800000000>;
137+ min-freq = <100000000>;
138+ tCKE = <3750>;
139+ tCKESR = <3750>;
140+ tFAW = <25000>;
141+ tMRD = <7000>;
142+ tR2R-C2C = <0>;
143+ tRAS = <23000>;
144+ tRC = <33750>;
145+ tRCD = <10000>;
146+ tRFC = <65000>;
147+ tRPab = <12000>;
148+ tRPpb = <12000>;
149+ tRRD = <6000>;
150+ tRTP = <3750>;
151+ tW2W-C2C = <0>;
152+ tWR = <7500>;
153+ tWTR = <3750>;
154+ tXP = <3750>;
155+ tXSR = <70000>;
156+ };
157+ };
Documentation/devicetree/bindings/memory-controllers/ddr/jedec,lpddr3.yaml+263−0
@@ -0,0 +1,263 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: LPDDR3 SDRAM compliant to JEDEC JESD209-3
8+
9+maintainers:
10+ - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11+
12+properties:
13+ compatible:
14+ items:
15+ - enum:
16+ - samsung,K3QF2F20DB
17+ - const: jedec,lpddr3
18+
19+ '#address-cells':
20+ const: 1
21+ deprecated: true
22+
23+ density:
24+ $ref: /schemas/types.yaml#/definitions/uint32
25+ description: |
26+ Density in megabits of SDRAM chip.
27+ enum:
28+ - 4096
29+ - 8192
30+ - 16384
31+ - 32768
32+
33+ io-width:
34+ $ref: /schemas/types.yaml#/definitions/uint32
35+ description: |
36+ IO bus width in bits of SDRAM chip.
37+ enum:
38+ - 32
39+ - 16
40+
41+ manufacturer-id:
42+ $ref: /schemas/types.yaml#/definitions/uint32
43+ description: |
44+ Manufacturer ID value read from Mode Register 5. The property is
45+ deprecated, manufacturer should be derived from the compatible.
46+ deprecated: true
47+
48+ revision-id:
49+ $ref: /schemas/types.yaml#/definitions/uint32-array
50+ minItems: 2
51+ maxItems: 2
52+ items:
53+ maximum: 255
54+ description: |
55+ Revision value of SDRAM chip read from Mode Registers 6 and 7.
56+
57+ '#size-cells':
58+ const: 0
59+ deprecated: true
60+
61+ tCKE-min-tck:
62+ $ref: /schemas/types.yaml#/definitions/uint32
63+ maximum: 15
64+ description: |
65+ CKE minimum pulse width (HIGH and LOW pulse width) in terms of number
66+ of clock cycles.
67+
68+ tCKESR-min-tck:
69+ $ref: /schemas/types.yaml#/definitions/uint32
70+ maximum: 15
71+ description: |
72+ CKE minimum pulse width during SELF REFRESH (low pulse width during
73+ SELF REFRESH) in terms of number of clock cycles.
74+
75+ tDQSCK-min-tck:
76+ $ref: /schemas/types.yaml#/definitions/uint32
77+ maximum: 15
78+ description: |
79+ DQS output data access time from CK_t/CK_c in terms of number of clock
80+ cycles.
81+
82+ tFAW-min-tck:
83+ $ref: /schemas/types.yaml#/definitions/uint32
84+ maximum: 63
85+ description: |
86+ Four-bank activate window in terms of number of clock cycles.
87+
88+ tMRD-min-tck:
89+ $ref: /schemas/types.yaml#/definitions/uint32
90+ maximum: 15
91+ description: |
92+ Mode register set command delay in terms of number of clock cycles.
93+
94+ tR2R-C2C-min-tck:
95+ $ref: /schemas/types.yaml#/definitions/uint32
96+ enum: [0, 1]
97+ description: |
98+ Additional READ-to-READ delay in chip-to-chip cases in terms of number
99+ of clock cycles.
100+
101+ tRAS-min-tck:
102+ $ref: /schemas/types.yaml#/definitions/uint32
103+ maximum: 63
104+ description: |
105+ Row active time in terms of number of clock cycles.
106+
107+ tRC-min-tck:
108+ $ref: /schemas/types.yaml#/definitions/uint32
109+ maximum: 63
110+ description: |
111+ ACTIVATE-to-ACTIVATE command period in terms of number of clock cycles.
112+
113+ tRCD-min-tck:
114+ $ref: /schemas/types.yaml#/definitions/uint32
115+ maximum: 15
116+ description: |
117+ RAS-to-CAS delay in terms of number of clock cycles.
118+
119+ tRFC-min-tck:
120+ $ref: /schemas/types.yaml#/definitions/uint32
121+ maximum: 255
122+ description: |
123+ Refresh Cycle time in terms of number of clock cycles.
124+
125+ tRL-min-tck:
126+ $ref: /schemas/types.yaml#/definitions/uint32
127+ maximum: 15
128+ description: |
129+ READ data latency in terms of number of clock cycles.
130+
131+ tRPab-min-tck:
132+ $ref: /schemas/types.yaml#/definitions/uint32
133+ maximum: 15
134+ description: |
135+ Row precharge time (all banks) in terms of number of clock cycles.
136+
137+ tRPpb-min-tck:
138+ $ref: /schemas/types.yaml#/definitions/uint32
139+ maximum: 15
140+ description: |
141+ Row precharge time (single banks) in terms of number of clock cycles.
142+
143+ tRRD-min-tck:
144+ $ref: /schemas/types.yaml#/definitions/uint32
145+ maximum: 15
146+ description: |
147+ Active bank A to active bank B in terms of number of clock cycles.
148+
149+ tRTP-min-tck:
150+ $ref: /schemas/types.yaml#/definitions/uint32
151+ maximum: 15
152+ description: |
153+ Internal READ to PRECHARGE command delay in terms of number of clock
154+ cycles.
155+
156+ tW2W-C2C-min-tck:
157+ $ref: /schemas/types.yaml#/definitions/uint32
158+ enum: [0, 1]
159+ description: |
160+ Additional WRITE-to-WRITE delay in chip-to-chip cases in terms of number
161+ of clock cycles.
162+
163+ tWL-min-tck:
164+ $ref: /schemas/types.yaml#/definitions/uint32
165+ maximum: 15
166+ description: |
167+ WRITE data latency in terms of number of clock cycles.
168+
169+ tWR-min-tck:
170+ $ref: /schemas/types.yaml#/definitions/uint32
171+ maximum: 15
172+ description: |
173+ WRITE recovery time in terms of number of clock cycles.
174+
175+ tWTR-min-tck:
176+ $ref: /schemas/types.yaml#/definitions/uint32
177+ maximum: 15
178+ description: |
179+ Internal WRITE-to-READ command delay in terms of number of clock cycles.
180+
181+ tXP-min-tck:
182+ $ref: /schemas/types.yaml#/definitions/uint32
183+ maximum: 255
184+ description: |
185+ Exit power-down to next valid command delay in terms of number of clock
186+ cycles.
187+
188+ tXSR-min-tck:
189+ $ref: /schemas/types.yaml#/definitions/uint32
190+ maximum: 1023
191+ description: |
192+ SELF REFRESH exit to next valid command delay in terms of number of clock
193+ cycles.
194+
195+patternProperties:
196+ "^timings((-[0-9])+|(@[0-9a-f]+))?$":
197+ $ref: jedec,lpddr3-timings.yaml
198+ description: |
199+ The lpddr3 node may have one or more child nodes with timings.
200+ Each timing node provides AC timing parameters of the device for a given
201+ speed-bin. The user may provide the timings for as many speed-bins as is
202+ required.
203+
204+required:
205+ - compatible
206+ - density
207+ - io-width
208+
209+additionalProperties: false
210+
211+examples:
212+ - |
213+ lpddr3 {
214+ compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
215+ density = <16384>;
216+ io-width = <32>;
217+
218+ tCKE-min-tck = <2>;
219+ tCKESR-min-tck = <2>;
220+ tDQSCK-min-tck = <5>;
221+ tFAW-min-tck = <5>;
222+ tMRD-min-tck = <5>;
223+ tR2R-C2C-min-tck = <0>;
224+ tRAS-min-tck = <5>;
225+ tRC-min-tck = <6>;
226+ tRCD-min-tck = <3>;
227+ tRFC-min-tck = <17>;
228+ tRL-min-tck = <14>;
229+ tRPab-min-tck = <2>;
230+ tRPpb-min-tck = <2>;
231+ tRRD-min-tck = <2>;
232+ tRTP-min-tck = <2>;
233+ tW2W-C2C-min-tck = <0>;
234+ tWL-min-tck = <8>;
235+ tWR-min-tck = <7>;
236+ tWTR-min-tck = <2>;
237+ tXP-min-tck = <2>;
238+ tXSR-min-tck = <12>;
239+
240+ timings {
241+ compatible = "jedec,lpddr3-timings";
242+ max-freq = <800000000>;
243+ min-freq = <100000000>;
244+ tCKE = <3750>;
245+ tCKESR = <3750>;
246+ tFAW = <25000>;
247+ tMRD = <7000>;
248+ tR2R-C2C = <0>;
249+ tRAS = <23000>;
250+ tRC = <33750>;
251+ tRCD = <10000>;
252+ tRFC = <65000>;
253+ tRPab = <12000>;
254+ tRPpb = <12000>;
255+ tRRD = <6000>;
256+ tRTP = <3750>;
257+ tW2W-C2C = <0>;
258+ tWR = <7500>;
259+ tWTR = <3750>;
260+ tXP = <3750>;
261+ tXSR = <70000>;
262+ };
263+ };
Documentation/devicetree/bindings/memory-controllers/ddr/lpddr2-timings.txt+0−52
@@ -1,52 +0,0 @@
1−* AC timing parameters of LPDDR2(JESD209-2) memories for a given speed-bin
2−
3−Required properties:
4−- compatible : Should be "jedec,lpddr2-timings"
5−- min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32>
6−- max-freq : maximum DDR clock frequency for the speed-bin. Type is <u32>
7−
8−Optional properties:
9−
10−The following properties represent AC timing parameters from the memory
11−data-sheet of the device for a given speed-bin. All these properties are
12−of type <u32> and the default unit is ps (pico seconds). Parameters with
13−a different unit have a suffix indicating the unit such as 'tRAS-max-ns'
14−- tRCD
15−- tWR
16−- tRAS-min
17−- tRRD
18−- tWTR
19−- tXP
20−- tRTP
21−- tDQSCK-max
22−- tFAW
23−- tZQCS
24−- tZQinit
25−- tRPab
26−- tZQCL
27−- tCKESR
28−- tRAS-max-ns
29−- tDQSCK-max-derated
30−
31−Example:
32−
33−timings_elpida_ECB240ABACN_400mhz: lpddr2-timings@0 {
34− compatible = "jedec,lpddr2-timings";
35− min-freq = <10000000>;
36− max-freq = <400000000>;
37− tRPab = <21000>;
38− tRCD = <18000>;
39− tWR = <15000>;
40− tRAS-min = <42000>;
41− tRRD = <10000>;
42− tWTR = <7500>;
43− tXP = <7500>;
44− tRTP = <7500>;
45− tCKESR = <15000>;
46− tDQSCK-max = <5500>;
47− tFAW = <50000>;
48− tZQCS = <90000>;
49− tZQCL = <360000>;
50− tZQinit = <1000000>;
51− tRAS-max-ns = <70000>;
52−};
Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt+0−58
@@ -1,58 +0,0 @@
1−* AC timing parameters of LPDDR3 memories for a given speed-bin.
2−
3−The structures are based on LPDDR2 and extended where needed.
4−
5−Required properties:
6−- compatible : Should be "jedec,lpddr3-timings"
7−- min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32>
8−- reg : maximum DDR clock frequency for the speed-bin. Type is <u32>
9−
10−Optional properties:
11−
12−The following properties represent AC timing parameters from the memory
13−data-sheet of the device for a given speed-bin. All these properties are
14−of type <u32> and the default unit is ps (pico seconds).
15−- tRFC
16−- tRRD
17−- tRPab
18−- tRPpb
19−- tRCD
20−- tRC
21−- tRAS
22−- tWTR
23−- tWR
24−- tRTP
25−- tW2W-C2C
26−- tR2R-C2C
27−- tFAW
28−- tXSR
29−- tXP
30−- tCKE
31−- tCKESR
32−- tMRD
33−
34−Example:
35−
36−timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
37− compatible = "jedec,lpddr3-timings";
38− reg = <800000000>; /* workaround: it shows max-freq */
39− min-freq = <100000000>;
40− tRFC = <65000>;
41− tRRD = <6000>;
42− tRPab = <12000>;
43− tRPpb = <12000>;
44− tRCD = <10000>;
45− tRC = <33750>;
46− tRAS = <23000>;
47− tWTR = <3750>;
48− tWR = <7500>;
49− tRTP = <3750>;
50− tW2W-C2C = <0>;
51− tR2R-C2C = <0>;
52− tFAW = <25000>;
53− tXSR = <70000>;
54− tXP = <3750>;
55− tCKE = <3750>;
56− tCKESR = <3750>;
57− tMRD = <7000>;
58−};
Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt+0−107
@@ -1,107 +0,0 @@
1−* LPDDR3 SDRAM memories compliant to JEDEC JESD209-3C
2−
3−Required properties:
4−- compatible : Should be "<vendor>,<type>", and generic value "jedec,lpddr3".
5− Example "<vendor>,<type>" values:
6− "samsung,K3QF2F20DB"
7−
8−- density : <u32> representing density in Mb (Mega bits)
9−- io-width : <u32> representing bus width. Possible values are 8, 16, 32, 64
10−- #address-cells: Must be set to 1
11−- #size-cells: Must be set to 0
12−
13−Optional properties:
14−
15−- manufacturer-id : <u32> Manufacturer ID value read from Mode Register 5
16−- revision-id : <u32 u32> Revision IDs read from Mode Registers 6 and 7
17−
18−The following optional properties represent the minimum value of some AC
19−timing parameters of the DDR device in terms of number of clock cycles.
20−These values shall be obtained from the device data-sheet.
21−- tRFC-min-tck
22−- tRRD-min-tck
23−- tRPab-min-tck
24−- tRPpb-min-tck
25−- tRCD-min-tck
26−- tRC-min-tck
27−- tRAS-min-tck
28−- tWTR-min-tck
29−- tWR-min-tck
30−- tRTP-min-tck
31−- tW2W-C2C-min-tck
32−- tR2R-C2C-min-tck
33−- tWL-min-tck
34−- tDQSCK-min-tck
35−- tRL-min-tck
36−- tFAW-min-tck
37−- tXSR-min-tck
38−- tXP-min-tck
39−- tCKE-min-tck
40−- tCKESR-min-tck
41−- tMRD-min-tck
42−
43−Child nodes:
44−- The lpddr3 node may have one or more child nodes of type "lpddr3-timings".
45− "lpddr3-timings" provides AC timing parameters of the device for
46− a given speed-bin. Please see
47− Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt
48− for more information on "lpddr3-timings"
49−
50−Example:
51−
52−samsung_K3QF2F20DB: lpddr3 {
53− compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
54− density = <16384>;
55− io-width = <32>;
56− manufacturer-id = <1>;
57− revision-id = <123 234>;
58− #address-cells = <1>;
59− #size-cells = <0>;
60−
61− tRFC-min-tck = <17>;
62− tRRD-min-tck = <2>;
63− tRPab-min-tck = <2>;
64− tRPpb-min-tck = <2>;
65− tRCD-min-tck = <3>;
66− tRC-min-tck = <6>;
67− tRAS-min-tck = <5>;
68− tWTR-min-tck = <2>;
69− tWR-min-tck = <7>;
70− tRTP-min-tck = <2>;
71− tW2W-C2C-min-tck = <0>;
72− tR2R-C2C-min-tck = <0>;
73− tWL-min-tck = <8>;
74− tDQSCK-min-tck = <5>;
75− tRL-min-tck = <14>;
76− tFAW-min-tck = <5>;
77− tXSR-min-tck = <12>;
78− tXP-min-tck = <2>;
79− tCKE-min-tck = <2>;
80− tCKESR-min-tck = <2>;
81− tMRD-min-tck = <5>;
82−
83− timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 {
84− compatible = "jedec,lpddr3-timings";
85− /* workaround: 'reg' shows max-freq */
86− reg = <800000000>;
87− min-freq = <100000000>;
88− tRFC = <65000>;
89− tRRD = <6000>;
90− tRPab = <12000>;
91− tRPpb = <12000>;
92− tRCD = <10000>;
93− tRC = <33750>;
94− tRAS = <23000>;
95− tWTR = <3750>;
96− tWR = <7500>;
97− tRTP = <3750>;
98− tW2W-C2C = <0>;
99− tR2R-C2C = <0>;
100− tFAW = <25000>;
101− tXSR = <70000>;
102− tXP = <3750>;
103− tCKE = <3750>;
104− tCKESR = <3750>;
105− tMRD = <7000>;
106− };
107−}
Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ifc.yaml+113−0
@@ -0,0 +1,113 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,ifc.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: FSL/NXP Integrated Flash Controller
8+
9+maintainers:
10+ - Li Yang <leoyang.li@nxp.com>
11+
12+description: |
13+ NXP's integrated flash controller (IFC) is an advanced version of the
14+ enhanced local bus controller which includes similar programming and signal
15+ interfaces with an extended feature set. The IFC provides access to multiple
16+ external memory types, such as NAND flash (SLC and MLC), NOR flash, EPROM,
17+ SRAM and other memories where address and data are shared on a bus.
18+
19+properties:
20+ $nodename:
21+ pattern: "^memory-controller@[0-9a-f]+$"
22+
23+ compatible:
24+ const: fsl,ifc
25+
26+ "#address-cells":
27+ enum: [2, 3]
28+ description: |
29+ Should be either two or three. The first cell is the chipselect
30+ number, and the remaining cells are the offset into the chipselect.
31+
32+ "#size-cells":
33+ enum: [1, 2]
34+ description: |
35+ Either one or two, depending on how large each chipselect can be.
36+
37+ reg:
38+ maxItems: 1
39+
40+ interrupts:
41+ minItems: 1
42+ maxItems: 2
43+ description: |
44+ IFC may have one or two interrupts. If two interrupt specifiers are
45+ present, the first is the "common" interrupt (CM_EVTER_STAT), and the
46+ second is the NAND interrupt (NAND_EVTER_STAT). If there is only one,
47+ that interrupt reports both types of event.
48+
49+ little-endian:
50+ type: boolean
51+ description: |
52+ If this property is absent, the big-endian mode will be in use as default
53+ for registers.
54+
55+ ranges:
56+ description: |
57+ Each range corresponds to a single chipselect, and covers the entire
58+ access window as configured.
59+
60+patternProperties:
61+ "^.*@[a-f0-9]+(,[a-f0-9]+)+$":
62+ type: object
63+ description: |
64+ Child device nodes describe the devices connected to IFC such as NOR (e.g.
65+ cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
66+ like FPGAs, CPLDs, etc.
67+
68+ required:
69+ - compatible
70+ - reg
71+
72+required:
73+ - compatible
74+ - reg
75+ - interrupts
76+
77+additionalProperties: false
78+
79+examples:
80+ - |
81+ soc {
82+ #address-cells = <2>;
83+ #size-cells = <2>;
84+
85+ memory-controller@ffe1e000 {
86+ compatible = "fsl,ifc";
87+ #address-cells = <2>;
88+ #size-cells = <1>;
89+ reg = <0x0 0xffe1e000 0 0x2000>;
90+ interrupts = <16 2 19 2>;
91+ little-endian;
92+
93+ /* NOR, NAND Flashes and CPLD on board */
94+ ranges = <0x0 0x0 0x0 0xee000000 0x02000000>,
95+ <0x1 0x0 0x0 0xffa00000 0x00010000>,
96+ <0x3 0x0 0x0 0xffb00000 0x00020000>;
97+
98+ flash@0,0 {
99+ #address-cells = <1>;
100+ #size-cells = <1>;
101+ compatible = "cfi-flash";
102+ reg = <0x0 0x0 0x2000000>;
103+ bank-width = <2>;
104+ device-width = <1>;
105+
106+ partition@0 {
107+ /* 32MB for user data */
108+ reg = <0x0 0x02000000>;
109+ label = "NOR Data";
110+ };
111+ };
112+ };
113+ };
Documentation/devicetree/bindings/memory-controllers/fsl/ifc.txt+0−82
@@ -1,82 +0,0 @@
1−Integrated Flash Controller
2−
3−Properties:
4−- name : Should be ifc
5−- compatible : should contain "fsl,ifc". The version of the integrated
6− flash controller can be found in the IFC_REV register at
7− offset zero.
8−
9−- #address-cells : Should be either two or three. The first cell is the
10− chipselect number, and the remaining cells are the
11− offset into the chipselect.
12−- #size-cells : Either one or two, depending on how large each chipselect
13− can be.
14−- reg : Offset and length of the register set for the device
15−- interrupts: IFC may have one or two interrupts. If two interrupt
16− specifiers are present, the first is the "common"
17− interrupt (CM_EVTER_STAT), and the second is the NAND
18− interrupt (NAND_EVTER_STAT). If there is only one,
19− that interrupt reports both types of event.
20−
21−- little-endian : If this property is absent, the big-endian mode will
22− be in use as default for registers.
23−
24−- ranges : Each range corresponds to a single chipselect, and covers
25− the entire access window as configured.
26−
27−Child device nodes describe the devices connected to IFC such as NOR (e.g.
28−cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
29−like FPGAs, CPLDs, etc.
30−
31−Example:
32−
33− ifc@ffe1e000 {
34− compatible = "fsl,ifc", "simple-bus";
35− #address-cells = <2>;
36− #size-cells = <1>;
37− reg = <0x0 0xffe1e000 0 0x2000>;
38− interrupts = <16 2 19 2>;
39− little-endian;
40−
41− /* NOR, NAND Flashes and CPLD on board */
42− ranges = <0x0 0x0 0x0 0xee000000 0x02000000
43− 0x1 0x0 0x0 0xffa00000 0x00010000
44− 0x3 0x0 0x0 0xffb00000 0x00020000>;
45−
46− flash@0,0 {
47− #address-cells = <1>;
48− #size-cells = <1>;
49− compatible = "cfi-flash";
50− reg = <0x0 0x0 0x2000000>;
51− bank-width = <2>;
52− device-width = <1>;
53−
54− partition@0 {
55− /* 32MB for user data */
56− reg = <0x0 0x02000000>;
57− label = "NOR Data";
58− };
59− };
60−
61− flash@1,0 {
62− #address-cells = <1>;
63− #size-cells = <1>;
64− compatible = "fsl,ifc-nand";
65− reg = <0x1 0x0 0x10000>;
66−
67− partition@0 {
68− /* This location must not be altered */
69− /* 1MB for u-boot Bootloader Image */
70− reg = <0x0 0x00100000>;
71− label = "NAND U-Boot Image";
72− read-only;
73− };
74− };
75−
76− cpld@3,0 {
77− #address-cells = <1>;
78− #size-cells = <1>;
79− compatible = "fsl,p1010rdb-cpld";
80− reg = <0x3 0x0 0x000001f>;
81− };
82− };
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml+15−17
@@ -16,7 +16,7 @@ description: | · 15 unmodified lines
1616 MediaTek SMI have two generations of HW architecture, here is the list
1717 which generation the SoCs use:
1818 generation 1: mt2701 and mt7623.
19− generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8192 and mt8195.
19+ generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195.
2020
2121 There's slight differences between the two SMI, for generation 2, the
2222 register which control the iommu port is at each larb's register base. But
@@ -35,6 +35,7 @@ properties: · 12 unmodified lines
3535 - mediatek,mt8167-smi-common
3636 - mediatek,mt8173-smi-common
3737 - mediatek,mt8183-smi-common
38+ - mediatek,mt8186-smi-common
3839 - mediatek,mt8192-smi-common
3940 - mediatek,mt8195-smi-common-vdo
4041 - mediatek,mt8195-smi-common-vpp
@@ -88,10 +89,9 @@ allOf: · 47 unmodified lines
8889 - mediatek,mt2701-smi-common
8990 then:
9091 properties:
91− clock:
92− items:
93− minItems: 3
94− maxItems: 3
92+ clocks:
93+ minItems: 3
94+ maxItems: 3
9595 clock-names:
9696 items:
9797 - const: apb
@@ -108,10 +108,9 @@ allOf: · 10 unmodified lines
108108 required:
109109 - mediatek,smi
110110 properties:
111− clock:
112− items:
113− minItems: 3
114− maxItems: 3
111+ clocks:
112+ minItems: 3
113+ maxItems: 3
115114 clock-names:
116115 items:
117116 - const: apb
@@ -127,16 +126,16 @@ allOf: · 9 unmodified lines
127126 enum:
128127 - mediatek,mt6779-smi-common
129128 - mediatek,mt8183-smi-common
129+ - mediatek,mt8186-smi-common
130130 - mediatek,mt8192-smi-common
131131 - mediatek,mt8195-smi-common-vdo
132132 - mediatek,mt8195-smi-common-vpp
133133
134134 then:
135135 properties:
136− clock:
137− items:
138− minItems: 4
139− maxItems: 4
136+ clocks:
137+ minItems: 4
138+ maxItems: 4
140139 clock-names:
141140 items:
142141 - const: apb
@@ -146,10 +145,9 @@ allOf: · 3 unmodified lines
146145
147146 else: # for gen2 HW that don't have gals
148147 properties:
149− clock:
150− items:
151− minItems: 2
152− maxItems: 2
148+ clocks:
149+ minItems: 2
150+ maxItems: 2
153151 clock-names:
154152 items:
155153 - const: apb
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml+10−9
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
2323 - mediatek,mt8167-smi-larb
2424 - mediatek,mt8173-smi-larb
2525 - mediatek,mt8183-smi-larb
26+ - mediatek,mt8186-smi-larb
2627 - mediatek,mt8192-smi-larb
2728 - mediatek,mt8195-smi-larb
2829
@@ -75,15 +76,16 @@ allOf: · 46 unmodified lines
7576 compatible:
7677 enum:
7778 - mediatek,mt8183-smi-larb
79+ - mediatek,mt8186-smi-larb
7880 - mediatek,mt8195-smi-larb
7981
8082 then:
8183 properties:
82− clock:
83− items:
84− minItems: 3
85− maxItems: 3
84+ clocks:
85+ minItems: 2
86+ maxItems: 3
8687 clock-names:
88+ minItems: 2
8789 items:
8890 - const: apb
8991 - const: smi
@@ -91,10 +93,9 @@ allOf: · 1 unmodified line
9193
9294 else:
9395 properties:
94− clock:
95− items:
96− minItems: 2
97− maxItems: 2
96+ clocks:
97+ minItems: 2
98+ maxItems: 2
9899 clock-names:
99100 items:
100101 - const: apb
@@ -108,7 +109,7 @@ allOf: · 7 unmodified lines
108109 - mediatek,mt2701-smi-larb
109110 - mediatek,mt2712-smi-larb
110111 - mediatek,mt6779-smi-larb
111− - mediatek,mt8167-smi-larb
112+ - mediatek,mt8186-smi-larb
112113 - mediatek,mt8192-smi-larb
113114 - mediatek,mt8195-smi-larb
114115
Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml+2−1
@@ -40,7 +40,8 @@ properties: · 39 unmodified lines
4040 - items:
4141 - enum:
4242 - renesas,r9a07g044-rpc-if # RZ/G2{L,LC}
43− - const: renesas,rzg2l-rpc-if # RZ/G2L family
43+ - renesas,r9a07g054-rpc-if # RZ/V2L
44+ - const: renesas,rzg2l-rpc-if
4445
4546 reg:
4647 items:
Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml+1−2
@@ -51,8 +51,7 @@ properties: · 50 unmodified lines
5151 $ref: '/schemas/types.yaml#/definitions/phandle'
5252 description: |
5353 phandle of the connected DRAM memory device. For more information please
54− refer to documentation file:
55− Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt
54+ refer to jedec,lpddr3.yaml.
5655
5756 operating-points-v2: true
5857
Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml+2−1
@@ -12,13 +12,14 @@ maintainers: · 11 unmodified lines
1212 - Jianxin Pan <jianxin.pan@amlogic.com>
1313
1414 description: |+
15− Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node
15+ Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node
1616 of secure-monitor.
1717
1818 properties:
1919 compatible:
2020 enum:
2121 - amlogic,meson-a1-pwrc
22+ - amlogic,meson-s4-pwrc
2223
2324 "#power-domain-cells":
2425 const: 1
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml+3−0
@@ -26,7 +26,9 @@ properties: · 25 unmodified lines
2626 - mediatek,mt8167-power-controller
2727 - mediatek,mt8173-power-controller
2828 - mediatek,mt8183-power-controller
29+ - mediatek,mt8186-power-controller
2930 - mediatek,mt8192-power-controller
31+ - mediatek,mt8195-power-controller
3032
3133 '#power-domain-cells':
3234 const: 1
@@ -64,6 +66,7 @@ patternProperties: · 31 unmodified lines
6466 "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
6567 "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
6668 "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
69+ "include/dt-bindings/power/mt8195-power.h" - for MT8195 type power domain.
6770 maxItems: 1
6871
6972 clocks:
Documentation/devicetree/bindings/power/qcom,rpmpd.yaml+1−0
@@ -17,6 +17,7 @@ properties: · 16 unmodified lines
1717 compatible:
1818 enum:
1919 - qcom,mdm9607-rpmpd
20+ - qcom,msm8226-rpmpd
2021 - qcom,msm8916-rpmpd
2122 - qcom,msm8939-rpmpd
2223 - qcom,msm8953-rpmpd
Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml+16−0
@@ -47,6 +47,10 @@ properties: · 46 unmodified lines
4747 - qcom,sm8350-cdsp-pas
4848 - qcom,sm8350-slpi-pas
4949 - qcom,sm8350-mpss-pas
50+ - qcom,sm8450-adsp-pas
51+ - qcom,sm8450-cdsp-pas
52+ - qcom,sm8450-mpss-pas
53+ - qcom,sm8450-slpi-pas
5054
5155 reg:
5256 maxItems: 1
@@ -175,6 +179,10 @@ allOf: · 122 unmodified lines
175179 - qcom,sm8350-cdsp-pas
176180 - qcom,sm8350-slpi-pas
177181 - qcom,sm8350-mpss-pas
182+ - qcom,sm8450-adsp-pas
183+ - qcom,sm8450-cdsp-pas
184+ - qcom,sm8450-slpi-pas
185+ - qcom,sm8450-mpss-pas
178186 then:
179187 properties:
180188 clocks:
@@ -283,6 +291,9 @@ allOf: · 102 unmodified lines
283291 - qcom,sm8350-adsp-pas
284292 - qcom,sm8350-cdsp-pas
285293 - qcom,sm8350-slpi-pas
294+ - qcom,sm8450-adsp-pas
295+ - qcom,sm8450-cdsp-pas
296+ - qcom,sm8450-slpi-pas
286297 then:
287298 properties:
288299 interrupts:
@@ -312,6 +323,7 @@ allOf: · 23 unmodified lines
312323 - qcom,sm6350-mpss-pas
313324 - qcom,sm8150-mpss-pas
314325 - qcom,sm8350-mpss-pas
326+ - qcom,sm8450-mpss-pas
315327 then:
316328 properties:
317329 interrupts:
@@ -434,6 +446,7 @@ allOf: · 116 unmodified lines
434446 - qcom,sm6350-mpss-pas
435447 - qcom,sm8150-mpss-pas
436448 - qcom,sm8350-mpss-pas
449+ - qcom,sm8450-mpss-pas
437450 then:
438451 properties:
439452 power-domains:
@@ -458,6 +471,8 @@ allOf: · 18 unmodified lines
458471 - qcom,sm8250-slpi-pas
459472 - qcom,sm8350-adsp-pas
460473 - qcom,sm8350-slpi-pas
474+ - qcom,sm8450-adsp-pas
475+ - qcom,sm8450-slpi-pas
461476 then:
462477 properties:
463478 power-domains:
@@ -475,6 +490,7 @@ allOf: · 11 unmodified lines
475490 contains:
476491 enum:
477492 - qcom,sm8350-cdsp-pas
493+ - qcom,sm8450-cdsp-pas
478494 then:
479495 properties:
480496 power-domains:
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt+1−0
@@ -27,6 +27,7 @@ Required properties in pwrap device node. · 26 unmodified lines
2727 "mediatek,mt8135-pwrap" for MT8135 SoCs
2828 "mediatek,mt8173-pwrap" for MT8173 SoCs
2929 "mediatek,mt8183-pwrap" for MT8183 SoCs
30+ "mediatek,mt8186-pwrap" for MT8186 SoCs
3031 "mediatek,mt8195-pwrap" for MT8195 SoCs
3132 "mediatek,mt8516-pwrap" for MT8516 SoCs
3233 - interrupts: IRQ for pwrap in SOC
arch/arm/mach-qcom/platsmp.c+1−2
@@ -357,8 +357,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus) · 356 unmodified lines
357357 {
358358 int cpu;
359359
360− if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,
361− cpu_present_mask)) {
360+ if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) {
362361 for_each_present_cpu(cpu) {
363362 if (cpu == smp_processor_id())
364363 continue;
arch/arm/mach-spear/spear13xx.c+1−1
@@ -29,7 +29,7 @@ void __init spear13xx_l2x0_init(void) · 28 unmodified lines
2929 /*
3030 * 512KB (64KB/way), 8-way associativity, parity supported
3131 *
32− * FIXME: 9th bit, of Auxillary Controller register must be set
32+ * FIXME: 9th bit, of Auxiliary Controller register must be set
3333 * for some spear13xx devices for stable L2 operation.
3434 *
3535 * Enable Early BRESP, L2 prefetch for Instruction and Data,
drivers/bus/imx-weim.c+126−9
@@ -64,6 +64,11 @@ struct cs_timing_state { · 63 unmodified lines
6464 struct cs_timing cs[MAX_CS_COUNT];
6565 };
6666
67+struct weim_priv {
68+ void __iomem *base;
69+ struct cs_timing_state timing_state;
70+};
71+
6772 static const struct of_device_id weim_id_table[] = {
6873 /* i.MX1/21 */
6974 { .compatible = "fsl,imx1-weim", .data = &imx1_weim_devtype, },
@@ -128,21 +133,26 @@ err: · 58 unmodified lines
128133 }
129134
130135 /* Parse and set the timing for this device. */
131−static int weim_timing_setup(struct device *dev,
132− struct device_node *np, void __iomem *base,
133− const struct imx_weim_devtype *devtype,
134− struct cs_timing_state *ts)
136+static int weim_timing_setup(struct device *dev, struct device_node *np,
137+ const struct imx_weim_devtype *devtype)
135138 {
136139 u32 cs_idx, value[MAX_CS_REGS_COUNT];
137140 int i, ret;
138141 int reg_idx, num_regs;
139142 struct cs_timing *cst;
143+ struct weim_priv *priv;
144+ struct cs_timing_state *ts;
145+ void __iomem *base;
140146
141147 if (WARN_ON(devtype->cs_regs_count > MAX_CS_REGS_COUNT))
142148 return -EINVAL;
143149 if (WARN_ON(devtype->cs_count > MAX_CS_COUNT))
144150 return -EINVAL;
145151
152+ priv = dev_get_drvdata(dev);
153+ base = priv->base;
154+ ts = &priv->timing_state;
155+
146156 ret = of_property_read_u32_array(np, "fsl,weim-cs-timing",
147157 value, devtype->cs_regs_count);
148158 if (ret)
@@ -189,14 +199,15 @@ static int weim_timing_setup(struct device *dev, · 40 unmodified lines
189199 return 0;
190200 }
191201
192−static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
202+static int weim_parse_dt(struct platform_device *pdev)
193203 {
194204 const struct of_device_id *of_id = of_match_device(weim_id_table,
195205 &pdev->dev);
196206 const struct imx_weim_devtype *devtype = of_id->data;
197207 struct device_node *child;
198208 int ret, have_child = 0;
199− struct cs_timing_state ts = {};
209+ struct weim_priv *priv;
210+ void __iomem *base;
200211 u32 reg;
201212
202213 if (devtype == &imx50_weim_devtype) {
@@ -205,6 +216,9 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) · 2 unmodified lines
205216 return ret;
206217 }
207218
219+ priv = dev_get_drvdata(&pdev->dev);
220+ base = priv->base;
221+
208222 if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) {
209223 if (devtype->wcr_bcm) {
210224 reg = readl(base + devtype->wcr_offset);
@@ -229,7 +243,7 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) · 18 unmodified lines
229243 }
230244
231245 for_each_available_child_of_node(pdev->dev.of_node, child) {
232− ret = weim_timing_setup(&pdev->dev, child, base, devtype, &ts);
246+ ret = weim_timing_setup(&pdev->dev, child, devtype);
233247 if (ret)
234248 dev_warn(&pdev->dev, "%pOF set timing failed.\n",
235249 child);
@@ -248,17 +262,25 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) · 12 unmodified lines
248262
249263 static int weim_probe(struct platform_device *pdev)
250264 {
265+ struct weim_priv *priv;
251266 struct resource *res;
252267 struct clk *clk;
253268 void __iomem *base;
254269 int ret;
255270
271+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
272+ if (!priv)
273+ return -ENOMEM;
274+
256275 /* get the resource */
257276 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258277 base = devm_ioremap_resource(&pdev->dev, res);
259278 if (IS_ERR(base))
260279 return PTR_ERR(base);
261280
281+ priv->base = base;
282+ dev_set_drvdata(&pdev->dev, priv);
283+
262284 /* get the clock */
263285 clk = devm_clk_get(&pdev->dev, NULL);
264286 if (IS_ERR(clk))
@@ -269,7 +291,7 @@ static int weim_probe(struct platform_device *pdev) · 4 unmodified lines
269291 return ret;
270292
271293 /* parse the device node */
272− ret = weim_parse_dt(pdev, base);
294+ ret = weim_parse_dt(pdev);
273295 if (ret)
274296 clk_disable_unprepare(clk);
275297 else
@@ -278,6 +300,81 @@ static int weim_probe(struct platform_device *pdev) · 2 unmodified lines
278300 return ret;
279301 }
280302
303+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
304+static int of_weim_notify(struct notifier_block *nb, unsigned long action,
305+ void *arg)
306+{
307+ const struct imx_weim_devtype *devtype;
308+ struct of_reconfig_data *rd = arg;
309+ const struct of_device_id *of_id;
310+ struct platform_device *pdev;
311+ int ret = NOTIFY_OK;
312+
313+ switch (of_reconfig_get_state_change(action, rd)) {
314+ case OF_RECONFIG_CHANGE_ADD:
315+ of_id = of_match_node(weim_id_table, rd->dn->parent);
316+ if (!of_id)
317+ return NOTIFY_OK; /* not for us */
318+
319+ devtype = of_id->data;
320+
321+ pdev = of_find_device_by_node(rd->dn->parent);
322+ if (!pdev) {
323+ pr_err("%s: could not find platform device for '%pOF'\n",
324+ __func__, rd->dn->parent);
325+
326+ return notifier_from_errno(-EINVAL);
327+ }
328+
329+ if (weim_timing_setup(&pdev->dev, rd->dn, devtype))
330+ dev_warn(&pdev->dev,
331+ "Failed to setup timing for '%pOF'\n", rd->dn);
332+
333+ if (!of_node_check_flag(rd->dn, OF_POPULATED)) {
334+ if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) {
335+ dev_err(&pdev->dev,
336+ "Failed to create child device '%pOF'\n",
337+ rd->dn);
338+ ret = notifier_from_errno(-EINVAL);
339+ }
340+ }
341+
342+ platform_device_put(pdev);
343+
344+ break;
345+ case OF_RECONFIG_CHANGE_REMOVE:
346+ if (!of_node_check_flag(rd->dn, OF_POPULATED))
347+ return NOTIFY_OK; /* device already destroyed */
348+
349+ of_id = of_match_node(weim_id_table, rd->dn->parent);
350+ if (!of_id)
351+ return NOTIFY_OK; /* not for us */
352+
353+ pdev = of_find_device_by_node(rd->dn);
354+ if (!pdev) {
355+ dev_err(&pdev->dev,
356+ "Could not find platform device for '%pOF'\n",
357+ rd->dn);
358+
359+ ret = notifier_from_errno(-EINVAL);
360+ } else {
361+ of_platform_device_destroy(&pdev->dev, NULL);
362+ platform_device_put(pdev);
363+ }
364+
365+ break;
366+ default:
367+ break;
368+ }
369+
370+ return ret;
371+}
372+
373+struct notifier_block weim_of_notifier = {
374+ .notifier_call = of_weim_notify,
375+};
376+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
377+
281378 static struct platform_driver weim_driver = {
282379 .driver = {
283380 .name = "imx-weim",
@@ -285,7 +382,27 @@ static struct platform_driver weim_driver = { · 1 unmodified line
285382 },
286383 .probe = weim_probe,
287384 };
288−module_platform_driver(weim_driver);
385+
386+static int __init weim_init(void)
387+{
388+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
389+ WARN_ON(of_reconfig_notifier_register(&weim_of_notifier));
390+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
391+
392+ return platform_driver_register(&weim_driver);
393+}
394+module_init(weim_init);
395+
396+static void __exit weim_exit(void)
397+{
398+#if IS_ENABLED(CONFIG_OF_DYNAMIC)
399+ of_reconfig_notifier_unregister(&weim_of_notifier);
400+#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
401+
402+ return platform_driver_unregister(&weim_driver);
403+
404+}
405+module_exit(weim_exit);
289406
290407 MODULE_AUTHOR("Freescale Semiconductor Inc.");
291408 MODULE_DESCRIPTION("i.MX EIM Controller Driver");
drivers/char/hw_random/optee-rng.c+3−3
@@ -145,10 +145,10 @@ static int optee_rng_init(struct hwrng *rng) · 144 unmodified lines
145145 struct optee_rng_private *pvt_data = to_optee_rng_private(rng);
146146 struct tee_shm *entropy_shm_pool = NULL;
147147
148− entropy_shm_pool = tee_shm_alloc(pvt_data->ctx, MAX_ENTROPY_REQ_SZ,
149− TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
148+ entropy_shm_pool = tee_shm_alloc_kernel_buf(pvt_data->ctx,
149+ MAX_ENTROPY_REQ_SZ);
150150 if (IS_ERR(entropy_shm_pool)) {
151− dev_err(pvt_data->dev, "tee_shm_alloc failed\n");
151+ dev_err(pvt_data->dev, "tee_shm_alloc_kernel_buf failed\n");
152152 return PTR_ERR(entropy_shm_pool);
153153 }
154154
drivers/clk/clk-scmi.c+60−11
@@ -2,7 +2,7 @@ · 1 unmodified line
22 /*
33 * System Control and Power Interface (SCMI) Protocol based clock driver
44 *
5− * Copyright (C) 2018-2021 ARM Ltd.
5+ * Copyright (C) 2018-2022 ARM Ltd.
66 */
77
88 #include <linux/clk-provider.h>
@@ -88,21 +88,51 @@ static void scmi_clk_disable(struct clk_hw *hw) · 79 unmodified lines
8888 scmi_proto_clk_ops->disable(clk->ph, clk->id);
8989 }
9090
91+static int scmi_clk_atomic_enable(struct clk_hw *hw)
92+{
93+ struct scmi_clk *clk = to_scmi_clk(hw);
94+
95+ return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
96+}
97+
98+static void scmi_clk_atomic_disable(struct clk_hw *hw)
99+{
100+ struct scmi_clk *clk = to_scmi_clk(hw);
101+
102+ scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
103+}
104+
105+/*
106+ * We can provide enable/disable atomic callbacks only if the underlying SCMI
107+ * transport for an SCMI instance is configured to handle SCMI commands in an
108+ * atomic manner.
109+ *
110+ * When no SCMI atomic transport support is available we instead provide only
111+ * the prepare/unprepare API, as allowed by the clock framework when atomic
112+ * calls are not available.
113+ *
114+ * Two distinct sets of clk_ops are provided since we could have multiple SCMI
115+ * instances with different underlying transport quality, so they cannot be
116+ * shared.
117+ */
91118 static const struct clk_ops scmi_clk_ops = {
92119 .recalc_rate = scmi_clk_recalc_rate,
93120 .round_rate = scmi_clk_round_rate,
94121 .set_rate = scmi_clk_set_rate,
95− /*
96− * We can't provide enable/disable callback as we can't perform the same
97− * in atomic context. Since the clock framework provides standard API
98− * clk_prepare_enable that helps cases using clk_enable in non-atomic
99− * context, it should be fine providing prepare/unprepare.
100− */
101122 .prepare = scmi_clk_enable,
102123 .unprepare = scmi_clk_disable,
103124 };
104125
105−static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
126+static const struct clk_ops scmi_atomic_clk_ops = {
127+ .recalc_rate = scmi_clk_recalc_rate,
128+ .round_rate = scmi_clk_round_rate,
129+ .set_rate = scmi_clk_set_rate,
130+ .enable = scmi_clk_atomic_enable,
131+ .disable = scmi_clk_atomic_disable,
132+};
133+
134+static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
135+ const struct clk_ops *scmi_ops)
106136 {
107137 int ret;
108138 unsigned long min_rate, max_rate;
@@ -110,7 +140,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) · 1 unmodified line
110140 struct clk_init_data init = {
111141 .flags = CLK_GET_RATE_NOCACHE,
112142 .num_parents = 0,
113− .ops = &scmi_clk_ops,
143+ .ops = scmi_ops,
114144 .name = sclk->info->name,
115145 };
116146
@@ -139,6 +169,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) · 22 unmodified lines
139169 static int scmi_clocks_probe(struct scmi_device *sdev)
140170 {
141171 int idx, count, err;
172+ unsigned int atomic_threshold;
173+ bool is_atomic;
142174 struct clk_hw **hws;
143175 struct clk_hw_onecell_data *clk_data;
144176 struct device *dev = &sdev->dev;
@@ -168,8 +200,11 @@ static int scmi_clocks_probe(struct scmi_device *sdev) · 23 unmodified lines
168200 clk_data->num = count;
169201 hws = clk_data->hws;
170202
203+ is_atomic = handle->is_transport_atomic(handle, &atomic_threshold);
204+
171205 for (idx = 0; idx < count; idx++) {
172206 struct scmi_clk *sclk;
207+ const struct clk_ops *scmi_ops;
173208
174209 sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
175210 if (!sclk)
@@ -184,13 +219,27 @@ static int scmi_clocks_probe(struct scmi_device *sdev) · 8 unmodified lines
184219 sclk->id = idx;
185220 sclk->ph = ph;
186221
187− err = scmi_clk_ops_init(dev, sclk);
222+ /*
223+ * Note that when transport is atomic but SCMI protocol did not
224+ * specify (or support) an enable_latency associated with a
225+ * clock, we default to use atomic operations mode.
226+ */
227+ if (is_atomic &&
228+ sclk->info->enable_latency <= atomic_threshold)
229+ scmi_ops = &scmi_atomic_clk_ops;
230+ else
231+ scmi_ops = &scmi_clk_ops;
232+
233+ err = scmi_clk_ops_init(dev, sclk, scmi_ops);
188234 if (err) {
189235 dev_err(dev, "failed to register clock %d\n", idx);
190236 devm_kfree(dev, sclk);
191237 hws[idx] = NULL;
192238 } else {
193− dev_dbg(dev, "Registered clock:%s\n", sclk->info->name);
239+ dev_dbg(dev, "Registered clock:%s%s\n",
240+ sclk->info->name,
241+ scmi_ops == &scmi_atomic_clk_ops ?
242+ " (atomic ops)" : "");
194243 hws[idx] = &sclk->hw;
195244 }
196245 }
drivers/clk/samsung/Kconfig+9−0
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG · 10 unmodified lines
1111 select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
1212 select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
1313 select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
14+ select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
1415
1516 config S3C64XX_COMMON_CLK
1617 bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,11 @@ config S3C2443_COMMON_CLK · 107 unmodified lines
124125 help
125126 Support for the clock controller present on the Samsung
126127 S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
128+
129+config TESLA_FSD_COMMON_CLK
130+ bool "Tesla FSD clock controller support" if COMPILE_TEST
131+ depends on COMMON_CLK_SAMSUNG
132+ depends on EXYNOS_ARM64_COMMON_CLK
133+ help
134+ Support for the clock controller present on the Tesla FSD SoC.
135+ Choose Y here only if you build for this SoC.
drivers/clk/samsung/Makefile+1−0
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o · 25 unmodified lines
2626 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
2727 obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o
2828 obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
29+obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o
drivers/clk/samsung/clk-fsd.c+1803−0
@@ -0,0 +1,1803 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
4+ * https://www.samsung.com
5+ * Copyright (c) 2017-2022 Tesla, Inc.
6+ * https://www.tesla.com
7+ *
8+ * Common Clock Framework support for FSD SoC.
9+ */
10+
11+#include <linux/clk.h>
12+#include <linux/clk-provider.h>
13+#include <linux/init.h>
14+#include <linux/kernel.h>
15+#include <linux/of.h>
16+#include <linux/of_address.h>
17+#include <linux/of_device.h>
18+#include <linux/platform_device.h>
19+
20+#include <dt-bindings/clock/fsd-clk.h>
21+
22+#include "clk.h"
23+#include "clk-exynos-arm64.h"
24+
25+/* Register Offset definitions for CMU_CMU (0x11c10000) */
26+#define PLL_LOCKTIME_PLL_SHARED0 0x0
27+#define PLL_LOCKTIME_PLL_SHARED1 0x4
28+#define PLL_LOCKTIME_PLL_SHARED2 0x8
29+#define PLL_LOCKTIME_PLL_SHARED3 0xc
30+#define PLL_CON0_PLL_SHARED0 0x100
31+#define PLL_CON0_PLL_SHARED1 0x120
32+#define PLL_CON0_PLL_SHARED2 0x140
33+#define PLL_CON0_PLL_SHARED3 0x160
34+#define MUX_CMU_CIS0_CLKMUX 0x1000
35+#define MUX_CMU_CIS1_CLKMUX 0x1004
36+#define MUX_CMU_CIS2_CLKMUX 0x1008
37+#define MUX_CMU_CPUCL_SWITCHMUX 0x100c
38+#define MUX_CMU_FSYS1_ACLK_MUX 0x1014
39+#define MUX_PLL_SHARED0_MUX 0x1020
40+#define MUX_PLL_SHARED1_MUX 0x1024
41+#define DIV_CMU_CIS0_CLK 0x1800
42+#define DIV_CMU_CIS1_CLK 0x1804
43+#define DIV_CMU_CIS2_CLK 0x1808
44+#define DIV_CMU_CMU_ACLK 0x180c
45+#define DIV_CMU_CPUCL_SWITCH 0x1810
46+#define DIV_CMU_FSYS0_SHARED0DIV4 0x181c
47+#define DIV_CMU_FSYS0_SHARED1DIV3 0x1820
48+#define DIV_CMU_FSYS0_SHARED1DIV4 0x1824
49+#define DIV_CMU_FSYS1_SHARED0DIV4 0x1828
50+#define DIV_CMU_FSYS1_SHARED0DIV8 0x182c
51+#define DIV_CMU_IMEM_ACLK 0x1834
52+#define DIV_CMU_IMEM_DMACLK 0x1838
53+#define DIV_CMU_IMEM_TCUCLK 0x183c
54+#define DIV_CMU_PERIC_SHARED0DIV20 0x1844
55+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK 0x1848
56+#define DIV_CMU_PERIC_SHARED1DIV36 0x184c
57+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK 0x1850
58+#define DIV_PLL_SHARED0_DIV2 0x1858
59+#define DIV_PLL_SHARED0_DIV3 0x185c
60+#define DIV_PLL_SHARED0_DIV4 0x1860
61+#define DIV_PLL_SHARED0_DIV6 0x1864
62+#define DIV_PLL_SHARED1_DIV3 0x1868
63+#define DIV_PLL_SHARED1_DIV36 0x186c
64+#define DIV_PLL_SHARED1_DIV4 0x1870
65+#define DIV_PLL_SHARED1_DIV9 0x1874
66+#define GAT_CMU_CIS0_CLKGATE 0x2000
67+#define GAT_CMU_CIS1_CLKGATE 0x2004
68+#define GAT_CMU_CIS2_CLKGATE 0x2008
69+#define GAT_CMU_CPUCL_SWITCH_GATE 0x200c
70+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE 0x2018
71+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK 0x201c
72+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE 0x2020
73+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE 0x2024
74+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE 0x2028
75+#define GAT_CMU_IMEM_ACLK_GATE 0x2030
76+#define GAT_CMU_IMEM_DMACLK_GATE 0x2034
77+#define GAT_CMU_IMEM_TCUCLK_GATE 0x2038
78+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE 0x2040
79+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE 0x2044
80+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE 0x2048
81+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE 0x204c
82+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK 0x2054
83+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK 0x2058
84+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU 0x205c
85+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK 0x2060
86+
87+static const unsigned long cmu_clk_regs[] __initconst = {
88+ PLL_LOCKTIME_PLL_SHARED0,
89+ PLL_LOCKTIME_PLL_SHARED1,
90+ PLL_LOCKTIME_PLL_SHARED2,
91+ PLL_LOCKTIME_PLL_SHARED3,
92+ PLL_CON0_PLL_SHARED0,
93+ PLL_CON0_PLL_SHARED1,
94+ PLL_CON0_PLL_SHARED2,
95+ PLL_CON0_PLL_SHARED3,
96+ MUX_CMU_CIS0_CLKMUX,
97+ MUX_CMU_CIS1_CLKMUX,
98+ MUX_CMU_CIS2_CLKMUX,
99+ MUX_CMU_CPUCL_SWITCHMUX,
100+ MUX_CMU_FSYS1_ACLK_MUX,
101+ MUX_PLL_SHARED0_MUX,
102+ MUX_PLL_SHARED1_MUX,
103+ DIV_CMU_CIS0_CLK,
104+ DIV_CMU_CIS1_CLK,
105+ DIV_CMU_CIS2_CLK,
106+ DIV_CMU_CMU_ACLK,
107+ DIV_CMU_CPUCL_SWITCH,
108+ DIV_CMU_FSYS0_SHARED0DIV4,
109+ DIV_CMU_FSYS0_SHARED1DIV3,
110+ DIV_CMU_FSYS0_SHARED1DIV4,
111+ DIV_CMU_FSYS1_SHARED0DIV4,
112+ DIV_CMU_FSYS1_SHARED0DIV8,
113+ DIV_CMU_IMEM_ACLK,
114+ DIV_CMU_IMEM_DMACLK,
115+ DIV_CMU_IMEM_TCUCLK,
116+ DIV_CMU_PERIC_SHARED0DIV20,
117+ DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
118+ DIV_CMU_PERIC_SHARED1DIV36,
119+ DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
120+ DIV_PLL_SHARED0_DIV2,
121+ DIV_PLL_SHARED0_DIV3,
122+ DIV_PLL_SHARED0_DIV4,
123+ DIV_PLL_SHARED0_DIV6,
124+ DIV_PLL_SHARED1_DIV3,
125+ DIV_PLL_SHARED1_DIV36,
126+ DIV_PLL_SHARED1_DIV4,
127+ DIV_PLL_SHARED1_DIV9,
128+ GAT_CMU_CIS0_CLKGATE,
129+ GAT_CMU_CIS1_CLKGATE,
130+ GAT_CMU_CIS2_CLKGATE,
131+ GAT_CMU_CPUCL_SWITCH_GATE,
132+ GAT_CMU_FSYS0_SHARED0DIV4_GATE,
133+ GAT_CMU_FSYS0_SHARED1DIV4_CLK,
134+ GAT_CMU_FSYS0_SHARED1DIV4_GATE,
135+ GAT_CMU_FSYS1_SHARED0DIV4_GATE,
136+ GAT_CMU_FSYS1_SHARED1DIV4_GATE,
137+ GAT_CMU_IMEM_ACLK_GATE,
138+ GAT_CMU_IMEM_DMACLK_GATE,
139+ GAT_CMU_IMEM_TCUCLK_GATE,
140+ GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
141+ GAT_CMU_PERIC_SHARED0DIVE4_GATE,
142+ GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
143+ GAT_CMU_PERIC_SHARED1DIVE4_GATE,
144+ GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
145+ GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
146+ GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
147+ GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
148+};
149+
150+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
151+ PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0),
152+};
153+
154+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
155+ PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
156+};
157+
158+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
159+ PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
160+};
161+
162+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
163+ PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0),
164+};
165+
166+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
167+ PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
168+ PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
169+ PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
170+ PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
171+ PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
172+ PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
173+ PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
174+ PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
175+};
176+
177+/* List of parent clocks for Muxes in CMU_CMU */
178+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
179+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
180+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
181+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
182+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
183+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
184+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
185+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
186+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
187+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
188+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
189+
190+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
191+ MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
192+ MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
193+ MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
194+ MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
195+ MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
196+ MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
197+ MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
198+ MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
199+ MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
200+ MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
201+ MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
202+ MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
203+};
204+
205+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
206+ DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
207+ DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
208+ DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
209+ DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
210+ DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
211+ DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
212+ DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
213+ DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
214+ DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
215+ DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
216+ DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
217+ DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
218+ DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
219+ DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
220+ DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
221+ DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
222+ DIV_CMU_IMEM_ACLK, 0, 4),
223+ DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
224+ DIV_CMU_IMEM_DMACLK, 0, 4),
225+ DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
226+ DIV_CMU_IMEM_TCUCLK, 0, 4),
227+ DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
228+ "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
229+ DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
230+ "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
231+ DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
232+ "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
233+ DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
234+ "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
235+ DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
236+ DIV_PLL_SHARED0_DIV2, 0, 4),
237+ DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
238+ DIV_PLL_SHARED0_DIV3, 0, 4),
239+ DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
240+ DIV_PLL_SHARED0_DIV4, 0, 4),
241+ DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
242+ DIV_PLL_SHARED0_DIV6, 0, 4),
243+ DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
244+ DIV_PLL_SHARED1_DIV3, 0, 4),
245+ DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
246+ DIV_PLL_SHARED1_DIV36, 0, 4),
247+ DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
248+ DIV_PLL_SHARED1_DIV4, 0, 4),
249+ DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
250+ DIV_PLL_SHARED1_DIV9, 0, 4),
251+};
252+
253+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
254+ GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
255+ CLK_IGNORE_UNUSED, 0),
256+ GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
257+ CLK_IGNORE_UNUSED, 0),
258+ GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
259+ CLK_IGNORE_UNUSED, 0),
260+ GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
261+ GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
262+ GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
263+ GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
264+ GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
265+ GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
266+ GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
267+ GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
268+ GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
269+ GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
270+ GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
271+ GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
272+ GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
273+ CLK_IGNORE_UNUSED, 0),
274+ GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
275+ CLK_IGNORE_UNUSED, 0),
276+ GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
277+ CLK_IGNORE_UNUSED, 0),
278+ GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
279+ GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
280+ GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
281+ GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
282+ GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
283+ GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
284+ GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
285+ GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
286+ GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
287+ GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
288+ GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
289+ GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
290+ GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
291+ GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
292+ GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
293+ GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
294+};
295+
296+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
297+ .pll_clks = cmu_pll_clks,
298+ .nr_pll_clks = ARRAY_SIZE(cmu_pll_clks),
299+ .mux_clks = cmu_mux_clks,
300+ .nr_mux_clks = ARRAY_SIZE(cmu_mux_clks),
301+ .div_clks = cmu_div_clks,
302+ .nr_div_clks = ARRAY_SIZE(cmu_div_clks),
303+ .gate_clks = cmu_gate_clks,
304+ .nr_gate_clks = ARRAY_SIZE(cmu_gate_clks),
305+ .nr_clk_ids = CMU_NR_CLK,
306+ .clk_regs = cmu_clk_regs,
307+ .nr_clk_regs = ARRAY_SIZE(cmu_clk_regs),
308+};
309+
310+static void __init fsd_clk_cmu_init(struct device_node *np)
311+{
312+ samsung_cmu_register_one(np, &cmu_cmu_info);
313+}
314+
315+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
316+
317+/* Register Offset definitions for CMU_PERIC (0x14010000) */
318+#define PLL_CON0_PERIC_DMACLK_MUX 0x100
319+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX 0x120
320+#define PLL_CON0_PERIC_PCLK_MUX 0x140
321+#define PLL_CON0_PERIC_TBUCLK_MUX 0x160
322+#define PLL_CON0_SPI_CLK 0x180
323+#define PLL_CON0_SPI_PCLK 0x1a0
324+#define PLL_CON0_UART_CLK 0x1c0
325+#define PLL_CON0_UART_PCLK 0x1e0
326+#define MUX_PERIC_EQOS_PHYRXCLK 0x1000
327+#define DIV_EQOS_BUSCLK 0x1800
328+#define DIV_PERIC_MCAN_CLK 0x1804
329+#define DIV_RGMII_CLK 0x1808
330+#define DIV_RII_CLK 0x180c
331+#define DIV_RMII_CLK 0x1810
332+#define DIV_SPI_CLK 0x1814
333+#define DIV_UART_CLK 0x1818
334+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I 0x2000
335+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK 0x2004
336+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK 0x2008
337+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK 0x200c
338+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK 0x2010
339+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK 0x2014
340+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM 0x2018
341+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS 0x201c
342+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM 0x2020
343+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS 0x2024
344+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK 0x2028
345+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK 0x202c
346+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK 0x2030
347+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK 0x2034
348+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK 0x2038
349+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK 0x203c
350+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK 0x2040
351+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK 0x2044
352+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK 0x2048
353+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I 0x204c
354+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I 0x2050
355+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I 0x2054
356+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I 0x2058
357+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I 0x205c
358+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I 0x2060
359+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK 0x2064
360+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D 0x2068
361+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P 0x206c
362+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0 0x2070
363+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK 0x2074
364+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK 0x2078
365+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK 0x207c
366+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK 0x2080
367+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK 0x2084
368+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK 0x2088
369+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK 0x208c
370+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK 0x2090
371+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK 0x2094
372+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK 0x2098
373+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK 0x209c
374+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK 0x20a0
375+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK 0x20a4
376+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK 0x20a8
377+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK 0x20ac
378+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK 0x20b0
379+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK 0x20b4
380+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK 0x20b8
381+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0 0x20bc
382+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0 0x20c0
383+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK 0x20c4
384+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK 0x20c8
385+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK 0x20cc
386+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI 0x20d0
387+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK 0x20d4
388+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI 0x20d8
389+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK 0x20dc
390+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI 0x20e0
391+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M 0x20e4
392+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK 0x20e8
393+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M 0x20ec
394+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK 0x20f0
395+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART 0x20f4
396+#define GAT_PERIC_UART0_IPCLKPORT_PCLK 0x20f8
397+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART 0x20fc
398+#define GAT_PERIC_UART1_IPCLKPORT_PCLK 0x2100
399+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK 0x2104
400+
401+static const unsigned long peric_clk_regs[] __initconst = {
402+ PLL_CON0_PERIC_DMACLK_MUX,
403+ PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
404+ PLL_CON0_PERIC_PCLK_MUX,
405+ PLL_CON0_PERIC_TBUCLK_MUX,
406+ PLL_CON0_SPI_CLK,
407+ PLL_CON0_SPI_PCLK,
408+ PLL_CON0_UART_CLK,
409+ PLL_CON0_UART_PCLK,
410+ MUX_PERIC_EQOS_PHYRXCLK,
411+ DIV_EQOS_BUSCLK,
412+ DIV_PERIC_MCAN_CLK,
413+ DIV_RGMII_CLK,
414+ DIV_RII_CLK,
415+ DIV_RMII_CLK,
416+ DIV_SPI_CLK,
417+ DIV_UART_CLK,
418+ GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
419+ GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
420+ GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
421+ GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
422+ GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
423+ GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
424+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
425+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
426+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
427+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
428+ GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
429+ GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
430+ GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
431+ GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
432+ GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
433+ GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
434+ GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
435+ GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
436+ GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
437+ GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
438+ GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
439+ GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
440+ GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
441+ GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
442+ GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
443+ GAT_GPIO_PERIC_IPCLKPORT_PCLK,
444+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
445+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
446+ GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
447+ GAT_PERIC_DMA0_IPCLKPORT_ACLK,
448+ GAT_PERIC_DMA1_IPCLKPORT_ACLK,
449+ GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
450+ GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
451+ GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
452+ GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
453+ GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
454+ GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
455+ GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
456+ GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
457+ GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
458+ GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
459+ GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
460+ GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
461+ GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
462+ GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
463+ GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
464+ GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
465+ GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
466+ GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
467+ GAT_PERIC_SMMU_IPCLKPORT_CCLK,
468+ GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
469+ GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
470+ GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
471+ GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
472+ GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
473+ GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
474+ GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
475+ GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
476+ GAT_PERIC_TDM0_IPCLKPORT_PCLK,
477+ GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
478+ GAT_PERIC_TDM1_IPCLKPORT_PCLK,
479+ GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
480+ GAT_PERIC_UART0_IPCLKPORT_PCLK,
481+ GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
482+ GAT_PERIC_UART1_IPCLKPORT_PCLK,
483+ GAT_SYSREG_PERI_IPCLKPORT_PCLK,
484+};
485+
486+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
487+ FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
488+};
489+
490+/* List of parent clocks for Muxes in CMU_PERIC */
491+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
492+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
493+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
494+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
495+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
496+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
497+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
498+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
499+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
500+
501+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
502+ MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
503+ MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
504+ PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
505+ MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
506+ MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
507+ MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
508+ MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
509+ MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
510+ MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
511+ MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
512+ MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
513+};
514+
515+static const struct samsung_div_clock peric_div_clks[] __initconst = {
516+ DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
517+ DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
518+ DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
519+ DIV_RGMII_CLK, 0, 4),
520+ DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
521+ DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
522+ DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
523+ DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
524+};
525+
526+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
527+ GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
528+ "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
529+ GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
530+ 21, CLK_IGNORE_UNUSED, 0),
531+ GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
532+ GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
533+ GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
534+ GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
535+ GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
536+ CLK_IGNORE_UNUSED, 0),
537+ GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
538+ CLK_IGNORE_UNUSED, 0),
539+ GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
540+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
541+ GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
542+ GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
543+ GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
544+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
545+ GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
546+ GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
547+ GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
548+ GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
549+ GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
550+ GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
551+ GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
552+ GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
553+ GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
554+ GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
555+ GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
556+ "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
557+ GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
558+ GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
559+ GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
560+ "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
561+ GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
562+ GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
563+ GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
564+ GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
565+ GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
566+ "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
567+ GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
568+ "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
569+ GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
570+ "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
571+ GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
572+ "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
573+ GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
574+ GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
575+ GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
576+ GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
577+ GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
578+ GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
579+ GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
580+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
581+ GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
582+ GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
583+ GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
584+ GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
585+ GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
586+ GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
587+ GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
588+ GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
589+ GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
590+ GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
591+ GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
592+ GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
593+ GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
594+ GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
595+ GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
596+ GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
597+ GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
598+ GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
599+ GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
600+ GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
601+ GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
602+ GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
603+ GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
604+ GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
605+ GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
606+ GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
607+ GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
608+ GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
609+ GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
610+ GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
611+ GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
612+ GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
613+ GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
614+ GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
615+ GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
616+ GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
617+ GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
618+ GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
619+ GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
620+ GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
621+ GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
622+ GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
623+ GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
624+ GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
625+ GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
626+ GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
627+ GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
628+ GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
629+ GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
630+ GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
631+ GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
632+ GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
633+ GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
634+ GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
635+ GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
636+ GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
637+ GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
638+ GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
639+ GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
640+ GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
641+ GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
642+ GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
643+ GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
644+ GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
645+ GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
646+ GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
647+ GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
648+ GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
649+ GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
650+ GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
651+ GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
652+ GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
653+ GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
654+ GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
655+ GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
656+ GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
657+ GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
658+ GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
659+};
660+
661+static const struct samsung_cmu_info peric_cmu_info __initconst = {
662+ .mux_clks = peric_mux_clks,
663+ .nr_mux_clks = ARRAY_SIZE(peric_mux_clks),
664+ .div_clks = peric_div_clks,
665+ .nr_div_clks = ARRAY_SIZE(peric_div_clks),
666+ .gate_clks = peric_gate_clks,
667+ .nr_gate_clks = ARRAY_SIZE(peric_gate_clks),
668+ .fixed_clks = peric_fixed_clks,
669+ .nr_fixed_clks = ARRAY_SIZE(peric_fixed_clks),
670+ .nr_clk_ids = PERIC_NR_CLK,
671+ .clk_regs = peric_clk_regs,
672+ .nr_clk_regs = ARRAY_SIZE(peric_clk_regs),
673+ .clk_name = "dout_cmu_pll_shared0_div4",
674+};
675+
676+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
677+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO 0x100
678+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK 0x140
679+#define PLL_CON0_EQOS_RGMII_125_MUX1 0x160
680+#define DIV_CLK_UNIPRO 0x1800
681+#define DIV_EQS_RGMII_CLK_125 0x1804
682+#define DIV_PERIBUS_GRP 0x1808
683+#define DIV_EQOS_RII_CLK2O5 0x180c
684+#define DIV_EQOS_RMIICLK_25 0x1810
685+#define DIV_PCIE_PHY_OSCCLK 0x1814
686+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 0x2004
687+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I 0x2008
688+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK 0x200c
689+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK 0x2010
690+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO 0x2014
691+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK 0x2018
692+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC 0x201c
693+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2020
694+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x2024
695+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2028
696+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x202c
697+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK 0x2038
698+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK 0x203c
699+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK 0x2040
700+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK 0x2044
701+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK 0x2048
702+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK 0x204c
703+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK 0x2050
704+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I 0x2054
705+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I 0x2058
706+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I 0x205c
707+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I 0x2060
708+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I 0x2064
709+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK 0x2068
710+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D 0x206c
711+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1 0x2070
712+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P 0x2074
713+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S 0x2078
714+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK 0x207c
715+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL 0x2080
716+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0 0x2084
717+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC 0x2088
718+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK 0x208c
719+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC 0x2090
720+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC 0x2094
721+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK 0x2098
722+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK 0x209c
723+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK 0x20a0
724+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS 0x20a4
725+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK 0x20a8
726+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO 0x20ac
727+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK 0x20b0
728+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS 0x20b4
729+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK 0x20b8
730+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO 0x20bc
731+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK 0x20c0
732+#define GAT_FSYS0_RII_CLK_DIVGATE 0x20d4
733+
734+static const unsigned long fsys0_clk_regs[] __initconst = {
735+ PLL_CON0_CLKCMU_FSYS0_UNIPRO,
736+ PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
737+ PLL_CON0_EQOS_RGMII_125_MUX1,
738+ DIV_CLK_UNIPRO,
739+ DIV_EQS_RGMII_CLK_125,
740+ DIV_PERIBUS_GRP,
741+ DIV_EQOS_RII_CLK2O5,
742+ DIV_EQOS_RMIICLK_25,
743+ DIV_PCIE_PHY_OSCCLK,
744+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
745+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
746+ GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
747+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
748+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
749+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
750+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
751+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
752+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
753+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
754+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
755+ GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
756+ GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
757+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
758+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
759+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
760+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
761+ GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
762+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
763+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
764+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
765+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
766+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
767+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
768+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
769+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
770+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
771+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
772+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
773+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
774+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
775+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
776+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
777+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
778+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
779+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
780+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
781+ GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
782+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
783+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
784+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
785+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
786+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
787+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
788+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
789+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
790+ GAT_FSYS0_RII_CLK_DIVGATE,
791+};
792+
793+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
794+ FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
795+ FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
796+ FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
797+};
798+
799+/* List of parent clocks for Muxes in CMU_FSYS0 */
800+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
801+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
802+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
803+
804+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
805+ MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
806+ PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
807+ MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
808+ PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
809+ MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
810+ PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
811+};
812+
813+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
814+ DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
815+ DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
816+ DIV_EQS_RGMII_CLK_125, 0, 4),
817+ DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
818+ "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
819+ DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
820+ DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
821+ DIV_EQOS_RMIICLK_25, 0, 5),
822+ DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
823+ DIV_PCIE_PHY_OSCCLK, 0, 4),
824+};
825+
826+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
827+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
828+ "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
829+ CLK_IGNORE_UNUSED, 0),
830+ GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
831+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
832+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
833+ CLK_IGNORE_UNUSED, 0),
834+ GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
835+ GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
836+ GATE(0,
837+ "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
838+ "xtal_clk_pcie_phy",
839+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
840+ CLK_IGNORE_UNUSED, 0),
841+ GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
842+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
843+ CLK_IGNORE_UNUSED, 0),
844+ GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
845+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
846+ CLK_IGNORE_UNUSED, 0),
847+ GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
848+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
849+ CLK_IGNORE_UNUSED, 0),
850+ GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
851+ "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
852+ CLK_IGNORE_UNUSED, 0),
853+ GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
854+ GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
855+ GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
856+ GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
857+ GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
858+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
859+ GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
860+ GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
861+ GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
862+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
863+ GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
864+ GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
865+ GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
866+ GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
867+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
868+ "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
869+ CLK_IGNORE_UNUSED, 0),
870+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
871+ "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
872+ CLK_IGNORE_UNUSED, 0),
873+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
874+ "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
875+ CLK_IGNORE_UNUSED, 0),
876+ GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
877+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
878+ GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
879+ GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
880+ GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
881+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
882+ GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
883+ GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
884+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
885+ "mout_fsys0_clk_fsys0_slavebusclk",
886+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
887+ CLK_IGNORE_UNUSED, 0),
888+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
889+ "mout_fsys0_eqos_rgmii_125_mux1",
890+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
891+ CLK_IGNORE_UNUSED, 0),
892+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
893+ "dout_fsys0_peribus_grp",
894+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
895+ CLK_IGNORE_UNUSED, 0),
896+ GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
897+ "mout_fsys0_clk_fsys0_slavebusclk",
898+ GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
899+ CLK_IGNORE_UNUSED, 0),
900+ GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
901+ "dout_fsys0_peribus_grp",
902+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
903+ CLK_IGNORE_UNUSED, 0),
904+ GATE(0,
905+ "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
906+ "dout_fsys0_pcie_phy_oscclk",
907+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
908+ 21, CLK_IGNORE_UNUSED, 0),
909+ GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
910+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
911+ GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
912+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
913+ GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
914+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
915+ "dout_fsys0_peribus_grp",
916+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
917+ CLK_IGNORE_UNUSED, 0),
918+ GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
919+ "dout_fsys0_peribus_grp",
920+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
921+ CLK_IGNORE_UNUSED, 0),
922+ GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
923+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
924+ "mout_fsys0_clk_fsys0_slavebusclk",
925+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
926+ CLK_IGNORE_UNUSED, 0),
927+ GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
928+ "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
929+ "mout_fsys0_clk_fsys0_slavebusclk",
930+ GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
931+ CLK_IGNORE_UNUSED, 0),
932+ GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
933+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
934+ GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
935+ GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
936+ GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
937+ GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
938+ GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
939+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
940+ GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
941+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
942+ GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
943+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
944+ GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
945+ GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
946+ GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
947+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
948+ GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
949+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
950+ GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
951+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
952+ GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
953+ GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
954+ GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
955+ 21, CLK_IGNORE_UNUSED, 0),
956+ GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
957+ "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
958+};
959+
960+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
961+ .mux_clks = fsys0_mux_clks,
962+ .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks),
963+ .div_clks = fsys0_div_clks,
964+ .nr_div_clks = ARRAY_SIZE(fsys0_div_clks),
965+ .gate_clks = fsys0_gate_clks,
966+ .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks),
967+ .fixed_clks = fsys0_fixed_clks,
968+ .nr_fixed_clks = ARRAY_SIZE(fsys0_fixed_clks),
969+ .nr_clk_ids = FSYS0_NR_CLK,
970+ .clk_regs = fsys0_clk_regs,
971+ .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs),
972+ .clk_name = "dout_cmu_fsys0_shared1div4",
973+};
974+
975+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
976+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX 0x100
977+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX 0x180
978+#define DIV_CLK_FSYS1_PHY0_OSCCLK 0x1800
979+#define DIV_CLK_FSYS1_PHY1_OSCCLK 0x1804
980+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK 0x2000
981+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK 0x2004
982+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK 0x2008
983+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK 0x200c
984+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL 0x202c
985+#define GAT_FSYS1_PHY0_OSCCLLK 0x2034
986+#define GAT_FSYS1_PHY1_OSCCLK 0x2038
987+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK 0x203c
988+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK 0x2040
989+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK 0x2048
990+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK 0x204c
991+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK 0x2054
992+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0 0x205c
993+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0 0x2064
994+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK 0x206c
995+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK 0x2070
996+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK 0x2074
997+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK 0x2078
998+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK 0x207c
999+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK 0x2080
1000+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK 0x2084
1001+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK 0x2088
1002+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK 0x208c
1003+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK 0x20a4
1004+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL 0x20a8
1005+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK 0x20b4
1006+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK 0x20b8
1007+
1008+static const unsigned long fsys1_clk_regs[] __initconst = {
1009+ PLL_CON0_ACLK_FSYS1_BUSP_MUX,
1010+ PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
1011+ DIV_CLK_FSYS1_PHY0_OSCCLK,
1012+ DIV_CLK_FSYS1_PHY1_OSCCLK,
1013+ GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
1014+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
1015+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
1016+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
1017+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
1018+ GAT_FSYS1_PHY0_OSCCLLK,
1019+ GAT_FSYS1_PHY1_OSCCLK,
1020+ GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
1021+ GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
1022+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
1023+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
1024+ GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
1025+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
1026+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
1027+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
1028+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
1029+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
1030+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
1031+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
1032+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
1033+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
1034+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
1035+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
1036+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
1037+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
1038+ GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
1039+ GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
1040+};
1041+
1042+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
1043+ FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
1044+ FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
1045+};
1046+
1047+/* List of parent clocks for Muxes in CMU_FSYS1 */
1048+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
1049+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
1050+
1051+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
1052+ MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
1053+ PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
1054+ MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
1055+ PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
1056+};
1057+
1058+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
1059+ DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
1060+ DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
1061+ DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
1062+ DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
1063+};
1064+
1065+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
1066+ GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
1067+ GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1068+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
1069+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
1070+ GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
1071+ GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
1072+ GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
1073+ GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
1074+ GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
1075+ GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1076+ GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
1077+ GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
1078+ GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
1079+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
1080+ GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
1081+ GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
1082+ GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
1083+ GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1084+ GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
1085+ "mout_fsys1_aclk_fsys1_busp_mux",
1086+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
1087+ CLK_IGNORE_UNUSED, 0),
1088+ GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
1089+ "mout_fsys1_aclk_fsys1_busp_mux",
1090+ GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
1091+ CLK_IGNORE_UNUSED, 0),
1092+ GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
1093+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
1094+ CLK_IGNORE_UNUSED, 0),
1095+ GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
1096+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
1097+ GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
1098+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
1099+ GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
1100+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
1101+ GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
1102+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
1103+ CLK_IGNORE_UNUSED, 0),
1104+ GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
1105+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
1106+ CLK_IGNORE_UNUSED, 0),
1107+ GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
1108+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
1109+ CLK_IGNORE_UNUSED, 0),
1110+ GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
1111+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
1112+ GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
1113+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
1114+ CLK_IGNORE_UNUSED, 0),
1115+ GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
1116+ "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
1117+ CLK_IGNORE_UNUSED, 0),
1118+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
1119+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
1120+ GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
1121+ GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
1122+ GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
1123+ GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
1124+ GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
1125+ GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
1126+ GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
1127+ GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1128+ GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
1129+ GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1130+};
1131+
1132+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
1133+ .mux_clks = fsys1_mux_clks,
1134+ .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks),
1135+ .div_clks = fsys1_div_clks,
1136+ .nr_div_clks = ARRAY_SIZE(fsys1_div_clks),
1137+ .gate_clks = fsys1_gate_clks,
1138+ .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks),
1139+ .fixed_clks = fsys1_fixed_clks,
1140+ .nr_fixed_clks = ARRAY_SIZE(fsys1_fixed_clks),
1141+ .nr_clk_ids = FSYS1_NR_CLK,
1142+ .clk_regs = fsys1_clk_regs,
1143+ .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs),
1144+ .clk_name = "dout_cmu_fsys1_shared0div4",
1145+};
1146+
1147+/* Register Offset definitions for CMU_IMEM (0x10010000) */
1148+#define PLL_CON0_CLK_IMEM_ACLK 0x100
1149+#define PLL_CON0_CLK_IMEM_INTMEMCLK 0x120
1150+#define PLL_CON0_CLK_IMEM_TCUCLK 0x140
1151+#define DIV_OSCCLK_IMEM_TMUTSCLK 0x1800
1152+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK 0x2000
1153+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO 0x2004
1154+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK 0x2008
1155+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK 0x200c
1156+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK 0x2010
1157+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS 0x2014
1158+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK 0x2018
1159+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS 0x201c
1160+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK 0x2020
1161+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS 0x2024
1162+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK 0x2028
1163+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS 0x202c
1164+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK 0x2030
1165+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS 0x2034
1166+#define GAT_IMEM_WDT0_IPCLKPORT_CLK 0x2038
1167+#define GAT_IMEM_WDT1_IPCLKPORT_CLK 0x203c
1168+#define GAT_IMEM_WDT2_IPCLKPORT_CLK 0x2040
1169+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM 0x2044
1170+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM 0x2048
1171+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM 0x204c
1172+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS 0x2050
1173+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS 0x2054
1174+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS 0x2058
1175+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM 0x205c
1176+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS 0x2060
1177+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM 0x2064
1178+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS 0x2068
1179+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK 0x206c
1180+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK 0x2070
1181+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK 0x2074
1182+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK 0x2078
1183+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK 0x207c
1184+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK 0x2080
1185+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK 0x2084
1186+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK 0x2088
1187+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK 0x208c
1188+#define GAT_IMEM_GIC_IPCLKPORT_CLK 0x2090
1189+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK 0x2094
1190+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK 0x2098
1191+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK 0x209c
1192+#define GAT_IMEM_MCT_IPCLKPORT_PCLK 0x20a0
1193+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D 0x20a4
1194+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU 0x20a8
1195+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P 0x20ac
1196+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK 0x20b0
1197+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK 0x20b4
1198+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK 0x20b8
1199+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK 0x20bc
1200+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK 0x20c0
1201+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK 0x20c4
1202+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK 0x20c8
1203+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK 0x20cc
1204+#define GAT_IMEM_TCU_IPCLKPORT_ACLK 0x20d0
1205+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK 0x20d4
1206+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK 0x20d8
1207+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK 0x20dc
1208+
1209+static const unsigned long imem_clk_regs[] __initconst = {
1210+ PLL_CON0_CLK_IMEM_ACLK,
1211+ PLL_CON0_CLK_IMEM_INTMEMCLK,
1212+ PLL_CON0_CLK_IMEM_TCUCLK,
1213+ DIV_OSCCLK_IMEM_TMUTSCLK,
1214+ GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
1215+ GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
1216+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
1217+ GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
1218+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
1219+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
1220+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
1221+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
1222+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
1223+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
1224+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
1225+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
1226+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
1227+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
1228+ GAT_IMEM_WDT0_IPCLKPORT_CLK,
1229+ GAT_IMEM_WDT1_IPCLKPORT_CLK,
1230+ GAT_IMEM_WDT2_IPCLKPORT_CLK,
1231+ GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
1232+ GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
1233+ GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
1234+ GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
1235+ GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
1236+ GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
1237+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
1238+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
1239+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
1240+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
1241+ GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
1242+ GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
1243+ GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
1244+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
1245+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
1246+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
1247+ GAT_IMEM_DMA0_IPCLKPORT_ACLK,
1248+ GAT_IMEM_DMA1_IPCLKPORT_ACLK,
1249+ GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
1250+ GAT_IMEM_GIC_IPCLKPORT_CLK,
1251+ GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
1252+ GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
1253+ GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
1254+ GAT_IMEM_MCT_IPCLKPORT_PCLK,
1255+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
1256+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
1257+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
1258+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
1259+ GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
1260+ GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
1261+ GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
1262+ GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
1263+ GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
1264+ GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
1265+ GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
1266+ GAT_IMEM_TCU_IPCLKPORT_ACLK,
1267+ GAT_IMEM_WDT0_IPCLKPORT_PCLK,
1268+ GAT_IMEM_WDT1_IPCLKPORT_PCLK,
1269+ GAT_IMEM_WDT2_IPCLKPORT_PCLK,
1270+};
1271+
1272+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
1273+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
1274+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
1275+
1276+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
1277+ MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
1278+ PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
1279+ MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
1280+ MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
1281+ PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
1282+};
1283+
1284+static const struct samsung_div_clock imem_div_clks[] __initconst = {
1285+ DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
1286+};
1287+
1288+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
1289+ GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1290+ GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1291+ GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
1292+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
1293+ GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
1294+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
1295+ GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
1296+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
1297+ GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
1298+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
1299+ GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
1300+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
1301+ GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
1302+ GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
1303+ GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
1304+ GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1305+ GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
1306+ GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1307+ GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
1308+ GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1309+ GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
1310+ "dout_imem_oscclk_imem_tmutsclk",
1311+ GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
1312+ GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
1313+ "dout_imem_oscclk_imem_tmutsclk",
1314+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
1315+ GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
1316+ "dout_imem_oscclk_imem_tmutsclk",
1317+ GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
1318+ GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
1319+ "dout_imem_oscclk_imem_tmutsclk",
1320+ GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
1321+ GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
1322+ "dout_imem_oscclk_imem_tmutsclk",
1323+ GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
1324+ GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
1325+ GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
1326+ GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
1327+ GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
1328+ GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
1329+ GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
1330+ GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
1331+ GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
1332+ GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
1333+ GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
1334+ GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
1335+ GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
1336+ GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
1337+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
1338+ GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
1339+ GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
1340+ GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
1341+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
1342+ GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
1343+ GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
1344+ GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
1345+ GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1346+ GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
1347+ GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1348+ GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
1349+ GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
1350+ GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
1351+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
1352+ GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
1353+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
1354+ GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
1355+ GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
1356+ GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
1357+ GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
1358+ GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
1359+ GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
1360+ GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
1361+ GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1362+ GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
1363+ GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1364+ GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
1365+ GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1366+ GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1367+ GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1368+ GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1369+ GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1370+ GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1371+ GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1372+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
1373+ "mout_imem_clk_imem_tcuclk",
1374+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
1375+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
1376+ "mout_imem_clk_imem_tcuclk",
1377+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
1378+ CLK_IGNORE_UNUSED, 0),
1379+ GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
1380+ GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
1381+ GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1382+ GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1383+ GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
1384+ GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1385+ GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
1386+ GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1387+ GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
1388+ GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1389+ GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
1390+ GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1391+ GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1392+ GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1393+ GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1394+ GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1395+ GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
1396+ GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
1397+ GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1398+ GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1399+ GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
1400+ GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1401+ GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
1402+ GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1403+ GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1404+ GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1405+ GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1406+ GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1407+ GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
1408+ GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1409+};
1410+
1411+static const struct samsung_cmu_info imem_cmu_info __initconst = {
1412+ .mux_clks = imem_mux_clks,
1413+ .nr_mux_clks = ARRAY_SIZE(imem_mux_clks),
1414+ .div_clks = imem_div_clks,
1415+ .nr_div_clks = ARRAY_SIZE(imem_div_clks),
1416+ .gate_clks = imem_gate_clks,
1417+ .nr_gate_clks = ARRAY_SIZE(imem_gate_clks),
1418+ .nr_clk_ids = IMEM_NR_CLK,
1419+ .clk_regs = imem_clk_regs,
1420+ .nr_clk_regs = ARRAY_SIZE(imem_clk_regs),
1421+};
1422+
1423+static void __init fsd_clk_imem_init(struct device_node *np)
1424+{
1425+ samsung_cmu_register_one(np, &imem_cmu_info);
1426+}
1427+
1428+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
1429+
1430+/* Register Offset definitions for CMU_MFC (0x12810000) */
1431+#define PLL_LOCKTIME_PLL_MFC 0x0
1432+#define PLL_CON0_PLL_MFC 0x100
1433+#define MUX_MFC_BUSD 0x1000
1434+#define MUX_MFC_BUSP 0x1008
1435+#define DIV_MFC_BUSD_DIV4 0x1800
1436+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK 0x2000
1437+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM 0x2004
1438+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS 0x2008
1439+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK 0x200c
1440+#define GAT_MFC_MFC_IPCLKPORT_ACLK 0x2010
1441+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D 0x2018
1442+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P 0x201c
1443+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK 0x2028
1444+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK 0x202c
1445+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK 0x2030
1446+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK 0x2034
1447+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK 0x2038
1448+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK 0x203c
1449+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK 0x2040
1450+#define GAT_MFC_BUSD_DIV4_GATE 0x2044
1451+#define GAT_MFC_BUSD_GATE 0x2048
1452+
1453+static const unsigned long mfc_clk_regs[] __initconst = {
1454+ PLL_LOCKTIME_PLL_MFC,
1455+ PLL_CON0_PLL_MFC,
1456+ MUX_MFC_BUSD,
1457+ MUX_MFC_BUSP,
1458+ DIV_MFC_BUSD_DIV4,
1459+ GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
1460+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
1461+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
1462+ GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
1463+ GAT_MFC_MFC_IPCLKPORT_ACLK,
1464+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
1465+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
1466+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
1467+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
1468+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
1469+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
1470+ GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
1471+ GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
1472+ GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
1473+ GAT_MFC_BUSD_DIV4_GATE,
1474+ GAT_MFC_BUSD_GATE,
1475+};
1476+
1477+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
1478+ PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0),
1479+};
1480+
1481+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
1482+ PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
1483+ PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
1484+};
1485+
1486+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
1487+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
1488+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
1489+
1490+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
1491+ MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
1492+ MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
1493+ MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
1494+};
1495+
1496+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
1497+ DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
1498+};
1499+
1500+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
1501+ GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
1502+ GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1503+ GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
1504+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
1505+ GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
1506+ GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
1507+ GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
1508+ GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1509+ GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
1510+ GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1511+ GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
1512+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
1513+ GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
1514+ GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
1515+ GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
1516+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1517+ GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
1518+ GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1519+ GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
1520+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1521+ GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
1522+ GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1523+ GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
1524+ GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1525+ GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
1526+ GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1527+ GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
1528+ GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
1529+ GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
1530+ GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
1531+ GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
1532+};
1533+
1534+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
1535+ .pll_clks = mfc_pll_clks,
1536+ .nr_pll_clks = ARRAY_SIZE(mfc_pll_clks),
1537+ .mux_clks = mfc_mux_clks,
1538+ .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks),
1539+ .div_clks = mfc_div_clks,
1540+ .nr_div_clks = ARRAY_SIZE(mfc_div_clks),
1541+ .gate_clks = mfc_gate_clks,
1542+ .nr_gate_clks = ARRAY_SIZE(mfc_gate_clks),
1543+ .nr_clk_ids = MFC_NR_CLK,
1544+ .clk_regs = mfc_clk_regs,
1545+ .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs),
1546+};
1547+
1548+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
1549+#define PLL_LOCKTIME_PLL_CAM_CSI 0x0
1550+#define PLL_CON0_PLL_CAM_CSI 0x100
1551+#define DIV_CAM_CSI0_ACLK 0x1800
1552+#define DIV_CAM_CSI1_ACLK 0x1804
1553+#define DIV_CAM_CSI2_ACLK 0x1808
1554+#define DIV_CAM_CSI_BUSD 0x180c
1555+#define DIV_CAM_CSI_BUSP 0x1810
1556+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK 0x2000
1557+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK 0x2004
1558+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0 0x2008
1559+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1 0x200c
1560+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2 0x2010
1561+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC 0x2014
1562+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC 0x2018
1563+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK 0x201c
1564+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK 0x2020
1565+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK 0x2024
1566+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK 0x2028
1567+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK 0x202c
1568+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK 0x2030
1569+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK 0x2034
1570+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK 0x2038
1571+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK 0x203c
1572+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK 0x2040
1573+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK 0x2044
1574+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK 0x2048
1575+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK 0x204c
1576+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK 0x2050
1577+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK 0x2054
1578+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK 0x2058
1579+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK 0x205c
1580+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK 0x2060
1581+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK 0x2064
1582+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK 0x2068
1583+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK 0x206c
1584+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK 0x2070
1585+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK 0x2074
1586+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK 0x2078
1587+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D 0x207c
1588+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P 0x2080
1589+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK 0x2084
1590+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK 0x2088
1591+
1592+static const unsigned long cam_csi_clk_regs[] __initconst = {
1593+ PLL_LOCKTIME_PLL_CAM_CSI,
1594+ PLL_CON0_PLL_CAM_CSI,
1595+ DIV_CAM_CSI0_ACLK,
1596+ DIV_CAM_CSI1_ACLK,
1597+ DIV_CAM_CSI2_ACLK,
1598+ DIV_CAM_CSI_BUSD,
1599+ DIV_CAM_CSI_BUSP,
1600+ GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
1601+ GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
1602+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
1603+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
1604+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
1605+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
1606+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
1607+ GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
1608+ GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
1609+ GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
1610+ GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
1611+ GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
1612+ GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
1613+ GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
1614+ GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
1615+ GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
1616+ GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
1617+ GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
1618+ GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
1619+ GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
1620+ GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
1621+ GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
1622+ GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
1623+ GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
1624+ GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
1625+ GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
1626+ GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
1627+ GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
1628+ GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
1629+ GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
1630+ GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
1631+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
1632+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
1633+ GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
1634+ GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
1635+};
1636+
1637+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
1638+ PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0),
1639+};
1640+
1641+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
1642+ PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
1643+ PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
1644+};
1645+
1646+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
1647+
1648+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
1649+ MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
1650+};
1651+
1652+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
1653+ DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
1654+ DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
1655+ DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
1656+ DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
1657+ DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
1658+};
1659+
1660+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
1661+ GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
1662+ GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1663+ GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
1664+ GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1665+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
1666+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
1667+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
1668+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
1669+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
1670+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
1671+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
1672+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
1673+ CLK_IGNORE_UNUSED, 0),
1674+ GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
1675+ GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
1676+ GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
1677+ GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1678+ GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
1679+ GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1680+ GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
1681+ GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1682+ GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
1683+ GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1684+ GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
1685+ GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1686+ GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
1687+ GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1688+ GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
1689+ GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1690+ GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
1691+ GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1692+ GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
1693+ GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1694+ GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
1695+ GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1696+ GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
1697+ GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1698+ GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
1699+ GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1700+ GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
1701+ GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1702+ GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
1703+ GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1704+ GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
1705+ GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1706+ GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
1707+ GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1708+ GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
1709+ GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1710+ GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
1711+ GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1712+ GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
1713+ GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1714+ GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
1715+ GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1716+ GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
1717+ GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1718+ GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
1719+ GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1720+ GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
1721+ GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1722+ GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
1723+ GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1724+ GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
1725+ "dout_cam_csi_busd",
1726+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
1727+ CLK_IGNORE_UNUSED, 0),
1728+ GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
1729+ "dout_cam_csi_busp",
1730+ GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
1731+ CLK_IGNORE_UNUSED, 0),
1732+ GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
1733+ GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
1734+ GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
1735+ GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
1736+};
1737+
1738+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
1739+ .pll_clks = cam_csi_pll_clks,
1740+ .nr_pll_clks = ARRAY_SIZE(cam_csi_pll_clks),
1741+ .mux_clks = cam_csi_mux_clks,
1742+ .nr_mux_clks = ARRAY_SIZE(cam_csi_mux_clks),
1743+ .div_clks = cam_csi_div_clks,
1744+ .nr_div_clks = ARRAY_SIZE(cam_csi_div_clks),
1745+ .gate_clks = cam_csi_gate_clks,
1746+ .nr_gate_clks = ARRAY_SIZE(cam_csi_gate_clks),
1747+ .nr_clk_ids = CAM_CSI_NR_CLK,
1748+ .clk_regs = cam_csi_clk_regs,
1749+ .nr_clk_regs = ARRAY_SIZE(cam_csi_clk_regs),
1750+};
1751+
1752+/**
1753+ * fsd_cmu_probe - Probe function for FSD platform clocks
1754+ * @pdev: Pointer to platform device
1755+ *
1756+ * Configure clock hierarchy for clock domains of FSD platform
1757+ */
1758+static int __init fsd_cmu_probe(struct platform_device *pdev)
1759+{
1760+ const struct samsung_cmu_info *info;
1761+ struct device *dev = &pdev->dev;
1762+
1763+ info = of_device_get_match_data(dev);
1764+ exynos_arm64_register_cmu(dev, dev->of_node, info);
1765+
1766+ return 0;
1767+}
1768+
1769+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
1770+static const struct of_device_id fsd_cmu_of_match[] = {
1771+ {
1772+ .compatible = "tesla,fsd-clock-peric",
1773+ .data = &peric_cmu_info,
1774+ }, {
1775+ .compatible = "tesla,fsd-clock-fsys0",
1776+ .data = &fsys0_cmu_info,
1777+ }, {
1778+ .compatible = "tesla,fsd-clock-fsys1",
1779+ .data = &fsys1_cmu_info,
1780+ }, {
1781+ .compatible = "tesla,fsd-clock-mfc",
1782+ .data = &mfc_cmu_info,
1783+ }, {
1784+ .compatible = "tesla,fsd-clock-cam_csi",
1785+ .data = &cam_csi_cmu_info,
1786+ }, {
1787+ },
1788+};
1789+
1790+static struct platform_driver fsd_cmu_driver __refdata = {
1791+ .driver = {
1792+ .name = "fsd-cmu",
1793+ .of_match_table = fsd_cmu_of_match,
1794+ .suppress_bind_attrs = true,
1795+ },
1796+ .probe = fsd_cmu_probe,
1797+};
1798+
1799+static int __init fsd_cmu_init(void)
1800+{
1801+ return platform_driver_register(&fsd_cmu_driver);
1802+}
1803+core_initcall(fsd_cmu_init);
drivers/clk/samsung/clk-pll.c+1−0
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, · 1468 unmodified lines
14691469 case pll_1450x:
14701470 case pll_1451x:
14711471 case pll_1452x:
1472+ case pll_142xx:
14721473 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
14731474 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
14741475 if (!pll->rate_table)
drivers/clk/samsung/clk-pll.h+1−0
@@ -39,6 +39,7 @@ enum samsung_pll_type { · 38 unmodified lines
3939 pll_1460x,
4040 pll_0822x,
4141 pll_0831x,
42+ pll_142xx,
4243 };
4344
4445 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
drivers/cpuidle/cpuidle-qcom-spm.c+24−4
@@ -122,10 +122,6 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu) · 121 unmodified lines
122122 if (ret <= 0)
123123 return ret ? : -ENODEV;
124124
125− ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu));
126− if (ret)
127− return ret;
128−
129125 return cpuidle_register(&data->cpuidle_driver, NULL);
130126 }
131127
@@ -136,6 +132,10 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev) · 4 unmodified lines
136132 if (!qcom_scm_is_available())
137133 return -EPROBE_DEFER;
138134
135+ ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm);
136+ if (ret)
137+ return dev_err_probe(&pdev->dev, ret, "set warm boot addr failed");
138+
139139 for_each_possible_cpu(cpu) {
140140 ret = spm_cpuidle_register(&pdev->dev, cpu);
141141 if (ret && ret != -ENODEV) {
@@ -155,6 +155,22 @@ static struct platform_driver spm_cpuidle_driver = { · 13 unmodified lines
155155 },
156156 };
157157
158+static bool __init qcom_spm_find_any_cpu(void)
159+{
160+ struct device_node *cpu_node, *saw_node;
161+
162+ for_each_of_cpu_node(cpu_node) {
163+ saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0);
164+ if (of_device_is_available(saw_node)) {
165+ of_node_put(saw_node);
166+ of_node_put(cpu_node);
167+ return true;
168+ }
169+ of_node_put(saw_node);
170+ }
171+ return false;
172+}
173+
158174 static int __init qcom_spm_cpuidle_init(void)
159175 {
160176 struct platform_device *pdev;
@@ -164,6 +180,10 @@ static int __init qcom_spm_cpuidle_init(void) · 3 unmodified lines
164180 if (ret)
165181 return ret;
166182
183+ /* Make sure there is actually any CPU managed by the SPM */
184+ if (!qcom_spm_find_any_cpu())
185+ return 0;
186+
167187 pdev = platform_device_register_simple("qcom-spm-cpuidle",
168188 -1, NULL, 0);
169189 if (IS_ERR(pdev)) {
drivers/firmware/arm_scmi/Kconfig+56−0
@@ -54,6 +54,18 @@ config ARM_SCMI_TRANSPORT_MAILBOX · 53 unmodified lines
5454 If you want the ARM SCMI PROTOCOL stack to include support for a
5555 transport based on mailboxes, answer Y.
5656
57+config ARM_SCMI_TRANSPORT_OPTEE
58+ bool "SCMI transport based on OP-TEE service"
59+ depends on OPTEE=y || OPTEE=ARM_SCMI_PROTOCOL
60+ select ARM_SCMI_HAVE_TRANSPORT
61+ select ARM_SCMI_HAVE_SHMEM
62+ default y
63+ help
64+ This enables the OP-TEE service based transport for SCMI.
65+
66+ If you want the ARM SCMI PROTOCOL stack to include support for a
67+ transport based on OP-TEE SCMI service, answer Y.
68+
5769 config ARM_SCMI_TRANSPORT_SMC
5870 bool "SCMI transport based on SMC"
5971 depends on HAVE_ARM_SMCCC_DISCOVERY
@@ -66,6 +78,20 @@ config ARM_SCMI_TRANSPORT_SMC · 6 unmodified lines
6678 If you want the ARM SCMI PROTOCOL stack to include support for a
6779 transport based on SMC, answer Y.
6880
81+config ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE
82+ bool "Enable atomic mode support for SCMI SMC transport"
83+ depends on ARM_SCMI_TRANSPORT_SMC
84+ help
85+ Enable support of atomic operation for SCMI SMC based transport.
86+
87+ If you want the SCMI SMC based transport to operate in atomic
88+ mode, avoiding any kind of sleeping behaviour for selected
89+ transactions on the TX path, answer Y.
90+ Enabling atomic mode operations allows any SCMI driver using this
91+ transport to optionally ask for atomic SCMI transactions and operate
92+ in atomic context too, at the price of using a number of busy-waiting
93+ primitives all over instead. If unsure say N.
94+
6995 config ARM_SCMI_TRANSPORT_VIRTIO
7096 bool "SCMI transport based on VirtIO"
7197 depends on VIRTIO=y || VIRTIO=ARM_SCMI_PROTOCOL
@@ -77,6 +103,36 @@ config ARM_SCMI_TRANSPORT_VIRTIO · 5 unmodified lines
77103 If you want the ARM SCMI PROTOCOL stack to include support for a
78104 transport based on VirtIO, answer Y.
79105
106+config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
107+ bool "SCMI VirtIO transport Version 1 compliance"
108+ depends on ARM_SCMI_TRANSPORT_VIRTIO
109+ default y
110+ help
111+ This enforces strict compliance with VirtIO Version 1 specification.
112+
113+ If you want the ARM SCMI VirtIO transport layer to refuse to work
114+ with Legacy VirtIO backends and instead support only VirtIO Version 1
115+ devices (or above), answer Y.
116+
117+ If you want instead to support also old Legacy VirtIO backends (like
118+ the ones implemented by kvmtool) and let the core Kernel VirtIO layer
119+ take care of the needed conversions, say N.
120+
121+config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
122+ bool "Enable atomic mode for SCMI VirtIO transport"
123+ depends on ARM_SCMI_TRANSPORT_VIRTIO
124+ help
125+ Enable support of atomic operation for SCMI VirtIO based transport.
126+
127+ If you want the SCMI VirtIO based transport to operate in atomic
128+ mode, avoiding any kind of sleeping behaviour for selected
129+ transactions on the TX path, answer Y.
130+
131+ Enabling atomic mode operations allows any SCMI driver using this
132+ transport to optionally ask for atomic SCMI transactions and operate
133+ in atomic context too, at the price of using a number of busy-waiting
134+ primitives all over instead. If unsure say N.
135+
80136 endif #ARM_SCMI_PROTOCOL
81137
82138 config ARM_SCMI_POWER_DOMAIN
drivers/firmware/arm_scmi/Makefile+8−0
@@ -6,8 +6,16 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o · 5 unmodified lines
66 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
77 scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
88 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
9+scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
910 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
1011 scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
1112 $(scmi-transport-y)
1213 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
1314 obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
15+
16+ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy)
17+# The use of R7 in the SMCCC conflicts with the compiler's use of R7 as a frame
18+# pointer in Thumb2 mode, which is forcibly enabled by Clang when profiling
19+# hooks are inserted via the -pg switch.
20+CFLAGS_REMOVE_smc.o += $(CC_FLAGS_FTRACE)
21+endif
drivers/firmware/arm_scmi/clock.c+28−6
@@ -27,7 +27,8 @@ struct scmi_msg_resp_clock_protocol_attributes { · 26 unmodified lines
2727 struct scmi_msg_resp_clock_attributes {
2828 __le32 attributes;
2929 #define CLOCK_ENABLE BIT(0)
30− u8 name[SCMI_MAX_STR_SIZE];
30+ u8 name[SCMI_MAX_STR_SIZE];
31+ __le32 clock_enable_latency;
3132 };
3233
3334 struct scmi_clock_set_config {
@@ -116,10 +117,15 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph, · 82 unmodified lines
116117 attr = t->rx.buf;
117118
118119 ret = ph->xops->do_xfer(ph, t);
119− if (!ret)
120+ if (!ret) {
120121 strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
121− else
122+ /* Is optional field clock_enable_latency provided ? */
123+ if (t->rx.len == sizeof(*attr))
124+ clk->enable_latency =
125+ le32_to_cpu(attr->clock_enable_latency);
126+ } else {
122127 clk->name[0] = '\0';
128+ }
123129
124130 ph->xops->xfer_put(ph, t);
125131 return ret;
@@ -273,7 +279,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph, · 147 unmodified lines
273279
274280 static int
275281 scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
276− u32 config)
282+ u32 config, bool atomic)
277283 {
278284 int ret;
279285 struct scmi_xfer *t;
@@ -284,6 +290,8 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, · 4 unmodified lines
284290 if (ret)
285291 return ret;
286292
293+ t->hdr.poll_completion = atomic;
294+
287295 cfg = t->tx.buf;
288296 cfg->id = cpu_to_le32(clk_id);
289297 cfg->attributes = cpu_to_le32(config);
@@ -296,12 +304,24 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, · 6 unmodified lines
296304
297305 static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
298306 {
299− return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);
307+ return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
300308 }
301309
302310 static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
303311 {
304− return scmi_clock_config_set(ph, clk_id, 0);
312+ return scmi_clock_config_set(ph, clk_id, 0, false);
313+}
314+
315+static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph,
316+ u32 clk_id)
317+{
318+ return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true);
319+}
320+
321+static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph,
322+ u32 clk_id)
323+{
324+ return scmi_clock_config_set(ph, clk_id, 0, true);
305325 }
306326
307327 static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -330,6 +350,8 @@ static const struct scmi_clk_proto_ops clk_proto_ops = { · 22 unmodified lines
330350 .rate_set = scmi_clock_rate_set,
331351 .enable = scmi_clock_enable,
332352 .disable = scmi_clock_disable,
353+ .enable_atomic = scmi_clock_enable_atomic,
354+ .disable_atomic = scmi_clock_disable_atomic,
333355 };
334356
335357 static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
drivers/firmware/arm_scmi/common.h+25−1
@@ -339,11 +339,16 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id); · 338 unmodified lines
339339 * @dev: Reference to device in the SCMI hierarchy corresponding to this
340340 * channel
341341 * @handle: Pointer to SCMI entity handle
342+ * @no_completion_irq: Flag to indicate that this channel has no completion
343+ * interrupt mechanism for synchronous commands.
344+ * This can be dynamically set by transports at run-time
345+ * inside their provided .chan_setup().
342346 * @transport_info: Transport layer related information
343347 */
344348 struct scmi_chan_info {
345349 struct device *dev;
346350 struct scmi_handle *handle;
351+ bool no_completion_irq;
347352 void *transport_info;
348353 };
349354
@@ -373,7 +378,8 @@ struct scmi_transport_ops { · 23 unmodified lines
373378 unsigned int (*get_max_msg)(struct scmi_chan_info *base_cinfo);
374379 int (*send_message)(struct scmi_chan_info *cinfo,
375380 struct scmi_xfer *xfer);
376− void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret);
381+ void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret,
382+ struct scmi_xfer *xfer);
377383 void (*fetch_response)(struct scmi_chan_info *cinfo,
378384 struct scmi_xfer *xfer);
379385 void (*fetch_notification)(struct scmi_chan_info *cinfo,
@@ -402,6 +408,18 @@ struct scmi_device *scmi_child_dev_find(struct device *parent, · 22 unmodified lines
402408 * be pending simultaneously in the system. May be overridden by the
403409 * get_max_msg op.
404410 * @max_msg_size: Maximum size of data per message that can be handled.
411+ * @force_polling: Flag to force this whole transport to use SCMI core polling
412+ * mechanism instead of completion interrupts even if available.
413+ * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
414+ * synchronous-command messages are atomically
415+ * completed on .send_message: no need to poll
416+ * actively waiting for a response.
417+ * Used by core internally only when polling is
418+ * selected as a waiting for reply method: i.e.
419+ * if a completion irq was found use that anyway.
420+ * @atomic_enabled: Flag to indicate that this transport, which is assured not
421+ * to sleep anywhere on the TX path, can be used in atomic mode
422+ * when requested.
405423 */
406424 struct scmi_desc {
407425 int (*transport_init)(void);
@@ -410,6 +428,9 @@ struct scmi_desc { · 2 unmodified lines
410428 int max_rx_timeout_ms;
411429 int max_msg;
412430 int max_msg_size;
431+ const bool force_polling;
432+ const bool sync_cmds_completed_on_ret;
433+ const bool atomic_enabled;
413434 };
414435
415436 #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
@@ -421,6 +442,9 @@ extern const struct scmi_desc scmi_smc_desc; · 5 unmodified lines
421442 #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
422443 extern const struct scmi_desc scmi_virtio_desc;
423444 #endif
445+#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
446+extern const struct scmi_desc scmi_optee_desc;
447+#endif
424448
425449 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
426450 void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
drivers/firmware/arm_scmi/driver.c+191−43
@@ -131,6 +131,12 @@ struct scmi_protocol_instance { · 130 unmodified lines
131131 * MAX_PROTOCOLS_IMP elements allocated by the base protocol
132132 * @active_protocols: IDR storing device_nodes for protocols actually defined
133133 * in the DT and confirmed as implemented by fw.
134+ * @atomic_threshold: Optional system wide DT-configured threshold, expressed
135+ * in microseconds, for atomic operations.
136+ * Only SCMI synchronous commands reported by the platform
137+ * to have an execution latency lesser-equal to the threshold
138+ * should be considered for atomic mode operation: such
139+ * decision is finally left up to the SCMI drivers.
134140 * @notify_priv: Pointer to private data structure specific to notifications.
135141 * @node: List head
136142 * @users: Number of users of this instance
@@ -149,6 +155,7 @@ struct scmi_info { · 12 unmodified lines
149155 struct mutex protocols_mtx;
150156 u8 *protocols_imp;
151157 struct idr active_protocols;
158+ unsigned int atomic_threshold;
152159 void *notify_priv;
153160 struct list_head node;
154161 int users;
@@ -609,6 +616,25 @@ static inline void scmi_clear_channel(struct scmi_info *info, · 454 unmodified lines
609616 info->desc->ops->clear_channel(cinfo);
610617 }
611618
619+static inline bool is_polling_required(struct scmi_chan_info *cinfo,
620+ struct scmi_info *info)
621+{
622+ return cinfo->no_completion_irq || info->desc->force_polling;
623+}
624+
625+static inline bool is_transport_polling_capable(struct scmi_info *info)
626+{
627+ return info->desc->ops->poll_done ||
628+ info->desc->sync_cmds_completed_on_ret;
629+}
630+
631+static inline bool is_polling_enabled(struct scmi_chan_info *cinfo,
632+ struct scmi_info *info)
633+{
634+ return is_polling_required(cinfo, info) &&
635+ is_transport_polling_capable(info);
636+}
637+
612638 static void scmi_handle_notification(struct scmi_chan_info *cinfo,
613639 u32 msg_hdr, void *priv)
614640 {
@@ -629,7 +655,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, · 14 unmodified lines
629655
630656 unpack_scmi_header(msg_hdr, &xfer->hdr);
631657 if (priv)
632− xfer->priv = priv;
658+ /* Ensure order between xfer->priv store and following ops */
659+ smp_store_mb(xfer->priv, priv);
633660 info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
634661 xfer);
635662 scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
@@ -661,7 +688,8 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, · 25 unmodified lines
661688 xfer->rx.len = info->desc->max_msg_size;
662689
663690 if (priv)
664− xfer->priv = priv;
691+ /* Ensure order between xfer->priv store and following ops */
692+ smp_store_mb(xfer->priv, priv);
665693 info->desc->ops->fetch_response(cinfo, xfer);
666694
667695 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
@@ -724,8 +752,6 @@ static void xfer_put(const struct scmi_protocol_handle *ph, · 56 unmodified lines
724752 __scmi_xfer_put(&info->tx_minfo, xfer);
725753 }
726754
727−#define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC)
728−
729755 static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
730756 struct scmi_xfer *xfer, ktime_t stop)
731757 {
@@ -740,6 +766,79 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, · 8 unmodified lines
740766 ktime_after(ktime_get(), stop);
741767 }
742768
769+/**
770+ * scmi_wait_for_message_response - An helper to group all the possible ways of
771+ * waiting for a synchronous message response.
772+ *
773+ * @cinfo: SCMI channel info
774+ * @xfer: Reference to the transfer being waited for.
775+ *
776+ * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on
777+ * configuration flags like xfer->hdr.poll_completion.
778+ *
779+ * Return: 0 on Success, error otherwise.
780+ */
781+static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo,
782+ struct scmi_xfer *xfer)
783+{
784+ struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
785+ struct device *dev = info->dev;
786+ int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms;
787+
788+ trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id,
789+ xfer->hdr.protocol_id, xfer->hdr.seq,
790+ timeout_ms,
791+ xfer->hdr.poll_completion);
792+
793+ if (xfer->hdr.poll_completion) {
794+ /*
795+ * Real polling is needed only if transport has NOT declared
796+ * itself to support synchronous commands replies.
797+ */
798+ if (!info->desc->sync_cmds_completed_on_ret) {
799+ /*
800+ * Poll on xfer using transport provided .poll_done();
801+ * assumes no completion interrupt was available.
802+ */
803+ ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms);
804+
805+ spin_until_cond(scmi_xfer_done_no_timeout(cinfo,
806+ xfer, stop));
807+ if (ktime_after(ktime_get(), stop)) {
808+ dev_err(dev,
809+ "timed out in resp(caller: %pS) - polling\n",
810+ (void *)_RET_IP_);
811+ ret = -ETIMEDOUT;
812+ }
813+ }
814+
815+ if (!ret) {
816+ unsigned long flags;
817+
818+ /*
819+ * Do not fetch_response if an out-of-order delayed
820+ * response is being processed.
821+ */
822+ spin_lock_irqsave(&xfer->lock, flags);
823+ if (xfer->state == SCMI_XFER_SENT_OK) {
824+ info->desc->ops->fetch_response(cinfo, xfer);
825+ xfer->state = SCMI_XFER_RESP_OK;
826+ }
827+ spin_unlock_irqrestore(&xfer->lock, flags);
828+ }
829+ } else {
830+ /* And we wait for the response. */
831+ if (!wait_for_completion_timeout(&xfer->done,
832+ msecs_to_jiffies(timeout_ms))) {
833+ dev_err(dev, "timed out in resp(caller: %pS)\n",
834+ (void *)_RET_IP_);
835+ ret = -ETIMEDOUT;
836+ }
837+ }
838+
839+ return ret;
840+}
841+
743842 /**
744843 * do_xfer() - Do one transfer
745844 *
@@ -754,18 +853,26 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 8 unmodified lines
754853 struct scmi_xfer *xfer)
755854 {
756855 int ret;
757− int timeout;
758856 const struct scmi_protocol_instance *pi = ph_to_pi(ph);
759857 struct scmi_info *info = handle_to_scmi_info(pi->handle);
760858 struct device *dev = info->dev;
761859 struct scmi_chan_info *cinfo;
762860
763− if (xfer->hdr.poll_completion && !info->desc->ops->poll_done) {
861+ /* Check for polling request on custom command xfers at first */
862+ if (xfer->hdr.poll_completion && !is_transport_polling_capable(info)) {
764863 dev_warn_once(dev,
765864 "Polling mode is not supported by transport.\n");
766865 return -EINVAL;
767866 }
768867
868+ cinfo = idr_find(&info->tx_idr, pi->proto->id);
869+ if (unlikely(!cinfo))
870+ return -EINVAL;
871+
872+ /* True ONLY if also supported by transport. */
873+ if (is_polling_enabled(cinfo, info))
874+ xfer->hdr.poll_completion = true;
875+
769876 /*
770877 * Initialise protocol id now from protocol handle to avoid it being
771878 * overridden by mistake (or malice) by the protocol code mangling with
@@ -774,10 +881,6 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 2 unmodified lines
774881 xfer->hdr.protocol_id = pi->proto->id;
775882 reinit_completion(&xfer->done);
776883
777− cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
778− if (unlikely(!cinfo))
779− return -EINVAL;
780−
781884 trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
782885 xfer->hdr.protocol_id, xfer->hdr.seq,
783886 xfer->hdr.poll_completion);
@@ -798,41 +901,12 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 14 unmodified lines
798901 return ret;
799902 }
800903
801− if (xfer->hdr.poll_completion) {
802− ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS);
803−
804− spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop));
805− if (ktime_before(ktime_get(), stop)) {
806− unsigned long flags;
807−
808− /*
809− * Do not fetch_response if an out-of-order delayed
810− * response is being processed.
811− */
812− spin_lock_irqsave(&xfer->lock, flags);
813− if (xfer->state == SCMI_XFER_SENT_OK) {
814− info->desc->ops->fetch_response(cinfo, xfer);
815− xfer->state = SCMI_XFER_RESP_OK;
816− }
817− spin_unlock_irqrestore(&xfer->lock, flags);
818− } else {
819− ret = -ETIMEDOUT;
820− }
821− } else {
822− /* And we wait for the response. */
823− timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
824− if (!wait_for_completion_timeout(&xfer->done, timeout)) {
825− dev_err(dev, "timed out in resp(caller: %pS)\n",
826− (void *)_RET_IP_);
827− ret = -ETIMEDOUT;
828− }
829− }
830−
904+ ret = scmi_wait_for_message_response(cinfo, xfer);
831905 if (!ret && xfer->hdr.status)
832906 ret = scmi_to_linux_errno(xfer->hdr.status);
833907
834908 if (info->desc->ops->mark_txdone)
835− info->desc->ops->mark_txdone(cinfo, ret);
909+ info->desc->ops->mark_txdone(cinfo, ret, xfer);
836910
837911 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
838912 xfer->hdr.protocol_id, xfer->hdr.seq, ret);
@@ -858,6 +932,20 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph, · 19 unmodified lines
858932 * @ph: Pointer to SCMI protocol handle
859933 * @xfer: Transfer to initiate and wait for response
860934 *
935+ * Using asynchronous commands in atomic/polling mode should be avoided since
936+ * it could cause long busy-waiting here, so ignore polling for the delayed
937+ * response and WARN if it was requested for this command transaction since
938+ * upper layers should refrain from issuing such kind of requests.
939+ *
940+ * The only other option would have been to refrain from using any asynchronous
941+ * command even if made available, when an atomic transport is detected, and
942+ * instead forcibly use the synchronous version (thing that can be easily
943+ * attained at the protocol layer), but this would also have led to longer
944+ * stalls of the channel for synchronous commands and possibly timeouts.
945+ * (in other words there is usually a good reason if a platform provides an
946+ * asynchronous version of a command and we should prefer to use it...just not
947+ * when using atomic/polling mode)
948+ *
861949 * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
862950 * return corresponding error, else if all goes well, return 0.
863951 */
@@ -869,12 +957,24 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, · 5 unmodified lines
869957
870958 xfer->async_done = &async_response;
871959
960+ /*
961+ * Delayed responses should not be polled, so an async command should
962+ * not have been used when requiring an atomic/poll context; WARN and
963+ * perform instead a sleeping wait.
964+ * (Note Async + IgnoreDelayedResponses are sent via do_xfer)
965+ */
966+ WARN_ON_ONCE(xfer->hdr.poll_completion);
967+
872968 ret = do_xfer(ph, xfer);
873969 if (!ret) {
874− if (!wait_for_completion_timeout(xfer->async_done, timeout))
970+ if (!wait_for_completion_timeout(xfer->async_done, timeout)) {
971+ dev_err(ph->dev,
972+ "timed out in delayed resp(caller: %pS)\n",
973+ (void *)_RET_IP_);
875974 ret = -ETIMEDOUT;
876− else if (xfer->hdr.status)
975+ } else if (xfer->hdr.status) {
877976 ret = scmi_to_linux_errno(xfer->hdr.status);
977+ }
878978 }
879979
880980 xfer->async_done = NULL;
@@ -1308,6 +1408,29 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id) · 427 unmodified lines
13081408 WARN_ON(ret);
13091409 }
13101410
1411+/**
1412+ * scmi_is_transport_atomic - Method to check if underlying transport for an
1413+ * SCMI instance is configured as atomic.
1414+ *
1415+ * @handle: A reference to the SCMI platform instance.
1416+ * @atomic_threshold: An optional return value for the system wide currently
1417+ * configured threshold for atomic operations.
1418+ *
1419+ * Return: True if transport is configured as atomic
1420+ */
1421+static bool scmi_is_transport_atomic(const struct scmi_handle *handle,
1422+ unsigned int *atomic_threshold)
1423+{
1424+ bool ret;
1425+ struct scmi_info *info = handle_to_scmi_info(handle);
1426+
1427+ ret = info->desc->atomic_enabled && is_transport_polling_capable(info);
1428+ if (ret && atomic_threshold)
1429+ *atomic_threshold = info->atomic_threshold;
1430+
1431+ return ret;
1432+}
1433+
13111434 static inline
13121435 struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
13131436 {
@@ -1499,6 +1622,16 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, · 185 unmodified lines
14991622 if (ret)
15001623 return ret;
15011624
1625+ if (tx && is_polling_required(cinfo, info)) {
1626+ if (is_transport_polling_capable(info))
1627+ dev_info(dev,
1628+ "Enabled polling mode TX channel - prot_id:%d\n",
1629+ prot_id);
1630+ else
1631+ dev_warn(dev,
1632+ "Polling mode NOT supported by transport.\n");
1633+ }
1634+
15021635 idr_alloc:
15031636 ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
15041637 if (ret != prot_id) {
@@ -1836,6 +1969,14 @@ static int scmi_probe(struct platform_device *pdev) · 331 unmodified lines
18361969 handle->devm_protocol_get = scmi_devm_protocol_get;
18371970 handle->devm_protocol_put = scmi_devm_protocol_put;
18381971
1972+ /* System wide atomic threshold for atomic ops .. if any */
1973+ if (!of_property_read_u32(np, "atomic-threshold-us",
1974+ &info->atomic_threshold))
1975+ dev_info(dev,
1976+ "SCMI System wide atomic threshold set to %d us\n",
1977+ info->atomic_threshold);
1978+ handle->is_transport_atomic = scmi_is_transport_atomic;
1979+
18391980 if (desc->ops->link_supplier) {
18401981 ret = desc->ops->link_supplier(dev);
18411982 if (ret)
@@ -1853,6 +1994,10 @@ static int scmi_probe(struct platform_device *pdev) · 11 unmodified lines
18531994 if (scmi_notification_init(handle))
18541995 dev_err(dev, "SCMI Notifications NOT available.\n");
18551996
1997+ if (info->desc->atomic_enabled && !is_transport_polling_capable(info))
1998+ dev_err(dev,
1999+ "Transport is not polling capable. Atomic mode not supported.\n");
2000+
18562001 /*
18572002 * Trigger SCMI Base protocol initialization.
18582003 * It's mandatory and won't be ever released/deinit until the
@@ -1994,6 +2139,9 @@ static const struct of_device_id scmi_of_match[] = { · 135 unmodified lines
19942139 #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
19952140 { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
19962141 #endif
2142+#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
2143+ { .compatible = "linaro,scmi-optee", .data = &scmi_optee_desc },
2144+#endif
19972145 #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
19982146 { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
19992147 #endif
drivers/firmware/arm_scmi/mailbox.c+2−1
@@ -140,7 +140,8 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo, · 139 unmodified lines
140140 return ret;
141141 }
142142
143−static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)
143+static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
144+ struct scmi_xfer *__unused)
144145 {
145146 struct scmi_mailbox *smbox = cinfo->transport_info;
146147
drivers/firmware/arm_scmi/optee.c+567−0
@@ -0,0 +1,567 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2019-2021 Linaro Ltd.
4+ */
5+
6+#include <linux/io.h>
7+#include <linux/of.h>
8+#include <linux/of_address.h>
9+#include <linux/kernel.h>
10+#include <linux/module.h>
11+#include <linux/mutex.h>
12+#include <linux/slab.h>
13+#include <linux/tee_drv.h>
14+#include <linux/uuid.h>
15+#include <uapi/linux/tee.h>
16+
17+#include "common.h"
18+
19+#define SCMI_OPTEE_MAX_MSG_SIZE 128
20+
21+enum scmi_optee_pta_cmd {
22+ /*
23+ * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
24+ *
25+ * [out] value[0].a: Capability bit mask (enum pta_scmi_caps)
26+ * [out] value[0].b: Extended capabilities or 0
27+ */
28+ PTA_SCMI_CMD_CAPABILITIES = 0,
29+
30+ /*
31+ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer
32+ *
33+ * [in] value[0].a: Channel handle
34+ *
35+ * Shared memory used for SCMI message/response exhange is expected
36+ * already identified and bound to channel handle in both SCMI agent
37+ * and SCMI server (OP-TEE) parts.
38+ * The memory uses SMT header to carry SCMI meta-data (protocol ID and
39+ * protocol message ID).
40+ */
41+ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1,
42+
43+ /*
44+ * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message
45+ *
46+ * [in] value[0].a: Channel handle
47+ * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload)
48+ *
49+ * Shared memory used for SCMI message/response is a SMT buffer
50+ * referenced by param[1]. It shall be 128 bytes large to fit response
51+ * payload whatever message playload size.
52+ * The memory uses SMT header to carry SCMI meta-data (protocol ID and
53+ * protocol message ID).
54+ */
55+ PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2,
56+
57+ /*
58+ * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle
59+ *
60+ * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM
61+ *
62+ * [in] value[0].a: Channel identifier
63+ * [out] value[0].a: Returned channel handle
64+ * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps)
65+ */
66+ PTA_SCMI_CMD_GET_CHANNEL = 3,
67+};
68+
69+/*
70+ * OP-TEE SCMI service capabilities bit flags (32bit)
71+ *
72+ * PTA_SCMI_CAPS_SMT_HEADER
73+ * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in
74+ * shared memory buffers to carry SCMI protocol synchronisation information.
75+ */
76+#define PTA_SCMI_CAPS_NONE 0
77+#define PTA_SCMI_CAPS_SMT_HEADER BIT(0)
78+
79+/**
80+ * struct scmi_optee_channel - Description of an OP-TEE SCMI channel
81+ *
82+ * @channel_id: OP-TEE channel ID used for this transport
83+ * @tee_session: TEE session identifier
84+ * @caps: OP-TEE SCMI channel capabilities
85+ * @mu: Mutex protection on channel access
86+ * @cinfo: SCMI channel information
87+ * @shmem: Virtual base address of the shared memory
88+ * @tee_shm: Reference to TEE shared memory or NULL if using static shmem
89+ * @link: Reference in agent's channel list
90+ */
91+struct scmi_optee_channel {
92+ u32 channel_id;
93+ u32 tee_session;
94+ u32 caps;
95+ struct mutex mu;
96+ struct scmi_chan_info *cinfo;
97+ struct scmi_shared_mem __iomem *shmem;
98+ struct tee_shm *tee_shm;
99+ struct list_head link;
100+};
101+
102+/**
103+ * struct scmi_optee_agent - OP-TEE transport private data
104+ *
105+ * @dev: Device used for communication with TEE
106+ * @tee_ctx: TEE context used for communication
107+ * @caps: Supported channel capabilities
108+ * @mu: Mutex for protection of @channel_list
109+ * @channel_list: List of all created channels for the agent
110+ */
111+struct scmi_optee_agent {
112+ struct device *dev;
113+ struct tee_context *tee_ctx;
114+ u32 caps;
115+ struct mutex mu;
116+ struct list_head channel_list;
117+};
118+
119+/* There can be only 1 SCMI service in OP-TEE we connect to */
120+static struct scmi_optee_agent *scmi_optee_private;
121+
122+/* Forward reference to scmi_optee transport initialization */
123+static int scmi_optee_init(void);
124+
125+/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
126+static int open_session(struct scmi_optee_agent *agent, u32 *tee_session)
127+{
128+ struct device *dev = agent->dev;
129+ struct tee_client_device *scmi_pta = to_tee_client_device(dev);
130+ struct tee_ioctl_open_session_arg arg = { };
131+ int ret;
132+
133+ memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN);
134+ arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
135+
136+ ret = tee_client_open_session(agent->tee_ctx, &arg, NULL);
137+ if (ret < 0 || arg.ret) {
138+ dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret);
139+ return -EOPNOTSUPP;
140+ }
141+
142+ *tee_session = arg.session;
143+
144+ return 0;
145+}
146+
147+static void close_session(struct scmi_optee_agent *agent, u32 tee_session)
148+{
149+ tee_client_close_session(agent->tee_ctx, tee_session);
150+}
151+
152+static int get_capabilities(struct scmi_optee_agent *agent)
153+{
154+ struct tee_ioctl_invoke_arg arg = { };
155+ struct tee_param param[1] = { };
156+ u32 caps;
157+ u32 tee_session;
158+ int ret;
159+
160+ ret = open_session(agent, &tee_session);
161+ if (ret)
162+ return ret;
163+
164+ arg.func = PTA_SCMI_CMD_CAPABILITIES;
165+ arg.session = tee_session;
166+ arg.num_params = 1;
167+
168+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
169+
170+ ret = tee_client_invoke_func(agent->tee_ctx, &arg, param);
171+
172+ close_session(agent, tee_session);
173+
174+ if (ret < 0 || arg.ret) {
175+ dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret);
176+ return -EOPNOTSUPP;
177+ }
178+
179+ caps = param[0].u.value.a;
180+
181+ if (!(caps & PTA_SCMI_CAPS_SMT_HEADER)) {
182+ dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT\n");
183+ return -EOPNOTSUPP;
184+ }
185+
186+ agent->caps = caps;
187+
188+ return 0;
189+}
190+
191+static int get_channel(struct scmi_optee_channel *channel)
192+{
193+ struct device *dev = scmi_optee_private->dev;
194+ struct tee_ioctl_invoke_arg arg = { };
195+ struct tee_param param[1] = { };
196+ unsigned int caps = PTA_SCMI_CAPS_SMT_HEADER;
197+ int ret;
198+
199+ arg.func = PTA_SCMI_CMD_GET_CHANNEL;
200+ arg.session = channel->tee_session;
201+ arg.num_params = 1;
202+
203+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
204+ param[0].u.value.a = channel->channel_id;
205+ param[0].u.value.b = caps;
206+
207+ ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
208+
209+ if (ret || arg.ret) {
210+ dev_err(dev, "Can't get channel with caps %#x: %d / %#x\n", caps, ret, arg.ret);
211+ return -EOPNOTSUPP;
212+ }
213+
214+ /* From now on use channel identifer provided by OP-TEE SCMI service */
215+ channel->channel_id = param[0].u.value.a;
216+ channel->caps = caps;
217+
218+ return 0;
219+}
220+
221+static int invoke_process_smt_channel(struct scmi_optee_channel *channel)
222+{
223+ struct tee_ioctl_invoke_arg arg = { };
224+ struct tee_param param[2] = { };
225+ int ret;
226+
227+ arg.session = channel->tee_session;
228+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
229+ param[0].u.value.a = channel->channel_id;
230+
231+ if (channel->tee_shm) {
232+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
233+ param[1].u.memref.shm = channel->tee_shm;
234+ param[1].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE;
235+ arg.num_params = 2;
236+ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE;
237+ } else {
238+ arg.num_params = 1;
239+ arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL;
240+ }
241+
242+ ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
243+ if (ret < 0 || arg.ret) {
244+ dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
245+ channel->channel_id, ret, arg.ret);
246+ return -EIO;
247+ }
248+
249+ return 0;
250+}
251+
252+static int scmi_optee_link_supplier(struct device *dev)
253+{
254+ if (!scmi_optee_private) {
255+ if (scmi_optee_init())
256+ dev_dbg(dev, "Optee bus not yet ready\n");
257+
258+ /* Wait for optee bus */
259+ return -EPROBE_DEFER;
260+ }
261+
262+ if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
263+ dev_err(dev, "Adding link to supplier optee device failed\n");
264+ return -ECANCELED;
265+ }
266+
267+ return 0;
268+}
269+
270+static bool scmi_optee_chan_available(struct device *dev, int idx)
271+{
272+ u32 channel_id;
273+
274+ return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id",
275+ idx, &channel_id);
276+}
277+
278+static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo)
279+{
280+ struct scmi_optee_channel *channel = cinfo->transport_info;
281+
282+ shmem_clear_channel(channel->shmem);
283+}
284+
285+static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo,
286+ struct scmi_optee_channel *channel)
287+{
288+ struct device_node *np;
289+ resource_size_t size;
290+ struct resource res;
291+ int ret;
292+
293+ np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0);
294+ if (!of_device_is_compatible(np, "arm,scmi-shmem")) {
295+ ret = -ENXIO;
296+ goto out;
297+ }
298+
299+ ret = of_address_to_resource(np, 0, &res);
300+ if (ret) {
301+ dev_err(dev, "Failed to get SCMI Tx shared memory\n");
302+ goto out;
303+ }
304+
305+ size = resource_size(&res);
306+
307+ channel->shmem = devm_ioremap(dev, res.start, size);
308+ if (!channel->shmem) {
309+ dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n");
310+ ret = -EADDRNOTAVAIL;
311+ goto out;
312+ }
313+
314+ ret = 0;
315+
316+out:
317+ of_node_put(np);
318+
319+ return ret;
320+}
321+
322+static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo,
323+ struct scmi_optee_channel *channel)
324+{
325+ if (of_find_property(cinfo->dev->of_node, "shmem", NULL))
326+ return setup_static_shmem(dev, cinfo, channel);
327+ else
328+ return -ENOMEM;
329+}
330+
331+static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx)
332+{
333+ struct scmi_optee_channel *channel;
334+ uint32_t channel_id;
335+ int ret;
336+
337+ if (!tx)
338+ return -ENODEV;
339+
340+ channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
341+ if (!channel)
342+ return -ENOMEM;
343+
344+ ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id",
345+ 0, &channel_id);
346+ if (ret)
347+ return ret;
348+
349+ cinfo->transport_info = channel;
350+ channel->cinfo = cinfo;
351+ channel->channel_id = channel_id;
352+ mutex_init(&channel->mu);
353+
354+ ret = setup_shmem(dev, cinfo, channel);
355+ if (ret)
356+ return ret;
357+
358+ ret = open_session(scmi_optee_private, &channel->tee_session);
359+ if (ret)
360+ goto err_free_shm;
361+
362+ ret = get_channel(channel);
363+ if (ret)
364+ goto err_close_sess;
365+
366+ /* Enable polling */
367+ cinfo->no_completion_irq = true;
368+
369+ mutex_lock(&scmi_optee_private->mu);
370+ list_add(&channel->link, &scmi_optee_private->channel_list);
371+ mutex_unlock(&scmi_optee_private->mu);
372+
373+ return 0;
374+
375+err_close_sess:
376+ close_session(scmi_optee_private, channel->tee_session);
377+err_free_shm:
378+ if (channel->tee_shm)
379+ tee_shm_free(channel->tee_shm);
380+
381+ return ret;
382+}
383+
384+static int scmi_optee_chan_free(int id, void *p, void *data)
385+{
386+ struct scmi_chan_info *cinfo = p;
387+ struct scmi_optee_channel *channel = cinfo->transport_info;
388+
389+ mutex_lock(&scmi_optee_private->mu);
390+ list_del(&channel->link);
391+ mutex_unlock(&scmi_optee_private->mu);
392+
393+ close_session(scmi_optee_private, channel->tee_session);
394+
395+ if (channel->tee_shm) {
396+ tee_shm_free(channel->tee_shm);
397+ channel->tee_shm = NULL;
398+ }
399+
400+ cinfo->transport_info = NULL;
401+ channel->cinfo = NULL;
402+
403+ scmi_free_channel(cinfo, data, id);
404+
405+ return 0;
406+}
407+
408+static struct scmi_shared_mem *get_channel_shm(struct scmi_optee_channel *chan,
409+ struct scmi_xfer *xfer)
410+{
411+ if (!chan)
412+ return NULL;
413+
414+ return chan->shmem;
415+}
416+
417+
418+static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
419+ struct scmi_xfer *xfer)
420+{
421+ struct scmi_optee_channel *channel = cinfo->transport_info;
422+ struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer);
423+ int ret;
424+
425+ mutex_lock(&channel->mu);
426+ shmem_tx_prepare(shmem, xfer);
427+
428+ ret = invoke_process_smt_channel(channel);
429+ if (ret)
430+ mutex_unlock(&channel->mu);
431+
432+ return ret;
433+}
434+
435+static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
436+ struct scmi_xfer *xfer)
437+{
438+ struct scmi_optee_channel *channel = cinfo->transport_info;
439+ struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer);
440+
441+ shmem_fetch_response(shmem, xfer);
442+}
443+
444+static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,
445+ struct scmi_xfer *__unused)
446+{
447+ struct scmi_optee_channel *channel = cinfo->transport_info;
448+
449+ mutex_unlock(&channel->mu);
450+}
451+
452+static struct scmi_transport_ops scmi_optee_ops = {
453+ .link_supplier = scmi_optee_link_supplier,
454+ .chan_available = scmi_optee_chan_available,
455+ .chan_setup = scmi_optee_chan_setup,
456+ .chan_free = scmi_optee_chan_free,
457+ .send_message = scmi_optee_send_message,
458+ .mark_txdone = scmi_optee_mark_txdone,
459+ .fetch_response = scmi_optee_fetch_response,
460+ .clear_channel = scmi_optee_clear_channel,
461+};
462+
463+static int scmi_optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
464+{
465+ return ver->impl_id == TEE_IMPL_ID_OPTEE;
466+}
467+
468+static int scmi_optee_service_probe(struct device *dev)
469+{
470+ struct scmi_optee_agent *agent;
471+ struct tee_context *tee_ctx;
472+ int ret;
473+
474+ /* Only one SCMI OP-TEE device allowed */
475+ if (scmi_optee_private) {
476+ dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n");
477+ return -EBUSY;
478+ }
479+
480+ tee_ctx = tee_client_open_context(NULL, scmi_optee_ctx_match, NULL, NULL);
481+ if (IS_ERR(tee_ctx))
482+ return -ENODEV;
483+
484+ agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL);
485+ if (!agent) {
486+ ret = -ENOMEM;
487+ goto err;
488+ }
489+
490+ agent->dev = dev;
491+ agent->tee_ctx = tee_ctx;
492+ INIT_LIST_HEAD(&agent->channel_list);
493+ mutex_init(&agent->mu);
494+
495+ ret = get_capabilities(agent);
496+ if (ret)
497+ goto err;
498+
499+ /* Ensure agent resources are all visible before scmi_optee_private is */
500+ smp_mb();
501+ scmi_optee_private = agent;
502+
503+ return 0;
504+
505+err:
506+ tee_client_close_context(tee_ctx);
507+
508+ return ret;
509+}
510+
511+static int scmi_optee_service_remove(struct device *dev)
512+{
513+ struct scmi_optee_agent *agent = scmi_optee_private;
514+
515+ if (!scmi_optee_private)
516+ return -EINVAL;
517+
518+ if (!list_empty(&scmi_optee_private->channel_list))
519+ return -EBUSY;
520+
521+ /* Ensure cleared reference is visible before resources are released */
522+ smp_store_mb(scmi_optee_private, NULL);
523+
524+ tee_client_close_context(agent->tee_ctx);
525+
526+ return 0;
527+}
528+
529+static const struct tee_client_device_id scmi_optee_service_id[] = {
530+ {
531+ UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e,
532+ 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99)
533+ },
534+ { }
535+};
536+
537+MODULE_DEVICE_TABLE(tee, scmi_optee_service_id);
538+
539+static struct tee_client_driver scmi_optee_driver = {
540+ .id_table = scmi_optee_service_id,
541+ .driver = {
542+ .name = "scmi-optee",
543+ .bus = &tee_bus_type,
544+ .probe = scmi_optee_service_probe,
545+ .remove = scmi_optee_service_remove,
546+ },
547+};
548+
549+static int scmi_optee_init(void)
550+{
551+ return driver_register(&scmi_optee_driver.driver);
552+}
553+
554+static void scmi_optee_exit(void)
555+{
556+ if (scmi_optee_private)
557+ driver_unregister(&scmi_optee_driver.driver);
558+}
559+
560+const struct scmi_desc scmi_optee_desc = {
561+ .transport_exit = scmi_optee_exit,
562+ .ops = &scmi_optee_ops,
563+ .max_rx_timeout_ms = 30,
564+ .max_msg = 20,
565+ .max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE,
566+ .sync_cmds_completed_on_ret = true,
567+};
drivers/firmware/arm_scmi/smc.c+72−26
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 */
88
99 #include <linux/arm-smccc.h>
10+#include <linux/atomic.h>
1011 #include <linux/device.h>
1112 #include <linux/err.h>
1213 #include <linux/interrupt.h>
@@ -14,6 +15,7 @@ · 1 unmodified line
1415 #include <linux/of.h>
1516 #include <linux/of_address.h>
1617 #include <linux/of_irq.h>
18+#include <linux/processor.h>
1719 #include <linux/slab.h>
1820
1921 #include "common.h"
@@ -23,26 +25,29 @@ · 3 unmodified lines
2325 *
2426 * @cinfo: SCMI channel info
2527 * @shmem: Transmit/Receive shared memory area
26− * @shmem_lock: Lock to protect access to Tx/Rx shared memory area
28+ * @shmem_lock: Lock to protect access to Tx/Rx shared memory area.
29+ * Used when NOT operating in atomic mode.
30+ * @inflight: Atomic flag to protect access to Tx/Rx shared memory area.
31+ * Used when operating in atomic mode.
2732 * @func_id: smc/hvc call function id
28− * @irq: Optional; employed when platforms indicates msg completion by intr.
29− * @tx_complete: Optional, employed only when irq is valid.
3033 */
3134
3235 struct scmi_smc {
3336 struct scmi_chan_info *cinfo;
3437 struct scmi_shared_mem __iomem *shmem;
38+ /* Protect access to shmem area */
3539 struct mutex shmem_lock;
40+#define INFLIGHT_NONE MSG_TOKEN_MAX
41+ atomic_t inflight;
3642 u32 func_id;
37− int irq;
38− struct completion tx_complete;
3943 };
4044
4145 static irqreturn_t smc_msg_done_isr(int irq, void *data)
4246 {
4347 struct scmi_smc *scmi_info = data;
4448
45− complete(&scmi_info->tx_complete);
49+ scmi_rx_callback(scmi_info->cinfo,
50+ shmem_read_header(scmi_info->shmem), NULL);
4651
4752 return IRQ_HANDLED;
4853 }
@@ -57,6 +62,41 @@ static bool smc_chan_available(struct device *dev, int idx) · 8 unmodified lines
5762 return true;
5863 }
5964
65+static inline void smc_channel_lock_init(struct scmi_smc *scmi_info)
66+{
67+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
68+ atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
69+ else
70+ mutex_init(&scmi_info->shmem_lock);
71+}
72+
73+static bool smc_xfer_inflight(struct scmi_xfer *xfer, atomic_t *inflight)
74+{
75+ int ret;
76+
77+ ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq);
78+
79+ return ret == INFLIGHT_NONE;
80+}
81+
82+static inline void
83+smc_channel_lock_acquire(struct scmi_smc *scmi_info,
84+ struct scmi_xfer *xfer __maybe_unused)
85+{
86+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
87+ spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight));
88+ else
89+ mutex_lock(&scmi_info->shmem_lock);
90+}
91+
92+static inline void smc_channel_lock_release(struct scmi_smc *scmi_info)
93+{
94+ if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE))
95+ atomic_set(&scmi_info->inflight, INFLIGHT_NONE);
96+ else
97+ mutex_unlock(&scmi_info->shmem_lock);
98+}
99+
60100 static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
61101 bool tx)
62102 {
@@ -111,13 +151,13 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 48 unmodified lines
111151 dev_err(dev, "failed to setup SCMI smc irq\n");
112152 return ret;
113153 }
114− init_completion(&scmi_info->tx_complete);
115− scmi_info->irq = irq;
154+ } else {
155+ cinfo->no_completion_irq = true;
116156 }
117157
118158 scmi_info->func_id = func_id;
119159 scmi_info->cinfo = cinfo;
120− mutex_init(&scmi_info->shmem_lock);
160+ smc_channel_lock_init(scmi_info);
121161 cinfo->transport_info = scmi_info;
122162
123163 return 0;
@@ -142,26 +182,22 @@ static int smc_send_message(struct scmi_chan_info *cinfo, · 18 unmodified lines
142182 struct scmi_smc *scmi_info = cinfo->transport_info;
143183 struct arm_smccc_res res;
144184
145− mutex_lock(&scmi_info->shmem_lock);
185+ /*
186+ * Channel will be released only once response has been
187+ * surely fully retrieved, so after .mark_txdone()
188+ */
189+ smc_channel_lock_acquire(scmi_info, xfer);
146190
147191 shmem_tx_prepare(scmi_info->shmem, xfer);
148192
149− if (scmi_info->irq)
150− reinit_completion(&scmi_info->tx_complete);
151−
152193 arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
153194
154− if (scmi_info->irq)
155− wait_for_completion(&scmi_info->tx_complete);
156−
157− scmi_rx_callback(scmi_info->cinfo,
158− shmem_read_header(scmi_info->shmem), NULL);
159−
160− mutex_unlock(&scmi_info->shmem_lock);
161−
162195 /* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
163− if (res.a0)
196+ if (res.a0) {
197+ smc_channel_lock_release(scmi_info);
164198 return -EOPNOTSUPP;
199+ }
200+
165201 return 0;
166202 }
167203
@@ -173,12 +209,12 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo, · 5 unmodified lines
173209 shmem_fetch_response(scmi_info->shmem, xfer);
174210 }
175211
176−static bool
177−smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
212+static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret,
213+ struct scmi_xfer *__unused)
178214 {
179215 struct scmi_smc *scmi_info = cinfo->transport_info;
180216
181− return shmem_poll_done(scmi_info->shmem, xfer);
217+ smc_channel_lock_release(scmi_info);
182218 }
183219
184220 static const struct scmi_transport_ops scmi_smc_ops = {
@@ -186,8 +222,8 @@ static const struct scmi_transport_ops scmi_smc_ops = { · 1 unmodified line
186222 .chan_setup = smc_chan_setup,
187223 .chan_free = smc_chan_free,
188224 .send_message = smc_send_message,
225+ .mark_txdone = smc_mark_txdone,
189226 .fetch_response = smc_fetch_response,
190− .poll_done = smc_poll_done,
191227 };
192228
193229 const struct scmi_desc scmi_smc_desc = {
@@ -195,4 +231,14 @@ const struct scmi_desc scmi_smc_desc = { · 1 unmodified line
195231 .max_rx_timeout_ms = 30,
196232 .max_msg = 20,
197233 .max_msg_size = 128,
234+ /*
235+ * Setting .sync_cmds_atomic_replies to true for SMC assumes that,
236+ * once the SMC instruction has completed successfully, the issued
237+ * SCMI command would have been already fully processed by the SCMI
238+ * platform firmware and so any possible response value expected
239+ * for the issued command will be immmediately ready to be fetched
240+ * from the shared memory area.
241+ */
242+ .sync_cmds_completed_on_ret = true,
243+ .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE),
198244 };
drivers/firmware/arm_scmi/virtio.c+517−96
@@ -3,8 +3,8 @@ · 2 unmodified lines
33 * Virtio Transport driver for Arm System Control and Management Interface
44 * (SCMI).
55 *
6− * Copyright (C) 2020-2021 OpenSynergy.
7− * Copyright (C) 2021 ARM Ltd.
6+ * Copyright (C) 2020-2022 OpenSynergy.
7+ * Copyright (C) 2021-2022 ARM Ltd.
88 */
99
1010 /**
@@ -17,7 +17,9 @@ · 6 unmodified lines
1717 * virtqueue. Access to each virtqueue is protected by spinlocks.
1818 */
1919
20+#include <linux/completion.h>
2021 #include <linux/errno.h>
22+#include <linux/refcount.h>
2123 #include <linux/slab.h>
2224 #include <linux/virtio.h>
2325 #include <linux/virtio_config.h>
@@ -27,6 +29,7 @@ · 3 unmodified lines
2729
2830 #include "common.h"
2931
32+#define VIRTIO_MAX_RX_TIMEOUT_MS 60000
3033 #define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */
3134 #define VIRTIO_SCMI_MAX_PDU_SIZE \
3235 (VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)
@@ -37,25 +40,46 @@ · 4 unmodified lines
3740 *
3841 * @vqueue: Associated virtqueue
3942 * @cinfo: SCMI Tx or Rx channel
43+ * @free_lock: Protects access to the @free_list.
4044 * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
45+ * @deferred_tx_work: Worker for TX deferred replies processing
46+ * @deferred_tx_wq: Workqueue for TX deferred replies
47+ * @pending_lock: Protects access to the @pending_cmds_list.
48+ * @pending_cmds_list: List of pre-fetched commands queueud for later processing
4149 * @is_rx: Whether channel is an Rx channel
42− * @ready: Whether transport user is ready to hear about channel
4350 * @max_msg: Maximum number of pending messages for this channel.
44− * @lock: Protects access to all members except ready.
45− * @ready_lock: Protects access to ready. If required, it must be taken before
46− * lock.
51+ * @lock: Protects access to all members except users, free_list and
52+ * pending_cmds_list.
53+ * @shutdown_done: A reference to a completion used when freeing this channel.
54+ * @users: A reference count to currently active users of this channel.
4755 */
4856 struct scmi_vio_channel {
4957 struct virtqueue *vqueue;
5058 struct scmi_chan_info *cinfo;
59+ /* lock to protect access to the free list. */
60+ spinlock_t free_lock;
5161 struct list_head free_list;
62+ /* lock to protect access to the pending list. */
63+ spinlock_t pending_lock;
64+ struct list_head pending_cmds_list;
65+ struct work_struct deferred_tx_work;
66+ struct workqueue_struct *deferred_tx_wq;
5267 bool is_rx;
53− bool ready;
5468 unsigned int max_msg;
55− /* lock to protect access to all members except ready. */
69+ /*
70+ * Lock to protect access to all members except users, free_list and
71+ * pending_cmds_list
72+ */
5673 spinlock_t lock;
57− /* lock to rotects access to ready flag. */
58− spinlock_t ready_lock;
74+ struct completion *shutdown_done;
75+ refcount_t users;
76+};
77+
78+enum poll_states {
79+ VIO_MSG_NOT_POLLED,
80+ VIO_MSG_POLL_TIMEOUT,
81+ VIO_MSG_POLLING,
82+ VIO_MSG_POLL_DONE,
5983 };
6084
6185 /**
@@ -65,29 +89,154 @@ struct scmi_vio_channel { · 3 unmodified lines
6589 * @input: SDU used for (delayed) responses and notifications
6690 * @list: List which scmi_vio_msg may be part of
6791 * @rx_len: Input SDU size in bytes, once input has been received
92+ * @poll_idx: Last used index registered for polling purposes if this message
93+ * transaction reply was configured for polling.
94+ * @poll_status: Polling state for this message.
95+ * @poll_lock: A lock to protect @poll_status
96+ * @users: A reference count to track this message users and avoid premature
97+ * freeing (and reuse) when polling and IRQ execution paths interleave.
6898 */
6999 struct scmi_vio_msg {
70100 struct scmi_msg_payld *request;
71101 struct scmi_msg_payld *input;
72102 struct list_head list;
73103 unsigned int rx_len;
104+ unsigned int poll_idx;
105+ enum poll_states poll_status;
106+ /* Lock to protect access to poll_status */
107+ spinlock_t poll_lock;
108+ refcount_t users;
74109 };
75110
76111 /* Only one SCMI VirtIO device can possibly exist */
77112 static struct virtio_device *scmi_vdev;
78113
114+static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch,
115+ struct scmi_chan_info *cinfo)
116+{
117+ unsigned long flags;
118+
119+ spin_lock_irqsave(&vioch->lock, flags);
120+ cinfo->transport_info = vioch;
121+ /* Indirectly setting channel not available any more */
122+ vioch->cinfo = cinfo;
123+ spin_unlock_irqrestore(&vioch->lock, flags);
124+
125+ refcount_set(&vioch->users, 1);
126+}
127+
128+static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch)
129+{
130+ return refcount_inc_not_zero(&vioch->users);
131+}
132+
133+static inline void scmi_vio_channel_release(struct scmi_vio_channel *vioch)
134+{
135+ if (refcount_dec_and_test(&vioch->users)) {
136+ unsigned long flags;
137+
138+ spin_lock_irqsave(&vioch->lock, flags);
139+ if (vioch->shutdown_done) {
140+ vioch->cinfo = NULL;
141+ complete(vioch->shutdown_done);
142+ }
143+ spin_unlock_irqrestore(&vioch->lock, flags);
144+ }
145+}
146+
147+static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
148+{
149+ unsigned long flags;
150+ DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done);
151+ void *deferred_wq = NULL;
152+
153+ /*
154+ * Prepare to wait for the last release if not already released
155+ * or in progress.
156+ */
157+ spin_lock_irqsave(&vioch->lock, flags);
158+ if (!vioch->cinfo || vioch->shutdown_done) {
159+ spin_unlock_irqrestore(&vioch->lock, flags);
160+ return;
161+ }
162+
163+ vioch->shutdown_done = &vioch_shutdown_done;
164+ virtio_break_device(vioch->vqueue->vdev);
165+ if (!vioch->is_rx && vioch->deferred_tx_wq) {
166+ deferred_wq = vioch->deferred_tx_wq;
167+ /* Cannot be kicked anymore after this...*/
168+ vioch->deferred_tx_wq = NULL;
169+ }
170+ spin_unlock_irqrestore(&vioch->lock, flags);
171+
172+ if (deferred_wq)
173+ destroy_workqueue(deferred_wq);
174+
175+ scmi_vio_channel_release(vioch);
176+
177+ /* Let any possibly concurrent RX path release the channel */
178+ wait_for_completion(vioch->shutdown_done);
179+}
180+
181+/* Assumes to be called with vio channel acquired already */
182+static struct scmi_vio_msg *
183+scmi_virtio_get_free_msg(struct scmi_vio_channel *vioch)
184+{
185+ unsigned long flags;
186+ struct scmi_vio_msg *msg;
187+
188+ spin_lock_irqsave(&vioch->free_lock, flags);
189+ if (list_empty(&vioch->free_list)) {
190+ spin_unlock_irqrestore(&vioch->free_lock, flags);
191+ return NULL;
192+ }
193+
194+ msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
195+ list_del_init(&msg->list);
196+ spin_unlock_irqrestore(&vioch->free_lock, flags);
197+
198+ /* Still no users, no need to acquire poll_lock */
199+ msg->poll_status = VIO_MSG_NOT_POLLED;
200+ refcount_set(&msg->users, 1);
201+
202+ return msg;
203+}
204+
205+static inline bool scmi_vio_msg_acquire(struct scmi_vio_msg *msg)
206+{
207+ return refcount_inc_not_zero(&msg->users);
208+}
209+
210+/* Assumes to be called with vio channel acquired already */
211+static inline bool scmi_vio_msg_release(struct scmi_vio_channel *vioch,
212+ struct scmi_vio_msg *msg)
213+{
214+ bool ret;
215+
216+ ret = refcount_dec_and_test(&msg->users);
217+ if (ret) {
218+ unsigned long flags;
219+
220+ spin_lock_irqsave(&vioch->free_lock, flags);
221+ list_add_tail(&msg->list, &vioch->free_list);
222+ spin_unlock_irqrestore(&vioch->free_lock, flags);
223+ }
224+
225+ return ret;
226+}
227+
79228 static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
80229 {
81230 return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
82231 }
83232
84233 static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
85− struct scmi_vio_msg *msg,
86− struct device *dev)
234+ struct scmi_vio_msg *msg)
87235 {
88236 struct scatterlist sg_in;
89237 int rc;
90238 unsigned long flags;
239+ struct device *dev = &vioch->vqueue->vdev->dev;
91240
92241 sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
93242
@@ -95,7 +244,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, · 1 unmodified line
95244
96245 rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
97246 if (rc)
98− dev_err_once(dev, "failed to add to virtqueue (%d)\n", rc);
247+ dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
99248 else
100249 virtqueue_kick(vioch->vqueue);
101250
@@ -104,22 +253,22 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, · 2 unmodified lines
104253 return rc;
105254 }
106255
256+/*
257+ * Assume to be called with channel already acquired or not ready at all;
258+ * vioch->lock MUST NOT have been already acquired.
259+ */
107260 static void scmi_finalize_message(struct scmi_vio_channel *vioch,
108261 struct scmi_vio_msg *msg)
109262 {
110− if (vioch->is_rx) {
111− scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
112− } else {
113− /* Here IRQs are assumed to be already disabled by the caller */
114− spin_lock(&vioch->lock);
115− list_add(&msg->list, &vioch->free_list);
116− spin_unlock(&vioch->lock);
117− }
263+ if (vioch->is_rx)
264+ scmi_vio_feed_vq_rx(vioch, msg);
265+ else
266+ scmi_vio_msg_release(vioch, msg);
118267 }
119268
120269 static void scmi_vio_complete_cb(struct virtqueue *vqueue)
121270 {
122− unsigned long ready_flags;
271+ unsigned long flags;
123272 unsigned int length;
124273 struct scmi_vio_channel *vioch;
125274 struct scmi_vio_msg *msg;
@@ -130,27 +279,25 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue) · 4 unmodified lines
130279 vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];
131280
132281 for (;;) {
133− spin_lock_irqsave(&vioch->ready_lock, ready_flags);
282+ if (!scmi_vio_channel_acquire(vioch))
283+ return;
134284
135− if (!vioch->ready) {
136− if (!cb_enabled)
137− (void)virtqueue_enable_cb(vqueue);
138− goto unlock_ready_out;
139− }
140−
141− /* IRQs already disabled here no need to irqsave */
142− spin_lock(&vioch->lock);
285+ spin_lock_irqsave(&vioch->lock, flags);
143286 if (cb_enabled) {
144287 virtqueue_disable_cb(vqueue);
145288 cb_enabled = false;
146289 }
290+
147291 msg = virtqueue_get_buf(vqueue, &length);
148292 if (!msg) {
149− if (virtqueue_enable_cb(vqueue))
150− goto unlock_out;
293+ if (virtqueue_enable_cb(vqueue)) {
294+ spin_unlock_irqrestore(&vioch->lock, flags);
295+ scmi_vio_channel_release(vioch);
296+ return;
297+ }
151298 cb_enabled = true;
152299 }
153− spin_unlock(&vioch->lock);
300+ spin_unlock_irqrestore(&vioch->lock, flags);
154301
155302 if (msg) {
156303 msg->rx_len = length;
@@ -161,19 +308,57 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue) · 4 unmodified lines
161308 }
162309
163310 /*
164− * Release ready_lock and re-enable IRQs between loop iterations
165− * to allow virtio_chan_free() to possibly kick in and set the
166− * flag vioch->ready to false even in between processing of
167− * messages, so as to force outstanding messages to be ignored
168− * when system is shutting down.
311+ * Release vio channel between loop iterations to allow
312+ * virtio_chan_free() to eventually fully release it when
313+ * shutting down; in such a case, any outstanding message will
314+ * be ignored since this loop will bail out at the next
315+ * iteration.
316+ */
317+ scmi_vio_channel_release(vioch);
318+ }
319+}
320+
321+static void scmi_vio_deferred_tx_worker(struct work_struct *work)
322+{
323+ unsigned long flags;
324+ struct scmi_vio_channel *vioch;
325+ struct scmi_vio_msg *msg, *tmp;
326+
327+ vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
328+
329+ if (!scmi_vio_channel_acquire(vioch))
330+ return;
331+
332+ /*
333+ * Process pre-fetched messages: these could be non-polled messages or
334+ * late timed-out replies to polled messages dequeued by chance while
335+ * polling for some other messages: this worker is in charge to process
336+ * the valid non-expired messages and anyway finally free all of them.
337+ */
338+ spin_lock_irqsave(&vioch->pending_lock, flags);
339+
340+ /* Scan the list of possibly pre-fetched messages during polling. */
341+ list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
342+ list_del(&msg->list);
343+
344+ /*
345+ * Channel is acquired here (cannot vanish) and this message
346+ * is no more processed elsewhere so no poll_lock needed.
169347 */
170− spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
348+ if (msg->poll_status == VIO_MSG_NOT_POLLED)
349+ scmi_rx_callback(vioch->cinfo,
350+ msg_read_header(msg->input), msg);
351+
352+ /* Free the processed message once done */
353+ scmi_vio_msg_release(vioch, msg);
171354 }
172355
173−unlock_out:
174− spin_unlock(&vioch->lock);
175−unlock_ready_out:
176− spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
356+ spin_unlock_irqrestore(&vioch->pending_lock, flags);
357+
358+ /* Process possibly still pending messages */
359+ scmi_vio_complete_cb(vioch->vqueue);
360+
361+ scmi_vio_channel_release(vioch);
177362 }
178363
179364 static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
@@ -193,8 +378,8 @@ static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo) · 13 unmodified lines
193378 static int virtio_link_supplier(struct device *dev)
194379 {
195380 if (!scmi_vdev) {
196− dev_notice_once(dev,
197− "Deferring probe after not finding a bound scmi-virtio device\n");
381+ dev_notice(dev,
382+ "Deferring probe after not finding a bound scmi-virtio device\n");
198383 return -EPROBE_DEFER;
199384 }
200385
@@ -234,7 +419,6 @@ static bool virtio_chan_available(struct device *dev, int idx) · 33 unmodified lines
234419 static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
235420 bool tx)
236421 {
237− unsigned long flags;
238422 struct scmi_vio_channel *vioch;
239423 int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;
240424 int i;
@@ -244,6 +428,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 3 unmodified lines
244428
245429 vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
246430
431+ /* Setup a deferred worker for polling. */
432+ if (tx && !vioch->deferred_tx_wq) {
433+ vioch->deferred_tx_wq =
434+ alloc_workqueue(dev_name(&scmi_vdev->dev),
435+ WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
436+ 0);
437+ if (!vioch->deferred_tx_wq)
438+ return -ENOMEM;
439+
440+ INIT_WORK(&vioch->deferred_tx_work,
441+ scmi_vio_deferred_tx_worker);
442+ }
443+
247444 for (i = 0; i < vioch->max_msg; i++) {
248445 struct scmi_vio_msg *msg;
249446
@@ -257,6 +454,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 7 unmodified lines
257454 GFP_KERNEL);
258455 if (!msg->request)
259456 return -ENOMEM;
457+ spin_lock_init(&msg->poll_lock);
458+ refcount_set(&msg->users, 1);
260459 }
261460
262461 msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
@@ -264,44 +463,23 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 1 unmodified line
264463 if (!msg->input)
265464 return -ENOMEM;
266465
267− if (tx) {
268− spin_lock_irqsave(&vioch->lock, flags);
269− list_add_tail(&msg->list, &vioch->free_list);
270− spin_unlock_irqrestore(&vioch->lock, flags);
271− } else {
272− scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
273− }
466+ scmi_finalize_message(vioch, msg);
274467 }
275468
276− spin_lock_irqsave(&vioch->lock, flags);
277− cinfo->transport_info = vioch;
278− /* Indirectly setting channel not available any more */
279− vioch->cinfo = cinfo;
280− spin_unlock_irqrestore(&vioch->lock, flags);
281−
282− spin_lock_irqsave(&vioch->ready_lock, flags);
283− vioch->ready = true;
284− spin_unlock_irqrestore(&vioch->ready_lock, flags);
469+ scmi_vio_channel_ready(vioch, cinfo);
285470
286471 return 0;
287472 }
288473
289474 static int virtio_chan_free(int id, void *p, void *data)
290475 {
291− unsigned long flags;
292476 struct scmi_chan_info *cinfo = p;
293477 struct scmi_vio_channel *vioch = cinfo->transport_info;
294478
295− spin_lock_irqsave(&vioch->ready_lock, flags);
296− vioch->ready = false;
297− spin_unlock_irqrestore(&vioch->ready_lock, flags);
479+ scmi_vio_channel_cleanup_sync(vioch);
298480
299481 scmi_free_channel(cinfo, data, id);
300482
301− spin_lock_irqsave(&vioch->lock, flags);
302− vioch->cinfo = NULL;
303− spin_unlock_irqrestore(&vioch->lock, flags);
304−
305483 return 0;
306484 }
307485
@@ -316,33 +494,56 @@ static int virtio_send_message(struct scmi_chan_info *cinfo, · 8 unmodified lines
316494 int rc;
317495 struct scmi_vio_msg *msg;
318496
319− spin_lock_irqsave(&vioch->lock, flags);
497+ if (!scmi_vio_channel_acquire(vioch))
498+ return -EINVAL;
320499
321− if (list_empty(&vioch->free_list)) {
322− spin_unlock_irqrestore(&vioch->lock, flags);
500+ msg = scmi_virtio_get_free_msg(vioch);
501+ if (!msg) {
502+ scmi_vio_channel_release(vioch);
323503 return -EBUSY;
324504 }
325505
326− msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
327− list_del(&msg->list);
328−
329506 msg_tx_prepare(msg->request, xfer);
330507
331508 sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
332509 sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
333510
511+ spin_lock_irqsave(&vioch->lock, flags);
512+
513+ /*
514+ * If polling was requested for this transaction:
515+ * - retrieve last used index (will be used as polling reference)
516+ * - bind the polled message to the xfer via .priv
517+ * - grab an additional msg refcount for the poll-path
518+ */
519+ if (xfer->hdr.poll_completion) {
520+ msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
521+ /* Still no users, no need to acquire poll_lock */
522+ msg->poll_status = VIO_MSG_POLLING;
523+ scmi_vio_msg_acquire(msg);
524+ /* Ensure initialized msg is visibly bound to xfer */
525+ smp_store_mb(xfer->priv, msg);
526+ }
527+
334528 rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
335− if (rc) {
336− list_add(&msg->list, &vioch->free_list);
337− dev_err_once(vioch->cinfo->dev,
338− "%s() failed to add to virtqueue (%d)\n", __func__,
339− rc);
340− } else {
529+ if (rc)
530+ dev_err(vioch->cinfo->dev,
531+ "failed to add to TX virtqueue (%d)\n", rc);
532+ else
341533 virtqueue_kick(vioch->vqueue);
342− }
343534
344535 spin_unlock_irqrestore(&vioch->lock, flags);
345536
537+ if (rc) {
538+ /* Ensure order between xfer->priv clear and vq feeding */
539+ smp_store_mb(xfer->priv, NULL);
540+ if (xfer->hdr.poll_completion)
541+ scmi_vio_msg_release(vioch, msg);
542+ scmi_vio_msg_release(vioch, msg);
543+ }
544+
545+ scmi_vio_channel_release(vioch);
546+
346547 return rc;
347548 }
348549
@@ -351,10 +552,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo, · 2 unmodified lines
351552 {
352553 struct scmi_vio_msg *msg = xfer->priv;
353554
354− if (msg) {
555+ if (msg)
355556 msg_fetch_response(msg->input, msg->rx_len, xfer);
356− xfer->priv = NULL;
357− }
358557 }
359558
360559 static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
@@ -362,10 +561,225 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo, · 1 unmodified line
362561 {
363562 struct scmi_vio_msg *msg = xfer->priv;
364563
365− if (msg) {
564+ if (msg)
366565 msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
367− xfer->priv = NULL;
566+}
567+
568+/**
569+ * virtio_mark_txdone - Mark transmission done
570+ *
571+ * Free only completed polling transfer messages.
572+ *
573+ * Note that in the SCMI VirtIO transport we never explicitly release still
574+ * outstanding but timed-out messages by forcibly re-adding them to the
575+ * free-list inside the TX code path; we instead let IRQ/RX callbacks, or the
576+ * TX deferred worker, eventually clean up such messages once, finally, a late
577+ * reply is received and discarded (if ever).
578+ *
579+ * This approach was deemed preferable since those pending timed-out buffers are
580+ * still effectively owned by the SCMI platform VirtIO device even after timeout
581+ * expiration: forcibly freeing and reusing them before they had been returned
582+ * explicitly by the SCMI platform could lead to subtle bugs due to message
583+ * corruption.
584+ * An SCMI platform VirtIO device which never returns message buffers is
585+ * anyway broken and it will quickly lead to exhaustion of available messages.
586+ *
587+ * For this same reason, here, we take care to free only the polled messages
588+ * that had been somehow replied (only if not by chance already processed on the
589+ * IRQ path - the initial scmi_vio_msg_release() takes care of this) and also
590+ * any timed-out polled message if that indeed appears to have been at least
591+ * dequeued from the virtqueues (VIO_MSG_POLL_DONE): this is needed since such
592+ * messages won't be freed elsewhere. Any other polled message is marked as
593+ * VIO_MSG_POLL_TIMEOUT.
594+ *
595+ * Possible late replies to timed-out polled messages will be eventually freed
596+ * by RX callbacks if delivered on the IRQ path or by the deferred TX worker if
597+ * dequeued on some other polling path.
598+ *
599+ * @cinfo: SCMI channel info
600+ * @ret: Transmission return code
601+ * @xfer: Transfer descriptor
602+ */
603+static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
604+ struct scmi_xfer *xfer)
605+{
606+ unsigned long flags;
607+ struct scmi_vio_channel *vioch = cinfo->transport_info;
608+ struct scmi_vio_msg *msg = xfer->priv;
609+
610+ if (!msg || !scmi_vio_channel_acquire(vioch))
611+ return;
612+
613+ /* Ensure msg is unbound from xfer anyway at this point */
614+ smp_store_mb(xfer->priv, NULL);
615+
616+ /* Must be a polled xfer and not already freed on the IRQ path */
617+ if (!xfer->hdr.poll_completion || scmi_vio_msg_release(vioch, msg)) {
618+ scmi_vio_channel_release(vioch);
619+ return;
368620 }
621+
622+ spin_lock_irqsave(&msg->poll_lock, flags);
623+ /* Do not free timedout polled messages only if still inflight */
624+ if (ret != -ETIMEDOUT || msg->poll_status == VIO_MSG_POLL_DONE)
625+ scmi_vio_msg_release(vioch, msg);
626+ else if (msg->poll_status == VIO_MSG_POLLING)
627+ msg->poll_status = VIO_MSG_POLL_TIMEOUT;
628+ spin_unlock_irqrestore(&msg->poll_lock, flags);
629+
630+ scmi_vio_channel_release(vioch);
631+}
632+
633+/**
634+ * virtio_poll_done - Provide polling support for VirtIO transport
635+ *
636+ * @cinfo: SCMI channel info
637+ * @xfer: Reference to the transfer being poll for.
638+ *
639+ * VirtIO core provides a polling mechanism based only on last used indexes:
640+ * this means that it is possible to poll the virtqueues waiting for something
641+ * new to arrive from the host side, but the only way to check if the freshly
642+ * arrived buffer was indeed what we were waiting for is to compare the newly
643+ * arrived message descriptor with the one we are polling on.
644+ *
645+ * As a consequence it can happen to dequeue something different from the buffer
646+ * we were poll-waiting for: if that is the case such early fetched buffers are
647+ * then added to a the @pending_cmds_list list for later processing by a
648+ * dedicated deferred worker.
649+ *
650+ * So, basically, once something new is spotted we proceed to de-queue all the
651+ * freshly received used buffers until we found the one we were polling on, or,
652+ * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
653+ * in the vqueue at the end of the polling loop (possible due to inherent races
654+ * in virtqueues handling mechanisms), we similarly kick the deferred worker
655+ * and let it process those, to avoid indefinitely looping in the .poll_done
656+ * busy-waiting helper.
657+ *
658+ * Finally, we delegate to the deferred worker also the final free of any timed
659+ * out reply to a polled message that we should dequeue.
660+ *
661+ * Note that, since we do NOT have per-message suppress notification mechanism,
662+ * the message we are polling for could be alternatively delivered via usual
663+ * IRQs callbacks on another core which happened to have IRQs enabled while we
664+ * are actively polling for it here: in such a case it will be handled as such
665+ * by scmi_rx_callback() and the polling loop in the SCMI Core TX path will be
666+ * transparently terminated anyway.
667+ *
668+ * Return: True once polling has successfully completed.
669+ */
670+static bool virtio_poll_done(struct scmi_chan_info *cinfo,
671+ struct scmi_xfer *xfer)
672+{
673+ bool pending, found = false;
674+ unsigned int length, any_prefetched = 0;
675+ unsigned long flags;
676+ struct scmi_vio_msg *next_msg, *msg = xfer->priv;
677+ struct scmi_vio_channel *vioch = cinfo->transport_info;
678+
679+ if (!msg)
680+ return true;
681+
682+ /*
683+ * Processed already by other polling loop on another CPU ?
684+ *
685+ * Note that this message is acquired on the poll path so cannot vanish
686+ * while inside this loop iteration even if concurrently processed on
687+ * the IRQ path.
688+ *
689+ * Avoid to acquire poll_lock since polled_status can be changed
690+ * in a relevant manner only later in this same thread of execution:
691+ * any other possible changes made concurrently by other polling loops
692+ * or by a reply delivered on the IRQ path have no meaningful impact on
693+ * this loop iteration: in other words it is harmless to allow this
694+ * possible race but let has avoid spinlocking with irqs off in this
695+ * initial part of the polling loop.
696+ */
697+ if (msg->poll_status == VIO_MSG_POLL_DONE)
698+ return true;
699+
700+ if (!scmi_vio_channel_acquire(vioch))
701+ return true;
702+
703+ /* Has cmdq index moved at all ? */
704+ pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
705+ if (!pending) {
706+ scmi_vio_channel_release(vioch);
707+ return false;
708+ }
709+
710+ spin_lock_irqsave(&vioch->lock, flags);
711+ virtqueue_disable_cb(vioch->vqueue);
712+
713+ /*
714+ * Process all new messages till the polled-for message is found OR
715+ * the vqueue is empty.
716+ */
717+ while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
718+ bool next_msg_done = false;
719+
720+ /*
721+ * Mark any dequeued buffer message as VIO_MSG_POLL_DONE so
722+ * that can be properly freed even on timeout in mark_txdone.
723+ */
724+ spin_lock(&next_msg->poll_lock);
725+ if (next_msg->poll_status == VIO_MSG_POLLING) {
726+ next_msg->poll_status = VIO_MSG_POLL_DONE;
727+ next_msg_done = true;
728+ }
729+ spin_unlock(&next_msg->poll_lock);
730+
731+ next_msg->rx_len = length;
732+ /* Is the message we were polling for ? */
733+ if (next_msg == msg) {
734+ found = true;
735+ break;
736+ } else if (next_msg_done) {
737+ /* Skip the rest if this was another polled msg */
738+ continue;
739+ }
740+
741+ /*
742+ * Enqueue for later processing any non-polled message and any
743+ * timed-out polled one that we happen to have dequeued.
744+ */
745+ spin_lock(&next_msg->poll_lock);
746+ if (next_msg->poll_status == VIO_MSG_NOT_POLLED ||
747+ next_msg->poll_status == VIO_MSG_POLL_TIMEOUT) {
748+ spin_unlock(&next_msg->poll_lock);
749+
750+ any_prefetched++;
751+ spin_lock(&vioch->pending_lock);
752+ list_add_tail(&next_msg->list,
753+ &vioch->pending_cmds_list);
754+ spin_unlock(&vioch->pending_lock);
755+ } else {
756+ spin_unlock(&next_msg->poll_lock);
757+ }
758+ }
759+
760+ /*
761+ * When the polling loop has successfully terminated if something
762+ * else was queued in the meantime, it will be served by a deferred
763+ * worker OR by the normal IRQ/callback OR by other poll loops.
764+ *
765+ * If we are still looking for the polled reply, the polling index has
766+ * to be updated to the current vqueue last used index.
767+ */
768+ if (found) {
769+ pending = !virtqueue_enable_cb(vioch->vqueue);
770+ } else {
771+ msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
772+ pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
773+ }
774+
775+ if (vioch->deferred_tx_wq && (any_prefetched || pending))
776+ queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);
777+
778+ spin_unlock_irqrestore(&vioch->lock, flags);
779+
780+ scmi_vio_channel_release(vioch);
781+
782+ return found;
369783 }
370784
371785 static const struct scmi_transport_ops scmi_virtio_ops = {
@@ -377,6 +791,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = { · 5 unmodified lines
377791 .send_message = virtio_send_message,
378792 .fetch_response = virtio_fetch_response,
379793 .fetch_notification = virtio_fetch_notification,
794+ .mark_txdone = virtio_mark_txdone,
795+ .poll_done = virtio_poll_done,
380796 };
381797
382798 static int scmi_vio_probe(struct virtio_device *vdev)
@@ -417,8 +833,10 @@ static int scmi_vio_probe(struct virtio_device *vdev) · 34 unmodified lines
417833 unsigned int sz;
418834
419835 spin_lock_init(&channels[i].lock);
420− spin_lock_init(&channels[i].ready_lock);
836+ spin_lock_init(&channels[i].free_lock);
421837 INIT_LIST_HEAD(&channels[i].free_list);
838+ spin_lock_init(&channels[i].pending_lock);
839+ INIT_LIST_HEAD(&channels[i].pending_cmds_list);
422840 channels[i].vqueue = vqs[i];
423841
424842 sz = virtqueue_get_vring_size(channels[i].vqueue);
@@ -427,10 +845,10 @@ static int scmi_vio_probe(struct virtio_device *vdev) · 2 unmodified lines
427845 sz /= DESCRIPTORS_PER_TX_MSG;
428846
429847 if (sz > MSG_TOKEN_MAX) {
430− dev_info_once(dev,
431− "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
432− channels[i].is_rx ? "rx" : "tx",
433− sz, MSG_TOKEN_MAX);
848+ dev_info(dev,
849+ "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
850+ channels[i].is_rx ? "rx" : "tx",
851+ sz, MSG_TOKEN_MAX);
434852 sz = MSG_TOKEN_MAX;
435853 }
436854 channels[i].max_msg = sz;
@@ -460,12 +878,13 @@ static void scmi_vio_remove(struct virtio_device *vdev) · 23 unmodified lines
460878
461879 static int scmi_vio_validate(struct virtio_device *vdev)
462880 {
881+#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
463882 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
464883 dev_err(&vdev->dev,
465884 "device does not comply with spec version 1.x\n");
466885 return -EINVAL;
467886 }
468−
887+#endif
469888 return 0;
470889 }
471890
@@ -503,7 +922,9 @@ const struct scmi_desc scmi_virtio_desc = { · 31 unmodified lines
503922 .transport_init = virtio_scmi_init,
504923 .transport_exit = virtio_scmi_exit,
505924 .ops = &scmi_virtio_ops,
506− .max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
925+ /* for non-realtime virtio devices */
926+ .max_rx_timeout_ms = VIRTIO_MAX_RX_TIMEOUT_MS,
507927 .max_msg = 0, /* overridden by virtio_get_max_msg() */
508928 .max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
929+ .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
509930 };
drivers/firmware/imx/rm.c+45−0
@@ -43,3 +43,48 @@ bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource) · 42 unmodified lines
4343 return hdr->func;
4444 }
4545 EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
46+
47+struct imx_sc_msg_rm_get_resource_owner {
48+ struct imx_sc_rpc_msg hdr;
49+ union {
50+ struct {
51+ u16 resource;
52+ } req;
53+ struct {
54+ u8 val;
55+ } resp;
56+ } data;
57+} __packed __aligned(4);
58+
59+/*
60+ * This function get @resource partition number
61+ *
62+ * @param[in] ipc IPC handle
63+ * @param[in] resource resource the control is associated with
64+ * @param[out] pt pointer to return the partition number
65+ *
66+ * @return Returns 0 for success and < 0 for errors.
67+ */
68+int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
69+{
70+ struct imx_sc_msg_rm_get_resource_owner msg;
71+ struct imx_sc_rpc_msg *hdr = &msg.hdr;
72+ int ret;
73+
74+ hdr->ver = IMX_SC_RPC_VERSION;
75+ hdr->svc = IMX_SC_RPC_SVC_RM;
76+ hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER;
77+ hdr->size = 2;
78+
79+ msg.data.req.resource = resource;
80+
81+ ret = imx_scu_call_rpc(ipc, &msg, true);
82+ if (ret)
83+ return ret;
84+
85+ if (pt)
86+ *pt = msg.data.resp.val;
87+
88+ return 0;
89+}
90+EXPORT_SYMBOL(imx_sc_rm_get_resource_owner);
drivers/firmware/imx/scu-pd.c+4−0
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = { · 154 unmodified lines
155155 { "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
156156 { "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
157157 { "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
158+ { "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
159+ { "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
160+ { "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
161+ { "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
158162
159163 /* GPU SS */
160164 { "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
drivers/firmware/qcom_scm.c+119−96
@@ -49,26 +49,12 @@ struct qcom_scm_mem_map_info { · 48 unmodified lines
4949 __le64 mem_size;
5050 };
5151
52−#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x00
53−#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01
54−#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08
55−#define QCOM_SCM_FLAG_COLDBOOT_CPU3 0x20
56−
57−#define QCOM_SCM_FLAG_WARMBOOT_CPU0 0x04
58−#define QCOM_SCM_FLAG_WARMBOOT_CPU1 0x02
59−#define QCOM_SCM_FLAG_WARMBOOT_CPU2 0x10
60−#define QCOM_SCM_FLAG_WARMBOOT_CPU3 0x40
61−
62−struct qcom_scm_wb_entry {
63− int flag;
64− void *entry;
52+/* Each bit configures cold/warm boot address for one of the 4 CPUs */
53+static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
54+ 0, BIT(0), BIT(3), BIT(5)
6555 };
66−
67−static struct qcom_scm_wb_entry qcom_scm_wb[] = {
68− { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 },
69− { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 },
70− { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 },
71− { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
56+static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
57+ BIT(2), BIT(1), BIT(4), BIT(6)
7258 };
7359
7460 static const char * const qcom_scm_convention_names[] = {
@@ -179,9 +165,8 @@ found: · 104 unmodified lines
179165 /**
180166 * qcom_scm_call() - Invoke a syscall in the secure world
181167 * @dev: device
182− * @svc_id: service identifier
183− * @cmd_id: command identifier
184168 * @desc: Descriptor structure containing arguments and return values
169+ * @res: Structure containing results from SMC/HVC call
185170 *
186171 * Sends a command to the SCM and waits for the command to finish processing.
187172 * This should *only* be called in pre-emptible context.
@@ -205,8 +190,6 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, · 17 unmodified lines
205190 /**
206191 * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
207192 * @dev: device
208− * @svc_id: service identifier
209− * @cmd_id: command identifier
210193 * @desc: Descriptor structure containing arguments and return values
211194 * @res: Structure containing results from SMC/HVC call
212195 *
@@ -260,97 +243,83 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id, · 47 unmodified lines
260243 return ret ? false : !!res.result[0];
261244 }
262245
263−/**
264− * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
265− * @entry: Entry point function for the cpus
266− * @cpus: The cpumask of cpus that will use the entry point
267− *
268− * Set the Linux entry point for the SCM to transfer control to when coming
269− * out of a power down. CPU power down may be executed on cpuidle or hotplug.
270− */
271−int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
246+static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits)
272247 {
273− int ret;
274− int flags = 0;
275248 int cpu;
249+ unsigned int flags = 0;
276250 struct qcom_scm_desc desc = {
277251 .svc = QCOM_SCM_SVC_BOOT,
278252 .cmd = QCOM_SCM_BOOT_SET_ADDR,
279253 .arginfo = QCOM_SCM_ARGS(2),
254+ .owner = ARM_SMCCC_OWNER_SIP,
280255 };
281256
282− /*
283− * Reassign only if we are switching from hotplug entry point
284− * to cpuidle entry point or vice versa.
285− */
286− for_each_cpu(cpu, cpus) {
287− if (entry == qcom_scm_wb[cpu].entry)
288− continue;
289− flags |= qcom_scm_wb[cpu].flag;
257+ for_each_present_cpu(cpu) {
258+ if (cpu >= QCOM_SCM_BOOT_MAX_CPUS)
259+ return -EINVAL;
260+ flags |= cpu_bits[cpu];
290261 }
291262
292− /* No change in entry function */
293− if (!flags)
294− return 0;
295−
296263 desc.args[0] = flags;
297264 desc.args[1] = virt_to_phys(entry);
298265
299− ret = qcom_scm_call(__scm->dev, &desc, NULL);
300− if (!ret) {
301− for_each_cpu(cpu, cpus)
302− qcom_scm_wb[cpu].entry = entry;
303− }
304−
305− return ret;
266+ return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
306267 }
307−EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
308268
309−/**
310− * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
311− * @entry: Entry point function for the cpus
312− * @cpus: The cpumask of cpus that will use the entry point
313− *
314− * Set the cold boot address of the cpus. Any cpu outside the supported
315− * range would be removed from the cpu present mask.
316− */
317−int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
269+static int qcom_scm_set_boot_addr_mc(void *entry, unsigned int flags)
318270 {
319− int flags = 0;
320− int cpu;
321− int scm_cb_flags[] = {
322− QCOM_SCM_FLAG_COLDBOOT_CPU0,
323− QCOM_SCM_FLAG_COLDBOOT_CPU1,
324− QCOM_SCM_FLAG_COLDBOOT_CPU2,
325− QCOM_SCM_FLAG_COLDBOOT_CPU3,
326− };
327271 struct qcom_scm_desc desc = {
328272 .svc = QCOM_SCM_SVC_BOOT,
329− .cmd = QCOM_SCM_BOOT_SET_ADDR,
330− .arginfo = QCOM_SCM_ARGS(2),
273+ .cmd = QCOM_SCM_BOOT_SET_ADDR_MC,
331274 .owner = ARM_SMCCC_OWNER_SIP,
275+ .arginfo = QCOM_SCM_ARGS(6),
276+ .args = {
277+ virt_to_phys(entry),
278+ /* Apply to all CPUs in all affinity levels */
279+ ~0ULL, ~0ULL, ~0ULL, ~0ULL,
280+ flags,
281+ },
332282 };
333283
334− if (!cpus || cpumask_empty(cpus))
335− return -EINVAL;
284+ /* Need a device for DMA of the additional arguments */
285+ if (!__scm || __get_convention() == SMC_CONVENTION_LEGACY)
286+ return -EOPNOTSUPP;
336287
337− for_each_cpu(cpu, cpus) {
338− if (cpu < ARRAY_SIZE(scm_cb_flags))
339− flags |= scm_cb_flags[cpu];
340− else
341− set_cpu_present(cpu, false);
342− }
288+ return qcom_scm_call(__scm->dev, &desc, NULL);
289+}
343290
344− desc.args[0] = flags;
345− desc.args[1] = virt_to_phys(entry);
291+/**
292+ * qcom_scm_set_warm_boot_addr() - Set the warm boot address for all cpus
293+ * @entry: Entry point function for the cpus
294+ *
295+ * Set the Linux entry point for the SCM to transfer control to when coming
296+ * out of a power down. CPU power down may be executed on cpuidle or hotplug.
297+ */
298+int qcom_scm_set_warm_boot_addr(void *entry)
299+{
300+ if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_WARMBOOT))
301+ /* Fallback to old SCM call */
302+ return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_warm_bits);
303+ return 0;
304+}
305+EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
346306
347− return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
307+/**
308+ * qcom_scm_set_cold_boot_addr() - Set the cold boot address for all cpus
309+ * @entry: Entry point function for the cpus
310+ */
311+int qcom_scm_set_cold_boot_addr(void *entry)
312+{
313+ if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_COLDBOOT))
314+ /* Fallback to old SCM call */
315+ return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_cold_bits);
316+ return 0;
348317 }
349318 EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
350319
351320 /**
352321 * qcom_scm_cpu_power_down() - Power down the cpu
353− * @flags - Flags to flush cache
322+ * @flags: Flags to flush cache
354323 *
355324 * This is an end point to power down cpu. If there was a pending interrupt,
356325 * the control would return from this function, otherwise, the cpu jumps to the
@@ -435,10 +404,16 @@ static void qcom_scm_set_download_mode(bool enable) · 78 unmodified lines
435404 * and optional blob of data used for authenticating the metadata
436405 * and the rest of the firmware
437406 * @size: size of the metadata
407+ * @ctx: optional metadata context
438408 *
439− * Returns 0 on success.
409+ * Return: 0 on success.
410+ *
411+ * Upon successful return, the PAS metadata context (@ctx) will be used to
412+ * track the metadata allocation, this needs to be released by invoking
413+ * qcom_scm_pas_metadata_release() by the caller.
440414 */
441−int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
415+int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
416+ struct qcom_scm_pas_metadata *ctx)
442417 {
443418 dma_addr_t mdata_phys;
444419 void *mdata_buf;
@@ -467,7 +442,7 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) · 22 unmodified lines
467442
468443 ret = qcom_scm_clk_enable();
469444 if (ret)
470− goto free_metadata;
445+ goto out;
471446
472447 desc.args[1] = mdata_phys;
473448
@@ -475,13 +450,36 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) · 1 unmodified line
475450
476451 qcom_scm_clk_disable();
477452
478−free_metadata:
479− dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
453+out:
454+ if (ret < 0 || !ctx) {
455+ dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
456+ } else if (ctx) {
457+ ctx->ptr = mdata_buf;
458+ ctx->phys = mdata_phys;
459+ ctx->size = size;
460+ }
480461
481462 return ret ? : res.result[0];
482463 }
483464 EXPORT_SYMBOL(qcom_scm_pas_init_image);
484465
466+/**
467+ * qcom_scm_pas_metadata_release() - release metadata context
468+ * @ctx: metadata context
469+ */
470+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
471+{
472+ if (!ctx->ptr)
473+ return;
474+
475+ dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
476+
477+ ctx->ptr = NULL;
478+ ctx->phys = 0;
479+ ctx->size = 0;
480+}
481+EXPORT_SYMBOL(qcom_scm_pas_metadata_release);
482+
485483 /**
486484 * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
487485 * for firmware loading
@@ -749,12 +747,6 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) · 261 unmodified lines
749747 };
750748 int ret;
751749
752− desc.args[0] = addr;
753− desc.args[1] = size;
754− desc.args[2] = spare;
755− desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL,
756− QCOM_SCM_VAL);
757−
758750 ret = qcom_scm_call(__scm->dev, &desc, NULL);
759751
760752 /* the pg table has been initialized already, ignore the error */
@@ -765,6 +757,21 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) · 4 unmodified lines
765757 }
766758 EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
767759
760+int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size)
761+{
762+ struct qcom_scm_desc desc = {
763+ .svc = QCOM_SCM_SVC_MP,
764+ .cmd = QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE,
765+ .arginfo = QCOM_SCM_ARGS(2),
766+ .args[0] = size,
767+ .args[1] = spare,
768+ .owner = ARM_SMCCC_OWNER_SIP,
769+ };
770+
771+ return qcom_scm_call(__scm->dev, &desc, NULL);
772+}
773+EXPORT_SYMBOL(qcom_scm_iommu_set_cp_pool_size);
774+
768775 int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
769776 u32 cp_nonpixel_start,
770777 u32 cp_nonpixel_size)
@@ -1131,6 +1138,22 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) · 360 unmodified lines
11311138 }
11321139 EXPORT_SYMBOL(qcom_scm_hdcp_req);
11331140
1141+int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt)
1142+{
1143+ struct qcom_scm_desc desc = {
1144+ .svc = QCOM_SCM_SVC_SMMU_PROGRAM,
1145+ .cmd = QCOM_SCM_SMMU_PT_FORMAT,
1146+ .arginfo = QCOM_SCM_ARGS(3),
1147+ .args[0] = sec_id,
1148+ .args[1] = ctx_num,
1149+ .args[2] = pt_fmt, /* 0: LPAE AArch32 - 1: AArch64 */
1150+ .owner = ARM_SMCCC_OWNER_SIP,
1151+ };
1152+
1153+ return qcom_scm_call(__scm->dev, &desc, NULL);
1154+}
1155+EXPORT_SYMBOL(qcom_scm_iommu_set_pt_format);
1156+
11341157 int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
11351158 {
11361159 struct qcom_scm_desc desc = {
drivers/firmware/qcom_scm.h+7−0
@@ -78,8 +78,13 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, · 77 unmodified lines
7878 #define QCOM_SCM_BOOT_SET_ADDR 0x01
7979 #define QCOM_SCM_BOOT_TERMINATE_PC 0x02
8080 #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
81+#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
8182 #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
8283 #define QCOM_SCM_FLUSH_FLAG_MASK 0x3
84+#define QCOM_SCM_BOOT_MAX_CPUS 4
85+#define QCOM_SCM_BOOT_MC_FLAG_AARCH64 BIT(0)
86+#define QCOM_SCM_BOOT_MC_FLAG_COLDBOOT BIT(1)
87+#define QCOM_SCM_BOOT_MC_FLAG_WARMBOOT BIT(2)
8388
8489 #define QCOM_SCM_SVC_PIL 0x02
8590 #define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x01
@@ -100,6 +105,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, · 14 unmodified lines
100105 #define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02
101106 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03
102107 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04
108+#define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05
103109 #define QCOM_SCM_MP_VIDEO_VAR 0x08
104110 #define QCOM_SCM_MP_ASSIGN 0x16
105111
@@ -119,6 +125,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, · 13 unmodified lines
119125 #define QCOM_SCM_LMH_LIMIT_DCVSH 0x10
120126
121127 #define QCOM_SCM_SVC_SMMU_PROGRAM 0x15
128+#define QCOM_SCM_SMMU_PT_FORMAT 0x01
122129 #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03
123130 #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02
124131
drivers/firmware/ti_sci.c+1−1
@@ -3412,7 +3412,7 @@ static int ti_sci_probe(struct platform_device *pdev) · 3411 unmodified lines
34123412 ret = register_restart_handler(&info->nb);
34133413 if (ret) {
34143414 dev_err(dev, "reboot registration fail(%d)\n", ret);
3415− return ret;
3415+ goto out;
34163416 }
34173417 }
34183418
drivers/memory/brcmstb_dpfe.c+1−1
@@ -424,7 +424,7 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv) · 423 unmodified lines
424424
425425 /*
426426 * It depends on the API version which MBOX register we have to write to
427− * to signal we are done.
427+ * signal we are done.
428428 */
429429 release_mbox = (priv->dpfe_api->version < 2)
430430 ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX;
drivers/memory/emif.c+5−3
@@ -1025,7 +1025,7 @@ static struct emif_data *__init_or_module get_device_details( · 1024 unmodified lines
10251025 temp = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
10261026 dev_info = devm_kzalloc(dev, sizeof(*dev_info), GFP_KERNEL);
10271027
1028− if (!emif || !pd || !dev_info) {
1028+ if (!emif || !temp || !dev_info) {
10291029 dev_err(dev, "%s:%d: allocation error\n", __func__, __LINE__);
10301030 goto error;
10311031 }
@@ -1117,7 +1117,7 @@ static int __init_or_module emif_probe(struct platform_device *pdev) · 85 unmodified lines
11171117 {
11181118 struct emif_data *emif;
11191119 struct resource *res;
1120− int irq;
1120+ int irq, ret;
11211121
11221122 if (pdev->dev.of_node)
11231123 emif = of_get_memory_device_details(pdev->dev.of_node, &pdev->dev);
@@ -1147,7 +1147,9 @@ static int __init_or_module emif_probe(struct platform_device *pdev) · 23 unmodified lines
11471147 emif_onetime_settings(emif);
11481148 emif_debugfs_init(emif);
11491149 disable_and_clear_all_interrupts(emif);
1150− setup_interrupts(emif, irq);
1150+ ret = setup_interrupts(emif, irq);
1151+ if (ret)
1152+ goto error;
11511153
11521154 /* One-time actions taken on probing the first device */
11531155 if (!emif1) {
drivers/memory/fsl_ifc.c+9−0
@@ -88,6 +88,7 @@ static int fsl_ifc_ctrl_remove(struct platform_device *dev) · 87 unmodified lines
8888 {
8989 struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(&dev->dev);
9090
91+ of_platform_depopulate(&dev->dev);
9192 free_irq(ctrl->nand_irq, ctrl);
9293 free_irq(ctrl->irq, ctrl);
9394
@@ -285,8 +286,16 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) · 191 unmodified lines
285286 }
286287 }
287288
289+ /* legacy dts may still use "simple-bus" compatible */
290+ ret = of_platform_populate(dev->dev.of_node, NULL, NULL,
291+ &dev->dev);
292+ if (ret)
293+ goto err_free_nandirq;
294+
288295 return 0;
289296
297+err_free_nandirq:
298+ free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev);
290299 err_free_irq:
291300 free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev);
292301 err_unmap_nandirq:
drivers/memory/mtk-smi.c+53−4
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/device.h>
99 #include <linux/err.h>
1010 #include <linux/io.h>
11+#include <linux/iopoll.h>
1112 #include <linux/module.h>
1213 #include <linux/of.h>
1314 #include <linux/of_platform.h>
@@ -32,6 +33,10 @@ · 18 unmodified lines
3233 #define SMI_DUMMY 0x444
3334
3435 /* SMI LARB */
36+#define SMI_LARB_SLP_CON 0xc
37+#define SLP_PROT_EN BIT(0)
38+#define SLP_PROT_RDY BIT(16)
39+
3540 #define SMI_LARB_CMD_THRT_CON 0x24
3641 #define SMI_LARB_THRT_RD_NU_LMT_MSK GENMASK(7, 4)
3742 #define SMI_LARB_THRT_RD_NU_LMT (5 << 4)
@@ -81,6 +86,7 @@ · 43 unmodified lines
8186
8287 #define MTK_SMI_FLAG_THRT_UPDATE BIT(0)
8388 #define MTK_SMI_FLAG_SW_FLAG BIT(1)
89+#define MTK_SMI_FLAG_SLEEP_CTL BIT(2)
8490 #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x)))
8591
8692 struct mtk_smi_reg_pair {
@@ -94,8 +100,6 @@ enum mtk_smi_type { · 7 unmodified lines
94100 MTK_SMI_GEN2_SUB_COMM, /* gen2 smi sub common */
95101 };
96102
97−#define MTK_SMI_CLK_NR_MAX 4
98−
99103 /* larbs: Require apb/smi clocks while gals is optional. */
100104 static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"};
101105 #define MTK_SMI_LARB_REQ_CLK_NR 2
@@ -106,6 +110,7 @@ static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"}; · 4 unmodified lines
106110 * sub common: Require apb/smi/gals0 clocks in has_gals case. Otherwise, only apb/smi are required.
107111 */
108112 static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"};
113+#define MTK_SMI_CLK_NR_MAX ARRAY_SIZE(mtk_smi_common_clks)
109114 #define MTK_SMI_COM_REQ_CLK_NR 2
110115 #define MTK_SMI_COM_GALS_REQ_CLK_NR MTK_SMI_CLK_NR_MAX
111116 #define MTK_SMI_SUB_COM_GALS_REQ_CLK_NR 3
@@ -335,13 +340,19 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = { · 223 unmodified lines
335340 /* IPU0 | IPU1 | CCU */
336341 };
337342
343+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
344+ .config_port = mtk_smi_larb_config_port_gen2_general,
345+ .flags_general = MTK_SMI_FLAG_SLEEP_CTL,
346+};
347+
338348 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
339349 .config_port = mtk_smi_larb_config_port_gen2_general,
340350 };
341351
342352 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
343353 .config_port = mtk_smi_larb_config_port_gen2_general,
344− .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG,
354+ .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG |
355+ MTK_SMI_FLAG_SLEEP_CTL,
345356 .ostd = mtk_smi_larb_mt8195_ostd,
346357 };
347358
@@ -352,11 +363,32 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { · 4 unmodified lines
352363 {.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
353364 {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
354365 {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
366+ {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
355367 {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
356368 {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
357369 {}
358370 };
359371
372+static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
373+{
374+ int ret;
375+ u32 tmp;
376+
377+ writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON);
378+ ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON,
379+ tmp, !!(tmp & SLP_PROT_RDY), 10, 1000);
380+ if (ret) {
381+ /* TODO: Reset this larb if it fails here. */
382+ dev_err(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp);
383+ }
384+ return ret;
385+}
386+
387+static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb)
388+{
389+ writel_relaxed(0, larb->base + SMI_LARB_SLP_CON);
390+}
391+
360392 static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
361393 {
362394 struct platform_device *smi_com_pdev;
@@ -466,9 +498,12 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) · 103 unmodified lines
466498 int ret;
467499
468500 ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
469− if (ret < 0)
501+ if (ret)
470502 return ret;
471503
504+ if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
505+ mtk_smi_larb_sleep_ctrl_disable(larb);
506+
472507 /* Configure the basic setting for this larb */
473508 larb_gen->config_port(dev);
474509
@@ -478,6 +513,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) · 3 unmodified lines
478513 static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
479514 {
480515 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
516+ int ret;
517+
518+ if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL)) {
519+ ret = mtk_smi_larb_sleep_ctrl_enable(larb);
520+ if (ret)
521+ return ret;
522+ }
481523
482524 clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
483525 return 0;
@@ -530,6 +572,12 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = { · 46 unmodified lines
530572 F_MMU1_LARB(7),
531573 };
532574
575+static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = {
576+ .type = MTK_SMI_GEN2,
577+ .has_gals = true,
578+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7),
579+};
580+
533581 static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
534582 .type = MTK_SMI_GEN2,
535583 .has_gals = true,
@@ -564,6 +612,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { · 28 unmodified lines
564612 {.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
565613 {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
566614 {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
615+ {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
567616 {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
568617 {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
569618 {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
drivers/memory/of_memory.c+19−10
@@ -212,8 +212,10 @@ static int of_lpddr3_do_get_timings(struct device_node *np, · 211 unmodified lines
212212 {
213213 int ret;
214214
215− /* The 'reg' param required since DT has changed, used as 'max-freq' */
216− ret = of_property_read_u32(np, "reg", &tim->max_freq);
215+ ret = of_property_read_u32(np, "max-freq", &tim->max_freq);
216+ if (ret)
217+ /* Deprecated way of passing max-freq as 'reg' */
218+ ret = of_property_read_u32(np, "reg", &tim->max_freq);
217219 ret |= of_property_read_u32(np, "min-freq", &tim->min_freq);
218220 ret |= of_property_read_u32(np, "tRFC", &tim->tRFC);
219221 ret |= of_property_read_u32(np, "tRRD", &tim->tRRD);
@@ -316,14 +318,21 @@ const struct lpddr2_info · 96 unmodified lines
316318 struct property *prop;
317319 const char *cp;
318320 int err;
319−
320− err = of_property_read_u32(np, "revision-id1", &info.revision_id1);
321− if (err)
322− info.revision_id1 = -ENOENT;
323−
324− err = of_property_read_u32(np, "revision-id2", &info.revision_id2);
325− if (err)
326− info.revision_id2 = -ENOENT;
321+ u32 revision_id[2];
322+
323+ err = of_property_read_u32_array(np, "revision-id", revision_id, 2);
324+ if (!err) {
325+ info.revision_id1 = revision_id[0];
326+ info.revision_id2 = revision_id[1];
327+ } else {
328+ err = of_property_read_u32(np, "revision-id1", &info.revision_id1);
329+ if (err)
330+ info.revision_id1 = -ENOENT;
331+
332+ err = of_property_read_u32(np, "revision-id2", &info.revision_id2);
333+ if (err)
334+ info.revision_id2 = -ENOENT;
335+ }
327336
328337 err = of_property_read_u32(np, "io-width", &info.io_width);
329338 if (err)
drivers/memory/tegra/Kconfig+1−0
@@ -28,6 +28,7 @@ config TEGRA30_EMC · 27 unmodified lines
2828 default y
2929 depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
3030 select PM_OPP
31+ select DDR
3132 help
3233 This driver is for the External Memory Controller (EMC) found on
3334 Tegra30 chips. The EMC controls the external DRAM on the board.
drivers/memory/tegra/tegra20-emc.c+1−1
@@ -540,7 +540,7 @@ static int emc_read_lpddr_mode_register(struct tegra_emc *emc, · 539 unmodified lines
540540 unsigned int register_addr,
541541 unsigned int *register_data)
542542 {
543− u32 memory_dev = emem_dev + 1;
543+ u32 memory_dev = emem_dev ? 1 : 2;
544544 u32 val, mr_mask = 0xff;
545545 int err;
546546
drivers/memory/tegra/tegra210-emc-core.c+1−1
@@ -711,7 +711,7 @@ static int tegra210_emc_cd_set_state(struct thermal_cooling_device *cd, · 710 unmodified lines
711711 return 0;
712712 }
713713
714−static struct thermal_cooling_device_ops tegra210_emc_cd_ops = {
714+static const struct thermal_cooling_device_ops tegra210_emc_cd_ops = {
715715 .get_max_state = tegra210_emc_cd_max_state,
716716 .get_cur_state = tegra210_emc_cd_get_state,
717717 .set_cur_state = tegra210_emc_cd_set_state,
drivers/memory/tegra/tegra30-emc.c+121−10
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 * Copyright (C) 2019 GRATE-DRIVER project
1010 */
1111
12+#include <linux/bitfield.h>
1213 #include <linux/clk.h>
1314 #include <linux/clk/tegra.h>
1415 #include <linux/debugfs.h>
@@ -31,11 +32,15 @@ · 16 unmodified lines
3132 #include <soc/tegra/common.h>
3233 #include <soc/tegra/fuse.h>
3334
35+#include "../jedec_ddr.h"
36+#include "../of_memory.h"
37+
3438 #include "mc.h"
3539
3640 #define EMC_INTSTATUS 0x000
3741 #define EMC_INTMASK 0x004
3842 #define EMC_DBG 0x008
43+#define EMC_ADR_CFG 0x010
3944 #define EMC_CFG 0x00c
4045 #define EMC_REFCTRL 0x020
4146 #define EMC_TIMING_CONTROL 0x028
@@ -81,6 +86,7 @@ · 39 unmodified lines
8186 #define EMC_EMRS 0x0d0
8287 #define EMC_SELF_REF 0x0e0
8388 #define EMC_MRW 0x0e8
89+#define EMC_MRR 0x0ec
8490 #define EMC_XM2DQSPADCTRL3 0x0f8
8591 #define EMC_FBIO_SPARE 0x100
8692 #define EMC_FBIO_CFG5 0x104
@@ -208,6 +214,13 @@ · 121 unmodified lines
208214
209215 #define EMC_REFRESH_OVERFLOW_INT BIT(3)
210216 #define EMC_CLKCHANGE_COMPLETE_INT BIT(4)
217+#define EMC_MRR_DIVLD_INT BIT(5)
218+
219+#define EMC_MRR_DEV_SELECTN GENMASK(31, 30)
220+#define EMC_MRR_MRR_MA GENMASK(23, 16)
221+#define EMC_MRR_MRR_DATA GENMASK(15, 0)
222+
223+#define EMC_ADR_CFG_EMEM_NUMDEV BIT(0)
211224
212225 enum emc_dram_type {
213226 DRAM_TYPE_DDR3,
@@ -378,6 +391,8 @@ struct tegra_emc { · 164 unmodified lines
378391
379392 /* protect shared rate-change code path */
380393 struct mutex rate_lock;
394+
395+ bool mrr_error;
381396 };
382397
383398 static int emc_seq_update_timing(struct tegra_emc *emc)
@@ -1008,12 +1023,18 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc, · 624 unmodified lines
10081023 return 0;
10091024 }
10101025
1011−static struct device_node *emc_find_node_by_ram_code(struct device *dev)
1026+static struct device_node *emc_find_node_by_ram_code(struct tegra_emc *emc)
10121027 {
1028+ struct device *dev = emc->dev;
10131029 struct device_node *np;
10141030 u32 value, ram_code;
10151031 int err;
10161032
1033+ if (emc->mrr_error) {
1034+ dev_warn(dev, "memory timings skipped due to MRR error\n");
1035+ return NULL;
1036+ }
1037+
10171038 if (of_get_child_count(dev->of_node) == 0) {
10181039 dev_info_once(dev, "device-tree doesn't have memory timings\n");
10191040 return NULL;
@@ -1035,11 +1056,73 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev) · 15 unmodified lines
10351056 return NULL;
10361057 }
10371058
1059+static int emc_read_lpddr_mode_register(struct tegra_emc *emc,
1060+ unsigned int emem_dev,
1061+ unsigned int register_addr,
1062+ unsigned int *register_data)
1063+{
1064+ u32 memory_dev = emem_dev ? 1 : 2;
1065+ u32 val, mr_mask = 0xff;
1066+ int err;
1067+
1068+ /* clear data-valid interrupt status */
1069+ writel_relaxed(EMC_MRR_DIVLD_INT, emc->regs + EMC_INTSTATUS);
1070+
1071+ /* issue mode register read request */
1072+ val = FIELD_PREP(EMC_MRR_DEV_SELECTN, memory_dev);
1073+ val |= FIELD_PREP(EMC_MRR_MRR_MA, register_addr);
1074+
1075+ writel_relaxed(val, emc->regs + EMC_MRR);
1076+
1077+ /* wait for the LPDDR2 data-valid interrupt */
1078+ err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, val,
1079+ val & EMC_MRR_DIVLD_INT,
1080+ 1, 100);
1081+ if (err) {
1082+ dev_err(emc->dev, "mode register %u read failed: %d\n",
1083+ register_addr, err);
1084+ emc->mrr_error = true;
1085+ return err;
1086+ }
1087+
1088+ /* read out mode register data */
1089+ val = readl_relaxed(emc->regs + EMC_MRR);
1090+ *register_data = FIELD_GET(EMC_MRR_MRR_DATA, val) & mr_mask;
1091+
1092+ return 0;
1093+}
1094+
1095+static void emc_read_lpddr_sdram_info(struct tegra_emc *emc,
1096+ unsigned int emem_dev)
1097+{
1098+ union lpddr2_basic_config4 basic_conf4;
1099+ unsigned int manufacturer_id;
1100+ unsigned int revision_id1;
1101+ unsigned int revision_id2;
1102+
1103+ /* these registers are standard for all LPDDR JEDEC memory chips */
1104+ emc_read_lpddr_mode_register(emc, emem_dev, 5, &manufacturer_id);
1105+ emc_read_lpddr_mode_register(emc, emem_dev, 6, &revision_id1);
1106+ emc_read_lpddr_mode_register(emc, emem_dev, 7, &revision_id2);
1107+ emc_read_lpddr_mode_register(emc, emem_dev, 8, &basic_conf4.value);
1108+
1109+ dev_info(emc->dev, "SDRAM[dev%u]: manufacturer: 0x%x (%s) rev1: 0x%x rev2: 0x%x prefetch: S%u density: %uMbit iowidth: %ubit\n",
1110+ emem_dev, manufacturer_id,
1111+ lpddr2_jedec_manufacturer(manufacturer_id),
1112+ revision_id1, revision_id2,
1113+ 4 >> basic_conf4.arch_type,
1114+ 64 << basic_conf4.density,
1115+ 32 >> basic_conf4.io_width);
1116+}
1117+
10381118 static int emc_setup_hw(struct tegra_emc *emc)
10391119 {
1120+ u32 fbio_cfg5, emc_cfg, emc_dbg, emc_adr_cfg;
10401121 u32 intmask = EMC_REFRESH_OVERFLOW_INT;
1041− u32 fbio_cfg5, emc_cfg, emc_dbg;
1122+ static bool print_sdram_info_once;
10421123 enum emc_dram_type dram_type;
1124+ const char *dram_type_str;
1125+ unsigned int emem_numdev;
10431126
10441127 fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5);
10451128 dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK;
@@ -1076,6 +1159,34 @@ static int emc_setup_hw(struct tegra_emc *emc) · 30 unmodified lines
10761159 emc_dbg &= ~EMC_DBG_FORCE_UPDATE;
10771160 writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
10781161
1162+ switch (dram_type) {
1163+ case DRAM_TYPE_DDR1:
1164+ dram_type_str = "DDR1";
1165+ break;
1166+ case DRAM_TYPE_LPDDR2:
1167+ dram_type_str = "LPDDR2";
1168+ break;
1169+ case DRAM_TYPE_DDR2:
1170+ dram_type_str = "DDR2";
1171+ break;
1172+ case DRAM_TYPE_DDR3:
1173+ dram_type_str = "DDR3";
1174+ break;
1175+ }
1176+
1177+ emc_adr_cfg = readl_relaxed(emc->regs + EMC_ADR_CFG);
1178+ emem_numdev = FIELD_GET(EMC_ADR_CFG_EMEM_NUMDEV, emc_adr_cfg) + 1;
1179+
1180+ dev_info_once(emc->dev, "%u %s %s attached\n", emem_numdev,
1181+ dram_type_str, emem_numdev == 2 ? "devices" : "device");
1182+
1183+ if (dram_type == DRAM_TYPE_LPDDR2 && !print_sdram_info_once) {
1184+ while (emem_numdev--)
1185+ emc_read_lpddr_sdram_info(emc, emem_numdev);
1186+
1187+ print_sdram_info_once = true;
1188+ }
1189+
10791190 return 0;
10801191 }
10811192
@@ -1538,14 +1649,6 @@ static int tegra_emc_probe(struct platform_device *pdev) · 456 unmodified lines
15381649 emc->clk_nb.notifier_call = emc_clk_change_notify;
15391650 emc->dev = &pdev->dev;
15401651
1541− np = emc_find_node_by_ram_code(&pdev->dev);
1542− if (np) {
1543− err = emc_load_timings_from_dt(emc, np);
1544− of_node_put(np);
1545− if (err)
1546− return err;
1547− }
1548−
15491652 emc->regs = devm_platform_ioremap_resource(pdev, 0);
15501653 if (IS_ERR(emc->regs))
15511654 return PTR_ERR(emc->regs);
@@ -1554,6 +1657,14 @@ static int tegra_emc_probe(struct platform_device *pdev) · 2 unmodified lines
15541657 if (err)
15551658 return err;
15561659
1660+ np = emc_find_node_by_ram_code(emc);
1661+ if (np) {
1662+ err = emc_load_timings_from_dt(emc, np);
1663+ of_node_put(np);
1664+ if (err)
1665+ return err;
1666+ }
1667+
15571668 err = platform_get_irq(pdev, 0);
15581669 if (err < 0)
15591670 return err;
drivers/remoteproc/qcom_q6v5_mss.c+4−3
@@ -928,7 +928,8 @@ static void q6v5proc_halt_axi_port(struct q6v5 *qproc, · 927 unmodified lines
928928 regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
929929 }
930930
931−static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
931+static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw,
932+ const char *fw_name)
932933 {
933934 unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
934935 dma_addr_t phys;
@@ -939,7 +940,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) · 4 unmodified lines
939940 void *ptr;
940941 int ret;
941942
942− metadata = qcom_mdt_read_metadata(fw, &size);
943+ metadata = qcom_mdt_read_metadata(fw, &size, fw_name, qproc->dev);
943944 if (IS_ERR(metadata))
944945 return PTR_ERR(metadata);
945946
@@ -1289,7 +1290,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc) · 343 unmodified lines
12891290 /* Initialize the RMB validator */
12901291 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
12911292
1292− ret = q6v5_mpss_init_image(qproc, fw);
1293+ ret = q6v5_mpss_init_image(qproc, fw, qproc->hexagon_mdt_image);
12931294 if (ret)
12941295 goto release_firmware;
12951296
drivers/remoteproc/qcom_q6v5_pas.c+33−3
@@ -79,6 +79,8 @@ struct qcom_adsp { · 78 unmodified lines
7979 struct qcom_rproc_subdev smd_subdev;
8080 struct qcom_rproc_ssr ssr_subdev;
8181 struct qcom_sysmon *sysmon;
82+
83+ struct qcom_scm_pas_metadata pas_metadata;
8284 };
8385
8486 static void adsp_minidump(struct rproc *rproc)
@@ -126,14 +128,34 @@ static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds, · 41 unmodified lines
126128 }
127129 }
128130
131+static int adsp_unprepare(struct rproc *rproc)
132+{
133+ struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
134+
135+ /*
136+ * adsp_load() did pass pas_metadata to the SCM driver for storing
137+ * metadata context. It might have been released already if
138+ * auth_and_reset() was successful, but in other cases clean it up
139+ * here.
140+ */
141+ qcom_scm_pas_metadata_release(&adsp->pas_metadata);
142+
143+ return 0;
144+}
145+
129146 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
130147 {
131148 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
132149 int ret;
133150
134− ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
135− adsp->mem_region, adsp->mem_phys, adsp->mem_size,
136− &adsp->mem_reloc);
151+ ret = qcom_mdt_pas_init(adsp->dev, fw, rproc->firmware, adsp->pas_id,
152+ adsp->mem_phys, &adsp->pas_metadata);
153+ if (ret)
154+ return ret;
155+
156+ ret = qcom_mdt_load_no_init(adsp->dev, fw, rproc->firmware, adsp->pas_id,
157+ adsp->mem_region, adsp->mem_phys, adsp->mem_size,
158+ &adsp->mem_reloc);
137159 if (ret)
138160 return ret;
139161
@@ -185,6 +207,8 @@ static int adsp_start(struct rproc *rproc) · 45 unmodified lines
185207 goto disable_px_supply;
186208 }
187209
210+ qcom_scm_pas_metadata_release(&adsp->pas_metadata);
211+
188212 return 0;
189213
190214 disable_px_supply:
@@ -255,6 +279,7 @@ static unsigned long adsp_panic(struct rproc *rproc) · 64 unmodified lines
255279 }
256280
257281 static const struct rproc_ops adsp_ops = {
282+ .unprepare = adsp_unprepare,
258283 .start = adsp_start,
259284 .stop = adsp_stop,
260285 .da_to_va = adsp_da_to_va,
@@ -264,6 +289,7 @@ static const struct rproc_ops adsp_ops = { · 3 unmodified lines
264289 };
265290
266291 static const struct rproc_ops adsp_minidump_ops = {
292+ .unprepare = adsp_unprepare,
267293 .start = adsp_start,
268294 .stop = adsp_stop,
269295 .da_to_va = adsp_da_to_va,
@@ -853,6 +879,10 @@ static const struct of_device_id adsp_of_match[] = { · 583 unmodified lines
853879 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
854880 { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
855881 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},
882+ { .compatible = "qcom,sm8450-adsp-pas", .data = &sm8350_adsp_resource},
883+ { .compatible = "qcom,sm8450-cdsp-pas", .data = &sm8350_cdsp_resource},
884+ { .compatible = "qcom,sm8450-slpi-pas", .data = &sm8350_slpi_resource},
885+ { .compatible = "qcom,sm8450-mpss-pas", .data = &mpss_resource_init},
856886 { },
857887 };
858888 MODULE_DEVICE_TABLE(of, adsp_of_match);
drivers/soc/amlogic/meson-secure-pwrc.c+22−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/platform_device.h>
1212 #include <linux/pm_domain.h>
1313 #include <dt-bindings/power/meson-a1-power.h>
14+#include <dt-bindings/power/meson-s4-power.h>
1415 #include <linux/arm-smccc.h>
1516 #include <linux/firmware/meson/meson_sm.h>
1617 #include <linux/module.h>
@@ -119,6 +120,18 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = { · 102 unmodified lines
119120 SEC_PD(RSA, 0),
120121 };
121122
123+static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
124+ SEC_PD(S4_DOS_HEVC, 0),
125+ SEC_PD(S4_DOS_VDEC, 0),
126+ SEC_PD(S4_VPU_HDMI, 0),
127+ SEC_PD(S4_USB_COMB, 0),
128+ SEC_PD(S4_GE2D, 0),
129+ /* ETH is for ethernet online wakeup, and should be always on */
130+ SEC_PD(S4_ETH, GENPD_FLAG_ALWAYS_ON),
131+ SEC_PD(S4_DEMOD, 0),
132+ SEC_PD(S4_AUDIO, 0),
133+};
134+
122135 static int meson_secure_pwrc_probe(struct platform_device *pdev)
123136 {
124137 int i;
@@ -187,11 +200,20 @@ static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = { · 62 unmodified lines
187200 .count = ARRAY_SIZE(a1_pwrc_domains),
188201 };
189202
203+static struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = {
204+ .domains = s4_pwrc_domains,
205+ .count = ARRAY_SIZE(s4_pwrc_domains),
206+};
207+
190208 static const struct of_device_id meson_secure_pwrc_match_table[] = {
191209 {
192210 .compatible = "amlogic,meson-a1-pwrc",
193211 .data = &meson_secure_a1_pwrc_data,
194212 },
213+ {
214+ .compatible = "amlogic,meson-s4-pwrc",
215+ .data = &meson_secure_s4_pwrc_data,
216+ },
195217 { /* sentinel */ }
196218 };
197219 MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table);
drivers/soc/atmel/soc.c+3−0
@@ -156,6 +156,9 @@ static const struct at91_soc socs[] __initconst = { · 155 unmodified lines
156156 AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
157157 AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH,
158158 "sama5d28c 256MiB LPDDR2 SiP", "sama5d2"),
159+ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
160+ AT91_CIDR_VERSION_MASK, SAMA5D29CN_EXID_MATCH,
161+ "sama5d29", "sama5d2"),
159162 AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
160163 AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH,
161164 "sama5d31", "sama5d3"),
drivers/soc/atmel/soc.h+1−0
@@ -95,6 +95,7 @@ at91_soc_init(const struct at91_soc *socs); · 94 unmodified lines
9595 #define SAMA5D28C_LD2G_EXID_MATCH 0x00000072
9696 #define SAMA5D28CU_EXID_MATCH 0x00000010
9797 #define SAMA5D28CN_EXID_MATCH 0x00000020
98+#define SAMA5D29CN_EXID_MATCH 0x00000023
9899
99100 #define SAMA5D3_CIDR_MATCH 0x0a5c07c0
100101 #define SAMA5D31_EXID_MATCH 0x00444300
drivers/soc/imx/imx8m-blk-ctrl.c+66−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515
1616 #include <dt-bindings/power/imx8mm-power.h>
1717 #include <dt-bindings/power/imx8mn-power.h>
18+#include <dt-bindings/power/imx8mq-power.h>
1819
1920 #define BLK_SFT_RSTN 0x0
2021 #define BLK_CLK_EN 0x4
@@ -589,6 +590,68 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = { · 568 unmodified lines
589590 .num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
590591 };
591592
593+static int imx8mq_vpu_power_notifier(struct notifier_block *nb,
594+ unsigned long action, void *data)
595+{
596+ struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
597+ power_nb);
598+
599+ if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
600+ return NOTIFY_OK;
601+
602+ /*
603+ * The ADB in the VPUMIX domain has no separate reset and clock
604+ * enable bits, but is ungated and reset together with the VPUs. The
605+ * reset and clock enable inputs to the ADB is a logical OR of the
606+ * VPU bits. In order to set the G2 fuse bits, the G2 clock must
607+ * also be enabled.
608+ */
609+ regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1));
610+ regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1));
611+
612+ if (action == GENPD_NOTIFY_ON) {
613+ /*
614+ * On power up we have no software backchannel to the GPC to
615+ * wait for the ADB handshake to happen, so we just delay for a
616+ * bit. On power down the GPC driver waits for the handshake.
617+ */
618+ udelay(5);
619+
620+ /* set "fuse" bits to enable the VPUs */
621+ regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
622+ regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
623+ regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
624+ }
625+
626+ return NOTIFY_OK;
627+}
628+
629+static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = {
630+ [IMX8MQ_VPUBLK_PD_G1] = {
631+ .name = "vpublk-g1",
632+ .clk_names = (const char *[]){ "g1", },
633+ .num_clks = 1,
634+ .gpc_name = "g1",
635+ .rst_mask = BIT(1),
636+ .clk_mask = BIT(1),
637+ },
638+ [IMX8MQ_VPUBLK_PD_G2] = {
639+ .name = "vpublk-g2",
640+ .clk_names = (const char *[]){ "g2", },
641+ .num_clks = 1,
642+ .gpc_name = "g2",
643+ .rst_mask = BIT(0),
644+ .clk_mask = BIT(0),
645+ },
646+};
647+
648+static const struct imx8m_blk_ctrl_data imx8mq_vpu_blk_ctl_dev_data = {
649+ .max_reg = 0x14,
650+ .power_notifier_fn = imx8mq_vpu_power_notifier,
651+ .domains = imx8mq_vpu_blk_ctl_domain_data,
652+ .num_domains = ARRAY_SIZE(imx8mq_vpu_blk_ctl_domain_data),
653+};
654+
592655 static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
593656 {
594657 .compatible = "fsl,imx8mm-vpu-blk-ctrl",
@@ -599,6 +662,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = { · 4 unmodified lines
599662 }, {
600663 .compatible = "fsl,imx8mn-disp-blk-ctrl",
601664 .data = &imx8mn_disp_blk_ctl_dev_data
665+ }, {
666+ .compatible = "fsl,imx8mq-vpu-blk-ctrl",
667+ .data = &imx8mq_vpu_blk_ctl_dev_data
602668 }, {
603669 /* Sentinel */
604670 }
drivers/soc/imx/soc-imx.c+0−3
@@ -40,9 +40,6 @@ static int __init imx_soc_device_init(void) · 39 unmodified lines
4040 if (!__mxc_cpu_type)
4141 return 0;
4242
43− if (of_machine_is_compatible("fsl,ls1021a"))
44− return 0;
45−
4643 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
4744 if (!soc_dev_attr)
4845 return -ENOMEM;
drivers/soc/mediatek/mt8167-pm-domains.h+14−2
@@ -18,6 +18,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 17 unmodified lines
1818 .name = "mm",
1919 .sta_mask = PWR_STATUS_DISP,
2020 .ctl_offs = SPM_DIS_PWR_CON,
21+ .pwr_sta_offs = SPM_PWR_STATUS,
22+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
2123 .sram_pdn_bits = GENMASK(11, 8),
2224 .sram_pdn_ack_bits = GENMASK(12, 12),
2325 .bp_infracfg = {
@@ -30,6 +32,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 6 unmodified lines
3032 .name = "vdec",
3133 .sta_mask = PWR_STATUS_VDEC,
3234 .ctl_offs = SPM_VDE_PWR_CON,
35+ .pwr_sta_offs = SPM_PWR_STATUS,
36+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
3337 .sram_pdn_bits = GENMASK(8, 8),
3438 .sram_pdn_ack_bits = GENMASK(12, 12),
3539 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -38,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 2 unmodified lines
3842 .name = "isp",
3943 .sta_mask = PWR_STATUS_ISP,
4044 .ctl_offs = SPM_ISP_PWR_CON,
45+ .pwr_sta_offs = SPM_PWR_STATUS,
46+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
4147 .sram_pdn_bits = GENMASK(11, 8),
4248 .sram_pdn_ack_bits = GENMASK(13, 12),
4349 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -46,6 +52,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 2 unmodified lines
4652 .name = "mfg_async",
4753 .sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
4854 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
55+ .pwr_sta_offs = SPM_PWR_STATUS,
56+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
4957 .sram_pdn_bits = 0,
5058 .sram_pdn_ack_bits = 0,
5159 .bp_infracfg = {
@@ -57,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 5 unmodified lines
5765 .name = "mfg_2d",
5866 .sta_mask = MT8167_PWR_STATUS_MFG_2D,
5967 .ctl_offs = SPM_MFG_2D_PWR_CON,
68+ .pwr_sta_offs = SPM_PWR_STATUS,
69+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
6070 .sram_pdn_bits = GENMASK(11, 8),
6171 .sram_pdn_ack_bits = GENMASK(15, 12),
6272 },
@@ -64,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 1 unmodified line
6474 .name = "mfg",
6575 .sta_mask = PWR_STATUS_MFG,
6676 .ctl_offs = SPM_MFG_PWR_CON,
77+ .pwr_sta_offs = SPM_PWR_STATUS,
78+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
6779 .sram_pdn_bits = GENMASK(11, 8),
6880 .sram_pdn_ack_bits = GENMASK(15, 12),
6981 },
@@ -71,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 1 unmodified line
7183 .name = "conn",
7284 .sta_mask = PWR_STATUS_CONN,
7385 .ctl_offs = SPM_CONN_PWR_CON,
86+ .pwr_sta_offs = SPM_PWR_STATUS,
87+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
7488 .sram_pdn_bits = GENMASK(8, 8),
7589 .sram_pdn_ack_bits = 0,
7690 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -85,8 +99,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 8 unmodified lines
8599 static const struct scpsys_soc_data mt8167_scpsys_data = {
86100 .domains_data = scpsys_domain_data_mt8167,
87101 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
88− .pwr_sta_offs = SPM_PWR_STATUS,
89− .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
90102 };
91103
92104 #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
drivers/soc/mediatek/mt8173-pm-domains.h+20−2
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 14 unmodified lines
1515 .name = "vdec",
1616 .sta_mask = PWR_STATUS_VDEC,
1717 .ctl_offs = SPM_VDE_PWR_CON,
18+ .pwr_sta_offs = SPM_PWR_STATUS,
19+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
1820 .sram_pdn_bits = GENMASK(11, 8),
1921 .sram_pdn_ack_bits = GENMASK(12, 12),
2022 },
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
2224 .name = "venc",
2325 .sta_mask = PWR_STATUS_VENC,
2426 .ctl_offs = SPM_VEN_PWR_CON,
27+ .pwr_sta_offs = SPM_PWR_STATUS,
28+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
2529 .sram_pdn_bits = GENMASK(11, 8),
2630 .sram_pdn_ack_bits = GENMASK(15, 12),
2731 },
@@ -29,6 +33,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
2933 .name = "isp",
3034 .sta_mask = PWR_STATUS_ISP,
3135 .ctl_offs = SPM_ISP_PWR_CON,
36+ .pwr_sta_offs = SPM_PWR_STATUS,
37+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
3238 .sram_pdn_bits = GENMASK(11, 8),
3339 .sram_pdn_ack_bits = GENMASK(13, 12),
3440 },
@@ -36,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
3642 .name = "mm",
3743 .sta_mask = PWR_STATUS_DISP,
3844 .ctl_offs = SPM_DIS_PWR_CON,
45+ .pwr_sta_offs = SPM_PWR_STATUS,
46+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
3947 .sram_pdn_bits = GENMASK(11, 8),
4048 .sram_pdn_ack_bits = GENMASK(12, 12),
4149 .bp_infracfg = {
@@ -47,6 +55,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 5 unmodified lines
4755 .name = "venc_lt",
4856 .sta_mask = PWR_STATUS_VENC_LT,
4957 .ctl_offs = SPM_VEN2_PWR_CON,
58+ .pwr_sta_offs = SPM_PWR_STATUS,
59+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
5060 .sram_pdn_bits = GENMASK(11, 8),
5161 .sram_pdn_ack_bits = GENMASK(15, 12),
5262 },
@@ -54,6 +64,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
5464 .name = "audio",
5565 .sta_mask = PWR_STATUS_AUDIO,
5666 .ctl_offs = SPM_AUDIO_PWR_CON,
67+ .pwr_sta_offs = SPM_PWR_STATUS,
68+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
5769 .sram_pdn_bits = GENMASK(11, 8),
5870 .sram_pdn_ack_bits = GENMASK(15, 12),
5971 },
@@ -61,6 +73,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
6173 .name = "usb",
6274 .sta_mask = PWR_STATUS_USB,
6375 .ctl_offs = SPM_USB_PWR_CON,
76+ .pwr_sta_offs = SPM_PWR_STATUS,
77+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
6478 .sram_pdn_bits = GENMASK(11, 8),
6579 .sram_pdn_ack_bits = GENMASK(15, 12),
6680 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 2 unmodified lines
6983 .name = "mfg_async",
7084 .sta_mask = PWR_STATUS_MFG_ASYNC,
7185 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
86+ .pwr_sta_offs = SPM_PWR_STATUS,
87+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
7288 .sram_pdn_bits = GENMASK(11, 8),
7389 .sram_pdn_ack_bits = 0,
7490 .caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -77,6 +93,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 2 unmodified lines
7793 .name = "mfg_2d",
7894 .sta_mask = PWR_STATUS_MFG_2D,
7995 .ctl_offs = SPM_MFG_2D_PWR_CON,
96+ .pwr_sta_offs = SPM_PWR_STATUS,
97+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
8098 .sram_pdn_bits = GENMASK(11, 8),
8199 .sram_pdn_ack_bits = GENMASK(13, 12),
82100 },
@@ -84,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
84102 .name = "mfg",
85103 .sta_mask = PWR_STATUS_MFG,
86104 .ctl_offs = SPM_MFG_PWR_CON,
105+ .pwr_sta_offs = SPM_PWR_STATUS,
106+ .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
87107 .sram_pdn_bits = GENMASK(13, 8),
88108 .sram_pdn_ack_bits = GENMASK(21, 16),
89109 .bp_infracfg = {
@@ -98,8 +118,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 8 unmodified lines
98118 static const struct scpsys_soc_data mt8173_scpsys_data = {
99119 .domains_data = scpsys_domain_data_mt8173,
100120 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
101− .pwr_sta_offs = SPM_PWR_STATUS,
102− .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
103121 };
104122
105123 #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
drivers/soc/mediatek/mt8183-mmsys.h+2−0
@@ -25,6 +25,8 @@ · 24 unmodified lines
2525 #define MT8183_RDMA0_SOUT_COLOR0 0x1
2626 #define MT8183_RDMA1_SOUT_DSI0 0x1
2727
28+#define MT8183_MMSYS_SW0_RST_B 0x140
29+
2830 static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
2931 {
3032 DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0,
drivers/soc/mediatek/mt8183-pm-domains.h+30−2
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 14 unmodified lines
1515 .name = "audio",
1616 .sta_mask = PWR_STATUS_AUDIO,
1717 .ctl_offs = 0x0314,
18+ .pwr_sta_offs = 0x0180,
19+ .pwr_sta2nd_offs = 0x0184,
1820 .sram_pdn_bits = GENMASK(11, 8),
1921 .sram_pdn_ack_bits = GENMASK(15, 12),
2022 },
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
2224 .name = "conn",
2325 .sta_mask = PWR_STATUS_CONN,
2426 .ctl_offs = 0x032c,
27+ .pwr_sta_offs = 0x0180,
28+ .pwr_sta2nd_offs = 0x0184,
2529 .sram_pdn_bits = 0,
2630 .sram_pdn_ack_bits = 0,
2731 .bp_infracfg = {
@@ -33,6 +37,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 5 unmodified lines
3337 .name = "mfg_async",
3438 .sta_mask = PWR_STATUS_MFG_ASYNC,
3539 .ctl_offs = 0x0334,
40+ .pwr_sta_offs = 0x0180,
41+ .pwr_sta2nd_offs = 0x0184,
3642 .sram_pdn_bits = 0,
3743 .sram_pdn_ack_bits = 0,
3844 },
@@ -40,6 +46,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
4046 .name = "mfg",
4147 .sta_mask = PWR_STATUS_MFG,
4248 .ctl_offs = 0x0338,
49+ .pwr_sta_offs = 0x0180,
50+ .pwr_sta2nd_offs = 0x0184,
4351 .sram_pdn_bits = GENMASK(8, 8),
4452 .sram_pdn_ack_bits = GENMASK(12, 12),
4553 .caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -48,6 +56,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 2 unmodified lines
4856 .name = "mfg_core0",
4957 .sta_mask = BIT(7),
5058 .ctl_offs = 0x034c,
59+ .pwr_sta_offs = 0x0180,
60+ .pwr_sta2nd_offs = 0x0184,
5161 .sram_pdn_bits = GENMASK(8, 8),
5262 .sram_pdn_ack_bits = GENMASK(12, 12),
5363 },
@@ -55,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
5565 .name = "mfg_core1",
5666 .sta_mask = BIT(20),
5767 .ctl_offs = 0x0310,
68+ .pwr_sta_offs = 0x0180,
69+ .pwr_sta2nd_offs = 0x0184,
5870 .sram_pdn_bits = GENMASK(8, 8),
5971 .sram_pdn_ack_bits = GENMASK(12, 12),
6072 },
@@ -62,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
6274 .name = "mfg_2d",
6375 .sta_mask = PWR_STATUS_MFG_2D,
6476 .ctl_offs = 0x0348,
77+ .pwr_sta_offs = 0x0180,
78+ .pwr_sta2nd_offs = 0x0184,
6579 .sram_pdn_bits = GENMASK(8, 8),
6680 .sram_pdn_ack_bits = GENMASK(12, 12),
6781 .bp_infracfg = {
@@ -75,6 +89,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
7589 .name = "disp",
7690 .sta_mask = PWR_STATUS_DISP,
7791 .ctl_offs = 0x030c,
92+ .pwr_sta_offs = 0x0180,
93+ .pwr_sta2nd_offs = 0x0184,
7894 .sram_pdn_bits = GENMASK(8, 8),
7995 .sram_pdn_ack_bits = GENMASK(12, 12),
8096 .bp_infracfg = {
@@ -94,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 13 unmodified lines
94110 .name = "cam",
95111 .sta_mask = BIT(25),
96112 .ctl_offs = 0x0344,
113+ .pwr_sta_offs = 0x0180,
114+ .pwr_sta2nd_offs = 0x0184,
97115 .sram_pdn_bits = GENMASK(9, 8),
98116 .sram_pdn_ack_bits = GENMASK(13, 12),
99117 .bp_infracfg = {
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 17 unmodified lines
117135 .name = "isp",
118136 .sta_mask = PWR_STATUS_ISP,
119137 .ctl_offs = 0x0308,
138+ .pwr_sta_offs = 0x0180,
139+ .pwr_sta2nd_offs = 0x0184,
120140 .sram_pdn_bits = GENMASK(9, 8),
121141 .sram_pdn_ack_bits = GENMASK(13, 12),
122142 .bp_infracfg = {
@@ -140,6 +160,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 17 unmodified lines
140160 .name = "vdec",
141161 .sta_mask = BIT(31),
142162 .ctl_offs = 0x0300,
163+ .pwr_sta_offs = 0x0180,
164+ .pwr_sta2nd_offs = 0x0184,
143165 .sram_pdn_bits = GENMASK(8, 8),
144166 .sram_pdn_ack_bits = GENMASK(12, 12),
145167 .bp_smi = {
@@ -153,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
153175 .name = "venc",
154176 .sta_mask = PWR_STATUS_VENC,
155177 .ctl_offs = 0x0304,
178+ .pwr_sta_offs = 0x0180,
179+ .pwr_sta2nd_offs = 0x0184,
156180 .sram_pdn_bits = GENMASK(11, 8),
157181 .sram_pdn_ack_bits = GENMASK(15, 12),
158182 .bp_smi = {
@@ -166,6 +190,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
166190 .name = "vpu_top",
167191 .sta_mask = BIT(26),
168192 .ctl_offs = 0x0324,
193+ .pwr_sta_offs = 0x0180,
194+ .pwr_sta2nd_offs = 0x0184,
169195 .sram_pdn_bits = GENMASK(8, 8),
170196 .sram_pdn_ack_bits = GENMASK(12, 12),
171197 .bp_infracfg = {
@@ -193,6 +219,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 21 unmodified lines
193219 .name = "vpu_core0",
194220 .sta_mask = BIT(27),
195221 .ctl_offs = 0x33c,
222+ .pwr_sta_offs = 0x0180,
223+ .pwr_sta2nd_offs = 0x0184,
196224 .sram_pdn_bits = GENMASK(11, 8),
197225 .sram_pdn_ack_bits = GENMASK(13, 12),
198226 .bp_infracfg = {
@@ -211,6 +239,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 12 unmodified lines
211239 .name = "vpu_core1",
212240 .sta_mask = BIT(28),
213241 .ctl_offs = 0x0340,
242+ .pwr_sta_offs = 0x0180,
243+ .pwr_sta2nd_offs = 0x0184,
214244 .sram_pdn_bits = GENMASK(11, 8),
215245 .sram_pdn_ack_bits = GENMASK(13, 12),
216246 .bp_infracfg = {
@@ -230,8 +260,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 13 unmodified lines
230260 static const struct scpsys_soc_data mt8183_scpsys_data = {
231261 .domains_data = scpsys_domain_data_mt8183,
232262 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
233− .pwr_sta_offs = 0x0180,
234− .pwr_sta2nd_offs = 0x0184
235263 };
236264
237265 #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
drivers/soc/mediatek/mt8186-mmsys.h+115−0
@@ -0,0 +1,115 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+#ifndef __SOC_MEDIATEK_MT8186_MMSYS_H
4+#define __SOC_MEDIATEK_MT8186_MMSYS_H
5+
6+#define MT8186_MMSYS_OVL_CON 0xF04
7+#define MT8186_MMSYS_OVL0_CON_MASK 0x3
8+#define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC
9+#define MT8186_OVL0_GO_BLEND BIT(0)
10+#define MT8186_OVL0_GO_BG BIT(1)
11+#define MT8186_OVL0_2L_GO_BLEND BIT(2)
12+#define MT8186_OVL0_2L_GO_BG BIT(3)
13+#define MT8186_DISP_RDMA0_SOUT_SEL 0xF0C
14+#define MT8186_RDMA0_SOUT_SEL_MASK 0xF
15+#define MT8186_RDMA0_SOUT_TO_DSI0 (0)
16+#define MT8186_RDMA0_SOUT_TO_COLOR0 (1)
17+#define MT8186_RDMA0_SOUT_TO_DPI0 (2)
18+#define MT8186_DISP_OVL0_2L_MOUT_EN 0xF14
19+#define MT8186_OVL0_2L_MOUT_EN_MASK 0xF
20+#define MT8186_OVL0_2L_MOUT_TO_RDMA0 BIT(0)
21+#define MT8186_OVL0_2L_MOUT_TO_RDMA1 BIT(3)
22+#define MT8186_DISP_OVL0_MOUT_EN 0xF18
23+#define MT8186_OVL0_MOUT_EN_MASK 0xF
24+#define MT8186_OVL0_MOUT_TO_RDMA0 BIT(0)
25+#define MT8186_OVL0_MOUT_TO_RDMA1 BIT(3)
26+#define MT8186_DISP_DITHER0_MOUT_EN 0xF20
27+#define MT8186_DITHER0_MOUT_EN_MASK 0xF
28+#define MT8186_DITHER0_MOUT_TO_DSI0 BIT(0)
29+#define MT8186_DITHER0_MOUT_TO_RDMA1 BIT(2)
30+#define MT8186_DITHER0_MOUT_TO_DPI0 BIT(3)
31+#define MT8186_DISP_RDMA0_SEL_IN 0xF28
32+#define MT8186_RDMA0_SEL_IN_MASK 0xF
33+#define MT8186_RDMA0_FROM_OVL0 0
34+#define MT8186_RDMA0_FROM_OVL0_2L 2
35+#define MT8186_DISP_DSI0_SEL_IN 0xF30
36+#define MT8186_DSI0_SEL_IN_MASK 0xF
37+#define MT8186_DSI0_FROM_RDMA0 0
38+#define MT8186_DSI0_FROM_DITHER0 1
39+#define MT8186_DSI0_FROM_RDMA1 2
40+#define MT8186_DISP_RDMA1_MOUT_EN 0xF3C
41+#define MT8186_RDMA1_MOUT_EN_MASK 0xF
42+#define MT8186_RDMA1_MOUT_TO_DPI0_SEL BIT(0)
43+#define MT8186_RDMA1_MOUT_TO_DSI0_SEL BIT(2)
44+#define MT8186_DISP_RDMA1_SEL_IN 0xF40
45+#define MT8186_RDMA1_SEL_IN_MASK 0xF
46+#define MT8186_RDMA1_FROM_OVL0 0
47+#define MT8186_RDMA1_FROM_OVL0_2L 2
48+#define MT8186_RDMA1_FROM_DITHER0 3
49+#define MT8186_DISP_DPI0_SEL_IN 0xF44
50+#define MT8186_DPI0_SEL_IN_MASK 0xF
51+#define MT8186_DPI0_FROM_RDMA1 0
52+#define MT8186_DPI0_FROM_DITHER0 1
53+#define MT8186_DPI0_FROM_RDMA0 2
54+
55+#define MT8186_MMSYS_SW0_RST_B 0x160
56+
57+static const struct mtk_mmsys_routes mmsys_mt8186_routing_table[] = {
58+ {
59+ DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
60+ MT8186_DISP_OVL0_MOUT_EN, MT8186_OVL0_MOUT_EN_MASK,
61+ MT8186_OVL0_MOUT_TO_RDMA0
62+ },
63+ {
64+ DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
65+ MT8186_DISP_RDMA0_SEL_IN, MT8186_RDMA0_SEL_IN_MASK,
66+ MT8186_RDMA0_FROM_OVL0
67+ },
68+ {
69+ DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
70+ MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_CON_MASK,
71+ MT8186_OVL0_GO_BLEND
72+ },
73+ {
74+ DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
75+ MT8186_DISP_RDMA0_SOUT_SEL, MT8186_RDMA0_SOUT_SEL_MASK,
76+ MT8186_RDMA0_SOUT_TO_COLOR0
77+ },
78+ {
79+ DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
80+ MT8186_DISP_DITHER0_MOUT_EN, MT8186_DITHER0_MOUT_EN_MASK,
81+ MT8186_DITHER0_MOUT_TO_DSI0,
82+ },
83+ {
84+ DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
85+ MT8186_DISP_DSI0_SEL_IN, MT8186_DSI0_SEL_IN_MASK,
86+ MT8186_DSI0_FROM_DITHER0
87+ },
88+ {
89+ DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
90+ MT8186_DISP_OVL0_2L_MOUT_EN, MT8186_OVL0_2L_MOUT_EN_MASK,
91+ MT8186_OVL0_2L_MOUT_TO_RDMA1
92+ },
93+ {
94+ DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
95+ MT8186_DISP_RDMA1_SEL_IN, MT8186_RDMA1_SEL_IN_MASK,
96+ MT8186_RDMA1_FROM_OVL0_2L
97+ },
98+ {
99+ DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
100+ MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_2L_CON_MASK,
101+ MT8186_OVL0_2L_GO_BLEND
102+ },
103+ {
104+ DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
105+ MT8186_DISP_RDMA1_MOUT_EN, MT8186_RDMA1_MOUT_EN_MASK,
106+ MT8186_RDMA1_MOUT_TO_DPI0_SEL
107+ },
108+ {
109+ DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
110+ MT8186_DISP_DPI0_SEL_IN, MT8186_DPI0_SEL_IN_MASK,
111+ MT8186_DPI0_FROM_RDMA1
112+ },
113+};
114+
115+#endif /* __SOC_MEDIATEK_MT8186_MMSYS_H */
drivers/soc/mediatek/mt8186-pm-domains.h+344−0
@@ -0,0 +1,344 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (c) 2022 MediaTek Inc.
4+ * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
5+ */
6+
7+#ifndef __SOC_MEDIATEK_MT8186_PM_DOMAINS_H
8+#define __SOC_MEDIATEK_MT8186_PM_DOMAINS_H
9+
10+#include "mtk-pm-domains.h"
11+#include <dt-bindings/power/mt8186-power.h>
12+
13+/*
14+ * MT8186 power domain support
15+ */
16+
17+static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
18+ [MT8186_POWER_DOMAIN_MFG0] = {
19+ .name = "mfg0",
20+ .sta_mask = BIT(2),
21+ .ctl_offs = 0x308,
22+ .pwr_sta_offs = 0x16C,
23+ .pwr_sta2nd_offs = 0x170,
24+ .sram_pdn_bits = BIT(8),
25+ .sram_pdn_ack_bits = BIT(12),
26+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
27+ },
28+ [MT8186_POWER_DOMAIN_MFG1] = {
29+ .name = "mfg1",
30+ .sta_mask = BIT(3),
31+ .ctl_offs = 0x30c,
32+ .pwr_sta_offs = 0x16C,
33+ .pwr_sta2nd_offs = 0x170,
34+ .sram_pdn_bits = BIT(8),
35+ .sram_pdn_ack_bits = BIT(12),
36+ .bp_infracfg = {
37+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1,
38+ MT8186_TOP_AXI_PROT_EN_1_SET,
39+ MT8186_TOP_AXI_PROT_EN_1_CLR,
40+ MT8186_TOP_AXI_PROT_EN_1_STA),
41+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP2,
42+ MT8186_TOP_AXI_PROT_EN_SET,
43+ MT8186_TOP_AXI_PROT_EN_CLR,
44+ MT8186_TOP_AXI_PROT_EN_STA),
45+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP3,
46+ MT8186_TOP_AXI_PROT_EN_SET,
47+ MT8186_TOP_AXI_PROT_EN_CLR,
48+ MT8186_TOP_AXI_PROT_EN_STA),
49+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4,
50+ MT8186_TOP_AXI_PROT_EN_1_SET,
51+ MT8186_TOP_AXI_PROT_EN_1_CLR,
52+ MT8186_TOP_AXI_PROT_EN_1_STA),
53+ },
54+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
55+ },
56+ [MT8186_POWER_DOMAIN_MFG2] = {
57+ .name = "mfg2",
58+ .sta_mask = BIT(4),
59+ .ctl_offs = 0x310,
60+ .pwr_sta_offs = 0x16C,
61+ .pwr_sta2nd_offs = 0x170,
62+ .sram_pdn_bits = BIT(8),
63+ .sram_pdn_ack_bits = BIT(12),
64+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
65+ },
66+ [MT8186_POWER_DOMAIN_MFG3] = {
67+ .name = "mfg3",
68+ .sta_mask = BIT(5),
69+ .ctl_offs = 0x314,
70+ .pwr_sta_offs = 0x16C,
71+ .pwr_sta2nd_offs = 0x170,
72+ .sram_pdn_bits = BIT(8),
73+ .sram_pdn_ack_bits = BIT(12),
74+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
75+ },
76+ [MT8186_POWER_DOMAIN_SSUSB] = {
77+ .name = "ssusb",
78+ .sta_mask = BIT(20),
79+ .ctl_offs = 0x9F0,
80+ .pwr_sta_offs = 0x16C,
81+ .pwr_sta2nd_offs = 0x170,
82+ .sram_pdn_bits = BIT(8),
83+ .sram_pdn_ack_bits = BIT(12),
84+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
85+ },
86+ [MT8186_POWER_DOMAIN_SSUSB_P1] = {
87+ .name = "ssusb_p1",
88+ .sta_mask = BIT(19),
89+ .ctl_offs = 0x9F4,
90+ .pwr_sta_offs = 0x16C,
91+ .pwr_sta2nd_offs = 0x170,
92+ .sram_pdn_bits = BIT(8),
93+ .sram_pdn_ack_bits = BIT(12),
94+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
95+ },
96+ [MT8186_POWER_DOMAIN_DIS] = {
97+ .name = "dis",
98+ .sta_mask = BIT(21),
99+ .ctl_offs = 0x354,
100+ .pwr_sta_offs = 0x16C,
101+ .pwr_sta2nd_offs = 0x170,
102+ .sram_pdn_bits = BIT(8),
103+ .sram_pdn_ack_bits = BIT(12),
104+ .bp_infracfg = {
105+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1,
106+ MT8186_TOP_AXI_PROT_EN_1_SET,
107+ MT8186_TOP_AXI_PROT_EN_1_CLR,
108+ MT8186_TOP_AXI_PROT_EN_1_STA),
109+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_DIS_STEP2,
110+ MT8186_TOP_AXI_PROT_EN_SET,
111+ MT8186_TOP_AXI_PROT_EN_CLR,
112+ MT8186_TOP_AXI_PROT_EN_STA),
113+ },
114+ },
115+ [MT8186_POWER_DOMAIN_IMG] = {
116+ .name = "img",
117+ .sta_mask = BIT(13),
118+ .ctl_offs = 0x334,
119+ .pwr_sta_offs = 0x16C,
120+ .pwr_sta2nd_offs = 0x170,
121+ .sram_pdn_bits = BIT(8),
122+ .sram_pdn_ack_bits = BIT(12),
123+ .bp_infracfg = {
124+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1,
125+ MT8186_TOP_AXI_PROT_EN_1_SET,
126+ MT8186_TOP_AXI_PROT_EN_1_CLR,
127+ MT8186_TOP_AXI_PROT_EN_1_STA),
128+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2,
129+ MT8186_TOP_AXI_PROT_EN_1_SET,
130+ MT8186_TOP_AXI_PROT_EN_1_CLR,
131+ MT8186_TOP_AXI_PROT_EN_1_STA),
132+ },
133+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
134+ },
135+ [MT8186_POWER_DOMAIN_IMG2] = {
136+ .name = "img2",
137+ .sta_mask = BIT(14),
138+ .ctl_offs = 0x338,
139+ .pwr_sta_offs = 0x16C,
140+ .pwr_sta2nd_offs = 0x170,
141+ .sram_pdn_bits = BIT(8),
142+ .sram_pdn_ack_bits = BIT(12),
143+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
144+ },
145+ [MT8186_POWER_DOMAIN_IPE] = {
146+ .name = "ipe",
147+ .sta_mask = BIT(15),
148+ .ctl_offs = 0x33C,
149+ .pwr_sta_offs = 0x16C,
150+ .pwr_sta2nd_offs = 0x170,
151+ .sram_pdn_bits = BIT(8),
152+ .sram_pdn_ack_bits = BIT(12),
153+ .bp_infracfg = {
154+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1,
155+ MT8186_TOP_AXI_PROT_EN_1_SET,
156+ MT8186_TOP_AXI_PROT_EN_1_CLR,
157+ MT8186_TOP_AXI_PROT_EN_1_STA),
158+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2,
159+ MT8186_TOP_AXI_PROT_EN_1_SET,
160+ MT8186_TOP_AXI_PROT_EN_1_CLR,
161+ MT8186_TOP_AXI_PROT_EN_1_STA),
162+ },
163+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
164+ },
165+ [MT8186_POWER_DOMAIN_CAM] = {
166+ .name = "cam",
167+ .sta_mask = BIT(23),
168+ .ctl_offs = 0x35C,
169+ .pwr_sta_offs = 0x16C,
170+ .pwr_sta2nd_offs = 0x170,
171+ .sram_pdn_bits = BIT(8),
172+ .sram_pdn_ack_bits = BIT(12),
173+ .bp_infracfg = {
174+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1,
175+ MT8186_TOP_AXI_PROT_EN_1_SET,
176+ MT8186_TOP_AXI_PROT_EN_1_CLR,
177+ MT8186_TOP_AXI_PROT_EN_1_STA),
178+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2,
179+ MT8186_TOP_AXI_PROT_EN_1_SET,
180+ MT8186_TOP_AXI_PROT_EN_1_CLR,
181+ MT8186_TOP_AXI_PROT_EN_1_STA),
182+ },
183+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
184+ },
185+ [MT8186_POWER_DOMAIN_CAM_RAWA] = {
186+ .name = "cam_rawa",
187+ .sta_mask = BIT(24),
188+ .ctl_offs = 0x360,
189+ .pwr_sta_offs = 0x16C,
190+ .pwr_sta2nd_offs = 0x170,
191+ .sram_pdn_bits = BIT(8),
192+ .sram_pdn_ack_bits = BIT(12),
193+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
194+ },
195+ [MT8186_POWER_DOMAIN_CAM_RAWB] = {
196+ .name = "cam_rawb",
197+ .sta_mask = BIT(25),
198+ .ctl_offs = 0x364,
199+ .pwr_sta_offs = 0x16C,
200+ .pwr_sta2nd_offs = 0x170,
201+ .sram_pdn_bits = BIT(8),
202+ .sram_pdn_ack_bits = BIT(12),
203+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
204+ },
205+ [MT8186_POWER_DOMAIN_VENC] = {
206+ .name = "venc",
207+ .sta_mask = BIT(18),
208+ .ctl_offs = 0x348,
209+ .pwr_sta_offs = 0x16C,
210+ .pwr_sta2nd_offs = 0x170,
211+ .sram_pdn_bits = BIT(8),
212+ .sram_pdn_ack_bits = BIT(12),
213+ .bp_infracfg = {
214+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1,
215+ MT8186_TOP_AXI_PROT_EN_1_SET,
216+ MT8186_TOP_AXI_PROT_EN_1_CLR,
217+ MT8186_TOP_AXI_PROT_EN_1_STA),
218+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2,
219+ MT8186_TOP_AXI_PROT_EN_1_SET,
220+ MT8186_TOP_AXI_PROT_EN_1_CLR,
221+ MT8186_TOP_AXI_PROT_EN_1_STA),
222+ },
223+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
224+ },
225+ [MT8186_POWER_DOMAIN_VDEC] = {
226+ .name = "vdec",
227+ .sta_mask = BIT(16),
228+ .ctl_offs = 0x340,
229+ .pwr_sta_offs = 0x16C,
230+ .pwr_sta2nd_offs = 0x170,
231+ .sram_pdn_bits = BIT(8),
232+ .sram_pdn_ack_bits = BIT(12),
233+ .bp_infracfg = {
234+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1,
235+ MT8186_TOP_AXI_PROT_EN_1_SET,
236+ MT8186_TOP_AXI_PROT_EN_1_CLR,
237+ MT8186_TOP_AXI_PROT_EN_1_STA),
238+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2,
239+ MT8186_TOP_AXI_PROT_EN_1_SET,
240+ MT8186_TOP_AXI_PROT_EN_1_CLR,
241+ MT8186_TOP_AXI_PROT_EN_1_STA),
242+ },
243+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
244+ },
245+ [MT8186_POWER_DOMAIN_WPE] = {
246+ .name = "wpe",
247+ .sta_mask = BIT(0),
248+ .ctl_offs = 0x3F8,
249+ .pwr_sta_offs = 0x16C,
250+ .pwr_sta2nd_offs = 0x170,
251+ .sram_pdn_bits = BIT(8),
252+ .sram_pdn_ack_bits = BIT(12),
253+ .bp_infracfg = {
254+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1,
255+ MT8186_TOP_AXI_PROT_EN_2_SET,
256+ MT8186_TOP_AXI_PROT_EN_2_CLR,
257+ MT8186_TOP_AXI_PROT_EN_2_STA),
258+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2,
259+ MT8186_TOP_AXI_PROT_EN_2_SET,
260+ MT8186_TOP_AXI_PROT_EN_2_CLR,
261+ MT8186_TOP_AXI_PROT_EN_2_STA),
262+ },
263+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
264+ },
265+ [MT8186_POWER_DOMAIN_CONN_ON] = {
266+ .name = "conn_on",
267+ .sta_mask = BIT(1),
268+ .ctl_offs = 0x304,
269+ .pwr_sta_offs = 0x16C,
270+ .pwr_sta2nd_offs = 0x170,
271+ .bp_infracfg = {
272+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1,
273+ MT8186_TOP_AXI_PROT_EN_1_SET,
274+ MT8186_TOP_AXI_PROT_EN_1_CLR,
275+ MT8186_TOP_AXI_PROT_EN_1_STA),
276+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2,
277+ MT8186_TOP_AXI_PROT_EN_SET,
278+ MT8186_TOP_AXI_PROT_EN_CLR,
279+ MT8186_TOP_AXI_PROT_EN_STA),
280+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3,
281+ MT8186_TOP_AXI_PROT_EN_SET,
282+ MT8186_TOP_AXI_PROT_EN_CLR,
283+ MT8186_TOP_AXI_PROT_EN_STA),
284+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4,
285+ MT8186_TOP_AXI_PROT_EN_SET,
286+ MT8186_TOP_AXI_PROT_EN_CLR,
287+ MT8186_TOP_AXI_PROT_EN_STA),
288+ },
289+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
290+ },
291+ [MT8186_POWER_DOMAIN_CSIRX_TOP] = {
292+ .name = "csirx_top",
293+ .sta_mask = BIT(6),
294+ .ctl_offs = 0x318,
295+ .pwr_sta_offs = 0x16C,
296+ .pwr_sta2nd_offs = 0x170,
297+ .sram_pdn_bits = BIT(8),
298+ .sram_pdn_ack_bits = BIT(12),
299+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
300+ },
301+ [MT8186_POWER_DOMAIN_ADSP_AO] = {
302+ .name = "adsp_ao",
303+ .sta_mask = BIT(17),
304+ .ctl_offs = 0x9FC,
305+ .pwr_sta_offs = 0x16C,
306+ .pwr_sta2nd_offs = 0x170,
307+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
308+ },
309+ [MT8186_POWER_DOMAIN_ADSP_INFRA] = {
310+ .name = "adsp_infra",
311+ .sta_mask = BIT(10),
312+ .ctl_offs = 0x9F8,
313+ .pwr_sta_offs = 0x16C,
314+ .pwr_sta2nd_offs = 0x170,
315+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
316+ },
317+ [MT8186_POWER_DOMAIN_ADSP_TOP] = {
318+ .name = "adsp_top",
319+ .sta_mask = BIT(31),
320+ .ctl_offs = 0x3E4,
321+ .pwr_sta_offs = 0x16C,
322+ .pwr_sta2nd_offs = 0x170,
323+ .sram_pdn_bits = BIT(8),
324+ .sram_pdn_ack_bits = BIT(12),
325+ .bp_infracfg = {
326+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1,
327+ MT8186_TOP_AXI_PROT_EN_3_SET,
328+ MT8186_TOP_AXI_PROT_EN_3_CLR,
329+ MT8186_TOP_AXI_PROT_EN_3_STA),
330+ BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2,
331+ MT8186_TOP_AXI_PROT_EN_3_SET,
332+ MT8186_TOP_AXI_PROT_EN_3_CLR,
333+ MT8186_TOP_AXI_PROT_EN_3_STA),
334+ },
335+ .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
336+ },
337+};
338+
339+static const struct scpsys_soc_data mt8186_scpsys_data = {
340+ .domains_data = scpsys_domain_data_mt8186,
341+ .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8186),
342+};
343+
344+#endif /* __SOC_MEDIATEK_MT8186_PM_DOMAINS_H */
drivers/soc/mediatek/mt8192-pm-domains.h+42−2
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 14 unmodified lines
1515 .name = "audio",
1616 .sta_mask = BIT(21),
1717 .ctl_offs = 0x0354,
18+ .pwr_sta_offs = 0x016c,
19+ .pwr_sta2nd_offs = 0x0170,
1820 .sram_pdn_bits = GENMASK(8, 8),
1921 .sram_pdn_ack_bits = GENMASK(12, 12),
2022 .bp_infracfg = {
@@ -28,6 +30,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 7 unmodified lines
2830 .name = "conn",
2931 .sta_mask = PWR_STATUS_CONN,
3032 .ctl_offs = 0x0304,
33+ .pwr_sta_offs = 0x016c,
34+ .pwr_sta2nd_offs = 0x0170,
3135 .sram_pdn_bits = 0,
3236 .sram_pdn_ack_bits = 0,
3337 .bp_infracfg = {
@@ -50,6 +54,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 16 unmodified lines
5054 .name = "mfg0",
5155 .sta_mask = BIT(2),
5256 .ctl_offs = 0x0308,
57+ .pwr_sta_offs = 0x016c,
58+ .pwr_sta2nd_offs = 0x0170,
5359 .sram_pdn_bits = GENMASK(8, 8),
5460 .sram_pdn_ack_bits = GENMASK(12, 12),
5561 },
@@ -57,6 +63,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
5763 .name = "mfg1",
5864 .sta_mask = BIT(3),
5965 .ctl_offs = 0x030c,
66+ .pwr_sta_offs = 0x016c,
67+ .pwr_sta2nd_offs = 0x0170,
6068 .sram_pdn_bits = GENMASK(8, 8),
6169 .sram_pdn_ack_bits = GENMASK(12, 12),
6270 .bp_infracfg = {
@@ -82,6 +90,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 19 unmodified lines
8290 .name = "mfg2",
8391 .sta_mask = BIT(4),
8492 .ctl_offs = 0x0310,
93+ .pwr_sta_offs = 0x016c,
94+ .pwr_sta2nd_offs = 0x0170,
8595 .sram_pdn_bits = GENMASK(8, 8),
8696 .sram_pdn_ack_bits = GENMASK(12, 12),
8797 },
@@ -89,6 +99,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
8999 .name = "mfg3",
90100 .sta_mask = BIT(5),
91101 .ctl_offs = 0x0314,
102+ .pwr_sta_offs = 0x016c,
103+ .pwr_sta2nd_offs = 0x0170,
92104 .sram_pdn_bits = GENMASK(8, 8),
93105 .sram_pdn_ack_bits = GENMASK(12, 12),
94106 },
@@ -96,6 +108,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
96108 .name = "mfg4",
97109 .sta_mask = BIT(6),
98110 .ctl_offs = 0x0318,
111+ .pwr_sta_offs = 0x016c,
112+ .pwr_sta2nd_offs = 0x0170,
99113 .sram_pdn_bits = GENMASK(8, 8),
100114 .sram_pdn_ack_bits = GENMASK(12, 12),
101115 },
@@ -103,6 +117,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
103117 .name = "mfg5",
104118 .sta_mask = BIT(7),
105119 .ctl_offs = 0x031c,
120+ .pwr_sta_offs = 0x016c,
121+ .pwr_sta2nd_offs = 0x0170,
106122 .sram_pdn_bits = GENMASK(8, 8),
107123 .sram_pdn_ack_bits = GENMASK(12, 12),
108124 },
@@ -110,6 +126,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
110126 .name = "mfg6",
111127 .sta_mask = BIT(8),
112128 .ctl_offs = 0x0320,
129+ .pwr_sta_offs = 0x016c,
130+ .pwr_sta2nd_offs = 0x0170,
113131 .sram_pdn_bits = GENMASK(8, 8),
114132 .sram_pdn_ack_bits = GENMASK(12, 12),
115133 },
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
117135 .name = "disp",
118136 .sta_mask = BIT(20),
119137 .ctl_offs = 0x0350,
138+ .pwr_sta_offs = 0x016c,
139+ .pwr_sta2nd_offs = 0x0170,
120140 .sram_pdn_bits = GENMASK(8, 8),
121141 .sram_pdn_ack_bits = GENMASK(12, 12),
122142 .bp_infracfg = {
@@ -146,6 +166,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 23 unmodified lines
146166 .name = "ipe",
147167 .sta_mask = BIT(14),
148168 .ctl_offs = 0x0338,
169+ .pwr_sta_offs = 0x016c,
170+ .pwr_sta2nd_offs = 0x0170,
149171 .sram_pdn_bits = GENMASK(8, 8),
150172 .sram_pdn_ack_bits = GENMASK(12, 12),
151173 .bp_infracfg = {
@@ -163,6 +185,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
163185 .name = "isp",
164186 .sta_mask = BIT(12),
165187 .ctl_offs = 0x0330,
188+ .pwr_sta_offs = 0x016c,
189+ .pwr_sta2nd_offs = 0x0170,
166190 .sram_pdn_bits = GENMASK(8, 8),
167191 .sram_pdn_ack_bits = GENMASK(12, 12),
168192 .bp_infracfg = {
@@ -180,6 +204,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
180204 .name = "isp2",
181205 .sta_mask = BIT(13),
182206 .ctl_offs = 0x0334,
207+ .pwr_sta_offs = 0x016c,
208+ .pwr_sta2nd_offs = 0x0170,
183209 .sram_pdn_bits = GENMASK(8, 8),
184210 .sram_pdn_ack_bits = GENMASK(12, 12),
185211 .bp_infracfg = {
@@ -197,6 +223,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
197223 .name = "mdp",
198224 .sta_mask = BIT(19),
199225 .ctl_offs = 0x034c,
226+ .pwr_sta_offs = 0x016c,
227+ .pwr_sta2nd_offs = 0x0170,
200228 .sram_pdn_bits = GENMASK(8, 8),
201229 .sram_pdn_ack_bits = GENMASK(12, 12),
202230 .bp_infracfg = {
@@ -214,6 +242,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
214242 .name = "venc",
215243 .sta_mask = BIT(17),
216244 .ctl_offs = 0x0344,
245+ .pwr_sta_offs = 0x016c,
246+ .pwr_sta2nd_offs = 0x0170,
217247 .sram_pdn_bits = GENMASK(8, 8),
218248 .sram_pdn_ack_bits = GENMASK(12, 12),
219249 .bp_infracfg = {
@@ -231,6 +261,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
231261 .name = "vdec",
232262 .sta_mask = BIT(15),
233263 .ctl_offs = 0x033c,
264+ .pwr_sta_offs = 0x016c,
265+ .pwr_sta2nd_offs = 0x0170,
234266 .sram_pdn_bits = GENMASK(8, 8),
235267 .sram_pdn_ack_bits = GENMASK(12, 12),
236268 .bp_infracfg = {
@@ -248,6 +280,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
248280 .name = "vdec2",
249281 .sta_mask = BIT(16),
250282 .ctl_offs = 0x0340,
283+ .pwr_sta_offs = 0x016c,
284+ .pwr_sta2nd_offs = 0x0170,
251285 .sram_pdn_bits = GENMASK(8, 8),
252286 .sram_pdn_ack_bits = GENMASK(12, 12),
253287 },
@@ -255,6 +289,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
255289 .name = "cam",
256290 .sta_mask = BIT(23),
257291 .ctl_offs = 0x035c,
292+ .pwr_sta_offs = 0x016c,
293+ .pwr_sta2nd_offs = 0x0170,
258294 .sram_pdn_bits = GENMASK(8, 8),
259295 .sram_pdn_ack_bits = GENMASK(12, 12),
260296 .bp_infracfg = {
@@ -284,6 +320,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 23 unmodified lines
284320 .name = "cam_rawa",
285321 .sta_mask = BIT(24),
286322 .ctl_offs = 0x0360,
323+ .pwr_sta_offs = 0x016c,
324+ .pwr_sta2nd_offs = 0x0170,
287325 .sram_pdn_bits = GENMASK(8, 8),
288326 .sram_pdn_ack_bits = GENMASK(12, 12),
289327 },
@@ -291,6 +329,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
291329 .name = "cam_rawb",
292330 .sta_mask = BIT(25),
293331 .ctl_offs = 0x0364,
332+ .pwr_sta_offs = 0x016c,
333+ .pwr_sta2nd_offs = 0x0170,
294334 .sram_pdn_bits = GENMASK(8, 8),
295335 .sram_pdn_ack_bits = GENMASK(12, 12),
296336 },
@@ -298,6 +338,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
298338 .name = "cam_rawc",
299339 .sta_mask = BIT(26),
300340 .ctl_offs = 0x0368,
341+ .pwr_sta_offs = 0x016c,
342+ .pwr_sta2nd_offs = 0x0170,
301343 .sram_pdn_bits = GENMASK(8, 8),
302344 .sram_pdn_ack_bits = GENMASK(12, 12),
303345 },
@@ -306,8 +348,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 2 unmodified lines
306348 static const struct scpsys_soc_data mt8192_scpsys_data = {
307349 .domains_data = scpsys_domain_data_mt8192,
308350 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
309− .pwr_sta_offs = 0x016c,
310− .pwr_sta2nd_offs = 0x0170,
311351 };
312352
313353 #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
drivers/soc/mediatek/mt8195-pm-domains.h+613−0
@@ -0,0 +1,613 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (c) 2021 MediaTek Inc.
4+ * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
5+ */
6+
7+#ifndef __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
8+#define __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
9+
10+#include "mtk-pm-domains.h"
11+#include <dt-bindings/power/mt8195-power.h>
12+
13+/*
14+ * MT8195 power domain support
15+ */
16+
17+static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
18+ [MT8195_POWER_DOMAIN_PCIE_MAC_P0] = {
19+ .name = "pcie_mac_p0",
20+ .sta_mask = BIT(11),
21+ .ctl_offs = 0x328,
22+ .pwr_sta_offs = 0x174,
23+ .pwr_sta2nd_offs = 0x178,
24+ .sram_pdn_bits = GENMASK(8, 8),
25+ .sram_pdn_ack_bits = GENMASK(12, 12),
26+ .bp_infracfg = {
27+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0,
28+ MT8195_TOP_AXI_PROT_EN_VDNR_SET,
29+ MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
30+ MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
31+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0,
32+ MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
33+ MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
34+ MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
35+ },
36+ },
37+ [MT8195_POWER_DOMAIN_PCIE_MAC_P1] = {
38+ .name = "pcie_mac_p1",
39+ .sta_mask = BIT(12),
40+ .ctl_offs = 0x32C,
41+ .pwr_sta_offs = 0x174,
42+ .pwr_sta2nd_offs = 0x178,
43+ .sram_pdn_bits = GENMASK(8, 8),
44+ .sram_pdn_ack_bits = GENMASK(12, 12),
45+ .bp_infracfg = {
46+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1,
47+ MT8195_TOP_AXI_PROT_EN_VDNR_SET,
48+ MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
49+ MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
50+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1,
51+ MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
52+ MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
53+ MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
54+ },
55+ },
56+ [MT8195_POWER_DOMAIN_PCIE_PHY] = {
57+ .name = "pcie_phy",
58+ .sta_mask = BIT(13),
59+ .ctl_offs = 0x330,
60+ .pwr_sta_offs = 0x174,
61+ .pwr_sta2nd_offs = 0x178,
62+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
63+ },
64+ [MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY] = {
65+ .name = "ssusb_pcie_phy",
66+ .sta_mask = BIT(14),
67+ .ctl_offs = 0x334,
68+ .pwr_sta_offs = 0x174,
69+ .pwr_sta2nd_offs = 0x178,
70+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
71+ },
72+ [MT8195_POWER_DOMAIN_CSI_RX_TOP] = {
73+ .name = "csi_rx_top",
74+ .sta_mask = BIT(18),
75+ .ctl_offs = 0x3C4,
76+ .pwr_sta_offs = 0x174,
77+ .pwr_sta2nd_offs = 0x178,
78+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
79+ },
80+ [MT8195_POWER_DOMAIN_ETHER] = {
81+ .name = "ether",
82+ .sta_mask = BIT(3),
83+ .ctl_offs = 0x344,
84+ .pwr_sta_offs = 0x16c,
85+ .pwr_sta2nd_offs = 0x170,
86+ .sram_pdn_bits = GENMASK(8, 8),
87+ .sram_pdn_ack_bits = GENMASK(12, 12),
88+ .caps = MTK_SCPD_ACTIVE_WAKEUP,
89+ },
90+ [MT8195_POWER_DOMAIN_ADSP] = {
91+ .name = "adsp",
92+ .sta_mask = BIT(10),
93+ .ctl_offs = 0x360,
94+ .pwr_sta_offs = 0x16c,
95+ .pwr_sta2nd_offs = 0x170,
96+ .sram_pdn_bits = GENMASK(8, 8),
97+ .sram_pdn_ack_bits = GENMASK(12, 12),
98+ .bp_infracfg = {
99+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_ADSP,
100+ MT8195_TOP_AXI_PROT_EN_2_SET,
101+ MT8195_TOP_AXI_PROT_EN_2_CLR,
102+ MT8195_TOP_AXI_PROT_EN_2_STA1),
103+ },
104+ .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP,
105+ },
106+ [MT8195_POWER_DOMAIN_AUDIO] = {
107+ .name = "audio",
108+ .sta_mask = BIT(8),
109+ .ctl_offs = 0x358,
110+ .pwr_sta_offs = 0x16c,
111+ .pwr_sta2nd_offs = 0x170,
112+ .sram_pdn_bits = GENMASK(8, 8),
113+ .sram_pdn_ack_bits = GENMASK(12, 12),
114+ .bp_infracfg = {
115+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_AUDIO,
116+ MT8195_TOP_AXI_PROT_EN_2_SET,
117+ MT8195_TOP_AXI_PROT_EN_2_CLR,
118+ MT8195_TOP_AXI_PROT_EN_2_STA1),
119+ },
120+ },
121+ [MT8195_POWER_DOMAIN_MFG0] = {
122+ .name = "mfg0",
123+ .sta_mask = BIT(1),
124+ .ctl_offs = 0x300,
125+ .pwr_sta_offs = 0x174,
126+ .pwr_sta2nd_offs = 0x178,
127+ .sram_pdn_bits = GENMASK(8, 8),
128+ .sram_pdn_ack_bits = GENMASK(12, 12),
129+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
130+ },
131+ [MT8195_POWER_DOMAIN_MFG1] = {
132+ .name = "mfg1",
133+ .sta_mask = BIT(2),
134+ .ctl_offs = 0x304,
135+ .pwr_sta_offs = 0x174,
136+ .pwr_sta2nd_offs = 0x178,
137+ .sram_pdn_bits = GENMASK(8, 8),
138+ .sram_pdn_ack_bits = GENMASK(12, 12),
139+ .bp_infracfg = {
140+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1,
141+ MT8195_TOP_AXI_PROT_EN_SET,
142+ MT8195_TOP_AXI_PROT_EN_CLR,
143+ MT8195_TOP_AXI_PROT_EN_STA1),
144+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1,
145+ MT8195_TOP_AXI_PROT_EN_2_SET,
146+ MT8195_TOP_AXI_PROT_EN_2_CLR,
147+ MT8195_TOP_AXI_PROT_EN_2_STA1),
148+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_MFG1,
149+ MT8195_TOP_AXI_PROT_EN_1_SET,
150+ MT8195_TOP_AXI_PROT_EN_1_CLR,
151+ MT8195_TOP_AXI_PROT_EN_1_STA1),
152+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND,
153+ MT8195_TOP_AXI_PROT_EN_2_SET,
154+ MT8195_TOP_AXI_PROT_EN_2_CLR,
155+ MT8195_TOP_AXI_PROT_EN_2_STA1),
156+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1_2ND,
157+ MT8195_TOP_AXI_PROT_EN_SET,
158+ MT8195_TOP_AXI_PROT_EN_CLR,
159+ MT8195_TOP_AXI_PROT_EN_STA1),
160+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1,
161+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
162+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
163+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
164+ },
165+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
166+ },
167+ [MT8195_POWER_DOMAIN_MFG2] = {
168+ .name = "mfg2",
169+ .sta_mask = BIT(3),
170+ .ctl_offs = 0x308,
171+ .pwr_sta_offs = 0x174,
172+ .pwr_sta2nd_offs = 0x178,
173+ .sram_pdn_bits = GENMASK(8, 8),
174+ .sram_pdn_ack_bits = GENMASK(12, 12),
175+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
176+ },
177+ [MT8195_POWER_DOMAIN_MFG3] = {
178+ .name = "mfg3",
179+ .sta_mask = BIT(4),
180+ .ctl_offs = 0x30C,
181+ .pwr_sta_offs = 0x174,
182+ .pwr_sta2nd_offs = 0x178,
183+ .sram_pdn_bits = GENMASK(8, 8),
184+ .sram_pdn_ack_bits = GENMASK(12, 12),
185+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
186+ },
187+ [MT8195_POWER_DOMAIN_MFG4] = {
188+ .name = "mfg4",
189+ .sta_mask = BIT(5),
190+ .ctl_offs = 0x310,
191+ .pwr_sta_offs = 0x174,
192+ .pwr_sta2nd_offs = 0x178,
193+ .sram_pdn_bits = GENMASK(8, 8),
194+ .sram_pdn_ack_bits = GENMASK(12, 12),
195+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
196+ },
197+ [MT8195_POWER_DOMAIN_MFG5] = {
198+ .name = "mfg5",
199+ .sta_mask = BIT(6),
200+ .ctl_offs = 0x314,
201+ .pwr_sta_offs = 0x174,
202+ .pwr_sta2nd_offs = 0x178,
203+ .sram_pdn_bits = GENMASK(8, 8),
204+ .sram_pdn_ack_bits = GENMASK(12, 12),
205+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
206+ },
207+ [MT8195_POWER_DOMAIN_MFG6] = {
208+ .name = "mfg6",
209+ .sta_mask = BIT(7),
210+ .ctl_offs = 0x318,
211+ .pwr_sta_offs = 0x174,
212+ .pwr_sta2nd_offs = 0x178,
213+ .sram_pdn_bits = GENMASK(8, 8),
214+ .sram_pdn_ack_bits = GENMASK(12, 12),
215+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
216+ },
217+ [MT8195_POWER_DOMAIN_VPPSYS0] = {
218+ .name = "vppsys0",
219+ .sta_mask = BIT(11),
220+ .ctl_offs = 0x364,
221+ .pwr_sta_offs = 0x16c,
222+ .pwr_sta2nd_offs = 0x170,
223+ .sram_pdn_bits = GENMASK(8, 8),
224+ .sram_pdn_ack_bits = GENMASK(12, 12),
225+ .bp_infracfg = {
226+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0,
227+ MT8195_TOP_AXI_PROT_EN_SET,
228+ MT8195_TOP_AXI_PROT_EN_CLR,
229+ MT8195_TOP_AXI_PROT_EN_STA1),
230+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0,
231+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
232+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
233+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
234+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND,
235+ MT8195_TOP_AXI_PROT_EN_SET,
236+ MT8195_TOP_AXI_PROT_EN_CLR,
237+ MT8195_TOP_AXI_PROT_EN_STA1),
238+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND,
239+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
240+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
241+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
242+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0,
243+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
244+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
245+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
246+ },
247+ },
248+ [MT8195_POWER_DOMAIN_VDOSYS0] = {
249+ .name = "vdosys0",
250+ .sta_mask = BIT(13),
251+ .ctl_offs = 0x36C,
252+ .pwr_sta_offs = 0x16c,
253+ .pwr_sta2nd_offs = 0x170,
254+ .sram_pdn_bits = GENMASK(8, 8),
255+ .sram_pdn_ack_bits = GENMASK(12, 12),
256+ .bp_infracfg = {
257+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0,
258+ MT8195_TOP_AXI_PROT_EN_MM_SET,
259+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
260+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
261+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDOSYS0,
262+ MT8195_TOP_AXI_PROT_EN_SET,
263+ MT8195_TOP_AXI_PROT_EN_CLR,
264+ MT8195_TOP_AXI_PROT_EN_STA1),
265+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0,
266+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
267+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
268+ MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
269+ },
270+ },
271+ [MT8195_POWER_DOMAIN_VPPSYS1] = {
272+ .name = "vppsys1",
273+ .sta_mask = BIT(12),
274+ .ctl_offs = 0x368,
275+ .pwr_sta_offs = 0x16c,
276+ .pwr_sta2nd_offs = 0x170,
277+ .sram_pdn_bits = GENMASK(8, 8),
278+ .sram_pdn_ack_bits = GENMASK(12, 12),
279+ .bp_infracfg = {
280+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1,
281+ MT8195_TOP_AXI_PROT_EN_MM_SET,
282+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
283+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
284+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND,
285+ MT8195_TOP_AXI_PROT_EN_MM_SET,
286+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
287+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
288+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1,
289+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
290+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
291+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
292+ },
293+ },
294+ [MT8195_POWER_DOMAIN_VDOSYS1] = {
295+ .name = "vdosys1",
296+ .sta_mask = BIT(14),
297+ .ctl_offs = 0x370,
298+ .pwr_sta_offs = 0x16c,
299+ .pwr_sta2nd_offs = 0x170,
300+ .sram_pdn_bits = GENMASK(8, 8),
301+ .sram_pdn_ack_bits = GENMASK(12, 12),
302+ .bp_infracfg = {
303+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1,
304+ MT8195_TOP_AXI_PROT_EN_MM_SET,
305+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
306+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
307+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND,
308+ MT8195_TOP_AXI_PROT_EN_MM_SET,
309+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
310+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
311+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1,
312+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
313+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
314+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
315+ },
316+ },
317+ [MT8195_POWER_DOMAIN_DP_TX] = {
318+ .name = "dp_tx",
319+ .sta_mask = BIT(16),
320+ .ctl_offs = 0x378,
321+ .pwr_sta_offs = 0x16c,
322+ .pwr_sta2nd_offs = 0x170,
323+ .sram_pdn_bits = GENMASK(8, 8),
324+ .sram_pdn_ack_bits = GENMASK(12, 12),
325+ .bp_infracfg = {
326+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX,
327+ MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
328+ MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
329+ MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
330+ },
331+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
332+ },
333+ [MT8195_POWER_DOMAIN_EPD_TX] = {
334+ .name = "epd_tx",
335+ .sta_mask = BIT(17),
336+ .ctl_offs = 0x37C,
337+ .pwr_sta_offs = 0x16c,
338+ .pwr_sta2nd_offs = 0x170,
339+ .sram_pdn_bits = GENMASK(8, 8),
340+ .sram_pdn_ack_bits = GENMASK(12, 12),
341+ .bp_infracfg = {
342+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX,
343+ MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
344+ MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
345+ MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
346+ },
347+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
348+ },
349+ [MT8195_POWER_DOMAIN_HDMI_TX] = {
350+ .name = "hdmi_tx",
351+ .sta_mask = BIT(18),
352+ .ctl_offs = 0x380,
353+ .pwr_sta_offs = 0x16c,
354+ .pwr_sta2nd_offs = 0x170,
355+ .sram_pdn_bits = GENMASK(8, 8),
356+ .sram_pdn_ack_bits = GENMASK(12, 12),
357+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
358+ },
359+ [MT8195_POWER_DOMAIN_WPESYS] = {
360+ .name = "wpesys",
361+ .sta_mask = BIT(15),
362+ .ctl_offs = 0x374,
363+ .pwr_sta_offs = 0x16c,
364+ .pwr_sta2nd_offs = 0x170,
365+ .sram_pdn_bits = GENMASK(8, 8),
366+ .sram_pdn_ack_bits = GENMASK(12, 12),
367+ .bp_infracfg = {
368+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS,
369+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
370+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
371+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
372+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_WPESYS,
373+ MT8195_TOP_AXI_PROT_EN_MM_SET,
374+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
375+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
376+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND,
377+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
378+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
379+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
380+ },
381+ },
382+ [MT8195_POWER_DOMAIN_VDEC0] = {
383+ .name = "vdec0",
384+ .sta_mask = BIT(20),
385+ .ctl_offs = 0x388,
386+ .pwr_sta_offs = 0x16c,
387+ .pwr_sta2nd_offs = 0x170,
388+ .sram_pdn_bits = GENMASK(8, 8),
389+ .sram_pdn_ack_bits = GENMASK(12, 12),
390+ .bp_infracfg = {
391+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0,
392+ MT8195_TOP_AXI_PROT_EN_MM_SET,
393+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
394+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
395+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0,
396+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
397+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
398+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
399+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND,
400+ MT8195_TOP_AXI_PROT_EN_MM_SET,
401+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
402+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
403+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND,
404+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
405+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
406+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
407+ },
408+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
409+ },
410+ [MT8195_POWER_DOMAIN_VDEC1] = {
411+ .name = "vdec1",
412+ .sta_mask = BIT(21),
413+ .ctl_offs = 0x38C,
414+ .pwr_sta_offs = 0x16c,
415+ .pwr_sta2nd_offs = 0x170,
416+ .sram_pdn_bits = GENMASK(8, 8),
417+ .sram_pdn_ack_bits = GENMASK(12, 12),
418+ .bp_infracfg = {
419+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1,
420+ MT8195_TOP_AXI_PROT_EN_MM_SET,
421+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
422+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
423+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND,
424+ MT8195_TOP_AXI_PROT_EN_MM_SET,
425+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
426+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
427+ },
428+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
429+ },
430+ [MT8195_POWER_DOMAIN_VDEC2] = {
431+ .name = "vdec2",
432+ .sta_mask = BIT(22),
433+ .ctl_offs = 0x390,
434+ .pwr_sta_offs = 0x16c,
435+ .pwr_sta2nd_offs = 0x170,
436+ .sram_pdn_bits = GENMASK(8, 8),
437+ .sram_pdn_ack_bits = GENMASK(12, 12),
438+ .bp_infracfg = {
439+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2,
440+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
441+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
442+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
443+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND,
444+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
445+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
446+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
447+ },
448+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
449+ },
450+ [MT8195_POWER_DOMAIN_VENC] = {
451+ .name = "venc",
452+ .sta_mask = BIT(23),
453+ .ctl_offs = 0x394,
454+ .pwr_sta_offs = 0x16c,
455+ .pwr_sta2nd_offs = 0x170,
456+ .sram_pdn_bits = GENMASK(8, 8),
457+ .sram_pdn_ack_bits = GENMASK(12, 12),
458+ .bp_infracfg = {
459+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC,
460+ MT8195_TOP_AXI_PROT_EN_MM_SET,
461+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
462+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
463+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND,
464+ MT8195_TOP_AXI_PROT_EN_MM_SET,
465+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
466+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
467+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC,
468+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
469+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
470+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
471+ },
472+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
473+ },
474+ [MT8195_POWER_DOMAIN_VENC_CORE1] = {
475+ .name = "venc_core1",
476+ .sta_mask = BIT(24),
477+ .ctl_offs = 0x398,
478+ .pwr_sta_offs = 0x16c,
479+ .pwr_sta2nd_offs = 0x170,
480+ .sram_pdn_bits = GENMASK(8, 8),
481+ .sram_pdn_ack_bits = GENMASK(12, 12),
482+ .bp_infracfg = {
483+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1,
484+ MT8195_TOP_AXI_PROT_EN_MM_SET,
485+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
486+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
487+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1,
488+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
489+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
490+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
491+ },
492+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
493+ },
494+ [MT8195_POWER_DOMAIN_IMG] = {
495+ .name = "img",
496+ .sta_mask = BIT(29),
497+ .ctl_offs = 0x3AC,
498+ .pwr_sta_offs = 0x16c,
499+ .pwr_sta2nd_offs = 0x170,
500+ .sram_pdn_bits = GENMASK(8, 8),
501+ .sram_pdn_ack_bits = GENMASK(12, 12),
502+ .bp_infracfg = {
503+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG,
504+ MT8195_TOP_AXI_PROT_EN_MM_SET,
505+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
506+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
507+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND,
508+ MT8195_TOP_AXI_PROT_EN_MM_SET,
509+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
510+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
511+ },
512+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
513+ },
514+ [MT8195_POWER_DOMAIN_DIP] = {
515+ .name = "dip",
516+ .sta_mask = BIT(30),
517+ .ctl_offs = 0x3B0,
518+ .pwr_sta_offs = 0x16c,
519+ .pwr_sta2nd_offs = 0x170,
520+ .sram_pdn_bits = GENMASK(8, 8),
521+ .sram_pdn_ack_bits = GENMASK(12, 12),
522+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
523+ },
524+ [MT8195_POWER_DOMAIN_IPE] = {
525+ .name = "ipe",
526+ .sta_mask = BIT(31),
527+ .ctl_offs = 0x3B4,
528+ .pwr_sta_offs = 0x16c,
529+ .pwr_sta2nd_offs = 0x170,
530+ .sram_pdn_bits = GENMASK(8, 8),
531+ .sram_pdn_ack_bits = GENMASK(12, 12),
532+ .bp_infracfg = {
533+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IPE,
534+ MT8195_TOP_AXI_PROT_EN_MM_SET,
535+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
536+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
537+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_IPE,
538+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
539+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
540+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
541+ },
542+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
543+ },
544+ [MT8195_POWER_DOMAIN_CAM] = {
545+ .name = "cam",
546+ .sta_mask = BIT(25),
547+ .ctl_offs = 0x39C,
548+ .pwr_sta_offs = 0x16c,
549+ .pwr_sta2nd_offs = 0x170,
550+ .sram_pdn_bits = GENMASK(8, 8),
551+ .sram_pdn_ack_bits = GENMASK(12, 12),
552+ .bp_infracfg = {
553+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_CAM,
554+ MT8195_TOP_AXI_PROT_EN_2_SET,
555+ MT8195_TOP_AXI_PROT_EN_2_CLR,
556+ MT8195_TOP_AXI_PROT_EN_2_STA1),
557+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM,
558+ MT8195_TOP_AXI_PROT_EN_MM_SET,
559+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
560+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
561+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_CAM,
562+ MT8195_TOP_AXI_PROT_EN_1_SET,
563+ MT8195_TOP_AXI_PROT_EN_1_CLR,
564+ MT8195_TOP_AXI_PROT_EN_1_STA1),
565+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND,
566+ MT8195_TOP_AXI_PROT_EN_MM_SET,
567+ MT8195_TOP_AXI_PROT_EN_MM_CLR,
568+ MT8195_TOP_AXI_PROT_EN_MM_STA1),
569+ BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_CAM,
570+ MT8195_TOP_AXI_PROT_EN_MM_2_SET,
571+ MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
572+ MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
573+ },
574+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
575+ },
576+ [MT8195_POWER_DOMAIN_CAM_RAWA] = {
577+ .name = "cam_rawa",
578+ .sta_mask = BIT(26),
579+ .ctl_offs = 0x3A0,
580+ .pwr_sta_offs = 0x16c,
581+ .pwr_sta2nd_offs = 0x170,
582+ .sram_pdn_bits = GENMASK(8, 8),
583+ .sram_pdn_ack_bits = GENMASK(12, 12),
584+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
585+ },
586+ [MT8195_POWER_DOMAIN_CAM_RAWB] = {
587+ .name = "cam_rawb",
588+ .sta_mask = BIT(27),
589+ .ctl_offs = 0x3A4,
590+ .pwr_sta_offs = 0x16c,
591+ .pwr_sta2nd_offs = 0x170,
592+ .sram_pdn_bits = GENMASK(8, 8),
593+ .sram_pdn_ack_bits = GENMASK(12, 12),
594+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
595+ },
596+ [MT8195_POWER_DOMAIN_CAM_MRAW] = {
597+ .name = "cam_mraw",
598+ .sta_mask = BIT(28),
599+ .ctl_offs = 0x3A8,
600+ .pwr_sta_offs = 0x16c,
601+ .pwr_sta2nd_offs = 0x170,
602+ .sram_pdn_bits = GENMASK(8, 8),
603+ .sram_pdn_ack_bits = GENMASK(12, 12),
604+ .caps = MTK_SCPD_KEEP_DEFAULT_OFF,
605+ },
606+};
607+
608+static const struct scpsys_soc_data mt8195_scpsys_data = {
609+ .domains_data = scpsys_domain_data_mt8195,
610+ .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195),
611+};
612+
613+#endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */
drivers/soc/mediatek/mtk-infracfg.c+19−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/export.h>
77 #include <linux/jiffies.h>
88 #include <linux/regmap.h>
9+#include <linux/mfd/syscon.h>
910 #include <linux/soc/mediatek/infracfg.h>
1011 #include <asm/processor.h>
1112
@@ -72,3 +73,21 @@ int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, · 60 unmodified lines
7273
7374 return ret;
7475 }
76+
77+static int __init mtk_infracfg_init(void)
78+{
79+ struct regmap *infracfg;
80+
81+ /*
82+ * MT8192 has an experimental path to route GPU traffic to the DSU's
83+ * Accelerator Coherency Port, which is inadvertently enabled by
84+ * default. It turns out not to work, so disable it to prevent spurious
85+ * GPU faults.
86+ */
87+ infracfg = syscon_regmap_lookup_by_compatible("mediatek,mt8192-infracfg");
88+ if (!IS_ERR(infracfg))
89+ regmap_set_bits(infracfg, MT8192_INFRA_CTRL,
90+ MT8192_INFRA_CTRL_DISABLE_MFG2ACP);
91+ return 0;
92+}
93+postcore_initcall(mtk_infracfg_init);
drivers/soc/mediatek/mtk-mmsys.c+16−2
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include "mtk-mmsys.h"
1616 #include "mt8167-mmsys.h"
1717 #include "mt8183-mmsys.h"
18+#include "mt8186-mmsys.h"
1819 #include "mt8192-mmsys.h"
1920 #include "mt8365-mmsys.h"
2021
@@ -48,12 +49,21 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = { · 27 unmodified lines
4849 .clk_driver = "clk-mt8173-mm",
4950 .routes = mmsys_default_routing_table,
5051 .num_routes = ARRAY_SIZE(mmsys_default_routing_table),
52+ .sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
5153 };
5254
5355 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
5456 .clk_driver = "clk-mt8183-mm",
5557 .routes = mmsys_mt8183_routing_table,
5658 .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
59+ .sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
60+};
61+
62+static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
63+ .clk_driver = "clk-mt8186-mm",
64+ .routes = mmsys_mt8186_routing_table,
65+ .num_routes = ARRAY_SIZE(mmsys_mt8186_routing_table),
66+ .sw0_rst_offset = MT8186_MMSYS_SW0_RST_B,
5767 };
5868
5969 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -121,14 +131,14 @@ static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned l · 61 unmodified lines
121131
122132 spin_lock_irqsave(&mmsys->lock, flags);
123133
124− reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
134+ reg = readl_relaxed(mmsys->regs + mmsys->data->sw0_rst_offset);
125135
126136 if (assert)
127137 reg &= ~BIT(id);
128138 else
129139 reg |= BIT(id);
130140
131− writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
141+ writel_relaxed(reg, mmsys->regs + mmsys->data->sw0_rst_offset);
132142
133143 spin_unlock_irqrestore(&mmsys->lock, flags);
134144
@@ -242,6 +252,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = { · 107 unmodified lines
242252 .compatible = "mediatek,mt8183-mmsys",
243253 .data = &mt8183_mmsys_driver_data,
244254 },
255+ {
256+ .compatible = "mediatek,mt8186-mmsys",
257+ .data = &mt8186_mmsys_driver_data,
258+ },
245259 {
246260 .compatible = "mediatek,mt8192-mmsys",
247261 .data = &mt8192_mmsys_driver_data,
drivers/soc/mediatek/mtk-mmsys.h+1−2
@@ -78,8 +78,6 @@ · 77 unmodified lines
7878 #define DSI_SEL_IN_RDMA 0x1
7979 #define DSI_SEL_IN_MASK 0x1
8080
81−#define MMSYS_SW0_RST_B 0x140
82−
8381 struct mtk_mmsys_routes {
8482 u32 from_comp;
8583 u32 to_comp;
@@ -92,6 +90,7 @@ struct mtk_mmsys_driver_data { · 6 unmodified lines
9290 const char *clk_driver;
9391 const struct mtk_mmsys_routes *routes;
9492 const unsigned int num_routes;
93+ const u16 sw0_rst_offset;
9594 };
9695
9796 /*
drivers/soc/mediatek/mtk-mutex.c+45−0
@@ -26,6 +26,23 @@ · 25 unmodified lines
2626
2727 #define INT_MUTEX BIT(1)
2828
29+#define MT8186_MUTEX_MOD_DISP_OVL0 0
30+#define MT8186_MUTEX_MOD_DISP_OVL0_2L 1
31+#define MT8186_MUTEX_MOD_DISP_RDMA0 2
32+#define MT8186_MUTEX_MOD_DISP_COLOR0 4
33+#define MT8186_MUTEX_MOD_DISP_CCORR0 5
34+#define MT8186_MUTEX_MOD_DISP_AAL0 7
35+#define MT8186_MUTEX_MOD_DISP_GAMMA0 8
36+#define MT8186_MUTEX_MOD_DISP_POSTMASK0 9
37+#define MT8186_MUTEX_MOD_DISP_DITHER0 10
38+#define MT8186_MUTEX_MOD_DISP_RDMA1 17
39+
40+#define MT8186_MUTEX_SOF_SINGLE_MODE 0
41+#define MT8186_MUTEX_SOF_DSI0 1
42+#define MT8186_MUTEX_SOF_DPI0 2
43+#define MT8186_MUTEX_EOF_DSI0 (MT8186_MUTEX_SOF_DSI0 << 6)
44+#define MT8186_MUTEX_EOF_DPI0 (MT8186_MUTEX_SOF_DPI0 << 6)
45+
2946 #define MT8167_MUTEX_MOD_DISP_PWM 1
3047 #define MT8167_MUTEX_MOD_DISP_OVL0 6
3148 #define MT8167_MUTEX_MOD_DISP_OVL1 7
@@ -226,6 +243,19 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = { · 194 unmodified lines
226243 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
227244 };
228245
246+static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
247+ [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
248+ [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
249+ [DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
250+ [DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0,
251+ [DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
252+ [DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
253+ [DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
254+ [DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
255+ [DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
256+ [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
257+};
258+
229259 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
230260 [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
231261 [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
@@ -264,6 +294,12 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = { · 32 unmodified lines
264294 [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
265295 };
266296
297+static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
298+ [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
299+ [MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
300+ [MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
301+};
302+
267303 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
268304 .mutex_mod = mt2701_mutex_mod,
269305 .mutex_sof = mt2712_mutex_sof,
@@ -301,6 +337,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { · 31 unmodified lines
301337 .no_clk = true,
302338 };
303339
340+static const struct mtk_mutex_data mt8186_mutex_driver_data = {
341+ .mutex_mod = mt8186_mutex_mod,
342+ .mutex_sof = mt8186_mutex_sof,
343+ .mutex_mod_reg = MT8183_MUTEX0_MOD0,
344+ .mutex_sof_reg = MT8183_MUTEX0_SOF0,
345+};
346+
304347 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
305348 .mutex_mod = mt8192_mutex_mod,
306349 .mutex_sof = mt8183_mutex_sof,
@@ -540,6 +583,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { · 233 unmodified lines
540583 .data = &mt8173_mutex_driver_data},
541584 { .compatible = "mediatek,mt8183-disp-mutex",
542585 .data = &mt8183_mutex_driver_data},
586+ { .compatible = "mediatek,mt8186-disp-mutex",
587+ .data = &mt8186_mutex_driver_data},
543588 { .compatible = "mediatek,mt8192-disp-mutex",
544589 .data = &mt8192_mutex_driver_data},
545590 {},
drivers/soc/mediatek/mtk-pm-domains.c+15−2
@@ -19,7 +19,9 @@ · 18 unmodified lines
1919 #include "mt8167-pm-domains.h"
2020 #include "mt8173-pm-domains.h"
2121 #include "mt8183-pm-domains.h"
22+#include "mt8186-pm-domains.h"
2223 #include "mt8192-pm-domains.h"
24+#include "mt8195-pm-domains.h"
2325
2426 #define MTK_POLL_DELAY_US 10
2527 #define MTK_POLL_TIMEOUT USEC_PER_SEC
@@ -60,10 +62,10 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd) · 34 unmodified lines
6062 struct scpsys *scpsys = pd->scpsys;
6163 u32 status, status2;
6264
63− regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);
65+ regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
6466 status &= pd->data->sta_mask;
6567
66− regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);
68+ regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
6769 status2 &= pd->data->sta_mask;
6870
6971 /* A domain is on when both status bits are set. */
@@ -443,6 +445,9 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no · 373 unmodified lines
443445 pd->genpd.power_off = scpsys_power_off;
444446 pd->genpd.power_on = scpsys_power_on;
445447
448+ if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP))
449+ pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
450+
446451 if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))
447452 pm_genpd_init(&pd->genpd, NULL, true);
448453 else
@@ -562,10 +567,18 @@ static const struct of_device_id scpsys_of_match[] = { · 113 unmodified lines
562567 .compatible = "mediatek,mt8183-power-controller",
563568 .data = &mt8183_scpsys_data,
564569 },
570+ {
571+ .compatible = "mediatek,mt8186-power-controller",
572+ .data = &mt8186_scpsys_data,
573+ },
565574 {
566575 .compatible = "mediatek,mt8192-power-controller",
567576 .data = &mt8192_scpsys_data,
568577 },
578+ {
579+ .compatible = "mediatek,mt8195-power-controller",
580+ .data = &mt8195_scpsys_data,
581+ },
569582 { }
570583 };
571584
drivers/soc/mediatek/mtk-pm-domains.h+3−5
@@ -37,7 +37,7 @@ · 36 unmodified lines
3737 #define PWR_STATUS_AUDIO BIT(24)
3838 #define PWR_STATUS_USB BIT(25)
3939
40−#define SPM_MAX_BUS_PROT_DATA 5
40+#define SPM_MAX_BUS_PROT_DATA 6
4141
4242 #define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \
4343 .bus_prot_mask = (_mask), \
@@ -72,8 +72,6 @@ struct scpsys_bus_prot_data { · 28 unmodified lines
7272 bool ignore_clr_ack;
7373 };
7474
75−#define MAX_SUBSYS_CLKS 10
76−
7775 /**
7876 * struct scpsys_domain_data - scp domain data for power on/off flow
7977 * @name: The name of the power domain.
@@ -94,13 +92,13 @@ struct scpsys_domain_data { · 14 unmodified lines
9492 u8 caps;
9593 const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
9694 const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
95+ int pwr_sta_offs;
96+ int pwr_sta2nd_offs;
9797 };
9898
9999 struct scpsys_soc_data {
100100 const struct scpsys_domain_data *domains_data;
101101 int num_domains;
102− int pwr_sta_offs;
103− int pwr_sta2nd_offs;
104102 };
105103
106104 #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
drivers/soc/mediatek/mtk-pmic-wrap.c+71−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #define PWRAP_GET_WACS_REQ(x) (((x) >> 19) & 0x00000001)
3131 #define PWRAP_STATE_SYNC_IDLE0 BIT(20)
3232 #define PWRAP_STATE_INIT_DONE0 BIT(21)
33+#define PWRAP_STATE_INIT_DONE0_MT8186 BIT(22)
3334 #define PWRAP_STATE_INIT_DONE1 BIT(15)
3435
3536 /* macro for WACS FSM */
@@ -77,6 +78,7 @@ · 41 unmodified lines
7778 #define PWRAP_CAP_INT1_EN BIT(3)
7879 #define PWRAP_CAP_WDT_SRC1 BIT(4)
7980 #define PWRAP_CAP_ARB BIT(5)
81+#define PWRAP_CAP_ARB_MT8186 BIT(8)
8082
8183 /* defines for slave device wrapper registers */
8284 enum dew_regs {
@@ -1063,6 +1065,55 @@ static int mt8516_regs[] = { · 980 unmodified lines
10631065 [PWRAP_MSB_FIRST] = 0x170,
10641066 };
10651067
1068+static int mt8186_regs[] = {
1069+ [PWRAP_MUX_SEL] = 0x0,
1070+ [PWRAP_WRAP_EN] = 0x4,
1071+ [PWRAP_DIO_EN] = 0x8,
1072+ [PWRAP_RDDMY] = 0x20,
1073+ [PWRAP_CSHEXT_WRITE] = 0x24,
1074+ [PWRAP_CSHEXT_READ] = 0x28,
1075+ [PWRAP_CSLEXT_WRITE] = 0x2C,
1076+ [PWRAP_CSLEXT_READ] = 0x30,
1077+ [PWRAP_EXT_CK_WRITE] = 0x34,
1078+ [PWRAP_STAUPD_CTRL] = 0x3C,
1079+ [PWRAP_STAUPD_GRPEN] = 0x40,
1080+ [PWRAP_EINT_STA0_ADR] = 0x44,
1081+ [PWRAP_EINT_STA1_ADR] = 0x48,
1082+ [PWRAP_INT_CLR] = 0xC8,
1083+ [PWRAP_INT_FLG] = 0xC4,
1084+ [PWRAP_MAN_EN] = 0x7C,
1085+ [PWRAP_MAN_CMD] = 0x80,
1086+ [PWRAP_WACS0_EN] = 0x8C,
1087+ [PWRAP_WACS1_EN] = 0x94,
1088+ [PWRAP_WACS2_EN] = 0x9C,
1089+ [PWRAP_INIT_DONE0] = 0x90,
1090+ [PWRAP_INIT_DONE1] = 0x98,
1091+ [PWRAP_INIT_DONE2] = 0xA0,
1092+ [PWRAP_INT_EN] = 0xBC,
1093+ [PWRAP_INT1_EN] = 0xCC,
1094+ [PWRAP_INT1_FLG] = 0xD4,
1095+ [PWRAP_INT1_CLR] = 0xD8,
1096+ [PWRAP_TIMER_EN] = 0xF0,
1097+ [PWRAP_WDT_UNIT] = 0xF8,
1098+ [PWRAP_WDT_SRC_EN] = 0xFC,
1099+ [PWRAP_WDT_SRC_EN_1] = 0x100,
1100+ [PWRAP_WDT_FLG] = 0x104,
1101+ [PWRAP_SPMINF_STA] = 0x1B4,
1102+ [PWRAP_DCM_EN] = 0x1EC,
1103+ [PWRAP_DCM_DBC_PRD] = 0x1F0,
1104+ [PWRAP_GPSINF_0_STA] = 0x204,
1105+ [PWRAP_GPSINF_1_STA] = 0x208,
1106+ [PWRAP_WACS0_CMD] = 0xC00,
1107+ [PWRAP_WACS0_RDATA] = 0xC04,
1108+ [PWRAP_WACS0_VLDCLR] = 0xC08,
1109+ [PWRAP_WACS1_CMD] = 0xC10,
1110+ [PWRAP_WACS1_RDATA] = 0xC14,
1111+ [PWRAP_WACS1_VLDCLR] = 0xC18,
1112+ [PWRAP_WACS2_CMD] = 0xC20,
1113+ [PWRAP_WACS2_RDATA] = 0xC24,
1114+ [PWRAP_WACS2_VLDCLR] = 0xC28,
1115+};
1116+
10661117 enum pmic_type {
10671118 PMIC_MT6323,
10681119 PMIC_MT6351,
@@ -1083,6 +1134,7 @@ enum pwrap_type { · 14 unmodified lines
10831134 PWRAP_MT8135,
10841135 PWRAP_MT8173,
10851136 PWRAP_MT8183,
1137+ PWRAP_MT8186,
10861138 PWRAP_MT8195,
10871139 PWRAP_MT8516,
10881140 };
@@ -1535,6 +1587,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) · 446 unmodified lines
15351587 case PWRAP_MT6779:
15361588 case PWRAP_MT6797:
15371589 case PWRAP_MT8173:
1590+ case PWRAP_MT8186:
15381591 case PWRAP_MT8516:
15391592 pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
15401593 break;
@@ -2069,6 +2122,19 @@ static struct pmic_wrapper_type pwrap_mt8516 = { · 528 unmodified lines
20692122 .init_soc_specific = NULL,
20702123 };
20712124
2125+static struct pmic_wrapper_type pwrap_mt8186 = {
2126+ .regs = mt8186_regs,
2127+ .type = PWRAP_MT8186,
2128+ .arb_en_all = 0xfb27f,
2129+ .int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1 */
2130+ .int1_en_all = 0x000017ff, /* disable Matching interrupt for bit 13 */
2131+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
2132+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
2133+ .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_ARB_MT8186,
2134+ .init_reg_clock = pwrap_common_init_reg_clock,
2135+ .init_soc_specific = NULL,
2136+};
2137+
20722138 static const struct of_device_id of_pwrap_match_tbl[] = {
20732139 {
20742140 .compatible = "mediatek,mt2701-pwrap",
@@ -2097,6 +2163,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = { · 22 unmodified lines
20972163 }, {
20982164 .compatible = "mediatek,mt8183-pwrap",
20992165 .data = &pwrap_mt8183,
2166+ }, {
2167+ .compatible = "mediatek,mt8186-pwrap",
2168+ .data = &pwrap_mt8186,
21002169 }, {
21012170 .compatible = "mediatek,mt8195-pwrap",
21022171 .data = &pwrap_mt8195,
@@ -2209,6 +2278,8 @@ static int pwrap_probe(struct platform_device *pdev) · 106 unmodified lines
22092278
22102279 if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
22112280 mask_done = PWRAP_STATE_INIT_DONE1;
2281+ else if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_MT8186))
2282+ mask_done = PWRAP_STATE_INIT_DONE0_MT8186;
22122283 else
22132284 mask_done = PWRAP_STATE_INIT_DONE0;
22142285
drivers/soc/microchip/mpfs-sys-controller.c+8−5
@@ -95,9 +95,9 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) · 94 unmodified lines
9595 {
9696 struct device *dev = &pdev->dev;
9797 struct mpfs_sys_controller *sys_controller;
98− int i;
98+ int i, ret;
9999
100− sys_controller = devm_kzalloc(dev, sizeof(*sys_controller), GFP_KERNEL);
100+ sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL);
101101 if (!sys_controller)
102102 return -ENOMEM;
103103
@@ -106,9 +106,12 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) · 2 unmodified lines
106106 sys_controller->client.tx_block = 1U;
107107
108108 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0);
109− if (IS_ERR(sys_controller->chan))
110− return dev_err_probe(dev, PTR_ERR(sys_controller->chan),
111− "Failed to get mbox channel\n");
109+ if (IS_ERR(sys_controller->chan)) {
110+ ret = dev_err_probe(dev, PTR_ERR(sys_controller->chan),
111+ "Failed to get mbox channel\n");
112+ kfree(sys_controller);
113+ return ret;
114+ }
112115
113116 init_completion(&sys_controller->c);
114117 kref_init(&sys_controller->consumers);
drivers/soc/qcom/apr.c+0−1
@@ -653,7 +653,6 @@ static void apr_remove(struct rpmsg_device *rpdev) · 652 unmodified lines
653653
654654 pdr_handle_release(apr->pdr);
655655 device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
656− flush_workqueue(apr->rxwq);
657656 destroy_workqueue(apr->rxwq);
658657 }
659658
drivers/soc/qcom/llcc-qcom.c+91−16
@@ -29,17 +29,13 @@ · 28 unmodified lines
2929 #define ATTR1_FIXED_SIZE_SHIFT 0x03
3030 #define ATTR1_PRIORITY_SHIFT 0x04
3131 #define ATTR1_MAX_CAP_SHIFT 0x10
32−#define ATTR0_RES_WAYS_MASK GENMASK(11, 0)
33−#define ATTR0_BONUS_WAYS_MASK GENMASK(27, 16)
32+#define ATTR0_RES_WAYS_MASK GENMASK(15, 0)
33+#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)
3434 #define ATTR0_BONUS_WAYS_SHIFT 0x10
3535 #define LLCC_STATUS_READ_DELAY 100
3636
3737 #define CACHE_LINE_SIZE_SHIFT 6
3838
39−#define LLCC_COMMON_HW_INFO 0x00030000
40−#define LLCC_MAJOR_VERSION_MASK GENMASK(31, 24)
41−
42−#define LLCC_COMMON_STATUS0 0x0003000c
4339 #define LLCC_LB_CNT_MASK GENMASK(31, 28)
4440 #define LLCC_LB_CNT_SHIFT 28
4541
@@ -52,9 +48,13 @@ · 6 unmodified lines
5248 #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
5349 #define LLCC_TRP_PCB_ACT 0x21f04
5450 #define LLCC_TRP_WRSC_EN 0x21f20
51+#define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c
5552
5653 #define BANK_OFFSET_STRIDE 0x80000
5754
55+#define LLCC_VERSION_2_0_0_0 0x02000000
56+#define LLCC_VERSION_2_1_0_0 0x02010000
57+
5858 /**
5959 * struct llcc_slice_config - Data associated with the llcc slice
6060 * @usecase_id: Unique id for the client's use case
@@ -79,6 +79,8 @@ · 18 unmodified lines
7979 * collapse.
8080 * @activate_on_init: Activate the slice immediately after it is programmed
8181 * @write_scid_en: Bit enables write cache support for a given scid.
82+ * @write_scid_cacheable_en: Enables write cache cacheable support for a
83+ * given scid (not supported on v2 or older hardware).
8284 */
8385 struct llcc_slice_config {
8486 u32 usecase_id;
@@ -94,12 +96,19 @@ struct llcc_slice_config { · 9 unmodified lines
9496 bool retain_on_pc;
9597 bool activate_on_init;
9698 bool write_scid_en;
99+ bool write_scid_cacheable_en;
97100 };
98101
99102 struct qcom_llcc_config {
100103 const struct llcc_slice_config *sct_data;
101104 int size;
102105 bool need_llcc_cfg;
106+ const u32 *reg_offset;
107+};
108+
109+enum llcc_reg_offset {
110+ LLCC_COMMON_HW_INFO,
111+ LLCC_COMMON_STATUS0,
103112 };
104113
105114 static const struct llcc_slice_config sc7180_data[] = {
@@ -217,42 +226,96 @@ static const struct llcc_slice_config sm8350_data[] = { · 111 unmodified lines
217226 { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
218227 };
219228
229+static const struct llcc_slice_config sm8450_data[] = {
230+ {LLCC_CPUSS, 1, 3072, 1, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 },
231+ {LLCC_VIDSC0, 2, 512, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
232+ {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },
233+ {LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
234+ {LLCC_MODHW, 9, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
235+ {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
236+ {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
237+ {LLCC_GPU, 12, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 1, 0 },
238+ {LLCC_MMUHWT, 13, 768, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },
239+ {LLCC_DISP, 16, 4096, 2, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
240+ {LLCC_MDMPNG, 21, 1024, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 },
241+ {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },
242+ {LLCC_CVP, 28, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
243+ {LLCC_MODPE, 29, 64, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 },
244+ {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0 },
245+ {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },
246+ {LLCC_CVPFW, 17, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
247+ {LLCC_CPUSS1, 3, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
248+ {LLCC_CAMEXP0, 4, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
249+ {LLCC_CPUMTE, 23, 256, 1, 1, 0x0FFF, 0x0, 0, 0, 0, 0, 1, 0, 0 },
250+ {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 },
251+ {LLCC_CAMEXP1, 27, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 },
252+ {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },
253+};
254+
255+static const u32 llcc_v1_2_reg_offset[] = {
256+ [LLCC_COMMON_HW_INFO] = 0x00030000,
257+ [LLCC_COMMON_STATUS0] = 0x0003000c,
258+};
259+
260+static const u32 llcc_v21_reg_offset[] = {
261+ [LLCC_COMMON_HW_INFO] = 0x00034000,
262+ [LLCC_COMMON_STATUS0] = 0x0003400c,
263+};
264+
220265 static const struct qcom_llcc_config sc7180_cfg = {
221266 .sct_data = sc7180_data,
222267 .size = ARRAY_SIZE(sc7180_data),
223268 .need_llcc_cfg = true,
269+ .reg_offset = llcc_v1_2_reg_offset,
224270 };
225271
226272 static const struct qcom_llcc_config sc7280_cfg = {
227273 .sct_data = sc7280_data,
228274 .size = ARRAY_SIZE(sc7280_data),
229275 .need_llcc_cfg = true,
276+ .reg_offset = llcc_v1_2_reg_offset,
230277 };
231278
232279 static const struct qcom_llcc_config sdm845_cfg = {
233280 .sct_data = sdm845_data,
234281 .size = ARRAY_SIZE(sdm845_data),
235282 .need_llcc_cfg = false,
283+ .reg_offset = llcc_v1_2_reg_offset,
236284 };
237285
238286 static const struct qcom_llcc_config sm6350_cfg = {
239287 .sct_data = sm6350_data,
240288 .size = ARRAY_SIZE(sm6350_data),
289+ .need_llcc_cfg = true,
290+ .reg_offset = llcc_v1_2_reg_offset,
241291 };
242292
243293 static const struct qcom_llcc_config sm8150_cfg = {
244294 .sct_data = sm8150_data,
245295 .size = ARRAY_SIZE(sm8150_data),
296+ .need_llcc_cfg = true,
297+ .reg_offset = llcc_v1_2_reg_offset,
246298 };
247299
248300 static const struct qcom_llcc_config sm8250_cfg = {
249301 .sct_data = sm8250_data,
250302 .size = ARRAY_SIZE(sm8250_data),
303+ .need_llcc_cfg = true,
304+ .reg_offset = llcc_v1_2_reg_offset,
251305 };
252306
253307 static const struct qcom_llcc_config sm8350_cfg = {
254308 .sct_data = sm8350_data,
255309 .size = ARRAY_SIZE(sm8350_data),
310+ .need_llcc_cfg = true,
311+ .reg_offset = llcc_v1_2_reg_offset,
312+};
313+
314+static const struct qcom_llcc_config sm8450_cfg = {
315+ .sct_data = sm8450_data,
316+ .size = ARRAY_SIZE(sm8450_data),
317+ .need_llcc_cfg = true,
318+ .reg_offset = llcc_v21_reg_offset,
256319 };
257320
258321 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
@@ -504,7 +567,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, · 245 unmodified lines
504567 return ret;
505568 }
506569
507− if (drv_data->major_version == 2) {
570+ if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
508571 u32 wren;
509572
510573 wren = config->write_scid_en << config->slice_id;
@@ -514,6 +577,16 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, · 3 unmodified lines
514577 return ret;
515578 }
516579
580+ if (drv_data->version >= LLCC_VERSION_2_1_0_0) {
581+ u32 wr_cache_en;
582+
583+ wr_cache_en = config->write_scid_cacheable_en << config->slice_id;
584+ ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN,
585+ BIT(config->slice_id), wr_cache_en);
586+ if (ret)
587+ return ret;
588+ }
589+
517590 if (config->activate_on_init) {
518591 desc.slice_id = config->slice_id;
519592 ret = llcc_slice_activate(&desc);
@@ -598,15 +671,18 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 78 unmodified lines
598671 goto err;
599672 }
600673
601− /* Extract major version of the IP */
602− ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
674+ cfg = of_device_get_match_data(&pdev->dev);
675+
676+ /* Extract version of the IP */
677+ ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
678+ &version);
603679 if (ret)
604680 goto err;
605681
606− drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version);
682+ drv_data->version = version;
607683
608− ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
609− &num_banks);
684+ ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0],
685+ &num_banks);
610686 if (ret)
611687 goto err;
612688
@@ -614,7 +690,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 1 unmodified line
614690 num_banks >>= LLCC_LB_CNT_SHIFT;
615691 drv_data->num_banks = num_banks;
616692
617− cfg = of_device_get_match_data(&pdev->dev);
618693 llcc_cfg = cfg->sct_data;
619694 sz = cfg->size;
620695
@@ -632,9 +707,8 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 11 unmodified lines
632707 for (i = 0; i < num_banks; i++)
633708 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
634709
635− drv_data->bitmap = devm_kcalloc(dev,
636− BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),
637− GFP_KERNEL);
710+ drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,
711+ GFP_KERNEL);
638712 if (!drv_data->bitmap) {
639713 ret = -ENOMEM;
640714 goto err;
@@ -672,6 +746,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { · 31 unmodified lines
672746 { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
673747 { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
674748 { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
749+ { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
675750 { }
676751 };
677752
drivers/soc/qcom/mdt_loader.c+151−81
@@ -31,6 +31,44 @@ static bool mdt_phdr_valid(const struct elf32_phdr *phdr) · 30 unmodified lines
3131 return true;
3232 }
3333
34+static ssize_t mdt_load_split_segment(void *ptr, const struct elf32_phdr *phdrs,
35+ unsigned int segment, const char *fw_name,
36+ struct device *dev)
37+{
38+ const struct elf32_phdr *phdr = &phdrs[segment];
39+ const struct firmware *seg_fw;
40+ char *seg_name;
41+ ssize_t ret;
42+
43+ if (strlen(fw_name) < 4)
44+ return -EINVAL;
45+
46+ seg_name = kstrdup(fw_name, GFP_KERNEL);
47+ if (!seg_name)
48+ return -ENOMEM;
49+
50+ sprintf(seg_name + strlen(fw_name) - 3, "b%02d", segment);
51+ ret = request_firmware_into_buf(&seg_fw, seg_name, dev,
52+ ptr, phdr->p_filesz);
53+ if (ret) {
54+ dev_err(dev, "error %zd loading %s\n", ret, seg_name);
55+ kfree(seg_name);
56+ return ret;
57+ }
58+
59+ if (seg_fw->size != phdr->p_filesz) {
60+ dev_err(dev,
61+ "failed to load segment %d from truncated file %s\n",
62+ segment, seg_name);
63+ ret = -EINVAL;
64+ }
65+
66+ release_firmware(seg_fw);
67+ kfree(seg_name);
68+
69+ return ret;
70+}
71+
3472 /**
3573 * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt
3674 * @fw: firmware object for the mdt file
@@ -83,13 +121,17 @@ EXPORT_SYMBOL_GPL(qcom_mdt_get_size); · 46 unmodified lines
83121 *
84122 * Return: pointer to data, or ERR_PTR()
85123 */
86−void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)
124+void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
125+ const char *fw_name, struct device *dev)
87126 {
88127 const struct elf32_phdr *phdrs;
89128 const struct elf32_hdr *ehdr;
129+ unsigned int hash_segment = 0;
90130 size_t hash_offset;
91131 size_t hash_size;
92132 size_t ehdr_size;
133+ unsigned int i;
134+ ssize_t ret;
93135 void *data;
94136
95137 ehdr = (struct elf32_hdr *)fw->data;
@@ -101,24 +143,44 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) · 5 unmodified lines
101143 if (phdrs[0].p_type == PT_LOAD)
102144 return ERR_PTR(-EINVAL);
103145
104− if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH)
146+ for (i = 1; i < ehdr->e_phnum; i++) {
147+ if ((phdrs[i].p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) {
148+ hash_segment = i;
149+ break;
150+ }
151+ }
152+
153+ if (!hash_segment) {
154+ dev_err(dev, "no hash segment found in %s\n", fw_name);
105155 return ERR_PTR(-EINVAL);
156+ }
106157
107158 ehdr_size = phdrs[0].p_filesz;
108− hash_size = phdrs[1].p_filesz;
159+ hash_size = phdrs[hash_segment].p_filesz;
109160
110161 data = kmalloc(ehdr_size + hash_size, GFP_KERNEL);
111162 if (!data)
112163 return ERR_PTR(-ENOMEM);
113164
114− /* Is the header and hash already packed */
115− if (ehdr_size + hash_size == fw->size)
116− hash_offset = phdrs[0].p_filesz;
117− else
118− hash_offset = phdrs[1].p_offset;
119−
165+ /* Copy ELF header */
120166 memcpy(data, fw->data, ehdr_size);
121− memcpy(data + ehdr_size, fw->data + hash_offset, hash_size);
167+
168+ if (ehdr_size + hash_size == fw->size) {
169+ /* Firmware is split and hash is packed following the ELF header */
170+ hash_offset = phdrs[0].p_filesz;
171+ memcpy(data + ehdr_size, fw->data + hash_offset, hash_size);
172+ } else if (phdrs[hash_segment].p_offset + hash_size <= fw->size) {
173+ /* Hash is in its own segment, but within the loaded file */
174+ hash_offset = phdrs[hash_segment].p_offset;
175+ memcpy(data + ehdr_size, fw->data + hash_offset, hash_size);
176+ } else {
177+ /* Hash is in its own segment, beyond the loaded file */
178+ ret = mdt_load_split_segment(data + ehdr_size, phdrs, hash_segment, fw_name, dev);
179+ if (ret) {
180+ kfree(data);
181+ return ERR_PTR(ret);
182+ }
183+ }
122184
123185 *data_len = ehdr_size + hash_size;
124186
@@ -126,23 +188,85 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) · 1 unmodified line
126188 }
127189 EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
128190
191+/**
192+ * qcom_mdt_pas_init() - initialize PAS region for firmware loading
193+ * @dev: device handle to associate resources with
194+ * @fw: firmware object for the mdt file
195+ * @firmware: name of the firmware, for construction of segment file names
196+ * @pas_id: PAS identifier
197+ * @mem_phys: physical address of allocated memory region
198+ * @ctx: PAS metadata context, to be released by caller
199+ *
200+ * Returns 0 on success, negative errno otherwise.
201+ */
202+int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
203+ const char *fw_name, int pas_id, phys_addr_t mem_phys,
204+ struct qcom_scm_pas_metadata *ctx)
205+{
206+ const struct elf32_phdr *phdrs;
207+ const struct elf32_phdr *phdr;
208+ const struct elf32_hdr *ehdr;
209+ phys_addr_t min_addr = PHYS_ADDR_MAX;
210+ phys_addr_t max_addr = 0;
211+ size_t metadata_len;
212+ void *metadata;
213+ int ret;
214+ int i;
215+
216+ ehdr = (struct elf32_hdr *)fw->data;
217+ phdrs = (struct elf32_phdr *)(ehdr + 1);
218+
219+ for (i = 0; i < ehdr->e_phnum; i++) {
220+ phdr = &phdrs[i];
221+
222+ if (!mdt_phdr_valid(phdr))
223+ continue;
224+
225+ if (phdr->p_paddr < min_addr)
226+ min_addr = phdr->p_paddr;
227+
228+ if (phdr->p_paddr + phdr->p_memsz > max_addr)
229+ max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
230+ }
231+
232+ metadata = qcom_mdt_read_metadata(fw, &metadata_len, fw_name, dev);
233+ if (IS_ERR(metadata)) {
234+ ret = PTR_ERR(metadata);
235+ dev_err(dev, "error %d reading firmware %s metadata\n", ret, fw_name);
236+ goto out;
237+ }
238+
239+ ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len, ctx);
240+ kfree(metadata);
241+ if (ret) {
242+ /* Invalid firmware metadata */
243+ dev_err(dev, "error %d initializing firmware %s\n", ret, fw_name);
244+ goto out;
245+ }
246+
247+ ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - min_addr);
248+ if (ret) {
249+ /* Unable to set up relocation */
250+ dev_err(dev, "error %d setting up firmware %s\n", ret, fw_name);
251+ goto out;
252+ }
253+
254+out:
255+ return ret;
256+}
257+EXPORT_SYMBOL_GPL(qcom_mdt_pas_init);
258+
129259 static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
130− const char *firmware, int pas_id, void *mem_region,
260+ const char *fw_name, int pas_id, void *mem_region,
131261 phys_addr_t mem_phys, size_t mem_size,
132262 phys_addr_t *reloc_base, bool pas_init)
133263 {
134264 const struct elf32_phdr *phdrs;
135265 const struct elf32_phdr *phdr;
136266 const struct elf32_hdr *ehdr;
137− const struct firmware *seg_fw;
138267 phys_addr_t mem_reloc;
139268 phys_addr_t min_addr = PHYS_ADDR_MAX;
140− phys_addr_t max_addr = 0;
141− size_t metadata_len;
142− size_t fw_name_len;
143269 ssize_t offset;
144− void *metadata;
145− char *fw_name;
146270 bool relocate = false;
147271 void *ptr;
148272 int ret = 0;
@@ -154,34 +278,6 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 5 unmodified lines
154278 ehdr = (struct elf32_hdr *)fw->data;
155279 phdrs = (struct elf32_phdr *)(ehdr + 1);
156280
157− fw_name_len = strlen(firmware);
158− if (fw_name_len <= 4)
159− return -EINVAL;
160−
161− fw_name = kstrdup(firmware, GFP_KERNEL);
162− if (!fw_name)
163− return -ENOMEM;
164−
165− if (pas_init) {
166− metadata = qcom_mdt_read_metadata(fw, &metadata_len);
167− if (IS_ERR(metadata)) {
168− ret = PTR_ERR(metadata);
169− dev_err(dev, "error %d reading firmware %s metadata\n",
170− ret, fw_name);
171− goto out;
172− }
173−
174− ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len);
175−
176− kfree(metadata);
177− if (ret) {
178− /* Invalid firmware metadata */
179− dev_err(dev, "error %d initializing firmware %s\n",
180− ret, fw_name);
181− goto out;
182− }
183− }
184−
185281 for (i = 0; i < ehdr->e_phnum; i++) {
186282 phdr = &phdrs[i];
187283
@@ -193,23 +289,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 5 unmodified lines
193289
194290 if (phdr->p_paddr < min_addr)
195291 min_addr = phdr->p_paddr;
196−
197− if (phdr->p_paddr + phdr->p_memsz > max_addr)
198− max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
199292 }
200293
201294 if (relocate) {
202− if (pas_init) {
203− ret = qcom_scm_pas_mem_setup(pas_id, mem_phys,
204− max_addr - min_addr);
205− if (ret) {
206− /* Unable to set up relocation */
207− dev_err(dev, "error %d setting up firmware %s\n",
208− ret, fw_name);
209− goto out;
210− }
211− }
212−
213295 /*
214296 * The image is relocatable, so offset each segment based on
215297 * the lowest segment address.
@@ -246,7 +328,8 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 30 unmodified lines
246328
247329 ptr = mem_region + offset;
248330
249− if (phdr->p_filesz && phdr->p_offset < fw->size) {
331+ if (phdr->p_filesz && phdr->p_offset < fw->size &&
332+ phdr->p_offset + phdr->p_filesz <= fw->size) {
250333 /* Firmware is large enough to be non-split */
251334 if (phdr->p_offset + phdr->p_filesz > fw->size) {
252335 dev_err(dev, "file %s segment %d would be truncated\n",
@@ -258,25 +341,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 5 unmodified lines
258341 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);
259342 } else if (phdr->p_filesz) {
260343 /* Firmware not large enough, load split-out segments */
261− sprintf(fw_name + fw_name_len - 3, "b%02d", i);
262− ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
263− ptr, phdr->p_filesz);
264− if (ret) {
265− dev_err(dev, "error %d loading %s\n",
266− ret, fw_name);
267− break;
268− }
269−
270− if (seg_fw->size != phdr->p_filesz) {
271− dev_err(dev,
272− "failed to load segment %d from truncated file %s\n",
273− i, fw_name);
274− release_firmware(seg_fw);
275− ret = -EINVAL;
344+ ret = mdt_load_split_segment(ptr, phdrs, i, fw_name, dev);
345+ if (ret)
276346 break;
277− }
278−
279− release_firmware(seg_fw);
280347 }
281348
282349 if (phdr->p_memsz > phdr->p_filesz)
@@ -286,9 +353,6 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 3 unmodified lines
286353 if (reloc_base)
287354 *reloc_base = mem_reloc;
288355
289−out:
290− kfree(fw_name);
291−
292356 return ret;
293357 }
294358
@@ -310,6 +374,12 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, · 15 unmodified lines
310374 phys_addr_t mem_phys, size_t mem_size,
311375 phys_addr_t *reloc_base)
312376 {
377+ int ret;
378+
379+ ret = qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL);
380+ if (ret)
381+ return ret;
382+
313383 return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
314384 mem_size, reloc_base, true);
315385 }
drivers/soc/qcom/ocmem.c+1−0
@@ -206,6 +206,7 @@ struct ocmem *of_get_ocmem(struct device *dev) · 205 unmodified lines
206206 ocmem = platform_get_drvdata(pdev);
207207 if (!ocmem) {
208208 dev_err(dev, "Cannot get ocmem\n");
209+ put_device(&pdev->dev);
209210 return ERR_PTR(-ENODEV);
210211 }
211212 return ocmem;
drivers/soc/qcom/qcom_aoss.c+6−2
@@ -451,7 +451,11 @@ struct qmp *qmp_get(struct device *dev) · 450 unmodified lines
451451
452452 qmp = platform_get_drvdata(pdev);
453453
454− return qmp ? qmp : ERR_PTR(-EPROBE_DEFER);
454+ if (!qmp) {
455+ put_device(&pdev->dev);
456+ return ERR_PTR(-EPROBE_DEFER);
457+ }
458+ return qmp;
455459 }
456460 EXPORT_SYMBOL(qmp_get);
457461
@@ -497,7 +501,7 @@ static int qmp_probe(struct platform_device *pdev) · 39 unmodified lines
497501 }
498502
499503 irq = platform_get_irq(pdev, 0);
500− ret = devm_request_irq(&pdev->dev, irq, qmp_intr, IRQF_ONESHOT,
504+ ret = devm_request_irq(&pdev->dev, irq, qmp_intr, 0,
501505 "aoss-qmp", qmp);
502506 if (ret < 0) {
503507 dev_err(&pdev->dev, "failed to request interrupt\n");
drivers/soc/qcom/rpmpd.c+20−0
@@ -138,6 +138,22 @@ static const struct rpmpd_desc mdm9607_desc = { · 137 unmodified lines
138138 .max_state = RPM_SMD_LEVEL_TURBO,
139139 };
140140
141+/* msm8226 RPM Power Domains */
142+DEFINE_RPMPD_PAIR(msm8226, vddcx, vddcx_ao, SMPA, CORNER, 1);
143+DEFINE_RPMPD_VFC(msm8226, vddcx_vfc, SMPA, 1);
144+
145+static struct rpmpd *msm8226_rpmpds[] = {
146+ [MSM8226_VDDCX] = &msm8226_vddcx,
147+ [MSM8226_VDDCX_AO] = &msm8226_vddcx_ao,
148+ [MSM8226_VDDCX_VFC] = &msm8226_vddcx_vfc,
149+};
150+
151+static const struct rpmpd_desc msm8226_desc = {
152+ .rpmpds = msm8226_rpmpds,
153+ .num_pds = ARRAY_SIZE(msm8226_rpmpds),
154+ .max_state = MAX_CORNER_RPMPD_STATE,
155+};
156+
141157 /* msm8939 RPM Power Domains */
142158 DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1);
143159 DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1);
@@ -436,6 +452,7 @@ static const struct rpmpd_desc qcm2290_desc = { · 292 unmodified lines
436452
437453 static const struct of_device_id rpmpd_match_table[] = {
438454 { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc },
455+ { .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc },
439456 { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
440457 { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },
441458 { .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc },
@@ -610,6 +627,9 @@ static int rpmpd_probe(struct platform_device *pdev) · 168 unmodified lines
610627
611628 data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains),
612629 GFP_KERNEL);
630+ if (!data->domains)
631+ return -ENOMEM;
632+
613633 data->num_domains = num;
614634
615635 for (i = 0; i < num; i++) {
drivers/soc/qcom/socinfo.c+12−0
@@ -104,6 +104,14 @@ static const char *const pmic_models[] = { · 103 unmodified lines
104104 [36] = "PM8009",
105105 [38] = "PM8150C",
106106 [41] = "SMB2351",
107+ [47] = "PMK8350",
108+ [48] = "PM8350",
109+ [49] = "PM8350C",
110+ [50] = "PM8350B",
111+ [51] = "PMR735A",
112+ [52] = "PMR735B",
113+ [58] = "PM8450",
114+ [65] = "PM8010",
107115 };
108116 #endif /* CONFIG_DEBUG_FS */
109117
@@ -314,10 +322,14 @@ static const struct soc_id soc_id[] = { · 204 unmodified lines
314322 { 422, "IPQ6010" },
315323 { 425, "SC7180" },
316324 { 434, "SM6350" },
325+ { 439, "SM8350" },
326+ { 449, "SC8280XP" },
317327 { 453, "IPQ6005" },
318328 { 455, "QRB5165" },
319329 { 457, "SM8450" },
320330 { 459, "SM7225" },
331+ { 460, "SA8540P" },
332+ { 480, "SM8450" },
321333 };
322334
323335 static const char *socinfo_machine(struct device *dev, unsigned int id)
drivers/soc/renesas/Kconfig+12−0
@@ -40,6 +40,11 @@ config ARCH_RMOBILE · 39 unmodified lines
4040 select SYS_SUPPORTS_SH_TMU
4141 select SYSC_RMOBILE
4242
43+config ARCH_RZG2L
44+ bool
45+ select PM
46+ select PM_GENERIC_DOMAINS
47+
4348 config ARCH_RZN1
4449 bool
4550 select ARM_AMBA
@@ -293,9 +298,16 @@ config ARCH_R8A774B1 · 247 unmodified lines
293298
294299 config ARCH_R9A07G044
295300 bool "ARM64 Platform support for RZ/G2L"
301+ select ARCH_RZG2L
296302 help
297303 This enables support for the Renesas RZ/G2L SoC variants.
298304
305+config ARCH_R9A07G054
306+ bool "ARM64 Platform support for RZ/V2L"
307+ select ARCH_RZG2L
308+ help
309+ This enables support for the Renesas RZ/V2L SoC variants.
310+
299311 endif # ARM64
300312
301313 config RST_RCAR
drivers/soc/renesas/renesas-soc.c+46−22
@@ -64,6 +64,10 @@ static const struct renesas_family fam_rzg2l __initconst __maybe_unused = { · 63 unmodified lines
6464 .name = "RZ/G2L",
6565 };
6666
67+static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
68+ .name = "RZ/V2L",
69+};
70+
6771 static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
6872 .name = "SH-Mobile",
6973 .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */
@@ -144,6 +148,11 @@ static const struct renesas_soc soc_rz_g2l __initconst __maybe_unused = { · 74 unmodified lines
144148 .id = 0x841c447,
145149 };
146150
151+static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
152+ .family = &fam_rzv2l,
153+ .id = 0x8447447,
154+};
155+
147156 static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
148157 .family = &fam_rcar_gen1,
149158 };
@@ -334,6 +343,9 @@ static const struct of_device_id renesas_socs[] __initconst = { · 184 unmodified lines
334343 #if defined(CONFIG_ARCH_R9A07G044)
335344 { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l },
336345 #endif
346+#if defined(CONFIG_ARCH_R9A07G054)
347+ { .compatible = "renesas,r9a07g054", .data = &soc_rz_v2l },
348+#endif
337349 #ifdef CONFIG_ARCH_SH73A0
338350 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
339351 #endif
@@ -367,6 +379,7 @@ static const struct renesas_id id_prr __initconst = { · 27 unmodified lines
367379 static const struct of_device_id renesas_ids[] __initconst = {
368380 { .compatible = "renesas,bsid", .data = &id_bsid },
369381 { .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },
382+ { .compatible = "renesas,r9a07g054-sysc", .data = &id_rzg2l },
370383 { .compatible = "renesas,prr", .data = &id_prr },
371384 { /* sentinel */ }
372385 };
@@ -380,9 +393,11 @@ static int __init renesas_soc_init(void) · 7 unmodified lines
380393 const struct renesas_soc *soc;
381394 const struct renesas_id *id;
382395 void __iomem *chipid = NULL;
396+ const char *rev_prefix = "";
383397 struct soc_device *soc_dev;
384398 struct device_node *np;
385399 const char *soc_id;
400+ int ret;
386401
387402 match = of_match_node(renesas_socs, of_root);
388403 if (!match)
@@ -403,6 +418,17 @@ static int __init renesas_soc_init(void) · 14 unmodified lines
403418 chipid = ioremap(family->reg, 4);
404419 }
405420
421+ soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
422+ if (!soc_dev_attr)
423+ return -ENOMEM;
424+
425+ np = of_find_node_by_path("/");
426+ of_property_read_string(np, "model", &soc_dev_attr->machine);
427+ of_node_put(np);
428+
429+ soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
430+ soc_dev_attr->soc_id = kstrdup_const(soc_id, GFP_KERNEL);
431+
406432 if (chipid) {
407433 product = readl(chipid + id->offset);
408434 iounmap(chipid);
@@ -417,41 +443,39 @@ static int __init renesas_soc_init(void) · 8 unmodified lines
417443
418444 eshi = ((product >> 4) & 0x0f) + 1;
419445 eslo = product & 0xf;
446+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
447+ eshi, eslo);
448+ } else if (id == &id_rzg2l) {
449+ eshi = ((product >> 28) & 0x0f);
450+ soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u",
451+ eshi);
452+ rev_prefix = "Rev ";
420453 }
421454
422455 if (soc->id &&
423456 ((product & id->mask) >> __ffs(id->mask)) != soc->id) {
424457 pr_warn("SoC mismatch (product = 0x%x)\n", product);
425− return -ENODEV;
458+ ret = -ENODEV;
459+ goto free_soc_dev_attr;
426460 }
427461 }
428462
429− soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
430− if (!soc_dev_attr)
431− return -ENOMEM;
432−
433− np = of_find_node_by_path("/");
434− of_property_read_string(np, "model", &soc_dev_attr->machine);
435− of_node_put(np);
436−
437− soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL);
438− soc_dev_attr->soc_id = kstrdup_const(soc_id, GFP_KERNEL);
439− if (eshi)
440− soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi,
441− eslo);
442−
443− pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family,
444− soc_dev_attr->soc_id, soc_dev_attr->revision ?: "");
463+ pr_info("Detected Renesas %s %s %s%s\n", soc_dev_attr->family,
464+ soc_dev_attr->soc_id, rev_prefix, soc_dev_attr->revision ?: "");
445465
446466 soc_dev = soc_device_register(soc_dev_attr);
447467 if (IS_ERR(soc_dev)) {
448− kfree(soc_dev_attr->revision);
449− kfree_const(soc_dev_attr->soc_id);
450− kfree_const(soc_dev_attr->family);
451− kfree(soc_dev_attr);
452− return PTR_ERR(soc_dev);
468+ ret = PTR_ERR(soc_dev);
469+ goto free_soc_dev_attr;
453470 }
454471
455472 return 0;
473+
474+free_soc_dev_attr:
475+ kfree(soc_dev_attr->revision);
476+ kfree_const(soc_dev_attr->soc_id);
477+ kfree_const(soc_dev_attr->family);
478+ kfree(soc_dev_attr);
479+ return ret;
456480 }
457481 early_initcall(renesas_soc_init);
drivers/soc/tegra/fuse/fuse-tegra.c+21−3
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.
3+ * Copyright (c) 2013-2021, NVIDIA CORPORATION. All rights reserved.
44 */
55
66 #include <linux/clk.h>
@@ -161,6 +161,12 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = { · 154 unmodified lines
161161 .bytes = 4,
162162 .bit_offset = 0,
163163 .nbits = 32,
164+ }, {
165+ .name = "gcplex-config-fuse",
166+ .offset = 0x1c8,
167+ .bytes = 4,
168+ .bit_offset = 0,
169+ .nbits = 32,
164170 }, {
165171 .name = "tsensor-realignment",
166172 .offset = 0x1fc,
@@ -179,13 +185,25 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = { · 12 unmodified lines
179185 .bytes = 4,
180186 .bit_offset = 0,
181187 .nbits = 32,
188+ }, {
189+ .name = "pdi0",
190+ .offset = 0x300,
191+ .bytes = 4,
192+ .bit_offset = 0,
193+ .nbits = 32,
194+ }, {
195+ .name = "pdi1",
196+ .offset = 0x304,
197+ .bytes = 4,
198+ .bit_offset = 0,
199+ .nbits = 32,
182200 },
183201 };
184202
185203 static void tegra_fuse_restore(void *base)
186204 {
205+ fuse->base = (void __iomem *)base;
187206 fuse->clk = NULL;
188− fuse->base = base;
189207 }
190208
191209 static int tegra_fuse_probe(struct platform_device *pdev)
@@ -195,7 +213,7 @@ static int tegra_fuse_probe(struct platform_device *pdev) · 3 unmodified lines
195213 struct resource *res;
196214 int err;
197215
198− err = devm_add_action(&pdev->dev, tegra_fuse_restore, base);
216+ err = devm_add_action(&pdev->dev, tegra_fuse_restore, (void __force *)base);
199217 if (err)
200218 return err;
201219
drivers/soc/tegra/pmc.c+11−5
@@ -3,7 +3,7 @@ · 2 unmodified lines
33 * drivers/soc/tegra/pmc.c
44 *
55 * Copyright (c) 2010 Google, Inc
6− * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
6+ * Copyright (c) 2018-2022, NVIDIA CORPORATION. All rights reserved.
77 *
88 * Author:
99 * Colin Cross <ccross@google.com>
@@ -54,6 +54,7 @@ · 44 unmodified lines
5454 #include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
5555 #include <dt-bindings/gpio/tegra186-gpio.h>
5656 #include <dt-bindings/gpio/tegra194-gpio.h>
57+#include <dt-bindings/gpio/tegra234-gpio.h>
5758 #include <dt-bindings/soc/tegra-pmc.h>
5859
5960 #define PMC_CNTRL 0x0
@@ -3066,7 +3067,7 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc, · 3006 unmodified lines
30663067 }
30673068
30683069 static const struct tegra_pmc_soc tegra20_pmc_soc = {
3069− .supports_core_domain = false,
3070+ .supports_core_domain = true,
30703071 .num_powergates = ARRAY_SIZE(tegra20_powergates),
30713072 .powergates = tegra20_powergates,
30723073 .num_cpu_powergates = 0,
@@ -3127,7 +3128,7 @@ static const char * const tegra30_reset_sources[] = { · 54 unmodified lines
31273128 };
31283129
31293130 static const struct tegra_pmc_soc tegra30_pmc_soc = {
3130− .supports_core_domain = false,
3131+ .supports_core_domain = true,
31313132 .num_powergates = ARRAY_SIZE(tegra30_powergates),
31323133 .powergates = tegra30_powergates,
31333134 .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
@@ -3788,6 +3789,11 @@ static const char * const tegra234_reset_sources[] = { · 654 unmodified lines
37883789 "FUSECRC",
37893790 };
37903791
3792+static const struct tegra_wake_event tegra234_wake_events[] = {
3793+ TEGRA_WAKE_GPIO("power", 29, 1, TEGRA234_AON_GPIO(EE, 4)),
3794+ TEGRA_WAKE_IRQ("rtc", 73, 10),
3795+};
3796+
37913797 static const struct tegra_pmc_soc tegra234_pmc_soc = {
37923798 .supports_core_domain = false,
37933799 .num_powergates = 0,
@@ -3812,8 +3818,8 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = { · 18 unmodified lines
38123818 .num_reset_sources = ARRAY_SIZE(tegra234_reset_sources),
38133819 .reset_levels = tegra186_reset_levels,
38143820 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
3815− .num_wake_events = 0,
3816− .wake_events = NULL,
3821+ .num_wake_events = ARRAY_SIZE(tegra234_wake_events),
3822+ .wake_events = tegra234_wake_events,
38173823 .pmc_clks_data = NULL,
38183824 .num_pmc_clks = 0,
38193825 .has_blink_output = false,
drivers/soc/ti/k3-ringacc.c+6−9
@@ -1402,12 +1402,10 @@ static int k3_ringacc_init(struct platform_device *pdev, · 1401 unmodified lines
14021402 sizeof(*ringacc->rings) *
14031403 ringacc->num_rings,
14041404 GFP_KERNEL);
1405− ringacc->rings_inuse = devm_kcalloc(dev,
1406− BITS_TO_LONGS(ringacc->num_rings),
1407− sizeof(unsigned long), GFP_KERNEL);
1408− ringacc->proxy_inuse = devm_kcalloc(dev,
1409− BITS_TO_LONGS(ringacc->num_proxies),
1410− sizeof(unsigned long), GFP_KERNEL);
1405+ ringacc->rings_inuse = devm_bitmap_zalloc(dev, ringacc->num_rings,
1406+ GFP_KERNEL);
1407+ ringacc->proxy_inuse = devm_bitmap_zalloc(dev, ringacc->num_proxies,
1408+ GFP_KERNEL);
14111409
14121410 if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse)
14131411 return -ENOMEM;
@@ -1483,9 +1481,8 @@ struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev, · 69 unmodified lines
14831481 sizeof(*ringacc->rings) *
14841482 ringacc->num_rings * 2,
14851483 GFP_KERNEL);
1486− ringacc->rings_inuse = devm_kcalloc(dev,
1487− BITS_TO_LONGS(ringacc->num_rings),
1488− sizeof(unsigned long), GFP_KERNEL);
1484+ ringacc->rings_inuse = devm_bitmap_zalloc(dev, ringacc->num_rings,
1485+ GFP_KERNEL);
14891486
14901487 if (!ringacc->rings || !ringacc->rings_inuse)
14911488 return ERR_PTR(-ENOMEM);
drivers/soc/ti/k3-socinfo.c+1−0
@@ -42,6 +42,7 @@ static const struct k3_soc_id { · 41 unmodified lines
4242 { 0xBB6D, "J7200" },
4343 { 0xBB38, "AM64X" },
4444 { 0xBB75, "J721S2"},
45+ { 0xBB7E, "AM62X" },
4546 };
4647
4748 static int
drivers/soc/ti/smartreflex.c+7−6
@@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev) · 818 unmodified lines
819819 {
820820 struct omap_sr *sr_info;
821821 struct omap_sr_data *pdata = pdev->dev.platform_data;
822− struct resource *mem, *irq;
822+ struct resource *mem;
823823 struct dentry *nvalue_dir;
824824 int i, ret = 0;
825825
@@ -844,7 +844,11 @@ static int omap_sr_probe(struct platform_device *pdev) · 18 unmodified lines
844844 if (IS_ERR(sr_info->base))
845845 return PTR_ERR(sr_info->base);
846846
847− irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
847+ ret = platform_get_irq_optional(pdev, 0);
848+ if (ret < 0 && ret != -ENXIO)
849+ return dev_err_probe(&pdev->dev, ret, "failed to get IRQ resource\n");
850+ if (ret > 0)
851+ sr_info->irq = ret;
848852
849853 sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
850854 if (IS_ERR(sr_info->fck))
@@ -870,9 +874,6 @@ static int omap_sr_probe(struct platform_device *pdev) · 19 unmodified lines
870874 sr_info->autocomp_active = false;
871875 sr_info->ip_type = pdata->ip_type;
872876
873− if (irq)
874− sr_info->irq = irq->start;
875−
876877 sr_set_clk_length(sr_info);
877878
878879 list_add(&sr_info->node, &sr_list);
@@ -926,7 +927,7 @@ static int omap_sr_probe(struct platform_device *pdev) · 47 unmodified lines
926927
927928 }
928929
929− return ret;
930+ return 0;
930931
931932 err_debugfs:
932933 debugfs_remove_recursive(sr_info->dbg_dir);
drivers/soc/ti/wkup_m3_ipc.c+2−2
@@ -450,9 +450,9 @@ static int wkup_m3_ipc_probe(struct platform_device *pdev) · 449 unmodified lines
450450 return PTR_ERR(m3_ipc->ipc_mem_base);
451451
452452 irq = platform_get_irq(pdev, 0);
453− if (!irq) {
453+ if (irq < 0) {
454454 dev_err(&pdev->dev, "no irq resource\n");
455− return -ENXIO;
455+ return irq;
456456 }
457457
458458 ret = devm_request_irq(dev, irq, wkup_m3_txev_handler,
drivers/tee/amdtee/call.c+1−1
@@ -122,7 +122,7 @@ static int amd_params_to_tee_params(struct tee_param *tee, u32 count, · 121 unmodified lines
122122 }
123123
124124 static DEFINE_MUTEX(ta_refcount_mutex);
125−static struct list_head ta_list = LIST_HEAD_INIT(ta_list);
125+static LIST_HEAD(ta_list);
126126
127127 static u32 get_ta_refcount(u32 ta_handle)
128128 {
drivers/tee/amdtee/shm_pool.c+16−39
@@ -8,13 +8,17 @@ · 7 unmodified lines
88 #include <linux/psp-sev.h>
99 #include "amdtee_private.h"
1010
11−static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm,
12− size_t size)
11+static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
12+ size_t size, size_t align)
1313 {
1414 unsigned int order = get_order(size);
1515 unsigned long va;
1616 int rc;
1717
18+ /*
19+ * Ignore alignment since this is already going to be page aligned
20+ * and there's no need for any larger alignment.
21+ */
1822 va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
1923 if (!va)
2024 return -ENOMEM;
@@ -34,7 +38,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, · 13 unmodified lines
3438 return 0;
3539 }
3640
37−static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm)
41+static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
3842 {
3943 /* Unmap the shared memory from TEE */
4044 amdtee_unmap_shmem(shm);
@@ -42,52 +46,25 @@ static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm) · 1 unmodified line
4246 shm->kaddr = NULL;
4347 }
4448
45−static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
49+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
4650 {
47− kfree(poolm);
51+ kfree(pool);
4852 }
4953
50−static const struct tee_shm_pool_mgr_ops pool_ops = {
54+static const struct tee_shm_pool_ops pool_ops = {
5155 .alloc = pool_op_alloc,
5256 .free = pool_op_free,
53− .destroy_poolmgr = pool_op_destroy_poolmgr,
57+ .destroy_pool = pool_op_destroy_pool,
5458 };
5559
56−static struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void)
57−{
58− struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
59−
60− if (!mgr)
61− return ERR_PTR(-ENOMEM);
62−
63− mgr->ops = &pool_ops;
64−
65− return mgr;
66−}
67−
6860 struct tee_shm_pool *amdtee_config_shm(void)
6961 {
70− struct tee_shm_pool_mgr *priv_mgr;
71− struct tee_shm_pool_mgr *dmabuf_mgr;
72− void *rc;
62+ struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
7363
74− rc = pool_mem_mgr_alloc();
75− if (IS_ERR(rc))
76− return rc;
77− priv_mgr = rc;
78−
79− rc = pool_mem_mgr_alloc();
80− if (IS_ERR(rc)) {
81− tee_shm_pool_mgr_destroy(priv_mgr);
82− return rc;
83− }
84− dmabuf_mgr = rc;
64+ if (!pool)
65+ return ERR_PTR(-ENOMEM);
8566
86− rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
87− if (IS_ERR(rc)) {
88− tee_shm_pool_mgr_destroy(priv_mgr);
89− tee_shm_pool_mgr_destroy(dmabuf_mgr);
90− }
67+ pool->ops = &pool_ops;
9168
92− return rc;
69+ return pool;
9370 }
drivers/tee/optee/Kconfig+0−8
@@ -7,11 +7,3 @@ config OPTEE · 6 unmodified lines
77 help
88 This implements the OP-TEE Trusted Execution Environment (TEE)
99 driver.
10−
11−config OPTEE_SHM_NUM_PRIV_PAGES
12− int "Private Shared Memory Pages"
13− default 1
14− depends on OPTEE
15− help
16− This sets the number of private shared memory pages to be
17− used by OP-TEE TEE driver.
drivers/tee/optee/call.c+1−1
@@ -120,7 +120,7 @@ struct tee_shm *optee_get_msg_arg(struct tee_context *ctx, size_t num_params, · 119 unmodified lines
120120 if (optee->rpc_arg_count)
121121 sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);
122122
123− shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);
123+ shm = tee_shm_alloc_priv_buf(ctx, sz);
124124 if (IS_ERR(shm))
125125 return shm;
126126
drivers/tee/optee/core.c+17−4
@@ -18,8 +18,8 @@ · 17 unmodified lines
1818 #include <linux/workqueue.h>
1919 #include "optee_private.h"
2020
21−int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
22− struct tee_shm *shm, size_t size,
21+int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
22+ size_t size, size_t align,
2323 int (*shm_register)(struct tee_context *ctx,
2424 struct tee_shm *shm,
2525 struct page **pages,
@@ -30,6 +30,10 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 4 unmodified lines
3030 struct page *page;
3131 int rc = 0;
3232
33+ /*
34+ * Ignore alignment since this is already going to be page aligned
35+ * and there's no need for any larger alignment.
36+ */
3337 page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
3438 if (!page)
3539 return -ENOMEM;
@@ -51,7 +55,6 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 15 unmodified lines
5155 for (i = 0; i < nr_pages; i++)
5256 pages[i] = page + i;
5357
54− shm->flags |= TEE_SHM_REGISTER;
5558 rc = shm_register(shm->ctx, shm, pages, nr_pages,
5659 (unsigned long)shm->kaddr);
5760 kfree(pages);
@@ -62,10 +65,20 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 4 unmodified lines
6265 return 0;
6366
6467 err:
65− __free_pages(page, order);
68+ free_pages((unsigned long)shm->kaddr, order);
6669 return rc;
6770 }
6871
72+void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
73+ int (*shm_unregister)(struct tee_context *ctx,
74+ struct tee_shm *shm))
75+{
76+ if (shm_unregister)
77+ shm_unregister(shm->ctx, shm);
78+ free_pages((unsigned long)shm->kaddr, get_order(shm->size));
79+ shm->kaddr = NULL;
80+}
81+
6982 static void optee_bus_scan(struct work_struct *work)
7083 {
7184 WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
drivers/tee/optee/device.c+2−3
@@ -121,10 +121,9 @@ static int __optee_enumerate_devices(u32 func) · 120 unmodified lines
121121 if (rc < 0 || !shm_size)
122122 goto out_sess;
123123
124− device_shm = tee_shm_alloc(ctx, shm_size,
125− TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
124+ device_shm = tee_shm_alloc_kernel_buf(ctx, shm_size);
126125 if (IS_ERR(device_shm)) {
127− pr_err("tee_shm_alloc failed\n");
126+ pr_err("tee_shm_alloc_kernel_buf failed\n");
128127 rc = PTR_ERR(device_shm);
129128 goto out_sess;
130129 }
drivers/tee/optee/ffa_abi.c+17−46
@@ -369,30 +369,28 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx, · 368 unmodified lines
369369 * The main function is optee_ffa_shm_pool_alloc_pages().
370370 */
371371
372−static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm,
373− struct tee_shm *shm, size_t size)
372+static int pool_ffa_op_alloc(struct tee_shm_pool *pool,
373+ struct tee_shm *shm, size_t size, size_t align)
374374 {
375− return optee_pool_op_alloc_helper(poolm, shm, size,
375+ return optee_pool_op_alloc_helper(pool, shm, size, align,
376376 optee_ffa_shm_register);
377377 }
378378
379−static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm,
379+static void pool_ffa_op_free(struct tee_shm_pool *pool,
380380 struct tee_shm *shm)
381381 {
382− optee_ffa_shm_unregister(shm->ctx, shm);
383− free_pages((unsigned long)shm->kaddr, get_order(shm->size));
384− shm->kaddr = NULL;
382+ optee_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
385383 }
386384
387−static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
385+static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool)
388386 {
389− kfree(poolm);
387+ kfree(pool);
390388 }
391389
392−static const struct tee_shm_pool_mgr_ops pool_ffa_ops = {
390+static const struct tee_shm_pool_ops pool_ffa_ops = {
393391 .alloc = pool_ffa_op_alloc,
394392 .free = pool_ffa_op_free,
395− .destroy_poolmgr = pool_ffa_op_destroy_poolmgr,
393+ .destroy_pool = pool_ffa_op_destroy_pool,
396394 };
397395
398396 /**
@@ -401,16 +399,16 @@ static const struct tee_shm_pool_mgr_ops pool_ffa_ops = { · 2 unmodified lines
401399 * This pool is used with OP-TEE over FF-A. In this case command buffers
402400 * and such are allocated from kernel's own memory.
403401 */
404−static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void)
402+static struct tee_shm_pool *optee_ffa_shm_pool_alloc_pages(void)
405403 {
406− struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
404+ struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
407405
408− if (!mgr)
406+ if (!pool)
409407 return ERR_PTR(-ENOMEM);
410408
411− mgr->ops = &pool_ffa_ops;
409+ pool->ops = &pool_ffa_ops;
412410
413− return mgr;
411+ return pool;
414412 }
415413
416414 /*
@@ -440,8 +438,8 @@ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx, · 23 unmodified lines
440438 shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);
441439 break;
442440 case OPTEE_RPC_SHM_TYPE_KERNEL:
443− shm = tee_shm_alloc(optee->ctx, arg->params[0].u.value.b,
444− TEE_SHM_MAPPED | TEE_SHM_PRIV);
441+ shm = tee_shm_alloc_priv_buf(optee->ctx,
442+ arg->params[0].u.value.b);
445443 break;
446444 default:
447445 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -700,33 +698,6 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, · 252 unmodified lines
700698 return true;
701699 }
702700
703−static struct tee_shm_pool *optee_ffa_config_dyn_shm(void)
704−{
705− struct tee_shm_pool_mgr *priv_mgr;
706− struct tee_shm_pool_mgr *dmabuf_mgr;
707− void *rc;
708−
709− rc = optee_ffa_shm_pool_alloc_pages();
710− if (IS_ERR(rc))
711− return rc;
712− priv_mgr = rc;
713−
714− rc = optee_ffa_shm_pool_alloc_pages();
715− if (IS_ERR(rc)) {
716− tee_shm_pool_mgr_destroy(priv_mgr);
717− return rc;
718− }
719− dmabuf_mgr = rc;
720−
721− rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
722− if (IS_ERR(rc)) {
723− tee_shm_pool_mgr_destroy(priv_mgr);
724− tee_shm_pool_mgr_destroy(dmabuf_mgr);
725− }
726−
727− return rc;
728−}
729−
730701 static void optee_ffa_get_version(struct tee_device *teedev,
731702 struct tee_ioctl_version_data *vers)
732703 {
@@ -824,7 +795,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) · 91 unmodified lines
824795 if (!optee)
825796 return -ENOMEM;
826797
827− pool = optee_ffa_config_dyn_shm();
798+ pool = optee_ffa_shm_pool_alloc_pages();
828799 if (IS_ERR(pool)) {
829800 rc = PTR_ERR(pool);
830801 goto err_free_optee;
drivers/tee/optee/optee_private.h+5−2
@@ -229,13 +229,16 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session); · 228 unmodified lines
229229 int optee_enumerate_devices(u32 func);
230230 void optee_unregister_devices(void);
231231
232−int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,
233− struct tee_shm *shm, size_t size,
232+int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
233+ size_t size, size_t align,
234234 int (*shm_register)(struct tee_context *ctx,
235235 struct tee_shm *shm,
236236 struct page **pages,
237237 size_t num_pages,
238238 unsigned long start));
239+void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
240+ int (*shm_unregister)(struct tee_context *ctx,
241+ struct tee_shm *shm));
239242
240243
241244 void optee_remove_common(struct optee *optee);
drivers/tee/optee/smc_abi.c+37−88
@@ -42,7 +42,15 @@ · 41 unmodified lines
4242 * 6. Driver initialization.
4343 */
4444
45−#define OPTEE_SHM_NUM_PRIV_PAGES CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
45+/*
46+ * A typical OP-TEE private shm allocation is 224 bytes (argument struct
47+ * with 6 parameters, needed for open session). So with an alignment of 512
48+ * we'll waste a bit more than 50%. However, it's only expected that we'll
49+ * have a handful of these structs allocated at a time. Most memory will
50+ * be allocated aligned to the page size, So all in all this should scale
51+ * up and down quite well.
52+ */
53+#define OPTEE_MIN_STATIC_POOL_ALIGN 9 /* 512 bytes aligned */
4654
4755 /*
4856 * 1. Convert between struct tee_param and struct optee_msg_param
@@ -220,7 +228,7 @@ static int optee_to_msg_param(struct optee *optee, · 171 unmodified lines
220228 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
221229 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
222230 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
223− if (tee_shm_is_registered(p->u.memref.shm))
231+ if (tee_shm_is_dynamic(p->u.memref.shm))
224232 rc = to_msg_param_reg_mem(mp, p);
225233 else
226234 rc = to_msg_param_tmp_mem(mp, p);
@@ -522,38 +530,38 @@ static int optee_shm_unregister_supp(struct tee_context *ctx, · 295 unmodified lines
522530 * The main function is optee_shm_pool_alloc_pages().
523531 */
524532
525−static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
526− struct tee_shm *shm, size_t size)
533+static int pool_op_alloc(struct tee_shm_pool *pool,
534+ struct tee_shm *shm, size_t size, size_t align)
527535 {
528536 /*
529537 * Shared memory private to the OP-TEE driver doesn't need
530538 * to be registered with OP-TEE.
531539 */
532540 if (shm->flags & TEE_SHM_PRIV)
533− return optee_pool_op_alloc_helper(poolm, shm, size, NULL);
541+ return optee_pool_op_alloc_helper(pool, shm, size, align, NULL);
534542
535− return optee_pool_op_alloc_helper(poolm, shm, size, optee_shm_register);
543+ return optee_pool_op_alloc_helper(pool, shm, size, align,
544+ optee_shm_register);
536545 }
537546
538−static void pool_op_free(struct tee_shm_pool_mgr *poolm,
547+static void pool_op_free(struct tee_shm_pool *pool,
539548 struct tee_shm *shm)
540549 {
541550 if (!(shm->flags & TEE_SHM_PRIV))
542− optee_shm_unregister(shm->ctx, shm);
543−
544− free_pages((unsigned long)shm->kaddr, get_order(shm->size));
545− shm->kaddr = NULL;
551+ optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
552+ else
553+ optee_pool_op_free_helper(pool, shm, NULL);
546554 }
547555
548−static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
556+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
549557 {
550− kfree(poolm);
558+ kfree(pool);
551559 }
552560
553−static const struct tee_shm_pool_mgr_ops pool_ops = {
561+static const struct tee_shm_pool_ops pool_ops = {
554562 .alloc = pool_op_alloc,
555563 .free = pool_op_free,
556− .destroy_poolmgr = pool_op_destroy_poolmgr,
564+ .destroy_pool = pool_op_destroy_pool,
557565 };
558566
559567 /**
@@ -562,16 +570,16 @@ static const struct tee_shm_pool_mgr_ops pool_ops = { · 2 unmodified lines
562570 * This pool is used when OP-TEE supports dymanic SHM. In this case
563571 * command buffers and such are allocated from kernel's own memory.
564572 */
565−static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
573+static struct tee_shm_pool *optee_shm_pool_alloc_pages(void)
566574 {
567− struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
575+ struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
568576
569− if (!mgr)
577+ if (!pool)
570578 return ERR_PTR(-ENOMEM);
571579
572− mgr->ops = &pool_ops;
580+ pool->ops = &pool_ops;
573581
574− return mgr;
582+ return pool;
575583 }
576584
577585 /*
@@ -642,8 +650,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, · 64 unmodified lines
642650 shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
643651 break;
644652 case OPTEE_RPC_SHM_TYPE_KERNEL:
645− shm = tee_shm_alloc(optee->ctx, sz,
646− TEE_SHM_MAPPED | TEE_SHM_PRIV);
653+ shm = tee_shm_alloc_priv_buf(optee->ctx, sz);
647654 break;
648655 default:
649656 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -662,7 +669,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, · 12 unmodified lines
662669
663670 sz = tee_shm_get_size(shm);
664671
665− if (tee_shm_is_registered(shm)) {
672+ if (tee_shm_is_dynamic(shm)) {
666673 struct page **pages;
667674 u64 *pages_list;
668675 size_t page_num;
@@ -768,8 +775,7 @@ static void optee_handle_rpc(struct tee_context *ctx, · 99 unmodified lines
768775
769776 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
770777 case OPTEE_SMC_RPC_FUNC_ALLOC:
771− shm = tee_shm_alloc(optee->ctx, param->a1,
772− TEE_SHM_MAPPED | TEE_SHM_PRIV);
778+ shm = tee_shm_alloc_priv_buf(optee->ctx, param->a1);
773779 if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
774780 reg_pair_from_64(&param->a1, &param->a2, pa);
775781 reg_pair_from_64(&param->a4, &param->a5,
@@ -1143,33 +1149,6 @@ static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn, · 367 unmodified lines
11431149 return true;
11441150 }
11451151
1146−static struct tee_shm_pool *optee_config_dyn_shm(void)
1147−{
1148− struct tee_shm_pool_mgr *priv_mgr;
1149− struct tee_shm_pool_mgr *dmabuf_mgr;
1150− void *rc;
1151−
1152− rc = optee_shm_pool_alloc_pages();
1153− if (IS_ERR(rc))
1154− return rc;
1155− priv_mgr = rc;
1156−
1157− rc = optee_shm_pool_alloc_pages();
1158− if (IS_ERR(rc)) {
1159− tee_shm_pool_mgr_destroy(priv_mgr);
1160− return rc;
1161− }
1162− dmabuf_mgr = rc;
1163−
1164− rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
1165− if (IS_ERR(rc)) {
1166− tee_shm_pool_mgr_destroy(priv_mgr);
1167− tee_shm_pool_mgr_destroy(dmabuf_mgr);
1168− }
1169−
1170− return rc;
1171−}
1172−
11731152 static struct tee_shm_pool *
11741153 optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
11751154 {
@@ -1183,10 +1162,7 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) · 7 unmodified lines
11831162 phys_addr_t begin;
11841163 phys_addr_t end;
11851164 void *va;
1186− struct tee_shm_pool_mgr *priv_mgr;
1187− struct tee_shm_pool_mgr *dmabuf_mgr;
11881165 void *rc;
1189− const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
11901166
11911167 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
11921168 if (res.result.status != OPTEE_SMC_RETURN_OK) {
@@ -1204,11 +1180,6 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) · 11 unmodified lines
12041180 paddr = begin;
12051181 size = end - begin;
12061182
1207− if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
1208− pr_err("too small shared memory area\n");
1209− return ERR_PTR(-EINVAL);
1210− }
1211−
12121183 va = memremap(paddr, size, MEMREMAP_WB);
12131184 if (!va) {
12141185 pr_err("shared memory ioremap failed\n");
@@ -1216,35 +1187,13 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) · 1 unmodified line
12161187 }
12171188 vaddr = (unsigned long)va;
12181189
1219− rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
1220− 3 /* 8 bytes aligned */);
1190+ rc = tee_shm_pool_alloc_res_mem(vaddr, paddr, size,
1191+ OPTEE_MIN_STATIC_POOL_ALIGN);
12211192 if (IS_ERR(rc))
1222− goto err_memunmap;
1223− priv_mgr = rc;
1224−
1225− vaddr += sz;
1226− paddr += sz;
1227− size -= sz;
1228−
1229− rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
1230− if (IS_ERR(rc))
1231− goto err_free_priv_mgr;
1232− dmabuf_mgr = rc;
1233−
1234− rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
1235− if (IS_ERR(rc))
1236− goto err_free_dmabuf_mgr;
1237−
1238− *memremaped_shm = va;
1239−
1240− return rc;
1193+ memunmap(va);
1194+ else
1195+ *memremaped_shm = va;
12411196
1242−err_free_dmabuf_mgr:
1243− tee_shm_pool_mgr_destroy(dmabuf_mgr);
1244−err_free_priv_mgr:
1245− tee_shm_pool_mgr_destroy(priv_mgr);
1246−err_memunmap:
1247− memunmap(va);
12481197 return rc;
12491198 }
12501199
@@ -1366,7 +1315,7 @@ static int optee_probe(struct platform_device *pdev) · 115 unmodified lines
13661315 * Try to use dynamic shared memory if possible
13671316 */
13681317 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
1369− pool = optee_config_dyn_shm();
1318+ pool = optee_shm_pool_alloc_pages();
13701319
13711320 /*
13721321 * If dynamic shared memory is not available or failed - try static one
drivers/tee/tee_core.c+2−3
@@ -297,7 +297,7 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx, · 296 unmodified lines
297297 if (data.flags)
298298 return -EINVAL;
299299
300− shm = tee_shm_alloc(ctx, data.size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
300+ shm = tee_shm_alloc_user_buf(ctx, data.size);
301301 if (IS_ERR(shm))
302302 return PTR_ERR(shm);
303303
@@ -334,8 +334,7 @@ tee_ioctl_shm_register(struct tee_context *ctx, · 30 unmodified lines
334334 if (data.flags)
335335 return -EINVAL;
336336
337− shm = tee_shm_register(ctx, data.addr, data.length,
338− TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED);
337+ shm = tee_shm_register_user_buf(ctx, data.addr, data.length);
339338 if (IS_ERR(shm))
340339 return PTR_ERR(shm);
341340
drivers/tee/tee_private.h+4−11
@@ -12,17 +12,6 @@ · 11 unmodified lines
1212 #include <linux/mutex.h>
1313 #include <linux/types.h>
1414
15−/**
16− * struct tee_shm_pool - shared memory pool
17− * @private_mgr: pool manager for shared memory only between kernel
18− * and secure world
19− * @dma_buf_mgr: pool manager for shared memory exported to user space
20− */
21−struct tee_shm_pool {
22− struct tee_shm_pool_mgr *private_mgr;
23− struct tee_shm_pool_mgr *dma_buf_mgr;
24−};
25−
2615 #define TEE_DEVICE_FLAG_REGISTERED 0x1
2716 #define TEE_MAX_DEV_NAME_LEN 32
2817
@@ -68,4 +57,8 @@ void tee_device_put(struct tee_device *teedev); · 39 unmodified lines
6857 void teedev_ctx_get(struct tee_context *ctx);
6958 void teedev_ctx_put(struct tee_context *ctx);
7059
60+struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size);
61+struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
62+ unsigned long addr, size_t length);
63+
7164 #endif /*TEE_PRIVATE_H*/
drivers/tee/tee_shm.c+210−110
@@ -12,17 +12,43 @@ · 11 unmodified lines
1212 #include <linux/uio.h>
1313 #include "tee_private.h"
1414
15+static void shm_put_kernel_pages(struct page **pages, size_t page_count)
16+{
17+ size_t n;
18+
19+ for (n = 0; n < page_count; n++)
20+ put_page(pages[n]);
21+}
22+
23+static int shm_get_kernel_pages(unsigned long start, size_t page_count,
24+ struct page **pages)
25+{
26+ struct kvec *kiov;
27+ size_t n;
28+ int rc;
29+
30+ kiov = kcalloc(page_count, sizeof(*kiov), GFP_KERNEL);
31+ if (!kiov)
32+ return -ENOMEM;
33+
34+ for (n = 0; n < page_count; n++) {
35+ kiov[n].iov_base = (void *)(start + n * PAGE_SIZE);
36+ kiov[n].iov_len = PAGE_SIZE;
37+ }
38+
39+ rc = get_kernel_pages(kiov, page_count, 0, pages);
40+ kfree(kiov);
41+
42+ return rc;
43+}
44+
1545 static void release_registered_pages(struct tee_shm *shm)
1646 {
1747 if (shm->pages) {
18− if (shm->flags & TEE_SHM_USER_MAPPED) {
48+ if (shm->flags & TEE_SHM_USER_MAPPED)
1949 unpin_user_pages(shm->pages, shm->num_pages);
20− } else {
21− size_t n;
22−
23− for (n = 0; n < shm->num_pages; n++)
24− put_page(shm->pages[n]);
25− }
50+ else
51+ shm_put_kernel_pages(shm->pages, shm->num_pages);
2652
2753 kfree(shm->pages);
2854 }
@@ -31,15 +57,8 @@ static void release_registered_pages(struct tee_shm *shm) · 2 unmodified lines
3157 static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
3258 {
3359 if (shm->flags & TEE_SHM_POOL) {
34− struct tee_shm_pool_mgr *poolm;
35−
36− if (shm->flags & TEE_SHM_DMA_BUF)
37− poolm = teedev->pool->dma_buf_mgr;
38− else
39− poolm = teedev->pool->private_mgr;
40−
41− poolm->ops->free(poolm, shm);
42− } else if (shm->flags & TEE_SHM_REGISTER) {
60+ teedev->pool->ops->free(teedev->pool, shm);
61+ } else if (shm->flags & TEE_SHM_DYNAMIC) {
4362 int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm);
4463
4564 if (rc)
@@ -56,25 +75,14 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) · 10 unmodified lines
5675 tee_device_put(teedev);
5776 }
5877
59−struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
78+static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size,
79+ size_t align, u32 flags, int id)
6080 {
6181 struct tee_device *teedev = ctx->teedev;
62− struct tee_shm_pool_mgr *poolm = NULL;
6382 struct tee_shm *shm;
6483 void *ret;
6584 int rc;
6685
67− if (!(flags & TEE_SHM_MAPPED)) {
68− dev_err(teedev->dev.parent,
69− "only mapped allocations supported\n");
70− return ERR_PTR(-EINVAL);
71− }
72−
73− if ((flags & ~(TEE_SHM_MAPPED | TEE_SHM_DMA_BUF | TEE_SHM_PRIV))) {
74− dev_err(teedev->dev.parent, "invalid shm flags 0x%x", flags);
75− return ERR_PTR(-EINVAL);
76− }
77−
7886 if (!tee_device_get(teedev))
7987 return ERR_PTR(-EINVAL);
8088
@@ -91,41 +99,76 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) · 10 unmodified lines
9199 }
92100
93101 refcount_set(&shm->refcount, 1);
94− shm->flags = flags | TEE_SHM_POOL;
102+ shm->flags = flags;
103+ shm->id = id;
104+
105+ /*
106+ * We're assigning this as it is needed if the shm is to be
107+ * registered. If this function returns OK then the caller expected
108+ * to call teedev_ctx_get() or clear shm->ctx in case it's not
109+ * needed any longer.
110+ */
95111 shm->ctx = ctx;
96− if (flags & TEE_SHM_DMA_BUF)
97− poolm = teedev->pool->dma_buf_mgr;
98− else
99− poolm = teedev->pool->private_mgr;
100112
101− rc = poolm->ops->alloc(poolm, shm, size);
113+ rc = teedev->pool->ops->alloc(teedev->pool, shm, size, align);
102114 if (rc) {
103115 ret = ERR_PTR(rc);
104116 goto err_kfree;
105117 }
106118
107− if (flags & TEE_SHM_DMA_BUF) {
108− mutex_lock(&teedev->mutex);
109− shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
110− mutex_unlock(&teedev->mutex);
111− if (shm->id < 0) {
112− ret = ERR_PTR(shm->id);
113− goto err_pool_free;
114− }
115− }
116−
117119 teedev_ctx_get(ctx);
118−
119120 return shm;
120−err_pool_free:
121− poolm->ops->free(poolm, shm);
122121 err_kfree:
123122 kfree(shm);
124123 err_dev_put:
125124 tee_device_put(teedev);
126125 return ret;
127126 }
128−EXPORT_SYMBOL_GPL(tee_shm_alloc);
127+
128+/**
129+ * tee_shm_alloc_user_buf() - Allocate shared memory for user space
130+ * @ctx: Context that allocates the shared memory
131+ * @size: Requested size of shared memory
132+ *
133+ * Memory allocated as user space shared memory is automatically freed when
134+ * the TEE file pointer is closed. The primary usage of this function is
135+ * when the TEE driver doesn't support registering ordinary user space
136+ * memory.
137+ *
138+ * @returns a pointer to 'struct tee_shm'
139+ */
140+struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size)
141+{
142+ u32 flags = TEE_SHM_DYNAMIC | TEE_SHM_POOL;
143+ struct tee_device *teedev = ctx->teedev;
144+ struct tee_shm *shm;
145+ void *ret;
146+ int id;
147+
148+ mutex_lock(&teedev->mutex);
149+ id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
150+ mutex_unlock(&teedev->mutex);
151+ if (id < 0)
152+ return ERR_PTR(id);
153+
154+ shm = shm_alloc_helper(ctx, size, PAGE_SIZE, flags, id);
155+ if (IS_ERR(shm)) {
156+ mutex_lock(&teedev->mutex);
157+ idr_remove(&teedev->idr, id);
158+ mutex_unlock(&teedev->mutex);
159+ return shm;
160+ }
161+
162+ mutex_lock(&teedev->mutex);
163+ ret = idr_replace(&teedev->idr, shm, id);
164+ mutex_unlock(&teedev->mutex);
165+ if (IS_ERR(ret)) {
166+ tee_shm_free(shm);
167+ return ret;
168+ }
169+
170+ return shm;
171+}
129172
130173 /**
131174 * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer
@@ -141,32 +184,54 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc); · 9 unmodified lines
141184 */
142185 struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size)
143186 {
144− return tee_shm_alloc(ctx, size, TEE_SHM_MAPPED);
187+ u32 flags = TEE_SHM_DYNAMIC | TEE_SHM_POOL;
188+
189+ return shm_alloc_helper(ctx, size, PAGE_SIZE, flags, -1);
145190 }
146191 EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf);
147192
148−struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
149− size_t length, u32 flags)
193+/**
194+ * tee_shm_alloc_priv_buf() - Allocate shared memory for a privately shared
195+ * kernel buffer
196+ * @ctx: Context that allocates the shared memory
197+ * @size: Requested size of shared memory
198+ *
199+ * This function returns similar shared memory as
200+ * tee_shm_alloc_kernel_buf(), but with the difference that the memory
201+ * might not be registered in secure world in case the driver supports
202+ * passing memory not registered in advance.
203+ *
204+ * This function should normally only be used internally in the TEE
205+ * drivers.
206+ *
207+ * @returns a pointer to 'struct tee_shm'
208+ */
209+struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size)
210+{
211+ u32 flags = TEE_SHM_PRIV | TEE_SHM_POOL;
212+
213+ return shm_alloc_helper(ctx, size, sizeof(long) * 2, flags, -1);
214+}
215+EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf);
216+
217+static struct tee_shm *
218+register_shm_helper(struct tee_context *ctx, unsigned long addr,
219+ size_t length, u32 flags, int id)
150220 {
151221 struct tee_device *teedev = ctx->teedev;
152− const u32 req_user_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED;
153− const u32 req_kernel_flags = TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED;
154222 struct tee_shm *shm;
223+ unsigned long start;
224+ size_t num_pages;
155225 void *ret;
156226 int rc;
157− int num_pages;
158− unsigned long start;
159−
160− if (flags != req_user_flags && flags != req_kernel_flags)
161− return ERR_PTR(-ENOTSUPP);
162227
163228 if (!tee_device_get(teedev))
164229 return ERR_PTR(-EINVAL);
165230
166231 if (!teedev->desc->ops->shm_register ||
167232 !teedev->desc->ops->shm_unregister) {
168− tee_device_put(teedev);
169− return ERR_PTR(-ENOTSUPP);
233+ ret = ERR_PTR(-ENOTSUPP);
234+ goto err_dev_put;
170235 }
171236
172237 teedev_ctx_get(ctx);
@@ -174,13 +239,13 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 1 unmodified line
174239 shm = kzalloc(sizeof(*shm), GFP_KERNEL);
175240 if (!shm) {
176241 ret = ERR_PTR(-ENOMEM);
177− goto err;
242+ goto err_ctx_put;
178243 }
179244
180245 refcount_set(&shm->refcount, 1);
181− shm->flags = flags | TEE_SHM_REGISTER;
246+ shm->flags = flags;
182247 shm->ctx = ctx;
183− shm->id = -1;
248+ shm->id = id;
184249 addr = untagged_addr(addr);
185250 start = rounddown(addr, PAGE_SIZE);
186251 shm->offset = addr - start;
@@ -189,71 +254,106 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 2 unmodified lines
189254 shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL);
190255 if (!shm->pages) {
191256 ret = ERR_PTR(-ENOMEM);
192− goto err;
257+ goto err_free_shm;
193258 }
194259
195− if (flags & TEE_SHM_USER_MAPPED) {
260+ if (flags & TEE_SHM_USER_MAPPED)
196261 rc = pin_user_pages_fast(start, num_pages, FOLL_WRITE,
197262 shm->pages);
198− } else {
199− struct kvec *kiov;
200− int i;
201−
202− kiov = kcalloc(num_pages, sizeof(*kiov), GFP_KERNEL);
203− if (!kiov) {
204− ret = ERR_PTR(-ENOMEM);
205− goto err;
206− }
207−
208− for (i = 0; i < num_pages; i++) {
209− kiov[i].iov_base = (void *)(start + i * PAGE_SIZE);
210− kiov[i].iov_len = PAGE_SIZE;
211− }
212−
213− rc = get_kernel_pages(kiov, num_pages, 0, shm->pages);
214− kfree(kiov);
215− }
263+ else
264+ rc = shm_get_kernel_pages(start, num_pages, shm->pages);
216265 if (rc > 0)
217266 shm->num_pages = rc;
218267 if (rc != num_pages) {
219268 if (rc >= 0)
220269 rc = -ENOMEM;
221270 ret = ERR_PTR(rc);
222− goto err;
223− }
224−
225− mutex_lock(&teedev->mutex);
226− shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL);
227− mutex_unlock(&teedev->mutex);
228−
229− if (shm->id < 0) {
230− ret = ERR_PTR(shm->id);
231− goto err;
271+ goto err_put_shm_pages;
232272 }
233273
234274 rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages,
235275 shm->num_pages, start);
236276 if (rc) {
237277 ret = ERR_PTR(rc);
238− goto err;
278+ goto err_put_shm_pages;
239279 }
240280
241281 return shm;
242−err:
243− if (shm) {
244− if (shm->id >= 0) {
245− mutex_lock(&teedev->mutex);
246− idr_remove(&teedev->idr, shm->id);
247− mutex_unlock(&teedev->mutex);
248− }
249− release_registered_pages(shm);
250− }
282+err_put_shm_pages:
283+ if (flags & TEE_SHM_USER_MAPPED)
284+ unpin_user_pages(shm->pages, shm->num_pages);
285+ else
286+ shm_put_kernel_pages(shm->pages, shm->num_pages);
287+ kfree(shm->pages);
288+err_free_shm:
251289 kfree(shm);
290+err_ctx_put:
252291 teedev_ctx_put(ctx);
292+err_dev_put:
253293 tee_device_put(teedev);
254294 return ret;
255295 }
256−EXPORT_SYMBOL_GPL(tee_shm_register);
296+
297+/**
298+ * tee_shm_register_user_buf() - Register a userspace shared memory buffer
299+ * @ctx: Context that registers the shared memory
300+ * @addr: The userspace address of the shared buffer
301+ * @length: Length of the shared buffer
302+ *
303+ * @returns a pointer to 'struct tee_shm'
304+ */
305+struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
306+ unsigned long addr, size_t length)
307+{
308+ u32 flags = TEE_SHM_USER_MAPPED | TEE_SHM_DYNAMIC;
309+ struct tee_device *teedev = ctx->teedev;
310+ struct tee_shm *shm;
311+ void *ret;
312+ int id;
313+
314+ mutex_lock(&teedev->mutex);
315+ id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL);
316+ mutex_unlock(&teedev->mutex);
317+ if (id < 0)
318+ return ERR_PTR(id);
319+
320+ shm = register_shm_helper(ctx, addr, length, flags, id);
321+ if (IS_ERR(shm)) {
322+ mutex_lock(&teedev->mutex);
323+ idr_remove(&teedev->idr, id);
324+ mutex_unlock(&teedev->mutex);
325+ return shm;
326+ }
327+
328+ mutex_lock(&teedev->mutex);
329+ ret = idr_replace(&teedev->idr, shm, id);
330+ mutex_unlock(&teedev->mutex);
331+ if (IS_ERR(ret)) {
332+ tee_shm_free(shm);
333+ return ret;
334+ }
335+
336+ return shm;
337+}
338+
339+/**
340+ * tee_shm_register_kernel_buf() - Register kernel memory to be shared with
341+ * secure world
342+ * @ctx: Context that registers the shared memory
343+ * @addr: The buffer
344+ * @length: Length of the buffer
345+ *
346+ * @returns a pointer to 'struct tee_shm'
347+ */
348+
349+struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
350+ void *addr, size_t length)
351+{
352+ u32 flags = TEE_SHM_DYNAMIC;
353+
354+ return register_shm_helper(ctx, (unsigned long)addr, length, flags, -1);
355+}
356+EXPORT_SYMBOL_GPL(tee_shm_register_kernel_buf);
257357
258358 static int tee_shm_fop_release(struct inode *inode, struct file *filp)
259359 {
@@ -293,7 +393,7 @@ int tee_shm_get_fd(struct tee_shm *shm) · 33 unmodified lines
293393 {
294394 int fd;
295395
296− if (!(shm->flags & TEE_SHM_DMA_BUF))
396+ if (shm->id < 0)
297397 return -EINVAL;
298398
299399 /* matched by tee_shm_put() in tee_shm_op_release() */
@@ -323,7 +423,7 @@ EXPORT_SYMBOL_GPL(tee_shm_free); · 23 unmodified lines
323423 */
324424 int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa)
325425 {
326− if (!(shm->flags & TEE_SHM_MAPPED))
426+ if (!shm->kaddr)
327427 return -EINVAL;
328428 /* Check that we're in the range of the shm */
329429 if ((char *)va < (char *)shm->kaddr)
@@ -345,7 +445,7 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa); · 15 unmodified lines
345445 */
346446 int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va)
347447 {
348− if (!(shm->flags & TEE_SHM_MAPPED))
448+ if (!shm->kaddr)
349449 return -EINVAL;
350450 /* Check that we're in the range of the shm */
351451 if (pa < shm->paddr)
@@ -373,7 +473,7 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va); · 21 unmodified lines
373473 */
374474 void *tee_shm_get_va(struct tee_shm *shm, size_t offs)
375475 {
376− if (!(shm->flags & TEE_SHM_MAPPED))
476+ if (!shm->kaddr)
377477 return ERR_PTR(-EINVAL);
378478 if (offs >= shm->size)
379479 return ERR_PTR(-EINVAL);
@@ -448,7 +548,7 @@ void tee_shm_put(struct tee_shm *shm) · 68 unmodified lines
448548 * the refcount_inc() in tee_shm_get_from_id() never starts
449549 * from 0.
450550 */
451− if (shm->flags & TEE_SHM_DMA_BUF)
551+ if (shm->id >= 0)
452552 idr_remove(&teedev->idr, shm->id);
453553 do_release = true;
454554 }
drivers/tee/tee_shm_pool.c+34−128
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2015, Linaro Limited
3+ * Copyright (c) 2015, 2017, 2022 Linaro Limited
44 */
55 #include <linux/device.h>
66 #include <linux/dma-buf.h>
@@ -9,14 +9,16 @@ · 2 unmodified lines
99 #include <linux/tee_drv.h>
1010 #include "tee_private.h"
1111
12−static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm,
13− struct tee_shm *shm, size_t size)
12+static int pool_op_gen_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
13+ size_t size, size_t align)
1414 {
1515 unsigned long va;
16− struct gen_pool *genpool = poolm->private_data;
17− size_t s = roundup(size, 1 << genpool->min_alloc_order);
16+ struct gen_pool *genpool = pool->private_data;
17+ size_t a = max_t(size_t, align, BIT(genpool->min_alloc_order));
18+ struct genpool_data_align data = { .align = a };
19+ size_t s = roundup(size, a);
1820
19− va = gen_pool_alloc(genpool, s);
21+ va = gen_pool_alloc_algo(genpool, s, gen_pool_first_fit_align, &data);
2022 if (!va)
2123 return -ENOMEM;
2224
@@ -24,163 +26,67 @@ static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm, · 1 unmodified line
2426 shm->kaddr = (void *)va;
2527 shm->paddr = gen_pool_virt_to_phys(genpool, va);
2628 shm->size = s;
29+ /*
30+ * This is from a static shared memory pool so no need to register
31+ * each chunk, and no need to unregister later either.
32+ */
33+ shm->flags &= ~TEE_SHM_DYNAMIC;
2734 return 0;
2835 }
2936
30−static void pool_op_gen_free(struct tee_shm_pool_mgr *poolm,
31− struct tee_shm *shm)
37+static void pool_op_gen_free(struct tee_shm_pool *pool, struct tee_shm *shm)
3238 {
33− gen_pool_free(poolm->private_data, (unsigned long)shm->kaddr,
39+ gen_pool_free(pool->private_data, (unsigned long)shm->kaddr,
3440 shm->size);
3541 shm->kaddr = NULL;
3642 }
3743
38−static void pool_op_gen_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
44+static void pool_op_gen_destroy_pool(struct tee_shm_pool *pool)
3945 {
40− gen_pool_destroy(poolm->private_data);
41− kfree(poolm);
46+ gen_pool_destroy(pool->private_data);
47+ kfree(pool);
4248 }
4349
44−static const struct tee_shm_pool_mgr_ops pool_ops_generic = {
50+static const struct tee_shm_pool_ops pool_ops_generic = {
4551 .alloc = pool_op_gen_alloc,
4652 .free = pool_op_gen_free,
47− .destroy_poolmgr = pool_op_gen_destroy_poolmgr,
53+ .destroy_pool = pool_op_gen_destroy_pool,
4854 };
4955
50−/**
51− * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved
52− * memory range
53− * @priv_info: Information for driver private shared memory pool
54− * @dmabuf_info: Information for dma-buf shared memory pool
55− *
56− * Start and end of pools will must be page aligned.
57− *
58− * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
59− * in @dmabuf, others will use the range provided by @priv.
60− *
61− * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
62− */
63−struct tee_shm_pool *
64−tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info *priv_info,
65− struct tee_shm_pool_mem_info *dmabuf_info)
66−{
67− struct tee_shm_pool_mgr *priv_mgr;
68− struct tee_shm_pool_mgr *dmabuf_mgr;
69− void *rc;
70−
71− /*
72− * Create the pool for driver private shared memory
73− */
74− rc = tee_shm_pool_mgr_alloc_res_mem(priv_info->vaddr, priv_info->paddr,
75− priv_info->size,
76− 3 /* 8 byte aligned */);
77− if (IS_ERR(rc))
78− return rc;
79− priv_mgr = rc;
80−
81− /*
82− * Create the pool for dma_buf shared memory
83− */
84− rc = tee_shm_pool_mgr_alloc_res_mem(dmabuf_info->vaddr,
85− dmabuf_info->paddr,
86− dmabuf_info->size, PAGE_SHIFT);
87− if (IS_ERR(rc))
88− goto err_free_priv_mgr;
89− dmabuf_mgr = rc;
90−
91− rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
92− if (IS_ERR(rc))
93− goto err_free_dmabuf_mgr;
94−
95− return rc;
96−
97−err_free_dmabuf_mgr:
98− tee_shm_pool_mgr_destroy(dmabuf_mgr);
99−err_free_priv_mgr:
100− tee_shm_pool_mgr_destroy(priv_mgr);
101−
102− return rc;
103−}
104−EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
105−
106−struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr,
107− phys_addr_t paddr,
108− size_t size,
109− int min_alloc_order)
56+struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
57+ phys_addr_t paddr, size_t size,
58+ int min_alloc_order)
11059 {
11160 const size_t page_mask = PAGE_SIZE - 1;
112− struct tee_shm_pool_mgr *mgr;
61+ struct tee_shm_pool *pool;
11362 int rc;
11463
11564 /* Start and end must be page aligned */
11665 if (vaddr & page_mask || paddr & page_mask || size & page_mask)
11766 return ERR_PTR(-EINVAL);
11867
119− mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
120− if (!mgr)
68+ pool = kzalloc(sizeof(*pool), GFP_KERNEL);
69+ if (!pool)
12170 return ERR_PTR(-ENOMEM);
12271
123− mgr->private_data = gen_pool_create(min_alloc_order, -1);
124− if (!mgr->private_data) {
72+ pool->private_data = gen_pool_create(min_alloc_order, -1);
73+ if (!pool->private_data) {
12574 rc = -ENOMEM;
12675 goto err;
12776 }
12877
129− gen_pool_set_algo(mgr->private_data, gen_pool_best_fit, NULL);
130− rc = gen_pool_add_virt(mgr->private_data, vaddr, paddr, size, -1);
78+ rc = gen_pool_add_virt(pool->private_data, vaddr, paddr, size, -1);
13179 if (rc) {
132− gen_pool_destroy(mgr->private_data);
80+ gen_pool_destroy(pool->private_data);
13381 goto err;
13482 }
13583
136− mgr->ops = &pool_ops_generic;
84+ pool->ops = &pool_ops_generic;
13785
138− return mgr;
86+ return pool;
13987 err:
140− kfree(mgr);
88+ kfree(pool);
14189
14290 return ERR_PTR(rc);
14391 }
144−EXPORT_SYMBOL_GPL(tee_shm_pool_mgr_alloc_res_mem);
145−
146−static bool check_mgr_ops(struct tee_shm_pool_mgr *mgr)
147−{
148− return mgr && mgr->ops && mgr->ops->alloc && mgr->ops->free &&
149− mgr->ops->destroy_poolmgr;
150−}
151−
152−struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr,
153− struct tee_shm_pool_mgr *dmabuf_mgr)
154−{
155− struct tee_shm_pool *pool;
156−
157− if (!check_mgr_ops(priv_mgr) || !check_mgr_ops(dmabuf_mgr))
158− return ERR_PTR(-EINVAL);
159−
160− pool = kzalloc(sizeof(*pool), GFP_KERNEL);
161− if (!pool)
162− return ERR_PTR(-ENOMEM);
163−
164− pool->private_mgr = priv_mgr;
165− pool->dma_buf_mgr = dmabuf_mgr;
166−
167− return pool;
168−}
169−EXPORT_SYMBOL_GPL(tee_shm_pool_alloc);
170−
171−/**
172− * tee_shm_pool_free() - Free a shared memory pool
173− * @pool: The shared memory pool to free
174− *
175− * There must be no remaining shared memory allocated from this pool when
176− * this function is called.
177− */
178−void tee_shm_pool_free(struct tee_shm_pool *pool)
179−{
180− if (pool->private_mgr)
181− tee_shm_pool_mgr_destroy(pool->private_mgr);
182− if (pool->dma_buf_mgr)
183− tee_shm_pool_mgr_destroy(pool->dma_buf_mgr);
184− kfree(pool);
185−}
186−EXPORT_SYMBOL_GPL(tee_shm_pool_free);
92+EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
include/dt-bindings/clock/fsd-clk.h+150−0
@@ -0,0 +1,150 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+/*
3+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
4+ * https://www.samsung.com
5+ * Copyright (c) 2017-2022 Tesla, Inc.
6+ * https://www.tesla.com
7+ *
8+ * The constants defined in this header are being used in dts
9+ * and fsd platform driver.
10+ */
11+
12+#ifndef _DT_BINDINGS_CLOCK_FSD_H
13+#define _DT_BINDINGS_CLOCK_FSD_H
14+
15+/* CMU */
16+#define DOUT_CMU_PLL_SHARED0_DIV4 1
17+#define DOUT_CMU_PERIC_SHARED1DIV36 2
18+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK 3
19+#define DOUT_CMU_PERIC_SHARED0DIV20 4
20+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK 5
21+#define DOUT_CMU_PLL_SHARED0_DIV6 6
22+#define DOUT_CMU_FSYS0_SHARED1DIV4 7
23+#define DOUT_CMU_FSYS0_SHARED0DIV4 8
24+#define DOUT_CMU_FSYS1_SHARED0DIV8 9
25+#define DOUT_CMU_FSYS1_SHARED0DIV4 10
26+#define CMU_CPUCL_SWITCH_GATE 11
27+#define DOUT_CMU_IMEM_TCUCLK 12
28+#define DOUT_CMU_IMEM_ACLK 13
29+#define DOUT_CMU_IMEM_DMACLK 14
30+#define GAT_CMU_FSYS0_SHARED0DIV4 15
31+#define CMU_NR_CLK 16
32+
33+/* PERIC */
34+#define PERIC_SCLK_UART0 1
35+#define PERIC_PCLK_UART0 2
36+#define PERIC_SCLK_UART1 3
37+#define PERIC_PCLK_UART1 4
38+#define PERIC_DMA0_IPCLKPORT_ACLK 5
39+#define PERIC_DMA1_IPCLKPORT_ACLK 6
40+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0 7
41+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0 8
42+#define PERIC_PCLK_SPI0 9
43+#define PERIC_SCLK_SPI0 10
44+#define PERIC_PCLK_SPI1 11
45+#define PERIC_SCLK_SPI1 12
46+#define PERIC_PCLK_SPI2 13
47+#define PERIC_SCLK_SPI2 14
48+#define PERIC_PCLK_TDM0 15
49+#define PERIC_PCLK_HSI2C0 16
50+#define PERIC_PCLK_HSI2C1 17
51+#define PERIC_PCLK_HSI2C2 18
52+#define PERIC_PCLK_HSI2C3 19
53+#define PERIC_PCLK_HSI2C4 20
54+#define PERIC_PCLK_HSI2C5 21
55+#define PERIC_PCLK_HSI2C6 22
56+#define PERIC_PCLK_HSI2C7 23
57+#define PERIC_MCAN0_IPCLKPORT_CCLK 24
58+#define PERIC_MCAN0_IPCLKPORT_PCLK 25
59+#define PERIC_MCAN1_IPCLKPORT_CCLK 26
60+#define PERIC_MCAN1_IPCLKPORT_PCLK 27
61+#define PERIC_MCAN2_IPCLKPORT_CCLK 28
62+#define PERIC_MCAN2_IPCLKPORT_PCLK 29
63+#define PERIC_MCAN3_IPCLKPORT_CCLK 30
64+#define PERIC_MCAN3_IPCLKPORT_PCLK 31
65+#define PERIC_PCLK_ADCIF 32
66+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I 33
67+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I 34
68+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I 35
69+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I 36
70+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I 37
71+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK 38
72+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK 39
73+#define PERIC_HCLK_TDM0 40
74+#define PERIC_PCLK_TDM1 41
75+#define PERIC_HCLK_TDM1 42
76+#define PERIC_EQOS_PHYRXCLK_MUX 43
77+#define PERIC_EQOS_PHYRXCLK 44
78+#define PERIC_DOUT_RGMII_CLK 45
79+#define PERIC_NR_CLK 46
80+
81+/* FSYS0 */
82+#define UFS0_MPHY_REFCLK_IXTAL24 1
83+#define UFS0_MPHY_REFCLK_IXTAL26 2
84+#define UFS1_MPHY_REFCLK_IXTAL24 3
85+#define UFS1_MPHY_REFCLK_IXTAL26 4
86+#define UFS0_TOP0_HCLK_BUS 5
87+#define UFS0_TOP0_ACLK 6
88+#define UFS0_TOP0_CLK_UNIPRO 7
89+#define UFS0_TOP0_FMP_CLK 8
90+#define UFS1_TOP1_HCLK_BUS 9
91+#define UFS1_TOP1_ACLK 10
92+#define UFS1_TOP1_CLK_UNIPRO 11
93+#define UFS1_TOP1_FMP_CLK 12
94+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC 13
95+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC 14
96+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC 15
97+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC 16
98+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
99+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I 18
100+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I 19
101+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I 20
102+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I 21
103+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP 22
104+#define FSYS0_NR_CLK 23
105+
106+/* FSYS1 */
107+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK 1
108+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK 2
109+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK 3
110+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK 4
111+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK 5
112+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK 6
113+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK 7
114+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK 8
115+#define FSYS1_NR_CLK 9
116+
117+/* IMEM */
118+#define IMEM_DMA0_IPCLKPORT_ACLK 1
119+#define IMEM_DMA1_IPCLKPORT_ACLK 2
120+#define IMEM_WDT0_IPCLKPORT_PCLK 3
121+#define IMEM_WDT1_IPCLKPORT_PCLK 4
122+#define IMEM_WDT2_IPCLKPORT_PCLK 5
123+#define IMEM_MCT_PCLK 6
124+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS 7
125+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS 8
126+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS 9
127+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS 10
128+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS 11
129+#define IMEM_NR_CLK 12
130+
131+/* MFC */
132+#define MFC_MFC_IPCLKPORT_ACLK 1
133+#define MFC_NR_CLK 2
134+
135+/* CAM_CSI */
136+#define CAM_CSI0_0_IPCLKPORT_I_ACLK 1
137+#define CAM_CSI0_1_IPCLKPORT_I_ACLK 2
138+#define CAM_CSI0_2_IPCLKPORT_I_ACLK 3
139+#define CAM_CSI0_3_IPCLKPORT_I_ACLK 4
140+#define CAM_CSI1_0_IPCLKPORT_I_ACLK 5
141+#define CAM_CSI1_1_IPCLKPORT_I_ACLK 6
142+#define CAM_CSI1_2_IPCLKPORT_I_ACLK 7
143+#define CAM_CSI1_3_IPCLKPORT_I_ACLK 8
144+#define CAM_CSI2_0_IPCLKPORT_I_ACLK 9
145+#define CAM_CSI2_1_IPCLKPORT_I_ACLK 10
146+#define CAM_CSI2_2_IPCLKPORT_I_ACLK 11
147+#define CAM_CSI2_3_IPCLKPORT_I_ACLK 12
148+#define CAM_CSI_NR_CLK 13
149+
150+#endif /*_DT_BINDINGS_CLOCK_FSD_H */
include/dt-bindings/power/imx8mq-power.h+3−0
@@ -18,4 +18,7 @@ · 17 unmodified lines
1818 #define IMX8M_POWER_DOMAIN_MIPI_CSI2 9
1919 #define IMX8M_POWER_DOMAIN_PCIE2 10
2020
21+#define IMX8MQ_VPUBLK_PD_G1 0
22+#define IMX8MQ_VPUBLK_PD_G2 1
23+
2124 #endif
include/dt-bindings/power/meson-s4-power.h+19−0
@@ -0,0 +1,19 @@
1+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
2+/*
3+ * Copyright (c) 2021 Amlogic, Inc.
4+ * Author: Shunzhou Jiang <shunzhou.jiang@amlogic.com>
5+ */
6+
7+#ifndef _DT_BINDINGS_MESON_S4_POWER_H
8+#define _DT_BINDINGS_MESON_S4_POWER_H
9+
10+#define PWRC_S4_DOS_HEVC_ID 0
11+#define PWRC_S4_DOS_VDEC_ID 1
12+#define PWRC_S4_VPU_HDMI_ID 2
13+#define PWRC_S4_USB_COMB_ID 3
14+#define PWRC_S4_GE2D_ID 4
15+#define PWRC_S4_ETH_ID 5
16+#define PWRC_S4_DEMOD_ID 6
17+#define PWRC_S4_AUDIO_ID 7
18+
19+#endif
include/dt-bindings/power/mt8186-power.h+32−0
@@ -0,0 +1,32 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2+/*
3+ * Copyright (c) 2022 MediaTek Inc.
4+ * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
5+ */
6+
7+#ifndef _DT_BINDINGS_POWER_MT8186_POWER_H
8+#define _DT_BINDINGS_POWER_MT8186_POWER_H
9+
10+#define MT8186_POWER_DOMAIN_MFG0 0
11+#define MT8186_POWER_DOMAIN_MFG1 1
12+#define MT8186_POWER_DOMAIN_MFG2 2
13+#define MT8186_POWER_DOMAIN_MFG3 3
14+#define MT8186_POWER_DOMAIN_SSUSB 4
15+#define MT8186_POWER_DOMAIN_SSUSB_P1 5
16+#define MT8186_POWER_DOMAIN_DIS 6
17+#define MT8186_POWER_DOMAIN_IMG 7
18+#define MT8186_POWER_DOMAIN_IMG2 8
19+#define MT8186_POWER_DOMAIN_IPE 9
20+#define MT8186_POWER_DOMAIN_CAM 10
21+#define MT8186_POWER_DOMAIN_CAM_RAWA 11
22+#define MT8186_POWER_DOMAIN_CAM_RAWB 12
23+#define MT8186_POWER_DOMAIN_VENC 13
24+#define MT8186_POWER_DOMAIN_VDEC 14
25+#define MT8186_POWER_DOMAIN_WPE 15
26+#define MT8186_POWER_DOMAIN_CONN_ON 16
27+#define MT8186_POWER_DOMAIN_CSIRX_TOP 17
28+#define MT8186_POWER_DOMAIN_ADSP_AO 18
29+#define MT8186_POWER_DOMAIN_ADSP_INFRA 19
30+#define MT8186_POWER_DOMAIN_ADSP_TOP 20
31+
32+#endif /* _DT_BINDINGS_POWER_MT8186_POWER_H */
include/dt-bindings/power/mt8195-power.h+46−0
@@ -0,0 +1,46 @@
1+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
2+/*
3+ * Copyright (c) 2021 MediaTek Inc.
4+ * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
5+ */
6+
7+#ifndef _DT_BINDINGS_POWER_MT8195_POWER_H
8+#define _DT_BINDINGS_POWER_MT8195_POWER_H
9+
10+#define MT8195_POWER_DOMAIN_PCIE_MAC_P0 0
11+#define MT8195_POWER_DOMAIN_PCIE_MAC_P1 1
12+#define MT8195_POWER_DOMAIN_PCIE_PHY 2
13+#define MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY 3
14+#define MT8195_POWER_DOMAIN_CSI_RX_TOP 4
15+#define MT8195_POWER_DOMAIN_ETHER 5
16+#define MT8195_POWER_DOMAIN_ADSP 6
17+#define MT8195_POWER_DOMAIN_AUDIO 7
18+#define MT8195_POWER_DOMAIN_MFG0 8
19+#define MT8195_POWER_DOMAIN_MFG1 9
20+#define MT8195_POWER_DOMAIN_MFG2 10
21+#define MT8195_POWER_DOMAIN_MFG3 11
22+#define MT8195_POWER_DOMAIN_MFG4 12
23+#define MT8195_POWER_DOMAIN_MFG5 13
24+#define MT8195_POWER_DOMAIN_MFG6 14
25+#define MT8195_POWER_DOMAIN_VPPSYS0 15
26+#define MT8195_POWER_DOMAIN_VDOSYS0 16
27+#define MT8195_POWER_DOMAIN_VPPSYS1 17
28+#define MT8195_POWER_DOMAIN_VDOSYS1 18
29+#define MT8195_POWER_DOMAIN_DP_TX 19
30+#define MT8195_POWER_DOMAIN_EPD_TX 20
31+#define MT8195_POWER_DOMAIN_HDMI_TX 21
32+#define MT8195_POWER_DOMAIN_WPESYS 22
33+#define MT8195_POWER_DOMAIN_VDEC0 23
34+#define MT8195_POWER_DOMAIN_VDEC1 24
35+#define MT8195_POWER_DOMAIN_VDEC2 25
36+#define MT8195_POWER_DOMAIN_VENC 26
37+#define MT8195_POWER_DOMAIN_VENC_CORE1 27
38+#define MT8195_POWER_DOMAIN_IMG 28
39+#define MT8195_POWER_DOMAIN_DIP 29
40+#define MT8195_POWER_DOMAIN_IPE 30
41+#define MT8195_POWER_DOMAIN_CAM 31
42+#define MT8195_POWER_DOMAIN_CAM_RAWA 32
43+#define MT8195_POWER_DOMAIN_CAM_RAWB 33
44+#define MT8195_POWER_DOMAIN_CAM_MRAW 34
45+
46+#endif /* _DT_BINDINGS_POWER_MT8195_POWER_H */
include/dt-bindings/power/qcom-rpmpd.h+5−0
@@ -139,6 +139,11 @@ · 138 unmodified lines
139139 #define MDM9607_VDDMX_AO 4
140140 #define MDM9607_VDDMX_VFL 5
141141
142+/* MSM8226 Power Domain Indexes */
143+#define MSM8226_VDDCX 0
144+#define MSM8226_VDDCX_AO 1
145+#define MSM8226_VDDCX_VFC 2
146+
142147 /* MSM8939 Power Domains */
143148 #define MSM8939_VDDMDCX 0
144149 #define MSM8939_VDDMDCX_AO 1
include/linux/firmware/imx/svc/rm.h+5−0
@@ -59,11 +59,16 @@ enum imx_sc_rm_func { · 58 unmodified lines
5959
6060 #if IS_ENABLED(CONFIG_IMX_SCU)
6161 bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
62+int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt);
6263 #else
6364 static inline bool
6465 imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
6566 {
6667 return true;
6768 }
69+static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
70+{
71+ return -EOPNOTSUPP;
72+}
6873 #endif
6974 #endif
include/linux/qcom_scm.h+13−3
@@ -63,13 +63,21 @@ enum qcom_scm_ice_cipher { · 62 unmodified lines
6363
6464 extern bool qcom_scm_is_available(void);
6565
66−extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
67−extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
66+extern int qcom_scm_set_cold_boot_addr(void *entry);
67+extern int qcom_scm_set_warm_boot_addr(void *entry);
6868 extern void qcom_scm_cpu_power_down(u32 flags);
6969 extern int qcom_scm_set_remote_state(u32 state, u32 id);
7070
71+struct qcom_scm_pas_metadata {
72+ void *ptr;
73+ dma_addr_t phys;
74+ ssize_t size;
75+};
76+
7177 extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
72− size_t size);
78+ size_t size,
79+ struct qcom_scm_pas_metadata *ctx);
80+void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
7381 extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
7482 phys_addr_t size);
7583 extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
@@ -83,6 +91,7 @@ extern bool qcom_scm_restore_sec_cfg_available(void); · 7 unmodified lines
8391 extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
8492 extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
8593 extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
94+extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
8695 extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
8796 u32 cp_nonpixel_start,
8897 u32 cp_nonpixel_size);
@@ -107,6 +116,7 @@ extern bool qcom_scm_hdcp_available(void); · 18 unmodified lines
107116 extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
108117 u32 *resp);
109118
119+extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
110120 extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
111121
112122 extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
include/linux/scmi_protocol.h+15−0
@@ -42,6 +42,7 @@ struct scmi_revision_info { · 41 unmodified lines
4242
4343 struct scmi_clock_info {
4444 char name[SCMI_MAX_STR_SIZE];
45+ unsigned int enable_latency;
4546 bool rate_discrete;
4647 union {
4748 struct {
@@ -82,6 +83,9 @@ struct scmi_clk_proto_ops { · 34 unmodified lines
8283 u64 rate);
8384 int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
8485 int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
86+ int (*enable_atomic)(const struct scmi_protocol_handle *ph, u32 clk_id);
87+ int (*disable_atomic)(const struct scmi_protocol_handle *ph,
88+ u32 clk_id);
8589 };
8690
8791 /**
@@ -612,6 +616,15 @@ struct scmi_notify_ops { · 524 unmodified lines
612616 * @devm_protocol_get: devres managed method to acquire a protocol and get specific
613617 * operations and a dedicated protocol handler
614618 * @devm_protocol_put: devres managed method to release a protocol
619+ * @is_transport_atomic: method to check if the underlying transport for this
620+ * instance handle is configured to support atomic
621+ * transactions for commands.
622+ * Some users of the SCMI stack in the upper layers could
623+ * be interested to know if they can assume SCMI
624+ * command transactions associated to this handle will
625+ * never sleep and act accordingly.
626+ * An optional atomic threshold value could be returned
627+ * where configured.
615628 * @notify_ops: pointer to set of notifications related operations
616629 */
617630 struct scmi_handle {
@@ -622,6 +635,8 @@ struct scmi_handle { · 4 unmodified lines
622635 (*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
623636 struct scmi_protocol_handle **ph);
624637 void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
638+ bool (*is_transport_atomic)(const struct scmi_handle *handle,
639+ unsigned int *atomic_threshold);
625640
626641 const struct scmi_notify_ops *notify_ops;
627642 };
include/linux/soc/mediatek/infracfg.h+133−0
@@ -2,6 +2,88 @@ · 1 unmodified line
22 #ifndef __SOC_MEDIATEK_INFRACFG_H
33 #define __SOC_MEDIATEK_INFRACFG_H
44
5+#define MT8195_TOP_AXI_PROT_EN_STA1 0x228
6+#define MT8195_TOP_AXI_PROT_EN_1_STA1 0x258
7+#define MT8195_TOP_AXI_PROT_EN_SET 0x2a0
8+#define MT8195_TOP_AXI_PROT_EN_CLR 0x2a4
9+#define MT8195_TOP_AXI_PROT_EN_1_SET 0x2a8
10+#define MT8195_TOP_AXI_PROT_EN_1_CLR 0x2ac
11+#define MT8195_TOP_AXI_PROT_EN_MM_SET 0x2d4
12+#define MT8195_TOP_AXI_PROT_EN_MM_CLR 0x2d8
13+#define MT8195_TOP_AXI_PROT_EN_MM_STA1 0x2ec
14+#define MT8195_TOP_AXI_PROT_EN_2_SET 0x714
15+#define MT8195_TOP_AXI_PROT_EN_2_CLR 0x718
16+#define MT8195_TOP_AXI_PROT_EN_2_STA1 0x724
17+#define MT8195_TOP_AXI_PROT_EN_VDNR_SET 0xb84
18+#define MT8195_TOP_AXI_PROT_EN_VDNR_CLR 0xb88
19+#define MT8195_TOP_AXI_PROT_EN_VDNR_STA1 0xb90
20+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_SET 0xba4
21+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR 0xba8
22+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1 0xbb0
23+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_SET 0xbb8
24+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_CLR 0xbbc
25+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_STA1 0xbc4
26+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET 0xbcc
27+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR 0xbd0
28+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1 0xbd8
29+#define MT8195_TOP_AXI_PROT_EN_MM_2_SET 0xdcc
30+#define MT8195_TOP_AXI_PROT_EN_MM_2_CLR 0xdd0
31+#define MT8195_TOP_AXI_PROT_EN_MM_2_STA1 0xdd8
32+
33+#define MT8195_TOP_AXI_PROT_EN_VDOSYS0 BIT(6)
34+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0 BIT(10)
35+#define MT8195_TOP_AXI_PROT_EN_MFG1 BIT(11)
36+#define MT8195_TOP_AXI_PROT_EN_MFG1_2ND GENMASK(22, 21)
37+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND BIT(23)
38+#define MT8195_TOP_AXI_PROT_EN_1_MFG1 GENMASK(20, 19)
39+#define MT8195_TOP_AXI_PROT_EN_1_CAM BIT(22)
40+#define MT8195_TOP_AXI_PROT_EN_2_CAM BIT(0)
41+#define MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND GENMASK(6, 5)
42+#define MT8195_TOP_AXI_PROT_EN_2_MFG1 BIT(7)
43+#define MT8195_TOP_AXI_PROT_EN_2_AUDIO (BIT(9) | BIT(11))
44+#define MT8195_TOP_AXI_PROT_EN_2_ADSP (BIT(12) | GENMASK(16, 14))
45+#define MT8195_TOP_AXI_PROT_EN_MM_CAM (BIT(0) | BIT(2) | BIT(4))
46+#define MT8195_TOP_AXI_PROT_EN_MM_IPE BIT(1)
47+#define MT8195_TOP_AXI_PROT_EN_MM_IMG BIT(3)
48+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0 GENMASK(21, 17)
49+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1 GENMASK(8, 5)
50+#define MT8195_TOP_AXI_PROT_EN_MM_VENC (BIT(9) | BIT(11))
51+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1 (BIT(10) | BIT(12))
52+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0 BIT(13)
53+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1 BIT(14)
54+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND BIT(22)
55+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND BIT(23)
56+#define MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND BIT(24)
57+#define MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND BIT(25)
58+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND BIT(26)
59+#define MT8195_TOP_AXI_PROT_EN_MM_WPESYS BIT(27)
60+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND BIT(28)
61+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND BIT(29)
62+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1 GENMASK(31, 30)
63+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND (GENMASK(1, 0) | BIT(4) | BIT(11))
64+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC BIT(2)
65+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1 (BIT(3) | BIT(15))
66+#define MT8195_TOP_AXI_PROT_EN_MM_2_CAM (BIT(5) | BIT(17))
67+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1 (GENMASK(7, 6) | BIT(18))
68+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0 GENMASK(9, 8)
69+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1 BIT(10)
70+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND BIT(12)
71+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND BIT(13)
72+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND BIT(14)
73+#define MT8195_TOP_AXI_PROT_EN_MM_2_IPE BIT(16)
74+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2 BIT(21)
75+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0 BIT(22)
76+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS GENMASK(24, 23)
77+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX BIT(1)
78+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX BIT(2)
79+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0 (BIT(11) | BIT(28))
80+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1 (BIT(12) | BIT(29))
81+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0 BIT(13)
82+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1 BIT(14)
83+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1 (BIT(17) | BIT(19))
84+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0 BIT(20)
85+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0 BIT(21)
86+
587 #define MT8192_TOP_AXI_PROT_EN_STA1 0x228
688 #define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258
789 #define MT8192_TOP_AXI_PROT_EN_SET 0x2a0
@@ -58,6 +140,54 @@ · 50 unmodified lines
58140 #define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13)
59141 #define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21)
60142
143+#define MT8186_TOP_AXI_PROT_EN_SET (0x2A0)
144+#define MT8186_TOP_AXI_PROT_EN_CLR (0x2A4)
145+#define MT8186_TOP_AXI_PROT_EN_STA (0x228)
146+#define MT8186_TOP_AXI_PROT_EN_1_SET (0x2A8)
147+#define MT8186_TOP_AXI_PROT_EN_1_CLR (0x2AC)
148+#define MT8186_TOP_AXI_PROT_EN_1_STA (0x258)
149+#define MT8186_TOP_AXI_PROT_EN_2_SET (0x2B0)
150+#define MT8186_TOP_AXI_PROT_EN_2_CLR (0x2B4)
151+#define MT8186_TOP_AXI_PROT_EN_2_STA (0x26C)
152+#define MT8186_TOP_AXI_PROT_EN_3_SET (0x2B8)
153+#define MT8186_TOP_AXI_PROT_EN_3_CLR (0x2BC)
154+#define MT8186_TOP_AXI_PROT_EN_3_STA (0x2C8)
155+
156+/* MFG1 */
157+#define MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1 (GENMASK(28, 27))
158+#define MT8186_TOP_AXI_PROT_EN_MFG1_STEP2 (GENMASK(22, 21))
159+#define MT8186_TOP_AXI_PROT_EN_MFG1_STEP3 (BIT(25))
160+#define MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4 (BIT(29))
161+/* DIS */
162+#define MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1 (GENMASK(12, 11))
163+#define MT8186_TOP_AXI_PROT_EN_DIS_STEP2 (GENMASK(2, 1) | GENMASK(11, 10))
164+/* IMG */
165+#define MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1 (BIT(23))
166+#define MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2 (BIT(15))
167+/* IPE */
168+#define MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1 (BIT(24))
169+#define MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2 (BIT(16))
170+/* CAM */
171+#define MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1 (GENMASK(22, 21))
172+#define MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2 (GENMASK(14, 13))
173+/* VENC */
174+#define MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1 (BIT(31))
175+#define MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2 (BIT(19))
176+/* VDEC */
177+#define MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1 (BIT(30))
178+#define MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2 (BIT(17))
179+/* WPE */
180+#define MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1 (BIT(17))
181+#define MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2 (BIT(16))
182+/* CONN_ON */
183+#define MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1 (BIT(18))
184+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2 (BIT(14))
185+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3 (BIT(13))
186+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4 (BIT(16))
187+/* ADSP_TOP */
188+#define MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1 (GENMASK(12, 11))
189+#define MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2 (GENMASK(1, 0))
190+
61191 #define MT8183_TOP_AXI_PROT_EN_STA1 0x228
62192 #define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258
63193 #define MT8183_TOP_AXI_PROT_EN_SET 0x2a0
@@ -147,6 +277,9 @@ · 83 unmodified lines
147277 #define INFRA_TOPAXI_PROTECTEN_SET 0x0260
148278 #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
149279
280+#define MT8192_INFRA_CTRL 0x290
281+#define MT8192_INFRA_CTRL_DISABLE_MFG2ACP BIT(9)
282+
150283 #define REG_INFRA_MISC 0xf00
151284 #define F_DDR_4GB_SUPPORT_EN BIT(13)
152285
include/linux/soc/qcom/llcc-qcom.h+7−2
@@ -35,7 +35,12 @@ · 34 unmodified lines
3535 #define LLCC_WRCACHE 31
3636 #define LLCC_CVPFW 32
3737 #define LLCC_CPUSS1 33
38+#define LLCC_CAMEXP0 34
39+#define LLCC_CPUMTE 35
3840 #define LLCC_CPUHWT 36
41+#define LLCC_MDMCLAD2 37
42+#define LLCC_CAMEXP1 38
43+#define LLCC_AENPU 45
3944
4045 /**
4146 * struct llcc_slice_desc - Cache slice descriptor
@@ -83,7 +88,7 @@ struct llcc_edac_reg_data { · 41 unmodified lines
8388 * @bitmap: Bit map to track the active slice ids
8489 * @offsets: Pointer to the bank offsets array
8590 * @ecc_irq: interrupt for llcc cache error detection and reporting
86− * @major_version: Indicates the LLCC major version
91+ * @version: Indicates the LLCC version
8792 */
8893 struct llcc_drv_data {
8994 struct regmap *regmap;
@@ -96,7 +101,7 @@ struct llcc_drv_data { · 6 unmodified lines
96101 unsigned long *bitmap;
97102 u32 *offsets;
98103 int ecc_irq;
99− u32 major_version;
104+ u32 version;
100105 };
101106
102107 #if IS_ENABLED(CONFIG_QCOM_LLCC)
include/linux/soc/qcom/mdt_loader.h+15−2
@@ -10,10 +10,14 @@ · 9 unmodified lines
1010
1111 struct device;
1212 struct firmware;
13+struct qcom_scm_pas_metadata;
1314
1415 #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
1516
1617 ssize_t qcom_mdt_get_size(const struct firmware *fw);
18+int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
19+ const char *fw_name, int pas_id, phys_addr_t mem_phys,
20+ struct qcom_scm_pas_metadata *pas_metadata_ctx);
1721 int qcom_mdt_load(struct device *dev, const struct firmware *fw,
1822 const char *fw_name, int pas_id, void *mem_region,
1923 phys_addr_t mem_phys, size_t mem_size,
@@ -23,7 +27,8 @@ int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, · 3 unmodified lines
2327 const char *fw_name, int pas_id, void *mem_region,
2428 phys_addr_t mem_phys, size_t mem_size,
2529 phys_addr_t *reloc_base);
26−void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len);
30+void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
31+ const char *fw_name, struct device *dev);
2732
2833 #else /* !IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */
2934
@@ -32,6 +37,13 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw) · 2 unmodified lines
3237 return -ENODEV;
3338 }
3439
40+static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
41+ const char *fw_name, int pas_id, phys_addr_t mem_phys,
42+ struct qcom_scm_pas_metadata *pas_metadata_ctx)
43+{
44+ return -ENODEV;
45+}
46+
3547 static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
3648 const char *fw_name, int pas_id,
3749 void *mem_region, phys_addr_t mem_phys,
@@ -51,7 +63,8 @@ static inline int qcom_mdt_load_no_init(struct device *dev, · 13 unmodified lines
5163 }
5264
5365 static inline void *qcom_mdt_read_metadata(const struct firmware *fw,
54− size_t *data_len)
66+ size_t *data_len, const char *fw_name,
67+ struct device *dev)
5568 {
5669 return ERR_PTR(-ENODEV);
5770 }
include/linux/soc/ti/ti_sci_protocol.h+1−1
@@ -645,7 +645,7 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, · 644 unmodified lines
645645
646646 static inline struct ti_sci_resource *
647647 devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
648− u32 dev_id, u32 sub_type);
648+ u32 dev_id, u32 sub_type)
649649 {
650650 return ERR_PTR(-EINVAL);
651651 }
include/linux/tee_drv.h+31−107
@@ -1,6 +1,6 @@
11 /* SPDX-License-Identifier: GPL-2.0-only */
22 /*
3− * Copyright (c) 2015-2016, Linaro Limited
3+ * Copyright (c) 2015-2022 Linaro Limited
44 */
55
66 #ifndef __TEE_DRV_H
@@ -20,14 +20,11 @@ · 13 unmodified lines
2020 * specific TEE driver.
2121 */
2222
23−#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */
24−#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */
25−#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */
26−#define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */
27−#define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */
28−#define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */
29−#define TEE_SHM_KERNEL_MAPPED BIT(6) /* Memory mapped in kernel space */
30−#define TEE_SHM_PRIV BIT(7) /* Memory private to TEE driver */
23+#define TEE_SHM_DYNAMIC BIT(0) /* Dynamic shared memory registered */
24+ /* in secure world */
25+#define TEE_SHM_USER_MAPPED BIT(1) /* Memory mapped in user space */
26+#define TEE_SHM_POOL BIT(2) /* Memory allocated from pool */
27+#define TEE_SHM_PRIV BIT(3) /* Memory private to TEE driver */
3128
3229 struct device;
3330 struct tee_device;
@@ -221,92 +218,39 @@ struct tee_shm { · 187 unmodified lines
221218 };
222219
223220 /**
224− * struct tee_shm_pool_mgr - shared memory manager
221+ * struct tee_shm_pool - shared memory pool
225222 * @ops: operations
226223 * @private_data: private data for the shared memory manager
227224 */
228−struct tee_shm_pool_mgr {
229− const struct tee_shm_pool_mgr_ops *ops;
225+struct tee_shm_pool {
226+ const struct tee_shm_pool_ops *ops;
230227 void *private_data;
231228 };
232229
233230 /**
234− * struct tee_shm_pool_mgr_ops - shared memory pool manager operations
231+ * struct tee_shm_pool_ops - shared memory pool operations
235232 * @alloc: called when allocating shared memory
236233 * @free: called when freeing shared memory
237− * @destroy_poolmgr: called when destroying the pool manager
234+ * @destroy_pool: called when destroying the pool
238235 */
239−struct tee_shm_pool_mgr_ops {
240− int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm,
241− size_t size);
242− void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm);
243− void (*destroy_poolmgr)(struct tee_shm_pool_mgr *poolmgr);
236+struct tee_shm_pool_ops {
237+ int (*alloc)(struct tee_shm_pool *pool, struct tee_shm *shm,
238+ size_t size, size_t align);
239+ void (*free)(struct tee_shm_pool *pool, struct tee_shm *shm);
240+ void (*destroy_pool)(struct tee_shm_pool *pool);
244241 };
245242
246−/**
247− * tee_shm_pool_alloc() - Create a shared memory pool from shm managers
248− * @priv_mgr: manager for driver private shared memory allocations
249− * @dmabuf_mgr: manager for dma-buf shared memory allocations
250− *
251− * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
252− * in @dmabuf, others will use the range provided by @priv.
253− *
254− * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
255− */
256−struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr,
257− struct tee_shm_pool_mgr *dmabuf_mgr);
258−
259243 /*
260− * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved
261− * memory
244+ * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory
262245 * @vaddr: Virtual address of start of pool
263246 * @paddr: Physical address of start of pool
264247 * @size: Size in bytes of the pool
265248 *
266− * @returns pointer to a 'struct tee_shm_pool_mgr' or an ERR_PTR on failure.
267− */
268−struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr,
269− phys_addr_t paddr,
270− size_t size,
271− int min_alloc_order);
272−
273−/**
274− * tee_shm_pool_mgr_destroy() - Free a shared memory manager
275− */
276−static inline void tee_shm_pool_mgr_destroy(struct tee_shm_pool_mgr *poolm)
277−{
278− poolm->ops->destroy_poolmgr(poolm);
279−}
280−
281−/**
282− * struct tee_shm_pool_mem_info - holds information needed to create a shared
283− * memory pool
284− * @vaddr: Virtual address of start of pool
285− * @paddr: Physical address of start of pool
286− * @size: Size in bytes of the pool
287− */
288−struct tee_shm_pool_mem_info {
289− unsigned long vaddr;
290− phys_addr_t paddr;
291− size_t size;
292−};
293−
294−/**
295− * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved
296− * memory range
297− * @priv_info: Information for driver private shared memory pool
298− * @dmabuf_info: Information for dma-buf shared memory pool
299− *
300− * Start and end of pools will must be page aligned.
301− *
302− * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
303− * in @dmabuf, others will use the range provided by @priv.
304− *
305249 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
306250 */
307−struct tee_shm_pool *
308−tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info *priv_info,
309− struct tee_shm_pool_mem_info *dmabuf_info);
251+struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
252+ phys_addr_t paddr, size_t size,
253+ int min_alloc_order);
310254
311255 /**
312256 * tee_shm_pool_free() - Free a shared memory pool
@@ -315,7 +259,10 @@ tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info *priv_info, · 2 unmodified lines
315259 * The must be no remaining shared memory allocated from this pool when
316260 * this function is called.
317261 */
318−void tee_shm_pool_free(struct tee_shm_pool *pool);
262+static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
263+{
264+ pool->ops->destroy_pool(pool);
265+}
319266
320267 /**
321268 * tee_get_drvdata() - Return driver_data pointer
@@ -323,43 +270,20 @@ void tee_shm_pool_free(struct tee_shm_pool *pool); · 1 unmodified line
323270 */
324271 void *tee_get_drvdata(struct tee_device *teedev);
325272
326−/**
327− * tee_shm_alloc() - Allocate shared memory
328− * @ctx: Context that allocates the shared memory
329− * @size: Requested size of shared memory
330− * @flags: Flags setting properties for the requested shared memory.
331− *
332− * Memory allocated as global shared memory is automatically freed when the
333− * TEE file pointer is closed. The @flags field uses the bits defined by
334− * TEE_SHM_* above. TEE_SHM_MAPPED must currently always be set. If
335− * TEE_SHM_DMA_BUF global shared memory will be allocated and associated
336− * with a dma-buf handle, else driver private memory.
337− *
338− * @returns a pointer to 'struct tee_shm'
339− */
340−struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
273+struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
341274 struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
342275
343−/**
344− * tee_shm_register() - Register shared memory buffer
345− * @ctx: Context that registers the shared memory
346− * @addr: Address is userspace of the shared buffer
347− * @length: Length of the shared buffer
348− * @flags: Flags setting properties for the requested shared memory.
349− *
350− * @returns a pointer to 'struct tee_shm'
351− */
352−struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
353− size_t length, u32 flags);
276+struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
277+ void *addr, size_t length);
354278
355279 /**
356− * tee_shm_is_registered() - Check if shared memory object in registered in TEE
280+ * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
357281 * @shm: Shared memory handle
358− * @returns true if object is registered in TEE
282+ * @returns true if object is dynamic shared memory
359283 */
360−static inline bool tee_shm_is_registered(struct tee_shm *shm)
284+static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
361285 {
362− return shm && (shm->flags & TEE_SHM_REGISTER);
286+ return shm && (shm->flags & TEE_SHM_DYNAMIC);
363287 }
364288
365289 /**
include/soc/tegra/bpmp-abi.h+1−1
@@ -931,7 +931,7 @@ enum mrq_reset_commands { · 930 unmodified lines
931931 * @brief Request with MRQ_RESET
932932 *
933933 * Used by the sender of an #MRQ_RESET message to request BPMP to
934− * assert or or deassert a given reset line.
934+ * assert or deassert a given reset line.
935935 */
936936 struct mrq_reset_request {
937937 /** @brief Reset action to perform (@ref mrq_reset_commands) */
include/trace/events/scmi.h+28−0
@@ -33,6 +33,34 @@ TRACE_EVENT(scmi_xfer_begin, · 32 unmodified lines
3333 __entry->seq, __entry->poll)
3434 );
3535
36+TRACE_EVENT(scmi_xfer_response_wait,
37+ TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
38+ u32 timeout, bool poll),
39+ TP_ARGS(transfer_id, msg_id, protocol_id, seq, timeout, poll),
40+
41+ TP_STRUCT__entry(
42+ __field(int, transfer_id)
43+ __field(u8, msg_id)
44+ __field(u8, protocol_id)
45+ __field(u16, seq)
46+ __field(u32, timeout)
47+ __field(bool, poll)
48+ ),
49+
50+ TP_fast_assign(
51+ __entry->transfer_id = transfer_id;
52+ __entry->msg_id = msg_id;
53+ __entry->protocol_id = protocol_id;
54+ __entry->seq = seq;
55+ __entry->timeout = timeout;
56+ __entry->poll = poll;
57+ ),
58+
59+ TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u tmo_ms=%u poll=%u",
60+ __entry->transfer_id, __entry->msg_id, __entry->protocol_id,
61+ __entry->seq, __entry->timeout, __entry->poll)
62+);
63+
3664 TRACE_EVENT(scmi_xfer_end,
3765 TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
3866 int status),
security/keys/trusted-keys/trusted_tee.c+9−14
@@ -70,17 +70,15 @@ static int trusted_tee_seal(struct trusted_key_payload *p, char *datablob) · 69 unmodified lines
7070 memset(&inv_arg, 0, sizeof(inv_arg));
7171 memset(&param, 0, sizeof(param));
7272
73− reg_shm_in = tee_shm_register(pvt_data.ctx, (unsigned long)p->key,
74− p->key_len, TEE_SHM_DMA_BUF |
75− TEE_SHM_KERNEL_MAPPED);
73+ reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
74+ p->key_len);
7675 if (IS_ERR(reg_shm_in)) {
7776 dev_err(pvt_data.dev, "key shm register failed\n");
7877 return PTR_ERR(reg_shm_in);
7978 }
8079
81− reg_shm_out = tee_shm_register(pvt_data.ctx, (unsigned long)p->blob,
82− sizeof(p->blob), TEE_SHM_DMA_BUF |
83− TEE_SHM_KERNEL_MAPPED);
80+ reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
81+ sizeof(p->blob));
8482 if (IS_ERR(reg_shm_out)) {
8583 dev_err(pvt_data.dev, "blob shm register failed\n");
8684 ret = PTR_ERR(reg_shm_out);
@@ -131,17 +129,15 @@ static int trusted_tee_unseal(struct trusted_key_payload *p, char *datablob) · 44 unmodified lines
131129 memset(&inv_arg, 0, sizeof(inv_arg));
132130 memset(&param, 0, sizeof(param));
133131
134− reg_shm_in = tee_shm_register(pvt_data.ctx, (unsigned long)p->blob,
135− p->blob_len, TEE_SHM_DMA_BUF |
136− TEE_SHM_KERNEL_MAPPED);
132+ reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
133+ p->blob_len);
137134 if (IS_ERR(reg_shm_in)) {
138135 dev_err(pvt_data.dev, "blob shm register failed\n");
139136 return PTR_ERR(reg_shm_in);
140137 }
141138
142− reg_shm_out = tee_shm_register(pvt_data.ctx, (unsigned long)p->key,
143− sizeof(p->key), TEE_SHM_DMA_BUF |
144− TEE_SHM_KERNEL_MAPPED);
139+ reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
140+ sizeof(p->key));
145141 if (IS_ERR(reg_shm_out)) {
146142 dev_err(pvt_data.dev, "key shm register failed\n");
147143 ret = PTR_ERR(reg_shm_out);
@@ -192,8 +188,7 @@ static int trusted_tee_get_random(unsigned char *key, size_t key_len) · 44 unmodified lines
192188 memset(&inv_arg, 0, sizeof(inv_arg));
193189 memset(&param, 0, sizeof(param));
194190
195− reg_shm = tee_shm_register(pvt_data.ctx, (unsigned long)key, key_len,
196− TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED);
191+ reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, key, key_len);
197192 if (IS_ERR(reg_shm)) {
198193 dev_err(pvt_data.dev, "key shm register failed\n");
199194 return PTR_ERR(reg_shm);