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 ...
Unified · Split
| @@ -29,6 +29,7 @@ properties: · 28 unmodified lines | |||
| 29 | - mediatek,mt8167-mmsys | 29 | - mediatek,mt8167-mmsys |
| 30 | - mediatek,mt8173-mmsys | 30 | - mediatek,mt8173-mmsys |
| 31 | - mediatek,mt8183-mmsys | 31 | - mediatek,mt8183-mmsys |
| 32 | - mediatek,mt8186-mmsys | ||
| 32 | - mediatek,mt8192-mmsys | 33 | - mediatek,mt8192-mmsys |
| 33 | - mediatek,mt8365-mmsys | 34 | - mediatek,mt8365-mmsys |
| 34 | - const: syscon | 35 | - const: syscon |
| @@ -27,6 +27,8 @@ properties: · 26 unmodified lines | |||
| 27 | - qcom,sm6350-llcc | 27 | - qcom,sm6350-llcc |
| 28 | - qcom,sm8150-llcc | 28 | - qcom,sm8150-llcc |
| 29 | - qcom,sm8250-llcc | 29 | - qcom,sm8250-llcc |
| 30 | - qcom,sm8350-llcc | ||
| 31 | - qcom,sm8450-llcc | ||
| 30 | 32 | ||
| 31 | reg: | 33 | reg: |
| 32 | items: | 34 | items: |
| @@ -0,0 +1,198 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Tesla FSD (Full Self-Driving) SoC clock controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Alim Akhtar <alim.akhtar@samsung.com> | ||
| 11 | - linux-fsd@tesla.com | ||
| 12 | |||
| 13 | description: | | ||
| 14 | FSD clock controller consist of several clock management unit | ||
| 15 | (CMU), which generates clocks for various inteernal SoC blocks. | ||
| 16 | The root clock comes from external OSC clock (24 MHz). | ||
| 17 | |||
| 18 | All available clocks are defined as preprocessor macros in | ||
| 19 | 'dt-bindings/clock/fsd-clk.h' header. | ||
| 20 | |||
| 21 | properties: | ||
| 22 | compatible: | ||
| 23 | enum: | ||
| 24 | - tesla,fsd-clock-cmu | ||
| 25 | - tesla,fsd-clock-imem | ||
| 26 | - tesla,fsd-clock-peric | ||
| 27 | - tesla,fsd-clock-fsys0 | ||
| 28 | - tesla,fsd-clock-fsys1 | ||
| 29 | - tesla,fsd-clock-mfc | ||
| 30 | - tesla,fsd-clock-cam_csi | ||
| 31 | |||
| 32 | clocks: | ||
| 33 | minItems: 1 | ||
| 34 | maxItems: 6 | ||
| 35 | |||
| 36 | clock-names: | ||
| 37 | minItems: 1 | ||
| 38 | maxItems: 6 | ||
| 39 | |||
| 40 | "#clock-cells": | ||
| 41 | const: 1 | ||
| 42 | |||
| 43 | reg: | ||
| 44 | maxItems: 1 | ||
| 45 | |||
| 46 | allOf: | ||
| 47 | - if: | ||
| 48 | properties: | ||
| 49 | compatible: | ||
| 50 | contains: | ||
| 51 | const: tesla,fsd-clock-cmu | ||
| 52 | then: | ||
| 53 | properties: | ||
| 54 | clocks: | ||
| 55 | items: | ||
| 56 | - description: External reference clock (24 MHz) | ||
| 57 | clock-names: | ||
| 58 | items: | ||
| 59 | - const: fin_pll | ||
| 60 | |||
| 61 | - if: | ||
| 62 | properties: | ||
| 63 | compatible: | ||
| 64 | contains: | ||
| 65 | const: tesla,fsd-clock-imem | ||
| 66 | then: | ||
| 67 | properties: | ||
| 68 | clocks: | ||
| 69 | items: | ||
| 70 | - description: External reference clock (24 MHz) | ||
| 71 | - description: IMEM TCU clock (from CMU_CMU) | ||
| 72 | - description: IMEM bus clock (from CMU_CMU) | ||
| 73 | - description: IMEM DMA clock (from CMU_CMU) | ||
| 74 | clock-names: | ||
| 75 | items: | ||
| 76 | - const: fin_pll | ||
| 77 | - const: dout_cmu_imem_tcuclk | ||
| 78 | - const: dout_cmu_imem_aclk | ||
| 79 | - const: dout_cmu_imem_dmaclk | ||
| 80 | |||
| 81 | - if: | ||
| 82 | properties: | ||
| 83 | compatible: | ||
| 84 | contains: | ||
| 85 | const: tesla,fsd-clock-peric | ||
| 86 | then: | ||
| 87 | properties: | ||
| 88 | clocks: | ||
| 89 | items: | ||
| 90 | - description: External reference clock (24 MHz) | ||
| 91 | - description: Shared0 PLL div4 clock (from CMU_CMU) | ||
| 92 | - description: PERIC shared1 div36 clock (from CMU_CMU) | ||
| 93 | - description: PERIC shared0 div3 TBU clock (from CMU_CMU) | ||
| 94 | - description: PERIC shared0 div20 clock (from CMU_CMU) | ||
| 95 | - description: PERIC shared1 div4 DMAclock (from CMU_CMU) | ||
| 96 | clock-names: | ||
| 97 | items: | ||
| 98 | - const: fin_pll | ||
| 99 | - const: dout_cmu_pll_shared0_div4 | ||
| 100 | - const: dout_cmu_peric_shared1div36 | ||
| 101 | - const: dout_cmu_peric_shared0div3_tbuclk | ||
| 102 | - const: dout_cmu_peric_shared0div20 | ||
| 103 | - const: dout_cmu_peric_shared1div4_dmaclk | ||
| 104 | |||
| 105 | - if: | ||
| 106 | properties: | ||
| 107 | compatible: | ||
| 108 | contains: | ||
| 109 | const: tesla,fsd-clock-fsys0 | ||
| 110 | then: | ||
| 111 | properties: | ||
| 112 | clocks: | ||
| 113 | items: | ||
| 114 | - description: External reference clock (24 MHz) | ||
| 115 | - description: Shared0 PLL div6 clock (from CMU_CMU) | ||
| 116 | - description: FSYS0 shared1 div4 clock (from CMU_CMU) | ||
| 117 | - description: FSYS0 shared0 div4 clock (from CMU_CMU) | ||
| 118 | clock-names: | ||
| 119 | items: | ||
| 120 | - const: fin_pll | ||
| 121 | - const: dout_cmu_pll_shared0_div6 | ||
| 122 | - const: dout_cmu_fsys0_shared1div4 | ||
| 123 | - const: dout_cmu_fsys0_shared0div4 | ||
| 124 | |||
| 125 | - if: | ||
| 126 | properties: | ||
| 127 | compatible: | ||
| 128 | contains: | ||
| 129 | const: tesla,fsd-clock-fsys1 | ||
| 130 | then: | ||
| 131 | properties: | ||
| 132 | clocks: | ||
| 133 | items: | ||
| 134 | - description: External reference clock (24 MHz) | ||
| 135 | - description: FSYS1 shared0 div8 clock (from CMU_CMU) | ||
| 136 | - description: FSYS1 shared0 div4 clock (from CMU_CMU) | ||
| 137 | clock-names: | ||
| 138 | items: | ||
| 139 | - const: fin_pll | ||
| 140 | - const: dout_cmu_fsys1_shared0div8 | ||
| 141 | - const: dout_cmu_fsys1_shared0div4 | ||
| 142 | |||
| 143 | - if: | ||
| 144 | properties: | ||
| 145 | compatible: | ||
| 146 | contains: | ||
| 147 | const: tesla,fsd-clock-mfc | ||
| 148 | then: | ||
| 149 | properties: | ||
| 150 | clocks: | ||
| 151 | items: | ||
| 152 | - description: External reference clock (24 MHz) | ||
| 153 | clock-names: | ||
| 154 | items: | ||
| 155 | - const: fin_pll | ||
| 156 | |||
| 157 | - if: | ||
| 158 | properties: | ||
| 159 | compatible: | ||
| 160 | contains: | ||
| 161 | const: tesla,fsd-clock-cam_csi | ||
| 162 | then: | ||
| 163 | properties: | ||
| 164 | clocks: | ||
| 165 | items: | ||
| 166 | - description: External reference clock (24 MHz) | ||
| 167 | clock-names: | ||
| 168 | items: | ||
| 169 | - const: fin_pll | ||
| 170 | |||
| 171 | required: | ||
| 172 | - compatible | ||
| 173 | - "#clock-cells" | ||
| 174 | - clocks | ||
| 175 | - clock-names | ||
| 176 | - reg | ||
| 177 | |||
| 178 | additionalProperties: false | ||
| 179 | |||
| 180 | examples: | ||
| 181 | # Clock controller node for CMU_FSYS1 | ||
| 182 | - | | ||
| 183 | #include <dt-bindings/clock/fsd-clk.h> | ||
| 184 | |||
| 185 | clock_fsys1: clock-controller@16810000 { | ||
| 186 | compatible = "tesla,fsd-clock-fsys1"; | ||
| 187 | reg = <0x16810000 0x3000>; | ||
| 188 | #clock-cells = <1>; | ||
| 189 | |||
| 190 | clocks = <&fin_pll>, | ||
| 191 | <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>, | ||
| 192 | <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>; | ||
| 193 | clock-names = "fin_pll", | ||
| 194 | "dout_cmu_fsys1_shared0div8", | ||
| 195 | "dout_cmu_fsys1_shared0div4"; | ||
| 196 | }; | ||
| 197 | |||
| 198 | ... | ||
| @@ -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-virtio | 40 | - 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: 0 | 82 | 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/uint32 | 93 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 83 | description: | 94 | description: |
| 84 | SMC id required when using smc or hvc transports | 95 | 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: object | 103 | type: object |
| 88 | properties: | 104 | properties: |
| @@ -195,6 +211,12 @@ patternProperties: · 106 unmodified lines | |||
| 195 | minItems: 1 | 211 | minItems: 1 |
| 196 | maxItems: 2 | 212 | 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 | - reg | 221 | - reg |
| 200 | 222 | ||
| @@ -226,6 +248,16 @@ else: · 25 unmodified lines | |||
| 226 | - arm,smc-id | 248 | - arm,smc-id |
| 227 | - shmem | 249 | - 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 | |||
| 229 | examples: | 261 | examples: |
| 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 | ||
| @@ -0,0 +1,135 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr2-timings.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: LPDDR2 SDRAM AC timing parameters for a given speed-bin | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | const: jedec,lpddr2-timings | ||
| 15 | |||
| 16 | max-freq: | ||
| 17 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 18 | description: | | ||
| 19 | Maximum DDR clock frequency for the speed-bin, in Hz. | ||
| 20 | |||
| 21 | min-freq: | ||
| 22 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 23 | description: | | ||
| 24 | Minimum DDR clock frequency for the speed-bin, in Hz. | ||
| 25 | |||
| 26 | tCKESR: | ||
| 27 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 28 | description: | | ||
| 29 | CKE minimum pulse width during SELF REFRESH (low pulse width during | ||
| 30 | SELF REFRESH) in pico seconds. | ||
| 31 | |||
| 32 | tDQSCK-max: | ||
| 33 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 34 | description: | | ||
| 35 | DQS output data access time from CK_t/CK_c in pico seconds. | ||
| 36 | |||
| 37 | tDQSCK-max-derated: | ||
| 38 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 39 | description: | | ||
| 40 | DQS output data access time from CK_t/CK_c, temperature de-rated, in pico | ||
| 41 | seconds. | ||
| 42 | |||
| 43 | tFAW: | ||
| 44 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 45 | description: | | ||
| 46 | Four-bank activate window in pico seconds. | ||
| 47 | |||
| 48 | tRAS-max-ns: | ||
| 49 | description: | | ||
| 50 | Row active time in nano seconds. | ||
| 51 | |||
| 52 | tRAS-min: | ||
| 53 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 54 | description: | | ||
| 55 | Row active time in pico seconds. | ||
| 56 | |||
| 57 | tRCD: | ||
| 58 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 59 | description: | | ||
| 60 | RAS-to-CAS delay in pico seconds. | ||
| 61 | |||
| 62 | tRPab: | ||
| 63 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 64 | description: | | ||
| 65 | Row precharge time (all banks) in pico seconds. | ||
| 66 | |||
| 67 | tRRD: | ||
| 68 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 69 | description: | | ||
| 70 | Active bank A to active bank B in pico seconds. | ||
| 71 | |||
| 72 | tRTP: | ||
| 73 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 74 | description: | | ||
| 75 | Internal READ to PRECHARGE command delay in pico seconds. | ||
| 76 | |||
| 77 | tWR: | ||
| 78 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 79 | description: | | ||
| 80 | WRITE recovery time in pico seconds. | ||
| 81 | |||
| 82 | tWTR: | ||
| 83 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 84 | description: | | ||
| 85 | Internal WRITE-to-READ command delay in pico seconds. | ||
| 86 | |||
| 87 | tXP: | ||
| 88 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 89 | description: | | ||
| 90 | Exit power-down to next valid command delay in pico seconds. | ||
| 91 | |||
| 92 | tZQCL: | ||
| 93 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 94 | description: | | ||
| 95 | Long calibration time in pico seconds. | ||
| 96 | |||
| 97 | tZQCS: | ||
| 98 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 99 | description: | | ||
| 100 | Short calibration time in pico seconds. | ||
| 101 | |||
| 102 | tZQinit: | ||
| 103 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 104 | description: | | ||
| 105 | Initialization calibration time in pico seconds. | ||
| 106 | |||
| 107 | required: | ||
| 108 | - compatible | ||
| 109 | - min-freq | ||
| 110 | - max-freq | ||
| 111 | |||
| 112 | additionalProperties: false | ||
| 113 | |||
| 114 | examples: | ||
| 115 | - | | ||
| 116 | timings { | ||
| 117 | compatible = "jedec,lpddr2-timings"; | ||
| 118 | min-freq = <10000000>; | ||
| 119 | max-freq = <400000000>; | ||
| 120 | tCKESR = <15000>; | ||
| 121 | tDQSCK-max = <5500>; | ||
| 122 | tFAW = <50000>; | ||
| 123 | tRAS-max-ns = <70000>; | ||
| 124 | tRAS-min = <42000>; | ||
| 125 | tRPab = <21000>; | ||
| 126 | tRCD = <18000>; | ||
| 127 | tRRD = <10000>; | ||
| 128 | tRTP = <7500>; | ||
| 129 | tWR = <15000>; | ||
| 130 | tWTR = <7500>; | ||
| 131 | tXP = <7500>; | ||
| 132 | tZQCL = <360000>; | ||
| 133 | tZQCS = <90000>; | ||
| 134 | tZQinit = <1000000>; | ||
| 135 | }; | ||
| @@ -30,12 +30,26 @@ properties: · 29 unmodified lines | |||
| 30 | maximum: 255 | 30 | 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/uint32 | 37 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 36 | maximum: 255 | 38 | 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/uint32 | 55 | $ref: /schemas/types.yaml#/definitions/uint32 |
| @@ -142,14 +156,12 @@ properties: · 100 unmodified lines | |||
| 142 | 156 | ||
| 143 | patternProperties: | 157 | patternProperties: |
| 144 | "^lpddr2-timings": | 158 | "^lpddr2-timings": |
| 145 | type: object | 159 | $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 for | 162 | "lpddr2-timings" provides AC timing parameters of the device for |
| 149 | a given speed-bin. The user may provide the timings for as many | 163 | 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 | ||
| 154 | required: | 166 | required: |
| 155 | - compatible | 167 | - 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>; |
| @@ -0,0 +1,157 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3-timings.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: LPDDR3 SDRAM AC timing parameters for a given speed-bin | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | const: jedec,lpddr3-timings | ||
| 15 | |||
| 16 | reg: | ||
| 17 | maxItems: 1 | ||
| 18 | description: | | ||
| 19 | Maximum DDR clock frequency for the speed-bin, in Hz. | ||
| 20 | Property is deprecated, use max-freq. | ||
| 21 | deprecated: true | ||
| 22 | |||
| 23 | max-freq: | ||
| 24 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 25 | description: | | ||
| 26 | Maximum DDR clock frequency for the speed-bin, in Hz. | ||
| 27 | |||
| 28 | min-freq: | ||
| 29 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 30 | description: | | ||
| 31 | Minimum DDR clock frequency for the speed-bin, in Hz. | ||
| 32 | |||
| 33 | tCKE: | ||
| 34 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 35 | description: | | ||
| 36 | CKE minimum pulse width (HIGH and LOW pulse width) in pico seconds. | ||
| 37 | |||
| 38 | tCKESR: | ||
| 39 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 40 | description: | | ||
| 41 | CKE minimum pulse width during SELF REFRESH (low pulse width during | ||
| 42 | SELF REFRESH) in pico seconds. | ||
| 43 | |||
| 44 | tFAW: | ||
| 45 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 46 | description: | | ||
| 47 | Four-bank activate window in pico seconds. | ||
| 48 | |||
| 49 | tMRD: | ||
| 50 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 51 | description: | | ||
| 52 | Mode register set command delay in pico seconds. | ||
| 53 | |||
| 54 | tR2R-C2C: | ||
| 55 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 56 | description: | | ||
| 57 | Additional READ-to-READ delay in chip-to-chip cases in pico seconds. | ||
| 58 | |||
| 59 | tRAS: | ||
| 60 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 61 | description: | | ||
| 62 | Row active time in pico seconds. | ||
| 63 | |||
| 64 | tRC: | ||
| 65 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 66 | description: | | ||
| 67 | ACTIVATE-to-ACTIVATE command period in pico seconds. | ||
| 68 | |||
| 69 | tRCD: | ||
| 70 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 71 | description: | | ||
| 72 | RAS-to-CAS delay in pico seconds. | ||
| 73 | |||
| 74 | tRFC: | ||
| 75 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 76 | description: | | ||
| 77 | Refresh Cycle time in pico seconds. | ||
| 78 | |||
| 79 | tRPab: | ||
| 80 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 81 | description: | | ||
| 82 | Row precharge time (all banks) in pico seconds. | ||
| 83 | |||
| 84 | tRPpb: | ||
| 85 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 86 | description: | | ||
| 87 | Row precharge time (single banks) in pico seconds. | ||
| 88 | |||
| 89 | tRRD: | ||
| 90 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 91 | description: | | ||
| 92 | Active bank A to active bank B in pico seconds. | ||
| 93 | |||
| 94 | tRTP: | ||
| 95 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 96 | description: | | ||
| 97 | Internal READ to PRECHARGE command delay in pico seconds. | ||
| 98 | |||
| 99 | tW2W-C2C: | ||
| 100 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 101 | description: | | ||
| 102 | Additional WRITE-to-WRITE delay in chip-to-chip cases in pico seconds. | ||
| 103 | |||
| 104 | tWR: | ||
| 105 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 106 | description: | | ||
| 107 | WRITE recovery time in pico seconds. | ||
| 108 | |||
| 109 | tWTR: | ||
| 110 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 111 | description: | | ||
| 112 | Internal WRITE-to-READ command delay in pico seconds. | ||
| 113 | |||
| 114 | tXP: | ||
| 115 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 116 | description: | | ||
| 117 | Exit power-down to next valid command delay in pico seconds. | ||
| 118 | |||
| 119 | tXSR: | ||
| 120 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 121 | description: | | ||
| 122 | SELF REFRESH exit to next valid command delay in pico seconds. | ||
| 123 | |||
| 124 | required: | ||
| 125 | - compatible | ||
| 126 | - min-freq | ||
| 127 | - max-freq | ||
| 128 | |||
| 129 | additionalProperties: false | ||
| 130 | |||
| 131 | examples: | ||
| 132 | - | | ||
| 133 | lpddr3 { | ||
| 134 | timings { | ||
| 135 | compatible = "jedec,lpddr3-timings"; | ||
| 136 | max-freq = <800000000>; | ||
| 137 | min-freq = <100000000>; | ||
| 138 | tCKE = <3750>; | ||
| 139 | tCKESR = <3750>; | ||
| 140 | tFAW = <25000>; | ||
| 141 | tMRD = <7000>; | ||
| 142 | tR2R-C2C = <0>; | ||
| 143 | tRAS = <23000>; | ||
| 144 | tRC = <33750>; | ||
| 145 | tRCD = <10000>; | ||
| 146 | tRFC = <65000>; | ||
| 147 | tRPab = <12000>; | ||
| 148 | tRPpb = <12000>; | ||
| 149 | tRRD = <6000>; | ||
| 150 | tRTP = <3750>; | ||
| 151 | tW2W-C2C = <0>; | ||
| 152 | tWR = <7500>; | ||
| 153 | tWTR = <3750>; | ||
| 154 | tXP = <3750>; | ||
| 155 | tXSR = <70000>; | ||
| 156 | }; | ||
| 157 | }; | ||
| @@ -0,0 +1,263 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/ddr/jedec,lpddr3.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: LPDDR3 SDRAM compliant to JEDEC JESD209-3 | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | items: | ||
| 15 | - enum: | ||
| 16 | - samsung,K3QF2F20DB | ||
| 17 | - const: jedec,lpddr3 | ||
| 18 | |||
| 19 | '#address-cells': | ||
| 20 | const: 1 | ||
| 21 | deprecated: true | ||
| 22 | |||
| 23 | density: | ||
| 24 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 25 | description: | | ||
| 26 | Density in megabits of SDRAM chip. | ||
| 27 | enum: | ||
| 28 | - 4096 | ||
| 29 | - 8192 | ||
| 30 | - 16384 | ||
| 31 | - 32768 | ||
| 32 | |||
| 33 | io-width: | ||
| 34 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 35 | description: | | ||
| 36 | IO bus width in bits of SDRAM chip. | ||
| 37 | enum: | ||
| 38 | - 32 | ||
| 39 | - 16 | ||
| 40 | |||
| 41 | manufacturer-id: | ||
| 42 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 43 | description: | | ||
| 44 | Manufacturer ID value read from Mode Register 5. The property is | ||
| 45 | deprecated, manufacturer should be derived from the compatible. | ||
| 46 | deprecated: true | ||
| 47 | |||
| 48 | revision-id: | ||
| 49 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
| 50 | minItems: 2 | ||
| 51 | maxItems: 2 | ||
| 52 | items: | ||
| 53 | maximum: 255 | ||
| 54 | description: | | ||
| 55 | Revision value of SDRAM chip read from Mode Registers 6 and 7. | ||
| 56 | |||
| 57 | '#size-cells': | ||
| 58 | const: 0 | ||
| 59 | deprecated: true | ||
| 60 | |||
| 61 | tCKE-min-tck: | ||
| 62 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 63 | maximum: 15 | ||
| 64 | description: | | ||
| 65 | CKE minimum pulse width (HIGH and LOW pulse width) in terms of number | ||
| 66 | of clock cycles. | ||
| 67 | |||
| 68 | tCKESR-min-tck: | ||
| 69 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 70 | maximum: 15 | ||
| 71 | description: | | ||
| 72 | CKE minimum pulse width during SELF REFRESH (low pulse width during | ||
| 73 | SELF REFRESH) in terms of number of clock cycles. | ||
| 74 | |||
| 75 | tDQSCK-min-tck: | ||
| 76 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 77 | maximum: 15 | ||
| 78 | description: | | ||
| 79 | DQS output data access time from CK_t/CK_c in terms of number of clock | ||
| 80 | cycles. | ||
| 81 | |||
| 82 | tFAW-min-tck: | ||
| 83 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 84 | maximum: 63 | ||
| 85 | description: | | ||
| 86 | Four-bank activate window in terms of number of clock cycles. | ||
| 87 | |||
| 88 | tMRD-min-tck: | ||
| 89 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 90 | maximum: 15 | ||
| 91 | description: | | ||
| 92 | Mode register set command delay in terms of number of clock cycles. | ||
| 93 | |||
| 94 | tR2R-C2C-min-tck: | ||
| 95 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 96 | enum: [0, 1] | ||
| 97 | description: | | ||
| 98 | Additional READ-to-READ delay in chip-to-chip cases in terms of number | ||
| 99 | of clock cycles. | ||
| 100 | |||
| 101 | tRAS-min-tck: | ||
| 102 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 103 | maximum: 63 | ||
| 104 | description: | | ||
| 105 | Row active time in terms of number of clock cycles. | ||
| 106 | |||
| 107 | tRC-min-tck: | ||
| 108 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 109 | maximum: 63 | ||
| 110 | description: | | ||
| 111 | ACTIVATE-to-ACTIVATE command period in terms of number of clock cycles. | ||
| 112 | |||
| 113 | tRCD-min-tck: | ||
| 114 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 115 | maximum: 15 | ||
| 116 | description: | | ||
| 117 | RAS-to-CAS delay in terms of number of clock cycles. | ||
| 118 | |||
| 119 | tRFC-min-tck: | ||
| 120 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 121 | maximum: 255 | ||
| 122 | description: | | ||
| 123 | Refresh Cycle time in terms of number of clock cycles. | ||
| 124 | |||
| 125 | tRL-min-tck: | ||
| 126 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 127 | maximum: 15 | ||
| 128 | description: | | ||
| 129 | READ data latency in terms of number of clock cycles. | ||
| 130 | |||
| 131 | tRPab-min-tck: | ||
| 132 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 133 | maximum: 15 | ||
| 134 | description: | | ||
| 135 | Row precharge time (all banks) in terms of number of clock cycles. | ||
| 136 | |||
| 137 | tRPpb-min-tck: | ||
| 138 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 139 | maximum: 15 | ||
| 140 | description: | | ||
| 141 | Row precharge time (single banks) in terms of number of clock cycles. | ||
| 142 | |||
| 143 | tRRD-min-tck: | ||
| 144 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 145 | maximum: 15 | ||
| 146 | description: | | ||
| 147 | Active bank A to active bank B in terms of number of clock cycles. | ||
| 148 | |||
| 149 | tRTP-min-tck: | ||
| 150 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 151 | maximum: 15 | ||
| 152 | description: | | ||
| 153 | Internal READ to PRECHARGE command delay in terms of number of clock | ||
| 154 | cycles. | ||
| 155 | |||
| 156 | tW2W-C2C-min-tck: | ||
| 157 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 158 | enum: [0, 1] | ||
| 159 | description: | | ||
| 160 | Additional WRITE-to-WRITE delay in chip-to-chip cases in terms of number | ||
| 161 | of clock cycles. | ||
| 162 | |||
| 163 | tWL-min-tck: | ||
| 164 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 165 | maximum: 15 | ||
| 166 | description: | | ||
| 167 | WRITE data latency in terms of number of clock cycles. | ||
| 168 | |||
| 169 | tWR-min-tck: | ||
| 170 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 171 | maximum: 15 | ||
| 172 | description: | | ||
| 173 | WRITE recovery time in terms of number of clock cycles. | ||
| 174 | |||
| 175 | tWTR-min-tck: | ||
| 176 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 177 | maximum: 15 | ||
| 178 | description: | | ||
| 179 | Internal WRITE-to-READ command delay in terms of number of clock cycles. | ||
| 180 | |||
| 181 | tXP-min-tck: | ||
| 182 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 183 | maximum: 255 | ||
| 184 | description: | | ||
| 185 | Exit power-down to next valid command delay in terms of number of clock | ||
| 186 | cycles. | ||
| 187 | |||
| 188 | tXSR-min-tck: | ||
| 189 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 190 | maximum: 1023 | ||
| 191 | description: | | ||
| 192 | SELF REFRESH exit to next valid command delay in terms of number of clock | ||
| 193 | cycles. | ||
| 194 | |||
| 195 | patternProperties: | ||
| 196 | "^timings((-[0-9])+|(@[0-9a-f]+))?$": | ||
| 197 | $ref: jedec,lpddr3-timings.yaml | ||
| 198 | description: | | ||
| 199 | The lpddr3 node may have one or more child nodes with timings. | ||
| 200 | Each timing node provides AC timing parameters of the device for a given | ||
| 201 | speed-bin. The user may provide the timings for as many speed-bins as is | ||
| 202 | required. | ||
| 203 | |||
| 204 | required: | ||
| 205 | - compatible | ||
| 206 | - density | ||
| 207 | - io-width | ||
| 208 | |||
| 209 | additionalProperties: false | ||
| 210 | |||
| 211 | examples: | ||
| 212 | - | | ||
| 213 | lpddr3 { | ||
| 214 | compatible = "samsung,K3QF2F20DB", "jedec,lpddr3"; | ||
| 215 | density = <16384>; | ||
| 216 | io-width = <32>; | ||
| 217 | |||
| 218 | tCKE-min-tck = <2>; | ||
| 219 | tCKESR-min-tck = <2>; | ||
| 220 | tDQSCK-min-tck = <5>; | ||
| 221 | tFAW-min-tck = <5>; | ||
| 222 | tMRD-min-tck = <5>; | ||
| 223 | tR2R-C2C-min-tck = <0>; | ||
| 224 | tRAS-min-tck = <5>; | ||
| 225 | tRC-min-tck = <6>; | ||
| 226 | tRCD-min-tck = <3>; | ||
| 227 | tRFC-min-tck = <17>; | ||
| 228 | tRL-min-tck = <14>; | ||
| 229 | tRPab-min-tck = <2>; | ||
| 230 | tRPpb-min-tck = <2>; | ||
| 231 | tRRD-min-tck = <2>; | ||
| 232 | tRTP-min-tck = <2>; | ||
| 233 | tW2W-C2C-min-tck = <0>; | ||
| 234 | tWL-min-tck = <8>; | ||
| 235 | tWR-min-tck = <7>; | ||
| 236 | tWTR-min-tck = <2>; | ||
| 237 | tXP-min-tck = <2>; | ||
| 238 | tXSR-min-tck = <12>; | ||
| 239 | |||
| 240 | timings { | ||
| 241 | compatible = "jedec,lpddr3-timings"; | ||
| 242 | max-freq = <800000000>; | ||
| 243 | min-freq = <100000000>; | ||
| 244 | tCKE = <3750>; | ||
| 245 | tCKESR = <3750>; | ||
| 246 | tFAW = <25000>; | ||
| 247 | tMRD = <7000>; | ||
| 248 | tR2R-C2C = <0>; | ||
| 249 | tRAS = <23000>; | ||
| 250 | tRC = <33750>; | ||
| 251 | tRCD = <10000>; | ||
| 252 | tRFC = <65000>; | ||
| 253 | tRPab = <12000>; | ||
| 254 | tRPpb = <12000>; | ||
| 255 | tRRD = <6000>; | ||
| 256 | tRTP = <3750>; | ||
| 257 | tW2W-C2C = <0>; | ||
| 258 | tWR = <7500>; | ||
| 259 | tWTR = <3750>; | ||
| 260 | tXP = <3750>; | ||
| 261 | tXSR = <70000>; | ||
| 262 | }; | ||
| 263 | }; | ||
| @@ -1,52 +0,0 @@ | |||
| 1 | * AC timing parameters of LPDDR2(JESD209-2) memories for a given speed-bin | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Should be "jedec,lpddr2-timings" | ||
| 5 | - min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32> | ||
| 6 | - max-freq : maximum DDR clock frequency for the speed-bin. Type is <u32> | ||
| 7 | |||
| 8 | Optional properties: | ||
| 9 | |||
| 10 | The following properties represent AC timing parameters from the memory | ||
| 11 | data-sheet of the device for a given speed-bin. All these properties are | ||
| 12 | of type <u32> and the default unit is ps (pico seconds). Parameters with | ||
| 13 | a different unit have a suffix indicating the unit such as 'tRAS-max-ns' | ||
| 14 | - tRCD | ||
| 15 | - tWR | ||
| 16 | - tRAS-min | ||
| 17 | - tRRD | ||
| 18 | - tWTR | ||
| 19 | - tXP | ||
| 20 | - tRTP | ||
| 21 | - tDQSCK-max | ||
| 22 | - tFAW | ||
| 23 | - tZQCS | ||
| 24 | - tZQinit | ||
| 25 | - tRPab | ||
| 26 | - tZQCL | ||
| 27 | - tCKESR | ||
| 28 | - tRAS-max-ns | ||
| 29 | - tDQSCK-max-derated | ||
| 30 | |||
| 31 | Example: | ||
| 32 | |||
| 33 | timings_elpida_ECB240ABACN_400mhz: lpddr2-timings@0 { | ||
| 34 | compatible = "jedec,lpddr2-timings"; | ||
| 35 | min-freq = <10000000>; | ||
| 36 | max-freq = <400000000>; | ||
| 37 | tRPab = <21000>; | ||
| 38 | tRCD = <18000>; | ||
| 39 | tWR = <15000>; | ||
| 40 | tRAS-min = <42000>; | ||
| 41 | tRRD = <10000>; | ||
| 42 | tWTR = <7500>; | ||
| 43 | tXP = <7500>; | ||
| 44 | tRTP = <7500>; | ||
| 45 | tCKESR = <15000>; | ||
| 46 | tDQSCK-max = <5500>; | ||
| 47 | tFAW = <50000>; | ||
| 48 | tZQCS = <90000>; | ||
| 49 | tZQCL = <360000>; | ||
| 50 | tZQinit = <1000000>; | ||
| 51 | tRAS-max-ns = <70000>; | ||
| 52 | }; | ||
| @@ -1,58 +0,0 @@ | |||
| 1 | * AC timing parameters of LPDDR3 memories for a given speed-bin. | ||
| 2 | |||
| 3 | The structures are based on LPDDR2 and extended where needed. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | - compatible : Should be "jedec,lpddr3-timings" | ||
| 7 | - min-freq : minimum DDR clock frequency for the speed-bin. Type is <u32> | ||
| 8 | - reg : maximum DDR clock frequency for the speed-bin. Type is <u32> | ||
| 9 | |||
| 10 | Optional properties: | ||
| 11 | |||
| 12 | The following properties represent AC timing parameters from the memory | ||
| 13 | data-sheet of the device for a given speed-bin. All these properties are | ||
| 14 | of type <u32> and the default unit is ps (pico seconds). | ||
| 15 | - tRFC | ||
| 16 | - tRRD | ||
| 17 | - tRPab | ||
| 18 | - tRPpb | ||
| 19 | - tRCD | ||
| 20 | - tRC | ||
| 21 | - tRAS | ||
| 22 | - tWTR | ||
| 23 | - tWR | ||
| 24 | - tRTP | ||
| 25 | - tW2W-C2C | ||
| 26 | - tR2R-C2C | ||
| 27 | - tFAW | ||
| 28 | - tXSR | ||
| 29 | - tXP | ||
| 30 | - tCKE | ||
| 31 | - tCKESR | ||
| 32 | - tMRD | ||
| 33 | |||
| 34 | Example: | ||
| 35 | |||
| 36 | timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 { | ||
| 37 | compatible = "jedec,lpddr3-timings"; | ||
| 38 | reg = <800000000>; /* workaround: it shows max-freq */ | ||
| 39 | min-freq = <100000000>; | ||
| 40 | tRFC = <65000>; | ||
| 41 | tRRD = <6000>; | ||
| 42 | tRPab = <12000>; | ||
| 43 | tRPpb = <12000>; | ||
| 44 | tRCD = <10000>; | ||
| 45 | tRC = <33750>; | ||
| 46 | tRAS = <23000>; | ||
| 47 | tWTR = <3750>; | ||
| 48 | tWR = <7500>; | ||
| 49 | tRTP = <3750>; | ||
| 50 | tW2W-C2C = <0>; | ||
| 51 | tR2R-C2C = <0>; | ||
| 52 | tFAW = <25000>; | ||
| 53 | tXSR = <70000>; | ||
| 54 | tXP = <3750>; | ||
| 55 | tCKE = <3750>; | ||
| 56 | tCKESR = <3750>; | ||
| 57 | tMRD = <7000>; | ||
| 58 | }; | ||
| @@ -1,107 +0,0 @@ | |||
| 1 | * LPDDR3 SDRAM memories compliant to JEDEC JESD209-3C | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : Should be "<vendor>,<type>", and generic value "jedec,lpddr3". | ||
| 5 | Example "<vendor>,<type>" values: | ||
| 6 | "samsung,K3QF2F20DB" | ||
| 7 | |||
| 8 | - density : <u32> representing density in Mb (Mega bits) | ||
| 9 | - io-width : <u32> representing bus width. Possible values are 8, 16, 32, 64 | ||
| 10 | - #address-cells: Must be set to 1 | ||
| 11 | - #size-cells: Must be set to 0 | ||
| 12 | |||
| 13 | Optional properties: | ||
| 14 | |||
| 15 | - manufacturer-id : <u32> Manufacturer ID value read from Mode Register 5 | ||
| 16 | - revision-id : <u32 u32> Revision IDs read from Mode Registers 6 and 7 | ||
| 17 | |||
| 18 | The following optional properties represent the minimum value of some AC | ||
| 19 | timing parameters of the DDR device in terms of number of clock cycles. | ||
| 20 | These values shall be obtained from the device data-sheet. | ||
| 21 | - tRFC-min-tck | ||
| 22 | - tRRD-min-tck | ||
| 23 | - tRPab-min-tck | ||
| 24 | - tRPpb-min-tck | ||
| 25 | - tRCD-min-tck | ||
| 26 | - tRC-min-tck | ||
| 27 | - tRAS-min-tck | ||
| 28 | - tWTR-min-tck | ||
| 29 | - tWR-min-tck | ||
| 30 | - tRTP-min-tck | ||
| 31 | - tW2W-C2C-min-tck | ||
| 32 | - tR2R-C2C-min-tck | ||
| 33 | - tWL-min-tck | ||
| 34 | - tDQSCK-min-tck | ||
| 35 | - tRL-min-tck | ||
| 36 | - tFAW-min-tck | ||
| 37 | - tXSR-min-tck | ||
| 38 | - tXP-min-tck | ||
| 39 | - tCKE-min-tck | ||
| 40 | - tCKESR-min-tck | ||
| 41 | - tMRD-min-tck | ||
| 42 | |||
| 43 | Child nodes: | ||
| 44 | - The lpddr3 node may have one or more child nodes of type "lpddr3-timings". | ||
| 45 | "lpddr3-timings" provides AC timing parameters of the device for | ||
| 46 | a given speed-bin. Please see | ||
| 47 | Documentation/devicetree/bindings/memory-controllers/ddr/lpddr3-timings.txt | ||
| 48 | for more information on "lpddr3-timings" | ||
| 49 | |||
| 50 | Example: | ||
| 51 | |||
| 52 | samsung_K3QF2F20DB: lpddr3 { | ||
| 53 | compatible = "samsung,K3QF2F20DB", "jedec,lpddr3"; | ||
| 54 | density = <16384>; | ||
| 55 | io-width = <32>; | ||
| 56 | manufacturer-id = <1>; | ||
| 57 | revision-id = <123 234>; | ||
| 58 | #address-cells = <1>; | ||
| 59 | #size-cells = <0>; | ||
| 60 | |||
| 61 | tRFC-min-tck = <17>; | ||
| 62 | tRRD-min-tck = <2>; | ||
| 63 | tRPab-min-tck = <2>; | ||
| 64 | tRPpb-min-tck = <2>; | ||
| 65 | tRCD-min-tck = <3>; | ||
| 66 | tRC-min-tck = <6>; | ||
| 67 | tRAS-min-tck = <5>; | ||
| 68 | tWTR-min-tck = <2>; | ||
| 69 | tWR-min-tck = <7>; | ||
| 70 | tRTP-min-tck = <2>; | ||
| 71 | tW2W-C2C-min-tck = <0>; | ||
| 72 | tR2R-C2C-min-tck = <0>; | ||
| 73 | tWL-min-tck = <8>; | ||
| 74 | tDQSCK-min-tck = <5>; | ||
| 75 | tRL-min-tck = <14>; | ||
| 76 | tFAW-min-tck = <5>; | ||
| 77 | tXSR-min-tck = <12>; | ||
| 78 | tXP-min-tck = <2>; | ||
| 79 | tCKE-min-tck = <2>; | ||
| 80 | tCKESR-min-tck = <2>; | ||
| 81 | tMRD-min-tck = <5>; | ||
| 82 | |||
| 83 | timings_samsung_K3QF2F20DB_800mhz: lpddr3-timings@800000000 { | ||
| 84 | compatible = "jedec,lpddr3-timings"; | ||
| 85 | /* workaround: 'reg' shows max-freq */ | ||
| 86 | reg = <800000000>; | ||
| 87 | min-freq = <100000000>; | ||
| 88 | tRFC = <65000>; | ||
| 89 | tRRD = <6000>; | ||
| 90 | tRPab = <12000>; | ||
| 91 | tRPpb = <12000>; | ||
| 92 | tRCD = <10000>; | ||
| 93 | tRC = <33750>; | ||
| 94 | tRAS = <23000>; | ||
| 95 | tWTR = <3750>; | ||
| 96 | tWR = <7500>; | ||
| 97 | tRTP = <3750>; | ||
| 98 | tW2W-C2C = <0>; | ||
| 99 | tR2R-C2C = <0>; | ||
| 100 | tFAW = <25000>; | ||
| 101 | tXSR = <70000>; | ||
| 102 | tXP = <3750>; | ||
| 103 | tCKE = <3750>; | ||
| 104 | tCKESR = <3750>; | ||
| 105 | tMRD = <7000>; | ||
| 106 | }; | ||
| 107 | } | ||
| @@ -0,0 +1,113 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/fsl/fsl,ifc.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: FSL/NXP Integrated Flash Controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Li Yang <leoyang.li@nxp.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | NXP's integrated flash controller (IFC) is an advanced version of the | ||
| 14 | enhanced local bus controller which includes similar programming and signal | ||
| 15 | interfaces with an extended feature set. The IFC provides access to multiple | ||
| 16 | external memory types, such as NAND flash (SLC and MLC), NOR flash, EPROM, | ||
| 17 | SRAM and other memories where address and data are shared on a bus. | ||
| 18 | |||
| 19 | properties: | ||
| 20 | $nodename: | ||
| 21 | pattern: "^memory-controller@[0-9a-f]+$" | ||
| 22 | |||
| 23 | compatible: | ||
| 24 | const: fsl,ifc | ||
| 25 | |||
| 26 | "#address-cells": | ||
| 27 | enum: [2, 3] | ||
| 28 | description: | | ||
| 29 | Should be either two or three. The first cell is the chipselect | ||
| 30 | number, and the remaining cells are the offset into the chipselect. | ||
| 31 | |||
| 32 | "#size-cells": | ||
| 33 | enum: [1, 2] | ||
| 34 | description: | | ||
| 35 | Either one or two, depending on how large each chipselect can be. | ||
| 36 | |||
| 37 | reg: | ||
| 38 | maxItems: 1 | ||
| 39 | |||
| 40 | interrupts: | ||
| 41 | minItems: 1 | ||
| 42 | maxItems: 2 | ||
| 43 | description: | | ||
| 44 | IFC may have one or two interrupts. If two interrupt specifiers are | ||
| 45 | present, the first is the "common" interrupt (CM_EVTER_STAT), and the | ||
| 46 | second is the NAND interrupt (NAND_EVTER_STAT). If there is only one, | ||
| 47 | that interrupt reports both types of event. | ||
| 48 | |||
| 49 | little-endian: | ||
| 50 | type: boolean | ||
| 51 | description: | | ||
| 52 | If this property is absent, the big-endian mode will be in use as default | ||
| 53 | for registers. | ||
| 54 | |||
| 55 | ranges: | ||
| 56 | description: | | ||
| 57 | Each range corresponds to a single chipselect, and covers the entire | ||
| 58 | access window as configured. | ||
| 59 | |||
| 60 | patternProperties: | ||
| 61 | "^.*@[a-f0-9]+(,[a-f0-9]+)+$": | ||
| 62 | type: object | ||
| 63 | description: | | ||
| 64 | Child device nodes describe the devices connected to IFC such as NOR (e.g. | ||
| 65 | cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices | ||
| 66 | like FPGAs, CPLDs, etc. | ||
| 67 | |||
| 68 | required: | ||
| 69 | - compatible | ||
| 70 | - reg | ||
| 71 | |||
| 72 | required: | ||
| 73 | - compatible | ||
| 74 | - reg | ||
| 75 | - interrupts | ||
| 76 | |||
| 77 | additionalProperties: false | ||
| 78 | |||
| 79 | examples: | ||
| 80 | - | | ||
| 81 | soc { | ||
| 82 | #address-cells = <2>; | ||
| 83 | #size-cells = <2>; | ||
| 84 | |||
| 85 | memory-controller@ffe1e000 { | ||
| 86 | compatible = "fsl,ifc"; | ||
| 87 | #address-cells = <2>; | ||
| 88 | #size-cells = <1>; | ||
| 89 | reg = <0x0 0xffe1e000 0 0x2000>; | ||
| 90 | interrupts = <16 2 19 2>; | ||
| 91 | little-endian; | ||
| 92 | |||
| 93 | /* NOR, NAND Flashes and CPLD on board */ | ||
| 94 | ranges = <0x0 0x0 0x0 0xee000000 0x02000000>, | ||
| 95 | <0x1 0x0 0x0 0xffa00000 0x00010000>, | ||
| 96 | <0x3 0x0 0x0 0xffb00000 0x00020000>; | ||
| 97 | |||
| 98 | flash@0,0 { | ||
| 99 | #address-cells = <1>; | ||
| 100 | #size-cells = <1>; | ||
| 101 | compatible = "cfi-flash"; | ||
| 102 | reg = <0x0 0x0 0x2000000>; | ||
| 103 | bank-width = <2>; | ||
| 104 | device-width = <1>; | ||
| 105 | |||
| 106 | partition@0 { | ||
| 107 | /* 32MB for user data */ | ||
| 108 | reg = <0x0 0x02000000>; | ||
| 109 | label = "NOR Data"; | ||
| 110 | }; | ||
| 111 | }; | ||
| 112 | }; | ||
| 113 | }; | ||
| @@ -1,82 +0,0 @@ | |||
| 1 | Integrated Flash Controller | ||
| 2 | |||
| 3 | Properties: | ||
| 4 | - name : Should be ifc | ||
| 5 | - compatible : should contain "fsl,ifc". The version of the integrated | ||
| 6 | flash controller can be found in the IFC_REV register at | ||
| 7 | offset zero. | ||
| 8 | |||
| 9 | - #address-cells : Should be either two or three. The first cell is the | ||
| 10 | chipselect number, and the remaining cells are the | ||
| 11 | offset into the chipselect. | ||
| 12 | - #size-cells : Either one or two, depending on how large each chipselect | ||
| 13 | can be. | ||
| 14 | - reg : Offset and length of the register set for the device | ||
| 15 | - interrupts: IFC may have one or two interrupts. If two interrupt | ||
| 16 | specifiers are present, the first is the "common" | ||
| 17 | interrupt (CM_EVTER_STAT), and the second is the NAND | ||
| 18 | interrupt (NAND_EVTER_STAT). If there is only one, | ||
| 19 | that interrupt reports both types of event. | ||
| 20 | |||
| 21 | - little-endian : If this property is absent, the big-endian mode will | ||
| 22 | be in use as default for registers. | ||
| 23 | |||
| 24 | - ranges : Each range corresponds to a single chipselect, and covers | ||
| 25 | the entire access window as configured. | ||
| 26 | |||
| 27 | Child device nodes describe the devices connected to IFC such as NOR (e.g. | ||
| 28 | cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices | ||
| 29 | like FPGAs, CPLDs, etc. | ||
| 30 | |||
| 31 | Example: | ||
| 32 | |||
| 33 | ifc@ffe1e000 { | ||
| 34 | compatible = "fsl,ifc", "simple-bus"; | ||
| 35 | #address-cells = <2>; | ||
| 36 | #size-cells = <1>; | ||
| 37 | reg = <0x0 0xffe1e000 0 0x2000>; | ||
| 38 | interrupts = <16 2 19 2>; | ||
| 39 | little-endian; | ||
| 40 | |||
| 41 | /* NOR, NAND Flashes and CPLD on board */ | ||
| 42 | ranges = <0x0 0x0 0x0 0xee000000 0x02000000 | ||
| 43 | 0x1 0x0 0x0 0xffa00000 0x00010000 | ||
| 44 | 0x3 0x0 0x0 0xffb00000 0x00020000>; | ||
| 45 | |||
| 46 | flash@0,0 { | ||
| 47 | #address-cells = <1>; | ||
| 48 | #size-cells = <1>; | ||
| 49 | compatible = "cfi-flash"; | ||
| 50 | reg = <0x0 0x0 0x2000000>; | ||
| 51 | bank-width = <2>; | ||
| 52 | device-width = <1>; | ||
| 53 | |||
| 54 | partition@0 { | ||
| 55 | /* 32MB for user data */ | ||
| 56 | reg = <0x0 0x02000000>; | ||
| 57 | label = "NOR Data"; | ||
| 58 | }; | ||
| 59 | }; | ||
| 60 | |||
| 61 | flash@1,0 { | ||
| 62 | #address-cells = <1>; | ||
| 63 | #size-cells = <1>; | ||
| 64 | compatible = "fsl,ifc-nand"; | ||
| 65 | reg = <0x1 0x0 0x10000>; | ||
| 66 | |||
| 67 | partition@0 { | ||
| 68 | /* This location must not be altered */ | ||
| 69 | /* 1MB for u-boot Bootloader Image */ | ||
| 70 | reg = <0x0 0x00100000>; | ||
| 71 | label = "NAND U-Boot Image"; | ||
| 72 | read-only; | ||
| 73 | }; | ||
| 74 | }; | ||
| 75 | |||
| 76 | cpld@3,0 { | ||
| 77 | #address-cells = <1>; | ||
| 78 | #size-cells = <1>; | ||
| 79 | compatible = "fsl,p1010rdb-cpld"; | ||
| 80 | reg = <0x3 0x0 0x000001f>; | ||
| 81 | }; | ||
| 82 | }; | ||
| @@ -16,7 +16,7 @@ description: | · 15 unmodified lines | |||
| 16 | MediaTek SMI have two generations of HW architecture, here is the list | 16 | 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, the | 21 | 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. But | 22 | 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-common | 35 | - mediatek,mt8167-smi-common |
| 36 | - mediatek,mt8173-smi-common | 36 | - mediatek,mt8173-smi-common |
| 37 | - mediatek,mt8183-smi-common | 37 | - mediatek,mt8183-smi-common |
| 38 | - mediatek,mt8186-smi-common | ||
| 38 | - mediatek,mt8192-smi-common | 39 | - mediatek,mt8192-smi-common |
| 39 | - mediatek,mt8195-smi-common-vdo | 40 | - mediatek,mt8195-smi-common-vdo |
| 40 | - mediatek,mt8195-smi-common-vpp | 41 | - mediatek,mt8195-smi-common-vpp |
| @@ -88,10 +89,9 @@ allOf: · 47 unmodified lines | |||
| 88 | - mediatek,mt2701-smi-common | 89 | - mediatek,mt2701-smi-common |
| 89 | then: | 90 | then: |
| 90 | properties: | 91 | properties: |
| 91 | clock: | 92 | clocks: |
| 92 | items: | 93 | minItems: 3 |
| 93 | minItems: 3 | 94 | maxItems: 3 |
| 94 | maxItems: 3 | ||
| 95 | clock-names: | 95 | clock-names: |
| 96 | items: | 96 | items: |
| 97 | - const: apb | 97 | - const: apb |
| @@ -108,10 +108,9 @@ allOf: · 10 unmodified lines | |||
| 108 | required: | 108 | required: |
| 109 | - mediatek,smi | 109 | - mediatek,smi |
| 110 | properties: | 110 | properties: |
| 111 | clock: | 111 | clocks: |
| 112 | items: | 112 | minItems: 3 |
| 113 | minItems: 3 | 113 | maxItems: 3 |
| 114 | maxItems: 3 | ||
| 115 | clock-names: | 114 | clock-names: |
| 116 | items: | 115 | items: |
| 117 | - const: apb | 116 | - const: apb |
| @@ -127,16 +126,16 @@ allOf: · 9 unmodified lines | |||
| 127 | enum: | 126 | enum: |
| 128 | - mediatek,mt6779-smi-common | 127 | - mediatek,mt6779-smi-common |
| 129 | - mediatek,mt8183-smi-common | 128 | - mediatek,mt8183-smi-common |
| 129 | - mediatek,mt8186-smi-common | ||
| 130 | - mediatek,mt8192-smi-common | 130 | - mediatek,mt8192-smi-common |
| 131 | - mediatek,mt8195-smi-common-vdo | 131 | - mediatek,mt8195-smi-common-vdo |
| 132 | - mediatek,mt8195-smi-common-vpp | 132 | - 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: 4 | 138 | maxItems: 4 |
| 139 | maxItems: 4 | ||
| 140 | clock-names: | 139 | clock-names: |
| 141 | items: | 140 | items: |
| 142 | - const: apb | 141 | - const: apb |
| @@ -146,10 +145,9 @@ allOf: · 3 unmodified lines | |||
| 146 | 145 | ||
| 147 | else: # for gen2 HW that don't have gals | 146 | else: # for gen2 HW that don't have gals |
| 148 | properties: | 147 | properties: |
| 149 | clock: | 148 | clocks: |
| 150 | items: | 149 | minItems: 2 |
| 151 | minItems: 2 | 150 | maxItems: 2 |
| 152 | maxItems: 2 | ||
| 153 | clock-names: | 151 | clock-names: |
| 154 | items: | 152 | items: |
| 155 | - const: apb | 153 | - const: apb |
| @@ -23,6 +23,7 @@ properties: · 22 unmodified lines | |||
| 23 | - mediatek,mt8167-smi-larb | 23 | - mediatek,mt8167-smi-larb |
| 24 | - mediatek,mt8173-smi-larb | 24 | - mediatek,mt8173-smi-larb |
| 25 | - mediatek,mt8183-smi-larb | 25 | - mediatek,mt8183-smi-larb |
| 26 | - mediatek,mt8186-smi-larb | ||
| 26 | - mediatek,mt8192-smi-larb | 27 | - mediatek,mt8192-smi-larb |
| 27 | - mediatek,mt8195-smi-larb | 28 | - 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-larb | 78 | - mediatek,mt8183-smi-larb |
| 79 | - mediatek,mt8186-smi-larb | ||
| 78 | - mediatek,mt8195-smi-larb | 80 | - 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: 3 | 86 | maxItems: 3 |
| 85 | maxItems: 3 | ||
| 86 | clock-names: | 87 | clock-names: |
| 88 | minItems: 2 | ||
| 87 | items: | 89 | items: |
| 88 | - const: apb | 90 | - const: apb |
| 89 | - const: smi | 91 | - 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: 2 | 98 | maxItems: 2 |
| 97 | maxItems: 2 | ||
| 98 | clock-names: | 99 | clock-names: |
| 99 | items: | 100 | items: |
| 100 | - const: apb | 101 | - const: apb |
| @@ -108,7 +109,7 @@ allOf: · 7 unmodified lines | |||
| 108 | - mediatek,mt2701-smi-larb | 109 | - mediatek,mt2701-smi-larb |
| 109 | - mediatek,mt2712-smi-larb | 110 | - mediatek,mt2712-smi-larb |
| 110 | - mediatek,mt6779-smi-larb | 111 | - mediatek,mt6779-smi-larb |
| 111 | - mediatek,mt8167-smi-larb | 112 | - mediatek,mt8186-smi-larb |
| 112 | - mediatek,mt8192-smi-larb | 113 | - mediatek,mt8192-smi-larb |
| 113 | - mediatek,mt8195-smi-larb | 114 | - mediatek,mt8195-smi-larb |
| 114 | 115 | ||
| @@ -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 family | 43 | - renesas,r9a07g054-rpc-if # RZ/V2L |
| 44 | - const: renesas,rzg2l-rpc-if | ||
| 44 | 45 | ||
| 45 | reg: | 46 | reg: |
| 46 | items: | 47 | items: |
| @@ -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 please | 53 | 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: true | 56 | operating-points-v2: true |
| 58 | 57 | ||
| @@ -12,13 +12,14 @@ maintainers: · 11 unmodified lines | |||
| 12 | - Jianxin Pan <jianxin.pan@amlogic.com> | 12 | - Jianxin Pan <jianxin.pan@amlogic.com> |
| 13 | 13 | ||
| 14 | description: |+ | 14 | description: |+ |
| 15 | Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node | 15 | Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node |
| 16 | of secure-monitor. | 16 | of secure-monitor. |
| 17 | 17 | ||
| 18 | properties: | 18 | properties: |
| 19 | compatible: | 19 | compatible: |
| 20 | enum: | 20 | enum: |
| 21 | - amlogic,meson-a1-pwrc | 21 | - amlogic,meson-a1-pwrc |
| 22 | - amlogic,meson-s4-pwrc | ||
| 22 | 23 | ||
| 23 | "#power-domain-cells": | 24 | "#power-domain-cells": |
| 24 | const: 1 | 25 | const: 1 |
| @@ -26,7 +26,9 @@ properties: · 25 unmodified lines | |||
| 26 | - mediatek,mt8167-power-controller | 26 | - mediatek,mt8167-power-controller |
| 27 | - mediatek,mt8173-power-controller | 27 | - mediatek,mt8173-power-controller |
| 28 | - mediatek,mt8183-power-controller | 28 | - mediatek,mt8183-power-controller |
| 29 | - mediatek,mt8186-power-controller | ||
| 29 | - mediatek,mt8192-power-controller | 30 | - mediatek,mt8192-power-controller |
| 31 | - mediatek,mt8195-power-controller | ||
| 30 | 32 | ||
| 31 | '#power-domain-cells': | 33 | '#power-domain-cells': |
| 32 | const: 1 | 34 | 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: 1 | 70 | maxItems: 1 |
| 68 | 71 | ||
| 69 | clocks: | 72 | clocks: |
| @@ -17,6 +17,7 @@ properties: · 16 unmodified lines | |||
| 17 | compatible: | 17 | compatible: |
| 18 | enum: | 18 | enum: |
| 19 | - qcom,mdm9607-rpmpd | 19 | - qcom,mdm9607-rpmpd |
| 20 | - qcom,msm8226-rpmpd | ||
| 20 | - qcom,msm8916-rpmpd | 21 | - qcom,msm8916-rpmpd |
| 21 | - qcom,msm8939-rpmpd | 22 | - qcom,msm8939-rpmpd |
| 22 | - qcom,msm8953-rpmpd | 23 | - qcom,msm8953-rpmpd |
| @@ -47,6 +47,10 @@ properties: · 46 unmodified lines | |||
| 47 | - qcom,sm8350-cdsp-pas | 47 | - qcom,sm8350-cdsp-pas |
| 48 | - qcom,sm8350-slpi-pas | 48 | - qcom,sm8350-slpi-pas |
| 49 | - qcom,sm8350-mpss-pas | 49 | - 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: 1 | 56 | maxItems: 1 |
| @@ -175,6 +179,10 @@ allOf: · 122 unmodified lines | |||
| 175 | - qcom,sm8350-cdsp-pas | 179 | - qcom,sm8350-cdsp-pas |
| 176 | - qcom,sm8350-slpi-pas | 180 | - qcom,sm8350-slpi-pas |
| 177 | - qcom,sm8350-mpss-pas | 181 | - 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-pas | 291 | - qcom,sm8350-adsp-pas |
| 284 | - qcom,sm8350-cdsp-pas | 292 | - qcom,sm8350-cdsp-pas |
| 285 | - qcom,sm8350-slpi-pas | 293 | - 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-pas | 323 | - qcom,sm6350-mpss-pas |
| 313 | - qcom,sm8150-mpss-pas | 324 | - qcom,sm8150-mpss-pas |
| 314 | - qcom,sm8350-mpss-pas | 325 | - 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-pas | 446 | - qcom,sm6350-mpss-pas |
| 435 | - qcom,sm8150-mpss-pas | 447 | - qcom,sm8150-mpss-pas |
| 436 | - qcom,sm8350-mpss-pas | 448 | - 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-pas | 471 | - qcom,sm8250-slpi-pas |
| 459 | - qcom,sm8350-adsp-pas | 472 | - qcom,sm8350-adsp-pas |
| 460 | - qcom,sm8350-slpi-pas | 473 | - 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-pas | 492 | - qcom,sm8350-cdsp-pas |
| 493 | - qcom,sm8450-cdsp-pas | ||
| 478 | then: | 494 | then: |
| 479 | properties: | 495 | properties: |
| 480 | power-domains: | 496 | power-domains: |
| @@ -27,6 +27,7 @@ Required properties in pwrap device node. · 26 unmodified lines | |||
| 27 | "mediatek,mt8135-pwrap" for MT8135 SoCs | 27 | "mediatek,mt8135-pwrap" for MT8135 SoCs |
| 28 | "mediatek,mt8173-pwrap" for MT8173 SoCs | 28 | "mediatek,mt8173-pwrap" for MT8173 SoCs |
| 29 | "mediatek,mt8183-pwrap" for MT8183 SoCs | 29 | "mediatek,mt8183-pwrap" for MT8183 SoCs |
| 30 | "mediatek,mt8186-pwrap" for MT8186 SoCs | ||
| 30 | "mediatek,mt8195-pwrap" for MT8195 SoCs | 31 | "mediatek,mt8195-pwrap" for MT8195 SoCs |
| 31 | "mediatek,mt8516-pwrap" for MT8516 SoCs | 32 | "mediatek,mt8516-pwrap" for MT8516 SoCs |
| 32 | - interrupts: IRQ for pwrap in SOC | 33 | - interrupts: IRQ for pwrap in SOC |
| @@ -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; |
| @@ -29,7 +29,7 @@ void __init spear13xx_l2x0_init(void) · 28 unmodified lines | |||
| 29 | /* | 29 | /* |
| 30 | * 512KB (64KB/way), 8-way associativity, parity supported | 30 | * 512KB (64KB/way), 8-way associativity, parity supported |
| 31 | * | 31 | * |
| 32 | * FIXME: 9th bit, of Auxillary Controller register must be set | 32 | * 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, |
| @@ -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 | ||
| 67 | struct weim_priv { | ||
| 68 | void __iomem *base; | ||
| 69 | struct cs_timing_state timing_state; | ||
| 70 | }; | ||
| 71 | |||
| 67 | static const struct of_device_id weim_id_table[] = { | 72 | static 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. */ |
| 131 | static int weim_timing_setup(struct device *dev, | 136 | static 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 | ||
| 192 | static int weim_parse_dt(struct platform_device *pdev, void __iomem *base) | 202 | static 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 | ||
| 249 | static int weim_probe(struct platform_device *pdev) | 263 | static 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 | else | 297 | 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) | ||
| 304 | static int of_weim_notify(struct notifier_block *nb, unsigned long action, | ||
| 305 | void *arg) | ||
| 306 | { | ||
| 307 | const struct imx_weim_devtype *devtype; | ||
| 308 | struct of_reconfig_data *rd = arg; | ||
| 309 | const struct of_device_id *of_id; | ||
| 310 | struct platform_device *pdev; | ||
| 311 | int ret = NOTIFY_OK; | ||
| 312 | |||
| 313 | switch (of_reconfig_get_state_change(action, rd)) { | ||
| 314 | case OF_RECONFIG_CHANGE_ADD: | ||
| 315 | of_id = of_match_node(weim_id_table, rd->dn->parent); | ||
| 316 | if (!of_id) | ||
| 317 | return NOTIFY_OK; /* not for us */ | ||
| 318 | |||
| 319 | devtype = of_id->data; | ||
| 320 | |||
| 321 | pdev = of_find_device_by_node(rd->dn->parent); | ||
| 322 | if (!pdev) { | ||
| 323 | pr_err("%s: could not find platform device for '%pOF'\n", | ||
| 324 | __func__, rd->dn->parent); | ||
| 325 | |||
| 326 | return notifier_from_errno(-EINVAL); | ||
| 327 | } | ||
| 328 | |||
| 329 | if (weim_timing_setup(&pdev->dev, rd->dn, devtype)) | ||
| 330 | dev_warn(&pdev->dev, | ||
| 331 | "Failed to setup timing for '%pOF'\n", rd->dn); | ||
| 332 | |||
| 333 | if (!of_node_check_flag(rd->dn, OF_POPULATED)) { | ||
| 334 | if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) { | ||
| 335 | dev_err(&pdev->dev, | ||
| 336 | "Failed to create child device '%pOF'\n", | ||
| 337 | rd->dn); | ||
| 338 | ret = notifier_from_errno(-EINVAL); | ||
| 339 | } | ||
| 340 | } | ||
| 341 | |||
| 342 | platform_device_put(pdev); | ||
| 343 | |||
| 344 | break; | ||
| 345 | case OF_RECONFIG_CHANGE_REMOVE: | ||
| 346 | if (!of_node_check_flag(rd->dn, OF_POPULATED)) | ||
| 347 | return NOTIFY_OK; /* device already destroyed */ | ||
| 348 | |||
| 349 | of_id = of_match_node(weim_id_table, rd->dn->parent); | ||
| 350 | if (!of_id) | ||
| 351 | return NOTIFY_OK; /* not for us */ | ||
| 352 | |||
| 353 | pdev = of_find_device_by_node(rd->dn); | ||
| 354 | if (!pdev) { | ||
| 355 | dev_err(&pdev->dev, | ||
| 356 | "Could not find platform device for '%pOF'\n", | ||
| 357 | rd->dn); | ||
| 358 | |||
| 359 | ret = notifier_from_errno(-EINVAL); | ||
| 360 | } else { | ||
| 361 | of_platform_device_destroy(&pdev->dev, NULL); | ||
| 362 | platform_device_put(pdev); | ||
| 363 | } | ||
| 364 | |||
| 365 | break; | ||
| 366 | default: | ||
| 367 | break; | ||
| 368 | } | ||
| 369 | |||
| 370 | return ret; | ||
| 371 | } | ||
| 372 | |||
| 373 | struct notifier_block weim_of_notifier = { | ||
| 374 | .notifier_call = of_weim_notify, | ||
| 375 | }; | ||
| 376 | #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ | ||
| 377 | |||
| 281 | static struct platform_driver weim_driver = { | 378 | static 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 | }; |
| 288 | module_platform_driver(weim_driver); | 385 | |
| 386 | static int __init weim_init(void) | ||
| 387 | { | ||
| 388 | #if IS_ENABLED(CONFIG_OF_DYNAMIC) | ||
| 389 | WARN_ON(of_reconfig_notifier_register(&weim_of_notifier)); | ||
| 390 | #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ | ||
| 391 | |||
| 392 | return platform_driver_register(&weim_driver); | ||
| 393 | } | ||
| 394 | module_init(weim_init); | ||
| 395 | |||
| 396 | static void __exit weim_exit(void) | ||
| 397 | { | ||
| 398 | #if IS_ENABLED(CONFIG_OF_DYNAMIC) | ||
| 399 | of_reconfig_notifier_unregister(&weim_of_notifier); | ||
| 400 | #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ | ||
| 401 | |||
| 402 | return platform_driver_unregister(&weim_driver); | ||
| 403 | |||
| 404 | } | ||
| 405 | module_exit(weim_exit); | ||
| 289 | 406 | ||
| 290 | MODULE_AUTHOR("Freescale Semiconductor Inc."); | 407 | MODULE_AUTHOR("Freescale Semiconductor Inc."); |
| 291 | MODULE_DESCRIPTION("i.MX EIM Controller Driver"); | 408 | MODULE_DESCRIPTION("i.MX EIM Controller Driver"); |
| @@ -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 | ||
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | /* | 2 | /* |
| 3 | * System Control and Power Interface (SCMI) Protocol based clock driver | 3 | * 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 | ||
| 91 | static int scmi_clk_atomic_enable(struct clk_hw *hw) | ||
| 92 | { | ||
| 93 | struct scmi_clk *clk = to_scmi_clk(hw); | ||
| 94 | |||
| 95 | return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id); | ||
| 96 | } | ||
| 97 | |||
| 98 | static void scmi_clk_atomic_disable(struct clk_hw *hw) | ||
| 99 | { | ||
| 100 | struct scmi_clk *clk = to_scmi_clk(hw); | ||
| 101 | |||
| 102 | scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id); | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * We can provide enable/disable atomic callbacks only if the underlying SCMI | ||
| 107 | * transport for an SCMI instance is configured to handle SCMI commands in an | ||
| 108 | * atomic manner. | ||
| 109 | * | ||
| 110 | * When no SCMI atomic transport support is available we instead provide only | ||
| 111 | * the prepare/unprepare API, as allowed by the clock framework when atomic | ||
| 112 | * calls are not available. | ||
| 113 | * | ||
| 114 | * Two distinct sets of clk_ops are provided since we could have multiple SCMI | ||
| 115 | * instances with different underlying transport quality, so they cannot be | ||
| 116 | * shared. | ||
| 117 | */ | ||
| 91 | static const struct clk_ops scmi_clk_ops = { | 118 | static 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 | ||
| 105 | static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) | 126 | static const struct clk_ops scmi_atomic_clk_ops = { |
| 127 | .recalc_rate = scmi_clk_recalc_rate, | ||
| 128 | .round_rate = scmi_clk_round_rate, | ||
| 129 | .set_rate = scmi_clk_set_rate, | ||
| 130 | .enable = scmi_clk_atomic_enable, | ||
| 131 | .disable = scmi_clk_atomic_disable, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk, | ||
| 135 | const struct clk_ops *scmi_ops) | ||
| 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 | |||
| 139 | static int scmi_clocks_probe(struct scmi_device *sdev) | 169 | static 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 | } |
| @@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG · 10 unmodified lines | |||
| 11 | select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410 | 11 | select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410 |
| 12 | select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420 | 12 | select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420 |
| 13 | select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS | 13 | select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS |
| 14 | select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD | ||
| 14 | 15 | ||
| 15 | config S3C64XX_COMMON_CLK | 16 | config S3C64XX_COMMON_CLK |
| 16 | bool "Samsung S3C64xx clock controller support" if COMPILE_TEST | 17 | bool "Samsung S3C64xx clock controller support" if COMPILE_TEST |
| @@ -124,3 +125,11 @@ config S3C2443_COMMON_CLK · 107 unmodified lines | |||
| 124 | help | 125 | help |
| 125 | Support for the clock controller present on the Samsung | 126 | 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 | |||
| 129 | config TESLA_FSD_COMMON_CLK | ||
| 130 | bool "Tesla FSD clock controller support" if COMPILE_TEST | ||
| 131 | depends on COMMON_CLK_SAMSUNG | ||
| 132 | depends on EXYNOS_ARM64_COMMON_CLK | ||
| 133 | help | ||
| 134 | Support for the clock controller present on the Tesla FSD SoC. | ||
| 135 | Choose Y here only if you build for this SoC. | ||
| @@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o · 25 unmodified lines | |||
| 26 | obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o | 26 | obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o |
| 27 | obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o | 27 | obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o |
| 28 | obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o | 28 | obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o |
| 29 | obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o | ||
| @@ -0,0 +1,1803 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd. | ||
| 4 | * https://www.samsung.com | ||
| 5 | * Copyright (c) 2017-2022 Tesla, Inc. | ||
| 6 | * https://www.tesla.com | ||
| 7 | * | ||
| 8 | * Common Clock Framework support for FSD SoC. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/clk.h> | ||
| 12 | #include <linux/clk-provider.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/of.h> | ||
| 16 | #include <linux/of_address.h> | ||
| 17 | #include <linux/of_device.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | |||
| 20 | #include <dt-bindings/clock/fsd-clk.h> | ||
| 21 | |||
| 22 | #include "clk.h" | ||
| 23 | #include "clk-exynos-arm64.h" | ||
| 24 | |||
| 25 | /* Register Offset definitions for CMU_CMU (0x11c10000) */ | ||
| 26 | #define PLL_LOCKTIME_PLL_SHARED0 0x0 | ||
| 27 | #define PLL_LOCKTIME_PLL_SHARED1 0x4 | ||
| 28 | #define PLL_LOCKTIME_PLL_SHARED2 0x8 | ||
| 29 | #define PLL_LOCKTIME_PLL_SHARED3 0xc | ||
| 30 | #define PLL_CON0_PLL_SHARED0 0x100 | ||
| 31 | #define PLL_CON0_PLL_SHARED1 0x120 | ||
| 32 | #define PLL_CON0_PLL_SHARED2 0x140 | ||
| 33 | #define PLL_CON0_PLL_SHARED3 0x160 | ||
| 34 | #define MUX_CMU_CIS0_CLKMUX 0x1000 | ||
| 35 | #define MUX_CMU_CIS1_CLKMUX 0x1004 | ||
| 36 | #define MUX_CMU_CIS2_CLKMUX 0x1008 | ||
| 37 | #define MUX_CMU_CPUCL_SWITCHMUX 0x100c | ||
| 38 | #define MUX_CMU_FSYS1_ACLK_MUX 0x1014 | ||
| 39 | #define MUX_PLL_SHARED0_MUX 0x1020 | ||
| 40 | #define MUX_PLL_SHARED1_MUX 0x1024 | ||
| 41 | #define DIV_CMU_CIS0_CLK 0x1800 | ||
| 42 | #define DIV_CMU_CIS1_CLK 0x1804 | ||
| 43 | #define DIV_CMU_CIS2_CLK 0x1808 | ||
| 44 | #define DIV_CMU_CMU_ACLK 0x180c | ||
| 45 | #define DIV_CMU_CPUCL_SWITCH 0x1810 | ||
| 46 | #define DIV_CMU_FSYS0_SHARED0DIV4 0x181c | ||
| 47 | #define DIV_CMU_FSYS0_SHARED1DIV3 0x1820 | ||
| 48 | #define DIV_CMU_FSYS0_SHARED1DIV4 0x1824 | ||
| 49 | #define DIV_CMU_FSYS1_SHARED0DIV4 0x1828 | ||
| 50 | #define DIV_CMU_FSYS1_SHARED0DIV8 0x182c | ||
| 51 | #define DIV_CMU_IMEM_ACLK 0x1834 | ||
| 52 | #define DIV_CMU_IMEM_DMACLK 0x1838 | ||
| 53 | #define DIV_CMU_IMEM_TCUCLK 0x183c | ||
| 54 | #define DIV_CMU_PERIC_SHARED0DIV20 0x1844 | ||
| 55 | #define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK 0x1848 | ||
| 56 | #define DIV_CMU_PERIC_SHARED1DIV36 0x184c | ||
| 57 | #define DIV_CMU_PERIC_SHARED1DIV4_DMACLK 0x1850 | ||
| 58 | #define DIV_PLL_SHARED0_DIV2 0x1858 | ||
| 59 | #define DIV_PLL_SHARED0_DIV3 0x185c | ||
| 60 | #define DIV_PLL_SHARED0_DIV4 0x1860 | ||
| 61 | #define DIV_PLL_SHARED0_DIV6 0x1864 | ||
| 62 | #define DIV_PLL_SHARED1_DIV3 0x1868 | ||
| 63 | #define DIV_PLL_SHARED1_DIV36 0x186c | ||
| 64 | #define DIV_PLL_SHARED1_DIV4 0x1870 | ||
| 65 | #define DIV_PLL_SHARED1_DIV9 0x1874 | ||
| 66 | #define GAT_CMU_CIS0_CLKGATE 0x2000 | ||
| 67 | #define GAT_CMU_CIS1_CLKGATE 0x2004 | ||
| 68 | #define GAT_CMU_CIS2_CLKGATE 0x2008 | ||
| 69 | #define GAT_CMU_CPUCL_SWITCH_GATE 0x200c | ||
| 70 | #define GAT_CMU_FSYS0_SHARED0DIV4_GATE 0x2018 | ||
| 71 | #define GAT_CMU_FSYS0_SHARED1DIV4_CLK 0x201c | ||
| 72 | #define GAT_CMU_FSYS0_SHARED1DIV4_GATE 0x2020 | ||
| 73 | #define GAT_CMU_FSYS1_SHARED0DIV4_GATE 0x2024 | ||
| 74 | #define GAT_CMU_FSYS1_SHARED1DIV4_GATE 0x2028 | ||
| 75 | #define GAT_CMU_IMEM_ACLK_GATE 0x2030 | ||
| 76 | #define GAT_CMU_IMEM_DMACLK_GATE 0x2034 | ||
| 77 | #define GAT_CMU_IMEM_TCUCLK_GATE 0x2038 | ||
| 78 | #define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE 0x2040 | ||
| 79 | #define GAT_CMU_PERIC_SHARED0DIVE4_GATE 0x2044 | ||
| 80 | #define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE 0x2048 | ||
| 81 | #define GAT_CMU_PERIC_SHARED1DIVE4_GATE 0x204c | ||
| 82 | #define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK 0x2054 | ||
| 83 | #define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK 0x2058 | ||
| 84 | #define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU 0x205c | ||
| 85 | #define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK 0x2060 | ||
| 86 | |||
| 87 | static const unsigned long cmu_clk_regs[] __initconst = { | ||
| 88 | PLL_LOCKTIME_PLL_SHARED0, | ||
| 89 | PLL_LOCKTIME_PLL_SHARED1, | ||
| 90 | PLL_LOCKTIME_PLL_SHARED2, | ||
| 91 | PLL_LOCKTIME_PLL_SHARED3, | ||
| 92 | PLL_CON0_PLL_SHARED0, | ||
| 93 | PLL_CON0_PLL_SHARED1, | ||
| 94 | PLL_CON0_PLL_SHARED2, | ||
| 95 | PLL_CON0_PLL_SHARED3, | ||
| 96 | MUX_CMU_CIS0_CLKMUX, | ||
| 97 | MUX_CMU_CIS1_CLKMUX, | ||
| 98 | MUX_CMU_CIS2_CLKMUX, | ||
| 99 | MUX_CMU_CPUCL_SWITCHMUX, | ||
| 100 | MUX_CMU_FSYS1_ACLK_MUX, | ||
| 101 | MUX_PLL_SHARED0_MUX, | ||
| 102 | MUX_PLL_SHARED1_MUX, | ||
| 103 | DIV_CMU_CIS0_CLK, | ||
| 104 | DIV_CMU_CIS1_CLK, | ||
| 105 | DIV_CMU_CIS2_CLK, | ||
| 106 | DIV_CMU_CMU_ACLK, | ||
| 107 | DIV_CMU_CPUCL_SWITCH, | ||
| 108 | DIV_CMU_FSYS0_SHARED0DIV4, | ||
| 109 | DIV_CMU_FSYS0_SHARED1DIV3, | ||
| 110 | DIV_CMU_FSYS0_SHARED1DIV4, | ||
| 111 | DIV_CMU_FSYS1_SHARED0DIV4, | ||
| 112 | DIV_CMU_FSYS1_SHARED0DIV8, | ||
| 113 | DIV_CMU_IMEM_ACLK, | ||
| 114 | DIV_CMU_IMEM_DMACLK, | ||
| 115 | DIV_CMU_IMEM_TCUCLK, | ||
| 116 | DIV_CMU_PERIC_SHARED0DIV20, | ||
| 117 | DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, | ||
| 118 | DIV_CMU_PERIC_SHARED1DIV36, | ||
| 119 | DIV_CMU_PERIC_SHARED1DIV4_DMACLK, | ||
| 120 | DIV_PLL_SHARED0_DIV2, | ||
| 121 | DIV_PLL_SHARED0_DIV3, | ||
| 122 | DIV_PLL_SHARED0_DIV4, | ||
| 123 | DIV_PLL_SHARED0_DIV6, | ||
| 124 | DIV_PLL_SHARED1_DIV3, | ||
| 125 | DIV_PLL_SHARED1_DIV36, | ||
| 126 | DIV_PLL_SHARED1_DIV4, | ||
| 127 | DIV_PLL_SHARED1_DIV9, | ||
| 128 | GAT_CMU_CIS0_CLKGATE, | ||
| 129 | GAT_CMU_CIS1_CLKGATE, | ||
| 130 | GAT_CMU_CIS2_CLKGATE, | ||
| 131 | GAT_CMU_CPUCL_SWITCH_GATE, | ||
| 132 | GAT_CMU_FSYS0_SHARED0DIV4_GATE, | ||
| 133 | GAT_CMU_FSYS0_SHARED1DIV4_CLK, | ||
| 134 | GAT_CMU_FSYS0_SHARED1DIV4_GATE, | ||
| 135 | GAT_CMU_FSYS1_SHARED0DIV4_GATE, | ||
| 136 | GAT_CMU_FSYS1_SHARED1DIV4_GATE, | ||
| 137 | GAT_CMU_IMEM_ACLK_GATE, | ||
| 138 | GAT_CMU_IMEM_DMACLK_GATE, | ||
| 139 | GAT_CMU_IMEM_TCUCLK_GATE, | ||
| 140 | GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, | ||
| 141 | GAT_CMU_PERIC_SHARED0DIVE4_GATE, | ||
| 142 | GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, | ||
| 143 | GAT_CMU_PERIC_SHARED1DIVE4_GATE, | ||
| 144 | GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, | ||
| 145 | GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, | ||
| 146 | GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, | ||
| 147 | GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, | ||
| 148 | }; | ||
| 149 | |||
| 150 | static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = { | ||
| 151 | PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0), | ||
| 152 | }; | ||
| 153 | |||
| 154 | static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = { | ||
| 155 | PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0), | ||
| 156 | }; | ||
| 157 | |||
| 158 | static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = { | ||
| 159 | PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0), | ||
| 160 | }; | ||
| 161 | |||
| 162 | static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = { | ||
| 163 | PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0), | ||
| 164 | }; | ||
| 165 | |||
| 166 | static const struct samsung_pll_clock cmu_pll_clks[] __initconst = { | ||
| 167 | PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0, | ||
| 168 | PLL_CON0_PLL_SHARED0, pll_shared0_rate_table), | ||
| 169 | PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1, | ||
| 170 | PLL_CON0_PLL_SHARED1, pll_shared1_rate_table), | ||
| 171 | PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2, | ||
| 172 | PLL_CON0_PLL_SHARED2, pll_shared2_rate_table), | ||
| 173 | PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3, | ||
| 174 | PLL_CON0_PLL_SHARED3, pll_shared3_rate_table), | ||
| 175 | }; | ||
| 176 | |||
| 177 | /* List of parent clocks for Muxes in CMU_CMU */ | ||
| 178 | PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" }; | ||
| 179 | PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" }; | ||
| 180 | PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" }; | ||
| 181 | PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" }; | ||
| 182 | PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" }; | ||
| 183 | PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" }; | ||
| 184 | PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" }; | ||
| 185 | PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" }; | ||
| 186 | PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" }; | ||
| 187 | PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" }; | ||
| 188 | PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" }; | ||
| 189 | |||
| 190 | static const struct samsung_mux_clock cmu_mux_clks[] __initconst = { | ||
| 191 | MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1), | ||
| 192 | MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1), | ||
| 193 | MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1), | ||
| 194 | MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1), | ||
| 195 | MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1), | ||
| 196 | MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1), | ||
| 197 | MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1), | ||
| 198 | MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p, | ||
| 199 | MUX_CMU_CPUCL_SWITCHMUX, 0, 1), | ||
| 200 | MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1), | ||
| 201 | MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1), | ||
| 202 | MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1), | ||
| 203 | }; | ||
| 204 | |||
| 205 | static const struct samsung_div_clock cmu_div_clks[] __initconst = { | ||
| 206 | DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4), | ||
| 207 | DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4), | ||
| 208 | DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4), | ||
| 209 | DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4), | ||
| 210 | DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4), | ||
| 211 | DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate", | ||
| 212 | DIV_CMU_FSYS0_SHARED0DIV4, 0, 4), | ||
| 213 | DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk", | ||
| 214 | DIV_CMU_FSYS0_SHARED1DIV3, 0, 4), | ||
| 215 | DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate", | ||
| 216 | DIV_CMU_FSYS0_SHARED1DIV4, 0, 4), | ||
| 217 | DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate", | ||
| 218 | DIV_CMU_FSYS1_SHARED0DIV4, 0, 4), | ||
| 219 | DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate", | ||
| 220 | DIV_CMU_FSYS1_SHARED0DIV8, 0, 4), | ||
| 221 | DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate", | ||
| 222 | DIV_CMU_IMEM_ACLK, 0, 4), | ||
| 223 | DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate", | ||
| 224 | DIV_CMU_IMEM_DMACLK, 0, 4), | ||
| 225 | DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate", | ||
| 226 | DIV_CMU_IMEM_TCUCLK, 0, 4), | ||
| 227 | DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20", | ||
| 228 | "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4), | ||
| 229 | DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk", | ||
| 230 | "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4), | ||
| 231 | DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36", | ||
| 232 | "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4), | ||
| 233 | DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk", | ||
| 234 | "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4), | ||
| 235 | DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux", | ||
| 236 | DIV_PLL_SHARED0_DIV2, 0, 4), | ||
| 237 | DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux", | ||
| 238 | DIV_PLL_SHARED0_DIV3, 0, 4), | ||
| 239 | DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2", | ||
| 240 | DIV_PLL_SHARED0_DIV4, 0, 4), | ||
| 241 | DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3", | ||
| 242 | DIV_PLL_SHARED0_DIV6, 0, 4), | ||
| 243 | DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux", | ||
| 244 | DIV_PLL_SHARED1_DIV3, 0, 4), | ||
| 245 | DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9", | ||
| 246 | DIV_PLL_SHARED1_DIV36, 0, 4), | ||
| 247 | DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux", | ||
| 248 | DIV_PLL_SHARED1_DIV4, 0, 4), | ||
| 249 | DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3", | ||
| 250 | DIV_PLL_SHARED1_DIV9, 0, 4), | ||
| 251 | }; | ||
| 252 | |||
| 253 | static const struct samsung_gate_clock cmu_gate_clks[] __initconst = { | ||
| 254 | GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21, | ||
| 255 | CLK_IGNORE_UNUSED, 0), | ||
| 256 | GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21, | ||
| 257 | CLK_IGNORE_UNUSED, 0), | ||
| 258 | GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21, | ||
| 259 | CLK_IGNORE_UNUSED, 0), | ||
| 260 | GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux", | ||
| 261 | GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 262 | GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4", | ||
| 263 | GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 264 | GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3", | ||
| 265 | GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 266 | GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4", | ||
| 267 | GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 268 | GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux", | ||
| 269 | GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 270 | GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4", | ||
| 271 | GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 272 | GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21, | ||
| 273 | CLK_IGNORE_UNUSED, 0), | ||
| 274 | GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21, | ||
| 275 | CLK_IGNORE_UNUSED, 0), | ||
| 276 | GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21, | ||
| 277 | CLK_IGNORE_UNUSED, 0), | ||
| 278 | GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3", | ||
| 279 | GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 280 | GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4", | ||
| 281 | GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 282 | GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4", | ||
| 283 | GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 284 | GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36", | ||
| 285 | GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 286 | GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk", | ||
| 287 | GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 288 | GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk", | ||
| 289 | GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 290 | GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk", | ||
| 291 | GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0), | ||
| 292 | GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk", | ||
| 293 | GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 294 | }; | ||
| 295 | |||
| 296 | static const struct samsung_cmu_info cmu_cmu_info __initconst = { | ||
| 297 | .pll_clks = cmu_pll_clks, | ||
| 298 | .nr_pll_clks = ARRAY_SIZE(cmu_pll_clks), | ||
| 299 | .mux_clks = cmu_mux_clks, | ||
| 300 | .nr_mux_clks = ARRAY_SIZE(cmu_mux_clks), | ||
| 301 | .div_clks = cmu_div_clks, | ||
| 302 | .nr_div_clks = ARRAY_SIZE(cmu_div_clks), | ||
| 303 | .gate_clks = cmu_gate_clks, | ||
| 304 | .nr_gate_clks = ARRAY_SIZE(cmu_gate_clks), | ||
| 305 | .nr_clk_ids = CMU_NR_CLK, | ||
| 306 | .clk_regs = cmu_clk_regs, | ||
| 307 | .nr_clk_regs = ARRAY_SIZE(cmu_clk_regs), | ||
| 308 | }; | ||
| 309 | |||
| 310 | static void __init fsd_clk_cmu_init(struct device_node *np) | ||
| 311 | { | ||
| 312 | samsung_cmu_register_one(np, &cmu_cmu_info); | ||
| 313 | } | ||
| 314 | |||
| 315 | CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init); | ||
| 316 | |||
| 317 | /* Register Offset definitions for CMU_PERIC (0x14010000) */ | ||
| 318 | #define PLL_CON0_PERIC_DMACLK_MUX 0x100 | ||
| 319 | #define PLL_CON0_PERIC_EQOS_BUSCLK_MUX 0x120 | ||
| 320 | #define PLL_CON0_PERIC_PCLK_MUX 0x140 | ||
| 321 | #define PLL_CON0_PERIC_TBUCLK_MUX 0x160 | ||
| 322 | #define PLL_CON0_SPI_CLK 0x180 | ||
| 323 | #define PLL_CON0_SPI_PCLK 0x1a0 | ||
| 324 | #define PLL_CON0_UART_CLK 0x1c0 | ||
| 325 | #define PLL_CON0_UART_PCLK 0x1e0 | ||
| 326 | #define MUX_PERIC_EQOS_PHYRXCLK 0x1000 | ||
| 327 | #define DIV_EQOS_BUSCLK 0x1800 | ||
| 328 | #define DIV_PERIC_MCAN_CLK 0x1804 | ||
| 329 | #define DIV_RGMII_CLK 0x1808 | ||
| 330 | #define DIV_RII_CLK 0x180c | ||
| 331 | #define DIV_RMII_CLK 0x1810 | ||
| 332 | #define DIV_SPI_CLK 0x1814 | ||
| 333 | #define DIV_UART_CLK 0x1818 | ||
| 334 | #define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I 0x2000 | ||
| 335 | #define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK 0x2004 | ||
| 336 | #define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK 0x2008 | ||
| 337 | #define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK 0x200c | ||
| 338 | #define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK 0x2010 | ||
| 339 | #define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK 0x2014 | ||
| 340 | #define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM 0x2018 | ||
| 341 | #define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS 0x201c | ||
| 342 | #define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM 0x2020 | ||
| 343 | #define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS 0x2024 | ||
| 344 | #define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK 0x2028 | ||
| 345 | #define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK 0x202c | ||
| 346 | #define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK 0x2030 | ||
| 347 | #define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK 0x2034 | ||
| 348 | #define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK 0x2038 | ||
| 349 | #define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK 0x203c | ||
| 350 | #define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK 0x2040 | ||
| 351 | #define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK 0x2044 | ||
| 352 | #define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK 0x2048 | ||
| 353 | #define GAT_EQOS_TOP_IPCLKPORT_ACLK_I 0x204c | ||
| 354 | #define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I 0x2050 | ||
| 355 | #define GAT_EQOS_TOP_IPCLKPORT_HCLK_I 0x2054 | ||
| 356 | #define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I 0x2058 | ||
| 357 | #define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I 0x205c | ||
| 358 | #define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I 0x2060 | ||
| 359 | #define GAT_GPIO_PERIC_IPCLKPORT_PCLK 0x2064 | ||
| 360 | #define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D 0x2068 | ||
| 361 | #define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P 0x206c | ||
| 362 | #define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0 0x2070 | ||
| 363 | #define GAT_PERIC_DMA0_IPCLKPORT_ACLK 0x2074 | ||
| 364 | #define GAT_PERIC_DMA1_IPCLKPORT_ACLK 0x2078 | ||
| 365 | #define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK 0x207c | ||
| 366 | #define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK 0x2080 | ||
| 367 | #define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK 0x2084 | ||
| 368 | #define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK 0x2088 | ||
| 369 | #define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK 0x208c | ||
| 370 | #define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK 0x2090 | ||
| 371 | #define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK 0x2094 | ||
| 372 | #define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK 0x2098 | ||
| 373 | #define GAT_PERIC_MCAN0_IPCLKPORT_CCLK 0x209c | ||
| 374 | #define GAT_PERIC_MCAN0_IPCLKPORT_PCLK 0x20a0 | ||
| 375 | #define GAT_PERIC_MCAN1_IPCLKPORT_CCLK 0x20a4 | ||
| 376 | #define GAT_PERIC_MCAN1_IPCLKPORT_PCLK 0x20a8 | ||
| 377 | #define GAT_PERIC_MCAN2_IPCLKPORT_CCLK 0x20ac | ||
| 378 | #define GAT_PERIC_MCAN2_IPCLKPORT_PCLK 0x20b0 | ||
| 379 | #define GAT_PERIC_MCAN3_IPCLKPORT_CCLK 0x20b4 | ||
| 380 | #define GAT_PERIC_MCAN3_IPCLKPORT_PCLK 0x20b8 | ||
| 381 | #define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0 0x20bc | ||
| 382 | #define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0 0x20c0 | ||
| 383 | #define GAT_PERIC_SMMU_IPCLKPORT_CCLK 0x20c4 | ||
| 384 | #define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK 0x20c8 | ||
| 385 | #define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK 0x20cc | ||
| 386 | #define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI 0x20d0 | ||
| 387 | #define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK 0x20d4 | ||
| 388 | #define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI 0x20d8 | ||
| 389 | #define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK 0x20dc | ||
| 390 | #define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI 0x20e0 | ||
| 391 | #define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M 0x20e4 | ||
| 392 | #define GAT_PERIC_TDM0_IPCLKPORT_PCLK 0x20e8 | ||
| 393 | #define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M 0x20ec | ||
| 394 | #define GAT_PERIC_TDM1_IPCLKPORT_PCLK 0x20f0 | ||
| 395 | #define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART 0x20f4 | ||
| 396 | #define GAT_PERIC_UART0_IPCLKPORT_PCLK 0x20f8 | ||
| 397 | #define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART 0x20fc | ||
| 398 | #define GAT_PERIC_UART1_IPCLKPORT_PCLK 0x2100 | ||
| 399 | #define GAT_SYSREG_PERI_IPCLKPORT_PCLK 0x2104 | ||
| 400 | |||
| 401 | static const unsigned long peric_clk_regs[] __initconst = { | ||
| 402 | PLL_CON0_PERIC_DMACLK_MUX, | ||
| 403 | PLL_CON0_PERIC_EQOS_BUSCLK_MUX, | ||
| 404 | PLL_CON0_PERIC_PCLK_MUX, | ||
| 405 | PLL_CON0_PERIC_TBUCLK_MUX, | ||
| 406 | PLL_CON0_SPI_CLK, | ||
| 407 | PLL_CON0_SPI_PCLK, | ||
| 408 | PLL_CON0_UART_CLK, | ||
| 409 | PLL_CON0_UART_PCLK, | ||
| 410 | MUX_PERIC_EQOS_PHYRXCLK, | ||
| 411 | DIV_EQOS_BUSCLK, | ||
| 412 | DIV_PERIC_MCAN_CLK, | ||
| 413 | DIV_RGMII_CLK, | ||
| 414 | DIV_RII_CLK, | ||
| 415 | DIV_RMII_CLK, | ||
| 416 | DIV_SPI_CLK, | ||
| 417 | DIV_UART_CLK, | ||
| 418 | GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, | ||
| 419 | GAT_GPIO_PERIC_IPCLKPORT_OSCCLK, | ||
| 420 | GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, | ||
| 421 | GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, | ||
| 422 | GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, | ||
| 423 | GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, | ||
| 424 | GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, | ||
| 425 | GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, | ||
| 426 | GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, | ||
| 427 | GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, | ||
| 428 | GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, | ||
| 429 | GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, | ||
| 430 | GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, | ||
| 431 | GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, | ||
| 432 | GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, | ||
| 433 | GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, | ||
| 434 | GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, | ||
| 435 | GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, | ||
| 436 | GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, | ||
| 437 | GAT_EQOS_TOP_IPCLKPORT_ACLK_I, | ||
| 438 | GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, | ||
| 439 | GAT_EQOS_TOP_IPCLKPORT_HCLK_I, | ||
| 440 | GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, | ||
| 441 | GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, | ||
| 442 | GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, | ||
| 443 | GAT_GPIO_PERIC_IPCLKPORT_PCLK, | ||
| 444 | GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, | ||
| 445 | GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, | ||
| 446 | GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, | ||
| 447 | GAT_PERIC_DMA0_IPCLKPORT_ACLK, | ||
| 448 | GAT_PERIC_DMA1_IPCLKPORT_ACLK, | ||
| 449 | GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, | ||
| 450 | GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, | ||
| 451 | GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, | ||
| 452 | GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, | ||
| 453 | GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, | ||
| 454 | GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, | ||
| 455 | GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, | ||
| 456 | GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, | ||
| 457 | GAT_PERIC_MCAN0_IPCLKPORT_CCLK, | ||
| 458 | GAT_PERIC_MCAN0_IPCLKPORT_PCLK, | ||
| 459 | GAT_PERIC_MCAN1_IPCLKPORT_CCLK, | ||
| 460 | GAT_PERIC_MCAN1_IPCLKPORT_PCLK, | ||
| 461 | GAT_PERIC_MCAN2_IPCLKPORT_CCLK, | ||
| 462 | GAT_PERIC_MCAN2_IPCLKPORT_PCLK, | ||
| 463 | GAT_PERIC_MCAN3_IPCLKPORT_CCLK, | ||
| 464 | GAT_PERIC_MCAN3_IPCLKPORT_PCLK, | ||
| 465 | GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, | ||
| 466 | GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, | ||
| 467 | GAT_PERIC_SMMU_IPCLKPORT_CCLK, | ||
| 468 | GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, | ||
| 469 | GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, | ||
| 470 | GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, | ||
| 471 | GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, | ||
| 472 | GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, | ||
| 473 | GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, | ||
| 474 | GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, | ||
| 475 | GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, | ||
| 476 | GAT_PERIC_TDM0_IPCLKPORT_PCLK, | ||
| 477 | GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, | ||
| 478 | GAT_PERIC_TDM1_IPCLKPORT_PCLK, | ||
| 479 | GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, | ||
| 480 | GAT_PERIC_UART0_IPCLKPORT_PCLK, | ||
| 481 | GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, | ||
| 482 | GAT_PERIC_UART1_IPCLKPORT_PCLK, | ||
| 483 | GAT_SYSREG_PERI_IPCLKPORT_PCLK, | ||
| 484 | }; | ||
| 485 | |||
| 486 | static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = { | ||
| 487 | FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000), | ||
| 488 | }; | ||
| 489 | |||
| 490 | /* List of parent clocks for Muxes in CMU_PERIC */ | ||
| 491 | PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" }; | ||
| 492 | PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" }; | ||
| 493 | PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" }; | ||
| 494 | PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" }; | ||
| 495 | PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" }; | ||
| 496 | PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" }; | ||
| 497 | PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" }; | ||
| 498 | PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" }; | ||
| 499 | PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" }; | ||
| 500 | |||
| 501 | static const struct samsung_mux_clock peric_mux_clks[] __initconst = { | ||
| 502 | MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1), | ||
| 503 | MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p, | ||
| 504 | PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1), | ||
| 505 | MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1), | ||
| 506 | MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1), | ||
| 507 | MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1), | ||
| 508 | MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1), | ||
| 509 | MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1), | ||
| 510 | MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1), | ||
| 511 | MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p, | ||
| 512 | MUX_PERIC_EQOS_PHYRXCLK, 0, 1), | ||
| 513 | }; | ||
| 514 | |||
| 515 | static const struct samsung_div_clock peric_div_clks[] __initconst = { | ||
| 516 | DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4), | ||
| 517 | DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4), | ||
| 518 | DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk", | ||
| 519 | DIV_RGMII_CLK, 0, 4), | ||
| 520 | DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4), | ||
| 521 | DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4), | ||
| 522 | DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6), | ||
| 523 | DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6), | ||
| 524 | }; | ||
| 525 | |||
| 526 | static const struct samsung_gate_clock peric_gate_clks[] __initconst = { | ||
| 527 | GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i", | ||
| 528 | "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 529 | GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK, | ||
| 530 | 21, CLK_IGNORE_UNUSED, 0), | ||
| 531 | GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll", | ||
| 532 | GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 533 | GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk", | ||
| 534 | GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 535 | GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21, | ||
| 536 | CLK_IGNORE_UNUSED, 0), | ||
| 537 | GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21, | ||
| 538 | CLK_IGNORE_UNUSED, 0), | ||
| 539 | GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk", | ||
| 540 | GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 541 | GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk", | ||
| 542 | GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 543 | GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk", | ||
| 544 | GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 545 | GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk", | ||
| 546 | GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 547 | GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk", | ||
| 548 | GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 549 | GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk", | ||
| 550 | GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 551 | GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk", | ||
| 552 | GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 553 | GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk", | ||
| 554 | GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 555 | GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk", | ||
| 556 | "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 557 | GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk", | ||
| 558 | GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 559 | GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk", | ||
| 560 | "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 561 | GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk", | ||
| 562 | GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 563 | GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk", | ||
| 564 | GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 565 | GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i", | ||
| 566 | "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 567 | GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i", | ||
| 568 | "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 569 | GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i", | ||
| 570 | "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 571 | GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i", | ||
| 572 | "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 573 | GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk", | ||
| 574 | GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 575 | GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk", | ||
| 576 | GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 577 | GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk", | ||
| 578 | GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 579 | GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk", | ||
| 580 | GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0), | ||
| 581 | GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk", | ||
| 582 | GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0), | ||
| 583 | GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk", | ||
| 584 | GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0), | ||
| 585 | GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk", | ||
| 586 | GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 587 | GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk", | ||
| 588 | GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 589 | GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 590 | GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 591 | GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 592 | GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 593 | GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 594 | GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 595 | GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 596 | GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 597 | GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 598 | GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 599 | GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 600 | GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 601 | GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 602 | GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 603 | GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk", | ||
| 604 | GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 605 | GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk", | ||
| 606 | GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 607 | GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk", | ||
| 608 | GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 609 | GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk", | ||
| 610 | GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 611 | GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk", | ||
| 612 | GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 613 | GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk", | ||
| 614 | GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 615 | GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk", | ||
| 616 | GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 617 | GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk", | ||
| 618 | GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 619 | GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk", | ||
| 620 | GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 621 | GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk", | ||
| 622 | GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0), | ||
| 623 | GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk", | ||
| 624 | GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0), | ||
| 625 | GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk", | ||
| 626 | GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 627 | GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk", | ||
| 628 | GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 629 | GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk", | ||
| 630 | GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 631 | GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk", | ||
| 632 | GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0), | ||
| 633 | GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk", | ||
| 634 | GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 635 | GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk", | ||
| 636 | GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0), | ||
| 637 | GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk", | ||
| 638 | GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 639 | GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk", | ||
| 640 | GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0), | ||
| 641 | GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk", | ||
| 642 | GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0), | ||
| 643 | GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk", | ||
| 644 | GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 645 | GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk", | ||
| 646 | GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0), | ||
| 647 | GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk", | ||
| 648 | GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 649 | GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk", | ||
| 650 | GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0), | ||
| 651 | GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk", | ||
| 652 | GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 653 | GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk", | ||
| 654 | GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0), | ||
| 655 | GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk", | ||
| 656 | GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 657 | GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk", | ||
| 658 | GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 659 | }; | ||
| 660 | |||
| 661 | static const struct samsung_cmu_info peric_cmu_info __initconst = { | ||
| 662 | .mux_clks = peric_mux_clks, | ||
| 663 | .nr_mux_clks = ARRAY_SIZE(peric_mux_clks), | ||
| 664 | .div_clks = peric_div_clks, | ||
| 665 | .nr_div_clks = ARRAY_SIZE(peric_div_clks), | ||
| 666 | .gate_clks = peric_gate_clks, | ||
| 667 | .nr_gate_clks = ARRAY_SIZE(peric_gate_clks), | ||
| 668 | .fixed_clks = peric_fixed_clks, | ||
| 669 | .nr_fixed_clks = ARRAY_SIZE(peric_fixed_clks), | ||
| 670 | .nr_clk_ids = PERIC_NR_CLK, | ||
| 671 | .clk_regs = peric_clk_regs, | ||
| 672 | .nr_clk_regs = ARRAY_SIZE(peric_clk_regs), | ||
| 673 | .clk_name = "dout_cmu_pll_shared0_div4", | ||
| 674 | }; | ||
| 675 | |||
| 676 | /* Register Offset definitions for CMU_FSYS0 (0x15010000) */ | ||
| 677 | #define PLL_CON0_CLKCMU_FSYS0_UNIPRO 0x100 | ||
| 678 | #define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK 0x140 | ||
| 679 | #define PLL_CON0_EQOS_RGMII_125_MUX1 0x160 | ||
| 680 | #define DIV_CLK_UNIPRO 0x1800 | ||
| 681 | #define DIV_EQS_RGMII_CLK_125 0x1804 | ||
| 682 | #define DIV_PERIBUS_GRP 0x1808 | ||
| 683 | #define DIV_EQOS_RII_CLK2O5 0x180c | ||
| 684 | #define DIV_EQOS_RMIICLK_25 0x1810 | ||
| 685 | #define DIV_PCIE_PHY_OSCCLK 0x1814 | ||
| 686 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 0x2004 | ||
| 687 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I 0x2008 | ||
| 688 | #define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK 0x200c | ||
| 689 | #define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK 0x2010 | ||
| 690 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO 0x2014 | ||
| 691 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK 0x2018 | ||
| 692 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC 0x201c | ||
| 693 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2020 | ||
| 694 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x2024 | ||
| 695 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24 0x2028 | ||
| 696 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26 0x202c | ||
| 697 | #define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK 0x2038 | ||
| 698 | #define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK 0x203c | ||
| 699 | #define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK 0x2040 | ||
| 700 | #define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK 0x2044 | ||
| 701 | #define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK 0x2048 | ||
| 702 | #define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK 0x204c | ||
| 703 | #define GAT_FSYS0_CPE425_IPCLKPORT_ACLK 0x2050 | ||
| 704 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I 0x2054 | ||
| 705 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I 0x2058 | ||
| 706 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I 0x205c | ||
| 707 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I 0x2060 | ||
| 708 | #define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I 0x2064 | ||
| 709 | #define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK 0x2068 | ||
| 710 | #define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D 0x206c | ||
| 711 | #define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1 0x2070 | ||
| 712 | #define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P 0x2074 | ||
| 713 | #define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S 0x2078 | ||
| 714 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK 0x207c | ||
| 715 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL 0x2080 | ||
| 716 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0 0x2084 | ||
| 717 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC 0x2088 | ||
| 718 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK 0x208c | ||
| 719 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC 0x2090 | ||
| 720 | #define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC 0x2094 | ||
| 721 | #define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK 0x2098 | ||
| 722 | #define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK 0x209c | ||
| 723 | #define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK 0x20a0 | ||
| 724 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS 0x20a4 | ||
| 725 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK 0x20a8 | ||
| 726 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO 0x20ac | ||
| 727 | #define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK 0x20b0 | ||
| 728 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS 0x20b4 | ||
| 729 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK 0x20b8 | ||
| 730 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO 0x20bc | ||
| 731 | #define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK 0x20c0 | ||
| 732 | #define GAT_FSYS0_RII_CLK_DIVGATE 0x20d4 | ||
| 733 | |||
| 734 | static const unsigned long fsys0_clk_regs[] __initconst = { | ||
| 735 | PLL_CON0_CLKCMU_FSYS0_UNIPRO, | ||
| 736 | PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, | ||
| 737 | PLL_CON0_EQOS_RGMII_125_MUX1, | ||
| 738 | DIV_CLK_UNIPRO, | ||
| 739 | DIV_EQS_RGMII_CLK_125, | ||
| 740 | DIV_PERIBUS_GRP, | ||
| 741 | DIV_EQOS_RII_CLK2O5, | ||
| 742 | DIV_EQOS_RMIICLK_25, | ||
| 743 | DIV_PCIE_PHY_OSCCLK, | ||
| 744 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, | ||
| 745 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, | ||
| 746 | GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, | ||
| 747 | GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, | ||
| 748 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, | ||
| 749 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, | ||
| 750 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, | ||
| 751 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, | ||
| 752 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, | ||
| 753 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, | ||
| 754 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, | ||
| 755 | GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, | ||
| 756 | GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, | ||
| 757 | GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, | ||
| 758 | GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, | ||
| 759 | GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, | ||
| 760 | GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, | ||
| 761 | GAT_FSYS0_CPE425_IPCLKPORT_ACLK, | ||
| 762 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, | ||
| 763 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, | ||
| 764 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, | ||
| 765 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, | ||
| 766 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, | ||
| 767 | GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, | ||
| 768 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, | ||
| 769 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, | ||
| 770 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, | ||
| 771 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, | ||
| 772 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, | ||
| 773 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL, | ||
| 774 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, | ||
| 775 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, | ||
| 776 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, | ||
| 777 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, | ||
| 778 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, | ||
| 779 | GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, | ||
| 780 | GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, | ||
| 781 | GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, | ||
| 782 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, | ||
| 783 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, | ||
| 784 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, | ||
| 785 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, | ||
| 786 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, | ||
| 787 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, | ||
| 788 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, | ||
| 789 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, | ||
| 790 | GAT_FSYS0_RII_CLK_DIVGATE, | ||
| 791 | }; | ||
| 792 | |||
| 793 | static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = { | ||
| 794 | FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000), | ||
| 795 | FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000), | ||
| 796 | FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000), | ||
| 797 | }; | ||
| 798 | |||
| 799 | /* List of parent clocks for Muxes in CMU_FSYS0 */ | ||
| 800 | PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" }; | ||
| 801 | PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" }; | ||
| 802 | PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" }; | ||
| 803 | |||
| 804 | static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = { | ||
| 805 | MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p, | ||
| 806 | PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1), | ||
| 807 | MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p, | ||
| 808 | PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1), | ||
| 809 | MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p, | ||
| 810 | PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1), | ||
| 811 | }; | ||
| 812 | |||
| 813 | static const struct samsung_div_clock fsys0_div_clks[] __initconst = { | ||
| 814 | DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4), | ||
| 815 | DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 816 | DIV_EQS_RGMII_CLK_125, 0, 4), | ||
| 817 | DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp", | ||
| 818 | "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4), | ||
| 819 | DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4), | ||
| 820 | DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 821 | DIV_EQOS_RMIICLK_25, 0, 5), | ||
| 822 | DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 823 | DIV_PCIE_PHY_OSCCLK, 0, 4), | ||
| 824 | }; | ||
| 825 | |||
| 826 | static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = { | ||
| 827 | GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i", | ||
| 828 | "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21, | ||
| 829 | CLK_IGNORE_UNUSED, 0), | ||
| 830 | GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC, | ||
| 831 | "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll", | ||
| 832 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21, | ||
| 833 | CLK_IGNORE_UNUSED, 0), | ||
| 834 | GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp", | ||
| 835 | GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 836 | GATE(0, | ||
| 837 | "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo", | ||
| 838 | "xtal_clk_pcie_phy", | ||
| 839 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21, | ||
| 840 | CLK_IGNORE_UNUSED, 0), | ||
| 841 | GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24", | ||
| 842 | "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21, | ||
| 843 | CLK_IGNORE_UNUSED, 0), | ||
| 844 | GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26", | ||
| 845 | "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21, | ||
| 846 | CLK_IGNORE_UNUSED, 0), | ||
| 847 | GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24", | ||
| 848 | "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21, | ||
| 849 | CLK_IGNORE_UNUSED, 0), | ||
| 850 | GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26", | ||
| 851 | "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21, | ||
| 852 | CLK_IGNORE_UNUSED, 0), | ||
| 853 | GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp", | ||
| 854 | GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 855 | GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp", | ||
| 856 | GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 857 | GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 858 | GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 859 | GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp", | ||
| 860 | GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 861 | GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp", | ||
| 862 | GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 863 | GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 864 | GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 865 | GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 866 | GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 867 | GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i", | ||
| 868 | "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21, | ||
| 869 | CLK_IGNORE_UNUSED, 0), | ||
| 870 | GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i", | ||
| 871 | "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21, | ||
| 872 | CLK_IGNORE_UNUSED, 0), | ||
| 873 | GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i", | ||
| 874 | "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21, | ||
| 875 | CLK_IGNORE_UNUSED, 0), | ||
| 876 | GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5", | ||
| 877 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 878 | GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25", | ||
| 879 | GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 880 | GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp", | ||
| 881 | GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 882 | GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll", | ||
| 883 | GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 884 | GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d", | ||
| 885 | "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 886 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21, | ||
| 887 | CLK_IGNORE_UNUSED, 0), | ||
| 888 | GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1", | ||
| 889 | "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 890 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21, | ||
| 891 | CLK_IGNORE_UNUSED, 0), | ||
| 892 | GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p", | ||
| 893 | "dout_fsys0_peribus_grp", | ||
| 894 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21, | ||
| 895 | CLK_IGNORE_UNUSED, 0), | ||
| 896 | GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s", | ||
| 897 | "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 898 | GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21, | ||
| 899 | CLK_IGNORE_UNUSED, 0), | ||
| 900 | GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk", | ||
| 901 | "dout_fsys0_peribus_grp", | ||
| 902 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21, | ||
| 903 | CLK_IGNORE_UNUSED, 0), | ||
| 904 | GATE(0, | ||
| 905 | "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll", | ||
| 906 | "dout_fsys0_pcie_phy_oscclk", | ||
| 907 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL, | ||
| 908 | 21, CLK_IGNORE_UNUSED, 0), | ||
| 909 | GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp", | ||
| 910 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0), | ||
| 911 | GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll", | ||
| 912 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 913 | GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC, | ||
| 914 | "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc", | ||
| 915 | "dout_fsys0_peribus_grp", | ||
| 916 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21, | ||
| 917 | CLK_IGNORE_UNUSED, 0), | ||
| 918 | GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk", | ||
| 919 | "dout_fsys0_peribus_grp", | ||
| 920 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21, | ||
| 921 | CLK_IGNORE_UNUSED, 0), | ||
| 922 | GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC, | ||
| 923 | "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc", | ||
| 924 | "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 925 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21, | ||
| 926 | CLK_IGNORE_UNUSED, 0), | ||
| 927 | GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC, | ||
| 928 | "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc", | ||
| 929 | "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 930 | GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21, | ||
| 931 | CLK_IGNORE_UNUSED, 0), | ||
| 932 | GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1", | ||
| 933 | GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 934 | GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk", | ||
| 935 | GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 936 | GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp", | ||
| 937 | GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 938 | GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp", | ||
| 939 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 940 | GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp", | ||
| 941 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 942 | GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro", | ||
| 943 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0), | ||
| 944 | GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp", | ||
| 945 | GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 946 | GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp", | ||
| 947 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 948 | GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp", | ||
| 949 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 950 | GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro", | ||
| 951 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0), | ||
| 952 | GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp", | ||
| 953 | GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 954 | GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE, | ||
| 955 | 21, CLK_IGNORE_UNUSED, 0), | ||
| 956 | GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i", | ||
| 957 | "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0), | ||
| 958 | }; | ||
| 959 | |||
| 960 | static const struct samsung_cmu_info fsys0_cmu_info __initconst = { | ||
| 961 | .mux_clks = fsys0_mux_clks, | ||
| 962 | .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), | ||
| 963 | .div_clks = fsys0_div_clks, | ||
| 964 | .nr_div_clks = ARRAY_SIZE(fsys0_div_clks), | ||
| 965 | .gate_clks = fsys0_gate_clks, | ||
| 966 | .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), | ||
| 967 | .fixed_clks = fsys0_fixed_clks, | ||
| 968 | .nr_fixed_clks = ARRAY_SIZE(fsys0_fixed_clks), | ||
| 969 | .nr_clk_ids = FSYS0_NR_CLK, | ||
| 970 | .clk_regs = fsys0_clk_regs, | ||
| 971 | .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), | ||
| 972 | .clk_name = "dout_cmu_fsys0_shared1div4", | ||
| 973 | }; | ||
| 974 | |||
| 975 | /* Register Offset definitions for CMU_FSYS1 (0x16810000) */ | ||
| 976 | #define PLL_CON0_ACLK_FSYS1_BUSP_MUX 0x100 | ||
| 977 | #define PLL_CON0_PCLKL_FSYS1_BUSP_MUX 0x180 | ||
| 978 | #define DIV_CLK_FSYS1_PHY0_OSCCLK 0x1800 | ||
| 979 | #define DIV_CLK_FSYS1_PHY1_OSCCLK 0x1804 | ||
| 980 | #define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK 0x2000 | ||
| 981 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK 0x2004 | ||
| 982 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK 0x2008 | ||
| 983 | #define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK 0x200c | ||
| 984 | #define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL 0x202c | ||
| 985 | #define GAT_FSYS1_PHY0_OSCCLLK 0x2034 | ||
| 986 | #define GAT_FSYS1_PHY1_OSCCLK 0x2038 | ||
| 987 | #define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK 0x203c | ||
| 988 | #define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK 0x2040 | ||
| 989 | #define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK 0x2048 | ||
| 990 | #define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK 0x204c | ||
| 991 | #define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK 0x2054 | ||
| 992 | #define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0 0x205c | ||
| 993 | #define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0 0x2064 | ||
| 994 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK 0x206c | ||
| 995 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK 0x2070 | ||
| 996 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK 0x2074 | ||
| 997 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK 0x2078 | ||
| 998 | #define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK 0x207c | ||
| 999 | #define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK 0x2080 | ||
| 1000 | #define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK 0x2084 | ||
| 1001 | #define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK 0x2088 | ||
| 1002 | #define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK 0x208c | ||
| 1003 | #define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK 0x20a4 | ||
| 1004 | #define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL 0x20a8 | ||
| 1005 | #define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK 0x20b4 | ||
| 1006 | #define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK 0x20b8 | ||
| 1007 | |||
| 1008 | static const unsigned long fsys1_clk_regs[] __initconst = { | ||
| 1009 | PLL_CON0_ACLK_FSYS1_BUSP_MUX, | ||
| 1010 | PLL_CON0_PCLKL_FSYS1_BUSP_MUX, | ||
| 1011 | DIV_CLK_FSYS1_PHY0_OSCCLK, | ||
| 1012 | DIV_CLK_FSYS1_PHY1_OSCCLK, | ||
| 1013 | GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, | ||
| 1014 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, | ||
| 1015 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, | ||
| 1016 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, | ||
| 1017 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, | ||
| 1018 | GAT_FSYS1_PHY0_OSCCLLK, | ||
| 1019 | GAT_FSYS1_PHY1_OSCCLK, | ||
| 1020 | GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, | ||
| 1021 | GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, | ||
| 1022 | GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, | ||
| 1023 | GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, | ||
| 1024 | GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, | ||
| 1025 | GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, | ||
| 1026 | GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, | ||
| 1027 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, | ||
| 1028 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, | ||
| 1029 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, | ||
| 1030 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, | ||
| 1031 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, | ||
| 1032 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, | ||
| 1033 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, | ||
| 1034 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, | ||
| 1035 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, | ||
| 1036 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, | ||
| 1037 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, | ||
| 1038 | GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, | ||
| 1039 | GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, | ||
| 1040 | }; | ||
| 1041 | |||
| 1042 | static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = { | ||
| 1043 | FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000), | ||
| 1044 | FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000), | ||
| 1045 | }; | ||
| 1046 | |||
| 1047 | /* List of parent clocks for Muxes in CMU_FSYS1 */ | ||
| 1048 | PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" }; | ||
| 1049 | PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" }; | ||
| 1050 | |||
| 1051 | static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = { | ||
| 1052 | MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p, | ||
| 1053 | PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1), | ||
| 1054 | MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p, | ||
| 1055 | PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1), | ||
| 1056 | }; | ||
| 1057 | |||
| 1058 | static const struct samsung_div_clock fsys1_div_clks[] __initconst = { | ||
| 1059 | DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk", | ||
| 1060 | DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4), | ||
| 1061 | DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk", | ||
| 1062 | DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4), | ||
| 1063 | }; | ||
| 1064 | |||
| 1065 | static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = { | ||
| 1066 | GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1067 | GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1068 | GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref", | ||
| 1069 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1070 | GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1071 | GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1072 | GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1073 | GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1074 | GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1075 | GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1076 | GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1077 | GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1078 | GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1079 | GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1080 | GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1081 | GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1082 | GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1083 | GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1084 | GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0", | ||
| 1085 | "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1086 | GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21, | ||
| 1087 | CLK_IGNORE_UNUSED, 0), | ||
| 1088 | GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0", | ||
| 1089 | "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1090 | GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21, | ||
| 1091 | CLK_IGNORE_UNUSED, 0), | ||
| 1092 | GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk", | ||
| 1093 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21, | ||
| 1094 | CLK_IGNORE_UNUSED, 0), | ||
| 1095 | GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1096 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1097 | GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll", | ||
| 1098 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1099 | GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1100 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1101 | GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk", | ||
| 1102 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21, | ||
| 1103 | CLK_IGNORE_UNUSED, 0), | ||
| 1104 | GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk", | ||
| 1105 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21, | ||
| 1106 | CLK_IGNORE_UNUSED, 0), | ||
| 1107 | GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk", | ||
| 1108 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21, | ||
| 1109 | CLK_IGNORE_UNUSED, 0), | ||
| 1110 | GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1111 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1112 | GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk", | ||
| 1113 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21, | ||
| 1114 | CLK_IGNORE_UNUSED, 0), | ||
| 1115 | GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk", | ||
| 1116 | "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21, | ||
| 1117 | CLK_IGNORE_UNUSED, 0), | ||
| 1118 | GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1119 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1120 | GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll", | ||
| 1121 | GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1122 | GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll", | ||
| 1123 | GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1124 | GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk", | ||
| 1125 | GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1126 | GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux", | ||
| 1127 | GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1128 | GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux", | ||
| 1129 | GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1130 | }; | ||
| 1131 | |||
| 1132 | static const struct samsung_cmu_info fsys1_cmu_info __initconst = { | ||
| 1133 | .mux_clks = fsys1_mux_clks, | ||
| 1134 | .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), | ||
| 1135 | .div_clks = fsys1_div_clks, | ||
| 1136 | .nr_div_clks = ARRAY_SIZE(fsys1_div_clks), | ||
| 1137 | .gate_clks = fsys1_gate_clks, | ||
| 1138 | .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), | ||
| 1139 | .fixed_clks = fsys1_fixed_clks, | ||
| 1140 | .nr_fixed_clks = ARRAY_SIZE(fsys1_fixed_clks), | ||
| 1141 | .nr_clk_ids = FSYS1_NR_CLK, | ||
| 1142 | .clk_regs = fsys1_clk_regs, | ||
| 1143 | .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), | ||
| 1144 | .clk_name = "dout_cmu_fsys1_shared0div4", | ||
| 1145 | }; | ||
| 1146 | |||
| 1147 | /* Register Offset definitions for CMU_IMEM (0x10010000) */ | ||
| 1148 | #define PLL_CON0_CLK_IMEM_ACLK 0x100 | ||
| 1149 | #define PLL_CON0_CLK_IMEM_INTMEMCLK 0x120 | ||
| 1150 | #define PLL_CON0_CLK_IMEM_TCUCLK 0x140 | ||
| 1151 | #define DIV_OSCCLK_IMEM_TMUTSCLK 0x1800 | ||
| 1152 | #define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK 0x2000 | ||
| 1153 | #define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO 0x2004 | ||
| 1154 | #define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK 0x2008 | ||
| 1155 | #define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK 0x200c | ||
| 1156 | #define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK 0x2010 | ||
| 1157 | #define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS 0x2014 | ||
| 1158 | #define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK 0x2018 | ||
| 1159 | #define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS 0x201c | ||
| 1160 | #define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK 0x2020 | ||
| 1161 | #define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS 0x2024 | ||
| 1162 | #define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK 0x2028 | ||
| 1163 | #define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS 0x202c | ||
| 1164 | #define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK 0x2030 | ||
| 1165 | #define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS 0x2034 | ||
| 1166 | #define GAT_IMEM_WDT0_IPCLKPORT_CLK 0x2038 | ||
| 1167 | #define GAT_IMEM_WDT1_IPCLKPORT_CLK 0x203c | ||
| 1168 | #define GAT_IMEM_WDT2_IPCLKPORT_CLK 0x2040 | ||
| 1169 | #define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM 0x2044 | ||
| 1170 | #define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM 0x2048 | ||
| 1171 | #define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM 0x204c | ||
| 1172 | #define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS 0x2050 | ||
| 1173 | #define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS 0x2054 | ||
| 1174 | #define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS 0x2058 | ||
| 1175 | #define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM 0x205c | ||
| 1176 | #define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS 0x2060 | ||
| 1177 | #define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM 0x2064 | ||
| 1178 | #define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS 0x2068 | ||
| 1179 | #define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK 0x206c | ||
| 1180 | #define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK 0x2070 | ||
| 1181 | #define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK 0x2074 | ||
| 1182 | #define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK 0x2078 | ||
| 1183 | #define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK 0x207c | ||
| 1184 | #define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK 0x2080 | ||
| 1185 | #define GAT_IMEM_DMA0_IPCLKPORT_ACLK 0x2084 | ||
| 1186 | #define GAT_IMEM_DMA1_IPCLKPORT_ACLK 0x2088 | ||
| 1187 | #define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK 0x208c | ||
| 1188 | #define GAT_IMEM_GIC_IPCLKPORT_CLK 0x2090 | ||
| 1189 | #define GAT_IMEM_INTMEM_IPCLKPORT_ACLK 0x2094 | ||
| 1190 | #define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK 0x2098 | ||
| 1191 | #define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK 0x209c | ||
| 1192 | #define GAT_IMEM_MCT_IPCLKPORT_PCLK 0x20a0 | ||
| 1193 | #define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D 0x20a4 | ||
| 1194 | #define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU 0x20a8 | ||
| 1195 | #define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P 0x20ac | ||
| 1196 | #define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK 0x20b0 | ||
| 1197 | #define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK 0x20b4 | ||
| 1198 | #define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK 0x20b8 | ||
| 1199 | #define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK 0x20bc | ||
| 1200 | #define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK 0x20c0 | ||
| 1201 | #define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK 0x20c4 | ||
| 1202 | #define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK 0x20c8 | ||
| 1203 | #define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK 0x20cc | ||
| 1204 | #define GAT_IMEM_TCU_IPCLKPORT_ACLK 0x20d0 | ||
| 1205 | #define GAT_IMEM_WDT0_IPCLKPORT_PCLK 0x20d4 | ||
| 1206 | #define GAT_IMEM_WDT1_IPCLKPORT_PCLK 0x20d8 | ||
| 1207 | #define GAT_IMEM_WDT2_IPCLKPORT_PCLK 0x20dc | ||
| 1208 | |||
| 1209 | static const unsigned long imem_clk_regs[] __initconst = { | ||
| 1210 | PLL_CON0_CLK_IMEM_ACLK, | ||
| 1211 | PLL_CON0_CLK_IMEM_INTMEMCLK, | ||
| 1212 | PLL_CON0_CLK_IMEM_TCUCLK, | ||
| 1213 | DIV_OSCCLK_IMEM_TMUTSCLK, | ||
| 1214 | GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, | ||
| 1215 | GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, | ||
| 1216 | GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, | ||
| 1217 | GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, | ||
| 1218 | GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, | ||
| 1219 | GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, | ||
| 1220 | GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, | ||
| 1221 | GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, | ||
| 1222 | GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, | ||
| 1223 | GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, | ||
| 1224 | GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, | ||
| 1225 | GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, | ||
| 1226 | GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, | ||
| 1227 | GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, | ||
| 1228 | GAT_IMEM_WDT0_IPCLKPORT_CLK, | ||
| 1229 | GAT_IMEM_WDT1_IPCLKPORT_CLK, | ||
| 1230 | GAT_IMEM_WDT2_IPCLKPORT_CLK, | ||
| 1231 | GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, | ||
| 1232 | GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, | ||
| 1233 | GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, | ||
| 1234 | GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, | ||
| 1235 | GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, | ||
| 1236 | GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, | ||
| 1237 | GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, | ||
| 1238 | GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, | ||
| 1239 | GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, | ||
| 1240 | GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, | ||
| 1241 | GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, | ||
| 1242 | GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, | ||
| 1243 | GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, | ||
| 1244 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, | ||
| 1245 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, | ||
| 1246 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, | ||
| 1247 | GAT_IMEM_DMA0_IPCLKPORT_ACLK, | ||
| 1248 | GAT_IMEM_DMA1_IPCLKPORT_ACLK, | ||
| 1249 | GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, | ||
| 1250 | GAT_IMEM_GIC_IPCLKPORT_CLK, | ||
| 1251 | GAT_IMEM_INTMEM_IPCLKPORT_ACLK, | ||
| 1252 | GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, | ||
| 1253 | GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, | ||
| 1254 | GAT_IMEM_MCT_IPCLKPORT_PCLK, | ||
| 1255 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, | ||
| 1256 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, | ||
| 1257 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, | ||
| 1258 | GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, | ||
| 1259 | GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, | ||
| 1260 | GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, | ||
| 1261 | GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, | ||
| 1262 | GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, | ||
| 1263 | GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, | ||
| 1264 | GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, | ||
| 1265 | GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, | ||
| 1266 | GAT_IMEM_TCU_IPCLKPORT_ACLK, | ||
| 1267 | GAT_IMEM_WDT0_IPCLKPORT_PCLK, | ||
| 1268 | GAT_IMEM_WDT1_IPCLKPORT_PCLK, | ||
| 1269 | GAT_IMEM_WDT2_IPCLKPORT_PCLK, | ||
| 1270 | }; | ||
| 1271 | |||
| 1272 | PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" }; | ||
| 1273 | PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" }; | ||
| 1274 | PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" }; | ||
| 1275 | |||
| 1276 | static const struct samsung_mux_clock imem_mux_clks[] __initconst = { | ||
| 1277 | MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p, | ||
| 1278 | PLL_CON0_CLK_IMEM_TCUCLK, 4, 1), | ||
| 1279 | MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1), | ||
| 1280 | MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p, | ||
| 1281 | PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1), | ||
| 1282 | }; | ||
| 1283 | |||
| 1284 | static const struct samsung_div_clock imem_div_clks[] __initconst = { | ||
| 1285 | DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4), | ||
| 1286 | }; | ||
| 1287 | |||
| 1288 | static const struct samsung_gate_clock imem_gate_clks[] __initconst = { | ||
| 1289 | GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1290 | GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1291 | GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll", | ||
| 1292 | GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1293 | GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll", | ||
| 1294 | GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1295 | GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll", | ||
| 1296 | GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1297 | GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll", | ||
| 1298 | GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1299 | GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll", | ||
| 1300 | GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1301 | GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll", | ||
| 1302 | GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1303 | GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll", | ||
| 1304 | GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1305 | GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll", | ||
| 1306 | GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1307 | GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll", | ||
| 1308 | GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1309 | GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts", | ||
| 1310 | "dout_imem_oscclk_imem_tmutsclk", | ||
| 1311 | GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1312 | GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts", | ||
| 1313 | "dout_imem_oscclk_imem_tmutsclk", | ||
| 1314 | GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1315 | GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts", | ||
| 1316 | "dout_imem_oscclk_imem_tmutsclk", | ||
| 1317 | GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1318 | GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts", | ||
| 1319 | "dout_imem_oscclk_imem_tmutsclk", | ||
| 1320 | GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1321 | GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts", | ||
| 1322 | "dout_imem_oscclk_imem_tmutsclk", | ||
| 1323 | GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1324 | GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk", | ||
| 1325 | GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1326 | GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk", | ||
| 1327 | GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1328 | GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk", | ||
| 1329 | GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1330 | GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk", | ||
| 1331 | GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1332 | GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk", | ||
| 1333 | GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1334 | GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk", | ||
| 1335 | GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1336 | GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk", | ||
| 1337 | GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1338 | GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk", | ||
| 1339 | GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1340 | GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk", | ||
| 1341 | GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1342 | GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk", | ||
| 1343 | GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1344 | GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk", | ||
| 1345 | GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1346 | GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk", | ||
| 1347 | GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1348 | GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk", | ||
| 1349 | GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1350 | GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk", | ||
| 1351 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1352 | GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk", | ||
| 1353 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1354 | GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk", | ||
| 1355 | GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1356 | GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk", | ||
| 1357 | GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0), | ||
| 1358 | GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk", | ||
| 1359 | GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0), | ||
| 1360 | GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk", | ||
| 1361 | GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1362 | GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk", | ||
| 1363 | GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1364 | GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk", | ||
| 1365 | GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1366 | GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1367 | GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1368 | GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1369 | GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1370 | GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1371 | GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1372 | GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d", | ||
| 1373 | "mout_imem_clk_imem_tcuclk", | ||
| 1374 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1375 | GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu", | ||
| 1376 | "mout_imem_clk_imem_tcuclk", | ||
| 1377 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21, | ||
| 1378 | CLK_IGNORE_UNUSED, 0), | ||
| 1379 | GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk", | ||
| 1380 | GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1381 | GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1382 | GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1383 | GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk", | ||
| 1384 | GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1385 | GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll", | ||
| 1386 | GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1387 | GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk", | ||
| 1388 | GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1389 | GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk", | ||
| 1390 | GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1391 | GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1392 | GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1393 | GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1394 | GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1395 | GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll", | ||
| 1396 | GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1397 | GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1398 | GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1399 | GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk", | ||
| 1400 | GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1401 | GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk", | ||
| 1402 | GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1403 | GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1404 | GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1405 | GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1406 | GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1407 | GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk", | ||
| 1408 | GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1409 | }; | ||
| 1410 | |||
| 1411 | static const struct samsung_cmu_info imem_cmu_info __initconst = { | ||
| 1412 | .mux_clks = imem_mux_clks, | ||
| 1413 | .nr_mux_clks = ARRAY_SIZE(imem_mux_clks), | ||
| 1414 | .div_clks = imem_div_clks, | ||
| 1415 | .nr_div_clks = ARRAY_SIZE(imem_div_clks), | ||
| 1416 | .gate_clks = imem_gate_clks, | ||
| 1417 | .nr_gate_clks = ARRAY_SIZE(imem_gate_clks), | ||
| 1418 | .nr_clk_ids = IMEM_NR_CLK, | ||
| 1419 | .clk_regs = imem_clk_regs, | ||
| 1420 | .nr_clk_regs = ARRAY_SIZE(imem_clk_regs), | ||
| 1421 | }; | ||
| 1422 | |||
| 1423 | static void __init fsd_clk_imem_init(struct device_node *np) | ||
| 1424 | { | ||
| 1425 | samsung_cmu_register_one(np, &imem_cmu_info); | ||
| 1426 | } | ||
| 1427 | |||
| 1428 | CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init); | ||
| 1429 | |||
| 1430 | /* Register Offset definitions for CMU_MFC (0x12810000) */ | ||
| 1431 | #define PLL_LOCKTIME_PLL_MFC 0x0 | ||
| 1432 | #define PLL_CON0_PLL_MFC 0x100 | ||
| 1433 | #define MUX_MFC_BUSD 0x1000 | ||
| 1434 | #define MUX_MFC_BUSP 0x1008 | ||
| 1435 | #define DIV_MFC_BUSD_DIV4 0x1800 | ||
| 1436 | #define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK 0x2000 | ||
| 1437 | #define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM 0x2004 | ||
| 1438 | #define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS 0x2008 | ||
| 1439 | #define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK 0x200c | ||
| 1440 | #define GAT_MFC_MFC_IPCLKPORT_ACLK 0x2010 | ||
| 1441 | #define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D 0x2018 | ||
| 1442 | #define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P 0x201c | ||
| 1443 | #define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK 0x2028 | ||
| 1444 | #define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK 0x202c | ||
| 1445 | #define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK 0x2030 | ||
| 1446 | #define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK 0x2034 | ||
| 1447 | #define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK 0x2038 | ||
| 1448 | #define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK 0x203c | ||
| 1449 | #define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK 0x2040 | ||
| 1450 | #define GAT_MFC_BUSD_DIV4_GATE 0x2044 | ||
| 1451 | #define GAT_MFC_BUSD_GATE 0x2048 | ||
| 1452 | |||
| 1453 | static const unsigned long mfc_clk_regs[] __initconst = { | ||
| 1454 | PLL_LOCKTIME_PLL_MFC, | ||
| 1455 | PLL_CON0_PLL_MFC, | ||
| 1456 | MUX_MFC_BUSD, | ||
| 1457 | MUX_MFC_BUSP, | ||
| 1458 | DIV_MFC_BUSD_DIV4, | ||
| 1459 | GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, | ||
| 1460 | GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, | ||
| 1461 | GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, | ||
| 1462 | GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, | ||
| 1463 | GAT_MFC_MFC_IPCLKPORT_ACLK, | ||
| 1464 | GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, | ||
| 1465 | GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, | ||
| 1466 | GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, | ||
| 1467 | GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, | ||
| 1468 | GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, | ||
| 1469 | GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, | ||
| 1470 | GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, | ||
| 1471 | GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, | ||
| 1472 | GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, | ||
| 1473 | GAT_MFC_BUSD_DIV4_GATE, | ||
| 1474 | GAT_MFC_BUSD_GATE, | ||
| 1475 | }; | ||
| 1476 | |||
| 1477 | static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = { | ||
| 1478 | PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0), | ||
| 1479 | }; | ||
| 1480 | |||
| 1481 | static const struct samsung_pll_clock mfc_pll_clks[] __initconst = { | ||
| 1482 | PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll", | ||
| 1483 | PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table), | ||
| 1484 | }; | ||
| 1485 | |||
| 1486 | PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" }; | ||
| 1487 | PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" }; | ||
| 1488 | PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" }; | ||
| 1489 | |||
| 1490 | static const struct samsung_mux_clock mfc_mux_clks[] __initconst = { | ||
| 1491 | MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1), | ||
| 1492 | MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1), | ||
| 1493 | MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1), | ||
| 1494 | }; | ||
| 1495 | |||
| 1496 | static const struct samsung_div_clock mfc_div_clks[] __initconst = { | ||
| 1497 | DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4), | ||
| 1498 | }; | ||
| 1499 | |||
| 1500 | static const struct samsung_gate_clock mfc_gate_clks[] __initconst = { | ||
| 1501 | GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp", | ||
| 1502 | GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1503 | GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd", | ||
| 1504 | GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1505 | GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp", | ||
| 1506 | GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1507 | GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp", | ||
| 1508 | GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1509 | GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd", | ||
| 1510 | GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1511 | GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd", | ||
| 1512 | GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1513 | GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp", | ||
| 1514 | GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1515 | GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd", | ||
| 1516 | GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1517 | GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp", | ||
| 1518 | GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1519 | GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd", | ||
| 1520 | GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1521 | GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp", | ||
| 1522 | GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1523 | GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp", | ||
| 1524 | GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1525 | GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd", | ||
| 1526 | GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1527 | GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd", | ||
| 1528 | GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1529 | GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll", | ||
| 1530 | GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1531 | GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0), | ||
| 1532 | }; | ||
| 1533 | |||
| 1534 | static const struct samsung_cmu_info mfc_cmu_info __initconst = { | ||
| 1535 | .pll_clks = mfc_pll_clks, | ||
| 1536 | .nr_pll_clks = ARRAY_SIZE(mfc_pll_clks), | ||
| 1537 | .mux_clks = mfc_mux_clks, | ||
| 1538 | .nr_mux_clks = ARRAY_SIZE(mfc_mux_clks), | ||
| 1539 | .div_clks = mfc_div_clks, | ||
| 1540 | .nr_div_clks = ARRAY_SIZE(mfc_div_clks), | ||
| 1541 | .gate_clks = mfc_gate_clks, | ||
| 1542 | .nr_gate_clks = ARRAY_SIZE(mfc_gate_clks), | ||
| 1543 | .nr_clk_ids = MFC_NR_CLK, | ||
| 1544 | .clk_regs = mfc_clk_regs, | ||
| 1545 | .nr_clk_regs = ARRAY_SIZE(mfc_clk_regs), | ||
| 1546 | }; | ||
| 1547 | |||
| 1548 | /* Register Offset definitions for CMU_CAM_CSI (0x12610000) */ | ||
| 1549 | #define PLL_LOCKTIME_PLL_CAM_CSI 0x0 | ||
| 1550 | #define PLL_CON0_PLL_CAM_CSI 0x100 | ||
| 1551 | #define DIV_CAM_CSI0_ACLK 0x1800 | ||
| 1552 | #define DIV_CAM_CSI1_ACLK 0x1804 | ||
| 1553 | #define DIV_CAM_CSI2_ACLK 0x1808 | ||
| 1554 | #define DIV_CAM_CSI_BUSD 0x180c | ||
| 1555 | #define DIV_CAM_CSI_BUSP 0x1810 | ||
| 1556 | #define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK 0x2000 | ||
| 1557 | #define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK 0x2004 | ||
| 1558 | #define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0 0x2008 | ||
| 1559 | #define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1 0x200c | ||
| 1560 | #define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2 0x2010 | ||
| 1561 | #define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC 0x2014 | ||
| 1562 | #define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC 0x2018 | ||
| 1563 | #define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK 0x201c | ||
| 1564 | #define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK 0x2020 | ||
| 1565 | #define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK 0x2024 | ||
| 1566 | #define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK 0x2028 | ||
| 1567 | #define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK 0x202c | ||
| 1568 | #define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK 0x2030 | ||
| 1569 | #define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK 0x2034 | ||
| 1570 | #define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK 0x2038 | ||
| 1571 | #define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK 0x203c | ||
| 1572 | #define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK 0x2040 | ||
| 1573 | #define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK 0x2044 | ||
| 1574 | #define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK 0x2048 | ||
| 1575 | #define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK 0x204c | ||
| 1576 | #define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK 0x2050 | ||
| 1577 | #define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK 0x2054 | ||
| 1578 | #define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK 0x2058 | ||
| 1579 | #define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK 0x205c | ||
| 1580 | #define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK 0x2060 | ||
| 1581 | #define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK 0x2064 | ||
| 1582 | #define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK 0x2068 | ||
| 1583 | #define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK 0x206c | ||
| 1584 | #define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK 0x2070 | ||
| 1585 | #define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK 0x2074 | ||
| 1586 | #define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK 0x2078 | ||
| 1587 | #define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D 0x207c | ||
| 1588 | #define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P 0x2080 | ||
| 1589 | #define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK 0x2084 | ||
| 1590 | #define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK 0x2088 | ||
| 1591 | |||
| 1592 | static const unsigned long cam_csi_clk_regs[] __initconst = { | ||
| 1593 | PLL_LOCKTIME_PLL_CAM_CSI, | ||
| 1594 | PLL_CON0_PLL_CAM_CSI, | ||
| 1595 | DIV_CAM_CSI0_ACLK, | ||
| 1596 | DIV_CAM_CSI1_ACLK, | ||
| 1597 | DIV_CAM_CSI2_ACLK, | ||
| 1598 | DIV_CAM_CSI_BUSD, | ||
| 1599 | DIV_CAM_CSI_BUSP, | ||
| 1600 | GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, | ||
| 1601 | GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, | ||
| 1602 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, | ||
| 1603 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, | ||
| 1604 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, | ||
| 1605 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, | ||
| 1606 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, | ||
| 1607 | GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, | ||
| 1608 | GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, | ||
| 1609 | GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, | ||
| 1610 | GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, | ||
| 1611 | GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, | ||
| 1612 | GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, | ||
| 1613 | GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, | ||
| 1614 | GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, | ||
| 1615 | GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, | ||
| 1616 | GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, | ||
| 1617 | GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, | ||
| 1618 | GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, | ||
| 1619 | GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, | ||
| 1620 | GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, | ||
| 1621 | GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, | ||
| 1622 | GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, | ||
| 1623 | GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, | ||
| 1624 | GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, | ||
| 1625 | GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, | ||
| 1626 | GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, | ||
| 1627 | GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, | ||
| 1628 | GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, | ||
| 1629 | GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, | ||
| 1630 | GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, | ||
| 1631 | GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, | ||
| 1632 | GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, | ||
| 1633 | GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, | ||
| 1634 | GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, | ||
| 1635 | }; | ||
| 1636 | |||
| 1637 | static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = { | ||
| 1638 | PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0), | ||
| 1639 | }; | ||
| 1640 | |||
| 1641 | static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = { | ||
| 1642 | PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll", | ||
| 1643 | PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table), | ||
| 1644 | }; | ||
| 1645 | |||
| 1646 | PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" }; | ||
| 1647 | |||
| 1648 | static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = { | ||
| 1649 | MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1), | ||
| 1650 | }; | ||
| 1651 | |||
| 1652 | static const struct samsung_div_clock cam_csi_div_clks[] __initconst = { | ||
| 1653 | DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4), | ||
| 1654 | DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4), | ||
| 1655 | DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4), | ||
| 1656 | DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4), | ||
| 1657 | DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4), | ||
| 1658 | }; | ||
| 1659 | |||
| 1660 | static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = { | ||
| 1661 | GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp", | ||
| 1662 | GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1663 | GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp", | ||
| 1664 | GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1665 | GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk", | ||
| 1666 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1667 | GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk", | ||
| 1668 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1669 | GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk", | ||
| 1670 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1671 | GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd", | ||
| 1672 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21, | ||
| 1673 | CLK_IGNORE_UNUSED, 0), | ||
| 1674 | GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd", | ||
| 1675 | GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1676 | GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk", | ||
| 1677 | GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1678 | GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1679 | GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1680 | GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk", | ||
| 1681 | GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1682 | GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1683 | GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1684 | GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk", | ||
| 1685 | GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1686 | GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1687 | GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1688 | GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk", | ||
| 1689 | GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1690 | GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1691 | GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1692 | GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk", | ||
| 1693 | GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1694 | GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1695 | GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1696 | GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk", | ||
| 1697 | GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1698 | GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1699 | GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1700 | GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk", | ||
| 1701 | GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1702 | GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1703 | GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1704 | GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk", | ||
| 1705 | GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1706 | GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1707 | GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1708 | GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk", | ||
| 1709 | GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1710 | GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1711 | GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1712 | GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk", | ||
| 1713 | GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1714 | GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1715 | GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1716 | GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk", | ||
| 1717 | GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1718 | GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1719 | GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1720 | GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk", | ||
| 1721 | GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1722 | GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp", | ||
| 1723 | GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1724 | GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d", | ||
| 1725 | "dout_cam_csi_busd", | ||
| 1726 | GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21, | ||
| 1727 | CLK_IGNORE_UNUSED, 0), | ||
| 1728 | GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p", | ||
| 1729 | "dout_cam_csi_busp", | ||
| 1730 | GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21, | ||
| 1731 | CLK_IGNORE_UNUSED, 0), | ||
| 1732 | GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp", | ||
| 1733 | GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1734 | GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd", | ||
| 1735 | GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0), | ||
| 1736 | }; | ||
| 1737 | |||
| 1738 | static const struct samsung_cmu_info cam_csi_cmu_info __initconst = { | ||
| 1739 | .pll_clks = cam_csi_pll_clks, | ||
| 1740 | .nr_pll_clks = ARRAY_SIZE(cam_csi_pll_clks), | ||
| 1741 | .mux_clks = cam_csi_mux_clks, | ||
| 1742 | .nr_mux_clks = ARRAY_SIZE(cam_csi_mux_clks), | ||
| 1743 | .div_clks = cam_csi_div_clks, | ||
| 1744 | .nr_div_clks = ARRAY_SIZE(cam_csi_div_clks), | ||
| 1745 | .gate_clks = cam_csi_gate_clks, | ||
| 1746 | .nr_gate_clks = ARRAY_SIZE(cam_csi_gate_clks), | ||
| 1747 | .nr_clk_ids = CAM_CSI_NR_CLK, | ||
| 1748 | .clk_regs = cam_csi_clk_regs, | ||
| 1749 | .nr_clk_regs = ARRAY_SIZE(cam_csi_clk_regs), | ||
| 1750 | }; | ||
| 1751 | |||
| 1752 | /** | ||
| 1753 | * fsd_cmu_probe - Probe function for FSD platform clocks | ||
| 1754 | * @pdev: Pointer to platform device | ||
| 1755 | * | ||
| 1756 | * Configure clock hierarchy for clock domains of FSD platform | ||
| 1757 | */ | ||
| 1758 | static int __init fsd_cmu_probe(struct platform_device *pdev) | ||
| 1759 | { | ||
| 1760 | const struct samsung_cmu_info *info; | ||
| 1761 | struct device *dev = &pdev->dev; | ||
| 1762 | |||
| 1763 | info = of_device_get_match_data(dev); | ||
| 1764 | exynos_arm64_register_cmu(dev, dev->of_node, info); | ||
| 1765 | |||
| 1766 | return 0; | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | /* CMUs which belong to Power Domains and need runtime PM to be implemented */ | ||
| 1770 | static const struct of_device_id fsd_cmu_of_match[] = { | ||
| 1771 | { | ||
| 1772 | .compatible = "tesla,fsd-clock-peric", | ||
| 1773 | .data = &peric_cmu_info, | ||
| 1774 | }, { | ||
| 1775 | .compatible = "tesla,fsd-clock-fsys0", | ||
| 1776 | .data = &fsys0_cmu_info, | ||
| 1777 | }, { | ||
| 1778 | .compatible = "tesla,fsd-clock-fsys1", | ||
| 1779 | .data = &fsys1_cmu_info, | ||
| 1780 | }, { | ||
| 1781 | .compatible = "tesla,fsd-clock-mfc", | ||
| 1782 | .data = &mfc_cmu_info, | ||
| 1783 | }, { | ||
| 1784 | .compatible = "tesla,fsd-clock-cam_csi", | ||
| 1785 | .data = &cam_csi_cmu_info, | ||
| 1786 | }, { | ||
| 1787 | }, | ||
| 1788 | }; | ||
| 1789 | |||
| 1790 | static struct platform_driver fsd_cmu_driver __refdata = { | ||
| 1791 | .driver = { | ||
| 1792 | .name = "fsd-cmu", | ||
| 1793 | .of_match_table = fsd_cmu_of_match, | ||
| 1794 | .suppress_bind_attrs = true, | ||
| 1795 | }, | ||
| 1796 | .probe = fsd_cmu_probe, | ||
| 1797 | }; | ||
| 1798 | |||
| 1799 | static int __init fsd_cmu_init(void) | ||
| 1800 | { | ||
| 1801 | return platform_driver_register(&fsd_cmu_driver); | ||
| 1802 | } | ||
| 1803 | core_initcall(fsd_cmu_init); | ||
| @@ -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) |
| @@ -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) \ |
| @@ -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 | ||
| 158 | static bool __init qcom_spm_find_any_cpu(void) | ||
| 159 | { | ||
| 160 | struct device_node *cpu_node, *saw_node; | ||
| 161 | |||
| 162 | for_each_of_cpu_node(cpu_node) { | ||
| 163 | saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); | ||
| 164 | if (of_device_is_available(saw_node)) { | ||
| 165 | of_node_put(saw_node); | ||
| 166 | of_node_put(cpu_node); | ||
| 167 | return true; | ||
| 168 | } | ||
| 169 | of_node_put(saw_node); | ||
| 170 | } | ||
| 171 | return false; | ||
| 172 | } | ||
| 173 | |||
| 158 | static int __init qcom_spm_cpuidle_init(void) | 174 | static 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)) { |
| @@ -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 a | 54 | 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 | ||
| 57 | config ARM_SCMI_TRANSPORT_OPTEE | ||
| 58 | bool "SCMI transport based on OP-TEE service" | ||
| 59 | depends on OPTEE=y || OPTEE=ARM_SCMI_PROTOCOL | ||
| 60 | select ARM_SCMI_HAVE_TRANSPORT | ||
| 61 | select ARM_SCMI_HAVE_SHMEM | ||
| 62 | default y | ||
| 63 | help | ||
| 64 | This enables the OP-TEE service based transport for SCMI. | ||
| 65 | |||
| 66 | If you want the ARM SCMI PROTOCOL stack to include support for a | ||
| 67 | transport based on OP-TEE SCMI service, answer Y. | ||
| 68 | |||
| 57 | config ARM_SCMI_TRANSPORT_SMC | 69 | config ARM_SCMI_TRANSPORT_SMC |
| 58 | bool "SCMI transport based on SMC" | 70 | bool "SCMI transport based on SMC" |
| 59 | depends on HAVE_ARM_SMCCC_DISCOVERY | 71 | 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 a | 78 | 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 | ||
| 81 | config ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE | ||
| 82 | bool "Enable atomic mode support for SCMI SMC transport" | ||
| 83 | depends on ARM_SCMI_TRANSPORT_SMC | ||
| 84 | help | ||
| 85 | Enable support of atomic operation for SCMI SMC based transport. | ||
| 86 | |||
| 87 | If you want the SCMI SMC based transport to operate in atomic | ||
| 88 | mode, avoiding any kind of sleeping behaviour for selected | ||
| 89 | transactions on the TX path, answer Y. | ||
| 90 | Enabling atomic mode operations allows any SCMI driver using this | ||
| 91 | transport to optionally ask for atomic SCMI transactions and operate | ||
| 92 | in atomic context too, at the price of using a number of busy-waiting | ||
| 93 | primitives all over instead. If unsure say N. | ||
| 94 | |||
| 69 | config ARM_SCMI_TRANSPORT_VIRTIO | 95 | config 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_PROTOCOL | 97 | 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 a | 103 | 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 | ||
| 106 | config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE | ||
| 107 | bool "SCMI VirtIO transport Version 1 compliance" | ||
| 108 | depends on ARM_SCMI_TRANSPORT_VIRTIO | ||
| 109 | default y | ||
| 110 | help | ||
| 111 | This enforces strict compliance with VirtIO Version 1 specification. | ||
| 112 | |||
| 113 | If you want the ARM SCMI VirtIO transport layer to refuse to work | ||
| 114 | with Legacy VirtIO backends and instead support only VirtIO Version 1 | ||
| 115 | devices (or above), answer Y. | ||
| 116 | |||
| 117 | If you want instead to support also old Legacy VirtIO backends (like | ||
| 118 | the ones implemented by kvmtool) and let the core Kernel VirtIO layer | ||
| 119 | take care of the needed conversions, say N. | ||
| 120 | |||
| 121 | config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE | ||
| 122 | bool "Enable atomic mode for SCMI VirtIO transport" | ||
| 123 | depends on ARM_SCMI_TRANSPORT_VIRTIO | ||
| 124 | help | ||
| 125 | Enable support of atomic operation for SCMI VirtIO based transport. | ||
| 126 | |||
| 127 | If you want the SCMI VirtIO based transport to operate in atomic | ||
| 128 | mode, avoiding any kind of sleeping behaviour for selected | ||
| 129 | transactions on the TX path, answer Y. | ||
| 130 | |||
| 131 | Enabling atomic mode operations allows any SCMI driver using this | ||
| 132 | transport to optionally ask for atomic SCMI transactions and operate | ||
| 133 | in atomic context too, at the price of using a number of busy-waiting | ||
| 134 | primitives all over instead. If unsure say N. | ||
| 135 | |||
| 80 | endif #ARM_SCMI_PROTOCOL | 136 | endif #ARM_SCMI_PROTOCOL |
| 81 | 137 | ||
| 82 | config ARM_SCMI_POWER_DOMAIN | 138 | config ARM_SCMI_POWER_DOMAIN |
| @@ -6,8 +6,16 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o · 5 unmodified lines | |||
| 6 | scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o | 6 | scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o |
| 7 | scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o | 7 | scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o |
| 8 | scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o | 8 | scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o |
| 9 | scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o | ||
| 9 | scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o | 10 | scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o |
| 10 | scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \ | 11 | scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \ |
| 11 | $(scmi-transport-y) | 12 | $(scmi-transport-y) |
| 12 | obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o | 13 | obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o |
| 13 | obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o | 14 | obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o |
| 15 | |||
| 16 | ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy) | ||
| 17 | # The use of R7 in the SMCCC conflicts with the compiler's use of R7 as a frame | ||
| 18 | # pointer in Thumb2 mode, which is forcibly enabled by Clang when profiling | ||
| 19 | # hooks are inserted via the -pg switch. | ||
| 20 | CFLAGS_REMOVE_smc.o += $(CC_FLAGS_FTRACE) | ||
| 21 | endif | ||
| @@ -27,7 +27,8 @@ struct scmi_msg_resp_clock_protocol_attributes { · 26 unmodified lines | |||
| 27 | struct scmi_msg_resp_clock_attributes { | 27 | struct 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 | ||
| 33 | struct scmi_clock_set_config { | 34 | struct 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 | else | 122 | /* Is optional field clock_enable_latency provided ? */ |
| 123 | if (t->rx.len == sizeof(*attr)) | ||
| 124 | clk->enable_latency = | ||
| 125 | le32_to_cpu(attr->clock_enable_latency); | ||
| 126 | } else { | ||
| 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 | ||
| 274 | static int | 280 | static int |
| 275 | scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id, | 281 | scmi_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 | ||
| 297 | static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id) | 305 | static 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 | ||
| 302 | static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id) | 310 | static 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 | |||
| 315 | static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph, | ||
| 316 | u32 clk_id) | ||
| 317 | { | ||
| 318 | return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true); | ||
| 319 | } | ||
| 320 | |||
| 321 | static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph, | ||
| 322 | u32 clk_id) | ||
| 323 | { | ||
| 324 | return scmi_clock_config_set(ph, clk_id, 0, true); | ||
| 305 | } | 325 | } |
| 306 | 326 | ||
| 307 | static int scmi_clock_count_get(const struct scmi_protocol_handle *ph) | 327 | static int scmi_clock_count_get(const struct scmi_protocol_handle *ph) |
| @@ -330,6 +350,8 @@ static const struct scmi_clk_proto_ops clk_proto_ops = { · 22 unmodified lines | |||
| 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 | ||
| 335 | static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph) | 357 | static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph) |
| @@ -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 this | 339 | * @dev: Reference to device in the SCMI hierarchy corresponding to this |
| 340 | * channel | 340 | * channel |
| 341 | * @handle: Pointer to SCMI entity handle | 341 | * @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 information | 346 | * @transport_info: Transport layer related information |
| 343 | */ | 347 | */ |
| 344 | struct scmi_chan_info { | 348 | struct 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 the | 408 | * 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 | */ |
| 406 | struct scmi_desc { | 424 | struct 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_MAILBOX | 436 | #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_VIRTIO | 442 | #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO |
| 422 | extern const struct scmi_desc scmi_virtio_desc; | 443 | extern const struct scmi_desc scmi_virtio_desc; |
| 423 | #endif | 444 | #endif |
| 445 | #ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE | ||
| 446 | extern const struct scmi_desc scmi_optee_desc; | ||
| 447 | #endif | ||
| 424 | 448 | ||
| 425 | void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv); | 449 | void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv); |
| 426 | void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id); | 450 | void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id); |
| @@ -131,6 +131,12 @@ struct scmi_protocol_instance { · 130 unmodified lines | |||
| 131 | * MAX_PROTOCOLS_IMP elements allocated by the base protocol | 131 | * MAX_PROTOCOLS_IMP elements allocated by the base protocol |
| 132 | * @active_protocols: IDR storing device_nodes for protocols actually defined | 132 | * @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 head | 141 | * @node: List head |
| 136 | * @users: Number of users of this instance | 142 | * @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 | ||
| 619 | static inline bool is_polling_required(struct scmi_chan_info *cinfo, | ||
| 620 | struct scmi_info *info) | ||
| 621 | { | ||
| 622 | return cinfo->no_completion_irq || info->desc->force_polling; | ||
| 623 | } | ||
| 624 | |||
| 625 | static inline bool is_transport_polling_capable(struct scmi_info *info) | ||
| 626 | { | ||
| 627 | return info->desc->ops->poll_done || | ||
| 628 | info->desc->sync_cmds_completed_on_ret; | ||
| 629 | } | ||
| 630 | |||
| 631 | static inline bool is_polling_enabled(struct scmi_chan_info *cinfo, | ||
| 632 | struct scmi_info *info) | ||
| 633 | { | ||
| 634 | return is_polling_required(cinfo, info) && | ||
| 635 | is_transport_polling_capable(info); | ||
| 636 | } | ||
| 637 | |||
| 612 | static void scmi_handle_notification(struct scmi_chan_info *cinfo, | 638 | static 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 | |||
| 729 | static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, | 755 | static 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 | */ | ||
| 781 | static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, | ||
| 782 | struct scmi_xfer *xfer) | ||
| 783 | { | ||
| 784 | struct scmi_info *info = handle_to_scmi_info(cinfo->handle); | ||
| 785 | struct device *dev = info->dev; | ||
| 786 | int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms; | ||
| 787 | |||
| 788 | trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id, | ||
| 789 | xfer->hdr.protocol_id, xfer->hdr.seq, | ||
| 790 | timeout_ms, | ||
| 791 | xfer->hdr.poll_completion); | ||
| 792 | |||
| 793 | if (xfer->hdr.poll_completion) { | ||
| 794 | /* | ||
| 795 | * Real polling is needed only if transport has NOT declared | ||
| 796 | * itself to support synchronous commands replies. | ||
| 797 | */ | ||
| 798 | if (!info->desc->sync_cmds_completed_on_ret) { | ||
| 799 | /* | ||
| 800 | * Poll on xfer using transport provided .poll_done(); | ||
| 801 | * assumes no completion interrupt was available. | ||
| 802 | */ | ||
| 803 | ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); | ||
| 804 | |||
| 805 | spin_until_cond(scmi_xfer_done_no_timeout(cinfo, | ||
| 806 | xfer, stop)); | ||
| 807 | if (ktime_after(ktime_get(), stop)) { | ||
| 808 | dev_err(dev, | ||
| 809 | "timed out in resp(caller: %pS) - polling\n", | ||
| 810 | (void *)_RET_IP_); | ||
| 811 | ret = -ETIMEDOUT; | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | if (!ret) { | ||
| 816 | unsigned long flags; | ||
| 817 | |||
| 818 | /* | ||
| 819 | * Do not fetch_response if an out-of-order delayed | ||
| 820 | * response is being processed. | ||
| 821 | */ | ||
| 822 | spin_lock_irqsave(&xfer->lock, flags); | ||
| 823 | if (xfer->state == SCMI_XFER_SENT_OK) { | ||
| 824 | info->desc->ops->fetch_response(cinfo, xfer); | ||
| 825 | xfer->state = SCMI_XFER_RESP_OK; | ||
| 826 | } | ||
| 827 | spin_unlock_irqrestore(&xfer->lock, flags); | ||
| 828 | } | ||
| 829 | } else { | ||
| 830 | /* And we wait for the response. */ | ||
| 831 | if (!wait_for_completion_timeout(&xfer->done, | ||
| 832 | msecs_to_jiffies(timeout_ms))) { | ||
| 833 | dev_err(dev, "timed out in resp(caller: %pS)\n", | ||
| 834 | (void *)_RET_IP_); | ||
| 835 | ret = -ETIMEDOUT; | ||
| 836 | } | ||
| 837 | } | ||
| 838 | |||
| 839 | return ret; | ||
| 840 | } | ||
| 841 | |||
| 743 | /** | 842 | /** |
| 744 | * do_xfer() - Do one transfer | 843 | * 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 being | 877 | * Initialise protocol id now from protocol handle to avoid it being |
| 771 | * overridden by mistake (or malice) by the protocol code mangling with | 878 | * 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 handle | 932 | * @ph: Pointer to SCMI protocol handle |
| 859 | * @xfer: Transfer to initiate and wait for response | 933 | * @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 | */ | ||
| 1421 | static bool scmi_is_transport_atomic(const struct scmi_handle *handle, | ||
| 1422 | unsigned int *atomic_threshold) | ||
| 1423 | { | ||
| 1424 | bool ret; | ||
| 1425 | struct scmi_info *info = handle_to_scmi_info(handle); | ||
| 1426 | |||
| 1427 | ret = info->desc->atomic_enabled && is_transport_polling_capable(info); | ||
| 1428 | if (ret && atomic_threshold) | ||
| 1429 | *atomic_threshold = info->atomic_threshold; | ||
| 1430 | |||
| 1431 | return ret; | ||
| 1432 | } | ||
| 1433 | |||
| 1311 | static inline | 1434 | static inline |
| 1312 | struct scmi_handle *scmi_handle_get_from_info_unlocked(struct scmi_info *info) | 1435 | struct 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 | |||
| 1502 | idr_alloc: | 1635 | idr_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 the | 2003 | * 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_MAILBOX | 2139 | #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX |
| 1995 | { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, | 2140 | { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, |
| 1996 | #endif | 2141 | #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_SMC | 2145 | #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 | #endif | 2147 | #endif |
| @@ -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 | ||
| 143 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret) | 143 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, |
| 144 | struct scmi_xfer *__unused) | ||
| 144 | { | 145 | { |
| 145 | struct scmi_mailbox *smbox = cinfo->transport_info; | 146 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 146 | 147 | ||
| @@ -0,0 +1,567 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2019-2021 Linaro Ltd. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/io.h> | ||
| 7 | #include <linux/of.h> | ||
| 8 | #include <linux/of_address.h> | ||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/mutex.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/tee_drv.h> | ||
| 14 | #include <linux/uuid.h> | ||
| 15 | #include <uapi/linux/tee.h> | ||
| 16 | |||
| 17 | #include "common.h" | ||
| 18 | |||
| 19 | #define SCMI_OPTEE_MAX_MSG_SIZE 128 | ||
| 20 | |||
| 21 | enum scmi_optee_pta_cmd { | ||
| 22 | /* | ||
| 23 | * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities | ||
| 24 | * | ||
| 25 | * [out] value[0].a: Capability bit mask (enum pta_scmi_caps) | ||
| 26 | * [out] value[0].b: Extended capabilities or 0 | ||
| 27 | */ | ||
| 28 | PTA_SCMI_CMD_CAPABILITIES = 0, | ||
| 29 | |||
| 30 | /* | ||
| 31 | * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer | ||
| 32 | * | ||
| 33 | * [in] value[0].a: Channel handle | ||
| 34 | * | ||
| 35 | * Shared memory used for SCMI message/response exhange is expected | ||
| 36 | * already identified and bound to channel handle in both SCMI agent | ||
| 37 | * and SCMI server (OP-TEE) parts. | ||
| 38 | * The memory uses SMT header to carry SCMI meta-data (protocol ID and | ||
| 39 | * protocol message ID). | ||
| 40 | */ | ||
| 41 | PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1, | ||
| 42 | |||
| 43 | /* | ||
| 44 | * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message | ||
| 45 | * | ||
| 46 | * [in] value[0].a: Channel handle | ||
| 47 | * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload) | ||
| 48 | * | ||
| 49 | * Shared memory used for SCMI message/response is a SMT buffer | ||
| 50 | * referenced by param[1]. It shall be 128 bytes large to fit response | ||
| 51 | * payload whatever message playload size. | ||
| 52 | * The memory uses SMT header to carry SCMI meta-data (protocol ID and | ||
| 53 | * protocol message ID). | ||
| 54 | */ | ||
| 55 | PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2, | ||
| 56 | |||
| 57 | /* | ||
| 58 | * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle | ||
| 59 | * | ||
| 60 | * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM | ||
| 61 | * | ||
| 62 | * [in] value[0].a: Channel identifier | ||
| 63 | * [out] value[0].a: Returned channel handle | ||
| 64 | * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) | ||
| 65 | */ | ||
| 66 | PTA_SCMI_CMD_GET_CHANNEL = 3, | ||
| 67 | }; | ||
| 68 | |||
| 69 | /* | ||
| 70 | * OP-TEE SCMI service capabilities bit flags (32bit) | ||
| 71 | * | ||
| 72 | * PTA_SCMI_CAPS_SMT_HEADER | ||
| 73 | * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in | ||
| 74 | * shared memory buffers to carry SCMI protocol synchronisation information. | ||
| 75 | */ | ||
| 76 | #define PTA_SCMI_CAPS_NONE 0 | ||
| 77 | #define PTA_SCMI_CAPS_SMT_HEADER BIT(0) | ||
| 78 | |||
| 79 | /** | ||
| 80 | * struct scmi_optee_channel - Description of an OP-TEE SCMI channel | ||
| 81 | * | ||
| 82 | * @channel_id: OP-TEE channel ID used for this transport | ||
| 83 | * @tee_session: TEE session identifier | ||
| 84 | * @caps: OP-TEE SCMI channel capabilities | ||
| 85 | * @mu: Mutex protection on channel access | ||
| 86 | * @cinfo: SCMI channel information | ||
| 87 | * @shmem: Virtual base address of the shared memory | ||
| 88 | * @tee_shm: Reference to TEE shared memory or NULL if using static shmem | ||
| 89 | * @link: Reference in agent's channel list | ||
| 90 | */ | ||
| 91 | struct scmi_optee_channel { | ||
| 92 | u32 channel_id; | ||
| 93 | u32 tee_session; | ||
| 94 | u32 caps; | ||
| 95 | struct mutex mu; | ||
| 96 | struct scmi_chan_info *cinfo; | ||
| 97 | struct scmi_shared_mem __iomem *shmem; | ||
| 98 | struct tee_shm *tee_shm; | ||
| 99 | struct list_head link; | ||
| 100 | }; | ||
| 101 | |||
| 102 | /** | ||
| 103 | * struct scmi_optee_agent - OP-TEE transport private data | ||
| 104 | * | ||
| 105 | * @dev: Device used for communication with TEE | ||
| 106 | * @tee_ctx: TEE context used for communication | ||
| 107 | * @caps: Supported channel capabilities | ||
| 108 | * @mu: Mutex for protection of @channel_list | ||
| 109 | * @channel_list: List of all created channels for the agent | ||
| 110 | */ | ||
| 111 | struct scmi_optee_agent { | ||
| 112 | struct device *dev; | ||
| 113 | struct tee_context *tee_ctx; | ||
| 114 | u32 caps; | ||
| 115 | struct mutex mu; | ||
| 116 | struct list_head channel_list; | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* There can be only 1 SCMI service in OP-TEE we connect to */ | ||
| 120 | static struct scmi_optee_agent *scmi_optee_private; | ||
| 121 | |||
| 122 | /* Forward reference to scmi_optee transport initialization */ | ||
| 123 | static int scmi_optee_init(void); | ||
| 124 | |||
| 125 | /* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */ | ||
| 126 | static int open_session(struct scmi_optee_agent *agent, u32 *tee_session) | ||
| 127 | { | ||
| 128 | struct device *dev = agent->dev; | ||
| 129 | struct tee_client_device *scmi_pta = to_tee_client_device(dev); | ||
| 130 | struct tee_ioctl_open_session_arg arg = { }; | ||
| 131 | int ret; | ||
| 132 | |||
| 133 | memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN); | ||
| 134 | arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; | ||
| 135 | |||
| 136 | ret = tee_client_open_session(agent->tee_ctx, &arg, NULL); | ||
| 137 | if (ret < 0 || arg.ret) { | ||
| 138 | dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret); | ||
| 139 | return -EOPNOTSUPP; | ||
| 140 | } | ||
| 141 | |||
| 142 | *tee_session = arg.session; | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static void close_session(struct scmi_optee_agent *agent, u32 tee_session) | ||
| 148 | { | ||
| 149 | tee_client_close_session(agent->tee_ctx, tee_session); | ||
| 150 | } | ||
| 151 | |||
| 152 | static int get_capabilities(struct scmi_optee_agent *agent) | ||
| 153 | { | ||
| 154 | struct tee_ioctl_invoke_arg arg = { }; | ||
| 155 | struct tee_param param[1] = { }; | ||
| 156 | u32 caps; | ||
| 157 | u32 tee_session; | ||
| 158 | int ret; | ||
| 159 | |||
| 160 | ret = open_session(agent, &tee_session); | ||
| 161 | if (ret) | ||
| 162 | return ret; | ||
| 163 | |||
| 164 | arg.func = PTA_SCMI_CMD_CAPABILITIES; | ||
| 165 | arg.session = tee_session; | ||
| 166 | arg.num_params = 1; | ||
| 167 | |||
| 168 | param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; | ||
| 169 | |||
| 170 | ret = tee_client_invoke_func(agent->tee_ctx, &arg, param); | ||
| 171 | |||
| 172 | close_session(agent, tee_session); | ||
| 173 | |||
| 174 | if (ret < 0 || arg.ret) { | ||
| 175 | dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret); | ||
| 176 | return -EOPNOTSUPP; | ||
| 177 | } | ||
| 178 | |||
| 179 | caps = param[0].u.value.a; | ||
| 180 | |||
| 181 | if (!(caps & PTA_SCMI_CAPS_SMT_HEADER)) { | ||
| 182 | dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT\n"); | ||
| 183 | return -EOPNOTSUPP; | ||
| 184 | } | ||
| 185 | |||
| 186 | agent->caps = caps; | ||
| 187 | |||
| 188 | return 0; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int get_channel(struct scmi_optee_channel *channel) | ||
| 192 | { | ||
| 193 | struct device *dev = scmi_optee_private->dev; | ||
| 194 | struct tee_ioctl_invoke_arg arg = { }; | ||
| 195 | struct tee_param param[1] = { }; | ||
| 196 | unsigned int caps = PTA_SCMI_CAPS_SMT_HEADER; | ||
| 197 | int ret; | ||
| 198 | |||
| 199 | arg.func = PTA_SCMI_CMD_GET_CHANNEL; | ||
| 200 | arg.session = channel->tee_session; | ||
| 201 | arg.num_params = 1; | ||
| 202 | |||
| 203 | param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; | ||
| 204 | param[0].u.value.a = channel->channel_id; | ||
| 205 | param[0].u.value.b = caps; | ||
| 206 | |||
| 207 | ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); | ||
| 208 | |||
| 209 | if (ret || arg.ret) { | ||
| 210 | dev_err(dev, "Can't get channel with caps %#x: %d / %#x\n", caps, ret, arg.ret); | ||
| 211 | return -EOPNOTSUPP; | ||
| 212 | } | ||
| 213 | |||
| 214 | /* From now on use channel identifer provided by OP-TEE SCMI service */ | ||
| 215 | channel->channel_id = param[0].u.value.a; | ||
| 216 | channel->caps = caps; | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int invoke_process_smt_channel(struct scmi_optee_channel *channel) | ||
| 222 | { | ||
| 223 | struct tee_ioctl_invoke_arg arg = { }; | ||
| 224 | struct tee_param param[2] = { }; | ||
| 225 | int ret; | ||
| 226 | |||
| 227 | arg.session = channel->tee_session; | ||
| 228 | param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; | ||
| 229 | param[0].u.value.a = channel->channel_id; | ||
| 230 | |||
| 231 | if (channel->tee_shm) { | ||
| 232 | param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT; | ||
| 233 | param[1].u.memref.shm = channel->tee_shm; | ||
| 234 | param[1].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE; | ||
| 235 | arg.num_params = 2; | ||
| 236 | arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE; | ||
| 237 | } else { | ||
| 238 | arg.num_params = 1; | ||
| 239 | arg.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL; | ||
| 240 | } | ||
| 241 | |||
| 242 | ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); | ||
| 243 | if (ret < 0 || arg.ret) { | ||
| 244 | dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n", | ||
| 245 | channel->channel_id, ret, arg.ret); | ||
| 246 | return -EIO; | ||
| 247 | } | ||
| 248 | |||
| 249 | return 0; | ||
| 250 | } | ||
| 251 | |||
| 252 | static int scmi_optee_link_supplier(struct device *dev) | ||
| 253 | { | ||
| 254 | if (!scmi_optee_private) { | ||
| 255 | if (scmi_optee_init()) | ||
| 256 | dev_dbg(dev, "Optee bus not yet ready\n"); | ||
| 257 | |||
| 258 | /* Wait for optee bus */ | ||
| 259 | return -EPROBE_DEFER; | ||
| 260 | } | ||
| 261 | |||
| 262 | if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) { | ||
| 263 | dev_err(dev, "Adding link to supplier optee device failed\n"); | ||
| 264 | return -ECANCELED; | ||
| 265 | } | ||
| 266 | |||
| 267 | return 0; | ||
| 268 | } | ||
| 269 | |||
| 270 | static bool scmi_optee_chan_available(struct device *dev, int idx) | ||
| 271 | { | ||
| 272 | u32 channel_id; | ||
| 273 | |||
| 274 | return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id", | ||
| 275 | idx, &channel_id); | ||
| 276 | } | ||
| 277 | |||
| 278 | static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo) | ||
| 279 | { | ||
| 280 | struct scmi_optee_channel *channel = cinfo->transport_info; | ||
| 281 | |||
| 282 | shmem_clear_channel(channel->shmem); | ||
| 283 | } | ||
| 284 | |||
| 285 | static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo, | ||
| 286 | struct scmi_optee_channel *channel) | ||
| 287 | { | ||
| 288 | struct device_node *np; | ||
| 289 | resource_size_t size; | ||
| 290 | struct resource res; | ||
| 291 | int ret; | ||
| 292 | |||
| 293 | np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0); | ||
| 294 | if (!of_device_is_compatible(np, "arm,scmi-shmem")) { | ||
| 295 | ret = -ENXIO; | ||
| 296 | goto out; | ||
| 297 | } | ||
| 298 | |||
| 299 | ret = of_address_to_resource(np, 0, &res); | ||
| 300 | if (ret) { | ||
| 301 | dev_err(dev, "Failed to get SCMI Tx shared memory\n"); | ||
| 302 | goto out; | ||
| 303 | } | ||
| 304 | |||
| 305 | size = resource_size(&res); | ||
| 306 | |||
| 307 | channel->shmem = devm_ioremap(dev, res.start, size); | ||
| 308 | if (!channel->shmem) { | ||
| 309 | dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); | ||
| 310 | ret = -EADDRNOTAVAIL; | ||
| 311 | goto out; | ||
| 312 | } | ||
| 313 | |||
| 314 | ret = 0; | ||
| 315 | |||
| 316 | out: | ||
| 317 | of_node_put(np); | ||
| 318 | |||
| 319 | return ret; | ||
| 320 | } | ||
| 321 | |||
| 322 | static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, | ||
| 323 | struct scmi_optee_channel *channel) | ||
| 324 | { | ||
| 325 | if (of_find_property(cinfo->dev->of_node, "shmem", NULL)) | ||
| 326 | return setup_static_shmem(dev, cinfo, channel); | ||
| 327 | else | ||
| 328 | return -ENOMEM; | ||
| 329 | } | ||
| 330 | |||
| 331 | static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx) | ||
| 332 | { | ||
| 333 | struct scmi_optee_channel *channel; | ||
| 334 | uint32_t channel_id; | ||
| 335 | int ret; | ||
| 336 | |||
| 337 | if (!tx) | ||
| 338 | return -ENODEV; | ||
| 339 | |||
| 340 | channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); | ||
| 341 | if (!channel) | ||
| 342 | return -ENOMEM; | ||
| 343 | |||
| 344 | ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id", | ||
| 345 | 0, &channel_id); | ||
| 346 | if (ret) | ||
| 347 | return ret; | ||
| 348 | |||
| 349 | cinfo->transport_info = channel; | ||
| 350 | channel->cinfo = cinfo; | ||
| 351 | channel->channel_id = channel_id; | ||
| 352 | mutex_init(&channel->mu); | ||
| 353 | |||
| 354 | ret = setup_shmem(dev, cinfo, channel); | ||
| 355 | if (ret) | ||
| 356 | return ret; | ||
| 357 | |||
| 358 | ret = open_session(scmi_optee_private, &channel->tee_session); | ||
| 359 | if (ret) | ||
| 360 | goto err_free_shm; | ||
| 361 | |||
| 362 | ret = get_channel(channel); | ||
| 363 | if (ret) | ||
| 364 | goto err_close_sess; | ||
| 365 | |||
| 366 | /* Enable polling */ | ||
| 367 | cinfo->no_completion_irq = true; | ||
| 368 | |||
| 369 | mutex_lock(&scmi_optee_private->mu); | ||
| 370 | list_add(&channel->link, &scmi_optee_private->channel_list); | ||
| 371 | mutex_unlock(&scmi_optee_private->mu); | ||
| 372 | |||
| 373 | return 0; | ||
| 374 | |||
| 375 | err_close_sess: | ||
| 376 | close_session(scmi_optee_private, channel->tee_session); | ||
| 377 | err_free_shm: | ||
| 378 | if (channel->tee_shm) | ||
| 379 | tee_shm_free(channel->tee_shm); | ||
| 380 | |||
| 381 | return ret; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int scmi_optee_chan_free(int id, void *p, void *data) | ||
| 385 | { | ||
| 386 | struct scmi_chan_info *cinfo = p; | ||
| 387 | struct scmi_optee_channel *channel = cinfo->transport_info; | ||
| 388 | |||
| 389 | mutex_lock(&scmi_optee_private->mu); | ||
| 390 | list_del(&channel->link); | ||
| 391 | mutex_unlock(&scmi_optee_private->mu); | ||
| 392 | |||
| 393 | close_session(scmi_optee_private, channel->tee_session); | ||
| 394 | |||
| 395 | if (channel->tee_shm) { | ||
| 396 | tee_shm_free(channel->tee_shm); | ||
| 397 | channel->tee_shm = NULL; | ||
| 398 | } | ||
| 399 | |||
| 400 | cinfo->transport_info = NULL; | ||
| 401 | channel->cinfo = NULL; | ||
| 402 | |||
| 403 | scmi_free_channel(cinfo, data, id); | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | static struct scmi_shared_mem *get_channel_shm(struct scmi_optee_channel *chan, | ||
| 409 | struct scmi_xfer *xfer) | ||
| 410 | { | ||
| 411 | if (!chan) | ||
| 412 | return NULL; | ||
| 413 | |||
| 414 | return chan->shmem; | ||
| 415 | } | ||
| 416 | |||
| 417 | |||
| 418 | static int scmi_optee_send_message(struct scmi_chan_info *cinfo, | ||
| 419 | struct scmi_xfer *xfer) | ||
| 420 | { | ||
| 421 | struct scmi_optee_channel *channel = cinfo->transport_info; | ||
| 422 | struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer); | ||
| 423 | int ret; | ||
| 424 | |||
| 425 | mutex_lock(&channel->mu); | ||
| 426 | shmem_tx_prepare(shmem, xfer); | ||
| 427 | |||
| 428 | ret = invoke_process_smt_channel(channel); | ||
| 429 | if (ret) | ||
| 430 | mutex_unlock(&channel->mu); | ||
| 431 | |||
| 432 | return ret; | ||
| 433 | } | ||
| 434 | |||
| 435 | static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo, | ||
| 436 | struct scmi_xfer *xfer) | ||
| 437 | { | ||
| 438 | struct scmi_optee_channel *channel = cinfo->transport_info; | ||
| 439 | struct scmi_shared_mem *shmem = get_channel_shm(channel, xfer); | ||
| 440 | |||
| 441 | shmem_fetch_response(shmem, xfer); | ||
| 442 | } | ||
| 443 | |||
| 444 | static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret, | ||
| 445 | struct scmi_xfer *__unused) | ||
| 446 | { | ||
| 447 | struct scmi_optee_channel *channel = cinfo->transport_info; | ||
| 448 | |||
| 449 | mutex_unlock(&channel->mu); | ||
| 450 | } | ||
| 451 | |||
| 452 | static struct scmi_transport_ops scmi_optee_ops = { | ||
| 453 | .link_supplier = scmi_optee_link_supplier, | ||
| 454 | .chan_available = scmi_optee_chan_available, | ||
| 455 | .chan_setup = scmi_optee_chan_setup, | ||
| 456 | .chan_free = scmi_optee_chan_free, | ||
| 457 | .send_message = scmi_optee_send_message, | ||
| 458 | .mark_txdone = scmi_optee_mark_txdone, | ||
| 459 | .fetch_response = scmi_optee_fetch_response, | ||
| 460 | .clear_channel = scmi_optee_clear_channel, | ||
| 461 | }; | ||
| 462 | |||
| 463 | static int scmi_optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) | ||
| 464 | { | ||
| 465 | return ver->impl_id == TEE_IMPL_ID_OPTEE; | ||
| 466 | } | ||
| 467 | |||
| 468 | static int scmi_optee_service_probe(struct device *dev) | ||
| 469 | { | ||
| 470 | struct scmi_optee_agent *agent; | ||
| 471 | struct tee_context *tee_ctx; | ||
| 472 | int ret; | ||
| 473 | |||
| 474 | /* Only one SCMI OP-TEE device allowed */ | ||
| 475 | if (scmi_optee_private) { | ||
| 476 | dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n"); | ||
| 477 | return -EBUSY; | ||
| 478 | } | ||
| 479 | |||
| 480 | tee_ctx = tee_client_open_context(NULL, scmi_optee_ctx_match, NULL, NULL); | ||
| 481 | if (IS_ERR(tee_ctx)) | ||
| 482 | return -ENODEV; | ||
| 483 | |||
| 484 | agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL); | ||
| 485 | if (!agent) { | ||
| 486 | ret = -ENOMEM; | ||
| 487 | goto err; | ||
| 488 | } | ||
| 489 | |||
| 490 | agent->dev = dev; | ||
| 491 | agent->tee_ctx = tee_ctx; | ||
| 492 | INIT_LIST_HEAD(&agent->channel_list); | ||
| 493 | mutex_init(&agent->mu); | ||
| 494 | |||
| 495 | ret = get_capabilities(agent); | ||
| 496 | if (ret) | ||
| 497 | goto err; | ||
| 498 | |||
| 499 | /* Ensure agent resources are all visible before scmi_optee_private is */ | ||
| 500 | smp_mb(); | ||
| 501 | scmi_optee_private = agent; | ||
| 502 | |||
| 503 | return 0; | ||
| 504 | |||
| 505 | err: | ||
| 506 | tee_client_close_context(tee_ctx); | ||
| 507 | |||
| 508 | return ret; | ||
| 509 | } | ||
| 510 | |||
| 511 | static int scmi_optee_service_remove(struct device *dev) | ||
| 512 | { | ||
| 513 | struct scmi_optee_agent *agent = scmi_optee_private; | ||
| 514 | |||
| 515 | if (!scmi_optee_private) | ||
| 516 | return -EINVAL; | ||
| 517 | |||
| 518 | if (!list_empty(&scmi_optee_private->channel_list)) | ||
| 519 | return -EBUSY; | ||
| 520 | |||
| 521 | /* Ensure cleared reference is visible before resources are released */ | ||
| 522 | smp_store_mb(scmi_optee_private, NULL); | ||
| 523 | |||
| 524 | tee_client_close_context(agent->tee_ctx); | ||
| 525 | |||
| 526 | return 0; | ||
| 527 | } | ||
| 528 | |||
| 529 | static const struct tee_client_device_id scmi_optee_service_id[] = { | ||
| 530 | { | ||
| 531 | UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e, | ||
| 532 | 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99) | ||
| 533 | }, | ||
| 534 | { } | ||
| 535 | }; | ||
| 536 | |||
| 537 | MODULE_DEVICE_TABLE(tee, scmi_optee_service_id); | ||
| 538 | |||
| 539 | static struct tee_client_driver scmi_optee_driver = { | ||
| 540 | .id_table = scmi_optee_service_id, | ||
| 541 | .driver = { | ||
| 542 | .name = "scmi-optee", | ||
| 543 | .bus = &tee_bus_type, | ||
| 544 | .probe = scmi_optee_service_probe, | ||
| 545 | .remove = scmi_optee_service_remove, | ||
| 546 | }, | ||
| 547 | }; | ||
| 548 | |||
| 549 | static int scmi_optee_init(void) | ||
| 550 | { | ||
| 551 | return driver_register(&scmi_optee_driver.driver); | ||
| 552 | } | ||
| 553 | |||
| 554 | static void scmi_optee_exit(void) | ||
| 555 | { | ||
| 556 | if (scmi_optee_private) | ||
| 557 | driver_unregister(&scmi_optee_driver.driver); | ||
| 558 | } | ||
| 559 | |||
| 560 | const struct scmi_desc scmi_optee_desc = { | ||
| 561 | .transport_exit = scmi_optee_exit, | ||
| 562 | .ops = &scmi_optee_ops, | ||
| 563 | .max_rx_timeout_ms = 30, | ||
| 564 | .max_msg = 20, | ||
| 565 | .max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE, | ||
| 566 | .sync_cmds_completed_on_ret = true, | ||
| 567 | }; | ||
| @@ -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 info | 26 | * @cinfo: SCMI channel info |
| 25 | * @shmem: Transmit/Receive shared memory area | 27 | * @shmem: Transmit/Receive shared memory area |
| 26 | * @shmem_lock: Lock to protect access to Tx/Rx shared memory area | 28 | * @shmem_lock: Lock to protect access to Tx/Rx shared memory area. |
| 29 | * Used when NOT operating in atomic mode. | ||
| 30 | * @inflight: Atomic flag to protect access to Tx/Rx shared memory area. | ||
| 31 | * Used when operating in atomic mode. | ||
| 27 | * @func_id: smc/hvc call function id | 32 | * @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 | ||
| 32 | struct scmi_smc { | 35 | struct 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 | ||
| 41 | static irqreturn_t smc_msg_done_isr(int irq, void *data) | 45 | static 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 | ||
| 65 | static inline void smc_channel_lock_init(struct scmi_smc *scmi_info) | ||
| 66 | { | ||
| 67 | if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) | ||
| 68 | atomic_set(&scmi_info->inflight, INFLIGHT_NONE); | ||
| 69 | else | ||
| 70 | mutex_init(&scmi_info->shmem_lock); | ||
| 71 | } | ||
| 72 | |||
| 73 | static bool smc_xfer_inflight(struct scmi_xfer *xfer, atomic_t *inflight) | ||
| 74 | { | ||
| 75 | int ret; | ||
| 76 | |||
| 77 | ret = atomic_cmpxchg(inflight, INFLIGHT_NONE, xfer->hdr.seq); | ||
| 78 | |||
| 79 | return ret == INFLIGHT_NONE; | ||
| 80 | } | ||
| 81 | |||
| 82 | static inline void | ||
| 83 | smc_channel_lock_acquire(struct scmi_smc *scmi_info, | ||
| 84 | struct scmi_xfer *xfer __maybe_unused) | ||
| 85 | { | ||
| 86 | if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) | ||
| 87 | spin_until_cond(smc_xfer_inflight(xfer, &scmi_info->inflight)); | ||
| 88 | else | ||
| 89 | mutex_lock(&scmi_info->shmem_lock); | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline void smc_channel_lock_release(struct scmi_smc *scmi_info) | ||
| 93 | { | ||
| 94 | if (IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE)) | ||
| 95 | atomic_set(&scmi_info->inflight, INFLIGHT_NONE); | ||
| 96 | else | ||
| 97 | mutex_unlock(&scmi_info->shmem_lock); | ||
| 98 | } | ||
| 99 | |||
| 60 | static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, | 100 | static 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 | ||
| 176 | static bool | 212 | static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret, |
| 177 | smc_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 | ||
| 184 | static const struct scmi_transport_ops scmi_smc_ops = { | 220 | static const struct scmi_transport_ops scmi_smc_ops = { |
| @@ -186,8 +222,8 @@ static const struct scmi_transport_ops scmi_smc_ops = { · 1 unmodified line | |||
| 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 | ||
| 193 | const struct scmi_desc scmi_smc_desc = { | 229 | const 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 | }; |
| @@ -3,8 +3,8 @@ · 2 unmodified lines | |||
| 3 | * Virtio Transport driver for Arm System Control and Management Interface | 3 | * 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 virtqueue | 41 | * @vqueue: Associated virtqueue |
| 39 | * @cinfo: SCMI Tx or Rx channel | 42 | * @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 only | 44 | * @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 channel | 49 | * @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 before | 52 | * 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 | */ |
| 48 | struct scmi_vio_channel { | 56 | struct 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 | |||
| 78 | enum 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 notifications | 89 | * @input: SDU used for (delayed) responses and notifications |
| 66 | * @list: List which scmi_vio_msg may be part of | 90 | * @list: List which scmi_vio_msg may be part of |
| 67 | * @rx_len: Input SDU size in bytes, once input has been received | 91 | * @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 | */ |
| 69 | struct scmi_vio_msg { | 99 | struct 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 */ |
| 77 | static struct virtio_device *scmi_vdev; | 112 | static struct virtio_device *scmi_vdev; |
| 78 | 113 | ||
| 114 | static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch, | ||
| 115 | struct scmi_chan_info *cinfo) | ||
| 116 | { | ||
| 117 | unsigned long flags; | ||
| 118 | |||
| 119 | spin_lock_irqsave(&vioch->lock, flags); | ||
| 120 | cinfo->transport_info = vioch; | ||
| 121 | /* Indirectly setting channel not available any more */ | ||
| 122 | vioch->cinfo = cinfo; | ||
| 123 | spin_unlock_irqrestore(&vioch->lock, flags); | ||
| 124 | |||
| 125 | refcount_set(&vioch->users, 1); | ||
| 126 | } | ||
| 127 | |||
| 128 | static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch) | ||
| 129 | { | ||
| 130 | return refcount_inc_not_zero(&vioch->users); | ||
| 131 | } | ||
| 132 | |||
| 133 | static inline void scmi_vio_channel_release(struct scmi_vio_channel *vioch) | ||
| 134 | { | ||
| 135 | if (refcount_dec_and_test(&vioch->users)) { | ||
| 136 | unsigned long flags; | ||
| 137 | |||
| 138 | spin_lock_irqsave(&vioch->lock, flags); | ||
| 139 | if (vioch->shutdown_done) { | ||
| 140 | vioch->cinfo = NULL; | ||
| 141 | complete(vioch->shutdown_done); | ||
| 142 | } | ||
| 143 | spin_unlock_irqrestore(&vioch->lock, flags); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) | ||
| 148 | { | ||
| 149 | unsigned long flags; | ||
| 150 | DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done); | ||
| 151 | void *deferred_wq = NULL; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Prepare to wait for the last release if not already released | ||
| 155 | * or in progress. | ||
| 156 | */ | ||
| 157 | spin_lock_irqsave(&vioch->lock, flags); | ||
| 158 | if (!vioch->cinfo || vioch->shutdown_done) { | ||
| 159 | spin_unlock_irqrestore(&vioch->lock, flags); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | vioch->shutdown_done = &vioch_shutdown_done; | ||
| 164 | virtio_break_device(vioch->vqueue->vdev); | ||
| 165 | if (!vioch->is_rx && vioch->deferred_tx_wq) { | ||
| 166 | deferred_wq = vioch->deferred_tx_wq; | ||
| 167 | /* Cannot be kicked anymore after this...*/ | ||
| 168 | vioch->deferred_tx_wq = NULL; | ||
| 169 | } | ||
| 170 | spin_unlock_irqrestore(&vioch->lock, flags); | ||
| 171 | |||
| 172 | if (deferred_wq) | ||
| 173 | destroy_workqueue(deferred_wq); | ||
| 174 | |||
| 175 | scmi_vio_channel_release(vioch); | ||
| 176 | |||
| 177 | /* Let any possibly concurrent RX path release the channel */ | ||
| 178 | wait_for_completion(vioch->shutdown_done); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* Assumes to be called with vio channel acquired already */ | ||
| 182 | static struct scmi_vio_msg * | ||
| 183 | scmi_virtio_get_free_msg(struct scmi_vio_channel *vioch) | ||
| 184 | { | ||
| 185 | unsigned long flags; | ||
| 186 | struct scmi_vio_msg *msg; | ||
| 187 | |||
| 188 | spin_lock_irqsave(&vioch->free_lock, flags); | ||
| 189 | if (list_empty(&vioch->free_list)) { | ||
| 190 | spin_unlock_irqrestore(&vioch->free_lock, flags); | ||
| 191 | return NULL; | ||
| 192 | } | ||
| 193 | |||
| 194 | msg = list_first_entry(&vioch->free_list, typeof(*msg), list); | ||
| 195 | list_del_init(&msg->list); | ||
| 196 | spin_unlock_irqrestore(&vioch->free_lock, flags); | ||
| 197 | |||
| 198 | /* Still no users, no need to acquire poll_lock */ | ||
| 199 | msg->poll_status = VIO_MSG_NOT_POLLED; | ||
| 200 | refcount_set(&msg->users, 1); | ||
| 201 | |||
| 202 | return msg; | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline bool scmi_vio_msg_acquire(struct scmi_vio_msg *msg) | ||
| 206 | { | ||
| 207 | return refcount_inc_not_zero(&msg->users); | ||
| 208 | } | ||
| 209 | |||
| 210 | /* Assumes to be called with vio channel acquired already */ | ||
| 211 | static inline bool scmi_vio_msg_release(struct scmi_vio_channel *vioch, | ||
| 212 | struct scmi_vio_msg *msg) | ||
| 213 | { | ||
| 214 | bool ret; | ||
| 215 | |||
| 216 | ret = refcount_dec_and_test(&msg->users); | ||
| 217 | if (ret) { | ||
| 218 | unsigned long flags; | ||
| 219 | |||
| 220 | spin_lock_irqsave(&vioch->free_lock, flags); | ||
| 221 | list_add_tail(&msg->list, &vioch->free_list); | ||
| 222 | spin_unlock_irqrestore(&vioch->free_lock, flags); | ||
| 223 | } | ||
| 224 | |||
| 225 | return ret; | ||
| 226 | } | ||
| 227 | |||
| 79 | static bool scmi_vio_have_vq_rx(struct virtio_device *vdev) | 228 | static 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 | ||
| 84 | static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch, | 233 | static 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 | else | 248 | 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 | */ | ||
| 107 | static void scmi_finalize_message(struct scmi_vio_channel *vioch, | 260 | static 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 | ||
| 120 | static void scmi_vio_complete_cb(struct virtqueue *vqueue) | 269 | static 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 iterations | 311 | * Release vio channel between loop iterations to allow |
| 165 | * to allow virtio_chan_free() to possibly kick in and set the | 312 | * virtio_chan_free() to eventually fully release it when |
| 166 | * flag vioch->ready to false even in between processing of | 313 | * shutting down; in such a case, any outstanding message will |
| 167 | * messages, so as to force outstanding messages to be ignored | 314 | * 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 | |||
| 321 | static void scmi_vio_deferred_tx_worker(struct work_struct *work) | ||
| 322 | { | ||
| 323 | unsigned long flags; | ||
| 324 | struct scmi_vio_channel *vioch; | ||
| 325 | struct scmi_vio_msg *msg, *tmp; | ||
| 326 | |||
| 327 | vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work); | ||
| 328 | |||
| 329 | if (!scmi_vio_channel_acquire(vioch)) | ||
| 330 | return; | ||
| 331 | |||
| 332 | /* | ||
| 333 | * Process pre-fetched messages: these could be non-polled messages or | ||
| 334 | * late timed-out replies to polled messages dequeued by chance while | ||
| 335 | * polling for some other messages: this worker is in charge to process | ||
| 336 | * the valid non-expired messages and anyway finally free all of them. | ||
| 337 | */ | ||
| 338 | spin_lock_irqsave(&vioch->pending_lock, flags); | ||
| 339 | |||
| 340 | /* Scan the list of possibly pre-fetched messages during polling. */ | ||
| 341 | list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) { | ||
| 342 | list_del(&msg->list); | ||
| 343 | |||
| 344 | /* | ||
| 345 | * Channel is acquired here (cannot vanish) and this message | ||
| 346 | * is no more processed elsewhere so no poll_lock needed. | ||
| 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 | ||
| 173 | unlock_out: | 356 | spin_unlock_irqrestore(&vioch->pending_lock, flags); |
| 174 | spin_unlock(&vioch->lock); | 357 | |
| 175 | unlock_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 | ||
| 179 | static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" }; | 364 | static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" }; |
| @@ -193,8 +378,8 @@ static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo) · 13 unmodified lines | |||
| 193 | static int virtio_link_supplier(struct device *dev) | 378 | static 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 | |||
| 234 | static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, | 419 | static 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 | ||
| 289 | static int virtio_chan_free(int id, void *p, void *data) | 474 | static 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 | ||
| 360 | static void virtio_fetch_notification(struct scmi_chan_info *cinfo, | 559 | static void virtio_fetch_notification(struct scmi_chan_info *cinfo, |
| @@ -362,10 +561,225 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo, · 1 unmodified line | |||
| 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 | */ | ||
| 603 | static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret, | ||
| 604 | struct scmi_xfer *xfer) | ||
| 605 | { | ||
| 606 | unsigned long flags; | ||
| 607 | struct scmi_vio_channel *vioch = cinfo->transport_info; | ||
| 608 | struct scmi_vio_msg *msg = xfer->priv; | ||
| 609 | |||
| 610 | if (!msg || !scmi_vio_channel_acquire(vioch)) | ||
| 611 | return; | ||
| 612 | |||
| 613 | /* Ensure msg is unbound from xfer anyway at this point */ | ||
| 614 | smp_store_mb(xfer->priv, NULL); | ||
| 615 | |||
| 616 | /* Must be a polled xfer and not already freed on the IRQ path */ | ||
| 617 | if (!xfer->hdr.poll_completion || scmi_vio_msg_release(vioch, msg)) { | ||
| 618 | scmi_vio_channel_release(vioch); | ||
| 619 | return; | ||
| 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 | */ | ||
| 670 | static bool virtio_poll_done(struct scmi_chan_info *cinfo, | ||
| 671 | struct scmi_xfer *xfer) | ||
| 672 | { | ||
| 673 | bool pending, found = false; | ||
| 674 | unsigned int length, any_prefetched = 0; | ||
| 675 | unsigned long flags; | ||
| 676 | struct scmi_vio_msg *next_msg, *msg = xfer->priv; | ||
| 677 | struct scmi_vio_channel *vioch = cinfo->transport_info; | ||
| 678 | |||
| 679 | if (!msg) | ||
| 680 | return true; | ||
| 681 | |||
| 682 | /* | ||
| 683 | * Processed already by other polling loop on another CPU ? | ||
| 684 | * | ||
| 685 | * Note that this message is acquired on the poll path so cannot vanish | ||
| 686 | * while inside this loop iteration even if concurrently processed on | ||
| 687 | * the IRQ path. | ||
| 688 | * | ||
| 689 | * Avoid to acquire poll_lock since polled_status can be changed | ||
| 690 | * in a relevant manner only later in this same thread of execution: | ||
| 691 | * any other possible changes made concurrently by other polling loops | ||
| 692 | * or by a reply delivered on the IRQ path have no meaningful impact on | ||
| 693 | * this loop iteration: in other words it is harmless to allow this | ||
| 694 | * possible race but let has avoid spinlocking with irqs off in this | ||
| 695 | * initial part of the polling loop. | ||
| 696 | */ | ||
| 697 | if (msg->poll_status == VIO_MSG_POLL_DONE) | ||
| 698 | return true; | ||
| 699 | |||
| 700 | if (!scmi_vio_channel_acquire(vioch)) | ||
| 701 | return true; | ||
| 702 | |||
| 703 | /* Has cmdq index moved at all ? */ | ||
| 704 | pending = virtqueue_poll(vioch->vqueue, msg->poll_idx); | ||
| 705 | if (!pending) { | ||
| 706 | scmi_vio_channel_release(vioch); | ||
| 707 | return false; | ||
| 708 | } | ||
| 709 | |||
| 710 | spin_lock_irqsave(&vioch->lock, flags); | ||
| 711 | virtqueue_disable_cb(vioch->vqueue); | ||
| 712 | |||
| 713 | /* | ||
| 714 | * Process all new messages till the polled-for message is found OR | ||
| 715 | * the vqueue is empty. | ||
| 716 | */ | ||
| 717 | while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) { | ||
| 718 | bool next_msg_done = false; | ||
| 719 | |||
| 720 | /* | ||
| 721 | * Mark any dequeued buffer message as VIO_MSG_POLL_DONE so | ||
| 722 | * that can be properly freed even on timeout in mark_txdone. | ||
| 723 | */ | ||
| 724 | spin_lock(&next_msg->poll_lock); | ||
| 725 | if (next_msg->poll_status == VIO_MSG_POLLING) { | ||
| 726 | next_msg->poll_status = VIO_MSG_POLL_DONE; | ||
| 727 | next_msg_done = true; | ||
| 728 | } | ||
| 729 | spin_unlock(&next_msg->poll_lock); | ||
| 730 | |||
| 731 | next_msg->rx_len = length; | ||
| 732 | /* Is the message we were polling for ? */ | ||
| 733 | if (next_msg == msg) { | ||
| 734 | found = true; | ||
| 735 | break; | ||
| 736 | } else if (next_msg_done) { | ||
| 737 | /* Skip the rest if this was another polled msg */ | ||
| 738 | continue; | ||
| 739 | } | ||
| 740 | |||
| 741 | /* | ||
| 742 | * Enqueue for later processing any non-polled message and any | ||
| 743 | * timed-out polled one that we happen to have dequeued. | ||
| 744 | */ | ||
| 745 | spin_lock(&next_msg->poll_lock); | ||
| 746 | if (next_msg->poll_status == VIO_MSG_NOT_POLLED || | ||
| 747 | next_msg->poll_status == VIO_MSG_POLL_TIMEOUT) { | ||
| 748 | spin_unlock(&next_msg->poll_lock); | ||
| 749 | |||
| 750 | any_prefetched++; | ||
| 751 | spin_lock(&vioch->pending_lock); | ||
| 752 | list_add_tail(&next_msg->list, | ||
| 753 | &vioch->pending_cmds_list); | ||
| 754 | spin_unlock(&vioch->pending_lock); | ||
| 755 | } else { | ||
| 756 | spin_unlock(&next_msg->poll_lock); | ||
| 757 | } | ||
| 758 | } | ||
| 759 | |||
| 760 | /* | ||
| 761 | * When the polling loop has successfully terminated if something | ||
| 762 | * else was queued in the meantime, it will be served by a deferred | ||
| 763 | * worker OR by the normal IRQ/callback OR by other poll loops. | ||
| 764 | * | ||
| 765 | * If we are still looking for the polled reply, the polling index has | ||
| 766 | * to be updated to the current vqueue last used index. | ||
| 767 | */ | ||
| 768 | if (found) { | ||
| 769 | pending = !virtqueue_enable_cb(vioch->vqueue); | ||
| 770 | } else { | ||
| 771 | msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue); | ||
| 772 | pending = virtqueue_poll(vioch->vqueue, msg->poll_idx); | ||
| 773 | } | ||
| 774 | |||
| 775 | if (vioch->deferred_tx_wq && (any_prefetched || pending)) | ||
| 776 | queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work); | ||
| 777 | |||
| 778 | spin_unlock_irqrestore(&vioch->lock, flags); | ||
| 779 | |||
| 780 | scmi_vio_channel_release(vioch); | ||
| 781 | |||
| 782 | return found; | ||
| 369 | } | 783 | } |
| 370 | 784 | ||
| 371 | static const struct scmi_transport_ops scmi_virtio_ops = { | 785 | static const struct scmi_transport_ops scmi_virtio_ops = { |
| @@ -377,6 +791,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = { · 5 unmodified lines | |||
| 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 | ||
| 382 | static int scmi_vio_probe(struct virtio_device *vdev) | 798 | static int scmi_vio_probe(struct virtio_device *vdev) |
| @@ -417,8 +833,10 @@ static int scmi_vio_probe(struct virtio_device *vdev) · 34 unmodified lines | |||
| 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 | ||
| 461 | static int scmi_vio_validate(struct virtio_device *vdev) | 879 | static 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 | }; |
| @@ -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 | } |
| 45 | EXPORT_SYMBOL(imx_sc_rm_is_resource_owned); | 45 | EXPORT_SYMBOL(imx_sc_rm_is_resource_owned); |
| 46 | |||
| 47 | struct imx_sc_msg_rm_get_resource_owner { | ||
| 48 | struct imx_sc_rpc_msg hdr; | ||
| 49 | union { | ||
| 50 | struct { | ||
| 51 | u16 resource; | ||
| 52 | } req; | ||
| 53 | struct { | ||
| 54 | u8 val; | ||
| 55 | } resp; | ||
| 56 | } data; | ||
| 57 | } __packed __aligned(4); | ||
| 58 | |||
| 59 | /* | ||
| 60 | * This function get @resource partition number | ||
| 61 | * | ||
| 62 | * @param[in] ipc IPC handle | ||
| 63 | * @param[in] resource resource the control is associated with | ||
| 64 | * @param[out] pt pointer to return the partition number | ||
| 65 | * | ||
| 66 | * @return Returns 0 for success and < 0 for errors. | ||
| 67 | */ | ||
| 68 | int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt) | ||
| 69 | { | ||
| 70 | struct imx_sc_msg_rm_get_resource_owner msg; | ||
| 71 | struct imx_sc_rpc_msg *hdr = &msg.hdr; | ||
| 72 | int ret; | ||
| 73 | |||
| 74 | hdr->ver = IMX_SC_RPC_VERSION; | ||
| 75 | hdr->svc = IMX_SC_RPC_SVC_RM; | ||
| 76 | hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER; | ||
| 77 | hdr->size = 2; | ||
| 78 | |||
| 79 | msg.data.req.resource = resource; | ||
| 80 | |||
| 81 | ret = imx_scu_call_rpc(ipc, &msg, true); | ||
| 82 | if (ret) | ||
| 83 | return ret; | ||
| 84 | |||
| 85 | if (pt) | ||
| 86 | *pt = msg.data.resp.val; | ||
| 87 | |||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | EXPORT_SYMBOL(imx_sc_rm_get_resource_owner); | ||
| @@ -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 }, |
| @@ -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 0x00 | 52 | /* Each bit configures cold/warm boot address for one of the 4 CPUs */ |
| 53 | #define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01 | 53 | static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = { |
| 54 | #define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08 | 54 | 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 | |||
| 62 | struct qcom_scm_wb_entry { | ||
| 63 | int flag; | ||
| 64 | void *entry; | ||
| 65 | }; | 55 | }; |
| 66 | 56 | static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = { | |
| 67 | static 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 | ||
| 74 | static const char * const qcom_scm_convention_names[] = { | 60 | static 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 world | 166 | * qcom_scm_call() - Invoke a syscall in the secure world |
| 181 | * @dev: device | 167 | * @dev: device |
| 182 | * @svc_id: service identifier | ||
| 183 | * @cmd_id: command identifier | ||
| 184 | * @desc: Descriptor structure containing arguments and return values | 168 | * @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: device | 192 | * @dev: device |
| 208 | * @svc_id: service identifier | ||
| 209 | * @cmd_id: command identifier | ||
| 210 | * @desc: Descriptor structure containing arguments and return values | 193 | * @desc: Descriptor structure containing arguments and return values |
| 211 | * @res: Structure containing results from SMC/HVC call | 194 | * @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 | /** | 246 | static 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 | */ | ||
| 271 | int 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 point | 258 | 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 | } |
| 307 | EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); | ||
| 308 | 268 | ||
| 309 | /** | 269 | static 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 | */ | ||
| 317 | int 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 | */ | ||
| 298 | int qcom_scm_set_warm_boot_addr(void *entry) | ||
| 299 | { | ||
| 300 | if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_WARMBOOT)) | ||
| 301 | /* Fallback to old SCM call */ | ||
| 302 | return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_warm_bits); | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); | ||
| 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 | */ | ||
| 311 | int qcom_scm_set_cold_boot_addr(void *entry) | ||
| 312 | { | ||
| 313 | if (qcom_scm_set_boot_addr_mc(entry, QCOM_SCM_BOOT_MC_FLAG_COLDBOOT)) | ||
| 314 | /* Fallback to old SCM call */ | ||
| 315 | return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_cold_bits); | ||
| 316 | return 0; | ||
| 348 | } | 317 | } |
| 349 | EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); | 318 | EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); |
| 350 | 319 | ||
| 351 | /** | 320 | /** |
| 352 | * qcom_scm_cpu_power_down() - Power down the cpu | 321 | * qcom_scm_cpu_power_down() - Power down the cpu |
| 353 | * @flags - Flags to flush cache | 322 | * @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 the | 325 | * 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 metadata | 404 | * and optional blob of data used for authenticating the metadata |
| 436 | * and the rest of the firmware | 405 | * and the rest of the firmware |
| 437 | * @size: size of the metadata | 406 | * @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 | */ |
| 441 | int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) | 415 | int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, |
| 416 | struct qcom_scm_pas_metadata *ctx) | ||
| 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 | ||
| 478 | free_metadata: | 453 | out: |
| 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 | } |
| 483 | EXPORT_SYMBOL(qcom_scm_pas_init_image); | 464 | EXPORT_SYMBOL(qcom_scm_pas_init_image); |
| 484 | 465 | ||
| 466 | /** | ||
| 467 | * qcom_scm_pas_metadata_release() - release metadata context | ||
| 468 | * @ctx: metadata context | ||
| 469 | */ | ||
| 470 | void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx) | ||
| 471 | { | ||
| 472 | if (!ctx->ptr) | ||
| 473 | return; | ||
| 474 | |||
| 475 | dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys); | ||
| 476 | |||
| 477 | ctx->ptr = NULL; | ||
| 478 | ctx->phys = 0; | ||
| 479 | ctx->size = 0; | ||
| 480 | } | ||
| 481 | EXPORT_SYMBOL(qcom_scm_pas_metadata_release); | ||
| 482 | |||
| 485 | /** | 483 | /** |
| 486 | * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral | 484 | * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral |
| 487 | * for firmware loading | 485 | * 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 | } |
| 766 | EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); | 758 | EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); |
| 767 | 759 | ||
| 760 | int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size) | ||
| 761 | { | ||
| 762 | struct qcom_scm_desc desc = { | ||
| 763 | .svc = QCOM_SCM_SVC_MP, | ||
| 764 | .cmd = QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE, | ||
| 765 | .arginfo = QCOM_SCM_ARGS(2), | ||
| 766 | .args[0] = size, | ||
| 767 | .args[1] = spare, | ||
| 768 | .owner = ARM_SMCCC_OWNER_SIP, | ||
| 769 | }; | ||
| 770 | |||
| 771 | return qcom_scm_call(__scm->dev, &desc, NULL); | ||
| 772 | } | ||
| 773 | EXPORT_SYMBOL(qcom_scm_iommu_set_cp_pool_size); | ||
| 774 | |||
| 768 | int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, | 775 | int 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 | } |
| 1132 | EXPORT_SYMBOL(qcom_scm_hdcp_req); | 1139 | EXPORT_SYMBOL(qcom_scm_hdcp_req); |
| 1133 | 1140 | ||
| 1141 | int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt) | ||
| 1142 | { | ||
| 1143 | struct qcom_scm_desc desc = { | ||
| 1144 | .svc = QCOM_SCM_SVC_SMMU_PROGRAM, | ||
| 1145 | .cmd = QCOM_SCM_SMMU_PT_FORMAT, | ||
| 1146 | .arginfo = QCOM_SCM_ARGS(3), | ||
| 1147 | .args[0] = sec_id, | ||
| 1148 | .args[1] = ctx_num, | ||
| 1149 | .args[2] = pt_fmt, /* 0: LPAE AArch32 - 1: AArch64 */ | ||
| 1150 | .owner = ARM_SMCCC_OWNER_SIP, | ||
| 1151 | }; | ||
| 1152 | |||
| 1153 | return qcom_scm_call(__scm->dev, &desc, NULL); | ||
| 1154 | } | ||
| 1155 | EXPORT_SYMBOL(qcom_scm_iommu_set_pt_format); | ||
| 1156 | |||
| 1134 | int qcom_scm_qsmmu500_wait_safe_toggle(bool en) | 1157 | int qcom_scm_qsmmu500_wait_safe_toggle(bool en) |
| 1135 | { | 1158 | { |
| 1136 | struct qcom_scm_desc desc = { | 1159 | struct qcom_scm_desc desc = { |
| @@ -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 0x01 | 78 | #define QCOM_SCM_BOOT_SET_ADDR 0x01 |
| 79 | #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 | 79 | #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 |
| 80 | #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 | 80 | #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 0x0a | 82 | #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a |
| 82 | #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 | 83 | #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 0x02 | 89 | #define QCOM_SCM_SVC_PIL 0x02 |
| 85 | #define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x01 | 90 | #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 0x02 | 105 | #define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02 |
| 101 | #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 | 106 | #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 |
| 102 | #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 | 107 | #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 0x08 | 109 | #define QCOM_SCM_MP_VIDEO_VAR 0x08 |
| 104 | #define QCOM_SCM_MP_ASSIGN 0x16 | 110 | #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 0x10 | 125 | #define QCOM_SCM_LMH_LIMIT_DCVSH 0x10 |
| 120 | 126 | ||
| 121 | #define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 | 127 | #define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 |
| 128 | #define QCOM_SCM_SMMU_PT_FORMAT 0x01 | ||
| 122 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 | 129 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 |
| 123 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 | 130 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 |
| 124 | 131 | ||
| @@ -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 | ||
| @@ -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 to | 426 | * 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; |
| @@ -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) { |
| @@ -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 | ||
| 297 | err_free_nandirq: | ||
| 298 | free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); | ||
| 290 | err_free_irq: | 299 | err_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); |
| 292 | err_unmap_nandirq: | 301 | err_unmap_nandirq: |
| @@ -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 0x444 | 33 | #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 0x24 | 40 | #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 | ||
| 86 | struct mtk_smi_reg_pair { | 92 | struct 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. */ |
| 100 | static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"}; | 104 | static const char * const mtk_smi_larb_clks[] = {"apb", "smi", "gals"}; |
| 101 | #define MTK_SMI_LARB_REQ_CLK_NR 2 | 105 | #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 | */ |
| 108 | static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"}; | 112 | static const char * const mtk_smi_common_clks[] = {"apb", "smi", "gals0", "gals1"}; |
| 113 | #define MTK_SMI_CLK_NR_MAX ARRAY_SIZE(mtk_smi_common_clks) | ||
| 109 | #define MTK_SMI_COM_REQ_CLK_NR 2 | 114 | #define MTK_SMI_COM_REQ_CLK_NR 2 |
| 110 | #define MTK_SMI_COM_GALS_REQ_CLK_NR MTK_SMI_CLK_NR_MAX | 115 | #define MTK_SMI_COM_GALS_REQ_CLK_NR MTK_SMI_CLK_NR_MAX |
| 111 | #define MTK_SMI_SUB_COM_GALS_REQ_CLK_NR 3 | 116 | #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 | ||
| 343 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = { | ||
| 344 | .config_port = mtk_smi_larb_config_port_gen2_general, | ||
| 345 | .flags_general = MTK_SMI_FLAG_SLEEP_CTL, | ||
| 346 | }; | ||
| 347 | |||
| 338 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = { | 348 | static 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 | ||
| 342 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = { | 352 | static 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 | ||
| 372 | static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb) | ||
| 373 | { | ||
| 374 | int ret; | ||
| 375 | u32 tmp; | ||
| 376 | |||
| 377 | writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON); | ||
| 378 | ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON, | ||
| 379 | tmp, !!(tmp & SLP_PROT_RDY), 10, 1000); | ||
| 380 | if (ret) { | ||
| 381 | /* TODO: Reset this larb if it fails here. */ | ||
| 382 | dev_err(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp); | ||
| 383 | } | ||
| 384 | return ret; | ||
| 385 | } | ||
| 386 | |||
| 387 | static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb) | ||
| 388 | { | ||
| 389 | writel_relaxed(0, larb->base + SMI_LARB_SLP_CON); | ||
| 390 | } | ||
| 391 | |||
| 360 | static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev) | 392 | static 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 | |||
| 478 | static int __maybe_unused mtk_smi_larb_suspend(struct device *dev) | 513 | static 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 | ||
| 575 | static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = { | ||
| 576 | .type = MTK_SMI_GEN2, | ||
| 577 | .has_gals = true, | ||
| 578 | .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7), | ||
| 579 | }; | ||
| 580 | |||
| 533 | static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = { | 581 | static 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}, |
| @@ -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) |
| @@ -28,6 +28,7 @@ config TEGRA30_EMC · 27 unmodified lines | |||
| 28 | default y | 28 | default y |
| 29 | depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST | 29 | depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST |
| 30 | select PM_OPP | 30 | select PM_OPP |
| 31 | select DDR | ||
| 31 | help | 32 | help |
| 32 | This driver is for the External Memory Controller (EMC) found on | 33 | 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. |
| @@ -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 | ||
| @@ -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 | ||
| 714 | static struct thermal_cooling_device_ops tegra210_emc_cd_ops = { | 714 | static 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, |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | * Copyright (C) 2019 GRATE-DRIVER project | 9 | * 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 0x000 | 40 | #define EMC_INTSTATUS 0x000 |
| 37 | #define EMC_INTMASK 0x004 | 41 | #define EMC_INTMASK 0x004 |
| 38 | #define EMC_DBG 0x008 | 42 | #define EMC_DBG 0x008 |
| 43 | #define EMC_ADR_CFG 0x010 | ||
| 39 | #define EMC_CFG 0x00c | 44 | #define EMC_CFG 0x00c |
| 40 | #define EMC_REFCTRL 0x020 | 45 | #define EMC_REFCTRL 0x020 |
| 41 | #define EMC_TIMING_CONTROL 0x028 | 46 | #define EMC_TIMING_CONTROL 0x028 |
| @@ -81,6 +86,7 @@ · 39 unmodified lines | |||
| 81 | #define EMC_EMRS 0x0d0 | 86 | #define EMC_EMRS 0x0d0 |
| 82 | #define EMC_SELF_REF 0x0e0 | 87 | #define EMC_SELF_REF 0x0e0 |
| 83 | #define EMC_MRW 0x0e8 | 88 | #define EMC_MRW 0x0e8 |
| 89 | #define EMC_MRR 0x0ec | ||
| 84 | #define EMC_XM2DQSPADCTRL3 0x0f8 | 90 | #define EMC_XM2DQSPADCTRL3 0x0f8 |
| 85 | #define EMC_FBIO_SPARE 0x100 | 91 | #define EMC_FBIO_SPARE 0x100 |
| 86 | #define EMC_FBIO_CFG5 0x104 | 92 | #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 | ||
| 212 | enum emc_dram_type { | 225 | enum 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 | ||
| 383 | static int emc_seq_update_timing(struct tegra_emc *emc) | 398 | static int emc_seq_update_timing(struct tegra_emc *emc) |
| @@ -1008,12 +1023,18 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc, · 624 unmodified lines | |||
| 1008 | return 0; | 1023 | return 0; |
| 1009 | } | 1024 | } |
| 1010 | 1025 | ||
| 1011 | static struct device_node *emc_find_node_by_ram_code(struct device *dev) | 1026 | static struct device_node *emc_find_node_by_ram_code(struct tegra_emc *emc) |
| 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 | ||
| 1059 | static int emc_read_lpddr_mode_register(struct tegra_emc *emc, | ||
| 1060 | unsigned int emem_dev, | ||
| 1061 | unsigned int register_addr, | ||
| 1062 | unsigned int *register_data) | ||
| 1063 | { | ||
| 1064 | u32 memory_dev = emem_dev ? 1 : 2; | ||
| 1065 | u32 val, mr_mask = 0xff; | ||
| 1066 | int err; | ||
| 1067 | |||
| 1068 | /* clear data-valid interrupt status */ | ||
| 1069 | writel_relaxed(EMC_MRR_DIVLD_INT, emc->regs + EMC_INTSTATUS); | ||
| 1070 | |||
| 1071 | /* issue mode register read request */ | ||
| 1072 | val = FIELD_PREP(EMC_MRR_DEV_SELECTN, memory_dev); | ||
| 1073 | val |= FIELD_PREP(EMC_MRR_MRR_MA, register_addr); | ||
| 1074 | |||
| 1075 | writel_relaxed(val, emc->regs + EMC_MRR); | ||
| 1076 | |||
| 1077 | /* wait for the LPDDR2 data-valid interrupt */ | ||
| 1078 | err = readl_relaxed_poll_timeout_atomic(emc->regs + EMC_INTSTATUS, val, | ||
| 1079 | val & EMC_MRR_DIVLD_INT, | ||
| 1080 | 1, 100); | ||
| 1081 | if (err) { | ||
| 1082 | dev_err(emc->dev, "mode register %u read failed: %d\n", | ||
| 1083 | register_addr, err); | ||
| 1084 | emc->mrr_error = true; | ||
| 1085 | return err; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | /* read out mode register data */ | ||
| 1089 | val = readl_relaxed(emc->regs + EMC_MRR); | ||
| 1090 | *register_data = FIELD_GET(EMC_MRR_MRR_DATA, val) & mr_mask; | ||
| 1091 | |||
| 1092 | return 0; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | static void emc_read_lpddr_sdram_info(struct tegra_emc *emc, | ||
| 1096 | unsigned int emem_dev) | ||
| 1097 | { | ||
| 1098 | union lpddr2_basic_config4 basic_conf4; | ||
| 1099 | unsigned int manufacturer_id; | ||
| 1100 | unsigned int revision_id1; | ||
| 1101 | unsigned int revision_id2; | ||
| 1102 | |||
| 1103 | /* these registers are standard for all LPDDR JEDEC memory chips */ | ||
| 1104 | emc_read_lpddr_mode_register(emc, emem_dev, 5, &manufacturer_id); | ||
| 1105 | emc_read_lpddr_mode_register(emc, emem_dev, 6, &revision_id1); | ||
| 1106 | emc_read_lpddr_mode_register(emc, emem_dev, 7, &revision_id2); | ||
| 1107 | emc_read_lpddr_mode_register(emc, emem_dev, 8, &basic_conf4.value); | ||
| 1108 | |||
| 1109 | dev_info(emc->dev, "SDRAM[dev%u]: manufacturer: 0x%x (%s) rev1: 0x%x rev2: 0x%x prefetch: S%u density: %uMbit iowidth: %ubit\n", | ||
| 1110 | emem_dev, manufacturer_id, | ||
| 1111 | lpddr2_jedec_manufacturer(manufacturer_id), | ||
| 1112 | revision_id1, revision_id2, | ||
| 1113 | 4 >> basic_conf4.arch_type, | ||
| 1114 | 64 << basic_conf4.density, | ||
| 1115 | 32 >> basic_conf4.io_width); | ||
| 1116 | } | ||
| 1117 | |||
| 1038 | static int emc_setup_hw(struct tegra_emc *emc) | 1118 | static 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; |
| @@ -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 | ||
| 931 | static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) | 931 | static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw, |
| 932 | const char *fw_name) | ||
| 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 | ||
| @@ -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 | ||
| 84 | static void adsp_minidump(struct rproc *rproc) | 86 | static void adsp_minidump(struct rproc *rproc) |
| @@ -126,14 +128,34 @@ static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds, · 41 unmodified lines | |||
| 126 | } | 128 | } |
| 127 | } | 129 | } |
| 128 | 130 | ||
| 131 | static int adsp_unprepare(struct rproc *rproc) | ||
| 132 | { | ||
| 133 | struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; | ||
| 134 | |||
| 135 | /* | ||
| 136 | * adsp_load() did pass pas_metadata to the SCM driver for storing | ||
| 137 | * metadata context. It might have been released already if | ||
| 138 | * auth_and_reset() was successful, but in other cases clean it up | ||
| 139 | * here. | ||
| 140 | */ | ||
| 141 | qcom_scm_pas_metadata_release(&adsp->pas_metadata); | ||
| 142 | |||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 129 | static int adsp_load(struct rproc *rproc, const struct firmware *fw) | 146 | static 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 | ||
| 190 | disable_px_supply: | 214 | disable_px_supply: |
| @@ -255,6 +279,7 @@ static unsigned long adsp_panic(struct rproc *rproc) · 64 unmodified lines | |||
| 255 | } | 279 | } |
| 256 | 280 | ||
| 257 | static const struct rproc_ops adsp_ops = { | 281 | static 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 | ||
| 266 | static const struct rproc_ops adsp_minidump_ops = { | 291 | static 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 | }; |
| 858 | MODULE_DEVICE_TABLE(of, adsp_of_match); | 888 | MODULE_DEVICE_TABLE(of, adsp_of_match); |
| @@ -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 | ||
| 123 | static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = { | ||
| 124 | SEC_PD(S4_DOS_HEVC, 0), | ||
| 125 | SEC_PD(S4_DOS_VDEC, 0), | ||
| 126 | SEC_PD(S4_VPU_HDMI, 0), | ||
| 127 | SEC_PD(S4_USB_COMB, 0), | ||
| 128 | SEC_PD(S4_GE2D, 0), | ||
| 129 | /* ETH is for ethernet online wakeup, and should be always on */ | ||
| 130 | SEC_PD(S4_ETH, GENPD_FLAG_ALWAYS_ON), | ||
| 131 | SEC_PD(S4_DEMOD, 0), | ||
| 132 | SEC_PD(S4_AUDIO, 0), | ||
| 133 | }; | ||
| 134 | |||
| 122 | static int meson_secure_pwrc_probe(struct platform_device *pdev) | 135 | static 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 | ||
| 203 | static struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = { | ||
| 204 | .domains = s4_pwrc_domains, | ||
| 205 | .count = ARRAY_SIZE(s4_pwrc_domains), | ||
| 206 | }; | ||
| 207 | |||
| 190 | static const struct of_device_id meson_secure_pwrc_match_table[] = { | 208 | static 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 | }; |
| 197 | MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table); | 219 | MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table); |
| @@ -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"), |
| @@ -95,6 +95,7 @@ at91_soc_init(const struct at91_soc *socs); · 94 unmodified lines | |||
| 95 | #define SAMA5D28C_LD2G_EXID_MATCH 0x00000072 | 95 | #define SAMA5D28C_LD2G_EXID_MATCH 0x00000072 |
| 96 | #define SAMA5D28CU_EXID_MATCH 0x00000010 | 96 | #define SAMA5D28CU_EXID_MATCH 0x00000010 |
| 97 | #define SAMA5D28CN_EXID_MATCH 0x00000020 | 97 | #define SAMA5D28CN_EXID_MATCH 0x00000020 |
| 98 | #define SAMA5D29CN_EXID_MATCH 0x00000023 | ||
| 98 | 99 | ||
| 99 | #define SAMA5D3_CIDR_MATCH 0x0a5c07c0 | 100 | #define SAMA5D3_CIDR_MATCH 0x0a5c07c0 |
| 100 | #define SAMA5D31_EXID_MATCH 0x00444300 | 101 | #define SAMA5D31_EXID_MATCH 0x00444300 |
| @@ -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 0x0 | 20 | #define BLK_SFT_RSTN 0x0 |
| 20 | #define BLK_CLK_EN 0x4 | 21 | #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 | ||
| 593 | static int imx8mq_vpu_power_notifier(struct notifier_block *nb, | ||
| 594 | unsigned long action, void *data) | ||
| 595 | { | ||
| 596 | struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, | ||
| 597 | power_nb); | ||
| 598 | |||
| 599 | if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) | ||
| 600 | return NOTIFY_OK; | ||
| 601 | |||
| 602 | /* | ||
| 603 | * The ADB in the VPUMIX domain has no separate reset and clock | ||
| 604 | * enable bits, but is ungated and reset together with the VPUs. The | ||
| 605 | * reset and clock enable inputs to the ADB is a logical OR of the | ||
| 606 | * VPU bits. In order to set the G2 fuse bits, the G2 clock must | ||
| 607 | * also be enabled. | ||
| 608 | */ | ||
| 609 | regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1)); | ||
| 610 | regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1)); | ||
| 611 | |||
| 612 | if (action == GENPD_NOTIFY_ON) { | ||
| 613 | /* | ||
| 614 | * On power up we have no software backchannel to the GPC to | ||
| 615 | * wait for the ADB handshake to happen, so we just delay for a | ||
| 616 | * bit. On power down the GPC driver waits for the handshake. | ||
| 617 | */ | ||
| 618 | udelay(5); | ||
| 619 | |||
| 620 | /* set "fuse" bits to enable the VPUs */ | ||
| 621 | regmap_set_bits(bc->regmap, 0x8, 0xffffffff); | ||
| 622 | regmap_set_bits(bc->regmap, 0xc, 0xffffffff); | ||
| 623 | regmap_set_bits(bc->regmap, 0x10, 0xffffffff); | ||
| 624 | } | ||
| 625 | |||
| 626 | return NOTIFY_OK; | ||
| 627 | } | ||
| 628 | |||
| 629 | static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = { | ||
| 630 | [IMX8MQ_VPUBLK_PD_G1] = { | ||
| 631 | .name = "vpublk-g1", | ||
| 632 | .clk_names = (const char *[]){ "g1", }, | ||
| 633 | .num_clks = 1, | ||
| 634 | .gpc_name = "g1", | ||
| 635 | .rst_mask = BIT(1), | ||
| 636 | .clk_mask = BIT(1), | ||
| 637 | }, | ||
| 638 | [IMX8MQ_VPUBLK_PD_G2] = { | ||
| 639 | .name = "vpublk-g2", | ||
| 640 | .clk_names = (const char *[]){ "g2", }, | ||
| 641 | .num_clks = 1, | ||
| 642 | .gpc_name = "g2", | ||
| 643 | .rst_mask = BIT(0), | ||
| 644 | .clk_mask = BIT(0), | ||
| 645 | }, | ||
| 646 | }; | ||
| 647 | |||
| 648 | static const struct imx8m_blk_ctrl_data imx8mq_vpu_blk_ctl_dev_data = { | ||
| 649 | .max_reg = 0x14, | ||
| 650 | .power_notifier_fn = imx8mq_vpu_power_notifier, | ||
| 651 | .domains = imx8mq_vpu_blk_ctl_domain_data, | ||
| 652 | .num_domains = ARRAY_SIZE(imx8mq_vpu_blk_ctl_domain_data), | ||
| 653 | }; | ||
| 654 | |||
| 592 | static const struct of_device_id imx8m_blk_ctrl_of_match[] = { | 655 | static 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_data | 664 | .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 | } |
| @@ -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; |
| @@ -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 | |||
| 85 | static const struct scpsys_soc_data mt8167_scpsys_data = { | 99 | static 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 */ |
| @@ -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 | |||
| 98 | static const struct scpsys_soc_data mt8173_scpsys_data = { | 118 | static 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 */ |
| @@ -25,6 +25,8 @@ · 24 unmodified lines | |||
| 25 | #define MT8183_RDMA0_SOUT_COLOR0 0x1 | 25 | #define MT8183_RDMA0_SOUT_COLOR0 0x1 |
| 26 | #define MT8183_RDMA1_SOUT_DSI0 0x1 | 26 | #define MT8183_RDMA1_SOUT_DSI0 0x1 |
| 27 | 27 | ||
| 28 | #define MT8183_MMSYS_SW0_RST_B 0x140 | ||
| 29 | |||
| 28 | static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = { | 30 | static 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, |
| @@ -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 | |||
| 230 | static const struct scpsys_soc_data mt8183_scpsys_data = { | 260 | static 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 */ |
| @@ -0,0 +1,115 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | |||
| 3 | #ifndef __SOC_MEDIATEK_MT8186_MMSYS_H | ||
| 4 | #define __SOC_MEDIATEK_MT8186_MMSYS_H | ||
| 5 | |||
| 6 | #define MT8186_MMSYS_OVL_CON 0xF04 | ||
| 7 | #define MT8186_MMSYS_OVL0_CON_MASK 0x3 | ||
| 8 | #define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC | ||
| 9 | #define MT8186_OVL0_GO_BLEND BIT(0) | ||
| 10 | #define MT8186_OVL0_GO_BG BIT(1) | ||
| 11 | #define MT8186_OVL0_2L_GO_BLEND BIT(2) | ||
| 12 | #define MT8186_OVL0_2L_GO_BG BIT(3) | ||
| 13 | #define MT8186_DISP_RDMA0_SOUT_SEL 0xF0C | ||
| 14 | #define MT8186_RDMA0_SOUT_SEL_MASK 0xF | ||
| 15 | #define MT8186_RDMA0_SOUT_TO_DSI0 (0) | ||
| 16 | #define MT8186_RDMA0_SOUT_TO_COLOR0 (1) | ||
| 17 | #define MT8186_RDMA0_SOUT_TO_DPI0 (2) | ||
| 18 | #define MT8186_DISP_OVL0_2L_MOUT_EN 0xF14 | ||
| 19 | #define MT8186_OVL0_2L_MOUT_EN_MASK 0xF | ||
| 20 | #define MT8186_OVL0_2L_MOUT_TO_RDMA0 BIT(0) | ||
| 21 | #define MT8186_OVL0_2L_MOUT_TO_RDMA1 BIT(3) | ||
| 22 | #define MT8186_DISP_OVL0_MOUT_EN 0xF18 | ||
| 23 | #define MT8186_OVL0_MOUT_EN_MASK 0xF | ||
| 24 | #define MT8186_OVL0_MOUT_TO_RDMA0 BIT(0) | ||
| 25 | #define MT8186_OVL0_MOUT_TO_RDMA1 BIT(3) | ||
| 26 | #define MT8186_DISP_DITHER0_MOUT_EN 0xF20 | ||
| 27 | #define MT8186_DITHER0_MOUT_EN_MASK 0xF | ||
| 28 | #define MT8186_DITHER0_MOUT_TO_DSI0 BIT(0) | ||
| 29 | #define MT8186_DITHER0_MOUT_TO_RDMA1 BIT(2) | ||
| 30 | #define MT8186_DITHER0_MOUT_TO_DPI0 BIT(3) | ||
| 31 | #define MT8186_DISP_RDMA0_SEL_IN 0xF28 | ||
| 32 | #define MT8186_RDMA0_SEL_IN_MASK 0xF | ||
| 33 | #define MT8186_RDMA0_FROM_OVL0 0 | ||
| 34 | #define MT8186_RDMA0_FROM_OVL0_2L 2 | ||
| 35 | #define MT8186_DISP_DSI0_SEL_IN 0xF30 | ||
| 36 | #define MT8186_DSI0_SEL_IN_MASK 0xF | ||
| 37 | #define MT8186_DSI0_FROM_RDMA0 0 | ||
| 38 | #define MT8186_DSI0_FROM_DITHER0 1 | ||
| 39 | #define MT8186_DSI0_FROM_RDMA1 2 | ||
| 40 | #define MT8186_DISP_RDMA1_MOUT_EN 0xF3C | ||
| 41 | #define MT8186_RDMA1_MOUT_EN_MASK 0xF | ||
| 42 | #define MT8186_RDMA1_MOUT_TO_DPI0_SEL BIT(0) | ||
| 43 | #define MT8186_RDMA1_MOUT_TO_DSI0_SEL BIT(2) | ||
| 44 | #define MT8186_DISP_RDMA1_SEL_IN 0xF40 | ||
| 45 | #define MT8186_RDMA1_SEL_IN_MASK 0xF | ||
| 46 | #define MT8186_RDMA1_FROM_OVL0 0 | ||
| 47 | #define MT8186_RDMA1_FROM_OVL0_2L 2 | ||
| 48 | #define MT8186_RDMA1_FROM_DITHER0 3 | ||
| 49 | #define MT8186_DISP_DPI0_SEL_IN 0xF44 | ||
| 50 | #define MT8186_DPI0_SEL_IN_MASK 0xF | ||
| 51 | #define MT8186_DPI0_FROM_RDMA1 0 | ||
| 52 | #define MT8186_DPI0_FROM_DITHER0 1 | ||
| 53 | #define MT8186_DPI0_FROM_RDMA0 2 | ||
| 54 | |||
| 55 | #define MT8186_MMSYS_SW0_RST_B 0x160 | ||
| 56 | |||
| 57 | static const struct mtk_mmsys_routes mmsys_mt8186_routing_table[] = { | ||
| 58 | { | ||
| 59 | DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, | ||
| 60 | MT8186_DISP_OVL0_MOUT_EN, MT8186_OVL0_MOUT_EN_MASK, | ||
| 61 | MT8186_OVL0_MOUT_TO_RDMA0 | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, | ||
| 65 | MT8186_DISP_RDMA0_SEL_IN, MT8186_RDMA0_SEL_IN_MASK, | ||
| 66 | MT8186_RDMA0_FROM_OVL0 | ||
| 67 | }, | ||
| 68 | { | ||
| 69 | DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0, | ||
| 70 | MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_CON_MASK, | ||
| 71 | MT8186_OVL0_GO_BLEND | ||
| 72 | }, | ||
| 73 | { | ||
| 74 | DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0, | ||
| 75 | MT8186_DISP_RDMA0_SOUT_SEL, MT8186_RDMA0_SOUT_SEL_MASK, | ||
| 76 | MT8186_RDMA0_SOUT_TO_COLOR0 | ||
| 77 | }, | ||
| 78 | { | ||
| 79 | DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0, | ||
| 80 | MT8186_DISP_DITHER0_MOUT_EN, MT8186_DITHER0_MOUT_EN_MASK, | ||
| 81 | MT8186_DITHER0_MOUT_TO_DSI0, | ||
| 82 | }, | ||
| 83 | { | ||
| 84 | DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0, | ||
| 85 | MT8186_DISP_DSI0_SEL_IN, MT8186_DSI0_SEL_IN_MASK, | ||
| 86 | MT8186_DSI0_FROM_DITHER0 | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1, | ||
| 90 | MT8186_DISP_OVL0_2L_MOUT_EN, MT8186_OVL0_2L_MOUT_EN_MASK, | ||
| 91 | MT8186_OVL0_2L_MOUT_TO_RDMA1 | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1, | ||
| 95 | MT8186_DISP_RDMA1_SEL_IN, MT8186_RDMA1_SEL_IN_MASK, | ||
| 96 | MT8186_RDMA1_FROM_OVL0_2L | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1, | ||
| 100 | MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_2L_CON_MASK, | ||
| 101 | MT8186_OVL0_2L_GO_BLEND | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, | ||
| 105 | MT8186_DISP_RDMA1_MOUT_EN, MT8186_RDMA1_MOUT_EN_MASK, | ||
| 106 | MT8186_RDMA1_MOUT_TO_DPI0_SEL | ||
| 107 | }, | ||
| 108 | { | ||
| 109 | DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0, | ||
| 110 | MT8186_DISP_DPI0_SEL_IN, MT8186_DPI0_SEL_IN_MASK, | ||
| 111 | MT8186_DPI0_FROM_RDMA1 | ||
| 112 | }, | ||
| 113 | }; | ||
| 114 | |||
| 115 | #endif /* __SOC_MEDIATEK_MT8186_MMSYS_H */ | ||
| @@ -0,0 +1,344 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022 MediaTek Inc. | ||
| 4 | * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __SOC_MEDIATEK_MT8186_PM_DOMAINS_H | ||
| 8 | #define __SOC_MEDIATEK_MT8186_PM_DOMAINS_H | ||
| 9 | |||
| 10 | #include "mtk-pm-domains.h" | ||
| 11 | #include <dt-bindings/power/mt8186-power.h> | ||
| 12 | |||
| 13 | /* | ||
| 14 | * MT8186 power domain support | ||
| 15 | */ | ||
| 16 | |||
| 17 | static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = { | ||
| 18 | [MT8186_POWER_DOMAIN_MFG0] = { | ||
| 19 | .name = "mfg0", | ||
| 20 | .sta_mask = BIT(2), | ||
| 21 | .ctl_offs = 0x308, | ||
| 22 | .pwr_sta_offs = 0x16C, | ||
| 23 | .pwr_sta2nd_offs = 0x170, | ||
| 24 | .sram_pdn_bits = BIT(8), | ||
| 25 | .sram_pdn_ack_bits = BIT(12), | ||
| 26 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, | ||
| 27 | }, | ||
| 28 | [MT8186_POWER_DOMAIN_MFG1] = { | ||
| 29 | .name = "mfg1", | ||
| 30 | .sta_mask = BIT(3), | ||
| 31 | .ctl_offs = 0x30c, | ||
| 32 | .pwr_sta_offs = 0x16C, | ||
| 33 | .pwr_sta2nd_offs = 0x170, | ||
| 34 | .sram_pdn_bits = BIT(8), | ||
| 35 | .sram_pdn_ack_bits = BIT(12), | ||
| 36 | .bp_infracfg = { | ||
| 37 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1, | ||
| 38 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 39 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 40 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 41 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP2, | ||
| 42 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 43 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 44 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 45 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP3, | ||
| 46 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 47 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 48 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 49 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4, | ||
| 50 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 51 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 52 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 53 | }, | ||
| 54 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 55 | }, | ||
| 56 | [MT8186_POWER_DOMAIN_MFG2] = { | ||
| 57 | .name = "mfg2", | ||
| 58 | .sta_mask = BIT(4), | ||
| 59 | .ctl_offs = 0x310, | ||
| 60 | .pwr_sta_offs = 0x16C, | ||
| 61 | .pwr_sta2nd_offs = 0x170, | ||
| 62 | .sram_pdn_bits = BIT(8), | ||
| 63 | .sram_pdn_ack_bits = BIT(12), | ||
| 64 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 65 | }, | ||
| 66 | [MT8186_POWER_DOMAIN_MFG3] = { | ||
| 67 | .name = "mfg3", | ||
| 68 | .sta_mask = BIT(5), | ||
| 69 | .ctl_offs = 0x314, | ||
| 70 | .pwr_sta_offs = 0x16C, | ||
| 71 | .pwr_sta2nd_offs = 0x170, | ||
| 72 | .sram_pdn_bits = BIT(8), | ||
| 73 | .sram_pdn_ack_bits = BIT(12), | ||
| 74 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 75 | }, | ||
| 76 | [MT8186_POWER_DOMAIN_SSUSB] = { | ||
| 77 | .name = "ssusb", | ||
| 78 | .sta_mask = BIT(20), | ||
| 79 | .ctl_offs = 0x9F0, | ||
| 80 | .pwr_sta_offs = 0x16C, | ||
| 81 | .pwr_sta2nd_offs = 0x170, | ||
| 82 | .sram_pdn_bits = BIT(8), | ||
| 83 | .sram_pdn_ack_bits = BIT(12), | ||
| 84 | .caps = MTK_SCPD_ACTIVE_WAKEUP, | ||
| 85 | }, | ||
| 86 | [MT8186_POWER_DOMAIN_SSUSB_P1] = { | ||
| 87 | .name = "ssusb_p1", | ||
| 88 | .sta_mask = BIT(19), | ||
| 89 | .ctl_offs = 0x9F4, | ||
| 90 | .pwr_sta_offs = 0x16C, | ||
| 91 | .pwr_sta2nd_offs = 0x170, | ||
| 92 | .sram_pdn_bits = BIT(8), | ||
| 93 | .sram_pdn_ack_bits = BIT(12), | ||
| 94 | .caps = MTK_SCPD_ACTIVE_WAKEUP, | ||
| 95 | }, | ||
| 96 | [MT8186_POWER_DOMAIN_DIS] = { | ||
| 97 | .name = "dis", | ||
| 98 | .sta_mask = BIT(21), | ||
| 99 | .ctl_offs = 0x354, | ||
| 100 | .pwr_sta_offs = 0x16C, | ||
| 101 | .pwr_sta2nd_offs = 0x170, | ||
| 102 | .sram_pdn_bits = BIT(8), | ||
| 103 | .sram_pdn_ack_bits = BIT(12), | ||
| 104 | .bp_infracfg = { | ||
| 105 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1, | ||
| 106 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 107 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 108 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 109 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_DIS_STEP2, | ||
| 110 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 111 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 112 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 113 | }, | ||
| 114 | }, | ||
| 115 | [MT8186_POWER_DOMAIN_IMG] = { | ||
| 116 | .name = "img", | ||
| 117 | .sta_mask = BIT(13), | ||
| 118 | .ctl_offs = 0x334, | ||
| 119 | .pwr_sta_offs = 0x16C, | ||
| 120 | .pwr_sta2nd_offs = 0x170, | ||
| 121 | .sram_pdn_bits = BIT(8), | ||
| 122 | .sram_pdn_ack_bits = BIT(12), | ||
| 123 | .bp_infracfg = { | ||
| 124 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1, | ||
| 125 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 126 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 127 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 128 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2, | ||
| 129 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 130 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 131 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 132 | }, | ||
| 133 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 134 | }, | ||
| 135 | [MT8186_POWER_DOMAIN_IMG2] = { | ||
| 136 | .name = "img2", | ||
| 137 | .sta_mask = BIT(14), | ||
| 138 | .ctl_offs = 0x338, | ||
| 139 | .pwr_sta_offs = 0x16C, | ||
| 140 | .pwr_sta2nd_offs = 0x170, | ||
| 141 | .sram_pdn_bits = BIT(8), | ||
| 142 | .sram_pdn_ack_bits = BIT(12), | ||
| 143 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 144 | }, | ||
| 145 | [MT8186_POWER_DOMAIN_IPE] = { | ||
| 146 | .name = "ipe", | ||
| 147 | .sta_mask = BIT(15), | ||
| 148 | .ctl_offs = 0x33C, | ||
| 149 | .pwr_sta_offs = 0x16C, | ||
| 150 | .pwr_sta2nd_offs = 0x170, | ||
| 151 | .sram_pdn_bits = BIT(8), | ||
| 152 | .sram_pdn_ack_bits = BIT(12), | ||
| 153 | .bp_infracfg = { | ||
| 154 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1, | ||
| 155 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 156 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 157 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 158 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2, | ||
| 159 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 160 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 161 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 162 | }, | ||
| 163 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 164 | }, | ||
| 165 | [MT8186_POWER_DOMAIN_CAM] = { | ||
| 166 | .name = "cam", | ||
| 167 | .sta_mask = BIT(23), | ||
| 168 | .ctl_offs = 0x35C, | ||
| 169 | .pwr_sta_offs = 0x16C, | ||
| 170 | .pwr_sta2nd_offs = 0x170, | ||
| 171 | .sram_pdn_bits = BIT(8), | ||
| 172 | .sram_pdn_ack_bits = BIT(12), | ||
| 173 | .bp_infracfg = { | ||
| 174 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1, | ||
| 175 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 176 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 177 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 178 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2, | ||
| 179 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 180 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 181 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 182 | }, | ||
| 183 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 184 | }, | ||
| 185 | [MT8186_POWER_DOMAIN_CAM_RAWA] = { | ||
| 186 | .name = "cam_rawa", | ||
| 187 | .sta_mask = BIT(24), | ||
| 188 | .ctl_offs = 0x360, | ||
| 189 | .pwr_sta_offs = 0x16C, | ||
| 190 | .pwr_sta2nd_offs = 0x170, | ||
| 191 | .sram_pdn_bits = BIT(8), | ||
| 192 | .sram_pdn_ack_bits = BIT(12), | ||
| 193 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 194 | }, | ||
| 195 | [MT8186_POWER_DOMAIN_CAM_RAWB] = { | ||
| 196 | .name = "cam_rawb", | ||
| 197 | .sta_mask = BIT(25), | ||
| 198 | .ctl_offs = 0x364, | ||
| 199 | .pwr_sta_offs = 0x16C, | ||
| 200 | .pwr_sta2nd_offs = 0x170, | ||
| 201 | .sram_pdn_bits = BIT(8), | ||
| 202 | .sram_pdn_ack_bits = BIT(12), | ||
| 203 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 204 | }, | ||
| 205 | [MT8186_POWER_DOMAIN_VENC] = { | ||
| 206 | .name = "venc", | ||
| 207 | .sta_mask = BIT(18), | ||
| 208 | .ctl_offs = 0x348, | ||
| 209 | .pwr_sta_offs = 0x16C, | ||
| 210 | .pwr_sta2nd_offs = 0x170, | ||
| 211 | .sram_pdn_bits = BIT(8), | ||
| 212 | .sram_pdn_ack_bits = BIT(12), | ||
| 213 | .bp_infracfg = { | ||
| 214 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1, | ||
| 215 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 216 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 217 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 218 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2, | ||
| 219 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 220 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 221 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 222 | }, | ||
| 223 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 224 | }, | ||
| 225 | [MT8186_POWER_DOMAIN_VDEC] = { | ||
| 226 | .name = "vdec", | ||
| 227 | .sta_mask = BIT(16), | ||
| 228 | .ctl_offs = 0x340, | ||
| 229 | .pwr_sta_offs = 0x16C, | ||
| 230 | .pwr_sta2nd_offs = 0x170, | ||
| 231 | .sram_pdn_bits = BIT(8), | ||
| 232 | .sram_pdn_ack_bits = BIT(12), | ||
| 233 | .bp_infracfg = { | ||
| 234 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1, | ||
| 235 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 236 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 237 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 238 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2, | ||
| 239 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 240 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 241 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 242 | }, | ||
| 243 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 244 | }, | ||
| 245 | [MT8186_POWER_DOMAIN_WPE] = { | ||
| 246 | .name = "wpe", | ||
| 247 | .sta_mask = BIT(0), | ||
| 248 | .ctl_offs = 0x3F8, | ||
| 249 | .pwr_sta_offs = 0x16C, | ||
| 250 | .pwr_sta2nd_offs = 0x170, | ||
| 251 | .sram_pdn_bits = BIT(8), | ||
| 252 | .sram_pdn_ack_bits = BIT(12), | ||
| 253 | .bp_infracfg = { | ||
| 254 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1, | ||
| 255 | MT8186_TOP_AXI_PROT_EN_2_SET, | ||
| 256 | MT8186_TOP_AXI_PROT_EN_2_CLR, | ||
| 257 | MT8186_TOP_AXI_PROT_EN_2_STA), | ||
| 258 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2, | ||
| 259 | MT8186_TOP_AXI_PROT_EN_2_SET, | ||
| 260 | MT8186_TOP_AXI_PROT_EN_2_CLR, | ||
| 261 | MT8186_TOP_AXI_PROT_EN_2_STA), | ||
| 262 | }, | ||
| 263 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 264 | }, | ||
| 265 | [MT8186_POWER_DOMAIN_CONN_ON] = { | ||
| 266 | .name = "conn_on", | ||
| 267 | .sta_mask = BIT(1), | ||
| 268 | .ctl_offs = 0x304, | ||
| 269 | .pwr_sta_offs = 0x16C, | ||
| 270 | .pwr_sta2nd_offs = 0x170, | ||
| 271 | .bp_infracfg = { | ||
| 272 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1, | ||
| 273 | MT8186_TOP_AXI_PROT_EN_1_SET, | ||
| 274 | MT8186_TOP_AXI_PROT_EN_1_CLR, | ||
| 275 | MT8186_TOP_AXI_PROT_EN_1_STA), | ||
| 276 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2, | ||
| 277 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 278 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 279 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 280 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3, | ||
| 281 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 282 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 283 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 284 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4, | ||
| 285 | MT8186_TOP_AXI_PROT_EN_SET, | ||
| 286 | MT8186_TOP_AXI_PROT_EN_CLR, | ||
| 287 | MT8186_TOP_AXI_PROT_EN_STA), | ||
| 288 | }, | ||
| 289 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, | ||
| 290 | }, | ||
| 291 | [MT8186_POWER_DOMAIN_CSIRX_TOP] = { | ||
| 292 | .name = "csirx_top", | ||
| 293 | .sta_mask = BIT(6), | ||
| 294 | .ctl_offs = 0x318, | ||
| 295 | .pwr_sta_offs = 0x16C, | ||
| 296 | .pwr_sta2nd_offs = 0x170, | ||
| 297 | .sram_pdn_bits = BIT(8), | ||
| 298 | .sram_pdn_ack_bits = BIT(12), | ||
| 299 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 300 | }, | ||
| 301 | [MT8186_POWER_DOMAIN_ADSP_AO] = { | ||
| 302 | .name = "adsp_ao", | ||
| 303 | .sta_mask = BIT(17), | ||
| 304 | .ctl_offs = 0x9FC, | ||
| 305 | .pwr_sta_offs = 0x16C, | ||
| 306 | .pwr_sta2nd_offs = 0x170, | ||
| 307 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 308 | }, | ||
| 309 | [MT8186_POWER_DOMAIN_ADSP_INFRA] = { | ||
| 310 | .name = "adsp_infra", | ||
| 311 | .sta_mask = BIT(10), | ||
| 312 | .ctl_offs = 0x9F8, | ||
| 313 | .pwr_sta_offs = 0x16C, | ||
| 314 | .pwr_sta2nd_offs = 0x170, | ||
| 315 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 316 | }, | ||
| 317 | [MT8186_POWER_DOMAIN_ADSP_TOP] = { | ||
| 318 | .name = "adsp_top", | ||
| 319 | .sta_mask = BIT(31), | ||
| 320 | .ctl_offs = 0x3E4, | ||
| 321 | .pwr_sta_offs = 0x16C, | ||
| 322 | .pwr_sta2nd_offs = 0x170, | ||
| 323 | .sram_pdn_bits = BIT(8), | ||
| 324 | .sram_pdn_ack_bits = BIT(12), | ||
| 325 | .bp_infracfg = { | ||
| 326 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1, | ||
| 327 | MT8186_TOP_AXI_PROT_EN_3_SET, | ||
| 328 | MT8186_TOP_AXI_PROT_EN_3_CLR, | ||
| 329 | MT8186_TOP_AXI_PROT_EN_3_STA), | ||
| 330 | BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2, | ||
| 331 | MT8186_TOP_AXI_PROT_EN_3_SET, | ||
| 332 | MT8186_TOP_AXI_PROT_EN_3_CLR, | ||
| 333 | MT8186_TOP_AXI_PROT_EN_3_STA), | ||
| 334 | }, | ||
| 335 | .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, | ||
| 336 | }, | ||
| 337 | }; | ||
| 338 | |||
| 339 | static const struct scpsys_soc_data mt8186_scpsys_data = { | ||
| 340 | .domains_data = scpsys_domain_data_mt8186, | ||
| 341 | .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8186), | ||
| 342 | }; | ||
| 343 | |||
| 344 | #endif /* __SOC_MEDIATEK_MT8186_PM_DOMAINS_H */ | ||
| @@ -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 | |||
| 306 | static const struct scpsys_soc_data mt8192_scpsys_data = { | 348 | static 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 */ |
| @@ -0,0 +1,613 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2021 MediaTek Inc. | ||
| 4 | * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __SOC_MEDIATEK_MT8195_PM_DOMAINS_H | ||
| 8 | #define __SOC_MEDIATEK_MT8195_PM_DOMAINS_H | ||
| 9 | |||
| 10 | #include "mtk-pm-domains.h" | ||
| 11 | #include <dt-bindings/power/mt8195-power.h> | ||
| 12 | |||
| 13 | /* | ||
| 14 | * MT8195 power domain support | ||
| 15 | */ | ||
| 16 | |||
| 17 | static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = { | ||
| 18 | [MT8195_POWER_DOMAIN_PCIE_MAC_P0] = { | ||
| 19 | .name = "pcie_mac_p0", | ||
| 20 | .sta_mask = BIT(11), | ||
| 21 | .ctl_offs = 0x328, | ||
| 22 | .pwr_sta_offs = 0x174, | ||
| 23 | .pwr_sta2nd_offs = 0x178, | ||
| 24 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 25 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 26 | .bp_infracfg = { | ||
| 27 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0, | ||
| 28 | MT8195_TOP_AXI_PROT_EN_VDNR_SET, | ||
| 29 | MT8195_TOP_AXI_PROT_EN_VDNR_CLR, | ||
| 30 | MT8195_TOP_AXI_PROT_EN_VDNR_STA1), | ||
| 31 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0, | ||
| 32 | MT8195_TOP_AXI_PROT_EN_VDNR_1_SET, | ||
| 33 | MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR, | ||
| 34 | MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1), | ||
| 35 | }, | ||
| 36 | }, | ||
| 37 | [MT8195_POWER_DOMAIN_PCIE_MAC_P1] = { | ||
| 38 | .name = "pcie_mac_p1", | ||
| 39 | .sta_mask = BIT(12), | ||
| 40 | .ctl_offs = 0x32C, | ||
| 41 | .pwr_sta_offs = 0x174, | ||
| 42 | .pwr_sta2nd_offs = 0x178, | ||
| 43 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 44 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 45 | .bp_infracfg = { | ||
| 46 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1, | ||
| 47 | MT8195_TOP_AXI_PROT_EN_VDNR_SET, | ||
| 48 | MT8195_TOP_AXI_PROT_EN_VDNR_CLR, | ||
| 49 | MT8195_TOP_AXI_PROT_EN_VDNR_STA1), | ||
| 50 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1, | ||
| 51 | MT8195_TOP_AXI_PROT_EN_VDNR_1_SET, | ||
| 52 | MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR, | ||
| 53 | MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1), | ||
| 54 | }, | ||
| 55 | }, | ||
| 56 | [MT8195_POWER_DOMAIN_PCIE_PHY] = { | ||
| 57 | .name = "pcie_phy", | ||
| 58 | .sta_mask = BIT(13), | ||
| 59 | .ctl_offs = 0x330, | ||
| 60 | .pwr_sta_offs = 0x174, | ||
| 61 | .pwr_sta2nd_offs = 0x178, | ||
| 62 | .caps = MTK_SCPD_ACTIVE_WAKEUP, | ||
| 63 | }, | ||
| 64 | [MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY] = { | ||
| 65 | .name = "ssusb_pcie_phy", | ||
| 66 | .sta_mask = BIT(14), | ||
| 67 | .ctl_offs = 0x334, | ||
| 68 | .pwr_sta_offs = 0x174, | ||
| 69 | .pwr_sta2nd_offs = 0x178, | ||
| 70 | .caps = MTK_SCPD_ACTIVE_WAKEUP, | ||
| 71 | }, | ||
| 72 | [MT8195_POWER_DOMAIN_CSI_RX_TOP] = { | ||
| 73 | .name = "csi_rx_top", | ||
| 74 | .sta_mask = BIT(18), | ||
| 75 | .ctl_offs = 0x3C4, | ||
| 76 | .pwr_sta_offs = 0x174, | ||
| 77 | .pwr_sta2nd_offs = 0x178, | ||
| 78 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 79 | }, | ||
| 80 | [MT8195_POWER_DOMAIN_ETHER] = { | ||
| 81 | .name = "ether", | ||
| 82 | .sta_mask = BIT(3), | ||
| 83 | .ctl_offs = 0x344, | ||
| 84 | .pwr_sta_offs = 0x16c, | ||
| 85 | .pwr_sta2nd_offs = 0x170, | ||
| 86 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 87 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 88 | .caps = MTK_SCPD_ACTIVE_WAKEUP, | ||
| 89 | }, | ||
| 90 | [MT8195_POWER_DOMAIN_ADSP] = { | ||
| 91 | .name = "adsp", | ||
| 92 | .sta_mask = BIT(10), | ||
| 93 | .ctl_offs = 0x360, | ||
| 94 | .pwr_sta_offs = 0x16c, | ||
| 95 | .pwr_sta2nd_offs = 0x170, | ||
| 96 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 97 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 98 | .bp_infracfg = { | ||
| 99 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_ADSP, | ||
| 100 | MT8195_TOP_AXI_PROT_EN_2_SET, | ||
| 101 | MT8195_TOP_AXI_PROT_EN_2_CLR, | ||
| 102 | MT8195_TOP_AXI_PROT_EN_2_STA1), | ||
| 103 | }, | ||
| 104 | .caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP, | ||
| 105 | }, | ||
| 106 | [MT8195_POWER_DOMAIN_AUDIO] = { | ||
| 107 | .name = "audio", | ||
| 108 | .sta_mask = BIT(8), | ||
| 109 | .ctl_offs = 0x358, | ||
| 110 | .pwr_sta_offs = 0x16c, | ||
| 111 | .pwr_sta2nd_offs = 0x170, | ||
| 112 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 113 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 114 | .bp_infracfg = { | ||
| 115 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_AUDIO, | ||
| 116 | MT8195_TOP_AXI_PROT_EN_2_SET, | ||
| 117 | MT8195_TOP_AXI_PROT_EN_2_CLR, | ||
| 118 | MT8195_TOP_AXI_PROT_EN_2_STA1), | ||
| 119 | }, | ||
| 120 | }, | ||
| 121 | [MT8195_POWER_DOMAIN_MFG0] = { | ||
| 122 | .name = "mfg0", | ||
| 123 | .sta_mask = BIT(1), | ||
| 124 | .ctl_offs = 0x300, | ||
| 125 | .pwr_sta_offs = 0x174, | ||
| 126 | .pwr_sta2nd_offs = 0x178, | ||
| 127 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 128 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 129 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY, | ||
| 130 | }, | ||
| 131 | [MT8195_POWER_DOMAIN_MFG1] = { | ||
| 132 | .name = "mfg1", | ||
| 133 | .sta_mask = BIT(2), | ||
| 134 | .ctl_offs = 0x304, | ||
| 135 | .pwr_sta_offs = 0x174, | ||
| 136 | .pwr_sta2nd_offs = 0x178, | ||
| 137 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 138 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 139 | .bp_infracfg = { | ||
| 140 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1, | ||
| 141 | MT8195_TOP_AXI_PROT_EN_SET, | ||
| 142 | MT8195_TOP_AXI_PROT_EN_CLR, | ||
| 143 | MT8195_TOP_AXI_PROT_EN_STA1), | ||
| 144 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1, | ||
| 145 | MT8195_TOP_AXI_PROT_EN_2_SET, | ||
| 146 | MT8195_TOP_AXI_PROT_EN_2_CLR, | ||
| 147 | MT8195_TOP_AXI_PROT_EN_2_STA1), | ||
| 148 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_MFG1, | ||
| 149 | MT8195_TOP_AXI_PROT_EN_1_SET, | ||
| 150 | MT8195_TOP_AXI_PROT_EN_1_CLR, | ||
| 151 | MT8195_TOP_AXI_PROT_EN_1_STA1), | ||
| 152 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND, | ||
| 153 | MT8195_TOP_AXI_PROT_EN_2_SET, | ||
| 154 | MT8195_TOP_AXI_PROT_EN_2_CLR, | ||
| 155 | MT8195_TOP_AXI_PROT_EN_2_STA1), | ||
| 156 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1_2ND, | ||
| 157 | MT8195_TOP_AXI_PROT_EN_SET, | ||
| 158 | MT8195_TOP_AXI_PROT_EN_CLR, | ||
| 159 | MT8195_TOP_AXI_PROT_EN_STA1), | ||
| 160 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1, | ||
| 161 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, | ||
| 162 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, | ||
| 163 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1), | ||
| 164 | }, | ||
| 165 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 166 | }, | ||
| 167 | [MT8195_POWER_DOMAIN_MFG2] = { | ||
| 168 | .name = "mfg2", | ||
| 169 | .sta_mask = BIT(3), | ||
| 170 | .ctl_offs = 0x308, | ||
| 171 | .pwr_sta_offs = 0x174, | ||
| 172 | .pwr_sta2nd_offs = 0x178, | ||
| 173 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 174 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 175 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 176 | }, | ||
| 177 | [MT8195_POWER_DOMAIN_MFG3] = { | ||
| 178 | .name = "mfg3", | ||
| 179 | .sta_mask = BIT(4), | ||
| 180 | .ctl_offs = 0x30C, | ||
| 181 | .pwr_sta_offs = 0x174, | ||
| 182 | .pwr_sta2nd_offs = 0x178, | ||
| 183 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 184 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 185 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 186 | }, | ||
| 187 | [MT8195_POWER_DOMAIN_MFG4] = { | ||
| 188 | .name = "mfg4", | ||
| 189 | .sta_mask = BIT(5), | ||
| 190 | .ctl_offs = 0x310, | ||
| 191 | .pwr_sta_offs = 0x174, | ||
| 192 | .pwr_sta2nd_offs = 0x178, | ||
| 193 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 194 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 195 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 196 | }, | ||
| 197 | [MT8195_POWER_DOMAIN_MFG5] = { | ||
| 198 | .name = "mfg5", | ||
| 199 | .sta_mask = BIT(6), | ||
| 200 | .ctl_offs = 0x314, | ||
| 201 | .pwr_sta_offs = 0x174, | ||
| 202 | .pwr_sta2nd_offs = 0x178, | ||
| 203 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 204 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 205 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 206 | }, | ||
| 207 | [MT8195_POWER_DOMAIN_MFG6] = { | ||
| 208 | .name = "mfg6", | ||
| 209 | .sta_mask = BIT(7), | ||
| 210 | .ctl_offs = 0x318, | ||
| 211 | .pwr_sta_offs = 0x174, | ||
| 212 | .pwr_sta2nd_offs = 0x178, | ||
| 213 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 214 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 215 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 216 | }, | ||
| 217 | [MT8195_POWER_DOMAIN_VPPSYS0] = { | ||
| 218 | .name = "vppsys0", | ||
| 219 | .sta_mask = BIT(11), | ||
| 220 | .ctl_offs = 0x364, | ||
| 221 | .pwr_sta_offs = 0x16c, | ||
| 222 | .pwr_sta2nd_offs = 0x170, | ||
| 223 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 224 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 225 | .bp_infracfg = { | ||
| 226 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0, | ||
| 227 | MT8195_TOP_AXI_PROT_EN_SET, | ||
| 228 | MT8195_TOP_AXI_PROT_EN_CLR, | ||
| 229 | MT8195_TOP_AXI_PROT_EN_STA1), | ||
| 230 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0, | ||
| 231 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 232 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 233 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 234 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND, | ||
| 235 | MT8195_TOP_AXI_PROT_EN_SET, | ||
| 236 | MT8195_TOP_AXI_PROT_EN_CLR, | ||
| 237 | MT8195_TOP_AXI_PROT_EN_STA1), | ||
| 238 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND, | ||
| 239 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 240 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 241 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 242 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0, | ||
| 243 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, | ||
| 244 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, | ||
| 245 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1), | ||
| 246 | }, | ||
| 247 | }, | ||
| 248 | [MT8195_POWER_DOMAIN_VDOSYS0] = { | ||
| 249 | .name = "vdosys0", | ||
| 250 | .sta_mask = BIT(13), | ||
| 251 | .ctl_offs = 0x36C, | ||
| 252 | .pwr_sta_offs = 0x16c, | ||
| 253 | .pwr_sta2nd_offs = 0x170, | ||
| 254 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 255 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 256 | .bp_infracfg = { | ||
| 257 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0, | ||
| 258 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 259 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 260 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 261 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDOSYS0, | ||
| 262 | MT8195_TOP_AXI_PROT_EN_SET, | ||
| 263 | MT8195_TOP_AXI_PROT_EN_CLR, | ||
| 264 | MT8195_TOP_AXI_PROT_EN_STA1), | ||
| 265 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0, | ||
| 266 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET, | ||
| 267 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR, | ||
| 268 | MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1), | ||
| 269 | }, | ||
| 270 | }, | ||
| 271 | [MT8195_POWER_DOMAIN_VPPSYS1] = { | ||
| 272 | .name = "vppsys1", | ||
| 273 | .sta_mask = BIT(12), | ||
| 274 | .ctl_offs = 0x368, | ||
| 275 | .pwr_sta_offs = 0x16c, | ||
| 276 | .pwr_sta2nd_offs = 0x170, | ||
| 277 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 278 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 279 | .bp_infracfg = { | ||
| 280 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1, | ||
| 281 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 282 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 283 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 284 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND, | ||
| 285 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 286 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 287 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 288 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1, | ||
| 289 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 290 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 291 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 292 | }, | ||
| 293 | }, | ||
| 294 | [MT8195_POWER_DOMAIN_VDOSYS1] = { | ||
| 295 | .name = "vdosys1", | ||
| 296 | .sta_mask = BIT(14), | ||
| 297 | .ctl_offs = 0x370, | ||
| 298 | .pwr_sta_offs = 0x16c, | ||
| 299 | .pwr_sta2nd_offs = 0x170, | ||
| 300 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 301 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 302 | .bp_infracfg = { | ||
| 303 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1, | ||
| 304 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 305 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 306 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 307 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND, | ||
| 308 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 309 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 310 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 311 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1, | ||
| 312 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 313 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 314 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 315 | }, | ||
| 316 | }, | ||
| 317 | [MT8195_POWER_DOMAIN_DP_TX] = { | ||
| 318 | .name = "dp_tx", | ||
| 319 | .sta_mask = BIT(16), | ||
| 320 | .ctl_offs = 0x378, | ||
| 321 | .pwr_sta_offs = 0x16c, | ||
| 322 | .pwr_sta2nd_offs = 0x170, | ||
| 323 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 324 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 325 | .bp_infracfg = { | ||
| 326 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX, | ||
| 327 | MT8195_TOP_AXI_PROT_EN_VDNR_1_SET, | ||
| 328 | MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR, | ||
| 329 | MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1), | ||
| 330 | }, | ||
| 331 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 332 | }, | ||
| 333 | [MT8195_POWER_DOMAIN_EPD_TX] = { | ||
| 334 | .name = "epd_tx", | ||
| 335 | .sta_mask = BIT(17), | ||
| 336 | .ctl_offs = 0x37C, | ||
| 337 | .pwr_sta_offs = 0x16c, | ||
| 338 | .pwr_sta2nd_offs = 0x170, | ||
| 339 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 340 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 341 | .bp_infracfg = { | ||
| 342 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX, | ||
| 343 | MT8195_TOP_AXI_PROT_EN_VDNR_1_SET, | ||
| 344 | MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR, | ||
| 345 | MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1), | ||
| 346 | }, | ||
| 347 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 348 | }, | ||
| 349 | [MT8195_POWER_DOMAIN_HDMI_TX] = { | ||
| 350 | .name = "hdmi_tx", | ||
| 351 | .sta_mask = BIT(18), | ||
| 352 | .ctl_offs = 0x380, | ||
| 353 | .pwr_sta_offs = 0x16c, | ||
| 354 | .pwr_sta2nd_offs = 0x170, | ||
| 355 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 356 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 357 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP, | ||
| 358 | }, | ||
| 359 | [MT8195_POWER_DOMAIN_WPESYS] = { | ||
| 360 | .name = "wpesys", | ||
| 361 | .sta_mask = BIT(15), | ||
| 362 | .ctl_offs = 0x374, | ||
| 363 | .pwr_sta_offs = 0x16c, | ||
| 364 | .pwr_sta2nd_offs = 0x170, | ||
| 365 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 366 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 367 | .bp_infracfg = { | ||
| 368 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS, | ||
| 369 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 370 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 371 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 372 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_WPESYS, | ||
| 373 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 374 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 375 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 376 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND, | ||
| 377 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 378 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 379 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 380 | }, | ||
| 381 | }, | ||
| 382 | [MT8195_POWER_DOMAIN_VDEC0] = { | ||
| 383 | .name = "vdec0", | ||
| 384 | .sta_mask = BIT(20), | ||
| 385 | .ctl_offs = 0x388, | ||
| 386 | .pwr_sta_offs = 0x16c, | ||
| 387 | .pwr_sta2nd_offs = 0x170, | ||
| 388 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 389 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 390 | .bp_infracfg = { | ||
| 391 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0, | ||
| 392 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 393 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 394 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 395 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0, | ||
| 396 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 397 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 398 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 399 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND, | ||
| 400 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 401 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 402 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 403 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND, | ||
| 404 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 405 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 406 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 407 | }, | ||
| 408 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 409 | }, | ||
| 410 | [MT8195_POWER_DOMAIN_VDEC1] = { | ||
| 411 | .name = "vdec1", | ||
| 412 | .sta_mask = BIT(21), | ||
| 413 | .ctl_offs = 0x38C, | ||
| 414 | .pwr_sta_offs = 0x16c, | ||
| 415 | .pwr_sta2nd_offs = 0x170, | ||
| 416 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 417 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 418 | .bp_infracfg = { | ||
| 419 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1, | ||
| 420 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 421 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 422 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 423 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND, | ||
| 424 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 425 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 426 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 427 | }, | ||
| 428 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 429 | }, | ||
| 430 | [MT8195_POWER_DOMAIN_VDEC2] = { | ||
| 431 | .name = "vdec2", | ||
| 432 | .sta_mask = BIT(22), | ||
| 433 | .ctl_offs = 0x390, | ||
| 434 | .pwr_sta_offs = 0x16c, | ||
| 435 | .pwr_sta2nd_offs = 0x170, | ||
| 436 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 437 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 438 | .bp_infracfg = { | ||
| 439 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2, | ||
| 440 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 441 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 442 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 443 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND, | ||
| 444 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 445 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 446 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 447 | }, | ||
| 448 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 449 | }, | ||
| 450 | [MT8195_POWER_DOMAIN_VENC] = { | ||
| 451 | .name = "venc", | ||
| 452 | .sta_mask = BIT(23), | ||
| 453 | .ctl_offs = 0x394, | ||
| 454 | .pwr_sta_offs = 0x16c, | ||
| 455 | .pwr_sta2nd_offs = 0x170, | ||
| 456 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 457 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 458 | .bp_infracfg = { | ||
| 459 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC, | ||
| 460 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 461 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 462 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 463 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND, | ||
| 464 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 465 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 466 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 467 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC, | ||
| 468 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 469 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 470 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 471 | }, | ||
| 472 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 473 | }, | ||
| 474 | [MT8195_POWER_DOMAIN_VENC_CORE1] = { | ||
| 475 | .name = "venc_core1", | ||
| 476 | .sta_mask = BIT(24), | ||
| 477 | .ctl_offs = 0x398, | ||
| 478 | .pwr_sta_offs = 0x16c, | ||
| 479 | .pwr_sta2nd_offs = 0x170, | ||
| 480 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 481 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 482 | .bp_infracfg = { | ||
| 483 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1, | ||
| 484 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 485 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 486 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 487 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1, | ||
| 488 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 489 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 490 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 491 | }, | ||
| 492 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 493 | }, | ||
| 494 | [MT8195_POWER_DOMAIN_IMG] = { | ||
| 495 | .name = "img", | ||
| 496 | .sta_mask = BIT(29), | ||
| 497 | .ctl_offs = 0x3AC, | ||
| 498 | .pwr_sta_offs = 0x16c, | ||
| 499 | .pwr_sta2nd_offs = 0x170, | ||
| 500 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 501 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 502 | .bp_infracfg = { | ||
| 503 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG, | ||
| 504 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 505 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 506 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 507 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND, | ||
| 508 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 509 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 510 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 511 | }, | ||
| 512 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 513 | }, | ||
| 514 | [MT8195_POWER_DOMAIN_DIP] = { | ||
| 515 | .name = "dip", | ||
| 516 | .sta_mask = BIT(30), | ||
| 517 | .ctl_offs = 0x3B0, | ||
| 518 | .pwr_sta_offs = 0x16c, | ||
| 519 | .pwr_sta2nd_offs = 0x170, | ||
| 520 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 521 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 522 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 523 | }, | ||
| 524 | [MT8195_POWER_DOMAIN_IPE] = { | ||
| 525 | .name = "ipe", | ||
| 526 | .sta_mask = BIT(31), | ||
| 527 | .ctl_offs = 0x3B4, | ||
| 528 | .pwr_sta_offs = 0x16c, | ||
| 529 | .pwr_sta2nd_offs = 0x170, | ||
| 530 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 531 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 532 | .bp_infracfg = { | ||
| 533 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IPE, | ||
| 534 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 535 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 536 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 537 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_IPE, | ||
| 538 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 539 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 540 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 541 | }, | ||
| 542 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 543 | }, | ||
| 544 | [MT8195_POWER_DOMAIN_CAM] = { | ||
| 545 | .name = "cam", | ||
| 546 | .sta_mask = BIT(25), | ||
| 547 | .ctl_offs = 0x39C, | ||
| 548 | .pwr_sta_offs = 0x16c, | ||
| 549 | .pwr_sta2nd_offs = 0x170, | ||
| 550 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 551 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 552 | .bp_infracfg = { | ||
| 553 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_CAM, | ||
| 554 | MT8195_TOP_AXI_PROT_EN_2_SET, | ||
| 555 | MT8195_TOP_AXI_PROT_EN_2_CLR, | ||
| 556 | MT8195_TOP_AXI_PROT_EN_2_STA1), | ||
| 557 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM, | ||
| 558 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 559 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 560 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 561 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_CAM, | ||
| 562 | MT8195_TOP_AXI_PROT_EN_1_SET, | ||
| 563 | MT8195_TOP_AXI_PROT_EN_1_CLR, | ||
| 564 | MT8195_TOP_AXI_PROT_EN_1_STA1), | ||
| 565 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND, | ||
| 566 | MT8195_TOP_AXI_PROT_EN_MM_SET, | ||
| 567 | MT8195_TOP_AXI_PROT_EN_MM_CLR, | ||
| 568 | MT8195_TOP_AXI_PROT_EN_MM_STA1), | ||
| 569 | BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_CAM, | ||
| 570 | MT8195_TOP_AXI_PROT_EN_MM_2_SET, | ||
| 571 | MT8195_TOP_AXI_PROT_EN_MM_2_CLR, | ||
| 572 | MT8195_TOP_AXI_PROT_EN_MM_2_STA1), | ||
| 573 | }, | ||
| 574 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 575 | }, | ||
| 576 | [MT8195_POWER_DOMAIN_CAM_RAWA] = { | ||
| 577 | .name = "cam_rawa", | ||
| 578 | .sta_mask = BIT(26), | ||
| 579 | .ctl_offs = 0x3A0, | ||
| 580 | .pwr_sta_offs = 0x16c, | ||
| 581 | .pwr_sta2nd_offs = 0x170, | ||
| 582 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 583 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 584 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 585 | }, | ||
| 586 | [MT8195_POWER_DOMAIN_CAM_RAWB] = { | ||
| 587 | .name = "cam_rawb", | ||
| 588 | .sta_mask = BIT(27), | ||
| 589 | .ctl_offs = 0x3A4, | ||
| 590 | .pwr_sta_offs = 0x16c, | ||
| 591 | .pwr_sta2nd_offs = 0x170, | ||
| 592 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 593 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 594 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 595 | }, | ||
| 596 | [MT8195_POWER_DOMAIN_CAM_MRAW] = { | ||
| 597 | .name = "cam_mraw", | ||
| 598 | .sta_mask = BIT(28), | ||
| 599 | .ctl_offs = 0x3A8, | ||
| 600 | .pwr_sta_offs = 0x16c, | ||
| 601 | .pwr_sta2nd_offs = 0x170, | ||
| 602 | .sram_pdn_bits = GENMASK(8, 8), | ||
| 603 | .sram_pdn_ack_bits = GENMASK(12, 12), | ||
| 604 | .caps = MTK_SCPD_KEEP_DEFAULT_OFF, | ||
| 605 | }, | ||
| 606 | }; | ||
| 607 | |||
| 608 | static const struct scpsys_soc_data mt8195_scpsys_data = { | ||
| 609 | .domains_data = scpsys_domain_data_mt8195, | ||
| 610 | .num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195), | ||
| 611 | }; | ||
| 612 | |||
| 613 | #endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */ | ||
| @@ -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 | |||
| 77 | static int __init mtk_infracfg_init(void) | ||
| 78 | { | ||
| 79 | struct regmap *infracfg; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * MT8192 has an experimental path to route GPU traffic to the DSU's | ||
| 83 | * Accelerator Coherency Port, which is inadvertently enabled by | ||
| 84 | * default. It turns out not to work, so disable it to prevent spurious | ||
| 85 | * GPU faults. | ||
| 86 | */ | ||
| 87 | infracfg = syscon_regmap_lookup_by_compatible("mediatek,mt8192-infracfg"); | ||
| 88 | if (!IS_ERR(infracfg)) | ||
| 89 | regmap_set_bits(infracfg, MT8192_INFRA_CTRL, | ||
| 90 | MT8192_INFRA_CTRL_DISABLE_MFG2ACP); | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | postcore_initcall(mtk_infracfg_init); | ||
| @@ -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 | ||
| 53 | static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = { | 55 | static 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 | |||
| 62 | static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = { | ||
| 63 | .clk_driver = "clk-mt8186-mm", | ||
| 64 | .routes = mmsys_mt8186_routing_table, | ||
| 65 | .num_routes = ARRAY_SIZE(mmsys_mt8186_routing_table), | ||
| 66 | .sw0_rst_offset = MT8186_MMSYS_SW0_RST_B, | ||
| 57 | }; | 67 | }; |
| 58 | 68 | ||
| 59 | static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { | 69 | static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = { |
| @@ -121,14 +131,14 @@ static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned l · 61 unmodified lines | |||
| 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 | else | 138 | 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, |
| @@ -78,8 +78,6 @@ · 77 unmodified lines | |||
| 78 | #define DSI_SEL_IN_RDMA 0x1 | 78 | #define DSI_SEL_IN_RDMA 0x1 |
| 79 | #define DSI_SEL_IN_MASK 0x1 | 79 | #define DSI_SEL_IN_MASK 0x1 |
| 80 | 80 | ||
| 81 | #define MMSYS_SW0_RST_B 0x140 | ||
| 82 | |||
| 83 | struct mtk_mmsys_routes { | 81 | struct 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 | /* |
| @@ -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 1 | 46 | #define MT8167_MUTEX_MOD_DISP_PWM 1 |
| 30 | #define MT8167_MUTEX_MOD_DISP_OVL0 6 | 47 | #define MT8167_MUTEX_MOD_DISP_OVL0 6 |
| 31 | #define MT8167_MUTEX_MOD_DISP_OVL1 7 | 48 | #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 | ||
| 246 | static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { | ||
| 247 | [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0, | ||
| 248 | [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0, | ||
| 249 | [DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0, | ||
| 250 | [DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0, | ||
| 251 | [DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0, | ||
| 252 | [DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0, | ||
| 253 | [DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L, | ||
| 254 | [DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0, | ||
| 255 | [DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0, | ||
| 256 | [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, | ||
| 257 | }; | ||
| 258 | |||
| 229 | static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { | 259 | static 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 | ||
| 297 | static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = { | ||
| 298 | [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, | ||
| 299 | [MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0, | ||
| 300 | [MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0, | ||
| 301 | }; | ||
| 302 | |||
| 267 | static const struct mtk_mutex_data mt2701_mutex_driver_data = { | 303 | static 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 | ||
| 340 | static const struct mtk_mutex_data mt8186_mutex_driver_data = { | ||
| 341 | .mutex_mod = mt8186_mutex_mod, | ||
| 342 | .mutex_sof = mt8186_mutex_sof, | ||
| 343 | .mutex_mod_reg = MT8183_MUTEX0_MOD0, | ||
| 344 | .mutex_sof_reg = MT8183_MUTEX0_SOF0, | ||
| 345 | }; | ||
| 346 | |||
| 304 | static const struct mtk_mutex_data mt8192_mutex_driver_data = { | 347 | static 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 | {}, |
| @@ -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 10 | 26 | #define MTK_POLL_DELAY_US 10 |
| 25 | #define MTK_POLL_TIMEOUT USEC_PER_SEC | 27 | #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 | else | 453 | 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 | ||
| @@ -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 5 | 40 | #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 flow | 76 | * 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 | ||
| 99 | struct scpsys_soc_data { | 99 | struct 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 */ |
| @@ -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 */ |
| 82 | enum dew_regs { | 84 | enum 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 | ||
| 1068 | static int mt8186_regs[] = { | ||
| 1069 | [PWRAP_MUX_SEL] = 0x0, | ||
| 1070 | [PWRAP_WRAP_EN] = 0x4, | ||
| 1071 | [PWRAP_DIO_EN] = 0x8, | ||
| 1072 | [PWRAP_RDDMY] = 0x20, | ||
| 1073 | [PWRAP_CSHEXT_WRITE] = 0x24, | ||
| 1074 | [PWRAP_CSHEXT_READ] = 0x28, | ||
| 1075 | [PWRAP_CSLEXT_WRITE] = 0x2C, | ||
| 1076 | [PWRAP_CSLEXT_READ] = 0x30, | ||
| 1077 | [PWRAP_EXT_CK_WRITE] = 0x34, | ||
| 1078 | [PWRAP_STAUPD_CTRL] = 0x3C, | ||
| 1079 | [PWRAP_STAUPD_GRPEN] = 0x40, | ||
| 1080 | [PWRAP_EINT_STA0_ADR] = 0x44, | ||
| 1081 | [PWRAP_EINT_STA1_ADR] = 0x48, | ||
| 1082 | [PWRAP_INT_CLR] = 0xC8, | ||
| 1083 | [PWRAP_INT_FLG] = 0xC4, | ||
| 1084 | [PWRAP_MAN_EN] = 0x7C, | ||
| 1085 | [PWRAP_MAN_CMD] = 0x80, | ||
| 1086 | [PWRAP_WACS0_EN] = 0x8C, | ||
| 1087 | [PWRAP_WACS1_EN] = 0x94, | ||
| 1088 | [PWRAP_WACS2_EN] = 0x9C, | ||
| 1089 | [PWRAP_INIT_DONE0] = 0x90, | ||
| 1090 | [PWRAP_INIT_DONE1] = 0x98, | ||
| 1091 | [PWRAP_INIT_DONE2] = 0xA0, | ||
| 1092 | [PWRAP_INT_EN] = 0xBC, | ||
| 1093 | [PWRAP_INT1_EN] = 0xCC, | ||
| 1094 | [PWRAP_INT1_FLG] = 0xD4, | ||
| 1095 | [PWRAP_INT1_CLR] = 0xD8, | ||
| 1096 | [PWRAP_TIMER_EN] = 0xF0, | ||
| 1097 | [PWRAP_WDT_UNIT] = 0xF8, | ||
| 1098 | [PWRAP_WDT_SRC_EN] = 0xFC, | ||
| 1099 | [PWRAP_WDT_SRC_EN_1] = 0x100, | ||
| 1100 | [PWRAP_WDT_FLG] = 0x104, | ||
| 1101 | [PWRAP_SPMINF_STA] = 0x1B4, | ||
| 1102 | [PWRAP_DCM_EN] = 0x1EC, | ||
| 1103 | [PWRAP_DCM_DBC_PRD] = 0x1F0, | ||
| 1104 | [PWRAP_GPSINF_0_STA] = 0x204, | ||
| 1105 | [PWRAP_GPSINF_1_STA] = 0x208, | ||
| 1106 | [PWRAP_WACS0_CMD] = 0xC00, | ||
| 1107 | [PWRAP_WACS0_RDATA] = 0xC04, | ||
| 1108 | [PWRAP_WACS0_VLDCLR] = 0xC08, | ||
| 1109 | [PWRAP_WACS1_CMD] = 0xC10, | ||
| 1110 | [PWRAP_WACS1_RDATA] = 0xC14, | ||
| 1111 | [PWRAP_WACS1_VLDCLR] = 0xC18, | ||
| 1112 | [PWRAP_WACS2_CMD] = 0xC20, | ||
| 1113 | [PWRAP_WACS2_RDATA] = 0xC24, | ||
| 1114 | [PWRAP_WACS2_VLDCLR] = 0xC28, | ||
| 1115 | }; | ||
| 1116 | |||
| 1066 | enum pmic_type { | 1117 | enum 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 | ||
| 2125 | static struct pmic_wrapper_type pwrap_mt8186 = { | ||
| 2126 | .regs = mt8186_regs, | ||
| 2127 | .type = PWRAP_MT8186, | ||
| 2128 | .arb_en_all = 0xfb27f, | ||
| 2129 | .int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1 */ | ||
| 2130 | .int1_en_all = 0x000017ff, /* disable Matching interrupt for bit 13 */ | ||
| 2131 | .spi_w = PWRAP_MAN_CMD_SPI_WRITE, | ||
| 2132 | .wdt_src = PWRAP_WDT_SRC_MASK_ALL, | ||
| 2133 | .caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_ARB_MT8186, | ||
| 2134 | .init_reg_clock = pwrap_common_init_reg_clock, | ||
| 2135 | .init_soc_specific = NULL, | ||
| 2136 | }; | ||
| 2137 | |||
| 2072 | static const struct of_device_id of_pwrap_match_tbl[] = { | 2138 | static 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 | else | 2283 | else |
| 2213 | mask_done = PWRAP_STATE_INIT_DONE0; | 2284 | mask_done = PWRAP_STATE_INIT_DONE0; |
| 2214 | 2285 | ||
| @@ -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); |
| @@ -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 | ||
| @@ -29,17 +29,13 @@ · 28 unmodified lines | |||
| 29 | #define ATTR1_FIXED_SIZE_SHIFT 0x03 | 29 | #define ATTR1_FIXED_SIZE_SHIFT 0x03 |
| 30 | #define ATTR1_PRIORITY_SHIFT 0x04 | 30 | #define ATTR1_PRIORITY_SHIFT 0x04 |
| 31 | #define ATTR1_MAX_CAP_SHIFT 0x10 | 31 | #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 0x10 | 34 | #define ATTR0_BONUS_WAYS_SHIFT 0x10 |
| 35 | #define LLCC_STATUS_READ_DELAY 100 | 35 | #define LLCC_STATUS_READ_DELAY 100 |
| 36 | 36 | ||
| 37 | #define CACHE_LINE_SIZE_SHIFT 6 | 37 | #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 28 | 40 | #define LLCC_LB_CNT_SHIFT 28 |
| 45 | 41 | ||
| @@ -52,9 +48,13 @@ · 6 unmodified lines | |||
| 52 | #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 | 48 | #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 |
| 53 | #define LLCC_TRP_PCB_ACT 0x21f04 | 49 | #define LLCC_TRP_PCB_ACT 0x21f04 |
| 54 | #define LLCC_TRP_WRSC_EN 0x21f20 | 50 | #define LLCC_TRP_WRSC_EN 0x21f20 |
| 51 | #define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c | ||
| 55 | 52 | ||
| 56 | #define BANK_OFFSET_STRIDE 0x80000 | 53 | #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 slice | 59 | * struct llcc_slice_config - Data associated with the llcc slice |
| 60 | * @usecase_id: Unique id for the client's use case | 60 | * @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 programmed | 80 | * @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 | */ |
| 83 | struct llcc_slice_config { | 85 | struct 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 | ||
| 99 | struct qcom_llcc_config { | 102 | struct 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 | |||
| 109 | enum llcc_reg_offset { | ||
| 110 | LLCC_COMMON_HW_INFO, | ||
| 111 | LLCC_COMMON_STATUS0, | ||
| 103 | }; | 112 | }; |
| 104 | 113 | ||
| 105 | static const struct llcc_slice_config sc7180_data[] = { | 114 | static 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 | ||
| 229 | static const struct llcc_slice_config sm8450_data[] = { | ||
| 230 | {LLCC_CPUSS, 1, 3072, 1, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 }, | ||
| 231 | {LLCC_VIDSC0, 2, 512, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 232 | {LLCC_AUDIO, 6, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 233 | {LLCC_MDMHPGRW, 7, 1024, 3, 0, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 234 | {LLCC_MODHW, 9, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 235 | {LLCC_CMPT, 10, 4096, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 236 | {LLCC_GPUHTW, 11, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 237 | {LLCC_GPU, 12, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 1, 0 }, | ||
| 238 | {LLCC_MMUHWT, 13, 768, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, | ||
| 239 | {LLCC_DISP, 16, 4096, 2, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 240 | {LLCC_MDMPNG, 21, 1024, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 241 | {LLCC_AUDHW, 22, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 242 | {LLCC_CVP, 28, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 243 | {LLCC_MODPE, 29, 64, 1, 1, 0xF000, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 244 | {LLCC_APTCM, 30, 1024, 3, 1, 0x0, 0xF0, 1, 0, 0, 1, 0, 0, 0 }, | ||
| 245 | {LLCC_WRCACHE, 31, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, | ||
| 246 | {LLCC_CVPFW, 17, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 247 | {LLCC_CPUSS1, 3, 1024, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 248 | {LLCC_CAMEXP0, 4, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 249 | {LLCC_CPUMTE, 23, 256, 1, 1, 0x0FFF, 0x0, 0, 0, 0, 0, 1, 0, 0 }, | ||
| 250 | {LLCC_CPUHWT, 5, 512, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 1, 0, 0 }, | ||
| 251 | {LLCC_CAMEXP1, 27, 256, 3, 1, 0xFFFF, 0x0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 252 | {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 253 | }; | ||
| 254 | |||
| 255 | static const u32 llcc_v1_2_reg_offset[] = { | ||
| 256 | [LLCC_COMMON_HW_INFO] = 0x00030000, | ||
| 257 | [LLCC_COMMON_STATUS0] = 0x0003000c, | ||
| 258 | }; | ||
| 259 | |||
| 260 | static const u32 llcc_v21_reg_offset[] = { | ||
| 261 | [LLCC_COMMON_HW_INFO] = 0x00034000, | ||
| 262 | [LLCC_COMMON_STATUS0] = 0x0003400c, | ||
| 263 | }; | ||
| 264 | |||
| 220 | static const struct qcom_llcc_config sc7180_cfg = { | 265 | static 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 | ||
| 226 | static const struct qcom_llcc_config sc7280_cfg = { | 272 | static 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 | ||
| 232 | static const struct qcom_llcc_config sdm845_cfg = { | 279 | static 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 | ||
| 238 | static const struct qcom_llcc_config sm6350_cfg = { | 286 | static 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 | ||
| 243 | static const struct qcom_llcc_config sm8150_cfg = { | 293 | static 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 | ||
| 248 | static const struct qcom_llcc_config sm8250_cfg = { | 300 | static 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 | ||
| 253 | static const struct qcom_llcc_config sm8350_cfg = { | 307 | static 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 | |||
| 314 | static const struct qcom_llcc_config sm8450_cfg = { | ||
| 315 | .sct_data = sm8450_data, | ||
| 316 | .size = ARRAY_SIZE(sm8450_data), | ||
| 317 | .need_llcc_cfg = true, | ||
| 318 | .reg_offset = llcc_v21_reg_offset, | ||
| 256 | }; | 319 | }; |
| 257 | 320 | ||
| 258 | static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; | 321 | static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; |
| @@ -504,7 +567,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config, · 245 unmodified lines | |||
| 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 | ||
| @@ -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 | ||
| 34 | static ssize_t mdt_load_split_segment(void *ptr, const struct elf32_phdr *phdrs, | ||
| 35 | unsigned int segment, const char *fw_name, | ||
| 36 | struct device *dev) | ||
| 37 | { | ||
| 38 | const struct elf32_phdr *phdr = &phdrs[segment]; | ||
| 39 | const struct firmware *seg_fw; | ||
| 40 | char *seg_name; | ||
| 41 | ssize_t ret; | ||
| 42 | |||
| 43 | if (strlen(fw_name) < 4) | ||
| 44 | return -EINVAL; | ||
| 45 | |||
| 46 | seg_name = kstrdup(fw_name, GFP_KERNEL); | ||
| 47 | if (!seg_name) | ||
| 48 | return -ENOMEM; | ||
| 49 | |||
| 50 | sprintf(seg_name + strlen(fw_name) - 3, "b%02d", segment); | ||
| 51 | ret = request_firmware_into_buf(&seg_fw, seg_name, dev, | ||
| 52 | ptr, phdr->p_filesz); | ||
| 53 | if (ret) { | ||
| 54 | dev_err(dev, "error %zd loading %s\n", ret, seg_name); | ||
| 55 | kfree(seg_name); | ||
| 56 | return ret; | ||
| 57 | } | ||
| 58 | |||
| 59 | if (seg_fw->size != phdr->p_filesz) { | ||
| 60 | dev_err(dev, | ||
| 61 | "failed to load segment %d from truncated file %s\n", | ||
| 62 | segment, seg_name); | ||
| 63 | ret = -EINVAL; | ||
| 64 | } | ||
| 65 | |||
| 66 | release_firmware(seg_fw); | ||
| 67 | kfree(seg_name); | ||
| 68 | |||
| 69 | return ret; | ||
| 70 | } | ||
| 71 | |||
| 34 | /** | 72 | /** |
| 35 | * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt | 73 | * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt |
| 36 | * @fw: firmware object for the mdt file | 74 | * @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 | */ |
| 86 | void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len) | 124 | void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, |
| 125 | const char *fw_name, struct device *dev) | ||
| 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 | } |
| 127 | EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata); | 189 | EXPORT_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 | */ | ||
| 202 | int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, | ||
| 203 | const char *fw_name, int pas_id, phys_addr_t mem_phys, | ||
| 204 | struct qcom_scm_pas_metadata *ctx) | ||
| 205 | { | ||
| 206 | const struct elf32_phdr *phdrs; | ||
| 207 | const struct elf32_phdr *phdr; | ||
| 208 | const struct elf32_hdr *ehdr; | ||
| 209 | phys_addr_t min_addr = PHYS_ADDR_MAX; | ||
| 210 | phys_addr_t max_addr = 0; | ||
| 211 | size_t metadata_len; | ||
| 212 | void *metadata; | ||
| 213 | int ret; | ||
| 214 | int i; | ||
| 215 | |||
| 216 | ehdr = (struct elf32_hdr *)fw->data; | ||
| 217 | phdrs = (struct elf32_phdr *)(ehdr + 1); | ||
| 218 | |||
| 219 | for (i = 0; i < ehdr->e_phnum; i++) { | ||
| 220 | phdr = &phdrs[i]; | ||
| 221 | |||
| 222 | if (!mdt_phdr_valid(phdr)) | ||
| 223 | continue; | ||
| 224 | |||
| 225 | if (phdr->p_paddr < min_addr) | ||
| 226 | min_addr = phdr->p_paddr; | ||
| 227 | |||
| 228 | if (phdr->p_paddr + phdr->p_memsz > max_addr) | ||
| 229 | max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); | ||
| 230 | } | ||
| 231 | |||
| 232 | metadata = qcom_mdt_read_metadata(fw, &metadata_len, fw_name, dev); | ||
| 233 | if (IS_ERR(metadata)) { | ||
| 234 | ret = PTR_ERR(metadata); | ||
| 235 | dev_err(dev, "error %d reading firmware %s metadata\n", ret, fw_name); | ||
| 236 | goto out; | ||
| 237 | } | ||
| 238 | |||
| 239 | ret = qcom_scm_pas_init_image(pas_id, metadata, metadata_len, ctx); | ||
| 240 | kfree(metadata); | ||
| 241 | if (ret) { | ||
| 242 | /* Invalid firmware metadata */ | ||
| 243 | dev_err(dev, "error %d initializing firmware %s\n", ret, fw_name); | ||
| 244 | goto out; | ||
| 245 | } | ||
| 246 | |||
| 247 | ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - min_addr); | ||
| 248 | if (ret) { | ||
| 249 | /* Unable to set up relocation */ | ||
| 250 | dev_err(dev, "error %d setting up firmware %s\n", ret, fw_name); | ||
| 251 | goto out; | ||
| 252 | } | ||
| 253 | |||
| 254 | out: | ||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | EXPORT_SYMBOL_GPL(qcom_mdt_pas_init); | ||
| 258 | |||
| 129 | static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, | 259 | static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, |
| 130 | const char *firmware, int pas_id, void *mem_region, | 260 | const char *fw_name, int pas_id, void *mem_region, |
| 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 on | 296 | * 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 | ||
| 289 | out: | ||
| 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 | } |
| @@ -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; |
| @@ -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 | } |
| 456 | EXPORT_SYMBOL(qmp_get); | 460 | EXPORT_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"); |
| @@ -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 */ | ||
| 142 | DEFINE_RPMPD_PAIR(msm8226, vddcx, vddcx_ao, SMPA, CORNER, 1); | ||
| 143 | DEFINE_RPMPD_VFC(msm8226, vddcx_vfc, SMPA, 1); | ||
| 144 | |||
| 145 | static struct rpmpd *msm8226_rpmpds[] = { | ||
| 146 | [MSM8226_VDDCX] = &msm8226_vddcx, | ||
| 147 | [MSM8226_VDDCX_AO] = &msm8226_vddcx_ao, | ||
| 148 | [MSM8226_VDDCX_VFC] = &msm8226_vddcx_vfc, | ||
| 149 | }; | ||
| 150 | |||
| 151 | static const struct rpmpd_desc msm8226_desc = { | ||
| 152 | .rpmpds = msm8226_rpmpds, | ||
| 153 | .num_pds = ARRAY_SIZE(msm8226_rpmpds), | ||
| 154 | .max_state = MAX_CORNER_RPMPD_STATE, | ||
| 155 | }; | ||
| 156 | |||
| 141 | /* msm8939 RPM Power Domains */ | 157 | /* msm8939 RPM Power Domains */ |
| 142 | DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1); | 158 | DEFINE_RPMPD_PAIR(msm8939, vddmd, vddmd_ao, SMPA, CORNER, 1); |
| 143 | DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1); | 159 | DEFINE_RPMPD_VFC(msm8939, vddmd_vfc, SMPA, 1); |
| @@ -436,6 +452,7 @@ static const struct rpmpd_desc qcm2290_desc = { · 292 unmodified lines | |||
| 436 | 452 | ||
| 437 | static const struct of_device_id rpmpd_match_table[] = { | 453 | static 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++) { |
| @@ -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 | ||
| 323 | static const char *socinfo_machine(struct device *dev, unsigned int id) | 335 | static const char *socinfo_machine(struct device *dev, unsigned int id) |
| @@ -40,6 +40,11 @@ config ARCH_RMOBILE · 39 unmodified lines | |||
| 40 | select SYS_SUPPORTS_SH_TMU | 40 | select SYS_SUPPORTS_SH_TMU |
| 41 | select SYSC_RMOBILE | 41 | select SYSC_RMOBILE |
| 42 | 42 | ||
| 43 | config ARCH_RZG2L | ||
| 44 | bool | ||
| 45 | select PM | ||
| 46 | select PM_GENERIC_DOMAINS | ||
| 47 | |||
| 43 | config ARCH_RZN1 | 48 | config ARCH_RZN1 |
| 44 | bool | 49 | bool |
| 45 | select ARM_AMBA | 50 | select ARM_AMBA |
| @@ -293,9 +298,16 @@ config ARCH_R8A774B1 · 247 unmodified lines | |||
| 293 | 298 | ||
| 294 | config ARCH_R9A07G044 | 299 | config ARCH_R9A07G044 |
| 295 | bool "ARM64 Platform support for RZ/G2L" | 300 | bool "ARM64 Platform support for RZ/G2L" |
| 301 | select ARCH_RZG2L | ||
| 296 | help | 302 | 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 | ||
| 305 | config ARCH_R9A07G054 | ||
| 306 | bool "ARM64 Platform support for RZ/V2L" | ||
| 307 | select ARCH_RZG2L | ||
| 308 | help | ||
| 309 | This enables support for the Renesas RZ/V2L SoC variants. | ||
| 310 | |||
| 299 | endif # ARM64 | 311 | endif # ARM64 |
| 300 | 312 | ||
| 301 | config RST_RCAR | 313 | config RST_RCAR |
| @@ -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 | ||
| 67 | static const struct renesas_family fam_rzv2l __initconst __maybe_unused = { | ||
| 68 | .name = "RZ/V2L", | ||
| 69 | }; | ||
| 70 | |||
| 67 | static const struct renesas_family fam_shmobile __initconst __maybe_unused = { | 71 | static 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 | ||
| 151 | static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = { | ||
| 152 | .family = &fam_rzv2l, | ||
| 153 | .id = 0x8447447, | ||
| 154 | }; | ||
| 155 | |||
| 147 | static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = { | 156 | static 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 | #endif | 345 | #endif |
| 346 | #if defined(CONFIG_ARCH_R9A07G054) | ||
| 347 | { .compatible = "renesas,r9a07g054", .data = &soc_rz_v2l }, | ||
| 348 | #endif | ||
| 337 | #ifdef CONFIG_ARCH_SH73A0 | 349 | #ifdef CONFIG_ARCH_SH73A0 |
| 338 | { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, | 350 | { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 }, |
| 339 | #endif | 351 | #endif |
| @@ -367,6 +379,7 @@ static const struct renesas_id id_prr __initconst = { · 27 unmodified lines | |||
| 367 | static const struct of_device_id renesas_ids[] __initconst = { | 379 | static 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 | |||
| 474 | free_soc_dev_attr: | ||
| 475 | kfree(soc_dev_attr->revision); | ||
| 476 | kfree_const(soc_dev_attr->soc_id); | ||
| 477 | kfree_const(soc_dev_attr->family); | ||
| 478 | kfree(soc_dev_attr); | ||
| 479 | return ret; | ||
| 456 | } | 480 | } |
| 457 | early_initcall(renesas_soc_init); | 481 | early_initcall(renesas_soc_init); |
| @@ -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) 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 | ||
| 185 | static void tegra_fuse_restore(void *base) | 203 | static 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 | ||
| 191 | static int tegra_fuse_probe(struct platform_device *pdev) | 209 | static int tegra_fuse_probe(struct platform_device *pdev) |
| @@ -195,7 +213,7 @@ static int tegra_fuse_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 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 | ||
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | * drivers/soc/tegra/pmc.c | 3 | * drivers/soc/tegra/pmc.c |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2010 Google, Inc | 5 | * 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 0x0 | 60 | #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 | ||
| 3068 | static const struct tegra_pmc_soc tegra20_pmc_soc = { | 3069 | static 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 | ||
| 3129 | static const struct tegra_pmc_soc tegra30_pmc_soc = { | 3130 | static 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 | ||
| 3792 | static const struct tegra_wake_event tegra234_wake_events[] = { | ||
| 3793 | TEGRA_WAKE_GPIO("power", 29, 1, TEGRA234_AON_GPIO(EE, 4)), | ||
| 3794 | TEGRA_WAKE_IRQ("rtc", 73, 10), | ||
| 3795 | }; | ||
| 3796 | |||
| 3791 | static const struct tegra_pmc_soc tegra234_pmc_soc = { | 3797 | static 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, |
| @@ -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); |
| @@ -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 | ||
| 47 | static int | 48 | static int |
| @@ -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 | ||
| 931 | err_debugfs: | 932 | err_debugfs: |
| 932 | debugfs_remove_recursive(sr_info->dbg_dir); | 933 | debugfs_remove_recursive(sr_info->dbg_dir); |
| @@ -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, |
| @@ -122,7 +122,7 @@ static int amd_params_to_tee_params(struct tee_param *tee, u32 count, · 121 unmodified lines | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static DEFINE_MUTEX(ta_refcount_mutex); | 124 | static DEFINE_MUTEX(ta_refcount_mutex); |
| 125 | static struct list_head ta_list = LIST_HEAD_INIT(ta_list); | 125 | static LIST_HEAD(ta_list); |
| 126 | 126 | ||
| 127 | static u32 get_ta_refcount(u32 ta_handle) | 127 | static u32 get_ta_refcount(u32 ta_handle) |
| 128 | { | 128 | { |
| @@ -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 | ||
| 11 | static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, | 11 | static 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 | ||
| 37 | static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm) | 41 | static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) |
| 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 | ||
| 45 | static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) | 49 | static void pool_op_destroy_pool(struct tee_shm_pool *pool) |
| 46 | { | 50 | { |
| 47 | kfree(poolm); | 51 | kfree(pool); |
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | static const struct tee_shm_pool_mgr_ops pool_ops = { | 54 | static 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 | ||
| 56 | static struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void) | ||
| 57 | { | ||
| 58 | struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); | ||
| 59 | |||
| 60 | if (!mgr) | ||
| 61 | return ERR_PTR(-ENOMEM); | ||
| 62 | |||
| 63 | mgr->ops = &pool_ops; | ||
| 64 | |||
| 65 | return mgr; | ||
| 66 | } | ||
| 67 | |||
| 68 | struct tee_shm_pool *amdtee_config_shm(void) | 60 | struct 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 | } |
| @@ -7,11 +7,3 @@ config OPTEE · 6 unmodified lines | |||
| 7 | help | 7 | 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 | |||
| 11 | config OPTEE_SHM_NUM_PRIV_PAGES | ||
| 12 | int "Private Shared Memory Pages" | ||
| 13 | default 1 | ||
| 14 | depends on OPTEE | ||
| 15 | help | ||
| 16 | This sets the number of private shared memory pages to be | ||
| 17 | used by OP-TEE TEE driver. | ||
| @@ -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 | ||
| @@ -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 | ||
| 21 | int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, | 21 | int 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 | ||
| 64 | err: | 67 | err: |
| 65 | __free_pages(page, order); | 68 | free_pages((unsigned long)shm->kaddr, order); |
| 66 | return rc; | 69 | return rc; |
| 67 | } | 70 | } |
| 68 | 71 | ||
| 72 | void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, | ||
| 73 | int (*shm_unregister)(struct tee_context *ctx, | ||
| 74 | struct tee_shm *shm)) | ||
| 75 | { | ||
| 76 | if (shm_unregister) | ||
| 77 | shm_unregister(shm->ctx, shm); | ||
| 78 | free_pages((unsigned long)shm->kaddr, get_order(shm->size)); | ||
| 79 | shm->kaddr = NULL; | ||
| 80 | } | ||
| 81 | |||
| 69 | static void optee_bus_scan(struct work_struct *work) | 82 | static 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)); |
| @@ -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 | } |
| @@ -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 | ||
| 372 | static int pool_ffa_op_alloc(struct tee_shm_pool_mgr *poolm, | 372 | static 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 | ||
| 379 | static void pool_ffa_op_free(struct tee_shm_pool_mgr *poolm, | 379 | static void pool_ffa_op_free(struct tee_shm_pool *pool, |
| 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 | ||
| 387 | static void pool_ffa_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) | 385 | static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool) |
| 388 | { | 386 | { |
| 389 | kfree(poolm); | 387 | kfree(pool); |
| 390 | } | 388 | } |
| 391 | 389 | ||
| 392 | static const struct tee_shm_pool_mgr_ops pool_ffa_ops = { | 390 | static 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 buffers | 399 | * 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 | */ |
| 404 | static struct tee_shm_pool_mgr *optee_ffa_shm_pool_alloc_pages(void) | 402 | static struct tee_shm_pool *optee_ffa_shm_pool_alloc_pages(void) |
| 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 | ||
| 703 | static struct tee_shm_pool *optee_ffa_config_dyn_shm(void) | ||
| 704 | { | ||
| 705 | struct tee_shm_pool_mgr *priv_mgr; | ||
| 706 | struct tee_shm_pool_mgr *dmabuf_mgr; | ||
| 707 | void *rc; | ||
| 708 | |||
| 709 | rc = optee_ffa_shm_pool_alloc_pages(); | ||
| 710 | if (IS_ERR(rc)) | ||
| 711 | return rc; | ||
| 712 | priv_mgr = rc; | ||
| 713 | |||
| 714 | rc = optee_ffa_shm_pool_alloc_pages(); | ||
| 715 | if (IS_ERR(rc)) { | ||
| 716 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 717 | return rc; | ||
| 718 | } | ||
| 719 | dmabuf_mgr = rc; | ||
| 720 | |||
| 721 | rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); | ||
| 722 | if (IS_ERR(rc)) { | ||
| 723 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 724 | tee_shm_pool_mgr_destroy(dmabuf_mgr); | ||
| 725 | } | ||
| 726 | |||
| 727 | return rc; | ||
| 728 | } | ||
| 729 | |||
| 730 | static void optee_ffa_get_version(struct tee_device *teedev, | 701 | static 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; |
| @@ -229,13 +229,16 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session); · 228 unmodified lines | |||
| 229 | int optee_enumerate_devices(u32 func); | 229 | int optee_enumerate_devices(u32 func); |
| 230 | void optee_unregister_devices(void); | 230 | void optee_unregister_devices(void); |
| 231 | 231 | ||
| 232 | int optee_pool_op_alloc_helper(struct tee_shm_pool_mgr *poolm, | 232 | int 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)); |
| 239 | void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm, | ||
| 240 | int (*shm_unregister)(struct tee_context *ctx, | ||
| 241 | struct tee_shm *shm)); | ||
| 239 | 242 | ||
| 240 | 243 | ||
| 241 | void optee_remove_common(struct optee *optee); | 244 | void optee_remove_common(struct optee *optee); |
| @@ -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_PAGES | 45 | /* |
| 46 | * A typical OP-TEE private shm allocation is 224 bytes (argument struct | ||
| 47 | * with 6 parameters, needed for open session). So with an alignment of 512 | ||
| 48 | * we'll waste a bit more than 50%. However, it's only expected that we'll | ||
| 49 | * have a handful of these structs allocated at a time. Most memory will | ||
| 50 | * be allocated aligned to the page size, So all in all this should scale | ||
| 51 | * up and down quite well. | ||
| 52 | */ | ||
| 53 | #define OPTEE_MIN_STATIC_POOL_ALIGN 9 /* 512 bytes aligned */ | ||
| 46 | 54 | ||
| 47 | /* | 55 | /* |
| 48 | * 1. Convert between struct tee_param and struct optee_msg_param | 56 | * 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 | else | 233 | 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 | ||
| 525 | static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, | 533 | static 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 need | 537 | * 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 | ||
| 538 | static void pool_op_free(struct tee_shm_pool_mgr *poolm, | 547 | static 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 | ||
| 548 | static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) | 556 | static void pool_op_destroy_pool(struct tee_shm_pool *pool) |
| 549 | { | 557 | { |
| 550 | kfree(poolm); | 558 | kfree(pool); |
| 551 | } | 559 | } |
| 552 | 560 | ||
| 553 | static const struct tee_shm_pool_mgr_ops pool_ops = { | 561 | static 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 case | 570 | * 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 | */ |
| 565 | static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void) | 573 | static struct tee_shm_pool *optee_shm_pool_alloc_pages(void) |
| 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(¶m->a1, ¶m->a2, pa); | 780 | reg_pair_from_64(¶m->a1, ¶m->a2, pa); |
| 775 | reg_pair_from_64(¶m->a4, ¶m->a5, | 781 | reg_pair_from_64(¶m->a4, ¶m->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 | ||
| 1146 | static struct tee_shm_pool *optee_config_dyn_shm(void) | ||
| 1147 | { | ||
| 1148 | struct tee_shm_pool_mgr *priv_mgr; | ||
| 1149 | struct tee_shm_pool_mgr *dmabuf_mgr; | ||
| 1150 | void *rc; | ||
| 1151 | |||
| 1152 | rc = optee_shm_pool_alloc_pages(); | ||
| 1153 | if (IS_ERR(rc)) | ||
| 1154 | return rc; | ||
| 1155 | priv_mgr = rc; | ||
| 1156 | |||
| 1157 | rc = optee_shm_pool_alloc_pages(); | ||
| 1158 | if (IS_ERR(rc)) { | ||
| 1159 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 1160 | return rc; | ||
| 1161 | } | ||
| 1162 | dmabuf_mgr = rc; | ||
| 1163 | |||
| 1164 | rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); | ||
| 1165 | if (IS_ERR(rc)) { | ||
| 1166 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 1167 | tee_shm_pool_mgr_destroy(dmabuf_mgr); | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | return rc; | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | static struct tee_shm_pool * | 1152 | static struct tee_shm_pool * |
| 1174 | optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm) | 1153 | optee_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 | ||
| 1242 | err_free_dmabuf_mgr: | ||
| 1243 | tee_shm_pool_mgr_destroy(dmabuf_mgr); | ||
| 1244 | err_free_priv_mgr: | ||
| 1245 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 1246 | err_memunmap: | ||
| 1247 | memunmap(va); | ||
| 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 possible | 1315 | * 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 one | 1321 | * If dynamic shared memory is not available or failed - try static one |
| @@ -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 | ||
| @@ -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 | */ | ||
| 21 | struct 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 0x1 | 15 | #define TEE_DEVICE_FLAG_REGISTERED 0x1 |
| 27 | #define TEE_MAX_DEV_NAME_LEN 32 | 16 | #define TEE_MAX_DEV_NAME_LEN 32 |
| 28 | 17 | ||
| @@ -68,4 +57,8 @@ void tee_device_put(struct tee_device *teedev); · 39 unmodified lines | |||
| 68 | void teedev_ctx_get(struct tee_context *ctx); | 57 | void teedev_ctx_get(struct tee_context *ctx); |
| 69 | void teedev_ctx_put(struct tee_context *ctx); | 58 | void teedev_ctx_put(struct tee_context *ctx); |
| 70 | 59 | ||
| 60 | struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size); | ||
| 61 | struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, | ||
| 62 | unsigned long addr, size_t length); | ||
| 63 | |||
| 71 | #endif /*TEE_PRIVATE_H*/ | 64 | #endif /*TEE_PRIVATE_H*/ |
| @@ -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 | ||
| 15 | static void shm_put_kernel_pages(struct page **pages, size_t page_count) | ||
| 16 | { | ||
| 17 | size_t n; | ||
| 18 | |||
| 19 | for (n = 0; n < page_count; n++) | ||
| 20 | put_page(pages[n]); | ||
| 21 | } | ||
| 22 | |||
| 23 | static int shm_get_kernel_pages(unsigned long start, size_t page_count, | ||
| 24 | struct page **pages) | ||
| 25 | { | ||
| 26 | struct kvec *kiov; | ||
| 27 | size_t n; | ||
| 28 | int rc; | ||
| 29 | |||
| 30 | kiov = kcalloc(page_count, sizeof(*kiov), GFP_KERNEL); | ||
| 31 | if (!kiov) | ||
| 32 | return -ENOMEM; | ||
| 33 | |||
| 34 | for (n = 0; n < page_count; n++) { | ||
| 35 | kiov[n].iov_base = (void *)(start + n * PAGE_SIZE); | ||
| 36 | kiov[n].iov_len = PAGE_SIZE; | ||
| 37 | } | ||
| 38 | |||
| 39 | rc = get_kernel_pages(kiov, page_count, 0, pages); | ||
| 40 | kfree(kiov); | ||
| 41 | |||
| 42 | return rc; | ||
| 43 | } | ||
| 44 | |||
| 15 | static void release_registered_pages(struct tee_shm *shm) | 45 | static 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 | |||
| 31 | static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) | 57 | static 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 | ||
| 59 | struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) | 78 | static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size, |
| 79 | size_t align, u32 flags, int id) | ||
| 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; |
| 120 | err_pool_free: | ||
| 121 | poolm->ops->free(poolm, shm); | ||
| 122 | err_kfree: | 121 | err_kfree: |
| 123 | kfree(shm); | 122 | kfree(shm); |
| 124 | err_dev_put: | 123 | err_dev_put: |
| 125 | tee_device_put(teedev); | 124 | tee_device_put(teedev); |
| 126 | return ret; | 125 | return ret; |
| 127 | } | 126 | } |
| 128 | EXPORT_SYMBOL_GPL(tee_shm_alloc); | 127 | |
| 128 | /** | ||
| 129 | * tee_shm_alloc_user_buf() - Allocate shared memory for user space | ||
| 130 | * @ctx: Context that allocates the shared memory | ||
| 131 | * @size: Requested size of shared memory | ||
| 132 | * | ||
| 133 | * Memory allocated as user space shared memory is automatically freed when | ||
| 134 | * the TEE file pointer is closed. The primary usage of this function is | ||
| 135 | * when the TEE driver doesn't support registering ordinary user space | ||
| 136 | * memory. | ||
| 137 | * | ||
| 138 | * @returns a pointer to 'struct tee_shm' | ||
| 139 | */ | ||
| 140 | struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size) | ||
| 141 | { | ||
| 142 | u32 flags = TEE_SHM_DYNAMIC | TEE_SHM_POOL; | ||
| 143 | struct tee_device *teedev = ctx->teedev; | ||
| 144 | struct tee_shm *shm; | ||
| 145 | void *ret; | ||
| 146 | int id; | ||
| 147 | |||
| 148 | mutex_lock(&teedev->mutex); | ||
| 149 | id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL); | ||
| 150 | mutex_unlock(&teedev->mutex); | ||
| 151 | if (id < 0) | ||
| 152 | return ERR_PTR(id); | ||
| 153 | |||
| 154 | shm = shm_alloc_helper(ctx, size, PAGE_SIZE, flags, id); | ||
| 155 | if (IS_ERR(shm)) { | ||
| 156 | mutex_lock(&teedev->mutex); | ||
| 157 | idr_remove(&teedev->idr, id); | ||
| 158 | mutex_unlock(&teedev->mutex); | ||
| 159 | return shm; | ||
| 160 | } | ||
| 161 | |||
| 162 | mutex_lock(&teedev->mutex); | ||
| 163 | ret = idr_replace(&teedev->idr, shm, id); | ||
| 164 | mutex_unlock(&teedev->mutex); | ||
| 165 | if (IS_ERR(ret)) { | ||
| 166 | tee_shm_free(shm); | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | |||
| 170 | return shm; | ||
| 171 | } | ||
| 129 | 172 | ||
| 130 | /** | 173 | /** |
| 131 | * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer | 174 | * 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 | */ |
| 142 | struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size) | 185 | struct 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 | } |
| 146 | EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf); | 191 | EXPORT_SYMBOL_GPL(tee_shm_alloc_kernel_buf); |
| 147 | 192 | ||
| 148 | struct 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 | */ | ||
| 209 | struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size) | ||
| 210 | { | ||
| 211 | u32 flags = TEE_SHM_PRIV | TEE_SHM_POOL; | ||
| 212 | |||
| 213 | return shm_alloc_helper(ctx, size, sizeof(long) * 2, flags, -1); | ||
| 214 | } | ||
| 215 | EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf); | ||
| 216 | |||
| 217 | static struct tee_shm * | ||
| 218 | register_shm_helper(struct tee_context *ctx, unsigned long addr, | ||
| 219 | size_t length, u32 flags, int id) | ||
| 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; |
| 242 | err: | 282 | err_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 | } | 288 | err_free_shm: |
| 249 | release_registered_pages(shm); | ||
| 250 | } | ||
| 251 | kfree(shm); | 289 | kfree(shm); |
| 290 | err_ctx_put: | ||
| 252 | teedev_ctx_put(ctx); | 291 | teedev_ctx_put(ctx); |
| 292 | err_dev_put: | ||
| 253 | tee_device_put(teedev); | 293 | tee_device_put(teedev); |
| 254 | return ret; | 294 | return ret; |
| 255 | } | 295 | } |
| 256 | EXPORT_SYMBOL_GPL(tee_shm_register); | 296 | |
| 297 | /** | ||
| 298 | * tee_shm_register_user_buf() - Register a userspace shared memory buffer | ||
| 299 | * @ctx: Context that registers the shared memory | ||
| 300 | * @addr: The userspace address of the shared buffer | ||
| 301 | * @length: Length of the shared buffer | ||
| 302 | * | ||
| 303 | * @returns a pointer to 'struct tee_shm' | ||
| 304 | */ | ||
| 305 | struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, | ||
| 306 | unsigned long addr, size_t length) | ||
| 307 | { | ||
| 308 | u32 flags = TEE_SHM_USER_MAPPED | TEE_SHM_DYNAMIC; | ||
| 309 | struct tee_device *teedev = ctx->teedev; | ||
| 310 | struct tee_shm *shm; | ||
| 311 | void *ret; | ||
| 312 | int id; | ||
| 313 | |||
| 314 | mutex_lock(&teedev->mutex); | ||
| 315 | id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL); | ||
| 316 | mutex_unlock(&teedev->mutex); | ||
| 317 | if (id < 0) | ||
| 318 | return ERR_PTR(id); | ||
| 319 | |||
| 320 | shm = register_shm_helper(ctx, addr, length, flags, id); | ||
| 321 | if (IS_ERR(shm)) { | ||
| 322 | mutex_lock(&teedev->mutex); | ||
| 323 | idr_remove(&teedev->idr, id); | ||
| 324 | mutex_unlock(&teedev->mutex); | ||
| 325 | return shm; | ||
| 326 | } | ||
| 327 | |||
| 328 | mutex_lock(&teedev->mutex); | ||
| 329 | ret = idr_replace(&teedev->idr, shm, id); | ||
| 330 | mutex_unlock(&teedev->mutex); | ||
| 331 | if (IS_ERR(ret)) { | ||
| 332 | tee_shm_free(shm); | ||
| 333 | return ret; | ||
| 334 | } | ||
| 335 | |||
| 336 | return shm; | ||
| 337 | } | ||
| 338 | |||
| 339 | /** | ||
| 340 | * tee_shm_register_kernel_buf() - Register kernel memory to be shared with | ||
| 341 | * secure world | ||
| 342 | * @ctx: Context that registers the shared memory | ||
| 343 | * @addr: The buffer | ||
| 344 | * @length: Length of the buffer | ||
| 345 | * | ||
| 346 | * @returns a pointer to 'struct tee_shm' | ||
| 347 | */ | ||
| 348 | |||
| 349 | struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, | ||
| 350 | void *addr, size_t length) | ||
| 351 | { | ||
| 352 | u32 flags = TEE_SHM_DYNAMIC; | ||
| 353 | |||
| 354 | return register_shm_helper(ctx, (unsigned long)addr, length, flags, -1); | ||
| 355 | } | ||
| 356 | EXPORT_SYMBOL_GPL(tee_shm_register_kernel_buf); | ||
| 257 | 357 | ||
| 258 | static int tee_shm_fop_release(struct inode *inode, struct file *filp) | 358 | static 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 | */ |
| 324 | int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa) | 424 | int 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 | */ |
| 346 | int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va) | 446 | int 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 | */ |
| 374 | void *tee_shm_get_va(struct tee_shm *shm, size_t offs) | 474 | void *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 starts | 548 | * 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 | } |
| @@ -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, Linaro Limited | 3 | * 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 | ||
| 12 | static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm, | 12 | static 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 | ||
| 30 | static void pool_op_gen_free(struct tee_shm_pool_mgr *poolm, | 37 | static 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 | ||
| 38 | static void pool_op_gen_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) | 44 | static void pool_op_gen_destroy_pool(struct tee_shm_pool *pool) |
| 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 | ||
| 44 | static const struct tee_shm_pool_mgr_ops pool_ops_generic = { | 50 | static 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 | /** | 56 | struct 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 reserved | 57 | phys_addr_t paddr, size_t size, |
| 52 | * memory range | 58 | 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 | */ | ||
| 63 | struct tee_shm_pool * | ||
| 64 | tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info *priv_info, | ||
| 65 | struct tee_shm_pool_mem_info *dmabuf_info) | ||
| 66 | { | ||
| 67 | struct tee_shm_pool_mgr *priv_mgr; | ||
| 68 | struct tee_shm_pool_mgr *dmabuf_mgr; | ||
| 69 | void *rc; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * Create the pool for driver private shared memory | ||
| 73 | */ | ||
| 74 | rc = tee_shm_pool_mgr_alloc_res_mem(priv_info->vaddr, priv_info->paddr, | ||
| 75 | priv_info->size, | ||
| 76 | 3 /* 8 byte aligned */); | ||
| 77 | if (IS_ERR(rc)) | ||
| 78 | return rc; | ||
| 79 | priv_mgr = rc; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Create the pool for dma_buf shared memory | ||
| 83 | */ | ||
| 84 | rc = tee_shm_pool_mgr_alloc_res_mem(dmabuf_info->vaddr, | ||
| 85 | dmabuf_info->paddr, | ||
| 86 | dmabuf_info->size, PAGE_SHIFT); | ||
| 87 | if (IS_ERR(rc)) | ||
| 88 | goto err_free_priv_mgr; | ||
| 89 | dmabuf_mgr = rc; | ||
| 90 | |||
| 91 | rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); | ||
| 92 | if (IS_ERR(rc)) | ||
| 93 | goto err_free_dmabuf_mgr; | ||
| 94 | |||
| 95 | return rc; | ||
| 96 | |||
| 97 | err_free_dmabuf_mgr: | ||
| 98 | tee_shm_pool_mgr_destroy(dmabuf_mgr); | ||
| 99 | err_free_priv_mgr: | ||
| 100 | tee_shm_pool_mgr_destroy(priv_mgr); | ||
| 101 | |||
| 102 | return rc; | ||
| 103 | } | ||
| 104 | EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem); | ||
| 105 | |||
| 106 | struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr, | ||
| 107 | phys_addr_t paddr, | ||
| 108 | size_t size, | ||
| 109 | int min_alloc_order) | ||
| 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; |
| 139 | err: | 87 | err: |
| 140 | kfree(mgr); | 88 | kfree(pool); |
| 141 | 89 | ||
| 142 | return ERR_PTR(rc); | 90 | return ERR_PTR(rc); |
| 143 | } | 91 | } |
| 144 | EXPORT_SYMBOL_GPL(tee_shm_pool_mgr_alloc_res_mem); | 92 | EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem); |
| 145 | |||
| 146 | static bool check_mgr_ops(struct tee_shm_pool_mgr *mgr) | ||
| 147 | { | ||
| 148 | return mgr && mgr->ops && mgr->ops->alloc && mgr->ops->free && | ||
| 149 | mgr->ops->destroy_poolmgr; | ||
| 150 | } | ||
| 151 | |||
| 152 | struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr, | ||
| 153 | struct tee_shm_pool_mgr *dmabuf_mgr) | ||
| 154 | { | ||
| 155 | struct tee_shm_pool *pool; | ||
| 156 | |||
| 157 | if (!check_mgr_ops(priv_mgr) || !check_mgr_ops(dmabuf_mgr)) | ||
| 158 | return ERR_PTR(-EINVAL); | ||
| 159 | |||
| 160 | pool = kzalloc(sizeof(*pool), GFP_KERNEL); | ||
| 161 | if (!pool) | ||
| 162 | return ERR_PTR(-ENOMEM); | ||
| 163 | |||
| 164 | pool->private_mgr = priv_mgr; | ||
| 165 | pool->dma_buf_mgr = dmabuf_mgr; | ||
| 166 | |||
| 167 | return pool; | ||
| 168 | } | ||
| 169 | EXPORT_SYMBOL_GPL(tee_shm_pool_alloc); | ||
| 170 | |||
| 171 | /** | ||
| 172 | * tee_shm_pool_free() - Free a shared memory pool | ||
| 173 | * @pool: The shared memory pool to free | ||
| 174 | * | ||
| 175 | * There must be no remaining shared memory allocated from this pool when | ||
| 176 | * this function is called. | ||
| 177 | */ | ||
| 178 | void tee_shm_pool_free(struct tee_shm_pool *pool) | ||
| 179 | { | ||
| 180 | if (pool->private_mgr) | ||
| 181 | tee_shm_pool_mgr_destroy(pool->private_mgr); | ||
| 182 | if (pool->dma_buf_mgr) | ||
| 183 | tee_shm_pool_mgr_destroy(pool->dma_buf_mgr); | ||
| 184 | kfree(pool); | ||
| 185 | } | ||
| 186 | EXPORT_SYMBOL_GPL(tee_shm_pool_free); | ||
| @@ -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 */ | ||
| @@ -18,4 +18,7 @@ · 17 unmodified lines | |||
| 18 | #define IMX8M_POWER_DOMAIN_MIPI_CSI2 9 | 18 | #define IMX8M_POWER_DOMAIN_MIPI_CSI2 9 |
| 19 | #define IMX8M_POWER_DOMAIN_PCIE2 10 | 19 | #define IMX8M_POWER_DOMAIN_PCIE2 10 |
| 20 | 20 | ||
| 21 | #define IMX8MQ_VPUBLK_PD_G1 0 | ||
| 22 | #define IMX8MQ_VPUBLK_PD_G2 1 | ||
| 23 | |||
| 21 | #endif | 24 | #endif |
| @@ -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 | ||
| @@ -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 */ | ||
| @@ -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 */ | ||
| @@ -139,6 +139,11 @@ · 138 unmodified lines | |||
| 139 | #define MDM9607_VDDMX_AO 4 | 139 | #define MDM9607_VDDMX_AO 4 |
| 140 | #define MDM9607_VDDMX_VFL 5 | 140 | #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 0 | 148 | #define MSM8939_VDDMDCX 0 |
| 144 | #define MSM8939_VDDMDCX_AO 1 | 149 | #define MSM8939_VDDMDCX_AO 1 |
| @@ -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) |
| 61 | bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource); | 61 | bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource); |
| 62 | int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt); | ||
| 62 | #else | 63 | #else |
| 63 | static inline bool | 64 | static inline bool |
| 64 | imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource) | 65 | imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource) |
| 65 | { | 66 | { |
| 66 | return true; | 67 | return true; |
| 67 | } | 68 | } |
| 69 | static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt) | ||
| 70 | { | ||
| 71 | return -EOPNOTSUPP; | ||
| 72 | } | ||
| 68 | #endif | 73 | #endif |
| 69 | #endif | 74 | #endif |
| @@ -63,13 +63,21 @@ enum qcom_scm_ice_cipher { · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | extern bool qcom_scm_is_available(void); | 64 | extern bool qcom_scm_is_available(void); |
| 65 | 65 | ||
| 66 | extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); | 66 | extern int qcom_scm_set_cold_boot_addr(void *entry); |
| 67 | extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); | 67 | extern int qcom_scm_set_warm_boot_addr(void *entry); |
| 68 | extern void qcom_scm_cpu_power_down(u32 flags); | 68 | extern void qcom_scm_cpu_power_down(u32 flags); |
| 69 | extern int qcom_scm_set_remote_state(u32 state, u32 id); | 69 | extern int qcom_scm_set_remote_state(u32 state, u32 id); |
| 70 | 70 | ||
| 71 | struct qcom_scm_pas_metadata { | ||
| 72 | void *ptr; | ||
| 73 | dma_addr_t phys; | ||
| 74 | ssize_t size; | ||
| 75 | }; | ||
| 76 | |||
| 71 | extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, | 77 | extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, |
| 72 | size_t size); | 78 | size_t size, |
| 79 | struct qcom_scm_pas_metadata *ctx); | ||
| 80 | void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx); | ||
| 73 | extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, | 81 | extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, |
| 74 | phys_addr_t size); | 82 | phys_addr_t size); |
| 75 | extern int qcom_scm_pas_auth_and_reset(u32 peripheral); | 83 | extern int qcom_scm_pas_auth_and_reset(u32 peripheral); |
| @@ -83,6 +91,7 @@ extern bool qcom_scm_restore_sec_cfg_available(void); · 7 unmodified lines | |||
| 83 | extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); | 91 | extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); |
| 84 | extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); | 92 | extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); |
| 85 | extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); | 93 | extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); |
| 94 | extern int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size); | ||
| 86 | extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, | 95 | extern 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 | |||
| 107 | extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, | 116 | extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, |
| 108 | u32 *resp); | 117 | u32 *resp); |
| 109 | 118 | ||
| 119 | extern int qcom_scm_iommu_set_pt_format(u32 sec_id, u32 ctx_num, u32 pt_fmt); | ||
| 110 | extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en); | 120 | extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en); |
| 111 | 121 | ||
| 112 | extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, | 122 | extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, |
| @@ -42,6 +42,7 @@ struct scmi_revision_info { · 41 unmodified lines | |||
| 42 | 42 | ||
| 43 | struct scmi_clock_info { | 43 | struct 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 specific | 616 | * @devm_protocol_get: devres managed method to acquire a protocol and get specific |
| 613 | * operations and a dedicated protocol handler | 617 | * operations and a dedicated protocol handler |
| 614 | * @devm_protocol_put: devres managed method to release a protocol | 618 | * @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 operations | 628 | * @notify_ops: pointer to set of notifications related operations |
| 616 | */ | 629 | */ |
| 617 | struct scmi_handle { | 630 | struct 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 | }; |
| @@ -2,6 +2,88 @@ · 1 unmodified line | |||
| 2 | #ifndef __SOC_MEDIATEK_INFRACFG_H | 2 | #ifndef __SOC_MEDIATEK_INFRACFG_H |
| 3 | #define __SOC_MEDIATEK_INFRACFG_H | 3 | #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 0x228 | 87 | #define MT8192_TOP_AXI_PROT_EN_STA1 0x228 |
| 6 | #define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258 | 88 | #define MT8192_TOP_AXI_PROT_EN_1_STA1 0x258 |
| 7 | #define MT8192_TOP_AXI_PROT_EN_SET 0x2a0 | 89 | #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 0x228 | 191 | #define MT8183_TOP_AXI_PROT_EN_STA1 0x228 |
| 62 | #define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258 | 192 | #define MT8183_TOP_AXI_PROT_EN_STA1_1 0x258 |
| 63 | #define MT8183_TOP_AXI_PROT_EN_SET 0x2a0 | 193 | #define MT8183_TOP_AXI_PROT_EN_SET 0x2a0 |
| @@ -147,6 +277,9 @@ · 83 unmodified lines | |||
| 147 | #define INFRA_TOPAXI_PROTECTEN_SET 0x0260 | 277 | #define INFRA_TOPAXI_PROTECTEN_SET 0x0260 |
| 148 | #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 | 278 | #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 0xf00 | 283 | #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 | ||
| @@ -35,7 +35,12 @@ · 34 unmodified lines | |||
| 35 | #define LLCC_WRCACHE 31 | 35 | #define LLCC_WRCACHE 31 |
| 36 | #define LLCC_CVPFW 32 | 36 | #define LLCC_CVPFW 32 |
| 37 | #define LLCC_CPUSS1 33 | 37 | #define LLCC_CPUSS1 33 |
| 38 | #define LLCC_CAMEXP0 34 | ||
| 39 | #define LLCC_CPUMTE 35 | ||
| 38 | #define LLCC_CPUHWT 36 | 40 | #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 descriptor | 46 | * 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 ids | 88 | * @bitmap: Bit map to track the active slice ids |
| 84 | * @offsets: Pointer to the bank offsets array | 89 | * @offsets: Pointer to the bank offsets array |
| 85 | * @ecc_irq: interrupt for llcc cache error detection and reporting | 90 | * @ecc_irq: interrupt for llcc cache error detection and reporting |
| 86 | * @major_version: Indicates the LLCC major version | 91 | * @version: Indicates the LLCC version |
| 87 | */ | 92 | */ |
| 88 | struct llcc_drv_data { | 93 | struct 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) |
| @@ -10,10 +10,14 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | struct device; | 11 | struct device; |
| 12 | struct firmware; | 12 | struct firmware; |
| 13 | struct qcom_scm_pas_metadata; | ||
| 13 | 14 | ||
| 14 | #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) | 15 | #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER) |
| 15 | 16 | ||
| 16 | ssize_t qcom_mdt_get_size(const struct firmware *fw); | 17 | ssize_t qcom_mdt_get_size(const struct firmware *fw); |
| 18 | int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, | ||
| 19 | const char *fw_name, int pas_id, phys_addr_t mem_phys, | ||
| 20 | struct qcom_scm_pas_metadata *pas_metadata_ctx); | ||
| 17 | int qcom_mdt_load(struct device *dev, const struct firmware *fw, | 21 | int 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); |
| 26 | void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len); | 30 | void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, |
| 31 | const char *fw_name, struct device *dev); | ||
| 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 | ||
| 40 | static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, | ||
| 41 | const char *fw_name, int pas_id, phys_addr_t mem_phys, | ||
| 42 | struct qcom_scm_pas_metadata *pas_metadata_ctx) | ||
| 43 | { | ||
| 44 | return -ENODEV; | ||
| 45 | } | ||
| 46 | |||
| 35 | static inline int qcom_mdt_load(struct device *dev, const struct firmware *fw, | 47 | static 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 | ||
| 53 | static inline void *qcom_mdt_read_metadata(const struct firmware *fw, | 65 | static inline void *qcom_mdt_read_metadata(const struct firmware *fw, |
| 54 | size_t *data_len) | 66 | size_t *data_len, const char *fw_name, |
| 67 | struct device *dev) | ||
| 55 | { | 68 | { |
| 56 | return ERR_PTR(-ENODEV); | 69 | return ERR_PTR(-ENODEV); |
| 57 | } | 70 | } |
| @@ -645,7 +645,7 @@ devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, · 644 unmodified lines | |||
| 645 | 645 | ||
| 646 | static inline struct ti_sci_resource * | 646 | static inline struct ti_sci_resource * |
| 647 | devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev, | 647 | devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev, |
| 648 | u32 dev_id, u32 sub_type); | 648 | u32 dev_id, u32 sub_type) |
| 649 | { | 649 | { |
| 650 | return ERR_PTR(-EINVAL); | 650 | return ERR_PTR(-EINVAL); |
| 651 | } | 651 | } |
| @@ -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 Limited | 3 | * Copyright (c) 2015-2022 Linaro Limited |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #ifndef __TEE_DRV_H | 6 | #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 | ||
| 32 | struct device; | 29 | struct device; |
| 33 | struct tee_device; | 30 | struct 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 manager | 221 | * struct tee_shm_pool - shared memory pool |
| 225 | * @ops: operations | 222 | * @ops: operations |
| 226 | * @private_data: private data for the shared memory manager | 223 | * @private_data: private data for the shared memory manager |
| 227 | */ | 224 | */ |
| 228 | struct tee_shm_pool_mgr { | 225 | struct 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 operations | 231 | * struct tee_shm_pool_ops - shared memory pool operations |
| 235 | * @alloc: called when allocating shared memory | 232 | * @alloc: called when allocating shared memory |
| 236 | * @free: called when freeing shared memory | 233 | * @free: called when freeing shared memory |
| 237 | * @destroy_poolmgr: called when destroying the pool manager | 234 | * @destroy_pool: called when destroying the pool |
| 238 | */ | 235 | */ |
| 239 | struct tee_shm_pool_mgr_ops { | 236 | struct 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 | */ | ||
| 256 | struct tee_shm_pool *tee_shm_pool_alloc(struct tee_shm_pool_mgr *priv_mgr, | ||
| 257 | struct tee_shm_pool_mgr *dmabuf_mgr); | ||
| 258 | |||
| 259 | /* | 243 | /* |
| 260 | * tee_shm_pool_mgr_alloc_res_mem() - Create a shm manager for reserved | 244 | * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory |
| 261 | * memory | ||
| 262 | * @vaddr: Virtual address of start of pool | 245 | * @vaddr: Virtual address of start of pool |
| 263 | * @paddr: Physical address of start of pool | 246 | * @paddr: Physical address of start of pool |
| 264 | * @size: Size in bytes of the pool | 247 | * @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 | */ | ||
| 268 | struct tee_shm_pool_mgr *tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr, | ||
| 269 | phys_addr_t paddr, | ||
| 270 | size_t size, | ||
| 271 | int min_alloc_order); | ||
| 272 | |||
| 273 | /** | ||
| 274 | * tee_shm_pool_mgr_destroy() - Free a shared memory manager | ||
| 275 | */ | ||
| 276 | static inline void tee_shm_pool_mgr_destroy(struct tee_shm_pool_mgr *poolm) | ||
| 277 | { | ||
| 278 | poolm->ops->destroy_poolmgr(poolm); | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * struct tee_shm_pool_mem_info - holds information needed to create a shared | ||
| 283 | * memory pool | ||
| 284 | * @vaddr: Virtual address of start of pool | ||
| 285 | * @paddr: Physical address of start of pool | ||
| 286 | * @size: Size in bytes of the pool | ||
| 287 | */ | ||
| 288 | struct tee_shm_pool_mem_info { | ||
| 289 | unsigned long vaddr; | ||
| 290 | phys_addr_t paddr; | ||
| 291 | size_t size; | ||
| 292 | }; | ||
| 293 | |||
| 294 | /** | ||
| 295 | * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved | ||
| 296 | * memory range | ||
| 297 | * @priv_info: Information for driver private shared memory pool | ||
| 298 | * @dmabuf_info: Information for dma-buf shared memory pool | ||
| 299 | * | ||
| 300 | * Start and end of pools will must be page aligned. | ||
| 301 | * | ||
| 302 | * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied | ||
| 303 | * in @dmabuf, others will use the range provided by @priv. | ||
| 304 | * | ||
| 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 | */ |
| 307 | struct tee_shm_pool * | 251 | struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr, |
| 308 | tee_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 pool | 256 | * 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 when | 259 | * The must be no remaining shared memory allocated from this pool when |
| 316 | * this function is called. | 260 | * this function is called. |
| 317 | */ | 261 | */ |
| 318 | void tee_shm_pool_free(struct tee_shm_pool *pool); | 262 | static inline void tee_shm_pool_free(struct tee_shm_pool *pool) |
| 263 | { | ||
| 264 | pool->ops->destroy_pool(pool); | ||
| 265 | } | ||
| 319 | 266 | ||
| 320 | /** | 267 | /** |
| 321 | * tee_get_drvdata() - Return driver_data pointer | 268 | * 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 | */ |
| 324 | void *tee_get_drvdata(struct tee_device *teedev); | 271 | void *tee_get_drvdata(struct tee_device *teedev); |
| 325 | 272 | ||
| 326 | /** | 273 | struct 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 | */ | ||
| 340 | struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); | ||
| 341 | struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size); | 274 | struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size); |
| 342 | 275 | ||
| 343 | /** | 276 | struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, |
| 344 | * tee_shm_register() - Register shared memory buffer | 277 | 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 | */ | ||
| 352 | struct 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 TEE | 280 | * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind |
| 357 | * @shm: Shared memory handle | 281 | * @shm: Shared memory handle |
| 358 | * @returns true if object is registered in TEE | 282 | * @returns true if object is dynamic shared memory |
| 359 | */ | 283 | */ |
| 360 | static inline bool tee_shm_is_registered(struct tee_shm *shm) | 284 | static 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 | /** |
| @@ -931,7 +931,7 @@ enum mrq_reset_commands { · 930 unmodified lines | |||
| 931 | * @brief Request with MRQ_RESET | 931 | * @brief Request with MRQ_RESET |
| 932 | * | 932 | * |
| 933 | * Used by the sender of an #MRQ_RESET message to request BPMP to | 933 | * 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 | */ |
| 936 | struct mrq_reset_request { | 936 | struct mrq_reset_request { |
| 937 | /** @brief Reset action to perform (@ref mrq_reset_commands) */ | 937 | /** @brief Reset action to perform (@ref mrq_reset_commands) */ |
| @@ -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 | ||
| 36 | TRACE_EVENT(scmi_xfer_response_wait, | ||
| 37 | TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq, | ||
| 38 | u32 timeout, bool poll), | ||
| 39 | TP_ARGS(transfer_id, msg_id, protocol_id, seq, timeout, poll), | ||
| 40 | |||
| 41 | TP_STRUCT__entry( | ||
| 42 | __field(int, transfer_id) | ||
| 43 | __field(u8, msg_id) | ||
| 44 | __field(u8, protocol_id) | ||
| 45 | __field(u16, seq) | ||
| 46 | __field(u32, timeout) | ||
| 47 | __field(bool, poll) | ||
| 48 | ), | ||
| 49 | |||
| 50 | TP_fast_assign( | ||
| 51 | __entry->transfer_id = transfer_id; | ||
| 52 | __entry->msg_id = msg_id; | ||
| 53 | __entry->protocol_id = protocol_id; | ||
| 54 | __entry->seq = seq; | ||
| 55 | __entry->timeout = timeout; | ||
| 56 | __entry->poll = poll; | ||
| 57 | ), | ||
| 58 | |||
| 59 | TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u tmo_ms=%u poll=%u", | ||
| 60 | __entry->transfer_id, __entry->msg_id, __entry->protocol_id, | ||
| 61 | __entry->seq, __entry->timeout, __entry->poll) | ||
| 62 | ); | ||
| 63 | |||
| 36 | TRACE_EVENT(scmi_xfer_end, | 64 | TRACE_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), |
| @@ -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(¶m, 0, sizeof(param)); | 71 | memset(¶m, 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(¶m, 0, sizeof(param)); | 130 | memset(¶m, 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(¶m, 0, sizeof(param)); | 189 | memset(¶m, 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); |