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
29 - mediatek,mt8167-mmsys29 - mediatek,mt8167-mmsys
30 - mediatek,mt8173-mmsys30 - mediatek,mt8173-mmsys
31 - mediatek,mt8183-mmsys31 - mediatek,mt8183-mmsys
32 - mediatek,mt8186-mmsys
32 - mediatek,mt8192-mmsys33 - mediatek,mt8192-mmsys
33 - mediatek,mt8365-mmsys34 - mediatek,mt8365-mmsys
34 - const: syscon35 - const: syscon
Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml+2−0
@@ -27,6 +27,8 @@ properties: · 26 unmodified lines
27 - qcom,sm6350-llcc27 - qcom,sm6350-llcc
28 - qcom,sm8150-llcc28 - qcom,sm8150-llcc
29 - qcom,sm8250-llcc29 - qcom,sm8250-llcc
30 - qcom,sm8350-llcc
31 - qcom,sm8450-llcc
30 32
31 reg:33 reg:
32 items:34 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
7title: Tesla FSD (Full Self-Driving) SoC clock controller
8
9maintainers:
10 - Alim Akhtar <alim.akhtar@samsung.com>
11 - linux-fsd@tesla.com
12
13description: |
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
21properties:
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
46allOf:
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
171required:
172 - compatible
173 - "#clock-cells"
174 - clocks
175 - clock-names
176 - reg
177
178additionalProperties: false
179
180examples:
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
38 The virtio transport only supports a single device.38 The virtio transport only supports a single device.
39 items:39 items:
40 - const: arm,scmi-virtio40 - const: arm,scmi-virtio
41 - description: SCMI compliant firmware with OP-TEE transport
42 items:
43 - const: linaro,scmi-optee
41 44
42 interrupts:45 interrupts:
43 description:46 description:
@@ -78,11 +81,24 @@ properties: · 34 unmodified lines
78 '#size-cells':81 '#size-cells':
79 const: 082 const: 0
80 83
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
81 arm,smc-id:92 arm,smc-id:
82 $ref: /schemas/types.yaml#/definitions/uint3293 $ref: /schemas/types.yaml#/definitions/uint32
83 description:94 description:
84 SMC id required when using smc or hvc transports95 SMC id required when using smc or hvc transports
85 96
97 linaro,optee-channel-id:
98 $ref: /schemas/types.yaml#/definitions/uint32
99 description:
100 Channel specifier required when using OP-TEE transport.
101
86 protocol@11:102 protocol@11:
87 type: object103 type: object
88 properties:104 properties:
@@ -195,6 +211,12 @@ patternProperties: · 106 unmodified lines
195 minItems: 1211 minItems: 1
196 maxItems: 2212 maxItems: 2
197 213
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
198 required:220 required:
199 - reg221 - reg
200 222
@@ -226,6 +248,16 @@ else: · 25 unmodified lines
226 - arm,smc-id248 - arm,smc-id
227 - shmem249 - shmem
228 250
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
229examples:261examples:
230 - |262 - |
231 firmware {263 firmware {
@@ -240,6 +272,8 @@ examples: · 8 unmodified lines
240 #address-cells = <1>;272 #address-cells = <1>;
241 #size-cells = <0>;273 #size-cells = <0>;
242 274
275 atomic-threshold-us = <10000>;
276
243 scmi_devpd: protocol@11 {277 scmi_devpd: protocol@11 {
244 reg = <0x11>;278 reg = <0x11>;
245 #power-domain-cells = <1>;279 #power-domain-cells = <1>;
@@ -340,7 +374,48 @@ examples: · 94 unmodified lines
340 reg = <0x11>;374 reg = <0x11>;
341 #power-domain-cells = <1>;375 #power-domain-cells = <1>;
342 };376 };
377 };
378 };
379
380 - |
381 firmware {
382 scmi {
383 compatible = "linaro,scmi-optee";
384 linaro,optee-channel-id = <0>;
343 385
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 };
344 };419 };
345 };420 };
346 421
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
7title: LPDDR2 SDRAM AC timing parameters for a given speed-bin
8
9maintainers:
10 - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11
12properties:
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
107required:
108 - compatible
109 - min-freq
110 - max-freq
111
112additionalProperties: false
113
114examples:
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
30 maximum: 25530 maximum: 255
31 description: |31 description: |
32 Revision 1 value of SDRAM chip. Obtained from device datasheet.32 Revision 1 value of SDRAM chip. Obtained from device datasheet.
33 Property is deprecated, use revision-id instead.
34 deprecated: true
33 35
34 revision-id2:36 revision-id2:
35 $ref: /schemas/types.yaml#/definitions/uint3237 $ref: /schemas/types.yaml#/definitions/uint32
36 maximum: 25538 maximum: 255
37 description: |39 description: |
38 Revision 2 value of SDRAM chip. Obtained from device datasheet.40 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
39 53
40 density:54 density:
41 $ref: /schemas/types.yaml#/definitions/uint3255 $ref: /schemas/types.yaml#/definitions/uint32
@@ -142,14 +156,12 @@ properties: · 100 unmodified lines
142 156
143patternProperties:157patternProperties:
144 "^lpddr2-timings":158 "^lpddr2-timings":
145 type: object159 $ref: jedec,lpddr2-timings.yaml
146 description: |160 description: |
147 The lpddr2 node may have one or more child nodes of type "lpddr2-timings".161 The lpddr2 node may have one or more child nodes of type "lpddr2-timings".
148 "lpddr2-timings" provides AC timing parameters of the device for162 "lpddr2-timings" provides AC timing parameters of the device for
149 a given speed-bin. The user may provide the timings for as many163 a given speed-bin. The user may provide the timings for as many
150 speed-bins as is required. Please see Documentation/devicetree/164 speed-bins as is required.
151 bindings/memory-controllers/ddr/lpddr2-timings.txt for more information
152 on "lpddr2-timings".
153 165
154required:166required:
155 - compatible167 - compatible
@@ -164,8 +176,7 @@ examples: · 8 unmodified lines
164 compatible = "elpida,ECB240ABACN", "jedec,lpddr2-s4";176 compatible = "elpida,ECB240ABACN", "jedec,lpddr2-s4";
165 density = <2048>;177 density = <2048>;
166 io-width = <32>;178 io-width = <32>;
167 revision-id1 = <1>;179 revision-id = <1 0>;
168 revision-id2 = <0>;
169 180
170 tRPab-min-tck = <3>;181 tRPab-min-tck = <3>;
171 tRCD-min-tck = <3>;182 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
7title: LPDDR3 SDRAM AC timing parameters for a given speed-bin
8
9maintainers:
10 - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11
12properties:
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
124required:
125 - compatible
126 - min-freq
127 - max-freq
128
129additionalProperties: false
130
131examples:
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
7title: LPDDR3 SDRAM compliant to JEDEC JESD209-3
8
9maintainers:
10 - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
11
12properties:
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
195patternProperties:
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
204required:
205 - compatible
206 - density
207 - io-width
208
209additionalProperties: false
210
211examples:
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
3Required 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
8Optional properties:
9
10The following properties represent AC timing parameters from the memory
11data-sheet of the device for a given speed-bin. All these properties are
12of type <u32> and the default unit is ps (pico seconds). Parameters with
13a 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
31Example:
32
33timings_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
3The structures are based on LPDDR2 and extended where needed.
4
5Required 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
10Optional properties:
11
12The following properties represent AC timing parameters from the memory
13data-sheet of the device for a given speed-bin. All these properties are
14of 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
34Example:
35
36timings_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
3Required 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
13Optional 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
18The following optional properties represent the minimum value of some AC
19timing parameters of the DDR device in terms of number of clock cycles.
20These 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
43Child 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
50Example:
51
52samsung_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
7title: FSL/NXP Integrated Flash Controller
8
9maintainers:
10 - Li Yang <leoyang.li@nxp.com>
11
12description: |
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
19properties:
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
60patternProperties:
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
72required:
73 - compatible
74 - reg
75 - interrupts
76
77additionalProperties: false
78
79examples:
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 @@
1Integrated Flash Controller
2
3Properties:
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
27Child device nodes describe the devices connected to IFC such as NOR (e.g.
28cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
29like FPGAs, CPLDs, etc.
30
31Example:
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
16 MediaTek SMI have two generations of HW architecture, here is the list16 MediaTek SMI have two generations of HW architecture, here is the list
17 which generation the SoCs use:17 which generation the SoCs use:
18 generation 1: mt2701 and mt7623.18 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.
20 20
21 There's slight differences between the two SMI, for generation 2, the21 There's slight differences between the two SMI, for generation 2, the
22 register which control the iommu port is at each larb's register base. But22 register which control the iommu port is at each larb's register base. But
@@ -35,6 +35,7 @@ properties: · 12 unmodified lines
35 - mediatek,mt8167-smi-common35 - mediatek,mt8167-smi-common
36 - mediatek,mt8173-smi-common36 - mediatek,mt8173-smi-common
37 - mediatek,mt8183-smi-common37 - mediatek,mt8183-smi-common
38 - mediatek,mt8186-smi-common
38 - mediatek,mt8192-smi-common39 - mediatek,mt8192-smi-common
39 - mediatek,mt8195-smi-common-vdo40 - mediatek,mt8195-smi-common-vdo
40 - mediatek,mt8195-smi-common-vpp41 - mediatek,mt8195-smi-common-vpp
@@ -88,10 +89,9 @@ allOf: · 47 unmodified lines
88 - mediatek,mt2701-smi-common89 - mediatek,mt2701-smi-common
89 then:90 then:
90 properties:91 properties:
91 clock:92 clocks:
92 items:93 minItems: 3
93 minItems: 394 maxItems: 3
94 maxItems: 3
95 clock-names:95 clock-names:
96 items:96 items:
97 - const: apb97 - const: apb
@@ -108,10 +108,9 @@ allOf: · 10 unmodified lines
108 required:108 required:
109 - mediatek,smi109 - mediatek,smi
110 properties:110 properties:
111 clock:111 clocks:
112 items:112 minItems: 3
113 minItems: 3113 maxItems: 3
114 maxItems: 3
115 clock-names:114 clock-names:
116 items:115 items:
117 - const: apb116 - const: apb
@@ -127,16 +126,16 @@ allOf: · 9 unmodified lines
127 enum:126 enum:
128 - mediatek,mt6779-smi-common127 - mediatek,mt6779-smi-common
129 - mediatek,mt8183-smi-common128 - mediatek,mt8183-smi-common
129 - mediatek,mt8186-smi-common
130 - mediatek,mt8192-smi-common130 - mediatek,mt8192-smi-common
131 - mediatek,mt8195-smi-common-vdo131 - mediatek,mt8195-smi-common-vdo
132 - mediatek,mt8195-smi-common-vpp132 - mediatek,mt8195-smi-common-vpp
133 133
134 then:134 then:
135 properties:135 properties:
136 clock:136 clocks:
137 items:137 minItems: 4
138 minItems: 4138 maxItems: 4
139 maxItems: 4
140 clock-names:139 clock-names:
141 items:140 items:
142 - const: apb141 - const: apb
@@ -146,10 +145,9 @@ allOf: · 3 unmodified lines
146 145
147 else: # for gen2 HW that don't have gals146 else: # for gen2 HW that don't have gals
148 properties:147 properties:
149 clock:148 clocks:
150 items:149 minItems: 2
151 minItems: 2150 maxItems: 2
152 maxItems: 2
153 clock-names:151 clock-names:
154 items:152 items:
155 - const: apb153 - const: apb
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml+10−9
@@ -23,6 +23,7 @@ properties: · 22 unmodified lines
23 - mediatek,mt8167-smi-larb23 - mediatek,mt8167-smi-larb
24 - mediatek,mt8173-smi-larb24 - mediatek,mt8173-smi-larb
25 - mediatek,mt8183-smi-larb25 - mediatek,mt8183-smi-larb
26 - mediatek,mt8186-smi-larb
26 - mediatek,mt8192-smi-larb27 - mediatek,mt8192-smi-larb
27 - mediatek,mt8195-smi-larb28 - mediatek,mt8195-smi-larb
28 29
@@ -75,15 +76,16 @@ allOf: · 46 unmodified lines
75 compatible:76 compatible:
76 enum:77 enum:
77 - mediatek,mt8183-smi-larb78 - mediatek,mt8183-smi-larb
79 - mediatek,mt8186-smi-larb
78 - mediatek,mt8195-smi-larb80 - mediatek,mt8195-smi-larb
79 81
80 then:82 then:
81 properties:83 properties:
82 clock:84 clocks:
83 items:85 minItems: 2
84 minItems: 386 maxItems: 3
85 maxItems: 3
86 clock-names:87 clock-names:
88 minItems: 2
87 items:89 items:
88 - const: apb90 - const: apb
89 - const: smi91 - const: smi
@@ -91,10 +93,9 @@ allOf: · 1 unmodified line
91 93
92 else:94 else:
93 properties:95 properties:
94 clock:96 clocks:
95 items:97 minItems: 2
96 minItems: 298 maxItems: 2
97 maxItems: 2
98 clock-names:99 clock-names:
99 items:100 items:
100 - const: apb101 - const: apb
@@ -108,7 +109,7 @@ allOf: · 7 unmodified lines
108 - mediatek,mt2701-smi-larb109 - mediatek,mt2701-smi-larb
109 - mediatek,mt2712-smi-larb110 - mediatek,mt2712-smi-larb
110 - mediatek,mt6779-smi-larb111 - mediatek,mt6779-smi-larb
111 - mediatek,mt8167-smi-larb112 - mediatek,mt8186-smi-larb
112 - mediatek,mt8192-smi-larb113 - mediatek,mt8192-smi-larb
113 - mediatek,mt8195-smi-larb114 - mediatek,mt8195-smi-larb
114 115
Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml+2−1
@@ -40,7 +40,8 @@ properties: · 39 unmodified lines
40 - items:40 - items:
41 - enum:41 - enum:
42 - renesas,r9a07g044-rpc-if # RZ/G2{L,LC}42 - renesas,r9a07g044-rpc-if # RZ/G2{L,LC}
43 - const: renesas,rzg2l-rpc-if # RZ/G2L family43 - renesas,r9a07g054-rpc-if # RZ/V2L
44 - const: renesas,rzg2l-rpc-if
44 45
45 reg:46 reg:
46 items:47 items:
Documentation/devicetree/bindings/memory-controllers/samsung,exynos5422-dmc.yaml+1−2
@@ -51,8 +51,7 @@ properties: · 50 unmodified lines
51 $ref: '/schemas/types.yaml#/definitions/phandle'51 $ref: '/schemas/types.yaml#/definitions/phandle'
52 description: |52 description: |
53 phandle of the connected DRAM memory device. For more information please53 phandle of the connected DRAM memory device. For more information please
54 refer to documentation file:54 refer to jedec,lpddr3.yaml.
55 Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3.txt
56 55
57 operating-points-v2: true56 operating-points-v2: true
58 57
Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml+2−1
@@ -12,13 +12,14 @@ maintainers: · 11 unmodified lines
12 - Jianxin Pan <jianxin.pan@amlogic.com>12 - Jianxin Pan <jianxin.pan@amlogic.com>
13 13
14description: |+14description: |+
15 Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node15 Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node
16 of secure-monitor.16 of secure-monitor.
17 17
18properties:18properties:
19 compatible:19 compatible:
20 enum:20 enum:
21 - amlogic,meson-a1-pwrc21 - amlogic,meson-a1-pwrc
22 - amlogic,meson-s4-pwrc
22 23
23 "#power-domain-cells":24 "#power-domain-cells":
24 const: 125 const: 1
Documentation/devicetree/bindings/power/mediatek,power-controller.yaml+3−0
@@ -26,7 +26,9 @@ properties: · 25 unmodified lines
26 - mediatek,mt8167-power-controller26 - mediatek,mt8167-power-controller
27 - mediatek,mt8173-power-controller27 - mediatek,mt8173-power-controller
28 - mediatek,mt8183-power-controller28 - mediatek,mt8183-power-controller
29 - mediatek,mt8186-power-controller
29 - mediatek,mt8192-power-controller30 - mediatek,mt8192-power-controller
31 - mediatek,mt8195-power-controller
30 32
31 '#power-domain-cells':33 '#power-domain-cells':
32 const: 134 const: 1
@@ -64,6 +66,7 @@ patternProperties: · 31 unmodified lines
64 "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.66 "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
65 "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.67 "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
66 "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.68 "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.
67 maxItems: 170 maxItems: 1
68 71
69 clocks:72 clocks:
Documentation/devicetree/bindings/power/qcom,rpmpd.yaml+1−0
@@ -17,6 +17,7 @@ properties: · 16 unmodified lines
17 compatible:17 compatible:
18 enum:18 enum:
19 - qcom,mdm9607-rpmpd19 - qcom,mdm9607-rpmpd
20 - qcom,msm8226-rpmpd
20 - qcom,msm8916-rpmpd21 - qcom,msm8916-rpmpd
21 - qcom,msm8939-rpmpd22 - qcom,msm8939-rpmpd
22 - qcom,msm8953-rpmpd23 - qcom,msm8953-rpmpd
Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml+16−0
@@ -47,6 +47,10 @@ properties: · 46 unmodified lines
47 - qcom,sm8350-cdsp-pas47 - qcom,sm8350-cdsp-pas
48 - qcom,sm8350-slpi-pas48 - qcom,sm8350-slpi-pas
49 - qcom,sm8350-mpss-pas49 - qcom,sm8350-mpss-pas
50 - qcom,sm8450-adsp-pas
51 - qcom,sm8450-cdsp-pas
52 - qcom,sm8450-mpss-pas
53 - qcom,sm8450-slpi-pas
50 54
51 reg:55 reg:
52 maxItems: 156 maxItems: 1
@@ -175,6 +179,10 @@ allOf: · 122 unmodified lines
175 - qcom,sm8350-cdsp-pas179 - qcom,sm8350-cdsp-pas
176 - qcom,sm8350-slpi-pas180 - qcom,sm8350-slpi-pas
177 - qcom,sm8350-mpss-pas181 - qcom,sm8350-mpss-pas
182 - qcom,sm8450-adsp-pas
183 - qcom,sm8450-cdsp-pas
184 - qcom,sm8450-slpi-pas
185 - qcom,sm8450-mpss-pas
178 then:186 then:
179 properties:187 properties:
180 clocks:188 clocks:
@@ -283,6 +291,9 @@ allOf: · 102 unmodified lines
283 - qcom,sm8350-adsp-pas291 - qcom,sm8350-adsp-pas
284 - qcom,sm8350-cdsp-pas292 - qcom,sm8350-cdsp-pas
285 - qcom,sm8350-slpi-pas293 - qcom,sm8350-slpi-pas
294 - qcom,sm8450-adsp-pas
295 - qcom,sm8450-cdsp-pas
296 - qcom,sm8450-slpi-pas
286 then:297 then:
287 properties:298 properties:
288 interrupts:299 interrupts:
@@ -312,6 +323,7 @@ allOf: · 23 unmodified lines
312 - qcom,sm6350-mpss-pas323 - qcom,sm6350-mpss-pas
313 - qcom,sm8150-mpss-pas324 - qcom,sm8150-mpss-pas
314 - qcom,sm8350-mpss-pas325 - qcom,sm8350-mpss-pas
326 - qcom,sm8450-mpss-pas
315 then:327 then:
316 properties:328 properties:
317 interrupts:329 interrupts:
@@ -434,6 +446,7 @@ allOf: · 116 unmodified lines
434 - qcom,sm6350-mpss-pas446 - qcom,sm6350-mpss-pas
435 - qcom,sm8150-mpss-pas447 - qcom,sm8150-mpss-pas
436 - qcom,sm8350-mpss-pas448 - qcom,sm8350-mpss-pas
449 - qcom,sm8450-mpss-pas
437 then:450 then:
438 properties:451 properties:
439 power-domains:452 power-domains:
@@ -458,6 +471,8 @@ allOf: · 18 unmodified lines
458 - qcom,sm8250-slpi-pas471 - qcom,sm8250-slpi-pas
459 - qcom,sm8350-adsp-pas472 - qcom,sm8350-adsp-pas
460 - qcom,sm8350-slpi-pas473 - qcom,sm8350-slpi-pas
474 - qcom,sm8450-adsp-pas
475 - qcom,sm8450-slpi-pas
461 then:476 then:
462 properties:477 properties:
463 power-domains:478 power-domains:
@@ -475,6 +490,7 @@ allOf: · 11 unmodified lines
475 contains:490 contains:
476 enum:491 enum:
477 - qcom,sm8350-cdsp-pas492 - qcom,sm8350-cdsp-pas
493 - qcom,sm8450-cdsp-pas
478 then:494 then:
479 properties:495 properties:
480 power-domains:496 power-domains:
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt+1−0
@@ -27,6 +27,7 @@ Required properties in pwrap device node. · 26 unmodified lines
27 "mediatek,mt8135-pwrap" for MT8135 SoCs27 "mediatek,mt8135-pwrap" for MT8135 SoCs
28 "mediatek,mt8173-pwrap" for MT8173 SoCs28 "mediatek,mt8173-pwrap" for MT8173 SoCs
29 "mediatek,mt8183-pwrap" for MT8183 SoCs29 "mediatek,mt8183-pwrap" for MT8183 SoCs
30 "mediatek,mt8186-pwrap" for MT8186 SoCs
30 "mediatek,mt8195-pwrap" for MT8195 SoCs31 "mediatek,mt8195-pwrap" for MT8195 SoCs
31 "mediatek,mt8516-pwrap" for MT8516 SoCs32 "mediatek,mt8516-pwrap" for MT8516 SoCs
32- interrupts: IRQ for pwrap in SOC33- 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
357{357{
358 int cpu;358 int cpu;
359 359
360 if (qcom_scm_set_cold_boot_addr(secondary_startup_arm,360 if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) {
361 cpu_present_mask)) {
362 for_each_present_cpu(cpu) {361 for_each_present_cpu(cpu) {
363 if (cpu == smp_processor_id())362 if (cpu == smp_processor_id())
364 continue;363 continue;
arch/arm/mach-spear/spear13xx.c+1−1
@@ -29,7 +29,7 @@ void __init spear13xx_l2x0_init(void) · 28 unmodified lines
29 /*29 /*
30 * 512KB (64KB/way), 8-way associativity, parity supported30 * 512KB (64KB/way), 8-way associativity, parity supported
31 *31 *
32 * FIXME: 9th bit, of Auxillary Controller register must be set32 * FIXME: 9th bit, of Auxiliary Controller register must be set
33 * for some spear13xx devices for stable L2 operation.33 * for some spear13xx devices for stable L2 operation.
34 *34 *
35 * Enable Early BRESP, L2 prefetch for Instruction and Data,35 * 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
64 struct cs_timing cs[MAX_CS_COUNT];64 struct cs_timing cs[MAX_CS_COUNT];
65};65};
66 66
67struct weim_priv {
68 void __iomem *base;
69 struct cs_timing_state timing_state;
70};
71
67static const struct of_device_id weim_id_table[] = {72static const struct of_device_id weim_id_table[] = {
68 /* i.MX1/21 */73 /* i.MX1/21 */
69 { .compatible = "fsl,imx1-weim", .data = &imx1_weim_devtype, },74 { .compatible = "fsl,imx1-weim", .data = &imx1_weim_devtype, },
@@ -128,21 +133,26 @@ err: · 58 unmodified lines
128}133}
129 134
130/* Parse and set the timing for this device. */135/* Parse and set the timing for this device. */
131static int weim_timing_setup(struct device *dev,136static int weim_timing_setup(struct device *dev, struct device_node *np,
132 struct device_node *np, void __iomem *base,137 const struct imx_weim_devtype *devtype)
133 const struct imx_weim_devtype *devtype,
134 struct cs_timing_state *ts)
135{138{
136 u32 cs_idx, value[MAX_CS_REGS_COUNT];139 u32 cs_idx, value[MAX_CS_REGS_COUNT];
137 int i, ret;140 int i, ret;
138 int reg_idx, num_regs;141 int reg_idx, num_regs;
139 struct cs_timing *cst;142 struct cs_timing *cst;
143 struct weim_priv *priv;
144 struct cs_timing_state *ts;
145 void __iomem *base;
140 146
141 if (WARN_ON(devtype->cs_regs_count > MAX_CS_REGS_COUNT))147 if (WARN_ON(devtype->cs_regs_count > MAX_CS_REGS_COUNT))
142 return -EINVAL;148 return -EINVAL;
143 if (WARN_ON(devtype->cs_count > MAX_CS_COUNT))149 if (WARN_ON(devtype->cs_count > MAX_CS_COUNT))
144 return -EINVAL;150 return -EINVAL;
145 151
152 priv = dev_get_drvdata(dev);
153 base = priv->base;
154 ts = &priv->timing_state;
155
146 ret = of_property_read_u32_array(np, "fsl,weim-cs-timing",156 ret = of_property_read_u32_array(np, "fsl,weim-cs-timing",
147 value, devtype->cs_regs_count);157 value, devtype->cs_regs_count);
148 if (ret)158 if (ret)
@@ -189,14 +199,15 @@ static int weim_timing_setup(struct device *dev, · 40 unmodified lines
189 return 0;199 return 0;
190}200}
191 201
192static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)202static int weim_parse_dt(struct platform_device *pdev)
193{203{
194 const struct of_device_id *of_id = of_match_device(weim_id_table,204 const struct of_device_id *of_id = of_match_device(weim_id_table,
195 &pdev->dev);205 &pdev->dev);
196 const struct imx_weim_devtype *devtype = of_id->data;206 const struct imx_weim_devtype *devtype = of_id->data;
197 struct device_node *child;207 struct device_node *child;
198 int ret, have_child = 0;208 int ret, have_child = 0;
199 struct cs_timing_state ts = {};209 struct weim_priv *priv;
210 void __iomem *base;
200 u32 reg;211 u32 reg;
201 212
202 if (devtype == &imx50_weim_devtype) {213 if (devtype == &imx50_weim_devtype) {
@@ -205,6 +216,9 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) · 2 unmodified lines
205 return ret;216 return ret;
206 }217 }
207 218
219 priv = dev_get_drvdata(&pdev->dev);
220 base = priv->base;
221
208 if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) {222 if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) {
209 if (devtype->wcr_bcm) {223 if (devtype->wcr_bcm) {
210 reg = readl(base + devtype->wcr_offset);224 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
229 }243 }
230 244
231 for_each_available_child_of_node(pdev->dev.of_node, child) {245 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);
233 if (ret)247 if (ret)
234 dev_warn(&pdev->dev, "%pOF set timing failed.\n",248 dev_warn(&pdev->dev, "%pOF set timing failed.\n",
235 child);249 child);
@@ -248,17 +262,25 @@ static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) · 12 unmodified lines
248 262
249static int weim_probe(struct platform_device *pdev)263static int weim_probe(struct platform_device *pdev)
250{264{
265 struct weim_priv *priv;
251 struct resource *res;266 struct resource *res;
252 struct clk *clk;267 struct clk *clk;
253 void __iomem *base;268 void __iomem *base;
254 int ret;269 int ret;
255 270
271 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
272 if (!priv)
273 return -ENOMEM;
274
256 /* get the resource */275 /* get the resource */
257 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);276 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258 base = devm_ioremap_resource(&pdev->dev, res);277 base = devm_ioremap_resource(&pdev->dev, res);
259 if (IS_ERR(base))278 if (IS_ERR(base))
260 return PTR_ERR(base);279 return PTR_ERR(base);
261 280
281 priv->base = base;
282 dev_set_drvdata(&pdev->dev, priv);
283
262 /* get the clock */284 /* get the clock */
263 clk = devm_clk_get(&pdev->dev, NULL);285 clk = devm_clk_get(&pdev->dev, NULL);
264 if (IS_ERR(clk))286 if (IS_ERR(clk))
@@ -269,7 +291,7 @@ static int weim_probe(struct platform_device *pdev) · 4 unmodified lines
269 return ret;291 return ret;
270 292
271 /* parse the device node */293 /* parse the device node */
272 ret = weim_parse_dt(pdev, base);294 ret = weim_parse_dt(pdev);
273 if (ret)295 if (ret)
274 clk_disable_unprepare(clk);296 clk_disable_unprepare(clk);
275 else297 else
@@ -278,6 +300,81 @@ static int weim_probe(struct platform_device *pdev) · 2 unmodified lines
278 return ret;300 return ret;
279}301}
280 302
303#if IS_ENABLED(CONFIG_OF_DYNAMIC)
304static 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
373struct notifier_block weim_of_notifier = {
374 .notifier_call = of_weim_notify,
375};
376#endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */
377
281static struct platform_driver weim_driver = {378static struct platform_driver weim_driver = {
282 .driver = {379 .driver = {
283 .name = "imx-weim",380 .name = "imx-weim",
@@ -285,7 +382,27 @@ static struct platform_driver weim_driver = { · 1 unmodified line
285 },382 },
286 .probe = weim_probe,383 .probe = weim_probe,
287};384};
288module_platform_driver(weim_driver);385
386static 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}
394module_init(weim_init);
395
396static 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}
405module_exit(weim_exit);
289 406
290MODULE_AUTHOR("Freescale Semiconductor Inc.");407MODULE_AUTHOR("Freescale Semiconductor Inc.");
291MODULE_DESCRIPTION("i.MX EIM Controller Driver");408MODULE_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
145 struct optee_rng_private *pvt_data = to_optee_rng_private(rng);145 struct optee_rng_private *pvt_data = to_optee_rng_private(rng);
146 struct tee_shm *entropy_shm_pool = NULL;146 struct tee_shm *entropy_shm_pool = NULL;
147 147
148 entropy_shm_pool = tee_shm_alloc(pvt_data->ctx, MAX_ENTROPY_REQ_SZ,148 entropy_shm_pool = tee_shm_alloc_kernel_buf(pvt_data->ctx,
149 TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);149 MAX_ENTROPY_REQ_SZ);
150 if (IS_ERR(entropy_shm_pool)) {150 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");
152 return PTR_ERR(entropy_shm_pool);152 return PTR_ERR(entropy_shm_pool);
153 }153 }
154 154
drivers/clk/clk-scmi.c+60−11
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*2/*
3 * System Control and Power Interface (SCMI) Protocol based clock driver3 * System Control and Power Interface (SCMI) Protocol based clock driver
4 *4 *
5 * Copyright (C) 2018-2021 ARM Ltd.5 * Copyright (C) 2018-2022 ARM Ltd.
6 */6 */
7 7
8#include <linux/clk-provider.h>8#include <linux/clk-provider.h>
@@ -88,21 +88,51 @@ static void scmi_clk_disable(struct clk_hw *hw) · 79 unmodified lines
88 scmi_proto_clk_ops->disable(clk->ph, clk->id);88 scmi_proto_clk_ops->disable(clk->ph, clk->id);
89}89}
90 90
91static 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
98static 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 */
91static const struct clk_ops scmi_clk_ops = {118static const struct clk_ops scmi_clk_ops = {
92 .recalc_rate = scmi_clk_recalc_rate,119 .recalc_rate = scmi_clk_recalc_rate,
93 .round_rate = scmi_clk_round_rate,120 .round_rate = scmi_clk_round_rate,
94 .set_rate = scmi_clk_set_rate,121 .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 */
101 .prepare = scmi_clk_enable,122 .prepare = scmi_clk_enable,
102 .unprepare = scmi_clk_disable,123 .unprepare = scmi_clk_disable,
103};124};
104 125
105static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)126static 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
134static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
135 const struct clk_ops *scmi_ops)
106{136{
107 int ret;137 int ret;
108 unsigned long min_rate, max_rate;138 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
110 struct clk_init_data init = {140 struct clk_init_data init = {
111 .flags = CLK_GET_RATE_NOCACHE,141 .flags = CLK_GET_RATE_NOCACHE,
112 .num_parents = 0,142 .num_parents = 0,
113 .ops = &scmi_clk_ops,143 .ops = scmi_ops,
114 .name = sclk->info->name,144 .name = sclk->info->name,
115 };145 };
116 146
@@ -139,6 +169,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) · 22 unmodified lines
139static int scmi_clocks_probe(struct scmi_device *sdev)169static int scmi_clocks_probe(struct scmi_device *sdev)
140{170{
141 int idx, count, err;171 int idx, count, err;
172 unsigned int atomic_threshold;
173 bool is_atomic;
142 struct clk_hw **hws;174 struct clk_hw **hws;
143 struct clk_hw_onecell_data *clk_data;175 struct clk_hw_onecell_data *clk_data;
144 struct device *dev = &sdev->dev;176 struct device *dev = &sdev->dev;
@@ -168,8 +200,11 @@ static int scmi_clocks_probe(struct scmi_device *sdev) · 23 unmodified lines
168 clk_data->num = count;200 clk_data->num = count;
169 hws = clk_data->hws;201 hws = clk_data->hws;
170 202
203 is_atomic = handle->is_transport_atomic(handle, &atomic_threshold);
204
171 for (idx = 0; idx < count; idx++) {205 for (idx = 0; idx < count; idx++) {
172 struct scmi_clk *sclk;206 struct scmi_clk *sclk;
207 const struct clk_ops *scmi_ops;
173 208
174 sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);209 sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
175 if (!sclk)210 if (!sclk)
@@ -184,13 +219,27 @@ static int scmi_clocks_probe(struct scmi_device *sdev) · 8 unmodified lines
184 sclk->id = idx;219 sclk->id = idx;
185 sclk->ph = ph;220 sclk->ph = ph;
186 221
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);
188 if (err) {234 if (err) {
189 dev_err(dev, "failed to register clock %d\n", idx);235 dev_err(dev, "failed to register clock %d\n", idx);
190 devm_kfree(dev, sclk);236 devm_kfree(dev, sclk);
191 hws[idx] = NULL;237 hws[idx] = NULL;
192 } else {238 } 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)" : "");
194 hws[idx] = &sclk->hw;243 hws[idx] = &sclk->hw;
195 }244 }
196 }245 }
drivers/clk/samsung/Kconfig+9−0
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG · 10 unmodified lines
11 select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS541011 select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
12 select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS542012 select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
13 select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS13 select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
14 select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
14 15
15config S3C64XX_COMMON_CLK16config S3C64XX_COMMON_CLK
16 bool "Samsung S3C64xx clock controller support" if COMPILE_TEST17 bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,11 @@ config S3C2443_COMMON_CLK · 107 unmodified lines
124 help125 help
125 Support for the clock controller present on the Samsung126 Support for the clock controller present on the Samsung
126 S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.127 S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
128
129config 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
26obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o26obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
27obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o27obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o
28obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o28obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
29obj-$(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
87static 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
150static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
151 PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0),
152};
153
154static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
155 PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
156};
157
158static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
159 PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
160};
161
162static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
163 PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0),
164};
165
166static 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 */
178PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
179PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
180PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
181PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
182PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
183PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
184PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
185PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
186PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
187PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
188PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
189
190static 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
205static 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
253static 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
296static 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
310static void __init fsd_clk_cmu_init(struct device_node *np)
311{
312 samsung_cmu_register_one(np, &cmu_cmu_info);
313}
314
315CLK_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
401static 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
486static 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 */
491PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
492PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
493PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
494PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
495PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
496PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
497PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
498PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
499PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
500
501static 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
515static 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
526static 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
661static 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
734static 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
793static 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 */
800PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
801PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
802PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
803
804static 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
813static 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
826static 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
960static 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
1008static 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
1042static 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 */
1048PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
1049PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
1050
1051static 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
1058static 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
1065static 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
1132static 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
1209static 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
1272PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
1273PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
1274PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
1275
1276static 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
1284static 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
1288static 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
1411static 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
1423static void __init fsd_clk_imem_init(struct device_node *np)
1424{
1425 samsung_cmu_register_one(np, &imem_cmu_info);
1426}
1427
1428CLK_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
1453static 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
1477static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
1478 PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0),
1479};
1480
1481static 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
1486PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
1487PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
1488PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
1489
1490static 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
1496static 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
1500static 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
1534static 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
1592static 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
1637static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
1638 PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0),
1639};
1640
1641static 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
1646PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
1647
1648static 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
1652static 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
1660static 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
1738static 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 */
1758static 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 */
1770static 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
1790static 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
1799static int __init fsd_cmu_init(void)
1800{
1801 return platform_driver_register(&fsd_cmu_driver);
1802}
1803core_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
1469 case pll_1450x:1469 case pll_1450x:
1470 case pll_1451x:1470 case pll_1451x:
1471 case pll_1452x:1471 case pll_1452x:
1472 case pll_142xx:
1472 pll->enable_offs = PLL35XX_ENABLE_SHIFT;1473 pll->enable_offs = PLL35XX_ENABLE_SHIFT;
1473 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;1474 pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
1474 if (!pll->rate_table)1475 if (!pll->rate_table)
drivers/clk/samsung/clk-pll.h+1−0
@@ -39,6 +39,7 @@ enum samsung_pll_type { · 38 unmodified lines
39 pll_1460x,39 pll_1460x,
40 pll_0822x,40 pll_0822x,
41 pll_0831x,41 pll_0831x,
42 pll_142xx,
42};43};
43 44
44#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \45#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
122 if (ret <= 0)122 if (ret <= 0)
123 return ret ? : -ENODEV;123 return ret ? : -ENODEV;
124 124
125 ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu));
126 if (ret)
127 return ret;
128
129 return cpuidle_register(&data->cpuidle_driver, NULL);125 return cpuidle_register(&data->cpuidle_driver, NULL);
130}126}
131 127
@@ -136,6 +132,10 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev) · 4 unmodified lines
136 if (!qcom_scm_is_available())132 if (!qcom_scm_is_available())
137 return -EPROBE_DEFER;133 return -EPROBE_DEFER;
138 134
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
139 for_each_possible_cpu(cpu) {139 for_each_possible_cpu(cpu) {
140 ret = spm_cpuidle_register(&pdev->dev, cpu);140 ret = spm_cpuidle_register(&pdev->dev, cpu);
141 if (ret && ret != -ENODEV) {141 if (ret && ret != -ENODEV) {
@@ -155,6 +155,22 @@ static struct platform_driver spm_cpuidle_driver = { · 13 unmodified lines
155 },155 },
156};156};
157 157
158static 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
158static int __init qcom_spm_cpuidle_init(void)174static int __init qcom_spm_cpuidle_init(void)
159{175{
160 struct platform_device *pdev;176 struct platform_device *pdev;
@@ -164,6 +180,10 @@ static int __init qcom_spm_cpuidle_init(void) · 3 unmodified lines
164 if (ret)180 if (ret)
165 return ret;181 return ret;
166 182
183 /* Make sure there is actually any CPU managed by the SPM */
184 if (!qcom_spm_find_any_cpu())
185 return 0;
186
167 pdev = platform_device_register_simple("qcom-spm-cpuidle",187 pdev = platform_device_register_simple("qcom-spm-cpuidle",
168 -1, NULL, 0);188 -1, NULL, 0);
169 if (IS_ERR(pdev)) {189 if (IS_ERR(pdev)) {
drivers/firmware/arm_scmi/Kconfig+56−0
@@ -54,6 +54,18 @@ config ARM_SCMI_TRANSPORT_MAILBOX · 53 unmodified lines
54 If you want the ARM SCMI PROTOCOL stack to include support for a54 If you want the ARM SCMI PROTOCOL stack to include support for a
55 transport based on mailboxes, answer Y.55 transport based on mailboxes, answer Y.
56 56
57config 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
57config ARM_SCMI_TRANSPORT_SMC69config ARM_SCMI_TRANSPORT_SMC
58 bool "SCMI transport based on SMC"70 bool "SCMI transport based on SMC"
59 depends on HAVE_ARM_SMCCC_DISCOVERY71 depends on HAVE_ARM_SMCCC_DISCOVERY
@@ -66,6 +78,20 @@ config ARM_SCMI_TRANSPORT_SMC · 6 unmodified lines
66 If you want the ARM SCMI PROTOCOL stack to include support for a78 If you want the ARM SCMI PROTOCOL stack to include support for a
67 transport based on SMC, answer Y.79 transport based on SMC, answer Y.
68 80
81config 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
69config ARM_SCMI_TRANSPORT_VIRTIO95config ARM_SCMI_TRANSPORT_VIRTIO
70 bool "SCMI transport based on VirtIO"96 bool "SCMI transport based on VirtIO"
71 depends on VIRTIO=y || VIRTIO=ARM_SCMI_PROTOCOL97 depends on VIRTIO=y || VIRTIO=ARM_SCMI_PROTOCOL
@@ -77,6 +103,36 @@ config ARM_SCMI_TRANSPORT_VIRTIO · 5 unmodified lines
77 If you want the ARM SCMI PROTOCOL stack to include support for a103 If you want the ARM SCMI PROTOCOL stack to include support for a
78 transport based on VirtIO, answer Y.104 transport based on VirtIO, answer Y.
79 105
106config 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
121config 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
80endif #ARM_SCMI_PROTOCOL136endif #ARM_SCMI_PROTOCOL
81 137
82config ARM_SCMI_POWER_DOMAIN138config 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
6scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o6scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
7scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o7scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
8scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o8scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
9scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
9scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o10scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o
10scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \11scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \
11 $(scmi-transport-y)12 $(scmi-transport-y)
12obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o13obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
13obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o14obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
15
16ifeq ($(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.
20CFLAGS_REMOVE_smc.o += $(CC_FLAGS_FTRACE)
21endif
drivers/firmware/arm_scmi/clock.c+28−6
@@ -27,7 +27,8 @@ struct scmi_msg_resp_clock_protocol_attributes { · 26 unmodified lines
27struct scmi_msg_resp_clock_attributes {27struct scmi_msg_resp_clock_attributes {
28 __le32 attributes;28 __le32 attributes;
29#define CLOCK_ENABLE BIT(0)29#define CLOCK_ENABLE BIT(0)
30 u8 name[SCMI_MAX_STR_SIZE];30 u8 name[SCMI_MAX_STR_SIZE];
31 __le32 clock_enable_latency;
31};32};
32 33
33struct scmi_clock_set_config {34struct scmi_clock_set_config {
@@ -116,10 +117,15 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph, · 82 unmodified lines
116 attr = t->rx.buf;117 attr = t->rx.buf;
117 118
118 ret = ph->xops->do_xfer(ph, t);119 ret = ph->xops->do_xfer(ph, t);
119 if (!ret)120 if (!ret) {
120 strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);121 strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
121 else122 /* 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 {
122 clk->name[0] = '\0';127 clk->name[0] = '\0';
128 }
123 129
124 ph->xops->xfer_put(ph, t);130 ph->xops->xfer_put(ph, t);
125 return ret;131 return ret;
@@ -273,7 +279,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph, · 147 unmodified lines
273 279
274static int280static int
275scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,281scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
276 u32 config)282 u32 config, bool atomic)
277{283{
278 int ret;284 int ret;
279 struct scmi_xfer *t;285 struct scmi_xfer *t;
@@ -284,6 +290,8 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, · 4 unmodified lines
284 if (ret)290 if (ret)
285 return ret;291 return ret;
286 292
293 t->hdr.poll_completion = atomic;
294
287 cfg = t->tx.buf;295 cfg = t->tx.buf;
288 cfg->id = cpu_to_le32(clk_id);296 cfg->id = cpu_to_le32(clk_id);
289 cfg->attributes = cpu_to_le32(config);297 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
296 304
297static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)305static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
298{306{
299 return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);307 return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
300}308}
301 309
302static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)310static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
303{311{
304 return scmi_clock_config_set(ph, clk_id, 0);312 return scmi_clock_config_set(ph, clk_id, 0, false);
313}
314
315static 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
321static 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);
305}325}
306 326
307static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)327static 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
330 .rate_set = scmi_clock_rate_set,350 .rate_set = scmi_clock_rate_set,
331 .enable = scmi_clock_enable,351 .enable = scmi_clock_enable,
332 .disable = scmi_clock_disable,352 .disable = scmi_clock_disable,
353 .enable_atomic = scmi_clock_enable_atomic,
354 .disable_atomic = scmi_clock_disable_atomic,
333};355};
334 356
335static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)357static 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
339 * @dev: Reference to device in the SCMI hierarchy corresponding to this339 * @dev: Reference to device in the SCMI hierarchy corresponding to this
340 * channel340 * channel
341 * @handle: Pointer to SCMI entity handle341 * @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().
342 * @transport_info: Transport layer related information346 * @transport_info: Transport layer related information
343 */347 */
344struct scmi_chan_info {348struct scmi_chan_info {
345 struct device *dev;349 struct device *dev;
346 struct scmi_handle *handle;350 struct scmi_handle *handle;
351 bool no_completion_irq;
347 void *transport_info;352 void *transport_info;
348};353};
349 354
@@ -373,7 +378,8 @@ struct scmi_transport_ops { · 23 unmodified lines
373 unsigned int (*get_max_msg)(struct scmi_chan_info *base_cinfo);378 unsigned int (*get_max_msg)(struct scmi_chan_info *base_cinfo);
374 int (*send_message)(struct scmi_chan_info *cinfo,379 int (*send_message)(struct scmi_chan_info *cinfo,
375 struct scmi_xfer *xfer);380 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);
377 void (*fetch_response)(struct scmi_chan_info *cinfo,383 void (*fetch_response)(struct scmi_chan_info *cinfo,
378 struct scmi_xfer *xfer);384 struct scmi_xfer *xfer);
379 void (*fetch_notification)(struct scmi_chan_info *cinfo,385 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
402 * be pending simultaneously in the system. May be overridden by the408 * be pending simultaneously in the system. May be overridden by the
403 * get_max_msg op.409 * get_max_msg op.
404 * @max_msg_size: Maximum size of data per message that can be handled.410 * @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.
405 */423 */
406struct scmi_desc {424struct scmi_desc {
407 int (*transport_init)(void);425 int (*transport_init)(void);
@@ -410,6 +428,9 @@ struct scmi_desc { · 2 unmodified lines
410 int max_rx_timeout_ms;428 int max_rx_timeout_ms;
411 int max_msg;429 int max_msg;
412 int max_msg_size;430 int max_msg_size;
431 const bool force_polling;
432 const bool sync_cmds_completed_on_ret;
433 const bool atomic_enabled;
413};434};
414 435
415#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX436#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
@@ -421,6 +442,9 @@ extern const struct scmi_desc scmi_smc_desc; · 5 unmodified lines
421#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO442#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
422extern const struct scmi_desc scmi_virtio_desc;443extern const struct scmi_desc scmi_virtio_desc;
423#endif444#endif
445#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
446extern const struct scmi_desc scmi_optee_desc;
447#endif
424 448
425void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);449void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
426void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);450void 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
131 * MAX_PROTOCOLS_IMP elements allocated by the base protocol131 * MAX_PROTOCOLS_IMP elements allocated by the base protocol
132 * @active_protocols: IDR storing device_nodes for protocols actually defined132 * @active_protocols: IDR storing device_nodes for protocols actually defined
133 * in the DT and confirmed as implemented by fw.133 * 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.
134 * @notify_priv: Pointer to private data structure specific to notifications.140 * @notify_priv: Pointer to private data structure specific to notifications.
135 * @node: List head141 * @node: List head
136 * @users: Number of users of this instance142 * @users: Number of users of this instance
@@ -149,6 +155,7 @@ struct scmi_info { · 12 unmodified lines
149 struct mutex protocols_mtx;155 struct mutex protocols_mtx;
150 u8 *protocols_imp;156 u8 *protocols_imp;
151 struct idr active_protocols;157 struct idr active_protocols;
158 unsigned int atomic_threshold;
152 void *notify_priv;159 void *notify_priv;
153 struct list_head node;160 struct list_head node;
154 int users;161 int users;
@@ -609,6 +616,25 @@ static inline void scmi_clear_channel(struct scmi_info *info, · 454 unmodified lines
609 info->desc->ops->clear_channel(cinfo);616 info->desc->ops->clear_channel(cinfo);
610}617}
611 618
619static 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
625static 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
631static 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
612static void scmi_handle_notification(struct scmi_chan_info *cinfo,638static void scmi_handle_notification(struct scmi_chan_info *cinfo,
613 u32 msg_hdr, void *priv)639 u32 msg_hdr, void *priv)
614{640{
@@ -629,7 +655,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, · 14 unmodified lines
629 655
630 unpack_scmi_header(msg_hdr, &xfer->hdr);656 unpack_scmi_header(msg_hdr, &xfer->hdr);
631 if (priv)657 if (priv)
632 xfer->priv = priv;658 /* Ensure order between xfer->priv store and following ops */
659 smp_store_mb(xfer->priv, priv);
633 info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,660 info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
634 xfer);661 xfer);
635 scmi_notify(cinfo->handle, xfer->hdr.protocol_id,662 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
661 xfer->rx.len = info->desc->max_msg_size;688 xfer->rx.len = info->desc->max_msg_size;
662 689
663 if (priv)690 if (priv)
664 xfer->priv = priv;691 /* Ensure order between xfer->priv store and following ops */
692 smp_store_mb(xfer->priv, priv);
665 info->desc->ops->fetch_response(cinfo, xfer);693 info->desc->ops->fetch_response(cinfo, xfer);
666 694
667 trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,695 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
724 __scmi_xfer_put(&info->tx_minfo, xfer);752 __scmi_xfer_put(&info->tx_minfo, xfer);
725}753}
726 754
727#define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC)
728
729static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,755static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo,
730 struct scmi_xfer *xfer, ktime_t stop)756 struct scmi_xfer *xfer, ktime_t stop)
731{757{
@@ -740,6 +766,79 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, · 8 unmodified lines
740 ktime_after(ktime_get(), stop);766 ktime_after(ktime_get(), stop);
741}767}
742 768
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 */
781static 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
743/**842/**
744 * do_xfer() - Do one transfer843 * do_xfer() - Do one transfer
745 *844 *
@@ -754,18 +853,26 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 8 unmodified lines
754 struct scmi_xfer *xfer)853 struct scmi_xfer *xfer)
755{854{
756 int ret;855 int ret;
757 int timeout;
758 const struct scmi_protocol_instance *pi = ph_to_pi(ph);856 const struct scmi_protocol_instance *pi = ph_to_pi(ph);
759 struct scmi_info *info = handle_to_scmi_info(pi->handle);857 struct scmi_info *info = handle_to_scmi_info(pi->handle);
760 struct device *dev = info->dev;858 struct device *dev = info->dev;
761 struct scmi_chan_info *cinfo;859 struct scmi_chan_info *cinfo;
762 860
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)) {
764 dev_warn_once(dev,863 dev_warn_once(dev,
765 "Polling mode is not supported by transport.\n");864 "Polling mode is not supported by transport.\n");
766 return -EINVAL;865 return -EINVAL;
767 }866 }
768 867
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
769 /*876 /*
770 * Initialise protocol id now from protocol handle to avoid it being877 * Initialise protocol id now from protocol handle to avoid it being
771 * overridden by mistake (or malice) by the protocol code mangling with878 * 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
774 xfer->hdr.protocol_id = pi->proto->id;881 xfer->hdr.protocol_id = pi->proto->id;
775 reinit_completion(&xfer->done);882 reinit_completion(&xfer->done);
776 883
777 cinfo = idr_find(&info->tx_idr, xfer->hdr.protocol_id);
778 if (unlikely(!cinfo))
779 return -EINVAL;
780
781 trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,884 trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
782 xfer->hdr.protocol_id, xfer->hdr.seq,885 xfer->hdr.protocol_id, xfer->hdr.seq,
783 xfer->hdr.poll_completion);886 xfer->hdr.poll_completion);
@@ -798,41 +901,12 @@ static int do_xfer(const struct scmi_protocol_handle *ph, · 14 unmodified lines
798 return ret;901 return ret;
799 }902 }
800 903
801 if (xfer->hdr.poll_completion) {904 ret = scmi_wait_for_message_response(cinfo, xfer);
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
831 if (!ret && xfer->hdr.status)905 if (!ret && xfer->hdr.status)
832 ret = scmi_to_linux_errno(xfer->hdr.status);906 ret = scmi_to_linux_errno(xfer->hdr.status);
833 907
834 if (info->desc->ops->mark_txdone)908 if (info->desc->ops->mark_txdone)
835 info->desc->ops->mark_txdone(cinfo, ret);909 info->desc->ops->mark_txdone(cinfo, ret, xfer);
836 910
837 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,911 trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
838 xfer->hdr.protocol_id, xfer->hdr.seq, ret);912 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
858 * @ph: Pointer to SCMI protocol handle932 * @ph: Pointer to SCMI protocol handle
859 * @xfer: Transfer to initiate and wait for response933 * @xfer: Transfer to initiate and wait for response
860 *934 *
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 *
861 * Return: -ETIMEDOUT in case of no delayed response, if transmit error,949 * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
862 * return corresponding error, else if all goes well, return 0.950 * return corresponding error, else if all goes well, return 0.
863 */951 */
@@ -869,12 +957,24 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, · 5 unmodified lines
869 957
870 xfer->async_done = &async_response;958 xfer->async_done = &async_response;
871 959
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
872 ret = do_xfer(ph, xfer);968 ret = do_xfer(ph, xfer);
873 if (!ret) {969 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_);
875 ret = -ETIMEDOUT;974 ret = -ETIMEDOUT;
876 else if (xfer->hdr.status)975 } else if (xfer->hdr.status) {
877 ret = scmi_to_linux_errno(xfer->hdr.status);976 ret = scmi_to_linux_errno(xfer->hdr.status);
977 }
878 }978 }
879 979
880 xfer->async_done = NULL;980 xfer->async_done = NULL;
@@ -1308,6 +1408,29 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id) · 427 unmodified lines
1308 WARN_ON(ret);1408 WARN_ON(ret);
1309}1409}
1310 1410
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 */
1421static 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
1311static inline1434static inline
1312struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)1435struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info)
1313{1436{
@@ -1499,6 +1622,16 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, · 185 unmodified lines
1499 if (ret)1622 if (ret)
1500 return ret;1623 return ret;
1501 1624
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
1502idr_alloc:1635idr_alloc:
1503 ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);1636 ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
1504 if (ret != prot_id) {1637 if (ret != prot_id) {
@@ -1836,6 +1969,14 @@ static int scmi_probe(struct platform_device *pdev) · 331 unmodified lines
1836 handle->devm_protocol_get = scmi_devm_protocol_get;1969 handle->devm_protocol_get = scmi_devm_protocol_get;
1837 handle->devm_protocol_put = scmi_devm_protocol_put;1970 handle->devm_protocol_put = scmi_devm_protocol_put;
1838 1971
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
1839 if (desc->ops->link_supplier) {1980 if (desc->ops->link_supplier) {
1840 ret = desc->ops->link_supplier(dev);1981 ret = desc->ops->link_supplier(dev);
1841 if (ret)1982 if (ret)
@@ -1853,6 +1994,10 @@ static int scmi_probe(struct platform_device *pdev) · 11 unmodified lines
1853 if (scmi_notification_init(handle))1994 if (scmi_notification_init(handle))
1854 dev_err(dev, "SCMI Notifications NOT available.\n");1995 dev_err(dev, "SCMI Notifications NOT available.\n");
1855 1996
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
1856 /*2001 /*
1857 * Trigger SCMI Base protocol initialization.2002 * Trigger SCMI Base protocol initialization.
1858 * It's mandatory and won't be ever released/deinit until the2003 * 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
1994#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX2139#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX
1995 { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },2140 { .compatible = "arm,scmi", .data = &scmi_mailbox_desc },
1996#endif2141#endif
2142#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE
2143 { .compatible = "linaro,scmi-optee", .data = &scmi_optee_desc },
2144#endif
1997#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC2145#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
1998 { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},2146 { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
1999#endif2147#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
140 return ret;140 return ret;
141}141}
142 142
143static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret)143static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
144 struct scmi_xfer *__unused)
144{145{
145 struct scmi_mailbox *smbox = cinfo->transport_info;146 struct scmi_mailbox *smbox = cinfo->transport_info;
146 147
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
21enum 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 */
91struct 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 */
111struct 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 */
120static struct scmi_optee_agent *scmi_optee_private;
121
122/* Forward reference to scmi_optee transport initialization */
123static int scmi_optee_init(void);
124
125/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
126static 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
147static void close_session(struct scmi_optee_agent *agent, u32 tee_session)
148{
149 tee_client_close_session(agent->tee_ctx, tee_session);
150}
151
152static 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
191static 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
221static 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
252static 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
270static 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
278static 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
285static 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
316out:
317 of_node_put(np);
318
319 return ret;
320}
321
322static 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
331static 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
375err_close_sess:
376 close_session(scmi_optee_private, channel->tee_session);
377err_free_shm:
378 if (channel->tee_shm)
379 tee_shm_free(channel->tee_shm);
380
381 return ret;
382}
383
384static 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
408static 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
418static 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
435static 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
444static 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
452static 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
463static 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
468static 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
505err:
506 tee_client_close_context(tee_ctx);
507
508 return ret;
509}
510
511static 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
529static 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
537MODULE_DEVICE_TABLE(tee, scmi_optee_service_id);
538
539static 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
549static int scmi_optee_init(void)
550{
551 return driver_register(&scmi_optee_driver.driver);
552}
553
554static void scmi_optee_exit(void)
555{
556 if (scmi_optee_private)
557 driver_unregister(&scmi_optee_driver.driver);
558}
559
560const 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
7 */7 */
8 8
9#include <linux/arm-smccc.h>9#include <linux/arm-smccc.h>
10#include <linux/atomic.h>
10#include <linux/device.h>11#include <linux/device.h>
11#include <linux/err.h>12#include <linux/err.h>
12#include <linux/interrupt.h>13#include <linux/interrupt.h>
@@ -14,6 +15,7 @@ · 1 unmodified line
14#include <linux/of.h>15#include <linux/of.h>
15#include <linux/of_address.h>16#include <linux/of_address.h>
16#include <linux/of_irq.h>17#include <linux/of_irq.h>
18#include <linux/processor.h>
17#include <linux/slab.h>19#include <linux/slab.h>
18 20
19#include "common.h"21#include "common.h"
@@ -23,26 +25,29 @@ · 3 unmodified lines
23 *25 *
24 * @cinfo: SCMI channel info26 * @cinfo: SCMI channel info
25 * @shmem: Transmit/Receive shared memory area27 * @shmem: Transmit/Receive shared memory area
26 * @shmem_lock: Lock to protect access to Tx/Rx shared memory area28 * @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.
27 * @func_id: smc/hvc call function id32 * @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.
30 */33 */
31 34
32struct scmi_smc {35struct scmi_smc {
33 struct scmi_chan_info *cinfo;36 struct scmi_chan_info *cinfo;
34 struct scmi_shared_mem __iomem *shmem;37 struct scmi_shared_mem __iomem *shmem;
38 /* Protect access to shmem area */
35 struct mutex shmem_lock;39 struct mutex shmem_lock;
40#define INFLIGHT_NONE MSG_TOKEN_MAX
41 atomic_t inflight;
36 u32 func_id;42 u32 func_id;
37 int irq;
38 struct completion tx_complete;
39};43};
40 44
41static irqreturn_t smc_msg_done_isr(int irq, void *data)45static irqreturn_t smc_msg_done_isr(int irq, void *data)
42{46{
43 struct scmi_smc *scmi_info = data;47 struct scmi_smc *scmi_info = data;
44 48
45 complete(&scmi_info->tx_complete);49 scmi_rx_callback(scmi_info->cinfo,
50 shmem_read_header(scmi_info->shmem), NULL);
46 51
47 return IRQ_HANDLED;52 return IRQ_HANDLED;
48}53}
@@ -57,6 +62,41 @@ static bool smc_chan_available(struct device *dev, int idx) · 8 unmodified lines
57 return true;62 return true;
58}63}
59 64
65static 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
73static 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
82static inline void
83smc_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
92static 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
60static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,100static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
61 bool tx)101 bool tx)
62{102{
@@ -111,13 +151,13 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 48 unmodified lines
111 dev_err(dev, "failed to setup SCMI smc irq\n");151 dev_err(dev, "failed to setup SCMI smc irq\n");
112 return ret;152 return ret;
113 }153 }
114 init_completion(&scmi_info->tx_complete);154 } else {
115 scmi_info->irq = irq;155 cinfo->no_completion_irq = true;
116 }156 }
117 157
118 scmi_info->func_id = func_id;158 scmi_info->func_id = func_id;
119 scmi_info->cinfo = cinfo;159 scmi_info->cinfo = cinfo;
120 mutex_init(&scmi_info->shmem_lock);160 smc_channel_lock_init(scmi_info);
121 cinfo->transport_info = scmi_info;161 cinfo->transport_info = scmi_info;
122 162
123 return 0;163 return 0;
@@ -142,26 +182,22 @@ static int smc_send_message(struct scmi_chan_info *cinfo, · 18 unmodified lines
142 struct scmi_smc *scmi_info = cinfo->transport_info;182 struct scmi_smc *scmi_info = cinfo->transport_info;
143 struct arm_smccc_res res;183 struct arm_smccc_res res;
144 184
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);
146 190
147 shmem_tx_prepare(scmi_info->shmem, xfer);191 shmem_tx_prepare(scmi_info->shmem, xfer);
148 192
149 if (scmi_info->irq)
150 reinit_completion(&scmi_info->tx_complete);
151
152 arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);193 arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
153 194
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
162 /* Only SMCCC_RET_NOT_SUPPORTED is valid error code */195 /* Only SMCCC_RET_NOT_SUPPORTED is valid error code */
163 if (res.a0)196 if (res.a0) {
197 smc_channel_lock_release(scmi_info);
164 return -EOPNOTSUPP;198 return -EOPNOTSUPP;
199 }
200
165 return 0;201 return 0;
166}202}
167 203
@@ -173,12 +209,12 @@ static void smc_fetch_response(struct scmi_chan_info *cinfo, · 5 unmodified lines
173 shmem_fetch_response(scmi_info->shmem, xfer);209 shmem_fetch_response(scmi_info->shmem, xfer);
174}210}
175 211
176static bool212static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret,
177smc_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)213 struct scmi_xfer *__unused)
178{214{
179 struct scmi_smc *scmi_info = cinfo->transport_info;215 struct scmi_smc *scmi_info = cinfo->transport_info;
180 216
181 return shmem_poll_done(scmi_info->shmem, xfer);217 smc_channel_lock_release(scmi_info);
182}218}
183 219
184static const struct scmi_transport_ops scmi_smc_ops = {220static const struct scmi_transport_ops scmi_smc_ops = {
@@ -186,8 +222,8 @@ static const struct scmi_transport_ops scmi_smc_ops = { · 1 unmodified line
186 .chan_setup = smc_chan_setup,222 .chan_setup = smc_chan_setup,
187 .chan_free = smc_chan_free,223 .chan_free = smc_chan_free,
188 .send_message = smc_send_message,224 .send_message = smc_send_message,
225 .mark_txdone = smc_mark_txdone,
189 .fetch_response = smc_fetch_response,226 .fetch_response = smc_fetch_response,
190 .poll_done = smc_poll_done,
191};227};
192 228
193const struct scmi_desc scmi_smc_desc = {229const struct scmi_desc scmi_smc_desc = {
@@ -195,4 +231,14 @@ const struct scmi_desc scmi_smc_desc = { · 1 unmodified line
195 .max_rx_timeout_ms = 30,231 .max_rx_timeout_ms = 30,
196 .max_msg = 20,232 .max_msg = 20,
197 .max_msg_size = 128,233 .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),
198};244};
drivers/firmware/arm_scmi/virtio.c+517−96
@@ -3,8 +3,8 @@ · 2 unmodified lines
3 * Virtio Transport driver for Arm System Control and Management Interface3 * Virtio Transport driver for Arm System Control and Management Interface
4 * (SCMI).4 * (SCMI).
5 *5 *
6 * Copyright (C) 2020-2021 OpenSynergy.6 * Copyright (C) 2020-2022 OpenSynergy.
7 * Copyright (C) 2021 ARM Ltd.7 * Copyright (C) 2021-2022 ARM Ltd.
8 */8 */
9 9
10/**10/**
@@ -17,7 +17,9 @@ · 6 unmodified lines
17 * virtqueue. Access to each virtqueue is protected by spinlocks.17 * virtqueue. Access to each virtqueue is protected by spinlocks.
18 */18 */
19 19
20#include <linux/completion.h>
20#include <linux/errno.h>21#include <linux/errno.h>
22#include <linux/refcount.h>
21#include <linux/slab.h>23#include <linux/slab.h>
22#include <linux/virtio.h>24#include <linux/virtio.h>
23#include <linux/virtio_config.h>25#include <linux/virtio_config.h>
@@ -27,6 +29,7 @@ · 3 unmodified lines
27 29
28#include "common.h"30#include "common.h"
29 31
32#define VIRTIO_MAX_RX_TIMEOUT_MS 60000
30#define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */33#define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */
31#define VIRTIO_SCMI_MAX_PDU_SIZE \34#define VIRTIO_SCMI_MAX_PDU_SIZE \
32 (VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)35 (VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)
@@ -37,25 +40,46 @@ · 4 unmodified lines
37 *40 *
38 * @vqueue: Associated virtqueue41 * @vqueue: Associated virtqueue
39 * @cinfo: SCMI Tx or Rx channel42 * @cinfo: SCMI Tx or Rx channel
43 * @free_lock: Protects access to the @free_list.
40 * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only44 * @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
41 * @is_rx: Whether channel is an Rx channel49 * @is_rx: Whether channel is an Rx channel
42 * @ready: Whether transport user is ready to hear about channel
43 * @max_msg: Maximum number of pending messages for this channel.50 * @max_msg: Maximum number of pending messages for this channel.
44 * @lock: Protects access to all members except ready.51 * @lock: Protects access to all members except users, free_list and
45 * @ready_lock: Protects access to ready. If required, it must be taken before52 * pending_cmds_list.
46 * lock.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.
47 */55 */
48struct scmi_vio_channel {56struct scmi_vio_channel {
49 struct virtqueue *vqueue;57 struct virtqueue *vqueue;
50 struct scmi_chan_info *cinfo;58 struct scmi_chan_info *cinfo;
59 /* lock to protect access to the free list. */
60 spinlock_t free_lock;
51 struct list_head free_list;61 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;
52 bool is_rx;67 bool is_rx;
53 bool ready;
54 unsigned int max_msg;68 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 */
56 spinlock_t lock;73 spinlock_t lock;
57 /* lock to rotects access to ready flag. */74 struct completion *shutdown_done;
58 spinlock_t ready_lock;75 refcount_t users;
76};
77
78enum poll_states {
79 VIO_MSG_NOT_POLLED,
80 VIO_MSG_POLL_TIMEOUT,
81 VIO_MSG_POLLING,
82 VIO_MSG_POLL_DONE,
59};83};
60 84
61/**85/**
@@ -65,29 +89,154 @@ struct scmi_vio_channel { · 3 unmodified lines
65 * @input: SDU used for (delayed) responses and notifications89 * @input: SDU used for (delayed) responses and notifications
66 * @list: List which scmi_vio_msg may be part of90 * @list: List which scmi_vio_msg may be part of
67 * @rx_len: Input SDU size in bytes, once input has been received91 * @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.
68 */98 */
69struct scmi_vio_msg {99struct scmi_vio_msg {
70 struct scmi_msg_payld *request;100 struct scmi_msg_payld *request;
71 struct scmi_msg_payld *input;101 struct scmi_msg_payld *input;
72 struct list_head list;102 struct list_head list;
73 unsigned int rx_len;103 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;
74};109};
75 110
76/* Only one SCMI VirtIO device can possibly exist */111/* Only one SCMI VirtIO device can possibly exist */
77static struct virtio_device *scmi_vdev;112static struct virtio_device *scmi_vdev;
78 113
114static 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
128static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch)
129{
130 return refcount_inc_not_zero(&vioch->users);
131}
132
133static 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
147static 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 */
182static struct scmi_vio_msg *
183scmi_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
205static 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 */
211static 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
79static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)228static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
80{229{
81 return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);230 return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
82}231}
83 232
84static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,233static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
85 struct scmi_vio_msg *msg,234 struct scmi_vio_msg *msg)
86 struct device *dev)
87{235{
88 struct scatterlist sg_in;236 struct scatterlist sg_in;
89 int rc;237 int rc;
90 unsigned long flags;238 unsigned long flags;
239 struct device *dev = &vioch->vqueue->vdev->dev;
91 240
92 sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);241 sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
93 242
@@ -95,7 +244,7 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, · 1 unmodified line
95 244
96 rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);245 rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
97 if (rc)246 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);
99 else248 else
100 virtqueue_kick(vioch->vqueue);249 virtqueue_kick(vioch->vqueue);
101 250
@@ -104,22 +253,22 @@ static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, · 2 unmodified lines
104 return rc;253 return rc;
105}254}
106 255
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 */
107static void scmi_finalize_message(struct scmi_vio_channel *vioch,260static void scmi_finalize_message(struct scmi_vio_channel *vioch,
108 struct scmi_vio_msg *msg)261 struct scmi_vio_msg *msg)
109{262{
110 if (vioch->is_rx) {263 if (vioch->is_rx)
111 scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);264 scmi_vio_feed_vq_rx(vioch, msg);
112 } else {265 else
113 /* Here IRQs are assumed to be already disabled by the caller */266 scmi_vio_msg_release(vioch, msg);
114 spin_lock(&vioch->lock);
115 list_add(&msg->list, &vioch->free_list);
116 spin_unlock(&vioch->lock);
117 }
118}267}
119 268
120static void scmi_vio_complete_cb(struct virtqueue *vqueue)269static void scmi_vio_complete_cb(struct virtqueue *vqueue)
121{270{
122 unsigned long ready_flags;271 unsigned long flags;
123 unsigned int length;272 unsigned int length;
124 struct scmi_vio_channel *vioch;273 struct scmi_vio_channel *vioch;
125 struct scmi_vio_msg *msg;274 struct scmi_vio_msg *msg;
@@ -130,27 +279,25 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue) · 4 unmodified lines
130 vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];279 vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];
131 280
132 for (;;) {281 for (;;) {
133 spin_lock_irqsave(&vioch->ready_lock, ready_flags);282 if (!scmi_vio_channel_acquire(vioch))
283 return;
134 284
135 if (!vioch->ready) {285 spin_lock_irqsave(&vioch->lock, flags);
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);
143 if (cb_enabled) {286 if (cb_enabled) {
144 virtqueue_disable_cb(vqueue);287 virtqueue_disable_cb(vqueue);
145 cb_enabled = false;288 cb_enabled = false;
146 }289 }
290
147 msg = virtqueue_get_buf(vqueue, &length);291 msg = virtqueue_get_buf(vqueue, &length);
148 if (!msg) {292 if (!msg) {
149 if (virtqueue_enable_cb(vqueue))293 if (virtqueue_enable_cb(vqueue)) {
150 goto unlock_out;294 spin_unlock_irqrestore(&vioch->lock, flags);
295 scmi_vio_channel_release(vioch);
296 return;
297 }
151 cb_enabled = true;298 cb_enabled = true;
152 }299 }
153 spin_unlock(&vioch->lock);300 spin_unlock_irqrestore(&vioch->lock, flags);
154 301
155 if (msg) {302 if (msg) {
156 msg->rx_len = length;303 msg->rx_len = length;
@@ -161,19 +308,57 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue) · 4 unmodified lines
161 }308 }
162 309
163 /*310 /*
164 * Release ready_lock and re-enable IRQs between loop iterations311 * Release vio channel between loop iterations to allow
165 * to allow virtio_chan_free() to possibly kick in and set the312 * virtio_chan_free() to eventually fully release it when
166 * flag vioch->ready to false even in between processing of313 * shutting down; in such a case, any outstanding message will
167 * messages, so as to force outstanding messages to be ignored314 * be ignored since this loop will bail out at the next
168 * when system is shutting down.315 * iteration.
316 */
317 scmi_vio_channel_release(vioch);
318 }
319}
320
321static 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.
169 */347 */
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);
171 }354 }
172 355
173unlock_out:356 spin_unlock_irqrestore(&vioch->pending_lock, flags);
174 spin_unlock(&vioch->lock);357
175unlock_ready_out:358 /* Process possibly still pending messages */
176 spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);359 scmi_vio_complete_cb(vioch->vqueue);
360
361 scmi_vio_channel_release(vioch);
177}362}
178 363
179static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };364static 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
193static int virtio_link_supplier(struct device *dev)378static int virtio_link_supplier(struct device *dev)
194{379{
195 if (!scmi_vdev) {380 if (!scmi_vdev) {
196 dev_notice_once(dev,381 dev_notice(dev,
197 "Deferring probe after not finding a bound scmi-virtio device\n");382 "Deferring probe after not finding a bound scmi-virtio device\n");
198 return -EPROBE_DEFER;383 return -EPROBE_DEFER;
199 }384 }
200 385
@@ -234,7 +419,6 @@ static bool virtio_chan_available(struct device *dev, int idx) · 33 unmodified lines
234static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,419static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
235 bool tx)420 bool tx)
236{421{
237 unsigned long flags;
238 struct scmi_vio_channel *vioch;422 struct scmi_vio_channel *vioch;
239 int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;423 int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;
240 int i;424 int i;
@@ -244,6 +428,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 3 unmodified lines
244 428
245 vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];429 vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
246 430
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
247 for (i = 0; i < vioch->max_msg; i++) {444 for (i = 0; i < vioch->max_msg; i++) {
248 struct scmi_vio_msg *msg;445 struct scmi_vio_msg *msg;
249 446
@@ -257,6 +454,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 7 unmodified lines
257 GFP_KERNEL);454 GFP_KERNEL);
258 if (!msg->request)455 if (!msg->request)
259 return -ENOMEM;456 return -ENOMEM;
457 spin_lock_init(&msg->poll_lock);
458 refcount_set(&msg->users, 1);
260 }459 }
261 460
262 msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,461 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
264 if (!msg->input)463 if (!msg->input)
265 return -ENOMEM;464 return -ENOMEM;
266 465
267 if (tx) {466 scmi_finalize_message(vioch, msg);
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 }
274 }467 }
275 468
276 spin_lock_irqsave(&vioch->lock, flags);469 scmi_vio_channel_ready(vioch, cinfo);
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);
285 470
286 return 0;471 return 0;
287}472}
288 473
289static int virtio_chan_free(int id, void *p, void *data)474static int virtio_chan_free(int id, void *p, void *data)
290{475{
291 unsigned long flags;
292 struct scmi_chan_info *cinfo = p;476 struct scmi_chan_info *cinfo = p;
293 struct scmi_vio_channel *vioch = cinfo->transport_info;477 struct scmi_vio_channel *vioch = cinfo->transport_info;
294 478
295 spin_lock_irqsave(&vioch->ready_lock, flags);479 scmi_vio_channel_cleanup_sync(vioch);
296 vioch->ready = false;
297 spin_unlock_irqrestore(&vioch->ready_lock, flags);
298 480
299 scmi_free_channel(cinfo, data, id);481 scmi_free_channel(cinfo, data, id);
300 482
301 spin_lock_irqsave(&vioch->lock, flags);
302 vioch->cinfo = NULL;
303 spin_unlock_irqrestore(&vioch->lock, flags);
304
305 return 0;483 return 0;
306}484}
307 485
@@ -316,33 +494,56 @@ static int virtio_send_message(struct scmi_chan_info *cinfo, · 8 unmodified lines
316 int rc;494 int rc;
317 struct scmi_vio_msg *msg;495 struct scmi_vio_msg *msg;
318 496
319 spin_lock_irqsave(&vioch->lock, flags);497 if (!scmi_vio_channel_acquire(vioch))
498 return -EINVAL;
320 499
321 if (list_empty(&vioch->free_list)) {500 msg = scmi_virtio_get_free_msg(vioch);
322 spin_unlock_irqrestore(&vioch->lock, flags);501 if (!msg) {
502 scmi_vio_channel_release(vioch);
323 return -EBUSY;503 return -EBUSY;
324 }504 }
325 505
326 msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
327 list_del(&msg->list);
328
329 msg_tx_prepare(msg->request, xfer);506 msg_tx_prepare(msg->request, xfer);
330 507
331 sg_init_one(&sg_out, msg->request, msg_command_size(xfer));508 sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
332 sg_init_one(&sg_in, msg->input, msg_response_size(xfer));509 sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
333 510
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
334 rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);528 rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
335 if (rc) {529 if (rc)
336 list_add(&msg->list, &vioch->free_list);530 dev_err(vioch->cinfo->dev,
337 dev_err_once(vioch->cinfo->dev,531 "failed to add to TX virtqueue (%d)\n", rc);
338 "%s() failed to add to virtqueue (%d)\n", __func__,532 else
339 rc);
340 } else {
341 virtqueue_kick(vioch->vqueue);533 virtqueue_kick(vioch->vqueue);
342 }
343 534
344 spin_unlock_irqrestore(&vioch->lock, flags);535 spin_unlock_irqrestore(&vioch->lock, flags);
345 536
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
346 return rc;547 return rc;
347}548}
348 549
@@ -351,10 +552,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo, · 2 unmodified lines
351{552{
352 struct scmi_vio_msg *msg = xfer->priv;553 struct scmi_vio_msg *msg = xfer->priv;
353 554
354 if (msg) {555 if (msg)
355 msg_fetch_response(msg->input, msg->rx_len, xfer);556 msg_fetch_response(msg->input, msg->rx_len, xfer);
356 xfer->priv = NULL;
357 }
358}557}
359 558
360static void virtio_fetch_notification(struct scmi_chan_info *cinfo,559static 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
362{561{
363 struct scmi_vio_msg *msg = xfer->priv;562 struct scmi_vio_msg *msg = xfer->priv;
364 563
365 if (msg) {564 if (msg)
366 msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);565 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 */
603static 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;
368 }620 }
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 */
670static 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;
369}783}
370 784
371static const struct scmi_transport_ops scmi_virtio_ops = {785static const struct scmi_transport_ops scmi_virtio_ops = {
@@ -377,6 +791,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = { · 5 unmodified lines
377 .send_message = virtio_send_message,791 .send_message = virtio_send_message,
378 .fetch_response = virtio_fetch_response,792 .fetch_response = virtio_fetch_response,
379 .fetch_notification = virtio_fetch_notification,793 .fetch_notification = virtio_fetch_notification,
794 .mark_txdone = virtio_mark_txdone,
795 .poll_done = virtio_poll_done,
380};796};
381 797
382static int scmi_vio_probe(struct virtio_device *vdev)798static int scmi_vio_probe(struct virtio_device *vdev)
@@ -417,8 +833,10 @@ static int scmi_vio_probe(struct virtio_device *vdev) · 34 unmodified lines
417 unsigned int sz;833 unsigned int sz;
418 834
419 spin_lock_init(&channels[i].lock);835 spin_lock_init(&channels[i].lock);
420 spin_lock_init(&channels[i].ready_lock);836 spin_lock_init(&channels[i].free_lock);
421 INIT_LIST_HEAD(&channels[i].free_list);837 INIT_LIST_HEAD(&channels[i].free_list);
838 spin_lock_init(&channels[i].pending_lock);
839 INIT_LIST_HEAD(&channels[i].pending_cmds_list);
422 channels[i].vqueue = vqs[i];840 channels[i].vqueue = vqs[i];
423 841
424 sz = virtqueue_get_vring_size(channels[i].vqueue);842 sz = virtqueue_get_vring_size(channels[i].vqueue);
@@ -427,10 +845,10 @@ static int scmi_vio_probe(struct virtio_device *vdev) · 2 unmodified lines
427 sz /= DESCRIPTORS_PER_TX_MSG;845 sz /= DESCRIPTORS_PER_TX_MSG;
428 846
429 if (sz > MSG_TOKEN_MAX) {847 if (sz > MSG_TOKEN_MAX) {
430 dev_info_once(dev,848 dev_info(dev,
431 "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",849 "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
432 channels[i].is_rx ? "rx" : "tx",850 channels[i].is_rx ? "rx" : "tx",
433 sz, MSG_TOKEN_MAX);851 sz, MSG_TOKEN_MAX);
434 sz = MSG_TOKEN_MAX;852 sz = MSG_TOKEN_MAX;
435 }853 }
436 channels[i].max_msg = sz;854 channels[i].max_msg = sz;
@@ -460,12 +878,13 @@ static void scmi_vio_remove(struct virtio_device *vdev) · 23 unmodified lines
460 878
461static int scmi_vio_validate(struct virtio_device *vdev)879static int scmi_vio_validate(struct virtio_device *vdev)
462{880{
881#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
463 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {882 if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
464 dev_err(&vdev->dev,883 dev_err(&vdev->dev,
465 "device does not comply with spec version 1.x\n");884 "device does not comply with spec version 1.x\n");
466 return -EINVAL;885 return -EINVAL;
467 }886 }
468 887#endif
469 return 0;888 return 0;
470}889}
471 890
@@ -503,7 +922,9 @@ const struct scmi_desc scmi_virtio_desc = { · 31 unmodified lines
503 .transport_init = virtio_scmi_init,922 .transport_init = virtio_scmi_init,
504 .transport_exit = virtio_scmi_exit,923 .transport_exit = virtio_scmi_exit,
505 .ops = &scmi_virtio_ops,924 .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,
507 .max_msg = 0, /* overridden by virtio_get_max_msg() */927 .max_msg = 0, /* overridden by virtio_get_max_msg() */
508 .max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,928 .max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
929 .atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
509};930};
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
43 return hdr->func;43 return hdr->func;
44}44}
45EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);45EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
46
47struct 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 */
68int 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}
90EXPORT_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
155 { "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },155 { "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
156 { "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },156 { "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
157 { "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },157 { "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 },
158 162
159 /* GPU SS */163 /* GPU SS */
160 { "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },164 { "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
49 __le64 mem_size;49 __le64 mem_size;
50};50};
51 51
52#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x0052/* Each bit configures cold/warm boot address for one of the 4 CPUs */
53#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x0153static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
54#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x0854 0, BIT(0), BIT(3), BIT(5)
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
62struct qcom_scm_wb_entry {
63 int flag;
64 void *entry;
65};55};
66 56static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
67static struct qcom_scm_wb_entry qcom_scm_wb[] = {57 BIT(2), BIT(1), BIT(4), BIT(6)
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 },
72};58};
73 59
74static const char * const qcom_scm_convention_names[] = {60static const char * const qcom_scm_convention_names[] = {
@@ -179,9 +165,8 @@ found: · 104 unmodified lines
179/**165/**
180 * qcom_scm_call() - Invoke a syscall in the secure world166 * qcom_scm_call() - Invoke a syscall in the secure world
181 * @dev: device167 * @dev: device
182 * @svc_id: service identifier
183 * @cmd_id: command identifier
184 * @desc: Descriptor structure containing arguments and return values168 * @desc: Descriptor structure containing arguments and return values
169 * @res: Structure containing results from SMC/HVC call
185 *170 *
186 * Sends a command to the SCM and waits for the command to finish processing.171 * Sends a command to the SCM and waits for the command to finish processing.
187 * This should *only* be called in pre-emptible context.172 * 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
205/**190/**
206 * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()191 * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
207 * @dev: device192 * @dev: device
208 * @svc_id: service identifier
209 * @cmd_id: command identifier
210 * @desc: Descriptor structure containing arguments and return values193 * @desc: Descriptor structure containing arguments and return values
211 * @res: Structure containing results from SMC/HVC call194 * @res: Structure containing results from SMC/HVC call
212 *195 *
@@ -260,97 +243,83 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id, · 47 unmodified lines
260 return ret ? false : !!res.result[0];243 return ret ? false : !!res.result[0];
261}244}
262 245
263/**246static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits)
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 */
271int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
272{247{
273 int ret;
274 int flags = 0;
275 int cpu;248 int cpu;
249 unsigned int flags = 0;
276 struct qcom_scm_desc desc = {250 struct qcom_scm_desc desc = {
277 .svc = QCOM_SCM_SVC_BOOT,251 .svc = QCOM_SCM_SVC_BOOT,
278 .cmd = QCOM_SCM_BOOT_SET_ADDR,252 .cmd = QCOM_SCM_BOOT_SET_ADDR,
279 .arginfo = QCOM_SCM_ARGS(2),253 .arginfo = QCOM_SCM_ARGS(2),
254 .owner = ARM_SMCCC_OWNER_SIP,
280 };255 };
281 256
282 /*257 for_each_present_cpu(cpu) {
283 * Reassign only if we are switching from hotplug entry point258 if (cpu >= QCOM_SCM_BOOT_MAX_CPUS)
284 * to cpuidle entry point or vice versa.259 return -EINVAL;
285 */260 flags |= cpu_bits[cpu];
286 for_each_cpu(cpu, cpus) {
287 if (entry == qcom_scm_wb[cpu].entry)
288 continue;
289 flags |= qcom_scm_wb[cpu].flag;
290 }261 }
291 262
292 /* No change in entry function */
293 if (!flags)
294 return 0;
295
296 desc.args[0] = flags;263 desc.args[0] = flags;
297 desc.args[1] = virt_to_phys(entry);264 desc.args[1] = virt_to_phys(entry);
298 265
299 ret = qcom_scm_call(__scm->dev, &desc, NULL);266 return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
300 if (!ret) {
301 for_each_cpu(cpu, cpus)
302 qcom_scm_wb[cpu].entry = entry;
303 }
304
305 return ret;
306}267}
307EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
308 268
309/**269static int qcom_scm_set_boot_addr_mc(void *entry, unsigned int flags)
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 */
317int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
318{270{
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 };
327 struct qcom_scm_desc desc = {271 struct qcom_scm_desc desc = {
328 .svc = QCOM_SCM_SVC_BOOT,272 .svc = QCOM_SCM_SVC_BOOT,
329 .cmd = QCOM_SCM_BOOT_SET_ADDR,273 .cmd = QCOM_SCM_BOOT_SET_ADDR_MC,
330 .arginfo = QCOM_SCM_ARGS(2),
331 .owner = ARM_SMCCC_OWNER_SIP,274 .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 },
332 };282 };
333 283
334 if (!cpus || cpumask_empty(cpus))284 /* Need a device for DMA of the additional arguments */
335 return -EINVAL;285 if (!__scm || __get_convention() == SMC_CONVENTION_LEGACY)
286 return -EOPNOTSUPP;
336 287
337 for_each_cpu(cpu, cpus) {288 return qcom_scm_call(__scm->dev, &desc, NULL);
338 if (cpu < ARRAY_SIZE(scm_cb_flags))289}
339 flags |= scm_cb_flags[cpu];
340 else
341 set_cpu_present(cpu, false);
342 }
343 290
344 desc.args[0] = flags;291/**
345 desc.args[1] = virt_to_phys(entry);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 */
298int 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}
305EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
346 306
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 */
311int 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;
348}317}
349EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);318EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
350 319
351/**320/**
352 * qcom_scm_cpu_power_down() - Power down the cpu321 * qcom_scm_cpu_power_down() - Power down the cpu
353 * @flags - Flags to flush cache322 * @flags: Flags to flush cache
354 *323 *
355 * This is an end point to power down cpu. If there was a pending interrupt,324 * This is an end point to power down cpu. If there was a pending interrupt,
356 * the control would return from this function, otherwise, the cpu jumps to the325 * 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
435 * and optional blob of data used for authenticating the metadata404 * and optional blob of data used for authenticating the metadata
436 * and the rest of the firmware405 * and the rest of the firmware
437 * @size: size of the metadata406 * @size: size of the metadata
407 * @ctx: optional metadata context
438 *408 *
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.
440 */414 */
441int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)415int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
416 struct qcom_scm_pas_metadata *ctx)
442{417{
443 dma_addr_t mdata_phys;418 dma_addr_t mdata_phys;
444 void *mdata_buf;419 void *mdata_buf;
@@ -467,7 +442,7 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) · 22 unmodified lines
467 442
468 ret = qcom_scm_clk_enable();443 ret = qcom_scm_clk_enable();
469 if (ret)444 if (ret)
470 goto free_metadata;445 goto out;
471 446
472 desc.args[1] = mdata_phys;447 desc.args[1] = mdata_phys;
473 448
@@ -475,13 +450,36 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) · 1 unmodified line
475 450
476 qcom_scm_clk_disable();451 qcom_scm_clk_disable();
477 452
478free_metadata:453out:
479 dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);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 }
480 461
481 return ret ? : res.result[0];462 return ret ? : res.result[0];
482}463}
483EXPORT_SYMBOL(qcom_scm_pas_init_image);464EXPORT_SYMBOL(qcom_scm_pas_init_image);
484 465
466/**
467 * qcom_scm_pas_metadata_release() - release metadata context
468 * @ctx: metadata context
469 */
470void 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}
481EXPORT_SYMBOL(qcom_scm_pas_metadata_release);
482
485/**483/**
486 * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral484 * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
487 * for firmware loading485 * for firmware loading
@@ -749,12 +747,6 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) · 261 unmodified lines
749 };747 };
750 int ret;748 int ret;
751 749
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
758 ret = qcom_scm_call(__scm->dev, &desc, NULL);750 ret = qcom_scm_call(__scm->dev, &desc, NULL);
759 751
760 /* the pg table has been initialized already, ignore the error */752 /* 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
765}757}
766EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);758EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
767 759
760int 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}
773EXPORT_SYMBOL(qcom_scm_iommu_set_cp_pool_size);
774
768int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,775int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
769 u32 cp_nonpixel_start,776 u32 cp_nonpixel_start,
770 u32 cp_nonpixel_size)777 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
1131}1138}
1132EXPORT_SYMBOL(qcom_scm_hdcp_req);1139EXPORT_SYMBOL(qcom_scm_hdcp_req);
1133 1140
1141int 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}
1155EXPORT_SYMBOL(qcom_scm_iommu_set_pt_format);
1156
1134int qcom_scm_qsmmu500_wait_safe_toggle(bool en)1157int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
1135{1158{
1136 struct qcom_scm_desc desc = {1159 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
78#define QCOM_SCM_BOOT_SET_ADDR 0x0178#define QCOM_SCM_BOOT_SET_ADDR 0x01
79#define QCOM_SCM_BOOT_TERMINATE_PC 0x0279#define QCOM_SCM_BOOT_TERMINATE_PC 0x02
80#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x1080#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10
81#define QCOM_SCM_BOOT_SET_ADDR_MC 0x11
81#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a82#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
82#define QCOM_SCM_FLUSH_FLAG_MASK 0x383#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)
83 88
84#define QCOM_SCM_SVC_PIL 0x0289#define QCOM_SCM_SVC_PIL 0x02
85#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x0190#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
100#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02105#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02
101#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03106#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03
102#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04107#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04
108#define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05
103#define QCOM_SCM_MP_VIDEO_VAR 0x08109#define QCOM_SCM_MP_VIDEO_VAR 0x08
104#define QCOM_SCM_MP_ASSIGN 0x16110#define QCOM_SCM_MP_ASSIGN 0x16
105 111
@@ -119,6 +125,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, · 13 unmodified lines
119#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10125#define QCOM_SCM_LMH_LIMIT_DCVSH 0x10
120 126
121#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15127#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15
128#define QCOM_SCM_SMMU_PT_FORMAT 0x01
122#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03129#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03
123#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02130#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02
124 131
drivers/firmware/ti_sci.c+1−1
@@ -3412,7 +3412,7 @@ static int ti_sci_probe(struct platform_device *pdev) · 3411 unmodified lines
3412 ret = register_restart_handler(&info->nb);3412 ret = register_restart_handler(&info->nb);
3413 if (ret) {3413 if (ret) {
3414 dev_err(dev, "reboot registration fail(%d)\n", ret);3414 dev_err(dev, "reboot registration fail(%d)\n", ret);
3415 return ret;3415 goto out;
3416 }3416 }
3417 }3417 }
3418 3418
drivers/memory/brcmstb_dpfe.c+1−1
@@ -424,7 +424,7 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv) · 423 unmodified lines
424 424
425 /*425 /*
426 * It depends on the API version which MBOX register we have to write to426 * 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.
428 */428 */
429 release_mbox = (priv->dpfe_api->version < 2)429 release_mbox = (priv->dpfe_api->version < 2)
430 ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX;430 ? 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
1025 temp = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);1025 temp = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
1026 dev_info = devm_kzalloc(dev, sizeof(*dev_info), GFP_KERNEL);1026 dev_info = devm_kzalloc(dev, sizeof(*dev_info), GFP_KERNEL);
1027 1027
1028 if (!emif || !pd || !dev_info) {1028 if (!emif || !temp || !dev_info) {
1029 dev_err(dev, "%s:%d: allocation error\n", __func__, __LINE__);1029 dev_err(dev, "%s:%d: allocation error\n", __func__, __LINE__);
1030 goto error;1030 goto error;
1031 }1031 }
@@ -1117,7 +1117,7 @@ static int __init_or_module emif_probe(struct platform_device *pdev) · 85 unmodified lines
1117{1117{
1118 struct emif_data *emif;1118 struct emif_data *emif;
1119 struct resource *res;1119 struct resource *res;
1120 int irq;1120 int irq, ret;
1121 1121
1122 if (pdev->dev.of_node)1122 if (pdev->dev.of_node)
1123 emif = of_get_memory_device_details(pdev->dev.of_node, &pdev->dev);1123 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
1147 emif_onetime_settings(emif);1147 emif_onetime_settings(emif);
1148 emif_debugfs_init(emif);1148 emif_debugfs_init(emif);
1149 disable_and_clear_all_interrupts(emif);1149 disable_and_clear_all_interrupts(emif);
1150 setup_interrupts(emif, irq);1150 ret = setup_interrupts(emif, irq);
1151 if (ret)
1152 goto error;
1151 1153
1152 /* One-time actions taken on probing the first device */1154 /* One-time actions taken on probing the first device */
1153 if (!emif1) {1155 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
88{88{
89 struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(&dev->dev);89 struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(&dev->dev);
90 90
91 of_platform_depopulate(&dev->dev);
91 free_irq(ctrl->nand_irq, ctrl);92 free_irq(ctrl->nand_irq, ctrl);
92 free_irq(ctrl->irq, ctrl);93 free_irq(ctrl->irq, ctrl);
93 94
@@ -285,8 +286,16 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) · 191 unmodified lines
285 }286 }
286 }287 }
287 288
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
288 return 0;295 return 0;
289 296
297err_free_nandirq:
298 free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev);
290err_free_irq:299err_free_irq:
291 free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev);300 free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev);
292err_unmap_nandirq:301err_unmap_nandirq:
drivers/memory/mtk-smi.c+53−4
@@ -8,6 +8,7 @@ · 7 unmodified lines
8#include <linux/device.h>8#include <linux/device.h>
9#include <linux/err.h>9#include <linux/err.h>
10#include <linux/io.h>10#include <linux/io.h>
11#include <linux/iopoll.h>
11#include <linux/module.h>12#include <linux/module.h>
12#include <linux/of.h>13#include <linux/of.h>
13#include <linux/of_platform.h>14#include <linux/of_platform.h>
@@ -32,6 +33,10 @@ · 18 unmodified lines
32#define SMI_DUMMY 0x44433#define SMI_DUMMY 0x444
33 34
34/* SMI LARB */35/* SMI LARB */
36#define SMI_LARB_SLP_CON 0xc
37#define SLP_PROT_EN BIT(0)
38#define SLP_PROT_RDY BIT(16)
39
35#define SMI_LARB_CMD_THRT_CON 0x2440#define SMI_LARB_CMD_THRT_CON 0x24
36#define SMI_LARB_THRT_RD_NU_LMT_MSK GENMASK(7, 4)41#define SMI_LARB_THRT_RD_NU_LMT_MSK GENMASK(7, 4)
37#define SMI_LARB_THRT_RD_NU_LMT (5 << 4)42#define SMI_LARB_THRT_RD_NU_LMT (5 << 4)
@@ -81,6 +86,7 @@ · 43 unmodified lines
81 86
82#define MTK_SMI_FLAG_THRT_UPDATE BIT(0)87#define MTK_SMI_FLAG_THRT_UPDATE BIT(0)
83#define MTK_SMI_FLAG_SW_FLAG BIT(1)88#define MTK_SMI_FLAG_SW_FLAG BIT(1)
89#define MTK_SMI_FLAG_SLEEP_CTL BIT(2)
84#define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x)))90#define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x)))
85 91
86struct mtk_smi_reg_pair {92struct mtk_smi_reg_pair {
@@ -94,8 +100,6 @@ enum mtk_smi_type { · 7 unmodified lines
94 MTK_SMI_GEN2_SUB_COMM, /* gen2 smi sub common */100 MTK_SMI_GEN2_SUB_COMM, /* gen2 smi sub common */
95};101};
96 102
97#define MTK_SMI_CLK_NR_MAX 4
98
99/* larbs: Require apb/smi clocks while gals is optional. */103/* larbs: Require apb/smi clocks while gals is optional. */
100static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"};104static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"};
101#define MTK_SMI_LARB_REQ_CLK_NR 2105#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
106 * sub common: Require apb/smi/gals0 clocks in has_gals case. Otherwise, only apb/smi are required.110 * sub common: Require apb/smi/gals0 clocks in has_gals case. Otherwise, only apb/smi are required.
107 */111 */
108static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"};112static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"};
113#define MTK_SMI_CLK_NR_MAX ARRAY_SIZE(mtk_smi_common_clks)
109#define MTK_SMI_COM_REQ_CLK_NR 2114#define MTK_SMI_COM_REQ_CLK_NR 2
110#define MTK_SMI_COM_GALS_REQ_CLK_NR MTK_SMI_CLK_NR_MAX115#define MTK_SMI_COM_GALS_REQ_CLK_NR MTK_SMI_CLK_NR_MAX
111#define MTK_SMI_SUB_COM_GALS_REQ_CLK_NR 3116#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
335 /* IPU0 | IPU1 | CCU */340 /* IPU0 | IPU1 | CCU */
336};341};
337 342
343static 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
338static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {348static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
339 .config_port = mtk_smi_larb_config_port_gen2_general,349 .config_port = mtk_smi_larb_config_port_gen2_general,
340};350};
341 351
342static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {352static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
343 .config_port = mtk_smi_larb_config_port_gen2_general,353 .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,
345 .ostd = mtk_smi_larb_mt8195_ostd,356 .ostd = mtk_smi_larb_mt8195_ostd,
346};357};
347 358
@@ -352,11 +363,32 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { · 4 unmodified lines
352 {.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},363 {.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
353 {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},364 {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
354 {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},365 {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
366 {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
355 {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},367 {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
356 {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},368 {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
357 {}369 {}
358};370};
359 371
372static 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
387static 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
360static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)392static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
361{393{
362 struct platform_device *smi_com_pdev;394 struct platform_device *smi_com_pdev;
@@ -466,9 +498,12 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) · 103 unmodified lines
466 int ret;498 int ret;
467 499
468 ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);500 ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
469 if (ret < 0)501 if (ret)
470 return ret;502 return ret;
471 503
504 if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
505 mtk_smi_larb_sleep_ctrl_disable(larb);
506
472 /* Configure the basic setting for this larb */507 /* Configure the basic setting for this larb */
473 larb_gen->config_port(dev);508 larb_gen->config_port(dev);
474 509
@@ -478,6 +513,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) · 3 unmodified lines
478static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)513static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
479{514{
480 struct mtk_smi_larb *larb = dev_get_drvdata(dev);515 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 }
481 523
482 clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);524 clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
483 return 0;525 return 0;
@@ -530,6 +572,12 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = { · 46 unmodified lines
530 F_MMU1_LARB(7),572 F_MMU1_LARB(7),
531};573};
532 574
575static 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
533static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {581static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
534 .type = MTK_SMI_GEN2,582 .type = MTK_SMI_GEN2,
535 .has_gals = true,583 .has_gals = true,
@@ -564,6 +612,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { · 28 unmodified lines
564 {.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},612 {.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
565 {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},613 {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
566 {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},614 {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
615 {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
567 {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},616 {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
568 {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},617 {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
569 {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},618 {.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
212{212{
213 int ret;213 int ret;
214 214
215 /* The 'reg' param required since DT has changed, used as 'max-freq' */215 ret = of_property_read_u32(np, "max-freq", &tim->max_freq);
216 ret = of_property_read_u32(np, "reg", &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);
217 ret |= of_property_read_u32(np, "min-freq", &tim->min_freq);219 ret |= of_property_read_u32(np, "min-freq", &tim->min_freq);
218 ret |= of_property_read_u32(np, "tRFC", &tim->tRFC);220 ret |= of_property_read_u32(np, "tRFC", &tim->tRFC);
219 ret |= of_property_read_u32(np, "tRRD", &tim->tRRD);221 ret |= of_property_read_u32(np, "tRRD", &tim->tRRD);
@@ -316,14 +318,21 @@ const struct lpddr2_info · 96 unmodified lines
316 struct property *prop;318 struct property *prop;
317 const char *cp;319 const char *cp;
318 int err;320 int err;
319 321 u32 revision_id[2];
320 err = of_property_read_u32(np, "revision-id1", &info.revision_id1);322
321 if (err)323 err = of_property_read_u32_array(np, "revision-id", revision_id, 2);
322 info.revision_id1 = -ENOENT;324 if (!err) {
323 325 info.revision_id1 = revision_id[0];
324 err = of_property_read_u32(np, "revision-id2", &info.revision_id2);326 info.revision_id2 = revision_id[1];
325 if (err)327 } else {
326 info.revision_id2 = -ENOENT;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 }
327 336
328 err = of_property_read_u32(np, "io-width", &info.io_width);337 err = of_property_read_u32(np, "io-width", &info.io_width);
329 if (err)338 if (err)
drivers/memory/tegra/Kconfig+1−0
@@ -28,6 +28,7 @@ config TEGRA30_EMC · 27 unmodified lines
28 default y28 default y
29 depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST29 depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST
30 select PM_OPP30 select PM_OPP
31 select DDR
31 help32 help
32 This driver is for the External Memory Controller (EMC) found on33 This driver is for the External Memory Controller (EMC) found on
33 Tegra30 chips. The EMC controls the external DRAM on the board.34 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
540 unsigned int register_addr,540 unsigned int register_addr,
541 unsigned int *register_data)541 unsigned int *register_data)
542{542{
543 u32 memory_dev = emem_dev + 1;543 u32 memory_dev = emem_dev ? 1 : 2;
544 u32 val, mr_mask = 0xff;544 u32 val, mr_mask = 0xff;
545 int err;545 int err;
546 546
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
711 return 0;711 return 0;
712}712}
713 713
714static struct thermal_cooling_device_ops tegra210_emc_cd_ops = {714static const struct thermal_cooling_device_ops tegra210_emc_cd_ops = {
715 .get_max_state = tegra210_emc_cd_max_state,715 .get_max_state = tegra210_emc_cd_max_state,
716 .get_cur_state = tegra210_emc_cd_get_state,716 .get_cur_state = tegra210_emc_cd_get_state,
717 .set_cur_state = tegra210_emc_cd_set_state,717 .set_cur_state = tegra210_emc_cd_set_state,
drivers/memory/tegra/tegra30-emc.c+121−10
@@ -9,6 +9,7 @@ · 8 unmodified lines
9 * Copyright (C) 2019 GRATE-DRIVER project9 * Copyright (C) 2019 GRATE-DRIVER project
10 */10 */
11 11
12#include <linux/bitfield.h>
12#include <linux/clk.h>13#include <linux/clk.h>
13#include <linux/clk/tegra.h>14#include <linux/clk/tegra.h>
14#include <linux/debugfs.h>15#include <linux/debugfs.h>
@@ -31,11 +32,15 @@ · 16 unmodified lines
31#include <soc/tegra/common.h>32#include <soc/tegra/common.h>
32#include <soc/tegra/fuse.h>33#include <soc/tegra/fuse.h>
33 34
35#include "../jedec_ddr.h"
36#include "../of_memory.h"
37
34#include "mc.h"38#include "mc.h"
35 39
36#define EMC_INTSTATUS 0x00040#define EMC_INTSTATUS 0x000
37#define EMC_INTMASK 0x00441#define EMC_INTMASK 0x004
38#define EMC_DBG 0x00842#define EMC_DBG 0x008
43#define EMC_ADR_CFG 0x010
39#define EMC_CFG 0x00c44#define EMC_CFG 0x00c
40#define EMC_REFCTRL 0x02045#define EMC_REFCTRL 0x020
41#define EMC_TIMING_CONTROL 0x02846#define EMC_TIMING_CONTROL 0x028
@@ -81,6 +86,7 @@ · 39 unmodified lines
81#define EMC_EMRS 0x0d086#define EMC_EMRS 0x0d0
82#define EMC_SELF_REF 0x0e087#define EMC_SELF_REF 0x0e0
83#define EMC_MRW 0x0e888#define EMC_MRW 0x0e8
89#define EMC_MRR 0x0ec
84#define EMC_XM2DQSPADCTRL3 0x0f890#define EMC_XM2DQSPADCTRL3 0x0f8
85#define EMC_FBIO_SPARE 0x10091#define EMC_FBIO_SPARE 0x100
86#define EMC_FBIO_CFG5 0x10492#define EMC_FBIO_CFG5 0x104
@@ -208,6 +214,13 @@ · 121 unmodified lines
208 214
209#define EMC_REFRESH_OVERFLOW_INT BIT(3)215#define EMC_REFRESH_OVERFLOW_INT BIT(3)
210#define EMC_CLKCHANGE_COMPLETE_INT BIT(4)216#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)
211 224
212enum emc_dram_type {225enum emc_dram_type {
213 DRAM_TYPE_DDR3,226 DRAM_TYPE_DDR3,
@@ -378,6 +391,8 @@ struct tegra_emc { · 164 unmodified lines
378 391
379 /* protect shared rate-change code path */392 /* protect shared rate-change code path */
380 struct mutex rate_lock;393 struct mutex rate_lock;
394
395 bool mrr_error;
381};396};
382 397
383static int emc_seq_update_timing(struct tegra_emc *emc)398static 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
1008 return 0;1023 return 0;
1009}1024}
1010 1025
1011static struct device_node *emc_find_node_by_ram_code(struct device *dev)1026static struct device_node *emc_find_node_by_ram_code(struct tegra_emc *emc)
1012{1027{
1028 struct device *dev = emc->dev;
1013 struct device_node *np;1029 struct device_node *np;
1014 u32 value, ram_code;1030 u32 value, ram_code;
1015 int err;1031 int err;
1016 1032
1033 if (emc->mrr_error) {
1034 dev_warn(dev, "memory timings skipped due to MRR error\n");
1035 return NULL;
1036 }
1037
1017 if (of_get_child_count(dev->of_node) == 0) {1038 if (of_get_child_count(dev->of_node) == 0) {
1018 dev_info_once(dev, "device-tree doesn't have memory timings\n");1039 dev_info_once(dev, "device-tree doesn't have memory timings\n");
1019 return NULL;1040 return NULL;
@@ -1035,11 +1056,73 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev) · 15 unmodified lines
1035 return NULL;1056 return NULL;
1036}1057}
1037 1058
1059static 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
1095static 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
1038static int emc_setup_hw(struct tegra_emc *emc)1118static int emc_setup_hw(struct tegra_emc *emc)
1039{1119{
1120 u32 fbio_cfg5, emc_cfg, emc_dbg, emc_adr_cfg;
1040 u32 intmask = EMC_REFRESH_OVERFLOW_INT;1121 u32 intmask = EMC_REFRESH_OVERFLOW_INT;
1041 u32 fbio_cfg5, emc_cfg, emc_dbg;1122 static bool print_sdram_info_once;
1042 enum emc_dram_type dram_type;1123 enum emc_dram_type dram_type;
1124 const char *dram_type_str;
1125 unsigned int emem_numdev;
1043 1126
1044 fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5);1127 fbio_cfg5 = readl_relaxed(emc->regs + EMC_FBIO_CFG5);
1045 dram_type = fbio_cfg5 & EMC_FBIO_CFG5_DRAM_TYPE_MASK;1128 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
1076 emc_dbg &= ~EMC_DBG_FORCE_UPDATE;1159 emc_dbg &= ~EMC_DBG_FORCE_UPDATE;
1077 writel_relaxed(emc_dbg, emc->regs + EMC_DBG);1160 writel_relaxed(emc_dbg, emc->regs + EMC_DBG);
1078 1161
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
1079 return 0;1190 return 0;
1080}1191}
1081 1192
@@ -1538,14 +1649,6 @@ static int tegra_emc_probe(struct platform_device *pdev) · 456 unmodified lines
1538 emc->clk_nb.notifier_call = emc_clk_change_notify;1649 emc->clk_nb.notifier_call = emc_clk_change_notify;
1539 emc->dev = &pdev->dev;1650 emc->dev = &pdev->dev;
1540 1651
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
1549 emc->regs = devm_platform_ioremap_resource(pdev, 0);1652 emc->regs = devm_platform_ioremap_resource(pdev, 0);
1550 if (IS_ERR(emc->regs))1653 if (IS_ERR(emc->regs))
1551 return PTR_ERR(emc->regs);1654 return PTR_ERR(emc->regs);
@@ -1554,6 +1657,14 @@ static int tegra_emc_probe(struct platform_device *pdev) · 2 unmodified lines
1554 if (err)1657 if (err)
1555 return err;1658 return err;
1556 1659
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
1557 err = platform_get_irq(pdev, 0);1668 err = platform_get_irq(pdev, 0);
1558 if (err < 0)1669 if (err < 0)
1559 return err;1670 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
928 regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);928 regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
929}929}
930 930
931static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)931static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw,
932 const char *fw_name)
932{933{
933 unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;934 unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
934 dma_addr_t phys;935 dma_addr_t phys;
@@ -939,7 +940,7 @@ static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) · 4 unmodified lines
939 void *ptr;940 void *ptr;
940 int ret;941 int ret;
941 942
942 metadata = qcom_mdt_read_metadata(fw, &size);943 metadata = qcom_mdt_read_metadata(fw, &size, fw_name, qproc->dev);
943 if (IS_ERR(metadata))944 if (IS_ERR(metadata))
944 return PTR_ERR(metadata);945 return PTR_ERR(metadata);
945 946
@@ -1289,7 +1290,7 @@ static int q6v5_mpss_load(struct q6v5 *qproc) · 343 unmodified lines
1289 /* Initialize the RMB validator */1290 /* Initialize the RMB validator */
1290 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);1291 writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG);
1291 1292
1292 ret = q6v5_mpss_init_image(qproc, fw);1293 ret = q6v5_mpss_init_image(qproc, fw, qproc->hexagon_mdt_image);
1293 if (ret)1294 if (ret)
1294 goto release_firmware;1295 goto release_firmware;
1295 1296
drivers/remoteproc/qcom_q6v5_pas.c+33−3
@@ -79,6 +79,8 @@ struct qcom_adsp { · 78 unmodified lines
79 struct qcom_rproc_subdev smd_subdev;79 struct qcom_rproc_subdev smd_subdev;
80 struct qcom_rproc_ssr ssr_subdev;80 struct qcom_rproc_ssr ssr_subdev;
81 struct qcom_sysmon *sysmon;81 struct qcom_sysmon *sysmon;
82
83 struct qcom_scm_pas_metadata pas_metadata;
82};84};
83 85
84static void adsp_minidump(struct rproc *rproc)86static 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
126 }128 }
127}129}
128 130
131static 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
129static int adsp_load(struct rproc *rproc, const struct firmware *fw)146static int adsp_load(struct rproc *rproc, const struct firmware *fw)
130{147{
131 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;148 struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
132 int ret;149 int ret;
133 150
134 ret = qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,151 ret = qcom_mdt_pas_init(adsp->dev, fw, rproc->firmware, adsp->pas_id,
135 adsp->mem_region, adsp->mem_phys, adsp->mem_size,152 adsp->mem_phys, &adsp->pas_metadata);
136 &adsp->mem_reloc);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);
137 if (ret)159 if (ret)
138 return ret;160 return ret;
139 161
@@ -185,6 +207,8 @@ static int adsp_start(struct rproc *rproc) · 45 unmodified lines
185 goto disable_px_supply;207 goto disable_px_supply;
186 }208 }
187 209
210 qcom_scm_pas_metadata_release(&adsp->pas_metadata);
211
188 return 0;212 return 0;
189 213
190disable_px_supply:214disable_px_supply:
@@ -255,6 +279,7 @@ static unsigned long adsp_panic(struct rproc *rproc) · 64 unmodified lines
255}279}
256 280
257static const struct rproc_ops adsp_ops = {281static const struct rproc_ops adsp_ops = {
282 .unprepare = adsp_unprepare,
258 .start = adsp_start,283 .start = adsp_start,
259 .stop = adsp_stop,284 .stop = adsp_stop,
260 .da_to_va = adsp_da_to_va,285 .da_to_va = adsp_da_to_va,
@@ -264,6 +289,7 @@ static const struct rproc_ops adsp_ops = { · 3 unmodified lines
264};289};
265 290
266static const struct rproc_ops adsp_minidump_ops = {291static const struct rproc_ops adsp_minidump_ops = {
292 .unprepare = adsp_unprepare,
267 .start = adsp_start,293 .start = adsp_start,
268 .stop = adsp_stop,294 .stop = adsp_stop,
269 .da_to_va = adsp_da_to_va,295 .da_to_va = adsp_da_to_va,
@@ -853,6 +879,10 @@ static const struct of_device_id adsp_of_match[] = { · 583 unmodified lines
853 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},879 { .compatible = "qcom,sm8350-cdsp-pas", .data = &sm8350_cdsp_resource},
854 { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},880 { .compatible = "qcom,sm8350-slpi-pas", .data = &sm8350_slpi_resource},
855 { .compatible = "qcom,sm8350-mpss-pas", .data = &mpss_resource_init},881 { .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},
856 { },886 { },
857};887};
858MODULE_DEVICE_TABLE(of, adsp_of_match);888MODULE_DEVICE_TABLE(of, adsp_of_match);
drivers/soc/amlogic/meson-secure-pwrc.c+22−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/platform_device.h>11#include <linux/platform_device.h>
12#include <linux/pm_domain.h>12#include <linux/pm_domain.h>
13#include <dt-bindings/power/meson-a1-power.h>13#include <dt-bindings/power/meson-a1-power.h>
14#include <dt-bindings/power/meson-s4-power.h>
14#include <linux/arm-smccc.h>15#include <linux/arm-smccc.h>
15#include <linux/firmware/meson/meson_sm.h>16#include <linux/firmware/meson/meson_sm.h>
16#include <linux/module.h>17#include <linux/module.h>
@@ -119,6 +120,18 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = { · 102 unmodified lines
119 SEC_PD(RSA, 0),120 SEC_PD(RSA, 0),
120};121};
121 122
123static 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
122static int meson_secure_pwrc_probe(struct platform_device *pdev)135static int meson_secure_pwrc_probe(struct platform_device *pdev)
123{136{
124 int i;137 int i;
@@ -187,11 +200,20 @@ static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = { · 62 unmodified lines
187 .count = ARRAY_SIZE(a1_pwrc_domains),200 .count = ARRAY_SIZE(a1_pwrc_domains),
188};201};
189 202
203static 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
190static const struct of_device_id meson_secure_pwrc_match_table[] = {208static const struct of_device_id meson_secure_pwrc_match_table[] = {
191 {209 {
192 .compatible = "amlogic,meson-a1-pwrc",210 .compatible = "amlogic,meson-a1-pwrc",
193 .data = &meson_secure_a1_pwrc_data,211 .data = &meson_secure_a1_pwrc_data,
194 },212 },
213 {
214 .compatible = "amlogic,meson-s4-pwrc",
215 .data = &meson_secure_s4_pwrc_data,
216 },
195 { /* sentinel */ }217 { /* sentinel */ }
196};218};
197MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table);219MODULE_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
156 AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK,156 AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
157 AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH,157 AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH,
158 "sama5d28c 256MiB LPDDR2 SiP", "sama5d2"),158 "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"),
159 AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK,162 AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
160 AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH,163 AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH,
161 "sama5d31", "sama5d3"),164 "sama5d31", "sama5d3"),
drivers/soc/atmel/soc.h+1−0
@@ -95,6 +95,7 @@ at91_soc_init(const struct at91_soc *socs); · 94 unmodified lines
95#define SAMA5D28C_LD2G_EXID_MATCH 0x0000007295#define SAMA5D28C_LD2G_EXID_MATCH 0x00000072
96#define SAMA5D28CU_EXID_MATCH 0x0000001096#define SAMA5D28CU_EXID_MATCH 0x00000010
97#define SAMA5D28CN_EXID_MATCH 0x0000002097#define SAMA5D28CN_EXID_MATCH 0x00000020
98#define SAMA5D29CN_EXID_MATCH 0x00000023
98 99
99#define SAMA5D3_CIDR_MATCH 0x0a5c07c0100#define SAMA5D3_CIDR_MATCH 0x0a5c07c0
100#define SAMA5D31_EXID_MATCH 0x00444300101#define SAMA5D31_EXID_MATCH 0x00444300
drivers/soc/imx/imx8m-blk-ctrl.c+66−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
15 15
16#include <dt-bindings/power/imx8mm-power.h>16#include <dt-bindings/power/imx8mm-power.h>
17#include <dt-bindings/power/imx8mn-power.h>17#include <dt-bindings/power/imx8mn-power.h>
18#include <dt-bindings/power/imx8mq-power.h>
18 19
19#define BLK_SFT_RSTN 0x020#define BLK_SFT_RSTN 0x0
20#define BLK_CLK_EN 0x421#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
589 .num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),590 .num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
590};591};
591 592
593static 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
629static 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
648static 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
592static const struct of_device_id imx8m_blk_ctrl_of_match[] = {655static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
593 {656 {
594 .compatible = "fsl,imx8mm-vpu-blk-ctrl",657 .compatible = "fsl,imx8mm-vpu-blk-ctrl",
@@ -599,6 +662,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = { · 4 unmodified lines
599 }, {662 }, {
600 .compatible = "fsl,imx8mn-disp-blk-ctrl",663 .compatible = "fsl,imx8mn-disp-blk-ctrl",
601 .data = &imx8mn_disp_blk_ctl_dev_data664 .data = &imx8mn_disp_blk_ctl_dev_data
665 }, {
666 .compatible = "fsl,imx8mq-vpu-blk-ctrl",
667 .data = &imx8mq_vpu_blk_ctl_dev_data
602 }, {668 }, {
603 /* Sentinel */669 /* Sentinel */
604 }670 }
drivers/soc/imx/soc-imx.c+0−3
@@ -40,9 +40,6 @@ static int __init imx_soc_device_init(void) · 39 unmodified lines
40 if (!__mxc_cpu_type)40 if (!__mxc_cpu_type)
41 return 0;41 return 0;
42 42
43 if (of_machine_is_compatible("fsl,ls1021a"))
44 return 0;
45
46 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);43 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
47 if (!soc_dev_attr)44 if (!soc_dev_attr)
48 return -ENOMEM;45 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
18 .name = "mm",18 .name = "mm",
19 .sta_mask = PWR_STATUS_DISP,19 .sta_mask = PWR_STATUS_DISP,
20 .ctl_offs = SPM_DIS_PWR_CON,20 .ctl_offs = SPM_DIS_PWR_CON,
21 .pwr_sta_offs = SPM_PWR_STATUS,
22 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
21 .sram_pdn_bits = GENMASK(11, 8),23 .sram_pdn_bits = GENMASK(11, 8),
22 .sram_pdn_ack_bits = GENMASK(12, 12),24 .sram_pdn_ack_bits = GENMASK(12, 12),
23 .bp_infracfg = {25 .bp_infracfg = {
@@ -30,6 +32,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 6 unmodified lines
30 .name = "vdec",32 .name = "vdec",
31 .sta_mask = PWR_STATUS_VDEC,33 .sta_mask = PWR_STATUS_VDEC,
32 .ctl_offs = SPM_VDE_PWR_CON,34 .ctl_offs = SPM_VDE_PWR_CON,
35 .pwr_sta_offs = SPM_PWR_STATUS,
36 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
33 .sram_pdn_bits = GENMASK(8, 8),37 .sram_pdn_bits = GENMASK(8, 8),
34 .sram_pdn_ack_bits = GENMASK(12, 12),38 .sram_pdn_ack_bits = GENMASK(12, 12),
35 .caps = MTK_SCPD_ACTIVE_WAKEUP,39 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -38,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 2 unmodified lines
38 .name = "isp",42 .name = "isp",
39 .sta_mask = PWR_STATUS_ISP,43 .sta_mask = PWR_STATUS_ISP,
40 .ctl_offs = SPM_ISP_PWR_CON,44 .ctl_offs = SPM_ISP_PWR_CON,
45 .pwr_sta_offs = SPM_PWR_STATUS,
46 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
41 .sram_pdn_bits = GENMASK(11, 8),47 .sram_pdn_bits = GENMASK(11, 8),
42 .sram_pdn_ack_bits = GENMASK(13, 12),48 .sram_pdn_ack_bits = GENMASK(13, 12),
43 .caps = MTK_SCPD_ACTIVE_WAKEUP,49 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -46,6 +52,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 2 unmodified lines
46 .name = "mfg_async",52 .name = "mfg_async",
47 .sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,53 .sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
48 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,54 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
55 .pwr_sta_offs = SPM_PWR_STATUS,
56 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
49 .sram_pdn_bits = 0,57 .sram_pdn_bits = 0,
50 .sram_pdn_ack_bits = 0,58 .sram_pdn_ack_bits = 0,
51 .bp_infracfg = {59 .bp_infracfg = {
@@ -57,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 5 unmodified lines
57 .name = "mfg_2d",65 .name = "mfg_2d",
58 .sta_mask = MT8167_PWR_STATUS_MFG_2D,66 .sta_mask = MT8167_PWR_STATUS_MFG_2D,
59 .ctl_offs = SPM_MFG_2D_PWR_CON,67 .ctl_offs = SPM_MFG_2D_PWR_CON,
68 .pwr_sta_offs = SPM_PWR_STATUS,
69 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
60 .sram_pdn_bits = GENMASK(11, 8),70 .sram_pdn_bits = GENMASK(11, 8),
61 .sram_pdn_ack_bits = GENMASK(15, 12),71 .sram_pdn_ack_bits = GENMASK(15, 12),
62 },72 },
@@ -64,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 1 unmodified line
64 .name = "mfg",74 .name = "mfg",
65 .sta_mask = PWR_STATUS_MFG,75 .sta_mask = PWR_STATUS_MFG,
66 .ctl_offs = SPM_MFG_PWR_CON,76 .ctl_offs = SPM_MFG_PWR_CON,
77 .pwr_sta_offs = SPM_PWR_STATUS,
78 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
67 .sram_pdn_bits = GENMASK(11, 8),79 .sram_pdn_bits = GENMASK(11, 8),
68 .sram_pdn_ack_bits = GENMASK(15, 12),80 .sram_pdn_ack_bits = GENMASK(15, 12),
69 },81 },
@@ -71,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 1 unmodified line
71 .name = "conn",83 .name = "conn",
72 .sta_mask = PWR_STATUS_CONN,84 .sta_mask = PWR_STATUS_CONN,
73 .ctl_offs = SPM_CONN_PWR_CON,85 .ctl_offs = SPM_CONN_PWR_CON,
86 .pwr_sta_offs = SPM_PWR_STATUS,
87 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
74 .sram_pdn_bits = GENMASK(8, 8),88 .sram_pdn_bits = GENMASK(8, 8),
75 .sram_pdn_ack_bits = 0,89 .sram_pdn_ack_bits = 0,
76 .caps = MTK_SCPD_ACTIVE_WAKEUP,90 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -85,8 +99,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = { · 8 unmodified lines
85static const struct scpsys_soc_data mt8167_scpsys_data = {99static const struct scpsys_soc_data mt8167_scpsys_data = {
86 .domains_data = scpsys_domain_data_mt8167,100 .domains_data = scpsys_domain_data_mt8167,
87 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),101 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
88 .pwr_sta_offs = SPM_PWR_STATUS,
89 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
90};102};
91 103
92#endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */104#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
15 .name = "vdec",15 .name = "vdec",
16 .sta_mask = PWR_STATUS_VDEC,16 .sta_mask = PWR_STATUS_VDEC,
17 .ctl_offs = SPM_VDE_PWR_CON,17 .ctl_offs = SPM_VDE_PWR_CON,
18 .pwr_sta_offs = SPM_PWR_STATUS,
19 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
18 .sram_pdn_bits = GENMASK(11, 8),20 .sram_pdn_bits = GENMASK(11, 8),
19 .sram_pdn_ack_bits = GENMASK(12, 12),21 .sram_pdn_ack_bits = GENMASK(12, 12),
20 },22 },
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
22 .name = "venc",24 .name = "venc",
23 .sta_mask = PWR_STATUS_VENC,25 .sta_mask = PWR_STATUS_VENC,
24 .ctl_offs = SPM_VEN_PWR_CON,26 .ctl_offs = SPM_VEN_PWR_CON,
27 .pwr_sta_offs = SPM_PWR_STATUS,
28 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
25 .sram_pdn_bits = GENMASK(11, 8),29 .sram_pdn_bits = GENMASK(11, 8),
26 .sram_pdn_ack_bits = GENMASK(15, 12),30 .sram_pdn_ack_bits = GENMASK(15, 12),
27 },31 },
@@ -29,6 +33,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
29 .name = "isp",33 .name = "isp",
30 .sta_mask = PWR_STATUS_ISP,34 .sta_mask = PWR_STATUS_ISP,
31 .ctl_offs = SPM_ISP_PWR_CON,35 .ctl_offs = SPM_ISP_PWR_CON,
36 .pwr_sta_offs = SPM_PWR_STATUS,
37 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
32 .sram_pdn_bits = GENMASK(11, 8),38 .sram_pdn_bits = GENMASK(11, 8),
33 .sram_pdn_ack_bits = GENMASK(13, 12),39 .sram_pdn_ack_bits = GENMASK(13, 12),
34 },40 },
@@ -36,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
36 .name = "mm",42 .name = "mm",
37 .sta_mask = PWR_STATUS_DISP,43 .sta_mask = PWR_STATUS_DISP,
38 .ctl_offs = SPM_DIS_PWR_CON,44 .ctl_offs = SPM_DIS_PWR_CON,
45 .pwr_sta_offs = SPM_PWR_STATUS,
46 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
39 .sram_pdn_bits = GENMASK(11, 8),47 .sram_pdn_bits = GENMASK(11, 8),
40 .sram_pdn_ack_bits = GENMASK(12, 12),48 .sram_pdn_ack_bits = GENMASK(12, 12),
41 .bp_infracfg = {49 .bp_infracfg = {
@@ -47,6 +55,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 5 unmodified lines
47 .name = "venc_lt",55 .name = "venc_lt",
48 .sta_mask = PWR_STATUS_VENC_LT,56 .sta_mask = PWR_STATUS_VENC_LT,
49 .ctl_offs = SPM_VEN2_PWR_CON,57 .ctl_offs = SPM_VEN2_PWR_CON,
58 .pwr_sta_offs = SPM_PWR_STATUS,
59 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
50 .sram_pdn_bits = GENMASK(11, 8),60 .sram_pdn_bits = GENMASK(11, 8),
51 .sram_pdn_ack_bits = GENMASK(15, 12),61 .sram_pdn_ack_bits = GENMASK(15, 12),
52 },62 },
@@ -54,6 +64,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
54 .name = "audio",64 .name = "audio",
55 .sta_mask = PWR_STATUS_AUDIO,65 .sta_mask = PWR_STATUS_AUDIO,
56 .ctl_offs = SPM_AUDIO_PWR_CON,66 .ctl_offs = SPM_AUDIO_PWR_CON,
67 .pwr_sta_offs = SPM_PWR_STATUS,
68 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
57 .sram_pdn_bits = GENMASK(11, 8),69 .sram_pdn_bits = GENMASK(11, 8),
58 .sram_pdn_ack_bits = GENMASK(15, 12),70 .sram_pdn_ack_bits = GENMASK(15, 12),
59 },71 },
@@ -61,6 +73,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
61 .name = "usb",73 .name = "usb",
62 .sta_mask = PWR_STATUS_USB,74 .sta_mask = PWR_STATUS_USB,
63 .ctl_offs = SPM_USB_PWR_CON,75 .ctl_offs = SPM_USB_PWR_CON,
76 .pwr_sta_offs = SPM_PWR_STATUS,
77 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
64 .sram_pdn_bits = GENMASK(11, 8),78 .sram_pdn_bits = GENMASK(11, 8),
65 .sram_pdn_ack_bits = GENMASK(15, 12),79 .sram_pdn_ack_bits = GENMASK(15, 12),
66 .caps = MTK_SCPD_ACTIVE_WAKEUP,80 .caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 2 unmodified lines
69 .name = "mfg_async",83 .name = "mfg_async",
70 .sta_mask = PWR_STATUS_MFG_ASYNC,84 .sta_mask = PWR_STATUS_MFG_ASYNC,
71 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,85 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
86 .pwr_sta_offs = SPM_PWR_STATUS,
87 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
72 .sram_pdn_bits = GENMASK(11, 8),88 .sram_pdn_bits = GENMASK(11, 8),
73 .sram_pdn_ack_bits = 0,89 .sram_pdn_ack_bits = 0,
74 .caps = MTK_SCPD_DOMAIN_SUPPLY,90 .caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -77,6 +93,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 2 unmodified lines
77 .name = "mfg_2d",93 .name = "mfg_2d",
78 .sta_mask = PWR_STATUS_MFG_2D,94 .sta_mask = PWR_STATUS_MFG_2D,
79 .ctl_offs = SPM_MFG_2D_PWR_CON,95 .ctl_offs = SPM_MFG_2D_PWR_CON,
96 .pwr_sta_offs = SPM_PWR_STATUS,
97 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
80 .sram_pdn_bits = GENMASK(11, 8),98 .sram_pdn_bits = GENMASK(11, 8),
81 .sram_pdn_ack_bits = GENMASK(13, 12),99 .sram_pdn_ack_bits = GENMASK(13, 12),
82 },100 },
@@ -84,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 1 unmodified line
84 .name = "mfg",102 .name = "mfg",
85 .sta_mask = PWR_STATUS_MFG,103 .sta_mask = PWR_STATUS_MFG,
86 .ctl_offs = SPM_MFG_PWR_CON,104 .ctl_offs = SPM_MFG_PWR_CON,
105 .pwr_sta_offs = SPM_PWR_STATUS,
106 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
87 .sram_pdn_bits = GENMASK(13, 8),107 .sram_pdn_bits = GENMASK(13, 8),
88 .sram_pdn_ack_bits = GENMASK(21, 16),108 .sram_pdn_ack_bits = GENMASK(21, 16),
89 .bp_infracfg = {109 .bp_infracfg = {
@@ -98,8 +118,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = { · 8 unmodified lines
98static const struct scpsys_soc_data mt8173_scpsys_data = {118static const struct scpsys_soc_data mt8173_scpsys_data = {
99 .domains_data = scpsys_domain_data_mt8173,119 .domains_data = scpsys_domain_data_mt8173,
100 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),120 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
101 .pwr_sta_offs = SPM_PWR_STATUS,
102 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
103};121};
104 122
105#endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */123#endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
drivers/soc/mediatek/mt8183-mmsys.h+2−0
@@ -25,6 +25,8 @@ · 24 unmodified lines
25#define MT8183_RDMA0_SOUT_COLOR0 0x125#define MT8183_RDMA0_SOUT_COLOR0 0x1
26#define MT8183_RDMA1_SOUT_DSI0 0x126#define MT8183_RDMA1_SOUT_DSI0 0x1
27 27
28#define MT8183_MMSYS_SW0_RST_B 0x140
29
28static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {30static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
29 {31 {
30 DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL_2L0,32 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
15 .name = "audio",15 .name = "audio",
16 .sta_mask = PWR_STATUS_AUDIO,16 .sta_mask = PWR_STATUS_AUDIO,
17 .ctl_offs = 0x0314,17 .ctl_offs = 0x0314,
18 .pwr_sta_offs = 0x0180,
19 .pwr_sta2nd_offs = 0x0184,
18 .sram_pdn_bits = GENMASK(11, 8),20 .sram_pdn_bits = GENMASK(11, 8),
19 .sram_pdn_ack_bits = GENMASK(15, 12),21 .sram_pdn_ack_bits = GENMASK(15, 12),
20 },22 },
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
22 .name = "conn",24 .name = "conn",
23 .sta_mask = PWR_STATUS_CONN,25 .sta_mask = PWR_STATUS_CONN,
24 .ctl_offs = 0x032c,26 .ctl_offs = 0x032c,
27 .pwr_sta_offs = 0x0180,
28 .pwr_sta2nd_offs = 0x0184,
25 .sram_pdn_bits = 0,29 .sram_pdn_bits = 0,
26 .sram_pdn_ack_bits = 0,30 .sram_pdn_ack_bits = 0,
27 .bp_infracfg = {31 .bp_infracfg = {
@@ -33,6 +37,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 5 unmodified lines
33 .name = "mfg_async",37 .name = "mfg_async",
34 .sta_mask = PWR_STATUS_MFG_ASYNC,38 .sta_mask = PWR_STATUS_MFG_ASYNC,
35 .ctl_offs = 0x0334,39 .ctl_offs = 0x0334,
40 .pwr_sta_offs = 0x0180,
41 .pwr_sta2nd_offs = 0x0184,
36 .sram_pdn_bits = 0,42 .sram_pdn_bits = 0,
37 .sram_pdn_ack_bits = 0,43 .sram_pdn_ack_bits = 0,
38 },44 },
@@ -40,6 +46,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
40 .name = "mfg",46 .name = "mfg",
41 .sta_mask = PWR_STATUS_MFG,47 .sta_mask = PWR_STATUS_MFG,
42 .ctl_offs = 0x0338,48 .ctl_offs = 0x0338,
49 .pwr_sta_offs = 0x0180,
50 .pwr_sta2nd_offs = 0x0184,
43 .sram_pdn_bits = GENMASK(8, 8),51 .sram_pdn_bits = GENMASK(8, 8),
44 .sram_pdn_ack_bits = GENMASK(12, 12),52 .sram_pdn_ack_bits = GENMASK(12, 12),
45 .caps = MTK_SCPD_DOMAIN_SUPPLY,53 .caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -48,6 +56,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 2 unmodified lines
48 .name = "mfg_core0",56 .name = "mfg_core0",
49 .sta_mask = BIT(7),57 .sta_mask = BIT(7),
50 .ctl_offs = 0x034c,58 .ctl_offs = 0x034c,
59 .pwr_sta_offs = 0x0180,
60 .pwr_sta2nd_offs = 0x0184,
51 .sram_pdn_bits = GENMASK(8, 8),61 .sram_pdn_bits = GENMASK(8, 8),
52 .sram_pdn_ack_bits = GENMASK(12, 12),62 .sram_pdn_ack_bits = GENMASK(12, 12),
53 },63 },
@@ -55,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
55 .name = "mfg_core1",65 .name = "mfg_core1",
56 .sta_mask = BIT(20),66 .sta_mask = BIT(20),
57 .ctl_offs = 0x0310,67 .ctl_offs = 0x0310,
68 .pwr_sta_offs = 0x0180,
69 .pwr_sta2nd_offs = 0x0184,
58 .sram_pdn_bits = GENMASK(8, 8),70 .sram_pdn_bits = GENMASK(8, 8),
59 .sram_pdn_ack_bits = GENMASK(12, 12),71 .sram_pdn_ack_bits = GENMASK(12, 12),
60 },72 },
@@ -62,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 1 unmodified line
62 .name = "mfg_2d",74 .name = "mfg_2d",
63 .sta_mask = PWR_STATUS_MFG_2D,75 .sta_mask = PWR_STATUS_MFG_2D,
64 .ctl_offs = 0x0348,76 .ctl_offs = 0x0348,
77 .pwr_sta_offs = 0x0180,
78 .pwr_sta2nd_offs = 0x0184,
65 .sram_pdn_bits = GENMASK(8, 8),79 .sram_pdn_bits = GENMASK(8, 8),
66 .sram_pdn_ack_bits = GENMASK(12, 12),80 .sram_pdn_ack_bits = GENMASK(12, 12),
67 .bp_infracfg = {81 .bp_infracfg = {
@@ -75,6 +89,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
75 .name = "disp",89 .name = "disp",
76 .sta_mask = PWR_STATUS_DISP,90 .sta_mask = PWR_STATUS_DISP,
77 .ctl_offs = 0x030c,91 .ctl_offs = 0x030c,
92 .pwr_sta_offs = 0x0180,
93 .pwr_sta2nd_offs = 0x0184,
78 .sram_pdn_bits = GENMASK(8, 8),94 .sram_pdn_bits = GENMASK(8, 8),
79 .sram_pdn_ack_bits = GENMASK(12, 12),95 .sram_pdn_ack_bits = GENMASK(12, 12),
80 .bp_infracfg = {96 .bp_infracfg = {
@@ -94,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 13 unmodified lines
94 .name = "cam",110 .name = "cam",
95 .sta_mask = BIT(25),111 .sta_mask = BIT(25),
96 .ctl_offs = 0x0344,112 .ctl_offs = 0x0344,
113 .pwr_sta_offs = 0x0180,
114 .pwr_sta2nd_offs = 0x0184,
97 .sram_pdn_bits = GENMASK(9, 8),115 .sram_pdn_bits = GENMASK(9, 8),
98 .sram_pdn_ack_bits = GENMASK(13, 12),116 .sram_pdn_ack_bits = GENMASK(13, 12),
99 .bp_infracfg = {117 .bp_infracfg = {
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 17 unmodified lines
117 .name = "isp",135 .name = "isp",
118 .sta_mask = PWR_STATUS_ISP,136 .sta_mask = PWR_STATUS_ISP,
119 .ctl_offs = 0x0308,137 .ctl_offs = 0x0308,
138 .pwr_sta_offs = 0x0180,
139 .pwr_sta2nd_offs = 0x0184,
120 .sram_pdn_bits = GENMASK(9, 8),140 .sram_pdn_bits = GENMASK(9, 8),
121 .sram_pdn_ack_bits = GENMASK(13, 12),141 .sram_pdn_ack_bits = GENMASK(13, 12),
122 .bp_infracfg = {142 .bp_infracfg = {
@@ -140,6 +160,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 17 unmodified lines
140 .name = "vdec",160 .name = "vdec",
141 .sta_mask = BIT(31),161 .sta_mask = BIT(31),
142 .ctl_offs = 0x0300,162 .ctl_offs = 0x0300,
163 .pwr_sta_offs = 0x0180,
164 .pwr_sta2nd_offs = 0x0184,
143 .sram_pdn_bits = GENMASK(8, 8),165 .sram_pdn_bits = GENMASK(8, 8),
144 .sram_pdn_ack_bits = GENMASK(12, 12),166 .sram_pdn_ack_bits = GENMASK(12, 12),
145 .bp_smi = {167 .bp_smi = {
@@ -153,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
153 .name = "venc",175 .name = "venc",
154 .sta_mask = PWR_STATUS_VENC,176 .sta_mask = PWR_STATUS_VENC,
155 .ctl_offs = 0x0304,177 .ctl_offs = 0x0304,
178 .pwr_sta_offs = 0x0180,
179 .pwr_sta2nd_offs = 0x0184,
156 .sram_pdn_bits = GENMASK(11, 8),180 .sram_pdn_bits = GENMASK(11, 8),
157 .sram_pdn_ack_bits = GENMASK(15, 12),181 .sram_pdn_ack_bits = GENMASK(15, 12),
158 .bp_smi = {182 .bp_smi = {
@@ -166,6 +190,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 7 unmodified lines
166 .name = "vpu_top",190 .name = "vpu_top",
167 .sta_mask = BIT(26),191 .sta_mask = BIT(26),
168 .ctl_offs = 0x0324,192 .ctl_offs = 0x0324,
193 .pwr_sta_offs = 0x0180,
194 .pwr_sta2nd_offs = 0x0184,
169 .sram_pdn_bits = GENMASK(8, 8),195 .sram_pdn_bits = GENMASK(8, 8),
170 .sram_pdn_ack_bits = GENMASK(12, 12),196 .sram_pdn_ack_bits = GENMASK(12, 12),
171 .bp_infracfg = {197 .bp_infracfg = {
@@ -193,6 +219,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 21 unmodified lines
193 .name = "vpu_core0",219 .name = "vpu_core0",
194 .sta_mask = BIT(27),220 .sta_mask = BIT(27),
195 .ctl_offs = 0x33c,221 .ctl_offs = 0x33c,
222 .pwr_sta_offs = 0x0180,
223 .pwr_sta2nd_offs = 0x0184,
196 .sram_pdn_bits = GENMASK(11, 8),224 .sram_pdn_bits = GENMASK(11, 8),
197 .sram_pdn_ack_bits = GENMASK(13, 12),225 .sram_pdn_ack_bits = GENMASK(13, 12),
198 .bp_infracfg = {226 .bp_infracfg = {
@@ -211,6 +239,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 12 unmodified lines
211 .name = "vpu_core1",239 .name = "vpu_core1",
212 .sta_mask = BIT(28),240 .sta_mask = BIT(28),
213 .ctl_offs = 0x0340,241 .ctl_offs = 0x0340,
242 .pwr_sta_offs = 0x0180,
243 .pwr_sta2nd_offs = 0x0184,
214 .sram_pdn_bits = GENMASK(11, 8),244 .sram_pdn_bits = GENMASK(11, 8),
215 .sram_pdn_ack_bits = GENMASK(13, 12),245 .sram_pdn_ack_bits = GENMASK(13, 12),
216 .bp_infracfg = {246 .bp_infracfg = {
@@ -230,8 +260,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = { · 13 unmodified lines
230static const struct scpsys_soc_data mt8183_scpsys_data = {260static const struct scpsys_soc_data mt8183_scpsys_data = {
231 .domains_data = scpsys_domain_data_mt8183,261 .domains_data = scpsys_domain_data_mt8183,
232 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),262 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
233 .pwr_sta_offs = 0x0180,
234 .pwr_sta2nd_offs = 0x0184
235};263};
236 264
237#endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */265#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
57static 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
17static 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
339static 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
15 .name = "audio",15 .name = "audio",
16 .sta_mask = BIT(21),16 .sta_mask = BIT(21),
17 .ctl_offs = 0x0354,17 .ctl_offs = 0x0354,
18 .pwr_sta_offs = 0x016c,
19 .pwr_sta2nd_offs = 0x0170,
18 .sram_pdn_bits = GENMASK(8, 8),20 .sram_pdn_bits = GENMASK(8, 8),
19 .sram_pdn_ack_bits = GENMASK(12, 12),21 .sram_pdn_ack_bits = GENMASK(12, 12),
20 .bp_infracfg = {22 .bp_infracfg = {
@@ -28,6 +30,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 7 unmodified lines
28 .name = "conn",30 .name = "conn",
29 .sta_mask = PWR_STATUS_CONN,31 .sta_mask = PWR_STATUS_CONN,
30 .ctl_offs = 0x0304,32 .ctl_offs = 0x0304,
33 .pwr_sta_offs = 0x016c,
34 .pwr_sta2nd_offs = 0x0170,
31 .sram_pdn_bits = 0,35 .sram_pdn_bits = 0,
32 .sram_pdn_ack_bits = 0,36 .sram_pdn_ack_bits = 0,
33 .bp_infracfg = {37 .bp_infracfg = {
@@ -50,6 +54,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 16 unmodified lines
50 .name = "mfg0",54 .name = "mfg0",
51 .sta_mask = BIT(2),55 .sta_mask = BIT(2),
52 .ctl_offs = 0x0308,56 .ctl_offs = 0x0308,
57 .pwr_sta_offs = 0x016c,
58 .pwr_sta2nd_offs = 0x0170,
53 .sram_pdn_bits = GENMASK(8, 8),59 .sram_pdn_bits = GENMASK(8, 8),
54 .sram_pdn_ack_bits = GENMASK(12, 12),60 .sram_pdn_ack_bits = GENMASK(12, 12),
55 },61 },
@@ -57,6 +63,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
57 .name = "mfg1",63 .name = "mfg1",
58 .sta_mask = BIT(3),64 .sta_mask = BIT(3),
59 .ctl_offs = 0x030c,65 .ctl_offs = 0x030c,
66 .pwr_sta_offs = 0x016c,
67 .pwr_sta2nd_offs = 0x0170,
60 .sram_pdn_bits = GENMASK(8, 8),68 .sram_pdn_bits = GENMASK(8, 8),
61 .sram_pdn_ack_bits = GENMASK(12, 12),69 .sram_pdn_ack_bits = GENMASK(12, 12),
62 .bp_infracfg = {70 .bp_infracfg = {
@@ -82,6 +90,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 19 unmodified lines
82 .name = "mfg2",90 .name = "mfg2",
83 .sta_mask = BIT(4),91 .sta_mask = BIT(4),
84 .ctl_offs = 0x0310,92 .ctl_offs = 0x0310,
93 .pwr_sta_offs = 0x016c,
94 .pwr_sta2nd_offs = 0x0170,
85 .sram_pdn_bits = GENMASK(8, 8),95 .sram_pdn_bits = GENMASK(8, 8),
86 .sram_pdn_ack_bits = GENMASK(12, 12),96 .sram_pdn_ack_bits = GENMASK(12, 12),
87 },97 },
@@ -89,6 +99,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
89 .name = "mfg3",99 .name = "mfg3",
90 .sta_mask = BIT(5),100 .sta_mask = BIT(5),
91 .ctl_offs = 0x0314,101 .ctl_offs = 0x0314,
102 .pwr_sta_offs = 0x016c,
103 .pwr_sta2nd_offs = 0x0170,
92 .sram_pdn_bits = GENMASK(8, 8),104 .sram_pdn_bits = GENMASK(8, 8),
93 .sram_pdn_ack_bits = GENMASK(12, 12),105 .sram_pdn_ack_bits = GENMASK(12, 12),
94 },106 },
@@ -96,6 +108,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
96 .name = "mfg4",108 .name = "mfg4",
97 .sta_mask = BIT(6),109 .sta_mask = BIT(6),
98 .ctl_offs = 0x0318,110 .ctl_offs = 0x0318,
111 .pwr_sta_offs = 0x016c,
112 .pwr_sta2nd_offs = 0x0170,
99 .sram_pdn_bits = GENMASK(8, 8),113 .sram_pdn_bits = GENMASK(8, 8),
100 .sram_pdn_ack_bits = GENMASK(12, 12),114 .sram_pdn_ack_bits = GENMASK(12, 12),
101 },115 },
@@ -103,6 +117,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
103 .name = "mfg5",117 .name = "mfg5",
104 .sta_mask = BIT(7),118 .sta_mask = BIT(7),
105 .ctl_offs = 0x031c,119 .ctl_offs = 0x031c,
120 .pwr_sta_offs = 0x016c,
121 .pwr_sta2nd_offs = 0x0170,
106 .sram_pdn_bits = GENMASK(8, 8),122 .sram_pdn_bits = GENMASK(8, 8),
107 .sram_pdn_ack_bits = GENMASK(12, 12),123 .sram_pdn_ack_bits = GENMASK(12, 12),
108 },124 },
@@ -110,6 +126,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
110 .name = "mfg6",126 .name = "mfg6",
111 .sta_mask = BIT(8),127 .sta_mask = BIT(8),
112 .ctl_offs = 0x0320,128 .ctl_offs = 0x0320,
129 .pwr_sta_offs = 0x016c,
130 .pwr_sta2nd_offs = 0x0170,
113 .sram_pdn_bits = GENMASK(8, 8),131 .sram_pdn_bits = GENMASK(8, 8),
114 .sram_pdn_ack_bits = GENMASK(12, 12),132 .sram_pdn_ack_bits = GENMASK(12, 12),
115 },133 },
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
117 .name = "disp",135 .name = "disp",
118 .sta_mask = BIT(20),136 .sta_mask = BIT(20),
119 .ctl_offs = 0x0350,137 .ctl_offs = 0x0350,
138 .pwr_sta_offs = 0x016c,
139 .pwr_sta2nd_offs = 0x0170,
120 .sram_pdn_bits = GENMASK(8, 8),140 .sram_pdn_bits = GENMASK(8, 8),
121 .sram_pdn_ack_bits = GENMASK(12, 12),141 .sram_pdn_ack_bits = GENMASK(12, 12),
122 .bp_infracfg = {142 .bp_infracfg = {
@@ -146,6 +166,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 23 unmodified lines
146 .name = "ipe",166 .name = "ipe",
147 .sta_mask = BIT(14),167 .sta_mask = BIT(14),
148 .ctl_offs = 0x0338,168 .ctl_offs = 0x0338,
169 .pwr_sta_offs = 0x016c,
170 .pwr_sta2nd_offs = 0x0170,
149 .sram_pdn_bits = GENMASK(8, 8),171 .sram_pdn_bits = GENMASK(8, 8),
150 .sram_pdn_ack_bits = GENMASK(12, 12),172 .sram_pdn_ack_bits = GENMASK(12, 12),
151 .bp_infracfg = {173 .bp_infracfg = {
@@ -163,6 +185,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
163 .name = "isp",185 .name = "isp",
164 .sta_mask = BIT(12),186 .sta_mask = BIT(12),
165 .ctl_offs = 0x0330,187 .ctl_offs = 0x0330,
188 .pwr_sta_offs = 0x016c,
189 .pwr_sta2nd_offs = 0x0170,
166 .sram_pdn_bits = GENMASK(8, 8),190 .sram_pdn_bits = GENMASK(8, 8),
167 .sram_pdn_ack_bits = GENMASK(12, 12),191 .sram_pdn_ack_bits = GENMASK(12, 12),
168 .bp_infracfg = {192 .bp_infracfg = {
@@ -180,6 +204,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
180 .name = "isp2",204 .name = "isp2",
181 .sta_mask = BIT(13),205 .sta_mask = BIT(13),
182 .ctl_offs = 0x0334,206 .ctl_offs = 0x0334,
207 .pwr_sta_offs = 0x016c,
208 .pwr_sta2nd_offs = 0x0170,
183 .sram_pdn_bits = GENMASK(8, 8),209 .sram_pdn_bits = GENMASK(8, 8),
184 .sram_pdn_ack_bits = GENMASK(12, 12),210 .sram_pdn_ack_bits = GENMASK(12, 12),
185 .bp_infracfg = {211 .bp_infracfg = {
@@ -197,6 +223,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
197 .name = "mdp",223 .name = "mdp",
198 .sta_mask = BIT(19),224 .sta_mask = BIT(19),
199 .ctl_offs = 0x034c,225 .ctl_offs = 0x034c,
226 .pwr_sta_offs = 0x016c,
227 .pwr_sta2nd_offs = 0x0170,
200 .sram_pdn_bits = GENMASK(8, 8),228 .sram_pdn_bits = GENMASK(8, 8),
201 .sram_pdn_ack_bits = GENMASK(12, 12),229 .sram_pdn_ack_bits = GENMASK(12, 12),
202 .bp_infracfg = {230 .bp_infracfg = {
@@ -214,6 +242,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
214 .name = "venc",242 .name = "venc",
215 .sta_mask = BIT(17),243 .sta_mask = BIT(17),
216 .ctl_offs = 0x0344,244 .ctl_offs = 0x0344,
245 .pwr_sta_offs = 0x016c,
246 .pwr_sta2nd_offs = 0x0170,
217 .sram_pdn_bits = GENMASK(8, 8),247 .sram_pdn_bits = GENMASK(8, 8),
218 .sram_pdn_ack_bits = GENMASK(12, 12),248 .sram_pdn_ack_bits = GENMASK(12, 12),
219 .bp_infracfg = {249 .bp_infracfg = {
@@ -231,6 +261,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
231 .name = "vdec",261 .name = "vdec",
232 .sta_mask = BIT(15),262 .sta_mask = BIT(15),
233 .ctl_offs = 0x033c,263 .ctl_offs = 0x033c,
264 .pwr_sta_offs = 0x016c,
265 .pwr_sta2nd_offs = 0x0170,
234 .sram_pdn_bits = GENMASK(8, 8),266 .sram_pdn_bits = GENMASK(8, 8),
235 .sram_pdn_ack_bits = GENMASK(12, 12),267 .sram_pdn_ack_bits = GENMASK(12, 12),
236 .bp_infracfg = {268 .bp_infracfg = {
@@ -248,6 +280,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 11 unmodified lines
248 .name = "vdec2",280 .name = "vdec2",
249 .sta_mask = BIT(16),281 .sta_mask = BIT(16),
250 .ctl_offs = 0x0340,282 .ctl_offs = 0x0340,
283 .pwr_sta_offs = 0x016c,
284 .pwr_sta2nd_offs = 0x0170,
251 .sram_pdn_bits = GENMASK(8, 8),285 .sram_pdn_bits = GENMASK(8, 8),
252 .sram_pdn_ack_bits = GENMASK(12, 12),286 .sram_pdn_ack_bits = GENMASK(12, 12),
253 },287 },
@@ -255,6 +289,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
255 .name = "cam",289 .name = "cam",
256 .sta_mask = BIT(23),290 .sta_mask = BIT(23),
257 .ctl_offs = 0x035c,291 .ctl_offs = 0x035c,
292 .pwr_sta_offs = 0x016c,
293 .pwr_sta2nd_offs = 0x0170,
258 .sram_pdn_bits = GENMASK(8, 8),294 .sram_pdn_bits = GENMASK(8, 8),
259 .sram_pdn_ack_bits = GENMASK(12, 12),295 .sram_pdn_ack_bits = GENMASK(12, 12),
260 .bp_infracfg = {296 .bp_infracfg = {
@@ -284,6 +320,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 23 unmodified lines
284 .name = "cam_rawa",320 .name = "cam_rawa",
285 .sta_mask = BIT(24),321 .sta_mask = BIT(24),
286 .ctl_offs = 0x0360,322 .ctl_offs = 0x0360,
323 .pwr_sta_offs = 0x016c,
324 .pwr_sta2nd_offs = 0x0170,
287 .sram_pdn_bits = GENMASK(8, 8),325 .sram_pdn_bits = GENMASK(8, 8),
288 .sram_pdn_ack_bits = GENMASK(12, 12),326 .sram_pdn_ack_bits = GENMASK(12, 12),
289 },327 },
@@ -291,6 +329,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
291 .name = "cam_rawb",329 .name = "cam_rawb",
292 .sta_mask = BIT(25),330 .sta_mask = BIT(25),
293 .ctl_offs = 0x0364,331 .ctl_offs = 0x0364,
332 .pwr_sta_offs = 0x016c,
333 .pwr_sta2nd_offs = 0x0170,
294 .sram_pdn_bits = GENMASK(8, 8),334 .sram_pdn_bits = GENMASK(8, 8),
295 .sram_pdn_ack_bits = GENMASK(12, 12),335 .sram_pdn_ack_bits = GENMASK(12, 12),
296 },336 },
@@ -298,6 +338,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 1 unmodified line
298 .name = "cam_rawc",338 .name = "cam_rawc",
299 .sta_mask = BIT(26),339 .sta_mask = BIT(26),
300 .ctl_offs = 0x0368,340 .ctl_offs = 0x0368,
341 .pwr_sta_offs = 0x016c,
342 .pwr_sta2nd_offs = 0x0170,
301 .sram_pdn_bits = GENMASK(8, 8),343 .sram_pdn_bits = GENMASK(8, 8),
302 .sram_pdn_ack_bits = GENMASK(12, 12),344 .sram_pdn_ack_bits = GENMASK(12, 12),
303 },345 },
@@ -306,8 +348,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = { · 2 unmodified lines
306static const struct scpsys_soc_data mt8192_scpsys_data = {348static const struct scpsys_soc_data mt8192_scpsys_data = {
307 .domains_data = scpsys_domain_data_mt8192,349 .domains_data = scpsys_domain_data_mt8192,
308 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),350 .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
309 .pwr_sta_offs = 0x016c,
310 .pwr_sta2nd_offs = 0x0170,
311};351};
312 352
313#endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */353#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
17static 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
608static 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
6#include <linux/export.h>6#include <linux/export.h>
7#include <linux/jiffies.h>7#include <linux/jiffies.h>
8#include <linux/regmap.h>8#include <linux/regmap.h>
9#include <linux/mfd/syscon.h>
9#include <linux/soc/mediatek/infracfg.h>10#include <linux/soc/mediatek/infracfg.h>
10#include <asm/processor.h>11#include <asm/processor.h>
11 12
@@ -72,3 +73,21 @@ int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, · 60 unmodified lines
72 73
73 return ret;74 return ret;
74}75}
76
77static 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}
93postcore_initcall(mtk_infracfg_init);
drivers/soc/mediatek/mtk-mmsys.c+16−2
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include "mtk-mmsys.h"15#include "mtk-mmsys.h"
16#include "mt8167-mmsys.h"16#include "mt8167-mmsys.h"
17#include "mt8183-mmsys.h"17#include "mt8183-mmsys.h"
18#include "mt8186-mmsys.h"
18#include "mt8192-mmsys.h"19#include "mt8192-mmsys.h"
19#include "mt8365-mmsys.h"20#include "mt8365-mmsys.h"
20 21
@@ -48,12 +49,21 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = { · 27 unmodified lines
48 .clk_driver = "clk-mt8173-mm",49 .clk_driver = "clk-mt8173-mm",
49 .routes = mmsys_default_routing_table,50 .routes = mmsys_default_routing_table,
50 .num_routes = ARRAY_SIZE(mmsys_default_routing_table),51 .num_routes = ARRAY_SIZE(mmsys_default_routing_table),
52 .sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
51};53};
52 54
53static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {55static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
54 .clk_driver = "clk-mt8183-mm",56 .clk_driver = "clk-mt8183-mm",
55 .routes = mmsys_mt8183_routing_table,57 .routes = mmsys_mt8183_routing_table,
56 .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),58 .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
59 .sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
60};
61
62static 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,
57};67};
58 68
59static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {69static 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
121 131
122 spin_lock_irqsave(&mmsys->lock, flags);132 spin_lock_irqsave(&mmsys->lock, flags);
123 133
124 reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);134 reg = readl_relaxed(mmsys->regs + mmsys->data->sw0_rst_offset);
125 135
126 if (assert)136 if (assert)
127 reg &= ~BIT(id);137 reg &= ~BIT(id);
128 else138 else
129 reg |= BIT(id);139 reg |= BIT(id);
130 140
131 writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);141 writel_relaxed(reg, mmsys->regs + mmsys->data->sw0_rst_offset);
132 142
133 spin_unlock_irqrestore(&mmsys->lock, flags);143 spin_unlock_irqrestore(&mmsys->lock, flags);
134 144
@@ -242,6 +252,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = { · 107 unmodified lines
242 .compatible = "mediatek,mt8183-mmsys",252 .compatible = "mediatek,mt8183-mmsys",
243 .data = &mt8183_mmsys_driver_data,253 .data = &mt8183_mmsys_driver_data,
244 },254 },
255 {
256 .compatible = "mediatek,mt8186-mmsys",
257 .data = &mt8186_mmsys_driver_data,
258 },
245 {259 {
246 .compatible = "mediatek,mt8192-mmsys",260 .compatible = "mediatek,mt8192-mmsys",
247 .data = &mt8192_mmsys_driver_data,261 .data = &mt8192_mmsys_driver_data,
drivers/soc/mediatek/mtk-mmsys.h+1−2
@@ -78,8 +78,6 @@ · 77 unmodified lines
78#define DSI_SEL_IN_RDMA 0x178#define DSI_SEL_IN_RDMA 0x1
79#define DSI_SEL_IN_MASK 0x179#define DSI_SEL_IN_MASK 0x1
80 80
81#define MMSYS_SW0_RST_B 0x140
82
83struct mtk_mmsys_routes {81struct mtk_mmsys_routes {
84 u32 from_comp;82 u32 from_comp;
85 u32 to_comp;83 u32 to_comp;
@@ -92,6 +90,7 @@ struct mtk_mmsys_driver_data { · 6 unmodified lines
92 const char *clk_driver;90 const char *clk_driver;
93 const struct mtk_mmsys_routes *routes;91 const struct mtk_mmsys_routes *routes;
94 const unsigned int num_routes;92 const unsigned int num_routes;
93 const u16 sw0_rst_offset;
95};94};
96 95
97/*96/*
drivers/soc/mediatek/mtk-mutex.c+45−0
@@ -26,6 +26,23 @@ · 25 unmodified lines
26 26
27#define INT_MUTEX BIT(1)27#define INT_MUTEX BIT(1)
28 28
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
29#define MT8167_MUTEX_MOD_DISP_PWM 146#define MT8167_MUTEX_MOD_DISP_PWM 1
30#define MT8167_MUTEX_MOD_DISP_OVL0 647#define MT8167_MUTEX_MOD_DISP_OVL0 6
31#define MT8167_MUTEX_MOD_DISP_OVL1 748#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
226 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,243 [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
227};244};
228 245
246static 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
229static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {259static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
230 [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,260 [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
231 [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,261 [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
264 [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,294 [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
265};295};
266 296
297static 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
267static const struct mtk_mutex_data mt2701_mutex_driver_data = {303static const struct mtk_mutex_data mt2701_mutex_driver_data = {
268 .mutex_mod = mt2701_mutex_mod,304 .mutex_mod = mt2701_mutex_mod,
269 .mutex_sof = mt2712_mutex_sof,305 .mutex_sof = mt2712_mutex_sof,
@@ -301,6 +337,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { · 31 unmodified lines
301 .no_clk = true,337 .no_clk = true,
302};338};
303 339
340static 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
304static const struct mtk_mutex_data mt8192_mutex_driver_data = {347static const struct mtk_mutex_data mt8192_mutex_driver_data = {
305 .mutex_mod = mt8192_mutex_mod,348 .mutex_mod = mt8192_mutex_mod,
306 .mutex_sof = mt8183_mutex_sof,349 .mutex_sof = mt8183_mutex_sof,
@@ -540,6 +583,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { · 233 unmodified lines
540 .data = &mt8173_mutex_driver_data},583 .data = &mt8173_mutex_driver_data},
541 { .compatible = "mediatek,mt8183-disp-mutex",584 { .compatible = "mediatek,mt8183-disp-mutex",
542 .data = &mt8183_mutex_driver_data},585 .data = &mt8183_mutex_driver_data},
586 { .compatible = "mediatek,mt8186-disp-mutex",
587 .data = &mt8186_mutex_driver_data},
543 { .compatible = "mediatek,mt8192-disp-mutex",588 { .compatible = "mediatek,mt8192-disp-mutex",
544 .data = &mt8192_mutex_driver_data},589 .data = &mt8192_mutex_driver_data},
545 {},590 {},
drivers/soc/mediatek/mtk-pm-domains.c+15−2
@@ -19,7 +19,9 @@ · 18 unmodified lines
19#include "mt8167-pm-domains.h"19#include "mt8167-pm-domains.h"
20#include "mt8173-pm-domains.h"20#include "mt8173-pm-domains.h"
21#include "mt8183-pm-domains.h"21#include "mt8183-pm-domains.h"
22#include "mt8186-pm-domains.h"
22#include "mt8192-pm-domains.h"23#include "mt8192-pm-domains.h"
24#include "mt8195-pm-domains.h"
23 25
24#define MTK_POLL_DELAY_US 1026#define MTK_POLL_DELAY_US 10
25#define MTK_POLL_TIMEOUT USEC_PER_SEC27#define MTK_POLL_TIMEOUT USEC_PER_SEC
@@ -60,10 +62,10 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd) · 34 unmodified lines
60 struct scpsys *scpsys = pd->scpsys;62 struct scpsys *scpsys = pd->scpsys;
61 u32 status, status2;63 u32 status, status2;
62 64
63 regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);65 regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
64 status &= pd->data->sta_mask;66 status &= pd->data->sta_mask;
65 67
66 regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);68 regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
67 status2 &= pd->data->sta_mask;69 status2 &= pd->data->sta_mask;
68 70
69 /* A domain is on when both status bits are set. */71 /* 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
443 pd->genpd.power_off = scpsys_power_off;445 pd->genpd.power_off = scpsys_power_off;
444 pd->genpd.power_on = scpsys_power_on;446 pd->genpd.power_on = scpsys_power_on;
445 447
448 if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP))
449 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
450
446 if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))451 if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))
447 pm_genpd_init(&pd->genpd, NULL, true);452 pm_genpd_init(&pd->genpd, NULL, true);
448 else453 else
@@ -562,10 +567,18 @@ static const struct of_device_id scpsys_of_match[] = { · 113 unmodified lines
562 .compatible = "mediatek,mt8183-power-controller",567 .compatible = "mediatek,mt8183-power-controller",
563 .data = &mt8183_scpsys_data,568 .data = &mt8183_scpsys_data,
564 },569 },
570 {
571 .compatible = "mediatek,mt8186-power-controller",
572 .data = &mt8186_scpsys_data,
573 },
565 {574 {
566 .compatible = "mediatek,mt8192-power-controller",575 .compatible = "mediatek,mt8192-power-controller",
567 .data = &mt8192_scpsys_data,576 .data = &mt8192_scpsys_data,
568 },577 },
578 {
579 .compatible = "mediatek,mt8195-power-controller",
580 .data = &mt8195_scpsys_data,
581 },
569 { }582 { }
570};583};
571 584
drivers/soc/mediatek/mtk-pm-domains.h+3−5
@@ -37,7 +37,7 @@ · 36 unmodified lines
37#define PWR_STATUS_AUDIO BIT(24)37#define PWR_STATUS_AUDIO BIT(24)
38#define PWR_STATUS_USB BIT(25)38#define PWR_STATUS_USB BIT(25)
39 39
40#define SPM_MAX_BUS_PROT_DATA 540#define SPM_MAX_BUS_PROT_DATA 6
41 41
42#define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \42#define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) { \
43 .bus_prot_mask = (_mask), \43 .bus_prot_mask = (_mask), \
@@ -72,8 +72,6 @@ struct scpsys_bus_prot_data { · 28 unmodified lines
72 bool ignore_clr_ack;72 bool ignore_clr_ack;
73};73};
74 74
75#define MAX_SUBSYS_CLKS 10
76
77/**75/**
78 * struct scpsys_domain_data - scp domain data for power on/off flow76 * struct scpsys_domain_data - scp domain data for power on/off flow
79 * @name: The name of the power domain.77 * @name: The name of the power domain.
@@ -94,13 +92,13 @@ struct scpsys_domain_data { · 14 unmodified lines
94 u8 caps;92 u8 caps;
95 const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];93 const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
96 const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];94 const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
95 int pwr_sta_offs;
96 int pwr_sta2nd_offs;
97};97};
98 98
99struct scpsys_soc_data {99struct scpsys_soc_data {
100 const struct scpsys_domain_data *domains_data;100 const struct scpsys_domain_data *domains_data;
101 int num_domains;101 int num_domains;
102 int pwr_sta_offs;
103 int pwr_sta2nd_offs;
104};102};
105 103
106#endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */104#endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
drivers/soc/mediatek/mtk-pmic-wrap.c+71−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
30#define PWRAP_GET_WACS_REQ(x) (((x) >> 19) & 0x00000001)30#define PWRAP_GET_WACS_REQ(x) (((x) >> 19) & 0x00000001)
31#define PWRAP_STATE_SYNC_IDLE0 BIT(20)31#define PWRAP_STATE_SYNC_IDLE0 BIT(20)
32#define PWRAP_STATE_INIT_DONE0 BIT(21)32#define PWRAP_STATE_INIT_DONE0 BIT(21)
33#define PWRAP_STATE_INIT_DONE0_MT8186 BIT(22)
33#define PWRAP_STATE_INIT_DONE1 BIT(15)34#define PWRAP_STATE_INIT_DONE1 BIT(15)
34 35
35/* macro for WACS FSM */36/* macro for WACS FSM */
@@ -77,6 +78,7 @@ · 41 unmodified lines
77#define PWRAP_CAP_INT1_EN BIT(3)78#define PWRAP_CAP_INT1_EN BIT(3)
78#define PWRAP_CAP_WDT_SRC1 BIT(4)79#define PWRAP_CAP_WDT_SRC1 BIT(4)
79#define PWRAP_CAP_ARB BIT(5)80#define PWRAP_CAP_ARB BIT(5)
81#define PWRAP_CAP_ARB_MT8186 BIT(8)
80 82
81/* defines for slave device wrapper registers */83/* defines for slave device wrapper registers */
82enum dew_regs {84enum dew_regs {
@@ -1063,6 +1065,55 @@ static int mt8516_regs[] = { · 980 unmodified lines
1063 [PWRAP_MSB_FIRST] = 0x170,1065 [PWRAP_MSB_FIRST] = 0x170,
1064};1066};
1065 1067
1068static 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
1066enum pmic_type {1117enum pmic_type {
1067 PMIC_MT6323,1118 PMIC_MT6323,
1068 PMIC_MT6351,1119 PMIC_MT6351,
@@ -1083,6 +1134,7 @@ enum pwrap_type { · 14 unmodified lines
1083 PWRAP_MT8135,1134 PWRAP_MT8135,
1084 PWRAP_MT8173,1135 PWRAP_MT8173,
1085 PWRAP_MT8183,1136 PWRAP_MT8183,
1137 PWRAP_MT8186,
1086 PWRAP_MT8195,1138 PWRAP_MT8195,
1087 PWRAP_MT8516,1139 PWRAP_MT8516,
1088};1140};
@@ -1535,6 +1587,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) · 446 unmodified lines
1535 case PWRAP_MT6779:1587 case PWRAP_MT6779:
1536 case PWRAP_MT6797:1588 case PWRAP_MT6797:
1537 case PWRAP_MT8173:1589 case PWRAP_MT8173:
1590 case PWRAP_MT8186:
1538 case PWRAP_MT8516:1591 case PWRAP_MT8516:
1539 pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);1592 pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
1540 break;1593 break;
@@ -2069,6 +2122,19 @@ static struct pmic_wrapper_type pwrap_mt8516 = { · 528 unmodified lines
2069 .init_soc_specific = NULL,2122 .init_soc_specific = NULL,
2070};2123};
2071 2124
2125static 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
2072static const struct of_device_id of_pwrap_match_tbl[] = {2138static const struct of_device_id of_pwrap_match_tbl[] = {
2073 {2139 {
2074 .compatible = "mediatek,mt2701-pwrap",2140 .compatible = "mediatek,mt2701-pwrap",
@@ -2097,6 +2163,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = { · 22 unmodified lines
2097 }, {2163 }, {
2098 .compatible = "mediatek,mt8183-pwrap",2164 .compatible = "mediatek,mt8183-pwrap",
2099 .data = &pwrap_mt8183,2165 .data = &pwrap_mt8183,
2166 }, {
2167 .compatible = "mediatek,mt8186-pwrap",
2168 .data = &pwrap_mt8186,
2100 }, {2169 }, {
2101 .compatible = "mediatek,mt8195-pwrap",2170 .compatible = "mediatek,mt8195-pwrap",
2102 .data = &pwrap_mt8195,2171 .data = &pwrap_mt8195,
@@ -2209,6 +2278,8 @@ static int pwrap_probe(struct platform_device *pdev) · 106 unmodified lines
2209 2278
2210 if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))2279 if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
2211 mask_done = PWRAP_STATE_INIT_DONE1;2280 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;
2212 else2283 else
2213 mask_done = PWRAP_STATE_INIT_DONE0;2284 mask_done = PWRAP_STATE_INIT_DONE0;
2214 2285
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
95{95{
96 struct device *dev = &pdev->dev;96 struct device *dev = &pdev->dev;
97 struct mpfs_sys_controller *sys_controller;97 struct mpfs_sys_controller *sys_controller;
98 int i;98 int i, ret;
99 99
100 sys_controller = devm_kzalloc(dev, sizeof(*sys_controller), GFP_KERNEL);100 sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL);
101 if (!sys_controller)101 if (!sys_controller)
102 return -ENOMEM;102 return -ENOMEM;
103 103
@@ -106,9 +106,12 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) · 2 unmodified lines
106 sys_controller->client.tx_block = 1U;106 sys_controller->client.tx_block = 1U;
107 107
108 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0);108 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0);
109 if (IS_ERR(sys_controller->chan))109 if (IS_ERR(sys_controller->chan)) {
110 return dev_err_probe(dev, PTR_ERR(sys_controller->chan),110 ret = dev_err_probe(dev, PTR_ERR(sys_controller->chan),
111 "Failed to get mbox channel\n");111 "Failed to get mbox channel\n");
112 kfree(sys_controller);
113 return ret;
114 }
112 115
113 init_completion(&sys_controller->c);116 init_completion(&sys_controller->c);
114 kref_init(&sys_controller->consumers);117 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
653 653
654 pdr_handle_release(apr->pdr);654 pdr_handle_release(apr->pdr);
655 device_for_each_child(&rpdev->dev, NULL, apr_remove_device);655 device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
656 flush_workqueue(apr->rxwq);
657 destroy_workqueue(apr->rxwq);656 destroy_workqueue(apr->rxwq);
658}657}
659 658
drivers/soc/qcom/llcc-qcom.c+91−16
@@ -29,17 +29,13 @@ · 28 unmodified lines
29#define ATTR1_FIXED_SIZE_SHIFT 0x0329#define ATTR1_FIXED_SIZE_SHIFT 0x03
30#define ATTR1_PRIORITY_SHIFT 0x0430#define ATTR1_PRIORITY_SHIFT 0x04
31#define ATTR1_MAX_CAP_SHIFT 0x1031#define ATTR1_MAX_CAP_SHIFT 0x10
32#define ATTR0_RES_WAYS_MASK GENMASK(11, 0)32#define ATTR0_RES_WAYS_MASK GENMASK(15, 0)
33#define ATTR0_BONUS_WAYS_MASK GENMASK(27, 16)33#define ATTR0_BONUS_WAYS_MASK GENMASK(31, 16)
34#define ATTR0_BONUS_WAYS_SHIFT 0x1034#define ATTR0_BONUS_WAYS_SHIFT 0x10
35#define LLCC_STATUS_READ_DELAY 10035#define LLCC_STATUS_READ_DELAY 100
36 36
37#define CACHE_LINE_SIZE_SHIFT 637#define CACHE_LINE_SIZE_SHIFT 6
38 38
39#define LLCC_COMMON_HW_INFO 0x00030000
40#define LLCC_MAJOR_VERSION_MASK GENMASK(31, 24)
41
42#define LLCC_COMMON_STATUS0 0x0003000c
43#define LLCC_LB_CNT_MASK GENMASK(31, 28)39#define LLCC_LB_CNT_MASK GENMASK(31, 28)
44#define LLCC_LB_CNT_SHIFT 2840#define LLCC_LB_CNT_SHIFT 28
45 41
@@ -52,9 +48,13 @@ · 6 unmodified lines
52#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f0048#define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00
53#define LLCC_TRP_PCB_ACT 0x21f0449#define LLCC_TRP_PCB_ACT 0x21f04
54#define LLCC_TRP_WRSC_EN 0x21f2050#define LLCC_TRP_WRSC_EN 0x21f20
51#define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c
55 52
56#define BANK_OFFSET_STRIDE 0x8000053#define BANK_OFFSET_STRIDE 0x80000
57 54
55#define LLCC_VERSION_2_0_0_0 0x02000000
56#define LLCC_VERSION_2_1_0_0 0x02010000
57
58/**58/**
59 * struct llcc_slice_config - Data associated with the llcc slice59 * struct llcc_slice_config - Data associated with the llcc slice
60 * @usecase_id: Unique id for the client's use case60 * @usecase_id: Unique id for the client's use case
@@ -79,6 +79,8 @@ · 18 unmodified lines
79 * collapse.79 * collapse.
80 * @activate_on_init: Activate the slice immediately after it is programmed80 * @activate_on_init: Activate the slice immediately after it is programmed
81 * @write_scid_en: Bit enables write cache support for a given scid.81 * @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).
82 */84 */
83struct llcc_slice_config {85struct llcc_slice_config {
84 u32 usecase_id;86 u32 usecase_id;
@@ -94,12 +96,19 @@ struct llcc_slice_config { · 9 unmodified lines
94 bool retain_on_pc;96 bool retain_on_pc;
95 bool activate_on_init;97 bool activate_on_init;
96 bool write_scid_en;98 bool write_scid_en;
99 bool write_scid_cacheable_en;
97};100};
98 101
99struct qcom_llcc_config {102struct qcom_llcc_config {
100 const struct llcc_slice_config *sct_data;103 const struct llcc_slice_config *sct_data;
101 int size;104 int size;
102 bool need_llcc_cfg;105 bool need_llcc_cfg;
106 const u32 *reg_offset;
107};
108
109enum llcc_reg_offset {
110 LLCC_COMMON_HW_INFO,
111 LLCC_COMMON_STATUS0,
103};112};
104 113
105static const struct llcc_slice_config sc7180_data[] = {114static const struct llcc_slice_config sc7180_data[] = {
@@ -217,42 +226,96 @@ static const struct llcc_slice_config sm8350_data[] = { · 111 unmodified lines
217 { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },226 { LLCC_CPUHWT, 5, 512, 1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
218};227};
219 228
229static 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
255static const u32 llcc_v1_2_reg_offset[] = {
256 [LLCC_COMMON_HW_INFO] = 0x00030000,
257 [LLCC_COMMON_STATUS0] = 0x0003000c,
258};
259
260static const u32 llcc_v21_reg_offset[] = {
261 [LLCC_COMMON_HW_INFO] = 0x00034000,
262 [LLCC_COMMON_STATUS0] = 0x0003400c,
263};
264
220static const struct qcom_llcc_config sc7180_cfg = {265static const struct qcom_llcc_config sc7180_cfg = {
221 .sct_data = sc7180_data,266 .sct_data = sc7180_data,
222 .size = ARRAY_SIZE(sc7180_data),267 .size = ARRAY_SIZE(sc7180_data),
223 .need_llcc_cfg = true,268 .need_llcc_cfg = true,
269 .reg_offset = llcc_v1_2_reg_offset,
224};270};
225 271
226static const struct qcom_llcc_config sc7280_cfg = {272static const struct qcom_llcc_config sc7280_cfg = {
227 .sct_data = sc7280_data,273 .sct_data = sc7280_data,
228 .size = ARRAY_SIZE(sc7280_data),274 .size = ARRAY_SIZE(sc7280_data),
229 .need_llcc_cfg = true,275 .need_llcc_cfg = true,
276 .reg_offset = llcc_v1_2_reg_offset,
230};277};
231 278
232static const struct qcom_llcc_config sdm845_cfg = {279static const struct qcom_llcc_config sdm845_cfg = {
233 .sct_data = sdm845_data,280 .sct_data = sdm845_data,
234 .size = ARRAY_SIZE(sdm845_data),281 .size = ARRAY_SIZE(sdm845_data),
235 .need_llcc_cfg = false,282 .need_llcc_cfg = false,
283 .reg_offset = llcc_v1_2_reg_offset,
236};284};
237 285
238static const struct qcom_llcc_config sm6350_cfg = {286static const struct qcom_llcc_config sm6350_cfg = {
239 .sct_data = sm6350_data,287 .sct_data = sm6350_data,
240 .size = ARRAY_SIZE(sm6350_data),288 .size = ARRAY_SIZE(sm6350_data),
289 .need_llcc_cfg = true,
290 .reg_offset = llcc_v1_2_reg_offset,
241};291};
242 292
243static const struct qcom_llcc_config sm8150_cfg = {293static const struct qcom_llcc_config sm8150_cfg = {
244 .sct_data = sm8150_data,294 .sct_data = sm8150_data,
245 .size = ARRAY_SIZE(sm8150_data),295 .size = ARRAY_SIZE(sm8150_data),
296 .need_llcc_cfg = true,
297 .reg_offset = llcc_v1_2_reg_offset,
246};298};
247 299
248static const struct qcom_llcc_config sm8250_cfg = {300static const struct qcom_llcc_config sm8250_cfg = {
249 .sct_data = sm8250_data,301 .sct_data = sm8250_data,
250 .size = ARRAY_SIZE(sm8250_data),302 .size = ARRAY_SIZE(sm8250_data),
303 .need_llcc_cfg = true,
304 .reg_offset = llcc_v1_2_reg_offset,
251};305};
252 306
253static const struct qcom_llcc_config sm8350_cfg = {307static const struct qcom_llcc_config sm8350_cfg = {
254 .sct_data = sm8350_data,308 .sct_data = sm8350_data,
255 .size = ARRAY_SIZE(sm8350_data),309 .size = ARRAY_SIZE(sm8350_data),
310 .need_llcc_cfg = true,
311 .reg_offset = llcc_v1_2_reg_offset,
312};
313
314static 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,
256};319};
257 320
258static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;321static 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
504 return ret;567 return ret;
505 }568 }
506 569
507 if (drv_data->major_version == 2) {570 if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
508 u32 wren;571 u32 wren;
509 572
510 wren = config->write_scid_en << config->slice_id;573 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
514 return ret;577 return ret;
515 }578 }
516 579
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
517 if (config->activate_on_init) {590 if (config->activate_on_init) {
518 desc.slice_id = config->slice_id;591 desc.slice_id = config->slice_id;
519 ret = llcc_slice_activate(&desc);592 ret = llcc_slice_activate(&desc);
@@ -598,15 +671,18 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 78 unmodified lines
598 goto err;671 goto err;
599 }672 }
600 673
601 /* Extract major version of the IP */674 cfg = of_device_get_match_data(&pdev->dev);
602 ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);675
676 /* Extract version of the IP */
677 ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
678 &version);
603 if (ret)679 if (ret)
604 goto err;680 goto err;
605 681
606 drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version);682 drv_data->version = version;
607 683
608 ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,684 ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0],
609 &num_banks);685 &num_banks);
610 if (ret)686 if (ret)
611 goto err;687 goto err;
612 688
@@ -614,7 +690,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 1 unmodified line
614 num_banks >>= LLCC_LB_CNT_SHIFT;690 num_banks >>= LLCC_LB_CNT_SHIFT;
615 drv_data->num_banks = num_banks;691 drv_data->num_banks = num_banks;
616 692
617 cfg = of_device_get_match_data(&pdev->dev);
618 llcc_cfg = cfg->sct_data;693 llcc_cfg = cfg->sct_data;
619 sz = cfg->size;694 sz = cfg->size;
620 695
@@ -632,9 +707,8 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 11 unmodified lines
632 for (i = 0; i < num_banks; i++)707 for (i = 0; i < num_banks; i++)
633 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;708 drv_data->offsets[i] = i * BANK_OFFSET_STRIDE;
634 709
635 drv_data->bitmap = devm_kcalloc(dev,710 drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,
636 BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long),711 GFP_KERNEL);
637 GFP_KERNEL);
638 if (!drv_data->bitmap) {712 if (!drv_data->bitmap) {
639 ret = -ENOMEM;713 ret = -ENOMEM;
640 goto err;714 goto err;
@@ -672,6 +746,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { · 31 unmodified lines
672 { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },746 { .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
673 { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },747 { .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
674 { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },748 { .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
749 { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
675 { }750 { }
676};751};
677 752
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
31 return true;31 return true;
32}32}
33 33
34static 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
34/**72/**
35 * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt73 * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt
36 * @fw: firmware object for the mdt file74 * @fw: firmware object for the mdt file
@@ -83,13 +121,17 @@ EXPORT_SYMBOL_GPL(qcom_mdt_get_size); · 46 unmodified lines
83 *121 *
84 * Return: pointer to data, or ERR_PTR()122 * Return: pointer to data, or ERR_PTR()
85 */123 */
86void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)124void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
125 const char *fw_name, struct device *dev)
87{126{
88 const struct elf32_phdr *phdrs;127 const struct elf32_phdr *phdrs;
89 const struct elf32_hdr *ehdr;128 const struct elf32_hdr *ehdr;
129 unsigned int hash_segment = 0;
90 size_t hash_offset;130 size_t hash_offset;
91 size_t hash_size;131 size_t hash_size;
92 size_t ehdr_size;132 size_t ehdr_size;
133 unsigned int i;
134 ssize_t ret;
93 void *data;135 void *data;
94 136
95 ehdr = (struct elf32_hdr *)fw->data;137 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
101 if (phdrs[0].p_type == PT_LOAD)143 if (phdrs[0].p_type == PT_LOAD)
102 return ERR_PTR(-EINVAL);144 return ERR_PTR(-EINVAL);
103 145
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);
105 return ERR_PTR(-EINVAL);155 return ERR_PTR(-EINVAL);
156 }
106 157
107 ehdr_size = phdrs[0].p_filesz;158 ehdr_size = phdrs[0].p_filesz;
108 hash_size = phdrs[1].p_filesz;159 hash_size = phdrs[hash_segment].p_filesz;
109 160
110 data = kmalloc(ehdr_size + hash_size, GFP_KERNEL);161 data = kmalloc(ehdr_size + hash_size, GFP_KERNEL);
111 if (!data)162 if (!data)
112 return ERR_PTR(-ENOMEM);163 return ERR_PTR(-ENOMEM);
113 164
114 /* Is the header and hash already packed */165 /* Copy ELF header */
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
120 memcpy(data, fw->data, ehdr_size);166 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 }
122 184
123 *data_len = ehdr_size + hash_size;185 *data_len = ehdr_size + hash_size;
124 186
@@ -126,23 +188,85 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) · 1 unmodified line
126}188}
127EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);189EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata);
128 190
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 */
202int 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
254out:
255 return ret;
256}
257EXPORT_SYMBOL_GPL(qcom_mdt_pas_init);
258
129static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,259static 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,
131 phys_addr_t mem_phys, size_t mem_size,261 phys_addr_t mem_phys, size_t mem_size,
132 phys_addr_t *reloc_base, bool pas_init)262 phys_addr_t *reloc_base, bool pas_init)
133{263{
134 const struct elf32_phdr *phdrs;264 const struct elf32_phdr *phdrs;
135 const struct elf32_phdr *phdr;265 const struct elf32_phdr *phdr;
136 const struct elf32_hdr *ehdr;266 const struct elf32_hdr *ehdr;
137 const struct firmware *seg_fw;
138 phys_addr_t mem_reloc;267 phys_addr_t mem_reloc;
139 phys_addr_t min_addr = PHYS_ADDR_MAX;268 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;
143 ssize_t offset;269 ssize_t offset;
144 void *metadata;
145 char *fw_name;
146 bool relocate = false;270 bool relocate = false;
147 void *ptr;271 void *ptr;
148 int ret = 0;272 int ret = 0;
@@ -154,34 +278,6 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 5 unmodified lines
154 ehdr = (struct elf32_hdr *)fw->data;278 ehdr = (struct elf32_hdr *)fw->data;
155 phdrs = (struct elf32_phdr *)(ehdr + 1);279 phdrs = (struct elf32_phdr *)(ehdr + 1);
156 280
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
185 for (i = 0; i < ehdr->e_phnum; i++) {281 for (i = 0; i < ehdr->e_phnum; i++) {
186 phdr = &phdrs[i];282 phdr = &phdrs[i];
187 283
@@ -193,23 +289,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 5 unmodified lines
193 289
194 if (phdr->p_paddr < min_addr)290 if (phdr->p_paddr < min_addr)
195 min_addr = phdr->p_paddr;291 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);
199 }292 }
200 293
201 if (relocate) {294 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
213 /*295 /*
214 * The image is relocatable, so offset each segment based on296 * The image is relocatable, so offset each segment based on
215 * the lowest segment address.297 * the lowest segment address.
@@ -246,7 +328,8 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, · 30 unmodified lines
246 328
247 ptr = mem_region + offset;329 ptr = mem_region + offset;
248 330
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) {
250 /* Firmware is large enough to be non-split */333 /* Firmware is large enough to be non-split */
251 if (phdr->p_offset + phdr->p_filesz > fw->size) {334 if (phdr->p_offset + phdr->p_filesz > fw->size) {
252 dev_err(dev, "file %s segment %d would be truncated\n",335 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
258 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);341 memcpy(ptr, fw->data + phdr->p_offset, phdr->p_filesz);
259 } else if (phdr->p_filesz) {342 } else if (phdr->p_filesz) {
260 /* Firmware not large enough, load split-out segments */343 /* Firmware not large enough, load split-out segments */
261 sprintf(fw_name + fw_name_len - 3, "b%02d", i);344 ret = mdt_load_split_segment(ptr, phdrs, i, fw_name, dev);
262 ret = request_firmware_into_buf(&seg_fw, fw_name, dev,345 if (ret)
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;
276 break;346 break;
277 }
278
279 release_firmware(seg_fw);
280 }347 }
281 348
282 if (phdr->p_memsz > phdr->p_filesz)349 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
286 if (reloc_base)353 if (reloc_base)
287 *reloc_base = mem_reloc;354 *reloc_base = mem_reloc;
288 355
289out:
290 kfree(fw_name);
291
292 return ret;356 return ret;
293}357}
294 358
@@ -310,6 +374,12 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, · 15 unmodified lines
310 phys_addr_t mem_phys, size_t mem_size,374 phys_addr_t mem_phys, size_t mem_size,
311 phys_addr_t *reloc_base)375 phys_addr_t *reloc_base)
312{376{
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
313 return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,383 return __qcom_mdt_load(dev, fw, firmware, pas_id, mem_region, mem_phys,
314 mem_size, reloc_base, true);384 mem_size, reloc_base, true);
315}385}
drivers/soc/qcom/ocmem.c+1−0
@@ -206,6 +206,7 @@ struct ocmem *of_get_ocmem(struct device *dev) · 205 unmodified lines
206 ocmem = platform_get_drvdata(pdev);206 ocmem = platform_get_drvdata(pdev);
207 if (!ocmem) {207 if (!ocmem) {
208 dev_err(dev, "Cannot get ocmem\n");208 dev_err(dev, "Cannot get ocmem\n");
209 put_device(&pdev->dev);
209 return ERR_PTR(-ENODEV);210 return ERR_PTR(-ENODEV);
210 }211 }
211 return ocmem;212 return ocmem;
drivers/soc/qcom/qcom_aoss.c+6−2
@@ -451,7 +451,11 @@ struct qmp *qmp_get(struct device *dev) · 450 unmodified lines
451 451
452 qmp = platform_get_drvdata(pdev);452 qmp = platform_get_drvdata(pdev);
453 453
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;
455}459}
456EXPORT_SYMBOL(qmp_get);460EXPORT_SYMBOL(qmp_get);
457 461
@@ -497,7 +501,7 @@ static int qmp_probe(struct platform_device *pdev) · 39 unmodified lines
497 }501 }
498 502
499 irq = platform_get_irq(pdev, 0);503 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,
501 "aoss-qmp", qmp);505 "aoss-qmp", qmp);
502 if (ret < 0) {506 if (ret < 0) {
503 dev_err(&pdev->dev, "failed to request interrupt\n");507 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
138 .max_state = RPM_SMD_LEVEL_TURBO,138 .max_state = RPM_SMD_LEVEL_TURBO,
139};139};
140 140
141/* msm8226 RPM Power Domains */
142DEFINE_RPMPD_PAIR(msm8226, vddcx, vddcx_ao, SMPA, CORNER, 1);
143DEFINE_RPMPD_VFC(msm8226, vddcx_vfc, SMPA, 1);
144
145static 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
151static 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
141/* msm8939 RPM Power Domains */157/* msm8939 RPM Power Domains */
142DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1);158DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1);
143DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1);159DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1);
@@ -436,6 +452,7 @@ static const struct rpmpd_desc qcm2290_desc = { · 292 unmodified lines
436 452
437static const struct of_device_id rpmpd_match_table[] = {453static const struct of_device_id rpmpd_match_table[] = {
438 { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc },454 { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc },
455 { .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc },
439 { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },456 { .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
440 { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },457 { .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },
441 { .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc },458 { .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc },
@@ -610,6 +627,9 @@ static int rpmpd_probe(struct platform_device *pdev) · 168 unmodified lines
610 627
611 data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains),628 data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains),
612 GFP_KERNEL);629 GFP_KERNEL);
630 if (!data->domains)
631 return -ENOMEM;
632
613 data->num_domains = num;633 data->num_domains = num;
614 634
615 for (i = 0; i < num; i++) {635 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
104 [36] = "PM8009",104 [36] = "PM8009",
105 [38] = "PM8150C",105 [38] = "PM8150C",
106 [41] = "SMB2351",106 [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",
107};115};
108#endif /* CONFIG_DEBUG_FS */116#endif /* CONFIG_DEBUG_FS */
109 117
@@ -314,10 +322,14 @@ static const struct soc_id soc_id[] = { · 204 unmodified lines
314 { 422, "IPQ6010" },322 { 422, "IPQ6010" },
315 { 425, "SC7180" },323 { 425, "SC7180" },
316 { 434, "SM6350" },324 { 434, "SM6350" },
325 { 439, "SM8350" },
326 { 449, "SC8280XP" },
317 { 453, "IPQ6005" },327 { 453, "IPQ6005" },
318 { 455, "QRB5165" },328 { 455, "QRB5165" },
319 { 457, "SM8450" },329 { 457, "SM8450" },
320 { 459, "SM7225" },330 { 459, "SM7225" },
331 { 460, "SA8540P" },
332 { 480, "SM8450" },
321};333};
322 334
323static const char *socinfo_machine(struct device *dev, unsigned int id)335static 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
40 select SYS_SUPPORTS_SH_TMU40 select SYS_SUPPORTS_SH_TMU
41 select SYSC_RMOBILE41 select SYSC_RMOBILE
42 42
43config ARCH_RZG2L
44 bool
45 select PM
46 select PM_GENERIC_DOMAINS
47
43config ARCH_RZN148config ARCH_RZN1
44 bool49 bool
45 select ARM_AMBA50 select ARM_AMBA
@@ -293,9 +298,16 @@ config ARCH_R8A774B1 · 247 unmodified lines
293 298
294config ARCH_R9A07G044299config ARCH_R9A07G044
295 bool "ARM64 Platform support for RZ/G2L"300 bool "ARM64 Platform support for RZ/G2L"
301 select ARCH_RZG2L
296 help302 help
297 This enables support for the Renesas RZ/G2L SoC variants.303 This enables support for the Renesas RZ/G2L SoC variants.
298 304
305config 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
299endif # ARM64311endif # ARM64
300 312
301config RST_RCAR313config 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
64 .name = "RZ/G2L",64 .name = "RZ/G2L",
65};65};
66 66
67static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
68 .name = "RZ/V2L",
69};
70
67static const struct renesas_family fam_shmobile __initconst __maybe_unused = {71static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
68 .name = "SH-Mobile",72 .name = "SH-Mobile",
69 .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */73 .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
144 .id = 0x841c447,148 .id = 0x841c447,
145};149};
146 150
151static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
152 .family = &fam_rzv2l,
153 .id = 0x8447447,
154};
155
147static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {156static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
148 .family = &fam_rcar_gen1,157 .family = &fam_rcar_gen1,
149};158};
@@ -334,6 +343,9 @@ static const struct of_device_id renesas_socs[] __initconst = { · 184 unmodified lines
334#if defined(CONFIG_ARCH_R9A07G044)343#if defined(CONFIG_ARCH_R9A07G044)
335 { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l },344 { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l },
336#endif345#endif
346#if defined(CONFIG_ARCH_R9A07G054)
347 { .compatible = "renesas,r9a07g054", .data = &soc_rz_v2l },
348#endif
337#ifdef CONFIG_ARCH_SH73A0349#ifdef CONFIG_ARCH_SH73A0
338 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },350 { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
339#endif351#endif
@@ -367,6 +379,7 @@ static const struct renesas_id id_prr __initconst = { · 27 unmodified lines
367static const struct of_device_id renesas_ids[] __initconst = {379static const struct of_device_id renesas_ids[] __initconst = {
368 { .compatible = "renesas,bsid", .data = &id_bsid },380 { .compatible = "renesas,bsid", .data = &id_bsid },
369 { .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },381 { .compatible = "renesas,r9a07g044-sysc", .data = &id_rzg2l },
382 { .compatible = "renesas,r9a07g054-sysc", .data = &id_rzg2l },
370 { .compatible = "renesas,prr", .data = &id_prr },383 { .compatible = "renesas,prr", .data = &id_prr },
371 { /* sentinel */ }384 { /* sentinel */ }
372};385};
@@ -380,9 +393,11 @@ static int __init renesas_soc_init(void) · 7 unmodified lines
380 const struct renesas_soc *soc;393 const struct renesas_soc *soc;
381 const struct renesas_id *id;394 const struct renesas_id *id;
382 void __iomem *chipid = NULL;395 void __iomem *chipid = NULL;
396 const char *rev_prefix = "";
383 struct soc_device *soc_dev;397 struct soc_device *soc_dev;
384 struct device_node *np;398 struct device_node *np;
385 const char *soc_id;399 const char *soc_id;
400 int ret;
386 401
387 match = of_match_node(renesas_socs, of_root);402 match = of_match_node(renesas_socs, of_root);
388 if (!match)403 if (!match)
@@ -403,6 +418,17 @@ static int __init renesas_soc_init(void) · 14 unmodified lines
403 chipid = ioremap(family->reg, 4);418 chipid = ioremap(family->reg, 4);
404 }419 }
405 420
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
406 if (chipid) {432 if (chipid) {
407 product = readl(chipid + id->offset);433 product = readl(chipid + id->offset);
408 iounmap(chipid);434 iounmap(chipid);
@@ -417,41 +443,39 @@ static int __init renesas_soc_init(void) · 8 unmodified lines
417 443
418 eshi = ((product >> 4) & 0x0f) + 1;444 eshi = ((product >> 4) & 0x0f) + 1;
419 eslo = product & 0xf;445 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 ";
420 }453 }
421 454
422 if (soc->id &&455 if (soc->id &&
423 ((product & id->mask) >> __ffs(id->mask)) != soc->id) {456 ((product & id->mask) >> __ffs(id->mask)) != soc->id) {
424 pr_warn("SoC mismatch (product = 0x%x)\n", product);457 pr_warn("SoC mismatch (product = 0x%x)\n", product);
425 return -ENODEV;458 ret = -ENODEV;
459 goto free_soc_dev_attr;
426 }460 }
427 }461 }
428 462
429 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);463 pr_info("Detected Renesas %s %s %s%s\n", soc_dev_attr->family,
430 if (!soc_dev_attr)464 soc_dev_attr->soc_id, rev_prefix, soc_dev_attr->revision ?: "");
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 ?: "");
445 465
446 soc_dev = soc_device_register(soc_dev_attr);466 soc_dev = soc_device_register(soc_dev_attr);
447 if (IS_ERR(soc_dev)) {467 if (IS_ERR(soc_dev)) {
448 kfree(soc_dev_attr->revision);468 ret = PTR_ERR(soc_dev);
449 kfree_const(soc_dev_attr->soc_id);469 goto free_soc_dev_attr;
450 kfree_const(soc_dev_attr->family);
451 kfree(soc_dev_attr);
452 return PTR_ERR(soc_dev);
453 }470 }
454 471
455 return 0;472 return 0;
473
474free_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;
456}480}
457early_initcall(renesas_soc_init);481early_initcall(renesas_soc_init);
drivers/soc/tegra/fuse/fuse-tegra.c+21−3
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2/*2/*
3 * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved.3 * Copyright (c) 2013-2021, NVIDIA CORPORATION. All rights reserved.
4 */4 */
5 5
6#include <linux/clk.h>6#include <linux/clk.h>
@@ -161,6 +161,12 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = { · 154 unmodified lines
161 .bytes = 4,161 .bytes = 4,
162 .bit_offset = 0,162 .bit_offset = 0,
163 .nbits = 32,163 .nbits = 32,
164 }, {
165 .name = "gcplex-config-fuse",
166 .offset = 0x1c8,
167 .bytes = 4,
168 .bit_offset = 0,
169 .nbits = 32,
164 }, {170 }, {
165 .name = "tsensor-realignment",171 .name = "tsensor-realignment",
166 .offset = 0x1fc,172 .offset = 0x1fc,
@@ -179,13 +185,25 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = { · 12 unmodified lines
179 .bytes = 4,185 .bytes = 4,
180 .bit_offset = 0,186 .bit_offset = 0,
181 .nbits = 32,187 .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,
182 },200 },
183};201};
184 202
185static void tegra_fuse_restore(void *base)203static void tegra_fuse_restore(void *base)
186{204{
205 fuse->base = (void __iomem *)base;
187 fuse->clk = NULL;206 fuse->clk = NULL;
188 fuse->base = base;
189}207}
190 208
191static int tegra_fuse_probe(struct platform_device *pdev)209static int tegra_fuse_probe(struct platform_device *pdev)
@@ -195,7 +213,7 @@ static int tegra_fuse_probe(struct platform_device *pdev) · 3 unmodified lines
195 struct resource *res;213 struct resource *res;
196 int err;214 int err;
197 215
198 err = devm_add_action(&pdev->dev, tegra_fuse_restore, base);216 err = devm_add_action(&pdev->dev, tegra_fuse_restore, (void __force *)base);
199 if (err)217 if (err)
200 return err;218 return err;
201 219
drivers/soc/tegra/pmc.c+11−5
@@ -3,7 +3,7 @@ · 2 unmodified lines
3 * drivers/soc/tegra/pmc.c3 * drivers/soc/tegra/pmc.c
4 *4 *
5 * Copyright (c) 2010 Google, Inc5 * 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.
7 *7 *
8 * Author:8 * Author:
9 * Colin Cross <ccross@google.com>9 * Colin Cross <ccross@google.com>
@@ -54,6 +54,7 @@ · 44 unmodified lines
54#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>54#include <dt-bindings/pinctrl/pinctrl-tegra-io-pad.h>
55#include <dt-bindings/gpio/tegra186-gpio.h>55#include <dt-bindings/gpio/tegra186-gpio.h>
56#include <dt-bindings/gpio/tegra194-gpio.h>56#include <dt-bindings/gpio/tegra194-gpio.h>
57#include <dt-bindings/gpio/tegra234-gpio.h>
57#include <dt-bindings/soc/tegra-pmc.h>58#include <dt-bindings/soc/tegra-pmc.h>
58 59
59#define PMC_CNTRL 0x060#define PMC_CNTRL 0x0
@@ -3066,7 +3067,7 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc, · 3006 unmodified lines
3066}3067}
3067 3068
3068static const struct tegra_pmc_soc tegra20_pmc_soc = {3069static const struct tegra_pmc_soc tegra20_pmc_soc = {
3069 .supports_core_domain = false,3070 .supports_core_domain = true,
3070 .num_powergates = ARRAY_SIZE(tegra20_powergates),3071 .num_powergates = ARRAY_SIZE(tegra20_powergates),
3071 .powergates = tegra20_powergates,3072 .powergates = tegra20_powergates,
3072 .num_cpu_powergates = 0,3073 .num_cpu_powergates = 0,
@@ -3127,7 +3128,7 @@ static const char * const tegra30_reset_sources[] = { · 54 unmodified lines
3127};3128};
3128 3129
3129static const struct tegra_pmc_soc tegra30_pmc_soc = {3130static const struct tegra_pmc_soc tegra30_pmc_soc = {
3130 .supports_core_domain = false,3131 .supports_core_domain = true,
3131 .num_powergates = ARRAY_SIZE(tegra30_powergates),3132 .num_powergates = ARRAY_SIZE(tegra30_powergates),
3132 .powergates = tegra30_powergates,3133 .powergates = tegra30_powergates,
3133 .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),3134 .num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
@@ -3788,6 +3789,11 @@ static const char * const tegra234_reset_sources[] = { · 654 unmodified lines
3788 "FUSECRC",3789 "FUSECRC",
3789};3790};
3790 3791
3792static 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
3791static const struct tegra_pmc_soc tegra234_pmc_soc = {3797static const struct tegra_pmc_soc tegra234_pmc_soc = {
3792 .supports_core_domain = false,3798 .supports_core_domain = false,
3793 .num_powergates = 0,3799 .num_powergates = 0,
@@ -3812,8 +3818,8 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = { · 18 unmodified lines
3812 .num_reset_sources = ARRAY_SIZE(tegra234_reset_sources),3818 .num_reset_sources = ARRAY_SIZE(tegra234_reset_sources),
3813 .reset_levels = tegra186_reset_levels,3819 .reset_levels = tegra186_reset_levels,
3814 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),3820 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels),
3815 .num_wake_events = 0,3821 .num_wake_events = ARRAY_SIZE(tegra234_wake_events),
3816 .wake_events = NULL,3822 .wake_events = tegra234_wake_events,
3817 .pmc_clks_data = NULL,3823 .pmc_clks_data = NULL,
3818 .num_pmc_clks = 0,3824 .num_pmc_clks = 0,
3819 .has_blink_output = false,3825 .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
1402 sizeof(*ringacc->rings) *1402 sizeof(*ringacc->rings) *
1403 ringacc->num_rings,1403 ringacc->num_rings,
1404 GFP_KERNEL);1404 GFP_KERNEL);
1405 ringacc->rings_inuse = devm_kcalloc(dev,1405 ringacc->rings_inuse = devm_bitmap_zalloc(dev, ringacc->num_rings,
1406 BITS_TO_LONGS(ringacc->num_rings),1406 GFP_KERNEL);
1407 sizeof(unsigned long), GFP_KERNEL);1407 ringacc->proxy_inuse = devm_bitmap_zalloc(dev, ringacc->num_proxies,
1408 ringacc->proxy_inuse = devm_kcalloc(dev,1408 GFP_KERNEL);
1409 BITS_TO_LONGS(ringacc->num_proxies),
1410 sizeof(unsigned long), GFP_KERNEL);
1411 1409
1412 if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse)1410 if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse)
1413 return -ENOMEM;1411 return -ENOMEM;
@@ -1483,9 +1481,8 @@ struct k3_ringacc *k3_ringacc_dmarings_init(struct platform_device *pdev, · 69 unmodified lines
1483 sizeof(*ringacc->rings) *1481 sizeof(*ringacc->rings) *
1484 ringacc->num_rings * 2,1482 ringacc->num_rings * 2,
1485 GFP_KERNEL);1483 GFP_KERNEL);
1486 ringacc->rings_inuse = devm_kcalloc(dev,1484 ringacc->rings_inuse = devm_bitmap_zalloc(dev, ringacc->num_rings,
1487 BITS_TO_LONGS(ringacc->num_rings),1485 GFP_KERNEL);
1488 sizeof(unsigned long), GFP_KERNEL);
1489 1486
1490 if (!ringacc->rings || !ringacc->rings_inuse)1487 if (!ringacc->rings || !ringacc->rings_inuse)
1491 return ERR_PTR(-ENOMEM);1488 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
42 { 0xBB6D, "J7200" },42 { 0xBB6D, "J7200" },
43 { 0xBB38, "AM64X" },43 { 0xBB38, "AM64X" },
44 { 0xBB75, "J721S2"},44 { 0xBB75, "J721S2"},
45 { 0xBB7E, "AM62X" },
45};46};
46 47
47static int48static int
drivers/soc/ti/smartreflex.c+7−6
@@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev) · 818 unmodified lines
819{819{
820 struct omap_sr *sr_info;820 struct omap_sr *sr_info;
821 struct omap_sr_data *pdata = pdev->dev.platform_data;821 struct omap_sr_data *pdata = pdev->dev.platform_data;
822 struct resource *mem, *irq;822 struct resource *mem;
823 struct dentry *nvalue_dir;823 struct dentry *nvalue_dir;
824 int i, ret = 0;824 int i, ret = 0;
825 825
@@ -844,7 +844,11 @@ static int omap_sr_probe(struct platform_device *pdev) · 18 unmodified lines
844 if (IS_ERR(sr_info->base))844 if (IS_ERR(sr_info->base))
845 return PTR_ERR(sr_info->base);845 return PTR_ERR(sr_info->base);
846 846
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;
848 852
849 sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");853 sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
850 if (IS_ERR(sr_info->fck))854 if (IS_ERR(sr_info->fck))
@@ -870,9 +874,6 @@ static int omap_sr_probe(struct platform_device *pdev) · 19 unmodified lines
870 sr_info->autocomp_active = false;874 sr_info->autocomp_active = false;
871 sr_info->ip_type = pdata->ip_type;875 sr_info->ip_type = pdata->ip_type;
872 876
873 if (irq)
874 sr_info->irq = irq->start;
875
876 sr_set_clk_length(sr_info);877 sr_set_clk_length(sr_info);
877 878
878 list_add(&sr_info->node, &sr_list);879 list_add(&sr_info->node, &sr_list);
@@ -926,7 +927,7 @@ static int omap_sr_probe(struct platform_device *pdev) · 47 unmodified lines
926 927
927 }928 }
928 929
929 return ret;930 return 0;
930 931
931err_debugfs:932err_debugfs:
932 debugfs_remove_recursive(sr_info->dbg_dir);933 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
450 return PTR_ERR(m3_ipc->ipc_mem_base);450 return PTR_ERR(m3_ipc->ipc_mem_base);
451 451
452 irq = platform_get_irq(pdev, 0);452 irq = platform_get_irq(pdev, 0);
453 if (!irq) {453 if (irq < 0) {
454 dev_err(&pdev->dev, "no irq resource\n");454 dev_err(&pdev->dev, "no irq resource\n");
455 return -ENXIO;455 return irq;
456 }456 }
457 457
458 ret = devm_request_irq(dev, irq, wkup_m3_txev_handler,458 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
122}122}
123 123
124static DEFINE_MUTEX(ta_refcount_mutex);124static DEFINE_MUTEX(ta_refcount_mutex);
125static struct list_head ta_list = LIST_HEAD_INIT(ta_list);125static LIST_HEAD(ta_list);
126 126
127static u32 get_ta_refcount(u32 ta_handle)127static u32 get_ta_refcount(u32 ta_handle)
128{128{
drivers/tee/amdtee/shm_pool.c+16−39
@@ -8,13 +8,17 @@ · 7 unmodified lines
8#include <linux/psp-sev.h>8#include <linux/psp-sev.h>
9#include "amdtee_private.h"9#include "amdtee_private.h"
10 10
11static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm,11static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
12 size_t size)12 size_t size, size_t align)
13{13{
14 unsigned int order = get_order(size);14 unsigned int order = get_order(size);
15 unsigned long va;15 unsigned long va;
16 int rc;16 int rc;
17 17
18 /*
19 * Ignore alignment since this is already going to be page aligned
20 * and there's no need for any larger alignment.
21 */
18 va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);22 va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
19 if (!va)23 if (!va)
20 return -ENOMEM;24 return -ENOMEM;
@@ -34,7 +38,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, · 13 unmodified lines
34 return 0;38 return 0;
35}39}
36 40
37static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm)41static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
38{42{
39 /* Unmap the shared memory from TEE */43 /* Unmap the shared memory from TEE */
40 amdtee_unmap_shmem(shm);44 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
42 shm->kaddr = NULL;46 shm->kaddr = NULL;
43}47}
44 48
45static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)49static void pool_op_destroy_pool(struct tee_shm_pool *pool)
46{50{
47 kfree(poolm);51 kfree(pool);
48}52}
49 53
50static const struct tee_shm_pool_mgr_ops pool_ops = {54static const struct tee_shm_pool_ops pool_ops = {
51 .alloc = pool_op_alloc,55 .alloc = pool_op_alloc,
52 .free = pool_op_free,56 .free = pool_op_free,
53 .destroy_poolmgr = pool_op_destroy_poolmgr,57 .destroy_pool = pool_op_destroy_pool,
54};58};
55 59
56static 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
68struct tee_shm_pool *amdtee_config_shm(void)60struct tee_shm_pool *amdtee_config_shm(void)
69{61{
70 struct tee_shm_pool_mgr *priv_mgr;62 struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
71 struct tee_shm_pool_mgr *dmabuf_mgr;
72 void *rc;
73 63
74 rc = pool_mem_mgr_alloc();64 if (!pool)
75 if (IS_ERR(rc))65 return ERR_PTR(-ENOMEM);
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;
85 66
86 rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);67 pool->ops = &pool_ops;
87 if (IS_ERR(rc)) {
88 tee_shm_pool_mgr_destroy(priv_mgr);
89 tee_shm_pool_mgr_destroy(dmabuf_mgr);
90 }
91 68
92 return rc;69 return pool;
93}70}
drivers/tee/optee/Kconfig+0−8
@@ -7,11 +7,3 @@ config OPTEE · 6 unmodified lines
7 help7 help
8 This implements the OP-TEE Trusted Execution Environment (TEE)8 This implements the OP-TEE Trusted Execution Environment (TEE)
9 driver.9 driver.
10
11config 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
120 if (optee->rpc_arg_count)120 if (optee->rpc_arg_count)
121 sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);121 sz += OPTEE_MSG_GET_ARG_SIZE(optee->rpc_arg_count);
122 122
123 shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED | TEE_SHM_PRIV);123 shm = tee_shm_alloc_priv_buf(ctx, sz);
124 if (IS_ERR(shm))124 if (IS_ERR(shm))
125 return shm;125 return shm;
126 126
drivers/tee/optee/core.c+17−4
@@ -18,8 +18,8 @@ · 17 unmodified lines
18#include <linux/workqueue.h>18#include <linux/workqueue.h>
19#include "optee_private.h"19#include "optee_private.h"
20 20
21int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,21int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
22 struct tee_shm *shm, size_t size,22 size_t size, size_t align,
23 int (*shm_register)(struct tee_context *ctx,23 int (*shm_register)(struct tee_context *ctx,
24 struct tee_shm *shm,24 struct tee_shm *shm,
25 struct page **pages,25 struct page **pages,
@@ -30,6 +30,10 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 4 unmodified lines
30 struct page *page;30 struct page *page;
31 int rc = 0;31 int rc = 0;
32 32
33 /*
34 * Ignore alignment since this is already going to be page aligned
35 * and there's no need for any larger alignment.
36 */
33 page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);37 page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
34 if (!page)38 if (!page)
35 return -ENOMEM;39 return -ENOMEM;
@@ -51,7 +55,6 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 15 unmodified lines
51 for (i = 0; i < nr_pages; i++)55 for (i = 0; i < nr_pages; i++)
52 pages[i] = page + i;56 pages[i] = page + i;
53 57
54 shm->flags |= TEE_SHM_REGISTER;
55 rc = shm_register(shm->ctx, shm, pages, nr_pages,58 rc = shm_register(shm->ctx, shm, pages, nr_pages,
56 (unsigned long)shm->kaddr);59 (unsigned long)shm->kaddr);
57 kfree(pages);60 kfree(pages);
@@ -62,10 +65,20 @@ int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, · 4 unmodified lines
62 return 0;65 return 0;
63 66
64err:67err:
65 __free_pages(page, order);68 free_pages((unsigned long)shm->kaddr, order);
66 return rc;69 return rc;
67}70}
68 71
72void 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
69static void optee_bus_scan(struct work_struct *work)82static void optee_bus_scan(struct work_struct *work)
70{83{
71 WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));84 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
121 if (rc < 0 || !shm_size)121 if (rc < 0 || !shm_size)
122 goto out_sess;122 goto out_sess;
123 123
124 device_shm = tee_shm_alloc(ctx, shm_size,124 device_shm = tee_shm_alloc_kernel_buf(ctx, shm_size);
125 TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
126 if (IS_ERR(device_shm)) {125 if (IS_ERR(device_shm)) {
127 pr_err("tee_shm_alloc failed\n");126 pr_err("tee_shm_alloc_kernel_buf failed\n");
128 rc = PTR_ERR(device_shm);127 rc = PTR_ERR(device_shm);
129 goto out_sess;128 goto out_sess;
130 }129 }
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
369 * The main function is optee_ffa_shm_pool_alloc_pages().369 * The main function is optee_ffa_shm_pool_alloc_pages().
370 */370 */
371 371
372static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm,372static int pool_ffa_op_alloc(struct tee_shm_pool *pool,
373 struct tee_shm *shm, size_t size)373 struct tee_shm *shm, size_t size, size_t align)
374{374{
375 return optee_pool_op_alloc_helper(poolm, shm, size,375 return optee_pool_op_alloc_helper(pool, shm, size, align,
376 optee_ffa_shm_register);376 optee_ffa_shm_register);
377}377}
378 378
379static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm,379static void pool_ffa_op_free(struct tee_shm_pool *pool,
380 struct tee_shm *shm)380 struct tee_shm *shm)
381{381{
382 optee_ffa_shm_unregister(shm->ctx, shm);382 optee_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
383 free_pages((unsigned long)shm->kaddr, get_order(shm->size));
384 shm->kaddr = NULL;
385}383}
386 384
387static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)385static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool)
388{386{
389 kfree(poolm);387 kfree(pool);
390}388}
391 389
392static const struct tee_shm_pool_mgr_ops pool_ffa_ops = {390static const struct tee_shm_pool_ops pool_ffa_ops = {
393 .alloc = pool_ffa_op_alloc,391 .alloc = pool_ffa_op_alloc,
394 .free = pool_ffa_op_free,392 .free = pool_ffa_op_free,
395 .destroy_poolmgr = pool_ffa_op_destroy_poolmgr,393 .destroy_pool = pool_ffa_op_destroy_pool,
396};394};
397 395
398/**396/**
@@ -401,16 +399,16 @@ static const struct tee_shm_pool_mgr_ops pool_ffa_ops = { · 2 unmodified lines
401 * This pool is used with OP-TEE over FF-A. In this case command buffers399 * This pool is used with OP-TEE over FF-A. In this case command buffers
402 * and such are allocated from kernel's own memory.400 * and such are allocated from kernel's own memory.
403 */401 */
404static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void)402static struct tee_shm_pool *optee_ffa_shm_pool_alloc_pages(void)
405{403{
406 struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);404 struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
407 405
408 if (!mgr)406 if (!pool)
409 return ERR_PTR(-ENOMEM);407 return ERR_PTR(-ENOMEM);
410 408
411 mgr->ops = &pool_ffa_ops;409 pool->ops = &pool_ffa_ops;
412 410
413 return mgr;411 return pool;
414}412}
415 413
416/*414/*
@@ -440,8 +438,8 @@ static void handle_ffa_rpc_func_cmd_shm_alloc(struct tee_context *ctx, · 23 unmodified lines
440 shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);438 shm = optee_rpc_cmd_alloc_suppl(ctx, arg->params[0].u.value.b);
441 break;439 break;
442 case OPTEE_RPC_SHM_TYPE_KERNEL:440 case OPTEE_RPC_SHM_TYPE_KERNEL:
443 shm = tee_shm_alloc(optee->ctx, arg->params[0].u.value.b,441 shm = tee_shm_alloc_priv_buf(optee->ctx,
444 TEE_SHM_MAPPED | TEE_SHM_PRIV);442 arg->params[0].u.value.b);
445 break;443 break;
446 default:444 default:
447 arg->ret = TEEC_ERROR_BAD_PARAMETERS;445 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -700,33 +698,6 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, · 252 unmodified lines
700 return true;698 return true;
701}699}
702 700
703static 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
730static void optee_ffa_get_version(struct tee_device *teedev,701static void optee_ffa_get_version(struct tee_device *teedev,
731 struct tee_ioctl_version_data *vers)702 struct tee_ioctl_version_data *vers)
732{703{
@@ -824,7 +795,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) · 91 unmodified lines
824 if (!optee)795 if (!optee)
825 return -ENOMEM;796 return -ENOMEM;
826 797
827 pool = optee_ffa_config_dyn_shm();798 pool = optee_ffa_shm_pool_alloc_pages();
828 if (IS_ERR(pool)) {799 if (IS_ERR(pool)) {
829 rc = PTR_ERR(pool);800 rc = PTR_ERR(pool);
830 goto err_free_optee;801 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
229int optee_enumerate_devices(u32 func);229int optee_enumerate_devices(u32 func);
230void optee_unregister_devices(void);230void optee_unregister_devices(void);
231 231
232int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm,232int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
233 struct tee_shm *shm, size_t size,233 size_t size, size_t align,
234 int (*shm_register)(struct tee_context *ctx,234 int (*shm_register)(struct tee_context *ctx,
235 struct tee_shm *shm,235 struct tee_shm *shm,
236 struct page **pages,236 struct page **pages,
237 size_t num_pages,237 size_t num_pages,
238 unsigned long start));238 unsigned long start));
239void 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));
239 242
240 243
241void optee_remove_common(struct optee *optee);244void optee_remove_common(struct optee *optee);
drivers/tee/optee/smc_abi.c+37−88
@@ -42,7 +42,15 @@ · 41 unmodified lines
42 * 6. Driver initialization.42 * 6. Driver initialization.
43 */43 */
44 44
45#define OPTEE_SHM_NUM_PRIV_PAGES CONFIG_OPTEE_SHM_NUM_PRIV_PAGES45/*
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 */
46 54
47/*55/*
48 * 1. Convert between struct tee_param and struct optee_msg_param56 * 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
220 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:228 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
221 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:229 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
222 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:230 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))
224 rc = to_msg_param_reg_mem(mp, p);232 rc = to_msg_param_reg_mem(mp, p);
225 else233 else
226 rc = to_msg_param_tmp_mem(mp, p);234 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
522 * The main function is optee_shm_pool_alloc_pages().530 * The main function is optee_shm_pool_alloc_pages().
523 */531 */
524 532
525static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,533static int pool_op_alloc(struct tee_shm_pool *pool,
526 struct tee_shm *shm, size_t size)534 struct tee_shm *shm, size_t size, size_t align)
527{535{
528 /*536 /*
529 * Shared memory private to the OP-TEE driver doesn't need537 * Shared memory private to the OP-TEE driver doesn't need
530 * to be registered with OP-TEE.538 * to be registered with OP-TEE.
531 */539 */
532 if (shm->flags & TEE_SHM_PRIV)540 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);
534 542
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);
536}545}
537 546
538static void pool_op_free(struct tee_shm_pool_mgr *poolm,547static void pool_op_free(struct tee_shm_pool *pool,
539 struct tee_shm *shm)548 struct tee_shm *shm)
540{549{
541 if (!(shm->flags & TEE_SHM_PRIV))550 if (!(shm->flags & TEE_SHM_PRIV))
542 optee_shm_unregister(shm->ctx, shm);551 optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
543 552 else
544 free_pages((unsigned long)shm->kaddr, get_order(shm->size));553 optee_pool_op_free_helper(pool, shm, NULL);
545 shm->kaddr = NULL;
546}554}
547 555
548static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)556static void pool_op_destroy_pool(struct tee_shm_pool *pool)
549{557{
550 kfree(poolm);558 kfree(pool);
551}559}
552 560
553static const struct tee_shm_pool_mgr_ops pool_ops = {561static const struct tee_shm_pool_ops pool_ops = {
554 .alloc = pool_op_alloc,562 .alloc = pool_op_alloc,
555 .free = pool_op_free,563 .free = pool_op_free,
556 .destroy_poolmgr = pool_op_destroy_poolmgr,564 .destroy_pool = pool_op_destroy_pool,
557};565};
558 566
559/**567/**
@@ -562,16 +570,16 @@ static const struct tee_shm_pool_mgr_ops pool_ops = { · 2 unmodified lines
562 * This pool is used when OP-TEE supports dymanic SHM. In this case570 * This pool is used when OP-TEE supports dymanic SHM. In this case
563 * command buffers and such are allocated from kernel's own memory.571 * command buffers and such are allocated from kernel's own memory.
564 */572 */
565static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)573static struct tee_shm_pool *optee_shm_pool_alloc_pages(void)
566{574{
567 struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);575 struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
568 576
569 if (!mgr)577 if (!pool)
570 return ERR_PTR(-ENOMEM);578 return ERR_PTR(-ENOMEM);
571 579
572 mgr->ops = &pool_ops;580 pool->ops = &pool_ops;
573 581
574 return mgr;582 return pool;
575}583}
576 584
577/*585/*
@@ -642,8 +650,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx, · 64 unmodified lines
642 shm = optee_rpc_cmd_alloc_suppl(ctx, sz);650 shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
643 break;651 break;
644 case OPTEE_RPC_SHM_TYPE_KERNEL:652 case OPTEE_RPC_SHM_TYPE_KERNEL:
645 shm = tee_shm_alloc(optee->ctx, sz,653 shm = tee_shm_alloc_priv_buf(optee->ctx, sz);
646 TEE_SHM_MAPPED | TEE_SHM_PRIV);
647 break;654 break;
648 default:655 default:
649 arg->ret = TEEC_ERROR_BAD_PARAMETERS;656 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
662 669
663 sz = tee_shm_get_size(shm);670 sz = tee_shm_get_size(shm);
664 671
665 if (tee_shm_is_registered(shm)) {672 if (tee_shm_is_dynamic(shm)) {
666 struct page **pages;673 struct page **pages;
667 u64 *pages_list;674 u64 *pages_list;
668 size_t page_num;675 size_t page_num;
@@ -768,8 +775,7 @@ static void optee_handle_rpc(struct tee_context *ctx, · 99 unmodified lines
768 775
769 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {776 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
770 case OPTEE_SMC_RPC_FUNC_ALLOC:777 case OPTEE_SMC_RPC_FUNC_ALLOC:
771 shm = tee_shm_alloc(optee->ctx, param->a1,778 shm = tee_shm_alloc_priv_buf(optee->ctx, param->a1);
772 TEE_SHM_MAPPED | TEE_SHM_PRIV);
773 if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {779 if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
774 reg_pair_from_64(&param->a1, &param->a2, pa);780 reg_pair_from_64(&param->a1, &param->a2, pa);
775 reg_pair_from_64(&param->a4, &param->a5,781 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
1143 return true;1149 return true;
1144}1150}
1145 1151
1146static 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
1173static struct tee_shm_pool *1152static struct tee_shm_pool *
1174optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)1153optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
1175{1154{
@@ -1183,10 +1162,7 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) · 7 unmodified lines
1183 phys_addr_t begin;1162 phys_addr_t begin;
1184 phys_addr_t end;1163 phys_addr_t end;
1185 void *va;1164 void *va;
1186 struct tee_shm_pool_mgr *priv_mgr;
1187 struct tee_shm_pool_mgr *dmabuf_mgr;
1188 void *rc;1165 void *rc;
1189 const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
1190 1166
1191 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);1167 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
1192 if (res.result.status != OPTEE_SMC_RETURN_OK) {1168 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
1204 paddr = begin;1180 paddr = begin;
1205 size = end - begin;1181 size = end - begin;
1206 1182
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
1212 va = memremap(paddr, size, MEMREMAP_WB);1183 va = memremap(paddr, size, MEMREMAP_WB);
1213 if (!va) {1184 if (!va) {
1214 pr_err("shared memory ioremap failed\n");1185 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
1216 }1187 }
1217 vaddr = (unsigned long)va;1188 vaddr = (unsigned long)va;
1218 1189
1219 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,1190 rc = tee_shm_pool_alloc_res_mem(vaddr, paddr, size,
1220 3 /* 8 bytes aligned */);1191 OPTEE_MIN_STATIC_POOL_ALIGN);
1221 if (IS_ERR(rc))1192 if (IS_ERR(rc))
1222 goto err_memunmap;1193 memunmap(va);
1223 priv_mgr = rc;1194 else
1224 1195 *memremaped_shm = va;
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;
1241 1196
1242err_free_dmabuf_mgr:
1243 tee_shm_pool_mgr_destroy(dmabuf_mgr);
1244err_free_priv_mgr:
1245 tee_shm_pool_mgr_destroy(priv_mgr);
1246err_memunmap:
1247 memunmap(va);
1248 return rc;1197 return rc;
1249}1198}
1250 1199
@@ -1366,7 +1315,7 @@ static int optee_probe(struct platform_device *pdev) · 115 unmodified lines
1366 * Try to use dynamic shared memory if possible1315 * Try to use dynamic shared memory if possible
1367 */1316 */
1368 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)1317 if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
1369 pool = optee_config_dyn_shm();1318 pool = optee_shm_pool_alloc_pages();
1370 1319
1371 /*1320 /*
1372 * If dynamic shared memory is not available or failed - try static one1321 * 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
297 if (data.flags)297 if (data.flags)
298 return -EINVAL;298 return -EINVAL;
299 299
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);
301 if (IS_ERR(shm))301 if (IS_ERR(shm))
302 return PTR_ERR(shm);302 return PTR_ERR(shm);
303 303
@@ -334,8 +334,7 @@ tee_ioctl_shm_register(struct tee_context *ctx, · 30 unmodified lines
334 if (data.flags)334 if (data.flags)
335 return -EINVAL;335 return -EINVAL;
336 336
337 shm = tee_shm_register(ctx, data.addr, data.length,337 shm = tee_shm_register_user_buf(ctx, data.addr, data.length);
338 TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED);
339 if (IS_ERR(shm))338 if (IS_ERR(shm))
340 return PTR_ERR(shm);339 return PTR_ERR(shm);
341 340
drivers/tee/tee_private.h+4−11
@@ -12,17 +12,6 @@ · 11 unmodified lines
12#include <linux/mutex.h>12#include <linux/mutex.h>
13#include <linux/types.h>13#include <linux/types.h>
14 14
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 */
21struct tee_shm_pool {
22 struct tee_shm_pool_mgr *private_mgr;
23 struct tee_shm_pool_mgr *dma_buf_mgr;
24};
25
26#define TEE_DEVICE_FLAG_REGISTERED 0x115#define TEE_DEVICE_FLAG_REGISTERED 0x1
27#define TEE_MAX_DEV_NAME_LEN 3216#define TEE_MAX_DEV_NAME_LEN 32
28 17
@@ -68,4 +57,8 @@ void tee_device_put(struct tee_device *teedev); · 39 unmodified lines
68void teedev_ctx_get(struct tee_context *ctx);57void teedev_ctx_get(struct tee_context *ctx);
69void teedev_ctx_put(struct tee_context *ctx);58void teedev_ctx_put(struct tee_context *ctx);
70 59
60struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size);
61struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx,
62 unsigned long addr, size_t length);
63
71#endif /*TEE_PRIVATE_H*/64#endif /*TEE_PRIVATE_H*/
drivers/tee/tee_shm.c+210−110
@@ -12,17 +12,43 @@ · 11 unmodified lines
12#include <linux/uio.h>12#include <linux/uio.h>
13#include "tee_private.h"13#include "tee_private.h"
14 14
15static 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
23static 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
15static void release_registered_pages(struct tee_shm *shm)45static void release_registered_pages(struct tee_shm *shm)
16{46{
17 if (shm->pages) {47 if (shm->pages) {
18 if (shm->flags & TEE_SHM_USER_MAPPED) {48 if (shm->flags & TEE_SHM_USER_MAPPED)
19 unpin_user_pages(shm->pages, shm->num_pages);49 unpin_user_pages(shm->pages, shm->num_pages);
20 } else {50 else
21 size_t n;51 shm_put_kernel_pages(shm->pages, shm->num_pages);
22
23 for (n = 0; n < shm->num_pages; n++)
24 put_page(shm->pages[n]);
25 }
26 52
27 kfree(shm->pages);53 kfree(shm->pages);
28 }54 }
@@ -31,15 +57,8 @@ static void release_registered_pages(struct tee_shm *shm) · 2 unmodified lines
31static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)57static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm)
32{58{
33 if (shm->flags & TEE_SHM_POOL) {59 if (shm->flags & TEE_SHM_POOL) {
34 struct tee_shm_pool_mgr *poolm;60 teedev->pool->ops->free(teedev->pool, shm);
35 61 } else if (shm->flags & TEE_SHM_DYNAMIC) {
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) {
43 int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm);62 int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm);
44 63
45 if (rc)64 if (rc)
@@ -56,25 +75,14 @@ static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) · 10 unmodified lines
56 tee_device_put(teedev);75 tee_device_put(teedev);
57}76}
58 77
59struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)78static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size,
79 size_t align, u32 flags, int id)
60{80{
61 struct tee_device *teedev = ctx->teedev;81 struct tee_device *teedev = ctx->teedev;
62 struct tee_shm_pool_mgr *poolm = NULL;
63 struct tee_shm *shm;82 struct tee_shm *shm;
64 void *ret;83 void *ret;
65 int rc;84 int rc;
66 85
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
78 if (!tee_device_get(teedev))86 if (!tee_device_get(teedev))
79 return ERR_PTR(-EINVAL);87 return ERR_PTR(-EINVAL);
80 88
@@ -91,41 +99,76 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) · 10 unmodified lines
91 }99 }
92 100
93 refcount_set(&shm->refcount, 1);101 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 */
95 shm->ctx = ctx;111 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;
100 112
101 rc = poolm->ops->alloc(poolm, shm, size);113 rc = teedev->pool->ops->alloc(teedev->pool, shm, size, align);
102 if (rc) {114 if (rc) {
103 ret = ERR_PTR(rc);115 ret = ERR_PTR(rc);
104 goto err_kfree;116 goto err_kfree;
105 }117 }
106 118
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
117 teedev_ctx_get(ctx);119 teedev_ctx_get(ctx);
118
119 return shm;120 return shm;
120err_pool_free:
121 poolm->ops->free(poolm, shm);
122err_kfree:121err_kfree:
123 kfree(shm);122 kfree(shm);
124err_dev_put:123err_dev_put:
125 tee_device_put(teedev);124 tee_device_put(teedev);
126 return ret;125 return ret;
127}126}
128EXPORT_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 */
140struct 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}
129 172
130/**173/**
131 * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer174 * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer
@@ -141,32 +184,54 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc); · 9 unmodified lines
141 */184 */
142struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size)185struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size)
143{186{
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);
145}190}
146EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf);191EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf);
147 192
148struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,193/**
149 size_t length, u32 flags)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 */
209struct 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}
215EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf);
216
217static struct tee_shm *
218register_shm_helper(struct tee_context *ctx, unsigned long addr,
219 size_t length, u32 flags, int id)
150{220{
151 struct tee_device *teedev = ctx->teedev;221 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;
154 struct tee_shm *shm;222 struct tee_shm *shm;
223 unsigned long start;
224 size_t num_pages;
155 void *ret;225 void *ret;
156 int rc;226 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);
162 227
163 if (!tee_device_get(teedev))228 if (!tee_device_get(teedev))
164 return ERR_PTR(-EINVAL);229 return ERR_PTR(-EINVAL);
165 230
166 if (!teedev->desc->ops->shm_register ||231 if (!teedev->desc->ops->shm_register ||
167 !teedev->desc->ops->shm_unregister) {232 !teedev->desc->ops->shm_unregister) {
168 tee_device_put(teedev);233 ret = ERR_PTR(-ENOTSUPP);
169 return ERR_PTR(-ENOTSUPP);234 goto err_dev_put;
170 }235 }
171 236
172 teedev_ctx_get(ctx);237 teedev_ctx_get(ctx);
@@ -174,13 +239,13 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 1 unmodified line
174 shm = kzalloc(sizeof(*shm), GFP_KERNEL);239 shm = kzalloc(sizeof(*shm), GFP_KERNEL);
175 if (!shm) {240 if (!shm) {
176 ret = ERR_PTR(-ENOMEM);241 ret = ERR_PTR(-ENOMEM);
177 goto err;242 goto err_ctx_put;
178 }243 }
179 244
180 refcount_set(&shm->refcount, 1);245 refcount_set(&shm->refcount, 1);
181 shm->flags = flags | TEE_SHM_REGISTER;246 shm->flags = flags;
182 shm->ctx = ctx;247 shm->ctx = ctx;
183 shm->id = -1;248 shm->id = id;
184 addr = untagged_addr(addr);249 addr = untagged_addr(addr);
185 start = rounddown(addr, PAGE_SIZE);250 start = rounddown(addr, PAGE_SIZE);
186 shm->offset = addr - start;251 shm->offset = addr - start;
@@ -189,71 +254,106 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, · 2 unmodified lines
189 shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL);254 shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL);
190 if (!shm->pages) {255 if (!shm->pages) {
191 ret = ERR_PTR(-ENOMEM);256 ret = ERR_PTR(-ENOMEM);
192 goto err;257 goto err_free_shm;
193 }258 }
194 259
195 if (flags & TEE_SHM_USER_MAPPED) {260 if (flags & TEE_SHM_USER_MAPPED)
196 rc = pin_user_pages_fast(start, num_pages, FOLL_WRITE,261 rc = pin_user_pages_fast(start, num_pages, FOLL_WRITE,
197 shm->pages);262 shm->pages);
198 } else {263 else
199 struct kvec *kiov;264 rc = shm_get_kernel_pages(start, num_pages, shm->pages);
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 }
216 if (rc > 0)265 if (rc > 0)
217 shm->num_pages = rc;266 shm->num_pages = rc;
218 if (rc != num_pages) {267 if (rc != num_pages) {
219 if (rc >= 0)268 if (rc >= 0)
220 rc = -ENOMEM;269 rc = -ENOMEM;
221 ret = ERR_PTR(rc);270 ret = ERR_PTR(rc);
222 goto err;271 goto err_put_shm_pages;
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;
232 }272 }
233 273
234 rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages,274 rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages,
235 shm->num_pages, start);275 shm->num_pages, start);
236 if (rc) {276 if (rc) {
237 ret = ERR_PTR(rc);277 ret = ERR_PTR(rc);
238 goto err;278 goto err_put_shm_pages;
239 }279 }
240 280
241 return shm;281 return shm;
242err:282err_put_shm_pages:
243 if (shm) {283 if (flags & TEE_SHM_USER_MAPPED)
244 if (shm->id >= 0) {284 unpin_user_pages(shm->pages, shm->num_pages);
245 mutex_lock(&teedev->mutex);285 else
246 idr_remove(&teedev->idr, shm->id);286 shm_put_kernel_pages(shm->pages, shm->num_pages);
247 mutex_unlock(&teedev->mutex);287 kfree(shm->pages);
248 }288err_free_shm:
249 release_registered_pages(shm);
250 }
251 kfree(shm);289 kfree(shm);
290err_ctx_put:
252 teedev_ctx_put(ctx);291 teedev_ctx_put(ctx);
292err_dev_put:
253 tee_device_put(teedev);293 tee_device_put(teedev);
254 return ret;294 return ret;
255}295}
256EXPORT_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 */
305struct 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
349struct 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}
356EXPORT_SYMBOL_GPL(tee_shm_register_kernel_buf);
257 357
258static int tee_shm_fop_release(struct inode *inode, struct file *filp)358static int tee_shm_fop_release(struct inode *inode, struct file *filp)
259{359{
@@ -293,7 +393,7 @@ int tee_shm_get_fd(struct tee_shm *shm) · 33 unmodified lines
293{393{
294 int fd;394 int fd;
295 395
296 if (!(shm->flags & TEE_SHM_DMA_BUF))396 if (shm->id < 0)
297 return -EINVAL;397 return -EINVAL;
298 398
299 /* matched by tee_shm_put() in tee_shm_op_release() */399 /* matched by tee_shm_put() in tee_shm_op_release() */
@@ -323,7 +423,7 @@ EXPORT_SYMBOL_GPL(tee_shm_free); · 23 unmodified lines
323 */423 */
324int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa)424int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa)
325{425{
326 if (!(shm->flags & TEE_SHM_MAPPED))426 if (!shm->kaddr)
327 return -EINVAL;427 return -EINVAL;
328 /* Check that we're in the range of the shm */428 /* Check that we're in the range of the shm */
329 if ((char *)va < (char *)shm->kaddr)429 if ((char *)va < (char *)shm->kaddr)
@@ -345,7 +445,7 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa); · 15 unmodified lines
345 */445 */
346int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va)446int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va)
347{447{
348 if (!(shm->flags & TEE_SHM_MAPPED))448 if (!shm->kaddr)
349 return -EINVAL;449 return -EINVAL;
350 /* Check that we're in the range of the shm */450 /* Check that we're in the range of the shm */
351 if (pa < shm->paddr)451 if (pa < shm->paddr)
@@ -373,7 +473,7 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va); · 21 unmodified lines
373 */473 */
374void *tee_shm_get_va(struct tee_shm *shm, size_t offs)474void *tee_shm_get_va(struct tee_shm *shm, size_t offs)
375{475{
376 if (!(shm->flags & TEE_SHM_MAPPED))476 if (!shm->kaddr)
377 return ERR_PTR(-EINVAL);477 return ERR_PTR(-EINVAL);
378 if (offs >= shm->size)478 if (offs >= shm->size)
379 return ERR_PTR(-EINVAL);479 return ERR_PTR(-EINVAL);
@@ -448,7 +548,7 @@ void tee_shm_put(struct tee_shm *shm) · 68 unmodified lines
448 * the refcount_inc() in tee_shm_get_from_id() never starts548 * the refcount_inc() in tee_shm_get_from_id() never starts
449 * from 0.549 * from 0.
450 */550 */
451 if (shm->flags & TEE_SHM_DMA_BUF)551 if (shm->id >= 0)
452 idr_remove(&teedev->idr, shm->id);552 idr_remove(&teedev->idr, shm->id);
453 do_release = true;553 do_release = true;
454 }554 }
drivers/tee/tee_shm_pool.c+34−128
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0-only1// SPDX-License-Identifier: GPL-2.0-only
2/*2/*
3 * Copyright (c) 2015, Linaro Limited3 * Copyright (c) 2015, 2017, 2022 Linaro Limited
4 */4 */
5#include <linux/device.h>5#include <linux/device.h>
6#include <linux/dma-buf.h>6#include <linux/dma-buf.h>
@@ -9,14 +9,16 @@ · 2 unmodified lines
9#include <linux/tee_drv.h>9#include <linux/tee_drv.h>
10#include "tee_private.h"10#include "tee_private.h"
11 11
12static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm,12static int pool_op_gen_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
13 struct tee_shm *shm, size_t size)13 size_t size, size_t align)
14{14{
15 unsigned long va;15 unsigned long va;
16 struct gen_pool *genpool = poolm->private_data;16 struct gen_pool *genpool = pool->private_data;
17 size_t s = roundup(size, 1 << genpool->min_alloc_order);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);
18 20
19 va = gen_pool_alloc(genpool, s);21 va = gen_pool_alloc_algo(genpool, s, gen_pool_first_fit_align, &data);
20 if (!va)22 if (!va)
21 return -ENOMEM;23 return -ENOMEM;
22 24
@@ -24,163 +26,67 @@ static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm, · 1 unmodified line
24 shm->kaddr = (void *)va;26 shm->kaddr = (void *)va;
25 shm->paddr = gen_pool_virt_to_phys(genpool, va);27 shm->paddr = gen_pool_virt_to_phys(genpool, va);
26 shm->size = s;28 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;
27 return 0;34 return 0;
28}35}
29 36
30static void pool_op_gen_free(struct tee_shm_pool_mgr *poolm,37static void pool_op_gen_free(struct tee_shm_pool *pool, struct tee_shm *shm)
31 struct tee_shm *shm)
32{38{
33 gen_pool_free(poolm->private_data, (unsigned long)shm->kaddr,39 gen_pool_free(pool->private_data, (unsigned long)shm->kaddr,
34 shm->size);40 shm->size);
35 shm->kaddr = NULL;41 shm->kaddr = NULL;
36}42}
37 43
38static void pool_op_gen_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)44static void pool_op_gen_destroy_pool(struct tee_shm_pool *pool)
39{45{
40 gen_pool_destroy(poolm->private_data);46 gen_pool_destroy(pool->private_data);
41 kfree(poolm);47 kfree(pool);
42}48}
43 49
44static const struct tee_shm_pool_mgr_ops pool_ops_generic = {50static const struct tee_shm_pool_ops pool_ops_generic = {
45 .alloc = pool_op_gen_alloc,51 .alloc = pool_op_gen_alloc,
46 .free = pool_op_gen_free,52 .free = pool_op_gen_free,
47 .destroy_poolmgr = pool_op_gen_destroy_poolmgr,53 .destroy_pool = pool_op_gen_destroy_pool,
48};54};
49 55
50/**56struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
51 * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved57 phys_addr_t paddr, size_t size,
52 * memory range58 int min_alloc_order)
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 */
63struct tee_shm_pool *
64tee_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
97err_free_dmabuf_mgr:
98 tee_shm_pool_mgr_destroy(dmabuf_mgr);
99err_free_priv_mgr:
100 tee_shm_pool_mgr_destroy(priv_mgr);
101
102 return rc;
103}
104EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
105
106struct 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)
110{59{
111 const size_t page_mask = PAGE_SIZE - 1;60 const size_t page_mask = PAGE_SIZE - 1;
112 struct tee_shm_pool_mgr *mgr;61 struct tee_shm_pool *pool;
113 int rc;62 int rc;
114 63
115 /* Start and end must be page aligned */64 /* Start and end must be page aligned */
116 if (vaddr & page_mask || paddr & page_mask || size & page_mask)65 if (vaddr & page_mask || paddr & page_mask || size & page_mask)
117 return ERR_PTR(-EINVAL);66 return ERR_PTR(-EINVAL);
118 67
119 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);68 pool = kzalloc(sizeof(*pool), GFP_KERNEL);
120 if (!mgr)69 if (!pool)
121 return ERR_PTR(-ENOMEM);70 return ERR_PTR(-ENOMEM);
122 71
123 mgr->private_data = gen_pool_create(min_alloc_order, -1);72 pool->private_data = gen_pool_create(min_alloc_order, -1);
124 if (!mgr->private_data) {73 if (!pool->private_data) {
125 rc = -ENOMEM;74 rc = -ENOMEM;
126 goto err;75 goto err;
127 }76 }
128 77
129 gen_pool_set_algo(mgr->private_data, gen_pool_best_fit, NULL);78 rc = gen_pool_add_virt(pool->private_data, vaddr, paddr, size, -1);
130 rc = gen_pool_add_virt(mgr->private_data, vaddr, paddr, size, -1);
131 if (rc) {79 if (rc) {
132 gen_pool_destroy(mgr->private_data);80 gen_pool_destroy(pool->private_data);
133 goto err;81 goto err;
134 }82 }
135 83
136 mgr->ops = &pool_ops_generic;84 pool->ops = &pool_ops_generic;
137 85
138 return mgr;86 return pool;
139err:87err:
140 kfree(mgr);88 kfree(pool);
141 89
142 return ERR_PTR(rc);90 return ERR_PTR(rc);
143}91}
144EXPORT_SYMBOL_GPL(tee_shm_pool_mgr_alloc_res_mem);92EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
145
146static 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
152struct 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}
169EXPORT_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 */
178void 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}
186EXPORT_SYMBOL_GPL(tee_shm_pool_free);
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
18#define IMX8M_POWER_DOMAIN_MIPI_CSI2 918#define IMX8M_POWER_DOMAIN_MIPI_CSI2 9
19#define IMX8M_POWER_DOMAIN_PCIE2 1019#define IMX8M_POWER_DOMAIN_PCIE2 10
20 20
21#define IMX8MQ_VPUBLK_PD_G1 0
22#define IMX8MQ_VPUBLK_PD_G2 1
23
21#endif24#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
139#define MDM9607_VDDMX_AO 4139#define MDM9607_VDDMX_AO 4
140#define MDM9607_VDDMX_VFL 5140#define MDM9607_VDDMX_VFL 5
141 141
142/* MSM8226 Power Domain Indexes */
143#define MSM8226_VDDCX 0
144#define MSM8226_VDDCX_AO 1
145#define MSM8226_VDDCX_VFC 2
146
142/* MSM8939 Power Domains */147/* MSM8939 Power Domains */
143#define MSM8939_VDDMDCX 0148#define MSM8939_VDDMDCX 0
144#define MSM8939_VDDMDCX_AO 1149#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
59 59
60#if IS_ENABLED(CONFIG_IMX_SCU)60#if IS_ENABLED(CONFIG_IMX_SCU)
61bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);61bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
62int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt);
62#else63#else
63static inline bool64static inline bool
64imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)65imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
65{66{
66 return true;67 return true;
67}68}
69static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
70{
71 return -EOPNOTSUPP;
72}
68#endif73#endif
69#endif74#endif
include/linux/qcom_scm.h+13−3
@@ -63,13 +63,21 @@ enum qcom_scm_ice_cipher { · 62 unmodified lines
63 63
64extern bool qcom_scm_is_available(void);64extern bool qcom_scm_is_available(void);
65 65
66extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);66extern int qcom_scm_set_cold_boot_addr(void *entry);
67extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);67extern int qcom_scm_set_warm_boot_addr(void *entry);
68extern void qcom_scm_cpu_power_down(u32 flags);68extern void qcom_scm_cpu_power_down(u32 flags);
69extern int qcom_scm_set_remote_state(u32 state, u32 id);69extern int qcom_scm_set_remote_state(u32 state, u32 id);
70 70
71struct qcom_scm_pas_metadata {
72 void *ptr;
73 dma_addr_t phys;
74 ssize_t size;
75};
76
71extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,77extern 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);
80void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
73extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,81extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
74 phys_addr_t size);82 phys_addr_t size);
75extern int qcom_scm_pas_auth_and_reset(u32 peripheral);83extern 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
83extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);91extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
84extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);92extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
85extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);93extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
94extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);
86extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,95extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
87 u32 cp_nonpixel_start,96 u32 cp_nonpixel_start,
88 u32 cp_nonpixel_size);97 u32 cp_nonpixel_size);
@@ -107,6 +116,7 @@ extern bool qcom_scm_hdcp_available(void); · 18 unmodified lines
107extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,116extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
108 u32 *resp);117 u32 *resp);
109 118
119extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt);
110extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);120extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
111 121
112extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,122extern 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
42 42
43struct scmi_clock_info {43struct scmi_clock_info {
44 char name[SCMI_MAX_STR_SIZE];44 char name[SCMI_MAX_STR_SIZE];
45 unsigned int enable_latency;
45 bool rate_discrete;46 bool rate_discrete;
46 union {47 union {
47 struct {48 struct {
@@ -82,6 +83,9 @@ struct scmi_clk_proto_ops { · 34 unmodified lines
82 u64 rate);83 u64 rate);
83 int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);84 int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
84 int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);85 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);
85};89};
86 90
87/**91/**
@@ -612,6 +616,15 @@ struct scmi_notify_ops { · 524 unmodified lines
612 * @devm_protocol_get: devres managed method to acquire a protocol and get specific616 * @devm_protocol_get: devres managed method to acquire a protocol and get specific
613 * operations and a dedicated protocol handler617 * operations and a dedicated protocol handler
614 * @devm_protocol_put: devres managed method to release a protocol618 * @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.
615 * @notify_ops: pointer to set of notifications related operations628 * @notify_ops: pointer to set of notifications related operations
616 */629 */
617struct scmi_handle {630struct scmi_handle {
@@ -622,6 +635,8 @@ struct scmi_handle { · 4 unmodified lines
622 (*devm_protocol_get)(struct scmi_device *sdev, u8 proto,635 (*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
623 struct scmi_protocol_handle **ph);636 struct scmi_protocol_handle **ph);
624 void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);637 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);
625 640
626 const struct scmi_notify_ops *notify_ops;641 const struct scmi_notify_ops *notify_ops;
627};642};
include/linux/soc/mediatek/infracfg.h+133−0
@@ -2,6 +2,88 @@ · 1 unmodified line
2#ifndef __SOC_MEDIATEK_INFRACFG_H2#ifndef __SOC_MEDIATEK_INFRACFG_H
3#define __SOC_MEDIATEK_INFRACFG_H3#define __SOC_MEDIATEK_INFRACFG_H
4 4
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
5#define MT8192_TOP_AXI_PROT_EN_STA1 0x22887#define MT8192_TOP_AXI_PROT_EN_STA1 0x228
6#define MT8192_TOP_AXI_PROT_EN_1_STA1 0x25888#define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258
7#define MT8192_TOP_AXI_PROT_EN_SET 0x2a089#define MT8192_TOP_AXI_PROT_EN_SET 0x2a0
@@ -58,6 +140,54 @@ · 50 unmodified lines
58#define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13)140#define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND BIT(13)
59#define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21)141#define MT8192_TOP_AXI_PROT_EN_VDNR_CAM BIT(21)
60 142
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
61#define MT8183_TOP_AXI_PROT_EN_STA1 0x228191#define MT8183_TOP_AXI_PROT_EN_STA1 0x228
62#define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258192#define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258
63#define MT8183_TOP_AXI_PROT_EN_SET 0x2a0193#define MT8183_TOP_AXI_PROT_EN_SET 0x2a0
@@ -147,6 +277,9 @@ · 83 unmodified lines
147#define INFRA_TOPAXI_PROTECTEN_SET 0x0260277#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
148#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264278#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
149 279
280#define MT8192_INFRA_CTRL 0x290
281#define MT8192_INFRA_CTRL_DISABLE_MFG2ACP BIT(9)
282
150#define REG_INFRA_MISC 0xf00283#define REG_INFRA_MISC 0xf00
151#define F_DDR_4GB_SUPPORT_EN BIT(13)284#define F_DDR_4GB_SUPPORT_EN BIT(13)
152 285
include/linux/soc/qcom/llcc-qcom.h+7−2
@@ -35,7 +35,12 @@ · 34 unmodified lines
35#define LLCC_WRCACHE 3135#define LLCC_WRCACHE 31
36#define LLCC_CVPFW 3236#define LLCC_CVPFW 32
37#define LLCC_CPUSS1 3337#define LLCC_CPUSS1 33
38#define LLCC_CAMEXP0 34
39#define LLCC_CPUMTE 35
38#define LLCC_CPUHWT 3640#define LLCC_CPUHWT 36
41#define LLCC_MDMCLAD2 37
42#define LLCC_CAMEXP1 38
43#define LLCC_AENPU 45
39 44
40/**45/**
41 * struct llcc_slice_desc - Cache slice descriptor46 * struct llcc_slice_desc - Cache slice descriptor
@@ -83,7 +88,7 @@ struct llcc_edac_reg_data { · 41 unmodified lines
83 * @bitmap: Bit map to track the active slice ids88 * @bitmap: Bit map to track the active slice ids
84 * @offsets: Pointer to the bank offsets array89 * @offsets: Pointer to the bank offsets array
85 * @ecc_irq: interrupt for llcc cache error detection and reporting90 * @ecc_irq: interrupt for llcc cache error detection and reporting
86 * @major_version: Indicates the LLCC major version91 * @version: Indicates the LLCC version
87 */92 */
88struct llcc_drv_data {93struct llcc_drv_data {
89 struct regmap *regmap;94 struct regmap *regmap;
@@ -96,7 +101,7 @@ struct llcc_drv_data { · 6 unmodified lines
96 unsigned long *bitmap;101 unsigned long *bitmap;
97 u32 *offsets;102 u32 *offsets;
98 int ecc_irq;103 int ecc_irq;
99 u32 major_version;104 u32 version;
100};105};
101 106
102#if IS_ENABLED(CONFIG_QCOM_LLCC)107#if IS_ENABLED(CONFIG_QCOM_LLCC)
include/linux/soc/qcom/mdt_loader.h+15−2
@@ -10,10 +10,14 @@ · 9 unmodified lines
10 10
11struct device;11struct device;
12struct firmware;12struct firmware;
13struct qcom_scm_pas_metadata;
13 14
14#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)15#if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
15 16
16ssize_t qcom_mdt_get_size(const struct firmware *fw);17ssize_t qcom_mdt_get_size(const struct firmware *fw);
18int 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);
17int qcom_mdt_load(struct device *dev, const struct firmware *fw,21int qcom_mdt_load(struct device *dev, const struct firmware *fw,
18 const char *fw_name, int pas_id, void *mem_region,22 const char *fw_name, int pas_id, void *mem_region,
19 phys_addr_t mem_phys, size_t mem_size,23 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
23 const char *fw_name, int pas_id, void *mem_region,27 const char *fw_name, int pas_id, void *mem_region,
24 phys_addr_t mem_phys, size_t mem_size,28 phys_addr_t mem_phys, size_t mem_size,
25 phys_addr_t *reloc_base);29 phys_addr_t *reloc_base);
26void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len);30void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
31 const char *fw_name, struct device *dev);
27 32
28#else /* !IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */33#else /* !IS_ENABLED(CONFIG_QCOM_MDT_LOADER) */
29 34
@@ -32,6 +37,13 @@ static inline ssize_t qcom_mdt_get_size(const struct firmware *fw) · 2 unmodified lines
32 return -ENODEV;37 return -ENODEV;
33}38}
34 39
40static 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
35static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,47static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw,
36 const char *fw_name, int pas_id,48 const char *fw_name, int pas_id,
37 void *mem_region, phys_addr_t mem_phys,49 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
51}63}
52 64
53static inline void *qcom_mdt_read_metadata(const struct firmware *fw,65static 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)
55{68{
56 return ERR_PTR(-ENODEV);69 return ERR_PTR(-ENODEV);
57}70}
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
645 645
646static inline struct ti_sci_resource *646static inline struct ti_sci_resource *
647devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,647devm_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)
649{649{
650 return ERR_PTR(-EINVAL);650 return ERR_PTR(-EINVAL);
651}651}
include/linux/tee_drv.h+31−107
@@ -1,6 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0-only */1/* SPDX-License-Identifier: GPL-2.0-only */
2/*2/*
3 * Copyright (c) 2015-2016, Linaro Limited3 * Copyright (c) 2015-2022 Linaro Limited
4 */4 */
5 5
6#ifndef __TEE_DRV_H6#ifndef __TEE_DRV_H
@@ -20,14 +20,11 @@ · 13 unmodified lines
20 * specific TEE driver.20 * specific TEE driver.
21 */21 */
22 22
23#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */23#define TEE_SHM_DYNAMIC BIT(0) /* Dynamic shared memory registered */
24#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */24 /* in secure world */
25#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */25#define TEE_SHM_USER_MAPPED BIT(1) /* Memory mapped in user space */
26#define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */26#define TEE_SHM_POOL BIT(2) /* Memory allocated from pool */
27#define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */27#define TEE_SHM_PRIV BIT(3) /* Memory private to TEE driver */
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 */
31 28
32struct device;29struct device;
33struct tee_device;30struct tee_device;
@@ -221,92 +218,39 @@ struct tee_shm { · 187 unmodified lines
221};218};
222 219
223/**220/**
224 * struct tee_shm_pool_mgr - shared memory manager221 * struct tee_shm_pool - shared memory pool
225 * @ops: operations222 * @ops: operations
226 * @private_data: private data for the shared memory manager223 * @private_data: private data for the shared memory manager
227 */224 */
228struct tee_shm_pool_mgr {225struct tee_shm_pool {
229 const struct tee_shm_pool_mgr_ops *ops;226 const struct tee_shm_pool_ops *ops;
230 void *private_data;227 void *private_data;
231};228};
232 229
233/**230/**
234 * struct tee_shm_pool_mgr_ops - shared memory pool manager operations231 * struct tee_shm_pool_ops - shared memory pool operations
235 * @alloc: called when allocating shared memory232 * @alloc: called when allocating shared memory
236 * @free: called when freeing shared memory233 * @free: called when freeing shared memory
237 * @destroy_poolmgr: called when destroying the pool manager234 * @destroy_pool: called when destroying the pool
238 */235 */
239struct tee_shm_pool_mgr_ops {236struct tee_shm_pool_ops {
240 int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm,237 int (*alloc)(struct tee_shm_pool *pool, struct tee_shm *shm,
241 size_t size);238 size_t size, size_t align);
242 void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm);239 void (*free)(struct tee_shm_pool *pool, struct tee_shm *shm);
243 void (*destroy_poolmgr)(struct tee_shm_pool_mgr *poolmgr);240 void (*destroy_pool)(struct tee_shm_pool *pool);
244};241};
245 242
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 */
256struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr,
257 struct tee_shm_pool_mgr *dmabuf_mgr);
258
259/*243/*
260 * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved244 * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory
261 * memory
262 * @vaddr: Virtual address of start of pool245 * @vaddr: Virtual address of start of pool
263 * @paddr: Physical address of start of pool246 * @paddr: Physical address of start of pool
264 * @size: Size in bytes of the pool247 * @size: Size in bytes of the pool
265 *248 *
266 * @returns pointer to a 'struct tee_shm_pool_mgr' or an ERR_PTR on failure.
267 */
268struct 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 */
276static 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 */
288struct 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 *
305 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.249 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
306 */250 */
307struct tee_shm_pool *251struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
308tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info *priv_info,252 phys_addr_t paddr, size_t size,
309 struct tee_shm_pool_mem_info *dmabuf_info);253 int min_alloc_order);
310 254
311/**255/**
312 * tee_shm_pool_free() - Free a shared memory pool256 * 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
315 * The must be no remaining shared memory allocated from this pool when259 * The must be no remaining shared memory allocated from this pool when
316 * this function is called.260 * this function is called.
317 */261 */
318void tee_shm_pool_free(struct tee_shm_pool *pool);262static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
263{
264 pool->ops->destroy_pool(pool);
265}
319 266
320/**267/**
321 * tee_get_drvdata() - Return driver_data pointer268 * tee_get_drvdata() - Return driver_data pointer
@@ -323,43 +270,20 @@ void tee_shm_pool_free(struct tee_shm_pool *pool); · 1 unmodified line
323 */270 */
324void *tee_get_drvdata(struct tee_device *teedev);271void *tee_get_drvdata(struct tee_device *teedev);
325 272
326/**273struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
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 */
340struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags);
341struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);274struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
342 275
343/**276struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
344 * tee_shm_register() - Register shared memory buffer277 void *addr, size_t length);
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 */
352struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
353 size_t length, u32 flags);
354 278
355/**279/**
356 * tee_shm_is_registered() - Check if shared memory object in registered in TEE280 * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
357 * @shm: Shared memory handle281 * @shm: Shared memory handle
358 * @returns true if object is registered in TEE282 * @returns true if object is dynamic shared memory
359 */283 */
360static inline bool tee_shm_is_registered(struct tee_shm *shm)284static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
361{285{
362 return shm && (shm->flags & TEE_SHM_REGISTER);286 return shm && (shm->flags & TEE_SHM_DYNAMIC);
363}287}
364 288
365/**289/**
include/soc/tegra/bpmp-abi.h+1−1
@@ -931,7 +931,7 @@ enum mrq_reset_commands { · 930 unmodified lines
931 * @brief Request with MRQ_RESET931 * @brief Request with MRQ_RESET
932 *932 *
933 * Used by the sender of an #MRQ_RESET message to request BPMP to933 * 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.
935 */935 */
936struct mrq_reset_request {936struct mrq_reset_request {
937 /** @brief Reset action to perform (@ref mrq_reset_commands) */937 /** @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
33 __entry->seq, __entry->poll)33 __entry->seq, __entry->poll)
34);34);
35 35
36TRACE_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
36TRACE_EVENT(scmi_xfer_end,64TRACE_EVENT(scmi_xfer_end,
37 TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,65 TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
38 int status),66 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
70 memset(&inv_arg, 0, sizeof(inv_arg));70 memset(&inv_arg, 0, sizeof(inv_arg));
71 memset(&param, 0, sizeof(param));71 memset(&param, 0, sizeof(param));
72 72
73 reg_shm_in = tee_shm_register(pvt_data.ctx, (unsigned long)p->key,73 reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
74 p->key_len, TEE_SHM_DMA_BUF |74 p->key_len);
75 TEE_SHM_KERNEL_MAPPED);
76 if (IS_ERR(reg_shm_in)) {75 if (IS_ERR(reg_shm_in)) {
77 dev_err(pvt_data.dev, "key shm register failed\n");76 dev_err(pvt_data.dev, "key shm register failed\n");
78 return PTR_ERR(reg_shm_in);77 return PTR_ERR(reg_shm_in);
79 }78 }
80 79
81 reg_shm_out = tee_shm_register(pvt_data.ctx, (unsigned long)p->blob,80 reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
82 sizeof(p->blob), TEE_SHM_DMA_BUF |81 sizeof(p->blob));
83 TEE_SHM_KERNEL_MAPPED);
84 if (IS_ERR(reg_shm_out)) {82 if (IS_ERR(reg_shm_out)) {
85 dev_err(pvt_data.dev, "blob shm register failed\n");83 dev_err(pvt_data.dev, "blob shm register failed\n");
86 ret = PTR_ERR(reg_shm_out);84 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
131 memset(&inv_arg, 0, sizeof(inv_arg));129 memset(&inv_arg, 0, sizeof(inv_arg));
132 memset(&param, 0, sizeof(param));130 memset(&param, 0, sizeof(param));
133 131
134 reg_shm_in = tee_shm_register(pvt_data.ctx, (unsigned long)p->blob,132 reg_shm_in = tee_shm_register_kernel_buf(pvt_data.ctx, p->blob,
135 p->blob_len, TEE_SHM_DMA_BUF |133 p->blob_len);
136 TEE_SHM_KERNEL_MAPPED);
137 if (IS_ERR(reg_shm_in)) {134 if (IS_ERR(reg_shm_in)) {
138 dev_err(pvt_data.dev, "blob shm register failed\n");135 dev_err(pvt_data.dev, "blob shm register failed\n");
139 return PTR_ERR(reg_shm_in);136 return PTR_ERR(reg_shm_in);
140 }137 }
141 138
142 reg_shm_out = tee_shm_register(pvt_data.ctx, (unsigned long)p->key,139 reg_shm_out = tee_shm_register_kernel_buf(pvt_data.ctx, p->key,
143 sizeof(p->key), TEE_SHM_DMA_BUF |140 sizeof(p->key));
144 TEE_SHM_KERNEL_MAPPED);
145 if (IS_ERR(reg_shm_out)) {141 if (IS_ERR(reg_shm_out)) {
146 dev_err(pvt_data.dev, "key shm register failed\n");142 dev_err(pvt_data.dev, "key shm register failed\n");
147 ret = PTR_ERR(reg_shm_out);143 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
192 memset(&inv_arg, 0, sizeof(inv_arg));188 memset(&inv_arg, 0, sizeof(inv_arg));
193 memset(&param, 0, sizeof(param));189 memset(&param, 0, sizeof(param));
194 190
195 reg_shm = tee_shm_register(pvt_data.ctx, (unsigned long)key, key_len,191 reg_shm = tee_shm_register_kernel_buf(pvt_data.ctx, key, key_len);
196 TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED);
197 if (IS_ERR(reg_shm)) {192 if (IS_ERR(reg_shm)) {
198 dev_err(pvt_data.dev, "key shm register failed\n");193 dev_err(pvt_data.dev, "key shm register failed\n");
199 return PTR_ERR(reg_shm);194 return PTR_ERR(reg_shm);