Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-msm-next-2021-10-26' of https://gitlab.freedesktop.org/drm/msm into drm-next

* eDP support in DP sub-driver (for newer SoCs with native eDP output)
* dpu irq handling cleanup
* CRC support for making igt happy
* Support for NO_CONNECTOR bridges
* dsi: 14nm phy support for msm8953
* mdp5: support for msm8x53, sdm450, sdm632
* various smaller fixes and cleanups

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGsH9EwcpqGNNRJeL99NvFFjHX3SUg+nTYu0dHG5U9+QuA@mail.gmail.com

+1750 -1323
+13 -2
Documentation/devicetree/bindings/display/msm/dp-controller.yaml
··· 17 17 compatible: 18 18 enum: 19 19 - qcom,sc7180-dp 20 + - qcom,sc8180x-dp 21 + - qcom,sc8180x-edp 20 22 21 23 reg: 22 - maxItems: 1 24 + items: 25 + - description: ahb register block 26 + - description: aux register block 27 + - description: link register block 28 + - description: p0 register block 29 + - description: p1 register block 23 30 24 31 interrupts: 25 32 maxItems: 1 ··· 107 100 108 101 displayport-controller@ae90000 { 109 102 compatible = "qcom,sc7180-dp"; 110 - reg = <0xae90000 0x1400>; 103 + reg = <0xae90000 0x200>, 104 + <0xae90200 0x200>, 105 + <0xae90400 0xc00>, 106 + <0xae91000 0x400>, 107 + <0xae91400 0x400>; 111 108 interrupt-parent = <&mdss>; 112 109 interrupts = <12>; 113 110 clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+232
Documentation/devicetree/bindings/display/msm/dpu-sc7280.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/display/msm/dpu-sc7280.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Display DPU dt properties for SC7280 8 + 9 + maintainers: 10 + - Krishna Manikandan <mkrishn@codeaurora.org> 11 + 12 + description: | 13 + Device tree bindings for MSM Mobile Display Subsystem (MDSS) that encapsulates 14 + sub-blocks like DPU display controller, DSI and DP interfaces etc. Device tree 15 + bindings of MDSS and DPU are mentioned for SC7280. 16 + 17 + properties: 18 + compatible: 19 + const: qcom,sc7280-mdss 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + reg-names: 25 + const: mdss 26 + 27 + power-domains: 28 + maxItems: 1 29 + 30 + clocks: 31 + items: 32 + - description: Display AHB clock from gcc 33 + - description: Display AHB clock from dispcc 34 + - description: Display core clock 35 + 36 + clock-names: 37 + items: 38 + - const: iface 39 + - const: ahb 40 + - const: core 41 + 42 + interrupts: 43 + maxItems: 1 44 + 45 + interrupt-controller: true 46 + 47 + "#address-cells": true 48 + 49 + "#size-cells": true 50 + 51 + "#interrupt-cells": 52 + const: 1 53 + 54 + iommus: 55 + items: 56 + - description: Phandle to apps_smmu node with SID mask for Hard-Fail port0 57 + 58 + ranges: true 59 + 60 + interconnects: 61 + items: 62 + - description: Interconnect path specifying the port ids for data bus 63 + 64 + interconnect-names: 65 + const: mdp0-mem 66 + 67 + patternProperties: 68 + "^display-controller@[0-9a-f]+$": 69 + type: object 70 + description: Node containing the properties of DPU. 71 + 72 + properties: 73 + compatible: 74 + const: qcom,sc7280-dpu 75 + 76 + reg: 77 + items: 78 + - description: Address offset and size for mdp register set 79 + - description: Address offset and size for vbif register set 80 + 81 + reg-names: 82 + items: 83 + - const: mdp 84 + - const: vbif 85 + 86 + clocks: 87 + items: 88 + - description: Display hf axi clock 89 + - description: Display sf axi clock 90 + - description: Display ahb clock 91 + - description: Display lut clock 92 + - description: Display core clock 93 + - description: Display vsync clock 94 + 95 + clock-names: 96 + items: 97 + - const: bus 98 + - const: nrt_bus 99 + - const: iface 100 + - const: lut 101 + - const: core 102 + - const: vsync 103 + 104 + interrupts: 105 + maxItems: 1 106 + 107 + power-domains: 108 + maxItems: 1 109 + 110 + operating-points-v2: true 111 + 112 + ports: 113 + $ref: /schemas/graph.yaml#/properties/ports 114 + description: | 115 + Contains the list of output ports from DPU device. These ports 116 + connect to interfaces that are external to the DPU hardware, 117 + such as DSI, DP etc. Each output port contains an endpoint that 118 + describes how it is connected to an external interface. 119 + 120 + properties: 121 + port@0: 122 + $ref: /schemas/graph.yaml#/properties/port 123 + description: DPU_INTF1 (DSI) 124 + 125 + port@1: 126 + $ref: /schemas/graph.yaml#/properties/port 127 + description: DPU_INTF5 (EDP) 128 + 129 + required: 130 + - port@0 131 + 132 + required: 133 + - compatible 134 + - reg 135 + - reg-names 136 + - clocks 137 + - interrupts 138 + - power-domains 139 + - operating-points-v2 140 + - ports 141 + 142 + required: 143 + - compatible 144 + - reg 145 + - reg-names 146 + - power-domains 147 + - clocks 148 + - interrupts 149 + - interrupt-controller 150 + - iommus 151 + - ranges 152 + 153 + additionalProperties: false 154 + 155 + examples: 156 + - | 157 + #include <dt-bindings/clock/qcom,dispcc-sc7280.h> 158 + #include <dt-bindings/clock/qcom,gcc-sc7280.h> 159 + #include <dt-bindings/interrupt-controller/arm-gic.h> 160 + #include <dt-bindings/interconnect/qcom,sc7280.h> 161 + #include <dt-bindings/power/qcom-rpmpd.h> 162 + 163 + display-subsystem@ae00000 { 164 + #address-cells = <1>; 165 + #size-cells = <1>; 166 + compatible = "qcom,sc7280-mdss"; 167 + reg = <0xae00000 0x1000>; 168 + reg-names = "mdss"; 169 + power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>; 170 + clocks = <&gcc GCC_DISP_AHB_CLK>, 171 + <&dispcc DISP_CC_MDSS_AHB_CLK>, 172 + <&dispcc DISP_CC_MDSS_MDP_CLK>; 173 + clock-names = "iface", 174 + "ahb", 175 + "core"; 176 + 177 + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; 178 + interrupt-controller; 179 + #interrupt-cells = <1>; 180 + 181 + interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; 182 + interconnect-names = "mdp0-mem"; 183 + 184 + iommus = <&apps_smmu 0x900 0x402>; 185 + ranges; 186 + 187 + display-controller@ae01000 { 188 + compatible = "qcom,sc7280-dpu"; 189 + reg = <0x0ae01000 0x8f000>, 190 + <0x0aeb0000 0x2008>; 191 + 192 + reg-names = "mdp", "vbif"; 193 + 194 + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, 195 + <&gcc GCC_DISP_SF_AXI_CLK>, 196 + <&dispcc DISP_CC_MDSS_AHB_CLK>, 197 + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, 198 + <&dispcc DISP_CC_MDSS_MDP_CLK>, 199 + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; 200 + clock-names = "bus", 201 + "nrt_bus", 202 + "iface", 203 + "lut", 204 + "core", 205 + "vsync"; 206 + 207 + interrupt-parent = <&mdss>; 208 + interrupts = <0>; 209 + power-domains = <&rpmhpd SC7280_CX>; 210 + operating-points-v2 = <&mdp_opp_table>; 211 + 212 + ports { 213 + #address-cells = <1>; 214 + #size-cells = <0>; 215 + 216 + port@0 { 217 + reg = <0>; 218 + dpu_intf1_out: endpoint { 219 + remote-endpoint = <&dsi0_in>; 220 + }; 221 + }; 222 + 223 + port@1 { 224 + reg = <1>; 225 + dpu_intf5_out: endpoint { 226 + remote-endpoint = <&edp_in>; 227 + }; 228 + }; 229 + }; 230 + }; 231 + }; 232 + ...
+1
Documentation/devicetree/bindings/display/msm/dsi-phy-14nm.yaml
··· 17 17 enum: 18 18 - qcom,dsi-phy-14nm 19 19 - qcom,dsi-phy-14nm-660 20 + - qcom,dsi-phy-14nm-8953 20 21 21 22 reg: 22 23 items:
-157
Documentation/devicetree/bindings/display/msm/gpu.txt
··· 1 - Qualcomm adreno/snapdragon GPU 2 - 3 - Required properties: 4 - - compatible: "qcom,adreno-XYZ.W", "qcom,adreno" or 5 - "amd,imageon-XYZ.W", "amd,imageon" 6 - for example: "qcom,adreno-306.0", "qcom,adreno" 7 - Note that you need to list the less specific "qcom,adreno" (since this 8 - is what the device is matched on), in addition to the more specific 9 - with the chip-id. 10 - If "amd,imageon" is used, there should be no top level msm device. 11 - - reg: Physical base address and length of the controller's registers. 12 - - interrupts: The interrupt signal from the gpu. 13 - - clocks: device clocks (if applicable) 14 - See ../clocks/clock-bindings.txt for details. 15 - - clock-names: the following clocks are required by a3xx, a4xx and a5xx 16 - cores: 17 - * "core" 18 - * "iface" 19 - * "mem_iface" 20 - For GMU attached devices the GPU clocks are not used and are not required. The 21 - following devices should not list clocks: 22 - - qcom,adreno-630.2 23 - - iommus: optional phandle to an adreno iommu instance 24 - - operating-points-v2: optional phandle to the OPP operating points 25 - - interconnects: optional phandle to an interconnect provider. See 26 - ../interconnect/interconnect.txt for details. Some A3xx and all A4xx platforms 27 - will have two paths; all others will have one path. 28 - - interconnect-names: The names of the interconnect paths that correspond to the 29 - interconnects property. Values must be gfx-mem and ocmem. 30 - - qcom,gmu: For GMU attached devices a phandle to the GMU device that will 31 - control the power for the GPU. Applicable targets: 32 - - qcom,adreno-630.2 33 - - zap-shader: For a5xx and a6xx devices this node contains a memory-region that 34 - points to reserved memory to store the zap shader that can be used to help 35 - bring the GPU out of secure mode. 36 - - firmware-name: optional property of the 'zap-shader' node, listing the 37 - relative path of the device specific zap firmware. 38 - - sram: phandle to the On Chip Memory (OCMEM) that's present on some a3xx and 39 - a4xx Snapdragon SoCs. See 40 - Documentation/devicetree/bindings/sram/qcom,ocmem.yaml. 41 - 42 - Optional properties: 43 - - #cooling-cells: The value must be 2. For details, please refer 44 - Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml. 45 - 46 - Example 3xx/4xx: 47 - 48 - / { 49 - ... 50 - 51 - gpu: adreno@fdb00000 { 52 - compatible = "qcom,adreno-330.2", 53 - "qcom,adreno"; 54 - reg = <0xfdb00000 0x10000>; 55 - reg-names = "kgsl_3d0_reg_memory"; 56 - interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; 57 - interrupt-names = "kgsl_3d0_irq"; 58 - clock-names = "core", 59 - "iface", 60 - "mem_iface"; 61 - clocks = <&mmcc OXILI_GFX3D_CLK>, 62 - <&mmcc OXILICX_AHB_CLK>, 63 - <&mmcc OXILICX_AXI_CLK>; 64 - sram = <&gpu_sram>; 65 - power-domains = <&mmcc OXILICX_GDSC>; 66 - operating-points-v2 = <&gpu_opp_table>; 67 - iommus = <&gpu_iommu 0>; 68 - #cooling-cells = <2>; 69 - }; 70 - 71 - gpu_sram: ocmem@fdd00000 { 72 - compatible = "qcom,msm8974-ocmem"; 73 - 74 - reg = <0xfdd00000 0x2000>, 75 - <0xfec00000 0x180000>; 76 - reg-names = "ctrl", 77 - "mem"; 78 - 79 - clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, 80 - <&mmcc OCMEMCX_OCMEMNOC_CLK>; 81 - clock-names = "core", 82 - "iface"; 83 - 84 - #address-cells = <1>; 85 - #size-cells = <1>; 86 - 87 - gpu_sram: gpu-sram@0 { 88 - reg = <0x0 0x100000>; 89 - ranges = <0 0 0xfec00000 0x100000>; 90 - }; 91 - }; 92 - }; 93 - 94 - Example a6xx (with GMU): 95 - 96 - / { 97 - ... 98 - 99 - gpu@5000000 { 100 - compatible = "qcom,adreno-630.2", "qcom,adreno"; 101 - #stream-id-cells = <16>; 102 - 103 - reg = <0x5000000 0x40000>, <0x509e000 0x10>; 104 - reg-names = "kgsl_3d0_reg_memory", "cx_mem"; 105 - 106 - #cooling-cells = <2>; 107 - 108 - /* 109 - * Look ma, no clocks! The GPU clocks and power are 110 - * controlled entirely by the GMU 111 - */ 112 - 113 - interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; 114 - 115 - iommus = <&adreno_smmu 0>; 116 - 117 - operating-points-v2 = <&gpu_opp_table>; 118 - 119 - interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>; 120 - interconnect-names = "gfx-mem"; 121 - 122 - gpu_opp_table: opp-table { 123 - compatible = "operating-points-v2"; 124 - 125 - opp-430000000 { 126 - opp-hz = /bits/ 64 <430000000>; 127 - opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; 128 - opp-peak-kBps = <5412000>; 129 - }; 130 - 131 - opp-355000000 { 132 - opp-hz = /bits/ 64 <355000000>; 133 - opp-level = <RPMH_REGULATOR_LEVEL_SVS>; 134 - opp-peak-kBps = <3072000>; 135 - }; 136 - 137 - opp-267000000 { 138 - opp-hz = /bits/ 64 <267000000>; 139 - opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; 140 - opp-peak-kBps = <3072000>; 141 - }; 142 - 143 - opp-180000000 { 144 - opp-hz = /bits/ 64 <180000000>; 145 - opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>; 146 - opp-peak-kBps = <1804000>; 147 - }; 148 - }; 149 - 150 - qcom,gmu = <&gmu>; 151 - 152 - zap-shader { 153 - memory-region = <&zap_shader_region>; 154 - firmware-name = "qcom/LENOVO/81JL/qcdxkmsuc850.mbn" 155 - }; 156 - }; 157 - };
+288
Documentation/devicetree/bindings/display/msm/gpu.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + 5 + $id: "http://devicetree.org/schemas/display/msm/gpu.yaml#" 6 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 7 + 8 + title: Devicetree bindings for the Adreno or Snapdragon GPUs 9 + 10 + maintainers: 11 + - Rob Clark <robdclark@gmail.com> 12 + 13 + properties: 14 + compatible: 15 + oneOf: 16 + - description: | 17 + The driver is parsing the compat string for Adreno to 18 + figure out the gpu-id and patch level. 19 + items: 20 + - pattern: '^qcom,adreno-[3-6][0-9][0-9]\.[0-9]$' 21 + - const: qcom,adreno 22 + - description: | 23 + The driver is parsing the compat string for Imageon to 24 + figure out the gpu-id and patch level. 25 + items: 26 + - pattern: '^amd,imageon-200\.[0-1]$' 27 + - const: amd,imageon 28 + 29 + clocks: true 30 + 31 + clock-names: true 32 + 33 + reg: 34 + minItems: 1 35 + maxItems: 3 36 + 37 + reg-names: 38 + minItems: 1 39 + items: 40 + - const: kgsl_3d0_reg_memory 41 + - const: cx_mem 42 + - const: cx_dbgc 43 + 44 + interrupts: 45 + maxItems: 1 46 + 47 + interrupt-names: 48 + maxItems: 1 49 + 50 + interconnects: 51 + minItems: 1 52 + maxItems: 2 53 + 54 + interconnect-names: 55 + minItems: 1 56 + items: 57 + - const: gfx-mem 58 + - const: ocmem 59 + 60 + iommus: 61 + maxItems: 1 62 + 63 + sram: 64 + $ref: /schemas/types.yaml#/definitions/phandle-array 65 + minItems: 1 66 + maxItems: 4 67 + description: | 68 + phandles to one or more reserved on-chip SRAM regions. 69 + phandle to the On Chip Memory (OCMEM) that's present on some a3xx and 70 + a4xx Snapdragon SoCs. See 71 + Documentation/devicetree/bindings/sram/qcom,ocmem.yaml 72 + 73 + operating-points-v2: true 74 + opp-table: 75 + type: object 76 + 77 + power-domains: 78 + maxItems: 1 79 + 80 + zap-shader: 81 + type: object 82 + description: | 83 + For a5xx and a6xx devices this node contains a memory-region that 84 + points to reserved memory to store the zap shader that can be used to 85 + help bring the GPU out of secure mode. 86 + properties: 87 + memory-region: 88 + $ref: /schemas/types.yaml#/definitions/phandle 89 + 90 + firmware-name: 91 + description: | 92 + Default name of the firmware to load to the remote processor. 93 + 94 + "#cooling-cells": 95 + const: 2 96 + 97 + nvmem-cell-names: 98 + maxItems: 1 99 + 100 + nvmem-cells: 101 + description: efuse registers 102 + maxItems: 1 103 + 104 + qcom,gmu: 105 + $ref: /schemas/types.yaml#/definitions/phandle 106 + description: | 107 + For GMU attached devices a phandle to the GMU device that will 108 + control the power for the GPU. 109 + 110 + 111 + required: 112 + - compatible 113 + - reg 114 + - interrupts 115 + 116 + additionalProperties: false 117 + 118 + allOf: 119 + - if: 120 + properties: 121 + compatible: 122 + contains: 123 + pattern: '^qcom,adreno-[3-5][0-9][0-9]\.[0-9]$' 124 + 125 + then: 126 + properties: 127 + clocks: 128 + minItems: 2 129 + maxItems: 7 130 + 131 + clock-names: 132 + items: 133 + anyOf: 134 + - const: core 135 + description: GPU Core clock 136 + - const: iface 137 + description: GPU Interface clock 138 + - const: mem 139 + description: GPU Memory clock 140 + - const: mem_iface 141 + description: GPU Memory Interface clock 142 + - const: alt_mem_iface 143 + description: GPU Alternative Memory Interface clock 144 + - const: gfx3d 145 + description: GPU 3D engine clock 146 + - const: rbbmtimer 147 + description: GPU RBBM Timer for Adreno 5xx series 148 + minItems: 2 149 + maxItems: 7 150 + 151 + required: 152 + - clocks 153 + - clock-names 154 + - if: 155 + properties: 156 + compatible: 157 + contains: 158 + pattern: '^qcom,adreno-6[0-9][0-9]\.[0-9]$' 159 + 160 + then: # Since Adreno 6xx series clocks should be defined in GMU 161 + properties: 162 + clocks: false 163 + clock-names: false 164 + 165 + examples: 166 + - | 167 + 168 + // Example a3xx/4xx: 169 + 170 + #include <dt-bindings/clock/qcom,mmcc-msm8974.h> 171 + #include <dt-bindings/clock/qcom,rpmcc.h> 172 + #include <dt-bindings/interrupt-controller/irq.h> 173 + #include <dt-bindings/interrupt-controller/arm-gic.h> 174 + 175 + gpu: gpu@fdb00000 { 176 + compatible = "qcom,adreno-330.2", "qcom,adreno"; 177 + 178 + reg = <0xfdb00000 0x10000>; 179 + reg-names = "kgsl_3d0_reg_memory"; 180 + 181 + clock-names = "core", "iface", "mem_iface"; 182 + clocks = <&mmcc OXILI_GFX3D_CLK>, 183 + <&mmcc OXILICX_AHB_CLK>, 184 + <&mmcc OXILICX_AXI_CLK>; 185 + 186 + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; 187 + interrupt-names = "kgsl_3d0_irq"; 188 + 189 + sram = <&gpu_sram>; 190 + power-domains = <&mmcc OXILICX_GDSC>; 191 + operating-points-v2 = <&gpu_opp_table>; 192 + iommus = <&gpu_iommu 0>; 193 + #cooling-cells = <2>; 194 + }; 195 + 196 + ocmem@fdd00000 { 197 + compatible = "qcom,msm8974-ocmem"; 198 + 199 + reg = <0xfdd00000 0x2000>, 200 + <0xfec00000 0x180000>; 201 + reg-names = "ctrl", "mem"; 202 + 203 + clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>, 204 + <&mmcc OCMEMCX_OCMEMNOC_CLK>; 205 + clock-names = "core", "iface"; 206 + 207 + #address-cells = <1>; 208 + #size-cells = <1>; 209 + ranges = <0 0xfec00000 0x100000>; 210 + 211 + gpu_sram: gpu-sram@0 { 212 + reg = <0x0 0x100000>; 213 + }; 214 + }; 215 + - | 216 + 217 + // Example a6xx (with GMU): 218 + 219 + #include <dt-bindings/clock/qcom,gpucc-sdm845.h> 220 + #include <dt-bindings/clock/qcom,gcc-sdm845.h> 221 + #include <dt-bindings/power/qcom-rpmpd.h> 222 + #include <dt-bindings/interrupt-controller/irq.h> 223 + #include <dt-bindings/interrupt-controller/arm-gic.h> 224 + #include <dt-bindings/interconnect/qcom,sdm845.h> 225 + 226 + reserved-memory { 227 + #address-cells = <2>; 228 + #size-cells = <2>; 229 + 230 + zap_shader_region: gpu@8f200000 { 231 + compatible = "shared-dma-pool"; 232 + reg = <0x0 0x90b00000 0x0 0xa00000>; 233 + no-map; 234 + }; 235 + }; 236 + 237 + gpu@5000000 { 238 + compatible = "qcom,adreno-630.2", "qcom,adreno"; 239 + 240 + reg = <0x5000000 0x40000>, <0x509e000 0x10>; 241 + reg-names = "kgsl_3d0_reg_memory", "cx_mem"; 242 + 243 + #cooling-cells = <2>; 244 + 245 + interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; 246 + 247 + iommus = <&adreno_smmu 0>; 248 + 249 + operating-points-v2 = <&gpu_opp_table>; 250 + 251 + interconnects = <&rsc_hlos MASTER_GFX3D &rsc_hlos SLAVE_EBI1>; 252 + interconnect-names = "gfx-mem"; 253 + 254 + qcom,gmu = <&gmu>; 255 + 256 + gpu_opp_table: opp-table { 257 + compatible = "operating-points-v2"; 258 + 259 + opp-430000000 { 260 + opp-hz = /bits/ 64 <430000000>; 261 + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; 262 + opp-peak-kBps = <5412000>; 263 + }; 264 + 265 + opp-355000000 { 266 + opp-hz = /bits/ 64 <355000000>; 267 + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; 268 + opp-peak-kBps = <3072000>; 269 + }; 270 + 271 + opp-267000000 { 272 + opp-hz = /bits/ 64 <267000000>; 273 + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; 274 + opp-peak-kBps = <3072000>; 275 + }; 276 + 277 + opp-180000000 { 278 + opp-hz = /bits/ 64 <180000000>; 279 + opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>; 280 + opp-peak-kBps = <1804000>; 281 + }; 282 + }; 283 + 284 + zap-shader { 285 + memory-region = <&zap_shader_region>; 286 + firmware-name = "qcom/LENOVO/81JL/qcdxkmsuc850.mbn"; 287 + }; 288 + };
-1
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
··· 1733 1733 1734 1734 DBG("%s", dev_name(gpu->dev)); 1735 1735 1736 - flush_workqueue(gpu->wq); 1737 1736 destroy_workqueue(gpu->wq); 1738 1737 1739 1738 etnaviv_sched_fini(gpu);
+2
drivers/gpu/drm/msm/Kconfig
··· 14 14 select REGULATOR 15 15 select DRM_KMS_HELPER 16 16 select DRM_PANEL 17 + select DRM_BRIDGE 18 + select DRM_PANEL_BRIDGE 17 19 select DRM_SCHED 18 20 select SHMEM 19 21 select TMPFS
-1
drivers/gpu/drm/msm/Makefile
··· 51 51 disp/mdp5/mdp5_mixer.o \ 52 52 disp/mdp5/mdp5_plane.o \ 53 53 disp/mdp5/mdp5_smp.o \ 54 - disp/dpu1/dpu_core_irq.o \ 55 54 disp/dpu1/dpu_core_perf.o \ 56 55 disp/dpu1/dpu_crtc.o \ 57 56 disp/dpu1/dpu_encoder.o \
+3 -3
drivers/gpu/drm/msm/adreno/a5xx_debugfs.c
··· 138 138 return 0; 139 139 } 140 140 141 - DEFINE_SIMPLE_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n"); 141 + DEFINE_DEBUGFS_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n"); 142 142 143 143 144 144 void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor) ··· 154 154 ARRAY_SIZE(a5xx_debugfs_list), 155 155 minor->debugfs_root, minor); 156 156 157 - debugfs_create_file("reset", S_IWUGO, minor->debugfs_root, dev, 158 - &reset_fops); 157 + debugfs_create_file_unsafe("reset", S_IWUGO, minor->debugfs_root, dev, 158 + &reset_fops); 159 159 }
+5 -5
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
··· 516 516 struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; 517 517 struct platform_device *pdev = to_platform_device(gmu->dev); 518 518 void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc"); 519 - void __iomem *seqptr; 519 + void __iomem *seqptr = NULL; 520 520 uint32_t pdc_address_offset; 521 521 bool pdc_in_aop = false; 522 522 523 - if (!pdcptr) 523 + if (IS_ERR(pdcptr)) 524 524 goto err; 525 525 526 526 if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) ··· 532 532 533 533 if (!pdc_in_aop) { 534 534 seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq"); 535 - if (!seqptr) 535 + if (IS_ERR(seqptr)) 536 536 goto err; 537 537 } 538 538 ··· 891 891 unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index]; 892 892 893 893 gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true); 894 - if (IS_ERR_OR_NULL(gpu_opp)) 894 + if (IS_ERR(gpu_opp)) 895 895 return; 896 896 897 897 gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */ ··· 905 905 unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index]; 906 906 907 907 gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true); 908 - if (IS_ERR_OR_NULL(gpu_opp)) 908 + if (IS_ERR(gpu_opp)) 909 909 return; 910 910 911 911 dev_pm_opp_set_opp(&gpu->pdev->dev, gpu_opp);
+1 -1
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
··· 180 180 msm_readl((ptr) + ((offset) << 2)) 181 181 182 182 /* read a value from the CX debug bus */ 183 - static int cx_debugbus_read(void *__iomem cxdbg, u32 block, u32 offset, 183 + static int cx_debugbus_read(void __iomem *cxdbg, u32 block, u32 offset, 184 184 u32 *data) 185 185 { 186 186 u32 reg = A6XX_CX_DBGC_CFG_DBGBUS_SEL_A_PING_INDEX(offset) |
-256
drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 - */ 4 - 5 - #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ 6 - 7 - #include <linux/debugfs.h> 8 - #include <linux/irqdomain.h> 9 - #include <linux/irq.h> 10 - #include <linux/kthread.h> 11 - 12 - #include "dpu_core_irq.h" 13 - #include "dpu_trace.h" 14 - 15 - /** 16 - * dpu_core_irq_callback_handler - dispatch core interrupts 17 - * @arg: private data of callback handler 18 - * @irq_idx: interrupt index 19 - */ 20 - static void dpu_core_irq_callback_handler(void *arg, int irq_idx) 21 - { 22 - struct dpu_kms *dpu_kms = arg; 23 - struct dpu_irq *irq_obj = &dpu_kms->irq_obj; 24 - struct dpu_irq_callback *cb; 25 - 26 - VERB("irq_idx=%d\n", irq_idx); 27 - 28 - if (list_empty(&irq_obj->irq_cb_tbl[irq_idx])) 29 - DRM_ERROR("no registered cb, idx:%d\n", irq_idx); 30 - 31 - atomic_inc(&irq_obj->irq_counts[irq_idx]); 32 - 33 - /* 34 - * Perform registered function callback 35 - */ 36 - list_for_each_entry(cb, &irq_obj->irq_cb_tbl[irq_idx], list) 37 - if (cb->func) 38 - cb->func(cb->arg, irq_idx); 39 - } 40 - 41 - u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx, bool clear) 42 - { 43 - if (!dpu_kms->hw_intr || 44 - !dpu_kms->hw_intr->ops.get_interrupt_status) 45 - return 0; 46 - 47 - if (irq_idx < 0) { 48 - DPU_ERROR("[%pS] invalid irq_idx=%d\n", 49 - __builtin_return_address(0), irq_idx); 50 - return 0; 51 - } 52 - 53 - return dpu_kms->hw_intr->ops.get_interrupt_status(dpu_kms->hw_intr, 54 - irq_idx, clear); 55 - } 56 - 57 - int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int irq_idx, 58 - struct dpu_irq_callback *register_irq_cb) 59 - { 60 - unsigned long irq_flags; 61 - 62 - if (!dpu_kms->irq_obj.irq_cb_tbl) { 63 - DPU_ERROR("invalid params\n"); 64 - return -EINVAL; 65 - } 66 - 67 - if (!register_irq_cb || !register_irq_cb->func) { 68 - DPU_ERROR("invalid irq_cb:%d func:%d\n", 69 - register_irq_cb != NULL, 70 - register_irq_cb ? 71 - register_irq_cb->func != NULL : -1); 72 - return -EINVAL; 73 - } 74 - 75 - if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { 76 - DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); 77 - return -EINVAL; 78 - } 79 - 80 - VERB("[%pS] irq_idx=%d\n", __builtin_return_address(0), irq_idx); 81 - 82 - irq_flags = dpu_kms->hw_intr->ops.lock(dpu_kms->hw_intr); 83 - trace_dpu_core_irq_register_callback(irq_idx, register_irq_cb); 84 - list_del_init(&register_irq_cb->list); 85 - list_add_tail(&register_irq_cb->list, 86 - &dpu_kms->irq_obj.irq_cb_tbl[irq_idx]); 87 - if (list_is_first(&register_irq_cb->list, 88 - &dpu_kms->irq_obj.irq_cb_tbl[irq_idx])) { 89 - int ret = dpu_kms->hw_intr->ops.enable_irq_locked( 90 - dpu_kms->hw_intr, 91 - irq_idx); 92 - if (ret) 93 - DPU_ERROR("Fail to enable IRQ for irq_idx:%d\n", 94 - irq_idx); 95 - } 96 - dpu_kms->hw_intr->ops.unlock(dpu_kms->hw_intr, irq_flags); 97 - 98 - return 0; 99 - } 100 - 101 - int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx, 102 - struct dpu_irq_callback *register_irq_cb) 103 - { 104 - unsigned long irq_flags; 105 - 106 - if (!dpu_kms->irq_obj.irq_cb_tbl) { 107 - DPU_ERROR("invalid params\n"); 108 - return -EINVAL; 109 - } 110 - 111 - if (!register_irq_cb || !register_irq_cb->func) { 112 - DPU_ERROR("invalid irq_cb:%d func:%d\n", 113 - register_irq_cb != NULL, 114 - register_irq_cb ? 115 - register_irq_cb->func != NULL : -1); 116 - return -EINVAL; 117 - } 118 - 119 - if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { 120 - DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); 121 - return -EINVAL; 122 - } 123 - 124 - VERB("[%pS] irq_idx=%d\n", __builtin_return_address(0), irq_idx); 125 - 126 - irq_flags = dpu_kms->hw_intr->ops.lock(dpu_kms->hw_intr); 127 - trace_dpu_core_irq_unregister_callback(irq_idx, register_irq_cb); 128 - list_del_init(&register_irq_cb->list); 129 - /* empty callback list but interrupt is still enabled */ 130 - if (list_empty(&dpu_kms->irq_obj.irq_cb_tbl[irq_idx])) { 131 - int ret = dpu_kms->hw_intr->ops.disable_irq_locked( 132 - dpu_kms->hw_intr, 133 - irq_idx); 134 - if (ret) 135 - DPU_ERROR("Fail to disable IRQ for irq_idx:%d\n", 136 - irq_idx); 137 - VERB("irq_idx=%d ret=%d\n", irq_idx, ret); 138 - } 139 - dpu_kms->hw_intr->ops.unlock(dpu_kms->hw_intr, irq_flags); 140 - 141 - return 0; 142 - } 143 - 144 - static void dpu_clear_all_irqs(struct dpu_kms *dpu_kms) 145 - { 146 - if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.clear_all_irqs) 147 - return; 148 - 149 - dpu_kms->hw_intr->ops.clear_all_irqs(dpu_kms->hw_intr); 150 - } 151 - 152 - static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms) 153 - { 154 - if (!dpu_kms->hw_intr || !dpu_kms->hw_intr->ops.disable_all_irqs) 155 - return; 156 - 157 - dpu_kms->hw_intr->ops.disable_all_irqs(dpu_kms->hw_intr); 158 - } 159 - 160 - #ifdef CONFIG_DEBUG_FS 161 - static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) 162 - { 163 - struct dpu_kms *dpu_kms = s->private; 164 - struct dpu_irq *irq_obj = &dpu_kms->irq_obj; 165 - struct dpu_irq_callback *cb; 166 - unsigned long irq_flags; 167 - int i, irq_count, cb_count; 168 - 169 - if (WARN_ON(!irq_obj->irq_cb_tbl)) 170 - return 0; 171 - 172 - for (i = 0; i < irq_obj->total_irqs; i++) { 173 - irq_flags = dpu_kms->hw_intr->ops.lock(dpu_kms->hw_intr); 174 - cb_count = 0; 175 - irq_count = atomic_read(&irq_obj->irq_counts[i]); 176 - list_for_each_entry(cb, &irq_obj->irq_cb_tbl[i], list) 177 - cb_count++; 178 - dpu_kms->hw_intr->ops.unlock(dpu_kms->hw_intr, irq_flags); 179 - 180 - if (irq_count || cb_count) 181 - seq_printf(s, "idx:%d irq:%d cb:%d\n", 182 - i, irq_count, cb_count); 183 - } 184 - 185 - return 0; 186 - } 187 - 188 - DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_core_irq); 189 - 190 - void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, 191 - struct dentry *parent) 192 - { 193 - debugfs_create_file("core_irq", 0600, parent, dpu_kms, 194 - &dpu_debugfs_core_irq_fops); 195 - } 196 - #endif 197 - 198 - void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms) 199 - { 200 - int i; 201 - 202 - pm_runtime_get_sync(&dpu_kms->pdev->dev); 203 - dpu_clear_all_irqs(dpu_kms); 204 - dpu_disable_all_irqs(dpu_kms); 205 - pm_runtime_put_sync(&dpu_kms->pdev->dev); 206 - 207 - /* Create irq callbacks for all possible irq_idx */ 208 - dpu_kms->irq_obj.total_irqs = dpu_kms->hw_intr->total_irqs; 209 - dpu_kms->irq_obj.irq_cb_tbl = kcalloc(dpu_kms->irq_obj.total_irqs, 210 - sizeof(struct list_head), GFP_KERNEL); 211 - dpu_kms->irq_obj.irq_counts = kcalloc(dpu_kms->irq_obj.total_irqs, 212 - sizeof(atomic_t), GFP_KERNEL); 213 - for (i = 0; i < dpu_kms->irq_obj.total_irqs; i++) { 214 - INIT_LIST_HEAD(&dpu_kms->irq_obj.irq_cb_tbl[i]); 215 - atomic_set(&dpu_kms->irq_obj.irq_counts[i], 0); 216 - } 217 - } 218 - 219 - void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms) 220 - { 221 - int i; 222 - 223 - pm_runtime_get_sync(&dpu_kms->pdev->dev); 224 - for (i = 0; i < dpu_kms->irq_obj.total_irqs; i++) 225 - if (!list_empty(&dpu_kms->irq_obj.irq_cb_tbl[i])) 226 - DPU_ERROR("irq_idx=%d still enabled/registered\n", i); 227 - 228 - dpu_clear_all_irqs(dpu_kms); 229 - dpu_disable_all_irqs(dpu_kms); 230 - pm_runtime_put_sync(&dpu_kms->pdev->dev); 231 - 232 - kfree(dpu_kms->irq_obj.irq_cb_tbl); 233 - kfree(dpu_kms->irq_obj.irq_counts); 234 - dpu_kms->irq_obj.irq_cb_tbl = NULL; 235 - dpu_kms->irq_obj.irq_counts = NULL; 236 - dpu_kms->irq_obj.total_irqs = 0; 237 - } 238 - 239 - irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms) 240 - { 241 - /* 242 - * Dispatch to HW driver to handle interrupt lookup that is being 243 - * fired. When matching interrupt is located, HW driver will call to 244 - * dpu_core_irq_callback_handler with the irq_idx from the lookup table. 245 - * dpu_core_irq_callback_handler will perform the registered function 246 - * callback, and do the interrupt status clearing once the registered 247 - * callback is finished. 248 - * Function will also clear the interrupt status after reading. 249 - */ 250 - dpu_kms->hw_intr->ops.dispatch_irqs( 251 - dpu_kms->hw_intr, 252 - dpu_core_irq_callback_handler, 253 - dpu_kms); 254 - 255 - return IRQ_HANDLED; 256 - }
+143 -8
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. 3 + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 4 4 * Copyright (C) 2013 Red Hat 5 5 * Author: Rob Clark <robdclark@gmail.com> 6 6 */ ··· 70 70 return NULL; 71 71 } 72 72 73 - static u32 dpu_crtc_get_vblank_counter(struct drm_crtc *crtc) 73 + static enum dpu_crtc_crc_source dpu_crtc_parse_crc_source(const char *src_name) 74 74 { 75 - struct drm_encoder *encoder; 75 + if (!src_name || 76 + !strcmp(src_name, "none")) 77 + return DPU_CRTC_CRC_SOURCE_NONE; 78 + if (!strcmp(src_name, "auto") || 79 + !strcmp(src_name, "lm")) 80 + return DPU_CRTC_CRC_SOURCE_LAYER_MIXER; 76 81 77 - encoder = get_encoder_from_crtc(crtc); 78 - if (!encoder) { 79 - DRM_ERROR("no encoder found for crtc %d\n", crtc->index); 80 - return false; 82 + return DPU_CRTC_CRC_SOURCE_INVALID; 83 + } 84 + 85 + static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc, 86 + const char *src_name, size_t *values_cnt) 87 + { 88 + enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); 89 + struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state); 90 + 91 + if (source < 0) { 92 + DRM_DEBUG_DRIVER("Invalid source %s for CRTC%d\n", src_name, crtc->index); 93 + return -EINVAL; 81 94 } 82 95 83 - return dpu_encoder_get_frame_count(encoder); 96 + if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) 97 + *values_cnt = crtc_state->num_mixers; 98 + 99 + return 0; 100 + } 101 + 102 + static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) 103 + { 104 + enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name); 105 + enum dpu_crtc_crc_source current_source; 106 + struct dpu_crtc_state *crtc_state; 107 + struct drm_device *drm_dev = crtc->dev; 108 + struct dpu_crtc_mixer *m; 109 + 110 + bool was_enabled; 111 + bool enable = false; 112 + int i, ret = 0; 113 + 114 + if (source < 0) { 115 + DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index); 116 + return -EINVAL; 117 + } 118 + 119 + ret = drm_modeset_lock(&crtc->mutex, NULL); 120 + 121 + if (ret) 122 + return ret; 123 + 124 + enable = (source != DPU_CRTC_CRC_SOURCE_NONE); 125 + crtc_state = to_dpu_crtc_state(crtc->state); 126 + 127 + spin_lock_irq(&drm_dev->event_lock); 128 + current_source = crtc_state->crc_source; 129 + spin_unlock_irq(&drm_dev->event_lock); 130 + 131 + was_enabled = (current_source != DPU_CRTC_CRC_SOURCE_NONE); 132 + 133 + if (!was_enabled && enable) { 134 + ret = drm_crtc_vblank_get(crtc); 135 + 136 + if (ret) 137 + goto cleanup; 138 + 139 + } else if (was_enabled && !enable) { 140 + drm_crtc_vblank_put(crtc); 141 + } 142 + 143 + spin_lock_irq(&drm_dev->event_lock); 144 + crtc_state->crc_source = source; 145 + spin_unlock_irq(&drm_dev->event_lock); 146 + 147 + crtc_state->crc_frame_skip_count = 0; 148 + 149 + for (i = 0; i < crtc_state->num_mixers; ++i) { 150 + m = &crtc_state->mixers[i]; 151 + 152 + if (!m->hw_lm || !m->hw_lm->ops.setup_misr) 153 + continue; 154 + 155 + /* Calculate MISR over 1 frame */ 156 + m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); 157 + } 158 + 159 + 160 + cleanup: 161 + drm_modeset_unlock(&crtc->mutex); 162 + 163 + return ret; 164 + } 165 + 166 + static u32 dpu_crtc_get_vblank_counter(struct drm_crtc *crtc) 167 + { 168 + struct drm_encoder *encoder = get_encoder_from_crtc(crtc); 169 + if (!encoder) { 170 + DRM_ERROR("no encoder found for crtc %d\n", crtc->index); 171 + return 0; 172 + } 173 + 174 + return dpu_encoder_get_vsync_count(encoder); 175 + } 176 + 177 + 178 + static int dpu_crtc_get_crc(struct drm_crtc *crtc) 179 + { 180 + struct dpu_crtc_state *crtc_state; 181 + struct dpu_crtc_mixer *m; 182 + u32 crcs[CRTC_DUAL_MIXERS]; 183 + 184 + int i = 0; 185 + int rc = 0; 186 + 187 + crtc_state = to_dpu_crtc_state(crtc->state); 188 + 189 + BUILD_BUG_ON(ARRAY_SIZE(crcs) != ARRAY_SIZE(crtc_state->mixers)); 190 + 191 + /* Skip first 2 frames in case of "uncooked" CRCs */ 192 + if (crtc_state->crc_frame_skip_count < 2) { 193 + crtc_state->crc_frame_skip_count++; 194 + return 0; 195 + } 196 + 197 + for (i = 0; i < crtc_state->num_mixers; ++i) { 198 + 199 + m = &crtc_state->mixers[i]; 200 + 201 + if (!m->hw_lm || !m->hw_lm->ops.collect_misr) 202 + continue; 203 + 204 + rc = m->hw_lm->ops.collect_misr(m->hw_lm, &crcs[i]); 205 + 206 + if (rc) { 207 + DRM_DEBUG_DRIVER("MISR read failed\n"); 208 + return rc; 209 + } 210 + } 211 + 212 + return drm_crtc_add_crc_entry(crtc, true, 213 + drm_crtc_accurate_vblank_count(crtc), crcs); 84 214 } 85 215 86 216 static bool dpu_crtc_get_scanout_position(struct drm_crtc *crtc, ··· 519 389 dpu_crtc->vblank_cb_time = ktime_get(); 520 390 else 521 391 dpu_crtc->vblank_cb_count++; 392 + 393 + dpu_crtc_get_crc(crtc); 394 + 522 395 drm_crtc_handle_vblank(crtc); 523 396 trace_dpu_crtc_vblank_cb(DRMID(crtc)); 524 397 } ··· 1465 1332 .atomic_destroy_state = dpu_crtc_destroy_state, 1466 1333 .late_register = dpu_crtc_late_register, 1467 1334 .early_unregister = dpu_crtc_early_unregister, 1335 + .verify_crc_source = dpu_crtc_verify_crc_source, 1336 + .set_crc_source = dpu_crtc_set_crc_source, 1468 1337 .enable_vblank = msm_crtc_enable_vblank, 1469 1338 .disable_vblank = msm_crtc_disable_vblank, 1470 1339 .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+18 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. 3 + * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. 4 4 * Copyright (C) 2013 Red Hat 5 5 * Author: Rob Clark <robdclark@gmail.com> 6 6 */ ··· 67 67 uint32_t state; 68 68 uint32_t transition_type; 69 69 uint32_t transition_error; 70 + }; 71 + 72 + /** 73 + * enum dpu_crtc_crc_source: CRC source 74 + * @DPU_CRTC_CRC_SOURCE_NONE: no source set 75 + * @DPU_CRTC_CRC_SOURCE_LAYER_MIXER: CRC in layer mixer 76 + * @DPU_CRTC_CRC_SOURCE_INVALID: Invalid source 77 + */ 78 + enum dpu_crtc_crc_source { 79 + DPU_CRTC_CRC_SOURCE_NONE = 0, 80 + DPU_CRTC_CRC_SOURCE_LAYER_MIXER, 81 + DPU_CRTC_CRC_SOURCE_MAX, 82 + DPU_CRTC_CRC_SOURCE_INVALID = -1 70 83 }; 71 84 72 85 /** ··· 152 139 * @event_lock : Spinlock around event handling code 153 140 * @phandle: Pointer to power handler 154 141 * @cur_perf : current performance committed to clock/bandwidth driver 142 + * @crc_source : CRC source 155 143 */ 156 144 struct dpu_crtc { 157 145 struct drm_crtc base; ··· 224 210 225 211 u32 num_ctls; 226 212 struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS]; 213 + 214 + enum dpu_crtc_crc_source crc_source; 215 + int crc_frame_skip_count; 227 216 }; 228 217 229 218 #define to_dpu_crtc_state(x) \
+17 -22
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
··· 168 168 * @vsync_event_work: worker to handle vsync event for autorefresh 169 169 * @topology: topology of the display 170 170 * @idle_timeout: idle timeout duration in milliseconds 171 + * @dp: msm_dp pointer, for DP encoders 171 172 */ 172 173 struct dpu_encoder_virt { 173 174 struct drm_encoder base; ··· 207 206 struct msm_display_topology topology; 208 207 209 208 u32 idle_timeout; 209 + 210 + struct msm_dp *dp; 210 211 }; 211 212 212 213 #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) ··· 398 395 return 0; 399 396 } 400 397 401 - int dpu_encoder_get_frame_count(struct drm_encoder *drm_enc) 398 + int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc) 402 399 { 403 - struct dpu_encoder_virt *dpu_enc; 404 - struct dpu_encoder_phys *phys; 405 - int framecount = 0; 406 - 407 - dpu_enc = to_dpu_encoder_virt(drm_enc); 408 - phys = dpu_enc ? dpu_enc->cur_master : NULL; 409 - 410 - if (phys && phys->ops.get_frame_count) 411 - framecount = phys->ops.get_frame_count(phys); 412 - 413 - return framecount; 400 + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); 401 + struct dpu_encoder_phys *phys = dpu_enc ? dpu_enc->cur_master : NULL; 402 + return phys ? atomic_read(&phys->vsync_cnt) : 0; 414 403 } 415 404 416 405 int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) ··· 995 1000 996 1001 trace_dpu_enc_mode_set(DRMID(drm_enc)); 997 1002 998 - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) 999 - msm_dp_display_mode_set(priv->dp, drm_enc, mode, adj_mode); 1003 + if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) 1004 + msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode); 1000 1005 1001 1006 list_for_each_entry(conn_iter, connector_list, head) 1002 1007 if (conn_iter->encoder == drm_enc) ··· 1177 1182 1178 1183 _dpu_encoder_virt_enable_helper(drm_enc); 1179 1184 1180 - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) { 1181 - ret = msm_dp_display_enable(priv->dp, 1182 - drm_enc); 1185 + if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { 1186 + ret = msm_dp_display_enable(dpu_enc->dp, drm_enc); 1183 1187 if (ret) { 1184 1188 DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n", 1185 1189 ret); ··· 1218 1224 /* wait for idle */ 1219 1225 dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); 1220 1226 1221 - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) { 1222 - if (msm_dp_display_pre_disable(priv->dp, drm_enc)) 1227 + if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { 1228 + if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc)) 1223 1229 DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n"); 1224 1230 } 1225 1231 ··· 1247 1253 1248 1254 DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); 1249 1255 1250 - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) { 1251 - if (msm_dp_display_disable(priv->dp, drm_enc)) 1256 + if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { 1257 + if (msm_dp_display_disable(dpu_enc->dp, drm_enc)) 1252 1258 DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n"); 1253 1259 } 1254 1260 ··· 2164 2170 timer_setup(&dpu_enc->vsync_event_timer, 2165 2171 dpu_encoder_vsync_event_handler, 2166 2172 0); 2167 - 2173 + else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) 2174 + dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]]; 2168 2175 2169 2176 INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, 2170 2177 dpu_encoder_off_work);
+2 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
··· 163 163 int dpu_encoder_get_linecount(struct drm_encoder *drm_enc); 164 164 165 165 /** 166 - * dpu_encoder_get_frame_count - get interface frame count for the encoder. 166 + * dpu_encoder_get_vsync_count - get vsync count for the encoder. 167 167 * @drm_enc: Pointer to previously created drm encoder structure 168 168 */ 169 - int dpu_encoder_get_frame_count(struct drm_encoder *drm_enc); 169 + int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc); 170 170 171 171 #endif /* __DPU_ENCODER_H__ */
+1 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
··· 42 42 43 43 static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) 44 44 { 45 - return (phys_enc->split_role != ENC_ROLE_SLAVE) ? true : false; 45 + return (phys_enc->split_role != ENC_ROLE_SLAVE); 46 46 } 47 47 48 48 static bool dpu_encoder_phys_cmd_mode_fixup(
+1 -7
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
··· 844 844 }; 845 845 846 846 static const struct dpu_intf_cfg sc7180_intf[] = { 847 - INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), 847 + INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25), 848 848 INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27), 849 849 }; 850 850 ··· 958 958 .min_core_ib = 2400000, 959 959 .min_llcc_ib = 800000, 960 960 .min_dram_ib = 800000, 961 - .core_ib_ff = "6.0", 962 - .core_clk_ff = "1.0", 963 - .comp_ratio_rt = 964 - "NV12/5/1/1.23 AB24/5/1/1.23 XB24/5/1/1.23", 965 - .comp_ratio_nrt = 966 - "NV12/5/1/1.25 AB24/5/1/1.25 XB24/5/1/1.25", 967 961 .undersized_prefill_lines = 2, 968 962 .xtra_prefill_lines = 2, 969 963 .dest_scale_prefill_lines = 3,
-8
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
··· 676 676 * @min_core_ib minimum mnoc ib vote in kbps 677 677 * @min_llcc_ib minimum llcc ib vote in kbps 678 678 * @min_dram_ib minimum dram ib vote in kbps 679 - * @core_ib_ff core instantaneous bandwidth fudge factor 680 - * @core_clk_ff core clock fudge factor 681 - * @comp_ratio_rt string of 0 or more of <fourcc>/<ven>/<mod>/<comp ratio> 682 - * @comp_ratio_nrt string of 0 or more of <fourcc>/<ven>/<mod>/<comp ratio> 683 679 * @undersized_prefill_lines undersized prefill in lines 684 680 * @xtra_prefill_lines extra prefill latency in lines 685 681 * @dest_scale_prefill_lines destination scaler latency in lines ··· 698 702 u32 min_core_ib; 699 703 u32 min_llcc_ib; 700 704 u32 min_dram_ib; 701 - const char *core_ib_ff; 702 - const char *core_clk_ff; 703 - const char *comp_ratio_rt; 704 - const char *comp_ratio_nrt; 705 705 u32 undersized_prefill_lines; 706 706 u32 xtra_prefill_lines; 707 707 u32 dest_scale_prefill_lines;
+202 -65
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
··· 3 3 */ 4 4 5 5 #include <linux/bitops.h> 6 + #include <linux/debugfs.h> 6 7 #include <linux/slab.h> 7 8 9 + #include "dpu_core_irq.h" 8 10 #include "dpu_kms.h" 9 11 #include "dpu_hw_interrupts.h" 10 12 #include "dpu_hw_util.h" 11 13 #include "dpu_hw_mdss.h" 14 + #include "dpu_trace.h" 12 15 13 16 /** 14 17 * Register offsets in MDSS register file for the interrupt registers ··· 120 117 #define DPU_IRQ_REG(irq_idx) (irq_idx / 32) 121 118 #define DPU_IRQ_MASK(irq_idx) (BIT(irq_idx % 32)) 122 119 123 - static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr *intr, 124 - int irq_idx) 120 + /** 121 + * dpu_core_irq_callback_handler - dispatch core interrupts 122 + * @arg: private data of callback handler 123 + * @irq_idx: interrupt index 124 + */ 125 + static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int irq_idx) 125 126 { 126 - int reg_idx; 127 + struct dpu_irq_callback *cb; 127 128 128 - if (!intr) 129 - return; 129 + VERB("irq_idx=%d\n", irq_idx); 130 130 131 - reg_idx = DPU_IRQ_REG(irq_idx); 132 - DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off, DPU_IRQ_MASK(irq_idx)); 131 + if (list_empty(&dpu_kms->hw_intr->irq_cb_tbl[irq_idx])) 132 + DRM_ERROR("no registered cb, idx:%d\n", irq_idx); 133 133 134 - /* ensure register writes go through */ 135 - wmb(); 134 + atomic_inc(&dpu_kms->hw_intr->irq_counts[irq_idx]); 135 + 136 + /* 137 + * Perform registered function callback 138 + */ 139 + list_for_each_entry(cb, &dpu_kms->hw_intr->irq_cb_tbl[irq_idx], list) 140 + if (cb->func) 141 + cb->func(cb->arg, irq_idx); 136 142 } 137 143 138 - static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr, 139 - void (*cbfunc)(void *, int), 140 - void *arg) 144 + irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms) 141 145 { 146 + struct dpu_hw_intr *intr = dpu_kms->hw_intr; 142 147 int reg_idx; 143 148 int irq_idx; 144 149 u32 irq_status; ··· 155 144 unsigned long irq_flags; 156 145 157 146 if (!intr) 158 - return; 147 + return IRQ_NONE; 159 148 160 - /* 161 - * The dispatcher will save the IRQ status before calling here. 162 - * Now need to go through each IRQ status and find matching 163 - * irq lookup index. 164 - */ 165 149 spin_lock_irqsave(&intr->irq_lock, irq_flags); 166 150 for (reg_idx = 0; reg_idx < ARRAY_SIZE(dpu_intr_set); reg_idx++) { 167 151 if (!test_bit(reg_idx, &intr->irq_mask)) ··· 184 178 */ 185 179 while ((bit = ffs(irq_status)) != 0) { 186 180 irq_idx = DPU_IRQ_IDX(reg_idx, bit - 1); 187 - /* 188 - * Once a match on irq mask, perform a callback 189 - * to the given cbfunc. cbfunc will take care 190 - * the interrupt status clearing. If cbfunc is 191 - * not provided, then the interrupt clearing 192 - * is here. 193 - */ 194 - if (cbfunc) 195 - cbfunc(arg, irq_idx); 196 181 197 - dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx); 182 + dpu_core_irq_callback_handler(dpu_kms, irq_idx); 198 183 199 184 /* 200 185 * When callback finish, clear the irq_status ··· 200 203 wmb(); 201 204 202 205 spin_unlock_irqrestore(&intr->irq_lock, irq_flags); 206 + 207 + return IRQ_HANDLED; 203 208 } 204 209 205 210 static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx) ··· 302 303 return 0; 303 304 } 304 305 305 - static int dpu_hw_intr_clear_irqs(struct dpu_hw_intr *intr) 306 + static void dpu_clear_irqs(struct dpu_kms *dpu_kms) 306 307 { 308 + struct dpu_hw_intr *intr = dpu_kms->hw_intr; 307 309 int i; 308 310 309 311 if (!intr) 310 - return -EINVAL; 312 + return; 311 313 312 314 for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) { 313 315 if (test_bit(i, &intr->irq_mask)) ··· 318 318 319 319 /* ensure register writes go through */ 320 320 wmb(); 321 - 322 - return 0; 323 321 } 324 322 325 - static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr) 323 + static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms) 326 324 { 325 + struct dpu_hw_intr *intr = dpu_kms->hw_intr; 327 326 int i; 328 327 329 328 if (!intr) 330 - return -EINVAL; 329 + return; 331 330 332 331 for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) { 333 332 if (test_bit(i, &intr->irq_mask)) ··· 336 337 337 338 /* ensure register writes go through */ 338 339 wmb(); 339 - 340 - return 0; 341 340 } 342 341 343 - static u32 dpu_hw_intr_get_interrupt_status(struct dpu_hw_intr *intr, 344 - int irq_idx, bool clear) 342 + u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx, bool clear) 345 343 { 344 + struct dpu_hw_intr *intr = dpu_kms->hw_intr; 346 345 int reg_idx; 347 346 unsigned long irq_flags; 348 347 u32 intr_status; 349 348 350 349 if (!intr) 351 350 return 0; 351 + 352 + if (irq_idx < 0) { 353 + DPU_ERROR("[%pS] invalid irq_idx=%d\n", 354 + __builtin_return_address(0), irq_idx); 355 + return 0; 356 + } 352 357 353 358 if (irq_idx < 0 || irq_idx >= intr->total_irqs) { 354 359 pr_err("invalid IRQ index: [%d]\n", irq_idx); ··· 377 374 return intr_status; 378 375 } 379 376 380 - static unsigned long dpu_hw_intr_lock(struct dpu_hw_intr *intr) 381 - { 382 - unsigned long irq_flags; 383 - 384 - spin_lock_irqsave(&intr->irq_lock, irq_flags); 385 - 386 - return irq_flags; 387 - } 388 - 389 - static void dpu_hw_intr_unlock(struct dpu_hw_intr *intr, unsigned long irq_flags) 390 - { 391 - spin_unlock_irqrestore(&intr->irq_lock, irq_flags); 392 - } 393 - 394 - static void __setup_intr_ops(struct dpu_hw_intr_ops *ops) 395 - { 396 - ops->enable_irq_locked = dpu_hw_intr_enable_irq_locked; 397 - ops->disable_irq_locked = dpu_hw_intr_disable_irq_locked; 398 - ops->dispatch_irqs = dpu_hw_intr_dispatch_irq; 399 - ops->clear_all_irqs = dpu_hw_intr_clear_irqs; 400 - ops->disable_all_irqs = dpu_hw_intr_disable_irqs; 401 - ops->get_interrupt_status = dpu_hw_intr_get_interrupt_status; 402 - ops->lock = dpu_hw_intr_lock; 403 - ops->unlock = dpu_hw_intr_unlock; 404 - } 405 - 406 377 static void __intr_offset(struct dpu_mdss_cfg *m, 407 378 void __iomem *addr, struct dpu_hw_blk_reg_map *hw) 408 379 { ··· 398 421 return ERR_PTR(-ENOMEM); 399 422 400 423 __intr_offset(m, addr, &intr->hw); 401 - __setup_intr_ops(&intr->ops); 402 424 403 425 intr->total_irqs = ARRAY_SIZE(dpu_intr_set) * 32; 404 426 ··· 419 443 { 420 444 if (intr) { 421 445 kfree(intr->cache_irq_mask); 446 + 447 + kfree(intr->irq_cb_tbl); 448 + kfree(intr->irq_counts); 449 + 422 450 kfree(intr); 423 451 } 424 452 } 425 453 454 + int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int irq_idx, 455 + struct dpu_irq_callback *register_irq_cb) 456 + { 457 + unsigned long irq_flags; 458 + 459 + if (!dpu_kms->hw_intr->irq_cb_tbl) { 460 + DPU_ERROR("invalid params\n"); 461 + return -EINVAL; 462 + } 463 + 464 + if (!register_irq_cb || !register_irq_cb->func) { 465 + DPU_ERROR("invalid irq_cb:%d func:%d\n", 466 + register_irq_cb != NULL, 467 + register_irq_cb ? 468 + register_irq_cb->func != NULL : -1); 469 + return -EINVAL; 470 + } 471 + 472 + if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { 473 + DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); 474 + return -EINVAL; 475 + } 476 + 477 + VERB("[%pS] irq_idx=%d\n", __builtin_return_address(0), irq_idx); 478 + 479 + spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 480 + trace_dpu_core_irq_register_callback(irq_idx, register_irq_cb); 481 + list_del_init(&register_irq_cb->list); 482 + list_add_tail(&register_irq_cb->list, 483 + &dpu_kms->hw_intr->irq_cb_tbl[irq_idx]); 484 + if (list_is_first(&register_irq_cb->list, 485 + &dpu_kms->hw_intr->irq_cb_tbl[irq_idx])) { 486 + int ret = dpu_hw_intr_enable_irq_locked( 487 + dpu_kms->hw_intr, 488 + irq_idx); 489 + if (ret) 490 + DPU_ERROR("Fail to enable IRQ for irq_idx:%d\n", 491 + irq_idx); 492 + } 493 + spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 494 + 495 + return 0; 496 + } 497 + 498 + int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int irq_idx, 499 + struct dpu_irq_callback *register_irq_cb) 500 + { 501 + unsigned long irq_flags; 502 + 503 + if (!dpu_kms->hw_intr->irq_cb_tbl) { 504 + DPU_ERROR("invalid params\n"); 505 + return -EINVAL; 506 + } 507 + 508 + if (!register_irq_cb || !register_irq_cb->func) { 509 + DPU_ERROR("invalid irq_cb:%d func:%d\n", 510 + register_irq_cb != NULL, 511 + register_irq_cb ? 512 + register_irq_cb->func != NULL : -1); 513 + return -EINVAL; 514 + } 515 + 516 + if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) { 517 + DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx); 518 + return -EINVAL; 519 + } 520 + 521 + VERB("[%pS] irq_idx=%d\n", __builtin_return_address(0), irq_idx); 522 + 523 + spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 524 + trace_dpu_core_irq_unregister_callback(irq_idx, register_irq_cb); 525 + list_del_init(&register_irq_cb->list); 526 + /* empty callback list but interrupt is still enabled */ 527 + if (list_empty(&dpu_kms->hw_intr->irq_cb_tbl[irq_idx])) { 528 + int ret = dpu_hw_intr_disable_irq_locked( 529 + dpu_kms->hw_intr, 530 + irq_idx); 531 + if (ret) 532 + DPU_ERROR("Fail to disable IRQ for irq_idx:%d\n", 533 + irq_idx); 534 + VERB("irq_idx=%d ret=%d\n", irq_idx, ret); 535 + } 536 + spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 537 + 538 + return 0; 539 + } 540 + 541 + #ifdef CONFIG_DEBUG_FS 542 + static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) 543 + { 544 + struct dpu_kms *dpu_kms = s->private; 545 + struct dpu_irq_callback *cb; 546 + unsigned long irq_flags; 547 + int i, irq_count, cb_count; 548 + 549 + if (WARN_ON(!dpu_kms->hw_intr->irq_cb_tbl)) 550 + return 0; 551 + 552 + for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { 553 + spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags); 554 + cb_count = 0; 555 + irq_count = atomic_read(&dpu_kms->hw_intr->irq_counts[i]); 556 + list_for_each_entry(cb, &dpu_kms->hw_intr->irq_cb_tbl[i], list) 557 + cb_count++; 558 + spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags); 559 + 560 + if (irq_count || cb_count) 561 + seq_printf(s, "idx:%d irq:%d cb:%d\n", 562 + i, irq_count, cb_count); 563 + } 564 + 565 + return 0; 566 + } 567 + 568 + DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_core_irq); 569 + 570 + void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, 571 + struct dentry *parent) 572 + { 573 + debugfs_create_file("core_irq", 0600, parent, dpu_kms, 574 + &dpu_debugfs_core_irq_fops); 575 + } 576 + #endif 577 + 578 + void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms) 579 + { 580 + int i; 581 + 582 + pm_runtime_get_sync(&dpu_kms->pdev->dev); 583 + dpu_clear_irqs(dpu_kms); 584 + dpu_disable_all_irqs(dpu_kms); 585 + pm_runtime_put_sync(&dpu_kms->pdev->dev); 586 + 587 + /* Create irq callbacks for all possible irq_idx */ 588 + dpu_kms->hw_intr->irq_cb_tbl = kcalloc(dpu_kms->hw_intr->total_irqs, 589 + sizeof(struct list_head), GFP_KERNEL); 590 + dpu_kms->hw_intr->irq_counts = kcalloc(dpu_kms->hw_intr->total_irqs, 591 + sizeof(atomic_t), GFP_KERNEL); 592 + for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) { 593 + INIT_LIST_HEAD(&dpu_kms->hw_intr->irq_cb_tbl[i]); 594 + atomic_set(&dpu_kms->hw_intr->irq_counts[i], 0); 595 + } 596 + } 597 + 598 + void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms) 599 + { 600 + int i; 601 + 602 + pm_runtime_get_sync(&dpu_kms->pdev->dev); 603 + for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) 604 + if (!list_empty(&dpu_kms->hw_intr->irq_cb_tbl[i])) 605 + DPU_ERROR("irq_idx=%d still enabled/registered\n", i); 606 + 607 + dpu_clear_irqs(dpu_kms); 608 + dpu_disable_all_irqs(dpu_kms); 609 + pm_runtime_put_sync(&dpu_kms->pdev->dev); 610 + }
+5 -87
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
··· 32 32 33 33 #define DPU_IRQ_IDX(reg_idx, offset) (reg_idx * 32 + offset) 34 34 35 - struct dpu_hw_intr; 36 - 37 - /** 38 - * Interrupt operations. 39 - */ 40 - struct dpu_hw_intr_ops { 41 - 42 - /** 43 - * enable_irq - Enable IRQ based on lookup IRQ index 44 - * @intr: HW interrupt handle 45 - * @irq_idx: Lookup irq index return from irq_idx_lookup 46 - * @return: 0 for success, otherwise failure 47 - */ 48 - int (*enable_irq_locked)( 49 - struct dpu_hw_intr *intr, 50 - int irq_idx); 51 - 52 - /** 53 - * disable_irq - Disable IRQ based on lookup IRQ index 54 - * @intr: HW interrupt handle 55 - * @irq_idx: Lookup irq index return from irq_idx_lookup 56 - * @return: 0 for success, otherwise failure 57 - */ 58 - int (*disable_irq_locked)( 59 - struct dpu_hw_intr *intr, 60 - int irq_idx); 61 - 62 - /** 63 - * clear_all_irqs - Clears all the interrupts (i.e. acknowledges 64 - * any asserted IRQs). Useful during reset. 65 - * @intr: HW interrupt handle 66 - * @return: 0 for success, otherwise failure 67 - */ 68 - int (*clear_all_irqs)( 69 - struct dpu_hw_intr *intr); 70 - 71 - /** 72 - * disable_all_irqs - Disables all the interrupts. Useful during reset. 73 - * @intr: HW interrupt handle 74 - * @return: 0 for success, otherwise failure 75 - */ 76 - int (*disable_all_irqs)( 77 - struct dpu_hw_intr *intr); 78 - 79 - /** 80 - * dispatch_irqs - IRQ dispatcher will call the given callback 81 - * function when a matching interrupt status bit is 82 - * found in the irq mapping table. 83 - * @intr: HW interrupt handle 84 - * @cbfunc: Callback function pointer 85 - * @arg: Argument to pass back during callback 86 - */ 87 - void (*dispatch_irqs)( 88 - struct dpu_hw_intr *intr, 89 - void (*cbfunc)(void *arg, int irq_idx), 90 - void *arg); 91 - 92 - /** 93 - * get_interrupt_status - Gets HW interrupt status, and clear if set, 94 - * based on given lookup IRQ index. 95 - * @intr: HW interrupt handle 96 - * @irq_idx: Lookup irq index return from irq_idx_lookup 97 - * @clear: True to clear irq after read 98 - */ 99 - u32 (*get_interrupt_status)( 100 - struct dpu_hw_intr *intr, 101 - int irq_idx, 102 - bool clear); 103 - 104 - /** 105 - * lock - take the IRQ lock 106 - * @intr: HW interrupt handle 107 - * @return: irq_flags for the taken spinlock 108 - */ 109 - unsigned long (*lock)( 110 - struct dpu_hw_intr *intr); 111 - 112 - /** 113 - * unlock - take the IRQ lock 114 - * @intr: HW interrupt handle 115 - * @irq_flags: the irq_flags returned from lock 116 - */ 117 - void (*unlock)( 118 - struct dpu_hw_intr *intr, unsigned long irq_flags); 119 - }; 120 - 121 35 /** 122 36 * struct dpu_hw_intr: hw interrupts handling data structure 123 37 * @hw: virtual address mapping ··· 40 126 * @save_irq_status: array of IRQ status reg storage created during init 41 127 * @total_irqs: total number of irq_idx mapped in the hw_interrupts 42 128 * @irq_lock: spinlock for accessing IRQ resources 129 + * @irq_cb_tbl: array of IRQ callbacks lists 130 + * @irq_counts: array of IRQ counts 43 131 */ 44 132 struct dpu_hw_intr { 45 133 struct dpu_hw_blk_reg_map hw; 46 - struct dpu_hw_intr_ops ops; 47 134 u32 *cache_irq_mask; 48 135 u32 *save_irq_status; 49 136 u32 total_irqs; 50 137 spinlock_t irq_lock; 51 138 unsigned long irq_mask; 139 + 140 + struct list_head *irq_cb_tbl; 141 + atomic_t *irq_counts; 52 142 }; 53 143 54 144 /**
+55 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 3 4 */ 4 5 5 6 #include "dpu_kms.h" ··· 24 23 25 24 #define LM_BLEND0_FG_ALPHA 0x04 26 25 #define LM_BLEND0_BG_ALPHA 0x08 26 + 27 + #define LM_MISR_CTRL 0x310 28 + #define LM_MISR_SIGNATURE 0x314 29 + #define LM_MISR_FRAME_COUNT_MASK 0xFF 30 + #define LM_MISR_CTRL_ENABLE BIT(8) 31 + #define LM_MISR_CTRL_STATUS BIT(9) 32 + #define LM_MISR_CTRL_STATUS_CLEAR BIT(10) 33 + #define LM_MISR_CTRL_FREE_RUN_MASK BIT(31) 34 + 27 35 28 36 static const struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, 29 37 const struct dpu_mdss_cfg *m, ··· 106 96 } 107 97 } 108 98 99 + static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) 100 + { 101 + struct dpu_hw_blk_reg_map *c = &ctx->hw; 102 + u32 config = 0; 103 + 104 + DPU_REG_WRITE(c, LM_MISR_CTRL, LM_MISR_CTRL_STATUS_CLEAR); 105 + 106 + /* Clear old MISR value (in case it's read before a new value is calculated)*/ 107 + wmb(); 108 + 109 + if (enable) { 110 + config = (frame_count & LM_MISR_FRAME_COUNT_MASK) | 111 + LM_MISR_CTRL_ENABLE | LM_MISR_CTRL_FREE_RUN_MASK; 112 + 113 + DPU_REG_WRITE(c, LM_MISR_CTRL, config); 114 + } else { 115 + DPU_REG_WRITE(c, LM_MISR_CTRL, 0); 116 + } 117 + 118 + } 119 + 120 + static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) 121 + { 122 + struct dpu_hw_blk_reg_map *c = &ctx->hw; 123 + u32 ctrl = 0; 124 + 125 + if (!misr_value) 126 + return -EINVAL; 127 + 128 + ctrl = DPU_REG_READ(c, LM_MISR_CTRL); 129 + 130 + if (!(ctrl & LM_MISR_CTRL_ENABLE)) 131 + return -EINVAL; 132 + 133 + if (!(ctrl & LM_MISR_CTRL_STATUS)) 134 + return -EINVAL; 135 + 136 + *misr_value = DPU_REG_READ(c, LM_MISR_SIGNATURE); 137 + 138 + return 0; 139 + } 140 + 109 141 static void dpu_hw_lm_setup_blend_config_sdm845(struct dpu_hw_mixer *ctx, 110 142 u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op) 111 143 { ··· 210 158 ops->setup_blend_config = dpu_hw_lm_setup_blend_config; 211 159 ops->setup_alpha_out = dpu_hw_lm_setup_color3; 212 160 ops->setup_border_color = dpu_hw_lm_setup_border_color; 161 + ops->setup_misr = dpu_hw_lm_setup_misr; 162 + ops->collect_misr = dpu_hw_lm_collect_misr; 213 163 } 214 164 215 165 struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx,
+12 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 3 4 */ 4 5 5 6 #ifndef _DPU_HW_LM_H ··· 54 53 void (*setup_border_color)(struct dpu_hw_mixer *ctx, 55 54 struct dpu_mdss_color *color, 56 55 u8 border_en); 56 + 57 + /** 58 + * setup_misr: Enable/disable MISR 59 + */ 60 + void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); 61 + 62 + /** 63 + * collect_misr: Read MISR signature 64 + */ 65 + int (*collect_misr)(struct dpu_hw_mixer *ctx, u32 *misr_value); 57 66 }; 58 67 59 68 struct dpu_hw_mixer {
+5 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
··· 138 138 u32 *idx) 139 139 { 140 140 int rc = 0; 141 - const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk; 141 + const struct dpu_sspp_sub_blks *sblk; 142 142 143 - if (!ctx) 143 + if (!ctx || !ctx->cap || !ctx->cap->sblk) 144 144 return -EINVAL; 145 + 146 + sblk = ctx->cap->sblk; 145 147 146 148 switch (s_id) { 147 149 case DPU_SSPP_SRC: ··· 421 419 422 420 (void)pe; 423 421 if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp 424 - || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk) 422 + || !scaler3_cfg) 425 423 return; 426 424 427 425 dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
+2 -1
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 2 + /* 3 + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. 3 4 */ 4 5 5 6 #ifndef _DPU_HW_UTIL_H
+44 -28
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
··· 188 188 struct dentry *entry; 189 189 struct drm_device *dev; 190 190 struct msm_drm_private *priv; 191 + int i; 191 192 192 193 if (!p) 193 194 return -EINVAL; ··· 204 203 dpu_debugfs_vbif_init(dpu_kms, entry); 205 204 dpu_debugfs_core_irq_init(dpu_kms, entry); 206 205 207 - if (priv->dp) 208 - msm_dp_debugfs_init(priv->dp, minor); 206 + for (i = 0; i < ARRAY_SIZE(priv->dp); i++) { 207 + if (priv->dp[i]) 208 + msm_dp_debugfs_init(priv->dp[i], minor); 209 + } 209 210 210 211 return dpu_core_perf_debugfs_init(dpu_kms, entry); 211 212 } ··· 547 544 { 548 545 struct drm_encoder *encoder = NULL; 549 546 struct msm_display_info info; 550 - int rc = 0; 547 + int rc; 548 + int i; 551 549 552 - if (!priv->dp) 553 - return rc; 550 + for (i = 0; i < ARRAY_SIZE(priv->dp); i++) { 551 + if (!priv->dp[i]) 552 + continue; 554 553 555 - encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS); 556 - if (IS_ERR(encoder)) { 557 - DPU_ERROR("encoder init failed for dsi display\n"); 558 - return PTR_ERR(encoder); 554 + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS); 555 + if (IS_ERR(encoder)) { 556 + DPU_ERROR("encoder init failed for dsi display\n"); 557 + return PTR_ERR(encoder); 558 + } 559 + 560 + memset(&info, 0, sizeof(info)); 561 + rc = msm_dp_modeset_init(priv->dp[i], dev, encoder); 562 + if (rc) { 563 + DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); 564 + drm_encoder_cleanup(encoder); 565 + return rc; 566 + } 567 + 568 + priv->encoders[priv->num_encoders++] = encoder; 569 + 570 + info.num_of_h_tiles = 1; 571 + info.h_tile_instance[0] = i; 572 + info.capabilities = MSM_DISPLAY_CAP_VID_MODE; 573 + info.intf_type = encoder->encoder_type; 574 + rc = dpu_encoder_setup(dev, encoder, &info); 575 + if (rc) { 576 + DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", 577 + encoder->base.id, rc); 578 + return rc; 579 + } 559 580 } 560 581 561 - memset(&info, 0, sizeof(info)); 562 - rc = msm_dp_modeset_init(priv->dp, dev, encoder); 563 - if (rc) { 564 - DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); 565 - drm_encoder_cleanup(encoder); 566 - return rc; 567 - } 568 - 569 - priv->encoders[priv->num_encoders++] = encoder; 570 - 571 - info.num_of_h_tiles = 1; 572 - info.capabilities = MSM_DISPLAY_CAP_VID_MODE; 573 - info.intf_type = encoder->encoder_type; 574 - rc = dpu_encoder_setup(dev, encoder, &info); 575 - if (rc) 576 - DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n", 577 - encoder->base.id, rc); 578 - return rc; 582 + return 0; 579 583 } 580 584 581 585 /** ··· 802 792 { 803 793 struct msm_drm_private *priv; 804 794 struct dpu_kms *dpu_kms = to_dpu_kms(kms); 795 + int i; 805 796 806 797 if (!dpu_kms || !dpu_kms->dev) 807 798 return -EINVAL; ··· 811 800 if (!priv) 812 801 return -EINVAL; 813 802 814 - msm_dp_irq_postinstall(priv->dp); 803 + for (i = 0; i < ARRAY_SIZE(priv->dp); i++) 804 + msm_dp_irq_postinstall(priv->dp[i]); 815 805 816 806 return 0; 817 807 } ··· 920 908 return 0; 921 909 922 910 mmu = msm_iommu_new(dpu_kms->dev->dev, domain); 911 + if (IS_ERR(mmu)) { 912 + iommu_domain_free(domain); 913 + return PTR_ERR(mmu); 914 + } 923 915 aspace = msm_gem_address_space_create(mmu, "dpu1", 924 916 0x1000, 0x100000000 - 0x1000); 925 917
-13
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
··· 78 78 void *arg; 79 79 }; 80 80 81 - /** 82 - * struct dpu_irq: IRQ structure contains callback registration info 83 - * @total_irq: total number of irq_idx obtained from HW interrupts mapping 84 - * @irq_cb_tbl: array of IRQ callbacks setting 85 - * @debugfs_file: debugfs file for irq statistics 86 - */ 87 - struct dpu_irq { 88 - u32 total_irqs; 89 - struct list_head *irq_cb_tbl; 90 - atomic_t *irq_counts; 91 - }; 92 - 93 81 struct dpu_kms { 94 82 struct msm_kms base; 95 83 struct drm_device *dev; ··· 92 104 struct regulator *venus; 93 105 94 106 struct dpu_hw_intr *hw_intr; 95 - struct dpu_irq irq_obj; 96 107 97 108 struct dpu_core_perf perf; 98 109
+2 -2
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
··· 1193 1193 if (DPU_FORMAT_IS_YUV(fmt)) 1194 1194 _dpu_plane_setup_csc(pdpu); 1195 1195 else 1196 - pdpu->csc_ptr = 0; 1196 + pdpu->csc_ptr = NULL; 1197 1197 } 1198 1198 1199 1199 _dpu_plane_set_qos_lut(plane, fb); ··· 1330 1330 /* remove previous state, if present */ 1331 1331 if (plane->state) { 1332 1332 dpu_plane_destroy_state(plane, plane->state); 1333 - plane->state = 0; 1333 + plane->state = NULL; 1334 1334 } 1335 1335 1336 1336 pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
+6 -12
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
··· 173 173 DBG(""); 174 174 175 175 clk_disable_unprepare(mdp4_kms->clk); 176 - if (mdp4_kms->pclk) 177 - clk_disable_unprepare(mdp4_kms->pclk); 178 - if (mdp4_kms->lut_clk) 179 - clk_disable_unprepare(mdp4_kms->lut_clk); 180 - if (mdp4_kms->axi_clk) 181 - clk_disable_unprepare(mdp4_kms->axi_clk); 176 + clk_disable_unprepare(mdp4_kms->pclk); 177 + clk_disable_unprepare(mdp4_kms->lut_clk); 178 + clk_disable_unprepare(mdp4_kms->axi_clk); 182 179 183 180 return 0; 184 181 } ··· 185 188 DBG(""); 186 189 187 190 clk_prepare_enable(mdp4_kms->clk); 188 - if (mdp4_kms->pclk) 189 - clk_prepare_enable(mdp4_kms->pclk); 190 - if (mdp4_kms->lut_clk) 191 - clk_prepare_enable(mdp4_kms->lut_clk); 192 - if (mdp4_kms->axi_clk) 193 - clk_prepare_enable(mdp4_kms->axi_clk); 191 + clk_prepare_enable(mdp4_kms->pclk); 192 + clk_prepare_enable(mdp4_kms->lut_clk); 193 + clk_prepare_enable(mdp4_kms->axi_clk); 194 194 195 195 return 0; 196 196 }
+89
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c
··· 752 752 .max_clk = 360000000, 753 753 }; 754 754 755 + static const struct mdp5_cfg_hw msm8x53_config = { 756 + .name = "msm8x53", 757 + .mdp = { 758 + .count = 1, 759 + .caps = MDP_CAP_CDM | 760 + MDP_CAP_SRC_SPLIT, 761 + }, 762 + .ctl = { 763 + .count = 3, 764 + .base = { 0x01000, 0x01200, 0x01400 }, 765 + .flush_hw_mask = 0xffffffff, 766 + }, 767 + .pipe_vig = { 768 + .count = 1, 769 + .base = { 0x04000 }, 770 + .caps = MDP_PIPE_CAP_HFLIP | 771 + MDP_PIPE_CAP_VFLIP | 772 + MDP_PIPE_CAP_SCALE | 773 + MDP_PIPE_CAP_CSC | 774 + MDP_PIPE_CAP_DECIMATION | 775 + MDP_PIPE_CAP_SW_PIX_EXT | 776 + 0, 777 + }, 778 + .pipe_rgb = { 779 + .count = 2, 780 + .base = { 0x14000, 0x16000 }, 781 + .caps = MDP_PIPE_CAP_HFLIP | 782 + MDP_PIPE_CAP_VFLIP | 783 + MDP_PIPE_CAP_DECIMATION | 784 + MDP_PIPE_CAP_SW_PIX_EXT | 785 + 0, 786 + }, 787 + .pipe_dma = { 788 + .count = 1, 789 + .base = { 0x24000 }, 790 + .caps = MDP_PIPE_CAP_HFLIP | 791 + MDP_PIPE_CAP_VFLIP | 792 + MDP_PIPE_CAP_SW_PIX_EXT | 793 + 0, 794 + }, 795 + .pipe_cursor = { 796 + .count = 1, 797 + .base = { 0x34000 }, 798 + .caps = MDP_PIPE_CAP_HFLIP | 799 + MDP_PIPE_CAP_VFLIP | 800 + MDP_PIPE_CAP_SW_PIX_EXT | 801 + MDP_PIPE_CAP_CURSOR | 802 + 0, 803 + }, 804 + 805 + .lm = { 806 + .count = 3, 807 + .base = { 0x44000, 0x45000 }, 808 + .instances = { 809 + { .id = 0, .pp = 0, .dspp = 0, 810 + .caps = MDP_LM_CAP_DISPLAY | 811 + MDP_LM_CAP_PAIR }, 812 + { .id = 1, .pp = 1, .dspp = -1, 813 + .caps = MDP_LM_CAP_DISPLAY }, 814 + }, 815 + .nb_stages = 5, 816 + .max_width = 2048, 817 + .max_height = 0xFFFF, 818 + }, 819 + .dspp = { 820 + .count = 1, 821 + .base = { 0x54000 }, 822 + 823 + }, 824 + .pp = { 825 + .count = 2, 826 + .base = { 0x70000, 0x70800 }, 827 + }, 828 + .cdm = { 829 + .count = 1, 830 + .base = { 0x79200 }, 831 + }, 832 + .intf = { 833 + .base = { 0x6a000, 0x6a800, 0x6b000 }, 834 + .connect = { 835 + [0] = INTF_DISABLED, 836 + [1] = INTF_DSI, 837 + [2] = INTF_DSI, 838 + }, 839 + }, 840 + .max_clk = 400000000, 841 + }; 842 + 755 843 static const struct mdp5_cfg_hw msm8917_config = { 756 844 .name = "msm8917", 757 845 .mdp = { ··· 1239 1151 { .revision = 7, .config = { .hw = &msm8x96_config } }, 1240 1152 { .revision = 11, .config = { .hw = &msm8x76_config } }, 1241 1153 { .revision = 15, .config = { .hw = &msm8917_config } }, 1154 + { .revision = 16, .config = { .hw = &msm8x53_config } }, 1242 1155 }; 1243 1156 1244 1157 static const struct mdp5_cfg_handler cfg_handlers_v3[] = {
+6 -12
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
··· 295 295 mdp5_kms->enable_count--; 296 296 WARN_ON(mdp5_kms->enable_count < 0); 297 297 298 - if (mdp5_kms->tbu_rt_clk) 299 - clk_disable_unprepare(mdp5_kms->tbu_rt_clk); 300 - if (mdp5_kms->tbu_clk) 301 - clk_disable_unprepare(mdp5_kms->tbu_clk); 298 + clk_disable_unprepare(mdp5_kms->tbu_rt_clk); 299 + clk_disable_unprepare(mdp5_kms->tbu_clk); 302 300 clk_disable_unprepare(mdp5_kms->ahb_clk); 303 301 clk_disable_unprepare(mdp5_kms->axi_clk); 304 302 clk_disable_unprepare(mdp5_kms->core_clk); 305 - if (mdp5_kms->lut_clk) 306 - clk_disable_unprepare(mdp5_kms->lut_clk); 303 + clk_disable_unprepare(mdp5_kms->lut_clk); 307 304 308 305 return 0; 309 306 } ··· 314 317 clk_prepare_enable(mdp5_kms->ahb_clk); 315 318 clk_prepare_enable(mdp5_kms->axi_clk); 316 319 clk_prepare_enable(mdp5_kms->core_clk); 317 - if (mdp5_kms->lut_clk) 318 - clk_prepare_enable(mdp5_kms->lut_clk); 319 - if (mdp5_kms->tbu_clk) 320 - clk_prepare_enable(mdp5_kms->tbu_clk); 321 - if (mdp5_kms->tbu_rt_clk) 322 - clk_prepare_enable(mdp5_kms->tbu_rt_clk); 320 + clk_prepare_enable(mdp5_kms->lut_clk); 321 + clk_prepare_enable(mdp5_kms->tbu_clk); 322 + clk_prepare_enable(mdp5_kms->tbu_rt_clk); 323 323 324 324 return 0; 325 325 }
+4 -8
drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
··· 136 136 DBG(""); 137 137 138 138 clk_prepare_enable(mdp5_mdss->ahb_clk); 139 - if (mdp5_mdss->axi_clk) 140 - clk_prepare_enable(mdp5_mdss->axi_clk); 141 - if (mdp5_mdss->vsync_clk) 142 - clk_prepare_enable(mdp5_mdss->vsync_clk); 139 + clk_prepare_enable(mdp5_mdss->axi_clk); 140 + clk_prepare_enable(mdp5_mdss->vsync_clk); 143 141 144 142 return 0; 145 143 } ··· 147 149 struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss); 148 150 DBG(""); 149 151 150 - if (mdp5_mdss->vsync_clk) 151 - clk_disable_unprepare(mdp5_mdss->vsync_clk); 152 - if (mdp5_mdss->axi_clk) 153 - clk_disable_unprepare(mdp5_mdss->axi_clk); 152 + clk_disable_unprepare(mdp5_mdss->vsync_clk); 153 + clk_disable_unprepare(mdp5_mdss->axi_clk); 154 154 clk_disable_unprepare(mdp5_mdss->ahb_clk); 155 155 156 156 return 0;
+6 -2
drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
··· 126 126 priv = drm_dev->dev_private; 127 127 kms = priv->kms; 128 128 129 - if (priv->dp) 130 - msm_dp_snapshot(disp_state, priv->dp); 129 + for (i = 0; i < ARRAY_SIZE(priv->dp); i++) { 130 + if (!priv->dp[i]) 131 + continue; 132 + 133 + msm_dp_snapshot(disp_state, priv->dp[i]); 134 + } 131 135 132 136 for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) { 133 137 if (!priv->dsi[i])
+20 -44
drivers/gpu/drm/msm/dp/dp_catalog.c
··· 24 24 #define DP_INTERRUPT_STATUS_ACK_SHIFT 1 25 25 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2 26 26 27 - #define MSM_DP_CONTROLLER_AHB_OFFSET 0x0000 28 - #define MSM_DP_CONTROLLER_AHB_SIZE 0x0200 29 - #define MSM_DP_CONTROLLER_AUX_OFFSET 0x0200 30 - #define MSM_DP_CONTROLLER_AUX_SIZE 0x0200 31 - #define MSM_DP_CONTROLLER_LINK_OFFSET 0x0400 32 - #define MSM_DP_CONTROLLER_LINK_SIZE 0x0C00 33 - #define MSM_DP_CONTROLLER_P0_OFFSET 0x1000 34 - #define MSM_DP_CONTROLLER_P0_SIZE 0x0400 35 - 36 27 #define DP_INTERRUPT_STATUS1 \ 37 28 (DP_INTR_AUX_I2C_DONE| \ 38 29 DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \ ··· 57 66 { 58 67 struct dp_catalog_private *catalog = container_of(dp_catalog, 59 68 struct dp_catalog_private, dp_catalog); 69 + struct dss_io_data *dss = &catalog->io->dp_controller; 60 70 61 - msm_disp_snapshot_add_block(disp_state, catalog->io->dp_controller.len, 62 - catalog->io->dp_controller.base, "dp_ctrl"); 71 + msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb"); 72 + msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux"); 73 + msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link"); 74 + msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0"); 63 75 } 64 76 65 77 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset) 66 78 { 67 - offset += MSM_DP_CONTROLLER_AUX_OFFSET; 68 - return readl_relaxed(catalog->io->dp_controller.base + offset); 79 + return readl_relaxed(catalog->io->dp_controller.aux.base + offset); 69 80 } 70 81 71 82 static inline void dp_write_aux(struct dp_catalog_private *catalog, 72 83 u32 offset, u32 data) 73 84 { 74 - offset += MSM_DP_CONTROLLER_AUX_OFFSET; 75 85 /* 76 86 * To make sure aux reg writes happens before any other operation, 77 87 * this function uses writel() instread of writel_relaxed() 78 88 */ 79 - writel(data, catalog->io->dp_controller.base + offset); 89 + writel(data, catalog->io->dp_controller.aux.base + offset); 80 90 } 81 91 82 92 static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 offset) 83 93 { 84 - offset += MSM_DP_CONTROLLER_AHB_OFFSET; 85 - return readl_relaxed(catalog->io->dp_controller.base + offset); 94 + return readl_relaxed(catalog->io->dp_controller.ahb.base + offset); 86 95 } 87 96 88 97 static inline void dp_write_ahb(struct dp_catalog_private *catalog, 89 98 u32 offset, u32 data) 90 99 { 91 - offset += MSM_DP_CONTROLLER_AHB_OFFSET; 92 100 /* 93 101 * To make sure phy reg writes happens before any other operation, 94 102 * this function uses writel() instread of writel_relaxed() 95 103 */ 96 - writel(data, catalog->io->dp_controller.base + offset); 104 + writel(data, catalog->io->dp_controller.ahb.base + offset); 97 105 } 98 106 99 107 static inline void dp_write_p0(struct dp_catalog_private *catalog, 100 108 u32 offset, u32 data) 101 109 { 102 - offset += MSM_DP_CONTROLLER_P0_OFFSET; 103 110 /* 104 111 * To make sure interface reg writes happens before any other operation, 105 112 * this function uses writel() instread of writel_relaxed() 106 113 */ 107 - writel(data, catalog->io->dp_controller.base + offset); 114 + writel(data, catalog->io->dp_controller.p0.base + offset); 108 115 } 109 116 110 117 static inline u32 dp_read_p0(struct dp_catalog_private *catalog, 111 118 u32 offset) 112 119 { 113 - offset += MSM_DP_CONTROLLER_P0_OFFSET; 114 120 /* 115 121 * To make sure interface reg writes happens before any other operation, 116 122 * this function uses writel() instread of writel_relaxed() 117 123 */ 118 - return readl_relaxed(catalog->io->dp_controller.base + offset); 124 + return readl_relaxed(catalog->io->dp_controller.p0.base + offset); 119 125 } 120 126 121 127 static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset) 122 128 { 123 - offset += MSM_DP_CONTROLLER_LINK_OFFSET; 124 - return readl_relaxed(catalog->io->dp_controller.base + offset); 129 + return readl_relaxed(catalog->io->dp_controller.link.base + offset); 125 130 } 126 131 127 132 static inline void dp_write_link(struct dp_catalog_private *catalog, 128 133 u32 offset, u32 data) 129 134 { 130 - offset += MSM_DP_CONTROLLER_LINK_OFFSET; 131 135 /* 132 136 * To make sure link reg writes happens before any other operation, 133 137 * this function uses writel() instread of writel_relaxed() 134 138 */ 135 - writel(data, catalog->io->dp_controller.base + offset); 139 + writel(data, catalog->io->dp_controller.link.base + offset); 136 140 } 137 141 138 142 /* aux related catalog functions */ ··· 262 276 263 277 void dp_catalog_dump_regs(struct dp_catalog *dp_catalog) 264 278 { 265 - u32 offset, len; 266 279 struct dp_catalog_private *catalog = container_of(dp_catalog, 267 280 struct dp_catalog_private, dp_catalog); 281 + struct dss_io_data *io = &catalog->io->dp_controller; 268 282 269 283 pr_info("AHB regs\n"); 270 - offset = MSM_DP_CONTROLLER_AHB_OFFSET; 271 - len = MSM_DP_CONTROLLER_AHB_SIZE; 272 - dump_regs(catalog->io->dp_controller.base + offset, len); 284 + dump_regs(io->ahb.base, io->ahb.len); 273 285 274 286 pr_info("AUXCLK regs\n"); 275 - offset = MSM_DP_CONTROLLER_AUX_OFFSET; 276 - len = MSM_DP_CONTROLLER_AUX_SIZE; 277 - dump_regs(catalog->io->dp_controller.base + offset, len); 287 + dump_regs(io->aux.base, io->aux.len); 278 288 279 289 pr_info("LCLK regs\n"); 280 - offset = MSM_DP_CONTROLLER_LINK_OFFSET; 281 - len = MSM_DP_CONTROLLER_LINK_SIZE; 282 - dump_regs(catalog->io->dp_controller.base + offset, len); 290 + dump_regs(io->link.base, io->link.len); 283 291 284 292 pr_info("P0CLK regs\n"); 285 - offset = MSM_DP_CONTROLLER_P0_OFFSET; 286 - len = MSM_DP_CONTROLLER_P0_SIZE; 287 - dump_regs(catalog->io->dp_controller.base + offset, len); 293 + dump_regs(io->p0.base, io->p0.len); 288 294 } 289 295 290 296 u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog) ··· 471 493 bit = BIT(pattern - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT; 472 494 473 495 /* Poll for mainlink ready status */ 474 - ret = readx_poll_timeout(readl, catalog->io->dp_controller.base + 475 - MSM_DP_CONTROLLER_LINK_OFFSET + 496 + ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base + 476 497 REG_DP_MAINLINK_READY, 477 498 data, data & bit, 478 499 POLLING_SLEEP_US, POLLING_TIMEOUT_US); ··· 518 541 struct dp_catalog_private, dp_catalog); 519 542 520 543 /* Poll for mainlink ready status */ 521 - ret = readl_poll_timeout(catalog->io->dp_controller.base + 522 - MSM_DP_CONTROLLER_LINK_OFFSET + 544 + ret = readl_poll_timeout(catalog->io->dp_controller.link.base + 523 545 REG_DP_MAINLINK_READY, 524 546 data, data & DP_MAINLINK_READY_FOR_VIDEO, 525 547 POLLING_SLEEP_US, POLLING_TIMEOUT_US);
+68 -224
drivers/gpu/drm/msm/dp/dp_debug.c
··· 24 24 struct dp_usbpd *usbpd; 25 25 struct dp_link *link; 26 26 struct dp_panel *panel; 27 - struct drm_connector **connector; 27 + struct drm_connector *connector; 28 28 struct device *dev; 29 29 struct drm_device *drm_dev; 30 30 31 31 struct dp_debug dp_debug; 32 32 }; 33 33 34 - static int dp_debug_check_buffer_overflow(int rc, int *max_size, int *len) 34 + static int dp_debug_show(struct seq_file *seq, void *p) 35 35 { 36 - if (rc >= *max_size) { 37 - DRM_ERROR("buffer overflow\n"); 38 - return -EINVAL; 39 - } 40 - *len += rc; 41 - *max_size = SZ_4K - *len; 42 - 43 - return 0; 44 - } 45 - 46 - static ssize_t dp_debug_read_info(struct file *file, char __user *user_buff, 47 - size_t count, loff_t *ppos) 48 - { 49 - struct dp_debug_private *debug = file->private_data; 50 - char *buf; 51 - u32 len = 0, rc = 0; 36 + struct dp_debug_private *debug = seq->private; 52 37 u64 lclk = 0; 53 - u32 max_size = SZ_4K; 54 38 u32 link_params_rate; 55 - struct drm_display_mode *drm_mode; 39 + const struct drm_display_mode *drm_mode; 56 40 57 41 if (!debug) 58 42 return -ENODEV; 59 43 60 - if (*ppos) 61 - return 0; 62 - 63 - buf = kzalloc(SZ_4K, GFP_KERNEL); 64 - if (!buf) 65 - return -ENOMEM; 66 - 67 44 drm_mode = &debug->panel->dp_mode.drm_mode; 68 45 69 - rc = snprintf(buf + len, max_size, "\tname = %s\n", DEBUG_NAME); 70 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 71 - goto error; 72 - 73 - rc = snprintf(buf + len, max_size, 74 - "\tdp_panel\n\t\tmax_pclk_khz = %d\n", 46 + seq_printf(seq, "\tname = %s\n", DEBUG_NAME); 47 + seq_printf(seq, "\tdp_panel\n\t\tmax_pclk_khz = %d\n", 75 48 debug->panel->max_pclk_khz); 76 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 77 - goto error; 78 - 79 - rc = snprintf(buf + len, max_size, 80 - "\tdrm_dp_link\n\t\trate = %u\n", 49 + seq_printf(seq, "\tdrm_dp_link\n\t\trate = %u\n", 81 50 debug->panel->link_info.rate); 82 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 83 - goto error; 84 - 85 - rc = snprintf(buf + len, max_size, 86 - "\t\tnum_lanes = %u\n", 51 + seq_printf(seq, "\t\tnum_lanes = %u\n", 87 52 debug->panel->link_info.num_lanes); 88 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 89 - goto error; 90 - 91 - rc = snprintf(buf + len, max_size, 92 - "\t\tcapabilities = %lu\n", 53 + seq_printf(seq, "\t\tcapabilities = %lu\n", 93 54 debug->panel->link_info.capabilities); 94 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 95 - goto error; 96 - 97 - rc = snprintf(buf + len, max_size, 98 - "\tdp_panel_info:\n\t\tactive = %dx%d\n", 55 + seq_printf(seq, "\tdp_panel_info:\n\t\tactive = %dx%d\n", 99 56 drm_mode->hdisplay, 100 57 drm_mode->vdisplay); 101 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 102 - goto error; 103 - 104 - rc = snprintf(buf + len, max_size, 105 - "\t\tback_porch = %dx%d\n", 58 + seq_printf(seq, "\t\tback_porch = %dx%d\n", 106 59 drm_mode->htotal - drm_mode->hsync_end, 107 60 drm_mode->vtotal - drm_mode->vsync_end); 108 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 109 - goto error; 110 - 111 - rc = snprintf(buf + len, max_size, 112 - "\t\tfront_porch = %dx%d\n", 61 + seq_printf(seq, "\t\tfront_porch = %dx%d\n", 113 62 drm_mode->hsync_start - drm_mode->hdisplay, 114 63 drm_mode->vsync_start - drm_mode->vdisplay); 115 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 116 - goto error; 117 - 118 - rc = snprintf(buf + len, max_size, 119 - "\t\tsync_width = %dx%d\n", 64 + seq_printf(seq, "\t\tsync_width = %dx%d\n", 120 65 drm_mode->hsync_end - drm_mode->hsync_start, 121 66 drm_mode->vsync_end - drm_mode->vsync_start); 122 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 123 - goto error; 124 - 125 - rc = snprintf(buf + len, max_size, 126 - "\t\tactive_low = %dx%d\n", 67 + seq_printf(seq, "\t\tactive_low = %dx%d\n", 127 68 debug->panel->dp_mode.h_active_low, 128 69 debug->panel->dp_mode.v_active_low); 129 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 130 - goto error; 131 - 132 - rc = snprintf(buf + len, max_size, 133 - "\t\th_skew = %d\n", 70 + seq_printf(seq, "\t\th_skew = %d\n", 134 71 drm_mode->hskew); 135 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 136 - goto error; 137 - 138 - rc = snprintf(buf + len, max_size, 139 - "\t\trefresh rate = %d\n", 72 + seq_printf(seq, "\t\trefresh rate = %d\n", 140 73 drm_mode_vrefresh(drm_mode)); 141 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 142 - goto error; 143 - 144 - rc = snprintf(buf + len, max_size, 145 - "\t\tpixel clock khz = %d\n", 74 + seq_printf(seq, "\t\tpixel clock khz = %d\n", 146 75 drm_mode->clock); 147 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 148 - goto error; 149 - 150 - rc = snprintf(buf + len, max_size, 151 - "\t\tbpp = %d\n", 76 + seq_printf(seq, "\t\tbpp = %d\n", 152 77 debug->panel->dp_mode.bpp); 153 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 154 - goto error; 155 78 156 79 /* Link Information */ 157 - rc = snprintf(buf + len, max_size, 158 - "\tdp_link:\n\t\ttest_requested = %d\n", 80 + seq_printf(seq, "\tdp_link:\n\t\ttest_requested = %d\n", 159 81 debug->link->sink_request); 160 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 161 - goto error; 162 - 163 - rc = snprintf(buf + len, max_size, 164 - "\t\tnum_lanes = %d\n", 82 + seq_printf(seq, "\t\tnum_lanes = %d\n", 165 83 debug->link->link_params.num_lanes); 166 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 167 - goto error; 168 - 169 84 link_params_rate = debug->link->link_params.rate; 170 - rc = snprintf(buf + len, max_size, 171 - "\t\tbw_code = %d\n", 85 + seq_printf(seq, "\t\tbw_code = %d\n", 172 86 drm_dp_link_rate_to_bw_code(link_params_rate)); 173 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 174 - goto error; 175 - 176 87 lclk = debug->link->link_params.rate * 1000; 177 - rc = snprintf(buf + len, max_size, 178 - "\t\tlclk = %lld\n", lclk); 179 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 180 - goto error; 181 - 182 - rc = snprintf(buf + len, max_size, 183 - "\t\tv_level = %d\n", 88 + seq_printf(seq, "\t\tlclk = %lld\n", lclk); 89 + seq_printf(seq, "\t\tv_level = %d\n", 184 90 debug->link->phy_params.v_level); 185 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 186 - goto error; 187 - 188 - rc = snprintf(buf + len, max_size, 189 - "\t\tp_level = %d\n", 91 + seq_printf(seq, "\t\tp_level = %d\n", 190 92 debug->link->phy_params.p_level); 191 - if (dp_debug_check_buffer_overflow(rc, &max_size, &len)) 192 - goto error; 193 93 194 - if (copy_to_user(user_buff, buf, len)) 195 - goto error; 196 - 197 - *ppos += len; 198 - 199 - kfree(buf); 200 - return len; 201 - error: 202 - kfree(buf); 203 - return -EINVAL; 94 + return 0; 204 95 } 96 + DEFINE_SHOW_ATTRIBUTE(dp_debug); 205 97 206 98 static int dp_test_data_show(struct seq_file *m, void *data) 207 99 { 208 - struct drm_device *dev; 209 - struct dp_debug_private *debug; 210 - struct drm_connector *connector; 211 - struct drm_connector_list_iter conn_iter; 100 + const struct dp_debug_private *debug = m->private; 101 + const struct drm_connector *connector = debug->connector; 212 102 u32 bpc; 213 103 214 - debug = m->private; 215 - dev = debug->drm_dev; 216 - drm_connector_list_iter_begin(dev, &conn_iter); 217 - drm_for_each_connector_iter(connector, &conn_iter) { 218 - 219 - if (connector->connector_type != 220 - DRM_MODE_CONNECTOR_DisplayPort) 221 - continue; 222 - 223 - if (connector->status == connector_status_connected) { 224 - bpc = debug->link->test_video.test_bit_depth; 225 - seq_printf(m, "hdisplay: %d\n", 226 - debug->link->test_video.test_h_width); 227 - seq_printf(m, "vdisplay: %d\n", 228 - debug->link->test_video.test_v_height); 229 - seq_printf(m, "bpc: %u\n", 230 - dp_link_bit_depth_to_bpc(bpc)); 231 - } else 232 - seq_puts(m, "0"); 104 + if (connector->status == connector_status_connected) { 105 + bpc = debug->link->test_video.test_bit_depth; 106 + seq_printf(m, "hdisplay: %d\n", 107 + debug->link->test_video.test_h_width); 108 + seq_printf(m, "vdisplay: %d\n", 109 + debug->link->test_video.test_v_height); 110 + seq_printf(m, "bpc: %u\n", 111 + dp_link_bit_depth_to_bpc(bpc)); 112 + } else { 113 + seq_puts(m, "0"); 233 114 } 234 - 235 - drm_connector_list_iter_end(&conn_iter); 236 115 237 116 return 0; 238 117 } ··· 119 240 120 241 static int dp_test_type_show(struct seq_file *m, void *data) 121 242 { 122 - struct dp_debug_private *debug = m->private; 123 - struct drm_device *dev = debug->drm_dev; 124 - struct drm_connector *connector; 125 - struct drm_connector_list_iter conn_iter; 243 + const struct dp_debug_private *debug = m->private; 244 + const struct drm_connector *connector = debug->connector; 126 245 127 - drm_connector_list_iter_begin(dev, &conn_iter); 128 - drm_for_each_connector_iter(connector, &conn_iter) { 129 - 130 - if (connector->connector_type != 131 - DRM_MODE_CONNECTOR_DisplayPort) 132 - continue; 133 - 134 - if (connector->status == connector_status_connected) 135 - seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN); 136 - else 137 - seq_puts(m, "0"); 138 - } 139 - drm_connector_list_iter_end(&conn_iter); 246 + if (connector->status == connector_status_connected) 247 + seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN); 248 + else 249 + seq_puts(m, "0"); 140 250 141 251 return 0; 142 252 } ··· 137 269 { 138 270 char *input_buffer; 139 271 int status = 0; 140 - struct dp_debug_private *debug; 141 - struct drm_device *dev; 142 - struct drm_connector *connector; 143 - struct drm_connector_list_iter conn_iter; 272 + const struct dp_debug_private *debug; 273 + const struct drm_connector *connector; 144 274 int val = 0; 145 275 146 276 debug = ((struct seq_file *)file->private_data)->private; 147 - dev = debug->drm_dev; 277 + connector = debug->connector; 148 278 149 279 if (len == 0) 150 280 return 0; ··· 153 287 154 288 DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len); 155 289 156 - drm_connector_list_iter_begin(dev, &conn_iter); 157 - drm_for_each_connector_iter(connector, &conn_iter) { 158 - if (connector->connector_type != 159 - DRM_MODE_CONNECTOR_DisplayPort) 160 - continue; 161 - 162 - if (connector->status == connector_status_connected) { 163 - status = kstrtoint(input_buffer, 10, &val); 164 - if (status < 0) 165 - break; 166 - DRM_DEBUG_DRIVER("Got %d for test active\n", val); 167 - /* To prevent erroneous activation of the compliance 168 - * testing code, only accept an actual value of 1 here 169 - */ 170 - if (val == 1) 171 - debug->panel->video_test = true; 172 - else 173 - debug->panel->video_test = false; 290 + if (connector->status == connector_status_connected) { 291 + status = kstrtoint(input_buffer, 10, &val); 292 + if (status < 0) { 293 + kfree(input_buffer); 294 + return status; 174 295 } 296 + DRM_DEBUG_DRIVER("Got %d for test active\n", val); 297 + /* To prevent erroneous activation of the compliance 298 + * testing code, only accept an actual value of 1 here 299 + */ 300 + if (val == 1) 301 + debug->panel->video_test = true; 302 + else 303 + debug->panel->video_test = false; 175 304 } 176 - drm_connector_list_iter_end(&conn_iter); 177 305 kfree(input_buffer); 178 - if (status < 0) 179 - return status; 180 306 181 307 *offp += len; 182 308 return len; ··· 177 319 static int dp_test_active_show(struct seq_file *m, void *data) 178 320 { 179 321 struct dp_debug_private *debug = m->private; 180 - struct drm_device *dev = debug->drm_dev; 181 - struct drm_connector *connector; 182 - struct drm_connector_list_iter conn_iter; 322 + struct drm_connector *connector = debug->connector; 183 323 184 - drm_connector_list_iter_begin(dev, &conn_iter); 185 - drm_for_each_connector_iter(connector, &conn_iter) { 186 - if (connector->connector_type != 187 - DRM_MODE_CONNECTOR_DisplayPort) 188 - continue; 189 - 190 - if (connector->status == connector_status_connected) { 191 - if (debug->panel->video_test) 192 - seq_puts(m, "1"); 193 - else 194 - seq_puts(m, "0"); 195 - } else 324 + if (connector->status == connector_status_connected) { 325 + if (debug->panel->video_test) 326 + seq_puts(m, "1"); 327 + else 196 328 seq_puts(m, "0"); 329 + } else { 330 + seq_puts(m, "0"); 197 331 } 198 - drm_connector_list_iter_end(&conn_iter); 199 332 200 333 return 0; 201 334 } ··· 197 348 return single_open(file, dp_test_active_show, 198 349 inode->i_private); 199 350 } 200 - 201 - static const struct file_operations dp_debug_fops = { 202 - .open = simple_open, 203 - .read = dp_debug_read_info, 204 - }; 205 351 206 352 static const struct file_operations test_active_fops = { 207 353 .owner = THIS_MODULE, ··· 235 391 236 392 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 237 393 struct dp_usbpd *usbpd, struct dp_link *link, 238 - struct drm_connector **connector, struct drm_minor *minor) 394 + struct drm_connector *connector, struct drm_minor *minor) 239 395 { 240 396 int rc = 0; 241 397 struct dp_debug_private *debug;
+2 -2
drivers/gpu/drm/msm/dp/dp_debug.h
··· 43 43 */ 44 44 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 45 45 struct dp_usbpd *usbpd, struct dp_link *link, 46 - struct drm_connector **connector, 46 + struct drm_connector *connector, 47 47 struct drm_minor *minor); 48 48 49 49 /** ··· 60 60 static inline 61 61 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, 62 62 struct dp_usbpd *usbpd, struct dp_link *link, 63 - struct drm_connector **connector, struct drm_minor *minor) 63 + struct drm_connector *connector, struct drm_minor *minor) 64 64 { 65 65 return ERR_PTR(-EINVAL); 66 66 }
+78 -65
drivers/gpu/drm/msm/dp/dp_display.c
··· 10 10 #include <linux/component.h> 11 11 #include <linux/of_irq.h> 12 12 #include <linux/delay.h> 13 + #include <drm/drm_panel.h> 13 14 14 15 #include "msm_drv.h" 15 16 #include "msm_kms.h" ··· 28 27 #include "dp_audio.h" 29 28 #include "dp_debug.h" 30 29 31 - static struct msm_dp *g_dp_display; 32 30 #define HPD_STRING_SIZE 30 33 31 34 32 enum { ··· 79 79 char *name; 80 80 int irq; 81 81 82 + unsigned int id; 83 + 82 84 /* state variables */ 83 85 bool core_initialized; 84 86 bool hpd_irq_on; ··· 118 116 struct dp_audio *audio; 119 117 }; 120 118 119 + struct msm_dp_desc { 120 + phys_addr_t io_start; 121 + unsigned int connector_type; 122 + }; 123 + 124 + struct msm_dp_config { 125 + const struct msm_dp_desc *descs; 126 + size_t num_descs; 127 + }; 128 + 129 + static const struct msm_dp_config sc7180_dp_cfg = { 130 + .descs = (const struct msm_dp_desc[]) { 131 + [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae90000, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, 132 + }, 133 + .num_descs = 1, 134 + }; 135 + 121 136 static const struct of_device_id dp_dt_match[] = { 122 - {.compatible = "qcom,sc7180-dp"}, 137 + { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg }, 123 138 {} 124 139 }; 140 + 141 + static struct dp_display_private *dev_get_dp_display_private(struct device *dev) 142 + { 143 + struct msm_dp *dp = dev_get_drvdata(dev); 144 + 145 + return container_of(dp, struct dp_display_private, dp_display); 146 + } 125 147 126 148 static int dp_add_event(struct dp_display_private *dp_priv, u32 event, 127 149 u32 data, u32 delay) ··· 223 197 void *data) 224 198 { 225 199 int rc = 0; 226 - struct dp_display_private *dp; 227 - struct drm_device *drm; 200 + struct dp_display_private *dp = dev_get_dp_display_private(dev); 228 201 struct msm_drm_private *priv; 202 + struct drm_device *drm; 229 203 230 204 drm = dev_get_drvdata(master); 231 205 232 - dp = container_of(g_dp_display, 233 - struct dp_display_private, dp_display); 234 - 235 206 dp->dp_display.drm_dev = drm; 236 207 priv = drm->dev_private; 237 - priv->dp = &(dp->dp_display); 208 + priv->dp[dp->id] = &dp->dp_display; 238 209 239 - rc = dp->parser->parse(dp->parser); 210 + rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type); 240 211 if (rc) { 241 212 DRM_ERROR("device tree parsing failed\n"); 242 213 goto end; 243 214 } 215 + 216 + dp->dp_display.panel_bridge = dp->parser->panel_bridge; 244 217 245 218 dp->aux->drm_dev = drm; 246 219 rc = dp_aux_register(dp->aux); ··· 265 240 static void dp_display_unbind(struct device *dev, struct device *master, 266 241 void *data) 267 242 { 268 - struct dp_display_private *dp; 243 + struct dp_display_private *dp = dev_get_dp_display_private(dev); 269 244 struct drm_device *drm = dev_get_drvdata(master); 270 245 struct msm_drm_private *priv = drm->dev_private; 271 246 272 - dp = container_of(g_dp_display, 273 - struct dp_display_private, dp_display); 274 - 275 247 dp_power_client_deinit(dp->power); 276 248 dp_aux_unregister(dp->aux); 277 - priv->dp = NULL; 249 + priv->dp[dp->id] = NULL; 278 250 } 279 251 280 252 static const struct component_ops dp_display_comp_ops = { ··· 401 379 402 380 static int dp_display_usbpd_configure_cb(struct device *dev) 403 381 { 404 - int rc = 0; 405 - struct dp_display_private *dp; 406 - 407 - if (!dev) { 408 - DRM_ERROR("invalid dev\n"); 409 - rc = -EINVAL; 410 - goto end; 411 - } 412 - 413 - dp = container_of(g_dp_display, 414 - struct dp_display_private, dp_display); 382 + struct dp_display_private *dp = dev_get_dp_display_private(dev); 415 383 416 384 dp_display_host_init(dp, false); 417 385 418 - rc = dp_display_process_hpd_high(dp); 419 - end: 420 - return rc; 386 + return dp_display_process_hpd_high(dp); 421 387 } 422 388 423 389 static int dp_display_usbpd_disconnect_cb(struct device *dev) 424 390 { 425 391 int rc = 0; 426 - struct dp_display_private *dp; 427 - 428 - if (!dev) { 429 - DRM_ERROR("invalid dev\n"); 430 - rc = -EINVAL; 431 - return rc; 432 - } 433 - 434 - dp = container_of(g_dp_display, 435 - struct dp_display_private, dp_display); 392 + struct dp_display_private *dp = dev_get_dp_display_private(dev); 436 393 437 394 dp_add_event(dp, EV_USER_NOTIFICATION, false, 0); 438 395 ··· 473 472 { 474 473 int rc = 0; 475 474 u32 sink_request; 476 - struct dp_display_private *dp; 477 - 478 - if (!dev) { 479 - DRM_ERROR("invalid dev\n"); 480 - return -EINVAL; 481 - } 482 - 483 - dp = container_of(g_dp_display, 484 - struct dp_display_private, dp_display); 475 + struct dp_display_private *dp = dev_get_dp_display_private(dev); 485 476 486 477 /* check for any test request issued by sink */ 487 478 rc = dp_link_process_request(dp->link); ··· 640 647 641 648 DRM_DEBUG_DP("hpd_state=%d\n", state); 642 649 /* signal the disconnect event early to ensure proper teardown */ 643 - dp_display_handle_plugged_change(g_dp_display, false); 650 + dp_display_handle_plugged_change(&dp->dp_display, false); 644 651 645 652 /* enable HDP plug interrupt to prepare for next plugin */ 646 653 dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); ··· 827 834 return 0; 828 835 } 829 836 830 - static int dp_display_prepare(struct msm_dp *dp) 837 + static int dp_display_prepare(struct msm_dp *dp_display) 831 838 { 832 839 return 0; 833 840 } ··· 835 842 static int dp_display_enable(struct dp_display_private *dp, u32 data) 836 843 { 837 844 int rc = 0; 838 - struct msm_dp *dp_display; 839 - 840 - dp_display = g_dp_display; 845 + struct msm_dp *dp_display = &dp->dp_display; 841 846 842 847 DRM_DEBUG_DP("sink_count=%d\n", dp->link->sink_count); 843 848 if (dp_display->power_on) { ··· 871 880 872 881 static int dp_display_disable(struct dp_display_private *dp, u32 data) 873 882 { 874 - struct msm_dp *dp_display; 875 - 876 - dp_display = g_dp_display; 883 + struct msm_dp *dp_display = &dp->dp_display; 877 884 878 885 if (!dp_display->power_on) 879 886 return 0; ··· 901 912 return 0; 902 913 } 903 914 904 - static int dp_display_unprepare(struct msm_dp *dp) 915 + static int dp_display_unprepare(struct msm_dp *dp_display) 905 916 { 906 917 return 0; 907 918 } ··· 1202 1213 return 0; 1203 1214 } 1204 1215 1216 + static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev, 1217 + unsigned int *id) 1218 + { 1219 + const struct msm_dp_config *cfg = of_device_get_match_data(&pdev->dev); 1220 + struct resource *res; 1221 + int i; 1222 + 1223 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1224 + if (!res) 1225 + return NULL; 1226 + 1227 + for (i = 0; i < cfg->num_descs; i++) { 1228 + if (cfg->descs[i].io_start == res->start) { 1229 + *id = i; 1230 + return &cfg->descs[i]; 1231 + } 1232 + } 1233 + 1234 + dev_err(&pdev->dev, "unknown displayport instance\n"); 1235 + return NULL; 1236 + } 1237 + 1205 1238 static int dp_display_probe(struct platform_device *pdev) 1206 1239 { 1207 1240 int rc = 0; 1208 1241 struct dp_display_private *dp; 1242 + const struct msm_dp_desc *desc; 1209 1243 1210 1244 if (!pdev || !pdev->dev.of_node) { 1211 1245 DRM_ERROR("pdev not found\n"); ··· 1239 1227 if (!dp) 1240 1228 return -ENOMEM; 1241 1229 1230 + desc = dp_display_get_desc(pdev, &dp->id); 1231 + if (!desc) 1232 + return -EINVAL; 1233 + 1242 1234 dp->pdev = pdev; 1243 1235 dp->name = "drm_dp"; 1236 + dp->dp_display.connector_type = desc->connector_type; 1244 1237 1245 1238 rc = dp_init_sub_modules(dp); 1246 1239 if (rc) { ··· 1254 1237 } 1255 1238 1256 1239 mutex_init(&dp->event_mutex); 1257 - g_dp_display = &dp->dp_display; 1258 1240 1259 1241 /* Store DP audio handle inside DP display */ 1260 - g_dp_display->dp_audio = dp->audio; 1242 + dp->dp_display.dp_audio = dp->audio; 1261 1243 1262 1244 init_completion(&dp->audio_comp); 1263 1245 1264 - platform_set_drvdata(pdev, g_dp_display); 1246 + platform_set_drvdata(pdev, &dp->dp_display); 1265 1247 1266 1248 rc = component_add(&pdev->dev, &dp_display_comp_ops); 1267 1249 if (rc) { ··· 1273 1257 1274 1258 static int dp_display_remove(struct platform_device *pdev) 1275 1259 { 1276 - struct dp_display_private *dp; 1277 - 1278 - dp = container_of(g_dp_display, 1279 - struct dp_display_private, dp_display); 1260 + struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev); 1280 1261 1281 1262 dp_display_deinit_sub_modules(dp); 1282 1263 ··· 1328 1315 dp->dp_display.is_connected = true; 1329 1316 } else { 1330 1317 dp->dp_display.is_connected = false; 1331 - dp_display_handle_plugged_change(g_dp_display, false); 1318 + dp_display_handle_plugged_change(dp_display, false); 1332 1319 } 1333 1320 1334 1321 DRM_DEBUG_DP("After, sink_count=%d is_connected=%d core_inited=%d power_on=%d\n", ··· 1442 1429 dev = &dp->pdev->dev; 1443 1430 1444 1431 dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd, 1445 - dp->link, &dp->dp_display.connector, 1432 + dp->link, dp->dp_display.connector, 1446 1433 minor); 1447 1434 if (IS_ERR(dp->debug)) { 1448 1435 rc = PTR_ERR(dp->debug);
+2
drivers/gpu/drm/msm/dp/dp_display.h
··· 15 15 struct device *codec_dev; 16 16 struct drm_connector *connector; 17 17 struct drm_encoder *encoder; 18 + struct drm_bridge *panel_bridge; 18 19 bool is_connected; 19 20 bool audio_enabled; 20 21 bool power_on; 22 + unsigned int connector_type; 21 23 22 24 hdmi_codec_plugged_cb plugged_cb; 23 25
+12 -1
drivers/gpu/drm/msm/dp/dp_drm.c
··· 5 5 6 6 #include <drm/drm_atomic_helper.h> 7 7 #include <drm/drm_atomic.h> 8 + #include <drm/drm_bridge.h> 8 9 #include <drm/drm_crtc.h> 9 10 10 11 #include "msm_drv.h" ··· 148 147 149 148 ret = drm_connector_init(dp_display->drm_dev, connector, 150 149 &dp_connector_funcs, 151 - DRM_MODE_CONNECTOR_DisplayPort); 150 + dp_display->connector_type); 152 151 if (ret) 153 152 return ERR_PTR(ret); 154 153 ··· 160 159 connector->polled = DRM_CONNECTOR_POLL_HPD; 161 160 162 161 drm_connector_attach_encoder(connector, dp_display->encoder); 162 + 163 + if (dp_display->panel_bridge) { 164 + ret = drm_bridge_attach(dp_display->encoder, 165 + dp_display->panel_bridge, NULL, 166 + DRM_BRIDGE_ATTACH_NO_CONNECTOR); 167 + if (ret < 0) { 168 + DRM_ERROR("failed to attach panel bridge: %d\n", ret); 169 + return ERR_PTR(ret); 170 + } 171 + } 163 172 164 173 return connector; 165 174 }
+1 -1
drivers/gpu/drm/msm/dp/dp_panel.c
··· 234 234 u32 mode_edid_bpp, u32 mode_pclk_khz) 235 235 { 236 236 struct dp_panel_private *panel; 237 - u32 bpp = mode_edid_bpp; 237 + u32 bpp; 238 238 239 239 if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) { 240 240 DRM_ERROR("invalid input\n");
+91 -47
drivers/gpu/drm/msm/dp/dp_parser.c
··· 6 6 #include <linux/of_gpio.h> 7 7 #include <linux/phy/phy.h> 8 8 9 + #include <drm/drm_of.h> 9 10 #include <drm/drm_print.h> 11 + #include <drm/drm_bridge.h> 10 12 11 13 #include "dp_parser.h" 12 14 #include "dp_reg.h" 15 + 16 + #define DP_DEFAULT_AHB_OFFSET 0x0000 17 + #define DP_DEFAULT_AHB_SIZE 0x0200 18 + #define DP_DEFAULT_AUX_OFFSET 0x0200 19 + #define DP_DEFAULT_AUX_SIZE 0x0200 20 + #define DP_DEFAULT_LINK_OFFSET 0x0400 21 + #define DP_DEFAULT_LINK_SIZE 0x0C00 22 + #define DP_DEFAULT_P0_OFFSET 0x1000 23 + #define DP_DEFAULT_P0_SIZE 0x0400 13 24 14 25 static const struct dp_regulator_cfg sdm845_dp_reg_cfg = { 15 26 .num = 2, ··· 30 19 }, 31 20 }; 32 21 33 - static int msm_dss_ioremap(struct platform_device *pdev, 34 - struct dss_io_data *io_data) 22 + static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len) 35 23 { 36 - struct resource *res = NULL; 24 + struct resource *res; 25 + void __iomem *base; 37 26 38 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 39 - if (!res) { 40 - DRM_ERROR("%pS->%s: msm_dss_get_res failed\n", 41 - __builtin_return_address(0), __func__); 42 - return -ENODEV; 43 - } 27 + base = devm_platform_get_and_ioremap_resource(pdev, idx, &res); 28 + if (!IS_ERR(base)) 29 + *len = resource_size(res); 44 30 45 - io_data->len = (u32)resource_size(res); 46 - io_data->base = ioremap(res->start, io_data->len); 47 - if (!io_data->base) { 48 - DRM_ERROR("%pS->%s: ioremap failed\n", 49 - __builtin_return_address(0), __func__); 50 - return -EIO; 51 - } 52 - 53 - return 0; 54 - } 55 - 56 - static void msm_dss_iounmap(struct dss_io_data *io_data) 57 - { 58 - if (io_data->base) { 59 - iounmap(io_data->base); 60 - io_data->base = NULL; 61 - } 62 - io_data->len = 0; 63 - } 64 - 65 - static void dp_parser_unmap_io_resources(struct dp_parser *parser) 66 - { 67 - struct dp_io *io = &parser->io; 68 - 69 - msm_dss_iounmap(&io->dp_controller); 31 + return base; 70 32 } 71 33 72 34 static int dp_parser_ctrl_res(struct dp_parser *parser) 73 35 { 74 - int rc = 0; 75 36 struct platform_device *pdev = parser->pdev; 76 37 struct dp_io *io = &parser->io; 38 + struct dss_io_data *dss = &io->dp_controller; 77 39 78 - rc = msm_dss_ioremap(pdev, &io->dp_controller); 79 - if (rc) { 80 - DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc); 81 - goto err; 40 + dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len); 41 + if (IS_ERR(dss->ahb.base)) 42 + return PTR_ERR(dss->ahb.base); 43 + 44 + dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len); 45 + if (IS_ERR(dss->aux.base)) { 46 + /* 47 + * The initial binding had a single reg, but in order to 48 + * support variation in the sub-region sizes this was split. 49 + * dp_ioremap() will fail with -EINVAL here if only a single 50 + * reg is specified, so fill in the sub-region offsets and 51 + * lengths based on this single region. 52 + */ 53 + if (PTR_ERR(dss->aux.base) == -EINVAL) { 54 + if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) { 55 + DRM_ERROR("legacy memory region not large enough\n"); 56 + return -EINVAL; 57 + } 58 + 59 + dss->ahb.len = DP_DEFAULT_AHB_SIZE; 60 + dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET; 61 + dss->aux.len = DP_DEFAULT_AUX_SIZE; 62 + dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET; 63 + dss->link.len = DP_DEFAULT_LINK_SIZE; 64 + dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET; 65 + dss->p0.len = DP_DEFAULT_P0_SIZE; 66 + } else { 67 + DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base); 68 + return PTR_ERR(dss->aux.base); 69 + } 70 + } else { 71 + dss->link.base = dp_ioremap(pdev, 2, &dss->link.len); 72 + if (IS_ERR(dss->link.base)) { 73 + DRM_ERROR("unable to remap link region: %pe\n", dss->link.base); 74 + return PTR_ERR(dss->link.base); 75 + } 76 + 77 + dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len); 78 + if (IS_ERR(dss->p0.base)) { 79 + DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base); 80 + return PTR_ERR(dss->p0.base); 81 + } 82 82 } 83 83 84 84 io->phy = devm_phy_get(&pdev->dev, "dp"); 85 - if (IS_ERR(io->phy)) { 86 - rc = PTR_ERR(io->phy); 87 - goto err; 88 - } 85 + if (IS_ERR(io->phy)) 86 + return PTR_ERR(io->phy); 89 87 90 88 return 0; 91 - err: 92 - dp_parser_unmap_io_resources(parser); 93 - return rc; 94 89 } 95 90 96 91 static int dp_parser_misc(struct dp_parser *parser) ··· 265 248 return 0; 266 249 } 267 250 268 - static int dp_parser_parse(struct dp_parser *parser) 251 + static int dp_parser_find_panel(struct dp_parser *parser) 252 + { 253 + struct device *dev = &parser->pdev->dev; 254 + struct drm_panel *panel; 255 + int rc; 256 + 257 + rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); 258 + if (rc) { 259 + DRM_ERROR("failed to acquire DRM panel: %d\n", rc); 260 + return rc; 261 + } 262 + 263 + parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel); 264 + if (IS_ERR(parser->panel_bridge)) { 265 + DRM_ERROR("failed to create panel bridge\n"); 266 + return PTR_ERR(parser->panel_bridge); 267 + } 268 + 269 + return 0; 270 + } 271 + 272 + static int dp_parser_parse(struct dp_parser *parser, int connector_type) 269 273 { 270 274 int rc = 0; 271 275 ··· 306 268 rc = dp_parser_clock(parser); 307 269 if (rc) 308 270 return rc; 271 + 272 + if (connector_type == DRM_MODE_CONNECTOR_eDP) { 273 + rc = dp_parser_find_panel(parser); 274 + if (rc) 275 + return rc; 276 + } 309 277 310 278 /* Map the corresponding regulator information according to 311 279 * version. Currently, since we only have one supported platform,
+11 -3
drivers/gpu/drm/msm/dp/dp_parser.h
··· 25 25 DP_MAX_PM 26 26 }; 27 27 28 - struct dss_io_data { 29 - u32 len; 28 + struct dss_io_region { 29 + size_t len; 30 30 void __iomem *base; 31 + }; 32 + 33 + struct dss_io_data { 34 + struct dss_io_region ahb; 35 + struct dss_io_region aux; 36 + struct dss_io_region link; 37 + struct dss_io_region p0; 31 38 }; 32 39 33 40 static inline const char *dp_parser_pm_name(enum dp_pm_type module) ··· 123 116 struct dp_display_data disp_data; 124 117 const struct dp_regulator_cfg *regulator_cfg; 125 118 u32 max_dp_lanes; 119 + struct drm_bridge *panel_bridge; 126 120 127 - int (*parse)(struct dp_parser *parser); 121 + int (*parse)(struct dp_parser *parser, int connector_type); 128 122 }; 129 123 130 124 /**
+2
drivers/gpu/drm/msm/dsi/dsi.h
··· 107 107 u32 dma_base, u32 len); 108 108 int msm_dsi_host_enable(struct mipi_dsi_host *host); 109 109 int msm_dsi_host_disable(struct mipi_dsi_host *host); 110 + void msm_dsi_host_enable_irq(struct mipi_dsi_host *host); 111 + void msm_dsi_host_disable_irq(struct mipi_dsi_host *host); 110 112 int msm_dsi_host_power_on(struct mipi_dsi_host *host, 111 113 struct msm_dsi_phy_shared_timings *phy_shared_timings, 112 114 bool is_bonded_dsi, struct msm_dsi_phy *phy);
+61 -86
drivers/gpu/drm/msm/dsi/dsi_host.c
··· 106 106 phys_addr_t ctrl_size; 107 107 struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX]; 108 108 109 - struct clk *bus_clks[DSI_BUS_CLK_MAX]; 109 + int num_bus_clks; 110 + struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX]; 110 111 111 112 struct clk *byte_clk; 112 113 struct clk *esc_clk; ··· 116 115 struct clk *pixel_clk_src; 117 116 struct clk *byte_intf_clk; 118 117 119 - u32 byte_clk_rate; 120 - u32 pixel_clk_rate; 121 - u32 esc_clk_rate; 118 + unsigned long byte_clk_rate; 119 + unsigned long pixel_clk_rate; 120 + unsigned long esc_clk_rate; 122 121 123 122 /* DSI v2 specific clocks */ 124 123 struct clk *src_clk; 125 124 struct clk *esc_clk_src; 126 125 struct clk *dsi_clk_src; 127 126 128 - u32 src_clk_rate; 127 + unsigned long src_clk_rate; 129 128 130 129 struct gpio_desc *disp_en_gpio; 131 130 struct gpio_desc *te_gpio; ··· 375 374 int i, ret = 0; 376 375 377 376 /* get bus clocks */ 378 - for (i = 0; i < cfg->num_bus_clks; i++) { 379 - msm_host->bus_clks[i] = msm_clk_get(pdev, 380 - cfg->bus_clk_names[i]); 381 - if (IS_ERR(msm_host->bus_clks[i])) { 382 - ret = PTR_ERR(msm_host->bus_clks[i]); 383 - pr_err("%s: Unable to get %s clock, ret = %d\n", 384 - __func__, cfg->bus_clk_names[i], ret); 385 - goto exit; 386 - } 377 + for (i = 0; i < cfg->num_bus_clks; i++) 378 + msm_host->bus_clks[i].id = cfg->bus_clk_names[i]; 379 + msm_host->num_bus_clks = cfg->num_bus_clks; 380 + 381 + ret = devm_clk_bulk_get(&pdev->dev, msm_host->num_bus_clks, msm_host->bus_clks); 382 + if (ret < 0) { 383 + dev_err(&pdev->dev, "Unable to get clocks, ret = %d\n", ret); 384 + goto exit; 387 385 } 388 386 389 387 /* get link and source clocks */ ··· 433 433 return ret; 434 434 } 435 435 436 - static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host) 437 - { 438 - const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; 439 - int i, ret; 440 - 441 - DBG("id=%d", msm_host->id); 442 - 443 - for (i = 0; i < cfg->num_bus_clks; i++) { 444 - ret = clk_prepare_enable(msm_host->bus_clks[i]); 445 - if (ret) { 446 - pr_err("%s: failed to enable bus clock %d ret %d\n", 447 - __func__, i, ret); 448 - goto err; 449 - } 450 - } 451 - 452 - return 0; 453 - err: 454 - while (--i >= 0) 455 - clk_disable_unprepare(msm_host->bus_clks[i]); 456 - 457 - return ret; 458 - } 459 - 460 - static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host) 461 - { 462 - const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; 463 - int i; 464 - 465 - DBG(""); 466 - 467 - for (i = cfg->num_bus_clks - 1; i >= 0; i--) 468 - clk_disable_unprepare(msm_host->bus_clks[i]); 469 - } 470 - 471 436 int msm_dsi_runtime_suspend(struct device *dev) 472 437 { 473 438 struct platform_device *pdev = to_platform_device(dev); ··· 443 478 if (!msm_host->cfg_hnd) 444 479 return 0; 445 480 446 - dsi_bus_clk_disable(msm_host); 481 + clk_bulk_disable_unprepare(msm_host->num_bus_clks, msm_host->bus_clks); 447 482 448 483 return 0; 449 484 } ··· 458 493 if (!msm_host->cfg_hnd) 459 494 return 0; 460 495 461 - return dsi_bus_clk_enable(msm_host); 496 + return clk_bulk_prepare_enable(msm_host->num_bus_clks, msm_host->bus_clks); 462 497 } 463 498 464 499 int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) 465 500 { 466 - u32 byte_intf_rate; 501 + unsigned long byte_intf_rate; 467 502 int ret; 468 503 469 - DBG("Set clk rates: pclk=%d, byteclk=%d", 504 + DBG("Set clk rates: pclk=%d, byteclk=%lu", 470 505 msm_host->mode->clock, msm_host->byte_clk_rate); 471 506 472 507 ret = dev_pm_opp_set_rate(&msm_host->pdev->dev, ··· 523 558 goto pixel_clk_err; 524 559 } 525 560 526 - if (msm_host->byte_intf_clk) { 527 - ret = clk_prepare_enable(msm_host->byte_intf_clk); 528 - if (ret) { 529 - pr_err("%s: Failed to enable byte intf clk\n", 530 - __func__); 531 - goto byte_intf_clk_err; 532 - } 561 + ret = clk_prepare_enable(msm_host->byte_intf_clk); 562 + if (ret) { 563 + pr_err("%s: Failed to enable byte intf clk\n", 564 + __func__); 565 + goto byte_intf_clk_err; 533 566 } 534 567 535 568 return 0; ··· 546 583 { 547 584 int ret; 548 585 549 - DBG("Set clk rates: pclk=%d, byteclk=%d, esc_clk=%d, dsi_src_clk=%d", 586 + DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", 550 587 msm_host->mode->clock, msm_host->byte_clk_rate, 551 588 msm_host->esc_clk_rate, msm_host->src_clk_rate); 552 589 ··· 623 660 dev_pm_opp_set_rate(&msm_host->pdev->dev, 0); 624 661 clk_disable_unprepare(msm_host->esc_clk); 625 662 clk_disable_unprepare(msm_host->pixel_clk); 626 - if (msm_host->byte_intf_clk) 627 - clk_disable_unprepare(msm_host->byte_intf_clk); 663 + clk_disable_unprepare(msm_host->byte_intf_clk); 628 664 clk_disable_unprepare(msm_host->byte_clk); 629 665 } 630 666 ··· 635 673 clk_disable_unprepare(msm_host->byte_clk); 636 674 } 637 675 638 - static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) 676 + static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) 639 677 { 640 678 struct drm_display_mode *mode = msm_host->mode; 641 - u32 pclk_rate; 679 + unsigned long pclk_rate; 642 680 643 681 pclk_rate = mode->clock * 1000; 644 682 ··· 658 696 { 659 697 u8 lanes = msm_host->lanes; 660 698 u32 bpp = dsi_get_bpp(msm_host->format); 661 - u32 pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); 699 + unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); 662 700 u64 pclk_bpp = (u64)pclk_rate * bpp; 663 701 664 702 if (lanes == 0) { ··· 675 713 msm_host->pixel_clk_rate = pclk_rate; 676 714 msm_host->byte_clk_rate = pclk_bpp; 677 715 678 - DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate, 716 + DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate, 679 717 msm_host->byte_clk_rate); 680 718 681 719 } ··· 734 772 735 773 msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div; 736 774 737 - DBG("esc=%d, src=%d", msm_host->esc_clk_rate, 775 + DBG("esc=%lu, src=%lu", msm_host->esc_clk_rate, 738 776 msm_host->src_clk_rate); 739 777 740 778 return 0; ··· 1860 1898 return ret; 1861 1899 } 1862 1900 1901 + msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 1902 + if (msm_host->irq < 0) { 1903 + ret = msm_host->irq; 1904 + dev_err(&pdev->dev, "failed to get irq: %d\n", ret); 1905 + return ret; 1906 + } 1907 + 1908 + /* do not autoenable, will be enabled later */ 1909 + ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq, 1910 + IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, 1911 + "dsi_isr", msm_host); 1912 + if (ret < 0) { 1913 + dev_err(&pdev->dev, "failed to request IRQ%u: %d\n", 1914 + msm_host->irq, ret); 1915 + return ret; 1916 + } 1917 + 1863 1918 init_completion(&msm_host->dma_comp); 1864 1919 init_completion(&msm_host->video_comp); 1865 1920 mutex_init(&msm_host->dev_mutex); ··· 1904 1925 DBG(""); 1905 1926 dsi_tx_buf_free(msm_host); 1906 1927 if (msm_host->workqueue) { 1907 - flush_workqueue(msm_host->workqueue); 1908 1928 destroy_workqueue(msm_host->workqueue); 1909 1929 msm_host->workqueue = NULL; 1910 1930 } ··· 1919 1941 { 1920 1942 struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 1921 1943 const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; 1922 - struct platform_device *pdev = msm_host->pdev; 1923 1944 int ret; 1924 - 1925 - msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 1926 - if (msm_host->irq < 0) { 1927 - ret = msm_host->irq; 1928 - DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); 1929 - return ret; 1930 - } 1931 - 1932 - ret = devm_request_irq(&pdev->dev, msm_host->irq, 1933 - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 1934 - "dsi_isr", msm_host); 1935 - if (ret < 0) { 1936 - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n", 1937 - msm_host->irq, ret); 1938 - return ret; 1939 - } 1940 1945 1941 1946 msm_host->dev = dev; 1942 1947 ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); ··· 2274 2313 else 2275 2314 clk_req->bitclk_rate = msm_host->byte_clk_rate * 8; 2276 2315 clk_req->escclk_rate = msm_host->esc_clk_rate; 2316 + } 2317 + 2318 + void msm_dsi_host_enable_irq(struct mipi_dsi_host *host) 2319 + { 2320 + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2321 + 2322 + enable_irq(msm_host->irq); 2323 + } 2324 + 2325 + void msm_dsi_host_disable_irq(struct mipi_dsi_host *host) 2326 + { 2327 + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); 2328 + 2329 + disable_irq(msm_host->irq); 2277 2330 } 2278 2331 2279 2332 int msm_dsi_host_enable(struct mipi_dsi_host *host)
+53 -13
drivers/gpu/drm/msm/dsi/dsi_manager.c
··· 3 3 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 4 4 */ 5 5 6 + #include "drm/drm_bridge_connector.h" 7 + 6 8 #include "msm_kms.h" 7 9 #include "dsi.h" 8 10 ··· 379 377 } 380 378 } 381 379 380 + /* 381 + * Enable before preparing the panel, disable after unpreparing, so 382 + * that the panel can communicate over the DSI link. 383 + */ 384 + msm_dsi_host_enable_irq(host); 385 + if (is_bonded_dsi && msm_dsi1) 386 + msm_dsi_host_enable_irq(msm_dsi1->host); 387 + 382 388 /* Always call panel functions once, because even for dual panels, 383 389 * there is only one drm_panel instance. 384 390 */ ··· 421 411 if (panel) 422 412 drm_panel_unprepare(panel); 423 413 panel_prep_fail: 414 + msm_dsi_host_disable_irq(host); 415 + if (is_bonded_dsi && msm_dsi1) 416 + msm_dsi_host_disable_irq(msm_dsi1->host); 417 + 424 418 if (is_bonded_dsi && msm_dsi1) 425 419 msm_dsi_host_power_off(msm_dsi1->host); 426 420 host1_on_fail: ··· 536 522 pr_err("%s: Panel %d unprepare failed,%d\n", __func__, 537 523 id, ret); 538 524 } 525 + 526 + msm_dsi_host_disable_irq(host); 527 + if (is_bonded_dsi && msm_dsi1) 528 + msm_dsi_host_disable_irq(msm_dsi1->host); 539 529 540 530 /* Save PHY status if it is a clock source */ 541 531 msm_dsi_phy_pll_save_state(msm_dsi->phy); ··· 706 688 { 707 689 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 708 690 struct drm_device *dev = msm_dsi->dev; 691 + struct drm_connector *connector; 709 692 struct drm_encoder *encoder; 710 693 struct drm_bridge *int_bridge, *ext_bridge; 711 - struct drm_connector *connector; 712 - struct list_head *connector_list; 694 + int ret; 713 695 714 696 int_bridge = msm_dsi->bridge; 715 697 ext_bridge = msm_dsi->external_bridge = ··· 717 699 718 700 encoder = msm_dsi->encoder; 719 701 720 - /* link the internal dsi bridge to the external bridge */ 721 - drm_bridge_attach(encoder, ext_bridge, int_bridge, 0); 722 - 723 702 /* 724 - * we need the drm_connector created by the external bridge 725 - * driver (or someone else) to feed it to our driver's 726 - * priv->connector[] list, mainly for msm_fbdev_init() 703 + * Try first to create the bridge without it creating its own 704 + * connector.. currently some bridges support this, and others 705 + * do not (and some support both modes) 727 706 */ 728 - connector_list = &dev->mode_config.connector_list; 707 + ret = drm_bridge_attach(encoder, ext_bridge, int_bridge, 708 + DRM_BRIDGE_ATTACH_NO_CONNECTOR); 709 + if (ret == -EINVAL) { 710 + struct drm_connector *connector; 711 + struct list_head *connector_list; 729 712 730 - list_for_each_entry(connector, connector_list, head) { 731 - if (drm_connector_has_possible_encoder(connector, encoder)) 732 - return connector; 713 + /* link the internal dsi bridge to the external bridge */ 714 + drm_bridge_attach(encoder, ext_bridge, int_bridge, 0); 715 + 716 + /* 717 + * we need the drm_connector created by the external bridge 718 + * driver (or someone else) to feed it to our driver's 719 + * priv->connector[] list, mainly for msm_fbdev_init() 720 + */ 721 + connector_list = &dev->mode_config.connector_list; 722 + 723 + list_for_each_entry(connector, connector_list, head) { 724 + if (drm_connector_has_possible_encoder(connector, encoder)) 725 + return connector; 726 + } 727 + 728 + return ERR_PTR(-ENODEV); 733 729 } 734 730 735 - return ERR_PTR(-ENODEV); 731 + connector = drm_bridge_connector_init(dev, encoder); 732 + if (IS_ERR(connector)) { 733 + DRM_ERROR("Unable to create bridge connector\n"); 734 + return ERR_CAST(connector); 735 + } 736 + 737 + drm_connector_attach_encoder(connector, encoder); 738 + 739 + return connector; 736 740 } 737 741 738 742 void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
+2
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
··· 627 627 .data = &dsi_phy_14nm_cfgs }, 628 628 { .compatible = "qcom,dsi-phy-14nm-660", 629 629 .data = &dsi_phy_14nm_660_cfgs }, 630 + { .compatible = "qcom,dsi-phy-14nm-8953", 631 + .data = &dsi_phy_14nm_8953_cfgs }, 630 632 #endif 631 633 #ifdef CONFIG_DRM_MSM_DSI_10NM_PHY 632 634 { .compatible = "qcom,dsi-phy-10nm",
+1
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
··· 48 48 extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs; 49 49 extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs; 50 50 extern const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs; 51 + extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs; 51 52 extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs; 52 53 extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs; 53 54 extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs;
+22 -3
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
··· 213 213 DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref); 214 214 215 215 dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref); 216 - div_u64_rem(dec_start_multiple, multiplier, &div_frac_start); 217 - 218 - dec_start = div_u64(dec_start_multiple, multiplier); 216 + dec_start = div_u64_rem(dec_start_multiple, multiplier, &div_frac_start); 219 217 220 218 pconf->dec_start = (u32)dec_start; 221 219 pconf->div_frac_start = div_frac_start; ··· 1061 1063 .min_pll_rate = VCO_MIN_RATE, 1062 1064 .max_pll_rate = VCO_MAX_RATE, 1063 1065 .io_start = { 0xc994400, 0xc996000 }, 1066 + .num_dsi_phy = 2, 1067 + }; 1068 + 1069 + const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = { 1070 + .has_phy_lane = true, 1071 + .reg_cfg = { 1072 + .num = 1, 1073 + .regs = { 1074 + {"vcca", 17000, 32}, 1075 + }, 1076 + }, 1077 + .ops = { 1078 + .enable = dsi_14nm_phy_enable, 1079 + .disable = dsi_14nm_phy_disable, 1080 + .pll_init = dsi_pll_14nm_init, 1081 + .save_pll_state = dsi_14nm_pll_save_state, 1082 + .restore_pll_state = dsi_14nm_pll_restore_state, 1083 + }, 1084 + .min_pll_rate = VCO_MIN_RATE, 1085 + .max_pll_rate = VCO_MAX_RATE, 1086 + .io_start = { 0x1a94400, 0x1a96400 }, 1064 1087 .num_dsi_phy = 2, 1065 1088 };
+1 -3
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
··· 114 114 115 115 multiplier = 1 << FRAC_BITS; 116 116 dec_multiple = div_u64(pll_freq * multiplier, divider); 117 - div_u64_rem(dec_multiple, multiplier, &frac); 118 - 119 - dec = div_u64(dec_multiple, multiplier); 117 + dec = div_u64_rem(dec_multiple, multiplier, &frac); 120 118 121 119 if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)) 122 120 config->pll_clock_inverters = 0x28;
+1 -4
drivers/gpu/drm/msm/edp/edp_ctrl.c
··· 1190 1190 return; 1191 1191 1192 1192 if (ctrl->workqueue) { 1193 - flush_workqueue(ctrl->workqueue); 1194 1193 destroy_workqueue(ctrl->workqueue); 1195 1194 ctrl->workqueue = NULL; 1196 1195 } ··· 1242 1243 int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, 1243 1244 struct drm_connector *connector, struct edid **edid) 1244 1245 { 1245 - int ret = 0; 1246 - 1247 1246 mutex_lock(&ctrl->dev_mutex); 1248 1247 1249 1248 if (ctrl->edid) { ··· 1276 1279 } 1277 1280 unlock_ret: 1278 1281 mutex_unlock(&ctrl->dev_mutex); 1279 - return ret; 1282 + return 0; 1280 1283 } 1281 1284 1282 1285 int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl,
+11 -27
drivers/gpu/drm/msm/hdmi/hdmi.c
··· 61 61 * at this point, hpd has been disabled, 62 62 * after flush workq, it's safe to deinit hdcp 63 63 */ 64 - if (hdmi->workq) { 65 - flush_workqueue(hdmi->workq); 64 + if (hdmi->workq) 66 65 destroy_workqueue(hdmi->workq); 67 - } 68 66 msm_hdmi_hdcp_destroy(hdmi); 69 67 70 68 if (hdmi->phy_dev) { ··· 152 154 ret = -ENOMEM; 153 155 goto fail; 154 156 } 155 - for (i = 0; i < config->hpd_reg_cnt; i++) { 156 - struct regulator *reg; 157 + for (i = 0; i < config->hpd_reg_cnt; i++) 158 + hdmi->hpd_regs[i].supply = config->hpd_reg_names[i]; 157 159 158 - reg = devm_regulator_get(&pdev->dev, 159 - config->hpd_reg_names[i]); 160 - if (IS_ERR(reg)) { 161 - ret = PTR_ERR(reg); 162 - DRM_DEV_ERROR(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", 163 - config->hpd_reg_names[i], ret); 164 - goto fail; 165 - } 166 - 167 - hdmi->hpd_regs[i] = reg; 160 + ret = devm_regulator_bulk_get(&pdev->dev, config->hpd_reg_cnt, hdmi->hpd_regs); 161 + if (ret) { 162 + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd regulator: %d\n", ret); 163 + goto fail; 168 164 } 169 165 170 166 hdmi->pwr_regs = devm_kcalloc(&pdev->dev, ··· 169 177 ret = -ENOMEM; 170 178 goto fail; 171 179 } 172 - for (i = 0; i < config->pwr_reg_cnt; i++) { 173 - struct regulator *reg; 174 180 175 - reg = devm_regulator_get(&pdev->dev, 176 - config->pwr_reg_names[i]); 177 - if (IS_ERR(reg)) { 178 - ret = PTR_ERR(reg); 179 - DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", 180 - config->pwr_reg_names[i], ret); 181 - goto fail; 182 - } 183 - 184 - hdmi->pwr_regs[i] = reg; 181 + ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs); 182 + if (ret) { 183 + DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %d\n", ret); 184 + goto fail; 185 185 } 186 186 187 187 hdmi->hpd_clks = devm_kcalloc(&pdev->dev,
+3 -3
drivers/gpu/drm/msm/hdmi/hdmi.h
··· 56 56 void __iomem *qfprom_mmio; 57 57 phys_addr_t mmio_phy_addr; 58 58 59 - struct regulator **hpd_regs; 60 - struct regulator **pwr_regs; 59 + struct regulator_bulk_data *hpd_regs; 60 + struct regulator_bulk_data *pwr_regs; 61 61 struct clk **hpd_clks; 62 62 struct clk **pwr_clks; 63 63 ··· 163 163 void __iomem *mmio; 164 164 struct hdmi_phy_cfg *cfg; 165 165 const struct hdmi_phy_funcs *funcs; 166 - struct regulator **regs; 166 + struct regulator_bulk_data *regs; 167 167 struct clk **clks; 168 168 }; 169 169
+6 -14
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
··· 28 28 29 29 pm_runtime_get_sync(&hdmi->pdev->dev); 30 30 31 - for (i = 0; i < config->pwr_reg_cnt; i++) { 32 - ret = regulator_enable(hdmi->pwr_regs[i]); 33 - if (ret) { 34 - DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %s (%d)\n", 35 - config->pwr_reg_names[i], ret); 36 - } 37 - } 31 + ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs); 32 + if (ret) 33 + DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret); 38 34 39 35 if (config->pwr_clk_cnt > 0) { 40 36 DBG("pixclock: %lu", hdmi->pixclock); ··· 66 70 for (i = 0; i < config->pwr_clk_cnt; i++) 67 71 clk_disable_unprepare(hdmi->pwr_clks[i]); 68 72 69 - for (i = 0; i < config->pwr_reg_cnt; i++) { 70 - ret = regulator_disable(hdmi->pwr_regs[i]); 71 - if (ret) { 72 - DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %s (%d)\n", 73 - config->pwr_reg_names[i], ret); 74 - } 75 - } 73 + ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs); 74 + if (ret) 75 + DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %d\n", ret); 76 76 77 77 pm_runtime_put_autosuspend(&hdmi->pdev->dev); 78 78 }
+9 -15
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
··· 146 146 const struct hdmi_platform_config *config = hdmi->config; 147 147 struct device *dev = &hdmi->pdev->dev; 148 148 uint32_t hpd_ctrl; 149 - int i, ret; 149 + int ret; 150 150 unsigned long flags; 151 151 152 - for (i = 0; i < config->hpd_reg_cnt; i++) { 153 - ret = regulator_enable(hdmi->hpd_regs[i]); 154 - if (ret) { 155 - DRM_DEV_ERROR(dev, "failed to enable hpd regulator: %s (%d)\n", 156 - config->hpd_reg_names[i], ret); 157 - goto fail; 158 - } 152 + ret = regulator_bulk_enable(config->hpd_reg_cnt, hdmi->hpd_regs); 153 + if (ret) { 154 + DRM_DEV_ERROR(dev, "failed to enable hpd regulators: %d\n", ret); 155 + goto fail; 159 156 } 160 157 161 158 ret = pinctrl_pm_select_default_state(dev); ··· 204 207 struct hdmi *hdmi = hdmi_connector->hdmi; 205 208 const struct hdmi_platform_config *config = hdmi->config; 206 209 struct device *dev = &hdmi->pdev->dev; 207 - int i, ret = 0; 210 + int ret; 208 211 209 212 /* Disable HPD interrupt */ 210 213 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0); ··· 222 225 if (ret) 223 226 dev_warn(dev, "pinctrl state chg failed: %d\n", ret); 224 227 225 - for (i = 0; i < config->hpd_reg_cnt; i++) { 226 - ret = regulator_disable(hdmi->hpd_regs[i]); 227 - if (ret) 228 - dev_warn(dev, "failed to disable hpd regulator: %s (%d)\n", 229 - config->hpd_reg_names[i], ret); 230 - } 228 + ret = regulator_bulk_disable(config->hpd_reg_cnt, hdmi->hpd_regs); 229 + if (ret) 230 + dev_warn(dev, "failed to disable hpd regulator: %d\n", ret); 231 231 } 232 232 233 233 static void
+12 -21
drivers/gpu/drm/msm/hdmi/hdmi_phy.c
··· 23 23 if (!phy->clks) 24 24 return -ENOMEM; 25 25 26 - for (i = 0; i < cfg->num_regs; i++) { 27 - struct regulator *reg; 26 + for (i = 0; i < cfg->num_regs; i++) 27 + phy->regs[i].supply = cfg->reg_names[i]; 28 28 29 - reg = devm_regulator_get(dev, cfg->reg_names[i]); 30 - if (IS_ERR(reg)) { 31 - ret = PTR_ERR(reg); 32 - if (ret != -EPROBE_DEFER) { 33 - DRM_DEV_ERROR(dev, 34 - "failed to get phy regulator: %s (%d)\n", 35 - cfg->reg_names[i], ret); 36 - } 29 + ret = devm_regulator_bulk_get(dev, cfg->num_regs, phy->regs); 30 + if (ret) { 31 + if (ret != -EPROBE_DEFER) 32 + DRM_DEV_ERROR(dev, "failed to get phy regulators: %d\n", ret); 37 33 38 - return ret; 39 - } 40 - 41 - phy->regs[i] = reg; 34 + return ret; 42 35 } 43 36 44 37 for (i = 0; i < cfg->num_clks; i++) { ··· 59 66 60 67 pm_runtime_get_sync(dev); 61 68 62 - for (i = 0; i < cfg->num_regs; i++) { 63 - ret = regulator_enable(phy->regs[i]); 64 - if (ret) 65 - DRM_DEV_ERROR(dev, "failed to enable regulator: %s (%d)\n", 66 - cfg->reg_names[i], ret); 69 + ret = regulator_bulk_enable(cfg->num_regs, phy->regs); 70 + if (ret) { 71 + DRM_DEV_ERROR(dev, "failed to enable regulators: (%d)\n", ret); 72 + return ret; 67 73 } 68 74 69 75 for (i = 0; i < cfg->num_clks; i++) { ··· 84 92 for (i = cfg->num_clks - 1; i >= 0; i--) 85 93 clk_disable_unprepare(phy->clks[i]); 86 94 87 - for (i = cfg->num_regs - 1; i >= 0; i--) 88 - regulator_disable(phy->regs[i]); 95 + regulator_bulk_disable(cfg->num_regs, phy->regs); 89 96 90 97 pm_runtime_put_sync(dev); 91 98 }
+2 -2
drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c
··· 682 682 return pll_locked; 683 683 } 684 684 685 - static struct clk_ops hdmi_8996_pll_ops = { 685 + static const struct clk_ops hdmi_8996_pll_ops = { 686 686 .set_rate = hdmi_8996_pll_set_clk_rate, 687 687 .round_rate = hdmi_8996_pll_round_rate, 688 688 .recalc_rate = hdmi_8996_pll_recalc_rate, ··· 695 695 "xo", 696 696 }; 697 697 698 - static struct clk_init_data pll_init = { 698 + static const struct clk_init_data pll_init = { 699 699 .name = "hdmipll", 700 700 .ops = &hdmi_8996_pll_ops, 701 701 .parent_names = hdmi_pll_parents,
+6 -15
drivers/gpu/drm/msm/msm_atomic.c
··· 116 116 trace_msm_atomic_async_commit_finish(crtc_mask); 117 117 } 118 118 119 - static enum hrtimer_restart msm_atomic_pending_timer(struct hrtimer *t) 120 - { 121 - struct msm_pending_timer *timer = container_of(t, 122 - struct msm_pending_timer, timer); 123 - 124 - kthread_queue_work(timer->worker, &timer->work); 125 - 126 - return HRTIMER_NORESTART; 127 - } 128 - 129 119 static void msm_atomic_pending_work(struct kthread_work *work) 130 120 { 131 121 struct msm_pending_timer *timer = container_of(work, 132 - struct msm_pending_timer, work); 122 + struct msm_pending_timer, work.work); 133 123 134 124 msm_atomic_async_commit(timer->kms, timer->crtc_idx); 135 125 } ··· 129 139 { 130 140 timer->kms = kms; 131 141 timer->crtc_idx = crtc_idx; 132 - hrtimer_init(&timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 133 - timer->timer.function = msm_atomic_pending_timer; 134 142 135 143 timer->worker = kthread_create_worker(0, "atomic-worker-%d", crtc_idx); 136 144 if (IS_ERR(timer->worker)) { ··· 137 149 return ret; 138 150 } 139 151 sched_set_fifo(timer->worker->task); 140 - kthread_init_work(&timer->work, msm_atomic_pending_work); 152 + 153 + msm_hrtimer_work_init(&timer->work, timer->worker, 154 + msm_atomic_pending_work, 155 + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 141 156 142 157 return 0; 143 158 } ··· 249 258 vsync_time = kms->funcs->vsync_time(kms, async_crtc); 250 259 wakeup_time = ktime_sub(vsync_time, ms_to_ktime(1)); 251 260 252 - hrtimer_start(&timer->timer, wakeup_time, 261 + msm_hrtimer_queue_work(&timer->work, wakeup_time, 253 262 HRTIMER_MODE_ABS); 254 263 } 255 264
+31 -2
drivers/gpu/drm/msm/msm_drv.c
··· 58 58 }; 59 59 60 60 #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING 61 - static bool reglog = false; 61 + static bool reglog; 62 62 MODULE_PARM_DESC(reglog, "Enable register read/write logging"); 63 63 module_param(reglog, bool, 0600); 64 64 #else ··· 75 75 MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)"); 76 76 module_param(vram, charp, 0); 77 77 78 - bool dumpstate = false; 78 + bool dumpstate; 79 79 MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors"); 80 80 module_param(dumpstate, bool, 0600); 81 81 ··· 198 198 199 199 val &= ~mask; 200 200 msm_writel(val | or, addr); 201 + } 202 + 203 + static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t) 204 + { 205 + struct msm_hrtimer_work *work = container_of(t, 206 + struct msm_hrtimer_work, timer); 207 + 208 + kthread_queue_work(work->worker, &work->work); 209 + 210 + return HRTIMER_NORESTART; 211 + } 212 + 213 + void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, 214 + ktime_t wakeup_time, 215 + enum hrtimer_mode mode) 216 + { 217 + hrtimer_start(&work->timer, wakeup_time, mode); 218 + } 219 + 220 + void msm_hrtimer_work_init(struct msm_hrtimer_work *work, 221 + struct kthread_worker *worker, 222 + kthread_work_func_t fn, 223 + clockid_t clock_id, 224 + enum hrtimer_mode mode) 225 + { 226 + hrtimer_init(&work->timer, clock_id, mode); 227 + work->timer.function = msm_hrtimer_worktimer; 228 + work->worker = worker; 229 + kthread_init_work(&work->work, fn); 201 230 } 202 231 203 232 static irqreturn_t msm_irq(int irq, void *arg)
+30 -1
drivers/gpu/drm/msm/msm_drv.h
··· 60 60 PLANE_PROP_MAX_NUM 61 61 }; 62 62 63 + enum msm_dp_controller { 64 + MSM_DP_CONTROLLER_0, 65 + MSM_DP_CONTROLLER_1, 66 + MSM_DP_CONTROLLER_2, 67 + MSM_DP_CONTROLLER_COUNT, 68 + }; 69 + 63 70 #define MSM_GPU_MAX_RINGS 4 64 71 #define MAX_H_TILES_PER_DISPLAY 2 65 72 ··· 160 153 /* DSI is shared by mdp4 and mdp5 */ 161 154 struct msm_dsi *dsi[2]; 162 155 163 - struct msm_dp *dp; 156 + struct msm_dp *dp[MSM_DP_CONTROLLER_COUNT]; 164 157 165 158 /* when we have more than one 'msm_gpu' these need to be an array: */ 166 159 struct msm_gpu *gpu; ··· 486 479 void msm_writel(u32 data, void __iomem *addr); 487 480 u32 msm_readl(const void __iomem *addr); 488 481 void msm_rmw(void __iomem *addr, u32 mask, u32 or); 482 + 483 + /** 484 + * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work 485 + * 486 + * @timer: hrtimer to control when the kthread work is triggered 487 + * @work: the kthread work 488 + * @worker: the kthread worker the work will be scheduled on 489 + */ 490 + struct msm_hrtimer_work { 491 + struct hrtimer timer; 492 + struct kthread_work work; 493 + struct kthread_worker *worker; 494 + }; 495 + 496 + void msm_hrtimer_queue_work(struct msm_hrtimer_work *work, 497 + ktime_t wakeup_time, 498 + enum hrtimer_mode mode); 499 + void msm_hrtimer_work_init(struct msm_hrtimer_work *work, 500 + struct kthread_worker *worker, 501 + kthread_work_func_t fn, 502 + clockid_t clock_id, 503 + enum hrtimer_mode mode); 489 504 490 505 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__) 491 506 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
+4 -2
drivers/gpu/drm/msm/msm_gem.c
··· 5 5 */ 6 6 7 7 #include <linux/dma-map-ops.h> 8 + #include <linux/vmalloc.h> 8 9 #include <linux/spinlock.h> 9 10 #include <linux/shmem_fs.h> 10 11 #include <linux/dma-buf.h> ··· 1133 1132 msm_obj->flags = flags; 1134 1133 msm_obj->madv = MSM_MADV_WILLNEED; 1135 1134 1135 + INIT_LIST_HEAD(&msm_obj->node); 1136 1136 INIT_LIST_HEAD(&msm_obj->vmas); 1137 1137 1138 1138 *obj = &msm_obj->base; ··· 1168 1166 1169 1167 ret = msm_gem_new_impl(dev, size, flags, &obj); 1170 1168 if (ret) 1171 - goto fail; 1169 + return ERR_PTR(ret); 1172 1170 1173 1171 msm_obj = to_msm_bo(obj); 1174 1172 ··· 1252 1250 1253 1251 ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj); 1254 1252 if (ret) 1255 - goto fail; 1253 + return ERR_PTR(ret); 1256 1254 1257 1255 drm_gem_private_object_init(dev, obj, size); 1258 1256
+2
drivers/gpu/drm/msm/msm_gem_shrinker.c
··· 4 4 * Author: Rob Clark <robdclark@gmail.com> 5 5 */ 6 6 7 + #include <linux/vmalloc.h> 8 + 7 9 #include "msm_drv.h" 8 10 #include "msm_gem.h" 9 11 #include "msm_gpu.h"
+1 -1
drivers/gpu/drm/msm/msm_gpu.c
··· 296 296 state->bos = kcalloc(nr, 297 297 sizeof(struct msm_gpu_state_bo), GFP_KERNEL); 298 298 299 - for (i = 0; i < submit->nr_bos; i++) { 299 + for (i = 0; state->bos && i < submit->nr_bos; i++) { 300 300 if (should_dump(submit, i)) { 301 301 msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, 302 302 submit->bos[i].iova, submit->bos[i].flags);
+7
drivers/gpu/drm/msm/msm_gpu.h
··· 112 112 * it is inactive. 113 113 */ 114 114 unsigned long idle_freq; 115 + 116 + /** 117 + * idle_work: 118 + * 119 + * Used to delay clamping to idle freq on active->idle transition. 120 + */ 121 + struct msm_hrtimer_work idle_work; 115 122 }; 116 123 117 124 struct msm_gpu {
+30 -8
drivers/gpu/drm/msm/msm_gpu_devfreq.c
··· 88 88 .get_cur_freq = msm_devfreq_get_cur_freq, 89 89 }; 90 90 91 + static void msm_devfreq_idle_work(struct kthread_work *work); 92 + 91 93 void msm_devfreq_init(struct msm_gpu *gpu) 92 94 { 95 + struct msm_gpu_devfreq *df = &gpu->devfreq; 96 + 93 97 /* We need target support to do devfreq */ 94 98 if (!gpu->funcs->gpu_busy) 95 99 return; ··· 109 105 msm_devfreq_profile.freq_table = NULL; 110 106 msm_devfreq_profile.max_state = 0; 111 107 112 - gpu->devfreq.devfreq = devm_devfreq_add_device(&gpu->pdev->dev, 108 + df->devfreq = devm_devfreq_add_device(&gpu->pdev->dev, 113 109 &msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, 114 110 NULL); 115 111 116 - if (IS_ERR(gpu->devfreq.devfreq)) { 112 + if (IS_ERR(df->devfreq)) { 117 113 DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); 118 - gpu->devfreq.devfreq = NULL; 114 + df->devfreq = NULL; 119 115 return; 120 116 } 121 117 122 - devfreq_suspend_device(gpu->devfreq.devfreq); 118 + devfreq_suspend_device(df->devfreq); 123 119 124 - gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, 125 - gpu->devfreq.devfreq); 120 + gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, df->devfreq); 126 121 if (IS_ERR(gpu->cooling)) { 127 122 DRM_DEV_ERROR(&gpu->pdev->dev, 128 123 "Couldn't register GPU cooling device\n"); 129 124 gpu->cooling = NULL; 130 125 } 126 + 127 + msm_hrtimer_work_init(&df->idle_work, gpu->worker, msm_devfreq_idle_work, 128 + CLOCK_MONOTONIC, HRTIMER_MODE_REL); 131 129 } 132 130 133 131 void msm_devfreq_cleanup(struct msm_gpu *gpu) ··· 161 155 return; 162 156 163 157 /* 158 + * Cancel any pending transition to idle frequency: 159 + */ 160 + hrtimer_cancel(&df->idle_work.timer); 161 + 162 + /* 164 163 * Hold devfreq lock to synchronize with get_dev_status()/ 165 164 * target() callbacks 166 165 */ ··· 195 184 mutex_unlock(&df->devfreq->lock); 196 185 } 197 186 198 - void msm_devfreq_idle(struct msm_gpu *gpu) 187 + 188 + static void msm_devfreq_idle_work(struct kthread_work *work) 199 189 { 200 - struct msm_gpu_devfreq *df = &gpu->devfreq; 190 + struct msm_gpu_devfreq *df = container_of(work, 191 + struct msm_gpu_devfreq, idle_work.work); 192 + struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); 201 193 unsigned long idle_freq, target_freq = 0; 202 194 203 195 if (!df->devfreq) ··· 221 207 df->idle_freq = idle_freq; 222 208 223 209 mutex_unlock(&df->devfreq->lock); 210 + } 211 + 212 + void msm_devfreq_idle(struct msm_gpu *gpu) 213 + { 214 + struct msm_gpu_devfreq *df = &gpu->devfreq; 215 + 216 + msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), 217 + HRTIMER_MODE_ABS); 224 218 }
+1 -2
drivers/gpu/drm/msm/msm_kms.h
··· 136 136 * shortly before vblank to flush pending async updates. 137 137 */ 138 138 struct msm_pending_timer { 139 - struct hrtimer timer; 140 - struct kthread_work work; 139 + struct msm_hrtimer_work work; 141 140 struct kthread_worker *worker; 142 141 struct msm_kms *kms; 143 142 unsigned crtc_idx;
+1
drivers/gpu/drm/msm/msm_submitqueue.c
··· 101 101 102 102 ret = drm_sched_entity_init(entity, sched_prio, &sched, 1, NULL); 103 103 if (ret) { 104 + mutex_unlock(&entity_lock); 104 105 kfree(entity); 105 106 return ERR_PTR(ret); 106 107 }
+1 -3
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 186 186 if (priv->mmio) 187 187 iounmap(priv->mmio); 188 188 189 - if (priv->wq) { 190 - flush_workqueue(priv->wq); 189 + if (priv->wq) 191 190 destroy_workqueue(priv->wq); 192 - } 193 191 194 192 dev->dev_private = NULL; 195 193
-1
drivers/gpu/drm/vmwgfx/ttm_memory.c
··· 468 468 struct ttm_mem_zone *zone; 469 469 unsigned int i; 470 470 471 - flush_workqueue(glob->swap_queue); 472 471 destroy_workqueue(glob->swap_queue); 473 472 glob->swap_queue = NULL; 474 473 for (i = 0; i < glob->num_zones; ++i) {