Updates for v6.8: Core: - Add support for SDM670, SM8650 - Handle the CFG interconnect to fix the obscure hangs / timeouts on register write - Kconfig fix for QMP dependency - DT schema fixes DPU: - Add support for SDM670, SM8650 - Enable SmartDMA on SM8350 and SM8450 - Correct UBWC settings for SC8280XP - Fix catalog settings for SC8180X - Actually make use of the version to switch between QSEED3/3LITE/4 scalers - Use devres-managed and drm-managed allocations where appropriate - misc other fixes - Enabled YUV writeback on SC7280, SM8250 - Enabled writeback on SM8350, SM8450 - CRC fix when encoder is selected as the input source - other misc fixes MDP4: - Use devres-managed and drm-managed allocations where appropriate - flush vblank event on CRTC disable MDP5: - Use devres-managed and drm-managed allocations where appropriate DP: - Add support for SM8650 - Enable PM runtime support - Merge msm-specific debugfs dir with the generic one - Described DisplayPort on SM8150 in DeviceTree bindings - Moved dp_display_get_next_bridge() to probe() DSI: - Add support for SM8650 - Enable PM runtime support GPU/GEM: - demote userspace triggerable warnings to debug - add GEM object metadata UAPI - move GPU devcoredumps to GPU device - fix hangcheck to skip retired submits - expose UBWC config to userspace - fix a680 chip-id - drm_exec conversion - drm/ci: remove rebase-merge directory (to unblock CI) [airlied: fix drm_exec/amd interaction] Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <robdclark@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGs9auYqmo-7NSd9FsbNBCDf7aBevd=4xkcF3A5G_OGvMQ@mail.gmail.com
Unified · Split
| @@ -26,8 +26,10 @@ properties: · 25 unmodified lines | ||
| 26 | 26 | - qcom,sc8280xp-edp |
| 27 | 27 | - qcom,sdm845-dp |
| 28 | 28 | - qcom,sm8350-dp |
| 29 | + - qcom,sm8650-dp | |
| 29 | 30 | - items: |
| 30 | 31 | - enum: |
| 32 | + - qcom,sm8150-dp | |
| 31 | 33 | - qcom,sm8250-dp |
| 32 | 34 | - qcom,sm8450-dp |
| 33 | 35 | - qcom,sm8550-dp |
| @@ -25,6 +25,7 @@ properties: · 24 unmodified lines | ||
| 25 | 25 | - qcom,sc7180-dsi-ctrl |
| 26 | 26 | - qcom,sc7280-dsi-ctrl |
| 27 | 27 | - qcom,sdm660-dsi-ctrl |
| 28 | + - qcom,sdm670-dsi-ctrl | |
| 28 | 29 | - qcom,sdm845-dsi-ctrl |
| 29 | 30 | - qcom,sm6115-dsi-ctrl |
| 30 | 31 | - qcom,sm6125-dsi-ctrl |
| @@ -35,6 +36,7 @@ properties: · 4 unmodified lines | ||
| 35 | 36 | - qcom,sm8350-dsi-ctrl |
| 36 | 37 | - qcom,sm8450-dsi-ctrl |
| 37 | 38 | - qcom,sm8550-dsi-ctrl |
| 39 | + - qcom,sm8650-dsi-ctrl | |
| 38 | 40 | - const: qcom,mdss-dsi-ctrl |
| 39 | 41 | - enum: |
| 40 | 42 | - qcom,dsi-ctrl-6g-qcm2290 |
| @@ -333,6 +335,7 @@ allOf: · 292 unmodified lines | ||
| 333 | 335 | - qcom,sm8350-dsi-ctrl |
| 334 | 336 | - qcom,sm8450-dsi-ctrl |
| 335 | 337 | - qcom,sm8550-dsi-ctrl |
| 338 | + - qcom,sm8650-dsi-ctrl | |
| 336 | 339 | then: |
| 337 | 340 | properties: |
| 338 | 341 | clocks: |
| @@ -22,6 +22,7 @@ properties: · 21 unmodified lines | ||
| 22 | 22 | - qcom,sm8350-dsi-phy-5nm |
| 23 | 23 | - qcom,sm8450-dsi-phy-5nm |
| 24 | 24 | - qcom,sm8550-dsi-phy-4nm |
| 25 | + - qcom,sm8650-dsi-phy-4nm | |
| 25 | 26 | |
| 26 | 27 | reg: |
| 27 | 28 | items: |
| @@ -61,17 +61,27 @@ properties: · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | ranges: true |
| 63 | 63 | |
| 64 | + # This is not a perfect description, but it's impossible to discern and match | |
| 65 | + # the entries like we do with interconnect-names | |
| 64 | 66 | interconnects: |
| 65 | 67 | minItems: 1 |
| 66 | 68 | items: |
| 67 | 69 | - description: Interconnect path from mdp0 (or a single mdp) port to the data bus |
| 68 | 70 | - description: Interconnect path from mdp1 port to the data bus |
| 71 | + - description: Interconnect path from CPU to the reg bus | |
| 69 | 72 | |
| 70 | 73 | interconnect-names: |
| 71 | − minItems: 1 | |
| 72 | − items: | |
| 73 | − - const: mdp0-mem | |
| 74 | − - const: mdp1-mem | |
| 74 | + oneOf: | |
| 75 | + - minItems: 1 | |
| 76 | + items: | |
| 77 | + - const: mdp0-mem | |
| 78 | + - const: cpu-cfg | |
| 79 | + | |
| 80 | + - minItems: 2 | |
| 81 | + items: | |
| 82 | + - const: mdp0-mem | |
| 83 | + - const: mdp1-mem | |
| 84 | + - const: cpu-cfg | |
| 75 | 85 | |
| 76 | 86 | resets: |
| 77 | 87 | items: |
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | maxItems: 2 |
| 37 | 37 | |
| 38 | 38 | interconnects: |
| 39 | − maxItems: 1 | |
| 39 | + items: | |
| 40 | + - description: Interconnect path from mdp0 port to the data bus | |
| 41 | + - description: Interconnect path from CPU to the reg bus | |
| 40 | 42 | |
| 41 | 43 | interconnect-names: |
| 42 | − maxItems: 1 | |
| 44 | + items: | |
| 45 | + - const: mdp0-mem | |
| 46 | + - const: cpu-cfg | |
| 43 | 47 | |
| 44 | 48 | patternProperties: |
| 45 | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -56,7 +60,9 @@ patternProperties: · 10 unmodified lines | ||
| 56 | 60 | |
| 57 | 61 | properties: |
| 58 | 62 | compatible: |
| 59 | − const: qcom,dsi-ctrl-6g-qcm2290 | |
| 63 | + items: | |
| 64 | + - const: qcom,qcm2290-dsi-ctrl | |
| 65 | + - const: qcom,mdss-dsi-ctrl | |
| 60 | 66 | |
| 61 | 67 | "^phy@[0-9a-f]+$": |
| 62 | 68 | type: object |
| @@ -96,8 +102,10 @@ examples: · 33 unmodified lines | ||
| 96 | 102 | interrupt-controller; |
| 97 | 103 | #interrupt-cells = <1>; |
| 98 | 104 | |
| 99 | − interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>; | |
| 100 | − interconnect-names = "mdp0-mem"; | |
| 105 | + interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>, | |
| 106 | + <&bimc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; | |
| 107 | + interconnect-names = "mdp0-mem", | |
| 108 | + "cpu-cfg"; | |
| 101 | 109 | |
| 102 | 110 | iommus = <&apps_smmu 0x420 0x2>, |
| 103 | 111 | <&apps_smmu 0x421 0x0>; |
| @@ -136,7 +144,8 @@ examples: · 32 unmodified lines | ||
| 136 | 144 | }; |
| 137 | 145 | |
| 138 | 146 | dsi@5e94000 { |
| 139 | − compatible = "qcom,dsi-ctrl-6g-qcm2290"; | |
| 147 | + compatible = "qcom,qcm2290-dsi-ctrl", | |
| 148 | + "qcom,mdss-dsi-ctrl"; | |
| 140 | 149 | reg = <0x05e94000 0x400>; |
| 141 | 150 | reg-names = "dsi_ctrl"; |
| 142 | 151 | |
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | maxItems: 1 |
| 37 | 37 | |
| 38 | 38 | interconnects: |
| 39 | − maxItems: 1 | |
| 39 | + items: | |
| 40 | + - description: Interconnect path from mdp0 port to the data bus | |
| 41 | + - description: Interconnect path from CPU to the reg bus | |
| 40 | 42 | |
| 41 | 43 | interconnect-names: |
| 42 | − maxItems: 1 | |
| 44 | + items: | |
| 45 | + - const: mdp0-mem | |
| 46 | + - const: cpu-cfg | |
| 43 | 47 | |
| 44 | 48 | patternProperties: |
| 45 | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -106,8 +110,10 @@ examples: · 60 unmodified lines | ||
| 106 | 110 | interrupt-controller; |
| 107 | 111 | #interrupt-cells = <1>; |
| 108 | 112 | |
| 109 | − interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; | |
| 110 | − interconnect-names = "mdp0-mem"; | |
| 113 | + interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, | |
| 114 | + <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; | |
| 115 | + interconnect-names = "mdp0-mem", | |
| 116 | + "cpu-cfg"; | |
| 111 | 117 | |
| 112 | 118 | iommus = <&apps_smmu 0x800 0x2>; |
| 113 | 119 | ranges; |
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | maxItems: 1 |
| 37 | 37 | |
| 38 | 38 | interconnects: |
| 39 | − maxItems: 1 | |
| 39 | + items: | |
| 40 | + - description: Interconnect path from mdp0 port to the data bus | |
| 41 | + - description: Interconnect path from CPU to the reg bus | |
| 40 | 42 | |
| 41 | 43 | interconnect-names: |
| 42 | − maxItems: 1 | |
| 44 | + items: | |
| 45 | + - const: mdp0-mem | |
| 46 | + - const: cpu-cfg | |
| 43 | 47 | |
| 44 | 48 | patternProperties: |
| 45 | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -118,8 +122,10 @@ examples: · 72 unmodified lines | ||
| 118 | 122 | interrupt-controller; |
| 119 | 123 | #interrupt-cells = <1>; |
| 120 | 124 | |
| 121 | − interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; | |
| 122 | − interconnect-names = "mdp0-mem"; | |
| 125 | + interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, | |
| 126 | + <&gem_noc MASTER_APPSS_PROC &cnoc2 SLAVE_DISPLAY_CFG>; | |
| 127 | + interconnect-names = "mdp0-mem", | |
| 128 | + "cpu-cfg"; | |
| 123 | 129 | |
| 124 | 130 | iommus = <&apps_smmu 0x900 0x402>; |
| 125 | 131 | ranges; |
| @@ -0,0 +1,292 @@ | ||
| 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/qcom,sdm670-mdss.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Qualcomm SDM670 Display MDSS | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Richard Acayan <mailingradian@gmail.com> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + SDM670 MSM Mobile Display Subsystem (MDSS), which encapsulates sub-blocks | |
| 14 | + like DPU display controller, DSI and DP interfaces etc. | |
| 15 | + | |
| 16 | +$ref: /schemas/display/msm/mdss-common.yaml# | |
| 17 | + | |
| 18 | +properties: | |
| 19 | + compatible: | |
| 20 | + const: qcom,sdm670-mdss | |
| 21 | + | |
| 22 | + clocks: | |
| 23 | + items: | |
| 24 | + - description: Display AHB clock from gcc | |
| 25 | + - description: Display core clock | |
| 26 | + | |
| 27 | + clock-names: | |
| 28 | + items: | |
| 29 | + - const: iface | |
| 30 | + - const: core | |
| 31 | + | |
| 32 | + iommus: | |
| 33 | + maxItems: 2 | |
| 34 | + | |
| 35 | + interconnects: | |
| 36 | + maxItems: 2 | |
| 37 | + | |
| 38 | + interconnect-names: | |
| 39 | + maxItems: 2 | |
| 40 | + | |
| 41 | +patternProperties: | |
| 42 | + "^display-controller@[0-9a-f]+$": | |
| 43 | + type: object | |
| 44 | + additionalProperties: true | |
| 45 | + | |
| 46 | + properties: | |
| 47 | + compatible: | |
| 48 | + const: qcom,sdm670-dpu | |
| 49 | + | |
| 50 | + "^displayport-controller@[0-9a-f]+$": | |
| 51 | + type: object | |
| 52 | + additionalProperties: true | |
| 53 | + | |
| 54 | + properties: | |
| 55 | + compatible: | |
| 56 | + const: qcom,sdm670-dp | |
| 57 | + | |
| 58 | + "^dsi@[0-9a-f]+$": | |
| 59 | + type: object | |
| 60 | + additionalProperties: true | |
| 61 | + | |
| 62 | + properties: | |
| 63 | + compatible: | |
| 64 | + contains: | |
| 65 | + const: qcom,sdm670-dsi-ctrl | |
| 66 | + | |
| 67 | + "^phy@[0-9a-f]+$": | |
| 68 | + type: object | |
| 69 | + additionalProperties: true | |
| 70 | + | |
| 71 | + properties: | |
| 72 | + compatible: | |
| 73 | + const: qcom,dsi-phy-10nm | |
| 74 | + | |
| 75 | +required: | |
| 76 | + - compatible | |
| 77 | + | |
| 78 | +unevaluatedProperties: false | |
| 79 | + | |
| 80 | +examples: | |
| 81 | + - | | |
| 82 | + #include <dt-bindings/clock/qcom,dispcc-sdm845.h> | |
| 83 | + #include <dt-bindings/clock/qcom,gcc-sdm845.h> | |
| 84 | + #include <dt-bindings/clock/qcom,rpmh.h> | |
| 85 | + #include <dt-bindings/interconnect/qcom,sdm670-rpmh.h> | |
| 86 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 87 | + #include <dt-bindings/power/qcom-rpmpd.h> | |
| 88 | + | |
| 89 | + display-subsystem@ae00000 { | |
| 90 | + compatible = "qcom,sdm670-mdss"; | |
| 91 | + reg = <0x0ae00000 0x1000>; | |
| 92 | + reg-names = "mdss"; | |
| 93 | + power-domains = <&dispcc MDSS_GDSC>; | |
| 94 | + | |
| 95 | + clocks = <&gcc GCC_DISP_AHB_CLK>, | |
| 96 | + <&dispcc DISP_CC_MDSS_MDP_CLK>; | |
| 97 | + clock-names = "iface", "core"; | |
| 98 | + | |
| 99 | + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; | |
| 100 | + interrupt-controller; | |
| 101 | + #interrupt-cells = <1>; | |
| 102 | + | |
| 103 | + interconnects = <&mmss_noc MASTER_MDP_PORT0 0 &mem_noc SLAVE_EBI_CH0 0>, | |
| 104 | + <&mmss_noc MASTER_MDP_PORT1 0 &mem_noc SLAVE_EBI_CH0 0>; | |
| 105 | + interconnect-names = "mdp0-mem", "mdp1-mem"; | |
| 106 | + | |
| 107 | + iommus = <&apps_smmu 0x880 0x8>, | |
| 108 | + <&apps_smmu 0xc80 0x8>; | |
| 109 | + | |
| 110 | + #address-cells = <1>; | |
| 111 | + #size-cells = <1>; | |
| 112 | + ranges; | |
| 113 | + | |
| 114 | + display-controller@ae01000 { | |
| 115 | + compatible = "qcom,sdm670-dpu"; | |
| 116 | + reg = <0x0ae01000 0x8f000>, | |
| 117 | + <0x0aeb0000 0x2008>; | |
| 118 | + reg-names = "mdp", "vbif"; | |
| 119 | + | |
| 120 | + clocks = <&gcc GCC_DISP_AXI_CLK>, | |
| 121 | + <&dispcc DISP_CC_MDSS_AHB_CLK>, | |
| 122 | + <&dispcc DISP_CC_MDSS_AXI_CLK>, | |
| 123 | + <&dispcc DISP_CC_MDSS_MDP_CLK>, | |
| 124 | + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; | |
| 125 | + clock-names = "gcc-bus", "iface", "bus", "core", "vsync"; | |
| 126 | + | |
| 127 | + interrupt-parent = <&mdss>; | |
| 128 | + interrupts = <0>; | |
| 129 | + power-domains = <&rpmhpd SDM670_CX>; | |
| 130 | + operating-points-v2 = <&mdp_opp_table>; | |
| 131 | + | |
| 132 | + ports { | |
| 133 | + #address-cells = <1>; | |
| 134 | + #size-cells = <0>; | |
| 135 | + | |
| 136 | + port@0 { | |
| 137 | + reg = <0>; | |
| 138 | + dpu_intf1_out: endpoint { | |
| 139 | + remote-endpoint = <&mdss_dsi0_in>; | |
| 140 | + }; | |
| 141 | + }; | |
| 142 | + | |
| 143 | + port@1 { | |
| 144 | + reg = <1>; | |
| 145 | + dpu_intf2_out: endpoint { | |
| 146 | + remote-endpoint = <&mdss_dsi1_in>; | |
| 147 | + }; | |
| 148 | + }; | |
| 149 | + }; | |
| 150 | + }; | |
| 151 | + | |
| 152 | + dsi@ae94000 { | |
| 153 | + compatible = "qcom,sdm670-dsi-ctrl", "qcom,mdss-dsi-ctrl"; | |
| 154 | + reg = <0x0ae94000 0x400>; | |
| 155 | + reg-names = "dsi_ctrl"; | |
| 156 | + | |
| 157 | + interrupt-parent = <&mdss>; | |
| 158 | + interrupts = <4>; | |
| 159 | + | |
| 160 | + clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>, | |
| 161 | + <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, | |
| 162 | + <&dispcc DISP_CC_MDSS_PCLK0_CLK>, | |
| 163 | + <&dispcc DISP_CC_MDSS_ESC0_CLK>, | |
| 164 | + <&dispcc DISP_CC_MDSS_AHB_CLK>, | |
| 165 | + <&dispcc DISP_CC_MDSS_AXI_CLK>; | |
| 166 | + clock-names = "byte", | |
| 167 | + "byte_intf", | |
| 168 | + "pixel", | |
| 169 | + "core", | |
| 170 | + "iface", | |
| 171 | + "bus"; | |
| 172 | + assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>, | |
| 173 | + <&dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>; | |
| 174 | + assigned-clock-parents = <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>; | |
| 175 | + | |
| 176 | + operating-points-v2 = <&dsi_opp_table>; | |
| 177 | + power-domains = <&rpmhpd SDM670_CX>; | |
| 178 | + | |
| 179 | + phys = <&mdss_dsi0_phy>; | |
| 180 | + phy-names = "dsi"; | |
| 181 | + | |
| 182 | + #address-cells = <1>; | |
| 183 | + #size-cells = <0>; | |
| 184 | + | |
| 185 | + ports { | |
| 186 | + #address-cells = <1>; | |
| 187 | + #size-cells = <0>; | |
| 188 | + | |
| 189 | + port@0 { | |
| 190 | + reg = <0>; | |
| 191 | + mdss_dsi0_in: endpoint { | |
| 192 | + remote-endpoint = <&dpu_intf1_out>; | |
| 193 | + }; | |
| 194 | + }; | |
| 195 | + | |
| 196 | + port@1 { | |
| 197 | + reg = <1>; | |
| 198 | + mdss_dsi0_out: endpoint { | |
| 199 | + }; | |
| 200 | + }; | |
| 201 | + }; | |
| 202 | + }; | |
| 203 | + | |
| 204 | + mdss_dsi0_phy: phy@ae94400 { | |
| 205 | + compatible = "qcom,dsi-phy-10nm"; | |
| 206 | + reg = <0x0ae94400 0x200>, | |
| 207 | + <0x0ae94600 0x280>, | |
| 208 | + <0x0ae94a00 0x1e0>; | |
| 209 | + reg-names = "dsi_phy", | |
| 210 | + "dsi_phy_lane", | |
| 211 | + "dsi_pll"; | |
| 212 | + | |
| 213 | + #clock-cells = <1>; | |
| 214 | + #phy-cells = <0>; | |
| 215 | + | |
| 216 | + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, | |
| 217 | + <&rpmhcc RPMH_CXO_CLK>; | |
| 218 | + clock-names = "iface", "ref"; | |
| 219 | + vdds-supply = <&vreg_dsi_phy>; | |
| 220 | + }; | |
| 221 | + | |
| 222 | + dsi@ae96000 { | |
| 223 | + compatible = "qcom,sdm670-dsi-ctrl", "qcom,mdss-dsi-ctrl"; | |
| 224 | + reg = <0x0ae96000 0x400>; | |
| 225 | + reg-names = "dsi_ctrl"; | |
| 226 | + | |
| 227 | + interrupt-parent = <&mdss>; | |
| 228 | + interrupts = <5>; | |
| 229 | + | |
| 230 | + clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>, | |
| 231 | + <&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>, | |
| 232 | + <&dispcc DISP_CC_MDSS_PCLK1_CLK>, | |
| 233 | + <&dispcc DISP_CC_MDSS_ESC1_CLK>, | |
| 234 | + <&dispcc DISP_CC_MDSS_AHB_CLK>, | |
| 235 | + <&dispcc DISP_CC_MDSS_AXI_CLK>; | |
| 236 | + clock-names = "byte", | |
| 237 | + "byte_intf", | |
| 238 | + "pixel", | |
| 239 | + "core", | |
| 240 | + "iface", | |
| 241 | + "bus"; | |
| 242 | + assigned-clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>, | |
| 243 | + <&dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>; | |
| 244 | + assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>; | |
| 245 | + | |
| 246 | + operating-points-v2 = <&dsi_opp_table>; | |
| 247 | + power-domains = <&rpmhpd SDM670_CX>; | |
| 248 | + | |
| 249 | + phys = <&dsi1_phy>; | |
| 250 | + phy-names = "dsi"; | |
| 251 | + | |
| 252 | + #address-cells = <1>; | |
| 253 | + #size-cells = <0>; | |
| 254 | + | |
| 255 | + ports { | |
| 256 | + #address-cells = <1>; | |
| 257 | + #size-cells = <0>; | |
| 258 | + | |
| 259 | + port@0 { | |
| 260 | + reg = <0>; | |
| 261 | + mdss_dsi1_in: endpoint { | |
| 262 | + remote-endpoint = <&dpu_intf2_out>; | |
| 263 | + }; | |
| 264 | + }; | |
| 265 | + | |
| 266 | + port@1 { | |
| 267 | + reg = <1>; | |
| 268 | + mdss_dsi1_out: endpoint { | |
| 269 | + }; | |
| 270 | + }; | |
| 271 | + }; | |
| 272 | + }; | |
| 273 | + | |
| 274 | + mdss_dsi1_phy: phy@ae96400 { | |
| 275 | + compatible = "qcom,dsi-phy-10nm"; | |
| 276 | + reg = <0x0ae96400 0x200>, | |
| 277 | + <0x0ae96600 0x280>, | |
| 278 | + <0x0ae96a00 0x10e>; | |
| 279 | + reg-names = "dsi_phy", | |
| 280 | + "dsi_phy_lane", | |
| 281 | + "dsi_pll"; | |
| 282 | + | |
| 283 | + #clock-cells = <1>; | |
| 284 | + #phy-cells = <0>; | |
| 285 | + | |
| 286 | + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, | |
| 287 | + <&rpmhcc RPMH_CXO_CLK>; | |
| 288 | + clock-names = "iface", "ref"; | |
| 289 | + vdds-supply = <&vreg_dsi_phy>; | |
| 290 | + }; | |
| 291 | + }; | |
| 292 | +... | |
| @@ -13,7 +13,9 @@ $ref: /schemas/display/msm/dpu-common.yaml# · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | properties: |
| 15 | 15 | compatible: |
| 16 | − const: qcom,sdm845-dpu | |
| 16 | + enum: | |
| 17 | + - qcom,sdm670-dpu | |
| 18 | + - qcom,sdm845-dpu | |
| 17 | 19 | |
| 18 | 20 | reg: |
| 19 | 21 | items: |
| @@ -29,6 +29,16 @@ properties: · 28 unmodified lines | ||
| 29 | 29 | iommus: |
| 30 | 30 | maxItems: 2 |
| 31 | 31 | |
| 32 | + interconnects: | |
| 33 | + items: | |
| 34 | + - description: Interconnect path from mdp0 port to the data bus | |
| 35 | + - description: Interconnect path from CPU to the reg bus | |
| 36 | + | |
| 37 | + interconnect-names: | |
| 38 | + items: | |
| 39 | + - const: mdp0-mem | |
| 40 | + - const: cpu-cfg | |
| 41 | + | |
| 32 | 42 | patternProperties: |
| 33 | 43 | "^display-controller@[0-9a-f]+$": |
| 34 | 44 | type: object |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | ||
| 35 | 35 | maxItems: 1 |
| 36 | 36 | |
| 37 | 37 | interconnects: |
| 38 | − maxItems: 2 | |
| 38 | + items: | |
| 39 | + - description: Interconnect path from mdp0 port to the data bus | |
| 40 | + - description: Interconnect path from CPU to the reg bus | |
| 39 | 41 | |
| 40 | 42 | interconnect-names: |
| 41 | − maxItems: 2 | |
| 43 | + items: | |
| 44 | + - const: mdp0-mem | |
| 45 | + - const: cpu-cfg | |
| 42 | 46 | |
| 43 | 47 | patternProperties: |
| 44 | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | ||
| 35 | 35 | maxItems: 1 |
| 36 | 36 | |
| 37 | 37 | interconnects: |
| 38 | − maxItems: 2 | |
| 38 | + items: | |
| 39 | + - description: Interconnect path from mdp0 port to the data bus | |
| 40 | + - description: Interconnect path from CPU to the reg bus | |
| 39 | 41 | |
| 40 | 42 | interconnect-names: |
| 41 | − maxItems: 2 | |
| 43 | + items: | |
| 44 | + - const: mdp0-mem | |
| 45 | + - const: cpu-cfg | |
| 42 | 46 | |
| 43 | 47 | patternProperties: |
| 44 | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | ||
| 35 | 35 | maxItems: 1 |
| 36 | 36 | |
| 37 | 37 | interconnects: |
| 38 | − maxItems: 2 | |
| 38 | + items: | |
| 39 | + - description: Interconnect path from mdp0 port to the data bus | |
| 40 | + - description: Interconnect path from CPU to the reg bus | |
| 39 | 41 | |
| 40 | 42 | interconnect-names: |
| 41 | − maxItems: 2 | |
| 43 | + items: | |
| 44 | + - const: mdp0-mem | |
| 45 | + - const: cpu-cfg | |
| 42 | 46 | |
| 43 | 47 | patternProperties: |
| 44 | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -69,7 +69,7 @@ patternProperties: · 68 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | properties: |
| 71 | 71 | compatible: |
| 72 | − const: qcom,dsi-phy-7nm | |
| 72 | + const: qcom,dsi-phy-7nm-8150 | |
| 73 | 73 | |
| 74 | 74 | unevaluatedProperties: false |
| 75 | 75 | |
| @@ -247,7 +247,7 @@ examples: · 171 unmodified lines | ||
| 247 | 247 | }; |
| 248 | 248 | |
| 249 | 249 | dsi0_phy: phy@ae94400 { |
| 250 | − compatible = "qcom,dsi-phy-7nm"; | |
| 250 | + compatible = "qcom,dsi-phy-7nm-8150"; | |
| 251 | 251 | reg = <0x0ae94400 0x200>, |
| 252 | 252 | <0x0ae94600 0x280>, |
| 253 | 253 | <0x0ae94900 0x260>; |
| @@ -318,7 +318,7 @@ examples: · 64 unmodified lines | ||
| 318 | 318 | }; |
| 319 | 319 | |
| 320 | 320 | dsi1_phy: phy@ae96400 { |
| 321 | − compatible = "qcom,dsi-phy-7nm"; | |
| 321 | + compatible = "qcom,dsi-phy-7nm-8150"; | |
| 322 | 322 | reg = <0x0ae96400 0x200>, |
| 323 | 323 | <0x0ae96600 0x280>, |
| 324 | 324 | <0x0ae96900 0x260>; |
| @@ -52,6 +52,16 @@ patternProperties: · 51 unmodified lines | ||
| 52 | 52 | compatible: |
| 53 | 53 | const: qcom,sm8250-dpu |
| 54 | 54 | |
| 55 | + "^displayport-controller@[0-9a-f]+$": | |
| 56 | + type: object | |
| 57 | + additionalProperties: true | |
| 58 | + | |
| 59 | + properties: | |
| 60 | + compatible: | |
| 61 | + items: | |
| 62 | + - const: qcom,sm8250-dp | |
| 63 | + - const: qcom,sm8350-dp | |
| 64 | + | |
| 55 | 65 | "^dsi@[0-9a-f]+$": |
| 56 | 66 | type: object |
| 57 | 67 | additionalProperties: true |
| @@ -30,10 +30,10 @@ properties: · 29 unmodified lines | ||
| 30 | 30 | maxItems: 1 |
| 31 | 31 | |
| 32 | 32 | interconnects: |
| 33 | − maxItems: 2 | |
| 33 | + maxItems: 3 | |
| 34 | 34 | |
| 35 | 35 | interconnect-names: |
| 36 | − maxItems: 2 | |
| 36 | + maxItems: 3 | |
| 37 | 37 | |
| 38 | 38 | patternProperties: |
| 39 | 39 | "^display-controller@[0-9a-f]+$": |
| @@ -91,9 +91,12 @@ examples: · 51 unmodified lines | ||
| 91 | 91 | reg = <0x0ae00000 0x1000>; |
| 92 | 92 | reg-names = "mdss"; |
| 93 | 93 | |
| 94 | − interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>, | |
| 95 | − <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>; | |
| 96 | − interconnect-names = "mdp0-mem", "mdp1-mem"; | |
| 94 | + interconnects = <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>, | |
| 95 | + <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>, | |
| 96 | + <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; | |
| 97 | + interconnect-names = "mdp0-mem", | |
| 98 | + "mdp1-mem", | |
| 99 | + "cpu-cfg"; | |
| 97 | 100 | |
| 98 | 101 | resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; |
| 99 | 102 | |
| @@ -0,0 +1,127 @@ | ||
| 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/qcom,sm8650-dpu.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Qualcomm SM8650 Display DPU | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Neil Armstrong <neil.armstrong@linaro.org> | |
| 11 | + | |
| 12 | +$ref: /schemas/display/msm/dpu-common.yaml# | |
| 13 | + | |
| 14 | +properties: | |
| 15 | + compatible: | |
| 16 | + const: qcom,sm8650-dpu | |
| 17 | + | |
| 18 | + reg: | |
| 19 | + items: | |
| 20 | + - description: Address offset and size for mdp register set | |
| 21 | + - description: Address offset and size for vbif register set | |
| 22 | + | |
| 23 | + reg-names: | |
| 24 | + items: | |
| 25 | + - const: mdp | |
| 26 | + - const: vbif | |
| 27 | + | |
| 28 | + clocks: | |
| 29 | + items: | |
| 30 | + - description: Display hf axi | |
| 31 | + - description: Display MDSS ahb | |
| 32 | + - description: Display lut | |
| 33 | + - description: Display core | |
| 34 | + - description: Display vsync | |
| 35 | + | |
| 36 | + clock-names: | |
| 37 | + items: | |
| 38 | + - const: nrt_bus | |
| 39 | + - const: iface | |
| 40 | + - const: lut | |
| 41 | + - const: core | |
| 42 | + - const: vsync | |
| 43 | + | |
| 44 | +required: | |
| 45 | + - compatible | |
| 46 | + - reg | |
| 47 | + - reg-names | |
| 48 | + - clocks | |
| 49 | + - clock-names | |
| 50 | + | |
| 51 | +unevaluatedProperties: false | |
| 52 | + | |
| 53 | +examples: | |
| 54 | + - | | |
| 55 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 56 | + #include <dt-bindings/power/qcom,rpmhpd.h> | |
| 57 | + | |
| 58 | + display-controller@ae01000 { | |
| 59 | + compatible = "qcom,sm8650-dpu"; | |
| 60 | + reg = <0x0ae01000 0x8f000>, | |
| 61 | + <0x0aeb0000 0x2008>; | |
| 62 | + reg-names = "mdp", "vbif"; | |
| 63 | + | |
| 64 | + clocks = <&gcc_axi_clk>, | |
| 65 | + <&dispcc_ahb_clk>, | |
| 66 | + <&dispcc_mdp_lut_clk>, | |
| 67 | + <&dispcc_mdp_clk>, | |
| 68 | + <&dispcc_vsync_clk>; | |
| 69 | + clock-names = "nrt_bus", | |
| 70 | + "iface", | |
| 71 | + "lut", | |
| 72 | + "core", | |
| 73 | + "vsync"; | |
| 74 | + | |
| 75 | + assigned-clocks = <&dispcc_vsync_clk>; | |
| 76 | + assigned-clock-rates = <19200000>; | |
| 77 | + | |
| 78 | + operating-points-v2 = <&mdp_opp_table>; | |
| 79 | + power-domains = <&rpmhpd RPMHPD_MMCX>; | |
| 80 | + | |
| 81 | + interrupt-parent = <&mdss>; | |
| 82 | + interrupts = <0>; | |
| 83 | + | |
| 84 | + ports { | |
| 85 | + #address-cells = <1>; | |
| 86 | + #size-cells = <0>; | |
| 87 | + | |
| 88 | + port@0 { | |
| 89 | + reg = <0>; | |
| 90 | + dpu_intf1_out: endpoint { | |
| 91 | + remote-endpoint = <&dsi0_in>; | |
| 92 | + }; | |
| 93 | + }; | |
| 94 | + | |
| 95 | + port@1 { | |
| 96 | + reg = <1>; | |
| 97 | + dpu_intf2_out: endpoint { | |
| 98 | + remote-endpoint = <&dsi1_in>; | |
| 99 | + }; | |
| 100 | + }; | |
| 101 | + }; | |
| 102 | + | |
| 103 | + mdp_opp_table: opp-table { | |
| 104 | + compatible = "operating-points-v2"; | |
| 105 | + | |
| 106 | + opp-200000000 { | |
| 107 | + opp-hz = /bits/ 64 <200000000>; | |
| 108 | + required-opps = <&rpmhpd_opp_low_svs>; | |
| 109 | + }; | |
| 110 | + | |
| 111 | + opp-325000000 { | |
| 112 | + opp-hz = /bits/ 64 <325000000>; | |
| 113 | + required-opps = <&rpmhpd_opp_svs>; | |
| 114 | + }; | |
| 115 | + | |
| 116 | + opp-375000000 { | |
| 117 | + opp-hz = /bits/ 64 <375000000>; | |
| 118 | + required-opps = <&rpmhpd_opp_svs_l1>; | |
| 119 | + }; | |
| 120 | + | |
| 121 | + opp-514000000 { | |
| 122 | + opp-hz = /bits/ 64 <514000000>; | |
| 123 | + required-opps = <&rpmhpd_opp_nom>; | |
| 124 | + }; | |
| 125 | + }; | |
| 126 | + }; | |
| 127 | +... | |
| @@ -0,0 +1,328 @@ | ||
| 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/qcom,sm8650-mdss.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Qualcomm SM8650 Display MDSS | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Neil Armstrong <neil.armstrong@linaro.org> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + SM8650 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like | |
| 14 | + DPU display controller, DSI and DP interfaces etc. | |
| 15 | + | |
| 16 | +$ref: /schemas/display/msm/mdss-common.yaml# | |
| 17 | + | |
| 18 | +properties: | |
| 19 | + compatible: | |
| 20 | + const: qcom,sm8650-mdss | |
| 21 | + | |
| 22 | + clocks: | |
| 23 | + items: | |
| 24 | + - description: Display AHB | |
| 25 | + - description: Display hf AXI | |
| 26 | + - description: Display core | |
| 27 | + | |
| 28 | + iommus: | |
| 29 | + maxItems: 1 | |
| 30 | + | |
| 31 | + interconnects: | |
| 32 | + maxItems: 2 | |
| 33 | + | |
| 34 | + interconnect-names: | |
| 35 | + maxItems: 2 | |
| 36 | + | |
| 37 | +patternProperties: | |
| 38 | + "^display-controller@[0-9a-f]+$": | |
| 39 | + type: object | |
| 40 | + properties: | |
| 41 | + compatible: | |
| 42 | + const: qcom,sm8650-dpu | |
| 43 | + | |
| 44 | + "^displayport-controller@[0-9a-f]+$": | |
| 45 | + type: object | |
| 46 | + properties: | |
| 47 | + compatible: | |
| 48 | + const: qcom,sm8650-dp | |
| 49 | + | |
| 50 | + "^dsi@[0-9a-f]+$": | |
| 51 | + type: object | |
| 52 | + properties: | |
| 53 | + compatible: | |
| 54 | + items: | |
| 55 | + - const: qcom,sm8650-dsi-ctrl | |
| 56 | + - const: qcom,mdss-dsi-ctrl | |
| 57 | + | |
| 58 | + "^phy@[0-9a-f]+$": | |
| 59 | + type: object | |
| 60 | + properties: | |
| 61 | + compatible: | |
| 62 | + const: qcom,sm8650-dsi-phy-4nm | |
| 63 | + | |
| 64 | +required: | |
| 65 | + - compatible | |
| 66 | + | |
| 67 | +unevaluatedProperties: false | |
| 68 | + | |
| 69 | +examples: | |
| 70 | + - | | |
| 71 | + #include <dt-bindings/clock/qcom,rpmh.h> | |
| 72 | + #include <dt-bindings/interrupt-controller/arm-gic.h> | |
| 73 | + #include <dt-bindings/power/qcom,rpmhpd.h> | |
| 74 | + | |
| 75 | + display-subsystem@ae00000 { | |
| 76 | + compatible = "qcom,sm8650-mdss"; | |
| 77 | + reg = <0x0ae00000 0x1000>; | |
| 78 | + reg-names = "mdss"; | |
| 79 | + | |
| 80 | + resets = <&dispcc_core_bcr>; | |
| 81 | + | |
| 82 | + power-domains = <&dispcc_gdsc>; | |
| 83 | + | |
| 84 | + clocks = <&gcc_ahb_clk>, | |
| 85 | + <&gcc_axi_clk>, | |
| 86 | + <&dispcc_mdp_clk>; | |
| 87 | + clock-names = "bus", "nrt_bus", "core"; | |
| 88 | + | |
| 89 | + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; | |
| 90 | + interrupt-controller; | |
| 91 | + #interrupt-cells = <1>; | |
| 92 | + | |
| 93 | + iommus = <&apps_smmu 0x1c00 0x2>; | |
| 94 | + | |
| 95 | + #address-cells = <1>; | |
| 96 | + #size-cells = <1>; | |
| 97 | + ranges; | |
| 98 | + | |
| 99 | + display-controller@ae01000 { | |
| 100 | + compatible = "qcom,sm8650-dpu"; | |
| 101 | + reg = <0x0ae01000 0x8f000>, | |
| 102 | + <0x0aeb0000 0x2008>; | |
| 103 | + reg-names = "mdp", "vbif"; | |
| 104 | + | |
| 105 | + clocks = <&gcc_axi_clk>, | |
| 106 | + <&dispcc_ahb_clk>, | |
| 107 | + <&dispcc_mdp_lut_clk>, | |
| 108 | + <&dispcc_mdp_clk>, | |
| 109 | + <&dispcc_mdp_vsync_clk>; | |
| 110 | + clock-names = "nrt_bus", | |
| 111 | + "iface", | |
| 112 | + "lut", | |
| 113 | + "core", | |
| 114 | + "vsync"; | |
| 115 | + | |
| 116 | + assigned-clocks = <&dispcc_mdp_vsync_clk>; | |
| 117 | + assigned-clock-rates = <19200000>; | |
| 118 | + | |
| 119 | + operating-points-v2 = <&mdp_opp_table>; | |
| 120 | + power-domains = <&rpmhpd RPMHPD_MMCX>; | |
| 121 | + | |
| 122 | + interrupt-parent = <&mdss>; | |
| 123 | + interrupts = <0>; | |
| 124 | + | |
| 125 | + ports { | |
| 126 | + #address-cells = <1>; | |
| 127 | + #size-cells = <0>; | |
| 128 | + | |
| 129 | + port@0 { | |
| 130 | + reg = <0>; | |
| 131 | + dpu_intf1_out: endpoint { | |
| 132 | + remote-endpoint = <&dsi0_in>; | |
| 133 | + }; | |
| 134 | + }; | |
| 135 | + | |
| 136 | + port@1 { | |
| 137 | + reg = <1>; | |
| 138 | + dpu_intf2_out: endpoint { | |
| 139 | + remote-endpoint = <&dsi1_in>; | |
| 140 | + }; | |
| 141 | + }; | |
| 142 | + }; | |
| 143 | + | |
| 144 | + mdp_opp_table: opp-table { | |
| 145 | + compatible = "operating-points-v2"; | |
| 146 | + | |
| 147 | + opp-200000000 { | |
| 148 | + opp-hz = /bits/ 64 <200000000>; | |
| 149 | + required-opps = <&rpmhpd_opp_low_svs>; | |
| 150 | + }; | |
| 151 | + | |
| 152 | + opp-325000000 { | |
| 153 | + opp-hz = /bits/ 64 <325000000>; | |
| 154 | + required-opps = <&rpmhpd_opp_svs>; | |
| 155 | + }; | |
| 156 | + | |
| 157 | + opp-375000000 { | |
| 158 | + opp-hz = /bits/ 64 <375000000>; | |
| 159 | + required-opps = <&rpmhpd_opp_svs_l1>; | |
| 160 | + }; | |
| 161 | + | |
| 162 | + opp-514000000 { | |
| 163 | + opp-hz = /bits/ 64 <514000000>; | |
| 164 | + required-opps = <&rpmhpd_opp_nom>; | |
| 165 | + }; | |
| 166 | + }; | |
| 167 | + }; | |
| 168 | + | |
| 169 | + dsi@ae94000 { | |
| 170 | + compatible = "qcom,sm8650-dsi-ctrl", "qcom,mdss-dsi-ctrl"; | |
| 171 | + reg = <0x0ae94000 0x400>; | |
| 172 | + reg-names = "dsi_ctrl"; | |
| 173 | + | |
| 174 | + interrupt-parent = <&mdss>; | |
| 175 | + interrupts = <4>; | |
| 176 | + | |
| 177 | + clocks = <&dispc_byte_clk>, | |
| 178 | + <&dispcc_intf_clk>, | |
| 179 | + <&dispcc_pclk>, | |
| 180 | + <&dispcc_esc_clk>, | |
| 181 | + <&dispcc_ahb_clk>, | |
| 182 | + <&gcc_bus_clk>; | |
| 183 | + clock-names = "byte", | |
| 184 | + "byte_intf", | |
| 185 | + "pixel", | |
| 186 | + "core", | |
| 187 | + "iface", | |
| 188 | + "bus"; | |
| 189 | + | |
| 190 | + assigned-clocks = <&dispcc_byte_clk>, | |
| 191 | + <&dispcc_pclk>; | |
| 192 | + assigned-clock-parents = <&dsi0_phy 0>, <&dsi0_phy 1>; | |
| 193 | + | |
| 194 | + operating-points-v2 = <&dsi_opp_table>; | |
| 195 | + power-domains = <&rpmhpd RPMHPD_MMCX>; | |
| 196 | + | |
| 197 | + phys = <&dsi0_phy>; | |
| 198 | + phy-names = "dsi"; | |
| 199 | + | |
| 200 | + #address-cells = <1>; | |
| 201 | + #size-cells = <0>; | |
| 202 | + | |
| 203 | + ports { | |
| 204 | + #address-cells = <1>; | |
| 205 | + #size-cells = <0>; | |
| 206 | + | |
| 207 | + port@0 { | |
| 208 | + reg = <0>; | |
| 209 | + dsi0_in: endpoint { | |
| 210 | + remote-endpoint = <&dpu_intf1_out>; | |
| 211 | + }; | |
| 212 | + }; | |
| 213 | + | |
| 214 | + port@1 { | |
| 215 | + reg = <1>; | |
| 216 | + dsi0_out: endpoint { | |
| 217 | + }; | |
| 218 | + }; | |
| 219 | + }; | |
| 220 | + | |
| 221 | + dsi_opp_table: opp-table { | |
| 222 | + compatible = "operating-points-v2"; | |
| 223 | + | |
| 224 | + opp-187500000 { | |
| 225 | + opp-hz = /bits/ 64 <187500000>; | |
| 226 | + required-opps = <&rpmhpd_opp_low_svs>; | |
| 227 | + }; | |
| 228 | + | |
| 229 | + opp-300000000 { | |
| 230 | + opp-hz = /bits/ 64 <300000000>; | |
| 231 | + required-opps = <&rpmhpd_opp_svs>; | |
| 232 | + }; | |
| 233 | + | |
| 234 | + opp-358000000 { | |
| 235 | + opp-hz = /bits/ 64 <358000000>; | |
| 236 | + required-opps = <&rpmhpd_opp_svs_l1>; | |
| 237 | + }; | |
| 238 | + }; | |
| 239 | + }; | |
| 240 | + | |
| 241 | + dsi0_phy: phy@ae94400 { | |
| 242 | + compatible = "qcom,sm8650-dsi-phy-4nm"; | |
| 243 | + reg = <0x0ae95000 0x200>, | |
| 244 | + <0x0ae95200 0x280>, | |
| 245 | + <0x0ae95500 0x400>; | |
| 246 | + reg-names = "dsi_phy", | |
| 247 | + "dsi_phy_lane", | |
| 248 | + "dsi_pll"; | |
| 249 | + | |
| 250 | + #clock-cells = <1>; | |
| 251 | + #phy-cells = <0>; | |
| 252 | + | |
| 253 | + clocks = <&dispcc_iface_clk>, | |
| 254 | + <&rpmhcc_ref_clk>; | |
| 255 | + clock-names = "iface", "ref"; | |
| 256 | + }; | |
| 257 | + | |
| 258 | + dsi@ae96000 { | |
| 259 | + compatible = "qcom,sm8650-dsi-ctrl", "qcom,mdss-dsi-ctrl"; | |
| 260 | + reg = <0x0ae96000 0x400>; | |
| 261 | + reg-names = "dsi_ctrl"; | |
| 262 | + | |
| 263 | + interrupt-parent = <&mdss>; | |
| 264 | + interrupts = <5>; | |
| 265 | + | |
| 266 | + clocks = <&dispc_byte_clk>, | |
| 267 | + <&dispcc_intf_clk>, | |
| 268 | + <&dispcc_pclk>, | |
| 269 | + <&dispcc_esc_clk>, | |
| 270 | + <&dispcc_ahb_clk>, | |
| 271 | + <&gcc_bus_clk>; | |
| 272 | + clock-names = "byte", | |
| 273 | + "byte_intf", | |
| 274 | + "pixel", | |
| 275 | + "core", | |
| 276 | + "iface", | |
| 277 | + "bus"; | |
| 278 | + | |
| 279 | + assigned-clocks = <&dispcc_byte_clk>, | |
| 280 | + <&dispcc_pclk>; | |
| 281 | + assigned-clock-parents = <&dsi1_phy 0>, <&dsi1_phy 1>; | |
| 282 | + | |
| 283 | + operating-points-v2 = <&dsi_opp_table>; | |
| 284 | + power-domains = <&rpmhpd RPMHPD_MMCX>; | |
| 285 | + | |
| 286 | + phys = <&dsi1_phy>; | |
| 287 | + phy-names = "dsi"; | |
| 288 | + | |
| 289 | + #address-cells = <1>; | |
| 290 | + #size-cells = <0>; | |
| 291 | + | |
| 292 | + ports { | |
| 293 | + #address-cells = <1>; | |
| 294 | + #size-cells = <0>; | |
| 295 | + | |
| 296 | + port@0 { | |
| 297 | + reg = <0>; | |
| 298 | + dsi1_in: endpoint { | |
| 299 | + remote-endpoint = <&dpu_intf2_out>; | |
| 300 | + }; | |
| 301 | + }; | |
| 302 | + | |
| 303 | + port@1 { | |
| 304 | + reg = <1>; | |
| 305 | + dsi1_out: endpoint { | |
| 306 | + }; | |
| 307 | + }; | |
| 308 | + }; | |
| 309 | + }; | |
| 310 | + | |
| 311 | + dsi1_phy: phy@ae96400 { | |
| 312 | + compatible = "qcom,sm8650-dsi-phy-4nm"; | |
| 313 | + reg = <0x0ae97000 0x200>, | |
| 314 | + <0x0ae97200 0x280>, | |
| 315 | + <0x0ae97500 0x400>; | |
| 316 | + reg-names = "dsi_phy", | |
| 317 | + "dsi_phy_lane", | |
| 318 | + "dsi_pll"; | |
| 319 | + | |
| 320 | + #clock-cells = <1>; | |
| 321 | + #phy-cells = <0>; | |
| 322 | + | |
| 323 | + clocks = <&dispcc_iface_clk>, | |
| 324 | + <&rpmhcc_ref_clk>; | |
| 325 | + clock-names = "iface", "ref"; | |
| 326 | + }; | |
| 327 | + }; | |
| 328 | +... | |
| @@ -1147,7 +1147,7 @@ static int reserve_bo_and_vm(struct kgd_mem *mem, · 1146 unmodified lines | ||
| 1147 | 1147 | |
| 1148 | 1148 | ctx->n_vms = 1; |
| 1149 | 1149 | ctx->sync = &mem->sync; |
| 1150 | − drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 1150 | + drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 1151 | 1151 | drm_exec_until_all_locked(&ctx->exec) { |
| 1152 | 1152 | ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2); |
| 1153 | 1153 | drm_exec_retry_on_contention(&ctx->exec); |
| @@ -1186,7 +1186,7 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem, · 32 unmodified lines | ||
| 1186 | 1186 | int ret; |
| 1187 | 1187 | |
| 1188 | 1188 | ctx->sync = &mem->sync; |
| 1189 | − drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 1189 | + drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 1190 | 1190 | drm_exec_until_all_locked(&ctx->exec) { |
| 1191 | 1191 | ctx->n_vms = 0; |
| 1192 | 1192 | list_for_each_entry(entry, &mem->attachments, list) { |
| @@ -2595,7 +2595,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info) · 1402 unmodified lines | ||
| 2595 | 2595 | |
| 2596 | 2596 | amdgpu_sync_create(&sync); |
| 2597 | 2597 | |
| 2598 | − drm_exec_init(&exec, 0); | |
| 2598 | + drm_exec_init(&exec, 0, 0); | |
| 2599 | 2599 | /* Reserve all BOs and page tables for validation */ |
| 2600 | 2600 | drm_exec_until_all_locked(&exec) { |
| 2601 | 2601 | /* Reserve all the page directories */ |
| @@ -2853,7 +2853,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef) · 251 unmodified lines | ||
| 2853 | 2853 | |
| 2854 | 2854 | mutex_lock(&process_info->lock); |
| 2855 | 2855 | |
| 2856 | − drm_exec_init(&exec, 0); | |
| 2856 | + drm_exec_init(&exec, 0, 0); | |
| 2857 | 2857 | drm_exec_until_all_locked(&exec) { |
| 2858 | 2858 | list_for_each_entry(peer_vm, &process_info->vm_list_head, |
| 2859 | 2859 | vm_list_node) { |
| @@ -66,7 +66,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | amdgpu_sync_create(&p->sync); |
| 68 | 68 | drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT | |
| 69 | − DRM_EXEC_IGNORE_DUPLICATES); | |
| 69 | + DRM_EXEC_IGNORE_DUPLICATES, 0); | |
| 70 | 70 | return 0; |
| 71 | 71 | } |
| 72 | 72 | |
| @@ -70,7 +70,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 69 unmodified lines | ||
| 70 | 70 | struct drm_exec exec; |
| 71 | 71 | int r; |
| 72 | 72 | |
| 73 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 73 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 74 | 74 | drm_exec_until_all_locked(&exec) { |
| 75 | 75 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 76 | 76 | if (likely(!r)) |
| @@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 33 unmodified lines | ||
| 110 | 110 | struct drm_exec exec; |
| 111 | 111 | int r; |
| 112 | 112 | |
| 113 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 113 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 114 | 114 | drm_exec_until_all_locked(&exec) { |
| 115 | 115 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 116 | 116 | if (likely(!r)) |
| @@ -203,7 +203,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj, · 202 unmodified lines | ||
| 203 | 203 | struct drm_exec exec; |
| 204 | 204 | long r; |
| 205 | 205 | |
| 206 | − drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES); | |
| 206 | + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); | |
| 207 | 207 | drm_exec_until_all_locked(&exec) { |
| 208 | 208 | r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1); |
| 209 | 209 | drm_exec_retry_on_contention(&exec); |
| @@ -739,7 +739,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, · 529 unmodified lines | ||
| 739 | 739 | } |
| 740 | 740 | |
| 741 | 741 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | |
| 742 | − DRM_EXEC_IGNORE_DUPLICATES); | |
| 742 | + DRM_EXEC_IGNORE_DUPLICATES, 0); | |
| 743 | 743 | drm_exec_until_all_locked(&exec) { |
| 744 | 744 | if (gobj) { |
| 745 | 745 | r = drm_exec_lock_obj(&exec, gobj); |
| @@ -1183,7 +1183,7 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev, · 1182 unmodified lines | ||
| 1183 | 1183 | |
| 1184 | 1184 | amdgpu_sync_create(&sync); |
| 1185 | 1185 | |
| 1186 | − drm_exec_init(&exec, 0); | |
| 1186 | + drm_exec_init(&exec, 0, 0); | |
| 1187 | 1187 | drm_exec_until_all_locked(&exec) { |
| 1188 | 1188 | r = drm_exec_lock_obj(&exec, |
| 1189 | 1189 | &ctx_data->meta_data_obj->tbo.base); |
| @@ -1254,7 +1254,7 @@ int amdgpu_mes_ctx_unmap_meta_data(struct amdgpu_device *adev, · 64 unmodified lines | ||
| 1254 | 1254 | struct drm_exec exec; |
| 1255 | 1255 | long r; |
| 1256 | 1256 | |
| 1257 | − drm_exec_init(&exec, 0); | |
| 1257 | + drm_exec_init(&exec, 0, 0); | |
| 1258 | 1258 | drm_exec_until_all_locked(&exec) { |
| 1259 | 1259 | r = drm_exec_lock_obj(&exec, |
| 1260 | 1260 | &ctx_data->meta_data_obj->tbo.base); |
| @@ -61,7 +61,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 60 unmodified lines | ||
| 61 | 61 | if (!bo) |
| 62 | 62 | return -EINVAL; |
| 63 | 63 | |
| 64 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 64 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 65 | 65 | drm_exec_until_all_locked(&exec) { |
| 66 | 66 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 67 | 67 | if (likely(!r)) |
| @@ -122,7 +122,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv) · 54 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | vm = &fpriv->vm; |
| 124 | 124 | |
| 125 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 125 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 126 | 126 | drm_exec_until_all_locked(&exec) { |
| 127 | 127 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 128 | 128 | if (likely(!r)) |
| @@ -86,7 +86,7 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | amdgpu_sync_create(&sync); |
| 88 | 88 | |
| 89 | − drm_exec_init(&exec, 0); | |
| 89 | + drm_exec_init(&exec, 0, 0); | |
| 90 | 90 | drm_exec_until_all_locked(&exec) { |
| 91 | 91 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); |
| 92 | 92 | drm_exec_retry_on_contention(&exec); |
| @@ -149,7 +149,7 @@ static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 56 unmodified lines | ||
| 149 | 149 | struct drm_exec exec; |
| 150 | 150 | long r; |
| 151 | 151 | |
| 152 | − drm_exec_init(&exec, 0); | |
| 152 | + drm_exec_init(&exec, 0, 0); | |
| 153 | 153 | drm_exec_until_all_locked(&exec) { |
| 154 | 154 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); |
| 155 | 155 | drm_exec_retry_on_contention(&exec); |
| @@ -1481,7 +1481,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr) · 1480 unmodified lines | ||
| 1481 | 1481 | uint32_t gpuidx; |
| 1482 | 1482 | int r; |
| 1483 | 1483 | |
| 1484 | − drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0); | |
| 1484 | + drm_exec_init(&ctx->exec, intr ? DRM_EXEC_INTERRUPTIBLE_WAIT: 0, 0); | |
| 1485 | 1485 | drm_exec_until_all_locked(&ctx->exec) { |
| 1486 | 1486 | for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) { |
| 1487 | 1487 | pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx); |
| @@ -58,6 +58,9 @@ git config --global user.email "fdo@example.com" · 57 unmodified lines | ||
| 58 | 58 | git config --global user.name "freedesktop.org CI" |
| 59 | 59 | git config --global pull.rebase true |
| 60 | 60 | |
| 61 | +# cleanup git state on the worker | |
| 62 | +rm -rf .git/rebase-merge | |
| 63 | + | |
| 61 | 64 | # Try to merge fixes from target repo |
| 62 | 65 | if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes)" ]; then |
| 63 | 66 | git pull ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes |
| @@ -69,16 +69,23 @@ static void drm_exec_unlock_all(struct drm_exec *exec) · 68 unmodified lines | ||
| 69 | 69 | * drm_exec_init - initialize a drm_exec object |
| 70 | 70 | * @exec: the drm_exec object to initialize |
| 71 | 71 | * @flags: controls locking behavior, see DRM_EXEC_* defines |
| 72 | + * @nr: the initial # of objects | |
| 72 | 73 | * |
| 73 | 74 | * Initialize the object and make sure that we can track locked objects. |
| 75 | + * | |
| 76 | + * If nr is non-zero then it is used as the initial objects table size. | |
| 77 | + * In either case, the table will grow (be re-allocated) on demand. | |
| 74 | 78 | */ |
| 75 | −void drm_exec_init(struct drm_exec *exec, uint32_t flags) | |
| 79 | +void drm_exec_init(struct drm_exec *exec, uint32_t flags, unsigned nr) | |
| 76 | 80 | { |
| 81 | + if (!nr) | |
| 82 | + nr = PAGE_SIZE / sizeof(void *); | |
| 83 | + | |
| 77 | 84 | exec->flags = flags; |
| 78 | − exec->objects = kmalloc(PAGE_SIZE, GFP_KERNEL); | |
| 85 | + exec->objects = kvmalloc_array(nr, sizeof(void *), GFP_KERNEL); | |
| 79 | 86 | |
| 80 | 87 | /* If allocation here fails, just delay that till the first use */ |
| 81 | − exec->max_objects = exec->objects ? PAGE_SIZE / sizeof(void *) : 0; | |
| 88 | + exec->max_objects = exec->objects ? nr : 0; | |
| 82 | 89 | exec->num_objects = 0; |
| 83 | 90 | exec->contended = DRM_EXEC_DUMMY; |
| 84 | 91 | exec->prelocked = NULL; |
| @@ -1250,7 +1250,7 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec) · 1249 unmodified lines | ||
| 1250 | 1250 | unsigned int num_fences = vm_exec->num_fences; |
| 1251 | 1251 | int ret; |
| 1252 | 1252 | |
| 1253 | − drm_exec_init(exec, vm_exec->flags); | |
| 1253 | + drm_exec_init(exec, vm_exec->flags, 0); | |
| 1254 | 1254 | |
| 1255 | 1255 | drm_exec_until_all_locked(exec) { |
| 1256 | 1256 | ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences); |
| @@ -1341,7 +1341,7 @@ drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec, · 84 unmodified lines | ||
| 1341 | 1341 | struct drm_exec *exec = &vm_exec->exec; |
| 1342 | 1342 | int ret; |
| 1343 | 1343 | |
| 1344 | − drm_exec_init(exec, vm_exec->flags); | |
| 1344 | + drm_exec_init(exec, vm_exec->flags, 0); | |
| 1345 | 1345 | |
| 1346 | 1346 | drm_exec_until_all_locked(exec) { |
| 1347 | 1347 | ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range, |
| @@ -746,7 +746,7 @@ pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file, · 745 unmodified lines | ||
| 746 | 746 | if (err) |
| 747 | 747 | goto out_job_data_cleanup; |
| 748 | 748 | |
| 749 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES); | |
| 749 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | DRM_EXEC_IGNORE_DUPLICATES, 0); | |
| 750 | 750 | |
| 751 | 751 | xa_init_flags(&signal_array, XA_FLAGS_ALLOC); |
| 752 | 752 | |
| @@ -6,6 +6,7 @@ config DRM_MSM · 5 unmodified lines | ||
| 6 | 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST |
| 7 | 7 | depends on COMMON_CLK |
| 8 | 8 | depends on IOMMU_SUPPORT |
| 9 | + depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | |
| 9 | 10 | depends on QCOM_OCMEM || QCOM_OCMEM=n |
| 10 | 11 | depends on QCOM_LLCC || QCOM_LLCC=n |
| 11 | 12 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n |
| @@ -16,6 +17,7 @@ config DRM_MSM · 4 unmodified lines | ||
| 16 | 17 | select DRM_DP_AUX_BUS |
| 17 | 18 | select DRM_DISPLAY_DP_HELPER |
| 18 | 19 | select DRM_DISPLAY_HELPER |
| 20 | + select DRM_EXEC | |
| 19 | 21 | select DRM_KMS_HELPER |
| 20 | 22 | select DRM_PANEL |
| 21 | 23 | select DRM_BRIDGE |
| @@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ · 62 unmodified lines | ||
| 63 | 63 | disp/dpu1/dpu_encoder_phys_wb.o \ |
| 64 | 64 | disp/dpu1/dpu_formats.o \ |
| 65 | 65 | disp/dpu1/dpu_hw_catalog.o \ |
| 66 | + disp/dpu1/dpu_hw_cdm.o \ | |
| 66 | 67 | disp/dpu1/dpu_hw_ctl.o \ |
| 67 | 68 | disp/dpu1/dpu_hw_dsc.o \ |
| 68 | 69 | disp/dpu1/dpu_hw_dsc_1_2.o \ |
| @@ -684,7 +684,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu) · 683 unmodified lines | ||
| 684 | 684 | { |
| 685 | 685 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 686 | 686 | struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); |
| 687 | − u32 regbit; | |
| 687 | + u32 hbb; | |
| 688 | 688 | int ret; |
| 689 | 689 | |
| 690 | 690 | gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003); |
| @@ -820,18 +820,15 @@ static int a5xx_hw_init(struct msm_gpu *gpu) · 129 unmodified lines | ||
| 820 | 820 | |
| 821 | 821 | gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F); |
| 822 | 822 | |
| 823 | − /* Set the highest bank bit */ | |
| 824 | − if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu)) | |
| 825 | − regbit = 2; | |
| 826 | − else | |
| 827 | − regbit = 1; | |
| 823 | + BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13); | |
| 824 | + hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13; | |
| 828 | 825 | |
| 829 | − gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7); | |
| 830 | − gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1); | |
| 826 | + gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7); | |
| 827 | + gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1); | |
| 831 | 828 | |
| 832 | 829 | if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) || |
| 833 | 830 | adreno_is_a540(adreno_gpu)) |
| 834 | − gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, regbit); | |
| 831 | + gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, hbb); | |
| 835 | 832 | |
| 836 | 833 | /* Disable All flat shading optimization (ALLFLATOPTDIS) */ |
| 837 | 834 | gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10)); |
| @@ -1785,5 +1782,11 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) · 947 unmodified lines | ||
| 1785 | 1782 | /* Set up the preemption specific bits and pieces for each ringbuffer */ |
| 1786 | 1783 | a5xx_preempt_init(gpu); |
| 1787 | 1784 | |
| 1785 | + /* Set the highest bank bit */ | |
| 1786 | + if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu)) | |
| 1787 | + adreno_gpu->ubwc_config.highest_bank_bit = 15; | |
| 1788 | + else | |
| 1789 | + adreno_gpu->ubwc_config.highest_bank_bit = 14; | |
| 1790 | + | |
| 1788 | 1791 | return gpu; |
| 1789 | 1792 | } |
| @@ -1270,87 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) · 1269 unmodified lines | ||
| 1270 | 1270 | gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]); |
| 1271 | 1271 | } |
| 1272 | 1272 | |
| 1273 | −static void a6xx_set_ubwc_config(struct msm_gpu *gpu) | |
| 1273 | +static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu) | |
| 1274 | 1274 | { |
| 1275 | − struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | |
| 1276 | 1275 | /* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */ |
| 1277 | − u32 rgb565_predicator = 0; | |
| 1276 | + gpu->ubwc_config.rgb565_predicator = 0; | |
| 1278 | 1277 | /* Unknown, introduced with A650 family */ |
| 1279 | − u32 uavflagprd_inv = 0; | |
| 1278 | + gpu->ubwc_config.uavflagprd_inv = 0; | |
| 1280 | 1279 | /* Whether the minimum access length is 64 bits */ |
| 1281 | − u32 min_acc_len = 0; | |
| 1280 | + gpu->ubwc_config.min_acc_len = 0; | |
| 1282 | 1281 | /* Entirely magic, per-GPU-gen value */ |
| 1283 | − u32 ubwc_mode = 0; | |
| 1282 | + gpu->ubwc_config.ubwc_mode = 0; | |
| 1284 | 1283 | /* |
| 1285 | 1284 | * The Highest Bank Bit value represents the bit of the highest DDR bank. |
| 1286 | − * We then subtract 13 from it (13 is the minimum value allowed by hw) and | |
| 1287 | − * write the lowest two bits of the remaining value as hbb_lo and the | |
| 1288 | − * one above it as hbb_hi to the hardware. This should ideally use DRAM | |
| 1289 | − * type detection. | |
| 1285 | + * This should ideally use DRAM type detection. | |
| 1290 | 1286 | */ |
| 1291 | − u32 hbb_hi = 0; | |
| 1292 | − u32 hbb_lo = 2; | |
| 1293 | − /* Unknown, introduced with A640/680 */ | |
| 1294 | − u32 amsbc = 0; | |
| 1287 | + gpu->ubwc_config.highest_bank_bit = 15; | |
| 1295 | 1288 | |
| 1296 | − if (adreno_is_a610(adreno_gpu)) { | |
| 1297 | − /* HBB = 14 */ | |
| 1298 | − hbb_lo = 1; | |
| 1299 | − min_acc_len = 1; | |
| 1300 | − ubwc_mode = 1; | |
| 1289 | + if (adreno_is_a610(gpu)) { | |
| 1290 | + gpu->ubwc_config.highest_bank_bit = 14; | |
| 1291 | + gpu->ubwc_config.min_acc_len = 1; | |
| 1292 | + gpu->ubwc_config.ubwc_mode = 1; | |
| 1301 | 1293 | } |
| 1302 | 1294 | |
| 1303 | 1295 | /* a618 is using the hw default values */ |
| 1304 | − if (adreno_is_a618(adreno_gpu)) | |
| 1296 | + if (adreno_is_a618(gpu)) | |
| 1305 | 1297 | return; |
| 1306 | 1298 | |
| 1307 | − if (adreno_is_a619_holi(adreno_gpu)) | |
| 1308 | − hbb_lo = 0; | |
| 1299 | + if (adreno_is_a619_holi(gpu)) | |
| 1300 | + gpu->ubwc_config.highest_bank_bit = 13; | |
| 1309 | 1301 | |
| 1310 | − if (adreno_is_a640_family(adreno_gpu)) | |
| 1311 | − amsbc = 1; | |
| 1302 | + if (adreno_is_a640_family(gpu)) | |
| 1303 | + gpu->ubwc_config.amsbc = 1; | |
| 1312 | 1304 | |
| 1313 | − if (adreno_is_a650(adreno_gpu) || | |
| 1314 | − adreno_is_a660(adreno_gpu) || | |
| 1315 | − adreno_is_a730(adreno_gpu) || | |
| 1316 | − adreno_is_a740_family(adreno_gpu)) { | |
| 1305 | + if (adreno_is_a650(gpu) || | |
| 1306 | + adreno_is_a660(gpu) || | |
| 1307 | + adreno_is_a690(gpu) || | |
| 1308 | + adreno_is_a730(gpu) || | |
| 1309 | + adreno_is_a740_family(gpu)) { | |
| 1317 | 1310 | /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ |
| 1318 | − hbb_lo = 3; | |
| 1319 | − amsbc = 1; | |
| 1320 | − rgb565_predicator = 1; | |
| 1321 | − uavflagprd_inv = 2; | |
| 1311 | + gpu->ubwc_config.highest_bank_bit = 16; | |
| 1312 | + gpu->ubwc_config.amsbc = 1; | |
| 1313 | + gpu->ubwc_config.rgb565_predicator = 1; | |
| 1314 | + gpu->ubwc_config.uavflagprd_inv = 2; | |
| 1322 | 1315 | } |
| 1323 | 1316 | |
| 1324 | − if (adreno_is_a690(adreno_gpu)) { | |
| 1325 | − hbb_lo = 2; | |
| 1326 | − amsbc = 1; | |
| 1327 | − rgb565_predicator = 1; | |
| 1328 | − uavflagprd_inv = 2; | |
| 1317 | + if (adreno_is_7c3(gpu)) { | |
| 1318 | + gpu->ubwc_config.highest_bank_bit = 14; | |
| 1319 | + gpu->ubwc_config.amsbc = 1; | |
| 1320 | + gpu->ubwc_config.rgb565_predicator = 1; | |
| 1321 | + gpu->ubwc_config.uavflagprd_inv = 2; | |
| 1329 | 1322 | } |
| 1323 | +} | |
| 1330 | 1324 | |
| 1331 | − if (adreno_is_7c3(adreno_gpu)) { | |
| 1332 | − hbb_lo = 1; | |
| 1333 | − amsbc = 1; | |
| 1334 | − rgb565_predicator = 1; | |
| 1335 | − uavflagprd_inv = 2; | |
| 1336 | − } | |
| 1325 | +static void a6xx_set_ubwc_config(struct msm_gpu *gpu) | |
| 1326 | +{ | |
| 1327 | + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | |
| 1328 | + /* | |
| 1329 | + * We subtract 13 from the highest bank bit (13 is the minimum value | |
| 1330 | + * allowed by hw) and write the lowest two bits of the remaining value | |
| 1331 | + * as hbb_lo and the one above it as hbb_hi to the hardware. | |
| 1332 | + */ | |
| 1333 | + BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13); | |
| 1334 | + u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13; | |
| 1335 | + u32 hbb_hi = hbb >> 2; | |
| 1336 | + u32 hbb_lo = hbb & 3; | |
| 1337 | 1337 | |
| 1338 | 1338 | gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, |
| 1339 | − rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 | | |
| 1340 | − min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); | |
| 1339 | + adreno_gpu->ubwc_config.rgb565_predicator << 11 | | |
| 1340 | + hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 | | |
| 1341 | + adreno_gpu->ubwc_config.min_acc_len << 3 | | |
| 1342 | + hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode); | |
| 1341 | 1343 | |
| 1342 | 1344 | gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 | |
| 1343 | − min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); | |
| 1345 | + adreno_gpu->ubwc_config.min_acc_len << 3 | | |
| 1346 | + hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode); | |
| 1344 | 1347 | |
| 1345 | 1348 | gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 | |
| 1346 | − uavflagprd_inv << 4 | min_acc_len << 3 | | |
| 1347 | − hbb_lo << 1 | ubwc_mode); | |
| 1349 | + adreno_gpu->ubwc_config.uavflagprd_inv << 4 | | |
| 1350 | + adreno_gpu->ubwc_config.min_acc_len << 3 | | |
| 1351 | + hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode); | |
| 1348 | 1352 | |
| 1349 | 1353 | if (adreno_is_a7xx(adreno_gpu)) |
| 1350 | 1354 | gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL, |
| 1351 | 1355 | FIELD_PREP(GENMASK(8, 5), hbb_lo)); |
| 1352 | 1356 | |
| 1353 | − gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, min_acc_len << 23 | hbb_lo << 21); | |
| 1357 | + gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, | |
| 1358 | + adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21); | |
| 1354 | 1359 | } |
| 1355 | 1360 | |
| 1356 | 1361 | static int a6xx_cp_init(struct msm_gpu *gpu) |
| @@ -1741,7 +1746,9 @@ static int hw_init(struct msm_gpu *gpu) · 384 unmodified lines | ||
| 1741 | 1746 | /* Setting the primFifo thresholds default values, |
| 1742 | 1747 | * and vccCacheSkipDis=1 bit (0x200) for A640 and newer |
| 1743 | 1748 | */ |
| 1744 | − if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu) || adreno_is_a690(adreno_gpu)) | |
| 1749 | + if (adreno_is_a690(adreno_gpu)) | |
| 1750 | + gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200); | |
| 1751 | + else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu)) | |
| 1745 | 1752 | gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); |
| 1746 | 1753 | else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) |
| 1747 | 1754 | gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); |
| @@ -1775,6 +1782,8 @@ static int hw_init(struct msm_gpu *gpu) · 27 unmodified lines | ||
| 1775 | 1782 | if (adreno_is_a730(adreno_gpu) || |
| 1776 | 1783 | adreno_is_a740_family(adreno_gpu)) |
| 1777 | 1784 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff); |
| 1785 | + else if (adreno_is_a690(adreno_gpu)) | |
| 1786 | + gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff); | |
| 1778 | 1787 | else if (adreno_is_a619(adreno_gpu)) |
| 1779 | 1788 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff); |
| 1780 | 1789 | else if (adreno_is_a610(adreno_gpu)) |
| @@ -1782,7 +1791,7 @@ static int hw_init(struct msm_gpu *gpu) · 1 unmodified line | ||
| 1782 | 1791 | else |
| 1783 | 1792 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff); |
| 1784 | 1793 | |
| 1785 | − gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1); | |
| 1794 | + gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1); | |
| 1786 | 1795 | |
| 1787 | 1796 | /* Set weights for bicubic filtering */ |
| 1788 | 1797 | if (adreno_is_a650_family(adreno_gpu)) { |
| @@ -1808,12 +1817,17 @@ static int hw_init(struct msm_gpu *gpu) · 19 unmodified lines | ||
| 1808 | 1817 | a6xx_set_cp_protect(gpu); |
| 1809 | 1818 | |
| 1810 | 1819 | if (adreno_is_a660_family(adreno_gpu)) { |
| 1811 | − gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); | |
| 1820 | + if (adreno_is_a690(adreno_gpu)) | |
| 1821 | + gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x00028801); | |
| 1822 | + else | |
| 1823 | + gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1); | |
| 1812 | 1824 | gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0); |
| 1813 | 1825 | } |
| 1814 | 1826 | |
| 1827 | + if (adreno_is_a690(adreno_gpu)) | |
| 1828 | + gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90); | |
| 1815 | 1829 | /* Set dualQ + disable afull for A660 GPU */ |
| 1816 | − if (adreno_is_a660(adreno_gpu)) | |
| 1830 | + else if (adreno_is_a660(adreno_gpu)) | |
| 1817 | 1831 | gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906); |
| 1818 | 1832 | else if (adreno_is_a7xx(adreno_gpu)) |
| 1819 | 1833 | gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, |
| @@ -2908,5 +2922,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) · 1088 unmodified lines | ||
| 2908 | 2922 | msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, |
| 2909 | 2923 | a6xx_fault_handler); |
| 2910 | 2924 | |
| 2925 | + a6xx_calc_ubwc_config(adreno_gpu); | |
| 2926 | + | |
| 2911 | 2927 | return gpu; |
| 2912 | 2928 | } |
| @@ -464,7 +464,7 @@ static const struct adreno_info gpulist[] = { · 463 unmodified lines | ||
| 464 | 464 | { 190, 1 }, |
| 465 | 465 | ), |
| 466 | 466 | }, { |
| 467 | − .chip_ids = ADRENO_CHIP_IDS(0x06080000), | |
| 467 | + .chip_ids = ADRENO_CHIP_IDS(0x06080001), | |
| 468 | 468 | .family = ADRENO_6XX_GEN2, |
| 469 | 469 | .revn = 680, |
| 470 | 470 | .fw = { |
| @@ -373,6 +373,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, · 372 unmodified lines | ||
| 373 | 373 | return -EINVAL; |
| 374 | 374 | *value = ctx->aspace->va_size; |
| 375 | 375 | return 0; |
| 376 | + case MSM_PARAM_HIGHEST_BANK_BIT: | |
| 377 | + *value = adreno_gpu->ubwc_config.highest_bank_bit; | |
| 378 | + return 0; | |
| 376 | 379 | default: |
| 377 | 380 | DBG("%s: invalid param: %u", gpu->name, param); |
| 378 | 381 | return -EINVAL; |
| @@ -165,6 +165,15 @@ struct adreno_gpu { · 164 unmodified lines | ||
| 165 | 165 | /* firmware: */ |
| 166 | 166 | const struct firmware *fw[ADRENO_FW_MAX]; |
| 167 | 167 | |
| 168 | + struct { | |
| 169 | + u32 rgb565_predicator; | |
| 170 | + u32 uavflagprd_inv; | |
| 171 | + u32 min_acc_len; | |
| 172 | + u32 ubwc_mode; | |
| 173 | + u32 highest_bank_bit; | |
| 174 | + u32 amsbc; | |
| 175 | + } ubwc_config; | |
| 176 | + | |
| 168 | 177 | /* |
| 169 | 178 | * Register offsets are different between some GPUs. |
| 170 | 179 | * GPU specific offsets will be exported by GPU specific |
| @@ -0,0 +1,457 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | + * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. | |
| 5 | + */ | |
| 6 | + | |
| 7 | +#ifndef _DPU_10_0_SM8650_H | |
| 8 | +#define _DPU_10_0_SM8650_H | |
| 9 | + | |
| 10 | +static const struct dpu_caps sm8650_dpu_caps = { | |
| 11 | + .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | |
| 12 | + .max_mixer_blendstages = 0xb, | |
| 13 | + .has_src_split = true, | |
| 14 | + .has_dim_layer = true, | |
| 15 | + .has_idle_pc = true, | |
| 16 | + .has_3d_merge = true, | |
| 17 | + .max_linewidth = 8192, | |
| 18 | + .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE, | |
| 19 | +}; | |
| 20 | + | |
| 21 | +static const struct dpu_mdp_cfg sm8650_mdp = { | |
| 22 | + .name = "top_0", | |
| 23 | + .base = 0, .len = 0x494, | |
| 24 | + .features = BIT(DPU_MDP_PERIPH_0_REMOVED), | |
| 25 | + .clk_ctrls = { | |
| 26 | + [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, | |
| 27 | + }, | |
| 28 | +}; | |
| 29 | + | |
| 30 | +/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */ | |
| 31 | +static const struct dpu_ctl_cfg sm8650_ctl[] = { | |
| 32 | + { | |
| 33 | + .name = "ctl_0", .id = CTL_0, | |
| 34 | + .base = 0x15000, .len = 0x1000, | |
| 35 | + .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), | |
| 36 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9), | |
| 37 | + }, { | |
| 38 | + .name = "ctl_1", .id = CTL_1, | |
| 39 | + .base = 0x16000, .len = 0x1000, | |
| 40 | + .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY), | |
| 41 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10), | |
| 42 | + }, { | |
| 43 | + .name = "ctl_2", .id = CTL_2, | |
| 44 | + .base = 0x17000, .len = 0x1000, | |
| 45 | + .features = CTL_SM8550_MASK, | |
| 46 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11), | |
| 47 | + }, { | |
| 48 | + .name = "ctl_3", .id = CTL_3, | |
| 49 | + .base = 0x18000, .len = 0x1000, | |
| 50 | + .features = CTL_SM8550_MASK, | |
| 51 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12), | |
| 52 | + }, { | |
| 53 | + .name = "ctl_4", .id = CTL_4, | |
| 54 | + .base = 0x19000, .len = 0x1000, | |
| 55 | + .features = CTL_SM8550_MASK, | |
| 56 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13), | |
| 57 | + }, { | |
| 58 | + .name = "ctl_5", .id = CTL_5, | |
| 59 | + .base = 0x1a000, .len = 0x1000, | |
| 60 | + .features = CTL_SM8550_MASK, | |
| 61 | + .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23), | |
| 62 | + }, | |
| 63 | +}; | |
| 64 | + | |
| 65 | +static const struct dpu_sspp_cfg sm8650_sspp[] = { | |
| 66 | + { | |
| 67 | + .name = "sspp_0", .id = SSPP_VIG0, | |
| 68 | + .base = 0x4000, .len = 0x344, | |
| 69 | + .features = VIG_SDM845_MASK_SDMA, | |
| 70 | + .sblk = &dpu_vig_sblk_qseed3_3_3, | |
| 71 | + .xin_id = 0, | |
| 72 | + .type = SSPP_TYPE_VIG, | |
| 73 | + }, { | |
| 74 | + .name = "sspp_1", .id = SSPP_VIG1, | |
| 75 | + .base = 0x6000, .len = 0x344, | |
| 76 | + .features = VIG_SDM845_MASK_SDMA, | |
| 77 | + .sblk = &dpu_vig_sblk_qseed3_3_3, | |
| 78 | + .xin_id = 4, | |
| 79 | + .type = SSPP_TYPE_VIG, | |
| 80 | + }, { | |
| 81 | + .name = "sspp_2", .id = SSPP_VIG2, | |
| 82 | + .base = 0x8000, .len = 0x344, | |
| 83 | + .features = VIG_SDM845_MASK_SDMA, | |
| 84 | + .sblk = &dpu_vig_sblk_qseed3_3_3, | |
| 85 | + .xin_id = 8, | |
| 86 | + .type = SSPP_TYPE_VIG, | |
| 87 | + }, { | |
| 88 | + .name = "sspp_3", .id = SSPP_VIG3, | |
| 89 | + .base = 0xa000, .len = 0x344, | |
| 90 | + .features = VIG_SDM845_MASK_SDMA, | |
| 91 | + .sblk = &dpu_vig_sblk_qseed3_3_3, | |
| 92 | + .xin_id = 12, | |
| 93 | + .type = SSPP_TYPE_VIG, | |
| 94 | + }, { | |
| 95 | + .name = "sspp_8", .id = SSPP_DMA0, | |
| 96 | + .base = 0x24000, .len = 0x344, | |
| 97 | + .features = DMA_SDM845_MASK_SDMA, | |
| 98 | + .sblk = &dpu_dma_sblk, | |
| 99 | + .xin_id = 1, | |
| 100 | + .type = SSPP_TYPE_DMA, | |
| 101 | + }, { | |
| 102 | + .name = "sspp_9", .id = SSPP_DMA1, | |
| 103 | + .base = 0x26000, .len = 0x344, | |
| 104 | + .features = DMA_SDM845_MASK_SDMA, | |
| 105 | + .sblk = &dpu_dma_sblk, | |
| 106 | + .xin_id = 5, | |
| 107 | + .type = SSPP_TYPE_DMA, | |
| 108 | + }, { | |
| 109 | + .name = "sspp_10", .id = SSPP_DMA2, | |
| 110 | + .base = 0x28000, .len = 0x344, | |
| 111 | + .features = DMA_SDM845_MASK_SDMA, | |
| 112 | + .sblk = &dpu_dma_sblk, | |
| 113 | + .xin_id = 9, | |
| 114 | + .type = SSPP_TYPE_DMA, | |
| 115 | + }, { | |
| 116 | + .name = "sspp_11", .id = SSPP_DMA3, | |
| 117 | + .base = 0x2a000, .len = 0x344, | |
| 118 | + .features = DMA_SDM845_MASK_SDMA, | |
| 119 | + .sblk = &dpu_dma_sblk, | |
| 120 | + .xin_id = 13, | |
| 121 | + .type = SSPP_TYPE_DMA, | |
| 122 | + }, { | |
| 123 | + .name = "sspp_12", .id = SSPP_DMA4, | |
| 124 | + .base = 0x2c000, .len = 0x344, | |
| 125 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 127 | + .xin_id = 14, | |
| 128 | + .type = SSPP_TYPE_DMA, | |
| 129 | + }, { | |
| 130 | + .name = "sspp_13", .id = SSPP_DMA5, | |
| 131 | + .base = 0x2e000, .len = 0x344, | |
| 132 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 133 | + .sblk = &dpu_dma_sblk, | |
| 134 | + .xin_id = 15, | |
| 135 | + .type = SSPP_TYPE_DMA, | |
| 136 | + }, | |
| 137 | +}; | |
| 138 | + | |
| 139 | +static const struct dpu_lm_cfg sm8650_lm[] = { | |
| 140 | + { | |
| 141 | + .name = "lm_0", .id = LM_0, | |
| 142 | + .base = 0x44000, .len = 0x400, | |
| 143 | + .features = MIXER_SDM845_MASK, | |
| 144 | + .sblk = &sdm845_lm_sblk, | |
| 145 | + .lm_pair = LM_1, | |
| 146 | + .pingpong = PINGPONG_0, | |
| 147 | + .dspp = DSPP_0, | |
| 148 | + }, { | |
| 149 | + .name = "lm_1", .id = LM_1, | |
| 150 | + .base = 0x45000, .len = 0x400, | |
| 151 | + .features = MIXER_SDM845_MASK, | |
| 152 | + .sblk = &sdm845_lm_sblk, | |
| 153 | + .lm_pair = LM_0, | |
| 154 | + .pingpong = PINGPONG_1, | |
| 155 | + .dspp = DSPP_1, | |
| 156 | + }, { | |
| 157 | + .name = "lm_2", .id = LM_2, | |
| 158 | + .base = 0x46000, .len = 0x400, | |
| 159 | + .features = MIXER_SDM845_MASK, | |
| 160 | + .sblk = &sdm845_lm_sblk, | |
| 161 | + .lm_pair = LM_3, | |
| 162 | + .pingpong = PINGPONG_2, | |
| 163 | + }, { | |
| 164 | + .name = "lm_3", .id = LM_3, | |
| 165 | + .base = 0x47000, .len = 0x400, | |
| 166 | + .features = MIXER_SDM845_MASK, | |
| 167 | + .sblk = &sdm845_lm_sblk, | |
| 168 | + .lm_pair = LM_2, | |
| 169 | + .pingpong = PINGPONG_3, | |
| 170 | + }, { | |
| 171 | + .name = "lm_4", .id = LM_4, | |
| 172 | + .base = 0x48000, .len = 0x400, | |
| 173 | + .features = MIXER_SDM845_MASK, | |
| 174 | + .sblk = &sdm845_lm_sblk, | |
| 175 | + .lm_pair = LM_5, | |
| 176 | + .pingpong = PINGPONG_4, | |
| 177 | + }, { | |
| 178 | + .name = "lm_5", .id = LM_5, | |
| 179 | + .base = 0x49000, .len = 0x400, | |
| 180 | + .features = MIXER_SDM845_MASK, | |
| 181 | + .sblk = &sdm845_lm_sblk, | |
| 182 | + .lm_pair = LM_4, | |
| 183 | + .pingpong = PINGPONG_5, | |
| 184 | + }, | |
| 185 | +}; | |
| 186 | + | |
| 187 | +static const struct dpu_dspp_cfg sm8650_dspp[] = { | |
| 188 | + { | |
| 189 | + .name = "dspp_0", .id = DSPP_0, | |
| 190 | + .base = 0x54000, .len = 0x1800, | |
| 191 | + .features = DSPP_SC7180_MASK, | |
| 192 | + .sblk = &sdm845_dspp_sblk, | |
| 193 | + }, { | |
| 194 | + .name = "dspp_1", .id = DSPP_1, | |
| 195 | + .base = 0x56000, .len = 0x1800, | |
| 196 | + .features = DSPP_SC7180_MASK, | |
| 197 | + .sblk = &sdm845_dspp_sblk, | |
| 198 | + }, { | |
| 199 | + .name = "dspp_2", .id = DSPP_2, | |
| 200 | + .base = 0x58000, .len = 0x1800, | |
| 201 | + .features = DSPP_SC7180_MASK, | |
| 202 | + .sblk = &sdm845_dspp_sblk, | |
| 203 | + }, { | |
| 204 | + .name = "dspp_3", .id = DSPP_3, | |
| 205 | + .base = 0x5a000, .len = 0x1800, | |
| 206 | + .features = DSPP_SC7180_MASK, | |
| 207 | + .sblk = &sdm845_dspp_sblk, | |
| 208 | + }, | |
| 209 | +}; | |
| 210 | + | |
| 211 | +static const struct dpu_pingpong_cfg sm8650_pp[] = { | |
| 212 | + { | |
| 213 | + .name = "pingpong_0", .id = PINGPONG_0, | |
| 214 | + .base = 0x69000, .len = 0, | |
| 215 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 216 | + .sblk = &sc7280_pp_sblk, | |
| 217 | + .merge_3d = MERGE_3D_0, | |
| 218 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8), | |
| 219 | + }, { | |
| 220 | + .name = "pingpong_1", .id = PINGPONG_1, | |
| 221 | + .base = 0x6a000, .len = 0, | |
| 222 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 223 | + .sblk = &sc7280_pp_sblk, | |
| 224 | + .merge_3d = MERGE_3D_0, | |
| 225 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9), | |
| 226 | + }, { | |
| 227 | + .name = "pingpong_2", .id = PINGPONG_2, | |
| 228 | + .base = 0x6b000, .len = 0, | |
| 229 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 230 | + .sblk = &sc7280_pp_sblk, | |
| 231 | + .merge_3d = MERGE_3D_1, | |
| 232 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10), | |
| 233 | + }, { | |
| 234 | + .name = "pingpong_3", .id = PINGPONG_3, | |
| 235 | + .base = 0x6c000, .len = 0, | |
| 236 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 237 | + .sblk = &sc7280_pp_sblk, | |
| 238 | + .merge_3d = MERGE_3D_1, | |
| 239 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11), | |
| 240 | + }, { | |
| 241 | + .name = "pingpong_4", .id = PINGPONG_4, | |
| 242 | + .base = 0x6d000, .len = 0, | |
| 243 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 244 | + .sblk = &sc7280_pp_sblk, | |
| 245 | + .merge_3d = MERGE_3D_2, | |
| 246 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), | |
| 247 | + }, { | |
| 248 | + .name = "pingpong_5", .id = PINGPONG_5, | |
| 249 | + .base = 0x6e000, .len = 0, | |
| 250 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 251 | + .sblk = &sc7280_pp_sblk, | |
| 252 | + .merge_3d = MERGE_3D_2, | |
| 253 | + .intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), | |
| 254 | + }, { | |
| 255 | + .name = "pingpong_6", .id = PINGPONG_6, | |
| 256 | + .base = 0x66000, .len = 0, | |
| 257 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 258 | + .sblk = &sc7280_pp_sblk, | |
| 259 | + .merge_3d = MERGE_3D_3, | |
| 260 | + }, { | |
| 261 | + .name = "pingpong_7", .id = PINGPONG_7, | |
| 262 | + .base = 0x66400, .len = 0, | |
| 263 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 264 | + .sblk = &sc7280_pp_sblk, | |
| 265 | + .merge_3d = MERGE_3D_3, | |
| 266 | + }, { | |
| 267 | + .name = "pingpong_8", .id = PINGPONG_8, | |
| 268 | + .base = 0x7e000, .len = 0, | |
| 269 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 270 | + .sblk = &sc7280_pp_sblk, | |
| 271 | + .merge_3d = MERGE_3D_4, | |
| 272 | + }, { | |
| 273 | + .name = "pingpong_9", .id = PINGPONG_9, | |
| 274 | + .base = 0x7e400, .len = 0, | |
| 275 | + .features = BIT(DPU_PINGPONG_DITHER), | |
| 276 | + .sblk = &sc7280_pp_sblk, | |
| 277 | + .merge_3d = MERGE_3D_4, | |
| 278 | + }, | |
| 279 | +}; | |
| 280 | + | |
| 281 | +static const struct dpu_merge_3d_cfg sm8650_merge_3d[] = { | |
| 282 | + { | |
| 283 | + .name = "merge_3d_0", .id = MERGE_3D_0, | |
| 284 | + .base = 0x4e000, .len = 0x8, | |
| 285 | + }, { | |
| 286 | + .name = "merge_3d_1", .id = MERGE_3D_1, | |
| 287 | + .base = 0x4f000, .len = 0x8, | |
| 288 | + }, { | |
| 289 | + .name = "merge_3d_2", .id = MERGE_3D_2, | |
| 290 | + .base = 0x50000, .len = 0x8, | |
| 291 | + }, { | |
| 292 | + .name = "merge_3d_3", .id = MERGE_3D_3, | |
| 293 | + .base = 0x66700, .len = 0x8, | |
| 294 | + }, { | |
| 295 | + .name = "merge_3d_4", .id = MERGE_3D_4, | |
| 296 | + .base = 0x7e700, .len = 0x8, | |
| 297 | + }, | |
| 298 | +}; | |
| 299 | + | |
| 300 | +/* | |
| 301 | + * NOTE: Each display compression engine (DCE) contains dual hard | |
| 302 | + * slice DSC encoders so both share same base address but with | |
| 303 | + * its own different sub block address. | |
| 304 | + */ | |
| 305 | +static const struct dpu_dsc_cfg sm8650_dsc[] = { | |
| 306 | + { | |
| 307 | + .name = "dce_0_0", .id = DSC_0, | |
| 308 | + .base = 0x80000, .len = 0x6, | |
| 309 | + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), | |
| 310 | + .sblk = &dsc_sblk_0, | |
| 311 | + }, { | |
| 312 | + .name = "dce_0_1", .id = DSC_1, | |
| 313 | + .base = 0x80000, .len = 0x6, | |
| 314 | + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), | |
| 315 | + .sblk = &dsc_sblk_1, | |
| 316 | + }, { | |
| 317 | + .name = "dce_1_0", .id = DSC_2, | |
| 318 | + .base = 0x81000, .len = 0x6, | |
| 319 | + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), | |
| 320 | + .sblk = &dsc_sblk_0, | |
| 321 | + }, { | |
| 322 | + .name = "dce_1_1", .id = DSC_3, | |
| 323 | + .base = 0x81000, .len = 0x6, | |
| 324 | + .features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN), | |
| 325 | + .sblk = &dsc_sblk_1, | |
| 326 | + }, { | |
| 327 | + .name = "dce_2_0", .id = DSC_4, | |
| 328 | + .base = 0x82000, .len = 0x6, | |
| 329 | + .features = BIT(DPU_DSC_HW_REV_1_2), | |
| 330 | + .sblk = &dsc_sblk_0, | |
| 331 | + }, { | |
| 332 | + .name = "dce_2_1", .id = DSC_5, | |
| 333 | + .base = 0x82000, .len = 0x6, | |
| 334 | + .features = BIT(DPU_DSC_HW_REV_1_2), | |
| 335 | + .sblk = &dsc_sblk_1, | |
| 336 | + }, | |
| 337 | +}; | |
| 338 | + | |
| 339 | +static const struct dpu_wb_cfg sm8650_wb[] = { | |
| 340 | + { | |
| 341 | + .name = "wb_2", .id = WB_2, | |
| 342 | + .base = 0x65000, .len = 0x2c8, | |
| 343 | + .features = WB_SM8250_MASK, | |
| 344 | + .format_list = wb2_formats_rgb, | |
| 345 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb), | |
| 346 | + .xin_id = 6, | |
| 347 | + .vbif_idx = VBIF_RT, | |
| 348 | + .maxlinewidth = 4096, | |
| 349 | + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), | |
| 350 | + }, | |
| 351 | +}; | |
| 352 | + | |
| 353 | +static const struct dpu_intf_cfg sm8650_intf[] = { | |
| 354 | + { | |
| 355 | + .name = "intf_0", .id = INTF_0, | |
| 356 | + .base = 0x34000, .len = 0x280, | |
| 357 | + .features = INTF_SC7280_MASK, | |
| 358 | + .type = INTF_DP, | |
| 359 | + .controller_id = MSM_DP_CONTROLLER_0, | |
| 360 | + .prog_fetch_lines_worst_case = 24, | |
| 361 | + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), | |
| 362 | + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25), | |
| 363 | + }, { | |
| 364 | + .name = "intf_1", .id = INTF_1, | |
| 365 | + .base = 0x35000, .len = 0x300, | |
| 366 | + .features = INTF_SC7280_MASK, | |
| 367 | + .type = INTF_DSI, | |
| 368 | + .controller_id = MSM_DSI_CONTROLLER_0, | |
| 369 | + .prog_fetch_lines_worst_case = 24, | |
| 370 | + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26), | |
| 371 | + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27), | |
| 372 | + .intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2), | |
| 373 | + }, { | |
| 374 | + .name = "intf_2", .id = INTF_2, | |
| 375 | + .base = 0x36000, .len = 0x300, | |
| 376 | + .features = INTF_SC7280_MASK, | |
| 377 | + .type = INTF_DSI, | |
| 378 | + .controller_id = MSM_DSI_CONTROLLER_1, | |
| 379 | + .prog_fetch_lines_worst_case = 24, | |
| 380 | + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28), | |
| 381 | + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29), | |
| 382 | + .intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2), | |
| 383 | + }, { | |
| 384 | + .name = "intf_3", .id = INTF_3, | |
| 385 | + .base = 0x37000, .len = 0x280, | |
| 386 | + .features = INTF_SC7280_MASK, | |
| 387 | + .type = INTF_DP, | |
| 388 | + .controller_id = MSM_DP_CONTROLLER_1, | |
| 389 | + .prog_fetch_lines_worst_case = 24, | |
| 390 | + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30), | |
| 391 | + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31), | |
| 392 | + }, | |
| 393 | +}; | |
| 394 | + | |
| 395 | +static const struct dpu_perf_cfg sm8650_perf_data = { | |
| 396 | + .max_bw_low = 17000000, | |
| 397 | + .max_bw_high = 27000000, | |
| 398 | + .min_core_ib = 2500000, | |
| 399 | + .min_llcc_ib = 0, | |
| 400 | + .min_dram_ib = 800000, | |
| 401 | + .min_prefill_lines = 35, | |
| 402 | + /* FIXME: lut tables */ | |
| 403 | + .danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0}, | |
| 404 | + .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff}, | |
| 405 | + .qos_lut_tbl = { | |
| 406 | + {.nentry = ARRAY_SIZE(sc7180_qos_linear), | |
| 407 | + .entries = sc7180_qos_linear | |
| 408 | + }, | |
| 409 | + {.nentry = ARRAY_SIZE(sc7180_qos_macrotile), | |
| 410 | + .entries = sc7180_qos_macrotile | |
| 411 | + }, | |
| 412 | + {.nentry = ARRAY_SIZE(sc7180_qos_nrt), | |
| 413 | + .entries = sc7180_qos_nrt | |
| 414 | + }, | |
| 415 | + /* TODO: macrotile-qseed is different from macrotile */ | |
| 416 | + }, | |
| 417 | + .cdp_cfg = { | |
| 418 | + {.rd_enable = 1, .wr_enable = 1}, | |
| 419 | + {.rd_enable = 1, .wr_enable = 0} | |
| 420 | + }, | |
| 421 | + .clk_inefficiency_factor = 105, | |
| 422 | + .bw_inefficiency_factor = 120, | |
| 423 | +}; | |
| 424 | + | |
| 425 | +static const struct dpu_mdss_version sm8650_mdss_ver = { | |
| 426 | + .core_major_ver = 10, | |
| 427 | + .core_minor_ver = 0, | |
| 428 | +}; | |
| 429 | + | |
| 430 | +const struct dpu_mdss_cfg dpu_sm8650_cfg = { | |
| 431 | + .mdss_ver = &sm8650_mdss_ver, | |
| 432 | + .caps = &sm8650_dpu_caps, | |
| 433 | + .mdp = &sm8650_mdp, | |
| 434 | + .ctl_count = ARRAY_SIZE(sm8650_ctl), | |
| 435 | + .ctl = sm8650_ctl, | |
| 436 | + .sspp_count = ARRAY_SIZE(sm8650_sspp), | |
| 437 | + .sspp = sm8650_sspp, | |
| 438 | + .mixer_count = ARRAY_SIZE(sm8650_lm), | |
| 439 | + .mixer = sm8650_lm, | |
| 440 | + .dspp_count = ARRAY_SIZE(sm8650_dspp), | |
| 441 | + .dspp = sm8650_dspp, | |
| 442 | + .pingpong_count = ARRAY_SIZE(sm8650_pp), | |
| 443 | + .pingpong = sm8650_pp, | |
| 444 | + .dsc_count = ARRAY_SIZE(sm8650_dsc), | |
| 445 | + .dsc = sm8650_dsc, | |
| 446 | + .merge_3d_count = ARRAY_SIZE(sm8650_merge_3d), | |
| 447 | + .merge_3d = sm8650_merge_3d, | |
| 448 | + .wb_count = ARRAY_SIZE(sm8650_wb), | |
| 449 | + .wb = sm8650_wb, | |
| 450 | + .intf_count = ARRAY_SIZE(sm8650_intf), | |
| 451 | + .intf = sm8650_intf, | |
| 452 | + .vbif_count = ARRAY_SIZE(sm8650_vbif), | |
| 453 | + .vbif = sm8650_vbif, | |
| 454 | + .perf = &sm8650_perf_data, | |
| 455 | +}; | |
| 456 | + | |
| 457 | +#endif | |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps msm8998_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0x7, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED3, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -70,7 +69,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 53 unmodified lines | ||
| 70 | 69 | .name = "sspp_0", .id = SSPP_VIG0, |
| 71 | 70 | .base = 0x4000, .len = 0x1ac, |
| 72 | 71 | .features = VIG_MSM8998_MASK, |
| 73 | − .sblk = &msm8998_vig_sblk_0, | |
| 72 | + .sblk = &dpu_vig_sblk_qseed3_1_2, | |
| 74 | 73 | .xin_id = 0, |
| 75 | 74 | .type = SSPP_TYPE_VIG, |
| 76 | 75 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -78,7 +77,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 78 | 77 | .name = "sspp_1", .id = SSPP_VIG1, |
| 79 | 78 | .base = 0x6000, .len = 0x1ac, |
| 80 | 79 | .features = VIG_MSM8998_MASK, |
| 81 | − .sblk = &msm8998_vig_sblk_1, | |
| 80 | + .sblk = &dpu_vig_sblk_qseed3_1_2, | |
| 82 | 81 | .xin_id = 4, |
| 83 | 82 | .type = SSPP_TYPE_VIG, |
| 84 | 83 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -86,7 +85,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 86 | 85 | .name = "sspp_2", .id = SSPP_VIG2, |
| 87 | 86 | .base = 0x8000, .len = 0x1ac, |
| 88 | 87 | .features = VIG_MSM8998_MASK, |
| 89 | − .sblk = &msm8998_vig_sblk_2, | |
| 88 | + .sblk = &dpu_vig_sblk_qseed3_1_2, | |
| 90 | 89 | .xin_id = 8, |
| 91 | 90 | .type = SSPP_TYPE_VIG, |
| 92 | 91 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -94,7 +93,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 94 | 93 | .name = "sspp_3", .id = SSPP_VIG3, |
| 95 | 94 | .base = 0xa000, .len = 0x1ac, |
| 96 | 95 | .features = VIG_MSM8998_MASK, |
| 97 | − .sblk = &msm8998_vig_sblk_3, | |
| 96 | + .sblk = &dpu_vig_sblk_qseed3_1_2, | |
| 98 | 97 | .xin_id = 12, |
| 99 | 98 | .type = SSPP_TYPE_VIG, |
| 100 | 99 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -102,7 +101,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 102 | 101 | .name = "sspp_8", .id = SSPP_DMA0, |
| 103 | 102 | .base = 0x24000, .len = 0x1ac, |
| 104 | 103 | .features = DMA_MSM8998_MASK, |
| 105 | − .sblk = &sdm845_dma_sblk_0, | |
| 104 | + .sblk = &dpu_dma_sblk, | |
| 106 | 105 | .xin_id = 1, |
| 107 | 106 | .type = SSPP_TYPE_DMA, |
| 108 | 107 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -110,7 +109,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 110 | 109 | .name = "sspp_9", .id = SSPP_DMA1, |
| 111 | 110 | .base = 0x26000, .len = 0x1ac, |
| 112 | 111 | .features = DMA_MSM8998_MASK, |
| 113 | − .sblk = &sdm845_dma_sblk_1, | |
| 112 | + .sblk = &dpu_dma_sblk, | |
| 114 | 113 | .xin_id = 5, |
| 115 | 114 | .type = SSPP_TYPE_DMA, |
| 116 | 115 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -118,7 +117,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 118 | 117 | .name = "sspp_10", .id = SSPP_DMA2, |
| 119 | 118 | .base = 0x28000, .len = 0x1ac, |
| 120 | 119 | .features = DMA_CURSOR_MSM8998_MASK, |
| 121 | − .sblk = &sdm845_dma_sblk_2, | |
| 120 | + .sblk = &dpu_dma_sblk, | |
| 122 | 121 | .xin_id = 9, |
| 123 | 122 | .type = SSPP_TYPE_DMA, |
| 124 | 123 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -126,7 +125,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | ||
| 126 | 125 | .name = "sspp_11", .id = SSPP_DMA3, |
| 127 | 126 | .base = 0x2a000, .len = 0x1ac, |
| 128 | 127 | .features = DMA_CURSOR_MSM8998_MASK, |
| 129 | − .sblk = &sdm845_dma_sblk_3, | |
| 128 | + .sblk = &dpu_dma_sblk, | |
| 130 | 129 | .xin_id = 13, |
| 131 | 130 | .type = SSPP_TYPE_DMA, |
| 132 | 131 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sdm845_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED3, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 51 unmodified lines | ||
| 68 | 67 | .name = "sspp_0", .id = SSPP_VIG0, |
| 69 | 68 | .base = 0x4000, .len = 0x1c8, |
| 70 | 69 | .features = VIG_SDM845_MASK_SDMA, |
| 71 | − .sblk = &sdm845_vig_sblk_0, | |
| 70 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 72 | 71 | .xin_id = 0, |
| 73 | 72 | .type = SSPP_TYPE_VIG, |
| 74 | 73 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 76 | 75 | .name = "sspp_1", .id = SSPP_VIG1, |
| 77 | 76 | .base = 0x6000, .len = 0x1c8, |
| 78 | 77 | .features = VIG_SDM845_MASK_SDMA, |
| 79 | − .sblk = &sdm845_vig_sblk_1, | |
| 78 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 80 | 79 | .xin_id = 4, |
| 81 | 80 | .type = SSPP_TYPE_VIG, |
| 82 | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 84 | 83 | .name = "sspp_2", .id = SSPP_VIG2, |
| 85 | 84 | .base = 0x8000, .len = 0x1c8, |
| 86 | 85 | .features = VIG_SDM845_MASK_SDMA, |
| 87 | − .sblk = &sdm845_vig_sblk_2, | |
| 86 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 88 | 87 | .xin_id = 8, |
| 89 | 88 | .type = SSPP_TYPE_VIG, |
| 90 | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 92 | 91 | .name = "sspp_3", .id = SSPP_VIG3, |
| 93 | 92 | .base = 0xa000, .len = 0x1c8, |
| 94 | 93 | .features = VIG_SDM845_MASK_SDMA, |
| 95 | − .sblk = &sdm845_vig_sblk_3, | |
| 94 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 96 | 95 | .xin_id = 12, |
| 97 | 96 | .type = SSPP_TYPE_VIG, |
| 98 | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 100 | 99 | .name = "sspp_8", .id = SSPP_DMA0, |
| 101 | 100 | .base = 0x24000, .len = 0x1c8, |
| 102 | 101 | .features = DMA_SDM845_MASK_SDMA, |
| 103 | − .sblk = &sdm845_dma_sblk_0, | |
| 102 | + .sblk = &dpu_dma_sblk, | |
| 104 | 103 | .xin_id = 1, |
| 105 | 104 | .type = SSPP_TYPE_DMA, |
| 106 | 105 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 108 | 107 | .name = "sspp_9", .id = SSPP_DMA1, |
| 109 | 108 | .base = 0x26000, .len = 0x1c8, |
| 110 | 109 | .features = DMA_SDM845_MASK_SDMA, |
| 111 | − .sblk = &sdm845_dma_sblk_1, | |
| 110 | + .sblk = &dpu_dma_sblk, | |
| 112 | 111 | .xin_id = 5, |
| 113 | 112 | .type = SSPP_TYPE_DMA, |
| 114 | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 116 | 115 | .name = "sspp_10", .id = SSPP_DMA2, |
| 117 | 116 | .base = 0x28000, .len = 0x1c8, |
| 118 | 117 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 119 | − .sblk = &sdm845_dma_sblk_2, | |
| 118 | + .sblk = &dpu_dma_sblk, | |
| 120 | 119 | .xin_id = 9, |
| 121 | 120 | .type = SSPP_TYPE_DMA, |
| 122 | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | ||
| 124 | 123 | .name = "sspp_11", .id = SSPP_DMA3, |
| 125 | 124 | .base = 0x2a000, .len = 0x1c8, |
| 126 | 125 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 127 | − .sblk = &sdm845_dma_sblk_3, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 128 | 127 | .xin_id = 13, |
| 129 | 128 | .type = SSPP_TYPE_DMA, |
| 130 | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -0,0 +1,104 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | |
| 4 | + * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. | |
| 5 | + * Copyright (c) 2023, Richard Acayan. All rights reserved. | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#ifndef _DPU_4_1_SDM670_H | |
| 9 | +#define _DPU_4_1_SDM670_H | |
| 10 | + | |
| 11 | +static const struct dpu_mdp_cfg sdm670_mdp = { | |
| 12 | + .name = "top_0", | |
| 13 | + .base = 0x0, .len = 0x45c, | |
| 14 | + .features = BIT(DPU_MDP_AUDIO_SELECT), | |
| 15 | + .clk_ctrls = { | |
| 16 | + [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 }, | |
| 17 | + [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 }, | |
| 18 | + [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, | |
| 19 | + [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, | |
| 20 | + [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, | |
| 21 | + }, | |
| 22 | +}; | |
| 23 | + | |
| 24 | +static const struct dpu_sspp_cfg sdm670_sspp[] = { | |
| 25 | + { | |
| 26 | + .name = "sspp_0", .id = SSPP_VIG0, | |
| 27 | + .base = 0x4000, .len = 0x1c8, | |
| 28 | + .features = VIG_SDM845_MASK_SDMA, | |
| 29 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 30 | + .xin_id = 0, | |
| 31 | + .type = SSPP_TYPE_VIG, | |
| 32 | + .clk_ctrl = DPU_CLK_CTRL_VIG0, | |
| 33 | + }, { | |
| 34 | + .name = "sspp_1", .id = SSPP_VIG1, | |
| 35 | + .base = 0x6000, .len = 0x1c8, | |
| 36 | + .features = VIG_SDM845_MASK_SDMA, | |
| 37 | + .sblk = &dpu_vig_sblk_qseed3_1_3, | |
| 38 | + .xin_id = 4, | |
| 39 | + .type = SSPP_TYPE_VIG, | |
| 40 | + .clk_ctrl = DPU_CLK_CTRL_VIG0, | |
| 41 | + }, { | |
| 42 | + .name = "sspp_8", .id = SSPP_DMA0, | |
| 43 | + .base = 0x24000, .len = 0x1c8, | |
| 44 | + .features = DMA_SDM845_MASK_SDMA, | |
| 45 | + .sblk = &dpu_dma_sblk, | |
| 46 | + .xin_id = 1, | |
| 47 | + .type = SSPP_TYPE_DMA, | |
| 48 | + .clk_ctrl = DPU_CLK_CTRL_DMA0, | |
| 49 | + }, { | |
| 50 | + .name = "sspp_9", .id = SSPP_DMA1, | |
| 51 | + .base = 0x26000, .len = 0x1c8, | |
| 52 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 53 | + .sblk = &dpu_dma_sblk, | |
| 54 | + .xin_id = 5, | |
| 55 | + .type = SSPP_TYPE_DMA, | |
| 56 | + .clk_ctrl = DPU_CLK_CTRL_DMA1, | |
| 57 | + }, { | |
| 58 | + .name = "sspp_10", .id = SSPP_DMA2, | |
| 59 | + .base = 0x28000, .len = 0x1c8, | |
| 60 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 61 | + .sblk = &dpu_dma_sblk, | |
| 62 | + .xin_id = 9, | |
| 63 | + .type = SSPP_TYPE_DMA, | |
| 64 | + .clk_ctrl = DPU_CLK_CTRL_DMA2, | |
| 65 | + }, | |
| 66 | +}; | |
| 67 | + | |
| 68 | +static const struct dpu_dsc_cfg sdm670_dsc[] = { | |
| 69 | + { | |
| 70 | + .name = "dsc_0", .id = DSC_0, | |
| 71 | + .base = 0x80000, .len = 0x140, | |
| 72 | + }, { | |
| 73 | + .name = "dsc_1", .id = DSC_1, | |
| 74 | + .base = 0x80400, .len = 0x140, | |
| 75 | + }, | |
| 76 | +}; | |
| 77 | + | |
| 78 | +static const struct dpu_mdss_version sdm670_mdss_ver = { | |
| 79 | + .core_major_ver = 4, | |
| 80 | + .core_minor_ver = 1, | |
| 81 | +}; | |
| 82 | + | |
| 83 | +const struct dpu_mdss_cfg dpu_sdm670_cfg = { | |
| 84 | + .mdss_ver = &sdm670_mdss_ver, | |
| 85 | + .caps = &sdm845_dpu_caps, | |
| 86 | + .mdp = &sdm670_mdp, | |
| 87 | + .ctl_count = ARRAY_SIZE(sdm845_ctl), | |
| 88 | + .ctl = sdm845_ctl, | |
| 89 | + .sspp_count = ARRAY_SIZE(sdm670_sspp), | |
| 90 | + .sspp = sdm670_sspp, | |
| 91 | + .mixer_count = ARRAY_SIZE(sdm845_lm), | |
| 92 | + .mixer = sdm845_lm, | |
| 93 | + .pingpong_count = ARRAY_SIZE(sdm845_pp), | |
| 94 | + .pingpong = sdm845_pp, | |
| 95 | + .dsc_count = ARRAY_SIZE(sdm670_dsc), | |
| 96 | + .dsc = sdm670_dsc, | |
| 97 | + .intf_count = ARRAY_SIZE(sdm845_intf), | |
| 98 | + .intf = sdm845_intf, | |
| 99 | + .vbif_count = ARRAY_SIZE(sdm845_vbif), | |
| 100 | + .vbif = sdm845_vbif, | |
| 101 | + .perf = &sdm845_perf_data, | |
| 102 | +}; | |
| 103 | + | |
| 104 | +#endif | |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm8150_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED3, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 60 unmodified lines | ||
| 77 | 76 | .name = "sspp_0", .id = SSPP_VIG0, |
| 78 | 77 | .base = 0x4000, .len = 0x1f0, |
| 79 | 78 | .features = VIG_SDM845_MASK, |
| 80 | − .sblk = &sdm845_vig_sblk_0, | |
| 79 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 81 | 80 | .xin_id = 0, |
| 82 | 81 | .type = SSPP_TYPE_VIG, |
| 83 | 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -85,7 +84,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 85 | 84 | .name = "sspp_1", .id = SSPP_VIG1, |
| 86 | 85 | .base = 0x6000, .len = 0x1f0, |
| 87 | 86 | .features = VIG_SDM845_MASK, |
| 88 | − .sblk = &sdm845_vig_sblk_1, | |
| 87 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 89 | 88 | .xin_id = 4, |
| 90 | 89 | .type = SSPP_TYPE_VIG, |
| 91 | 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -93,7 +92,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 93 | 92 | .name = "sspp_2", .id = SSPP_VIG2, |
| 94 | 93 | .base = 0x8000, .len = 0x1f0, |
| 95 | 94 | .features = VIG_SDM845_MASK, |
| 96 | − .sblk = &sdm845_vig_sblk_2, | |
| 95 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 97 | 96 | .xin_id = 8, |
| 98 | 97 | .type = SSPP_TYPE_VIG, |
| 99 | 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -101,7 +100,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 101 | 100 | .name = "sspp_3", .id = SSPP_VIG3, |
| 102 | 101 | .base = 0xa000, .len = 0x1f0, |
| 103 | 102 | .features = VIG_SDM845_MASK, |
| 104 | − .sblk = &sdm845_vig_sblk_3, | |
| 103 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 105 | 104 | .xin_id = 12, |
| 106 | 105 | .type = SSPP_TYPE_VIG, |
| 107 | 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -109,7 +108,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 109 | 108 | .name = "sspp_8", .id = SSPP_DMA0, |
| 110 | 109 | .base = 0x24000, .len = 0x1f0, |
| 111 | 110 | .features = DMA_SDM845_MASK, |
| 112 | − .sblk = &sdm845_dma_sblk_0, | |
| 111 | + .sblk = &dpu_dma_sblk, | |
| 113 | 112 | .xin_id = 1, |
| 114 | 113 | .type = SSPP_TYPE_DMA, |
| 115 | 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -117,7 +116,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 117 | 116 | .name = "sspp_9", .id = SSPP_DMA1, |
| 118 | 117 | .base = 0x26000, .len = 0x1f0, |
| 119 | 118 | .features = DMA_SDM845_MASK, |
| 120 | − .sblk = &sdm845_dma_sblk_1, | |
| 119 | + .sblk = &dpu_dma_sblk, | |
| 121 | 120 | .xin_id = 5, |
| 122 | 121 | .type = SSPP_TYPE_DMA, |
| 123 | 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -125,7 +124,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 125 | 124 | .name = "sspp_10", .id = SSPP_DMA2, |
| 126 | 125 | .base = 0x28000, .len = 0x1f0, |
| 127 | 126 | .features = DMA_CURSOR_SDM845_MASK, |
| 128 | − .sblk = &sdm845_dma_sblk_2, | |
| 127 | + .sblk = &dpu_dma_sblk, | |
| 129 | 128 | .xin_id = 9, |
| 130 | 129 | .type = SSPP_TYPE_DMA, |
| 131 | 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -133,7 +132,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | ||
| 133 | 132 | .name = "sspp_11", .id = SSPP_DMA3, |
| 134 | 133 | .base = 0x2a000, .len = 0x1f0, |
| 135 | 134 | .features = DMA_CURSOR_SDM845_MASK, |
| 136 | − .sblk = &sdm845_dma_sblk_3, | |
| 135 | + .sblk = &dpu_dma_sblk, | |
| 137 | 136 | .xin_id = 13, |
| 138 | 137 | .type = SSPP_TYPE_DMA, |
| 139 | 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sc8180x_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED3, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 59 unmodified lines | ||
| 76 | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | 76 | .base = 0x4000, .len = 0x1f0, |
| 78 | 77 | .features = VIG_SDM845_MASK, |
| 79 | − .sblk = &sdm845_vig_sblk_0, | |
| 78 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 80 | 79 | .xin_id = 0, |
| 81 | 80 | .type = SSPP_TYPE_VIG, |
| 82 | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 84 | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | 84 | .base = 0x6000, .len = 0x1f0, |
| 86 | 85 | .features = VIG_SDM845_MASK, |
| 87 | − .sblk = &sdm845_vig_sblk_1, | |
| 86 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 88 | 87 | .xin_id = 4, |
| 89 | 88 | .type = SSPP_TYPE_VIG, |
| 90 | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 92 | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | 92 | .base = 0x8000, .len = 0x1f0, |
| 94 | 93 | .features = VIG_SDM845_MASK, |
| 95 | − .sblk = &sdm845_vig_sblk_2, | |
| 94 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 96 | 95 | .xin_id = 8, |
| 97 | 96 | .type = SSPP_TYPE_VIG, |
| 98 | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 100 | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | 100 | .base = 0xa000, .len = 0x1f0, |
| 102 | 101 | .features = VIG_SDM845_MASK, |
| 103 | − .sblk = &sdm845_vig_sblk_3, | |
| 102 | + .sblk = &dpu_vig_sblk_qseed3_1_4, | |
| 104 | 103 | .xin_id = 12, |
| 105 | 104 | .type = SSPP_TYPE_VIG, |
| 106 | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 108 | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | 108 | .base = 0x24000, .len = 0x1f0, |
| 110 | 109 | .features = DMA_SDM845_MASK, |
| 111 | − .sblk = &sdm845_dma_sblk_0, | |
| 110 | + .sblk = &dpu_dma_sblk, | |
| 112 | 111 | .xin_id = 1, |
| 113 | 112 | .type = SSPP_TYPE_DMA, |
| 114 | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 116 | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | 116 | .base = 0x26000, .len = 0x1f0, |
| 118 | 117 | .features = DMA_SDM845_MASK, |
| 119 | − .sblk = &sdm845_dma_sblk_1, | |
| 118 | + .sblk = &dpu_dma_sblk, | |
| 120 | 119 | .xin_id = 5, |
| 121 | 120 | .type = SSPP_TYPE_DMA, |
| 122 | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 124 | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | 124 | .base = 0x28000, .len = 0x1f0, |
| 126 | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | − .sblk = &sdm845_dma_sblk_2, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 128 | 127 | .xin_id = 9, |
| 129 | 128 | .type = SSPP_TYPE_DMA, |
| 130 | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | ||
| 132 | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | 132 | .base = 0x2a000, .len = 0x1f0, |
| 134 | 133 | .features = DMA_CURSOR_SDM845_MASK, |
| 135 | − .sblk = &sdm845_dma_sblk_3, | |
| 134 | + .sblk = &dpu_dma_sblk, | |
| 136 | 135 | .xin_id = 13, |
| 137 | 136 | .type = SSPP_TYPE_DMA, |
| 138 | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -367,6 +366,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = { · 228 unmodified lines | ||
| 367 | 366 | .min_llcc_ib = 800000, |
| 368 | 367 | .min_dram_ib = 800000, |
| 369 | 368 | .danger_lut_tbl = {0xf, 0xffff, 0x0}, |
| 369 | + .safe_lut_tbl = {0xfff0, 0xf000, 0xffff}, | |
| 370 | 370 | .qos_lut_tbl = { |
| 371 | 371 | {.nentry = ARRAY_SIZE(sc7180_qos_linear), |
| 372 | 372 | .entries = sc7180_qos_linear |
| @@ -68,8 +68,8 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 67 unmodified lines | ||
| 68 | 68 | { |
| 69 | 69 | .name = "sspp_0", .id = SSPP_VIG0, |
| 70 | 70 | .base = 0x4000, .len = 0x1f0, |
| 71 | − .features = VIG_SM6125_MASK, | |
| 72 | − .sblk = &sm6125_vig_sblk_0, | |
| 71 | + .features = VIG_SDM845_MASK, | |
| 72 | + .sblk = &dpu_vig_sblk_qseed3_2_4, | |
| 73 | 73 | .xin_id = 0, |
| 74 | 74 | .type = SSPP_TYPE_VIG, |
| 75 | 75 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line | ||
| 77 | 77 | .name = "sspp_8", .id = SSPP_DMA0, |
| 78 | 78 | .base = 0x24000, .len = 0x1f0, |
| 79 | 79 | .features = DMA_SDM845_MASK, |
| 80 | − .sblk = &sdm845_dma_sblk_0, | |
| 80 | + .sblk = &dpu_dma_sblk, | |
| 81 | 81 | .xin_id = 1, |
| 82 | 82 | .type = SSPP_TYPE_DMA, |
| 83 | 83 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line | ||
| 85 | 85 | .name = "sspp_9", .id = SSPP_DMA1, |
| 86 | 86 | .base = 0x26000, .len = 0x1f0, |
| 87 | 87 | .features = DMA_SDM845_MASK, |
| 88 | − .sblk = &sdm845_dma_sblk_1, | |
| 88 | + .sblk = &dpu_dma_sblk, | |
| 89 | 89 | .xin_id = 5, |
| 90 | 90 | .type = SSPP_TYPE_DMA, |
| 91 | 91 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm8250_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -32,7 +31,7 @@ static const struct dpu_mdp_cfg sm8250_mdp = { · 15 unmodified lines | ||
| 32 | 31 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 33 | 32 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 34 | 33 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, |
| 35 | − [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, | |
| 34 | + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | |
| 36 | 35 | }, |
| 37 | 36 | }; |
| 38 | 37 | |
| @@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 36 unmodified lines | ||
| 75 | 74 | { |
| 76 | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | 76 | .base = 0x4000, .len = 0x1f8, |
| 78 | − .features = VIG_SC7180_MASK_SDMA, | |
| 79 | − .sblk = &sm8250_vig_sblk_0, | |
| 77 | + .features = VIG_SDM845_MASK_SDMA, | |
| 78 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 80 | 79 | .xin_id = 0, |
| 81 | 80 | .type = SSPP_TYPE_VIG, |
| 82 | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | 82 | }, { |
| 84 | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | 84 | .base = 0x6000, .len = 0x1f8, |
| 86 | − .features = VIG_SC7180_MASK_SDMA, | |
| 87 | − .sblk = &sm8250_vig_sblk_1, | |
| 85 | + .features = VIG_SDM845_MASK_SDMA, | |
| 86 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 88 | 87 | .xin_id = 4, |
| 89 | 88 | .type = SSPP_TYPE_VIG, |
| 90 | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | 90 | }, { |
| 92 | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | 92 | .base = 0x8000, .len = 0x1f8, |
| 94 | − .features = VIG_SC7180_MASK_SDMA, | |
| 95 | − .sblk = &sm8250_vig_sblk_2, | |
| 93 | + .features = VIG_SDM845_MASK_SDMA, | |
| 94 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 96 | 95 | .xin_id = 8, |
| 97 | 96 | .type = SSPP_TYPE_VIG, |
| 98 | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | 98 | }, { |
| 100 | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | 100 | .base = 0xa000, .len = 0x1f8, |
| 102 | − .features = VIG_SC7180_MASK_SDMA, | |
| 103 | − .sblk = &sm8250_vig_sblk_3, | |
| 101 | + .features = VIG_SDM845_MASK_SDMA, | |
| 102 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 104 | 103 | .xin_id = 12, |
| 105 | 104 | .type = SSPP_TYPE_VIG, |
| 106 | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | ||
| 108 | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | 108 | .base = 0x24000, .len = 0x1f8, |
| 110 | 109 | .features = DMA_SDM845_MASK_SDMA, |
| 111 | − .sblk = &sdm845_dma_sblk_0, | |
| 110 | + .sblk = &dpu_dma_sblk, | |
| 112 | 111 | .xin_id = 1, |
| 113 | 112 | .type = SSPP_TYPE_DMA, |
| 114 | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | ||
| 116 | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | 116 | .base = 0x26000, .len = 0x1f8, |
| 118 | 117 | .features = DMA_SDM845_MASK_SDMA, |
| 119 | − .sblk = &sdm845_dma_sblk_1, | |
| 118 | + .sblk = &dpu_dma_sblk, | |
| 120 | 119 | .xin_id = 5, |
| 121 | 120 | .type = SSPP_TYPE_DMA, |
| 122 | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | ||
| 124 | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | 124 | .base = 0x28000, .len = 0x1f8, |
| 126 | 125 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 127 | − .sblk = &sdm845_dma_sblk_2, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 128 | 127 | .xin_id = 9, |
| 129 | 128 | .type = SSPP_TYPE_DMA, |
| 130 | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | ||
| 132 | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | 132 | .base = 0x2a000, .len = 0x1f8, |
| 134 | 133 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 135 | − .sblk = &sdm845_dma_sblk_3, | |
| 134 | + .sblk = &dpu_dma_sblk, | |
| 136 | 135 | .xin_id = 13, |
| 137 | 136 | .type = SSPP_TYPE_DMA, |
| 138 | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -337,8 +336,8 @@ static const struct dpu_wb_cfg sm8250_wb[] = { · 198 unmodified lines | ||
| 337 | 336 | .name = "wb_2", .id = WB_2, |
| 338 | 337 | .base = 0x65000, .len = 0x2c8, |
| 339 | 338 | .features = WB_SM8250_MASK, |
| 340 | − .format_list = wb2_formats, | |
| 341 | − .num_formats = ARRAY_SIZE(wb2_formats), | |
| 339 | + .format_list = wb2_formats_rgb_yuv, | |
| 340 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), | |
| 342 | 341 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 343 | 342 | .xin_id = 6, |
| 344 | 343 | .vbif_idx = VBIF_RT, |
| @@ -385,6 +384,7 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { · 40 unmodified lines | ||
| 385 | 384 | .mdss_ver = &sm8250_mdss_ver, |
| 386 | 385 | .caps = &sm8250_dpu_caps, |
| 387 | 386 | .mdp = &sm8250_mdp, |
| 387 | + .cdm = &sc7280_cdm, | |
| 388 | 388 | .ctl_count = ARRAY_SIZE(sm8250_ctl), |
| 389 | 389 | .ctl = sm8250_ctl, |
| 390 | 390 | .sspp_count = ARRAY_SIZE(sm8250_sspp), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sc7180_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0x9, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_dim_layer = true, |
| 15 | 14 | .has_idle_pc = true, |
| 16 | 15 | .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| @@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7180_mdp = { · 8 unmodified lines | ||
| 25 | 24 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, |
| 26 | 25 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 27 | 26 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 28 | − [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, | |
| 27 | + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | |
| 29 | 28 | }, |
| 30 | 29 | }; |
| 31 | 30 | |
| @@ -52,8 +51,8 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 20 unmodified lines | ||
| 52 | 51 | { |
| 53 | 52 | .name = "sspp_0", .id = SSPP_VIG0, |
| 54 | 53 | .base = 0x4000, .len = 0x1f8, |
| 55 | − .features = VIG_SC7180_MASK, | |
| 56 | − .sblk = &sc7180_vig_sblk_0, | |
| 54 | + .features = VIG_SDM845_MASK, | |
| 55 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 57 | 56 | .xin_id = 0, |
| 58 | 57 | .type = SSPP_TYPE_VIG, |
| 59 | 58 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -61,7 +60,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | ||
| 61 | 60 | .name = "sspp_8", .id = SSPP_DMA0, |
| 62 | 61 | .base = 0x24000, .len = 0x1f8, |
| 63 | 62 | .features = DMA_SDM845_MASK, |
| 64 | − .sblk = &sdm845_dma_sblk_0, | |
| 63 | + .sblk = &dpu_dma_sblk, | |
| 65 | 64 | .xin_id = 1, |
| 66 | 65 | .type = SSPP_TYPE_DMA, |
| 67 | 66 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -69,7 +68,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | ||
| 69 | 68 | .name = "sspp_9", .id = SSPP_DMA1, |
| 70 | 69 | .base = 0x26000, .len = 0x1f8, |
| 71 | 70 | .features = DMA_CURSOR_SDM845_MASK, |
| 72 | − .sblk = &sdm845_dma_sblk_1, | |
| 71 | + .sblk = &dpu_dma_sblk, | |
| 73 | 72 | .xin_id = 5, |
| 74 | 73 | .type = SSPP_TYPE_DMA, |
| 75 | 74 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | ||
| 77 | 76 | .name = "sspp_10", .id = SSPP_DMA2, |
| 78 | 77 | .base = 0x28000, .len = 0x1f8, |
| 79 | 78 | .features = DMA_CURSOR_SDM845_MASK, |
| 80 | − .sblk = &sdm845_dma_sblk_2, | |
| 79 | + .sblk = &dpu_dma_sblk, | |
| 81 | 80 | .xin_id = 9, |
| 82 | 81 | .type = SSPP_TYPE_DMA, |
| 83 | 82 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -158,8 +157,8 @@ static const struct dpu_wb_cfg sc7180_wb[] = { · 74 unmodified lines | ||
| 158 | 157 | .name = "wb_2", .id = WB_2, |
| 159 | 158 | .base = 0x65000, .len = 0x2c8, |
| 160 | 159 | .features = WB_SM8250_MASK, |
| 161 | − .format_list = wb2_formats, | |
| 162 | − .num_formats = ARRAY_SIZE(wb2_formats), | |
| 160 | + .format_list = wb2_formats_rgb, | |
| 161 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb), | |
| 163 | 162 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 164 | 163 | .xin_id = 6, |
| 165 | 164 | .vbif_idx = VBIF_RT, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm6115_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0x4, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_dim_layer = true, |
| 15 | 14 | .has_idle_pc = true, |
| 16 | 15 | .max_linewidth = 2160, |
| @@ -39,8 +38,8 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 22 unmodified lines | ||
| 39 | 38 | { |
| 40 | 39 | .name = "sspp_0", .id = SSPP_VIG0, |
| 41 | 40 | .base = 0x4000, .len = 0x1f8, |
| 42 | − .features = VIG_SC7180_MASK, | |
| 43 | − .sblk = &sm6115_vig_sblk_0, | |
| 41 | + .features = VIG_SDM845_MASK, | |
| 42 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 44 | 43 | .xin_id = 0, |
| 45 | 44 | .type = SSPP_TYPE_VIG, |
| 46 | 45 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -48,7 +47,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 1 unmodified line | ||
| 48 | 47 | .name = "sspp_8", .id = SSPP_DMA0, |
| 49 | 48 | .base = 0x24000, .len = 0x1f8, |
| 50 | 49 | .features = DMA_SDM845_MASK, |
| 51 | − .sblk = &sdm845_dma_sblk_0, | |
| 50 | + .sblk = &dpu_dma_sblk, | |
| 52 | 51 | .xin_id = 1, |
| 53 | 52 | .type = SSPP_TYPE_DMA, |
| 54 | 53 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | static const struct dpu_caps sm6350_dpu_caps = { |
| 12 | 12 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 13 | 13 | .max_mixer_blendstages = 0x7, |
| 14 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 15 | 14 | .has_src_split = true, |
| 16 | 15 | .has_dim_layer = true, |
| 17 | 16 | .has_idle_pc = true, |
| @@ -59,8 +58,8 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 41 unmodified lines | ||
| 59 | 58 | { |
| 60 | 59 | .name = "sspp_0", .id = SSPP_VIG0, |
| 61 | 60 | .base = 0x4000, .len = 0x1f8, |
| 62 | − .features = VIG_SC7180_MASK, | |
| 63 | − .sblk = &sc7180_vig_sblk_0, | |
| 61 | + .features = VIG_SDM845_MASK, | |
| 62 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 64 | 63 | .xin_id = 0, |
| 65 | 64 | .type = SSPP_TYPE_VIG, |
| 66 | 65 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | ||
| 68 | 67 | .name = "sspp_8", .id = SSPP_DMA0, |
| 69 | 68 | .base = 0x24000, .len = 0x1f8, |
| 70 | 69 | .features = DMA_SDM845_MASK, |
| 71 | − .sblk = &sdm845_dma_sblk_0, | |
| 70 | + .sblk = &dpu_dma_sblk, | |
| 72 | 71 | .xin_id = 1, |
| 73 | 72 | .type = SSPP_TYPE_DMA, |
| 74 | 73 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | ||
| 76 | 75 | .name = "sspp_9", .id = SSPP_DMA1, |
| 77 | 76 | .base = 0x26000, .len = 0x1f8, |
| 78 | 77 | .features = DMA_CURSOR_SDM845_MASK, |
| 79 | − .sblk = &sdm845_dma_sblk_1, | |
| 78 | + .sblk = &dpu_dma_sblk, | |
| 80 | 79 | .xin_id = 5, |
| 81 | 80 | .type = SSPP_TYPE_DMA, |
| 82 | 81 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | ||
| 84 | 83 | .name = "sspp_10", .id = SSPP_DMA2, |
| 85 | 84 | .base = 0x28000, .len = 0x1f8, |
| 86 | 85 | .features = DMA_CURSOR_SDM845_MASK, |
| 87 | − .sblk = &sdm845_dma_sblk_2, | |
| 86 | + .sblk = &dpu_dma_sblk, | |
| 88 | 87 | .xin_id = 9, |
| 89 | 88 | .type = SSPP_TYPE_DMA, |
| 90 | 89 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 38 unmodified lines | ||
| 39 | 39 | .name = "sspp_0", .id = SSPP_VIG0, |
| 40 | 40 | .base = 0x4000, .len = 0x1f8, |
| 41 | 41 | .features = VIG_QCM2290_MASK, |
| 42 | − .sblk = &qcm2290_vig_sblk_0, | |
| 42 | + .sblk = &dpu_vig_sblk_noscale, | |
| 43 | 43 | .xin_id = 0, |
| 44 | 44 | .type = SSPP_TYPE_VIG, |
| 45 | 45 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 1 unmodified line | ||
| 47 | 47 | .name = "sspp_8", .id = SSPP_DMA0, |
| 48 | 48 | .base = 0x24000, .len = 0x1f8, |
| 49 | 49 | .features = DMA_SDM845_MASK, |
| 50 | − .sblk = &qcm2290_dma_sblk_0, | |
| 50 | + .sblk = &dpu_dma_sblk, | |
| 51 | 51 | .xin_id = 1, |
| 52 | 52 | .type = SSPP_TYPE_DMA, |
| 53 | 53 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | static const struct dpu_caps sm6375_dpu_caps = { |
| 12 | 12 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, |
| 13 | 13 | .max_mixer_blendstages = 0x4, |
| 14 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| 17 | 16 | .max_linewidth = 2160, |
| @@ -40,8 +39,8 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 22 unmodified lines | ||
| 40 | 39 | { |
| 41 | 40 | .name = "sspp_0", .id = SSPP_VIG0, |
| 42 | 41 | .base = 0x4000, .len = 0x1f8, |
| 43 | − .features = VIG_SC7180_MASK, | |
| 44 | − .sblk = &sm6115_vig_sblk_0, | |
| 42 | + .features = VIG_SDM845_MASK, | |
| 43 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 45 | 44 | .xin_id = 0, |
| 46 | 45 | .type = SSPP_TYPE_VIG, |
| 47 | 46 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -49,7 +48,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 1 unmodified line | ||
| 49 | 48 | .name = "sspp_8", .id = SSPP_DMA0, |
| 50 | 49 | .base = 0x24000, .len = 0x1f8, |
| 51 | 50 | .features = DMA_SDM845_MASK, |
| 52 | − .sblk = &sdm845_dma_sblk_0, | |
| 51 | + .sblk = &dpu_dma_sblk, | |
| 53 | 52 | .xin_id = 1, |
| 54 | 53 | .type = SSPP_TYPE_DMA, |
| 55 | 54 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm8350_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -31,6 +30,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = { · 14 unmodified lines | ||
| 31 | 30 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 32 | 31 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 33 | 32 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 33 | + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | |
| 34 | 34 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, |
| 35 | 35 | }, |
| 36 | 36 | }; |
| @@ -74,64 +74,64 @@ static const struct dpu_sspp_cfg sm8350_sspp[] = { · 37 unmodified lines | ||
| 74 | 74 | { |
| 75 | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 76 | 76 | .base = 0x4000, .len = 0x1f8, |
| 77 | − .features = VIG_SC7180_MASK, | |
| 78 | − .sblk = &sm8250_vig_sblk_0, | |
| 77 | + .features = VIG_SDM845_MASK_SDMA, | |
| 78 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 79 | 79 | .xin_id = 0, |
| 80 | 80 | .type = SSPP_TYPE_VIG, |
| 81 | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 82 | 82 | }, { |
| 83 | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 84 | 84 | .base = 0x6000, .len = 0x1f8, |
| 85 | − .features = VIG_SC7180_MASK, | |
| 86 | − .sblk = &sm8250_vig_sblk_1, | |
| 85 | + .features = VIG_SDM845_MASK_SDMA, | |
| 86 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 87 | 87 | .xin_id = 4, |
| 88 | 88 | .type = SSPP_TYPE_VIG, |
| 89 | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 90 | 90 | }, { |
| 91 | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 92 | 92 | .base = 0x8000, .len = 0x1f8, |
| 93 | − .features = VIG_SC7180_MASK, | |
| 94 | − .sblk = &sm8250_vig_sblk_2, | |
| 93 | + .features = VIG_SDM845_MASK_SDMA, | |
| 94 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 95 | 95 | .xin_id = 8, |
| 96 | 96 | .type = SSPP_TYPE_VIG, |
| 97 | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 98 | 98 | }, { |
| 99 | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 100 | 100 | .base = 0xa000, .len = 0x1f8, |
| 101 | − .features = VIG_SC7180_MASK, | |
| 102 | − .sblk = &sm8250_vig_sblk_3, | |
| 101 | + .features = VIG_SDM845_MASK_SDMA, | |
| 102 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 103 | 103 | .xin_id = 12, |
| 104 | 104 | .type = SSPP_TYPE_VIG, |
| 105 | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| 106 | 106 | }, { |
| 107 | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 108 | 108 | .base = 0x24000, .len = 0x1f8, |
| 109 | − .features = DMA_SDM845_MASK, | |
| 110 | − .sblk = &sdm845_dma_sblk_0, | |
| 109 | + .features = DMA_SDM845_MASK_SDMA, | |
| 110 | + .sblk = &dpu_dma_sblk, | |
| 111 | 111 | .xin_id = 1, |
| 112 | 112 | .type = SSPP_TYPE_DMA, |
| 113 | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| 114 | 114 | }, { |
| 115 | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 116 | 116 | .base = 0x26000, .len = 0x1f8, |
| 117 | − .features = DMA_SDM845_MASK, | |
| 118 | − .sblk = &sdm845_dma_sblk_1, | |
| 117 | + .features = DMA_SDM845_MASK_SDMA, | |
| 118 | + .sblk = &dpu_dma_sblk, | |
| 119 | 119 | .xin_id = 5, |
| 120 | 120 | .type = SSPP_TYPE_DMA, |
| 121 | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| 122 | 122 | }, { |
| 123 | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 124 | 124 | .base = 0x28000, .len = 0x1f8, |
| 125 | − .features = DMA_CURSOR_SDM845_MASK, | |
| 126 | − .sblk = &sdm845_dma_sblk_2, | |
| 125 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 127 | 127 | .xin_id = 9, |
| 128 | 128 | .type = SSPP_TYPE_DMA, |
| 129 | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| 130 | 130 | }, { |
| 131 | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 132 | 132 | .base = 0x2a000, .len = 0x1f8, |
| 133 | − .features = DMA_CURSOR_SDM845_MASK, | |
| 134 | − .sblk = &sdm845_dma_sblk_3, | |
| 133 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 134 | + .sblk = &dpu_dma_sblk, | |
| 135 | 135 | .xin_id = 13, |
| 136 | 136 | .type = SSPP_TYPE_DMA, |
| 137 | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -298,6 +298,21 @@ static const struct dpu_dsc_cfg sm8350_dsc[] = { · 160 unmodified lines | ||
| 298 | 298 | }, |
| 299 | 299 | }; |
| 300 | 300 | |
| 301 | +static const struct dpu_wb_cfg sm8350_wb[] = { | |
| 302 | + { | |
| 303 | + .name = "wb_2", .id = WB_2, | |
| 304 | + .base = 0x65000, .len = 0x2c8, | |
| 305 | + .features = WB_SM8250_MASK, | |
| 306 | + .format_list = wb2_formats_rgb, | |
| 307 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb), | |
| 308 | + .clk_ctrl = DPU_CLK_CTRL_WB2, | |
| 309 | + .xin_id = 6, | |
| 310 | + .vbif_idx = VBIF_RT, | |
| 311 | + .maxlinewidth = 4096, | |
| 312 | + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), | |
| 313 | + }, | |
| 314 | +}; | |
| 315 | + | |
| 301 | 316 | static const struct dpu_intf_cfg sm8350_intf[] = { |
| 302 | 317 | { |
| 303 | 318 | .name = "intf_0", .id = INTF_0, |
| @@ -393,6 +408,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { · 89 unmodified lines | ||
| 393 | 408 | .dsc = sm8350_dsc, |
| 394 | 409 | .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), |
| 395 | 410 | .merge_3d = sm8350_merge_3d, |
| 411 | + .wb_count = ARRAY_SIZE(sm8350_wb), | |
| 412 | + .wb = sm8350_wb, | |
| 396 | 413 | .intf_count = ARRAY_SIZE(sm8350_intf), |
| 397 | 414 | .intf = sm8350_intf, |
| 398 | 415 | .vbif_count = ARRAY_SIZE(sdm845_vbif), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sc7280_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0x7, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_dim_layer = true, |
| 15 | 14 | .has_idle_pc = true, |
| 16 | 15 | .max_linewidth = 2400, |
| @@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7280_mdp = { · 8 unmodified lines | ||
| 25 | 24 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, |
| 26 | 25 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 27 | 26 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 28 | − [DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, | |
| 27 | + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | |
| 29 | 28 | }, |
| 30 | 29 | }; |
| 31 | 30 | |
| @@ -58,7 +57,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 26 unmodified lines | ||
| 58 | 57 | .name = "sspp_0", .id = SSPP_VIG0, |
| 59 | 58 | .base = 0x4000, .len = 0x1f8, |
| 60 | 59 | .features = VIG_SC7280_MASK_SDMA, |
| 61 | − .sblk = &sc7280_vig_sblk_0, | |
| 60 | + .sblk = &dpu_vig_sblk_qseed3_3_0_rot_v2, | |
| 62 | 61 | .xin_id = 0, |
| 63 | 62 | .type = SSPP_TYPE_VIG, |
| 64 | 63 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -66,7 +65,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | ||
| 66 | 65 | .name = "sspp_8", .id = SSPP_DMA0, |
| 67 | 66 | .base = 0x24000, .len = 0x1f8, |
| 68 | 67 | .features = DMA_SDM845_MASK_SDMA, |
| 69 | − .sblk = &sdm845_dma_sblk_0, | |
| 68 | + .sblk = &dpu_dma_sblk, | |
| 70 | 69 | .xin_id = 1, |
| 71 | 70 | .type = SSPP_TYPE_DMA, |
| 72 | 71 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | ||
| 74 | 73 | .name = "sspp_9", .id = SSPP_DMA1, |
| 75 | 74 | .base = 0x26000, .len = 0x1f8, |
| 76 | 75 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 77 | − .sblk = &sdm845_dma_sblk_1, | |
| 76 | + .sblk = &dpu_dma_sblk, | |
| 78 | 77 | .xin_id = 5, |
| 79 | 78 | .type = SSPP_TYPE_DMA, |
| 80 | 79 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | ||
| 82 | 81 | .name = "sspp_10", .id = SSPP_DMA2, |
| 83 | 82 | .base = 0x28000, .len = 0x1f8, |
| 84 | 83 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 85 | − .sblk = &sdm845_dma_sblk_2, | |
| 84 | + .sblk = &dpu_dma_sblk, | |
| 86 | 85 | .xin_id = 9, |
| 87 | 86 | .type = SSPP_TYPE_DMA, |
| 88 | 87 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -170,8 +169,8 @@ static const struct dpu_wb_cfg sc7280_wb[] = { · 81 unmodified lines | ||
| 170 | 169 | .name = "wb_2", .id = WB_2, |
| 171 | 170 | .base = 0x65000, .len = 0x2c8, |
| 172 | 171 | .features = WB_SM8250_MASK, |
| 173 | − .format_list = wb2_formats, | |
| 174 | − .num_formats = ARRAY_SIZE(wb2_formats), | |
| 172 | + .format_list = wb2_formats_rgb_yuv, | |
| 173 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), | |
| 175 | 174 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 176 | 175 | .xin_id = 6, |
| 177 | 176 | .vbif_idx = VBIF_RT, |
| @@ -249,6 +248,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { · 71 unmodified lines | ||
| 249 | 248 | .mdss_ver = &sc7280_mdss_ver, |
| 250 | 249 | .caps = &sc7280_dpu_caps, |
| 251 | 250 | .mdp = &sc7280_mdp, |
| 251 | + .cdm = &sc7280_cdm, | |
| 252 | 252 | .ctl_count = ARRAY_SIZE(sc7280_ctl), |
| 253 | 253 | .ctl = sc7280_ctl, |
| 254 | 254 | .sspp_count = ARRAY_SIZE(sc7280_sspp), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sc8280xp_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 11, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 58 unmodified lines | ||
| 75 | 74 | { |
| 76 | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | 76 | .base = 0x4000, .len = 0x2ac, |
| 78 | − .features = VIG_SC7180_MASK, | |
| 79 | − .sblk = &sm8250_vig_sblk_0, | |
| 77 | + .features = VIG_SDM845_MASK, | |
| 78 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 80 | 79 | .xin_id = 0, |
| 81 | 80 | .type = SSPP_TYPE_VIG, |
| 82 | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | 82 | }, { |
| 84 | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | 84 | .base = 0x6000, .len = 0x2ac, |
| 86 | − .features = VIG_SC7180_MASK, | |
| 87 | − .sblk = &sm8250_vig_sblk_1, | |
| 85 | + .features = VIG_SDM845_MASK, | |
| 86 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 88 | 87 | .xin_id = 4, |
| 89 | 88 | .type = SSPP_TYPE_VIG, |
| 90 | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | 90 | }, { |
| 92 | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | 92 | .base = 0x8000, .len = 0x2ac, |
| 94 | − .features = VIG_SC7180_MASK, | |
| 95 | − .sblk = &sm8250_vig_sblk_2, | |
| 93 | + .features = VIG_SDM845_MASK, | |
| 94 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 96 | 95 | .xin_id = 8, |
| 97 | 96 | .type = SSPP_TYPE_VIG, |
| 98 | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | 98 | }, { |
| 100 | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | 100 | .base = 0xa000, .len = 0x2ac, |
| 102 | − .features = VIG_SC7180_MASK, | |
| 103 | − .sblk = &sm8250_vig_sblk_3, | |
| 101 | + .features = VIG_SDM845_MASK, | |
| 102 | + .sblk = &dpu_vig_sblk_qseed3_3_0, | |
| 104 | 103 | .xin_id = 12, |
| 105 | 104 | .type = SSPP_TYPE_VIG, |
| 106 | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | ||
| 108 | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | 108 | .base = 0x24000, .len = 0x2ac, |
| 110 | 109 | .features = DMA_SDM845_MASK, |
| 111 | − .sblk = &sdm845_dma_sblk_0, | |
| 110 | + .sblk = &dpu_dma_sblk, | |
| 112 | 111 | .xin_id = 1, |
| 113 | 112 | .type = SSPP_TYPE_DMA, |
| 114 | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | ||
| 116 | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | 116 | .base = 0x26000, .len = 0x2ac, |
| 118 | 117 | .features = DMA_SDM845_MASK, |
| 119 | − .sblk = &sdm845_dma_sblk_1, | |
| 118 | + .sblk = &dpu_dma_sblk, | |
| 120 | 119 | .xin_id = 5, |
| 121 | 120 | .type = SSPP_TYPE_DMA, |
| 122 | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | ||
| 124 | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | 124 | .base = 0x28000, .len = 0x2ac, |
| 126 | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | − .sblk = &sdm845_dma_sblk_2, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 128 | 127 | .xin_id = 9, |
| 129 | 128 | .type = SSPP_TYPE_DMA, |
| 130 | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | ||
| 132 | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | 132 | .base = 0x2a000, .len = 0x2ac, |
| 134 | 133 | .features = DMA_CURSOR_SDM845_MASK, |
| 135 | − .sblk = &sdm845_dma_sblk_3, | |
| 134 | + .sblk = &dpu_dma_sblk, | |
| 136 | 135 | .xin_id = 13, |
| 137 | 136 | .type = SSPP_TYPE_DMA, |
| 138 | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm8450_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -32,6 +31,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = { · 15 unmodified lines | ||
| 32 | 31 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 33 | 32 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 34 | 33 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 34 | + [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | |
| 35 | 35 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, |
| 36 | 36 | }, |
| 37 | 37 | }; |
| @@ -75,64 +75,64 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = { · 37 unmodified lines | ||
| 75 | 75 | { |
| 76 | 76 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | 77 | .base = 0x4000, .len = 0x32c, |
| 78 | − .features = VIG_SC7180_MASK, | |
| 79 | − .sblk = &sm8250_vig_sblk_0, | |
| 78 | + .features = VIG_SDM845_MASK_SDMA, | |
| 79 | + .sblk = &dpu_vig_sblk_qseed3_3_1, | |
| 80 | 80 | .xin_id = 0, |
| 81 | 81 | .type = SSPP_TYPE_VIG, |
| 82 | 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | 83 | }, { |
| 84 | 84 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | 85 | .base = 0x6000, .len = 0x32c, |
| 86 | − .features = VIG_SC7180_MASK, | |
| 87 | − .sblk = &sm8250_vig_sblk_1, | |
| 86 | + .features = VIG_SDM845_MASK_SDMA, | |
| 87 | + .sblk = &dpu_vig_sblk_qseed3_3_1, | |
| 88 | 88 | .xin_id = 4, |
| 89 | 89 | .type = SSPP_TYPE_VIG, |
| 90 | 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | 91 | }, { |
| 92 | 92 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | 93 | .base = 0x8000, .len = 0x32c, |
| 94 | − .features = VIG_SC7180_MASK, | |
| 95 | − .sblk = &sm8250_vig_sblk_2, | |
| 94 | + .features = VIG_SDM845_MASK_SDMA, | |
| 95 | + .sblk = &dpu_vig_sblk_qseed3_3_1, | |
| 96 | 96 | .xin_id = 8, |
| 97 | 97 | .type = SSPP_TYPE_VIG, |
| 98 | 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | 99 | }, { |
| 100 | 100 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | 101 | .base = 0xa000, .len = 0x32c, |
| 102 | − .features = VIG_SC7180_MASK, | |
| 103 | − .sblk = &sm8250_vig_sblk_3, | |
| 102 | + .features = VIG_SDM845_MASK_SDMA, | |
| 103 | + .sblk = &dpu_vig_sblk_qseed3_3_1, | |
| 104 | 104 | .xin_id = 12, |
| 105 | 105 | .type = SSPP_TYPE_VIG, |
| 106 | 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| 107 | 107 | }, { |
| 108 | 108 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | 109 | .base = 0x24000, .len = 0x32c, |
| 110 | − .features = DMA_SDM845_MASK, | |
| 111 | − .sblk = &sdm845_dma_sblk_0, | |
| 110 | + .features = DMA_SDM845_MASK_SDMA, | |
| 111 | + .sblk = &dpu_dma_sblk, | |
| 112 | 112 | .xin_id = 1, |
| 113 | 113 | .type = SSPP_TYPE_DMA, |
| 114 | 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| 115 | 115 | }, { |
| 116 | 116 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | 117 | .base = 0x26000, .len = 0x32c, |
| 118 | − .features = DMA_SDM845_MASK, | |
| 119 | − .sblk = &sdm845_dma_sblk_1, | |
| 118 | + .features = DMA_SDM845_MASK_SDMA, | |
| 119 | + .sblk = &dpu_dma_sblk, | |
| 120 | 120 | .xin_id = 5, |
| 121 | 121 | .type = SSPP_TYPE_DMA, |
| 122 | 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| 123 | 123 | }, { |
| 124 | 124 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | 125 | .base = 0x28000, .len = 0x32c, |
| 126 | − .features = DMA_CURSOR_SDM845_MASK, | |
| 127 | − .sblk = &sdm845_dma_sblk_2, | |
| 126 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 127 | + .sblk = &dpu_dma_sblk, | |
| 128 | 128 | .xin_id = 9, |
| 129 | 129 | .type = SSPP_TYPE_DMA, |
| 130 | 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| 131 | 131 | }, { |
| 132 | 132 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | 133 | .base = 0x2a000, .len = 0x32c, |
| 134 | − .features = DMA_CURSOR_SDM845_MASK, | |
| 135 | − .sblk = &sdm845_dma_sblk_3, | |
| 134 | + .features = DMA_CURSOR_SDM845_MASK_SDMA, | |
| 135 | + .sblk = &dpu_dma_sblk, | |
| 136 | 136 | .xin_id = 13, |
| 137 | 137 | .type = SSPP_TYPE_DMA, |
| 138 | 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -316,6 +316,21 @@ static const struct dpu_dsc_cfg sm8450_dsc[] = { · 177 unmodified lines | ||
| 316 | 316 | }, |
| 317 | 317 | }; |
| 318 | 318 | |
| 319 | +static const struct dpu_wb_cfg sm8450_wb[] = { | |
| 320 | + { | |
| 321 | + .name = "wb_2", .id = WB_2, | |
| 322 | + .base = 0x65000, .len = 0x2c8, | |
| 323 | + .features = WB_SM8250_MASK, | |
| 324 | + .format_list = wb2_formats_rgb, | |
| 325 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb), | |
| 326 | + .clk_ctrl = DPU_CLK_CTRL_WB2, | |
| 327 | + .xin_id = 6, | |
| 328 | + .vbif_idx = VBIF_RT, | |
| 329 | + .maxlinewidth = 4096, | |
| 330 | + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), | |
| 331 | + }, | |
| 332 | +}; | |
| 333 | + | |
| 319 | 334 | static const struct dpu_intf_cfg sm8450_intf[] = { |
| 320 | 335 | { |
| 321 | 336 | .name = "intf_0", .id = INTF_0, |
| @@ -411,6 +426,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { · 89 unmodified lines | ||
| 411 | 426 | .dsc = sm8450_dsc, |
| 412 | 427 | .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), |
| 413 | 428 | .merge_3d = sm8450_merge_3d, |
| 429 | + .wb_count = ARRAY_SIZE(sm8450_wb), | |
| 430 | + .wb = sm8450_wb, | |
| 414 | 431 | .intf_count = ARRAY_SIZE(sm8450_intf), |
| 415 | 432 | .intf = sm8450_intf, |
| 416 | 433 | .vbif_count = ARRAY_SIZE(sdm845_vbif), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | static const struct dpu_caps sm8550_dpu_caps = { |
| 11 | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | 12 | .max_mixer_blendstages = 0xb, |
| 13 | − .qseed_type = DPU_SSPP_SCALER_QSEED4, | |
| 14 | 13 | .has_src_split = true, |
| 15 | 14 | .has_dim_layer = true, |
| 16 | 15 | .has_idle_pc = true, |
| @@ -67,71 +66,71 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = { · 50 unmodified lines | ||
| 67 | 66 | { |
| 68 | 67 | .name = "sspp_0", .id = SSPP_VIG0, |
| 69 | 68 | .base = 0x4000, .len = 0x344, |
| 70 | − .features = VIG_SC7180_MASK, | |
| 71 | − .sblk = &sm8550_vig_sblk_0, | |
| 69 | + .features = VIG_SDM845_MASK, | |
| 70 | + .sblk = &dpu_vig_sblk_qseed3_3_2, | |
| 72 | 71 | .xin_id = 0, |
| 73 | 72 | .type = SSPP_TYPE_VIG, |
| 74 | 73 | }, { |
| 75 | 74 | .name = "sspp_1", .id = SSPP_VIG1, |
| 76 | 75 | .base = 0x6000, .len = 0x344, |
| 77 | − .features = VIG_SC7180_MASK, | |
| 78 | − .sblk = &sm8550_vig_sblk_1, | |
| 76 | + .features = VIG_SDM845_MASK, | |
| 77 | + .sblk = &dpu_vig_sblk_qseed3_3_2, | |
| 79 | 78 | .xin_id = 4, |
| 80 | 79 | .type = SSPP_TYPE_VIG, |
| 81 | 80 | }, { |
| 82 | 81 | .name = "sspp_2", .id = SSPP_VIG2, |
| 83 | 82 | .base = 0x8000, .len = 0x344, |
| 84 | − .features = VIG_SC7180_MASK, | |
| 85 | − .sblk = &sm8550_vig_sblk_2, | |
| 83 | + .features = VIG_SDM845_MASK, | |
| 84 | + .sblk = &dpu_vig_sblk_qseed3_3_2, | |
| 86 | 85 | .xin_id = 8, |
| 87 | 86 | .type = SSPP_TYPE_VIG, |
| 88 | 87 | }, { |
| 89 | 88 | .name = "sspp_3", .id = SSPP_VIG3, |
| 90 | 89 | .base = 0xa000, .len = 0x344, |
| 91 | − .features = VIG_SC7180_MASK, | |
| 92 | − .sblk = &sm8550_vig_sblk_3, | |
| 90 | + .features = VIG_SDM845_MASK, | |
| 91 | + .sblk = &dpu_vig_sblk_qseed3_3_2, | |
| 93 | 92 | .xin_id = 12, |
| 94 | 93 | .type = SSPP_TYPE_VIG, |
| 95 | 94 | }, { |
| 96 | 95 | .name = "sspp_8", .id = SSPP_DMA0, |
| 97 | 96 | .base = 0x24000, .len = 0x344, |
| 98 | 97 | .features = DMA_SDM845_MASK, |
| 99 | − .sblk = &sdm845_dma_sblk_0, | |
| 98 | + .sblk = &dpu_dma_sblk, | |
| 100 | 99 | .xin_id = 1, |
| 101 | 100 | .type = SSPP_TYPE_DMA, |
| 102 | 101 | }, { |
| 103 | 102 | .name = "sspp_9", .id = SSPP_DMA1, |
| 104 | 103 | .base = 0x26000, .len = 0x344, |
| 105 | 104 | .features = DMA_SDM845_MASK, |
| 106 | − .sblk = &sdm845_dma_sblk_1, | |
| 105 | + .sblk = &dpu_dma_sblk, | |
| 107 | 106 | .xin_id = 5, |
| 108 | 107 | .type = SSPP_TYPE_DMA, |
| 109 | 108 | }, { |
| 110 | 109 | .name = "sspp_10", .id = SSPP_DMA2, |
| 111 | 110 | .base = 0x28000, .len = 0x344, |
| 112 | 111 | .features = DMA_SDM845_MASK, |
| 113 | − .sblk = &sdm845_dma_sblk_2, | |
| 112 | + .sblk = &dpu_dma_sblk, | |
| 114 | 113 | .xin_id = 9, |
| 115 | 114 | .type = SSPP_TYPE_DMA, |
| 116 | 115 | }, { |
| 117 | 116 | .name = "sspp_11", .id = SSPP_DMA3, |
| 118 | 117 | .base = 0x2a000, .len = 0x344, |
| 119 | 118 | .features = DMA_SDM845_MASK, |
| 120 | − .sblk = &sdm845_dma_sblk_3, | |
| 119 | + .sblk = &dpu_dma_sblk, | |
| 121 | 120 | .xin_id = 13, |
| 122 | 121 | .type = SSPP_TYPE_DMA, |
| 123 | 122 | }, { |
| 124 | 123 | .name = "sspp_12", .id = SSPP_DMA4, |
| 125 | 124 | .base = 0x2c000, .len = 0x344, |
| 126 | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | − .sblk = &sm8550_dma_sblk_4, | |
| 126 | + .sblk = &dpu_dma_sblk, | |
| 128 | 127 | .xin_id = 14, |
| 129 | 128 | .type = SSPP_TYPE_DMA, |
| 130 | 129 | }, { |
| 131 | 130 | .name = "sspp_13", .id = SSPP_DMA5, |
| 132 | 131 | .base = 0x2e000, .len = 0x344, |
| 133 | 132 | .features = DMA_CURSOR_SDM845_MASK, |
| 134 | − .sblk = &sm8550_dma_sblk_5, | |
| 133 | + .sblk = &dpu_dma_sblk, | |
| 135 | 134 | .xin_id = 15, |
| 136 | 135 | .type = SSPP_TYPE_DMA, |
| 137 | 136 | }, |
| @@ -316,8 +315,8 @@ static const struct dpu_wb_cfg sm8550_wb[] = { · 178 unmodified lines | ||
| 316 | 315 | .name = "wb_2", .id = WB_2, |
| 317 | 316 | .base = 0x65000, .len = 0x2c8, |
| 318 | 317 | .features = WB_SM8250_MASK, |
| 319 | − .format_list = wb2_formats, | |
| 320 | − .num_formats = ARRAY_SIZE(wb2_formats), | |
| 318 | + .format_list = wb2_formats_rgb, | |
| 319 | + .num_formats = ARRAY_SIZE(wb2_formats_rgb), | |
| 321 | 320 | .xin_id = 6, |
| 322 | 321 | .vbif_idx = VBIF_RT, |
| 323 | 322 | .maxlinewidth = 4096, |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. |
| 5 | 5 | * Copyright (C) 2013 Red Hat |
| 6 | 6 | * Author: Rob Clark <robdclark@gmail.com> |
| @@ -51,17 +51,6 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) · 44 unmodified lines | ||
| 51 | 51 | return to_dpu_kms(priv->kms); |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | −static void dpu_crtc_destroy(struct drm_crtc *crtc) | |
| 55 | −{ | |
| 56 | − struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); | |
| 57 | − | |
| 58 | − if (!crtc) | |
| 59 | − return; | |
| 60 | − | |
| 61 | − drm_crtc_cleanup(crtc); | |
| 62 | − kfree(dpu_crtc); | |
| 63 | −} | |
| 64 | − | |
| 65 | 54 | static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) |
| 66 | 55 | { |
| 67 | 56 | struct drm_device *dev = crtc->dev; |
| @@ -125,7 +114,7 @@ static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state) · 57 unmodified lines | ||
| 125 | 114 | continue; |
| 126 | 115 | |
| 127 | 116 | /* Calculate MISR over 1 frame */ |
| 128 | − m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); | |
| 117 | + m->hw_lm->ops.setup_misr(m->hw_lm); | |
| 129 | 118 | } |
| 130 | 119 | } |
| 131 | 120 | |
| @@ -1435,7 +1424,6 @@ static int dpu_crtc_late_register(struct drm_crtc *crtc) · 1303 unmodified lines | ||
| 1435 | 1424 | |
| 1436 | 1425 | static const struct drm_crtc_funcs dpu_crtc_funcs = { |
| 1437 | 1426 | .set_config = drm_atomic_helper_set_config, |
| 1438 | − .destroy = dpu_crtc_destroy, | |
| 1439 | 1427 | .page_flip = drm_atomic_helper_page_flip, |
| 1440 | 1428 | .reset = dpu_crtc_reset, |
| 1441 | 1429 | .atomic_duplicate_state = dpu_crtc_duplicate_state, |
| @@ -1469,9 +1457,13 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, · 27 unmodified lines | ||
| 1469 | 1457 | struct dpu_crtc *dpu_crtc; |
| 1470 | 1458 | int i, ret; |
| 1471 | 1459 | |
| 1472 | − dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL); | |
| 1473 | − if (!dpu_crtc) | |
| 1474 | − return ERR_PTR(-ENOMEM); | |
| 1460 | + dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base, | |
| 1461 | + plane, cursor, | |
| 1462 | + &dpu_crtc_funcs, | |
| 1463 | + NULL); | |
| 1464 | + | |
| 1465 | + if (IS_ERR(dpu_crtc)) | |
| 1466 | + return ERR_CAST(dpu_crtc); | |
| 1475 | 1467 | |
| 1476 | 1468 | crtc = &dpu_crtc->base; |
| 1477 | 1469 | crtc->dev = dev; |
| @@ -1491,9 +1483,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, · 13 unmodified lines | ||
| 1491 | 1483 | dpu_crtc_frame_event_work); |
| 1492 | 1484 | } |
| 1493 | 1485 | |
| 1494 | − drm_crtc_init_with_planes(dev, crtc, plane, cursor, &dpu_crtc_funcs, | |
| 1495 | − NULL); | |
| 1496 | − | |
| 1497 | 1486 | drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); |
| 1498 | 1487 | |
| 1499 | 1488 | if (dpu_kms->catalog->dspp_count) |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2013 Red Hat |
| 4 | 4 | * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. |
| 5 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 5 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 6 | 6 | * |
| 7 | 7 | * Author: Rob Clark <robdclark@gmail.com> |
| 8 | 8 | */ |
| @@ -16,6 +16,7 @@ · 7 unmodified lines | ||
| 16 | 16 | #include <drm/drm_crtc.h> |
| 17 | 17 | #include <drm/drm_file.h> |
| 18 | 18 | #include <drm/drm_probe_helper.h> |
| 19 | +#include <drm/drm_framebuffer.h> | |
| 19 | 20 | |
| 20 | 21 | #include "msm_drv.h" |
| 21 | 22 | #include "dpu_kms.h" |
| @@ -26,6 +27,7 @@ · 4 unmodified lines | ||
| 26 | 27 | #include "dpu_hw_dspp.h" |
| 27 | 28 | #include "dpu_hw_dsc.h" |
| 28 | 29 | #include "dpu_hw_merge3d.h" |
| 30 | +#include "dpu_hw_cdm.h" | |
| 29 | 31 | #include "dpu_formats.h" |
| 30 | 32 | #include "dpu_encoder_phys.h" |
| 31 | 33 | #include "dpu_crtc.h" |
| @@ -39,6 +41,9 @@ · 7 unmodified lines | ||
| 39 | 41 | #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ |
| 40 | 42 | (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) |
| 41 | 43 | |
| 44 | +#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ | |
| 45 | + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) | |
| 46 | + | |
| 42 | 47 | /* |
| 43 | 48 | * Two to anticipate panels that can do cmd/vid dynamic switching |
| 44 | 49 | * plan is to create all possible physical encoder types, and switch between |
| @@ -151,6 +156,8 @@ enum dpu_enc_rc_states { · 106 unmodified lines | ||
| 151 | 156 | * @crtc_frame_event_cb: callback handler for frame event |
| 152 | 157 | * @crtc_frame_event_cb_data: callback handler private data |
| 153 | 158 | * @frame_done_timeout_ms: frame done timeout in ms |
| 159 | + * @frame_done_timeout_cnt: atomic counter tracking the number of frame | |
| 160 | + * done timeouts | |
| 154 | 161 | * @frame_done_timer: watchdog timer for frame done event |
| 155 | 162 | * @disp_info: local copy of msm_display_info struct |
| 156 | 163 | * @idle_pc_supported: indicate if idle power collaps is supported |
| @@ -184,13 +191,13 @@ struct dpu_encoder_virt { · 27 unmodified lines | ||
| 184 | 191 | struct drm_crtc *crtc; |
| 185 | 192 | struct drm_connector *connector; |
| 186 | 193 | |
| 187 | − struct dentry *debugfs_root; | |
| 188 | 194 | struct mutex enc_lock; |
| 189 | 195 | DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL); |
| 190 | 196 | void (*crtc_frame_event_cb)(void *, u32 event); |
| 191 | 197 | void *crtc_frame_event_cb_data; |
| 192 | 198 | |
| 193 | 199 | atomic_t frame_done_timeout_ms; |
| 200 | + atomic_t frame_done_timeout_cnt; | |
| 194 | 201 | struct timer_list frame_done_timer; |
| 195 | 202 | |
| 196 | 203 | struct msm_display_info disp_info; |
| @@ -255,7 +262,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) · 58 unmodified lines | ||
| 255 | 262 | if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) |
| 256 | 263 | continue; |
| 257 | 264 | |
| 258 | − phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); | |
| 265 | + phys->hw_intf->ops.setup_misr(phys->hw_intf); | |
| 259 | 266 | } |
| 260 | 267 | } |
| 261 | 268 | |
| @@ -439,41 +446,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) · 177 unmodified lines | ||
| 439 | 446 | return linecount; |
| 440 | 447 | } |
| 441 | 448 | |
| 442 | −static void dpu_encoder_destroy(struct drm_encoder *drm_enc) | |
| 443 | −{ | |
| 444 | − struct dpu_encoder_virt *dpu_enc = NULL; | |
| 445 | − int i = 0; | |
| 446 | − | |
| 447 | − if (!drm_enc) { | |
| 448 | − DPU_ERROR("invalid encoder\n"); | |
| 449 | − return; | |
| 450 | − } | |
| 451 | − | |
| 452 | − dpu_enc = to_dpu_encoder_virt(drm_enc); | |
| 453 | − DPU_DEBUG_ENC(dpu_enc, "\n"); | |
| 454 | − | |
| 455 | − mutex_lock(&dpu_enc->enc_lock); | |
| 456 | − | |
| 457 | − for (i = 0; i < dpu_enc->num_phys_encs; i++) { | |
| 458 | − struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; | |
| 459 | − | |
| 460 | − if (phys->ops.destroy) { | |
| 461 | − phys->ops.destroy(phys); | |
| 462 | − --dpu_enc->num_phys_encs; | |
| 463 | − dpu_enc->phys_encs[i] = NULL; | |
| 464 | − } | |
| 465 | − } | |
| 466 | − | |
| 467 | − if (dpu_enc->num_phys_encs) | |
| 468 | − DPU_ERROR_ENC(dpu_enc, "expected 0 num_phys_encs not %d\n", | |
| 469 | − dpu_enc->num_phys_encs); | |
| 470 | − dpu_enc->num_phys_encs = 0; | |
| 471 | − mutex_unlock(&dpu_enc->enc_lock); | |
| 472 | − | |
| 473 | − drm_encoder_cleanup(drm_enc); | |
| 474 | − mutex_destroy(&dpu_enc->enc_lock); | |
| 475 | −} | |
| 476 | − | |
| 477 | 449 | void dpu_encoder_helper_split_config( |
| 478 | 450 | struct dpu_encoder_phys *phys_enc, |
| 479 | 451 | enum dpu_intf interface) |
| @@ -614,6 +586,7 @@ static int dpu_encoder_virt_atomic_check( · 134 unmodified lines | ||
| 614 | 586 | struct drm_display_mode *adj_mode; |
| 615 | 587 | struct msm_display_topology topology; |
| 616 | 588 | struct dpu_global_state *global_state; |
| 589 | + struct drm_framebuffer *fb; | |
| 617 | 590 | struct drm_dsc_config *dsc; |
| 618 | 591 | int i = 0; |
| 619 | 592 | int ret = 0; |
| @@ -654,6 +627,22 @@ static int dpu_encoder_virt_atomic_check( · 34 unmodified lines | ||
| 654 | 627 | |
| 655 | 628 | topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc); |
| 656 | 629 | |
| 630 | + /* | |
| 631 | + * Use CDM only for writeback at the moment as other interfaces cannot handle it. | |
| 632 | + * if writeback itself cannot handle cdm for some reason it will fail in its atomic_check() | |
| 633 | + * earlier. | |
| 634 | + */ | |
| 635 | + if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) { | |
| 636 | + fb = conn_state->writeback_job->fb; | |
| 637 | + | |
| 638 | + if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb)))) | |
| 639 | + topology.needs_cdm = true; | |
| 640 | + if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm) | |
| 641 | + crtc_state->mode_changed = true; | |
| 642 | + else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm) | |
| 643 | + crtc_state->mode_changed = true; | |
| 644 | + } | |
| 645 | + | |
| 657 | 646 | /* |
| 658 | 647 | * Release and Allocate resources on every modeset |
| 659 | 648 | * Dont allocate when active is false. |
| @@ -1094,6 +1083,15 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 434 unmodified lines | ||
| 1094 | 1083 | |
| 1095 | 1084 | dpu_enc->dsc_mask = dsc_mask; |
| 1096 | 1085 | |
| 1086 | + if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) { | |
| 1087 | + struct dpu_hw_blk *hw_cdm = NULL; | |
| 1088 | + | |
| 1089 | + dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 1090 | + drm_enc->base.id, DPU_HW_BLK_CDM, | |
| 1091 | + &hw_cdm, 1); | |
| 1092 | + dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; | |
| 1093 | + } | |
| 1094 | + | |
| 1097 | 1095 | cstate = to_dpu_crtc_state(crtc_state); |
| 1098 | 1096 | |
| 1099 | 1097 | for (i = 0; i < num_lm; i++) { |
| @@ -1204,6 +1202,8 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, · 104 unmodified lines | ||
| 1204 | 1202 | |
| 1205 | 1203 | dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc); |
| 1206 | 1204 | |
| 1205 | + atomic_set(&dpu_enc->frame_done_timeout_cnt, 0); | |
| 1206 | + | |
| 1207 | 1207 | if (disp_info->intf_type == INTF_DP) |
| 1208 | 1208 | dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); |
| 1209 | 1209 | else if (disp_info->intf_type == INTF_DSI) |
| @@ -2080,6 +2080,15 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) · 870 unmodified lines | ||
| 2080 | 2080 | phys_enc->hw_pp->merge_3d->idx); |
| 2081 | 2081 | } |
| 2082 | 2082 | |
| 2083 | + if (phys_enc->hw_cdm) { | |
| 2084 | + if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp) | |
| 2085 | + phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm, | |
| 2086 | + PINGPONG_NONE); | |
| 2087 | + if (phys_enc->hw_ctl->ops.update_pending_flush_cdm) | |
| 2088 | + phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl, | |
| 2089 | + phys_enc->hw_cdm->idx); | |
| 2090 | + } | |
| 2091 | + | |
| 2083 | 2092 | if (dpu_enc->dsc) { |
| 2084 | 2093 | dpu_encoder_unprep_dsc(dpu_enc); |
| 2085 | 2094 | dpu_enc->dsc = NULL; |
| @@ -2108,18 +2117,20 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) · 22 unmodified lines | ||
| 2108 | 2117 | #ifdef CONFIG_DEBUG_FS |
| 2109 | 2118 | static int _dpu_encoder_status_show(struct seq_file *s, void *data) |
| 2110 | 2119 | { |
| 2111 | − struct dpu_encoder_virt *dpu_enc = s->private; | |
| 2120 | + struct drm_encoder *drm_enc = s->private; | |
| 2121 | + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); | |
| 2112 | 2122 | int i; |
| 2113 | 2123 | |
| 2114 | 2124 | mutex_lock(&dpu_enc->enc_lock); |
| 2115 | 2125 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 2116 | 2126 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; |
| 2117 | 2127 | |
| 2118 | − seq_printf(s, "intf:%d wb:%d vsync:%8d underrun:%8d ", | |
| 2128 | + seq_printf(s, "intf:%d wb:%d vsync:%8d underrun:%8d frame_done_cnt:%d", | |
| 2119 | 2129 | phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1, |
| 2120 | 2130 | phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1, |
| 2121 | 2131 | atomic_read(&phys->vsync_cnt), |
| 2122 | − atomic_read(&phys->underrun_cnt)); | |
| 2132 | + atomic_read(&phys->underrun_cnt), | |
| 2133 | + atomic_read(&dpu_enc->frame_done_timeout_cnt)); | |
| 2123 | 2134 | |
| 2124 | 2135 | seq_printf(s, "mode: %s\n", dpu_encoder_helper_get_intf_type(phys->intf_mode)); |
| 2125 | 2136 | } |
| @@ -2130,49 +2141,18 @@ static int _dpu_encoder_status_show(struct seq_file *s, void *data) · 4 unmodified lines | ||
| 2130 | 2141 | |
| 2131 | 2142 | DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status); |
| 2132 | 2143 | |
| 2133 | −static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) | |
| 2144 | +static void dpu_encoder_debugfs_init(struct drm_encoder *drm_enc, struct dentry *root) | |
| 2134 | 2145 | { |
| 2135 | − struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); | |
| 2136 | − | |
| 2137 | − char name[12]; | |
| 2138 | − | |
| 2139 | − if (!drm_enc->dev) { | |
| 2140 | − DPU_ERROR("invalid encoder or kms\n"); | |
| 2141 | − return -EINVAL; | |
| 2142 | − } | |
| 2143 | − | |
| 2144 | − snprintf(name, sizeof(name), "encoder%u", drm_enc->base.id); | |
| 2145 | − | |
| 2146 | − /* create overall sub-directory for the encoder */ | |
| 2147 | − dpu_enc->debugfs_root = debugfs_create_dir(name, | |
| 2148 | − drm_enc->dev->primary->debugfs_root); | |
| 2149 | − | |
| 2150 | 2146 | /* don't error check these */ |
| 2151 | 2147 | debugfs_create_file("status", 0600, |
| 2152 | − dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops); | |
| 2153 | − | |
| 2154 | − return 0; | |
| 2148 | + root, drm_enc, &_dpu_encoder_status_fops); | |
| 2155 | 2149 | } |
| 2156 | 2150 | #else |
| 2157 | −static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) | |
| 2158 | −{ | |
| 2159 | − return 0; | |
| 2160 | −} | |
| 2151 | +#define dpu_encoder_debugfs_init NULL | |
| 2161 | 2152 | #endif |
| 2162 | 2153 | |
| 2163 | −static int dpu_encoder_late_register(struct drm_encoder *encoder) | |
| 2164 | −{ | |
| 2165 | − return _dpu_encoder_init_debugfs(encoder); | |
| 2166 | −} | |
| 2167 | − | |
| 2168 | −static void dpu_encoder_early_unregister(struct drm_encoder *encoder) | |
| 2169 | −{ | |
| 2170 | − struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder); | |
| 2171 | − | |
| 2172 | − debugfs_remove_recursive(dpu_enc->debugfs_root); | |
| 2173 | −} | |
| 2174 | − | |
| 2175 | 2154 | static int dpu_encoder_virt_add_phys_encs( |
| 2155 | + struct drm_device *dev, | |
| 2176 | 2156 | struct msm_display_info *disp_info, |
| 2177 | 2157 | struct dpu_encoder_virt *dpu_enc, |
| 2178 | 2158 | struct dpu_enc_phys_init_params *params) |
| @@ -2194,7 +2174,7 @@ static int dpu_encoder_virt_add_phys_encs( · 15 unmodified lines | ||
| 2194 | 2174 | |
| 2195 | 2175 | |
| 2196 | 2176 | if (disp_info->intf_type == INTF_WB) { |
| 2197 | − enc = dpu_encoder_phys_wb_init(params); | |
| 2177 | + enc = dpu_encoder_phys_wb_init(dev, params); | |
| 2198 | 2178 | |
| 2199 | 2179 | if (IS_ERR(enc)) { |
| 2200 | 2180 | DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", |
| @@ -2205,7 +2185,7 @@ static int dpu_encoder_virt_add_phys_encs( · 4 unmodified lines | ||
| 2205 | 2185 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; |
| 2206 | 2186 | ++dpu_enc->num_phys_encs; |
| 2207 | 2187 | } else if (disp_info->is_cmd_mode) { |
| 2208 | − enc = dpu_encoder_phys_cmd_init(params); | |
| 2188 | + enc = dpu_encoder_phys_cmd_init(dev, params); | |
| 2209 | 2189 | |
| 2210 | 2190 | if (IS_ERR(enc)) { |
| 2211 | 2191 | DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n", |
| @@ -2216,7 +2196,7 @@ static int dpu_encoder_virt_add_phys_encs( · 4 unmodified lines | ||
| 2216 | 2196 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; |
| 2217 | 2197 | ++dpu_enc->num_phys_encs; |
| 2218 | 2198 | } else { |
| 2219 | − enc = dpu_encoder_phys_vid_init(params); | |
| 2199 | + enc = dpu_encoder_phys_vid_init(dev, params); | |
| 2220 | 2200 | |
| 2221 | 2201 | if (IS_ERR(enc)) { |
| 2222 | 2202 | DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n", |
| @@ -2305,7 +2285,7 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, · 82 unmodified lines | ||
| 2305 | 2285 | break; |
| 2306 | 2286 | } |
| 2307 | 2287 | |
| 2308 | − ret = dpu_encoder_virt_add_phys_encs(disp_info, | |
| 2288 | + ret = dpu_encoder_virt_add_phys_encs(dpu_kms->dev, disp_info, | |
| 2309 | 2289 | dpu_enc, &phys_params); |
| 2310 | 2290 | if (ret) { |
| 2311 | 2291 | DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); |
| @@ -2339,7 +2319,10 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) · 27 unmodified lines | ||
| 2339 | 2319 | return; |
| 2340 | 2320 | } |
| 2341 | 2321 | |
| 2342 | − DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); | |
| 2322 | + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); | |
| 2323 | + | |
| 2324 | + if (atomic_inc_return(&dpu_enc->frame_done_timeout_cnt) == 1) | |
| 2325 | + msm_disp_snapshot_state(drm_enc->dev); | |
| 2343 | 2326 | |
| 2344 | 2327 | event = DPU_ENCODER_FRAME_EVENT_ERROR; |
| 2345 | 2328 | trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); |
| @@ -2354,9 +2337,7 @@ static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = { · 8 unmodified lines | ||
| 2354 | 2337 | }; |
| 2355 | 2338 | |
| 2356 | 2339 | static const struct drm_encoder_funcs dpu_encoder_funcs = { |
| 2357 | − .destroy = dpu_encoder_destroy, | |
| 2358 | − .late_register = dpu_encoder_late_register, | |
| 2359 | − .early_unregister = dpu_encoder_early_unregister, | |
| 2340 | + .debugfs_init = dpu_encoder_debugfs_init, | |
| 2360 | 2341 | }; |
| 2361 | 2342 | |
| 2362 | 2343 | struct drm_encoder *dpu_encoder_init(struct drm_device *dev, |
| @@ -2365,20 +2346,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 2 unmodified lines | ||
| 2365 | 2346 | { |
| 2366 | 2347 | struct msm_drm_private *priv = dev->dev_private; |
| 2367 | 2348 | struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); |
| 2368 | − struct drm_encoder *drm_enc = NULL; | |
| 2369 | − struct dpu_encoder_virt *dpu_enc = NULL; | |
| 2370 | − int ret = 0; | |
| 2371 | − | |
| 2372 | − dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); | |
| 2373 | − if (!dpu_enc) | |
| 2374 | − return ERR_PTR(-ENOMEM); | |
| 2349 | + struct dpu_encoder_virt *dpu_enc; | |
| 2350 | + int ret; | |
| 2375 | 2351 | |
| 2376 | − ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, | |
| 2377 | − drm_enc_mode, NULL); | |
| 2378 | − if (ret) { | |
| 2379 | − devm_kfree(dev->dev, dpu_enc); | |
| 2380 | − return ERR_PTR(ret); | |
| 2381 | − } | |
| 2352 | + dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base, | |
| 2353 | + &dpu_encoder_funcs, drm_enc_mode, NULL); | |
| 2354 | + if (IS_ERR(dpu_enc)) | |
| 2355 | + return ERR_CAST(dpu_enc); | |
| 2382 | 2356 | |
| 2383 | 2357 | drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs); |
| 2384 | 2358 | |
| @@ -2388,10 +2362,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 3 unmodified lines | ||
| 2388 | 2362 | mutex_init(&dpu_enc->rc_lock); |
| 2389 | 2363 | |
| 2390 | 2364 | ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); |
| 2391 | − if (ret) | |
| 2392 | − goto fail; | |
| 2365 | + if (ret) { | |
| 2366 | + DPU_ERROR("failed to setup encoder\n"); | |
| 2367 | + return ERR_PTR(-ENOMEM); | |
| 2368 | + } | |
| 2393 | 2369 | |
| 2394 | 2370 | atomic_set(&dpu_enc->frame_done_timeout_ms, 0); |
| 2371 | + atomic_set(&dpu_enc->frame_done_timeout_cnt, 0); | |
| 2395 | 2372 | timer_setup(&dpu_enc->frame_done_timer, |
| 2396 | 2373 | dpu_encoder_frame_done_timeout, 0); |
| 2397 | 2374 | |
| @@ -2404,13 +2381,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 6 unmodified lines | ||
| 2404 | 2381 | DPU_DEBUG_ENC(dpu_enc, "created\n"); |
| 2405 | 2382 | |
| 2406 | 2383 | return &dpu_enc->base; |
| 2407 | − | |
| 2408 | −fail: | |
| 2409 | − DPU_ERROR("failed to create encoder\n"); | |
| 2410 | − if (drm_enc) | |
| 2411 | − dpu_encoder_destroy(drm_enc); | |
| 2412 | − | |
| 2413 | − return ERR_PTR(ret); | |
| 2414 | 2384 | } |
| 2415 | 2385 | |
| 2416 | 2386 | int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, |
| @@ -2437,9 +2407,6 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, · 20 unmodified lines | ||
| 2437 | 2407 | case MSM_ENC_TX_COMPLETE: |
| 2438 | 2408 | fn_wait = phys->ops.wait_for_tx_complete; |
| 2439 | 2409 | break; |
| 2440 | − case MSM_ENC_VBLANK: | |
| 2441 | − fn_wait = phys->ops.wait_for_vblank; | |
| 2442 | − break; | |
| 2443 | 2410 | default: |
| 2444 | 2411 | DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n", |
| 2445 | 2412 | event); |
| @@ -2497,7 +2464,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, · 51 unmodified lines | ||
| 2497 | 2464 | phys_enc->enc_spinlock = p->enc_spinlock; |
| 2498 | 2465 | phys_enc->enable_state = DPU_ENC_DISABLED; |
| 2499 | 2466 | |
| 2500 | − atomic_set(&phys_enc->vblank_refcount, 0); | |
| 2501 | 2467 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 2502 | 2468 | atomic_set(&phys_enc->pending_ctlstart_cnt, 0); |
| 2503 | 2469 | |
| @@ -14,8 +14,10 @@ · 13 unmodified lines | ||
| 14 | 14 | #include "dpu_hw_intf.h" |
| 15 | 15 | #include "dpu_hw_wb.h" |
| 16 | 16 | #include "dpu_hw_pingpong.h" |
| 17 | +#include "dpu_hw_cdm.h" | |
| 17 | 18 | #include "dpu_hw_ctl.h" |
| 18 | 19 | #include "dpu_hw_top.h" |
| 20 | +#include "dpu_hw_util.h" | |
| 19 | 21 | #include "dpu_encoder.h" |
| 20 | 22 | #include "dpu_crtc.h" |
| 21 | 23 | |
| @@ -72,7 +74,6 @@ struct dpu_encoder_phys; · 50 unmodified lines | ||
| 72 | 74 | * @enable: DRM Call. Enable a DRM mode. |
| 73 | 75 | * @disable: DRM Call. Disable mode. |
| 74 | 76 | * @atomic_check: DRM Call. Atomic check new DRM state. |
| 75 | − * @destroy: DRM Call. Destroy and release resources. | |
| 76 | 77 | * @control_vblank_irq Register/Deregister for VBLANK IRQ |
| 77 | 78 | * @wait_for_commit_done: Wait for hardware to have flushed the |
| 78 | 79 | * current pending frames to hardware |
| @@ -102,11 +103,9 @@ struct dpu_encoder_phys_ops { · 23 unmodified lines | ||
| 102 | 103 | int (*atomic_check)(struct dpu_encoder_phys *encoder, |
| 103 | 104 | struct drm_crtc_state *crtc_state, |
| 104 | 105 | struct drm_connector_state *conn_state); |
| 105 | − void (*destroy)(struct dpu_encoder_phys *encoder); | |
| 106 | 106 | int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); |
| 107 | 107 | int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); |
| 108 | 108 | int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); |
| 109 | − int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc); | |
| 110 | 109 | void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc); |
| 111 | 110 | void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); |
| 112 | 111 | void (*trigger_start)(struct dpu_encoder_phys *phys_enc); |
| @@ -153,8 +152,10 @@ enum dpu_intr_idx { · 40 unmodified lines | ||
| 153 | 152 | * @hw_pp: Hardware interface to the ping pong registers |
| 154 | 153 | * @hw_intf: Hardware interface to the intf registers |
| 155 | 154 | * @hw_wb: Hardware interface to the wb registers |
| 155 | + * @hw_cdm: Hardware interface to the CDM registers | |
| 156 | 156 | * @dpu_kms: Pointer to the dpu_kms top level |
| 157 | 157 | * @cached_mode: DRM mode cached at mode_set time, acted on in enable |
| 158 | + * @vblank_ctl_lock: Vblank ctl mutex lock to protect vblank_refcount | |
| 158 | 159 | * @enabled: Whether the encoder has enabled and running a mode |
| 159 | 160 | * @split_role: Role to play in a split-panel configuration |
| 160 | 161 | * @intf_mode: Interface mode |
| @@ -181,13 +182,15 @@ struct dpu_encoder_phys { · 20 unmodified lines | ||
| 181 | 182 | struct dpu_hw_pingpong *hw_pp; |
| 182 | 183 | struct dpu_hw_intf *hw_intf; |
| 183 | 184 | struct dpu_hw_wb *hw_wb; |
| 185 | + struct dpu_hw_cdm *hw_cdm; | |
| 184 | 186 | struct dpu_kms *dpu_kms; |
| 185 | 187 | struct drm_display_mode cached_mode; |
| 188 | + struct mutex vblank_ctl_lock; | |
| 186 | 189 | enum dpu_enc_split_role split_role; |
| 187 | 190 | enum dpu_intf_mode intf_mode; |
| 188 | 191 | spinlock_t *enc_spinlock; |
| 189 | 192 | enum dpu_enc_enable_state enable_state; |
| 190 | − atomic_t vblank_refcount; | |
| 193 | + int vblank_refcount; | |
| 191 | 194 | atomic_t vsync_cnt; |
| 192 | 195 | atomic_t underrun_cnt; |
| 193 | 196 | atomic_t pending_ctlstart_cnt; |
| @@ -210,6 +213,7 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) · 16 unmodified lines | ||
| 210 | 213 | * @wbirq_refcount: Reference count of writeback interrupt |
| 211 | 214 | * @wb_done_timeout_cnt: number of wb done irq timeout errors |
| 212 | 215 | * @wb_cfg: writeback block config to store fb related details |
| 216 | + * @cdm_cfg: cdm block config needed to store writeback block's CDM configuration | |
| 213 | 217 | * @wb_conn: backpointer to writeback connector |
| 214 | 218 | * @wb_job: backpointer to current writeback job |
| 215 | 219 | * @dest: dpu buffer layout for current writeback output buffer |
| @@ -219,6 +223,7 @@ struct dpu_encoder_phys_wb { · 3 unmodified lines | ||
| 219 | 223 | atomic_t wbirq_refcount; |
| 220 | 224 | int wb_done_timeout_cnt; |
| 221 | 225 | struct dpu_hw_wb_cfg wb_cfg; |
| 226 | + struct dpu_hw_cdm_cfg cdm_cfg; | |
| 222 | 227 | struct drm_writeback_connector *wb_conn; |
| 223 | 228 | struct drm_writeback_job *wb_job; |
| 224 | 229 | struct dpu_hw_fmt_layout dest; |
| @@ -281,22 +286,24 @@ struct dpu_encoder_wait_info { · 56 unmodified lines | ||
| 281 | 286 | * @p: Pointer to init params structure |
| 282 | 287 | * Return: Error code or newly allocated encoder |
| 283 | 288 | */ |
| 284 | −struct dpu_encoder_phys *dpu_encoder_phys_vid_init( | |
| 289 | +struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev, | |
| 285 | 290 | struct dpu_enc_phys_init_params *p); |
| 286 | 291 | |
| 287 | 292 | /** |
| 288 | 293 | * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder |
| 294 | + * @dev: Corresponding device for devres management | |
| 289 | 295 | * @p: Pointer to init params structure |
| 290 | 296 | * Return: Error code or newly allocated encoder |
| 291 | 297 | */ |
| 292 | −struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( | |
| 298 | +struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev, | |
| 293 | 299 | struct dpu_enc_phys_init_params *p); |
| 294 | 300 | |
| 295 | 301 | /** |
| 296 | 302 | * dpu_encoder_phys_wb_init - initialize writeback encoder |
| 303 | + * @dev: Corresponding device for devres management | |
| 297 | 304 | * @init: Pointer to init info structure with initialization params |
| 298 | 305 | */ |
| 299 | −struct dpu_encoder_phys *dpu_encoder_phys_wb_init( | |
| 306 | +struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev, | |
| 300 | 307 | struct dpu_enc_phys_init_params *p); |
| 301 | 308 | |
| 302 | 309 | /** |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | #include "dpu_trace.h" |
| 14 | 14 | #include "disp/msm_disp_snapshot.h" |
| 15 | 15 | |
| 16 | +#include <drm/drm_managed.h> | |
| 17 | + | |
| 16 | 18 | #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ |
| 17 | 19 | (e) && (e)->base.parent ? \ |
| 18 | 20 | (e)->base.parent->base.id : -1, \ |
| @@ -244,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( · 225 unmodified lines | ||
| 244 | 246 | return -EINVAL; |
| 245 | 247 | } |
| 246 | 248 | |
| 247 | − refcount = atomic_read(&phys_enc->vblank_refcount); | |
| 249 | + mutex_lock(&phys_enc->vblank_ctl_lock); | |
| 250 | + refcount = phys_enc->vblank_refcount; | |
| 248 | 251 | |
| 249 | 252 | /* Slave encoders don't report vblank */ |
| 250 | 253 | if (!dpu_encoder_phys_cmd_is_master(phys_enc)) |
| @@ -260,16 +263,24 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( · 9 unmodified lines | ||
| 260 | 263 | phys_enc->hw_pp->idx - PINGPONG_0, |
| 261 | 264 | enable ? "true" : "false", refcount); |
| 262 | 265 | |
| 263 | − if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) | |
| 264 | − ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | |
| 265 | − phys_enc->irq[INTR_IDX_RDPTR], | |
| 266 | − dpu_encoder_phys_cmd_te_rd_ptr_irq, | |
| 267 | − phys_enc); | |
| 268 | − else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) | |
| 269 | − ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | |
| 270 | − phys_enc->irq[INTR_IDX_RDPTR]); | |
| 266 | + if (enable) { | |
| 267 | + if (phys_enc->vblank_refcount == 0) | |
| 268 | + ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | |
| 269 | + phys_enc->irq[INTR_IDX_RDPTR], | |
| 270 | + dpu_encoder_phys_cmd_te_rd_ptr_irq, | |
| 271 | + phys_enc); | |
| 272 | + if (!ret) | |
| 273 | + phys_enc->vblank_refcount++; | |
| 274 | + } else if (!enable) { | |
| 275 | + if (phys_enc->vblank_refcount == 1) | |
| 276 | + ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | |
| 277 | + phys_enc->irq[INTR_IDX_RDPTR]); | |
| 278 | + if (!ret) | |
| 279 | + phys_enc->vblank_refcount--; | |
| 280 | + } | |
| 271 | 281 | |
| 272 | 282 | end: |
| 283 | + mutex_unlock(&phys_enc->vblank_ctl_lock); | |
| 273 | 284 | if (ret) { |
| 274 | 285 | DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n", |
| 275 | 286 | DRMID(phys_enc->parent), |
| @@ -285,7 +296,7 @@ static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc, · 9 unmodified lines | ||
| 285 | 296 | { |
| 286 | 297 | trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent), |
| 287 | 298 | phys_enc->hw_pp->idx - PINGPONG_0, |
| 288 | − enable, atomic_read(&phys_enc->vblank_refcount)); | |
| 299 | + enable, phys_enc->vblank_refcount); | |
| 289 | 300 | |
| 290 | 301 | if (enable) { |
| 291 | 302 | dpu_core_irq_register_callback(phys_enc->dpu_kms, |
| @@ -558,14 +569,6 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc) · 266 unmodified lines | ||
| 558 | 569 | phys_enc->enable_state = DPU_ENC_DISABLED; |
| 559 | 570 | } |
| 560 | 571 | |
| 561 | −static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc) | |
| 562 | −{ | |
| 563 | − struct dpu_encoder_phys_cmd *cmd_enc = | |
| 564 | − to_dpu_encoder_phys_cmd(phys_enc); | |
| 565 | − | |
| 566 | − kfree(cmd_enc); | |
| 567 | −} | |
| 568 | − | |
| 569 | 572 | static void dpu_encoder_phys_cmd_prepare_for_kickoff( |
| 570 | 573 | struct dpu_encoder_phys *phys_enc) |
| 571 | 574 | { |
| @@ -681,33 +684,6 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done( · 109 unmodified lines | ||
| 681 | 684 | return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); |
| 682 | 685 | } |
| 683 | 686 | |
| 684 | −static int dpu_encoder_phys_cmd_wait_for_vblank( | |
| 685 | − struct dpu_encoder_phys *phys_enc) | |
| 686 | −{ | |
| 687 | − int rc = 0; | |
| 688 | − struct dpu_encoder_phys_cmd *cmd_enc; | |
| 689 | − struct dpu_encoder_wait_info wait_info; | |
| 690 | − | |
| 691 | − cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); | |
| 692 | − | |
| 693 | − /* only required for master controller */ | |
| 694 | − if (!dpu_encoder_phys_cmd_is_master(phys_enc)) | |
| 695 | − return rc; | |
| 696 | − | |
| 697 | − wait_info.wq = &cmd_enc->pending_vblank_wq; | |
| 698 | − wait_info.atomic_cnt = &cmd_enc->pending_vblank_cnt; | |
| 699 | − wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; | |
| 700 | − | |
| 701 | − atomic_inc(&cmd_enc->pending_vblank_cnt); | |
| 702 | − | |
| 703 | − rc = dpu_encoder_helper_wait_for_irq(phys_enc, | |
| 704 | − phys_enc->irq[INTR_IDX_RDPTR], | |
| 705 | − dpu_encoder_phys_cmd_te_rd_ptr_irq, | |
| 706 | − &wait_info); | |
| 707 | − | |
| 708 | − return rc; | |
| 709 | −} | |
| 710 | − | |
| 711 | 687 | static void dpu_encoder_phys_cmd_handle_post_kickoff( |
| 712 | 688 | struct dpu_encoder_phys *phys_enc) |
| 713 | 689 | { |
| @@ -731,12 +707,10 @@ static void dpu_encoder_phys_cmd_init_ops( · 17 unmodified lines | ||
| 731 | 707 | ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; |
| 732 | 708 | ops->enable = dpu_encoder_phys_cmd_enable; |
| 733 | 709 | ops->disable = dpu_encoder_phys_cmd_disable; |
| 734 | − ops->destroy = dpu_encoder_phys_cmd_destroy; | |
| 735 | 710 | ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq; |
| 736 | 711 | ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done; |
| 737 | 712 | ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff; |
| 738 | 713 | ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete; |
| 739 | − ops->wait_for_vblank = dpu_encoder_phys_cmd_wait_for_vblank; | |
| 740 | 714 | ops->trigger_start = dpu_encoder_phys_cmd_trigger_start; |
| 741 | 715 | ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush; |
| 742 | 716 | ops->irq_control = dpu_encoder_phys_cmd_irq_control; |
| @@ -746,7 +720,7 @@ static void dpu_encoder_phys_cmd_init_ops( · 3 unmodified lines | ||
| 746 | 720 | ops->get_line_count = dpu_encoder_phys_cmd_get_line_count; |
| 747 | 721 | } |
| 748 | 722 | |
| 749 | −struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( | |
| 723 | +struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev, | |
| 750 | 724 | struct dpu_enc_phys_init_params *p) |
| 751 | 725 | { |
| 752 | 726 | struct dpu_encoder_phys *phys_enc = NULL; |
| @@ -754,7 +728,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( · 1 unmodified line | ||
| 754 | 728 | |
| 755 | 729 | DPU_DEBUG("intf\n"); |
| 756 | 730 | |
| 757 | − cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL); | |
| 731 | + cmd_enc = drmm_kzalloc(dev, sizeof(*cmd_enc), GFP_KERNEL); | |
| 758 | 732 | if (!cmd_enc) { |
| 759 | 733 | DPU_ERROR("failed to allocate\n"); |
| 760 | 734 | return ERR_PTR(-ENOMEM); |
| @@ -763,6 +737,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( · 2 unmodified lines | ||
| 763 | 737 | |
| 764 | 738 | dpu_encoder_phys_init(phys_enc, p); |
| 765 | 739 | |
| 740 | + mutex_init(&phys_enc->vblank_ctl_lock); | |
| 741 | + phys_enc->vblank_refcount = 0; | |
| 742 | + | |
| 766 | 743 | dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); |
| 767 | 744 | phys_enc->intf_mode = INTF_MODE_CMD; |
| 768 | 745 | cmd_enc->stream_sel = 0; |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "dpu_trace.h" |
| 12 | 12 | #include "disp/msm_disp_snapshot.h" |
| 13 | 13 | |
| 14 | +#include <drm/drm_managed.h> | |
| 15 | + | |
| 14 | 16 | #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ |
| 15 | 17 | (e) && (e)->parent ? \ |
| 16 | 18 | (e)->parent->base.id : -1, \ |
| @@ -364,7 +366,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq( · 347 unmodified lines | ||
| 364 | 366 | int ret = 0; |
| 365 | 367 | int refcount; |
| 366 | 368 | |
| 367 | − refcount = atomic_read(&phys_enc->vblank_refcount); | |
| 369 | + mutex_lock(&phys_enc->vblank_ctl_lock); | |
| 370 | + refcount = phys_enc->vblank_refcount; | |
| 368 | 371 | |
| 369 | 372 | /* Slave encoders don't report vblank */ |
| 370 | 373 | if (!dpu_encoder_phys_vid_is_master(phys_enc)) |
| @@ -377,18 +380,26 @@ static int dpu_encoder_phys_vid_control_vblank_irq( · 6 unmodified lines | ||
| 377 | 380 | } |
| 378 | 381 | |
| 379 | 382 | DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable, |
| 380 | − atomic_read(&phys_enc->vblank_refcount)); | |
| 383 | + refcount); | |
| 381 | 384 | |
| 382 | − if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) | |
| 383 | − ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | |
| 384 | − phys_enc->irq[INTR_IDX_VSYNC], | |
| 385 | − dpu_encoder_phys_vid_vblank_irq, | |
| 386 | − phys_enc); | |
| 387 | − else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) | |
| 388 | − ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | |
| 389 | − phys_enc->irq[INTR_IDX_VSYNC]); | |
| 385 | + if (enable) { | |
| 386 | + if (phys_enc->vblank_refcount == 0) | |
| 387 | + ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | |
| 388 | + phys_enc->irq[INTR_IDX_VSYNC], | |
| 389 | + dpu_encoder_phys_vid_vblank_irq, | |
| 390 | + phys_enc); | |
| 391 | + if (!ret) | |
| 392 | + phys_enc->vblank_refcount++; | |
| 393 | + } else if (!enable) { | |
| 394 | + if (phys_enc->vblank_refcount == 1) | |
| 395 | + ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | |
| 396 | + phys_enc->irq[INTR_IDX_VSYNC]); | |
| 397 | + if (!ret) | |
| 398 | + phys_enc->vblank_refcount--; | |
| 399 | + } | |
| 390 | 400 | |
| 391 | 401 | end: |
| 402 | + mutex_unlock(&phys_enc->vblank_ctl_lock); | |
| 392 | 403 | if (ret) { |
| 393 | 404 | DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", |
| 394 | 405 | DRMID(phys_enc->parent), |
| @@ -438,13 +449,7 @@ skip_flush: · 43 unmodified lines | ||
| 438 | 449 | phys_enc->enable_state = DPU_ENC_ENABLING; |
| 439 | 450 | } |
| 440 | 451 | |
| 441 | −static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) | |
| 442 | −{ | |
| 443 | − DPU_DEBUG_VIDENC(phys_enc, "\n"); | |
| 444 | − kfree(phys_enc); | |
| 445 | −} | |
| 446 | − | |
| 447 | −static int dpu_encoder_phys_vid_wait_for_vblank( | |
| 452 | +static int dpu_encoder_phys_vid_wait_for_tx_complete( | |
| 448 | 453 | struct dpu_encoder_phys *phys_enc) |
| 449 | 454 | { |
| 450 | 455 | struct dpu_encoder_wait_info wait_info; |
| @@ -558,7 +563,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) · 107 unmodified lines | ||
| 558 | 563 | * scanout buffer) don't latch properly.. |
| 559 | 564 | */ |
| 560 | 565 | if (dpu_encoder_phys_vid_is_master(phys_enc)) { |
| 561 | − ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); | |
| 566 | + ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc); | |
| 562 | 567 | if (ret) { |
| 563 | 568 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 564 | 569 | DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", |
| @@ -578,7 +583,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) · 13 unmodified lines | ||
| 578 | 583 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); |
| 579 | 584 | dpu_encoder_phys_inc_pending(phys_enc); |
| 580 | 585 | spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); |
| 581 | − ret = dpu_encoder_phys_vid_wait_for_vblank(phys_enc); | |
| 586 | + ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc); | |
| 582 | 587 | if (ret) { |
| 583 | 588 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 584 | 589 | DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", |
| @@ -618,7 +623,7 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, · 33 unmodified lines | ||
| 618 | 623 | trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), |
| 619 | 624 | phys_enc->hw_intf->idx - INTF_0, |
| 620 | 625 | enable, |
| 621 | − atomic_read(&phys_enc->vblank_refcount)); | |
| 626 | + phys_enc->vblank_refcount); | |
| 622 | 627 | |
| 623 | 628 | if (enable) { |
| 624 | 629 | ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true); |
| @@ -681,11 +686,9 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) · 56 unmodified lines | ||
| 681 | 686 | ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; |
| 682 | 687 | ops->enable = dpu_encoder_phys_vid_enable; |
| 683 | 688 | ops->disable = dpu_encoder_phys_vid_disable; |
| 684 | − ops->destroy = dpu_encoder_phys_vid_destroy; | |
| 685 | 689 | ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; |
| 686 | 690 | ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done; |
| 687 | − ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank; | |
| 688 | − ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_vblank; | |
| 691 | + ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_tx_complete; | |
| 689 | 692 | ops->irq_control = dpu_encoder_phys_vid_irq_control; |
| 690 | 693 | ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; |
| 691 | 694 | ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff; |
| @@ -694,7 +697,7 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) · 2 unmodified lines | ||
| 694 | 697 | ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count; |
| 695 | 698 | } |
| 696 | 699 | |
| 697 | −struct dpu_encoder_phys *dpu_encoder_phys_vid_init( | |
| 700 | +struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev, | |
| 698 | 701 | struct dpu_enc_phys_init_params *p) |
| 699 | 702 | { |
| 700 | 703 | struct dpu_encoder_phys *phys_enc = NULL; |
| @@ -704,7 +707,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( · 3 unmodified lines | ||
| 704 | 707 | return ERR_PTR(-EINVAL); |
| 705 | 708 | } |
| 706 | 709 | |
| 707 | − phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL); | |
| 710 | + phys_enc = drmm_kzalloc(dev, sizeof(*phys_enc), GFP_KERNEL); | |
| 708 | 711 | if (!phys_enc) { |
| 709 | 712 | DPU_ERROR("failed to create encoder due to memory allocation error\n"); |
| 710 | 713 | return ERR_PTR(-ENOMEM); |
| @@ -713,6 +716,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( · 2 unmodified lines | ||
| 713 | 716 | DPU_DEBUG_VIDENC(phys_enc, "\n"); |
| 714 | 717 | |
| 715 | 718 | dpu_encoder_phys_init(phys_enc, p); |
| 719 | + mutex_init(&phys_enc->vblank_ctl_lock); | |
| 720 | + phys_enc->vblank_refcount = 0; | |
| 716 | 721 | |
| 717 | 722 | dpu_encoder_phys_vid_init_ops(&phys_enc->ops); |
| 718 | 723 | phys_enc->intf_mode = INTF_MODE_VIDEO; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/debugfs.h> |
| 9 | 9 | |
| 10 | 10 | #include <drm/drm_framebuffer.h> |
| 11 | +#include <drm/drm_managed.h> | |
| 11 | 12 | |
| 12 | 13 | #include "dpu_encoder_phys.h" |
| 13 | 14 | #include "dpu_formats.h" |
| @@ -206,13 +207,14 @@ static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc, · 192 unmodified lines | ||
| 206 | 207 | } |
| 207 | 208 | |
| 208 | 209 | /** |
| 209 | − * dpu_encoder_phys_wb_setup_cdp - setup chroma down prefetch block | |
| 210 | + * dpu_encoder_phys_wb_setup_ctl - setup wb pipeline for ctl path | |
| 210 | 211 | * @phys_enc:Pointer to physical encoder |
| 211 | 212 | */ |
| 212 | −static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) | |
| 213 | +static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc) | |
| 213 | 214 | { |
| 214 | 215 | struct dpu_hw_wb *hw_wb; |
| 215 | 216 | struct dpu_hw_ctl *ctl; |
| 217 | + struct dpu_hw_cdm *hw_cdm; | |
| 216 | 218 | |
| 217 | 219 | if (!phys_enc) { |
| 218 | 220 | DPU_ERROR("invalid encoder\n"); |
| @@ -221,6 +223,7 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | ||
| 221 | 223 | |
| 222 | 224 | hw_wb = phys_enc->hw_wb; |
| 223 | 225 | ctl = phys_enc->hw_ctl; |
| 226 | + hw_cdm = phys_enc->hw_cdm; | |
| 224 | 227 | |
| 225 | 228 | if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && |
| 226 | 229 | (phys_enc->hw_ctl && |
| @@ -237,6 +240,9 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) · 10 unmodified lines | ||
| 237 | 240 | if (mode_3d && hw_pp && hw_pp->merge_3d) |
| 238 | 241 | intf_cfg.merge_3d = hw_pp->merge_3d->idx; |
| 239 | 242 | |
| 243 | + if (hw_cdm) | |
| 244 | + intf_cfg.cdm = hw_cdm->idx; | |
| 245 | + | |
| 240 | 246 | if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode) |
| 241 | 247 | phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, |
| 242 | 248 | mode_3d); |
| @@ -258,6 +264,96 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) · 15 unmodified lines | ||
| 258 | 264 | } |
| 259 | 265 | } |
| 260 | 266 | |
| 267 | +/** | |
| 268 | + * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block | |
| 269 | + * This API does not handle DPU_CHROMA_H1V2. | |
| 270 | + * @phys_enc:Pointer to physical encoder | |
| 271 | + */ | |
| 272 | +static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc) | |
| 273 | +{ | |
| 274 | + struct dpu_hw_cdm *hw_cdm; | |
| 275 | + struct dpu_hw_cdm_cfg *cdm_cfg; | |
| 276 | + struct dpu_hw_pingpong *hw_pp; | |
| 277 | + struct dpu_encoder_phys_wb *wb_enc; | |
| 278 | + const struct msm_format *format; | |
| 279 | + const struct dpu_format *dpu_fmt; | |
| 280 | + struct drm_writeback_job *wb_job; | |
| 281 | + int ret; | |
| 282 | + | |
| 283 | + if (!phys_enc) | |
| 284 | + return; | |
| 285 | + | |
| 286 | + wb_enc = to_dpu_encoder_phys_wb(phys_enc); | |
| 287 | + cdm_cfg = &wb_enc->cdm_cfg; | |
| 288 | + hw_pp = phys_enc->hw_pp; | |
| 289 | + hw_cdm = phys_enc->hw_cdm; | |
| 290 | + wb_job = wb_enc->wb_job; | |
| 291 | + | |
| 292 | + format = msm_framebuffer_format(wb_enc->wb_job->fb); | |
| 293 | + dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier); | |
| 294 | + | |
| 295 | + if (!hw_cdm) | |
| 296 | + return; | |
| 297 | + | |
| 298 | + if (!DPU_FORMAT_IS_YUV(dpu_fmt)) { | |
| 299 | + DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent), | |
| 300 | + dpu_fmt->base.pixel_format); | |
| 301 | + if (hw_cdm->ops.bind_pingpong_blk) | |
| 302 | + hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE); | |
| 303 | + | |
| 304 | + return; | |
| 305 | + } | |
| 306 | + | |
| 307 | + memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg)); | |
| 308 | + | |
| 309 | + cdm_cfg->output_width = wb_job->fb->width; | |
| 310 | + cdm_cfg->output_height = wb_job->fb->height; | |
| 311 | + cdm_cfg->output_fmt = dpu_fmt; | |
| 312 | + cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB; | |
| 313 | + cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ? | |
| 314 | + CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT; | |
| 315 | + cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l; | |
| 316 | + | |
| 317 | + /* enable 10 bit logic */ | |
| 318 | + switch (cdm_cfg->output_fmt->chroma_sample) { | |
| 319 | + case DPU_CHROMA_RGB: | |
| 320 | + cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; | |
| 321 | + cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; | |
| 322 | + break; | |
| 323 | + case DPU_CHROMA_H2V1: | |
| 324 | + cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; | |
| 325 | + cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; | |
| 326 | + break; | |
| 327 | + case DPU_CHROMA_420: | |
| 328 | + cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE; | |
| 329 | + cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE; | |
| 330 | + break; | |
| 331 | + case DPU_CHROMA_H1V2: | |
| 332 | + default: | |
| 333 | + DPU_ERROR("[enc:%d] unsupported chroma sampling type\n", | |
| 334 | + DRMID(phys_enc->parent)); | |
| 335 | + cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE; | |
| 336 | + cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE; | |
| 337 | + break; | |
| 338 | + } | |
| 339 | + | |
| 340 | + DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n", | |
| 341 | + DRMID(phys_enc->parent), cdm_cfg->output_width, | |
| 342 | + cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format, | |
| 343 | + cdm_cfg->output_type, cdm_cfg->output_bit_depth, | |
| 344 | + cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type); | |
| 345 | + | |
| 346 | + if (hw_cdm->ops.enable) { | |
| 347 | + cdm_cfg->pp_id = hw_pp->idx; | |
| 348 | + ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg); | |
| 349 | + if (ret < 0) { | |
| 350 | + DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n", | |
| 351 | + DRMID(phys_enc->parent), ret); | |
| 352 | + return; | |
| 353 | + } | |
| 354 | + } | |
| 355 | +} | |
| 356 | + | |
| 261 | 357 | /** |
| 262 | 358 | * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states |
| 263 | 359 | * @phys_enc: Pointer to physical encoder |
| @@ -307,7 +403,7 @@ static int dpu_encoder_phys_wb_atomic_check( · 43 unmodified lines | ||
| 307 | 403 | return -EINVAL; |
| 308 | 404 | } |
| 309 | 405 | |
| 310 | − return 0; | |
| 406 | + return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state); | |
| 311 | 407 | } |
| 312 | 408 | |
| 313 | 409 | |
| @@ -320,6 +416,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 6 unmodified lines | ||
| 320 | 416 | struct dpu_hw_wb *hw_wb; |
| 321 | 417 | struct dpu_hw_ctl *hw_ctl; |
| 322 | 418 | struct dpu_hw_pingpong *hw_pp; |
| 419 | + struct dpu_hw_cdm *hw_cdm; | |
| 323 | 420 | u32 pending_flush = 0; |
| 324 | 421 | |
| 325 | 422 | if (!phys_enc) |
| @@ -328,6 +425,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | ||
| 328 | 425 | hw_wb = phys_enc->hw_wb; |
| 329 | 426 | hw_pp = phys_enc->hw_pp; |
| 330 | 427 | hw_ctl = phys_enc->hw_ctl; |
| 428 | + hw_cdm = phys_enc->hw_cdm; | |
| 331 | 429 | |
| 332 | 430 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); |
| 333 | 431 | |
| @@ -343,6 +441,9 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 9 unmodified lines | ||
| 343 | 441 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 344 | 442 | hw_pp->merge_3d->idx); |
| 345 | 443 | |
| 444 | + if (hw_cdm && hw_ctl->ops.update_pending_flush_cdm) | |
| 445 | + hw_ctl->ops.update_pending_flush_cdm(hw_ctl, hw_cdm->idx); | |
| 446 | + | |
| 346 | 447 | if (hw_ctl->ops.get_pending_flush) |
| 347 | 448 | pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl); |
| 348 | 449 | |
| @@ -374,8 +475,9 @@ static void dpu_encoder_phys_wb_setup( · 25 unmodified lines | ||
| 374 | 475 | |
| 375 | 476 | dpu_encoder_phys_wb_setup_fb(phys_enc, fb); |
| 376 | 477 | |
| 377 | − dpu_encoder_phys_wb_setup_cdp(phys_enc); | |
| 478 | + dpu_encoder_helper_phys_setup_cdm(phys_enc); | |
| 378 | 479 | |
| 480 | + dpu_encoder_phys_wb_setup_ctl(phys_enc); | |
| 379 | 481 | } |
| 380 | 482 | |
| 381 | 483 | /** |
| @@ -580,20 +682,6 @@ static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc) · 198 unmodified lines | ||
| 580 | 682 | phys_enc->enable_state = DPU_ENC_DISABLED; |
| 581 | 683 | } |
| 582 | 684 | |
| 583 | −/** | |
| 584 | − * dpu_encoder_phys_wb_destroy - destroy writeback encoder | |
| 585 | − * @phys_enc: Pointer to physical encoder | |
| 586 | − */ | |
| 587 | −static void dpu_encoder_phys_wb_destroy(struct dpu_encoder_phys *phys_enc) | |
| 588 | −{ | |
| 589 | − if (!phys_enc) | |
| 590 | − return; | |
| 591 | − | |
| 592 | − DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0); | |
| 593 | − | |
| 594 | − kfree(phys_enc); | |
| 595 | −} | |
| 596 | − | |
| 597 | 685 | static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc, |
| 598 | 686 | struct drm_writeback_job *job) |
| 599 | 687 | { |
| @@ -689,7 +777,6 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) · 89 unmodified lines | ||
| 689 | 777 | ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set; |
| 690 | 778 | ops->enable = dpu_encoder_phys_wb_enable; |
| 691 | 779 | ops->disable = dpu_encoder_phys_wb_disable; |
| 692 | − ops->destroy = dpu_encoder_phys_wb_destroy; | |
| 693 | 780 | ops->atomic_check = dpu_encoder_phys_wb_atomic_check; |
| 694 | 781 | ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done; |
| 695 | 782 | ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff; |
| @@ -705,9 +792,10 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) · 9 unmodified lines | ||
| 705 | 792 | |
| 706 | 793 | /** |
| 707 | 794 | * dpu_encoder_phys_wb_init - initialize writeback encoder |
| 795 | + * @dev: Corresponding device for devres management | |
| 708 | 796 | * @p: Pointer to init info structure with initialization params |
| 709 | 797 | */ |
| 710 | −struct dpu_encoder_phys *dpu_encoder_phys_wb_init( | |
| 798 | +struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev, | |
| 711 | 799 | struct dpu_enc_phys_init_params *p) |
| 712 | 800 | { |
| 713 | 801 | struct dpu_encoder_phys *phys_enc = NULL; |
| @@ -720,7 +808,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( · 6 unmodified lines | ||
| 720 | 808 | return ERR_PTR(-EINVAL); |
| 721 | 809 | } |
| 722 | 810 | |
| 723 | − wb_enc = kzalloc(sizeof(*wb_enc), GFP_KERNEL); | |
| 811 | + wb_enc = drmm_kzalloc(dev, sizeof(*wb_enc), GFP_KERNEL); | |
| 724 | 812 | if (!wb_enc) { |
| 725 | 813 | DPU_ERROR("failed to allocate wb phys_enc enc\n"); |
| 726 | 814 | return ERR_PTR(-ENOMEM); |
| @@ -22,23 +22,14 @@ · 21 unmodified lines | ||
| 22 | 22 | BIT(DPU_SSPP_CSC_10BIT)) |
| 23 | 23 | |
| 24 | 24 | #define VIG_MSM8998_MASK \ |
| 25 | − (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3)) | |
| 25 | + (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) | |
| 26 | 26 | |
| 27 | 27 | #define VIG_SDM845_MASK \ |
| 28 | − (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3)) | |
| 28 | + (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE)) | |
| 29 | 29 | |
| 30 | 30 | #define VIG_SDM845_MASK_SDMA \ |
| 31 | 31 | (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) |
| 32 | 32 | |
| 33 | −#define VIG_SC7180_MASK \ | |
| 34 | − (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4)) | |
| 35 | − | |
| 36 | −#define VIG_SM6125_MASK \ | |
| 37 | − (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE)) | |
| 38 | − | |
| 39 | −#define VIG_SC7180_MASK_SDMA \ | |
| 40 | − (VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) | |
| 41 | − | |
| 42 | 33 | #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) |
| 43 | 34 | |
| 44 | 35 | #define DMA_MSM8998_MASK \ |
| @@ -47,7 +38,7 @@ · 2 unmodified lines | ||
| 47 | 38 | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) |
| 48 | 39 | |
| 49 | 40 | #define VIG_SC7280_MASK \ |
| 50 | − (VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION)) | |
| 41 | + (VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION)) | |
| 51 | 42 | |
| 52 | 43 | #define VIG_SC7280_MASK_SDMA \ |
| 53 | 44 | (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) |
| @@ -211,7 +202,7 @@ static const u32 rotation_v2_formats[] = { · 157 unmodified lines | ||
| 211 | 202 | /* TODO add formats after validation */ |
| 212 | 203 | }; |
| 213 | 204 | |
| 214 | −static const uint32_t wb2_formats[] = { | |
| 205 | +static const u32 wb2_formats_rgb[] = { | |
| 215 | 206 | DRM_FORMAT_RGB565, |
| 216 | 207 | DRM_FORMAT_BGR565, |
| 217 | 208 | DRM_FORMAT_RGB888, |
| @@ -245,21 +236,56 @@ static const uint32_t wb2_formats[] = { · 27 unmodified lines | ||
| 245 | 236 | DRM_FORMAT_XBGR4444, |
| 246 | 237 | }; |
| 247 | 238 | |
| 239 | +static const u32 wb2_formats_rgb_yuv[] = { | |
| 240 | + DRM_FORMAT_RGB565, | |
| 241 | + DRM_FORMAT_BGR565, | |
| 242 | + DRM_FORMAT_RGB888, | |
| 243 | + DRM_FORMAT_ARGB8888, | |
| 244 | + DRM_FORMAT_RGBA8888, | |
| 245 | + DRM_FORMAT_ABGR8888, | |
| 246 | + DRM_FORMAT_XRGB8888, | |
| 247 | + DRM_FORMAT_RGBX8888, | |
| 248 | + DRM_FORMAT_XBGR8888, | |
| 249 | + DRM_FORMAT_ARGB1555, | |
| 250 | + DRM_FORMAT_RGBA5551, | |
| 251 | + DRM_FORMAT_XRGB1555, | |
| 252 | + DRM_FORMAT_RGBX5551, | |
| 253 | + DRM_FORMAT_ARGB4444, | |
| 254 | + DRM_FORMAT_RGBA4444, | |
| 255 | + DRM_FORMAT_RGBX4444, | |
| 256 | + DRM_FORMAT_XRGB4444, | |
| 257 | + DRM_FORMAT_BGR565, | |
| 258 | + DRM_FORMAT_BGR888, | |
| 259 | + DRM_FORMAT_ABGR8888, | |
| 260 | + DRM_FORMAT_BGRA8888, | |
| 261 | + DRM_FORMAT_BGRX8888, | |
| 262 | + DRM_FORMAT_XBGR8888, | |
| 263 | + DRM_FORMAT_ABGR1555, | |
| 264 | + DRM_FORMAT_BGRA5551, | |
| 265 | + DRM_FORMAT_XBGR1555, | |
| 266 | + DRM_FORMAT_BGRX5551, | |
| 267 | + DRM_FORMAT_ABGR4444, | |
| 268 | + DRM_FORMAT_BGRA4444, | |
| 269 | + DRM_FORMAT_BGRX4444, | |
| 270 | + DRM_FORMAT_XBGR4444, | |
| 271 | + DRM_FORMAT_NV12, | |
| 272 | +}; | |
| 273 | + | |
| 248 | 274 | /************************************************************* |
| 249 | 275 | * SSPP sub blocks config |
| 250 | 276 | *************************************************************/ |
| 251 | 277 | |
| 278 | +#define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min)) | |
| 279 | + | |
| 252 | 280 | /* SSPP common configuration */ |
| 253 | −#define _VIG_SBLK(sdma_pri, qseed_ver) \ | |
| 281 | +#define _VIG_SBLK(scaler_ver) \ | |
| 254 | 282 | { \ |
| 255 | 283 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ |
| 256 | 284 | .maxupscale = MAX_UPSCALE_RATIO, \ |
| 257 | − .smart_dma_priority = sdma_pri, \ | |
| 258 | 285 | .scaler_blk = {.name = "scaler", \ |
| 259 | − .id = qseed_ver, \ | |
| 286 | + .version = scaler_ver, \ | |
| 260 | 287 | .base = 0xa00, .len = 0xa0,}, \ |
| 261 | 288 | .csc_blk = {.name = "csc", \ |
| 262 | − .id = DPU_SSPP_CSC_10BIT, \ | |
| 263 | 289 | .base = 0x1a00, .len = 0x100,}, \ |
| 264 | 290 | .format_list = plane_formats_yuv, \ |
| 265 | 291 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ |
| @@ -268,16 +294,14 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines | ||
| 268 | 294 | .rotation_cfg = NULL, \ |
| 269 | 295 | } |
| 270 | 296 | |
| 271 | −#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, rot_cfg) \ | |
| 297 | +#define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \ | |
| 272 | 298 | { \ |
| 273 | 299 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ |
| 274 | 300 | .maxupscale = MAX_UPSCALE_RATIO, \ |
| 275 | − .smart_dma_priority = sdma_pri, \ | |
| 276 | 301 | .scaler_blk = {.name = "scaler", \ |
| 277 | − .id = qseed_ver, \ | |
| 302 | + .version = scaler_ver, \ | |
| 278 | 303 | .base = 0xa00, .len = 0xa0,}, \ |
| 279 | 304 | .csc_blk = {.name = "csc", \ |
| 280 | − .id = DPU_SSPP_CSC_10BIT, \ | |
| 281 | 305 | .base = 0x1a00, .len = 0x100,}, \ |
| 282 | 306 | .format_list = plane_formats_yuv, \ |
| 283 | 307 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ |
| @@ -286,91 +310,64 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines | ||
| 286 | 310 | .rotation_cfg = rot_cfg, \ |
| 287 | 311 | } |
| 288 | 312 | |
| 289 | −#define _DMA_SBLK(sdma_pri) \ | |
| 313 | +#define _VIG_SBLK_NOSCALE() \ | |
| 314 | + { \ | |
| 315 | + .maxdwnscale = SSPP_UNITY_SCALE, \ | |
| 316 | + .maxupscale = SSPP_UNITY_SCALE, \ | |
| 317 | + .format_list = plane_formats_yuv, \ | |
| 318 | + .num_formats = ARRAY_SIZE(plane_formats_yuv), \ | |
| 319 | + .virt_format_list = plane_formats, \ | |
| 320 | + .virt_num_formats = ARRAY_SIZE(plane_formats), \ | |
| 321 | + } | |
| 322 | + | |
| 323 | +#define _DMA_SBLK() \ | |
| 290 | 324 | { \ |
| 291 | 325 | .maxdwnscale = SSPP_UNITY_SCALE, \ |
| 292 | 326 | .maxupscale = SSPP_UNITY_SCALE, \ |
| 293 | − .smart_dma_priority = sdma_pri, \ | |
| 294 | 327 | .format_list = plane_formats, \ |
| 295 | 328 | .num_formats = ARRAY_SIZE(plane_formats), \ |
| 296 | 329 | .virt_format_list = plane_formats, \ |
| 297 | 330 | .virt_num_formats = ARRAY_SIZE(plane_formats), \ |
| 298 | 331 | } |
| 299 | 332 | |
| 300 | −static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = | |
| 301 | − _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); | |
| 302 | −static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = | |
| 303 | − _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); | |
| 304 | −static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = | |
| 305 | − _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); | |
| 306 | −static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = | |
| 307 | − _VIG_SBLK(0, DPU_SSPP_SCALER_QSEED3); | |
| 308 | − | |
| 309 | 333 | static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { |
| 310 | 334 | .rot_maxheight = 1088, |
| 311 | 335 | .rot_num_formats = ARRAY_SIZE(rotation_v2_formats), |
| 312 | 336 | .rot_format_list = rotation_v2_formats, |
| 313 | 337 | }; |
| 314 | 338 | |
| 315 | −static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = | |
| 316 | − _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3); | |
| 317 | −static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = | |
| 318 | − _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3); | |
| 319 | −static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = | |
| 320 | − _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3); | |
| 321 | −static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = | |
| 322 | − _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3); | |
| 323 | − | |
| 324 | −static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1); | |
| 325 | −static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2); | |
| 326 | −static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3); | |
| 327 | −static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4); | |
| 328 | − | |
| 329 | −static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 = | |
| 330 | − _VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4); | |
| 331 | − | |
| 332 | −static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 = | |
| 333 | − _VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); | |
| 334 | − | |
| 335 | −static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 = | |
| 336 | − _VIG_SBLK(2, DPU_SSPP_SCALER_QSEED4); | |
| 337 | − | |
| 338 | −static const struct dpu_sspp_sub_blks sm6125_vig_sblk_0 = | |
| 339 | − _VIG_SBLK(3, DPU_SSPP_SCALER_QSEED3LITE); | |
| 340 | − | |
| 341 | −static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 = | |
| 342 | − _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED4); | |
| 343 | −static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 = | |
| 344 | − _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED4); | |
| 345 | −static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 = | |
| 346 | − _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4); | |
| 347 | −static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 = | |
| 348 | − _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4); | |
| 349 | − | |
| 350 | −static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 = | |
| 351 | − _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4); | |
| 352 | −static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 = | |
| 353 | − _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4); | |
| 354 | −static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 = | |
| 355 | − _VIG_SBLK(9, DPU_SSPP_SCALER_QSEED4); | |
| 356 | −static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 = | |
| 357 | − _VIG_SBLK(10, DPU_SSPP_SCALER_QSEED4); | |
| 358 | −static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK(5); | |
| 359 | −static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK(6); | |
| 360 | − | |
| 361 | −#define _VIG_SBLK_NOSCALE(sdma_pri) \ | |
| 362 | − { \ | |
| 363 | − .maxdwnscale = SSPP_UNITY_SCALE, \ | |
| 364 | − .maxupscale = SSPP_UNITY_SCALE, \ | |
| 365 | − .smart_dma_priority = sdma_pri, \ | |
| 366 | − .format_list = plane_formats_yuv, \ | |
| 367 | − .num_formats = ARRAY_SIZE(plane_formats_yuv), \ | |
| 368 | − .virt_format_list = plane_formats, \ | |
| 369 | − .virt_num_formats = ARRAY_SIZE(plane_formats), \ | |
| 370 | − } | |
| 339 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale = | |
| 340 | + _VIG_SBLK_NOSCALE(); | |
| 341 | + | |
| 342 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_2 = | |
| 343 | + _VIG_SBLK(SSPP_SCALER_VER(1, 2)); | |
| 344 | + | |
| 345 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_3 = | |
| 346 | + _VIG_SBLK(SSPP_SCALER_VER(1, 3)); | |
| 347 | + | |
| 348 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_4 = | |
| 349 | + _VIG_SBLK(SSPP_SCALER_VER(1, 4)); | |
| 350 | + | |
| 351 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_2_4 = | |
| 352 | + _VIG_SBLK(SSPP_SCALER_VER(2, 4)); | |
| 353 | + | |
| 354 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0 = | |
| 355 | + _VIG_SBLK(SSPP_SCALER_VER(3, 0)); | |
| 356 | + | |
| 357 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0_rot_v2 = | |
| 358 | + _VIG_SBLK_ROT(SSPP_SCALER_VER(3, 0), | |
| 359 | + &dpu_rot_sc7280_cfg_v2); | |
| 360 | + | |
| 361 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_1 = | |
| 362 | + _VIG_SBLK(SSPP_SCALER_VER(3, 1)); | |
| 363 | + | |
| 364 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 = | |
| 365 | + _VIG_SBLK(SSPP_SCALER_VER(3, 2)); | |
| 366 | + | |
| 367 | +static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 = | |
| 368 | + _VIG_SBLK(SSPP_SCALER_VER(3, 3)); | |
| 371 | 369 | |
| 372 | −static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE(2); | |
| 373 | −static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK(1); | |
| 370 | +static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK(); | |
| 374 | 371 | |
| 375 | 372 | /************************************************************* |
| 376 | 373 | * MIXER sub blocks config |
| @@ -422,12 +419,12 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { · 45 unmodified lines | ||
| 422 | 419 | * DSPP sub blocks config |
| 423 | 420 | *************************************************************/ |
| 424 | 421 | static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { |
| 425 | − .pcc = {.name = "pcc", .id = DPU_DSPP_PCC, .base = 0x1700, | |
| 422 | + .pcc = {.name = "pcc", .base = 0x1700, | |
| 426 | 423 | .len = 0x90, .version = 0x10007}, |
| 427 | 424 | }; |
| 428 | 425 | |
| 429 | 426 | static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = { |
| 430 | − .pcc = {.name = "pcc", .id = DPU_DSPP_PCC, .base = 0x1700, | |
| 427 | + .pcc = {.name = "pcc", .base = 0x1700, | |
| 431 | 428 | .len = 0x90, .version = 0x40000}, |
| 432 | 429 | }; |
| 433 | 430 | |
| @@ -435,19 +432,19 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = { · 1 unmodified line | ||
| 435 | 432 | * PINGPONG sub blocks config |
| 436 | 433 | *************************************************************/ |
| 437 | 434 | static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = { |
| 438 | − .te2 = {.name = "te2", .id = DPU_PINGPONG_TE2, .base = 0x2000, .len = 0x0, | |
| 435 | + .te2 = {.name = "te2", .base = 0x2000, .len = 0x0, | |
| 439 | 436 | .version = 0x1}, |
| 440 | − .dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0, | |
| 437 | + .dither = {.name = "dither", .base = 0x30e0, | |
| 441 | 438 | .len = 0x20, .version = 0x10000}, |
| 442 | 439 | }; |
| 443 | 440 | |
| 444 | 441 | static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = { |
| 445 | − .dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0, | |
| 442 | + .dither = {.name = "dither", .base = 0x30e0, | |
| 446 | 443 | .len = 0x20, .version = 0x10000}, |
| 447 | 444 | }; |
| 448 | 445 | |
| 449 | 446 | static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { |
| 450 | − .dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0xe0, | |
| 447 | + .dither = {.name = "dither", .base = 0xe0, | |
| 451 | 448 | .len = 0x20, .version = 0x20000}, |
| 452 | 449 | }; |
| 453 | 450 | |
| @@ -464,6 +461,16 @@ static const struct dpu_dsc_sub_blks dsc_sblk_1 = { · 10 unmodified lines | ||
| 464 | 461 | .ctl = {.name = "ctl", .base = 0xF80, .len = 0x10}, |
| 465 | 462 | }; |
| 466 | 463 | |
| 464 | +/************************************************************* | |
| 465 | + * CDM block config | |
| 466 | + *************************************************************/ | |
| 467 | +static const struct dpu_cdm_cfg sc7280_cdm = { | |
| 468 | + .name = "cdm_0", | |
| 469 | + .id = CDM_0, | |
| 470 | + .len = 0x228, | |
| 471 | + .base = 0x79200, | |
| 472 | +}; | |
| 473 | + | |
| 467 | 474 | /************************************************************* |
| 468 | 475 | * VBIF sub blocks config |
| 469 | 476 | *************************************************************/ |
| @@ -472,6 +479,7 @@ static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2}; · 2 unmodified lines | ||
| 472 | 479 | static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1}; |
| 473 | 480 | static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6}; |
| 474 | 481 | static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3}; |
| 482 | +static const u32 sm8650_rt_pri_lvl[] = {4, 4, 5, 5, 5, 5, 5, 6}; | |
| 475 | 483 | |
| 476 | 484 | static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { |
| 477 | 485 | { |
| @@ -558,6 +566,26 @@ static const struct dpu_vbif_cfg sm8550_vbif[] = { · 80 unmodified lines | ||
| 558 | 566 | }, |
| 559 | 567 | }; |
| 560 | 568 | |
| 569 | +static const struct dpu_vbif_cfg sm8650_vbif[] = { | |
| 570 | + { | |
| 571 | + .name = "vbif_rt", .id = VBIF_RT, | |
| 572 | + .base = 0, .len = 0x1074, | |
| 573 | + .features = BIT(DPU_VBIF_QOS_REMAP), | |
| 574 | + .xin_halt_timeout = 0x4000, | |
| 575 | + .qos_rp_remap_size = 0x40, | |
| 576 | + .qos_rt_tbl = { | |
| 577 | + .npriority_lvl = ARRAY_SIZE(sm8650_rt_pri_lvl), | |
| 578 | + .priority_lvl = sm8650_rt_pri_lvl, | |
| 579 | + }, | |
| 580 | + .qos_nrt_tbl = { | |
| 581 | + .npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl), | |
| 582 | + .priority_lvl = sdm845_nrt_pri_lvl, | |
| 583 | + }, | |
| 584 | + .memtype_count = 16, | |
| 585 | + .memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, | |
| 586 | + }, | |
| 587 | +}; | |
| 588 | + | |
| 561 | 589 | /************************************************************* |
| 562 | 590 | * PERF data config |
| 563 | 591 | *************************************************************/ |
| @@ -654,6 +682,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { · 90 unmodified lines | ||
| 654 | 682 | #include "catalog/dpu_3_0_msm8998.h" |
| 655 | 683 | |
| 656 | 684 | #include "catalog/dpu_4_0_sdm845.h" |
| 685 | +#include "catalog/dpu_4_1_sdm670.h" | |
| 657 | 686 | |
| 658 | 687 | #include "catalog/dpu_5_0_sm8150.h" |
| 659 | 688 | #include "catalog/dpu_5_1_sc8180x.h" |
| @@ -673,3 +702,5 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { · 13 unmodified lines | ||
| 673 | 702 | #include "catalog/dpu_8_1_sm8450.h" |
| 674 | 703 | |
| 675 | 704 | #include "catalog/dpu_9_0_sm8550.h" |
| 705 | + | |
| 706 | +#include "catalog/dpu_10_0_sm8650.h" | |
| @@ -51,9 +51,7 @@ enum { · 50 unmodified lines | ||
| 51 | 51 | /** |
| 52 | 52 | * SSPP sub-blocks/features |
| 53 | 53 | * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support |
| 54 | − * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support | |
| 55 | − * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support | |
| 56 | − * @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support | |
| 54 | + * @DPU_SSPP_SCALER_QSEED3_COMPATIBLE, QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4) | |
| 57 | 55 | * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes |
| 58 | 56 | * @DPU_SSPP_CSC, Support of Color space converion |
| 59 | 57 | * @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion |
| @@ -71,9 +69,7 @@ enum { · 11 unmodified lines | ||
| 71 | 69 | */ |
| 72 | 70 | enum { |
| 73 | 71 | DPU_SSPP_SCALER_QSEED2 = 0x1, |
| 74 | − DPU_SSPP_SCALER_QSEED3, | |
| 75 | − DPU_SSPP_SCALER_QSEED3LITE, | |
| 76 | − DPU_SSPP_SCALER_QSEED4, | |
| 72 | + DPU_SSPP_SCALER_QSEED3_COMPATIBLE, | |
| 77 | 73 | DPU_SSPP_SCALER_RGB, |
| 78 | 74 | DPU_SSPP_CSC, |
| 79 | 75 | DPU_SSPP_CSC_10BIT, |
| @@ -248,50 +244,51 @@ enum { · 168 unmodified lines | ||
| 248 | 244 | u32 len; \ |
| 249 | 245 | unsigned long features |
| 250 | 246 | |
| 251 | −/** | |
| 252 | − * MACRO DPU_HW_SUBBLK_INFO - information of HW sub-block inside DPU | |
| 253 | − * @name: string name for debug purposes | |
| 254 | − * @id: enum identifying this sub-block | |
| 255 | − * @base: offset of this sub-block relative to the block | |
| 256 | − * offset | |
| 257 | − * @len register block length of this sub-block | |
| 258 | − */ | |
| 259 | −#define DPU_HW_SUBBLK_INFO \ | |
| 260 | − char name[DPU_HW_BLK_NAME_LEN]; \ | |
| 261 | − u32 id; \ | |
| 262 | − u32 base; \ | |
| 263 | − u32 len | |
| 264 | − | |
| 265 | 247 | /** |
| 266 | 248 | * struct dpu_scaler_blk: Scaler information |
| 267 | − * @info: HW register and features supported by this sub-blk | |
| 268 | − * @version: qseed block revision | |
| 249 | + * @name: string name for debug purposes | |
| 250 | + * @base: offset of this sub-block relative to the block offset | |
| 251 | + * @len: register block length of this sub-block | |
| 252 | + * @version: qseed block revision, on QSEED3+ platforms this is the value of | |
| 253 | + * scaler_blk.base + QSEED3_HW_VERSION registers. | |
| 269 | 254 | */ |
| 270 | 255 | struct dpu_scaler_blk { |
| 271 | − DPU_HW_SUBBLK_INFO; | |
| 256 | + char name[DPU_HW_BLK_NAME_LEN]; | |
| 257 | + u32 base; | |
| 258 | + u32 len; | |
| 272 | 259 | u32 version; |
| 273 | 260 | }; |
| 274 | 261 | |
| 275 | 262 | struct dpu_csc_blk { |
| 276 | − DPU_HW_SUBBLK_INFO; | |
| 263 | + char name[DPU_HW_BLK_NAME_LEN]; | |
| 264 | + u32 base; | |
| 265 | + u32 len; | |
| 277 | 266 | }; |
| 278 | 267 | |
| 279 | 268 | /** |
| 280 | 269 | * struct dpu_pp_blk : Pixel processing sub-blk information |
| 281 | − * @info: HW register and features supported by this sub-blk | |
| 270 | + * @name: string name for debug purposes | |
| 271 | + * @base: offset of this sub-block relative to the block offset | |
| 272 | + * @len: register block length of this sub-block | |
| 282 | 273 | * @version: HW Algorithm version |
| 283 | 274 | */ |
| 284 | 275 | struct dpu_pp_blk { |
| 285 | − DPU_HW_SUBBLK_INFO; | |
| 276 | + char name[DPU_HW_BLK_NAME_LEN]; | |
| 277 | + u32 base; | |
| 278 | + u32 len; | |
| 286 | 279 | u32 version; |
| 287 | 280 | }; |
| 288 | 281 | |
| 289 | 282 | /** |
| 290 | 283 | * struct dpu_dsc_blk - DSC Encoder sub-blk information |
| 291 | − * @info: HW register and features supported by this sub-blk | |
| 284 | + * @name: string name for debug purposes | |
| 285 | + * @base: offset of this sub-block relative to the block offset | |
| 286 | + * @len: register block length of this sub-block | |
| 292 | 287 | */ |
| 293 | 288 | struct dpu_dsc_blk { |
| 294 | − DPU_HW_SUBBLK_INFO; | |
| 289 | + char name[DPU_HW_BLK_NAME_LEN]; | |
| 290 | + u32 base; | |
| 291 | + u32 len; | |
| 295 | 292 | }; |
| 296 | 293 | |
| 297 | 294 | /** |
| @@ -341,7 +338,6 @@ struct dpu_rotation_cfg { · 43 unmodified lines | ||
| 341 | 338 | * @max_mixer_width max layer mixer line width support. |
| 342 | 339 | * @max_mixer_blendstages max layer mixer blend stages or |
| 343 | 340 | * supported z order |
| 344 | − * @qseed_type qseed2 or qseed3 support. | |
| 345 | 341 | * @has_src_split source split feature status |
| 346 | 342 | * @has_dim_layer dim layer feature status |
| 347 | 343 | * @has_idle_pc indicate if idle power collapse feature is supported |
| @@ -354,7 +350,6 @@ struct dpu_rotation_cfg { · 6 unmodified lines | ||
| 354 | 350 | struct dpu_caps { |
| 355 | 351 | u32 max_mixer_width; |
| 356 | 352 | u32 max_mixer_blendstages; |
| 357 | − u32 qseed_type; | |
| 358 | 353 | bool has_src_split; |
| 359 | 354 | bool has_dim_layer; |
| 360 | 355 | bool has_idle_pc; |
| @@ -371,7 +366,6 @@ struct dpu_caps { · 10 unmodified lines | ||
| 371 | 366 | * common: Pointer to common configurations shared by sub blocks |
| 372 | 367 | * @maxdwnscale: max downscale ratio supported(without DECIMATION) |
| 373 | 368 | * @maxupscale: maxupscale ratio supported |
| 374 | − * @smart_dma_priority: hw priority of rect1 of multirect pipe | |
| 375 | 369 | * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps |
| 376 | 370 | * @qseed_ver: qseed version |
| 377 | 371 | * @scaler_blk: |
| @@ -385,7 +379,6 @@ struct dpu_caps { · 7 unmodified lines | ||
| 385 | 379 | struct dpu_sspp_sub_blks { |
| 386 | 380 | u32 maxdwnscale; |
| 387 | 381 | u32 maxupscale; |
| 388 | − u32 smart_dma_priority; | |
| 389 | 382 | u32 max_per_pipe_bw; |
| 390 | 383 | u32 qseed_ver; |
| 391 | 384 | struct dpu_scaler_blk scaler_blk; |
| @@ -689,6 +682,17 @@ struct dpu_vbif_cfg { · 297 unmodified lines | ||
| 689 | 682 | u32 memtype[MAX_XIN_COUNT]; |
| 690 | 683 | }; |
| 691 | 684 | |
| 685 | +/** | |
| 686 | + * struct dpu_cdm_cfg - information of chroma down blocks | |
| 687 | + * @name string name for debug purposes | |
| 688 | + * @id enum identifying this block | |
| 689 | + * @base register offset of this block | |
| 690 | + * @features bit mask identifying sub-blocks/features | |
| 691 | + */ | |
| 692 | +struct dpu_cdm_cfg { | |
| 693 | + DPU_HW_BLK_INFO; | |
| 694 | +}; | |
| 695 | + | |
| 692 | 696 | /** |
| 693 | 697 | * Define CDP use cases |
| 694 | 698 | * @DPU_PERF_CDP_UDAGE_RT: real-time use cases |
| @@ -812,6 +816,8 @@ struct dpu_mdss_cfg { · 117 unmodified lines | ||
| 812 | 816 | u32 wb_count; |
| 813 | 817 | const struct dpu_wb_cfg *wb; |
| 814 | 818 | |
| 819 | + const struct dpu_cdm_cfg *cdm; | |
| 820 | + | |
| 815 | 821 | u32 ad_count; |
| 816 | 822 | |
| 817 | 823 | u32 dspp_count; |
| @@ -827,6 +833,7 @@ struct dpu_mdss_cfg { · 9 unmodified lines | ||
| 827 | 833 | |
| 828 | 834 | extern const struct dpu_mdss_cfg dpu_msm8998_cfg; |
| 829 | 835 | extern const struct dpu_mdss_cfg dpu_sdm845_cfg; |
| 836 | +extern const struct dpu_mdss_cfg dpu_sdm670_cfg; | |
| 830 | 837 | extern const struct dpu_mdss_cfg dpu_sm8150_cfg; |
| 831 | 838 | extern const struct dpu_mdss_cfg dpu_sc8180x_cfg; |
| 832 | 839 | extern const struct dpu_mdss_cfg dpu_sm8250_cfg; |
| @@ -841,5 +848,6 @@ extern const struct dpu_mdss_cfg dpu_sc7280_cfg; · 8 unmodified lines | ||
| 841 | 848 | extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg; |
| 842 | 849 | extern const struct dpu_mdss_cfg dpu_sm8450_cfg; |
| 843 | 850 | extern const struct dpu_mdss_cfg dpu_sm8550_cfg; |
| 851 | +extern const struct dpu_mdss_cfg dpu_sm8650_cfg; | |
| 844 | 852 | |
| 845 | 853 | #endif /* _DPU_HW_CATALOG_H */ |
| @@ -0,0 +1,247 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2023, The Linux Foundation. All rights reserved. | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include <linux/bitfield.h> | |
| 7 | + | |
| 8 | +#include <drm/drm_managed.h> | |
| 9 | + | |
| 10 | +#include "dpu_hw_mdss.h" | |
| 11 | +#include "dpu_hw_util.h" | |
| 12 | +#include "dpu_hw_catalog.h" | |
| 13 | +#include "dpu_hw_cdm.h" | |
| 14 | +#include "dpu_kms.h" | |
| 15 | + | |
| 16 | +#define CDM_CSC_10_OPMODE 0x000 | |
| 17 | +#define CDM_CSC_10_BASE 0x004 | |
| 18 | + | |
| 19 | +#define CDM_CDWN2_OP_MODE 0x100 | |
| 20 | +#define CDM_CDWN2_CLAMP_OUT 0x104 | |
| 21 | +#define CDM_CDWN2_PARAMS_3D_0 0x108 | |
| 22 | +#define CDM_CDWN2_PARAMS_3D_1 0x10C | |
| 23 | +#define CDM_CDWN2_COEFF_COSITE_H_0 0x110 | |
| 24 | +#define CDM_CDWN2_COEFF_COSITE_H_1 0x114 | |
| 25 | +#define CDM_CDWN2_COEFF_COSITE_H_2 0x118 | |
| 26 | +#define CDM_CDWN2_COEFF_OFFSITE_H_0 0x11C | |
| 27 | +#define CDM_CDWN2_COEFF_OFFSITE_H_1 0x120 | |
| 28 | +#define CDM_CDWN2_COEFF_OFFSITE_H_2 0x124 | |
| 29 | +#define CDM_CDWN2_COEFF_COSITE_V 0x128 | |
| 30 | +#define CDM_CDWN2_COEFF_OFFSITE_V 0x12C | |
| 31 | +#define CDM_CDWN2_OUT_SIZE 0x130 | |
| 32 | + | |
| 33 | +#define CDM_HDMI_PACK_OP_MODE 0x200 | |
| 34 | +#define CDM_CSC_10_MATRIX_COEFF_0 0x004 | |
| 35 | + | |
| 36 | +#define CDM_MUX 0x224 | |
| 37 | + | |
| 38 | +/* CDM CDWN2 sub-block bit definitions */ | |
| 39 | +#define CDM_CDWN2_OP_MODE_EN BIT(0) | |
| 40 | +#define CDM_CDWN2_OP_MODE_ENABLE_H BIT(1) | |
| 41 | +#define CDM_CDWN2_OP_MODE_ENABLE_V BIT(2) | |
| 42 | +#define CDM_CDWN2_OP_MODE_BITS_OUT_8BIT BIT(7) | |
| 43 | +#define CDM_CDWN2_V_PIXEL_METHOD_MASK GENMASK(6, 5) | |
| 44 | +#define CDM_CDWN2_H_PIXEL_METHOD_MASK GENMASK(4, 3) | |
| 45 | + | |
| 46 | +/* CDM CSC10 sub-block bit definitions */ | |
| 47 | +#define CDM_CSC10_OP_MODE_EN BIT(0) | |
| 48 | +#define CDM_CSC10_OP_MODE_SRC_FMT_YUV BIT(1) | |
| 49 | +#define CDM_CSC10_OP_MODE_DST_FMT_YUV BIT(2) | |
| 50 | + | |
| 51 | +/* CDM HDMI pack sub-block bit definitions */ | |
| 52 | +#define CDM_HDMI_PACK_OP_MODE_EN BIT(0) | |
| 53 | + | |
| 54 | +/* | |
| 55 | + * Horizontal coefficients for cosite chroma downscale | |
| 56 | + * s13 representation of coefficients | |
| 57 | + */ | |
| 58 | +static u32 cosite_h_coeff[] = {0x00000016, 0x000001cc, 0x0100009e}; | |
| 59 | + | |
| 60 | +/* | |
| 61 | + * Horizontal coefficients for offsite chroma downscale | |
| 62 | + */ | |
| 63 | +static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; | |
| 64 | + | |
| 65 | +/* | |
| 66 | + * Vertical coefficients for cosite chroma downscale | |
| 67 | + */ | |
| 68 | +static u32 cosite_v_coeff[] = {0x00080004}; | |
| 69 | +/* | |
| 70 | + * Vertical coefficients for offsite chroma downscale | |
| 71 | + */ | |
| 72 | +static u32 offsite_v_coeff[] = {0x00060002}; | |
| 73 | + | |
| 74 | +static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cfg) | |
| 75 | +{ | |
| 76 | + struct dpu_hw_blk_reg_map *c = &ctx->hw; | |
| 77 | + u32 opmode; | |
| 78 | + u32 out_size; | |
| 79 | + | |
| 80 | + switch (cfg->h_cdwn_type) { | |
| 81 | + case CDM_CDWN_DISABLE: | |
| 82 | + opmode = 0; | |
| 83 | + break; | |
| 84 | + case CDM_CDWN_PIXEL_DROP: | |
| 85 | + opmode = CDM_CDWN2_OP_MODE_ENABLE_H | | |
| 86 | + FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, | |
| 87 | + CDM_CDWN2_METHOD_PIXEL_DROP); | |
| 88 | + break; | |
| 89 | + case CDM_CDWN_AVG: | |
| 90 | + opmode = CDM_CDWN2_OP_MODE_ENABLE_H | | |
| 91 | + FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, | |
| 92 | + CDM_CDWN2_METHOD_AVG); | |
| 93 | + break; | |
| 94 | + case CDM_CDWN_COSITE: | |
| 95 | + opmode = CDM_CDWN2_OP_MODE_ENABLE_H | | |
| 96 | + FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, | |
| 97 | + CDM_CDWN2_METHOD_COSITE); | |
| 98 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0, | |
| 99 | + cosite_h_coeff[0]); | |
| 100 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1, | |
| 101 | + cosite_h_coeff[1]); | |
| 102 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_2, | |
| 103 | + cosite_h_coeff[2]); | |
| 104 | + break; | |
| 105 | + case CDM_CDWN_OFFSITE: | |
| 106 | + opmode = CDM_CDWN2_OP_MODE_ENABLE_H | | |
| 107 | + FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, CDM_CDWN2_METHOD_OFFSITE); | |
| 108 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_0, | |
| 109 | + offsite_h_coeff[0]); | |
| 110 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_1, | |
| 111 | + offsite_h_coeff[1]); | |
| 112 | + DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_2, | |
| 113 | + offsite_h_coeff[2]); | |
| 114 | + break; | |
| 115 | + default: | |
| 116 | + DPU_ERROR("%s invalid horz down sampling type\n", __func__); | |
| 117 | + return -EINVAL; | |
| 118 | + } | |
| 119 | + | |
| 120 | + switch (cfg->v_cdwn_type) { | |
| 121 | + case CDM_CDWN_DISABLE: | |
| 122 | + /* if its only Horizontal downsample, we dont need to do anything here */ | |
| 123 | + break; | |
| 124 | + case CDM_CDWN_PIXEL_DROP: | |
| 125 | + opmode |= CDM_CDWN2_OP_MODE_ENABLE_V | | |
| 126 | + FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK, | |
| 127 | + CDM_CDWN2_METHOD_PIXEL_DROP); | |
| 128 | + break; | |
| 129 | + case CDM_CDWN_AVG: | |
| 130 | + opmode |= CDM_CDWN2_OP_MODE_ENABLE_V | | |
| 131 | + FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK, | |
| 132 | + CDM_CDWN2_METHOD_AVG); | |
| 133 | + break; | |
| 134 | + case CDM_CDWN_COSITE: | |
| 135 | + opmode |= CDM_CDWN2_OP_MODE_ENABLE_V | | |
| 136 | + FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK, | |
| 137 | + CDM_CDWN2_METHOD_COSITE); | |
| 138 | + DPU_REG_WRITE(c, | |
| 139 | + CDM_CDWN2_COEFF_COSITE_V, | |
| 140 | + cosite_v_coeff[0]); | |
| 141 | + break; | |
| 142 | + case CDM_CDWN_OFFSITE: | |
| 143 | + opmode |= CDM_CDWN2_OP_MODE_ENABLE_V | | |
| 144 | + FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK, | |
| 145 | + CDM_CDWN2_METHOD_OFFSITE); | |
| 146 | + DPU_REG_WRITE(c, | |
| 147 | + CDM_CDWN2_COEFF_OFFSITE_V, | |
| 148 | + offsite_v_coeff[0]); | |
| 149 | + break; | |
| 150 | + default: | |
| 151 | + return -EINVAL; | |
| 152 | + } | |
| 153 | + | |
| 154 | + if (cfg->output_bit_depth != CDM_CDWN_OUTPUT_10BIT) | |
| 155 | + opmode |= CDM_CDWN2_OP_MODE_BITS_OUT_8BIT; | |
| 156 | + | |
| 157 | + if (cfg->v_cdwn_type || cfg->h_cdwn_type) | |
| 158 | + opmode |= CDM_CDWN2_OP_MODE_EN; /* EN CDWN module */ | |
| 159 | + else | |
| 160 | + opmode &= ~CDM_CDWN2_OP_MODE_EN; | |
| 161 | + | |
| 162 | + out_size = (cfg->output_width & 0xFFFF) | ((cfg->output_height & 0xFFFF) << 16); | |
| 163 | + DPU_REG_WRITE(c, CDM_CDWN2_OUT_SIZE, out_size); | |
| 164 | + DPU_REG_WRITE(c, CDM_CDWN2_OP_MODE, opmode); | |
| 165 | + DPU_REG_WRITE(c, CDM_CDWN2_CLAMP_OUT, ((0x3FF << 16) | 0x0)); | |
| 166 | + | |
| 167 | + return 0; | |
| 168 | +} | |
| 169 | + | |
| 170 | +static int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cdm) | |
| 171 | +{ | |
| 172 | + struct dpu_hw_blk_reg_map *c = &ctx->hw; | |
| 173 | + const struct dpu_format *fmt; | |
| 174 | + u32 opmode = 0; | |
| 175 | + u32 csc = 0; | |
| 176 | + | |
| 177 | + if (!ctx || !cdm) | |
| 178 | + return -EINVAL; | |
| 179 | + | |
| 180 | + fmt = cdm->output_fmt; | |
| 181 | + | |
| 182 | + if (!DPU_FORMAT_IS_YUV(fmt)) | |
| 183 | + return -EINVAL; | |
| 184 | + | |
| 185 | + dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, cdm->csc_cfg, true); | |
| 186 | + dpu_hw_cdm_setup_cdwn(ctx, cdm); | |
| 187 | + | |
| 188 | + if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) { | |
| 189 | + if (fmt->chroma_sample != DPU_CHROMA_H1V2) | |
| 190 | + return -EINVAL; /*unsupported format */ | |
| 191 | + opmode = CDM_HDMI_PACK_OP_MODE_EN; | |
| 192 | + opmode |= (fmt->chroma_sample << 1); | |
| 193 | + } | |
| 194 | + | |
| 195 | + csc |= CDM_CSC10_OP_MODE_DST_FMT_YUV; | |
| 196 | + csc &= ~CDM_CSC10_OP_MODE_SRC_FMT_YUV; | |
| 197 | + csc |= CDM_CSC10_OP_MODE_EN; | |
| 198 | + | |
| 199 | + if (ctx && ctx->ops.bind_pingpong_blk) | |
| 200 | + ctx->ops.bind_pingpong_blk(ctx, cdm->pp_id); | |
| 201 | + | |
| 202 | + DPU_REG_WRITE(c, CDM_CSC_10_OPMODE, csc); | |
| 203 | + DPU_REG_WRITE(c, CDM_HDMI_PACK_OP_MODE, opmode); | |
| 204 | + return 0; | |
| 205 | +} | |
| 206 | + | |
| 207 | +static void dpu_hw_cdm_bind_pingpong_blk(struct dpu_hw_cdm *ctx, const enum dpu_pingpong pp) | |
| 208 | +{ | |
| 209 | + struct dpu_hw_blk_reg_map *c; | |
| 210 | + int mux_cfg; | |
| 211 | + | |
| 212 | + c = &ctx->hw; | |
| 213 | + | |
| 214 | + mux_cfg = DPU_REG_READ(c, CDM_MUX); | |
| 215 | + mux_cfg &= ~0xf; | |
| 216 | + | |
| 217 | + if (pp) | |
| 218 | + mux_cfg |= (pp - PINGPONG_0) & 0x7; | |
| 219 | + else | |
| 220 | + mux_cfg |= 0xf; | |
| 221 | + | |
| 222 | + DPU_REG_WRITE(c, CDM_MUX, mux_cfg); | |
| 223 | +} | |
| 224 | + | |
| 225 | +struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev, | |
| 226 | + const struct dpu_cdm_cfg *cfg, void __iomem *addr, | |
| 227 | + const struct dpu_mdss_version *mdss_rev) | |
| 228 | +{ | |
| 229 | + struct dpu_hw_cdm *c; | |
| 230 | + | |
| 231 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 232 | + if (!c) | |
| 233 | + return ERR_PTR(-ENOMEM); | |
| 234 | + | |
| 235 | + c->hw.blk_addr = addr + cfg->base; | |
| 236 | + c->hw.log_mask = DPU_DBG_MASK_CDM; | |
| 237 | + | |
| 238 | + /* Assign ops */ | |
| 239 | + c->idx = cfg->id; | |
| 240 | + c->caps = cfg; | |
| 241 | + | |
| 242 | + c->ops.enable = dpu_hw_cdm_enable; | |
| 243 | + if (mdss_rev->core_major_ver >= 5) | |
| 244 | + c->ops.bind_pingpong_blk = dpu_hw_cdm_bind_pingpong_blk; | |
| 245 | + | |
| 246 | + return c; | |
| 247 | +} | |
| @@ -0,0 +1,142 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * Copyright (c) 2023, The Linux Foundation. All rights reserved. | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#ifndef _DPU_HW_CDM_H | |
| 7 | +#define _DPU_HW_CDM_H | |
| 8 | + | |
| 9 | +#include "dpu_hw_mdss.h" | |
| 10 | +#include "dpu_hw_top.h" | |
| 11 | + | |
| 12 | +struct dpu_hw_cdm; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * struct dpu_hw_cdm_cfg : current configuration of CDM block | |
| 16 | + * | |
| 17 | + * @output_width: output ROI width of CDM block | |
| 18 | + * @output_height: output ROI height of CDM block | |
| 19 | + * @output_bit_depth: output bit-depth of CDM block | |
| 20 | + * @h_cdwn_type: downsample type used for horizontal pixels | |
| 21 | + * @v_cdwn_type: downsample type used for vertical pixels | |
| 22 | + * @output_fmt: handle to dpu_format of CDM block | |
| 23 | + * @csc_cfg: handle to CSC matrix programmed for CDM block | |
| 24 | + * @output_type: interface to which CDM is paired (HDMI/WB) | |
| 25 | + * @pp_id: ping-pong block to which CDM is bound to | |
| 26 | + */ | |
| 27 | +struct dpu_hw_cdm_cfg { | |
| 28 | + u32 output_width; | |
| 29 | + u32 output_height; | |
| 30 | + u32 output_bit_depth; | |
| 31 | + u32 h_cdwn_type; | |
| 32 | + u32 v_cdwn_type; | |
| 33 | + const struct dpu_format *output_fmt; | |
| 34 | + const struct dpu_csc_cfg *csc_cfg; | |
| 35 | + u32 output_type; | |
| 36 | + int pp_id; | |
| 37 | +}; | |
| 38 | + | |
| 39 | +/* | |
| 40 | + * These values are used indicate which type of downsample is used | |
| 41 | + * in the horizontal/vertical direction for the CDM block. | |
| 42 | + */ | |
| 43 | +enum dpu_hw_cdwn_type { | |
| 44 | + CDM_CDWN_DISABLE, | |
| 45 | + CDM_CDWN_PIXEL_DROP, | |
| 46 | + CDM_CDWN_AVG, | |
| 47 | + CDM_CDWN_COSITE, | |
| 48 | + CDM_CDWN_OFFSITE, | |
| 49 | +}; | |
| 50 | + | |
| 51 | +/* | |
| 52 | + * CDM block can be paired with WB or HDMI block. These values match | |
| 53 | + * the input with which the CDM block is paired. | |
| 54 | + */ | |
| 55 | +enum dpu_hw_cdwn_output_type { | |
| 56 | + CDM_CDWN_OUTPUT_HDMI, | |
| 57 | + CDM_CDWN_OUTPUT_WB, | |
| 58 | +}; | |
| 59 | + | |
| 60 | +/* | |
| 61 | + * CDM block can give an 8-bit or 10-bit output. These values | |
| 62 | + * are used to indicate the output bit depth of CDM block | |
| 63 | + */ | |
| 64 | +enum dpu_hw_cdwn_output_bit_depth { | |
| 65 | + CDM_CDWN_OUTPUT_8BIT, | |
| 66 | + CDM_CDWN_OUTPUT_10BIT, | |
| 67 | +}; | |
| 68 | + | |
| 69 | +/* | |
| 70 | + * CDM block can downsample using different methods. These values | |
| 71 | + * are used to indicate the downsample method which can be used | |
| 72 | + * either in the horizontal or vertical direction. | |
| 73 | + */ | |
| 74 | +enum dpu_hw_cdwn_op_mode_method_h_v { | |
| 75 | + CDM_CDWN2_METHOD_PIXEL_DROP, | |
| 76 | + CDM_CDWN2_METHOD_AVG, | |
| 77 | + CDM_CDWN2_METHOD_COSITE, | |
| 78 | + CDM_CDWN2_METHOD_OFFSITE | |
| 79 | +}; | |
| 80 | + | |
| 81 | +/** | |
| 82 | + * struct dpu_hw_cdm_ops : Interface to the chroma down Hw driver functions | |
| 83 | + * Assumption is these functions will be called after | |
| 84 | + * clocks are enabled | |
| 85 | + * @enable: Enables the output to interface and programs the | |
| 86 | + * output packer | |
| 87 | + * @bind_pingpong_blk: enable/disable the connection with pingpong which | |
| 88 | + * will feed pixels to this cdm | |
| 89 | + */ | |
| 90 | +struct dpu_hw_cdm_ops { | |
| 91 | + /** | |
| 92 | + * Enable the CDM module | |
| 93 | + * @cdm Pointer to chroma down context | |
| 94 | + */ | |
| 95 | + int (*enable)(struct dpu_hw_cdm *cdm, struct dpu_hw_cdm_cfg *cfg); | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * Enable/disable the connection with pingpong | |
| 99 | + * @cdm Pointer to chroma down context | |
| 100 | + * @pp pingpong block id. | |
| 101 | + */ | |
| 102 | + void (*bind_pingpong_blk)(struct dpu_hw_cdm *cdm, const enum dpu_pingpong pp); | |
| 103 | +}; | |
| 104 | + | |
| 105 | +/** | |
| 106 | + * struct dpu_hw_cdm - cdm description | |
| 107 | + * @base: Hardware block base structure | |
| 108 | + * @hw: Block hardware details | |
| 109 | + * @idx: CDM index | |
| 110 | + * @caps: Pointer to cdm_cfg | |
| 111 | + * @ops: handle to operations possible for this CDM | |
| 112 | + */ | |
| 113 | +struct dpu_hw_cdm { | |
| 114 | + struct dpu_hw_blk base; | |
| 115 | + struct dpu_hw_blk_reg_map hw; | |
| 116 | + | |
| 117 | + /* chroma down */ | |
| 118 | + const struct dpu_cdm_cfg *caps; | |
| 119 | + enum dpu_cdm idx; | |
| 120 | + | |
| 121 | + /* ops */ | |
| 122 | + struct dpu_hw_cdm_ops ops; | |
| 123 | +}; | |
| 124 | + | |
| 125 | +/** | |
| 126 | + * dpu_hw_cdm_init - initializes the cdm hw driver object. | |
| 127 | + * should be called once before accessing every cdm. | |
| 128 | + * @dev: DRM device handle | |
| 129 | + * @cdm: CDM catalog entry for which driver object is required | |
| 130 | + * @addr : mapped register io address of MDSS | |
| 131 | + * @mdss_rev: mdss hw core revision | |
| 132 | + */ | |
| 133 | +struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev, | |
| 134 | + const struct dpu_cdm_cfg *cdm, void __iomem *addr, | |
| 135 | + const struct dpu_mdss_version *mdss_rev); | |
| 136 | + | |
| 137 | +static inline struct dpu_hw_cdm *to_dpu_hw_cdm(struct dpu_hw_blk *hw) | |
| 138 | +{ | |
| 139 | + return container_of(hw, struct dpu_hw_cdm, base); | |
| 140 | +} | |
| 141 | + | |
| 142 | +#endif /*_DPU_HW_CDM_H */ | |
| @@ -4,6 +4,9 @@ · 3 unmodified lines | ||
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/delay.h> |
| 7 | + | |
| 8 | +#include <drm/drm_managed.h> | |
| 9 | + | |
| 7 | 10 | #include "dpu_hwio.h" |
| 8 | 11 | #include "dpu_hw_ctl.h" |
| 9 | 12 | #include "dpu_kms.h" |
| @@ -29,11 +32,13 @@ · 19 unmodified lines | ||
| 29 | 32 | #define CTL_DSC_ACTIVE 0x0E8 |
| 30 | 33 | #define CTL_WB_ACTIVE 0x0EC |
| 31 | 34 | #define CTL_INTF_ACTIVE 0x0F4 |
| 35 | +#define CTL_CDM_ACTIVE 0x0F8 | |
| 32 | 36 | #define CTL_FETCH_PIPE_ACTIVE 0x0FC |
| 33 | 37 | #define CTL_MERGE_3D_FLUSH 0x100 |
| 34 | 38 | #define CTL_DSC_FLUSH 0x104 |
| 35 | 39 | #define CTL_WB_FLUSH 0x108 |
| 36 | 40 | #define CTL_INTF_FLUSH 0x110 |
| 41 | +#define CTL_CDM_FLUSH 0x114 | |
| 37 | 42 | #define CTL_INTF_MASTER 0x134 |
| 38 | 43 | #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) |
| 39 | 44 | |
| @@ -43,6 +48,7 @@ · 3 unmodified lines | ||
| 43 | 48 | #define DPU_REG_RESET_TIMEOUT_US 2000 |
| 44 | 49 | #define MERGE_3D_IDX 23 |
| 45 | 50 | #define DSC_IDX 22 |
| 51 | +#define CDM_IDX 26 | |
| 46 | 52 | #define INTF_IDX 31 |
| 47 | 53 | #define WB_IDX 16 |
| 48 | 54 | #define DSPP_IDX 29 /* From DPU hw rev 7.x.x */ |
| @@ -104,6 +110,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) · 55 unmodified lines | ||
| 104 | 110 | ctx->pending_wb_flush_mask = 0; |
| 105 | 111 | ctx->pending_merge_3d_flush_mask = 0; |
| 106 | 112 | ctx->pending_dsc_flush_mask = 0; |
| 113 | + ctx->pending_cdm_flush_mask = 0; | |
| 107 | 114 | |
| 108 | 115 | memset(ctx->pending_dspp_flush_mask, 0, |
| 109 | 116 | sizeof(ctx->pending_dspp_flush_mask)); |
| @@ -148,6 +155,10 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) · 38 unmodified lines | ||
| 148 | 155 | DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, |
| 149 | 156 | ctx->pending_dsc_flush_mask); |
| 150 | 157 | |
| 158 | + if (ctx->pending_flush_mask & BIT(CDM_IDX)) | |
| 159 | + DPU_REG_WRITE(&ctx->hw, CTL_CDM_FLUSH, | |
| 160 | + ctx->pending_cdm_flush_mask); | |
| 161 | + | |
| 151 | 162 | DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); |
| 152 | 163 | } |
| 153 | 164 | |
| @@ -279,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx, · 125 unmodified lines | ||
| 279 | 290 | } |
| 280 | 291 | } |
| 281 | 292 | |
| 293 | +static void dpu_hw_ctl_update_pending_flush_cdm(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num) | |
| 294 | +{ | |
| 295 | + /* update pending flush only if CDM_0 is flushed */ | |
| 296 | + if (cdm_num == CDM_0) | |
| 297 | + ctx->pending_flush_mask |= BIT(CDM_IDX); | |
| 298 | +} | |
| 299 | + | |
| 282 | 300 | static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, |
| 283 | 301 | enum dpu_wb wb) |
| 284 | 302 | { |
| @@ -307,6 +325,12 @@ static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, · 22 unmodified lines | ||
| 307 | 325 | ctx->pending_flush_mask |= BIT(DSC_IDX); |
| 308 | 326 | } |
| 309 | 327 | |
| 328 | +static void dpu_hw_ctl_update_pending_flush_cdm_v1(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num) | |
| 329 | +{ | |
| 330 | + ctx->pending_cdm_flush_mask |= BIT(cdm_num - CDM_0); | |
| 331 | + ctx->pending_flush_mask |= BIT(CDM_IDX); | |
| 332 | +} | |
| 333 | + | |
| 310 | 334 | static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, |
| 311 | 335 | enum dpu_dspp dspp, u32 dspp_sub_blk) |
| 312 | 336 | { |
| @@ -540,6 +564,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, · 227 unmodified lines | ||
| 540 | 564 | |
| 541 | 565 | if (cfg->dsc) |
| 542 | 566 | DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); |
| 567 | + | |
| 568 | + if (cfg->cdm) | |
| 569 | + DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm); | |
| 543 | 570 | } |
| 544 | 571 | |
| 545 | 572 | static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, |
| @@ -583,6 +610,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, · 37 unmodified lines | ||
| 583 | 610 | u32 wb_active = 0; |
| 584 | 611 | u32 merge3d_active = 0; |
| 585 | 612 | u32 dsc_active; |
| 613 | + u32 cdm_active; | |
| 586 | 614 | |
| 587 | 615 | /* |
| 588 | 616 | * This API resets each portion of the CTL path namely, |
| @@ -618,6 +646,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, · 29 unmodified lines | ||
| 618 | 646 | dsc_active &= ~cfg->dsc; |
| 619 | 647 | DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); |
| 620 | 648 | } |
| 649 | + | |
| 650 | + if (cfg->cdm) { | |
| 651 | + cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE); | |
| 652 | + cdm_active &= ~cfg->cdm; | |
| 653 | + DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cdm_active); | |
| 654 | + } | |
| 621 | 655 | } |
| 622 | 656 | |
| 623 | 657 | static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, |
| @@ -651,12 +685,14 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, · 27 unmodified lines | ||
| 651 | 685 | ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; |
| 652 | 686 | ops->update_pending_flush_dsc = |
| 653 | 687 | dpu_hw_ctl_update_pending_flush_dsc_v1; |
| 688 | + ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1; | |
| 654 | 689 | } else { |
| 655 | 690 | ops->trigger_flush = dpu_hw_ctl_trigger_flush; |
| 656 | 691 | ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; |
| 657 | 692 | ops->update_pending_flush_intf = |
| 658 | 693 | dpu_hw_ctl_update_pending_flush_intf; |
| 659 | 694 | ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb; |
| 695 | + ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm; | |
| 660 | 696 | } |
| 661 | 697 | ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; |
| 662 | 698 | ops->update_pending_flush = dpu_hw_ctl_update_pending_flush; |
| @@ -680,14 +716,15 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, · 17 unmodified lines | ||
| 680 | 716 | ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; |
| 681 | 717 | }; |
| 682 | 718 | |
| 683 | −struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, | |
| 684 | − void __iomem *addr, | |
| 685 | − u32 mixer_count, | |
| 686 | − const struct dpu_lm_cfg *mixer) | |
| 719 | +struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, | |
| 720 | + const struct dpu_ctl_cfg *cfg, | |
| 721 | + void __iomem *addr, | |
| 722 | + u32 mixer_count, | |
| 723 | + const struct dpu_lm_cfg *mixer) | |
| 687 | 724 | { |
| 688 | 725 | struct dpu_hw_ctl *c; |
| 689 | 726 | |
| 690 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 727 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 691 | 728 | if (!c) |
| 692 | 729 | return ERR_PTR(-ENOMEM); |
| 693 | 730 | |
| @@ -702,8 +739,3 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, · 8 unmodified lines | ||
| 702 | 739 | |
| 703 | 740 | return c; |
| 704 | 741 | } |
| 705 | − | |
| 706 | −void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx) | |
| 707 | −{ | |
| 708 | − kfree(ctx); | |
| 709 | −} | |
| @@ -39,6 +39,7 @@ struct dpu_hw_stage_cfg { · 38 unmodified lines | ||
| 39 | 39 | * @mode_3d: 3d mux configuration |
| 40 | 40 | * @merge_3d: 3d merge block used |
| 41 | 41 | * @intf_mode_sel: Interface mode, cmd / vid |
| 42 | + * @cdm: CDM block used | |
| 42 | 43 | * @stream_sel: Stream selection for multi-stream interfaces |
| 43 | 44 | * @dsc: DSC BIT masks used |
| 44 | 45 | */ |
| @@ -48,6 +49,7 @@ struct dpu_hw_intf_cfg { · 3 unmodified lines | ||
| 48 | 49 | enum dpu_3d_blend_mode mode_3d; |
| 49 | 50 | enum dpu_merge_3d merge_3d; |
| 50 | 51 | enum dpu_ctl_mode_sel intf_mode_sel; |
| 52 | + enum dpu_cdm cdm; | |
| 51 | 53 | int stream_sel; |
| 52 | 54 | unsigned int dsc; |
| 53 | 55 | }; |
| @@ -166,6 +168,14 @@ struct dpu_hw_ctl_ops { · 112 unmodified lines | ||
| 166 | 168 | void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx, |
| 167 | 169 | enum dpu_dsc blk); |
| 168 | 170 | |
| 171 | + /** | |
| 172 | + * OR in the given flushbits to the cached pending_(cdm_)flush_mask | |
| 173 | + * No effect on hardware | |
| 174 | + * @ctx: ctl path ctx pointer | |
| 175 | + * @cdm_num: idx of cdm to be flushed | |
| 176 | + */ | |
| 177 | + void (*update_pending_flush_cdm)(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num); | |
| 178 | + | |
| 169 | 179 | /** |
| 170 | 180 | * Write the value of the pending_flush_mask to hardware |
| 171 | 181 | * @ctx : ctl path ctx pointer |
| @@ -239,6 +249,7 @@ struct dpu_hw_ctl_ops { · 67 unmodified lines | ||
| 239 | 249 | * @pending_intf_flush_mask: pending INTF flush |
| 240 | 250 | * @pending_wb_flush_mask: pending WB flush |
| 241 | 251 | * @pending_dsc_flush_mask: pending DSC flush |
| 252 | + * @pending_cdm_flush_mask: pending CDM flush | |
| 242 | 253 | * @ops: operation list |
| 243 | 254 | */ |
| 244 | 255 | struct dpu_hw_ctl { |
| @@ -256,6 +267,7 @@ struct dpu_hw_ctl { · 11 unmodified lines | ||
| 256 | 267 | u32 pending_merge_3d_flush_mask; |
| 257 | 268 | u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0]; |
| 258 | 269 | u32 pending_dsc_flush_mask; |
| 270 | + u32 pending_cdm_flush_mask; | |
| 259 | 271 | |
| 260 | 272 | /* ops */ |
| 261 | 273 | struct dpu_hw_ctl_ops ops; |
| @@ -274,20 +286,16 @@ static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw) · 12 unmodified lines | ||
| 274 | 286 | /** |
| 275 | 287 | * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. |
| 276 | 288 | * Should be called before accessing any ctl_path register. |
| 289 | + * @dev: Corresponding device for devres management | |
| 277 | 290 | * @cfg: ctl_path catalog entry for which driver object is required |
| 278 | 291 | * @addr: mapped register io address of MDP |
| 279 | 292 | * @mixer_count: Number of mixers in @mixer |
| 280 | 293 | * @mixer: Pointer to an array of Layer Mixers defined in the catalog |
| 281 | 294 | */ |
| 282 | −struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, | |
| 283 | − void __iomem *addr, | |
| 284 | − u32 mixer_count, | |
| 285 | − const struct dpu_lm_cfg *mixer); | |
| 286 | − | |
| 287 | −/** | |
| 288 | − * dpu_hw_ctl_destroy(): Destroys ctl driver context | |
| 289 | − * should be called to free the context | |
| 290 | − */ | |
| 291 | −void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx); | |
| 295 | +struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, | |
| 296 | + const struct dpu_ctl_cfg *cfg, | |
| 297 | + void __iomem *addr, | |
| 298 | + u32 mixer_count, | |
| 299 | + const struct dpu_lm_cfg *mixer); | |
| 292 | 300 | |
| 293 | 301 | #endif /*_DPU_HW_CTL_H */ |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright (c) 2020-2022, Linaro Limited |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | +#include <drm/drm_managed.h> | |
| 7 | + | |
| 6 | 8 | #include <drm/display/drm_dsc_helper.h> |
| 7 | 9 | |
| 8 | 10 | #include "dpu_kms.h" |
| @@ -188,12 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, · 179 unmodified lines | ||
| 188 | 190 | ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk; |
| 189 | 191 | }; |
| 190 | 192 | |
| 191 | −struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, | |
| 193 | +struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev, | |
| 194 | + const struct dpu_dsc_cfg *cfg, | |
| 192 | 195 | void __iomem *addr) |
| 193 | 196 | { |
| 194 | 197 | struct dpu_hw_dsc *c; |
| 195 | 198 | |
| 196 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 199 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 197 | 200 | if (!c) |
| 198 | 201 | return ERR_PTR(-ENOMEM); |
| 199 | 202 | |
| @@ -206,8 +209,3 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, · 6 unmodified lines | ||
| 206 | 209 | |
| 207 | 210 | return c; |
| 208 | 211 | } |
| 209 | − | |
| 210 | −void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc) | |
| 211 | −{ | |
| 212 | − kfree(dsc); | |
| 213 | −} | |
| @@ -64,20 +64,24 @@ struct dpu_hw_dsc { · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | /** |
| 66 | 66 | * dpu_hw_dsc_init() - Initializes the DSC hw driver object. |
| 67 | + * @dev: Corresponding device for devres management | |
| 67 | 68 | * @cfg: DSC catalog entry for which driver object is required |
| 68 | 69 | * @addr: Mapped register io address of MDP |
| 69 | 70 | * Return: Error code or allocated dpu_hw_dsc context |
| 70 | 71 | */ |
| 71 | −struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, | |
| 72 | − void __iomem *addr); | |
| 72 | +struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev, | |
| 73 | + const struct dpu_dsc_cfg *cfg, | |
| 74 | + void __iomem *addr); | |
| 73 | 75 | |
| 74 | 76 | /** |
| 75 | 77 | * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object |
| 78 | + * @dev: Corresponding device for devres management | |
| 76 | 79 | * @cfg: DSC catalog entry for which driver object is required |
| 77 | 80 | * @addr: Mapped register io address of MDP |
| 78 | 81 | * Returns: Error code or allocated dpu_hw_dsc context |
| 79 | 82 | */ |
| 80 | −struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg, | |
| 83 | +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, | |
| 84 | + const struct dpu_dsc_cfg *cfg, | |
| 81 | 85 | void __iomem *addr); |
| 82 | 86 | |
| 83 | 87 | /** |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <drm/drm_managed.h> | |
| 8 | + | |
| 7 | 9 | #include <drm/display/drm_dsc_helper.h> |
| 8 | 10 | |
| 9 | 11 | #include "dpu_kms.h" |
| @@ -367,12 +369,13 @@ static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops, · 357 unmodified lines | ||
| 367 | 369 | ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2; |
| 368 | 370 | } |
| 369 | 371 | |
| 370 | −struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg, | |
| 372 | +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, | |
| 373 | + const struct dpu_dsc_cfg *cfg, | |
| 371 | 374 | void __iomem *addr) |
| 372 | 375 | { |
| 373 | 376 | struct dpu_hw_dsc *c; |
| 374 | 377 | |
| 375 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 378 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 376 | 379 | if (!c) |
| 377 | 380 | return ERR_PTR(-ENOMEM); |
| 378 | 381 | |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | 3 | */ |
| 4 | 4 | |
| 5 | +#include <drm/drm_managed.h> | |
| 6 | + | |
| 5 | 7 | #include "dpu_hwio.h" |
| 6 | 8 | #include "dpu_hw_catalog.h" |
| 7 | 9 | #include "dpu_hw_lm.h" |
| @@ -68,15 +70,16 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c, · 60 unmodified lines | ||
| 68 | 70 | c->ops.setup_pcc = dpu_setup_dspp_pcc; |
| 69 | 71 | } |
| 70 | 72 | |
| 71 | −struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, | |
| 72 | − void __iomem *addr) | |
| 73 | +struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, | |
| 74 | + const struct dpu_dspp_cfg *cfg, | |
| 75 | + void __iomem *addr) | |
| 73 | 76 | { |
| 74 | 77 | struct dpu_hw_dspp *c; |
| 75 | 78 | |
| 76 | 79 | if (!addr) |
| 77 | 80 | return ERR_PTR(-EINVAL); |
| 78 | 81 | |
| 79 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 82 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 80 | 83 | if (!c) |
| 81 | 84 | return ERR_PTR(-ENOMEM); |
| 82 | 85 | |
| @@ -90,10 +93,3 @@ struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, · 7 unmodified lines | ||
| 90 | 93 | |
| 91 | 94 | return c; |
| 92 | 95 | } |
| 93 | − | |
| 94 | −void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp) | |
| 95 | −{ | |
| 96 | − kfree(dspp); | |
| 97 | −} | |
| 98 | − | |
| 99 | − | |
| @@ -81,18 +81,14 @@ static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw) · 80 unmodified lines | ||
| 81 | 81 | /** |
| 82 | 82 | * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. |
| 83 | 83 | * should be called once before accessing every DSPP. |
| 84 | + * @dev: Corresponding device for devres management | |
| 84 | 85 | * @cfg: DSPP catalog entry for which driver object is required |
| 85 | 86 | * @addr: Mapped register io address of MDP |
| 86 | 87 | * Return: pointer to structure or ERR_PTR |
| 87 | 88 | */ |
| 88 | −struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, | |
| 89 | − void __iomem *addr); | |
| 90 | − | |
| 91 | −/** | |
| 92 | − * dpu_hw_dspp_destroy(): Destroys DSPP driver context | |
| 93 | − * @dspp: Pointer to DSPP driver context | |
| 94 | − */ | |
| 95 | −void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp); | |
| 89 | +struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, | |
| 90 | + const struct dpu_dspp_cfg *cfg, | |
| 91 | + void __iomem *addr); | |
| 96 | 92 | |
| 97 | 93 | #endif /*_DPU_HW_DSPP_H */ |
| 98 | 94 | |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/debugfs.h> |
| 7 | 7 | #include <linux/slab.h> |
| 8 | 8 | |
| 9 | +#include <drm/drm_managed.h> | |
| 10 | + | |
| 9 | 11 | #include "dpu_core_irq.h" |
| 10 | 12 | #include "dpu_kms.h" |
| 11 | 13 | #include "dpu_hw_interrupts.h" |
| @@ -472,8 +474,9 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, · 460 unmodified lines | ||
| 472 | 474 | return intr_status; |
| 473 | 475 | } |
| 474 | 476 | |
| 475 | −struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, | |
| 476 | − const struct dpu_mdss_cfg *m) | |
| 477 | +struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, | |
| 478 | + void __iomem *addr, | |
| 479 | + const struct dpu_mdss_cfg *m) | |
| 477 | 480 | { |
| 478 | 481 | struct dpu_hw_intr *intr; |
| 479 | 482 | unsigned int i; |
| @@ -481,7 +484,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, · 1 unmodified line | ||
| 481 | 484 | if (!addr || !m) |
| 482 | 485 | return ERR_PTR(-EINVAL); |
| 483 | 486 | |
| 484 | − intr = kzalloc(sizeof(*intr), GFP_KERNEL); | |
| 487 | + intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL); | |
| 485 | 488 | if (!intr) |
| 486 | 489 | return ERR_PTR(-ENOMEM); |
| 487 | 490 | |
| @@ -512,11 +515,6 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, · 24 unmodified lines | ||
| 512 | 515 | return intr; |
| 513 | 516 | } |
| 514 | 517 | |
| 515 | −void dpu_hw_intr_destroy(struct dpu_hw_intr *intr) | |
| 516 | −{ | |
| 517 | − kfree(intr); | |
| 518 | −} | |
| 519 | − | |
| 520 | 518 | int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, |
| 521 | 519 | unsigned int irq_idx, |
| 522 | 520 | void (*irq_cb)(void *arg), |
| @@ -70,15 +70,12 @@ struct dpu_hw_intr { · 69 unmodified lines | ||
| 70 | 70 | |
| 71 | 71 | /** |
| 72 | 72 | * dpu_hw_intr_init(): Initializes the interrupts hw object |
| 73 | + * @dev: Corresponding device for devres management | |
| 73 | 74 | * @addr: mapped register io address of MDP |
| 74 | 75 | * @m: pointer to MDSS catalog data |
| 75 | 76 | */ |
| 76 | −struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, | |
| 77 | − const struct dpu_mdss_cfg *m); | |
| 77 | +struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, | |
| 78 | + void __iomem *addr, | |
| 79 | + const struct dpu_mdss_cfg *m); | |
| 78 | 80 | |
| 79 | −/** | |
| 80 | − * dpu_hw_intr_destroy(): Cleanup interrutps hw object | |
| 81 | − * @intr: pointer to interrupts hw object | |
| 82 | − */ | |
| 83 | −void dpu_hw_intr_destroy(struct dpu_hw_intr *intr); | |
| 84 | 81 | #endif |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -12,6 +12,8 @@ · 5 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #include <linux/iopoll.h> |
| 14 | 14 | |
| 15 | +#include <drm/drm_managed.h> | |
| 16 | + | |
| 15 | 17 | #define INTF_TIMING_ENGINE_EN 0x000 |
| 16 | 18 | #define INTF_CONFIG 0x004 |
| 17 | 19 | #define INTF_HSYNC_CTL 0x008 |
| @@ -318,9 +320,9 @@ static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) · 300 unmodified lines | ||
| 318 | 320 | return DPU_REG_READ(c, INTF_LINE_COUNT); |
| 319 | 321 | } |
| 320 | 322 | |
| 321 | −static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) | |
| 323 | +static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) | |
| 322 | 324 | { |
| 323 | − dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); | |
| 325 | + dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1); | |
| 324 | 326 | } |
| 325 | 327 | |
| 326 | 328 | static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) |
| @@ -527,8 +529,10 @@ static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx, · 200 unmodified lines | ||
| 527 | 529 | DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2); |
| 528 | 530 | } |
| 529 | 531 | |
| 530 | −struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, | |
| 531 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | |
| 532 | +struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, | |
| 533 | + const struct dpu_intf_cfg *cfg, | |
| 534 | + void __iomem *addr, | |
| 535 | + const struct dpu_mdss_version *mdss_rev) | |
| 532 | 536 | { |
| 533 | 537 | struct dpu_hw_intf *c; |
| 534 | 538 | |
| @@ -537,7 +541,7 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, · 2 unmodified lines | ||
| 537 | 541 | return NULL; |
| 538 | 542 | } |
| 539 | 543 | |
| 540 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 544 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 541 | 545 | if (!c) |
| 542 | 546 | return ERR_PTR(-ENOMEM); |
| 543 | 547 | |
| @@ -581,9 +585,3 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, · 37 unmodified lines | ||
| 581 | 585 | |
| 582 | 586 | return c; |
| 583 | 587 | } |
| 584 | − | |
| 585 | −void dpu_hw_intf_destroy(struct dpu_hw_intf *intf) | |
| 586 | −{ | |
| 587 | − kfree(intf); | |
| 588 | −} | |
| 589 | − | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -95,7 +95,7 @@ struct dpu_hw_intf_ops { · 88 unmodified lines | ||
| 95 | 95 | |
| 96 | 96 | void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, |
| 97 | 97 | const enum dpu_pingpong pp); |
| 98 | − void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); | |
| 98 | + void (*setup_misr)(struct dpu_hw_intf *intf); | |
| 99 | 99 | int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); |
| 100 | 100 | |
| 101 | 101 | // Tearcheck on INTF since DPU 5.0.0 |
| @@ -131,17 +131,14 @@ struct dpu_hw_intf { · 29 unmodified lines | ||
| 131 | 131 | /** |
| 132 | 132 | * dpu_hw_intf_init() - Initializes the INTF driver for the passed |
| 133 | 133 | * interface catalog entry. |
| 134 | + * @dev: Corresponding device for devres management | |
| 134 | 135 | * @cfg: interface catalog entry for which driver object is required |
| 135 | 136 | * @addr: mapped register io address of MDP |
| 136 | 137 | * @mdss_rev: dpu core's major and minor versions |
| 137 | 138 | */ |
| 138 | −struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, | |
| 139 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | |
| 140 | − | |
| 141 | −/** | |
| 142 | − * dpu_hw_intf_destroy(): Destroys INTF driver context | |
| 143 | − * @intf: Pointer to INTF driver context | |
| 144 | − */ | |
| 145 | −void dpu_hw_intf_destroy(struct dpu_hw_intf *intf); | |
| 139 | +struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, | |
| 140 | + const struct dpu_intf_cfg *cfg, | |
| 141 | + void __iomem *addr, | |
| 142 | + const struct dpu_mdss_version *mdss_rev); | |
| 146 | 143 | |
| 147 | 144 | #endif /*_DPU_HW_INTF_H */ |
| @@ -1,9 +1,11 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | +#include <drm/drm_managed.h> | |
| 8 | + | |
| 7 | 9 | #include "dpu_kms.h" |
| 8 | 10 | #include "dpu_hw_catalog.h" |
| 9 | 11 | #include "dpu_hwio.h" |
| @@ -81,9 +83,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, · 71 unmodified lines | ||
| 81 | 83 | } |
| 82 | 84 | } |
| 83 | 85 | |
| 84 | −static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) | |
| 86 | +static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) | |
| 85 | 87 | { |
| 86 | − dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); | |
| 88 | + dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); | |
| 87 | 89 | } |
| 88 | 90 | |
| 89 | 91 | static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) |
| @@ -156,8 +158,9 @@ static void _setup_mixer_ops(struct dpu_hw_lm_ops *ops, · 66 unmodified lines | ||
| 156 | 158 | ops->collect_misr = dpu_hw_lm_collect_misr; |
| 157 | 159 | } |
| 158 | 160 | |
| 159 | −struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, | |
| 160 | − void __iomem *addr) | |
| 161 | +struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, | |
| 162 | + const struct dpu_lm_cfg *cfg, | |
| 163 | + void __iomem *addr) | |
| 161 | 164 | { |
| 162 | 165 | struct dpu_hw_mixer *c; |
| 163 | 166 | |
| @@ -166,7 +169,7 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, · 2 unmodified lines | ||
| 166 | 169 | return NULL; |
| 167 | 170 | } |
| 168 | 171 | |
| 169 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 172 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 170 | 173 | if (!c) |
| 171 | 174 | return ERR_PTR(-ENOMEM); |
| 172 | 175 | |
| @@ -180,8 +183,3 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, · 7 unmodified lines | ||
| 180 | 183 | |
| 181 | 184 | return c; |
| 182 | 185 | } |
| 183 | − | |
| 184 | −void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm) | |
| 185 | −{ | |
| 186 | − kfree(lm); | |
| 187 | −} | |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | 2 | /* |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | 4 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. |
| 4 | 5 | */ |
| 5 | 6 | |
| @@ -57,7 +58,7 @@ struct dpu_hw_lm_ops { · 51 unmodified lines | ||
| 57 | 58 | /** |
| 58 | 59 | * setup_misr: Enable/disable MISR |
| 59 | 60 | */ |
| 60 | − void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); | |
| 61 | + void (*setup_misr)(struct dpu_hw_mixer *ctx); | |
| 61 | 62 | |
| 62 | 63 | /** |
| 63 | 64 | * collect_misr: Read MISR signature |
| @@ -95,16 +96,12 @@ static inline struct dpu_hw_mixer *to_dpu_hw_mixer(struct dpu_hw_blk *hw) · 31 unmodified lines | ||
| 95 | 96 | /** |
| 96 | 97 | * dpu_hw_lm_init() - Initializes the mixer hw driver object. |
| 97 | 98 | * should be called once before accessing every mixer. |
| 99 | + * @dev: Corresponding device for devres management | |
| 98 | 100 | * @cfg: mixer catalog entry for which driver object is required |
| 99 | 101 | * @addr: mapped register io address of MDP |
| 100 | 102 | */ |
| 101 | −struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, | |
| 102 | − void __iomem *addr); | |
| 103 | − | |
| 104 | −/** | |
| 105 | − * dpu_hw_lm_destroy(): Destroys layer mixer driver context | |
| 106 | − * @lm: Pointer to LM driver context | |
| 107 | − */ | |
| 108 | −void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm); | |
| 103 | +struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, | |
| 104 | + const struct dpu_lm_cfg *cfg, | |
| 105 | + void __iomem *addr); | |
| 109 | 106 | |
| 110 | 107 | #endif /*_DPU_HW_LM_H */ |
| @@ -98,6 +98,7 @@ enum dpu_hw_blk_type { · 97 unmodified lines | ||
| 98 | 98 | DPU_HW_BLK_DSPP, |
| 99 | 99 | DPU_HW_BLK_MERGE_3D, |
| 100 | 100 | DPU_HW_BLK_DSC, |
| 101 | + DPU_HW_BLK_CDM, | |
| 101 | 102 | DPU_HW_BLK_MAX, |
| 102 | 103 | }; |
| 103 | 104 | |
| @@ -185,6 +186,11 @@ enum dpu_dsc { · 81 unmodified lines | ||
| 185 | 186 | DSC_MAX |
| 186 | 187 | }; |
| 187 | 188 | |
| 189 | +enum dpu_cdm { | |
| 190 | + CDM_0 = 1, | |
| 191 | + CDM_MAX | |
| 192 | +}; | |
| 193 | + | |
| 188 | 194 | enum dpu_pingpong { |
| 189 | 195 | PINGPONG_NONE, |
| 190 | 196 | PINGPONG_0, |
| @@ -195,6 +201,8 @@ enum dpu_pingpong { · 4 unmodified lines | ||
| 195 | 201 | PINGPONG_5, |
| 196 | 202 | PINGPONG_6, |
| 197 | 203 | PINGPONG_7, |
| 204 | + PINGPONG_8, | |
| 205 | + PINGPONG_9, | |
| 198 | 206 | PINGPONG_S0, |
| 199 | 207 | PINGPONG_MAX |
| 200 | 208 | }; |
| @@ -204,6 +212,7 @@ enum dpu_merge_3d { · 3 unmodified lines | ||
| 204 | 212 | MERGE_3D_1, |
| 205 | 213 | MERGE_3D_2, |
| 206 | 214 | MERGE_3D_3, |
| 215 | + MERGE_3D_4, | |
| 207 | 216 | MERGE_3D_MAX |
| 208 | 217 | }; |
| 209 | 218 | |
| @@ -458,6 +467,7 @@ struct dpu_mdss_color { · 248 unmodified lines | ||
| 458 | 467 | #define DPU_DBG_MASK_ROT (1 << 9) |
| 459 | 468 | #define DPU_DBG_MASK_DSPP (1 << 10) |
| 460 | 469 | #define DPU_DBG_MASK_DSC (1 << 11) |
| 470 | +#define DPU_DBG_MASK_CDM (1 << 12) | |
| 461 | 471 | |
| 462 | 472 | /** |
| 463 | 473 | * struct dpu_hw_tear_check - Struct contains parameters to configure |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <linux/iopoll.h> |
| 6 | 6 | |
| 7 | +#include <drm/drm_managed.h> | |
| 8 | + | |
| 7 | 9 | #include "dpu_hw_mdss.h" |
| 8 | 10 | #include "dpu_hwio.h" |
| 9 | 11 | #include "dpu_hw_catalog.h" |
| @@ -37,12 +39,13 @@ static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c, · 27 unmodified lines | ||
| 37 | 39 | c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode; |
| 38 | 40 | }; |
| 39 | 41 | |
| 40 | −struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, | |
| 41 | − void __iomem *addr) | |
| 42 | +struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, | |
| 43 | + const struct dpu_merge_3d_cfg *cfg, | |
| 44 | + void __iomem *addr) | |
| 42 | 45 | { |
| 43 | 46 | struct dpu_hw_merge_3d *c; |
| 44 | 47 | |
| 45 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 48 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 46 | 49 | if (!c) |
| 47 | 50 | return ERR_PTR(-ENOMEM); |
| 48 | 51 | |
| @@ -55,8 +58,3 @@ struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, · 6 unmodified lines | ||
| 55 | 58 | |
| 56 | 59 | return c; |
| 57 | 60 | } |
| 58 | − | |
| 59 | −void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *hw) | |
| 60 | −{ | |
| 61 | − kfree(hw); | |
| 62 | −} | |
| @@ -48,18 +48,13 @@ static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw) · 47 unmodified lines | ||
| 48 | 48 | /** |
| 49 | 49 | * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed |
| 50 | 50 | * merge3d catalog entry. |
| 51 | + * @dev: Corresponding device for devres management | |
| 51 | 52 | * @cfg: Pingpong catalog entry for which driver object is required |
| 52 | 53 | * @addr: Mapped register io address of MDP |
| 53 | 54 | * Return: Error code or allocated dpu_hw_merge_3d context |
| 54 | 55 | */ |
| 55 | −struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, | |
| 56 | − void __iomem *addr); | |
| 57 | − | |
| 58 | −/** | |
| 59 | − * dpu_hw_merge_3d_destroy - destroys merge_3d driver context | |
| 60 | − * should be called to free the context | |
| 61 | − * @pp: Pointer to PP driver context returned by dpu_hw_merge_3d_init | |
| 62 | − */ | |
| 63 | −void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *pp); | |
| 56 | +struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, | |
| 57 | + const struct dpu_merge_3d_cfg *cfg, | |
| 58 | + void __iomem *addr); | |
| 64 | 59 | |
| 65 | 60 | #endif /*_DPU_HW_MERGE3D_H */ |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <linux/iopoll.h> |
| 6 | 6 | |
| 7 | +#include <drm/drm_managed.h> | |
| 8 | + | |
| 7 | 9 | #include "dpu_hw_mdss.h" |
| 8 | 10 | #include "dpu_hwio.h" |
| 9 | 11 | #include "dpu_hw_catalog.h" |
| @@ -281,12 +283,14 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp) · 271 unmodified lines | ||
| 281 | 283 | return 0; |
| 282 | 284 | } |
| 283 | 285 | |
| 284 | −struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, | |
| 285 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | |
| 286 | +struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, | |
| 287 | + const struct dpu_pingpong_cfg *cfg, | |
| 288 | + void __iomem *addr, | |
| 289 | + const struct dpu_mdss_version *mdss_rev) | |
| 286 | 290 | { |
| 287 | 291 | struct dpu_hw_pingpong *c; |
| 288 | 292 | |
| 289 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 293 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 290 | 294 | if (!c) |
| 291 | 295 | return ERR_PTR(-ENOMEM); |
| 292 | 296 | |
| @@ -317,8 +321,3 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, · 24 unmodified lines | ||
| 317 | 321 | |
| 318 | 322 | return c; |
| 319 | 323 | } |
| 320 | − | |
| 321 | −void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp) | |
| 322 | −{ | |
| 323 | − kfree(pp); | |
| 324 | −} | |
| @@ -121,19 +121,15 @@ static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) · 120 unmodified lines | ||
| 121 | 121 | /** |
| 122 | 122 | * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed |
| 123 | 123 | * pingpong catalog entry. |
| 124 | + * @dev: Corresponding device for devres management | |
| 124 | 125 | * @cfg: Pingpong catalog entry for which driver object is required |
| 125 | 126 | * @addr: Mapped register io address of MDP |
| 126 | 127 | * @mdss_rev: dpu core's major and minor versions |
| 127 | 128 | * Return: Error code or allocated dpu_hw_pingpong context |
| 128 | 129 | */ |
| 129 | −struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, | |
| 130 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | |
| 131 | − | |
| 132 | −/** | |
| 133 | − * dpu_hw_pingpong_destroy - destroys pingpong driver context | |
| 134 | − * should be called to free the context | |
| 135 | − * @pp: Pointer to PP driver context returned by dpu_hw_pingpong_init | |
| 136 | − */ | |
| 137 | −void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp); | |
| 130 | +struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, | |
| 131 | + const struct dpu_pingpong_cfg *cfg, | |
| 132 | + void __iomem *addr, | |
| 133 | + const struct dpu_mdss_version *mdss_rev); | |
| 138 | 134 | |
| 139 | 135 | #endif /*_DPU_HW_PINGPONG_H */ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "msm_mdss.h" |
| 12 | 12 | |
| 13 | 13 | #include <drm/drm_file.h> |
| 14 | +#include <drm/drm_managed.h> | |
| 14 | 15 | |
| 15 | 16 | #define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087 |
| 16 | 17 | |
| @@ -395,15 +396,6 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx, · 378 unmodified lines | ||
| 395 | 396 | format); |
| 396 | 397 | } |
| 397 | 398 | |
| 398 | −static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx) | |
| 399 | −{ | |
| 400 | − if (!ctx) | |
| 401 | − return 0; | |
| 402 | − | |
| 403 | − return dpu_hw_get_scaler3_ver(&ctx->hw, | |
| 404 | − ctx->cap->sblk->scaler_blk.base); | |
| 405 | −} | |
| 406 | − | |
| 407 | 399 | /* |
| 408 | 400 | * dpu_hw_sspp_setup_rects() |
| 409 | 401 | */ |
| @@ -614,12 +606,8 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c, · 204 unmodified lines | ||
| 614 | 606 | test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features)) |
| 615 | 607 | c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; |
| 616 | 608 | |
| 617 | − if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) || | |
| 618 | − test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) || | |
| 619 | − test_bit(DPU_SSPP_SCALER_QSEED4, &features)) { | |
| 609 | + if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, &features)) | |
| 620 | 610 | c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3; |
| 621 | − c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver; | |
| 622 | − } | |
| 623 | 611 | |
| 624 | 612 | if (test_bit(DPU_SSPP_CDP, &features)) |
| 625 | 613 | c->ops.setup_cdp = dpu_hw_sspp_setup_cdp; |
| @@ -654,10 +642,7 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, · 28 unmodified lines | ||
| 654 | 642 | cfg->len, |
| 655 | 643 | kms); |
| 656 | 644 | |
| 657 | − if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) || | |
| 658 | − cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) || | |
| 659 | − cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) || | |
| 660 | − cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) | |
| 645 | + if (sblk->scaler_blk.len) | |
| 661 | 646 | dpu_debugfs_create_regset32("scaler_blk", 0400, |
| 662 | 647 | debugfs_root, |
| 663 | 648 | sblk->scaler_blk.base + cfg->base, |
| @@ -685,16 +670,18 @@ int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, · 21 unmodified lines | ||
| 685 | 670 | } |
| 686 | 671 | #endif |
| 687 | 672 | |
| 688 | −struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, | |
| 689 | − void __iomem *addr, const struct msm_mdss_data *mdss_data, | |
| 690 | − const struct dpu_mdss_version *mdss_rev) | |
| 673 | +struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, | |
| 674 | + const struct dpu_sspp_cfg *cfg, | |
| 675 | + void __iomem *addr, | |
| 676 | + const struct msm_mdss_data *mdss_data, | |
| 677 | + const struct dpu_mdss_version *mdss_rev) | |
| 691 | 678 | { |
| 692 | 679 | struct dpu_hw_sspp *hw_pipe; |
| 693 | 680 | |
| 694 | 681 | if (!addr) |
| 695 | 682 | return ERR_PTR(-EINVAL); |
| 696 | 683 | |
| 697 | − hw_pipe = kzalloc(sizeof(*hw_pipe), GFP_KERNEL); | |
| 684 | + hw_pipe = drmm_kzalloc(dev, sizeof(*hw_pipe), GFP_KERNEL); | |
| 698 | 685 | if (!hw_pipe) |
| 699 | 686 | return ERR_PTR(-ENOMEM); |
| 700 | 687 | |
| @@ -709,9 +696,3 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, · 8 unmodified lines | ||
| 709 | 696 | |
| 710 | 697 | return hw_pipe; |
| 711 | 698 | } |
| 712 | − | |
| 713 | −void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx) | |
| 714 | −{ | |
| 715 | − kfree(ctx); | |
| 716 | −} | |
| 717 | − | |
| @@ -21,21 +21,6 @@ struct dpu_hw_sspp; · 20 unmodified lines | ||
| 21 | 21 | #define DPU_SSPP_ROT_90 BIT(3) |
| 22 | 22 | #define DPU_SSPP_SOLID_FILL BIT(4) |
| 23 | 23 | |
| 24 | −/** | |
| 25 | − * Define all scaler feature bits in catalog | |
| 26 | − */ | |
| 27 | −#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \ | |
| 28 | − BIT(DPU_SSPP_SCALER_QSEED2) | \ | |
| 29 | − BIT(DPU_SSPP_SCALER_QSEED3) | \ | |
| 30 | − BIT(DPU_SSPP_SCALER_QSEED3LITE) | \ | |
| 31 | − BIT(DPU_SSPP_SCALER_QSEED4)) | |
| 32 | − | |
| 33 | −/* | |
| 34 | − * Define all CSC feature bits in catalog | |
| 35 | − */ | |
| 36 | −#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \ | |
| 37 | − BIT(DPU_SSPP_CSC_10BIT)) | |
| 38 | − | |
| 39 | 24 | /** |
| 40 | 25 | * Component indices |
| 41 | 26 | */ |
| @@ -296,12 +281,6 @@ struct dpu_hw_sspp_ops { · 254 unmodified lines | ||
| 296 | 281 | struct dpu_hw_scaler3_cfg *scaler3_cfg, |
| 297 | 282 | const struct dpu_format *format); |
| 298 | 283 | |
| 299 | − /** | |
| 300 | − * get_scaler_ver - get scaler h/w version | |
| 301 | − * @ctx: Pointer to pipe context | |
| 302 | − */ | |
| 303 | − u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx); | |
| 304 | − | |
| 305 | 284 | /** |
| 306 | 285 | * setup_cdp - setup client driven prefetch |
| 307 | 286 | * @pipe: Pointer to software pipe context |
| @@ -339,21 +318,17 @@ struct dpu_kms; · 31 unmodified lines | ||
| 339 | 318 | /** |
| 340 | 319 | * dpu_hw_sspp_init() - Initializes the sspp hw driver object. |
| 341 | 320 | * Should be called once before accessing every pipe. |
| 321 | + * @dev: Corresponding device for devres management | |
| 342 | 322 | * @cfg: Pipe catalog entry for which driver object is required |
| 343 | 323 | * @addr: Mapped register io address of MDP |
| 344 | 324 | * @mdss_data: UBWC / MDSS configuration data |
| 345 | 325 | * @mdss_rev: dpu core's major and minor versions |
| 346 | 326 | */ |
| 347 | −struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, | |
| 348 | − void __iomem *addr, const struct msm_mdss_data *mdss_data, | |
| 349 | − const struct dpu_mdss_version *mdss_rev); | |
| 350 | − | |
| 351 | −/** | |
| 352 | − * dpu_hw_sspp_destroy(): Destroys SSPP driver context | |
| 353 | − * should be called during Hw pipe cleanup. | |
| 354 | − * @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init | |
| 355 | − */ | |
| 356 | −void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx); | |
| 327 | +struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, | |
| 328 | + const struct dpu_sspp_cfg *cfg, | |
| 329 | + void __iomem *addr, | |
| 330 | + const struct msm_mdss_data *mdss_data, | |
| 331 | + const struct dpu_mdss_version *mdss_rev); | |
| 357 | 332 | |
| 358 | 333 | int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, |
| 359 | 334 | struct dentry *entry); |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | 3 | */ |
| 4 | 4 | |
| 5 | +#include <drm/drm_managed.h> | |
| 6 | + | |
| 5 | 7 | #include "dpu_hwio.h" |
| 6 | 8 | #include "dpu_hw_catalog.h" |
| 7 | 9 | #include "dpu_hw_top.h" |
| @@ -247,16 +249,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, · 239 unmodified lines | ||
| 247 | 249 | ops->intf_audio_select = dpu_hw_intf_audio_select; |
| 248 | 250 | } |
| 249 | 251 | |
| 250 | −struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, | |
| 251 | − void __iomem *addr, | |
| 252 | − const struct dpu_mdss_cfg *m) | |
| 252 | +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, | |
| 253 | + const struct dpu_mdp_cfg *cfg, | |
| 254 | + void __iomem *addr, | |
| 255 | + const struct dpu_mdss_cfg *m) | |
| 253 | 256 | { |
| 254 | 257 | struct dpu_hw_mdp *mdp; |
| 255 | 258 | |
| 256 | 259 | if (!addr) |
| 257 | 260 | return ERR_PTR(-EINVAL); |
| 258 | 261 | |
| 259 | − mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); | |
| 262 | + mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); | |
| 260 | 263 | if (!mdp) |
| 261 | 264 | return ERR_PTR(-ENOMEM); |
| 262 | 265 | |
| @@ -271,9 +274,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, · 8 unmodified lines | ||
| 271 | 274 | |
| 272 | 275 | return mdp; |
| 273 | 276 | } |
| 274 | − | |
| 275 | −void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp) | |
| 276 | −{ | |
| 277 | − kfree(mdp); | |
| 278 | −} | |
| 279 | − | |
| @@ -145,13 +145,15 @@ struct dpu_hw_mdp { · 144 unmodified lines | ||
| 145 | 145 | |
| 146 | 146 | /** |
| 147 | 147 | * dpu_hw_mdptop_init - initializes the top driver for the passed config |
| 148 | + * @dev: Corresponding device for devres management | |
| 148 | 149 | * @cfg: MDP TOP configuration from catalog |
| 149 | 150 | * @addr: Mapped register io address of MDP |
| 150 | 151 | * @m: Pointer to mdss catalog data |
| 151 | 152 | */ |
| 152 | −struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, | |
| 153 | − void __iomem *addr, | |
| 154 | − const struct dpu_mdss_cfg *m); | |
| 153 | +struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, | |
| 154 | + const struct dpu_mdp_cfg *cfg, | |
| 155 | + void __iomem *addr, | |
| 156 | + const struct dpu_mdss_cfg *m); | |
| 155 | 157 | |
| 156 | 158 | void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); |
| 157 | 159 | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 5 | 5 | */ |
| 6 | 6 | #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ |
| @@ -381,12 +381,6 @@ end: · 374 unmodified lines | ||
| 381 | 381 | DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode); |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | −u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, | |
| 385 | − u32 scaler_offset) | |
| 386 | −{ | |
| 387 | − return DPU_REG_READ(c, QSEED3_HW_VERSION + scaler_offset); | |
| 388 | −} | |
| 389 | − | |
| 390 | 384 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, |
| 391 | 385 | u32 csc_reg_off, |
| 392 | 386 | const struct dpu_csc_cfg *data, bool csc10) |
| @@ -481,9 +475,11 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, · 88 unmodified lines | ||
| 481 | 475 | cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); |
| 482 | 476 | } |
| 483 | 477 | |
| 478 | +/* | |
| 479 | + * note: Aside from encoders, input_sel should be set to 0x0 by default | |
| 480 | + */ | |
| 484 | 481 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, |
| 485 | − u32 misr_ctrl_offset, | |
| 486 | − bool enable, u32 frame_count) | |
| 482 | + u32 misr_ctrl_offset, u8 input_sel) | |
| 487 | 483 | { |
| 488 | 484 | u32 config = 0; |
| 489 | 485 | |
| @@ -492,15 +488,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, · 2 unmodified lines | ||
| 492 | 488 | /* Clear old MISR value (in case it's read before a new value is calculated)*/ |
| 493 | 489 | wmb(); |
| 494 | 490 | |
| 495 | − if (enable) { | |
| 496 | − config = (frame_count & MISR_FRAME_COUNT_MASK) | | |
| 497 | − MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; | |
| 498 | − | |
| 499 | − DPU_REG_WRITE(c, misr_ctrl_offset, config); | |
| 500 | − } else { | |
| 501 | − DPU_REG_WRITE(c, misr_ctrl_offset, 0); | |
| 502 | − } | |
| 503 | − | |
| 491 | + config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | | |
| 492 | + ((input_sel & 0xF) << 24); | |
| 493 | + DPU_REG_WRITE(c, misr_ctrl_offset, config); | |
| 504 | 494 | } |
| 505 | 495 | |
| 506 | 496 | int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, |
| @@ -567,3 +557,47 @@ bool dpu_hw_clk_force_ctrl(struct dpu_hw_blk_reg_map *c, · 60 unmodified lines | ||
| 567 | 557 | |
| 568 | 558 | return clk_forced_on; |
| 569 | 559 | } |
| 560 | + | |
| 561 | +#define TO_S15D16(_x_)((_x_) << 7) | |
| 562 | + | |
| 563 | +const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { | |
| 564 | + { | |
| 565 | + /* S15.16 format */ | |
| 566 | + 0x00012A00, 0x00000000, 0x00019880, | |
| 567 | + 0x00012A00, 0xFFFF9B80, 0xFFFF3000, | |
| 568 | + 0x00012A00, 0x00020480, 0x00000000, | |
| 569 | + }, | |
| 570 | + /* signed bias */ | |
| 571 | + { 0xfff0, 0xff80, 0xff80,}, | |
| 572 | + { 0x0, 0x0, 0x0,}, | |
| 573 | + /* unsigned clamp */ | |
| 574 | + { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,}, | |
| 575 | + { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,}, | |
| 576 | +}; | |
| 577 | + | |
| 578 | +const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = { | |
| 579 | + { | |
| 580 | + /* S15.16 format */ | |
| 581 | + 0x00012A00, 0x00000000, 0x00019880, | |
| 582 | + 0x00012A00, 0xFFFF9B80, 0xFFFF3000, | |
| 583 | + 0x00012A00, 0x00020480, 0x00000000, | |
| 584 | + }, | |
| 585 | + /* signed bias */ | |
| 586 | + { 0xffc0, 0xfe00, 0xfe00,}, | |
| 587 | + { 0x0, 0x0, 0x0,}, | |
| 588 | + /* unsigned clamp */ | |
| 589 | + { 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,}, | |
| 590 | + { 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,}, | |
| 591 | +}; | |
| 592 | + | |
| 593 | +const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l = { | |
| 594 | + { | |
| 595 | + TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032), | |
| 596 | + TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1), | |
| 597 | + TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc) | |
| 598 | + }, | |
| 599 | + { 0x00, 0x00, 0x00 }, | |
| 600 | + { 0x0040, 0x0200, 0x0200 }, | |
| 601 | + { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, | |
| 602 | + { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, | |
| 603 | +}; | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | 2 | /* |
| 3 | − * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 3 | + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | |
| 4 | 4 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. |
| 5 | 5 | */ |
| 6 | 6 | |
| @@ -13,12 +13,18 @@ · 6 unmodified lines | ||
| 13 | 13 | #include "dpu_hw_catalog.h" |
| 14 | 14 | |
| 15 | 15 | #define REG_MASK(n) ((BIT(n)) - 1) |
| 16 | −#define MISR_FRAME_COUNT_MASK 0xFF | |
| 16 | +#define MISR_FRAME_COUNT 0x1 | |
| 17 | 17 | #define MISR_CTRL_ENABLE BIT(8) |
| 18 | 18 | #define MISR_CTRL_STATUS BIT(9) |
| 19 | 19 | #define MISR_CTRL_STATUS_CLEAR BIT(10) |
| 20 | 20 | #define MISR_CTRL_FREE_RUN_MASK BIT(31) |
| 21 | 21 | |
| 22 | +#define TO_S15D16(_x_)((_x_) << 7) | |
| 23 | + | |
| 24 | +extern const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L; | |
| 25 | +extern const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L; | |
| 26 | +extern const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l; | |
| 27 | + | |
| 22 | 28 | /* |
| 23 | 29 | * This is the common struct maintained by each sub block |
| 24 | 30 | * for mapping the register offsets in this block to the |
| @@ -340,9 +346,6 @@ void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c, · 315 unmodified lines | ||
| 340 | 346 | u32 scaler_offset, u32 scaler_version, |
| 341 | 347 | const struct dpu_format *format); |
| 342 | 348 | |
| 343 | −u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, | |
| 344 | − u32 scaler_offset); | |
| 345 | − | |
| 346 | 349 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, |
| 347 | 350 | u32 csc_reg_off, |
| 348 | 351 | const struct dpu_csc_cfg *data, bool csc10); |
| @@ -358,9 +361,7 @@ void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset, · 9 unmodified lines | ||
| 358 | 361 | const struct dpu_hw_qos_cfg *cfg); |
| 359 | 362 | |
| 360 | 363 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, |
| 361 | − u32 misr_ctrl_offset, | |
| 362 | − bool enable, | |
| 363 | − u32 frame_count); | |
| 364 | + u32 misr_ctrl_offset, u8 input_sel); | |
| 364 | 365 | |
| 365 | 366 | int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, |
| 366 | 367 | u32 misr_ctrl_offset, |
| @@ -2,6 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | 3 | */ |
| 4 | 4 | |
| 5 | +#include <drm/drm_managed.h> | |
| 6 | + | |
| 5 | 7 | #include "dpu_hwio.h" |
| 6 | 8 | #include "dpu_hw_catalog.h" |
| 7 | 9 | #include "dpu_hw_vbif.h" |
| @@ -211,12 +213,13 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, · 203 unmodified lines | ||
| 211 | 213 | ops->set_write_gather_en = dpu_hw_set_write_gather_en; |
| 212 | 214 | } |
| 213 | 215 | |
| 214 | −struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, | |
| 215 | − void __iomem *addr) | |
| 216 | +struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, | |
| 217 | + const struct dpu_vbif_cfg *cfg, | |
| 218 | + void __iomem *addr) | |
| 216 | 219 | { |
| 217 | 220 | struct dpu_hw_vbif *c; |
| 218 | 221 | |
| 219 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 222 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 220 | 223 | if (!c) |
| 221 | 224 | return ERR_PTR(-ENOMEM); |
| 222 | 225 | |
| @@ -234,8 +237,3 @@ struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, · 11 unmodified lines | ||
| 234 | 237 | |
| 235 | 238 | return c; |
| 236 | 239 | } |
| 237 | − | |
| 238 | −void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif) | |
| 239 | −{ | |
| 240 | − kfree(vbif); | |
| 241 | −} | |
| @@ -108,12 +108,12 @@ struct dpu_hw_vbif { · 107 unmodified lines | ||
| 108 | 108 | /** |
| 109 | 109 | * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed |
| 110 | 110 | * VBIF catalog entry. |
| 111 | + * @dev: Corresponding device for devres management | |
| 111 | 112 | * @cfg: VBIF catalog entry for which driver object is required |
| 112 | 113 | * @addr: Mapped register io address of MDSS |
| 113 | 114 | */ |
| 114 | −struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, | |
| 115 | − void __iomem *addr); | |
| 116 | − | |
| 117 | −void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif); | |
| 115 | +struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, | |
| 116 | + const struct dpu_vbif_cfg *cfg, | |
| 117 | + void __iomem *addr); | |
| 118 | 118 | |
| 119 | 119 | #endif /*_DPU_HW_VBIF_H */ |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | +#include <drm/drm_managed.h> | |
| 7 | + | |
| 6 | 8 | #include "dpu_hw_mdss.h" |
| 7 | 9 | #include "dpu_hwio.h" |
| 8 | 10 | #include "dpu_hw_catalog.h" |
| @@ -87,6 +89,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, · 78 unmodified lines | ||
| 87 | 89 | dst_format |= BIT(14); /* DST_ALPHA_X */ |
| 88 | 90 | } |
| 89 | 91 | |
| 92 | + if (DPU_FORMAT_IS_YUV(fmt)) | |
| 93 | + dst_format |= BIT(15); | |
| 94 | + | |
| 90 | 95 | pattern = (fmt->element[3] << 24) | |
| 91 | 96 | (fmt->element[2] << 16) | |
| 92 | 97 | (fmt->element[1] << 8) | |
| @@ -208,15 +213,17 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, · 115 unmodified lines | ||
| 208 | 213 | ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl; |
| 209 | 214 | } |
| 210 | 215 | |
| 211 | −struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, | |
| 212 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | |
| 216 | +struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, | |
| 217 | + const struct dpu_wb_cfg *cfg, | |
| 218 | + void __iomem *addr, | |
| 219 | + const struct dpu_mdss_version *mdss_rev) | |
| 213 | 220 | { |
| 214 | 221 | struct dpu_hw_wb *c; |
| 215 | 222 | |
| 216 | 223 | if (!addr) |
| 217 | 224 | return ERR_PTR(-EINVAL); |
| 218 | 225 | |
| 219 | − c = kzalloc(sizeof(*c), GFP_KERNEL); | |
| 226 | + c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); | |
| 220 | 227 | if (!c) |
| 221 | 228 | return ERR_PTR(-ENOMEM); |
| 222 | 229 | |
| @@ -230,8 +237,3 @@ struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, · 7 unmodified lines | ||
| 230 | 237 | |
| 231 | 238 | return c; |
| 232 | 239 | } |
| 233 | − | |
| 234 | −void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb) | |
| 235 | −{ | |
| 236 | − kfree(hw_wb); | |
| 237 | −} | |
| @@ -76,18 +76,15 @@ struct dpu_hw_wb { · 75 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | /** |
| 78 | 78 | * dpu_hw_wb_init() - Initializes the writeback hw driver object. |
| 79 | + * @dev: Corresponding device for devres management | |
| 79 | 80 | * @cfg: wb_path catalog entry for which driver object is required |
| 80 | 81 | * @addr: mapped register io address of MDP |
| 81 | 82 | * @mdss_rev: dpu core's major and minor versions |
| 82 | 83 | * Return: Error code or allocated dpu_hw_wb context |
| 83 | 84 | */ |
| 84 | −struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, | |
| 85 | − void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | |
| 86 | − | |
| 87 | −/** | |
| 88 | − * dpu_hw_wb_destroy(): Destroy writeback hw driver object. | |
| 89 | − * @hw_wb: Pointer to writeback hw driver object | |
| 90 | − */ | |
| 91 | −void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb); | |
| 85 | +struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, | |
| 86 | + const struct dpu_wb_cfg *cfg, | |
| 87 | + void __iomem *addr, | |
| 88 | + const struct dpu_mdss_version *mdss_rev); | |
| 92 | 89 | |
| 93 | 90 | #endif /*_DPU_HW_WB_H */ |
| @@ -274,9 +274,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) · 273 unmodified lines | ||
| 274 | 274 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); |
| 275 | 275 | void *p = dpu_hw_util_get_log_mask_ptr(); |
| 276 | 276 | struct dentry *entry; |
| 277 | − struct drm_device *dev; | |
| 278 | − struct msm_drm_private *priv; | |
| 279 | − int i; | |
| 280 | 277 | |
| 281 | 278 | if (!p) |
| 282 | 279 | return -EINVAL; |
| @@ -285,9 +282,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) · 2 unmodified lines | ||
| 285 | 282 | if (minor->type != DRM_MINOR_PRIMARY) |
| 286 | 283 | return 0; |
| 287 | 284 | |
| 288 | − dev = dpu_kms->dev; | |
| 289 | − priv = dev->dev_private; | |
| 290 | − | |
| 291 | 285 | entry = debugfs_create_dir("debug", minor->debugfs_root); |
| 292 | 286 | |
| 293 | 287 | debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, entry, p); |
| @@ -297,11 +291,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) · 3 unmodified lines | ||
| 297 | 291 | dpu_debugfs_core_irq_init(dpu_kms, entry); |
| 298 | 292 | dpu_debugfs_sspp_init(dpu_kms, entry); |
| 299 | 293 | |
| 300 | − for (i = 0; i < ARRAY_SIZE(priv->dp); i++) { | |
| 301 | − if (priv->dp[i]) | |
| 302 | − msm_dp_debugfs_init(priv->dp[i], minor); | |
| 303 | − } | |
| 304 | − | |
| 305 | 294 | return dpu_core_perf_debugfs_init(dpu_kms, entry); |
| 306 | 295 | } |
| 307 | 296 | #endif |
| @@ -597,7 +586,6 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, · 289 unmodified lines | ||
| 597 | 586 | rc = msm_dp_modeset_init(priv->dp[i], dev, encoder); |
| 598 | 587 | if (rc) { |
| 599 | 588 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); |
| 600 | − drm_encoder_cleanup(encoder); | |
| 601 | 589 | return rc; |
| 602 | 590 | } |
| 603 | 591 | } |
| @@ -630,7 +618,6 @@ static int _dpu_kms_initialize_hdmi(struct drm_device *dev, · 26 unmodified lines | ||
| 630 | 618 | rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); |
| 631 | 619 | if (rc) { |
| 632 | 620 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); |
| 633 | − drm_encoder_cleanup(encoder); | |
| 634 | 621 | return rc; |
| 635 | 622 | } |
| 636 | 623 | |
| @@ -662,7 +649,6 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev, · 25 unmodified lines | ||
| 662 | 649 | n_formats); |
| 663 | 650 | if (rc) { |
| 664 | 651 | DPU_ERROR("dpu_writeback_init, rc = %d\n", rc); |
| 665 | − drm_encoder_cleanup(encoder); | |
| 666 | 652 | return rc; |
| 667 | 653 | } |
| 668 | 654 | |
| @@ -806,30 +792,17 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) · 137 unmodified lines | ||
| 806 | 792 | { |
| 807 | 793 | int i; |
| 808 | 794 | |
| 809 | − if (dpu_kms->hw_intr) | |
| 810 | − dpu_hw_intr_destroy(dpu_kms->hw_intr); | |
| 811 | 795 | dpu_kms->hw_intr = NULL; |
| 812 | 796 | |
| 813 | 797 | /* safe to call these more than once during shutdown */ |
| 814 | 798 | _dpu_kms_mmu_destroy(dpu_kms); |
| 815 | 799 | |
| 816 | − if (dpu_kms->catalog) { | |
| 817 | − for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { | |
| 818 | − if (dpu_kms->hw_vbif[i]) { | |
| 819 | − dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); | |
| 820 | − dpu_kms->hw_vbif[i] = NULL; | |
| 821 | − } | |
| 822 | − } | |
| 800 | + for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { | |
| 801 | + dpu_kms->hw_vbif[i] = NULL; | |
| 823 | 802 | } |
| 824 | 803 | |
| 825 | − if (dpu_kms->rm_init) | |
| 826 | − dpu_rm_destroy(&dpu_kms->rm); | |
| 827 | − dpu_kms->rm_init = false; | |
| 828 | − | |
| 829 | 804 | dpu_kms->catalog = NULL; |
| 830 | 805 | |
| 831 | − if (dpu_kms->hw_mdp) | |
| 832 | − dpu_hw_mdp_destroy(dpu_kms->hw_mdp); | |
| 833 | 806 | dpu_kms->hw_mdp = NULL; |
| 834 | 807 | } |
| 835 | 808 | |
| @@ -856,7 +829,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) · 20 unmodified lines | ||
| 856 | 829 | { |
| 857 | 830 | struct msm_drm_private *priv; |
| 858 | 831 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); |
| 859 | − int i; | |
| 860 | 832 | |
| 861 | 833 | if (!dpu_kms || !dpu_kms->dev) |
| 862 | 834 | return -EINVAL; |
| @@ -865,9 +837,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) · 2 unmodified lines | ||
| 865 | 837 | if (!priv) |
| 866 | 838 | return -EINVAL; |
| 867 | 839 | |
| 868 | − for (i = 0; i < ARRAY_SIZE(priv->dp); i++) | |
| 869 | − msm_dp_irq_postinstall(priv->dp[i]); | |
| 870 | − | |
| 871 | 840 | return 0; |
| 872 | 841 | } |
| 873 | 842 | |
| @@ -975,6 +944,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k · 101 unmodified lines | ||
| 975 | 944 | } |
| 976 | 945 | } |
| 977 | 946 | |
| 947 | + if (cat->cdm) | |
| 948 | + msm_disp_snapshot_add_block(disp_state, cat->cdm->len, | |
| 949 | + dpu_kms->mmio + cat->cdm->base, cat->cdm->name); | |
| 950 | + | |
| 978 | 951 | pm_runtime_put_sync(&dpu_kms->pdev->dev); |
| 979 | 952 | } |
| 980 | 953 | |
| @@ -1078,7 +1051,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 97 unmodified lines | ||
| 1078 | 1051 | if (!dpu_kms->catalog) { |
| 1079 | 1052 | DPU_ERROR("device config not known!\n"); |
| 1080 | 1053 | rc = -EINVAL; |
| 1081 | − goto power_error; | |
| 1054 | + goto err_pm_put; | |
| 1082 | 1055 | } |
| 1083 | 1056 | |
| 1084 | 1057 | /* |
| @@ -1088,49 +1061,48 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 3 unmodified lines | ||
| 1088 | 1061 | rc = _dpu_kms_mmu_init(dpu_kms); |
| 1089 | 1062 | if (rc) { |
| 1090 | 1063 | DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc); |
| 1091 | − goto power_error; | |
| 1064 | + goto err_pm_put; | |
| 1092 | 1065 | } |
| 1093 | 1066 | |
| 1094 | 1067 | dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent); |
| 1095 | 1068 | if (IS_ERR(dpu_kms->mdss)) { |
| 1096 | 1069 | rc = PTR_ERR(dpu_kms->mdss); |
| 1097 | 1070 | DPU_ERROR("failed to get MDSS data: %d\n", rc); |
| 1098 | − goto power_error; | |
| 1071 | + goto err_pm_put; | |
| 1099 | 1072 | } |
| 1100 | 1073 | |
| 1101 | 1074 | if (!dpu_kms->mdss) { |
| 1102 | 1075 | rc = -EINVAL; |
| 1103 | 1076 | DPU_ERROR("NULL MDSS data\n"); |
| 1104 | − goto power_error; | |
| 1077 | + goto err_pm_put; | |
| 1105 | 1078 | } |
| 1106 | 1079 | |
| 1107 | − rc = dpu_rm_init(&dpu_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio); | |
| 1080 | + rc = dpu_rm_init(dev, &dpu_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio); | |
| 1108 | 1081 | if (rc) { |
| 1109 | 1082 | DPU_ERROR("rm init failed: %d\n", rc); |
| 1110 | − goto power_error; | |
| 1083 | + goto err_pm_put; | |
| 1111 | 1084 | } |
| 1112 | 1085 | |
| 1113 | − dpu_kms->rm_init = true; | |
| 1114 | − | |
| 1115 | − dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp, | |
| 1086 | + dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev, | |
| 1087 | + dpu_kms->catalog->mdp, | |
| 1116 | 1088 | dpu_kms->mmio, |
| 1117 | 1089 | dpu_kms->catalog); |
| 1118 | 1090 | if (IS_ERR(dpu_kms->hw_mdp)) { |
| 1119 | 1091 | rc = PTR_ERR(dpu_kms->hw_mdp); |
| 1120 | 1092 | DPU_ERROR("failed to get hw_mdp: %d\n", rc); |
| 1121 | 1093 | dpu_kms->hw_mdp = NULL; |
| 1122 | − goto power_error; | |
| 1094 | + goto err_pm_put; | |
| 1123 | 1095 | } |
| 1124 | 1096 | |
| 1125 | 1097 | for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { |
| 1126 | 1098 | struct dpu_hw_vbif *hw; |
| 1127 | 1099 | const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i]; |
| 1128 | 1100 | |
| 1129 | − hw = dpu_hw_vbif_init(vbif, dpu_kms->vbif[vbif->id]); | |
| 1101 | + hw = dpu_hw_vbif_init(dev, vbif, dpu_kms->vbif[vbif->id]); | |
| 1130 | 1102 | if (IS_ERR(hw)) { |
| 1131 | 1103 | rc = PTR_ERR(hw); |
| 1132 | 1104 | DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); |
| 1133 | − goto power_error; | |
| 1105 | + goto err_pm_put; | |
| 1134 | 1106 | } |
| 1135 | 1107 | |
| 1136 | 1108 | dpu_kms->hw_vbif[vbif->id] = hw; |
| @@ -1146,15 +1118,15 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 9 unmodified lines | ||
| 1146 | 1118 | rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); |
| 1147 | 1119 | if (rc) { |
| 1148 | 1120 | DPU_ERROR("failed to init perf %d\n", rc); |
| 1149 | − goto perf_err; | |
| 1121 | + goto err_pm_put; | |
| 1150 | 1122 | } |
| 1151 | 1123 | |
| 1152 | − dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog); | |
| 1153 | − if (IS_ERR_OR_NULL(dpu_kms->hw_intr)) { | |
| 1124 | + dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog); | |
| 1125 | + if (IS_ERR(dpu_kms->hw_intr)) { | |
| 1154 | 1126 | rc = PTR_ERR(dpu_kms->hw_intr); |
| 1155 | 1127 | DPU_ERROR("hw_intr init failed: %d\n", rc); |
| 1156 | 1128 | dpu_kms->hw_intr = NULL; |
| 1157 | − goto hw_intr_init_err; | |
| 1129 | + goto err_pm_put; | |
| 1158 | 1130 | } |
| 1159 | 1131 | |
| 1160 | 1132 | dev->mode_config.min_width = 0; |
| @@ -1179,7 +1151,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 18 unmodified lines | ||
| 1179 | 1151 | rc = _dpu_kms_drm_obj_init(dpu_kms); |
| 1180 | 1152 | if (rc) { |
| 1181 | 1153 | DPU_ERROR("modeset init failed: %d\n", rc); |
| 1182 | − goto drm_obj_init_err; | |
| 1154 | + goto err_pm_put; | |
| 1183 | 1155 | } |
| 1184 | 1156 | |
| 1185 | 1157 | dpu_vbif_init_memtypes(dpu_kms); |
| @@ -1188,10 +1160,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 2 unmodified lines | ||
| 1188 | 1160 | |
| 1189 | 1161 | return 0; |
| 1190 | 1162 | |
| 1191 | −drm_obj_init_err: | |
| 1192 | −hw_intr_init_err: | |
| 1193 | −perf_err: | |
| 1194 | −power_error: | |
| 1163 | +err_pm_put: | |
| 1195 | 1164 | pm_runtime_put_sync(&dpu_kms->pdev->dev); |
| 1196 | 1165 | error: |
| 1197 | 1166 | _dpu_kms_hw_destroy(dpu_kms); |
| @@ -1349,6 +1318,7 @@ static const struct dev_pm_ops dpu_pm_ops = { · 151 unmodified lines | ||
| 1349 | 1318 | static const struct of_device_id dpu_dt_match[] = { |
| 1350 | 1319 | { .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, }, |
| 1351 | 1320 | { .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, }, |
| 1321 | + { .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, }, | |
| 1352 | 1322 | { .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, }, |
| 1353 | 1323 | { .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, }, |
| 1354 | 1324 | { .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, }, |
| @@ -1363,6 +1333,7 @@ static const struct of_device_id dpu_dt_match[] = { · 8 unmodified lines | ||
| 1363 | 1333 | { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, }, |
| 1364 | 1334 | { .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, }, |
| 1365 | 1335 | { .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, }, |
| 1336 | + { .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, }, | |
| 1366 | 1337 | {} |
| 1367 | 1338 | }; |
| 1368 | 1339 | MODULE_DEVICE_TABLE(of, dpu_dt_match); |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | } while (0) |
| 52 | 52 | |
| 53 | 53 | #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) |
| 54 | +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) | |
| 54 | 55 | |
| 55 | 56 | /** |
| 56 | 57 | * ktime_compare_safe - compare two ktime structures |
| @@ -88,7 +89,6 @@ struct dpu_kms { · 31 unmodified lines | ||
| 88 | 89 | struct drm_private_obj global_state; |
| 89 | 90 | |
| 90 | 91 | struct dpu_rm rm; |
| 91 | − bool rm_init; | |
| 92 | 92 | |
| 93 | 93 | struct dpu_hw_vbif *hw_vbif[VBIF_MAX]; |
| 94 | 94 | struct dpu_hw_mdp *hw_mdp; |
| @@ -136,6 +136,7 @@ struct dpu_global_state { · 41 unmodified lines | ||
| 136 | 136 | uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; |
| 137 | 137 | uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; |
| 138 | 138 | uint32_t dsc_to_enc_id[DSC_MAX - DSC_0]; |
| 139 | + uint32_t cdm_to_enc_id; | |
| 139 | 140 | }; |
| 140 | 141 | |
| 141 | 142 | struct dpu_global_state |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include "dpu_kms.h" |
| 22 | 22 | #include "dpu_formats.h" |
| 23 | 23 | #include "dpu_hw_sspp.h" |
| 24 | +#include "dpu_hw_util.h" | |
| 24 | 25 | #include "dpu_trace.h" |
| 25 | 26 | #include "dpu_crtc.h" |
| 26 | 27 | #include "dpu_vbif.h" |
| @@ -78,8 +79,6 @@ static const uint32_t qcom_compressed_supported_formats[] = { · 51 unmodified lines | ||
| 78 | 79 | struct dpu_plane { |
| 79 | 80 | struct drm_plane base; |
| 80 | 81 | |
| 81 | − struct mutex lock; | |
| 82 | − | |
| 83 | 82 | enum dpu_sspp pipe; |
| 84 | 83 | |
| 85 | 84 | uint32_t color_fill; |
| @@ -470,8 +469,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw, · 384 unmodified lines | ||
| 470 | 469 | scale_cfg->src_height[i] /= chroma_subsmpl_v; |
| 471 | 470 | } |
| 472 | 471 | |
| 473 | − if (pipe_hw->cap->features & | |
| 474 | − BIT(DPU_SSPP_SCALER_QSEED4)) { | |
| 472 | + if (pipe_hw->cap->sblk->scaler_blk.version >= 0x3000) { | |
| 475 | 473 | scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H; |
| 476 | 474 | scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V; |
| 477 | 475 | } else { |
| @@ -511,36 +509,6 @@ static void _dpu_plane_setup_pixel_ext(struct dpu_hw_scaler3_cfg *scale_cfg, · 33 unmodified lines | ||
| 511 | 509 | } |
| 512 | 510 | } |
| 513 | 511 | |
| 514 | −static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { | |
| 515 | − { | |
| 516 | − /* S15.16 format */ | |
| 517 | − 0x00012A00, 0x00000000, 0x00019880, | |
| 518 | − 0x00012A00, 0xFFFF9B80, 0xFFFF3000, | |
| 519 | − 0x00012A00, 0x00020480, 0x00000000, | |
| 520 | − }, | |
| 521 | − /* signed bias */ | |
| 522 | − { 0xfff0, 0xff80, 0xff80,}, | |
| 523 | − { 0x0, 0x0, 0x0,}, | |
| 524 | − /* unsigned clamp */ | |
| 525 | − { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,}, | |
| 526 | − { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,}, | |
| 527 | −}; | |
| 528 | − | |
| 529 | −static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = { | |
| 530 | − { | |
| 531 | − /* S15.16 format */ | |
| 532 | − 0x00012A00, 0x00000000, 0x00019880, | |
| 533 | − 0x00012A00, 0xFFFF9B80, 0xFFFF3000, | |
| 534 | − 0x00012A00, 0x00020480, 0x00000000, | |
| 535 | − }, | |
| 536 | − /* signed bias */ | |
| 537 | − { 0xffc0, 0xfe00, 0xfe00,}, | |
| 538 | − { 0x0, 0x0, 0x0,}, | |
| 539 | − /* unsigned clamp */ | |
| 540 | − { 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,}, | |
| 541 | − { 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,}, | |
| 542 | −}; | |
| 543 | − | |
| 544 | 512 | static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, |
| 545 | 513 | const struct dpu_format *fmt) |
| 546 | 514 | { |
| @@ -774,8 +742,8 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, · 227 unmodified lines | ||
| 774 | 742 | min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; |
| 775 | 743 | |
| 776 | 744 | if (DPU_FORMAT_IS_YUV(fmt) && |
| 777 | − (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) || | |
| 778 | − !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) { | |
| 745 | + (!pipe->sspp->cap->sblk->scaler_blk.len || | |
| 746 | + !pipe->sspp->cap->sblk->csc_blk.len)) { | |
| 779 | 747 | DPU_DEBUG_PLANE(pdpu, |
| 780 | 748 | "plane doesn't have scaler/csc for yuv\n"); |
| 781 | 749 | return -EINVAL; |
| @@ -824,6 +792,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, · 42 unmodified lines | ||
| 824 | 792 | plane); |
| 825 | 793 | int ret = 0, min_scale; |
| 826 | 794 | struct dpu_plane *pdpu = to_dpu_plane(plane); |
| 795 | + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); | |
| 796 | + u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate; | |
| 827 | 797 | struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); |
| 828 | 798 | struct dpu_sw_pipe *pipe = &pstate->pipe; |
| 829 | 799 | struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; |
| @@ -892,14 +862,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, · 62 unmodified lines | ||
| 892 | 862 | |
| 893 | 863 | max_linewidth = pdpu->catalog->caps->max_linewidth; |
| 894 | 864 | |
| 895 | − if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { | |
| 865 | + if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) || | |
| 866 | + _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) { | |
| 896 | 867 | /* |
| 897 | 868 | * In parallel multirect case only the half of the usual width |
| 898 | 869 | * is supported for tiled formats. If we are here, we know that |
| 899 | 870 | * full width is more than max_linewidth, thus each rect is |
| 900 | 871 | * wider than allowed. |
| 901 | 872 | */ |
| 902 | − if (DPU_FORMAT_IS_UBWC(fmt)) { | |
| 873 | + if (DPU_FORMAT_IS_UBWC(fmt) && | |
| 874 | + drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { | |
| 903 | 875 | DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n", |
| 904 | 876 | DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); |
| 905 | 877 | return -E2BIG; |
| @@ -1213,29 +1185,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, · 307 unmodified lines | ||
| 1213 | 1185 | } |
| 1214 | 1186 | } |
| 1215 | 1187 | |
| 1216 | −static void dpu_plane_destroy(struct drm_plane *plane) | |
| 1217 | −{ | |
| 1218 | − struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL; | |
| 1219 | − struct dpu_plane_state *pstate; | |
| 1220 | − | |
| 1221 | − DPU_DEBUG_PLANE(pdpu, "\n"); | |
| 1222 | − | |
| 1223 | − if (pdpu) { | |
| 1224 | − pstate = to_dpu_plane_state(plane->state); | |
| 1225 | − _dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false); | |
| 1226 | − | |
| 1227 | − if (pstate->r_pipe.sspp) | |
| 1228 | − _dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false); | |
| 1229 | − | |
| 1230 | − mutex_destroy(&pdpu->lock); | |
| 1231 | − | |
| 1232 | − /* this will destroy the states as well */ | |
| 1233 | − drm_plane_cleanup(plane); | |
| 1234 | − | |
| 1235 | − kfree(pdpu); | |
| 1236 | − } | |
| 1237 | −} | |
| 1238 | − | |
| 1239 | 1188 | static void dpu_plane_destroy_state(struct drm_plane *plane, |
| 1240 | 1189 | struct drm_plane_state *state) |
| 1241 | 1190 | { |
| @@ -1405,7 +1354,6 @@ static bool dpu_plane_format_mod_supported(struct drm_plane *plane, · 163 unmodified lines | ||
| 1405 | 1354 | static const struct drm_plane_funcs dpu_plane_funcs = { |
| 1406 | 1355 | .update_plane = drm_atomic_helper_update_plane, |
| 1407 | 1356 | .disable_plane = drm_atomic_helper_disable_plane, |
| 1408 | − .destroy = dpu_plane_destroy, | |
| 1409 | 1357 | .reset = dpu_plane_reset, |
| 1410 | 1358 | .atomic_duplicate_state = dpu_plane_duplicate_state, |
| 1411 | 1359 | .atomic_destroy_state = dpu_plane_destroy_state, |
| @@ -1433,35 +1381,28 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 21 unmodified lines | ||
| 1433 | 1381 | struct dpu_hw_sspp *pipe_hw; |
| 1434 | 1382 | uint32_t num_formats; |
| 1435 | 1383 | uint32_t supported_rotations; |
| 1436 | − int ret = -EINVAL; | |
| 1437 | − | |
| 1438 | − /* create and zero local structure */ | |
| 1439 | − pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL); | |
| 1440 | − if (!pdpu) { | |
| 1441 | − DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe); | |
| 1442 | − ret = -ENOMEM; | |
| 1443 | − return ERR_PTR(ret); | |
| 1444 | − } | |
| 1445 | − | |
| 1446 | − /* cache local stuff for later */ | |
| 1447 | − plane = &pdpu->base; | |
| 1448 | − pdpu->pipe = pipe; | |
| 1384 | + int ret; | |
| 1449 | 1385 | |
| 1450 | 1386 | /* initialize underlying h/w driver */ |
| 1451 | 1387 | pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe); |
| 1452 | 1388 | if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { |
| 1453 | 1389 | DPU_ERROR("[%u]SSPP is invalid\n", pipe); |
| 1454 | − goto clean_plane; | |
| 1390 | + return ERR_PTR(-EINVAL); | |
| 1455 | 1391 | } |
| 1456 | 1392 | |
| 1457 | 1393 | format_list = pipe_hw->cap->sblk->format_list; |
| 1458 | 1394 | num_formats = pipe_hw->cap->sblk->num_formats; |
| 1459 | 1395 | |
| 1460 | − ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, | |
| 1396 | + pdpu = drmm_universal_plane_alloc(dev, struct dpu_plane, base, | |
| 1397 | + 0xff, &dpu_plane_funcs, | |
| 1461 | 1398 | format_list, num_formats, |
| 1462 | 1399 | supported_format_modifiers, type, NULL); |
| 1463 | − if (ret) | |
| 1464 | − goto clean_plane; | |
| 1400 | + if (IS_ERR(pdpu)) | |
| 1401 | + return ERR_CAST(pdpu); | |
| 1402 | + | |
| 1403 | + /* cache local stuff for later */ | |
| 1404 | + plane = &pdpu->base; | |
| 1405 | + pdpu->pipe = pipe; | |
| 1465 | 1406 | |
| 1466 | 1407 | pdpu->catalog = kms->catalog; |
| 1467 | 1408 | |
| @@ -1488,13 +1429,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 20 unmodified lines | ||
| 1488 | 1429 | /* success! finalize initialization */ |
| 1489 | 1430 | drm_plane_helper_add(plane, &dpu_plane_helper_funcs); |
| 1490 | 1431 | |
| 1491 | − mutex_init(&pdpu->lock); | |
| 1492 | − | |
| 1493 | 1432 | DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, |
| 1494 | 1433 | pipe, plane->base.id); |
| 1495 | 1434 | return plane; |
| 1496 | − | |
| 1497 | −clean_plane: | |
| 1498 | − kfree(pdpu); | |
| 1499 | − return ERR_PTR(ret); | |
| 1500 | 1435 | } |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include "dpu_kms.h" |
| 9 | 9 | #include "dpu_hw_lm.h" |
| 10 | 10 | #include "dpu_hw_ctl.h" |
| 11 | +#include "dpu_hw_cdm.h" | |
| 11 | 12 | #include "dpu_hw_pingpong.h" |
| 12 | 13 | #include "dpu_hw_sspp.h" |
| 13 | 14 | #include "dpu_hw_intf.h" |
| @@ -34,72 +35,8 @@ struct dpu_rm_requirements { · 20 unmodified lines | ||
| 34 | 35 | struct msm_display_topology topology; |
| 35 | 36 | }; |
| 36 | 37 | |
| 37 | −int dpu_rm_destroy(struct dpu_rm *rm) | |
| 38 | −{ | |
| 39 | − int i; | |
| 40 | − | |
| 41 | − for (i = 0; i < ARRAY_SIZE(rm->dspp_blks); i++) { | |
| 42 | − struct dpu_hw_dspp *hw; | |
| 43 | − | |
| 44 | − if (rm->dspp_blks[i]) { | |
| 45 | − hw = to_dpu_hw_dspp(rm->dspp_blks[i]); | |
| 46 | − dpu_hw_dspp_destroy(hw); | |
| 47 | − } | |
| 48 | − } | |
| 49 | − for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) { | |
| 50 | − struct dpu_hw_pingpong *hw; | |
| 51 | − | |
| 52 | − if (rm->pingpong_blks[i]) { | |
| 53 | − hw = to_dpu_hw_pingpong(rm->pingpong_blks[i]); | |
| 54 | − dpu_hw_pingpong_destroy(hw); | |
| 55 | − } | |
| 56 | − } | |
| 57 | − for (i = 0; i < ARRAY_SIZE(rm->merge_3d_blks); i++) { | |
| 58 | − struct dpu_hw_merge_3d *hw; | |
| 59 | − | |
| 60 | − if (rm->merge_3d_blks[i]) { | |
| 61 | − hw = to_dpu_hw_merge_3d(rm->merge_3d_blks[i]); | |
| 62 | − dpu_hw_merge_3d_destroy(hw); | |
| 63 | − } | |
| 64 | − } | |
| 65 | − for (i = 0; i < ARRAY_SIZE(rm->mixer_blks); i++) { | |
| 66 | − struct dpu_hw_mixer *hw; | |
| 67 | − | |
| 68 | − if (rm->mixer_blks[i]) { | |
| 69 | − hw = to_dpu_hw_mixer(rm->mixer_blks[i]); | |
| 70 | − dpu_hw_lm_destroy(hw); | |
| 71 | − } | |
| 72 | − } | |
| 73 | − for (i = 0; i < ARRAY_SIZE(rm->ctl_blks); i++) { | |
| 74 | − struct dpu_hw_ctl *hw; | |
| 75 | − | |
| 76 | − if (rm->ctl_blks[i]) { | |
| 77 | − hw = to_dpu_hw_ctl(rm->ctl_blks[i]); | |
| 78 | − dpu_hw_ctl_destroy(hw); | |
| 79 | − } | |
| 80 | − } | |
| 81 | − for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++) | |
| 82 | − dpu_hw_intf_destroy(rm->hw_intf[i]); | |
| 83 | − | |
| 84 | − for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) { | |
| 85 | − struct dpu_hw_dsc *hw; | |
| 86 | − | |
| 87 | − if (rm->dsc_blks[i]) { | |
| 88 | − hw = to_dpu_hw_dsc(rm->dsc_blks[i]); | |
| 89 | − dpu_hw_dsc_destroy(hw); | |
| 90 | − } | |
| 91 | − } | |
| 92 | − | |
| 93 | − for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++) | |
| 94 | − dpu_hw_wb_destroy(rm->hw_wb[i]); | |
| 95 | − | |
| 96 | − for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++) | |
| 97 | − dpu_hw_sspp_destroy(rm->hw_sspp[i]); | |
| 98 | − | |
| 99 | − return 0; | |
| 100 | −} | |
| 101 | − | |
| 102 | −int dpu_rm_init(struct dpu_rm *rm, | |
| 38 | +int dpu_rm_init(struct drm_device *dev, | |
| 39 | + struct dpu_rm *rm, | |
| 103 | 40 | const struct dpu_mdss_cfg *cat, |
| 104 | 41 | const struct msm_mdss_data *mdss_data, |
| 105 | 42 | void __iomem *mmio) |
| @@ -119,7 +56,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 13 unmodified lines | ||
| 119 | 56 | struct dpu_hw_mixer *hw; |
| 120 | 57 | const struct dpu_lm_cfg *lm = &cat->mixer[i]; |
| 121 | 58 | |
| 122 | − hw = dpu_hw_lm_init(lm, mmio); | |
| 59 | + hw = dpu_hw_lm_init(dev, lm, mmio); | |
| 123 | 60 | if (IS_ERR(hw)) { |
| 124 | 61 | rc = PTR_ERR(hw); |
| 125 | 62 | DPU_ERROR("failed lm object creation: err %d\n", rc); |
| @@ -132,7 +69,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 6 unmodified lines | ||
| 132 | 69 | struct dpu_hw_merge_3d *hw; |
| 133 | 70 | const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i]; |
| 134 | 71 | |
| 135 | − hw = dpu_hw_merge_3d_init(merge_3d, mmio); | |
| 72 | + hw = dpu_hw_merge_3d_init(dev, merge_3d, mmio); | |
| 136 | 73 | if (IS_ERR(hw)) { |
| 137 | 74 | rc = PTR_ERR(hw); |
| 138 | 75 | DPU_ERROR("failed merge_3d object creation: err %d\n", |
| @@ -146,7 +83,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 7 unmodified lines | ||
| 146 | 83 | struct dpu_hw_pingpong *hw; |
| 147 | 84 | const struct dpu_pingpong_cfg *pp = &cat->pingpong[i]; |
| 148 | 85 | |
| 149 | − hw = dpu_hw_pingpong_init(pp, mmio, cat->mdss_ver); | |
| 86 | + hw = dpu_hw_pingpong_init(dev, pp, mmio, cat->mdss_ver); | |
| 150 | 87 | if (IS_ERR(hw)) { |
| 151 | 88 | rc = PTR_ERR(hw); |
| 152 | 89 | DPU_ERROR("failed pingpong object creation: err %d\n", |
| @@ -162,7 +99,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 9 unmodified lines | ||
| 162 | 99 | struct dpu_hw_intf *hw; |
| 163 | 100 | const struct dpu_intf_cfg *intf = &cat->intf[i]; |
| 164 | 101 | |
| 165 | − hw = dpu_hw_intf_init(intf, mmio, cat->mdss_ver); | |
| 102 | + hw = dpu_hw_intf_init(dev, intf, mmio, cat->mdss_ver); | |
| 166 | 103 | if (IS_ERR(hw)) { |
| 167 | 104 | rc = PTR_ERR(hw); |
| 168 | 105 | DPU_ERROR("failed intf object creation: err %d\n", rc); |
| @@ -175,7 +112,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 6 unmodified lines | ||
| 175 | 112 | struct dpu_hw_wb *hw; |
| 176 | 113 | const struct dpu_wb_cfg *wb = &cat->wb[i]; |
| 177 | 114 | |
| 178 | − hw = dpu_hw_wb_init(wb, mmio, cat->mdss_ver); | |
| 115 | + hw = dpu_hw_wb_init(dev, wb, mmio, cat->mdss_ver); | |
| 179 | 116 | if (IS_ERR(hw)) { |
| 180 | 117 | rc = PTR_ERR(hw); |
| 181 | 118 | DPU_ERROR("failed wb object creation: err %d\n", rc); |
| @@ -188,7 +125,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 6 unmodified lines | ||
| 188 | 125 | struct dpu_hw_ctl *hw; |
| 189 | 126 | const struct dpu_ctl_cfg *ctl = &cat->ctl[i]; |
| 190 | 127 | |
| 191 | − hw = dpu_hw_ctl_init(ctl, mmio, cat->mixer_count, cat->mixer); | |
| 128 | + hw = dpu_hw_ctl_init(dev, ctl, mmio, cat->mixer_count, cat->mixer); | |
| 192 | 129 | if (IS_ERR(hw)) { |
| 193 | 130 | rc = PTR_ERR(hw); |
| 194 | 131 | DPU_ERROR("failed ctl object creation: err %d\n", rc); |
| @@ -201,7 +138,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 6 unmodified lines | ||
| 201 | 138 | struct dpu_hw_dspp *hw; |
| 202 | 139 | const struct dpu_dspp_cfg *dspp = &cat->dspp[i]; |
| 203 | 140 | |
| 204 | − hw = dpu_hw_dspp_init(dspp, mmio); | |
| 141 | + hw = dpu_hw_dspp_init(dev, dspp, mmio); | |
| 205 | 142 | if (IS_ERR(hw)) { |
| 206 | 143 | rc = PTR_ERR(hw); |
| 207 | 144 | DPU_ERROR("failed dspp object creation: err %d\n", rc); |
| @@ -215,9 +152,9 @@ int dpu_rm_init(struct dpu_rm *rm, · 7 unmodified lines | ||
| 215 | 152 | const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; |
| 216 | 153 | |
| 217 | 154 | if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features)) |
| 218 | − hw = dpu_hw_dsc_init_1_2(dsc, mmio); | |
| 155 | + hw = dpu_hw_dsc_init_1_2(dev, dsc, mmio); | |
| 219 | 156 | else |
| 220 | − hw = dpu_hw_dsc_init(dsc, mmio); | |
| 157 | + hw = dpu_hw_dsc_init(dev, dsc, mmio); | |
| 221 | 158 | |
| 222 | 159 | if (IS_ERR(hw)) { |
| 223 | 160 | rc = PTR_ERR(hw); |
| @@ -231,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 7 unmodified lines | ||
| 231 | 168 | struct dpu_hw_sspp *hw; |
| 232 | 169 | const struct dpu_sspp_cfg *sspp = &cat->sspp[i]; |
| 233 | 170 | |
| 234 | − hw = dpu_hw_sspp_init(sspp, mmio, mdss_data, cat->mdss_ver); | |
| 171 | + hw = dpu_hw_sspp_init(dev, sspp, mmio, mdss_data, cat->mdss_ver); | |
| 235 | 172 | if (IS_ERR(hw)) { |
| 236 | 173 | rc = PTR_ERR(hw); |
| 237 | 174 | DPU_ERROR("failed sspp object creation: err %d\n", rc); |
| @@ -240,11 +177,21 @@ int dpu_rm_init(struct dpu_rm *rm, · 2 unmodified lines | ||
| 240 | 177 | rm->hw_sspp[sspp->id - SSPP_NONE] = hw; |
| 241 | 178 | } |
| 242 | 179 | |
| 180 | + if (cat->cdm) { | |
| 181 | + struct dpu_hw_cdm *hw; | |
| 182 | + | |
| 183 | + hw = dpu_hw_cdm_init(dev, cat->cdm, mmio, cat->mdss_ver); | |
| 184 | + if (IS_ERR(hw)) { | |
| 185 | + rc = PTR_ERR(hw); | |
| 186 | + DPU_ERROR("failed cdm object creation: err %d\n", rc); | |
| 187 | + goto fail; | |
| 188 | + } | |
| 189 | + rm->cdm_blk = &hw->base; | |
| 190 | + } | |
| 191 | + | |
| 243 | 192 | return 0; |
| 244 | 193 | |
| 245 | 194 | fail: |
| 246 | − dpu_rm_destroy(rm); | |
| 247 | − | |
| 248 | 195 | return rc ? rc : -EFAULT; |
| 249 | 196 | } |
| 250 | 197 | |
| @@ -488,6 +435,26 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, · 237 unmodified lines | ||
| 488 | 435 | return 0; |
| 489 | 436 | } |
| 490 | 437 | |
| 438 | +static int _dpu_rm_reserve_cdm(struct dpu_rm *rm, | |
| 439 | + struct dpu_global_state *global_state, | |
| 440 | + struct drm_encoder *enc) | |
| 441 | +{ | |
| 442 | + /* try allocating only one CDM block */ | |
| 443 | + if (!rm->cdm_blk) { | |
| 444 | + DPU_ERROR("CDM block does not exist\n"); | |
| 445 | + return -EIO; | |
| 446 | + } | |
| 447 | + | |
| 448 | + if (global_state->cdm_to_enc_id) { | |
| 449 | + DPU_ERROR("CDM_0 is already allocated\n"); | |
| 450 | + return -EIO; | |
| 451 | + } | |
| 452 | + | |
| 453 | + global_state->cdm_to_enc_id = enc->base.id; | |
| 454 | + | |
| 455 | + return 0; | |
| 456 | +} | |
| 457 | + | |
| 491 | 458 | static int _dpu_rm_make_reservation( |
| 492 | 459 | struct dpu_rm *rm, |
| 493 | 460 | struct dpu_global_state *global_state, |
| @@ -513,6 +480,14 @@ static int _dpu_rm_make_reservation( · 19 unmodified lines | ||
| 513 | 480 | if (ret) |
| 514 | 481 | return ret; |
| 515 | 482 | |
| 483 | + if (reqs->topology.needs_cdm) { | |
| 484 | + ret = _dpu_rm_reserve_cdm(rm, global_state, enc); | |
| 485 | + if (ret) { | |
| 486 | + DPU_ERROR("unable to find CDM blk\n"); | |
| 487 | + return ret; | |
| 488 | + } | |
| 489 | + } | |
| 490 | + | |
| 516 | 491 | return ret; |
| 517 | 492 | } |
| 518 | 493 | |
| @@ -523,9 +498,9 @@ static int _dpu_rm_populate_requirements( · 4 unmodified lines | ||
| 523 | 498 | { |
| 524 | 499 | reqs->topology = req_topology; |
| 525 | 500 | |
| 526 | − DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d\n", | |
| 501 | + DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d cdm: %d\n", | |
| 527 | 502 | reqs->topology.num_lm, reqs->topology.num_dsc, |
| 528 | − reqs->topology.num_intf); | |
| 503 | + reqs->topology.num_intf, reqs->topology.needs_cdm); | |
| 529 | 504 | |
| 530 | 505 | return 0; |
| 531 | 506 | } |
| @@ -554,6 +529,7 @@ void dpu_rm_release(struct dpu_global_state *global_state, · 22 unmodified lines | ||
| 554 | 529 | ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id); |
| 555 | 530 | _dpu_rm_clear_mapping(global_state->dspp_to_enc_id, |
| 556 | 531 | ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id); |
| 532 | + _dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id); | |
| 557 | 533 | } |
| 558 | 534 | |
| 559 | 535 | int dpu_rm_reserve( |
| @@ -627,6 +603,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, · 67 unmodified lines | ||
| 627 | 603 | hw_to_enc_id = global_state->dsc_to_enc_id; |
| 628 | 604 | max_blks = ARRAY_SIZE(rm->dsc_blks); |
| 629 | 605 | break; |
| 606 | + case DPU_HW_BLK_CDM: | |
| 607 | + hw_blks = &rm->cdm_blk; | |
| 608 | + hw_to_enc_id = &global_state->cdm_to_enc_id; | |
| 609 | + max_blks = 1; | |
| 610 | + break; | |
| 630 | 611 | default: |
| 631 | 612 | DPU_ERROR("blk type %d not managed by rm\n", type); |
| 632 | 613 | return 0; |
| @@ -22,6 +22,7 @@ struct dpu_global_state; · 21 unmodified lines | ||
| 22 | 22 | * @hw_wb: array of wb hardware resources |
| 23 | 23 | * @dspp_blks: array of dspp hardware resources |
| 24 | 24 | * @hw_sspp: array of sspp hardware resources |
| 25 | + * @cdm_blk: cdm hardware resource | |
| 25 | 26 | */ |
| 26 | 27 | struct dpu_rm { |
| 27 | 28 | struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; |
| @@ -33,29 +34,25 @@ struct dpu_rm { · 5 unmodified lines | ||
| 33 | 34 | struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; |
| 34 | 35 | struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; |
| 35 | 36 | struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE]; |
| 37 | + struct dpu_hw_blk *cdm_blk; | |
| 36 | 38 | }; |
| 37 | 39 | |
| 38 | 40 | /** |
| 39 | 41 | * dpu_rm_init - Read hardware catalog and create reservation tracking objects |
| 40 | 42 | * for all HW blocks. |
| 43 | + * @dev: Corresponding device for devres management | |
| 41 | 44 | * @rm: DPU Resource Manager handle |
| 42 | 45 | * @cat: Pointer to hardware catalog |
| 43 | 46 | * @mdss_data: Pointer to MDSS / UBWC configuration |
| 44 | 47 | * @mmio: mapped register io address of MDP |
| 45 | 48 | * @Return: 0 on Success otherwise -ERROR |
| 46 | 49 | */ |
| 47 | −int dpu_rm_init(struct dpu_rm *rm, | |
| 50 | +int dpu_rm_init(struct drm_device *dev, | |
| 51 | + struct dpu_rm *rm, | |
| 48 | 52 | const struct dpu_mdss_cfg *cat, |
| 49 | 53 | const struct msm_mdss_data *mdss_data, |
| 50 | 54 | void __iomem *mmio); |
| 51 | 55 | |
| 52 | −/** | |
| 53 | − * dpu_rm_destroy - Free all memory allocated by dpu_rm_init | |
| 54 | − * @rm: DPU Resource Manager handle | |
| 55 | − * @Return: 0 on Success otherwise -ERROR | |
| 56 | − */ | |
| 57 | −int dpu_rm_destroy(struct dpu_rm *rm); | |
| 58 | − | |
| 59 | 56 | /** |
| 60 | 57 | * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze |
| 61 | 58 | * the use connections and user requirements, specified through related |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include <drm/drm_crtc.h> |
| 8 | 8 | #include <drm/drm_flip_work.h> |
| 9 | +#include <drm/drm_managed.h> | |
| 9 | 10 | #include <drm/drm_mode.h> |
| 10 | 11 | #include <drm/drm_probe_helper.h> |
| 11 | 12 | #include <drm/drm_vblank.h> |
| @@ -123,16 +124,6 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) · 111 unmodified lines | ||
| 123 | 124 | drm_gem_object_put(val); |
| 124 | 125 | } |
| 125 | 126 | |
| 126 | −static void mdp4_crtc_destroy(struct drm_crtc *crtc) | |
| 127 | −{ | |
| 128 | − struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | |
| 129 | − | |
| 130 | − drm_crtc_cleanup(crtc); | |
| 131 | − drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work); | |
| 132 | − | |
| 133 | − kfree(mdp4_crtc); | |
| 134 | −} | |
| 135 | − | |
| 136 | 127 | /* statically (for now) map planes to mixer stage (z-order): */ |
| 137 | 128 | static const int idxs[] = { |
| 138 | 129 | [VG1] = 1, |
| @@ -269,6 +260,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, · 130 unmodified lines | ||
| 269 | 260 | { |
| 270 | 261 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 271 | 262 | struct mdp4_kms *mdp4_kms = get_kms(crtc); |
| 263 | + unsigned long flags; | |
| 272 | 264 | |
| 273 | 265 | DBG("%s", mdp4_crtc->name); |
| 274 | 266 | |
| @@ -281,6 +273,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, · 6 unmodified lines | ||
| 281 | 273 | mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); |
| 282 | 274 | mdp4_disable(mdp4_kms); |
| 283 | 275 | |
| 276 | + if (crtc->state->event && !crtc->state->active) { | |
| 277 | + WARN_ON(mdp4_crtc->event); | |
| 278 | + spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); | |
| 279 | + drm_crtc_send_vblank_event(crtc, crtc->state->event); | |
| 280 | + crtc->state->event = NULL; | |
| 281 | + spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); | |
| 282 | + } | |
| 283 | + | |
| 284 | 284 | mdp4_crtc->enabled = false; |
| 285 | 285 | } |
| 286 | 286 | |
| @@ -475,7 +475,6 @@ static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) · 188 unmodified lines | ||
| 475 | 475 | |
| 476 | 476 | static const struct drm_crtc_funcs mdp4_crtc_funcs = { |
| 477 | 477 | .set_config = drm_atomic_helper_set_config, |
| 478 | − .destroy = mdp4_crtc_destroy, | |
| 479 | 478 | .page_flip = drm_atomic_helper_page_flip, |
| 480 | 479 | .cursor_set = mdp4_crtc_cursor_set, |
| 481 | 480 | .cursor_move = mdp4_crtc_cursor_move, |
| @@ -616,6 +615,13 @@ static const char *dma_names[] = { · 134 unmodified lines | ||
| 616 | 615 | "DMA_P", "DMA_S", "DMA_E", |
| 617 | 616 | }; |
| 618 | 617 | |
| 618 | +static void mdp4_crtc_flip_cleanup(struct drm_device *dev, void *ptr) | |
| 619 | +{ | |
| 620 | + struct mdp4_crtc *mdp4_crtc = ptr; | |
| 621 | + | |
| 622 | + drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work); | |
| 623 | +} | |
| 624 | + | |
| 619 | 625 | /* initialize crtc */ |
| 620 | 626 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, |
| 621 | 627 | struct drm_plane *plane, int id, int ovlp_id, |
| @@ -623,10 +629,13 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, · 1 unmodified line | ||
| 623 | 629 | { |
| 624 | 630 | struct drm_crtc *crtc = NULL; |
| 625 | 631 | struct mdp4_crtc *mdp4_crtc; |
| 632 | + int ret; | |
| 626 | 633 | |
| 627 | − mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL); | |
| 628 | − if (!mdp4_crtc) | |
| 629 | − return ERR_PTR(-ENOMEM); | |
| 634 | + mdp4_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp4_crtc, base, | |
| 635 | + plane, NULL, | |
| 636 | + &mdp4_crtc_funcs, NULL); | |
| 637 | + if (IS_ERR(mdp4_crtc)) | |
| 638 | + return ERR_CAST(mdp4_crtc); | |
| 630 | 639 | |
| 631 | 640 | crtc = &mdp4_crtc->base; |
| 632 | 641 | |
| @@ -648,9 +657,10 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, · 15 unmodified lines | ||
| 648 | 657 | |
| 649 | 658 | drm_flip_work_init(&mdp4_crtc->unref_cursor_work, |
| 650 | 659 | "unref cursor", unref_cursor_worker); |
| 660 | + ret = drmm_add_action_or_reset(dev, mdp4_crtc_flip_cleanup, mdp4_crtc); | |
| 661 | + if (ret) | |
| 662 | + return ERR_PTR(ret); | |
| 651 | 663 | |
| 652 | − drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs, | |
| 653 | − NULL); | |
| 654 | 664 | drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); |
| 655 | 665 | |
| 656 | 666 | return crtc; |
| @@ -26,18 +26,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 25 unmodified lines | ||
| 26 | 26 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | −static void mdp4_dsi_encoder_destroy(struct drm_encoder *encoder) | |
| 30 | −{ | |
| 31 | − struct mdp4_dsi_encoder *mdp4_dsi_encoder = to_mdp4_dsi_encoder(encoder); | |
| 32 | − | |
| 33 | − drm_encoder_cleanup(encoder); | |
| 34 | − kfree(mdp4_dsi_encoder); | |
| 35 | −} | |
| 36 | − | |
| 37 | −static const struct drm_encoder_funcs mdp4_dsi_encoder_funcs = { | |
| 38 | − .destroy = mdp4_dsi_encoder_destroy, | |
| 39 | −}; | |
| 40 | − | |
| 41 | 29 | static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder, |
| 42 | 30 | struct drm_display_mode *mode, |
| 43 | 31 | struct drm_display_mode *adjusted_mode) |
| @@ -148,28 +136,18 @@ static const struct drm_encoder_helper_funcs mdp4_dsi_encoder_helper_funcs = { · 104 unmodified lines | ||
| 148 | 136 | /* initialize encoder */ |
| 149 | 137 | struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev) |
| 150 | 138 | { |
| 151 | − struct drm_encoder *encoder = NULL; | |
| 139 | + struct drm_encoder *encoder; | |
| 152 | 140 | struct mdp4_dsi_encoder *mdp4_dsi_encoder; |
| 153 | − int ret; | |
| 154 | 141 | |
| 155 | − mdp4_dsi_encoder = kzalloc(sizeof(*mdp4_dsi_encoder), GFP_KERNEL); | |
| 156 | − if (!mdp4_dsi_encoder) { | |
| 157 | − ret = -ENOMEM; | |
| 158 | − goto fail; | |
| 159 | − } | |
| 142 | + mdp4_dsi_encoder = drmm_encoder_alloc(dev, struct mdp4_dsi_encoder, base, | |
| 143 | + NULL, DRM_MODE_ENCODER_DSI, NULL); | |
| 144 | + if (IS_ERR(mdp4_dsi_encoder)) | |
| 145 | + return ERR_CAST(mdp4_dsi_encoder); | |
| 160 | 146 | |
| 161 | 147 | encoder = &mdp4_dsi_encoder->base; |
| 162 | 148 | |
| 163 | − drm_encoder_init(dev, encoder, &mdp4_dsi_encoder_funcs, | |
| 164 | − DRM_MODE_ENCODER_DSI, NULL); | |
| 165 | 149 | drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs); |
| 166 | 150 | |
| 167 | 151 | return encoder; |
| 168 | − | |
| 169 | −fail: | |
| 170 | − if (encoder) | |
| 171 | − mdp4_dsi_encoder_destroy(encoder); | |
| 172 | − | |
| 173 | − return ERR_PTR(ret); | |
| 174 | 152 | } |
| 175 | 153 | #endif /* CONFIG_DRM_MSM_DSI */ |
| @@ -25,17 +25,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 24 unmodified lines | ||
| 25 | 25 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | −static void mdp4_dtv_encoder_destroy(struct drm_encoder *encoder) | |
| 29 | −{ | |
| 30 | − struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); | |
| 31 | − drm_encoder_cleanup(encoder); | |
| 32 | − kfree(mdp4_dtv_encoder); | |
| 33 | −} | |
| 34 | − | |
| 35 | −static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = { | |
| 36 | − .destroy = mdp4_dtv_encoder_destroy, | |
| 37 | −}; | |
| 38 | − | |
| 39 | 28 | static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, |
| 40 | 29 | struct drm_display_mode *mode, |
| 41 | 30 | struct drm_display_mode *adjusted_mode) |
| @@ -173,41 +162,29 @@ long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate) · 131 unmodified lines | ||
| 173 | 162 | /* initialize encoder */ |
| 174 | 163 | struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev) |
| 175 | 164 | { |
| 176 | − struct drm_encoder *encoder = NULL; | |
| 165 | + struct drm_encoder *encoder; | |
| 177 | 166 | struct mdp4_dtv_encoder *mdp4_dtv_encoder; |
| 178 | − int ret; | |
| 179 | 167 | |
| 180 | − mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL); | |
| 181 | − if (!mdp4_dtv_encoder) { | |
| 182 | − ret = -ENOMEM; | |
| 183 | − goto fail; | |
| 184 | − } | |
| 168 | + mdp4_dtv_encoder = drmm_encoder_alloc(dev, struct mdp4_dtv_encoder, base, | |
| 169 | + NULL, DRM_MODE_ENCODER_TMDS, NULL); | |
| 170 | + if (IS_ERR(mdp4_dtv_encoder)) | |
| 171 | + return ERR_CAST(mdp4_dtv_encoder); | |
| 185 | 172 | |
| 186 | 173 | encoder = &mdp4_dtv_encoder->base; |
| 187 | 174 | |
| 188 | − drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs, | |
| 189 | − DRM_MODE_ENCODER_TMDS, NULL); | |
| 190 | 175 | drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs); |
| 191 | 176 | |
| 192 | 177 | mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk"); |
| 193 | 178 | if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) { |
| 194 | 179 | DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n"); |
| 195 | − ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk); | |
| 196 | − goto fail; | |
| 180 | + return ERR_CAST(mdp4_dtv_encoder->hdmi_clk); | |
| 197 | 181 | } |
| 198 | 182 | |
| 199 | 183 | mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk"); |
| 200 | 184 | if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) { |
| 201 | 185 | DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n"); |
| 202 | − ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk); | |
| 203 | − goto fail; | |
| 186 | + return ERR_CAST(mdp4_dtv_encoder->mdp_clk); | |
| 204 | 187 | } |
| 205 | 188 | |
| 206 | 189 | return encoder; |
| 207 | − | |
| 208 | −fail: | |
| 209 | − if (encoder) | |
| 210 | − mdp4_dtv_encoder_destroy(encoder); | |
| 211 | − | |
| 212 | − return ERR_PTR(ret); | |
| 213 | 190 | } |
| @@ -18,7 +18,7 @@ struct mdp4_lcdc_encoder { · 17 unmodified lines | ||
| 18 | 18 | struct drm_panel *panel; |
| 19 | 19 | struct clk *lcdc_clk; |
| 20 | 20 | unsigned long int pixclock; |
| 21 | − struct regulator *regs[3]; | |
| 21 | + struct regulator_bulk_data regs[3]; | |
| 22 | 22 | bool enabled; |
| 23 | 23 | uint32_t bsc; |
| 24 | 24 | }; |
| @@ -30,18 +30,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 5 unmodified lines | ||
| 30 | 30 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | −static void mdp4_lcdc_encoder_destroy(struct drm_encoder *encoder) | |
| 34 | −{ | |
| 35 | − struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = | |
| 36 | − to_mdp4_lcdc_encoder(encoder); | |
| 37 | − drm_encoder_cleanup(encoder); | |
| 38 | − kfree(mdp4_lcdc_encoder); | |
| 39 | −} | |
| 40 | − | |
| 41 | −static const struct drm_encoder_funcs mdp4_lcdc_encoder_funcs = { | |
| 42 | − .destroy = mdp4_lcdc_encoder_destroy, | |
| 43 | −}; | |
| 44 | − | |
| 45 | 33 | /* this should probably be a helper: */ |
| 46 | 34 | static struct drm_connector *get_connector(struct drm_encoder *encoder) |
| 47 | 35 | { |
| @@ -271,12 +259,10 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder, · 223 unmodified lines | ||
| 271 | 259 | |
| 272 | 260 | static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) |
| 273 | 261 | { |
| 274 | − struct drm_device *dev = encoder->dev; | |
| 275 | 262 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = |
| 276 | 263 | to_mdp4_lcdc_encoder(encoder); |
| 277 | 264 | struct mdp4_kms *mdp4_kms = get_kms(encoder); |
| 278 | 265 | struct drm_panel *panel; |
| 279 | − int i, ret; | |
| 280 | 266 | |
| 281 | 267 | if (WARN_ON(!mdp4_lcdc_encoder->enabled)) |
| 282 | 268 | return; |
| @@ -301,11 +287,8 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) · 18 unmodified lines | ||
| 301 | 287 | |
| 302 | 288 | clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); |
| 303 | 289 | |
| 304 | − for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | |
| 305 | − ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); | |
| 306 | − if (ret) | |
| 307 | − DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret); | |
| 308 | − } | |
| 290 | + regulator_bulk_disable(ARRAY_SIZE(mdp4_lcdc_encoder->regs), | |
| 291 | + mdp4_lcdc_encoder->regs); | |
| 309 | 292 | |
| 310 | 293 | mdp4_lcdc_encoder->enabled = false; |
| 311 | 294 | } |
| @@ -319,7 +302,7 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · 7 unmodified lines | ||
| 319 | 302 | struct mdp4_kms *mdp4_kms = get_kms(encoder); |
| 320 | 303 | struct drm_panel *panel; |
| 321 | 304 | uint32_t config; |
| 322 | − int i, ret; | |
| 305 | + int ret; | |
| 323 | 306 | |
| 324 | 307 | if (WARN_ON(mdp4_lcdc_encoder->enabled)) |
| 325 | 308 | return; |
| @@ -339,11 +322,10 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · 13 unmodified lines | ||
| 339 | 322 | mdp4_crtc_set_config(encoder->crtc, config); |
| 340 | 323 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); |
| 341 | 324 | |
| 342 | − for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | |
| 343 | − ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); | |
| 344 | − if (ret) | |
| 345 | − DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret); | |
| 346 | − } | |
| 325 | + ret = regulator_bulk_enable(ARRAY_SIZE(mdp4_lcdc_encoder->regs), | |
| 326 | + mdp4_lcdc_encoder->regs); | |
| 327 | + if (ret) | |
| 328 | + DRM_DEV_ERROR(dev->dev, "failed to enable regulators: %d\n", ret); | |
| 347 | 329 | |
| 348 | 330 | DBG("setting lcdc_clk=%lu", pc); |
| 349 | 331 | ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); |
| @@ -383,63 +365,38 @@ long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) · 33 unmodified lines | ||
| 383 | 365 | struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, |
| 384 | 366 | struct device_node *panel_node) |
| 385 | 367 | { |
| 386 | − struct drm_encoder *encoder = NULL; | |
| 368 | + struct drm_encoder *encoder; | |
| 387 | 369 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; |
| 388 | − struct regulator *reg; | |
| 389 | 370 | int ret; |
| 390 | 371 | |
| 391 | − mdp4_lcdc_encoder = kzalloc(sizeof(*mdp4_lcdc_encoder), GFP_KERNEL); | |
| 392 | − if (!mdp4_lcdc_encoder) { | |
| 393 | − ret = -ENOMEM; | |
| 394 | − goto fail; | |
| 395 | − } | |
| 372 | + mdp4_lcdc_encoder = drmm_encoder_alloc(dev, struct mdp4_lcdc_encoder, base, | |
| 373 | + NULL, DRM_MODE_ENCODER_LVDS, NULL); | |
| 374 | + if (IS_ERR(mdp4_lcdc_encoder)) | |
| 375 | + return ERR_CAST(mdp4_lcdc_encoder); | |
| 396 | 376 | |
| 397 | 377 | mdp4_lcdc_encoder->panel_node = panel_node; |
| 398 | 378 | |
| 399 | 379 | encoder = &mdp4_lcdc_encoder->base; |
| 400 | 380 | |
| 401 | − drm_encoder_init(dev, encoder, &mdp4_lcdc_encoder_funcs, | |
| 402 | − DRM_MODE_ENCODER_LVDS, NULL); | |
| 403 | 381 | drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); |
| 404 | 382 | |
| 405 | 383 | /* TODO: do we need different pll in other cases? */ |
| 406 | 384 | mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); |
| 407 | 385 | if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { |
| 408 | 386 | DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); |
| 409 | − ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk); | |
| 410 | − goto fail; | |
| 387 | + return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk); | |
| 411 | 388 | } |
| 412 | 389 | |
| 413 | 390 | /* TODO: different regulators in other cases? */ |
| 414 | − reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v"); | |
| 415 | − if (IS_ERR(reg)) { | |
| 416 | − ret = PTR_ERR(reg); | |
| 417 | − DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); | |
| 418 | − goto fail; | |
| 419 | − } | |
| 420 | − mdp4_lcdc_encoder->regs[0] = reg; | |
| 421 | − | |
| 422 | − reg = devm_regulator_get(dev->dev, "lvds-pll-vdda"); | |
| 423 | − if (IS_ERR(reg)) { | |
| 424 | − ret = PTR_ERR(reg); | |
| 425 | − DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); | |
| 426 | − goto fail; | |
| 427 | − } | |
| 428 | − mdp4_lcdc_encoder->regs[1] = reg; | |
| 391 | + mdp4_lcdc_encoder->regs[0].supply = "lvds-vccs-3p3v"; | |
| 392 | + mdp4_lcdc_encoder->regs[1].supply = "lvds-vccs-3p3v"; | |
| 393 | + mdp4_lcdc_encoder->regs[2].supply = "lvds-vdda"; | |
| 429 | 394 | |
| 430 | − reg = devm_regulator_get(dev->dev, "lvds-vdda"); | |
| 431 | − if (IS_ERR(reg)) { | |
| 432 | − ret = PTR_ERR(reg); | |
| 433 | − DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret); | |
| 434 | − goto fail; | |
| 435 | − } | |
| 436 | − mdp4_lcdc_encoder->regs[2] = reg; | |
| 395 | + ret = devm_regulator_bulk_get(dev->dev, | |
| 396 | + ARRAY_SIZE(mdp4_lcdc_encoder->regs), | |
| 397 | + mdp4_lcdc_encoder->regs); | |
| 398 | + if (ret) | |
| 399 | + return ERR_PTR(ret); | |
| 437 | 400 | |
| 438 | 401 | return encoder; |
| 439 | − | |
| 440 | −fail: | |
| 441 | − if (encoder) | |
| 442 | − mdp4_lcdc_encoder_destroy(encoder); | |
| 443 | − | |
| 444 | − return ERR_PTR(ret); | |
| 445 | 402 | } |
| @@ -1350,23 +1350,17 @@ int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler) · 1349 unmodified lines | ||
| 1350 | 1350 | return cfg_handler->revision; |
| 1351 | 1351 | } |
| 1352 | 1352 | |
| 1353 | −void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler) | |
| 1354 | −{ | |
| 1355 | − kfree(cfg_handler); | |
| 1356 | −} | |
| 1357 | − | |
| 1358 | 1353 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, |
| 1359 | 1354 | uint32_t major, uint32_t minor) |
| 1360 | 1355 | { |
| 1361 | 1356 | struct drm_device *dev = mdp5_kms->dev; |
| 1362 | 1357 | struct mdp5_cfg_handler *cfg_handler; |
| 1363 | 1358 | const struct mdp5_cfg_handler *cfg_handlers; |
| 1364 | − int i, ret = 0, num_handlers; | |
| 1359 | + int i, num_handlers; | |
| 1365 | 1360 | |
| 1366 | − cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL); | |
| 1361 | + cfg_handler = devm_kzalloc(dev->dev, sizeof(*cfg_handler), GFP_KERNEL); | |
| 1367 | 1362 | if (unlikely(!cfg_handler)) { |
| 1368 | − ret = -ENOMEM; | |
| 1369 | − goto fail; | |
| 1363 | + return ERR_PTR(-ENOMEM); | |
| 1370 | 1364 | } |
| 1371 | 1365 | |
| 1372 | 1366 | switch (major) { |
| @@ -1381,8 +1375,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 8 unmodified lines | ||
| 1381 | 1375 | default: |
| 1382 | 1376 | DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n", |
| 1383 | 1377 | major, minor); |
| 1384 | − ret = -ENXIO; | |
| 1385 | − goto fail; | |
| 1378 | + return ERR_PTR(-ENXIO); | |
| 1386 | 1379 | } |
| 1387 | 1380 | |
| 1388 | 1381 | /* only after mdp5_cfg global pointer's init can we access the hw */ |
| @@ -1396,8 +1389,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 7 unmodified lines | ||
| 1396 | 1389 | if (unlikely(!mdp5_cfg)) { |
| 1397 | 1390 | DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n", |
| 1398 | 1391 | major, minor); |
| 1399 | − ret = -ENXIO; | |
| 1400 | − goto fail; | |
| 1392 | + return ERR_PTR(-ENXIO); | |
| 1401 | 1393 | } |
| 1402 | 1394 | |
| 1403 | 1395 | cfg_handler->revision = minor; |
| @@ -1406,10 +1398,4 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 2 unmodified lines | ||
| 1406 | 1398 | DBG("MDP5: %s hw config selected", mdp5_cfg->name); |
| 1407 | 1399 | |
| 1408 | 1400 | return cfg_handler; |
| 1409 | − | |
| 1410 | −fail: | |
| 1411 | − if (cfg_handler) | |
| 1412 | − mdp5_cfg_destroy(cfg_handler); | |
| 1413 | − | |
| 1414 | − return ERR_PTR(ret); | |
| 1415 | 1401 | } |
| @@ -121,6 +121,5 @@ int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd); · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, |
| 123 | 123 | uint32_t major, uint32_t minor); |
| 124 | −void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd); | |
| 125 | 124 | |
| 126 | 125 | #endif /* __MDP5_CFG_H__ */ |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <drm/drm_crtc.h> |
| 14 | 14 | #include <drm/drm_flip_work.h> |
| 15 | 15 | #include <drm/drm_fourcc.h> |
| 16 | +#include <drm/drm_managed.h> | |
| 16 | 17 | #include <drm/drm_probe_helper.h> |
| 17 | 18 | #include <drm/drm_vblank.h> |
| 18 | 19 | |
| @@ -172,14 +173,11 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) · 153 unmodified lines | ||
| 172 | 173 | drm_gem_object_put(val); |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | −static void mdp5_crtc_destroy(struct drm_crtc *crtc) | |
| 176 | +static void mdp5_crtc_flip_cleanup(struct drm_device *dev, void *ptr) | |
| 176 | 177 | { |
| 177 | − struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | |
| 178 | + struct mdp5_crtc *mdp5_crtc = ptr; | |
| 178 | 179 | |
| 179 | − drm_crtc_cleanup(crtc); | |
| 180 | 180 | drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work); |
| 181 | − | |
| 182 | − kfree(mdp5_crtc); | |
| 183 | 181 | } |
| 184 | 182 | |
| 185 | 183 | static inline u32 mdp5_lm_use_fg_alpha_mask(enum mdp_mixer_stage_id stage) |
| @@ -1147,7 +1145,6 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc) · 961 unmodified lines | ||
| 1147 | 1145 | |
| 1148 | 1146 | static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { |
| 1149 | 1147 | .set_config = drm_atomic_helper_set_config, |
| 1150 | − .destroy = mdp5_crtc_destroy, | |
| 1151 | 1148 | .page_flip = drm_atomic_helper_page_flip, |
| 1152 | 1149 | .reset = mdp5_crtc_reset, |
| 1153 | 1150 | .atomic_duplicate_state = mdp5_crtc_duplicate_state, |
| @@ -1161,7 +1158,6 @@ static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { · 7 unmodified lines | ||
| 1161 | 1158 | |
| 1162 | 1159 | static const struct drm_crtc_funcs mdp5_crtc_funcs = { |
| 1163 | 1160 | .set_config = drm_atomic_helper_set_config, |
| 1164 | − .destroy = mdp5_crtc_destroy, | |
| 1165 | 1161 | .page_flip = drm_atomic_helper_page_flip, |
| 1166 | 1162 | .reset = mdp5_crtc_reset, |
| 1167 | 1163 | .atomic_duplicate_state = mdp5_crtc_duplicate_state, |
| @@ -1327,10 +1323,16 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, · 159 unmodified lines | ||
| 1327 | 1323 | { |
| 1328 | 1324 | struct drm_crtc *crtc = NULL; |
| 1329 | 1325 | struct mdp5_crtc *mdp5_crtc; |
| 1326 | + int ret; | |
| 1330 | 1327 | |
| 1331 | − mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL); | |
| 1332 | − if (!mdp5_crtc) | |
| 1333 | − return ERR_PTR(-ENOMEM); | |
| 1328 | + mdp5_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp5_crtc, base, | |
| 1329 | + plane, cursor_plane, | |
| 1330 | + cursor_plane ? | |
| 1331 | + &mdp5_crtc_no_lm_cursor_funcs : | |
| 1332 | + &mdp5_crtc_funcs, | |
| 1333 | + NULL); | |
| 1334 | + if (IS_ERR(mdp5_crtc)) | |
| 1335 | + return ERR_CAST(mdp5_crtc); | |
| 1334 | 1336 | |
| 1335 | 1337 | crtc = &mdp5_crtc->base; |
| 1336 | 1338 | |
| @@ -1346,13 +1348,11 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, · 9 unmodified lines | ||
| 1346 | 1348 | |
| 1347 | 1349 | mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true; |
| 1348 | 1350 | |
| 1349 | − drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane, | |
| 1350 | − cursor_plane ? | |
| 1351 | − &mdp5_crtc_no_lm_cursor_funcs : | |
| 1352 | − &mdp5_crtc_funcs, NULL); | |
| 1353 | − | |
| 1354 | 1351 | drm_flip_work_init(&mdp5_crtc->unref_cursor_work, |
| 1355 | 1352 | "unref cursor", unref_cursor_worker); |
| 1353 | + ret = drmm_add_action_or_reset(dev, mdp5_crtc_flip_cleanup, mdp5_crtc); | |
| 1354 | + if (ret) | |
| 1355 | + return ERR_PTR(ret); | |
| 1356 | 1356 | |
| 1357 | 1357 | drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); |
| 1358 | 1358 | |
| @@ -681,11 +681,6 @@ void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctl_mgr) · 680 unmodified lines | ||
| 681 | 681 | } |
| 682 | 682 | } |
| 683 | 683 | |
| 684 | −void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctl_mgr) | |
| 685 | −{ | |
| 686 | − kfree(ctl_mgr); | |
| 687 | −} | |
| 688 | − | |
| 689 | 684 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, |
| 690 | 685 | void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd) |
| 691 | 686 | { |
| @@ -697,18 +692,16 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 5 unmodified lines | ||
| 697 | 692 | unsigned long flags; |
| 698 | 693 | int c, ret; |
| 699 | 694 | |
| 700 | − ctl_mgr = kzalloc(sizeof(*ctl_mgr), GFP_KERNEL); | |
| 695 | + ctl_mgr = devm_kzalloc(dev->dev, sizeof(*ctl_mgr), GFP_KERNEL); | |
| 701 | 696 | if (!ctl_mgr) { |
| 702 | 697 | DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n"); |
| 703 | − ret = -ENOMEM; | |
| 704 | − goto fail; | |
| 698 | + return ERR_PTR(-ENOMEM); | |
| 705 | 699 | } |
| 706 | 700 | |
| 707 | 701 | if (WARN_ON(ctl_cfg->count > MAX_CTL)) { |
| 708 | 702 | DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n", |
| 709 | 703 | ctl_cfg->count); |
| 710 | − ret = -ENOSPC; | |
| 711 | − goto fail; | |
| 704 | + return ERR_PTR(-ENOSPC); | |
| 712 | 705 | } |
| 713 | 706 | |
| 714 | 707 | /* initialize the CTL manager: */ |
| @@ -727,7 +720,7 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 12 unmodified lines | ||
| 727 | 720 | DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c); |
| 728 | 721 | ret = -EINVAL; |
| 729 | 722 | spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); |
| 730 | − goto fail; | |
| 723 | + return ERR_PTR(ret); | |
| 731 | 724 | } |
| 732 | 725 | ctl->ctlm = ctl_mgr; |
| 733 | 726 | ctl->id = c; |
| @@ -755,10 +748,4 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 21 unmodified lines | ||
| 755 | 748 | DBG("Pool of %d CTLs created.", ctl_mgr->nctl); |
| 756 | 749 | |
| 757 | 750 | return ctl_mgr; |
| 758 | − | |
| 759 | −fail: | |
| 760 | − if (ctl_mgr) | |
| 761 | − mdp5_ctlm_destroy(ctl_mgr); | |
| 762 | − | |
| 763 | − return ERR_PTR(ret); | |
| 764 | 751 | } |
| @@ -17,7 +17,6 @@ struct mdp5_ctl_manager; · 16 unmodified lines | ||
| 17 | 17 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, |
| 18 | 18 | void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd); |
| 19 | 19 | void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctlm); |
| 20 | −void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm); | |
| 21 | 20 | |
| 22 | 21 | /* |
| 23 | 22 | * CTL prototypes: |
| @@ -16,17 +16,6 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder) · 15 unmodified lines | ||
| 16 | 16 | return to_mdp5_kms(to_mdp_kms(priv->kms)); |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | −static void mdp5_encoder_destroy(struct drm_encoder *encoder) | |
| 20 | −{ | |
| 21 | − struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | |
| 22 | − drm_encoder_cleanup(encoder); | |
| 23 | − kfree(mdp5_encoder); | |
| 24 | −} | |
| 25 | − | |
| 26 | −static const struct drm_encoder_funcs mdp5_encoder_funcs = { | |
| 27 | − .destroy = mdp5_encoder_destroy, | |
| 28 | −}; | |
| 29 | − | |
| 30 | 19 | static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, |
| 31 | 20 | struct drm_display_mode *mode, |
| 32 | 21 | struct drm_display_mode *adjusted_mode) |
| @@ -342,13 +331,11 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, · 309 unmodified lines | ||
| 342 | 331 | struct mdp5_encoder *mdp5_encoder; |
| 343 | 332 | int enc_type = (intf->type == INTF_DSI) ? |
| 344 | 333 | DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS; |
| 345 | − int ret; | |
| 346 | 334 | |
| 347 | − mdp5_encoder = kzalloc(sizeof(*mdp5_encoder), GFP_KERNEL); | |
| 348 | − if (!mdp5_encoder) { | |
| 349 | − ret = -ENOMEM; | |
| 350 | − goto fail; | |
| 351 | − } | |
| 335 | + mdp5_encoder = drmm_encoder_alloc(dev, struct mdp5_encoder, base, | |
| 336 | + NULL, enc_type, NULL); | |
| 337 | + if (IS_ERR(mdp5_encoder)) | |
| 338 | + return ERR_CAST(mdp5_encoder); | |
| 352 | 339 | |
| 353 | 340 | encoder = &mdp5_encoder->base; |
| 354 | 341 | mdp5_encoder->ctl = ctl; |
| @@ -356,15 +343,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, · 1 unmodified line | ||
| 356 | 343 | |
| 357 | 344 | spin_lock_init(&mdp5_encoder->intf_lock); |
| 358 | 345 | |
| 359 | − drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type, NULL); | |
| 360 | − | |
| 361 | 346 | drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); |
| 362 | 347 | |
| 363 | 348 | return encoder; |
| 364 | − | |
| 365 | −fail: | |
| 366 | − if (encoder) | |
| 367 | − mdp5_encoder_destroy(encoder); | |
| 368 | − | |
| 369 | − return ERR_PTR(ret); | |
| 370 | 349 | } |
| @@ -209,13 +209,6 @@ static void mdp5_kms_destroy(struct msm_kms *kms) · 208 unmodified lines | ||
| 209 | 209 | { |
| 210 | 210 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
| 211 | 211 | struct msm_gem_address_space *aspace = kms->aspace; |
| 212 | − int i; | |
| 213 | − | |
| 214 | − for (i = 0; i < mdp5_kms->num_hwmixers; i++) | |
| 215 | − mdp5_mixer_destroy(mdp5_kms->hwmixers[i]); | |
| 216 | − | |
| 217 | − for (i = 0; i < mdp5_kms->num_hwpipes; i++) | |
| 218 | − mdp5_pipe_destroy(mdp5_kms->hwpipes[i]); | |
| 219 | 212 | |
| 220 | 213 | if (aspace) { |
| 221 | 214 | aspace->mmu->funcs->detach(aspace->mmu); |
| @@ -623,18 +616,6 @@ fail: · 401 unmodified lines | ||
| 623 | 616 | |
| 624 | 617 | static void mdp5_destroy(struct mdp5_kms *mdp5_kms) |
| 625 | 618 | { |
| 626 | − int i; | |
| 627 | − | |
| 628 | − if (mdp5_kms->ctlm) | |
| 629 | − mdp5_ctlm_destroy(mdp5_kms->ctlm); | |
| 630 | − if (mdp5_kms->smp) | |
| 631 | − mdp5_smp_destroy(mdp5_kms->smp); | |
| 632 | − if (mdp5_kms->cfg) | |
| 633 | − mdp5_cfg_destroy(mdp5_kms->cfg); | |
| 634 | − | |
| 635 | − for (i = 0; i < mdp5_kms->num_intfs; i++) | |
| 636 | − kfree(mdp5_kms->intfs[i]); | |
| 637 | − | |
| 638 | 619 | if (mdp5_kms->rpm_enabled) |
| 639 | 620 | pm_runtime_disable(&mdp5_kms->pdev->dev); |
| 640 | 621 | |
| @@ -652,7 +633,7 @@ static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt, · 11 unmodified lines | ||
| 652 | 633 | for (i = 0; i < cnt; i++) { |
| 653 | 634 | struct mdp5_hw_pipe *hwpipe; |
| 654 | 635 | |
| 655 | − hwpipe = mdp5_pipe_init(pipes[i], offsets[i], caps); | |
| 636 | + hwpipe = mdp5_pipe_init(dev, pipes[i], offsets[i], caps); | |
| 656 | 637 | if (IS_ERR(hwpipe)) { |
| 657 | 638 | ret = PTR_ERR(hwpipe); |
| 658 | 639 | DRM_DEV_ERROR(dev->dev, "failed to construct pipe for %s (%d)\n", |
| @@ -724,7 +705,7 @@ static int hwmixer_init(struct mdp5_kms *mdp5_kms) · 65 unmodified lines | ||
| 724 | 705 | for (i = 0; i < hw_cfg->lm.count; i++) { |
| 725 | 706 | struct mdp5_hw_mixer *mixer; |
| 726 | 707 | |
| 727 | − mixer = mdp5_mixer_init(&hw_cfg->lm.instances[i]); | |
| 708 | + mixer = mdp5_mixer_init(dev, &hw_cfg->lm.instances[i]); | |
| 728 | 709 | if (IS_ERR(mixer)) { |
| 729 | 710 | ret = PTR_ERR(mixer); |
| 730 | 711 | DRM_DEV_ERROR(dev->dev, "failed to construct LM%d (%d)\n", |
| @@ -755,7 +736,7 @@ static int interface_init(struct mdp5_kms *mdp5_kms) · 24 unmodified lines | ||
| 755 | 736 | if (intf_types[i] == INTF_DISABLED) |
| 756 | 737 | continue; |
| 757 | 738 | |
| 758 | − intf = kzalloc(sizeof(*intf), GFP_KERNEL); | |
| 739 | + intf = devm_kzalloc(dev->dev, sizeof(*intf), GFP_KERNEL); | |
| 759 | 740 | if (!intf) { |
| 760 | 741 | DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i); |
| 761 | 742 | return -ENOMEM; |
| @@ -140,20 +140,16 @@ int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) · 139 unmodified lines | ||
| 140 | 140 | return 0; |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | −void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer) | |
| 144 | −{ | |
| 145 | − kfree(mixer); | |
| 146 | −} | |
| 147 | − | |
| 148 | 143 | static const char * const mixer_names[] = { |
| 149 | 144 | "LM0", "LM1", "LM2", "LM3", "LM4", "LM5", |
| 150 | 145 | }; |
| 151 | 146 | |
| 152 | −struct mdp5_hw_mixer *mdp5_mixer_init(const struct mdp5_lm_instance *lm) | |
| 147 | +struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev, | |
| 148 | + const struct mdp5_lm_instance *lm) | |
| 153 | 149 | { |
| 154 | 150 | struct mdp5_hw_mixer *mixer; |
| 155 | 151 | |
| 156 | − mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); | |
| 152 | + mixer = devm_kzalloc(dev->dev, sizeof(*mixer), GFP_KERNEL); | |
| 157 | 153 | if (!mixer) |
| 158 | 154 | return ERR_PTR(-ENOMEM); |
| 159 | 155 | |
| @@ -25,8 +25,8 @@ struct mdp5_hw_mixer_state { · 24 unmodified lines | ||
| 25 | 25 | struct drm_crtc *hwmixer_to_crtc[8]; |
| 26 | 26 | }; |
| 27 | 27 | |
| 28 | −struct mdp5_hw_mixer *mdp5_mixer_init(const struct mdp5_lm_instance *lm); | |
| 29 | −void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm); | |
| 28 | +struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev, | |
| 29 | + const struct mdp5_lm_instance *lm); | |
| 30 | 30 | int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, |
| 31 | 31 | uint32_t caps, struct mdp5_hw_mixer **mixer, |
| 32 | 32 | struct mdp5_hw_mixer **r_mixer); |
| @@ -151,17 +151,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) · 150 unmodified lines | ||
| 151 | 151 | return 0; |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | −void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) | |
| 155 | −{ | |
| 156 | − kfree(hwpipe); | |
| 157 | −} | |
| 158 | − | |
| 159 | −struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, | |
| 154 | +struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev, | |
| 155 | + enum mdp5_pipe pipe, | |
| 160 | 156 | uint32_t reg_offset, uint32_t caps) |
| 161 | 157 | { |
| 162 | 158 | struct mdp5_hw_pipe *hwpipe; |
| 163 | 159 | |
| 164 | − hwpipe = kzalloc(sizeof(*hwpipe), GFP_KERNEL); | |
| 160 | + hwpipe = devm_kzalloc(dev->dev, sizeof(*hwpipe), GFP_KERNEL); | |
| 165 | 161 | if (!hwpipe) |
| 166 | 162 | return ERR_PTR(-ENOMEM); |
| 167 | 163 | |
| @@ -39,8 +39,8 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, · 38 unmodified lines | ||
| 39 | 39 | struct mdp5_hw_pipe **r_hwpipe); |
| 40 | 40 | int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); |
| 41 | 41 | |
| 42 | −struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, | |
| 42 | +struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev, | |
| 43 | + enum mdp5_pipe pipe, | |
| 43 | 44 | uint32_t reg_offset, uint32_t caps); |
| 44 | −void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe); | |
| 45 | 45 | |
| 46 | 46 | #endif /* __MDP5_PIPE_H__ */ |
| @@ -370,23 +370,17 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p) · 369 unmodified lines | ||
| 370 | 370 | drm_modeset_unlock(&mdp5_kms->glob_state_lock); |
| 371 | 371 | } |
| 372 | 372 | |
| 373 | −void mdp5_smp_destroy(struct mdp5_smp *smp) | |
| 374 | −{ | |
| 375 | − kfree(smp); | |
| 376 | −} | |
| 377 | 373 | |
| 378 | 374 | struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_block *cfg) |
| 379 | 375 | { |
| 376 | + struct drm_device *dev = mdp5_kms->dev; | |
| 380 | 377 | struct mdp5_smp_state *state; |
| 381 | 378 | struct mdp5_global_state *global_state; |
| 382 | 379 | struct mdp5_smp *smp; |
| 383 | − int ret; | |
| 384 | 380 | |
| 385 | − smp = kzalloc(sizeof(*smp), GFP_KERNEL); | |
| 386 | − if (unlikely(!smp)) { | |
| 387 | − ret = -ENOMEM; | |
| 388 | − goto fail; | |
| 389 | − } | |
| 381 | + smp = devm_kzalloc(dev->dev, sizeof(*smp), GFP_KERNEL); | |
| 382 | + if (unlikely(!smp)) | |
| 383 | + return ERR_PTR(-ENOMEM); | |
| 390 | 384 | |
| 391 | 385 | smp->dev = mdp5_kms->dev; |
| 392 | 386 | smp->blk_cnt = cfg->mmb_count; |
| @@ -400,9 +394,4 @@ struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_ · 7 unmodified lines | ||
| 400 | 394 | memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved)); |
| 401 | 395 | |
| 402 | 396 | return smp; |
| 403 | −fail: | |
| 404 | − if (smp) | |
| 405 | − mdp5_smp_destroy(smp); | |
| 406 | − | |
| 407 | − return ERR_PTR(ret); | |
| 408 | 397 | } |
| @@ -68,7 +68,6 @@ struct mdp5_smp; · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, |
| 70 | 70 | const struct mdp5_smp_block *cfg); |
| 71 | −void mdp5_smp_destroy(struct mdp5_smp *smp); | |
| 72 | 71 | |
| 73 | 72 | void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p); |
| 74 | 73 | |
| @@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 290 unmodified lines | ||
| 291 | 291 | return -EINVAL; |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | + ret = pm_runtime_resume_and_get(dp_aux->dev); | |
| 295 | + if (ret) | |
| 296 | + return ret; | |
| 297 | + | |
| 294 | 298 | mutex_lock(&aux->mutex); |
| 295 | 299 | if (!aux->initted) { |
| 296 | 300 | ret = -EIO; |
| @@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 67 unmodified lines | ||
| 364 | 368 | |
| 365 | 369 | exit: |
| 366 | 370 | mutex_unlock(&aux->mutex); |
| 371 | + pm_runtime_put_sync(dp_aux->dev); | |
| 367 | 372 | |
| 368 | 373 | return ret; |
| 369 | 374 | } |
| @@ -474,7 +479,6 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux) · 104 unmodified lines | ||
| 474 | 479 | |
| 475 | 480 | int dp_aux_register(struct drm_dp_aux *dp_aux) |
| 476 | 481 | { |
| 477 | − struct dp_aux_private *aux; | |
| 478 | 482 | int ret; |
| 479 | 483 | |
| 480 | 484 | if (!dp_aux) { |
| @@ -482,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux) · 1 unmodified line | ||
| 482 | 486 | return -EINVAL; |
| 483 | 487 | } |
| 484 | 488 | |
| 485 | − aux = container_of(dp_aux, struct dp_aux_private, dp_aux); | |
| 486 | − | |
| 487 | − aux->dp_aux.name = "dpu_dp_aux"; | |
| 488 | − aux->dp_aux.dev = aux->dev; | |
| 489 | − aux->dp_aux.transfer = dp_aux_transfer; | |
| 490 | − ret = drm_dp_aux_register(&aux->dp_aux); | |
| 489 | + ret = drm_dp_aux_register(dp_aux); | |
| 491 | 490 | if (ret) { |
| 492 | 491 | DRM_ERROR("%s: failed to register drm aux: %d\n", __func__, |
| 493 | 492 | ret); |
| @@ -502,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux) · 8 unmodified lines | ||
| 502 | 501 | drm_dp_aux_unregister(dp_aux); |
| 503 | 502 | } |
| 504 | 503 | |
| 504 | +static int dp_wait_hpd_asserted(struct drm_dp_aux *dp_aux, | |
| 505 | + unsigned long wait_us) | |
| 506 | +{ | |
| 507 | + int ret; | |
| 508 | + struct dp_aux_private *aux; | |
| 509 | + | |
| 510 | + aux = container_of(dp_aux, struct dp_aux_private, dp_aux); | |
| 511 | + | |
| 512 | + pm_runtime_get_sync(aux->dev); | |
| 513 | + ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog); | |
| 514 | + pm_runtime_put_sync(aux->dev); | |
| 515 | + | |
| 516 | + return ret; | |
| 517 | +} | |
| 518 | + | |
| 505 | 519 | struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, |
| 506 | 520 | bool is_edp) |
| 507 | 521 | { |
| @@ -525,6 +539,17 @@ struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, · 17 unmodified lines | ||
| 525 | 539 | aux->catalog = catalog; |
| 526 | 540 | aux->retry_cnt = 0; |
| 527 | 541 | |
| 542 | + /* | |
| 543 | + * Use the drm_dp_aux_init() to use the aux adapter | |
| 544 | + * before registering AUX with the DRM device so that | |
| 545 | + * msm eDP panel can be detected by generic_dep_panel_probe(). | |
| 546 | + */ | |
| 547 | + aux->dp_aux.name = "dpu_dp_aux"; | |
| 548 | + aux->dp_aux.dev = dev; | |
| 549 | + aux->dp_aux.transfer = dp_aux_transfer; | |
| 550 | + aux->dp_aux.wait_hpd_asserted = dp_wait_hpd_asserted; | |
| 551 | + drm_dp_aux_init(&aux->dp_aux); | |
| 552 | + | |
| 528 | 553 | return &aux->dp_aux; |
| 529 | 554 | } |
| 530 | 555 | |
| @@ -19,13 +19,9 @@ · 18 unmodified lines | ||
| 19 | 19 | #define DEBUG_NAME "msm_dp" |
| 20 | 20 | |
| 21 | 21 | struct dp_debug_private { |
| 22 | − struct dentry *root; | |
| 23 | − | |
| 24 | 22 | struct dp_link *link; |
| 25 | 23 | struct dp_panel *panel; |
| 26 | 24 | struct drm_connector *connector; |
| 27 | − struct device *dev; | |
| 28 | − struct drm_device *drm_dev; | |
| 29 | 25 | |
| 30 | 26 | struct dp_debug dp_debug; |
| 31 | 27 | }; |
| @@ -204,35 +200,33 @@ static const struct file_operations test_active_fops = { · 172 unmodified lines | ||
| 204 | 200 | .write = dp_test_active_write |
| 205 | 201 | }; |
| 206 | 202 | |
| 207 | −static void dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor) | |
| 203 | +static void dp_debug_init(struct dp_debug *dp_debug, struct dentry *root, bool is_edp) | |
| 208 | 204 | { |
| 209 | − char path[64]; | |
| 210 | 205 | struct dp_debug_private *debug = container_of(dp_debug, |
| 211 | 206 | struct dp_debug_private, dp_debug); |
| 212 | 207 | |
| 213 | − snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name); | |
| 214 | − | |
| 215 | − debug->root = debugfs_create_dir(path, minor->debugfs_root); | |
| 216 | − | |
| 217 | − debugfs_create_file("dp_debug", 0444, debug->root, | |
| 208 | + debugfs_create_file("dp_debug", 0444, root, | |
| 218 | 209 | debug, &dp_debug_fops); |
| 219 | 210 | |
| 220 | − debugfs_create_file("msm_dp_test_active", 0444, | |
| 221 | − debug->root, | |
| 222 | − debug, &test_active_fops); | |
| 211 | + if (!is_edp) { | |
| 212 | + debugfs_create_file("msm_dp_test_active", 0444, | |
| 213 | + root, | |
| 214 | + debug, &test_active_fops); | |
| 223 | 215 | |
| 224 | − debugfs_create_file("msm_dp_test_data", 0444, | |
| 225 | − debug->root, | |
| 226 | − debug, &dp_test_data_fops); | |
| 216 | + debugfs_create_file("msm_dp_test_data", 0444, | |
| 217 | + root, | |
| 218 | + debug, &dp_test_data_fops); | |
| 227 | 219 | |
| 228 | − debugfs_create_file("msm_dp_test_type", 0444, | |
| 229 | − debug->root, | |
| 230 | − debug, &dp_test_type_fops); | |
| 220 | + debugfs_create_file("msm_dp_test_type", 0444, | |
| 221 | + root, | |
| 222 | + debug, &dp_test_type_fops); | |
| 223 | + } | |
| 231 | 224 | } |
| 232 | 225 | |
| 233 | 226 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 234 | 227 | struct dp_link *link, |
| 235 | − struct drm_connector *connector, struct drm_minor *minor) | |
| 228 | + struct drm_connector *connector, | |
| 229 | + struct dentry *root, bool is_edp) | |
| 236 | 230 | { |
| 237 | 231 | struct dp_debug_private *debug; |
| 238 | 232 | struct dp_debug *dp_debug; |
| @@ -253,46 +247,15 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, · 14 unmodified lines | ||
| 253 | 247 | debug->dp_debug.debug_en = false; |
| 254 | 248 | debug->link = link; |
| 255 | 249 | debug->panel = panel; |
| 256 | − debug->dev = dev; | |
| 257 | − debug->drm_dev = minor->dev; | |
| 258 | − debug->connector = connector; | |
| 259 | 250 | |
| 260 | 251 | dp_debug = &debug->dp_debug; |
| 261 | 252 | dp_debug->vdisplay = 0; |
| 262 | 253 | dp_debug->hdisplay = 0; |
| 263 | 254 | dp_debug->vrefresh = 0; |
| 264 | 255 | |
| 265 | − dp_debug_init(dp_debug, minor); | |
| 256 | + dp_debug_init(dp_debug, root, is_edp); | |
| 266 | 257 | |
| 267 | 258 | return dp_debug; |
| 268 | 259 | error: |
| 269 | 260 | return ERR_PTR(rc); |
| 270 | 261 | } |
| 271 | − | |
| 272 | −static int dp_debug_deinit(struct dp_debug *dp_debug) | |
| 273 | −{ | |
| 274 | − struct dp_debug_private *debug; | |
| 275 | − | |
| 276 | − if (!dp_debug) | |
| 277 | − return -EINVAL; | |
| 278 | − | |
| 279 | − debug = container_of(dp_debug, struct dp_debug_private, dp_debug); | |
| 280 | − | |
| 281 | − debugfs_remove_recursive(debug->root); | |
| 282 | − | |
| 283 | − return 0; | |
| 284 | −} | |
| 285 | − | |
| 286 | −void dp_debug_put(struct dp_debug *dp_debug) | |
| 287 | −{ | |
| 288 | − struct dp_debug_private *debug; | |
| 289 | − | |
| 290 | − if (!dp_debug) | |
| 291 | − return; | |
| 292 | − | |
| 293 | − debug = container_of(dp_debug, struct dp_debug_private, dp_debug); | |
| 294 | − | |
| 295 | − dp_debug_deinit(dp_debug); | |
| 296 | − | |
| 297 | − devm_kfree(debug->dev, debug); | |
| 298 | −} | |
| @@ -34,7 +34,8 @@ struct dp_debug { · 33 unmodified lines | ||
| 34 | 34 | * @panel: instance of panel module |
| 35 | 35 | * @link: instance of link module |
| 36 | 36 | * @connector: double pointer to display connector |
| 37 | − * @minor: pointer to drm minor number after device registration | |
| 37 | + * @root: connector's debugfs root | |
| 38 | + * @is_edp: set for eDP connectors / panels | |
| 38 | 39 | * return: pointer to allocated debug module data |
| 39 | 40 | * |
| 40 | 41 | * This function sets up the debug module and provides a way |
| @@ -43,31 +44,21 @@ struct dp_debug { · 2 unmodified lines | ||
| 43 | 44 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 44 | 45 | struct dp_link *link, |
| 45 | 46 | struct drm_connector *connector, |
| 46 | − struct drm_minor *minor); | |
| 47 | − | |
| 48 | −/** | |
| 49 | − * dp_debug_put() | |
| 50 | − * | |
| 51 | − * Cleans up dp_debug instance | |
| 52 | − * | |
| 53 | − * @dp_debug: instance of dp_debug | |
| 54 | − */ | |
| 55 | −void dp_debug_put(struct dp_debug *dp_debug); | |
| 47 | + struct dentry *root, | |
| 48 | + bool is_edp); | |
| 56 | 49 | |
| 57 | 50 | #else |
| 58 | 51 | |
| 59 | 52 | static inline |
| 60 | 53 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 61 | 54 | struct dp_link *link, |
| 62 | − struct drm_connector *connector, struct drm_minor *minor) | |
| 55 | + struct drm_connector *connector, | |
| 56 | + struct dentry *root, | |
| 57 | + bool is_edp) | |
| 63 | 58 | { |
| 64 | 59 | return ERR_PTR(-EINVAL); |
| 65 | 60 | } |
| 66 | 61 | |
| 67 | −static inline void dp_debug_put(struct dp_debug *dp_debug) | |
| 68 | −{ | |
| 69 | −} | |
| 70 | − | |
| 71 | 62 | #endif /* defined(CONFIG_DEBUG_FS) */ |
| 72 | 63 | |
| 73 | 64 | #endif /* _DP_DEBUG_H_ */ |
| @@ -49,13 +49,11 @@ enum { · 48 unmodified lines | ||
| 49 | 49 | ST_CONNECTED, |
| 50 | 50 | ST_DISCONNECT_PENDING, |
| 51 | 51 | ST_DISPLAY_OFF, |
| 52 | − ST_SUSPENDED, | |
| 53 | 52 | }; |
| 54 | 53 | |
| 55 | 54 | enum { |
| 56 | 55 | EV_NO_EVENT, |
| 57 | 56 | /* hpd events */ |
| 58 | − EV_HPD_INIT_SETUP, | |
| 59 | 57 | EV_HPD_PLUG_INT, |
| 60 | 58 | EV_IRQ_HPD_INT, |
| 61 | 59 | EV_HPD_UNPLUG_INT, |
| @@ -170,6 +168,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = { · 108 unmodified lines | ||
| 170 | 168 | {} |
| 171 | 169 | }; |
| 172 | 170 | |
| 171 | +static const struct msm_dp_desc sm8650_dp_descs[] = { | |
| 172 | + { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, | |
| 173 | + {} | |
| 174 | +}; | |
| 175 | + | |
| 173 | 176 | static const struct of_device_id dp_dt_match[] = { |
| 174 | 177 | { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, |
| 175 | 178 | { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, |
| @@ -180,6 +183,7 @@ static const struct of_device_id dp_dt_match[] = { · 4 unmodified lines | ||
| 180 | 183 | { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, |
| 181 | 184 | { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, |
| 182 | 185 | { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs }, |
| 186 | + { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, | |
| 183 | 187 | {} |
| 184 | 188 | }; |
| 185 | 189 | |
| @@ -275,11 +279,6 @@ static int dp_display_bind(struct device *dev, struct device *master, · 89 unmodified lines | ||
| 275 | 279 | dp->dp_display.drm_dev = drm; |
| 276 | 280 | priv->dp[dp->id] = &dp->dp_display; |
| 277 | 281 | |
| 278 | − rc = dp->parser->parse(dp->parser); | |
| 279 | − if (rc) { | |
| 280 | − DRM_ERROR("device tree parsing failed\n"); | |
| 281 | − goto end; | |
| 282 | − } | |
| 283 | 282 | |
| 284 | 283 | |
| 285 | 284 | dp->drm_dev = drm; |
| @@ -290,11 +289,6 @@ static int dp_display_bind(struct device *dev, struct device *master, · 4 unmodified lines | ||
| 290 | 289 | goto end; |
| 291 | 290 | } |
| 292 | 291 | |
| 293 | − rc = dp_power_client_init(dp->power); | |
| 294 | − if (rc) { | |
| 295 | − DRM_ERROR("Power client create failed\n"); | |
| 296 | − goto end; | |
| 297 | − } | |
| 298 | 292 | |
| 299 | 293 | rc = dp_register_audio_driver(dev, dp->audio); |
| 300 | 294 | if (rc) { |
| @@ -319,15 +313,10 @@ static void dp_display_unbind(struct device *dev, struct device *master, · 18 unmodified lines | ||
| 319 | 313 | struct dp_display_private *dp = dev_get_dp_display_private(dev); |
| 320 | 314 | struct msm_drm_private *priv = dev_get_drvdata(master); |
| 321 | 315 | |
| 322 | − /* disable all HPD interrupts */ | |
| 323 | − if (dp->core_initialized) | |
| 324 | − dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); | |
| 325 | − | |
| 326 | 316 | kthread_stop(dp->ev_tsk); |
| 327 | 317 | |
| 328 | 318 | of_dp_aux_depopulate_bus(dp->aux); |
| 329 | 319 | |
| 330 | − dp_power_client_deinit(dp->power); | |
| 331 | 320 | dp_unregister_audio_driver(dev, dp->audio); |
| 332 | 321 | dp_aux_unregister(dp->aux); |
| 333 | 322 | dp->drm_dev = NULL; |
| @@ -340,27 +329,10 @@ static const struct component_ops dp_display_comp_ops = { · 6 unmodified lines | ||
| 340 | 329 | .unbind = dp_display_unbind, |
| 341 | 330 | }; |
| 342 | 331 | |
| 343 | −static void dp_display_send_hpd_event(struct msm_dp *dp_display) | |
| 344 | −{ | |
| 345 | − struct dp_display_private *dp; | |
| 346 | − struct drm_connector *connector; | |
| 347 | − | |
| 348 | − dp = container_of(dp_display, struct dp_display_private, dp_display); | |
| 349 | − | |
| 350 | − connector = dp->dp_display.connector; | |
| 351 | − drm_helper_hpd_irq_event(connector->dev); | |
| 352 | −} | |
| 353 | − | |
| 354 | − | |
| 355 | 332 | static int dp_display_send_hpd_notification(struct dp_display_private *dp, |
| 356 | 333 | bool hpd) |
| 357 | 334 | { |
| 358 | − if ((hpd && dp->dp_display.is_connected) || | |
| 359 | − (!hpd && !dp->dp_display.is_connected)) { | |
| 360 | − drm_dbg_dp(dp->drm_dev, "HPD already %s\n", | |
| 361 | − (hpd ? "on" : "off")); | |
| 362 | − return 0; | |
| 363 | − } | |
| 335 | + struct drm_bridge *bridge = dp->dp_display.bridge; | |
| 364 | 336 | |
| 365 | 337 | /* reset video pattern flag on disconnect */ |
| 366 | 338 | if (!hpd) { |
| @@ -372,11 +344,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, · 5 unmodified lines | ||
| 372 | 344 | dp->panel->downstream_ports); |
| 373 | 345 | } |
| 374 | 346 | |
| 375 | − dp->dp_display.is_connected = hpd; | |
| 347 | + dp->dp_display.link_ready = hpd; | |
| 376 | 348 | |
| 377 | 349 | drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n", |
| 378 | 350 | dp->dp_display.connector_type, hpd); |
| 379 | − dp_display_send_hpd_event(&dp->dp_display); | |
| 351 | + drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready); | |
| 380 | 352 | |
| 381 | 353 | return 0; |
| 382 | 354 | } |
| @@ -575,6 +547,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 192 unmodified lines | ||
| 575 | 547 | { |
| 576 | 548 | u32 state; |
| 577 | 549 | int ret; |
| 550 | + struct platform_device *pdev = dp->dp_display.pdev; | |
| 578 | 551 | |
| 579 | 552 | mutex_lock(&dp->event_mutex); |
| 580 | 553 | |
| @@ -582,7 +555,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 1 unmodified line | ||
| 582 | 555 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", |
| 583 | 556 | dp->dp_display.connector_type, state); |
| 584 | 557 | |
| 585 | − if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { | |
| 558 | + if (state == ST_DISPLAY_OFF) { | |
| 586 | 559 | mutex_unlock(&dp->event_mutex); |
| 587 | 560 | return 0; |
| 588 | 561 | } |
| @@ -599,7 +572,14 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 10 unmodified lines | ||
| 599 | 572 | return 0; |
| 600 | 573 | } |
| 601 | 574 | |
| 602 | − ret = dp_display_usbpd_configure_cb(&dp->dp_display.pdev->dev); | |
| 575 | + ret = pm_runtime_resume_and_get(&pdev->dev); | |
| 576 | + if (ret) { | |
| 577 | + DRM_ERROR("failed to pm_runtime_resume\n"); | |
| 578 | + mutex_unlock(&dp->event_mutex); | |
| 579 | + return ret; | |
| 580 | + } | |
| 581 | + | |
| 582 | + ret = dp_display_usbpd_configure_cb(&pdev->dev); | |
| 603 | 583 | if (ret) { /* link train failed */ |
| 604 | 584 | dp->hpd_state = ST_DISCONNECTED; |
| 605 | 585 | } else { |
| @@ -631,6 +611,7 @@ static void dp_display_handle_plugged_change(struct msm_dp *dp_display, · 25 unmodified lines | ||
| 631 | 611 | static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) |
| 632 | 612 | { |
| 633 | 613 | u32 state; |
| 614 | + struct platform_device *pdev = dp->dp_display.pdev; | |
| 634 | 615 | |
| 635 | 616 | mutex_lock(&dp->event_mutex); |
| 636 | 617 | |
| @@ -681,6 +662,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) · 44 unmodified lines | ||
| 681 | 662 | dp->dp_display.connector_type, state); |
| 682 | 663 | |
| 683 | 664 | /* uevent will complete disconnection part */ |
| 665 | + pm_runtime_put_sync(&pdev->dev); | |
| 684 | 666 | mutex_unlock(&dp->event_mutex); |
| 685 | 667 | return 0; |
| 686 | 668 | } |
| @@ -696,7 +678,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 9 unmodified lines | ||
| 696 | 678 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", |
| 697 | 679 | dp->dp_display.connector_type, state); |
| 698 | 680 | |
| 699 | − if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) { | |
| 681 | + if (state == ST_DISPLAY_OFF) { | |
| 700 | 682 | mutex_unlock(&dp->event_mutex); |
| 701 | 683 | return 0; |
| 702 | 684 | } |
| @@ -720,7 +702,6 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 17 unmodified lines | ||
| 720 | 702 | |
| 721 | 703 | static void dp_display_deinit_sub_modules(struct dp_display_private *dp) |
| 722 | 704 | { |
| 723 | − dp_debug_put(dp->debug); | |
| 724 | 705 | dp_audio_put(dp->audio); |
| 725 | 706 | dp_panel_put(dp->panel); |
| 726 | 707 | dp_aux_put(dp->aux); |
| @@ -918,7 +899,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display, · 191 unmodified lines | ||
| 918 | 899 | |
| 919 | 900 | dp_display->plugged_cb = fn; |
| 920 | 901 | dp_display->codec_dev = codec_dev; |
| 921 | − plugged = dp_display->is_connected; | |
| 902 | + plugged = dp_display->link_ready; | |
| 922 | 903 | dp_display_handle_plugged_change(dp_display, plugged); |
| 923 | 904 | |
| 924 | 905 | return 0; |
| @@ -1108,9 +1089,6 @@ static int hpd_event_thread(void *data) · 183 unmodified lines | ||
| 1108 | 1089 | spin_unlock_irqrestore(&dp_priv->event_lock, flag); |
| 1109 | 1090 | |
| 1110 | 1091 | switch (todo->event_id) { |
| 1111 | − case EV_HPD_INIT_SETUP: | |
| 1112 | − dp_display_host_init(dp_priv); | |
| 1113 | − break; | |
| 1114 | 1092 | case EV_HPD_PLUG_INT: |
| 1115 | 1093 | dp_hpd_plug_handle(dp_priv, todo->data); |
| 1116 | 1094 | break; |
| @@ -1189,27 +1167,21 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) · 72 unmodified lines | ||
| 1189 | 1167 | return ret; |
| 1190 | 1168 | } |
| 1191 | 1169 | |
| 1192 | −int dp_display_request_irq(struct msm_dp *dp_display) | |
| 1170 | +static int dp_display_request_irq(struct dp_display_private *dp) | |
| 1193 | 1171 | { |
| 1194 | 1172 | int rc = 0; |
| 1195 | − struct dp_display_private *dp; | |
| 1196 | − | |
| 1197 | − if (!dp_display) { | |
| 1198 | − DRM_ERROR("invalid input\n"); | |
| 1199 | − return -EINVAL; | |
| 1200 | − } | |
| 1173 | + struct platform_device *pdev = dp->dp_display.pdev; | |
| 1201 | 1174 | |
| 1202 | − dp = container_of(dp_display, struct dp_display_private, dp_display); | |
| 1203 | − | |
| 1204 | − dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0); | |
| 1205 | − if (!dp->irq) { | |
| 1175 | + dp->irq = platform_get_irq(pdev, 0); | |
| 1176 | + if (dp->irq < 0) { | |
| 1206 | 1177 | DRM_ERROR("failed to get irq\n"); |
| 1207 | − return -EINVAL; | |
| 1178 | + return dp->irq; | |
| 1208 | 1179 | } |
| 1209 | 1180 | |
| 1210 | − rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq, | |
| 1211 | − dp_display_irq_handler, | |
| 1212 | − IRQF_TRIGGER_HIGH, "dp_display_isr", dp); | |
| 1181 | + rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler, | |
| 1182 | + IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN, | |
| 1183 | + "dp_display_isr", dp); | |
| 1184 | + | |
| 1213 | 1185 | if (rc < 0) { |
| 1214 | 1186 | DRM_ERROR("failed to request IRQ%u: %d\n", |
| 1215 | 1187 | dp->irq, rc); |
| @@ -1238,6 +1210,29 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde · 22 unmodified lines | ||
| 1238 | 1210 | return NULL; |
| 1239 | 1211 | } |
| 1240 | 1212 | |
| 1213 | +static int dp_display_get_next_bridge(struct msm_dp *dp); | |
| 1214 | + | |
| 1215 | +static int dp_display_probe_tail(struct device *dev) | |
| 1216 | +{ | |
| 1217 | + struct msm_dp *dp = dev_get_drvdata(dev); | |
| 1218 | + int ret; | |
| 1219 | + | |
| 1220 | + ret = dp_display_get_next_bridge(dp); | |
| 1221 | + if (ret) | |
| 1222 | + return ret; | |
| 1223 | + | |
| 1224 | + ret = component_add(dev, &dp_display_comp_ops); | |
| 1225 | + if (ret) | |
| 1226 | + DRM_ERROR("component add failed, rc=%d\n", ret); | |
| 1227 | + | |
| 1228 | + return ret; | |
| 1229 | +} | |
| 1230 | + | |
| 1231 | +static int dp_auxbus_done_probe(struct drm_dp_aux *aux) | |
| 1232 | +{ | |
| 1233 | + return dp_display_probe_tail(aux->dev); | |
| 1234 | +} | |
| 1235 | + | |
| 1241 | 1236 | static int dp_display_probe(struct platform_device *pdev) |
| 1242 | 1237 | { |
| 1243 | 1238 | int rc = 0; |
| @@ -1271,6 +1266,18 @@ static int dp_display_probe(struct platform_device *pdev) · 27 unmodified lines | ||
| 1271 | 1266 | return -EPROBE_DEFER; |
| 1272 | 1267 | } |
| 1273 | 1268 | |
| 1269 | + rc = dp->parser->parse(dp->parser); | |
| 1270 | + if (rc) { | |
| 1271 | + DRM_ERROR("device tree parsing failed\n"); | |
| 1272 | + goto err; | |
| 1273 | + } | |
| 1274 | + | |
| 1275 | + rc = dp_power_client_init(dp->power); | |
| 1276 | + if (rc) { | |
| 1277 | + DRM_ERROR("Power client create failed\n"); | |
| 1278 | + goto err; | |
| 1279 | + } | |
| 1280 | + | |
| 1274 | 1281 | /* setup event q */ |
| 1275 | 1282 | mutex_init(&dp->event_mutex); |
| 1276 | 1283 | init_waitqueue_head(&dp->event_q); |
| @@ -1283,13 +1290,31 @@ static int dp_display_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 1283 | 1290 | |
| 1284 | 1291 | platform_set_drvdata(pdev, &dp->dp_display); |
| 1285 | 1292 | |
| 1286 | − rc = component_add(&pdev->dev, &dp_display_comp_ops); | |
| 1287 | − if (rc) { | |
| 1288 | − DRM_ERROR("component add failed, rc=%d\n", rc); | |
| 1289 | − dp_display_deinit_sub_modules(dp); | |
| 1293 | + rc = devm_pm_runtime_enable(&pdev->dev); | |
| 1294 | + if (rc) | |
| 1295 | + goto err; | |
| 1296 | + | |
| 1297 | + rc = dp_display_request_irq(dp); | |
| 1298 | + if (rc) | |
| 1299 | + goto err; | |
| 1300 | + | |
| 1301 | + if (dp->dp_display.is_edp) { | |
| 1302 | + rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe); | |
| 1303 | + if (rc) { | |
| 1304 | + DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc); | |
| 1305 | + goto err; | |
| 1306 | + } | |
| 1307 | + } else { | |
| 1308 | + rc = dp_display_probe_tail(&pdev->dev); | |
| 1309 | + if (rc) | |
| 1310 | + goto err; | |
| 1290 | 1311 | } |
| 1291 | 1312 | |
| 1292 | 1313 | return rc; |
| 1314 | + | |
| 1315 | +err: | |
| 1316 | + dp_display_deinit_sub_modules(dp); | |
| 1317 | + return rc; | |
| 1293 | 1318 | } |
| 1294 | 1319 | |
| 1295 | 1320 | static void dp_display_remove(struct platform_device *pdev) |
| @@ -1298,113 +1323,50 @@ static void dp_display_remove(struct platform_device *pdev) · 2 unmodified lines | ||
| 1298 | 1323 | |
| 1299 | 1324 | component_del(&pdev->dev, &dp_display_comp_ops); |
| 1300 | 1325 | dp_display_deinit_sub_modules(dp); |
| 1301 | − | |
| 1302 | 1326 | platform_set_drvdata(pdev, NULL); |
| 1303 | 1327 | } |
| 1304 | 1328 | |
| 1305 | −static int dp_pm_resume(struct device *dev) | |
| 1329 | +static int dp_pm_runtime_suspend(struct device *dev) | |
| 1306 | 1330 | { |
| 1307 | − struct platform_device *pdev = to_platform_device(dev); | |
| 1308 | − struct msm_dp *dp_display = platform_get_drvdata(pdev); | |
| 1309 | − struct dp_display_private *dp; | |
| 1310 | − int sink_count = 0; | |
| 1311 | − | |
| 1312 | − dp = container_of(dp_display, struct dp_display_private, dp_display); | |
| 1313 | − | |
| 1314 | − mutex_lock(&dp->event_mutex); | |
| 1315 | − | |
| 1316 | − drm_dbg_dp(dp->drm_dev, | |
| 1317 | − "Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", | |
| 1318 | − dp->dp_display.connector_type, dp->core_initialized, | |
| 1319 | − dp->phy_initialized, dp_display->power_on); | |
| 1320 | − | |
| 1321 | − /* start from disconnected state */ | |
| 1322 | − dp->hpd_state = ST_DISCONNECTED; | |
| 1323 | − | |
| 1324 | − /* turn on dp ctrl/phy */ | |
| 1325 | − dp_display_host_init(dp); | |
| 1326 | − | |
| 1327 | − if (dp_display->is_edp) | |
| 1328 | − dp_catalog_ctrl_hpd_enable(dp->catalog); | |
| 1331 | + struct dp_display_private *dp = dev_get_dp_display_private(dev); | |
| 1329 | 1332 | |
| 1330 | − if (dp_catalog_link_is_connected(dp->catalog)) { | |
| 1331 | − /* | |
| 1332 | − * set sink to normal operation mode -- D0 | |
| 1333 | − * before dpcd read | |
| 1334 | − */ | |
| 1335 | − dp_display_host_phy_init(dp); | |
| 1336 | − dp_link_psm_config(dp->link, &dp->panel->link_info, false); | |
| 1337 | − sink_count = drm_dp_read_sink_count(dp->aux); | |
| 1338 | − if (sink_count < 0) | |
| 1339 | − sink_count = 0; | |
| 1333 | + disable_irq(dp->irq); | |
| 1340 | 1334 | |
| 1335 | + if (dp->dp_display.is_edp) { | |
| 1341 | 1336 | dp_display_host_phy_exit(dp); |
| 1337 | + dp_catalog_ctrl_hpd_disable(dp->catalog); | |
| 1342 | 1338 | } |
| 1343 | − | |
| 1344 | − dp->link->sink_count = sink_count; | |
| 1345 | − /* | |
| 1346 | − * can not declared display is connected unless | |
| 1347 | − * HDMI cable is plugged in and sink_count of | |
| 1348 | − * dongle become 1 | |
| 1349 | − * also only signal audio when disconnected | |
| 1350 | − */ | |
| 1351 | − if (dp->link->sink_count) { | |
| 1352 | − dp->dp_display.is_connected = true; | |
| 1353 | − } else { | |
| 1354 | − dp->dp_display.is_connected = false; | |
| 1355 | − dp_display_handle_plugged_change(dp_display, false); | |
| 1356 | − } | |
| 1357 | − | |
| 1358 | − drm_dbg_dp(dp->drm_dev, | |
| 1359 | − "After, type=%d sink=%d conn=%d core_init=%d phy_init=%d power=%d\n", | |
| 1360 | − dp->dp_display.connector_type, dp->link->sink_count, | |
| 1361 | − dp->dp_display.is_connected, dp->core_initialized, | |
| 1362 | − dp->phy_initialized, dp_display->power_on); | |
| 1363 | − | |
| 1364 | − mutex_unlock(&dp->event_mutex); | |
| 1339 | + dp_display_host_deinit(dp); | |
| 1365 | 1340 | |
| 1366 | 1341 | return 0; |
| 1367 | 1342 | } |
| 1368 | 1343 | |
| 1369 | −static int dp_pm_suspend(struct device *dev) | |
| 1344 | +static int dp_pm_runtime_resume(struct device *dev) | |
| 1370 | 1345 | { |
| 1371 | − struct platform_device *pdev = to_platform_device(dev); | |
| 1372 | − struct msm_dp *dp_display = platform_get_drvdata(pdev); | |
| 1373 | − struct dp_display_private *dp; | |
| 1374 | − | |
| 1375 | − dp = container_of(dp_display, struct dp_display_private, dp_display); | |
| 1376 | − | |
| 1377 | − mutex_lock(&dp->event_mutex); | |
| 1378 | − | |
| 1379 | − drm_dbg_dp(dp->drm_dev, | |
| 1380 | − "Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n", | |
| 1381 | − dp->dp_display.connector_type, dp->core_initialized, | |
| 1382 | − dp->phy_initialized, dp_display->power_on); | |
| 1383 | − | |
| 1384 | − /* mainlink enabled */ | |
| 1385 | − if (dp_power_clk_status(dp->power, DP_CTRL_PM)) | |
| 1386 | − dp_ctrl_off_link_stream(dp->ctrl); | |
| 1387 | − | |
| 1388 | − dp_display_host_phy_exit(dp); | |
| 1389 | − | |
| 1390 | − /* host_init will be called at pm_resume */ | |
| 1391 | − dp_display_host_deinit(dp); | |
| 1392 | − | |
| 1393 | − dp->hpd_state = ST_SUSPENDED; | |
| 1394 | − | |
| 1395 | − drm_dbg_dp(dp->drm_dev, | |
| 1396 | − "After, type=%d core_inited=%d phy_inited=%d power_on=%d\n", | |
| 1397 | − dp->dp_display.connector_type, dp->core_initialized, | |
| 1398 | − dp->phy_initialized, dp_display->power_on); | |
| 1346 | + struct dp_display_private *dp = dev_get_dp_display_private(dev); | |
| 1399 | 1347 | |
| 1400 | − mutex_unlock(&dp->event_mutex); | |
| 1348 | + /* | |
| 1349 | + * for eDP, host cotroller, HPD block and PHY are enabled here | |
| 1350 | + * but with HPD irq disabled | |
| 1351 | + * | |
| 1352 | + * for DP, only host controller is enabled here. | |
| 1353 | + * HPD block is enabled at dp_bridge_hpd_enable() | |
| 1354 | + * PHY will be enabled at plugin handler later | |
| 1355 | + */ | |
| 1356 | + dp_display_host_init(dp); | |
| 1357 | + if (dp->dp_display.is_edp) { | |
| 1358 | + dp_catalog_ctrl_hpd_enable(dp->catalog); | |
| 1359 | + dp_display_host_phy_init(dp); | |
| 1360 | + } | |
| 1401 | 1361 | |
| 1362 | + enable_irq(dp->irq); | |
| 1402 | 1363 | return 0; |
| 1403 | 1364 | } |
| 1404 | 1365 | |
| 1405 | 1366 | static const struct dev_pm_ops dp_pm_ops = { |
| 1406 | − .suspend = dp_pm_suspend, | |
| 1407 | − .resume = dp_pm_resume, | |
| 1367 | + SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL) | |
| 1368 | + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | |
| 1369 | + pm_runtime_force_resume) | |
| 1408 | 1370 | }; |
| 1409 | 1371 | |
| 1410 | 1372 | static struct platform_driver dp_display_driver = { |
| @@ -1434,19 +1396,6 @@ void __exit msm_dp_unregister(void) · 23 unmodified lines | ||
| 1434 | 1396 | platform_driver_unregister(&dp_display_driver); |
| 1435 | 1397 | } |
| 1436 | 1398 | |
| 1437 | −void msm_dp_irq_postinstall(struct msm_dp *dp_display) | |
| 1438 | −{ | |
| 1439 | − struct dp_display_private *dp; | |
| 1440 | − | |
| 1441 | − if (!dp_display) | |
| 1442 | − return; | |
| 1443 | − | |
| 1444 | − dp = container_of(dp_display, struct dp_display_private, dp_display); | |
| 1445 | − | |
| 1446 | − if (!dp_display->is_edp) | |
| 1447 | − dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0); | |
| 1448 | −} | |
| 1449 | − | |
| 1450 | 1399 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) |
| 1451 | 1400 | { |
| 1452 | 1401 | struct dp_display_private *dp; |
| @@ -1456,7 +1405,7 @@ bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) · 3 unmodified lines | ||
| 1456 | 1405 | return dp->wide_bus_en; |
| 1457 | 1406 | } |
| 1458 | 1407 | |
| 1459 | −void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) | |
| 1408 | +void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, bool is_edp) | |
| 1460 | 1409 | { |
| 1461 | 1410 | struct dp_display_private *dp; |
| 1462 | 1411 | struct device *dev; |
| @@ -1467,7 +1416,7 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) · 4 unmodified lines | ||
| 1467 | 1416 | |
| 1468 | 1417 | dp->debug = dp_debug_get(dev, dp->panel, |
| 1469 | 1418 | dp->link, dp->dp_display.connector, |
| 1470 | − minor); | |
| 1419 | + root, is_edp); | |
| 1471 | 1420 | if (IS_ERR(dp->debug)) { |
| 1472 | 1421 | rc = PTR_ERR(dp->debug); |
| 1473 | 1422 | DRM_ERROR("failed to initialize debug, rc = %d\n", rc); |
| @@ -1479,33 +1428,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) · 5 unmodified lines | ||
| 1479 | 1428 | { |
| 1480 | 1429 | int rc; |
| 1481 | 1430 | struct dp_display_private *dp_priv; |
| 1482 | − struct device_node *aux_bus; | |
| 1483 | − struct device *dev; | |
| 1484 | 1431 | |
| 1485 | 1432 | dp_priv = container_of(dp, struct dp_display_private, dp_display); |
| 1486 | − dev = &dp_priv->dp_display.pdev->dev; | |
| 1487 | − aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); | |
| 1488 | − | |
| 1489 | − if (aux_bus && dp->is_edp) { | |
| 1490 | − dp_display_host_init(dp_priv); | |
| 1491 | − dp_catalog_ctrl_hpd_enable(dp_priv->catalog); | |
| 1492 | − dp_display_host_phy_init(dp_priv); | |
| 1493 | − | |
| 1494 | − /* | |
| 1495 | − * The code below assumes that the panel will finish probing | |
| 1496 | − * by the time devm_of_dp_aux_populate_ep_devices() returns. | |
| 1497 | − * This isn't a great assumption since it will fail if the | |
| 1498 | − * panel driver is probed asynchronously but is the best we | |
| 1499 | − * can do without a bigger driver reorganization. | |
| 1500 | − */ | |
| 1501 | − rc = of_dp_aux_populate_bus(dp_priv->aux, NULL); | |
| 1502 | − of_node_put(aux_bus); | |
| 1503 | − if (rc) | |
| 1504 | − goto error; | |
| 1505 | − } else if (dp->is_edp) { | |
| 1506 | − DRM_ERROR("eDP aux_bus not found\n"); | |
| 1507 | − return -ENODEV; | |
| 1508 | − } | |
| 1509 | 1433 | |
| 1510 | 1434 | /* |
| 1511 | 1435 | * External bridges are mandatory for eDP interfaces: one has to |
| @@ -1514,21 +1438,13 @@ static int dp_display_get_next_bridge(struct msm_dp *dp) · 2 unmodified lines | ||
| 1514 | 1438 | * For DisplayPort interfaces external bridges are optional, so |
| 1515 | 1439 | * silently ignore an error if one is not present (-ENODEV). |
| 1516 | 1440 | */ |
| 1517 | − rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser); | |
| 1441 | + rc = devm_dp_parser_find_next_bridge(&dp->pdev->dev, dp_priv->parser); | |
| 1518 | 1442 | if (!dp->is_edp && rc == -ENODEV) |
| 1519 | 1443 | return 0; |
| 1520 | 1444 | |
| 1521 | − if (!rc) { | |
| 1445 | + if (!rc) | |
| 1522 | 1446 | dp->next_bridge = dp_priv->parser->next_bridge; |
| 1523 | − return 0; | |
| 1524 | − } | |
| 1525 | 1447 | |
| 1526 | −error: | |
| 1527 | − if (dp->is_edp) { | |
| 1528 | − of_dp_aux_depopulate_bus(dp_priv->aux); | |
| 1529 | − dp_display_host_phy_exit(dp_priv); | |
| 1530 | − dp_display_host_deinit(dp_priv); | |
| 1531 | − } | |
| 1532 | 1448 | return rc; |
| 1533 | 1449 | } |
| 1534 | 1450 | |
| @@ -1542,16 +1458,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, · 7 unmodified lines | ||
| 1542 | 1458 | |
| 1543 | 1459 | dp_priv = container_of(dp_display, struct dp_display_private, dp_display); |
| 1544 | 1460 | |
| 1545 | − ret = dp_display_request_irq(dp_display); | |
| 1546 | − if (ret) { | |
| 1547 | − DRM_ERROR("request_irq failed, ret=%d\n", ret); | |
| 1548 | − return ret; | |
| 1549 | − } | |
| 1550 | − | |
| 1551 | − ret = dp_display_get_next_bridge(dp_display); | |
| 1552 | − if (ret) | |
| 1553 | − return ret; | |
| 1554 | − | |
| 1555 | 1461 | ret = dp_bridge_init(dp_display, dev, encoder); |
| 1556 | 1462 | if (ret) { |
| 1557 | 1463 | DRM_DEV_ERROR(dev->dev, |
| @@ -1593,6 +1499,11 @@ void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, · 35 unmodified lines | ||
| 1593 | 1499 | dp_hpd_plug_handle(dp_display, 0); |
| 1594 | 1500 | |
| 1595 | 1501 | mutex_lock(&dp_display->event_mutex); |
| 1502 | + if (pm_runtime_resume_and_get(&dp->pdev->dev)) { | |
| 1503 | + DRM_ERROR("failed to pm_runtime_resume\n"); | |
| 1504 | + mutex_unlock(&dp_display->event_mutex); | |
| 1505 | + return; | |
| 1506 | + } | |
| 1596 | 1507 | |
| 1597 | 1508 | state = dp_display->hpd_state; |
| 1598 | 1509 | if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) { |
| @@ -1657,10 +1568,9 @@ void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, · 58 unmodified lines | ||
| 1657 | 1568 | mutex_lock(&dp_display->event_mutex); |
| 1658 | 1569 | |
| 1659 | 1570 | state = dp_display->hpd_state; |
| 1660 | − if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) { | |
| 1661 | − mutex_unlock(&dp_display->event_mutex); | |
| 1662 | − return; | |
| 1663 | − } | |
| 1571 | + if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) | |
| 1572 | + drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n", | |
| 1573 | + dp->connector_type, state); | |
| 1664 | 1574 | |
| 1665 | 1575 | dp_display_disable(dp_display); |
| 1666 | 1576 | |
| @@ -1673,6 +1583,8 @@ void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, · 6 unmodified lines | ||
| 1673 | 1583 | } |
| 1674 | 1584 | |
| 1675 | 1585 | drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type); |
| 1586 | + | |
| 1587 | + pm_runtime_put_sync(&dp->pdev->dev); | |
| 1676 | 1588 | mutex_unlock(&dp_display->event_mutex); |
| 1677 | 1589 | } |
| 1678 | 1590 | |
| @@ -1711,7 +1623,21 @@ void dp_bridge_hpd_enable(struct drm_bridge *bridge) · 32 unmodified lines | ||
| 1711 | 1623 | struct msm_dp *dp_display = dp_bridge->dp_display; |
| 1712 | 1624 | struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display); |
| 1713 | 1625 | |
| 1626 | + /* | |
| 1627 | + * this is for external DP with hpd irq enabled case, | |
| 1628 | + * step-1: dp_pm_runtime_resume() enable dp host only | |
| 1629 | + * step-2: enable hdp block and have hpd irq enabled here | |
| 1630 | + * step-3: waiting for plugin irq while phy is not initialized | |
| 1631 | + * step-4: DP PHY is initialized at plugin handler before link training | |
| 1632 | + * | |
| 1633 | + */ | |
| 1714 | 1634 | mutex_lock(&dp->event_mutex); |
| 1635 | + if (pm_runtime_resume_and_get(&dp_display->pdev->dev)) { | |
| 1636 | + DRM_ERROR("failed to resume power\n"); | |
| 1637 | + mutex_unlock(&dp->event_mutex); | |
| 1638 | + return; | |
| 1639 | + } | |
| 1640 | + | |
| 1715 | 1641 | dp_catalog_ctrl_hpd_enable(dp->catalog); |
| 1716 | 1642 | |
| 1717 | 1643 | /* enable HDP interrupts */ |
| @@ -1733,6 +1659,8 @@ void dp_bridge_hpd_disable(struct drm_bridge *bridge) · 15 unmodified lines | ||
| 1733 | 1659 | dp_catalog_ctrl_hpd_disable(dp->catalog); |
| 1734 | 1660 | |
| 1735 | 1661 | dp_display->internal_hpd = false; |
| 1662 | + | |
| 1663 | + pm_runtime_put_sync(&dp_display->pdev->dev); | |
| 1736 | 1664 | mutex_unlock(&dp->event_mutex); |
| 1737 | 1665 | } |
| 1738 | 1666 | |
| @@ -1747,13 +1675,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge, · 8 unmodified lines | ||
| 1747 | 1675 | if (dp_display->internal_hpd) |
| 1748 | 1676 | return; |
| 1749 | 1677 | |
| 1750 | − if (!dp->core_initialized) { | |
| 1751 | − drm_dbg_dp(dp->drm_dev, "not initialized\n"); | |
| 1752 | − return; | |
| 1753 | − } | |
| 1754 | − | |
| 1755 | − if (!dp_display->is_connected && status == connector_status_connected) | |
| 1678 | + if (!dp_display->link_ready && status == connector_status_connected) | |
| 1756 | 1679 | dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0); |
| 1757 | − else if (dp_display->is_connected && status == connector_status_disconnected) | |
| 1680 | + else if (dp_display->link_ready && status == connector_status_disconnected) | |
| 1758 | 1681 | dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0); |
| 1759 | 1682 | } |
| @@ -17,7 +17,7 @@ struct msm_dp { · 16 unmodified lines | ||
| 17 | 17 | struct drm_bridge *bridge; |
| 18 | 18 | struct drm_connector *connector; |
| 19 | 19 | struct drm_bridge *next_bridge; |
| 20 | − bool is_connected; | |
| 20 | + bool link_ready; | |
| 21 | 21 | bool audio_enabled; |
| 22 | 22 | bool power_on; |
| 23 | 23 | unsigned int connector_type; |
| @@ -36,11 +36,11 @@ struct msm_dp { · 12 unmodified lines | ||
| 36 | 36 | int dp_display_set_plugged_cb(struct msm_dp *dp_display, |
| 37 | 37 | hdmi_codec_plugged_cb fn, struct device *codec_dev); |
| 38 | 38 | int dp_display_get_modes(struct msm_dp *dp_display); |
| 39 | −int dp_display_request_irq(struct msm_dp *dp_display); | |
| 40 | 39 | bool dp_display_check_video_test(struct msm_dp *dp_display); |
| 41 | 40 | int dp_display_get_test_bpp(struct msm_dp *dp_display); |
| 42 | 41 | void dp_display_signal_audio_start(struct msm_dp *dp_display); |
| 43 | 42 | void dp_display_signal_audio_complete(struct msm_dp *dp_display); |
| 44 | 43 | void dp_display_set_psr(struct msm_dp *dp, bool enter); |
| 44 | +void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *dentry, bool is_edp); | |
| 45 | 45 | |
| 46 | 46 | #endif /* _DP_DISPLAY_H_ */ |
| @@ -24,10 +24,10 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge) · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | dp = to_dp_bridge(bridge)->dp_display; |
| 26 | 26 | |
| 27 | − drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", | |
| 28 | − (dp->is_connected) ? "true" : "false"); | |
| 27 | + drm_dbg_dp(dp->drm_dev, "link_ready = %s\n", | |
| 28 | + (dp->link_ready) ? "true" : "false"); | |
| 29 | 29 | |
| 30 | − return (dp->is_connected) ? connector_status_connected : | |
| 30 | + return (dp->link_ready) ? connector_status_connected : | |
| 31 | 31 | connector_status_disconnected; |
| 32 | 32 | } |
| 33 | 33 | |
| @@ -40,8 +40,8 @@ static int dp_bridge_atomic_check(struct drm_bridge *bridge, · 6 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | dp = to_dp_bridge(bridge)->dp_display; |
| 42 | 42 | |
| 43 | − drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", | |
| 44 | − (dp->is_connected) ? "true" : "false"); | |
| 43 | + drm_dbg_dp(dp->drm_dev, "link_ready = %s\n", | |
| 44 | + (dp->link_ready) ? "true" : "false"); | |
| 45 | 45 | |
| 46 | 46 | /* |
| 47 | 47 | * There is no protection in the DRM framework to check if the display |
| @@ -55,7 +55,7 @@ static int dp_bridge_atomic_check(struct drm_bridge *bridge, · 7 unmodified lines | ||
| 55 | 55 | * After that this piece of code can be removed. |
| 56 | 56 | */ |
| 57 | 57 | if (bridge->ops & DRM_BRIDGE_OP_HPD) |
| 58 | − return (dp->is_connected) ? 0 : -ENOTCONN; | |
| 58 | + return (dp->link_ready) ? 0 : -ENOTCONN; | |
| 59 | 59 | |
| 60 | 60 | return 0; |
| 61 | 61 | } |
| @@ -78,7 +78,7 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector * · 16 unmodified lines | ||
| 78 | 78 | dp = to_dp_bridge(bridge)->dp_display; |
| 79 | 79 | |
| 80 | 80 | /* pluggable case assumes EDID is read when HPD */ |
| 81 | − if (dp->is_connected) { | |
| 81 | + if (dp->link_ready) { | |
| 82 | 82 | rc = dp_display_get_modes(dp); |
| 83 | 83 | if (rc <= 0) { |
| 84 | 84 | DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc); |
| @@ -90,6 +90,13 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector * · 5 unmodified lines | ||
| 90 | 90 | return rc; |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | +static void dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) | |
| 94 | +{ | |
| 95 | + struct msm_dp *dp = to_dp_bridge(bridge)->dp_display; | |
| 96 | + | |
| 97 | + dp_display_debugfs_init(dp, root, false); | |
| 98 | +} | |
| 99 | + | |
| 93 | 100 | static const struct drm_bridge_funcs dp_bridge_ops = { |
| 94 | 101 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
| 95 | 102 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, |
| @@ -105,6 +112,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = { · 9 unmodified lines | ||
| 105 | 112 | .hpd_enable = dp_bridge_hpd_enable, |
| 106 | 113 | .hpd_disable = dp_bridge_hpd_disable, |
| 107 | 114 | .hpd_notify = dp_bridge_hpd_notify, |
| 115 | + .debugfs_init = dp_bridge_debugfs_init, | |
| 108 | 116 | }; |
| 109 | 117 | |
| 110 | 118 | static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, |
| @@ -260,6 +268,13 @@ static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge, · 149 unmodified lines | ||
| 260 | 268 | return MODE_OK; |
| 261 | 269 | } |
| 262 | 270 | |
| 271 | +static void edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root) | |
| 272 | +{ | |
| 273 | + struct msm_dp *dp = to_dp_bridge(bridge)->dp_display; | |
| 274 | + | |
| 275 | + dp_display_debugfs_init(dp, root, true); | |
| 276 | +} | |
| 277 | + | |
| 263 | 278 | static const struct drm_bridge_funcs edp_bridge_ops = { |
| 264 | 279 | .atomic_enable = edp_bridge_atomic_enable, |
| 265 | 280 | .atomic_disable = edp_bridge_atomic_disable, |
| @@ -270,6 +285,7 @@ static const struct drm_bridge_funcs edp_bridge_ops = { · 4 unmodified lines | ||
| 270 | 285 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
| 271 | 286 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, |
| 272 | 287 | .atomic_check = edp_bridge_atomic_check, |
| 288 | + .debugfs_init = edp_bridge_debugfs_init, | |
| 273 | 289 | }; |
| 274 | 290 | |
| 275 | 291 | int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, |
| @@ -152,45 +152,17 @@ int dp_power_client_init(struct dp_power *dp_power) · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | power = container_of(dp_power, struct dp_power_private, dp_power); |
| 154 | 154 | |
| 155 | − pm_runtime_enable(power->dev); | |
| 156 | − | |
| 157 | 155 | return dp_power_clk_init(power); |
| 158 | 156 | } |
| 159 | 157 | |
| 160 | −void dp_power_client_deinit(struct dp_power *dp_power) | |
| 161 | −{ | |
| 162 | − struct dp_power_private *power; | |
| 163 | − | |
| 164 | − power = container_of(dp_power, struct dp_power_private, dp_power); | |
| 165 | − | |
| 166 | − pm_runtime_disable(power->dev); | |
| 167 | −} | |
| 168 | − | |
| 169 | 158 | int dp_power_init(struct dp_power *dp_power) |
| 170 | 159 | { |
| 171 | − int rc = 0; | |
| 172 | − struct dp_power_private *power = NULL; | |
| 173 | − | |
| 174 | − power = container_of(dp_power, struct dp_power_private, dp_power); | |
| 175 | − | |
| 176 | − pm_runtime_get_sync(power->dev); | |
| 177 | − | |
| 178 | − rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true); | |
| 179 | − if (rc) | |
| 180 | − pm_runtime_put_sync(power->dev); | |
| 181 | − | |
| 182 | − return rc; | |
| 160 | + return dp_power_clk_enable(dp_power, DP_CORE_PM, true); | |
| 183 | 161 | } |
| 184 | 162 | |
| 185 | 163 | int dp_power_deinit(struct dp_power *dp_power) |
| 186 | 164 | { |
| 187 | − struct dp_power_private *power; | |
| 188 | − | |
| 189 | − power = container_of(dp_power, struct dp_power_private, dp_power); | |
| 190 | − | |
| 191 | − dp_power_clk_enable(dp_power, DP_CORE_PM, false); | |
| 192 | − pm_runtime_put_sync(power->dev); | |
| 193 | − return 0; | |
| 165 | + return dp_power_clk_enable(dp_power, DP_CORE_PM, false); | |
| 194 | 166 | } |
| 195 | 167 | |
| 196 | 168 | struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) |
| @@ -80,17 +80,6 @@ int dp_power_clk_enable(struct dp_power *power, enum dp_pm_type pm_type, · 79 unmodified lines | ||
| 80 | 80 | */ |
| 81 | 81 | int dp_power_client_init(struct dp_power *power); |
| 82 | 82 | |
| 83 | −/** | |
| 84 | − * dp_power_clinet_deinit() - de-initialize clock and regulator modules | |
| 85 | − * | |
| 86 | − * @power: instance of power module | |
| 87 | − * return: 0 for success, error for failure. | |
| 88 | − * | |
| 89 | − * This API will de-initialize the DisplayPort's clocks and regulator | |
| 90 | − * modules. | |
| 91 | − */ | |
| 92 | −void dp_power_client_deinit(struct dp_power *power); | |
| 93 | − | |
| 94 | 83 | /** |
| 95 | 84 | * dp_power_get() - configure and get the DisplayPort power module data |
| 96 | 85 | * |
| @@ -190,6 +190,21 @@ static const struct msm_dsi_config sm8550_dsi_cfg = { · 189 unmodified lines | ||
| 190 | 190 | }, |
| 191 | 191 | }; |
| 192 | 192 | |
| 193 | +static const struct regulator_bulk_data sm8650_dsi_regulators[] = { | |
| 194 | + { .supply = "vdda", .init_load_uA = 16600 }, /* 1.2 V */ | |
| 195 | +}; | |
| 196 | + | |
| 197 | +static const struct msm_dsi_config sm8650_dsi_cfg = { | |
| 198 | + .io_offset = DSI_6G_REG_SHIFT, | |
| 199 | + .regulator_data = sm8650_dsi_regulators, | |
| 200 | + .num_regulators = ARRAY_SIZE(sm8650_dsi_regulators), | |
| 201 | + .bus_clk_names = dsi_v2_4_clk_names, | |
| 202 | + .num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names), | |
| 203 | + .io_start = { | |
| 204 | + { 0xae94000, 0xae96000 }, | |
| 205 | + }, | |
| 206 | +}; | |
| 207 | + | |
| 193 | 208 | static const struct regulator_bulk_data sc7280_dsi_regulators[] = { |
| 194 | 209 | { .supply = "vdda", .init_load_uA = 8350 }, /* 1.2 V */ |
| 195 | 210 | { .supply = "refgen" }, |
| @@ -281,6 +296,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { · 85 unmodified lines | ||
| 281 | 296 | &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops}, |
| 282 | 297 | {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0, |
| 283 | 298 | &sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops}, |
| 299 | + {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_8_0, | |
| 300 | + &sm8650_dsi_cfg, &msm_dsi_6g_v2_host_ops}, | |
| 284 | 301 | }; |
| 285 | 302 | |
| 286 | 303 | const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor) |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000 |
| 29 | 29 | #define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000 |
| 30 | 30 | #define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000 |
| 31 | +#define MSM_DSI_6G_VER_MINOR_V2_8_0 0x20080000 | |
| 31 | 32 | |
| 32 | 33 | #define MSM_DSI_V2_VER_MINOR_8064 0x0 |
| 33 | 34 | |
| @@ -516,7 +516,9 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) · 515 unmodified lines | ||
| 516 | 516 | struct device *dev = &phy->pdev->dev; |
| 517 | 517 | int ret; |
| 518 | 518 | |
| 519 | − pm_runtime_get_sync(dev); | |
| 519 | + ret = pm_runtime_resume_and_get(dev); | |
| 520 | + if (ret) | |
| 521 | + return ret; | |
| 520 | 522 | |
| 521 | 523 | ret = clk_prepare_enable(phy->ahb_clk); |
| 522 | 524 | if (ret) { |
| @@ -585,6 +587,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { · 62 unmodified lines | ||
| 585 | 587 | .data = &dsi_phy_5nm_8450_cfgs }, |
| 586 | 588 | { .compatible = "qcom,sm8550-dsi-phy-4nm", |
| 587 | 589 | .data = &dsi_phy_4nm_8550_cfgs }, |
| 590 | + { .compatible = "qcom,sm8650-dsi-phy-4nm", | |
| 591 | + .data = &dsi_phy_4nm_8650_cfgs }, | |
| 588 | 592 | #endif |
| 589 | 593 | {} |
| 590 | 594 | }; |
| @@ -689,6 +693,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) · 98 unmodified lines | ||
| 689 | 693 | return dev_err_probe(dev, PTR_ERR(phy->ahb_clk), |
| 690 | 694 | "Unable to get ahb clk\n"); |
| 691 | 695 | |
| 696 | + ret = devm_pm_runtime_enable(&pdev->dev); | |
| 697 | + if (ret) | |
| 698 | + return ret; | |
| 699 | + | |
| 692 | 700 | /* PLL init will call into clk_register which requires |
| 693 | 701 | * register access, so we need to enable power and ahb clock. |
| 694 | 702 | */ |
| @@ -62,6 +62,7 @@ extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs; · 61 unmodified lines | ||
| 62 | 62 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs; |
| 63 | 63 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs; |
| 64 | 64 | extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs; |
| 65 | +extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs; | |
| 65 | 66 | |
| 66 | 67 | struct msm_dsi_dphy_timing { |
| 67 | 68 | u32 clk_zero; |
| @@ -1121,6 +1121,10 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = { · 1120 unmodified lines | ||
| 1121 | 1121 | { .supply = "vdds", .init_load_uA = 37550 }, |
| 1122 | 1122 | }; |
| 1123 | 1123 | |
| 1124 | +static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = { | |
| 1125 | + { .supply = "vdds", .init_load_uA = 98000 }, | |
| 1126 | +}; | |
| 1127 | + | |
| 1124 | 1128 | static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = { |
| 1125 | 1129 | { .supply = "vdds", .init_load_uA = 97800 }, |
| 1126 | 1130 | }; |
| @@ -1281,3 +1285,26 @@ const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = { · 154 unmodified lines | ||
| 1281 | 1285 | .num_dsi_phy = 2, |
| 1282 | 1286 | .quirks = DSI_PHY_7NM_QUIRK_V5_2, |
| 1283 | 1287 | }; |
| 1288 | + | |
| 1289 | +const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs = { | |
| 1290 | + .has_phy_lane = true, | |
| 1291 | + .regulator_data = dsi_phy_7nm_98000uA_regulators, | |
| 1292 | + .num_regulators = ARRAY_SIZE(dsi_phy_7nm_98000uA_regulators), | |
| 1293 | + .ops = { | |
| 1294 | + .enable = dsi_7nm_phy_enable, | |
| 1295 | + .disable = dsi_7nm_phy_disable, | |
| 1296 | + .pll_init = dsi_pll_7nm_init, | |
| 1297 | + .save_pll_state = dsi_7nm_pll_save_state, | |
| 1298 | + .restore_pll_state = dsi_7nm_pll_restore_state, | |
| 1299 | + .set_continuous_clock = dsi_7nm_set_continuous_clock, | |
| 1300 | + }, | |
| 1301 | + .min_pll_rate = 600000000UL, | |
| 1302 | +#ifdef CONFIG_64BIT | |
| 1303 | + .max_pll_rate = 5000000000UL, | |
| 1304 | +#else | |
| 1305 | + .max_pll_rate = ULONG_MAX, | |
| 1306 | +#endif | |
| 1307 | + .io_start = { 0xae95000, 0xae97000 }, | |
| 1308 | + .num_dsi_phy = 2, | |
| 1309 | + .quirks = DSI_PHY_7NM_QUIRK_V5_2, | |
| 1310 | +}; | |
| @@ -304,36 +304,21 @@ int msm_debugfs_late_init(struct drm_device *dev) · 303 unmodified lines | ||
| 304 | 304 | return ret; |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | −void msm_debugfs_init(struct drm_minor *minor) | |
| 307 | +static void msm_debugfs_gpu_init(struct drm_minor *minor) | |
| 308 | 308 | { |
| 309 | 309 | struct drm_device *dev = minor->dev; |
| 310 | 310 | struct msm_drm_private *priv = dev->dev_private; |
| 311 | 311 | struct dentry *gpu_devfreq; |
| 312 | 312 | |
| 313 | − drm_debugfs_create_files(msm_debugfs_list, | |
| 314 | − ARRAY_SIZE(msm_debugfs_list), | |
| 315 | − minor->debugfs_root, minor); | |
| 316 | − | |
| 317 | 313 | debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, |
| 318 | 314 | dev, &msm_gpu_fops); |
| 319 | 315 | |
| 320 | − if (priv->kms) { | |
| 321 | − drm_debugfs_create_files(msm_kms_debugfs_list, | |
| 322 | − ARRAY_SIZE(msm_kms_debugfs_list), | |
| 323 | − minor->debugfs_root, minor); | |
| 324 | − debugfs_create_file("kms", S_IRUSR, minor->debugfs_root, | |
| 325 | − dev, &msm_kms_fops); | |
| 326 | − } | |
| 327 | − | |
| 328 | 316 | debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, |
| 329 | 317 | &priv->hangcheck_period); |
| 330 | 318 | |
| 331 | 319 | debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, |
| 332 | 320 | &priv->disable_err_irq); |
| 333 | 321 | |
| 334 | − debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, | |
| 335 | − dev, &shrink_fops); | |
| 336 | − | |
| 337 | 322 | gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root); |
| 338 | 323 | |
| 339 | 324 | debugfs_create_bool("idle_clamp",0600, gpu_devfreq, |
| @@ -344,6 +329,30 @@ void msm_debugfs_init(struct drm_minor *minor) · 4 unmodified lines | ||
| 344 | 329 | |
| 345 | 330 | debugfs_create_u32("downdifferential",0600, gpu_devfreq, |
| 346 | 331 | &priv->gpu_devfreq_config.downdifferential); |
| 332 | +} | |
| 333 | + | |
| 334 | +void msm_debugfs_init(struct drm_minor *minor) | |
| 335 | +{ | |
| 336 | + struct drm_device *dev = minor->dev; | |
| 337 | + struct msm_drm_private *priv = dev->dev_private; | |
| 338 | + | |
| 339 | + drm_debugfs_create_files(msm_debugfs_list, | |
| 340 | + ARRAY_SIZE(msm_debugfs_list), | |
| 341 | + minor->debugfs_root, minor); | |
| 342 | + | |
| 343 | + if (priv->gpu_pdev) | |
| 344 | + msm_debugfs_gpu_init(minor); | |
| 345 | + | |
| 346 | + if (priv->kms) { | |
| 347 | + drm_debugfs_create_files(msm_kms_debugfs_list, | |
| 348 | + ARRAY_SIZE(msm_kms_debugfs_list), | |
| 349 | + minor->debugfs_root, minor); | |
| 350 | + debugfs_create_file("kms", S_IRUSR, minor->debugfs_root, | |
| 351 | + dev, &msm_kms_fops); | |
| 352 | + } | |
| 353 | + | |
| 354 | + debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, | |
| 355 | + dev, &shrink_fops); | |
| 347 | 356 | |
| 348 | 357 | if (priv->kms && priv->kms->funcs->debugfs_init) |
| 349 | 358 | priv->kms->funcs->debugfs_init(priv->kms, minor); |
| @@ -37,9 +37,10 @@ · 36 unmodified lines | ||
| 37 | 37 | * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN |
| 38 | 38 | * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT |
| 39 | 39 | * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST) |
| 40 | + * - 1.12.0 - Add MSM_INFO_SET_METADATA and MSM_INFO_GET_METADATA | |
| 40 | 41 | */ |
| 41 | 42 | #define MSM_VERSION_MAJOR 1 |
| 42 | −#define MSM_VERSION_MINOR 10 | |
| 43 | +#define MSM_VERSION_MINOR 12 | |
| 43 | 44 | #define MSM_VERSION_PATCHLEVEL 0 |
| 44 | 45 | |
| 45 | 46 | static void msm_deinit_vram(struct drm_device *ddev); |
| @@ -544,6 +545,85 @@ static int msm_ioctl_gem_info_set_iova(struct drm_device *dev, · 498 unmodified lines | ||
| 544 | 545 | return msm_gem_set_iova(obj, ctx->aspace, iova); |
| 545 | 546 | } |
| 546 | 547 | |
| 548 | +static int msm_ioctl_gem_info_set_metadata(struct drm_gem_object *obj, | |
| 549 | + __user void *metadata, | |
| 550 | + u32 metadata_size) | |
| 551 | +{ | |
| 552 | + struct msm_gem_object *msm_obj = to_msm_bo(obj); | |
| 553 | + void *buf; | |
| 554 | + int ret; | |
| 555 | + | |
| 556 | + /* Impose a moderate upper bound on metadata size: */ | |
| 557 | + if (metadata_size > 128) { | |
| 558 | + return -EOVERFLOW; | |
| 559 | + } | |
| 560 | + | |
| 561 | + /* Use a temporary buf to keep copy_from_user() outside of gem obj lock: */ | |
| 562 | + buf = memdup_user(metadata, metadata_size); | |
| 563 | + if (IS_ERR(buf)) | |
| 564 | + return PTR_ERR(buf); | |
| 565 | + | |
| 566 | + ret = msm_gem_lock_interruptible(obj); | |
| 567 | + if (ret) | |
| 568 | + goto out; | |
| 569 | + | |
| 570 | + msm_obj->metadata = | |
| 571 | + krealloc(msm_obj->metadata, metadata_size, GFP_KERNEL); | |
| 572 | + msm_obj->metadata_size = metadata_size; | |
| 573 | + memcpy(msm_obj->metadata, buf, metadata_size); | |
| 574 | + | |
| 575 | + msm_gem_unlock(obj); | |
| 576 | + | |
| 577 | +out: | |
| 578 | + kfree(buf); | |
| 579 | + | |
| 580 | + return ret; | |
| 581 | +} | |
| 582 | + | |
| 583 | +static int msm_ioctl_gem_info_get_metadata(struct drm_gem_object *obj, | |
| 584 | + __user void *metadata, | |
| 585 | + u32 *metadata_size) | |
| 586 | +{ | |
| 587 | + struct msm_gem_object *msm_obj = to_msm_bo(obj); | |
| 588 | + void *buf; | |
| 589 | + int ret, len; | |
| 590 | + | |
| 591 | + if (!metadata) { | |
| 592 | + /* | |
| 593 | + * Querying the size is inherently racey, but | |
| 594 | + * EXT_external_objects expects the app to confirm | |
| 595 | + * via device and driver UUIDs that the exporter and | |
| 596 | + * importer versions match. All we can do from the | |
| 597 | + * kernel side is check the length under obj lock | |
| 598 | + * when userspace tries to retrieve the metadata | |
| 599 | + */ | |
| 600 | + *metadata_size = msm_obj->metadata_size; | |
| 601 | + return 0; | |
| 602 | + } | |
| 603 | + | |
| 604 | + ret = msm_gem_lock_interruptible(obj); | |
| 605 | + if (ret) | |
| 606 | + return ret; | |
| 607 | + | |
| 608 | + /* Avoid copy_to_user() under gem obj lock: */ | |
| 609 | + len = msm_obj->metadata_size; | |
| 610 | + buf = kmemdup(msm_obj->metadata, len, GFP_KERNEL); | |
| 611 | + | |
| 612 | + msm_gem_unlock(obj); | |
| 613 | + | |
| 614 | + if (*metadata_size < len) { | |
| 615 | + ret = -ETOOSMALL; | |
| 616 | + } else if (copy_to_user(metadata, buf, len)) { | |
| 617 | + ret = -EFAULT; | |
| 618 | + } else { | |
| 619 | + *metadata_size = len; | |
| 620 | + } | |
| 621 | + | |
| 622 | + kfree(buf); | |
| 623 | + | |
| 624 | + return 0; | |
| 625 | +} | |
| 626 | + | |
| 547 | 627 | static int msm_ioctl_gem_info(struct drm_device *dev, void *data, |
| 548 | 628 | struct drm_file *file) |
| 549 | 629 | { |
| @@ -566,6 +646,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 16 unmodified lines | ||
| 566 | 646 | break; |
| 567 | 647 | case MSM_INFO_SET_NAME: |
| 568 | 648 | case MSM_INFO_GET_NAME: |
| 649 | + case MSM_INFO_SET_METADATA: | |
| 650 | + case MSM_INFO_GET_METADATA: | |
| 569 | 651 | break; |
| 570 | 652 | default: |
| 571 | 653 | return -EINVAL; |
| @@ -618,7 +700,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 46 unmodified lines | ||
| 618 | 700 | break; |
| 619 | 701 | case MSM_INFO_GET_NAME: |
| 620 | 702 | if (args->value && (args->len < strlen(msm_obj->name))) { |
| 621 | − ret = -EINVAL; | |
| 703 | + ret = -ETOOSMALL; | |
| 622 | 704 | break; |
| 623 | 705 | } |
| 624 | 706 | args->len = strlen(msm_obj->name); |
| @@ -628,6 +710,14 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 3 unmodified lines | ||
| 628 | 710 | ret = -EFAULT; |
| 629 | 711 | } |
| 630 | 712 | break; |
| 713 | + case MSM_INFO_SET_METADATA: | |
| 714 | + ret = msm_ioctl_gem_info_set_metadata( | |
| 715 | + obj, u64_to_user_ptr(args->value), args->len); | |
| 716 | + break; | |
| 717 | + case MSM_INFO_GET_METADATA: | |
| 718 | + ret = msm_ioctl_gem_info_get_metadata( | |
| 719 | + obj, u64_to_user_ptr(args->value), &args->len); | |
| 720 | + break; | |
| 631 | 721 | } |
| 632 | 722 | |
| 633 | 723 | drm_gem_object_put(obj); |
| @@ -78,12 +78,10 @@ enum msm_dsi_controller { · 77 unmodified lines | ||
| 78 | 78 | * enum msm_event_wait - type of HW events to wait for |
| 79 | 79 | * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW |
| 80 | 80 | * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel |
| 81 | − * @MSM_ENC_VBLANK - wait for the HW VBLANK event (for driver-internal waiters) | |
| 82 | 81 | */ |
| 83 | 82 | enum msm_event_wait { |
| 84 | 83 | MSM_ENC_COMMIT_DONE = 0, |
| 85 | 84 | MSM_ENC_TX_COMPLETE, |
| 86 | − MSM_ENC_VBLANK, | |
| 87 | 85 | }; |
| 88 | 86 | |
| 89 | 87 | /** |
| @@ -92,12 +90,14 @@ enum msm_event_wait { · 2 unmodified lines | ||
| 92 | 90 | * @num_intf: number of interfaces the panel is mounted on |
| 93 | 91 | * @num_dspp: number of dspp blocks used |
| 94 | 92 | * @num_dsc: number of Display Stream Compression (DSC) blocks used |
| 93 | + * @needs_cdm: indicates whether cdm block is needed for this display topology | |
| 95 | 94 | */ |
| 96 | 95 | struct msm_display_topology { |
| 97 | 96 | u32 num_lm; |
| 98 | 97 | u32 num_intf; |
| 99 | 98 | u32 num_dspp; |
| 100 | 99 | u32 num_dsc; |
| 100 | + bool needs_cdm; | |
| 101 | 101 | }; |
| 102 | 102 | |
| 103 | 103 | /* Commit/Event thread specific structure */ |
| @@ -386,10 +386,8 @@ int __init msm_dp_register(void); · 282 unmodified lines | ||
| 386 | 386 | void __exit msm_dp_unregister(void); |
| 387 | 387 | int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, |
| 388 | 388 | struct drm_encoder *encoder); |
| 389 | −void msm_dp_irq_postinstall(struct msm_dp *dp_display); | |
| 390 | 389 | void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display); |
| 391 | 390 | |
| 392 | −void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor); | |
| 393 | 391 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display); |
| 394 | 392 | |
| 395 | 393 | #else |
| @@ -407,19 +405,10 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display, · 11 unmodified lines | ||
| 407 | 405 | return -EINVAL; |
| 408 | 406 | } |
| 409 | 407 | |
| 410 | −static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display) | |
| 411 | −{ | |
| 412 | −} | |
| 413 | − | |
| 414 | 408 | static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display) |
| 415 | 409 | { |
| 416 | 410 | } |
| 417 | 411 | |
| 418 | −static inline void msm_dp_debugfs_init(struct msm_dp *dp_display, | |
| 419 | − struct drm_minor *minor) | |
| 420 | −{ | |
| 421 | −} | |
| 422 | − | |
| 423 | 412 | static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) |
| 424 | 413 | { |
| 425 | 414 | return false; |
| @@ -226,9 +226,9 @@ static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj, · 225 unmodified lines | ||
| 226 | 226 | |
| 227 | 227 | msm_gem_assert_locked(obj); |
| 228 | 228 | |
| 229 | − if (GEM_WARN_ON(msm_obj->madv > madv)) { | |
| 230 | − DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n", | |
| 231 | − msm_obj->madv, madv); | |
| 229 | + if (msm_obj->madv > madv) { | |
| 230 | + DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n", | |
| 231 | + msm_obj->madv, madv); | |
| 232 | 232 | return ERR_PTR(-EBUSY); |
| 233 | 233 | } |
| 234 | 234 | |
| @@ -1058,6 +1058,7 @@ static void msm_gem_free_object(struct drm_gem_object *obj) · 823 unmodified lines | ||
| 1058 | 1058 | |
| 1059 | 1059 | drm_gem_object_release(obj); |
| 1060 | 1060 | |
| 1061 | + kfree(msm_obj->metadata); | |
| 1061 | 1062 | kfree(msm_obj); |
| 1062 | 1063 | } |
| 1063 | 1064 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <linux/kref.h> |
| 11 | 11 | #include <linux/dma-resv.h> |
| 12 | +#include "drm/drm_exec.h" | |
| 12 | 13 | #include "drm/gpu_scheduler.h" |
| 13 | 14 | #include "msm_drv.h" |
| 14 | 15 | |
| @@ -108,6 +109,10 @@ struct msm_gem_object { · 93 unmodified lines | ||
| 108 | 109 | |
| 109 | 110 | char name[32]; /* Identifier to print for the debugfs files */ |
| 110 | 111 | |
| 112 | + /* userspace metadata backchannel */ | |
| 113 | + void *metadata; | |
| 114 | + u32 metadata_size; | |
| 115 | + | |
| 111 | 116 | /** |
| 112 | 117 | * pin_count: Number of times the pages are pinned |
| 113 | 118 | * |
| @@ -254,7 +259,7 @@ struct msm_gem_submit { · 140 unmodified lines | ||
| 254 | 259 | struct msm_gpu *gpu; |
| 255 | 260 | struct msm_gem_address_space *aspace; |
| 256 | 261 | struct list_head node; /* node in ring submit list */ |
| 257 | − struct ww_acquire_ctx ticket; | |
| 262 | + struct drm_exec exec; | |
| 258 | 263 | uint32_t seqno; /* Sequence number of the submit on the ring */ |
| 259 | 264 | |
| 260 | 265 | /* Hw fence, which is created when the scheduler executes the job, and |
| @@ -270,9 +275,9 @@ struct msm_gem_submit { · 9 unmodified lines | ||
| 270 | 275 | int fence_id; /* key into queue->fence_idr */ |
| 271 | 276 | struct msm_gpu_submitqueue *queue; |
| 272 | 277 | struct pid *pid; /* submitting process */ |
| 273 | − bool fault_dumped; /* Limit devcoredump dumping to one per submit */ | |
| 274 | − bool valid; /* true if no cmdstream patching needed */ | |
| 275 | − bool in_rb; /* "sudo" mode, copy cmds into RB */ | |
| 278 | + bool bos_pinned : 1; | |
| 279 | + bool fault_dumped:1;/* Limit devcoredump dumping to one per submit */ | |
| 280 | + bool in_rb : 1; /* "sudo" mode, copy cmds into RB */ | |
| 276 | 281 | struct msm_ringbuffer *ring; |
| 277 | 282 | unsigned int nr_cmds; |
| 278 | 283 | unsigned int nr_bos; |
| @@ -287,10 +292,6 @@ struct msm_gem_submit { · 8 unmodified lines | ||
| 287 | 292 | struct drm_msm_gem_submit_reloc *relocs; |
| 288 | 293 | } *cmd; /* array of size nr_cmds */ |
| 289 | 294 | struct { |
| 290 | −/* make sure these don't conflict w/ MSM_SUBMIT_BO_x */ | |
| 291 | −#define BO_VALID 0x8000 /* is current addr in cmdstream correct/valid? */ | |
| 292 | −#define BO_LOCKED 0x4000 /* obj lock is held */ | |
| 293 | −#define BO_PINNED 0x2000 /* obj (pages) is pinned and on active list */ | |
| 294 | 295 | uint32_t flags; |
| 295 | 296 | union { |
| 296 | 297 | struct drm_gem_object *obj; |
| @@ -75,7 +75,7 @@ static bool · 74 unmodified lines | ||
| 75 | 75 | wait_for_idle(struct drm_gem_object *obj) |
| 76 | 76 | { |
| 77 | 77 | enum dma_resv_usage usage = dma_resv_usage_rw(true); |
| 78 | − return dma_resv_wait_timeout(obj->resv, usage, false, 1000) > 0; | |
| 78 | + return dma_resv_wait_timeout(obj->resv, usage, false, 10) > 0; | |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | 81 | static bool |
| @@ -17,6 +17,12 @@ · 16 unmodified lines | ||
| 17 | 17 | #include "msm_gem.h" |
| 18 | 18 | #include "msm_gpu_trace.h" |
| 19 | 19 | |
| 20 | +/* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable | |
| 21 | + * error msgs for debugging, but we don't spam dmesg by default | |
| 22 | + */ | |
| 23 | +#define SUBMIT_ERROR(submit, fmt, ...) \ | |
| 24 | + DRM_DEV_DEBUG_DRIVER((submit)->dev->dev, fmt, ##__VA_ARGS__) | |
| 25 | + | |
| 20 | 26 | /* |
| 21 | 27 | * Cmdstream submission: |
| 22 | 28 | */ |
| @@ -37,7 +43,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 14 unmodified lines | ||
| 37 | 43 | if (sz > SIZE_MAX) |
| 38 | 44 | return ERR_PTR(-ENOMEM); |
| 39 | 45 | |
| 40 | − submit = kzalloc(sz, GFP_KERNEL); | |
| 46 | + submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); | |
| 41 | 47 | if (!submit) |
| 42 | 48 | return ERR_PTR(-ENOMEM); |
| 43 | 49 | |
| @@ -136,7 +142,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 92 unmodified lines | ||
| 136 | 142 | |
| 137 | 143 | if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || |
| 138 | 144 | !(submit_bo.flags & MANDATORY_FLAGS)) { |
| 139 | − DRM_ERROR("invalid flags: %x\n", submit_bo.flags); | |
| 145 | + SUBMIT_ERROR(submit, "invalid flags: %x\n", submit_bo.flags); | |
| 140 | 146 | ret = -EINVAL; |
| 141 | 147 | i = 0; |
| 142 | 148 | goto out; |
| @@ -144,8 +150,6 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 1 unmodified line | ||
| 144 | 150 | |
| 145 | 151 | submit->bos[i].handle = submit_bo.handle; |
| 146 | 152 | submit->bos[i].flags = submit_bo.flags; |
| 147 | − /* in validate_objects() we figure out if this is true: */ | |
| 148 | − submit->bos[i].iova = submit_bo.presumed; | |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | 155 | spin_lock(&file->table_lock); |
| @@ -158,7 +162,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 6 unmodified lines | ||
| 158 | 162 | */ |
| 159 | 163 | obj = idr_find(&file->object_idr, submit->bos[i].handle); |
| 160 | 164 | if (!obj) { |
| 161 | − DRM_ERROR("invalid handle %u at index %u\n", submit->bos[i].handle, i); | |
| 165 | + SUBMIT_ERROR(submit, "invalid handle %u at index %u\n", submit->bos[i].handle, i); | |
| 162 | 166 | ret = -EINVAL; |
| 163 | 167 | goto out_unlock; |
| 164 | 168 | } |
| @@ -202,13 +206,13 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 37 unmodified lines | ||
| 202 | 206 | case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: |
| 203 | 207 | break; |
| 204 | 208 | default: |
| 205 | − DRM_ERROR("invalid type: %08x\n", submit_cmd.type); | |
| 209 | + SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type); | |
| 206 | 210 | return -EINVAL; |
| 207 | 211 | } |
| 208 | 212 | |
| 209 | 213 | if (submit_cmd.size % 4) { |
| 210 | − DRM_ERROR("non-aligned cmdstream buffer size: %u\n", | |
| 211 | − submit_cmd.size); | |
| 214 | + SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n", | |
| 215 | + submit_cmd.size); | |
| 212 | 216 | ret = -EINVAL; |
| 213 | 217 | goto out; |
| 214 | 218 | } |
| @@ -228,7 +232,7 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 13 unmodified lines | ||
| 228 | 232 | ret = -ENOMEM; |
| 229 | 233 | goto out; |
| 230 | 234 | } |
| 231 | − submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL); | |
| 235 | + submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN); | |
| 232 | 236 | if (!submit->cmd[i].relocs) { |
| 233 | 237 | ret = -ENOMEM; |
| 234 | 238 | goto out; |
| @@ -244,101 +248,30 @@ out: · 9 unmodified lines | ||
| 244 | 248 | return ret; |
| 245 | 249 | } |
| 246 | 250 | |
| 247 | −/* Unwind bo state, according to cleanup_flags. In the success case, only | |
| 248 | − * the lock is dropped at the end of the submit (and active/pin ref is dropped | |
| 249 | − * later when the submit is retired). | |
| 250 | − */ | |
| 251 | −static void submit_cleanup_bo(struct msm_gem_submit *submit, int i, | |
| 252 | − unsigned cleanup_flags) | |
| 253 | −{ | |
| 254 | − struct drm_gem_object *obj = submit->bos[i].obj; | |
| 255 | − unsigned flags = submit->bos[i].flags & cleanup_flags; | |
| 256 | − | |
| 257 | − /* | |
| 258 | − * Clear flags bit before dropping lock, so that the msm_job_run() | |
| 259 | − * path isn't racing with submit_cleanup() (ie. the read/modify/ | |
| 260 | − * write is protected by the obj lock in all paths) | |
| 261 | − */ | |
| 262 | − submit->bos[i].flags &= ~cleanup_flags; | |
| 263 | − | |
| 264 | − if (flags & BO_PINNED) | |
| 265 | − msm_gem_unpin_locked(obj); | |
| 266 | − | |
| 267 | − if (flags & BO_LOCKED) | |
| 268 | − dma_resv_unlock(obj->resv); | |
| 269 | −} | |
| 270 | − | |
| 271 | −static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i) | |
| 272 | −{ | |
| 273 | − unsigned cleanup_flags = BO_PINNED | BO_LOCKED; | |
| 274 | − submit_cleanup_bo(submit, i, cleanup_flags); | |
| 275 | − | |
| 276 | − if (!(submit->bos[i].flags & BO_VALID)) | |
| 277 | − submit->bos[i].iova = 0; | |
| 278 | −} | |
| 279 | − | |
| 280 | 251 | /* This is where we make sure all the bo's are reserved and pin'd: */ |
| 281 | 252 | static int submit_lock_objects(struct msm_gem_submit *submit) |
| 282 | 253 | { |
| 283 | − int contended, slow_locked = -1, i, ret = 0; | |
| 284 | − | |
| 285 | −retry: | |
| 286 | − for (i = 0; i < submit->nr_bos; i++) { | |
| 287 | − struct drm_gem_object *obj = submit->bos[i].obj; | |
| 288 | − | |
| 289 | − if (slow_locked == i) | |
| 290 | − slow_locked = -1; | |
| 254 | + int ret; | |
| 291 | 255 | |
| 292 | − contended = i; | |
| 256 | + drm_exec_init(&submit->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, submit->nr_bos); | |
| 293 | 257 | |
| 294 | − if (!(submit->bos[i].flags & BO_LOCKED)) { | |
| 295 | − ret = dma_resv_lock_interruptible(obj->resv, | |
| 296 | − &submit->ticket); | |
| 258 | + drm_exec_until_all_locked (&submit->exec) { | |
| 259 | + for (unsigned i = 0; i < submit->nr_bos; i++) { | |
| 260 | + struct drm_gem_object *obj = submit->bos[i].obj; | |
| 261 | + ret = drm_exec_prepare_obj(&submit->exec, obj, 1); | |
| 262 | + drm_exec_retry_on_contention(&submit->exec); | |
| 297 | 263 | if (ret) |
| 298 | − goto fail; | |
| 299 | − submit->bos[i].flags |= BO_LOCKED; | |
| 264 | + goto error; | |
| 300 | 265 | } |
| 301 | 266 | } |
| 302 | 267 | |
| 303 | − ww_acquire_done(&submit->ticket); | |
| 304 | − | |
| 305 | 268 | return 0; |
| 306 | 269 | |
| 307 | −fail: | |
| 308 | − if (ret == -EALREADY) { | |
| 309 | − DRM_ERROR("handle %u at index %u already on submit list\n", | |
| 310 | − submit->bos[i].handle, i); | |
| 311 | − ret = -EINVAL; | |
| 312 | − } | |
| 313 | − | |
| 314 | − for (; i >= 0; i--) | |
| 315 | − submit_unlock_unpin_bo(submit, i); | |
| 316 | − | |
| 317 | − if (slow_locked > 0) | |
| 318 | − submit_unlock_unpin_bo(submit, slow_locked); | |
| 319 | − | |
| 320 | − if (ret == -EDEADLK) { | |
| 321 | − struct drm_gem_object *obj = submit->bos[contended].obj; | |
| 322 | − /* we lost out in a seqno race, lock and retry.. */ | |
| 323 | − ret = dma_resv_lock_slow_interruptible(obj->resv, | |
| 324 | − &submit->ticket); | |
| 325 | − if (!ret) { | |
| 326 | − submit->bos[contended].flags |= BO_LOCKED; | |
| 327 | − slow_locked = contended; | |
| 328 | − goto retry; | |
| 329 | − } | |
| 330 | − | |
| 331 | − /* Not expecting -EALREADY here, if the bo was already | |
| 332 | − * locked, we should have gotten -EALREADY already from | |
| 333 | − * the dma_resv_lock_interruptable() call. | |
| 334 | − */ | |
| 335 | − WARN_ON_ONCE(ret == -EALREADY); | |
| 336 | − } | |
| 337 | − | |
| 270 | +error: | |
| 338 | 271 | return ret; |
| 339 | 272 | } |
| 340 | 273 | |
| 341 | −static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) | |
| 274 | +static int submit_fence_sync(struct msm_gem_submit *submit) | |
| 342 | 275 | { |
| 343 | 276 | int i, ret = 0; |
| 344 | 277 | |
| @@ -346,22 +279,6 @@ static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) · 1 unmodified line | ||
| 346 | 279 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 347 | 280 | bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE; |
| 348 | 281 | |
| 349 | − /* NOTE: _reserve_shared() must happen before | |
| 350 | − * _add_shared_fence(), which makes this a slightly | |
| 351 | − * strange place to call it. OTOH this is a | |
| 352 | − * convenient can-fail point to hook it in. | |
| 353 | − */ | |
| 354 | − ret = dma_resv_reserve_fences(obj->resv, 1); | |
| 355 | − if (ret) | |
| 356 | − return ret; | |
| 357 | − | |
| 358 | − /* If userspace has determined that explicit fencing is | |
| 359 | − * used, it can disable implicit sync on the entire | |
| 360 | − * submit: | |
| 361 | − */ | |
| 362 | − if (no_implicit) | |
| 363 | − continue; | |
| 364 | − | |
| 365 | 282 | /* Otherwise userspace can ask for implicit sync to be |
| 366 | 283 | * disabled on specific buffers. This is useful for internal |
| 367 | 284 | * usermode driver managed buffers, suballocation, etc. |
| @@ -384,8 +301,6 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 16 unmodified lines | ||
| 384 | 301 | struct msm_drm_private *priv = submit->dev->dev_private; |
| 385 | 302 | int i, ret = 0; |
| 386 | 303 | |
| 387 | − submit->valid = true; | |
| 388 | − | |
| 389 | 304 | for (i = 0; i < submit->nr_bos; i++) { |
| 390 | 305 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 391 | 306 | struct msm_gem_vma *vma; |
| @@ -401,14 +316,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 9 unmodified lines | ||
| 401 | 316 | if (ret) |
| 402 | 317 | break; |
| 403 | 318 | |
| 404 | − if (vma->iova == submit->bos[i].iova) { | |
| 405 | − submit->bos[i].flags |= BO_VALID; | |
| 406 | − } else { | |
| 407 | − submit->bos[i].iova = vma->iova; | |
| 408 | − /* iova changed, so address in cmdstream is not valid: */ | |
| 409 | − submit->bos[i].flags &= ~BO_VALID; | |
| 410 | − submit->valid = false; | |
| 411 | − } | |
| 319 | + submit->bos[i].iova = vma->iova; | |
| 412 | 320 | } |
| 413 | 321 | |
| 414 | 322 | /* |
| @@ -421,13 +329,28 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 6 unmodified lines | ||
| 421 | 329 | mutex_lock(&priv->lru.lock); |
| 422 | 330 | for (i = 0; i < submit->nr_bos; i++) { |
| 423 | 331 | msm_gem_pin_obj_locked(submit->bos[i].obj); |
| 424 | − submit->bos[i].flags |= BO_PINNED; | |
| 425 | 332 | } |
| 426 | 333 | mutex_unlock(&priv->lru.lock); |
| 427 | 334 | |
| 335 | + submit->bos_pinned = true; | |
| 336 | + | |
| 428 | 337 | return ret; |
| 429 | 338 | } |
| 430 | 339 | |
| 340 | +static void submit_unpin_objects(struct msm_gem_submit *submit) | |
| 341 | +{ | |
| 342 | + if (!submit->bos_pinned) | |
| 343 | + return; | |
| 344 | + | |
| 345 | + for (int i = 0; i < submit->nr_bos; i++) { | |
| 346 | + struct drm_gem_object *obj = submit->bos[i].obj; | |
| 347 | + | |
| 348 | + msm_gem_unpin_locked(obj); | |
| 349 | + } | |
| 350 | + | |
| 351 | + submit->bos_pinned = false; | |
| 352 | +} | |
| 353 | + | |
| 431 | 354 | static void submit_attach_object_fences(struct msm_gem_submit *submit) |
| 432 | 355 | { |
| 433 | 356 | int i; |
| @@ -445,11 +368,11 @@ static void submit_attach_object_fences(struct msm_gem_submit *submit) · 11 unmodified lines | ||
| 445 | 368 | } |
| 446 | 369 | |
| 447 | 370 | static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, |
| 448 | − struct drm_gem_object **obj, uint64_t *iova, bool *valid) | |
| 371 | + struct drm_gem_object **obj, uint64_t *iova) | |
| 449 | 372 | { |
| 450 | 373 | if (idx >= submit->nr_bos) { |
| 451 | − DRM_ERROR("invalid buffer index: %u (out of %u)\n", | |
| 452 | − idx, submit->nr_bos); | |
| 374 | + SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n", | |
| 375 | + idx, submit->nr_bos); | |
| 453 | 376 | return -EINVAL; |
| 454 | 377 | } |
| 455 | 378 | |
| @@ -457,8 +380,6 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, · 1 unmodified line | ||
| 457 | 380 | *obj = submit->bos[idx].obj; |
| 458 | 381 | if (iova) |
| 459 | 382 | *iova = submit->bos[idx].iova; |
| 460 | − if (valid) | |
| 461 | − *valid = !!(submit->bos[idx].flags & BO_VALID); | |
| 462 | 383 | |
| 463 | 384 | return 0; |
| 464 | 385 | } |
| @@ -471,11 +392,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 6 unmodified lines | ||
| 471 | 392 | uint32_t *ptr; |
| 472 | 393 | int ret = 0; |
| 473 | 394 | |
| 474 | − if (!nr_relocs) | |
| 475 | − return 0; | |
| 476 | − | |
| 477 | 395 | if (offset % 4) { |
| 478 | − DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); | |
| 396 | + SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", offset); | |
| 479 | 397 | return -EINVAL; |
| 480 | 398 | } |
| 481 | 399 | |
| @@ -494,11 +412,10 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 12 unmodified lines | ||
| 494 | 412 | struct drm_msm_gem_submit_reloc submit_reloc = relocs[i]; |
| 495 | 413 | uint32_t off; |
| 496 | 414 | uint64_t iova; |
| 497 | − bool valid; | |
| 498 | 415 | |
| 499 | 416 | if (submit_reloc.submit_offset % 4) { |
| 500 | − DRM_ERROR("non-aligned reloc offset: %u\n", | |
| 501 | − submit_reloc.submit_offset); | |
| 417 | + SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n", | |
| 418 | + submit_reloc.submit_offset); | |
| 502 | 419 | ret = -EINVAL; |
| 503 | 420 | goto out; |
| 504 | 421 | } |
| @@ -508,18 +425,15 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 3 unmodified lines | ||
| 508 | 425 | |
| 509 | 426 | if ((off >= (obj->size / 4)) || |
| 510 | 427 | (off < last_offset)) { |
| 511 | − DRM_ERROR("invalid offset %u at reloc %u\n", off, i); | |
| 428 | + SUBMIT_ERROR(submit, "invalid offset %u at reloc %u\n", off, i); | |
| 512 | 429 | ret = -EINVAL; |
| 513 | 430 | goto out; |
| 514 | 431 | } |
| 515 | 432 | |
| 516 | − ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid); | |
| 433 | + ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova); | |
| 517 | 434 | if (ret) |
| 518 | 435 | goto out; |
| 519 | 436 | |
| 520 | − if (valid) | |
| 521 | − continue; | |
| 522 | − | |
| 523 | 437 | iova += submit_reloc.reloc_offset; |
| 524 | 438 | |
| 525 | 439 | if (submit_reloc.shift < 0) |
| @@ -544,18 +458,14 @@ out: · 18 unmodified lines | ||
| 544 | 458 | */ |
| 545 | 459 | static void submit_cleanup(struct msm_gem_submit *submit, bool error) |
| 546 | 460 | { |
| 547 | − unsigned cleanup_flags = BO_LOCKED; | |
| 548 | − unsigned i; | |
| 549 | − | |
| 550 | − if (error) | |
| 551 | − cleanup_flags |= BO_PINNED; | |
| 552 | − | |
| 553 | − for (i = 0; i < submit->nr_bos; i++) { | |
| 554 | − struct drm_gem_object *obj = submit->bos[i].obj; | |
| 555 | − submit_cleanup_bo(submit, i, cleanup_flags); | |
| 556 | − if (error) | |
| 557 | − drm_gem_object_put(obj); | |
| 461 | + if (error) { | |
| 462 | + submit_unpin_objects(submit); | |
| 463 | + /* job wasn't enqueued to scheduler, so early retirement: */ | |
| 464 | + msm_submit_retire(submit); | |
| 558 | 465 | } |
| 466 | + | |
| 467 | + if (submit->exec.objects) | |
| 468 | + drm_exec_fini(&submit->exec); | |
| 559 | 469 | } |
| 560 | 470 | |
| 561 | 471 | void msm_submit_retire(struct msm_gem_submit *submit) |
| @@ -749,7 +659,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 187 unmodified lines | ||
| 749 | 659 | struct msm_submit_post_dep *post_deps = NULL; |
| 750 | 660 | struct drm_syncobj **syncobjs_to_reset = NULL; |
| 751 | 661 | int out_fence_fd = -1; |
| 752 | − bool has_ww_ticket = false; | |
| 753 | 662 | unsigned i; |
| 754 | 663 | int ret; |
| 755 | 664 | |
| @@ -855,15 +764,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 99 unmodified lines | ||
| 855 | 764 | goto out; |
| 856 | 765 | |
| 857 | 766 | /* copy_*_user while holding a ww ticket upsets lockdep */ |
| 858 | − ww_acquire_init(&submit->ticket, &reservation_ww_class); | |
| 859 | − has_ww_ticket = true; | |
| 860 | 767 | ret = submit_lock_objects(submit); |
| 861 | 768 | if (ret) |
| 862 | 769 | goto out; |
| 863 | 770 | |
| 864 | − ret = submit_fence_sync(submit, !!(args->flags & MSM_SUBMIT_NO_IMPLICIT)); | |
| 865 | − if (ret) | |
| 866 | − goto out; | |
| 771 | + if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) { | |
| 772 | + ret = submit_fence_sync(submit); | |
| 773 | + if (ret) | |
| 774 | + goto out; | |
| 775 | + } | |
| 867 | 776 | |
| 868 | 777 | ret = submit_pin_objects(submit); |
| 869 | 778 | if (ret) |
| @@ -873,32 +782,27 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 3 unmodified lines | ||
| 873 | 782 | struct drm_gem_object *obj; |
| 874 | 783 | uint64_t iova; |
| 875 | 784 | |
| 876 | − ret = submit_bo(submit, submit->cmd[i].idx, | |
| 877 | − &obj, &iova, NULL); | |
| 785 | + ret = submit_bo(submit, submit->cmd[i].idx, &obj, &iova); | |
| 878 | 786 | if (ret) |
| 879 | 787 | goto out; |
| 880 | 788 | |
| 881 | 789 | if (!submit->cmd[i].size || |
| 882 | 790 | ((submit->cmd[i].size + submit->cmd[i].offset) > |
| 883 | 791 | obj->size / 4)) { |
| 884 | − DRM_ERROR("invalid cmdstream size: %u\n", submit->cmd[i].size * 4); | |
| 792 | + SUBMIT_ERROR(submit, "invalid cmdstream size: %u\n", submit->cmd[i].size * 4); | |
| 885 | 793 | ret = -EINVAL; |
| 886 | 794 | goto out; |
| 887 | 795 | } |
| 888 | 796 | |
| 889 | 797 | submit->cmd[i].iova = iova + (submit->cmd[i].offset * 4); |
| 890 | 798 | |
| 891 | − if (submit->valid) | |
| 799 | + if (likely(!submit->cmd[i].nr_relocs)) | |
| 892 | 800 | continue; |
| 893 | 801 | |
| 894 | 802 | if (!gpu->allow_relocs) { |
| 895 | − if (submit->cmd[i].nr_relocs) { | |
| 896 | − DRM_ERROR("relocs not allowed\n"); | |
| 897 | − ret = -EINVAL; | |
| 898 | − goto out; | |
| 899 | − } | |
| 900 | − | |
| 901 | − continue; | |
| 803 | + SUBMIT_ERROR(submit, "relocs not allowed\n"); | |
| 804 | + ret = -EINVAL; | |
| 805 | + goto out; | |
| 902 | 806 | } |
| 903 | 807 | |
| 904 | 808 | ret = submit_reloc(submit, obj, submit->cmd[i].offset * 4, |
| @@ -974,6 +878,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 69 unmodified lines | ||
| 974 | 878 | } |
| 975 | 879 | } |
| 976 | 880 | |
| 881 | + if (ret) | |
| 882 | + goto out; | |
| 883 | + | |
| 977 | 884 | submit_attach_object_fences(submit); |
| 978 | 885 | |
| 979 | 886 | /* The scheduler owns a ref now: */ |
| @@ -993,8 +900,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 13 unmodified lines | ||
| 993 | 900 | |
| 994 | 901 | out: |
| 995 | 902 | submit_cleanup(submit, !!ret); |
| 996 | − if (has_ww_ticket) | |
| 997 | − ww_acquire_fini(&submit->ticket); | |
| 998 | 903 | out_unlock: |
| 999 | 904 | mutex_unlock(&queue->lock); |
| 1000 | 905 | out_post_unlock: |
| @@ -292,8 +292,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, · 291 unmodified lines | ||
| 292 | 292 | /* Set the active crash state to be dumped on failure */ |
| 293 | 293 | gpu->crashstate = state; |
| 294 | 294 | |
| 295 | − /* FIXME: Release the crashstate if this errors out? */ | |
| 296 | − dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL, | |
| 295 | + dev_coredumpm(&gpu->pdev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL, | |
| 297 | 296 | msm_gpu_devcoredump_read, msm_gpu_devcoredump_free); |
| 298 | 297 | } |
| 299 | 298 | #else |
| @@ -366,29 +365,31 @@ static void recover_worker(struct kthread_work *work) · 66 unmodified lines | ||
| 366 | 365 | DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name); |
| 367 | 366 | |
| 368 | 367 | submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); |
| 369 | − if (submit) { | |
| 370 | − /* Increment the fault counts */ | |
| 371 | − submit->queue->faults++; | |
| 372 | − if (submit->aspace) | |
| 373 | − submit->aspace->faults++; | |
| 374 | 368 | |
| 375 | − get_comm_cmdline(submit, &comm, &cmd); | |
| 369 | + /* | |
| 370 | + * If the submit retired while we were waiting for the worker to run, | |
| 371 | + * or waiting to acquire the gpu lock, then nothing more to do. | |
| 372 | + */ | |
| 373 | + if (!submit) | |
| 374 | + goto out_unlock; | |
| 376 | 375 | |
| 377 | − if (comm && cmd) { | |
| 378 | − DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", | |
| 379 | − gpu->name, comm, cmd); | |
| 376 | + /* Increment the fault counts */ | |
| 377 | + submit->queue->faults++; | |
| 378 | + if (submit->aspace) | |
| 379 | + submit->aspace->faults++; | |
| 380 | 380 | |
| 381 | − msm_rd_dump_submit(priv->hangrd, submit, | |
| 382 | − "offending task: %s (%s)", comm, cmd); | |
| 383 | − } else { | |
| 384 | − msm_rd_dump_submit(priv->hangrd, submit, NULL); | |
| 385 | − } | |
| 381 | + get_comm_cmdline(submit, &comm, &cmd); | |
| 382 | + | |
| 383 | + if (comm && cmd) { | |
| 384 | + DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", | |
| 385 | + gpu->name, comm, cmd); | |
| 386 | + | |
| 387 | + msm_rd_dump_submit(priv->hangrd, submit, | |
| 388 | + "offending task: %s (%s)", comm, cmd); | |
| 386 | 389 | } else { |
| 387 | − /* | |
| 388 | − * We couldn't attribute this fault to any particular context, | |
| 389 | − * so increment the global fault count instead. | |
| 390 | − */ | |
| 391 | − gpu->global_faults++; | |
| 390 | + DRM_DEV_ERROR(dev->dev, "%s: offending task: unknown\n", gpu->name); | |
| 391 | + | |
| 392 | + msm_rd_dump_submit(priv->hangrd, submit, NULL); | |
| 392 | 393 | } |
| 393 | 394 | |
| 394 | 395 | /* Record the crash state */ |
| @@ -441,6 +442,7 @@ static void recover_worker(struct kthread_work *work) · 46 unmodified lines | ||
| 441 | 442 | |
| 442 | 443 | pm_runtime_put(&gpu->pdev->dev); |
| 443 | 444 | |
| 445 | +out_unlock: | |
| 444 | 446 | mutex_unlock(&gpu->lock); |
| 445 | 447 | |
| 446 | 448 | msm_gpu_retire(gpu); |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #define MIN_IB_BW 400000000UL /* Min ib vote 400MB */ |
| 30 | 30 | |
| 31 | +#define DEFAULT_REG_BW 153600 /* Used in mdss fbdev driver */ | |
| 32 | + | |
| 31 | 33 | struct msm_mdss { |
| 32 | 34 | struct device *dev; |
| 33 | 35 | |
| @@ -40,8 +42,9 @@ struct msm_mdss { · 6 unmodified lines | ||
| 40 | 42 | struct irq_domain *domain; |
| 41 | 43 | } irq_controller; |
| 42 | 44 | const struct msm_mdss_data *mdss_data; |
| 43 | − struct icc_path *path[2]; | |
| 44 | − u32 num_paths; | |
| 45 | + struct icc_path *mdp_path[2]; | |
| 46 | + u32 num_mdp_paths; | |
| 47 | + struct icc_path *reg_bus_path; | |
| 45 | 48 | }; |
| 46 | 49 | |
| 47 | 50 | static int msm_mdss_parse_data_bus_icc_path(struct device *dev, |
| @@ -49,38 +52,26 @@ static int msm_mdss_parse_data_bus_icc_path(struct device *dev, · 1 unmodified line | ||
| 49 | 52 | { |
| 50 | 53 | struct icc_path *path0; |
| 51 | 54 | struct icc_path *path1; |
| 55 | + struct icc_path *reg_bus_path; | |
| 52 | 56 | |
| 53 | − path0 = of_icc_get(dev, "mdp0-mem"); | |
| 57 | + path0 = devm_of_icc_get(dev, "mdp0-mem"); | |
| 54 | 58 | if (IS_ERR_OR_NULL(path0)) |
| 55 | 59 | return PTR_ERR_OR_ZERO(path0); |
| 56 | 60 | |
| 57 | − msm_mdss->path[0] = path0; | |
| 58 | − msm_mdss->num_paths = 1; | |
| 61 | + msm_mdss->mdp_path[0] = path0; | |
| 62 | + msm_mdss->num_mdp_paths = 1; | |
| 59 | 63 | |
| 60 | − path1 = of_icc_get(dev, "mdp1-mem"); | |
| 64 | + path1 = devm_of_icc_get(dev, "mdp1-mem"); | |
| 61 | 65 | if (!IS_ERR_OR_NULL(path1)) { |
| 62 | − msm_mdss->path[1] = path1; | |
| 63 | − msm_mdss->num_paths++; | |
| 66 | + msm_mdss->mdp_path[1] = path1; | |
| 67 | + msm_mdss->num_mdp_paths++; | |
| 64 | 68 | } |
| 65 | 69 | |
| 66 | − return 0; | |
| 67 | −} | |
| 68 | − | |
| 69 | −static void msm_mdss_put_icc_path(void *data) | |
| 70 | −{ | |
| 71 | − struct msm_mdss *msm_mdss = data; | |
| 72 | − int i; | |
| 73 | − | |
| 74 | − for (i = 0; i < msm_mdss->num_paths; i++) | |
| 75 | − icc_put(msm_mdss->path[i]); | |
| 76 | −} | |
| 77 | − | |
| 78 | −static void msm_mdss_icc_request_bw(struct msm_mdss *msm_mdss, unsigned long bw) | |
| 79 | −{ | |
| 80 | − int i; | |
| 70 | + reg_bus_path = of_icc_get(dev, "cpu-cfg"); | |
| 71 | + if (!IS_ERR_OR_NULL(reg_bus_path)) | |
| 72 | + msm_mdss->reg_bus_path = reg_bus_path; | |
| 81 | 73 | |
| 82 | − for (i = 0; i < msm_mdss->num_paths; i++) | |
| 83 | − icc_set_bw(msm_mdss->path[i], 0, Bps_to_icc(bw)); | |
| 74 | + return 0; | |
| 84 | 75 | } |
| 85 | 76 | |
| 86 | 77 | static void msm_mdss_irq(struct irq_desc *desc) |
| @@ -236,14 +227,22 @@ const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev) · 149 unmodified lines | ||
| 236 | 227 | |
| 237 | 228 | static int msm_mdss_enable(struct msm_mdss *msm_mdss) |
| 238 | 229 | { |
| 239 | − int ret; | |
| 230 | + int ret, i; | |
| 240 | 231 | |
| 241 | 232 | /* |
| 242 | 233 | * Several components have AXI clocks that can only be turned on if |
| 243 | 234 | * the interconnect is enabled (non-zero bandwidth). Let's make sure |
| 244 | 235 | * that the interconnects are at least at a minimum amount. |
| 245 | 236 | */ |
| 246 | − msm_mdss_icc_request_bw(msm_mdss, MIN_IB_BW); | |
| 237 | + for (i = 0; i < msm_mdss->num_mdp_paths; i++) | |
| 238 | + icc_set_bw(msm_mdss->mdp_path[i], 0, Bps_to_icc(MIN_IB_BW)); | |
| 239 | + | |
| 240 | + if (msm_mdss->mdss_data && msm_mdss->mdss_data->reg_bus_bw) | |
| 241 | + icc_set_bw(msm_mdss->reg_bus_path, 0, | |
| 242 | + msm_mdss->mdss_data->reg_bus_bw); | |
| 243 | + else | |
| 244 | + icc_set_bw(msm_mdss->reg_bus_path, 0, | |
| 245 | + DEFAULT_REG_BW); | |
| 247 | 246 | |
| 248 | 247 | ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks); |
| 249 | 248 | if (ret) { |
| @@ -295,8 +294,15 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) · 45 unmodified lines | ||
| 295 | 294 | |
| 296 | 295 | static int msm_mdss_disable(struct msm_mdss *msm_mdss) |
| 297 | 296 | { |
| 297 | + int i; | |
| 298 | + | |
| 298 | 299 | clk_bulk_disable_unprepare(msm_mdss->num_clocks, msm_mdss->clocks); |
| 299 | − msm_mdss_icc_request_bw(msm_mdss, 0); | |
| 300 | + | |
| 301 | + for (i = 0; i < msm_mdss->num_mdp_paths; i++) | |
| 302 | + icc_set_bw(msm_mdss->mdp_path[i], 0, 0); | |
| 303 | + | |
| 304 | + if (msm_mdss->reg_bus_path) | |
| 305 | + icc_set_bw(msm_mdss->reg_bus_path, 0, 0); | |
| 300 | 306 | |
| 301 | 307 | return 0; |
| 302 | 308 | } |
| @@ -384,6 +390,8 @@ static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5 · 81 unmodified lines | ||
| 384 | 390 | if (!msm_mdss) |
| 385 | 391 | return ERR_PTR(-ENOMEM); |
| 386 | 392 | |
| 393 | + msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev); | |
| 394 | + | |
| 387 | 395 | msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss"); |
| 388 | 396 | if (IS_ERR(msm_mdss->mmio)) |
| 389 | 397 | return ERR_CAST(msm_mdss->mmio); |
| @@ -391,9 +399,6 @@ static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5 · 1 unmodified line | ||
| 391 | 399 | dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio); |
| 392 | 400 | |
| 393 | 401 | ret = msm_mdss_parse_data_bus_icc_path(&pdev->dev, msm_mdss); |
| 394 | − if (ret) | |
| 395 | − return ERR_PTR(ret); | |
| 396 | − ret = devm_add_action_or_reset(&pdev->dev, msm_mdss_put_icc_path, msm_mdss); | |
| 397 | 402 | if (ret) |
| 398 | 403 | return ERR_PTR(ret); |
| 399 | 404 | |
| @@ -477,8 +482,6 @@ static int mdss_probe(struct platform_device *pdev) · 77 unmodified lines | ||
| 477 | 482 | if (IS_ERR(mdss)) |
| 478 | 483 | return PTR_ERR(mdss); |
| 479 | 484 | |
| 480 | − mdss->mdss_data = of_device_get_match_data(&pdev->dev); | |
| 481 | − | |
| 482 | 485 | platform_set_drvdata(pdev, mdss); |
| 483 | 486 | |
| 484 | 487 | /* |
| @@ -510,11 +513,13 @@ static const struct msm_mdss_data msm8998_data = { · 25 unmodified lines | ||
| 510 | 513 | .ubwc_enc_version = UBWC_1_0, |
| 511 | 514 | .ubwc_dec_version = UBWC_1_0, |
| 512 | 515 | .highest_bank_bit = 2, |
| 516 | + .reg_bus_bw = 76800, | |
| 513 | 517 | }; |
| 514 | 518 | |
| 515 | 519 | static const struct msm_mdss_data qcm2290_data = { |
| 516 | 520 | /* no UBWC */ |
| 517 | 521 | .highest_bank_bit = 0x2, |
| 522 | + .reg_bus_bw = 76800, | |
| 518 | 523 | }; |
| 519 | 524 | |
| 520 | 525 | static const struct msm_mdss_data sc7180_data = { |
| @@ -522,6 +527,7 @@ static const struct msm_mdss_data sc7180_data = { · 1 unmodified line | ||
| 522 | 527 | .ubwc_dec_version = UBWC_2_0, |
| 523 | 528 | .ubwc_static = 0x1e, |
| 524 | 529 | .highest_bank_bit = 0x3, |
| 530 | + .reg_bus_bw = 76800, | |
| 525 | 531 | }; |
| 526 | 532 | |
| 527 | 533 | static const struct msm_mdss_data sc7280_data = { |
| @@ -531,6 +537,7 @@ static const struct msm_mdss_data sc7280_data = { · 3 unmodified lines | ||
| 531 | 537 | .ubwc_static = 1, |
| 532 | 538 | .highest_bank_bit = 1, |
| 533 | 539 | .macrotile_mode = 1, |
| 540 | + .reg_bus_bw = 74000, | |
| 534 | 541 | }; |
| 535 | 542 | |
| 536 | 543 | static const struct msm_mdss_data sc8180x_data = { |
| @@ -538,6 +545,7 @@ static const struct msm_mdss_data sc8180x_data = { · 1 unmodified line | ||
| 538 | 545 | .ubwc_dec_version = UBWC_3_0, |
| 539 | 546 | .highest_bank_bit = 3, |
| 540 | 547 | .macrotile_mode = 1, |
| 548 | + .reg_bus_bw = 76800, | |
| 541 | 549 | }; |
| 542 | 550 | |
| 543 | 551 | static const struct msm_mdss_data sc8280xp_data = { |
| @@ -545,14 +553,22 @@ static const struct msm_mdss_data sc8280xp_data = { · 1 unmodified line | ||
| 545 | 553 | .ubwc_dec_version = UBWC_4_0, |
| 546 | 554 | .ubwc_swizzle = 6, |
| 547 | 555 | .ubwc_static = 1, |
| 548 | − .highest_bank_bit = 2, | |
| 556 | + .highest_bank_bit = 3, | |
| 549 | 557 | .macrotile_mode = 1, |
| 558 | + .reg_bus_bw = 76800, | |
| 559 | +}; | |
| 560 | + | |
| 561 | +static const struct msm_mdss_data sdm670_data = { | |
| 562 | + .ubwc_enc_version = UBWC_2_0, | |
| 563 | + .ubwc_dec_version = UBWC_2_0, | |
| 564 | + .highest_bank_bit = 1, | |
| 550 | 565 | }; |
| 551 | 566 | |
| 552 | 567 | static const struct msm_mdss_data sdm845_data = { |
| 553 | 568 | .ubwc_enc_version = UBWC_2_0, |
| 554 | 569 | .ubwc_dec_version = UBWC_2_0, |
| 555 | 570 | .highest_bank_bit = 2, |
| 571 | + .reg_bus_bw = 76800, | |
| 556 | 572 | }; |
| 557 | 573 | |
| 558 | 574 | static const struct msm_mdss_data sm6350_data = { |
| @@ -561,12 +577,14 @@ static const struct msm_mdss_data sm6350_data = { · 2 unmodified lines | ||
| 561 | 577 | .ubwc_swizzle = 6, |
| 562 | 578 | .ubwc_static = 0x1e, |
| 563 | 579 | .highest_bank_bit = 1, |
| 580 | + .reg_bus_bw = 76800, | |
| 564 | 581 | }; |
| 565 | 582 | |
| 566 | 583 | static const struct msm_mdss_data sm8150_data = { |
| 567 | 584 | .ubwc_enc_version = UBWC_3_0, |
| 568 | 585 | .ubwc_dec_version = UBWC_3_0, |
| 569 | 586 | .highest_bank_bit = 2, |
| 587 | + .reg_bus_bw = 76800, | |
| 570 | 588 | }; |
| 571 | 589 | |
| 572 | 590 | static const struct msm_mdss_data sm6115_data = { |
| @@ -575,6 +593,7 @@ static const struct msm_mdss_data sm6115_data = { · 2 unmodified lines | ||
| 575 | 593 | .ubwc_swizzle = 7, |
| 576 | 594 | .ubwc_static = 0x11f, |
| 577 | 595 | .highest_bank_bit = 0x1, |
| 596 | + .reg_bus_bw = 76800, | |
| 578 | 597 | }; |
| 579 | 598 | |
| 580 | 599 | static const struct msm_mdss_data sm6125_data = { |
| @@ -592,6 +611,18 @@ static const struct msm_mdss_data sm8250_data = { · 11 unmodified lines | ||
| 592 | 611 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ |
| 593 | 612 | .highest_bank_bit = 3, |
| 594 | 613 | .macrotile_mode = 1, |
| 614 | + .reg_bus_bw = 76800, | |
| 615 | +}; | |
| 616 | + | |
| 617 | +static const struct msm_mdss_data sm8350_data = { | |
| 618 | + .ubwc_enc_version = UBWC_4_0, | |
| 619 | + .ubwc_dec_version = UBWC_4_0, | |
| 620 | + .ubwc_swizzle = 6, | |
| 621 | + .ubwc_static = 1, | |
| 622 | + /* TODO: highest_bank_bit = 2 for LP_DDR4 */ | |
| 623 | + .highest_bank_bit = 3, | |
| 624 | + .macrotile_mode = 1, | |
| 625 | + .reg_bus_bw = 74000, | |
| 595 | 626 | }; |
| 596 | 627 | |
| 597 | 628 | static const struct msm_mdss_data sm8550_data = { |
| @@ -602,11 +633,13 @@ static const struct msm_mdss_data sm8550_data = { · 4 unmodified lines | ||
| 602 | 633 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ |
| 603 | 634 | .highest_bank_bit = 3, |
| 604 | 635 | .macrotile_mode = 1, |
| 636 | + .reg_bus_bw = 57000, | |
| 605 | 637 | }; |
| 606 | 638 | static const struct of_device_id mdss_dt_match[] = { |
| 607 | 639 | { .compatible = "qcom,mdss" }, |
| 608 | 640 | { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data }, |
| 609 | 641 | { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data }, |
| 642 | + { .compatible = "qcom,sdm670-mdss", .data = &sdm670_data }, | |
| 610 | 643 | { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data }, |
| 611 | 644 | { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, |
| 612 | 645 | { .compatible = "qcom,sc7280-mdss", .data = &sc7280_data }, |
| @@ -618,9 +651,10 @@ static const struct of_device_id mdss_dt_match[] = { · 5 unmodified lines | ||
| 618 | 651 | { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data }, |
| 619 | 652 | { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data }, |
| 620 | 653 | { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, |
| 621 | − { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, | |
| 622 | − { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data }, | |
| 654 | + { .compatible = "qcom,sm8350-mdss", .data = &sm8350_data }, | |
| 655 | + { .compatible = "qcom,sm8450-mdss", .data = &sm8350_data }, | |
| 623 | 656 | { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, |
| 657 | + { .compatible = "qcom,sm8650-mdss", .data = &sm8550_data}, | |
| 624 | 658 | {} |
| 625 | 659 | }; |
| 626 | 660 | MODULE_DEVICE_TABLE(of, mdss_dt_match); |
| @@ -14,6 +14,7 @@ struct msm_mdss_data { · 13 unmodified lines | ||
| 14 | 14 | u32 ubwc_static; |
| 15 | 15 | u32 highest_bank_bit; |
| 16 | 16 | u32 macrotile_mode; |
| 17 | + u32 reg_bus_bw; | |
| 17 | 18 | }; |
| 18 | 19 | |
| 19 | 20 | #define UBWC_1_0 0x10000000 |
| @@ -270,6 +270,9 @@ int msm_rd_debugfs_init(struct drm_minor *minor) · 269 unmodified lines | ||
| 270 | 270 | struct msm_rd_state *rd; |
| 271 | 271 | int ret; |
| 272 | 272 | |
| 273 | + if (!priv->gpu_pdev) | |
| 274 | + return 0; | |
| 275 | + | |
| 273 | 276 | /* only create on first minor: */ |
| 274 | 277 | if (priv->rd) |
| 275 | 278 | return 0; |
| @@ -29,9 +29,10 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job) · 28 unmodified lines | ||
| 29 | 29 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 30 | 30 | |
| 31 | 31 | msm_gem_unpin_active(obj); |
| 32 | − submit->bos[i].flags &= ~BO_PINNED; | |
| 33 | 32 | } |
| 34 | 33 | |
| 34 | + submit->bos_pinned = false; | |
| 35 | + | |
| 35 | 36 | mutex_unlock(&priv->lru.lock); |
| 36 | 37 | |
| 37 | 38 | msm_gpu_submit(gpu, submit); |
| @@ -1347,7 +1347,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job, · 1346 unmodified lines | ||
| 1347 | 1347 | } |
| 1348 | 1348 | } |
| 1349 | 1349 | |
| 1350 | − drm_exec_init(exec, vme->flags); | |
| 1350 | + drm_exec_init(exec, vme->flags, 0); | |
| 1351 | 1351 | drm_exec_until_all_locked(exec) { |
| 1352 | 1352 | ret = bind_lock_validate(job, exec, vme->num_fences); |
| 1353 | 1353 | drm_exec_retry_on_contention(exec); |
| @@ -46,7 +46,7 @@ static void sanitycheck(struct kunit *test) · 45 unmodified lines | ||
| 46 | 46 | { |
| 47 | 47 | struct drm_exec exec; |
| 48 | 48 | |
| 49 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 49 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 50 | 50 | drm_exec_fini(&exec); |
| 51 | 51 | KUNIT_SUCCEED(test); |
| 52 | 52 | } |
| @@ -60,7 +60,7 @@ static void test_lock(struct kunit *test) · 7 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); |
| 62 | 62 | |
| 63 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 63 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 64 | 64 | drm_exec_until_all_locked(&exec) { |
| 65 | 65 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 66 | 66 | drm_exec_retry_on_contention(&exec); |
| @@ -80,7 +80,7 @@ static void test_lock_unlock(struct kunit *test) · 13 unmodified lines | ||
| 80 | 80 | |
| 81 | 81 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); |
| 82 | 82 | |
| 83 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 83 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 84 | 84 | drm_exec_until_all_locked(&exec) { |
| 85 | 85 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 86 | 86 | drm_exec_retry_on_contention(&exec); |
| @@ -107,7 +107,7 @@ static void test_duplicates(struct kunit *test) · 20 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); |
| 109 | 109 | |
| 110 | − drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES); | |
| 110 | + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); | |
| 111 | 111 | drm_exec_until_all_locked(&exec) { |
| 112 | 112 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 113 | 113 | drm_exec_retry_on_contention(&exec); |
| @@ -134,7 +134,7 @@ static void test_prepare(struct kunit *test) · 20 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); |
| 136 | 136 | |
| 137 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 137 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 138 | 138 | drm_exec_until_all_locked(&exec) { |
| 139 | 139 | ret = drm_exec_prepare_obj(&exec, &gobj, 1); |
| 140 | 140 | drm_exec_retry_on_contention(&exec); |
| @@ -159,7 +159,7 @@ static void test_prepare_array(struct kunit *test) · 18 unmodified lines | ||
| 159 | 159 | drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE); |
| 160 | 160 | drm_gem_private_object_init(priv->drm, &gobj2, PAGE_SIZE); |
| 161 | 161 | |
| 162 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 162 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 163 | 163 | drm_exec_until_all_locked(&exec) |
| 164 | 164 | ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array), |
| 165 | 165 | 1); |
| @@ -174,14 +174,14 @@ static void test_multiple_loops(struct kunit *test) · 8 unmodified lines | ||
| 174 | 174 | { |
| 175 | 175 | struct drm_exec exec; |
| 176 | 176 | |
| 177 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 177 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 178 | 178 | drm_exec_until_all_locked(&exec) |
| 179 | 179 | { |
| 180 | 180 | break; |
| 181 | 181 | } |
| 182 | 182 | drm_exec_fini(&exec); |
| 183 | 183 | |
| 184 | − drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT); | |
| 184 | + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); | |
| 185 | 185 | drm_exec_until_all_locked(&exec) |
| 186 | 186 | { |
| 187 | 187 | break; |
| @@ -135,7 +135,7 @@ static inline bool drm_exec_is_contended(struct drm_exec *exec) · 134 unmodified lines | ||
| 135 | 135 | return !!exec->contended; |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | −void drm_exec_init(struct drm_exec *exec, uint32_t flags); | |
| 138 | +void drm_exec_init(struct drm_exec *exec, uint32_t flags, unsigned nr); | |
| 139 | 139 | void drm_exec_fini(struct drm_exec *exec); |
| 140 | 140 | bool drm_exec_cleanup(struct drm_exec *exec); |
| 141 | 141 | int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj); |
| @@ -86,6 +86,7 @@ struct drm_msm_timespec { · 85 unmodified lines | ||
| 86 | 86 | #define MSM_PARAM_CMDLINE 0x0d /* WO: override for task cmdline */ |
| 87 | 87 | #define MSM_PARAM_VA_START 0x0e /* RO: start of valid GPU iova range */ |
| 88 | 88 | #define MSM_PARAM_VA_SIZE 0x0f /* RO: size of valid GPU iova range (bytes) */ |
| 89 | +#define MSM_PARAM_HIGHEST_BANK_BIT 0x10 /* RO */ | |
| 89 | 90 | |
| 90 | 91 | /* For backwards compat. The original support for preemption was based on |
| 91 | 92 | * a single ring per priority level so # of priority levels equals the # |
| @@ -139,6 +140,8 @@ struct drm_msm_gem_new { · 47 unmodified lines | ||
| 139 | 140 | #define MSM_INFO_GET_NAME 0x03 /* get debug name, returned by pointer */ |
| 140 | 141 | #define MSM_INFO_SET_IOVA 0x04 /* set the iova, passed by value */ |
| 141 | 142 | #define MSM_INFO_GET_FLAGS 0x05 /* get the MSM_BO_x flags */ |
| 143 | +#define MSM_INFO_SET_METADATA 0x06 /* set userspace metadata */ | |
| 144 | +#define MSM_INFO_GET_METADATA 0x07 /* get userspace metadata */ | |
| 142 | 145 | |
| 143 | 146 | struct drm_msm_gem_info { |
| 144 | 147 | __u32 handle; /* in */ |