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 | - qcom,sc8280xp-edp | 26 | - qcom,sc8280xp-edp |
| 27 | - qcom,sdm845-dp | 27 | - qcom,sdm845-dp |
| 28 | - qcom,sm8350-dp | 28 | - qcom,sm8350-dp |
| 29 | - qcom,sm8650-dp | ||
| 29 | - items: | 30 | - items: |
| 30 | - enum: | 31 | - enum: |
| 32 | - qcom,sm8150-dp | ||
| 31 | - qcom,sm8250-dp | 33 | - qcom,sm8250-dp |
| 32 | - qcom,sm8450-dp | 34 | - qcom,sm8450-dp |
| 33 | - qcom,sm8550-dp | 35 | - qcom,sm8550-dp |
| @@ -25,6 +25,7 @@ properties: · 24 unmodified lines | |||
| 25 | - qcom,sc7180-dsi-ctrl | 25 | - qcom,sc7180-dsi-ctrl |
| 26 | - qcom,sc7280-dsi-ctrl | 26 | - qcom,sc7280-dsi-ctrl |
| 27 | - qcom,sdm660-dsi-ctrl | 27 | - qcom,sdm660-dsi-ctrl |
| 28 | - qcom,sdm670-dsi-ctrl | ||
| 28 | - qcom,sdm845-dsi-ctrl | 29 | - qcom,sdm845-dsi-ctrl |
| 29 | - qcom,sm6115-dsi-ctrl | 30 | - qcom,sm6115-dsi-ctrl |
| 30 | - qcom,sm6125-dsi-ctrl | 31 | - qcom,sm6125-dsi-ctrl |
| @@ -35,6 +36,7 @@ properties: · 4 unmodified lines | |||
| 35 | - qcom,sm8350-dsi-ctrl | 36 | - qcom,sm8350-dsi-ctrl |
| 36 | - qcom,sm8450-dsi-ctrl | 37 | - qcom,sm8450-dsi-ctrl |
| 37 | - qcom,sm8550-dsi-ctrl | 38 | - qcom,sm8550-dsi-ctrl |
| 39 | - qcom,sm8650-dsi-ctrl | ||
| 38 | - const: qcom,mdss-dsi-ctrl | 40 | - const: qcom,mdss-dsi-ctrl |
| 39 | - enum: | 41 | - enum: |
| 40 | - qcom,dsi-ctrl-6g-qcm2290 | 42 | - qcom,dsi-ctrl-6g-qcm2290 |
| @@ -333,6 +335,7 @@ allOf: · 292 unmodified lines | |||
| 333 | - qcom,sm8350-dsi-ctrl | 335 | - qcom,sm8350-dsi-ctrl |
| 334 | - qcom,sm8450-dsi-ctrl | 336 | - qcom,sm8450-dsi-ctrl |
| 335 | - qcom,sm8550-dsi-ctrl | 337 | - qcom,sm8550-dsi-ctrl |
| 338 | - qcom,sm8650-dsi-ctrl | ||
| 336 | then: | 339 | then: |
| 337 | properties: | 340 | properties: |
| 338 | clocks: | 341 | clocks: |
| @@ -22,6 +22,7 @@ properties: · 21 unmodified lines | |||
| 22 | - qcom,sm8350-dsi-phy-5nm | 22 | - qcom,sm8350-dsi-phy-5nm |
| 23 | - qcom,sm8450-dsi-phy-5nm | 23 | - qcom,sm8450-dsi-phy-5nm |
| 24 | - qcom,sm8550-dsi-phy-4nm | 24 | - qcom,sm8550-dsi-phy-4nm |
| 25 | - qcom,sm8650-dsi-phy-4nm | ||
| 25 | 26 | ||
| 26 | reg: | 27 | reg: |
| 27 | items: | 28 | items: |
| @@ -61,17 +61,27 @@ properties: · 60 unmodified lines | |||
| 61 | 61 | ||
| 62 | ranges: true | 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 | interconnects: | 66 | interconnects: |
| 65 | minItems: 1 | 67 | minItems: 1 |
| 66 | items: | 68 | items: |
| 67 | - description: Interconnect path from mdp0 (or a single mdp) port to the data bus | 69 | - description: Interconnect path from mdp0 (or a single mdp) port to the data bus |
| 68 | - description: Interconnect path from mdp1 port to the data bus | 70 | - description: Interconnect path from mdp1 port to the data bus |
| 71 | - description: Interconnect path from CPU to the reg bus | ||
| 69 | 72 | ||
| 70 | interconnect-names: | 73 | interconnect-names: |
| 71 | minItems: 1 | 74 | oneOf: |
| 72 | items: | 75 | - minItems: 1 |
| 73 | - const: mdp0-mem | 76 | items: |
| 74 | - const: mdp1-mem | 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 | resets: | 86 | resets: |
| 77 | items: | 87 | items: |
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | |||
| 36 | maxItems: 2 | 36 | maxItems: 2 |
| 37 | 37 | ||
| 38 | interconnects: | 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 | interconnect-names: | 43 | interconnect-names: |
| 42 | maxItems: 1 | 44 | items: |
| 45 | - const: mdp0-mem | ||
| 46 | - const: cpu-cfg | ||
| 43 | 47 | ||
| 44 | patternProperties: | 48 | patternProperties: |
| 45 | "^display-controller@[0-9a-f]+$": | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -56,7 +60,9 @@ patternProperties: · 10 unmodified lines | |||
| 56 | 60 | ||
| 57 | properties: | 61 | properties: |
| 58 | compatible: | 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 | "^phy@[0-9a-f]+$": | 67 | "^phy@[0-9a-f]+$": |
| 62 | type: object | 68 | type: object |
| @@ -96,8 +102,10 @@ examples: · 33 unmodified lines | |||
| 96 | interrupt-controller; | 102 | interrupt-controller; |
| 97 | #interrupt-cells = <1>; | 103 | #interrupt-cells = <1>; |
| 98 | 104 | ||
| 99 | interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>; | 105 | interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>, |
| 100 | interconnect-names = "mdp0-mem"; | 106 | <&bimc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; |
| 107 | interconnect-names = "mdp0-mem", | ||
| 108 | "cpu-cfg"; | ||
| 101 | 109 | ||
| 102 | iommus = <&apps_smmu 0x420 0x2>, | 110 | iommus = <&apps_smmu 0x420 0x2>, |
| 103 | <&apps_smmu 0x421 0x0>; | 111 | <&apps_smmu 0x421 0x0>; |
| @@ -136,7 +144,8 @@ examples: · 32 unmodified lines | |||
| 136 | }; | 144 | }; |
| 137 | 145 | ||
| 138 | dsi@5e94000 { | 146 | dsi@5e94000 { |
| 139 | compatible = "qcom,dsi-ctrl-6g-qcm2290"; | 147 | compatible = "qcom,qcm2290-dsi-ctrl", |
| 148 | "qcom,mdss-dsi-ctrl"; | ||
| 140 | reg = <0x05e94000 0x400>; | 149 | reg = <0x05e94000 0x400>; |
| 141 | reg-names = "dsi_ctrl"; | 150 | reg-names = "dsi_ctrl"; |
| 142 | 151 | ||
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | |||
| 36 | maxItems: 1 | 36 | maxItems: 1 |
| 37 | 37 | ||
| 38 | interconnects: | 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 | interconnect-names: | 43 | interconnect-names: |
| 42 | maxItems: 1 | 44 | items: |
| 45 | - const: mdp0-mem | ||
| 46 | - const: cpu-cfg | ||
| 43 | 47 | ||
| 44 | patternProperties: | 48 | patternProperties: |
| 45 | "^display-controller@[0-9a-f]+$": | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -106,8 +110,10 @@ examples: · 60 unmodified lines | |||
| 106 | interrupt-controller; | 110 | interrupt-controller; |
| 107 | #interrupt-cells = <1>; | 111 | #interrupt-cells = <1>; |
| 108 | 112 | ||
| 109 | interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; | 113 | interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, |
| 110 | interconnect-names = "mdp0-mem"; | 114 | <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>; |
| 115 | interconnect-names = "mdp0-mem", | ||
| 116 | "cpu-cfg"; | ||
| 111 | 117 | ||
| 112 | iommus = <&apps_smmu 0x800 0x2>; | 118 | iommus = <&apps_smmu 0x800 0x2>; |
| 113 | ranges; | 119 | ranges; |
| @@ -36,10 +36,14 @@ properties: · 35 unmodified lines | |||
| 36 | maxItems: 1 | 36 | maxItems: 1 |
| 37 | 37 | ||
| 38 | interconnects: | 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 | interconnect-names: | 43 | interconnect-names: |
| 42 | maxItems: 1 | 44 | items: |
| 45 | - const: mdp0-mem | ||
| 46 | - const: cpu-cfg | ||
| 43 | 47 | ||
| 44 | patternProperties: | 48 | patternProperties: |
| 45 | "^display-controller@[0-9a-f]+$": | 49 | "^display-controller@[0-9a-f]+$": |
| @@ -118,8 +122,10 @@ examples: · 72 unmodified lines | |||
| 118 | interrupt-controller; | 122 | interrupt-controller; |
| 119 | #interrupt-cells = <1>; | 123 | #interrupt-cells = <1>; |
| 120 | 124 | ||
| 121 | interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>; | 125 | interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>, |
| 122 | interconnect-names = "mdp0-mem"; | 126 | <&gem_noc MASTER_APPSS_PROC &cnoc2 SLAVE_DISPLAY_CFG>; |
| 127 | interconnect-names = "mdp0-mem", | ||
| 128 | "cpu-cfg"; | ||
| 123 | 129 | ||
| 124 | iommus = <&apps_smmu 0x900 0x402>; | 130 | iommus = <&apps_smmu 0x900 0x402>; |
| 125 | ranges; | 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 | properties: | 14 | properties: |
| 15 | compatible: | 15 | compatible: |
| 16 | const: qcom,sdm845-dpu | 16 | enum: |
| 17 | - qcom,sdm670-dpu | ||
| 18 | - qcom,sdm845-dpu | ||
| 17 | 19 | ||
| 18 | reg: | 20 | reg: |
| 19 | items: | 21 | items: |
| @@ -29,6 +29,16 @@ properties: · 28 unmodified lines | |||
| 29 | iommus: | 29 | iommus: |
| 30 | maxItems: 2 | 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 | patternProperties: | 42 | patternProperties: |
| 33 | "^display-controller@[0-9a-f]+$": | 43 | "^display-controller@[0-9a-f]+$": |
| 34 | type: object | 44 | type: object |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | |||
| 35 | maxItems: 1 | 35 | maxItems: 1 |
| 36 | 36 | ||
| 37 | interconnects: | 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 | interconnect-names: | 42 | interconnect-names: |
| 41 | maxItems: 2 | 43 | items: |
| 44 | - const: mdp0-mem | ||
| 45 | - const: cpu-cfg | ||
| 42 | 46 | ||
| 43 | patternProperties: | 47 | patternProperties: |
| 44 | "^display-controller@[0-9a-f]+$": | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | |||
| 35 | maxItems: 1 | 35 | maxItems: 1 |
| 36 | 36 | ||
| 37 | interconnects: | 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 | interconnect-names: | 42 | interconnect-names: |
| 41 | maxItems: 2 | 43 | items: |
| 44 | - const: mdp0-mem | ||
| 45 | - const: cpu-cfg | ||
| 42 | 46 | ||
| 43 | patternProperties: | 47 | patternProperties: |
| 44 | "^display-controller@[0-9a-f]+$": | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -35,10 +35,14 @@ properties: · 34 unmodified lines | |||
| 35 | maxItems: 1 | 35 | maxItems: 1 |
| 36 | 36 | ||
| 37 | interconnects: | 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 | interconnect-names: | 42 | interconnect-names: |
| 41 | maxItems: 2 | 43 | items: |
| 44 | - const: mdp0-mem | ||
| 45 | - const: cpu-cfg | ||
| 42 | 46 | ||
| 43 | patternProperties: | 47 | patternProperties: |
| 44 | "^display-controller@[0-9a-f]+$": | 48 | "^display-controller@[0-9a-f]+$": |
| @@ -69,7 +69,7 @@ patternProperties: · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | properties: | 70 | properties: |
| 71 | compatible: | 71 | compatible: |
| 72 | const: qcom,dsi-phy-7nm | 72 | const: qcom,dsi-phy-7nm-8150 |
| 73 | 73 | ||
| 74 | unevaluatedProperties: false | 74 | unevaluatedProperties: false |
| 75 | 75 | ||
| @@ -247,7 +247,7 @@ examples: · 171 unmodified lines | |||
| 247 | }; | 247 | }; |
| 248 | 248 | ||
| 249 | dsi0_phy: phy@ae94400 { | 249 | dsi0_phy: phy@ae94400 { |
| 250 | compatible = "qcom,dsi-phy-7nm"; | 250 | compatible = "qcom,dsi-phy-7nm-8150"; |
| 251 | reg = <0x0ae94400 0x200>, | 251 | reg = <0x0ae94400 0x200>, |
| 252 | <0x0ae94600 0x280>, | 252 | <0x0ae94600 0x280>, |
| 253 | <0x0ae94900 0x260>; | 253 | <0x0ae94900 0x260>; |
| @@ -318,7 +318,7 @@ examples: · 64 unmodified lines | |||
| 318 | }; | 318 | }; |
| 319 | 319 | ||
| 320 | dsi1_phy: phy@ae96400 { | 320 | dsi1_phy: phy@ae96400 { |
| 321 | compatible = "qcom,dsi-phy-7nm"; | 321 | compatible = "qcom,dsi-phy-7nm-8150"; |
| 322 | reg = <0x0ae96400 0x200>, | 322 | reg = <0x0ae96400 0x200>, |
| 323 | <0x0ae96600 0x280>, | 323 | <0x0ae96600 0x280>, |
| 324 | <0x0ae96900 0x260>; | 324 | <0x0ae96900 0x260>; |
| @@ -52,6 +52,16 @@ patternProperties: · 51 unmodified lines | |||
| 52 | compatible: | 52 | compatible: |
| 53 | const: qcom,sm8250-dpu | 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 | "^dsi@[0-9a-f]+$": | 65 | "^dsi@[0-9a-f]+$": |
| 56 | type: object | 66 | type: object |
| 57 | additionalProperties: true | 67 | additionalProperties: true |
| @@ -30,10 +30,10 @@ properties: · 29 unmodified lines | |||
| 30 | maxItems: 1 | 30 | maxItems: 1 |
| 31 | 31 | ||
| 32 | interconnects: | 32 | interconnects: |
| 33 | maxItems: 2 | 33 | maxItems: 3 |
| 34 | 34 | ||
| 35 | interconnect-names: | 35 | interconnect-names: |
| 36 | maxItems: 2 | 36 | maxItems: 3 |
| 37 | 37 | ||
| 38 | patternProperties: | 38 | patternProperties: |
| 39 | "^display-controller@[0-9a-f]+$": | 39 | "^display-controller@[0-9a-f]+$": |
| @@ -91,9 +91,12 @@ examples: · 51 unmodified lines | |||
| 91 | reg = <0x0ae00000 0x1000>; | 91 | reg = <0x0ae00000 0x1000>; |
| 92 | reg-names = "mdss"; | 92 | reg-names = "mdss"; |
| 93 | 93 | ||
| 94 | interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>, | 94 | interconnects = <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>, |
| 95 | <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>; | 95 | <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>, |
| 96 | interconnect-names = "mdp0-mem", "mdp1-mem"; | 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 | resets = <&dispcc DISP_CC_MDSS_CORE_BCR>; | 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 | ctx->n_vms = 1; | 1148 | ctx->n_vms = 1; |
| 1149 | ctx->sync = &mem->sync; | 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 | drm_exec_until_all_locked(&ctx->exec) { | 1151 | drm_exec_until_all_locked(&ctx->exec) { |
| 1152 | ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2); | 1152 | ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2); |
| 1153 | drm_exec_retry_on_contention(&ctx->exec); | 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 | int ret; | 1186 | int ret; |
| 1187 | 1187 | ||
| 1188 | ctx->sync = &mem->sync; | 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 | drm_exec_until_all_locked(&ctx->exec) { | 1190 | drm_exec_until_all_locked(&ctx->exec) { |
| 1191 | ctx->n_vms = 0; | 1191 | ctx->n_vms = 0; |
| 1192 | list_for_each_entry(entry, &mem->attachments, list) { | 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 | amdgpu_sync_create(&sync); | 2596 | amdgpu_sync_create(&sync); |
| 2597 | 2597 | ||
| 2598 | drm_exec_init(&exec, 0); | 2598 | drm_exec_init(&exec, 0, 0); |
| 2599 | /* Reserve all BOs and page tables for validation */ | 2599 | /* Reserve all BOs and page tables for validation */ |
| 2600 | drm_exec_until_all_locked(&exec) { | 2600 | drm_exec_until_all_locked(&exec) { |
| 2601 | /* Reserve all the page directories */ | 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 | mutex_lock(&process_info->lock); | 2854 | mutex_lock(&process_info->lock); |
| 2855 | 2855 | ||
| 2856 | drm_exec_init(&exec, 0); | 2856 | drm_exec_init(&exec, 0, 0); |
| 2857 | drm_exec_until_all_locked(&exec) { | 2857 | drm_exec_until_all_locked(&exec) { |
| 2858 | list_for_each_entry(peer_vm, &process_info->vm_list_head, | 2858 | list_for_each_entry(peer_vm, &process_info->vm_list_head, |
| 2859 | vm_list_node) { | 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 | amdgpu_sync_create(&p->sync); | 67 | amdgpu_sync_create(&p->sync); |
| 68 | drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT | | 68 | drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT | |
| 69 | DRM_EXEC_IGNORE_DUPLICATES); | 69 | DRM_EXEC_IGNORE_DUPLICATES, 0); |
| 70 | return 0; | 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 | struct drm_exec exec; | 70 | struct drm_exec exec; |
| 71 | int r; | 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 | drm_exec_until_all_locked(&exec) { | 74 | drm_exec_until_all_locked(&exec) { |
| 75 | r = amdgpu_vm_lock_pd(vm, &exec, 0); | 75 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 76 | if (likely(!r)) | 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 | struct drm_exec exec; | 110 | struct drm_exec exec; |
| 111 | int r; | 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 | drm_exec_until_all_locked(&exec) { | 114 | drm_exec_until_all_locked(&exec) { |
| 115 | r = amdgpu_vm_lock_pd(vm, &exec, 0); | 115 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 116 | if (likely(!r)) | 116 | if (likely(!r)) |
| @@ -203,7 +203,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj, · 202 unmodified lines | |||
| 203 | struct drm_exec exec; | 203 | struct drm_exec exec; |
| 204 | long r; | 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 | drm_exec_until_all_locked(&exec) { | 207 | drm_exec_until_all_locked(&exec) { |
| 208 | r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1); | 208 | r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1); |
| 209 | drm_exec_retry_on_contention(&exec); | 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 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | | 741 | drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT | |
| 742 | DRM_EXEC_IGNORE_DUPLICATES); | 742 | DRM_EXEC_IGNORE_DUPLICATES, 0); |
| 743 | drm_exec_until_all_locked(&exec) { | 743 | drm_exec_until_all_locked(&exec) { |
| 744 | if (gobj) { | 744 | if (gobj) { |
| 745 | r = drm_exec_lock_obj(&exec, gobj); | 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 | amdgpu_sync_create(&sync); | 1184 | amdgpu_sync_create(&sync); |
| 1185 | 1185 | ||
| 1186 | drm_exec_init(&exec, 0); | 1186 | drm_exec_init(&exec, 0, 0); |
| 1187 | drm_exec_until_all_locked(&exec) { | 1187 | drm_exec_until_all_locked(&exec) { |
| 1188 | r = drm_exec_lock_obj(&exec, | 1188 | r = drm_exec_lock_obj(&exec, |
| 1189 | &ctx_data->meta_data_obj->tbo.base); | 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 | struct drm_exec exec; | 1254 | struct drm_exec exec; |
| 1255 | long r; | 1255 | long r; |
| 1256 | 1256 | ||
| 1257 | drm_exec_init(&exec, 0); | 1257 | drm_exec_init(&exec, 0, 0); |
| 1258 | drm_exec_until_all_locked(&exec) { | 1258 | drm_exec_until_all_locked(&exec) { |
| 1259 | r = drm_exec_lock_obj(&exec, | 1259 | r = drm_exec_lock_obj(&exec, |
| 1260 | &ctx_data->meta_data_obj->tbo.base); | 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 | if (!bo) | 61 | if (!bo) |
| 62 | return -EINVAL; | 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 | drm_exec_until_all_locked(&exec) { | 65 | drm_exec_until_all_locked(&exec) { |
| 66 | r = amdgpu_vm_lock_pd(vm, &exec, 0); | 66 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 67 | if (likely(!r)) | 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 | vm = &fpriv->vm; | 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 | drm_exec_until_all_locked(&exec) { | 126 | drm_exec_until_all_locked(&exec) { |
| 127 | r = amdgpu_vm_lock_pd(vm, &exec, 0); | 127 | r = amdgpu_vm_lock_pd(vm, &exec, 0); |
| 128 | if (likely(!r)) | 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 | amdgpu_sync_create(&sync); | 87 | amdgpu_sync_create(&sync); |
| 88 | 88 | ||
| 89 | drm_exec_init(&exec, 0); | 89 | drm_exec_init(&exec, 0, 0); |
| 90 | drm_exec_until_all_locked(&exec) { | 90 | drm_exec_until_all_locked(&exec) { |
| 91 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); | 91 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); |
| 92 | drm_exec_retry_on_contention(&exec); | 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 | struct drm_exec exec; | 149 | struct drm_exec exec; |
| 150 | long r; | 150 | long r; |
| 151 | 151 | ||
| 152 | drm_exec_init(&exec, 0); | 152 | drm_exec_init(&exec, 0, 0); |
| 153 | drm_exec_until_all_locked(&exec) { | 153 | drm_exec_until_all_locked(&exec) { |
| 154 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); | 154 | r = drm_exec_lock_obj(&exec, &bo->tbo.base); |
| 155 | drm_exec_retry_on_contention(&exec); | 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 | uint32_t gpuidx; | 1481 | uint32_t gpuidx; |
| 1482 | int r; | 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 | drm_exec_until_all_locked(&ctx->exec) { | 1485 | drm_exec_until_all_locked(&ctx->exec) { |
| 1486 | for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) { | 1486 | for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) { |
| 1487 | pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx); | 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 | git config --global user.name "freedesktop.org CI" | 58 | git config --global user.name "freedesktop.org CI" |
| 59 | git config --global pull.rebase true | 59 | git config --global pull.rebase true |
| 60 | 60 | ||
| 61 | # cleanup git state on the worker | ||
| 62 | rm -rf .git/rebase-merge | ||
| 63 | |||
| 61 | # Try to merge fixes from target repo | 64 | # Try to merge fixes from target repo |
| 62 | if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes)" ]; then | 65 | if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes)" ]; then |
| 63 | git pull ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes | 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 | * drm_exec_init - initialize a drm_exec object | 69 | * drm_exec_init - initialize a drm_exec object |
| 70 | * @exec: the drm_exec object to initialize | 70 | * @exec: the drm_exec object to initialize |
| 71 | * @flags: controls locking behavior, see DRM_EXEC_* defines | 71 | * @flags: controls locking behavior, see DRM_EXEC_* defines |
| 72 | * @nr: the initial # of objects | ||
| 72 | * | 73 | * |
| 73 | * Initialize the object and make sure that we can track locked objects. | 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 | exec->flags = flags; | 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 | /* If allocation here fails, just delay that till the first use */ | 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 | exec->num_objects = 0; | 89 | exec->num_objects = 0; |
| 83 | exec->contended = DRM_EXEC_DUMMY; | 90 | exec->contended = DRM_EXEC_DUMMY; |
| 84 | exec->prelocked = NULL; | 91 | exec->prelocked = NULL; |
| @@ -1250,7 +1250,7 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec) · 1249 unmodified lines | |||
| 1250 | unsigned int num_fences = vm_exec->num_fences; | 1250 | unsigned int num_fences = vm_exec->num_fences; |
| 1251 | int ret; | 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 | drm_exec_until_all_locked(exec) { | 1255 | drm_exec_until_all_locked(exec) { |
| 1256 | ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences); | 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 | struct drm_exec *exec = &vm_exec->exec; | 1341 | struct drm_exec *exec = &vm_exec->exec; |
| 1342 | int ret; | 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 | drm_exec_until_all_locked(exec) { | 1346 | drm_exec_until_all_locked(exec) { |
| 1347 | ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range, | 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 | if (err) | 746 | if (err) |
| 747 | goto out_job_data_cleanup; | 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 | xa_init_flags(&signal_array, XA_FLAGS_ALLOC); | 751 | xa_init_flags(&signal_array, XA_FLAGS_ALLOC); |
| 752 | 752 | ||
| @@ -6,6 +6,7 @@ config DRM_MSM · 5 unmodified lines | |||
| 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST | 6 | depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST |
| 7 | depends on COMMON_CLK | 7 | depends on COMMON_CLK |
| 8 | depends on IOMMU_SUPPORT | 8 | depends on IOMMU_SUPPORT |
| 9 | depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n | ||
| 9 | depends on QCOM_OCMEM || QCOM_OCMEM=n | 10 | depends on QCOM_OCMEM || QCOM_OCMEM=n |
| 10 | depends on QCOM_LLCC || QCOM_LLCC=n | 11 | depends on QCOM_LLCC || QCOM_LLCC=n |
| 11 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n | 12 | depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n |
| @@ -16,6 +17,7 @@ config DRM_MSM · 4 unmodified lines | |||
| 16 | select DRM_DP_AUX_BUS | 17 | select DRM_DP_AUX_BUS |
| 17 | select DRM_DISPLAY_DP_HELPER | 18 | select DRM_DISPLAY_DP_HELPER |
| 18 | select DRM_DISPLAY_HELPER | 19 | select DRM_DISPLAY_HELPER |
| 20 | select DRM_EXEC | ||
| 19 | select DRM_KMS_HELPER | 21 | select DRM_KMS_HELPER |
| 20 | select DRM_PANEL | 22 | select DRM_PANEL |
| 21 | select DRM_BRIDGE | 23 | select DRM_BRIDGE |
| @@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ · 62 unmodified lines | |||
| 63 | disp/dpu1/dpu_encoder_phys_wb.o \ | 63 | disp/dpu1/dpu_encoder_phys_wb.o \ |
| 64 | disp/dpu1/dpu_formats.o \ | 64 | disp/dpu1/dpu_formats.o \ |
| 65 | disp/dpu1/dpu_hw_catalog.o \ | 65 | disp/dpu1/dpu_hw_catalog.o \ |
| 66 | disp/dpu1/dpu_hw_cdm.o \ | ||
| 66 | disp/dpu1/dpu_hw_ctl.o \ | 67 | disp/dpu1/dpu_hw_ctl.o \ |
| 67 | disp/dpu1/dpu_hw_dsc.o \ | 68 | disp/dpu1/dpu_hw_dsc.o \ |
| 68 | disp/dpu1/dpu_hw_dsc_1_2.o \ | 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 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); | 685 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 686 | struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); | 686 | struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); |
| 687 | u32 regbit; | 687 | u32 hbb; |
| 688 | int ret; | 688 | int ret; |
| 689 | 689 | ||
| 690 | gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003); | 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 | gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F); | 821 | gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F); |
| 822 | 822 | ||
| 823 | /* Set the highest bank bit */ | 823 | BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13); |
| 824 | if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu)) | 824 | hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13; |
| 825 | regbit = 2; | ||
| 826 | else | ||
| 827 | regbit = 1; | ||
| 828 | 825 | ||
| 829 | gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7); | 826 | gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7); |
| 830 | gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1); | 827 | gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1); |
| 831 | 828 | ||
| 832 | if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) || | 829 | if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) || |
| 833 | adreno_is_a540(adreno_gpu)) | 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 | /* Disable All flat shading optimization (ALLFLATOPTDIS) */ | 833 | /* Disable All flat shading optimization (ALLFLATOPTDIS) */ |
| 837 | gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10)); | 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 | /* Set up the preemption specific bits and pieces for each ringbuffer */ | 1782 | /* Set up the preemption specific bits and pieces for each ringbuffer */ |
| 1786 | a5xx_preempt_init(gpu); | 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 | return gpu; | 1791 | return gpu; |
| 1789 | } | 1792 | } |
| @@ -1270,87 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) · 1269 unmodified lines | |||
| 1270 | gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]); | 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 | /* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */ | 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 | /* Unknown, introduced with A650 family */ | 1277 | /* Unknown, introduced with A650 family */ |
| 1279 | u32 uavflagprd_inv = 0; | 1278 | gpu->ubwc_config.uavflagprd_inv = 0; |
| 1280 | /* Whether the minimum access length is 64 bits */ | 1279 | /* Whether the minimum access length is 64 bits */ |
| 1281 | u32 min_acc_len = 0; | 1280 | gpu->ubwc_config.min_acc_len = 0; |
| 1282 | /* Entirely magic, per-GPU-gen value */ | 1281 | /* Entirely magic, per-GPU-gen value */ |
| 1283 | u32 ubwc_mode = 0; | 1282 | gpu->ubwc_config.ubwc_mode = 0; |
| 1284 | /* | 1283 | /* |
| 1285 | * The Highest Bank Bit value represents the bit of the highest DDR bank. | 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 | 1285 | * This should ideally use DRAM type detection. |
| 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. | ||
| 1290 | */ | 1286 | */ |
| 1291 | u32 hbb_hi = 0; | 1287 | gpu->ubwc_config.highest_bank_bit = 15; |
| 1292 | u32 hbb_lo = 2; | ||
| 1293 | /* Unknown, introduced with A640/680 */ | ||
| 1294 | u32 amsbc = 0; | ||
| 1295 | 1288 | ||
| 1296 | if (adreno_is_a610(adreno_gpu)) { | 1289 | if (adreno_is_a610(gpu)) { |
| 1297 | /* HBB = 14 */ | 1290 | gpu->ubwc_config.highest_bank_bit = 14; |
| 1298 | hbb_lo = 1; | 1291 | gpu->ubwc_config.min_acc_len = 1; |
| 1299 | min_acc_len = 1; | 1292 | gpu->ubwc_config.ubwc_mode = 1; |
| 1300 | ubwc_mode = 1; | ||
| 1301 | } | 1293 | } |
| 1302 | 1294 | ||
| 1303 | /* a618 is using the hw default values */ | 1295 | /* a618 is using the hw default values */ |
| 1304 | if (adreno_is_a618(adreno_gpu)) | 1296 | if (adreno_is_a618(gpu)) |
| 1305 | return; | 1297 | return; |
| 1306 | 1298 | ||
| 1307 | if (adreno_is_a619_holi(adreno_gpu)) | 1299 | if (adreno_is_a619_holi(gpu)) |
| 1308 | hbb_lo = 0; | 1300 | gpu->ubwc_config.highest_bank_bit = 13; |
| 1309 | 1301 | ||
| 1310 | if (adreno_is_a640_family(adreno_gpu)) | 1302 | if (adreno_is_a640_family(gpu)) |
| 1311 | amsbc = 1; | 1303 | gpu->ubwc_config.amsbc = 1; |
| 1312 | 1304 | ||
| 1313 | if (adreno_is_a650(adreno_gpu) || | 1305 | if (adreno_is_a650(gpu) || |
| 1314 | adreno_is_a660(adreno_gpu) || | 1306 | adreno_is_a660(gpu) || |
| 1315 | adreno_is_a730(adreno_gpu) || | 1307 | adreno_is_a690(gpu) || |
| 1316 | adreno_is_a740_family(adreno_gpu)) { | 1308 | adreno_is_a730(gpu) || |
| 1309 | adreno_is_a740_family(gpu)) { | ||
| 1317 | /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ | 1310 | /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */ |
| 1318 | hbb_lo = 3; | 1311 | gpu->ubwc_config.highest_bank_bit = 16; |
| 1319 | amsbc = 1; | 1312 | gpu->ubwc_config.amsbc = 1; |
| 1320 | rgb565_predicator = 1; | 1313 | gpu->ubwc_config.rgb565_predicator = 1; |
| 1321 | uavflagprd_inv = 2; | 1314 | gpu->ubwc_config.uavflagprd_inv = 2; |
| 1322 | } | 1315 | } |
| 1323 | 1316 | ||
| 1324 | if (adreno_is_a690(adreno_gpu)) { | 1317 | if (adreno_is_7c3(gpu)) { |
| 1325 | hbb_lo = 2; | 1318 | gpu->ubwc_config.highest_bank_bit = 14; |
| 1326 | amsbc = 1; | 1319 | gpu->ubwc_config.amsbc = 1; |
| 1327 | rgb565_predicator = 1; | 1320 | gpu->ubwc_config.rgb565_predicator = 1; |
| 1328 | uavflagprd_inv = 2; | 1321 | gpu->ubwc_config.uavflagprd_inv = 2; |
| 1329 | } | 1322 | } |
| 1323 | } | ||
| 1330 | 1324 | ||
| 1331 | if (adreno_is_7c3(adreno_gpu)) { | 1325 | static void a6xx_set_ubwc_config(struct msm_gpu *gpu) |
| 1332 | hbb_lo = 1; | 1326 | { |
| 1333 | amsbc = 1; | 1327 | struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); |
| 1334 | rgb565_predicator = 1; | 1328 | /* |
| 1335 | uavflagprd_inv = 2; | 1329 | * We subtract 13 from the highest bank bit (13 is the minimum value |
| 1336 | } | 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 | gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, | 1338 | gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, |
| 1339 | rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 | | 1339 | adreno_gpu->ubwc_config.rgb565_predicator << 11 | |
| 1340 | min_acc_len << 3 | hbb_lo << 1 | ubwc_mode); | 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 | gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 | | 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 | gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 | | 1348 | gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 | |
| 1346 | uavflagprd_inv << 4 | min_acc_len << 3 | | 1349 | adreno_gpu->ubwc_config.uavflagprd_inv << 4 | |
| 1347 | hbb_lo << 1 | ubwc_mode); | 1350 | adreno_gpu->ubwc_config.min_acc_len << 3 | |
| 1351 | hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode); | ||
| 1348 | 1352 | ||
| 1349 | if (adreno_is_a7xx(adreno_gpu)) | 1353 | if (adreno_is_a7xx(adreno_gpu)) |
| 1350 | gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL, | 1354 | gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL, |
| 1351 | FIELD_PREP(GENMASK(8, 5), hbb_lo)); | 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 | static int a6xx_cp_init(struct msm_gpu *gpu) | 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 | /* Setting the primFifo thresholds default values, | 1746 | /* Setting the primFifo thresholds default values, |
| 1742 | * and vccCacheSkipDis=1 bit (0x200) for A640 and newer | 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 | gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); | 1752 | gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200); |
| 1746 | else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) | 1753 | else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu)) |
| 1747 | gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200); | 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 | if (adreno_is_a730(adreno_gpu) || | 1782 | if (adreno_is_a730(adreno_gpu) || |
| 1776 | adreno_is_a740_family(adreno_gpu)) | 1783 | adreno_is_a740_family(adreno_gpu)) |
| 1777 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff); | 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 | else if (adreno_is_a619(adreno_gpu)) | 1787 | else if (adreno_is_a619(adreno_gpu)) |
| 1779 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff); | 1788 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff); |
| 1780 | else if (adreno_is_a610(adreno_gpu)) | 1789 | else if (adreno_is_a610(adreno_gpu)) |
| @@ -1782,7 +1791,7 @@ static int hw_init(struct msm_gpu *gpu) · 1 unmodified line | |||
| 1782 | else | 1791 | else |
| 1783 | gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff); | 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 | /* Set weights for bicubic filtering */ | 1796 | /* Set weights for bicubic filtering */ |
| 1788 | if (adreno_is_a650_family(adreno_gpu)) { | 1797 | if (adreno_is_a650_family(adreno_gpu)) { |
| @@ -1808,12 +1817,17 @@ static int hw_init(struct msm_gpu *gpu) · 19 unmodified lines | |||
| 1808 | a6xx_set_cp_protect(gpu); | 1817 | a6xx_set_cp_protect(gpu); |
| 1809 | 1818 | ||
| 1810 | if (adreno_is_a660_family(adreno_gpu)) { | 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 | gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0); | 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 | /* Set dualQ + disable afull for A660 GPU */ | 1829 | /* Set dualQ + disable afull for A660 GPU */ |
| 1816 | if (adreno_is_a660(adreno_gpu)) | 1830 | else if (adreno_is_a660(adreno_gpu)) |
| 1817 | gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906); | 1831 | gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906); |
| 1818 | else if (adreno_is_a7xx(adreno_gpu)) | 1832 | else if (adreno_is_a7xx(adreno_gpu)) |
| 1819 | gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, | 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 | msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, | 2922 | msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, |
| 2909 | a6xx_fault_handler); | 2923 | a6xx_fault_handler); |
| 2910 | 2924 | ||
| 2925 | a6xx_calc_ubwc_config(adreno_gpu); | ||
| 2926 | |||
| 2911 | return gpu; | 2927 | return gpu; |
| 2912 | } | 2928 | } |
| @@ -464,7 +464,7 @@ static const struct adreno_info gpulist[] = { · 463 unmodified lines | |||
| 464 | { 190, 1 }, | 464 | { 190, 1 }, |
| 465 | ), | 465 | ), |
| 466 | }, { | 466 | }, { |
| 467 | .chip_ids = ADRENO_CHIP_IDS(0x06080000), | 467 | .chip_ids = ADRENO_CHIP_IDS(0x06080001), |
| 468 | .family = ADRENO_6XX_GEN2, | 468 | .family = ADRENO_6XX_GEN2, |
| 469 | .revn = 680, | 469 | .revn = 680, |
| 470 | .fw = { | 470 | .fw = { |
| @@ -373,6 +373,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, · 372 unmodified lines | |||
| 373 | return -EINVAL; | 373 | return -EINVAL; |
| 374 | *value = ctx->aspace->va_size; | 374 | *value = ctx->aspace->va_size; |
| 375 | return 0; | 375 | return 0; |
| 376 | case MSM_PARAM_HIGHEST_BANK_BIT: | ||
| 377 | *value = adreno_gpu->ubwc_config.highest_bank_bit; | ||
| 378 | return 0; | ||
| 376 | default: | 379 | default: |
| 377 | DBG("%s: invalid param: %u", gpu->name, param); | 380 | DBG("%s: invalid param: %u", gpu->name, param); |
| 378 | return -EINVAL; | 381 | return -EINVAL; |
| @@ -165,6 +165,15 @@ struct adreno_gpu { · 164 unmodified lines | |||
| 165 | /* firmware: */ | 165 | /* firmware: */ |
| 166 | const struct firmware *fw[ADRENO_FW_MAX]; | 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 | * Register offsets are different between some GPUs. | 178 | * Register offsets are different between some GPUs. |
| 170 | * GPU specific offsets will be exported by GPU specific | 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 | static const struct dpu_caps msm8998_dpu_caps = { | 10 | static const struct dpu_caps msm8998_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0x7, | 12 | .max_mixer_blendstages = 0x7, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED3, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -70,7 +69,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 53 unmodified lines | |||
| 70 | .name = "sspp_0", .id = SSPP_VIG0, | 69 | .name = "sspp_0", .id = SSPP_VIG0, |
| 71 | .base = 0x4000, .len = 0x1ac, | 70 | .base = 0x4000, .len = 0x1ac, |
| 72 | .features = VIG_MSM8998_MASK, | 71 | .features = VIG_MSM8998_MASK, |
| 73 | .sblk = &msm8998_vig_sblk_0, | 72 | .sblk = &dpu_vig_sblk_qseed3_1_2, |
| 74 | .xin_id = 0, | 73 | .xin_id = 0, |
| 75 | .type = SSPP_TYPE_VIG, | 74 | .type = SSPP_TYPE_VIG, |
| 76 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 75 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -78,7 +77,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 78 | .name = "sspp_1", .id = SSPP_VIG1, | 77 | .name = "sspp_1", .id = SSPP_VIG1, |
| 79 | .base = 0x6000, .len = 0x1ac, | 78 | .base = 0x6000, .len = 0x1ac, |
| 80 | .features = VIG_MSM8998_MASK, | 79 | .features = VIG_MSM8998_MASK, |
| 81 | .sblk = &msm8998_vig_sblk_1, | 80 | .sblk = &dpu_vig_sblk_qseed3_1_2, |
| 82 | .xin_id = 4, | 81 | .xin_id = 4, |
| 83 | .type = SSPP_TYPE_VIG, | 82 | .type = SSPP_TYPE_VIG, |
| 84 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 83 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -86,7 +85,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 86 | .name = "sspp_2", .id = SSPP_VIG2, | 85 | .name = "sspp_2", .id = SSPP_VIG2, |
| 87 | .base = 0x8000, .len = 0x1ac, | 86 | .base = 0x8000, .len = 0x1ac, |
| 88 | .features = VIG_MSM8998_MASK, | 87 | .features = VIG_MSM8998_MASK, |
| 89 | .sblk = &msm8998_vig_sblk_2, | 88 | .sblk = &dpu_vig_sblk_qseed3_1_2, |
| 90 | .xin_id = 8, | 89 | .xin_id = 8, |
| 91 | .type = SSPP_TYPE_VIG, | 90 | .type = SSPP_TYPE_VIG, |
| 92 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 91 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -94,7 +93,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 94 | .name = "sspp_3", .id = SSPP_VIG3, | 93 | .name = "sspp_3", .id = SSPP_VIG3, |
| 95 | .base = 0xa000, .len = 0x1ac, | 94 | .base = 0xa000, .len = 0x1ac, |
| 96 | .features = VIG_MSM8998_MASK, | 95 | .features = VIG_MSM8998_MASK, |
| 97 | .sblk = &msm8998_vig_sblk_3, | 96 | .sblk = &dpu_vig_sblk_qseed3_1_2, |
| 98 | .xin_id = 12, | 97 | .xin_id = 12, |
| 99 | .type = SSPP_TYPE_VIG, | 98 | .type = SSPP_TYPE_VIG, |
| 100 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 99 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -102,7 +101,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 102 | .name = "sspp_8", .id = SSPP_DMA0, | 101 | .name = "sspp_8", .id = SSPP_DMA0, |
| 103 | .base = 0x24000, .len = 0x1ac, | 102 | .base = 0x24000, .len = 0x1ac, |
| 104 | .features = DMA_MSM8998_MASK, | 103 | .features = DMA_MSM8998_MASK, |
| 105 | .sblk = &sdm845_dma_sblk_0, | 104 | .sblk = &dpu_dma_sblk, |
| 106 | .xin_id = 1, | 105 | .xin_id = 1, |
| 107 | .type = SSPP_TYPE_DMA, | 106 | .type = SSPP_TYPE_DMA, |
| 108 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 107 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -110,7 +109,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 110 | .name = "sspp_9", .id = SSPP_DMA1, | 109 | .name = "sspp_9", .id = SSPP_DMA1, |
| 111 | .base = 0x26000, .len = 0x1ac, | 110 | .base = 0x26000, .len = 0x1ac, |
| 112 | .features = DMA_MSM8998_MASK, | 111 | .features = DMA_MSM8998_MASK, |
| 113 | .sblk = &sdm845_dma_sblk_1, | 112 | .sblk = &dpu_dma_sblk, |
| 114 | .xin_id = 5, | 113 | .xin_id = 5, |
| 115 | .type = SSPP_TYPE_DMA, | 114 | .type = SSPP_TYPE_DMA, |
| 116 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 115 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -118,7 +117,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 118 | .name = "sspp_10", .id = SSPP_DMA2, | 117 | .name = "sspp_10", .id = SSPP_DMA2, |
| 119 | .base = 0x28000, .len = 0x1ac, | 118 | .base = 0x28000, .len = 0x1ac, |
| 120 | .features = DMA_CURSOR_MSM8998_MASK, | 119 | .features = DMA_CURSOR_MSM8998_MASK, |
| 121 | .sblk = &sdm845_dma_sblk_2, | 120 | .sblk = &dpu_dma_sblk, |
| 122 | .xin_id = 9, | 121 | .xin_id = 9, |
| 123 | .type = SSPP_TYPE_DMA, | 122 | .type = SSPP_TYPE_DMA, |
| 124 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 123 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -126,7 +125,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line | |||
| 126 | .name = "sspp_11", .id = SSPP_DMA3, | 125 | .name = "sspp_11", .id = SSPP_DMA3, |
| 127 | .base = 0x2a000, .len = 0x1ac, | 126 | .base = 0x2a000, .len = 0x1ac, |
| 128 | .features = DMA_CURSOR_MSM8998_MASK, | 127 | .features = DMA_CURSOR_MSM8998_MASK, |
| 129 | .sblk = &sdm845_dma_sblk_3, | 128 | .sblk = &dpu_dma_sblk, |
| 130 | .xin_id = 13, | 129 | .xin_id = 13, |
| 131 | .type = SSPP_TYPE_DMA, | 130 | .type = SSPP_TYPE_DMA, |
| 132 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 131 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sdm845_dpu_caps = { | 10 | static const struct dpu_caps sdm845_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED3, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 51 unmodified lines | |||
| 68 | .name = "sspp_0", .id = SSPP_VIG0, | 67 | .name = "sspp_0", .id = SSPP_VIG0, |
| 69 | .base = 0x4000, .len = 0x1c8, | 68 | .base = 0x4000, .len = 0x1c8, |
| 70 | .features = VIG_SDM845_MASK_SDMA, | 69 | .features = VIG_SDM845_MASK_SDMA, |
| 71 | .sblk = &sdm845_vig_sblk_0, | 70 | .sblk = &dpu_vig_sblk_qseed3_1_3, |
| 72 | .xin_id = 0, | 71 | .xin_id = 0, |
| 73 | .type = SSPP_TYPE_VIG, | 72 | .type = SSPP_TYPE_VIG, |
| 74 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 73 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 76 | .name = "sspp_1", .id = SSPP_VIG1, | 75 | .name = "sspp_1", .id = SSPP_VIG1, |
| 77 | .base = 0x6000, .len = 0x1c8, | 76 | .base = 0x6000, .len = 0x1c8, |
| 78 | .features = VIG_SDM845_MASK_SDMA, | 77 | .features = VIG_SDM845_MASK_SDMA, |
| 79 | .sblk = &sdm845_vig_sblk_1, | 78 | .sblk = &dpu_vig_sblk_qseed3_1_3, |
| 80 | .xin_id = 4, | 79 | .xin_id = 4, |
| 81 | .type = SSPP_TYPE_VIG, | 80 | .type = SSPP_TYPE_VIG, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 84 | .name = "sspp_2", .id = SSPP_VIG2, | 83 | .name = "sspp_2", .id = SSPP_VIG2, |
| 85 | .base = 0x8000, .len = 0x1c8, | 84 | .base = 0x8000, .len = 0x1c8, |
| 86 | .features = VIG_SDM845_MASK_SDMA, | 85 | .features = VIG_SDM845_MASK_SDMA, |
| 87 | .sblk = &sdm845_vig_sblk_2, | 86 | .sblk = &dpu_vig_sblk_qseed3_1_3, |
| 88 | .xin_id = 8, | 87 | .xin_id = 8, |
| 89 | .type = SSPP_TYPE_VIG, | 88 | .type = SSPP_TYPE_VIG, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 92 | .name = "sspp_3", .id = SSPP_VIG3, | 91 | .name = "sspp_3", .id = SSPP_VIG3, |
| 93 | .base = 0xa000, .len = 0x1c8, | 92 | .base = 0xa000, .len = 0x1c8, |
| 94 | .features = VIG_SDM845_MASK_SDMA, | 93 | .features = VIG_SDM845_MASK_SDMA, |
| 95 | .sblk = &sdm845_vig_sblk_3, | 94 | .sblk = &dpu_vig_sblk_qseed3_1_3, |
| 96 | .xin_id = 12, | 95 | .xin_id = 12, |
| 97 | .type = SSPP_TYPE_VIG, | 96 | .type = SSPP_TYPE_VIG, |
| 98 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 100 | .name = "sspp_8", .id = SSPP_DMA0, | 99 | .name = "sspp_8", .id = SSPP_DMA0, |
| 101 | .base = 0x24000, .len = 0x1c8, | 100 | .base = 0x24000, .len = 0x1c8, |
| 102 | .features = DMA_SDM845_MASK_SDMA, | 101 | .features = DMA_SDM845_MASK_SDMA, |
| 103 | .sblk = &sdm845_dma_sblk_0, | 102 | .sblk = &dpu_dma_sblk, |
| 104 | .xin_id = 1, | 103 | .xin_id = 1, |
| 105 | .type = SSPP_TYPE_DMA, | 104 | .type = SSPP_TYPE_DMA, |
| 106 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 105 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 108 | .name = "sspp_9", .id = SSPP_DMA1, | 107 | .name = "sspp_9", .id = SSPP_DMA1, |
| 109 | .base = 0x26000, .len = 0x1c8, | 108 | .base = 0x26000, .len = 0x1c8, |
| 110 | .features = DMA_SDM845_MASK_SDMA, | 109 | .features = DMA_SDM845_MASK_SDMA, |
| 111 | .sblk = &sdm845_dma_sblk_1, | 110 | .sblk = &dpu_dma_sblk, |
| 112 | .xin_id = 5, | 111 | .xin_id = 5, |
| 113 | .type = SSPP_TYPE_DMA, | 112 | .type = SSPP_TYPE_DMA, |
| 114 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 116 | .name = "sspp_10", .id = SSPP_DMA2, | 115 | .name = "sspp_10", .id = SSPP_DMA2, |
| 117 | .base = 0x28000, .len = 0x1c8, | 116 | .base = 0x28000, .len = 0x1c8, |
| 118 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 117 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 119 | .sblk = &sdm845_dma_sblk_2, | 118 | .sblk = &dpu_dma_sblk, |
| 120 | .xin_id = 9, | 119 | .xin_id = 9, |
| 121 | .type = SSPP_TYPE_DMA, | 120 | .type = SSPP_TYPE_DMA, |
| 122 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line | |||
| 124 | .name = "sspp_11", .id = SSPP_DMA3, | 123 | .name = "sspp_11", .id = SSPP_DMA3, |
| 125 | .base = 0x2a000, .len = 0x1c8, | 124 | .base = 0x2a000, .len = 0x1c8, |
| 126 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 125 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 127 | .sblk = &sdm845_dma_sblk_3, | 126 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 13, | 127 | .xin_id = 13, |
| 129 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 130 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 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 | static const struct dpu_caps sm8150_dpu_caps = { | 10 | static const struct dpu_caps sm8150_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED3, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 60 unmodified lines | |||
| 77 | .name = "sspp_0", .id = SSPP_VIG0, | 76 | .name = "sspp_0", .id = SSPP_VIG0, |
| 78 | .base = 0x4000, .len = 0x1f0, | 77 | .base = 0x4000, .len = 0x1f0, |
| 79 | .features = VIG_SDM845_MASK, | 78 | .features = VIG_SDM845_MASK, |
| 80 | .sblk = &sdm845_vig_sblk_0, | 79 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 81 | .xin_id = 0, | 80 | .xin_id = 0, |
| 82 | .type = SSPP_TYPE_VIG, | 81 | .type = SSPP_TYPE_VIG, |
| 83 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -85,7 +84,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 85 | .name = "sspp_1", .id = SSPP_VIG1, | 84 | .name = "sspp_1", .id = SSPP_VIG1, |
| 86 | .base = 0x6000, .len = 0x1f0, | 85 | .base = 0x6000, .len = 0x1f0, |
| 87 | .features = VIG_SDM845_MASK, | 86 | .features = VIG_SDM845_MASK, |
| 88 | .sblk = &sdm845_vig_sblk_1, | 87 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 89 | .xin_id = 4, | 88 | .xin_id = 4, |
| 90 | .type = SSPP_TYPE_VIG, | 89 | .type = SSPP_TYPE_VIG, |
| 91 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -93,7 +92,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 93 | .name = "sspp_2", .id = SSPP_VIG2, | 92 | .name = "sspp_2", .id = SSPP_VIG2, |
| 94 | .base = 0x8000, .len = 0x1f0, | 93 | .base = 0x8000, .len = 0x1f0, |
| 95 | .features = VIG_SDM845_MASK, | 94 | .features = VIG_SDM845_MASK, |
| 96 | .sblk = &sdm845_vig_sblk_2, | 95 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 97 | .xin_id = 8, | 96 | .xin_id = 8, |
| 98 | .type = SSPP_TYPE_VIG, | 97 | .type = SSPP_TYPE_VIG, |
| 99 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -101,7 +100,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 101 | .name = "sspp_3", .id = SSPP_VIG3, | 100 | .name = "sspp_3", .id = SSPP_VIG3, |
| 102 | .base = 0xa000, .len = 0x1f0, | 101 | .base = 0xa000, .len = 0x1f0, |
| 103 | .features = VIG_SDM845_MASK, | 102 | .features = VIG_SDM845_MASK, |
| 104 | .sblk = &sdm845_vig_sblk_3, | 103 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 105 | .xin_id = 12, | 104 | .xin_id = 12, |
| 106 | .type = SSPP_TYPE_VIG, | 105 | .type = SSPP_TYPE_VIG, |
| 107 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -109,7 +108,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 109 | .name = "sspp_8", .id = SSPP_DMA0, | 108 | .name = "sspp_8", .id = SSPP_DMA0, |
| 110 | .base = 0x24000, .len = 0x1f0, | 109 | .base = 0x24000, .len = 0x1f0, |
| 111 | .features = DMA_SDM845_MASK, | 110 | .features = DMA_SDM845_MASK, |
| 112 | .sblk = &sdm845_dma_sblk_0, | 111 | .sblk = &dpu_dma_sblk, |
| 113 | .xin_id = 1, | 112 | .xin_id = 1, |
| 114 | .type = SSPP_TYPE_DMA, | 113 | .type = SSPP_TYPE_DMA, |
| 115 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -117,7 +116,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 117 | .name = "sspp_9", .id = SSPP_DMA1, | 116 | .name = "sspp_9", .id = SSPP_DMA1, |
| 118 | .base = 0x26000, .len = 0x1f0, | 117 | .base = 0x26000, .len = 0x1f0, |
| 119 | .features = DMA_SDM845_MASK, | 118 | .features = DMA_SDM845_MASK, |
| 120 | .sblk = &sdm845_dma_sblk_1, | 119 | .sblk = &dpu_dma_sblk, |
| 121 | .xin_id = 5, | 120 | .xin_id = 5, |
| 122 | .type = SSPP_TYPE_DMA, | 121 | .type = SSPP_TYPE_DMA, |
| 123 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -125,7 +124,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 125 | .name = "sspp_10", .id = SSPP_DMA2, | 124 | .name = "sspp_10", .id = SSPP_DMA2, |
| 126 | .base = 0x28000, .len = 0x1f0, | 125 | .base = 0x28000, .len = 0x1f0, |
| 127 | .features = DMA_CURSOR_SDM845_MASK, | 126 | .features = DMA_CURSOR_SDM845_MASK, |
| 128 | .sblk = &sdm845_dma_sblk_2, | 127 | .sblk = &dpu_dma_sblk, |
| 129 | .xin_id = 9, | 128 | .xin_id = 9, |
| 130 | .type = SSPP_TYPE_DMA, | 129 | .type = SSPP_TYPE_DMA, |
| 131 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -133,7 +132,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line | |||
| 133 | .name = "sspp_11", .id = SSPP_DMA3, | 132 | .name = "sspp_11", .id = SSPP_DMA3, |
| 134 | .base = 0x2a000, .len = 0x1f0, | 133 | .base = 0x2a000, .len = 0x1f0, |
| 135 | .features = DMA_CURSOR_SDM845_MASK, | 134 | .features = DMA_CURSOR_SDM845_MASK, |
| 136 | .sblk = &sdm845_dma_sblk_3, | 135 | .sblk = &dpu_dma_sblk, |
| 137 | .xin_id = 13, | 136 | .xin_id = 13, |
| 138 | .type = SSPP_TYPE_DMA, | 137 | .type = SSPP_TYPE_DMA, |
| 139 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sc8180x_dpu_caps = { | 10 | static const struct dpu_caps sc8180x_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED3, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 59 unmodified lines | |||
| 76 | .name = "sspp_0", .id = SSPP_VIG0, | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | .base = 0x4000, .len = 0x1f0, | 76 | .base = 0x4000, .len = 0x1f0, |
| 78 | .features = VIG_SDM845_MASK, | 77 | .features = VIG_SDM845_MASK, |
| 79 | .sblk = &sdm845_vig_sblk_0, | 78 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 80 | .xin_id = 0, | 79 | .xin_id = 0, |
| 81 | .type = SSPP_TYPE_VIG, | 80 | .type = SSPP_TYPE_VIG, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 84 | .name = "sspp_1", .id = SSPP_VIG1, | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | .base = 0x6000, .len = 0x1f0, | 84 | .base = 0x6000, .len = 0x1f0, |
| 86 | .features = VIG_SDM845_MASK, | 85 | .features = VIG_SDM845_MASK, |
| 87 | .sblk = &sdm845_vig_sblk_1, | 86 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 88 | .xin_id = 4, | 87 | .xin_id = 4, |
| 89 | .type = SSPP_TYPE_VIG, | 88 | .type = SSPP_TYPE_VIG, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| @@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 92 | .name = "sspp_2", .id = SSPP_VIG2, | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | .base = 0x8000, .len = 0x1f0, | 92 | .base = 0x8000, .len = 0x1f0, |
| 94 | .features = VIG_SDM845_MASK, | 93 | .features = VIG_SDM845_MASK, |
| 95 | .sblk = &sdm845_vig_sblk_2, | 94 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 96 | .xin_id = 8, | 95 | .xin_id = 8, |
| 97 | .type = SSPP_TYPE_VIG, | 96 | .type = SSPP_TYPE_VIG, |
| 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| @@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 100 | .name = "sspp_3", .id = SSPP_VIG3, | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | .base = 0xa000, .len = 0x1f0, | 100 | .base = 0xa000, .len = 0x1f0, |
| 102 | .features = VIG_SDM845_MASK, | 101 | .features = VIG_SDM845_MASK, |
| 103 | .sblk = &sdm845_vig_sblk_3, | 102 | .sblk = &dpu_vig_sblk_qseed3_1_4, |
| 104 | .xin_id = 12, | 103 | .xin_id = 12, |
| 105 | .type = SSPP_TYPE_VIG, | 104 | .type = SSPP_TYPE_VIG, |
| 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 108 | .name = "sspp_8", .id = SSPP_DMA0, | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | .base = 0x24000, .len = 0x1f0, | 108 | .base = 0x24000, .len = 0x1f0, |
| 110 | .features = DMA_SDM845_MASK, | 109 | .features = DMA_SDM845_MASK, |
| 111 | .sblk = &sdm845_dma_sblk_0, | 110 | .sblk = &dpu_dma_sblk, |
| 112 | .xin_id = 1, | 111 | .xin_id = 1, |
| 113 | .type = SSPP_TYPE_DMA, | 112 | .type = SSPP_TYPE_DMA, |
| 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 116 | .name = "sspp_9", .id = SSPP_DMA1, | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | .base = 0x26000, .len = 0x1f0, | 116 | .base = 0x26000, .len = 0x1f0, |
| 118 | .features = DMA_SDM845_MASK, | 117 | .features = DMA_SDM845_MASK, |
| 119 | .sblk = &sdm845_dma_sblk_1, | 118 | .sblk = &dpu_dma_sblk, |
| 120 | .xin_id = 5, | 119 | .xin_id = 5, |
| 121 | .type = SSPP_TYPE_DMA, | 120 | .type = SSPP_TYPE_DMA, |
| 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 124 | .name = "sspp_10", .id = SSPP_DMA2, | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | .base = 0x28000, .len = 0x1f0, | 124 | .base = 0x28000, .len = 0x1f0, |
| 126 | .features = DMA_CURSOR_SDM845_MASK, | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | .sblk = &sdm845_dma_sblk_2, | 126 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 9, | 127 | .xin_id = 9, |
| 129 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line | |||
| 132 | .name = "sspp_11", .id = SSPP_DMA3, | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | .base = 0x2a000, .len = 0x1f0, | 132 | .base = 0x2a000, .len = 0x1f0, |
| 134 | .features = DMA_CURSOR_SDM845_MASK, | 133 | .features = DMA_CURSOR_SDM845_MASK, |
| 135 | .sblk = &sdm845_dma_sblk_3, | 134 | .sblk = &dpu_dma_sblk, |
| 136 | .xin_id = 13, | 135 | .xin_id = 13, |
| 137 | .type = SSPP_TYPE_DMA, | 136 | .type = SSPP_TYPE_DMA, |
| 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -367,6 +366,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = { · 228 unmodified lines | |||
| 367 | .min_llcc_ib = 800000, | 366 | .min_llcc_ib = 800000, |
| 368 | .min_dram_ib = 800000, | 367 | .min_dram_ib = 800000, |
| 369 | .danger_lut_tbl = {0xf, 0xffff, 0x0}, | 368 | .danger_lut_tbl = {0xf, 0xffff, 0x0}, |
| 369 | .safe_lut_tbl = {0xfff0, 0xf000, 0xffff}, | ||
| 370 | .qos_lut_tbl = { | 370 | .qos_lut_tbl = { |
| 371 | {.nentry = ARRAY_SIZE(sc7180_qos_linear), | 371 | {.nentry = ARRAY_SIZE(sc7180_qos_linear), |
| 372 | .entries = sc7180_qos_linear | 372 | .entries = sc7180_qos_linear |
| @@ -68,8 +68,8 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 67 unmodified lines | |||
| 68 | { | 68 | { |
| 69 | .name = "sspp_0", .id = SSPP_VIG0, | 69 | .name = "sspp_0", .id = SSPP_VIG0, |
| 70 | .base = 0x4000, .len = 0x1f0, | 70 | .base = 0x4000, .len = 0x1f0, |
| 71 | .features = VIG_SM6125_MASK, | 71 | .features = VIG_SDM845_MASK, |
| 72 | .sblk = &sm6125_vig_sblk_0, | 72 | .sblk = &dpu_vig_sblk_qseed3_2_4, |
| 73 | .xin_id = 0, | 73 | .xin_id = 0, |
| 74 | .type = SSPP_TYPE_VIG, | 74 | .type = SSPP_TYPE_VIG, |
| 75 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 75 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line | |||
| 77 | .name = "sspp_8", .id = SSPP_DMA0, | 77 | .name = "sspp_8", .id = SSPP_DMA0, |
| 78 | .base = 0x24000, .len = 0x1f0, | 78 | .base = 0x24000, .len = 0x1f0, |
| 79 | .features = DMA_SDM845_MASK, | 79 | .features = DMA_SDM845_MASK, |
| 80 | .sblk = &sdm845_dma_sblk_0, | 80 | .sblk = &dpu_dma_sblk, |
| 81 | .xin_id = 1, | 81 | .xin_id = 1, |
| 82 | .type = SSPP_TYPE_DMA, | 82 | .type = SSPP_TYPE_DMA, |
| 83 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 83 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line | |||
| 85 | .name = "sspp_9", .id = SSPP_DMA1, | 85 | .name = "sspp_9", .id = SSPP_DMA1, |
| 86 | .base = 0x26000, .len = 0x1f0, | 86 | .base = 0x26000, .len = 0x1f0, |
| 87 | .features = DMA_SDM845_MASK, | 87 | .features = DMA_SDM845_MASK, |
| 88 | .sblk = &sdm845_dma_sblk_1, | 88 | .sblk = &dpu_dma_sblk, |
| 89 | .xin_id = 5, | 89 | .xin_id = 5, |
| 90 | .type = SSPP_TYPE_DMA, | 90 | .type = SSPP_TYPE_DMA, |
| 91 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 91 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sm8250_dpu_caps = { | 10 | static const struct dpu_caps sm8250_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -32,7 +31,7 @@ static const struct dpu_mdp_cfg sm8250_mdp = { · 15 unmodified lines | |||
| 32 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, | 31 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 33 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, | 32 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 34 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, | 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 | .name = "sspp_0", .id = SSPP_VIG0, | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | .base = 0x4000, .len = 0x1f8, | 76 | .base = 0x4000, .len = 0x1f8, |
| 78 | .features = VIG_SC7180_MASK_SDMA, | 77 | .features = VIG_SDM845_MASK_SDMA, |
| 79 | .sblk = &sm8250_vig_sblk_0, | 78 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 80 | .xin_id = 0, | 79 | .xin_id = 0, |
| 81 | .type = SSPP_TYPE_VIG, | 80 | .type = SSPP_TYPE_VIG, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | }, { | 82 | }, { |
| 84 | .name = "sspp_1", .id = SSPP_VIG1, | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | .base = 0x6000, .len = 0x1f8, | 84 | .base = 0x6000, .len = 0x1f8, |
| 86 | .features = VIG_SC7180_MASK_SDMA, | 85 | .features = VIG_SDM845_MASK_SDMA, |
| 87 | .sblk = &sm8250_vig_sblk_1, | 86 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 88 | .xin_id = 4, | 87 | .xin_id = 4, |
| 89 | .type = SSPP_TYPE_VIG, | 88 | .type = SSPP_TYPE_VIG, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | }, { | 90 | }, { |
| 92 | .name = "sspp_2", .id = SSPP_VIG2, | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | .base = 0x8000, .len = 0x1f8, | 92 | .base = 0x8000, .len = 0x1f8, |
| 94 | .features = VIG_SC7180_MASK_SDMA, | 93 | .features = VIG_SDM845_MASK_SDMA, |
| 95 | .sblk = &sm8250_vig_sblk_2, | 94 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 96 | .xin_id = 8, | 95 | .xin_id = 8, |
| 97 | .type = SSPP_TYPE_VIG, | 96 | .type = SSPP_TYPE_VIG, |
| 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | }, { | 98 | }, { |
| 100 | .name = "sspp_3", .id = SSPP_VIG3, | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | .base = 0xa000, .len = 0x1f8, | 100 | .base = 0xa000, .len = 0x1f8, |
| 102 | .features = VIG_SC7180_MASK_SDMA, | 101 | .features = VIG_SDM845_MASK_SDMA, |
| 103 | .sblk = &sm8250_vig_sblk_3, | 102 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 104 | .xin_id = 12, | 103 | .xin_id = 12, |
| 105 | .type = SSPP_TYPE_VIG, | 104 | .type = SSPP_TYPE_VIG, |
| 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | |||
| 108 | .name = "sspp_8", .id = SSPP_DMA0, | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | .base = 0x24000, .len = 0x1f8, | 108 | .base = 0x24000, .len = 0x1f8, |
| 110 | .features = DMA_SDM845_MASK_SDMA, | 109 | .features = DMA_SDM845_MASK_SDMA, |
| 111 | .sblk = &sdm845_dma_sblk_0, | 110 | .sblk = &dpu_dma_sblk, |
| 112 | .xin_id = 1, | 111 | .xin_id = 1, |
| 113 | .type = SSPP_TYPE_DMA, | 112 | .type = SSPP_TYPE_DMA, |
| 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | |||
| 116 | .name = "sspp_9", .id = SSPP_DMA1, | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | .base = 0x26000, .len = 0x1f8, | 116 | .base = 0x26000, .len = 0x1f8, |
| 118 | .features = DMA_SDM845_MASK_SDMA, | 117 | .features = DMA_SDM845_MASK_SDMA, |
| 119 | .sblk = &sdm845_dma_sblk_1, | 118 | .sblk = &dpu_dma_sblk, |
| 120 | .xin_id = 5, | 119 | .xin_id = 5, |
| 121 | .type = SSPP_TYPE_DMA, | 120 | .type = SSPP_TYPE_DMA, |
| 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | |||
| 124 | .name = "sspp_10", .id = SSPP_DMA2, | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | .base = 0x28000, .len = 0x1f8, | 124 | .base = 0x28000, .len = 0x1f8, |
| 126 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 125 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 127 | .sblk = &sdm845_dma_sblk_2, | 126 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 9, | 127 | .xin_id = 9, |
| 129 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line | |||
| 132 | .name = "sspp_11", .id = SSPP_DMA3, | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | .base = 0x2a000, .len = 0x1f8, | 132 | .base = 0x2a000, .len = 0x1f8, |
| 134 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 133 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 135 | .sblk = &sdm845_dma_sblk_3, | 134 | .sblk = &dpu_dma_sblk, |
| 136 | .xin_id = 13, | 135 | .xin_id = 13, |
| 137 | .type = SSPP_TYPE_DMA, | 136 | .type = SSPP_TYPE_DMA, |
| 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -337,8 +336,8 @@ static const struct dpu_wb_cfg sm8250_wb[] = { · 198 unmodified lines | |||
| 337 | .name = "wb_2", .id = WB_2, | 336 | .name = "wb_2", .id = WB_2, |
| 338 | .base = 0x65000, .len = 0x2c8, | 337 | .base = 0x65000, .len = 0x2c8, |
| 339 | .features = WB_SM8250_MASK, | 338 | .features = WB_SM8250_MASK, |
| 340 | .format_list = wb2_formats, | 339 | .format_list = wb2_formats_rgb_yuv, |
| 341 | .num_formats = ARRAY_SIZE(wb2_formats), | 340 | .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), |
| 342 | .clk_ctrl = DPU_CLK_CTRL_WB2, | 341 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 343 | .xin_id = 6, | 342 | .xin_id = 6, |
| 344 | .vbif_idx = VBIF_RT, | 343 | .vbif_idx = VBIF_RT, |
| @@ -385,6 +384,7 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { · 40 unmodified lines | |||
| 385 | .mdss_ver = &sm8250_mdss_ver, | 384 | .mdss_ver = &sm8250_mdss_ver, |
| 386 | .caps = &sm8250_dpu_caps, | 385 | .caps = &sm8250_dpu_caps, |
| 387 | .mdp = &sm8250_mdp, | 386 | .mdp = &sm8250_mdp, |
| 387 | .cdm = &sc7280_cdm, | ||
| 388 | .ctl_count = ARRAY_SIZE(sm8250_ctl), | 388 | .ctl_count = ARRAY_SIZE(sm8250_ctl), |
| 389 | .ctl = sm8250_ctl, | 389 | .ctl = sm8250_ctl, |
| 390 | .sspp_count = ARRAY_SIZE(sm8250_sspp), | 390 | .sspp_count = ARRAY_SIZE(sm8250_sspp), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sc7180_dpu_caps = { | 10 | static const struct dpu_caps sc7180_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0x9, | 12 | .max_mixer_blendstages = 0x9, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_dim_layer = true, | 13 | .has_dim_layer = true, |
| 15 | .has_idle_pc = true, | 14 | .has_idle_pc = true, |
| 16 | .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 15 | .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| @@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7180_mdp = { · 8 unmodified lines | |||
| 25 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, | 24 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, |
| 26 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, | 25 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 27 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, | 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 | .name = "sspp_0", .id = SSPP_VIG0, | 52 | .name = "sspp_0", .id = SSPP_VIG0, |
| 54 | .base = 0x4000, .len = 0x1f8, | 53 | .base = 0x4000, .len = 0x1f8, |
| 55 | .features = VIG_SC7180_MASK, | 54 | .features = VIG_SDM845_MASK, |
| 56 | .sblk = &sc7180_vig_sblk_0, | 55 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 57 | .xin_id = 0, | 56 | .xin_id = 0, |
| 58 | .type = SSPP_TYPE_VIG, | 57 | .type = SSPP_TYPE_VIG, |
| 59 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 58 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -61,7 +60,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | |||
| 61 | .name = "sspp_8", .id = SSPP_DMA0, | 60 | .name = "sspp_8", .id = SSPP_DMA0, |
| 62 | .base = 0x24000, .len = 0x1f8, | 61 | .base = 0x24000, .len = 0x1f8, |
| 63 | .features = DMA_SDM845_MASK, | 62 | .features = DMA_SDM845_MASK, |
| 64 | .sblk = &sdm845_dma_sblk_0, | 63 | .sblk = &dpu_dma_sblk, |
| 65 | .xin_id = 1, | 64 | .xin_id = 1, |
| 66 | .type = SSPP_TYPE_DMA, | 65 | .type = SSPP_TYPE_DMA, |
| 67 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 66 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -69,7 +68,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | |||
| 69 | .name = "sspp_9", .id = SSPP_DMA1, | 68 | .name = "sspp_9", .id = SSPP_DMA1, |
| 70 | .base = 0x26000, .len = 0x1f8, | 69 | .base = 0x26000, .len = 0x1f8, |
| 71 | .features = DMA_CURSOR_SDM845_MASK, | 70 | .features = DMA_CURSOR_SDM845_MASK, |
| 72 | .sblk = &sdm845_dma_sblk_1, | 71 | .sblk = &dpu_dma_sblk, |
| 73 | .xin_id = 5, | 72 | .xin_id = 5, |
| 74 | .type = SSPP_TYPE_DMA, | 73 | .type = SSPP_TYPE_DMA, |
| 75 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 74 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line | |||
| 77 | .name = "sspp_10", .id = SSPP_DMA2, | 76 | .name = "sspp_10", .id = SSPP_DMA2, |
| 78 | .base = 0x28000, .len = 0x1f8, | 77 | .base = 0x28000, .len = 0x1f8, |
| 79 | .features = DMA_CURSOR_SDM845_MASK, | 78 | .features = DMA_CURSOR_SDM845_MASK, |
| 80 | .sblk = &sdm845_dma_sblk_2, | 79 | .sblk = &dpu_dma_sblk, |
| 81 | .xin_id = 9, | 80 | .xin_id = 9, |
| 82 | .type = SSPP_TYPE_DMA, | 81 | .type = SSPP_TYPE_DMA, |
| 83 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 82 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -158,8 +157,8 @@ static const struct dpu_wb_cfg sc7180_wb[] = { · 74 unmodified lines | |||
| 158 | .name = "wb_2", .id = WB_2, | 157 | .name = "wb_2", .id = WB_2, |
| 159 | .base = 0x65000, .len = 0x2c8, | 158 | .base = 0x65000, .len = 0x2c8, |
| 160 | .features = WB_SM8250_MASK, | 159 | .features = WB_SM8250_MASK, |
| 161 | .format_list = wb2_formats, | 160 | .format_list = wb2_formats_rgb, |
| 162 | .num_formats = ARRAY_SIZE(wb2_formats), | 161 | .num_formats = ARRAY_SIZE(wb2_formats_rgb), |
| 163 | .clk_ctrl = DPU_CLK_CTRL_WB2, | 162 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 164 | .xin_id = 6, | 163 | .xin_id = 6, |
| 165 | .vbif_idx = VBIF_RT, | 164 | .vbif_idx = VBIF_RT, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sm6115_dpu_caps = { | 10 | static const struct dpu_caps sm6115_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0x4, | 12 | .max_mixer_blendstages = 0x4, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_dim_layer = true, | 13 | .has_dim_layer = true, |
| 15 | .has_idle_pc = true, | 14 | .has_idle_pc = true, |
| 16 | .max_linewidth = 2160, | 15 | .max_linewidth = 2160, |
| @@ -39,8 +38,8 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 22 unmodified lines | |||
| 39 | { | 38 | { |
| 40 | .name = "sspp_0", .id = SSPP_VIG0, | 39 | .name = "sspp_0", .id = SSPP_VIG0, |
| 41 | .base = 0x4000, .len = 0x1f8, | 40 | .base = 0x4000, .len = 0x1f8, |
| 42 | .features = VIG_SC7180_MASK, | 41 | .features = VIG_SDM845_MASK, |
| 43 | .sblk = &sm6115_vig_sblk_0, | 42 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 44 | .xin_id = 0, | 43 | .xin_id = 0, |
| 45 | .type = SSPP_TYPE_VIG, | 44 | .type = SSPP_TYPE_VIG, |
| 46 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 45 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -48,7 +47,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 1 unmodified line | |||
| 48 | .name = "sspp_8", .id = SSPP_DMA0, | 47 | .name = "sspp_8", .id = SSPP_DMA0, |
| 49 | .base = 0x24000, .len = 0x1f8, | 48 | .base = 0x24000, .len = 0x1f8, |
| 50 | .features = DMA_SDM845_MASK, | 49 | .features = DMA_SDM845_MASK, |
| 51 | .sblk = &sdm845_dma_sblk_0, | 50 | .sblk = &dpu_dma_sblk, |
| 52 | .xin_id = 1, | 51 | .xin_id = 1, |
| 53 | .type = SSPP_TYPE_DMA, | 52 | .type = SSPP_TYPE_DMA, |
| 54 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 53 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | |||
| 11 | static const struct dpu_caps sm6350_dpu_caps = { | 11 | static const struct dpu_caps sm6350_dpu_caps = { |
| 12 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 12 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 13 | .max_mixer_blendstages = 0x7, | 13 | .max_mixer_blendstages = 0x7, |
| 14 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 15 | .has_src_split = true, | 14 | .has_src_split = true, |
| 16 | .has_dim_layer = true, | 15 | .has_dim_layer = true, |
| 17 | .has_idle_pc = true, | 16 | .has_idle_pc = true, |
| @@ -59,8 +58,8 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 41 unmodified lines | |||
| 59 | { | 58 | { |
| 60 | .name = "sspp_0", .id = SSPP_VIG0, | 59 | .name = "sspp_0", .id = SSPP_VIG0, |
| 61 | .base = 0x4000, .len = 0x1f8, | 60 | .base = 0x4000, .len = 0x1f8, |
| 62 | .features = VIG_SC7180_MASK, | 61 | .features = VIG_SDM845_MASK, |
| 63 | .sblk = &sc7180_vig_sblk_0, | 62 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 64 | .xin_id = 0, | 63 | .xin_id = 0, |
| 65 | .type = SSPP_TYPE_VIG, | 64 | .type = SSPP_TYPE_VIG, |
| 66 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 65 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | |||
| 68 | .name = "sspp_8", .id = SSPP_DMA0, | 67 | .name = "sspp_8", .id = SSPP_DMA0, |
| 69 | .base = 0x24000, .len = 0x1f8, | 68 | .base = 0x24000, .len = 0x1f8, |
| 70 | .features = DMA_SDM845_MASK, | 69 | .features = DMA_SDM845_MASK, |
| 71 | .sblk = &sdm845_dma_sblk_0, | 70 | .sblk = &dpu_dma_sblk, |
| 72 | .xin_id = 1, | 71 | .xin_id = 1, |
| 73 | .type = SSPP_TYPE_DMA, | 72 | .type = SSPP_TYPE_DMA, |
| 74 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 73 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | |||
| 76 | .name = "sspp_9", .id = SSPP_DMA1, | 75 | .name = "sspp_9", .id = SSPP_DMA1, |
| 77 | .base = 0x26000, .len = 0x1f8, | 76 | .base = 0x26000, .len = 0x1f8, |
| 78 | .features = DMA_CURSOR_SDM845_MASK, | 77 | .features = DMA_CURSOR_SDM845_MASK, |
| 79 | .sblk = &sdm845_dma_sblk_1, | 78 | .sblk = &dpu_dma_sblk, |
| 80 | .xin_id = 5, | 79 | .xin_id = 5, |
| 81 | .type = SSPP_TYPE_DMA, | 80 | .type = SSPP_TYPE_DMA, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 81 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line | |||
| 84 | .name = "sspp_10", .id = SSPP_DMA2, | 83 | .name = "sspp_10", .id = SSPP_DMA2, |
| 85 | .base = 0x28000, .len = 0x1f8, | 84 | .base = 0x28000, .len = 0x1f8, |
| 86 | .features = DMA_CURSOR_SDM845_MASK, | 85 | .features = DMA_CURSOR_SDM845_MASK, |
| 87 | .sblk = &sdm845_dma_sblk_2, | 86 | .sblk = &dpu_dma_sblk, |
| 88 | .xin_id = 9, | 87 | .xin_id = 9, |
| 89 | .type = SSPP_TYPE_DMA, | 88 | .type = SSPP_TYPE_DMA, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 89 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 38 unmodified lines | |||
| 39 | .name = "sspp_0", .id = SSPP_VIG0, | 39 | .name = "sspp_0", .id = SSPP_VIG0, |
| 40 | .base = 0x4000, .len = 0x1f8, | 40 | .base = 0x4000, .len = 0x1f8, |
| 41 | .features = VIG_QCM2290_MASK, | 41 | .features = VIG_QCM2290_MASK, |
| 42 | .sblk = &qcm2290_vig_sblk_0, | 42 | .sblk = &dpu_vig_sblk_noscale, |
| 43 | .xin_id = 0, | 43 | .xin_id = 0, |
| 44 | .type = SSPP_TYPE_VIG, | 44 | .type = SSPP_TYPE_VIG, |
| 45 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 45 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 1 unmodified line | |||
| 47 | .name = "sspp_8", .id = SSPP_DMA0, | 47 | .name = "sspp_8", .id = SSPP_DMA0, |
| 48 | .base = 0x24000, .len = 0x1f8, | 48 | .base = 0x24000, .len = 0x1f8, |
| 49 | .features = DMA_SDM845_MASK, | 49 | .features = DMA_SDM845_MASK, |
| 50 | .sblk = &qcm2290_dma_sblk_0, | 50 | .sblk = &dpu_dma_sblk, |
| 51 | .xin_id = 1, | 51 | .xin_id = 1, |
| 52 | .type = SSPP_TYPE_DMA, | 52 | .type = SSPP_TYPE_DMA, |
| 53 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 53 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | |||
| 11 | static const struct dpu_caps sm6375_dpu_caps = { | 11 | static const struct dpu_caps sm6375_dpu_caps = { |
| 12 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, | 12 | .max_mixer_width = DEFAULT_DPU_LINE_WIDTH, |
| 13 | .max_mixer_blendstages = 0x4, | 13 | .max_mixer_blendstages = 0x4, |
| 14 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| 17 | .max_linewidth = 2160, | 16 | .max_linewidth = 2160, |
| @@ -40,8 +39,8 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 22 unmodified lines | |||
| 40 | { | 39 | { |
| 41 | .name = "sspp_0", .id = SSPP_VIG0, | 40 | .name = "sspp_0", .id = SSPP_VIG0, |
| 42 | .base = 0x4000, .len = 0x1f8, | 41 | .base = 0x4000, .len = 0x1f8, |
| 43 | .features = VIG_SC7180_MASK, | 42 | .features = VIG_SDM845_MASK, |
| 44 | .sblk = &sm6115_vig_sblk_0, | 43 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 45 | .xin_id = 0, | 44 | .xin_id = 0, |
| 46 | .type = SSPP_TYPE_VIG, | 45 | .type = SSPP_TYPE_VIG, |
| 47 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 46 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -49,7 +48,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 1 unmodified line | |||
| 49 | .name = "sspp_8", .id = SSPP_DMA0, | 48 | .name = "sspp_8", .id = SSPP_DMA0, |
| 50 | .base = 0x24000, .len = 0x1f8, | 49 | .base = 0x24000, .len = 0x1f8, |
| 51 | .features = DMA_SDM845_MASK, | 50 | .features = DMA_SDM845_MASK, |
| 52 | .sblk = &sdm845_dma_sblk_0, | 51 | .sblk = &dpu_dma_sblk, |
| 53 | .xin_id = 1, | 52 | .xin_id = 1, |
| 54 | .type = SSPP_TYPE_DMA, | 53 | .type = SSPP_TYPE_DMA, |
| 55 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 54 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sm8350_dpu_caps = { | 10 | static const struct dpu_caps sm8350_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -31,6 +30,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = { · 14 unmodified lines | |||
| 31 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, | 30 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 32 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, | 31 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 33 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, | 32 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 33 | [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | ||
| 34 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, | 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 | .name = "sspp_0", .id = SSPP_VIG0, | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 76 | .base = 0x4000, .len = 0x1f8, | 76 | .base = 0x4000, .len = 0x1f8, |
| 77 | .features = VIG_SC7180_MASK, | 77 | .features = VIG_SDM845_MASK_SDMA, |
| 78 | .sblk = &sm8250_vig_sblk_0, | 78 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 79 | .xin_id = 0, | 79 | .xin_id = 0, |
| 80 | .type = SSPP_TYPE_VIG, | 80 | .type = SSPP_TYPE_VIG, |
| 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 82 | }, { | 82 | }, { |
| 83 | .name = "sspp_1", .id = SSPP_VIG1, | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 84 | .base = 0x6000, .len = 0x1f8, | 84 | .base = 0x6000, .len = 0x1f8, |
| 85 | .features = VIG_SC7180_MASK, | 85 | .features = VIG_SDM845_MASK_SDMA, |
| 86 | .sblk = &sm8250_vig_sblk_1, | 86 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 87 | .xin_id = 4, | 87 | .xin_id = 4, |
| 88 | .type = SSPP_TYPE_VIG, | 88 | .type = SSPP_TYPE_VIG, |
| 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 90 | }, { | 90 | }, { |
| 91 | .name = "sspp_2", .id = SSPP_VIG2, | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 92 | .base = 0x8000, .len = 0x1f8, | 92 | .base = 0x8000, .len = 0x1f8, |
| 93 | .features = VIG_SC7180_MASK, | 93 | .features = VIG_SDM845_MASK_SDMA, |
| 94 | .sblk = &sm8250_vig_sblk_2, | 94 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 95 | .xin_id = 8, | 95 | .xin_id = 8, |
| 96 | .type = SSPP_TYPE_VIG, | 96 | .type = SSPP_TYPE_VIG, |
| 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 98 | }, { | 98 | }, { |
| 99 | .name = "sspp_3", .id = SSPP_VIG3, | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 100 | .base = 0xa000, .len = 0x1f8, | 100 | .base = 0xa000, .len = 0x1f8, |
| 101 | .features = VIG_SC7180_MASK, | 101 | .features = VIG_SDM845_MASK_SDMA, |
| 102 | .sblk = &sm8250_vig_sblk_3, | 102 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 103 | .xin_id = 12, | 103 | .xin_id = 12, |
| 104 | .type = SSPP_TYPE_VIG, | 104 | .type = SSPP_TYPE_VIG, |
| 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| 106 | }, { | 106 | }, { |
| 107 | .name = "sspp_8", .id = SSPP_DMA0, | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 108 | .base = 0x24000, .len = 0x1f8, | 108 | .base = 0x24000, .len = 0x1f8, |
| 109 | .features = DMA_SDM845_MASK, | 109 | .features = DMA_SDM845_MASK_SDMA, |
| 110 | .sblk = &sdm845_dma_sblk_0, | 110 | .sblk = &dpu_dma_sblk, |
| 111 | .xin_id = 1, | 111 | .xin_id = 1, |
| 112 | .type = SSPP_TYPE_DMA, | 112 | .type = SSPP_TYPE_DMA, |
| 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| 114 | }, { | 114 | }, { |
| 115 | .name = "sspp_9", .id = SSPP_DMA1, | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 116 | .base = 0x26000, .len = 0x1f8, | 116 | .base = 0x26000, .len = 0x1f8, |
| 117 | .features = DMA_SDM845_MASK, | 117 | .features = DMA_SDM845_MASK_SDMA, |
| 118 | .sblk = &sdm845_dma_sblk_1, | 118 | .sblk = &dpu_dma_sblk, |
| 119 | .xin_id = 5, | 119 | .xin_id = 5, |
| 120 | .type = SSPP_TYPE_DMA, | 120 | .type = SSPP_TYPE_DMA, |
| 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| 122 | }, { | 122 | }, { |
| 123 | .name = "sspp_10", .id = SSPP_DMA2, | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 124 | .base = 0x28000, .len = 0x1f8, | 124 | .base = 0x28000, .len = 0x1f8, |
| 125 | .features = DMA_CURSOR_SDM845_MASK, | 125 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 126 | .sblk = &sdm845_dma_sblk_2, | 126 | .sblk = &dpu_dma_sblk, |
| 127 | .xin_id = 9, | 127 | .xin_id = 9, |
| 128 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| 130 | }, { | 130 | }, { |
| 131 | .name = "sspp_11", .id = SSPP_DMA3, | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 132 | .base = 0x2a000, .len = 0x1f8, | 132 | .base = 0x2a000, .len = 0x1f8, |
| 133 | .features = DMA_CURSOR_SDM845_MASK, | 133 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 134 | .sblk = &sdm845_dma_sblk_3, | 134 | .sblk = &dpu_dma_sblk, |
| 135 | .xin_id = 13, | 135 | .xin_id = 13, |
| 136 | .type = SSPP_TYPE_DMA, | 136 | .type = SSPP_TYPE_DMA, |
| 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 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 | static const struct dpu_intf_cfg sm8350_intf[] = { | 316 | static const struct dpu_intf_cfg sm8350_intf[] = { |
| 302 | { | 317 | { |
| 303 | .name = "intf_0", .id = INTF_0, | 318 | .name = "intf_0", .id = INTF_0, |
| @@ -393,6 +408,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { · 89 unmodified lines | |||
| 393 | .dsc = sm8350_dsc, | 408 | .dsc = sm8350_dsc, |
| 394 | .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), | 409 | .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), |
| 395 | .merge_3d = sm8350_merge_3d, | 410 | .merge_3d = sm8350_merge_3d, |
| 411 | .wb_count = ARRAY_SIZE(sm8350_wb), | ||
| 412 | .wb = sm8350_wb, | ||
| 396 | .intf_count = ARRAY_SIZE(sm8350_intf), | 413 | .intf_count = ARRAY_SIZE(sm8350_intf), |
| 397 | .intf = sm8350_intf, | 414 | .intf = sm8350_intf, |
| 398 | .vbif_count = ARRAY_SIZE(sdm845_vbif), | 415 | .vbif_count = ARRAY_SIZE(sdm845_vbif), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sc7280_dpu_caps = { | 10 | static const struct dpu_caps sc7280_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0x7, | 12 | .max_mixer_blendstages = 0x7, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_dim_layer = true, | 13 | .has_dim_layer = true, |
| 15 | .has_idle_pc = true, | 14 | .has_idle_pc = true, |
| 16 | .max_linewidth = 2400, | 15 | .max_linewidth = 2400, |
| @@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7280_mdp = { · 8 unmodified lines | |||
| 25 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, | 24 | [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, |
| 26 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, | 25 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 27 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, | 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 | .name = "sspp_0", .id = SSPP_VIG0, | 57 | .name = "sspp_0", .id = SSPP_VIG0, |
| 59 | .base = 0x4000, .len = 0x1f8, | 58 | .base = 0x4000, .len = 0x1f8, |
| 60 | .features = VIG_SC7280_MASK_SDMA, | 59 | .features = VIG_SC7280_MASK_SDMA, |
| 61 | .sblk = &sc7280_vig_sblk_0, | 60 | .sblk = &dpu_vig_sblk_qseed3_3_0_rot_v2, |
| 62 | .xin_id = 0, | 61 | .xin_id = 0, |
| 63 | .type = SSPP_TYPE_VIG, | 62 | .type = SSPP_TYPE_VIG, |
| 64 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 63 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| @@ -66,7 +65,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | |||
| 66 | .name = "sspp_8", .id = SSPP_DMA0, | 65 | .name = "sspp_8", .id = SSPP_DMA0, |
| 67 | .base = 0x24000, .len = 0x1f8, | 66 | .base = 0x24000, .len = 0x1f8, |
| 68 | .features = DMA_SDM845_MASK_SDMA, | 67 | .features = DMA_SDM845_MASK_SDMA, |
| 69 | .sblk = &sdm845_dma_sblk_0, | 68 | .sblk = &dpu_dma_sblk, |
| 70 | .xin_id = 1, | 69 | .xin_id = 1, |
| 71 | .type = SSPP_TYPE_DMA, | 70 | .type = SSPP_TYPE_DMA, |
| 72 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 71 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | |||
| 74 | .name = "sspp_9", .id = SSPP_DMA1, | 73 | .name = "sspp_9", .id = SSPP_DMA1, |
| 75 | .base = 0x26000, .len = 0x1f8, | 74 | .base = 0x26000, .len = 0x1f8, |
| 76 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 75 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 77 | .sblk = &sdm845_dma_sblk_1, | 76 | .sblk = &dpu_dma_sblk, |
| 78 | .xin_id = 5, | 77 | .xin_id = 5, |
| 79 | .type = SSPP_TYPE_DMA, | 78 | .type = SSPP_TYPE_DMA, |
| 80 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 79 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line | |||
| 82 | .name = "sspp_10", .id = SSPP_DMA2, | 81 | .name = "sspp_10", .id = SSPP_DMA2, |
| 83 | .base = 0x28000, .len = 0x1f8, | 82 | .base = 0x28000, .len = 0x1f8, |
| 84 | .features = DMA_CURSOR_SDM845_MASK_SDMA, | 83 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 85 | .sblk = &sdm845_dma_sblk_2, | 84 | .sblk = &dpu_dma_sblk, |
| 86 | .xin_id = 9, | 85 | .xin_id = 9, |
| 87 | .type = SSPP_TYPE_DMA, | 86 | .type = SSPP_TYPE_DMA, |
| 88 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 87 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -170,8 +169,8 @@ static const struct dpu_wb_cfg sc7280_wb[] = { · 81 unmodified lines | |||
| 170 | .name = "wb_2", .id = WB_2, | 169 | .name = "wb_2", .id = WB_2, |
| 171 | .base = 0x65000, .len = 0x2c8, | 170 | .base = 0x65000, .len = 0x2c8, |
| 172 | .features = WB_SM8250_MASK, | 171 | .features = WB_SM8250_MASK, |
| 173 | .format_list = wb2_formats, | 172 | .format_list = wb2_formats_rgb_yuv, |
| 174 | .num_formats = ARRAY_SIZE(wb2_formats), | 173 | .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv), |
| 175 | .clk_ctrl = DPU_CLK_CTRL_WB2, | 174 | .clk_ctrl = DPU_CLK_CTRL_WB2, |
| 176 | .xin_id = 6, | 175 | .xin_id = 6, |
| 177 | .vbif_idx = VBIF_RT, | 176 | .vbif_idx = VBIF_RT, |
| @@ -249,6 +248,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { · 71 unmodified lines | |||
| 249 | .mdss_ver = &sc7280_mdss_ver, | 248 | .mdss_ver = &sc7280_mdss_ver, |
| 250 | .caps = &sc7280_dpu_caps, | 249 | .caps = &sc7280_dpu_caps, |
| 251 | .mdp = &sc7280_mdp, | 250 | .mdp = &sc7280_mdp, |
| 251 | .cdm = &sc7280_cdm, | ||
| 252 | .ctl_count = ARRAY_SIZE(sc7280_ctl), | 252 | .ctl_count = ARRAY_SIZE(sc7280_ctl), |
| 253 | .ctl = sc7280_ctl, | 253 | .ctl = sc7280_ctl, |
| 254 | .sspp_count = ARRAY_SIZE(sc7280_sspp), | 254 | .sspp_count = ARRAY_SIZE(sc7280_sspp), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sc8280xp_dpu_caps = { | 10 | static const struct dpu_caps sc8280xp_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 11, | 12 | .max_mixer_blendstages = 11, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 58 unmodified lines | |||
| 75 | { | 74 | { |
| 76 | .name = "sspp_0", .id = SSPP_VIG0, | 75 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | .base = 0x4000, .len = 0x2ac, | 76 | .base = 0x4000, .len = 0x2ac, |
| 78 | .features = VIG_SC7180_MASK, | 77 | .features = VIG_SDM845_MASK, |
| 79 | .sblk = &sm8250_vig_sblk_0, | 78 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 80 | .xin_id = 0, | 79 | .xin_id = 0, |
| 81 | .type = SSPP_TYPE_VIG, | 80 | .type = SSPP_TYPE_VIG, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 81 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | }, { | 82 | }, { |
| 84 | .name = "sspp_1", .id = SSPP_VIG1, | 83 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | .base = 0x6000, .len = 0x2ac, | 84 | .base = 0x6000, .len = 0x2ac, |
| 86 | .features = VIG_SC7180_MASK, | 85 | .features = VIG_SDM845_MASK, |
| 87 | .sblk = &sm8250_vig_sblk_1, | 86 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 88 | .xin_id = 4, | 87 | .xin_id = 4, |
| 89 | .type = SSPP_TYPE_VIG, | 88 | .type = SSPP_TYPE_VIG, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 89 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | }, { | 90 | }, { |
| 92 | .name = "sspp_2", .id = SSPP_VIG2, | 91 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | .base = 0x8000, .len = 0x2ac, | 92 | .base = 0x8000, .len = 0x2ac, |
| 94 | .features = VIG_SC7180_MASK, | 93 | .features = VIG_SDM845_MASK, |
| 95 | .sblk = &sm8250_vig_sblk_2, | 94 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 96 | .xin_id = 8, | 95 | .xin_id = 8, |
| 97 | .type = SSPP_TYPE_VIG, | 96 | .type = SSPP_TYPE_VIG, |
| 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 97 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | }, { | 98 | }, { |
| 100 | .name = "sspp_3", .id = SSPP_VIG3, | 99 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | .base = 0xa000, .len = 0x2ac, | 100 | .base = 0xa000, .len = 0x2ac, |
| 102 | .features = VIG_SC7180_MASK, | 101 | .features = VIG_SDM845_MASK, |
| 103 | .sblk = &sm8250_vig_sblk_3, | 102 | .sblk = &dpu_vig_sblk_qseed3_3_0, |
| 104 | .xin_id = 12, | 103 | .xin_id = 12, |
| 105 | .type = SSPP_TYPE_VIG, | 104 | .type = SSPP_TYPE_VIG, |
| 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 105 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| @@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | |||
| 108 | .name = "sspp_8", .id = SSPP_DMA0, | 107 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | .base = 0x24000, .len = 0x2ac, | 108 | .base = 0x24000, .len = 0x2ac, |
| 110 | .features = DMA_SDM845_MASK, | 109 | .features = DMA_SDM845_MASK, |
| 111 | .sblk = &sdm845_dma_sblk_0, | 110 | .sblk = &dpu_dma_sblk, |
| 112 | .xin_id = 1, | 111 | .xin_id = 1, |
| 113 | .type = SSPP_TYPE_DMA, | 112 | .type = SSPP_TYPE_DMA, |
| 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 113 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| @@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | |||
| 116 | .name = "sspp_9", .id = SSPP_DMA1, | 115 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | .base = 0x26000, .len = 0x2ac, | 116 | .base = 0x26000, .len = 0x2ac, |
| 118 | .features = DMA_SDM845_MASK, | 117 | .features = DMA_SDM845_MASK, |
| 119 | .sblk = &sdm845_dma_sblk_1, | 118 | .sblk = &dpu_dma_sblk, |
| 120 | .xin_id = 5, | 119 | .xin_id = 5, |
| 121 | .type = SSPP_TYPE_DMA, | 120 | .type = SSPP_TYPE_DMA, |
| 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 121 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| @@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | |||
| 124 | .name = "sspp_10", .id = SSPP_DMA2, | 123 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | .base = 0x28000, .len = 0x2ac, | 124 | .base = 0x28000, .len = 0x2ac, |
| 126 | .features = DMA_CURSOR_SDM845_MASK, | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | .sblk = &sdm845_dma_sblk_2, | 126 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 9, | 127 | .xin_id = 9, |
| 129 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 129 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| @@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line | |||
| 132 | .name = "sspp_11", .id = SSPP_DMA3, | 131 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | .base = 0x2a000, .len = 0x2ac, | 132 | .base = 0x2a000, .len = 0x2ac, |
| 134 | .features = DMA_CURSOR_SDM845_MASK, | 133 | .features = DMA_CURSOR_SDM845_MASK, |
| 135 | .sblk = &sdm845_dma_sblk_3, | 134 | .sblk = &dpu_dma_sblk, |
| 136 | .xin_id = 13, | 135 | .xin_id = 13, |
| 137 | .type = SSPP_TYPE_DMA, | 136 | .type = SSPP_TYPE_DMA, |
| 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 137 | .clk_ctrl = DPU_CLK_CTRL_DMA3, |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sm8450_dpu_caps = { | 10 | static const struct dpu_caps sm8450_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -32,6 +31,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = { · 15 unmodified lines | |||
| 32 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, | 31 | [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, |
| 33 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, | 32 | [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, |
| 34 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, | 33 | [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, |
| 34 | [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, | ||
| 35 | [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, | 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 | .name = "sspp_0", .id = SSPP_VIG0, | 76 | .name = "sspp_0", .id = SSPP_VIG0, |
| 77 | .base = 0x4000, .len = 0x32c, | 77 | .base = 0x4000, .len = 0x32c, |
| 78 | .features = VIG_SC7180_MASK, | 78 | .features = VIG_SDM845_MASK_SDMA, |
| 79 | .sblk = &sm8250_vig_sblk_0, | 79 | .sblk = &dpu_vig_sblk_qseed3_3_1, |
| 80 | .xin_id = 0, | 80 | .xin_id = 0, |
| 81 | .type = SSPP_TYPE_VIG, | 81 | .type = SSPP_TYPE_VIG, |
| 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, | 82 | .clk_ctrl = DPU_CLK_CTRL_VIG0, |
| 83 | }, { | 83 | }, { |
| 84 | .name = "sspp_1", .id = SSPP_VIG1, | 84 | .name = "sspp_1", .id = SSPP_VIG1, |
| 85 | .base = 0x6000, .len = 0x32c, | 85 | .base = 0x6000, .len = 0x32c, |
| 86 | .features = VIG_SC7180_MASK, | 86 | .features = VIG_SDM845_MASK_SDMA, |
| 87 | .sblk = &sm8250_vig_sblk_1, | 87 | .sblk = &dpu_vig_sblk_qseed3_3_1, |
| 88 | .xin_id = 4, | 88 | .xin_id = 4, |
| 89 | .type = SSPP_TYPE_VIG, | 89 | .type = SSPP_TYPE_VIG, |
| 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, | 90 | .clk_ctrl = DPU_CLK_CTRL_VIG1, |
| 91 | }, { | 91 | }, { |
| 92 | .name = "sspp_2", .id = SSPP_VIG2, | 92 | .name = "sspp_2", .id = SSPP_VIG2, |
| 93 | .base = 0x8000, .len = 0x32c, | 93 | .base = 0x8000, .len = 0x32c, |
| 94 | .features = VIG_SC7180_MASK, | 94 | .features = VIG_SDM845_MASK_SDMA, |
| 95 | .sblk = &sm8250_vig_sblk_2, | 95 | .sblk = &dpu_vig_sblk_qseed3_3_1, |
| 96 | .xin_id = 8, | 96 | .xin_id = 8, |
| 97 | .type = SSPP_TYPE_VIG, | 97 | .type = SSPP_TYPE_VIG, |
| 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, | 98 | .clk_ctrl = DPU_CLK_CTRL_VIG2, |
| 99 | }, { | 99 | }, { |
| 100 | .name = "sspp_3", .id = SSPP_VIG3, | 100 | .name = "sspp_3", .id = SSPP_VIG3, |
| 101 | .base = 0xa000, .len = 0x32c, | 101 | .base = 0xa000, .len = 0x32c, |
| 102 | .features = VIG_SC7180_MASK, | 102 | .features = VIG_SDM845_MASK_SDMA, |
| 103 | .sblk = &sm8250_vig_sblk_3, | 103 | .sblk = &dpu_vig_sblk_qseed3_3_1, |
| 104 | .xin_id = 12, | 104 | .xin_id = 12, |
| 105 | .type = SSPP_TYPE_VIG, | 105 | .type = SSPP_TYPE_VIG, |
| 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, | 106 | .clk_ctrl = DPU_CLK_CTRL_VIG3, |
| 107 | }, { | 107 | }, { |
| 108 | .name = "sspp_8", .id = SSPP_DMA0, | 108 | .name = "sspp_8", .id = SSPP_DMA0, |
| 109 | .base = 0x24000, .len = 0x32c, | 109 | .base = 0x24000, .len = 0x32c, |
| 110 | .features = DMA_SDM845_MASK, | 110 | .features = DMA_SDM845_MASK_SDMA, |
| 111 | .sblk = &sdm845_dma_sblk_0, | 111 | .sblk = &dpu_dma_sblk, |
| 112 | .xin_id = 1, | 112 | .xin_id = 1, |
| 113 | .type = SSPP_TYPE_DMA, | 113 | .type = SSPP_TYPE_DMA, |
| 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, | 114 | .clk_ctrl = DPU_CLK_CTRL_DMA0, |
| 115 | }, { | 115 | }, { |
| 116 | .name = "sspp_9", .id = SSPP_DMA1, | 116 | .name = "sspp_9", .id = SSPP_DMA1, |
| 117 | .base = 0x26000, .len = 0x32c, | 117 | .base = 0x26000, .len = 0x32c, |
| 118 | .features = DMA_SDM845_MASK, | 118 | .features = DMA_SDM845_MASK_SDMA, |
| 119 | .sblk = &sdm845_dma_sblk_1, | 119 | .sblk = &dpu_dma_sblk, |
| 120 | .xin_id = 5, | 120 | .xin_id = 5, |
| 121 | .type = SSPP_TYPE_DMA, | 121 | .type = SSPP_TYPE_DMA, |
| 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, | 122 | .clk_ctrl = DPU_CLK_CTRL_DMA1, |
| 123 | }, { | 123 | }, { |
| 124 | .name = "sspp_10", .id = SSPP_DMA2, | 124 | .name = "sspp_10", .id = SSPP_DMA2, |
| 125 | .base = 0x28000, .len = 0x32c, | 125 | .base = 0x28000, .len = 0x32c, |
| 126 | .features = DMA_CURSOR_SDM845_MASK, | 126 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 127 | .sblk = &sdm845_dma_sblk_2, | 127 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 9, | 128 | .xin_id = 9, |
| 129 | .type = SSPP_TYPE_DMA, | 129 | .type = SSPP_TYPE_DMA, |
| 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, | 130 | .clk_ctrl = DPU_CLK_CTRL_DMA2, |
| 131 | }, { | 131 | }, { |
| 132 | .name = "sspp_11", .id = SSPP_DMA3, | 132 | .name = "sspp_11", .id = SSPP_DMA3, |
| 133 | .base = 0x2a000, .len = 0x32c, | 133 | .base = 0x2a000, .len = 0x32c, |
| 134 | .features = DMA_CURSOR_SDM845_MASK, | 134 | .features = DMA_CURSOR_SDM845_MASK_SDMA, |
| 135 | .sblk = &sdm845_dma_sblk_3, | 135 | .sblk = &dpu_dma_sblk, |
| 136 | .xin_id = 13, | 136 | .xin_id = 13, |
| 137 | .type = SSPP_TYPE_DMA, | 137 | .type = SSPP_TYPE_DMA, |
| 138 | .clk_ctrl = DPU_CLK_CTRL_DMA3, | 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 | static const struct dpu_intf_cfg sm8450_intf[] = { | 334 | static const struct dpu_intf_cfg sm8450_intf[] = { |
| 320 | { | 335 | { |
| 321 | .name = "intf_0", .id = INTF_0, | 336 | .name = "intf_0", .id = INTF_0, |
| @@ -411,6 +426,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { · 89 unmodified lines | |||
| 411 | .dsc = sm8450_dsc, | 426 | .dsc = sm8450_dsc, |
| 412 | .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), | 427 | .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), |
| 413 | .merge_3d = sm8450_merge_3d, | 428 | .merge_3d = sm8450_merge_3d, |
| 429 | .wb_count = ARRAY_SIZE(sm8450_wb), | ||
| 430 | .wb = sm8450_wb, | ||
| 414 | .intf_count = ARRAY_SIZE(sm8450_intf), | 431 | .intf_count = ARRAY_SIZE(sm8450_intf), |
| 415 | .intf = sm8450_intf, | 432 | .intf = sm8450_intf, |
| 416 | .vbif_count = ARRAY_SIZE(sdm845_vbif), | 433 | .vbif_count = ARRAY_SIZE(sdm845_vbif), |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | static const struct dpu_caps sm8550_dpu_caps = { | 10 | static const struct dpu_caps sm8550_dpu_caps = { |
| 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, | 11 | .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH, |
| 12 | .max_mixer_blendstages = 0xb, | 12 | .max_mixer_blendstages = 0xb, |
| 13 | .qseed_type = DPU_SSPP_SCALER_QSEED4, | ||
| 14 | .has_src_split = true, | 13 | .has_src_split = true, |
| 15 | .has_dim_layer = true, | 14 | .has_dim_layer = true, |
| 16 | .has_idle_pc = true, | 15 | .has_idle_pc = true, |
| @@ -67,71 +66,71 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = { · 50 unmodified lines | |||
| 67 | { | 66 | { |
| 68 | .name = "sspp_0", .id = SSPP_VIG0, | 67 | .name = "sspp_0", .id = SSPP_VIG0, |
| 69 | .base = 0x4000, .len = 0x344, | 68 | .base = 0x4000, .len = 0x344, |
| 70 | .features = VIG_SC7180_MASK, | 69 | .features = VIG_SDM845_MASK, |
| 71 | .sblk = &sm8550_vig_sblk_0, | 70 | .sblk = &dpu_vig_sblk_qseed3_3_2, |
| 72 | .xin_id = 0, | 71 | .xin_id = 0, |
| 73 | .type = SSPP_TYPE_VIG, | 72 | .type = SSPP_TYPE_VIG, |
| 74 | }, { | 73 | }, { |
| 75 | .name = "sspp_1", .id = SSPP_VIG1, | 74 | .name = "sspp_1", .id = SSPP_VIG1, |
| 76 | .base = 0x6000, .len = 0x344, | 75 | .base = 0x6000, .len = 0x344, |
| 77 | .features = VIG_SC7180_MASK, | 76 | .features = VIG_SDM845_MASK, |
| 78 | .sblk = &sm8550_vig_sblk_1, | 77 | .sblk = &dpu_vig_sblk_qseed3_3_2, |
| 79 | .xin_id = 4, | 78 | .xin_id = 4, |
| 80 | .type = SSPP_TYPE_VIG, | 79 | .type = SSPP_TYPE_VIG, |
| 81 | }, { | 80 | }, { |
| 82 | .name = "sspp_2", .id = SSPP_VIG2, | 81 | .name = "sspp_2", .id = SSPP_VIG2, |
| 83 | .base = 0x8000, .len = 0x344, | 82 | .base = 0x8000, .len = 0x344, |
| 84 | .features = VIG_SC7180_MASK, | 83 | .features = VIG_SDM845_MASK, |
| 85 | .sblk = &sm8550_vig_sblk_2, | 84 | .sblk = &dpu_vig_sblk_qseed3_3_2, |
| 86 | .xin_id = 8, | 85 | .xin_id = 8, |
| 87 | .type = SSPP_TYPE_VIG, | 86 | .type = SSPP_TYPE_VIG, |
| 88 | }, { | 87 | }, { |
| 89 | .name = "sspp_3", .id = SSPP_VIG3, | 88 | .name = "sspp_3", .id = SSPP_VIG3, |
| 90 | .base = 0xa000, .len = 0x344, | 89 | .base = 0xa000, .len = 0x344, |
| 91 | .features = VIG_SC7180_MASK, | 90 | .features = VIG_SDM845_MASK, |
| 92 | .sblk = &sm8550_vig_sblk_3, | 91 | .sblk = &dpu_vig_sblk_qseed3_3_2, |
| 93 | .xin_id = 12, | 92 | .xin_id = 12, |
| 94 | .type = SSPP_TYPE_VIG, | 93 | .type = SSPP_TYPE_VIG, |
| 95 | }, { | 94 | }, { |
| 96 | .name = "sspp_8", .id = SSPP_DMA0, | 95 | .name = "sspp_8", .id = SSPP_DMA0, |
| 97 | .base = 0x24000, .len = 0x344, | 96 | .base = 0x24000, .len = 0x344, |
| 98 | .features = DMA_SDM845_MASK, | 97 | .features = DMA_SDM845_MASK, |
| 99 | .sblk = &sdm845_dma_sblk_0, | 98 | .sblk = &dpu_dma_sblk, |
| 100 | .xin_id = 1, | 99 | .xin_id = 1, |
| 101 | .type = SSPP_TYPE_DMA, | 100 | .type = SSPP_TYPE_DMA, |
| 102 | }, { | 101 | }, { |
| 103 | .name = "sspp_9", .id = SSPP_DMA1, | 102 | .name = "sspp_9", .id = SSPP_DMA1, |
| 104 | .base = 0x26000, .len = 0x344, | 103 | .base = 0x26000, .len = 0x344, |
| 105 | .features = DMA_SDM845_MASK, | 104 | .features = DMA_SDM845_MASK, |
| 106 | .sblk = &sdm845_dma_sblk_1, | 105 | .sblk = &dpu_dma_sblk, |
| 107 | .xin_id = 5, | 106 | .xin_id = 5, |
| 108 | .type = SSPP_TYPE_DMA, | 107 | .type = SSPP_TYPE_DMA, |
| 109 | }, { | 108 | }, { |
| 110 | .name = "sspp_10", .id = SSPP_DMA2, | 109 | .name = "sspp_10", .id = SSPP_DMA2, |
| 111 | .base = 0x28000, .len = 0x344, | 110 | .base = 0x28000, .len = 0x344, |
| 112 | .features = DMA_SDM845_MASK, | 111 | .features = DMA_SDM845_MASK, |
| 113 | .sblk = &sdm845_dma_sblk_2, | 112 | .sblk = &dpu_dma_sblk, |
| 114 | .xin_id = 9, | 113 | .xin_id = 9, |
| 115 | .type = SSPP_TYPE_DMA, | 114 | .type = SSPP_TYPE_DMA, |
| 116 | }, { | 115 | }, { |
| 117 | .name = "sspp_11", .id = SSPP_DMA3, | 116 | .name = "sspp_11", .id = SSPP_DMA3, |
| 118 | .base = 0x2a000, .len = 0x344, | 117 | .base = 0x2a000, .len = 0x344, |
| 119 | .features = DMA_SDM845_MASK, | 118 | .features = DMA_SDM845_MASK, |
| 120 | .sblk = &sdm845_dma_sblk_3, | 119 | .sblk = &dpu_dma_sblk, |
| 121 | .xin_id = 13, | 120 | .xin_id = 13, |
| 122 | .type = SSPP_TYPE_DMA, | 121 | .type = SSPP_TYPE_DMA, |
| 123 | }, { | 122 | }, { |
| 124 | .name = "sspp_12", .id = SSPP_DMA4, | 123 | .name = "sspp_12", .id = SSPP_DMA4, |
| 125 | .base = 0x2c000, .len = 0x344, | 124 | .base = 0x2c000, .len = 0x344, |
| 126 | .features = DMA_CURSOR_SDM845_MASK, | 125 | .features = DMA_CURSOR_SDM845_MASK, |
| 127 | .sblk = &sm8550_dma_sblk_4, | 126 | .sblk = &dpu_dma_sblk, |
| 128 | .xin_id = 14, | 127 | .xin_id = 14, |
| 129 | .type = SSPP_TYPE_DMA, | 128 | .type = SSPP_TYPE_DMA, |
| 130 | }, { | 129 | }, { |
| 131 | .name = "sspp_13", .id = SSPP_DMA5, | 130 | .name = "sspp_13", .id = SSPP_DMA5, |
| 132 | .base = 0x2e000, .len = 0x344, | 131 | .base = 0x2e000, .len = 0x344, |
| 133 | .features = DMA_CURSOR_SDM845_MASK, | 132 | .features = DMA_CURSOR_SDM845_MASK, |
| 134 | .sblk = &sm8550_dma_sblk_5, | 133 | .sblk = &dpu_dma_sblk, |
| 135 | .xin_id = 15, | 134 | .xin_id = 15, |
| 136 | .type = SSPP_TYPE_DMA, | 135 | .type = SSPP_TYPE_DMA, |
| 137 | }, | 136 | }, |
| @@ -316,8 +315,8 @@ static const struct dpu_wb_cfg sm8550_wb[] = { · 178 unmodified lines | |||
| 316 | .name = "wb_2", .id = WB_2, | 315 | .name = "wb_2", .id = WB_2, |
| 317 | .base = 0x65000, .len = 0x2c8, | 316 | .base = 0x65000, .len = 0x2c8, |
| 318 | .features = WB_SM8250_MASK, | 317 | .features = WB_SM8250_MASK, |
| 319 | .format_list = wb2_formats, | 318 | .format_list = wb2_formats_rgb, |
| 320 | .num_formats = ARRAY_SIZE(wb2_formats), | 319 | .num_formats = ARRAY_SIZE(wb2_formats_rgb), |
| 321 | .xin_id = 6, | 320 | .xin_id = 6, |
| 322 | .vbif_idx = VBIF_RT, | 321 | .vbif_idx = VBIF_RT, |
| 323 | .maxlinewidth = 4096, | 322 | .maxlinewidth = 4096, |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | 3 | * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. |
| 4 | * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. |
| 5 | * Copyright (C) 2013 Red Hat | 5 | * Copyright (C) 2013 Red Hat |
| 6 | * Author: Rob Clark <robdclark@gmail.com> | 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 | return to_dpu_kms(priv->kms); | 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 | static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) | 54 | static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc) |
| 66 | { | 55 | { |
| 67 | struct drm_device *dev = crtc->dev; | 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 | continue; | 114 | continue; |
| 126 | 115 | ||
| 127 | /* Calculate MISR over 1 frame */ | 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 | static const struct drm_crtc_funcs dpu_crtc_funcs = { | 1425 | static const struct drm_crtc_funcs dpu_crtc_funcs = { |
| 1437 | .set_config = drm_atomic_helper_set_config, | 1426 | .set_config = drm_atomic_helper_set_config, |
| 1438 | .destroy = dpu_crtc_destroy, | ||
| 1439 | .page_flip = drm_atomic_helper_page_flip, | 1427 | .page_flip = drm_atomic_helper_page_flip, |
| 1440 | .reset = dpu_crtc_reset, | 1428 | .reset = dpu_crtc_reset, |
| 1441 | .atomic_duplicate_state = dpu_crtc_duplicate_state, | 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 | struct dpu_crtc *dpu_crtc; | 1457 | struct dpu_crtc *dpu_crtc; |
| 1470 | int i, ret; | 1458 | int i, ret; |
| 1471 | 1459 | ||
| 1472 | dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL); | 1460 | dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base, |
| 1473 | if (!dpu_crtc) | 1461 | plane, cursor, |
| 1474 | return ERR_PTR(-ENOMEM); | 1462 | &dpu_crtc_funcs, |
| 1463 | NULL); | ||
| 1464 | |||
| 1465 | if (IS_ERR(dpu_crtc)) | ||
| 1466 | return ERR_CAST(dpu_crtc); | ||
| 1475 | 1467 | ||
| 1476 | crtc = &dpu_crtc->base; | 1468 | crtc = &dpu_crtc->base; |
| 1477 | crtc->dev = dev; | 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 | dpu_crtc_frame_event_work); | 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 | drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); | 1486 | drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); |
| 1498 | 1487 | ||
| 1499 | if (dpu_kms->catalog->dspp_count) | 1488 | if (dpu_kms->catalog->dspp_count) |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | /* | 2 | /* |
| 3 | * Copyright (C) 2013 Red Hat | 3 | * Copyright (C) 2013 Red Hat |
| 4 | * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. | 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 | * Author: Rob Clark <robdclark@gmail.com> | 7 | * Author: Rob Clark <robdclark@gmail.com> |
| 8 | */ | 8 | */ |
| @@ -16,6 +16,7 @@ · 7 unmodified lines | |||
| 16 | #include <drm/drm_crtc.h> | 16 | #include <drm/drm_crtc.h> |
| 17 | #include <drm/drm_file.h> | 17 | #include <drm/drm_file.h> |
| 18 | #include <drm/drm_probe_helper.h> | 18 | #include <drm/drm_probe_helper.h> |
| 19 | #include <drm/drm_framebuffer.h> | ||
| 19 | 20 | ||
| 20 | #include "msm_drv.h" | 21 | #include "msm_drv.h" |
| 21 | #include "dpu_kms.h" | 22 | #include "dpu_kms.h" |
| @@ -26,6 +27,7 @@ · 4 unmodified lines | |||
| 26 | #include "dpu_hw_dspp.h" | 27 | #include "dpu_hw_dspp.h" |
| 27 | #include "dpu_hw_dsc.h" | 28 | #include "dpu_hw_dsc.h" |
| 28 | #include "dpu_hw_merge3d.h" | 29 | #include "dpu_hw_merge3d.h" |
| 30 | #include "dpu_hw_cdm.h" | ||
| 29 | #include "dpu_formats.h" | 31 | #include "dpu_formats.h" |
| 30 | #include "dpu_encoder_phys.h" | 32 | #include "dpu_encoder_phys.h" |
| 31 | #include "dpu_crtc.h" | 33 | #include "dpu_crtc.h" |
| @@ -39,6 +41,9 @@ · 7 unmodified lines | |||
| 39 | #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ | 41 | #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ |
| 40 | (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) | 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 | * Two to anticipate panels that can do cmd/vid dynamic switching | 48 | * Two to anticipate panels that can do cmd/vid dynamic switching |
| 44 | * plan is to create all possible physical encoder types, and switch between | 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 | * @crtc_frame_event_cb: callback handler for frame event | 156 | * @crtc_frame_event_cb: callback handler for frame event |
| 152 | * @crtc_frame_event_cb_data: callback handler private data | 157 | * @crtc_frame_event_cb_data: callback handler private data |
| 153 | * @frame_done_timeout_ms: frame done timeout in ms | 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 | * @frame_done_timer: watchdog timer for frame done event | 161 | * @frame_done_timer: watchdog timer for frame done event |
| 155 | * @disp_info: local copy of msm_display_info struct | 162 | * @disp_info: local copy of msm_display_info struct |
| 156 | * @idle_pc_supported: indicate if idle power collaps is supported | 163 | * @idle_pc_supported: indicate if idle power collaps is supported |
| @@ -184,13 +191,13 @@ struct dpu_encoder_virt { · 27 unmodified lines | |||
| 184 | struct drm_crtc *crtc; | 191 | struct drm_crtc *crtc; |
| 185 | struct drm_connector *connector; | 192 | struct drm_connector *connector; |
| 186 | 193 | ||
| 187 | struct dentry *debugfs_root; | ||
| 188 | struct mutex enc_lock; | 194 | struct mutex enc_lock; |
| 189 | DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL); | 195 | DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL); |
| 190 | void (*crtc_frame_event_cb)(void *, u32 event); | 196 | void (*crtc_frame_event_cb)(void *, u32 event); |
| 191 | void *crtc_frame_event_cb_data; | 197 | void *crtc_frame_event_cb_data; |
| 192 | 198 | ||
| 193 | atomic_t frame_done_timeout_ms; | 199 | atomic_t frame_done_timeout_ms; |
| 200 | atomic_t frame_done_timeout_cnt; | ||
| 194 | struct timer_list frame_done_timer; | 201 | struct timer_list frame_done_timer; |
| 195 | 202 | ||
| 196 | struct msm_display_info disp_info; | 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 | if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) | 262 | if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) |
| 256 | continue; | 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 | return linecount; | 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 | void dpu_encoder_helper_split_config( | 449 | void dpu_encoder_helper_split_config( |
| 478 | struct dpu_encoder_phys *phys_enc, | 450 | struct dpu_encoder_phys *phys_enc, |
| 479 | enum dpu_intf interface) | 451 | enum dpu_intf interface) |
| @@ -614,6 +586,7 @@ static int dpu_encoder_virt_atomic_check( · 134 unmodified lines | |||
| 614 | struct drm_display_mode *adj_mode; | 586 | struct drm_display_mode *adj_mode; |
| 615 | struct msm_display_topology topology; | 587 | struct msm_display_topology topology; |
| 616 | struct dpu_global_state *global_state; | 588 | struct dpu_global_state *global_state; |
| 589 | struct drm_framebuffer *fb; | ||
| 617 | struct drm_dsc_config *dsc; | 590 | struct drm_dsc_config *dsc; |
| 618 | int i = 0; | 591 | int i = 0; |
| 619 | int ret = 0; | 592 | int ret = 0; |
| @@ -654,6 +627,22 @@ static int dpu_encoder_virt_atomic_check( · 34 unmodified lines | |||
| 654 | 627 | ||
| 655 | topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc); | 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 | * Release and Allocate resources on every modeset | 647 | * Release and Allocate resources on every modeset |
| 659 | * Dont allocate when active is false. | 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 | dpu_enc->dsc_mask = dsc_mask; | 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 | cstate = to_dpu_crtc_state(crtc_state); | 1095 | cstate = to_dpu_crtc_state(crtc_state); |
| 1098 | 1096 | ||
| 1099 | for (i = 0; i < num_lm; i++) { | 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 | dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc); | 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 | if (disp_info->intf_type == INTF_DP) | 1207 | if (disp_info->intf_type == INTF_DP) |
| 1208 | dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); | 1208 | dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]); |
| 1209 | else if (disp_info->intf_type == INTF_DSI) | 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 | phys_enc->hw_pp->merge_3d->idx); | 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 | if (dpu_enc->dsc) { | 2092 | if (dpu_enc->dsc) { |
| 2084 | dpu_encoder_unprep_dsc(dpu_enc); | 2093 | dpu_encoder_unprep_dsc(dpu_enc); |
| 2085 | dpu_enc->dsc = NULL; | 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 | #ifdef CONFIG_DEBUG_FS | 2117 | #ifdef CONFIG_DEBUG_FS |
| 2109 | static int _dpu_encoder_status_show(struct seq_file *s, void *data) | 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 | int i; | 2122 | int i; |
| 2113 | 2123 | ||
| 2114 | mutex_lock(&dpu_enc->enc_lock); | 2124 | mutex_lock(&dpu_enc->enc_lock); |
| 2115 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { | 2125 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 2116 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; | 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 | phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1, | 2129 | phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1, |
| 2120 | phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1, | 2130 | phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1, |
| 2121 | atomic_read(&phys->vsync_cnt), | 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 | seq_printf(s, "mode: %s\n", dpu_encoder_helper_get_intf_type(phys->intf_mode)); | 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 | DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status); | 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 | /* don't error check these */ | 2146 | /* don't error check these */ |
| 2151 | debugfs_create_file("status", 0600, | 2147 | debugfs_create_file("status", 0600, |
| 2152 | dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops); | 2148 | root, drm_enc, &_dpu_encoder_status_fops); |
| 2153 | |||
| 2154 | return 0; | ||
| 2155 | } | 2149 | } |
| 2156 | #else | 2150 | #else |
| 2157 | static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) | 2151 | #define dpu_encoder_debugfs_init NULL |
| 2158 | { | ||
| 2159 | return 0; | ||
| 2160 | } | ||
| 2161 | #endif | 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 | static int dpu_encoder_virt_add_phys_encs( | 2154 | static int dpu_encoder_virt_add_phys_encs( |
| 2155 | struct drm_device *dev, | ||
| 2176 | struct msm_display_info *disp_info, | 2156 | struct msm_display_info *disp_info, |
| 2177 | struct dpu_encoder_virt *dpu_enc, | 2157 | struct dpu_encoder_virt *dpu_enc, |
| 2178 | struct dpu_enc_phys_init_params *params) | 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 | if (disp_info->intf_type == INTF_WB) { | 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 | if (IS_ERR(enc)) { | 2179 | if (IS_ERR(enc)) { |
| 2200 | DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", | 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 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; | 2185 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; |
| 2206 | ++dpu_enc->num_phys_encs; | 2186 | ++dpu_enc->num_phys_encs; |
| 2207 | } else if (disp_info->is_cmd_mode) { | 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 | if (IS_ERR(enc)) { | 2190 | if (IS_ERR(enc)) { |
| 2211 | DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n", | 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 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; | 2196 | dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; |
| 2217 | ++dpu_enc->num_phys_encs; | 2197 | ++dpu_enc->num_phys_encs; |
| 2218 | } else { | 2198 | } else { |
| 2219 | enc = dpu_encoder_phys_vid_init(params); | 2199 | enc = dpu_encoder_phys_vid_init(dev, params); |
| 2220 | 2200 | ||
| 2221 | if (IS_ERR(enc)) { | 2201 | if (IS_ERR(enc)) { |
| 2222 | DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n", | 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 | break; | 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 | dpu_enc, &phys_params); | 2289 | dpu_enc, &phys_params); |
| 2310 | if (ret) { | 2290 | if (ret) { |
| 2311 | DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); | 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 | return; | 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 | event = DPU_ENCODER_FRAME_EVENT_ERROR; | 2327 | event = DPU_ENCODER_FRAME_EVENT_ERROR; |
| 2345 | trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); | 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 | static const struct drm_encoder_funcs dpu_encoder_funcs = { | 2339 | static const struct drm_encoder_funcs dpu_encoder_funcs = { |
| 2357 | .destroy = dpu_encoder_destroy, | 2340 | .debugfs_init = dpu_encoder_debugfs_init, |
| 2358 | .late_register = dpu_encoder_late_register, | ||
| 2359 | .early_unregister = dpu_encoder_early_unregister, | ||
| 2360 | }; | 2341 | }; |
| 2361 | 2342 | ||
| 2362 | struct drm_encoder *dpu_encoder_init(struct drm_device *dev, | 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 | struct msm_drm_private *priv = dev->dev_private; | 2347 | struct msm_drm_private *priv = dev->dev_private; |
| 2367 | struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); | 2348 | struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); |
| 2368 | struct drm_encoder *drm_enc = NULL; | 2349 | struct dpu_encoder_virt *dpu_enc; |
| 2369 | struct dpu_encoder_virt *dpu_enc = NULL; | 2350 | int ret; |
| 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); | ||
| 2375 | 2351 | ||
| 2376 | ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, | 2352 | dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base, |
| 2377 | drm_enc_mode, NULL); | 2353 | &dpu_encoder_funcs, drm_enc_mode, NULL); |
| 2378 | if (ret) { | 2354 | if (IS_ERR(dpu_enc)) |
| 2379 | devm_kfree(dev->dev, dpu_enc); | 2355 | return ERR_CAST(dpu_enc); |
| 2380 | return ERR_PTR(ret); | ||
| 2381 | } | ||
| 2382 | 2356 | ||
| 2383 | drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs); | 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 | mutex_init(&dpu_enc->rc_lock); | 2362 | mutex_init(&dpu_enc->rc_lock); |
| 2389 | 2363 | ||
| 2390 | ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); | 2364 | ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); |
| 2391 | if (ret) | 2365 | if (ret) { |
| 2392 | goto fail; | 2366 | DPU_ERROR("failed to setup encoder\n"); |
| 2367 | return ERR_PTR(-ENOMEM); | ||
| 2368 | } | ||
| 2393 | 2369 | ||
| 2394 | atomic_set(&dpu_enc->frame_done_timeout_ms, 0); | 2370 | atomic_set(&dpu_enc->frame_done_timeout_ms, 0); |
| 2371 | atomic_set(&dpu_enc->frame_done_timeout_cnt, 0); | ||
| 2395 | timer_setup(&dpu_enc->frame_done_timer, | 2372 | timer_setup(&dpu_enc->frame_done_timer, |
| 2396 | dpu_encoder_frame_done_timeout, 0); | 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 | DPU_DEBUG_ENC(dpu_enc, "created\n"); | 2381 | DPU_DEBUG_ENC(dpu_enc, "created\n"); |
| 2405 | 2382 | ||
| 2406 | return &dpu_enc->base; | 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 | int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc, | 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 | case MSM_ENC_TX_COMPLETE: | 2407 | case MSM_ENC_TX_COMPLETE: |
| 2438 | fn_wait = phys->ops.wait_for_tx_complete; | 2408 | fn_wait = phys->ops.wait_for_tx_complete; |
| 2439 | break; | 2409 | break; |
| 2440 | case MSM_ENC_VBLANK: | ||
| 2441 | fn_wait = phys->ops.wait_for_vblank; | ||
| 2442 | break; | ||
| 2443 | default: | 2410 | default: |
| 2444 | DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n", | 2411 | DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n", |
| 2445 | event); | 2412 | event); |
| @@ -2497,7 +2464,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, · 51 unmodified lines | |||
| 2497 | phys_enc->enc_spinlock = p->enc_spinlock; | 2464 | phys_enc->enc_spinlock = p->enc_spinlock; |
| 2498 | phys_enc->enable_state = DPU_ENC_DISABLED; | 2465 | phys_enc->enable_state = DPU_ENC_DISABLED; |
| 2499 | 2466 | ||
| 2500 | atomic_set(&phys_enc->vblank_refcount, 0); | ||
| 2501 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); | 2467 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 2502 | atomic_set(&phys_enc->pending_ctlstart_cnt, 0); | 2468 | atomic_set(&phys_enc->pending_ctlstart_cnt, 0); |
| 2503 | 2469 | ||
| @@ -14,8 +14,10 @@ · 13 unmodified lines | |||
| 14 | #include "dpu_hw_intf.h" | 14 | #include "dpu_hw_intf.h" |
| 15 | #include "dpu_hw_wb.h" | 15 | #include "dpu_hw_wb.h" |
| 16 | #include "dpu_hw_pingpong.h" | 16 | #include "dpu_hw_pingpong.h" |
| 17 | #include "dpu_hw_cdm.h" | ||
| 17 | #include "dpu_hw_ctl.h" | 18 | #include "dpu_hw_ctl.h" |
| 18 | #include "dpu_hw_top.h" | 19 | #include "dpu_hw_top.h" |
| 20 | #include "dpu_hw_util.h" | ||
| 19 | #include "dpu_encoder.h" | 21 | #include "dpu_encoder.h" |
| 20 | #include "dpu_crtc.h" | 22 | #include "dpu_crtc.h" |
| 21 | 23 | ||
| @@ -72,7 +74,6 @@ struct dpu_encoder_phys; · 50 unmodified lines | |||
| 72 | * @enable: DRM Call. Enable a DRM mode. | 74 | * @enable: DRM Call. Enable a DRM mode. |
| 73 | * @disable: DRM Call. Disable mode. | 75 | * @disable: DRM Call. Disable mode. |
| 74 | * @atomic_check: DRM Call. Atomic check new DRM state. | 76 | * @atomic_check: DRM Call. Atomic check new DRM state. |
| 75 | * @destroy: DRM Call. Destroy and release resources. | ||
| 76 | * @control_vblank_irq Register/Deregister for VBLANK IRQ | 77 | * @control_vblank_irq Register/Deregister for VBLANK IRQ |
| 77 | * @wait_for_commit_done: Wait for hardware to have flushed the | 78 | * @wait_for_commit_done: Wait for hardware to have flushed the |
| 78 | * current pending frames to hardware | 79 | * current pending frames to hardware |
| @@ -102,11 +103,9 @@ struct dpu_encoder_phys_ops { · 23 unmodified lines | |||
| 102 | int (*atomic_check)(struct dpu_encoder_phys *encoder, | 103 | int (*atomic_check)(struct dpu_encoder_phys *encoder, |
| 103 | struct drm_crtc_state *crtc_state, | 104 | struct drm_crtc_state *crtc_state, |
| 104 | struct drm_connector_state *conn_state); | 105 | struct drm_connector_state *conn_state); |
| 105 | void (*destroy)(struct dpu_encoder_phys *encoder); | ||
| 106 | int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); | 106 | int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); |
| 107 | int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); | 107 | int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); |
| 108 | int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); | 108 | int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); |
| 109 | int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc); | ||
| 110 | void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc); | 109 | void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc); |
| 111 | void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); | 110 | void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); |
| 112 | void (*trigger_start)(struct dpu_encoder_phys *phys_enc); | 111 | void (*trigger_start)(struct dpu_encoder_phys *phys_enc); |
| @@ -153,8 +152,10 @@ enum dpu_intr_idx { · 40 unmodified lines | |||
| 153 | * @hw_pp: Hardware interface to the ping pong registers | 152 | * @hw_pp: Hardware interface to the ping pong registers |
| 154 | * @hw_intf: Hardware interface to the intf registers | 153 | * @hw_intf: Hardware interface to the intf registers |
| 155 | * @hw_wb: Hardware interface to the wb registers | 154 | * @hw_wb: Hardware interface to the wb registers |
| 155 | * @hw_cdm: Hardware interface to the CDM registers | ||
| 156 | * @dpu_kms: Pointer to the dpu_kms top level | 156 | * @dpu_kms: Pointer to the dpu_kms top level |
| 157 | * @cached_mode: DRM mode cached at mode_set time, acted on in enable | 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 | * @enabled: Whether the encoder has enabled and running a mode | 159 | * @enabled: Whether the encoder has enabled and running a mode |
| 159 | * @split_role: Role to play in a split-panel configuration | 160 | * @split_role: Role to play in a split-panel configuration |
| 160 | * @intf_mode: Interface mode | 161 | * @intf_mode: Interface mode |
| @@ -181,13 +182,15 @@ struct dpu_encoder_phys { · 20 unmodified lines | |||
| 181 | struct dpu_hw_pingpong *hw_pp; | 182 | struct dpu_hw_pingpong *hw_pp; |
| 182 | struct dpu_hw_intf *hw_intf; | 183 | struct dpu_hw_intf *hw_intf; |
| 183 | struct dpu_hw_wb *hw_wb; | 184 | struct dpu_hw_wb *hw_wb; |
| 185 | struct dpu_hw_cdm *hw_cdm; | ||
| 184 | struct dpu_kms *dpu_kms; | 186 | struct dpu_kms *dpu_kms; |
| 185 | struct drm_display_mode cached_mode; | 187 | struct drm_display_mode cached_mode; |
| 188 | struct mutex vblank_ctl_lock; | ||
| 186 | enum dpu_enc_split_role split_role; | 189 | enum dpu_enc_split_role split_role; |
| 187 | enum dpu_intf_mode intf_mode; | 190 | enum dpu_intf_mode intf_mode; |
| 188 | spinlock_t *enc_spinlock; | 191 | spinlock_t *enc_spinlock; |
| 189 | enum dpu_enc_enable_state enable_state; | 192 | enum dpu_enc_enable_state enable_state; |
| 190 | atomic_t vblank_refcount; | 193 | int vblank_refcount; |
| 191 | atomic_t vsync_cnt; | 194 | atomic_t vsync_cnt; |
| 192 | atomic_t underrun_cnt; | 195 | atomic_t underrun_cnt; |
| 193 | atomic_t pending_ctlstart_cnt; | 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 | * @wbirq_refcount: Reference count of writeback interrupt | 213 | * @wbirq_refcount: Reference count of writeback interrupt |
| 211 | * @wb_done_timeout_cnt: number of wb done irq timeout errors | 214 | * @wb_done_timeout_cnt: number of wb done irq timeout errors |
| 212 | * @wb_cfg: writeback block config to store fb related details | 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 | * @wb_conn: backpointer to writeback connector | 217 | * @wb_conn: backpointer to writeback connector |
| 214 | * @wb_job: backpointer to current writeback job | 218 | * @wb_job: backpointer to current writeback job |
| 215 | * @dest: dpu buffer layout for current writeback output buffer | 219 | * @dest: dpu buffer layout for current writeback output buffer |
| @@ -219,6 +223,7 @@ struct dpu_encoder_phys_wb { · 3 unmodified lines | |||
| 219 | atomic_t wbirq_refcount; | 223 | atomic_t wbirq_refcount; |
| 220 | int wb_done_timeout_cnt; | 224 | int wb_done_timeout_cnt; |
| 221 | struct dpu_hw_wb_cfg wb_cfg; | 225 | struct dpu_hw_wb_cfg wb_cfg; |
| 226 | struct dpu_hw_cdm_cfg cdm_cfg; | ||
| 222 | struct drm_writeback_connector *wb_conn; | 227 | struct drm_writeback_connector *wb_conn; |
| 223 | struct drm_writeback_job *wb_job; | 228 | struct drm_writeback_job *wb_job; |
| 224 | struct dpu_hw_fmt_layout dest; | 229 | struct dpu_hw_fmt_layout dest; |
| @@ -281,22 +286,24 @@ struct dpu_encoder_wait_info { · 56 unmodified lines | |||
| 281 | * @p: Pointer to init params structure | 286 | * @p: Pointer to init params structure |
| 282 | * Return: Error code or newly allocated encoder | 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 | struct dpu_enc_phys_init_params *p); | 290 | struct dpu_enc_phys_init_params *p); |
| 286 | 291 | ||
| 287 | /** | 292 | /** |
| 288 | * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder | 293 | * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder |
| 294 | * @dev: Corresponding device for devres management | ||
| 289 | * @p: Pointer to init params structure | 295 | * @p: Pointer to init params structure |
| 290 | * Return: Error code or newly allocated encoder | 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 | struct dpu_enc_phys_init_params *p); | 299 | struct dpu_enc_phys_init_params *p); |
| 294 | 300 | ||
| 295 | /** | 301 | /** |
| 296 | * dpu_encoder_phys_wb_init - initialize writeback encoder | 302 | * dpu_encoder_phys_wb_init - initialize writeback encoder |
| 303 | * @dev: Corresponding device for devres management | ||
| 297 | * @init: Pointer to init info structure with initialization params | 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 | struct dpu_enc_phys_init_params *p); | 307 | struct dpu_enc_phys_init_params *p); |
| 301 | 308 | ||
| 302 | /** | 309 | /** |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | |||
| 13 | #include "dpu_trace.h" | 13 | #include "dpu_trace.h" |
| 14 | #include "disp/msm_disp_snapshot.h" | 14 | #include "disp/msm_disp_snapshot.h" |
| 15 | 15 | ||
| 16 | #include <drm/drm_managed.h> | ||
| 17 | |||
| 16 | #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ | 18 | #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ |
| 17 | (e) && (e)->base.parent ? \ | 19 | (e) && (e)->base.parent ? \ |
| 18 | (e)->base.parent->base.id : -1, \ | 20 | (e)->base.parent->base.id : -1, \ |
| @@ -244,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( · 225 unmodified lines | |||
| 244 | return -EINVAL; | 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 | /* Slave encoders don't report vblank */ | 252 | /* Slave encoders don't report vblank */ |
| 250 | if (!dpu_encoder_phys_cmd_is_master(phys_enc)) | 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 | phys_enc->hw_pp->idx - PINGPONG_0, | 263 | phys_enc->hw_pp->idx - PINGPONG_0, |
| 261 | enable ? "true" : "false", refcount); | 264 | enable ? "true" : "false", refcount); |
| 262 | 265 | ||
| 263 | if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1) | 266 | if (enable) { |
| 264 | ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | 267 | if (phys_enc->vblank_refcount == 0) |
| 265 | phys_enc->irq[INTR_IDX_RDPTR], | 268 | ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, |
| 266 | dpu_encoder_phys_cmd_te_rd_ptr_irq, | 269 | phys_enc->irq[INTR_IDX_RDPTR], |
| 267 | phys_enc); | 270 | dpu_encoder_phys_cmd_te_rd_ptr_irq, |
| 268 | else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) | 271 | phys_enc); |
| 269 | ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | 272 | if (!ret) |
| 270 | phys_enc->irq[INTR_IDX_RDPTR]); | 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 | end: | 282 | end: |
| 283 | mutex_unlock(&phys_enc->vblank_ctl_lock); | ||
| 273 | if (ret) { | 284 | if (ret) { |
| 274 | DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n", | 285 | DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n", |
| 275 | DRMID(phys_enc->parent), | 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 | trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent), | 297 | trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent), |
| 287 | phys_enc->hw_pp->idx - PINGPONG_0, | 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 | if (enable) { | 301 | if (enable) { |
| 291 | dpu_core_irq_register_callback(phys_enc->dpu_kms, | 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 | phys_enc->enable_state = DPU_ENC_DISABLED; | 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 | static void dpu_encoder_phys_cmd_prepare_for_kickoff( | 572 | static void dpu_encoder_phys_cmd_prepare_for_kickoff( |
| 570 | struct dpu_encoder_phys *phys_enc) | 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 | return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc); | 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 | static void dpu_encoder_phys_cmd_handle_post_kickoff( | 687 | static void dpu_encoder_phys_cmd_handle_post_kickoff( |
| 712 | struct dpu_encoder_phys *phys_enc) | 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 | ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; | 707 | ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set; |
| 732 | ops->enable = dpu_encoder_phys_cmd_enable; | 708 | ops->enable = dpu_encoder_phys_cmd_enable; |
| 733 | ops->disable = dpu_encoder_phys_cmd_disable; | 709 | ops->disable = dpu_encoder_phys_cmd_disable; |
| 734 | ops->destroy = dpu_encoder_phys_cmd_destroy; | ||
| 735 | ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq; | 710 | ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq; |
| 736 | ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done; | 711 | ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done; |
| 737 | ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff; | 712 | ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff; |
| 738 | ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete; | 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 | ops->trigger_start = dpu_encoder_phys_cmd_trigger_start; | 714 | ops->trigger_start = dpu_encoder_phys_cmd_trigger_start; |
| 741 | ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush; | 715 | ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush; |
| 742 | ops->irq_control = dpu_encoder_phys_cmd_irq_control; | 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 | ops->get_line_count = dpu_encoder_phys_cmd_get_line_count; | 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 | struct dpu_enc_phys_init_params *p) | 724 | struct dpu_enc_phys_init_params *p) |
| 751 | { | 725 | { |
| 752 | struct dpu_encoder_phys *phys_enc = NULL; | 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 | DPU_DEBUG("intf\n"); | 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 | if (!cmd_enc) { | 732 | if (!cmd_enc) { |
| 759 | DPU_ERROR("failed to allocate\n"); | 733 | DPU_ERROR("failed to allocate\n"); |
| 760 | return ERR_PTR(-ENOMEM); | 734 | return ERR_PTR(-ENOMEM); |
| @@ -763,6 +737,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( · 2 unmodified lines | |||
| 763 | 737 | ||
| 764 | dpu_encoder_phys_init(phys_enc, p); | 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 | dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); | 743 | dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); |
| 767 | phys_enc->intf_mode = INTF_MODE_CMD; | 744 | phys_enc->intf_mode = INTF_MODE_CMD; |
| 768 | cmd_enc->stream_sel = 0; | 745 | cmd_enc->stream_sel = 0; |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include "dpu_trace.h" | 11 | #include "dpu_trace.h" |
| 12 | #include "disp/msm_disp_snapshot.h" | 12 | #include "disp/msm_disp_snapshot.h" |
| 13 | 13 | ||
| 14 | #include <drm/drm_managed.h> | ||
| 15 | |||
| 14 | #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ | 16 | #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ |
| 15 | (e) && (e)->parent ? \ | 17 | (e) && (e)->parent ? \ |
| 16 | (e)->parent->base.id : -1, \ | 18 | (e)->parent->base.id : -1, \ |
| @@ -364,7 +366,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq( · 347 unmodified lines | |||
| 364 | int ret = 0; | 366 | int ret = 0; |
| 365 | int refcount; | 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 | /* Slave encoders don't report vblank */ | 372 | /* Slave encoders don't report vblank */ |
| 370 | if (!dpu_encoder_phys_vid_is_master(phys_enc)) | 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 | DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable, | 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) | 385 | if (enable) { |
| 383 | ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, | 386 | if (phys_enc->vblank_refcount == 0) |
| 384 | phys_enc->irq[INTR_IDX_VSYNC], | 387 | ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, |
| 385 | dpu_encoder_phys_vid_vblank_irq, | 388 | phys_enc->irq[INTR_IDX_VSYNC], |
| 386 | phys_enc); | 389 | dpu_encoder_phys_vid_vblank_irq, |
| 387 | else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0) | 390 | phys_enc); |
| 388 | ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, | 391 | if (!ret) |
| 389 | phys_enc->irq[INTR_IDX_VSYNC]); | 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 | end: | 401 | end: |
| 402 | mutex_unlock(&phys_enc->vblank_ctl_lock); | ||
| 392 | if (ret) { | 403 | if (ret) { |
| 393 | DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", | 404 | DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", |
| 394 | DRMID(phys_enc->parent), | 405 | DRMID(phys_enc->parent), |
| @@ -438,13 +449,7 @@ skip_flush: · 43 unmodified lines | |||
| 438 | phys_enc->enable_state = DPU_ENC_ENABLING; | 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) | 452 | static int dpu_encoder_phys_vid_wait_for_tx_complete( |
| 442 | { | ||
| 443 | DPU_DEBUG_VIDENC(phys_enc, "\n"); | ||
| 444 | kfree(phys_enc); | ||
| 445 | } | ||
| 446 | |||
| 447 | static int dpu_encoder_phys_vid_wait_for_vblank( | ||
| 448 | struct dpu_encoder_phys *phys_enc) | 453 | struct dpu_encoder_phys *phys_enc) |
| 449 | { | 454 | { |
| 450 | struct dpu_encoder_wait_info wait_info; | 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 | * scanout buffer) don't latch properly.. | 563 | * scanout buffer) don't latch properly.. |
| 559 | */ | 564 | */ |
| 560 | if (dpu_encoder_phys_vid_is_master(phys_enc)) { | 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 | if (ret) { | 567 | if (ret) { |
| 563 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); | 568 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 564 | DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", | 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 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); | 583 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); |
| 579 | dpu_encoder_phys_inc_pending(phys_enc); | 584 | dpu_encoder_phys_inc_pending(phys_enc); |
| 580 | spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); | 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 | if (ret) { | 587 | if (ret) { |
| 583 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); | 588 | atomic_set(&phys_enc->pending_kickoff_cnt, 0); |
| 584 | DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", | 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 | trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), | 623 | trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), |
| 619 | phys_enc->hw_intf->idx - INTF_0, | 624 | phys_enc->hw_intf->idx - INTF_0, |
| 620 | enable, | 625 | enable, |
| 621 | atomic_read(&phys_enc->vblank_refcount)); | 626 | phys_enc->vblank_refcount); |
| 622 | 627 | ||
| 623 | if (enable) { | 628 | if (enable) { |
| 624 | ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true); | 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 | ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; | 686 | ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set; |
| 682 | ops->enable = dpu_encoder_phys_vid_enable; | 687 | ops->enable = dpu_encoder_phys_vid_enable; |
| 683 | ops->disable = dpu_encoder_phys_vid_disable; | 688 | ops->disable = dpu_encoder_phys_vid_disable; |
| 684 | ops->destroy = dpu_encoder_phys_vid_destroy; | ||
| 685 | ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; | 689 | ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq; |
| 686 | ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done; | 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; | 691 | ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_tx_complete; |
| 688 | ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_vblank; | ||
| 689 | ops->irq_control = dpu_encoder_phys_vid_irq_control; | 692 | ops->irq_control = dpu_encoder_phys_vid_irq_control; |
| 690 | ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; | 693 | ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; |
| 691 | ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff; | 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 | ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count; | 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 | struct dpu_enc_phys_init_params *p) | 701 | struct dpu_enc_phys_init_params *p) |
| 699 | { | 702 | { |
| 700 | struct dpu_encoder_phys *phys_enc = NULL; | 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 | return ERR_PTR(-EINVAL); | 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 | if (!phys_enc) { | 711 | if (!phys_enc) { |
| 709 | DPU_ERROR("failed to create encoder due to memory allocation error\n"); | 712 | DPU_ERROR("failed to create encoder due to memory allocation error\n"); |
| 710 | return ERR_PTR(-ENOMEM); | 713 | return ERR_PTR(-ENOMEM); |
| @@ -713,6 +716,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( · 2 unmodified lines | |||
| 713 | DPU_DEBUG_VIDENC(phys_enc, "\n"); | 716 | DPU_DEBUG_VIDENC(phys_enc, "\n"); |
| 714 | 717 | ||
| 715 | dpu_encoder_phys_init(phys_enc, p); | 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 | dpu_encoder_phys_vid_init_ops(&phys_enc->ops); | 722 | dpu_encoder_phys_vid_init_ops(&phys_enc->ops); |
| 718 | phys_enc->intf_mode = INTF_MODE_VIDEO; | 723 | phys_enc->intf_mode = INTF_MODE_VIDEO; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | #include <linux/debugfs.h> | 8 | #include <linux/debugfs.h> |
| 9 | 9 | ||
| 10 | #include <drm/drm_framebuffer.h> | 10 | #include <drm/drm_framebuffer.h> |
| 11 | #include <drm/drm_managed.h> | ||
| 11 | 12 | ||
| 12 | #include "dpu_encoder_phys.h" | 13 | #include "dpu_encoder_phys.h" |
| 13 | #include "dpu_formats.h" | 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 | * @phys_enc:Pointer to physical encoder | 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 | struct dpu_hw_wb *hw_wb; | 215 | struct dpu_hw_wb *hw_wb; |
| 215 | struct dpu_hw_ctl *ctl; | 216 | struct dpu_hw_ctl *ctl; |
| 217 | struct dpu_hw_cdm *hw_cdm; | ||
| 216 | 218 | ||
| 217 | if (!phys_enc) { | 219 | if (!phys_enc) { |
| 218 | DPU_ERROR("invalid encoder\n"); | 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 | hw_wb = phys_enc->hw_wb; | 224 | hw_wb = phys_enc->hw_wb; |
| 223 | ctl = phys_enc->hw_ctl; | 225 | ctl = phys_enc->hw_ctl; |
| 226 | hw_cdm = phys_enc->hw_cdm; | ||
| 224 | 227 | ||
| 225 | if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && | 228 | if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && |
| 226 | (phys_enc->hw_ctl && | 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 | if (mode_3d && hw_pp && hw_pp->merge_3d) | 240 | if (mode_3d && hw_pp && hw_pp->merge_3d) |
| 238 | intf_cfg.merge_3d = hw_pp->merge_3d->idx; | 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 | if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode) | 246 | if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode) |
| 241 | phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, | 247 | phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, |
| 242 | mode_3d); | 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 | * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states | 358 | * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states |
| 263 | * @phys_enc: Pointer to physical encoder | 359 | * @phys_enc: Pointer to physical encoder |
| @@ -307,7 +403,7 @@ static int dpu_encoder_phys_wb_atomic_check( · 43 unmodified lines | |||
| 307 | return -EINVAL; | 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 | struct dpu_hw_wb *hw_wb; | 416 | struct dpu_hw_wb *hw_wb; |
| 321 | struct dpu_hw_ctl *hw_ctl; | 417 | struct dpu_hw_ctl *hw_ctl; |
| 322 | struct dpu_hw_pingpong *hw_pp; | 418 | struct dpu_hw_pingpong *hw_pp; |
| 419 | struct dpu_hw_cdm *hw_cdm; | ||
| 323 | u32 pending_flush = 0; | 420 | u32 pending_flush = 0; |
| 324 | 421 | ||
| 325 | if (!phys_enc) | 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 | hw_wb = phys_enc->hw_wb; | 425 | hw_wb = phys_enc->hw_wb; |
| 329 | hw_pp = phys_enc->hw_pp; | 426 | hw_pp = phys_enc->hw_pp; |
| 330 | hw_ctl = phys_enc->hw_ctl; | 427 | hw_ctl = phys_enc->hw_ctl; |
| 428 | hw_cdm = phys_enc->hw_cdm; | ||
| 331 | 429 | ||
| 332 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); | 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 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, | 441 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 344 | hw_pp->merge_3d->idx); | 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 | if (hw_ctl->ops.get_pending_flush) | 447 | if (hw_ctl->ops.get_pending_flush) |
| 347 | pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl); | 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 | dpu_encoder_phys_wb_setup_fb(phys_enc, fb); | 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 | phys_enc->enable_state = DPU_ENC_DISABLED; | 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 | static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc, | 685 | static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc, |
| 598 | struct drm_writeback_job *job) | 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 | ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set; | 777 | ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set; |
| 690 | ops->enable = dpu_encoder_phys_wb_enable; | 778 | ops->enable = dpu_encoder_phys_wb_enable; |
| 691 | ops->disable = dpu_encoder_phys_wb_disable; | 779 | ops->disable = dpu_encoder_phys_wb_disable; |
| 692 | ops->destroy = dpu_encoder_phys_wb_destroy; | ||
| 693 | ops->atomic_check = dpu_encoder_phys_wb_atomic_check; | 780 | ops->atomic_check = dpu_encoder_phys_wb_atomic_check; |
| 694 | ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done; | 781 | ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done; |
| 695 | ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff; | 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 | * dpu_encoder_phys_wb_init - initialize writeback encoder | 794 | * dpu_encoder_phys_wb_init - initialize writeback encoder |
| 795 | * @dev: Corresponding device for devres management | ||
| 708 | * @p: Pointer to init info structure with initialization params | 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 | struct dpu_enc_phys_init_params *p) | 799 | struct dpu_enc_phys_init_params *p) |
| 712 | { | 800 | { |
| 713 | struct dpu_encoder_phys *phys_enc = NULL; | 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 | return ERR_PTR(-EINVAL); | 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 | if (!wb_enc) { | 812 | if (!wb_enc) { |
| 725 | DPU_ERROR("failed to allocate wb phys_enc enc\n"); | 813 | DPU_ERROR("failed to allocate wb phys_enc enc\n"); |
| 726 | return ERR_PTR(-ENOMEM); | 814 | return ERR_PTR(-ENOMEM); |
| @@ -22,23 +22,14 @@ · 21 unmodified lines | |||
| 22 | BIT(DPU_SSPP_CSC_10BIT)) | 22 | BIT(DPU_SSPP_CSC_10BIT)) |
| 23 | 23 | ||
| 24 | #define VIG_MSM8998_MASK \ | 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 | #define VIG_SDM845_MASK \ | 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 | #define VIG_SDM845_MASK_SDMA \ | 30 | #define VIG_SDM845_MASK_SDMA \ |
| 31 | (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) | 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 | #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) | 33 | #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL)) |
| 43 | 34 | ||
| 44 | #define DMA_MSM8998_MASK \ | 35 | #define DMA_MSM8998_MASK \ |
| @@ -47,7 +38,7 @@ · 2 unmodified lines | |||
| 47 | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) | 38 | BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) |
| 48 | 39 | ||
| 49 | #define VIG_SC7280_MASK \ | 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 | #define VIG_SC7280_MASK_SDMA \ | 43 | #define VIG_SC7280_MASK_SDMA \ |
| 53 | (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) | 44 | (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2)) |
| @@ -211,7 +202,7 @@ static const u32 rotation_v2_formats[] = { · 157 unmodified lines | |||
| 211 | /* TODO add formats after validation */ | 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 | DRM_FORMAT_RGB565, | 206 | DRM_FORMAT_RGB565, |
| 216 | DRM_FORMAT_BGR565, | 207 | DRM_FORMAT_BGR565, |
| 217 | DRM_FORMAT_RGB888, | 208 | DRM_FORMAT_RGB888, |
| @@ -245,21 +236,56 @@ static const uint32_t wb2_formats[] = { · 27 unmodified lines | |||
| 245 | DRM_FORMAT_XBGR4444, | 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 | * SSPP sub blocks config | 275 | * SSPP sub blocks config |
| 250 | *************************************************************/ | 276 | *************************************************************/ |
| 251 | 277 | ||
| 278 | #define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min)) | ||
| 279 | |||
| 252 | /* SSPP common configuration */ | 280 | /* SSPP common configuration */ |
| 253 | #define _VIG_SBLK(sdma_pri, qseed_ver) \ | 281 | #define _VIG_SBLK(scaler_ver) \ |
| 254 | { \ | 282 | { \ |
| 255 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ | 283 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ |
| 256 | .maxupscale = MAX_UPSCALE_RATIO, \ | 284 | .maxupscale = MAX_UPSCALE_RATIO, \ |
| 257 | .smart_dma_priority = sdma_pri, \ | ||
| 258 | .scaler_blk = {.name = "scaler", \ | 285 | .scaler_blk = {.name = "scaler", \ |
| 259 | .id = qseed_ver, \ | 286 | .version = scaler_ver, \ |
| 260 | .base = 0xa00, .len = 0xa0,}, \ | 287 | .base = 0xa00, .len = 0xa0,}, \ |
| 261 | .csc_blk = {.name = "csc", \ | 288 | .csc_blk = {.name = "csc", \ |
| 262 | .id = DPU_SSPP_CSC_10BIT, \ | ||
| 263 | .base = 0x1a00, .len = 0x100,}, \ | 289 | .base = 0x1a00, .len = 0x100,}, \ |
| 264 | .format_list = plane_formats_yuv, \ | 290 | .format_list = plane_formats_yuv, \ |
| 265 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ | 291 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ |
| @@ -268,16 +294,14 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines | |||
| 268 | .rotation_cfg = NULL, \ | 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 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ | 299 | .maxdwnscale = MAX_DOWNSCALE_RATIO, \ |
| 274 | .maxupscale = MAX_UPSCALE_RATIO, \ | 300 | .maxupscale = MAX_UPSCALE_RATIO, \ |
| 275 | .smart_dma_priority = sdma_pri, \ | ||
| 276 | .scaler_blk = {.name = "scaler", \ | 301 | .scaler_blk = {.name = "scaler", \ |
| 277 | .id = qseed_ver, \ | 302 | .version = scaler_ver, \ |
| 278 | .base = 0xa00, .len = 0xa0,}, \ | 303 | .base = 0xa00, .len = 0xa0,}, \ |
| 279 | .csc_blk = {.name = "csc", \ | 304 | .csc_blk = {.name = "csc", \ |
| 280 | .id = DPU_SSPP_CSC_10BIT, \ | ||
| 281 | .base = 0x1a00, .len = 0x100,}, \ | 305 | .base = 0x1a00, .len = 0x100,}, \ |
| 282 | .format_list = plane_formats_yuv, \ | 306 | .format_list = plane_formats_yuv, \ |
| 283 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ | 307 | .num_formats = ARRAY_SIZE(plane_formats_yuv), \ |
| @@ -286,91 +310,64 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines | |||
| 286 | .rotation_cfg = rot_cfg, \ | 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 | .maxdwnscale = SSPP_UNITY_SCALE, \ | 325 | .maxdwnscale = SSPP_UNITY_SCALE, \ |
| 292 | .maxupscale = SSPP_UNITY_SCALE, \ | 326 | .maxupscale = SSPP_UNITY_SCALE, \ |
| 293 | .smart_dma_priority = sdma_pri, \ | ||
| 294 | .format_list = plane_formats, \ | 327 | .format_list = plane_formats, \ |
| 295 | .num_formats = ARRAY_SIZE(plane_formats), \ | 328 | .num_formats = ARRAY_SIZE(plane_formats), \ |
| 296 | .virt_format_list = plane_formats, \ | 329 | .virt_format_list = plane_formats, \ |
| 297 | .virt_num_formats = ARRAY_SIZE(plane_formats), \ | 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 | static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { | 333 | static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { |
| 310 | .rot_maxheight = 1088, | 334 | .rot_maxheight = 1088, |
| 311 | .rot_num_formats = ARRAY_SIZE(rotation_v2_formats), | 335 | .rot_num_formats = ARRAY_SIZE(rotation_v2_formats), |
| 312 | .rot_format_list = rotation_v2_formats, | 336 | .rot_format_list = rotation_v2_formats, |
| 313 | }; | 337 | }; |
| 314 | 338 | ||
| 315 | static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = | 339 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale = |
| 316 | _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3); | 340 | _VIG_SBLK_NOSCALE(); |
| 317 | static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = | 341 | |
| 318 | _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3); | 342 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_2 = |
| 319 | static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = | 343 | _VIG_SBLK(SSPP_SCALER_VER(1, 2)); |
| 320 | _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3); | 344 | |
| 321 | static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 = | 345 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_3 = |
| 322 | _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3); | 346 | _VIG_SBLK(SSPP_SCALER_VER(1, 3)); |
| 323 | 347 | ||
| 324 | static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1); | 348 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_4 = |
| 325 | static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2); | 349 | _VIG_SBLK(SSPP_SCALER_VER(1, 4)); |
| 326 | static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3); | 350 | |
| 327 | static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4); | 351 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_2_4 = |
| 328 | 352 | _VIG_SBLK(SSPP_SCALER_VER(2, 4)); | |
| 329 | static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 = | 353 | |
| 330 | _VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4); | 354 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0 = |
| 331 | 355 | _VIG_SBLK(SSPP_SCALER_VER(3, 0)); | |
| 332 | static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 = | 356 | |
| 333 | _VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2); | 357 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0_rot_v2 = |
| 334 | 358 | _VIG_SBLK_ROT(SSPP_SCALER_VER(3, 0), | |
| 335 | static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 = | 359 | &dpu_rot_sc7280_cfg_v2); |
| 336 | _VIG_SBLK(2, DPU_SSPP_SCALER_QSEED4); | 360 | |
| 337 | 361 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_1 = | |
| 338 | static const struct dpu_sspp_sub_blks sm6125_vig_sblk_0 = | 362 | _VIG_SBLK(SSPP_SCALER_VER(3, 1)); |
| 339 | _VIG_SBLK(3, DPU_SSPP_SCALER_QSEED3LITE); | 363 | |
| 340 | 364 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 = | |
| 341 | static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 = | 365 | _VIG_SBLK(SSPP_SCALER_VER(3, 2)); |
| 342 | _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED4); | 366 | |
| 343 | static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 = | 367 | static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 = |
| 344 | _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED4); | 368 | _VIG_SBLK(SSPP_SCALER_VER(3, 3)); |
| 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 | } | ||
| 371 | 369 | ||
| 372 | static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE(2); | 370 | static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK(); |
| 373 | static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK(1); | ||
| 374 | 371 | ||
| 375 | /************************************************************* | 372 | /************************************************************* |
| 376 | * MIXER sub blocks config | 373 | * MIXER sub blocks config |
| @@ -422,12 +419,12 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { · 45 unmodified lines | |||
| 422 | * DSPP sub blocks config | 419 | * DSPP sub blocks config |
| 423 | *************************************************************/ | 420 | *************************************************************/ |
| 424 | static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = { | 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 | .len = 0x90, .version = 0x10007}, | 423 | .len = 0x90, .version = 0x10007}, |
| 427 | }; | 424 | }; |
| 428 | 425 | ||
| 429 | static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = { | 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 | .len = 0x90, .version = 0x40000}, | 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 | * PINGPONG sub blocks config | 432 | * PINGPONG sub blocks config |
| 436 | *************************************************************/ | 433 | *************************************************************/ |
| 437 | static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = { | 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 | .version = 0x1}, | 436 | .version = 0x1}, |
| 440 | .dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0, | 437 | .dither = {.name = "dither", .base = 0x30e0, |
| 441 | .len = 0x20, .version = 0x10000}, | 438 | .len = 0x20, .version = 0x10000}, |
| 442 | }; | 439 | }; |
| 443 | 440 | ||
| 444 | static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = { | 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 | .len = 0x20, .version = 0x10000}, | 443 | .len = 0x20, .version = 0x10000}, |
| 447 | }; | 444 | }; |
| 448 | 445 | ||
| 449 | static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = { | 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 | .len = 0x20, .version = 0x20000}, | 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 | .ctl = {.name = "ctl", .base = 0xF80, .len = 0x10}, | 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 | * VBIF sub blocks config | 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 | static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1}; | 479 | static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1}; |
| 473 | static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6}; | 480 | static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6}; |
| 474 | static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3}; | 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 | static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = { | 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 | * PERF data config | 590 | * PERF data config |
| 563 | *************************************************************/ | 591 | *************************************************************/ |
| @@ -654,6 +682,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { · 90 unmodified lines | |||
| 654 | #include "catalog/dpu_3_0_msm8998.h" | 682 | #include "catalog/dpu_3_0_msm8998.h" |
| 655 | 683 | ||
| 656 | #include "catalog/dpu_4_0_sdm845.h" | 684 | #include "catalog/dpu_4_0_sdm845.h" |
| 685 | #include "catalog/dpu_4_1_sdm670.h" | ||
| 657 | 686 | ||
| 658 | #include "catalog/dpu_5_0_sm8150.h" | 687 | #include "catalog/dpu_5_0_sm8150.h" |
| 659 | #include "catalog/dpu_5_1_sc8180x.h" | 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 | #include "catalog/dpu_8_1_sm8450.h" | 702 | #include "catalog/dpu_8_1_sm8450.h" |
| 674 | 703 | ||
| 675 | #include "catalog/dpu_9_0_sm8550.h" | 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 | * SSPP sub-blocks/features | 52 | * SSPP sub-blocks/features |
| 53 | * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support | 53 | * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support |
| 54 | * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support | 54 | * @DPU_SSPP_SCALER_QSEED3_COMPATIBLE, QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4) |
| 55 | * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support | ||
| 56 | * @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support | ||
| 57 | * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes | 55 | * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes |
| 58 | * @DPU_SSPP_CSC, Support of Color space converion | 56 | * @DPU_SSPP_CSC, Support of Color space converion |
| 59 | * @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion | 57 | * @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion |
| @@ -71,9 +69,7 @@ enum { · 11 unmodified lines | |||
| 71 | */ | 69 | */ |
| 72 | enum { | 70 | enum { |
| 73 | DPU_SSPP_SCALER_QSEED2 = 0x1, | 71 | DPU_SSPP_SCALER_QSEED2 = 0x1, |
| 74 | DPU_SSPP_SCALER_QSEED3, | 72 | DPU_SSPP_SCALER_QSEED3_COMPATIBLE, |
| 75 | DPU_SSPP_SCALER_QSEED3LITE, | ||
| 76 | DPU_SSPP_SCALER_QSEED4, | ||
| 77 | DPU_SSPP_SCALER_RGB, | 73 | DPU_SSPP_SCALER_RGB, |
| 78 | DPU_SSPP_CSC, | 74 | DPU_SSPP_CSC, |
| 79 | DPU_SSPP_CSC_10BIT, | 75 | DPU_SSPP_CSC_10BIT, |
| @@ -248,50 +244,51 @@ enum { · 168 unmodified lines | |||
| 248 | u32 len; \ | 244 | u32 len; \ |
| 249 | unsigned long features | 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 | * struct dpu_scaler_blk: Scaler information | 248 | * struct dpu_scaler_blk: Scaler information |
| 267 | * @info: HW register and features supported by this sub-blk | 249 | * @name: string name for debug purposes |
| 268 | * @version: qseed block revision | 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 | struct dpu_scaler_blk { | 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 | u32 version; | 259 | u32 version; |
| 273 | }; | 260 | }; |
| 274 | 261 | ||
| 275 | struct dpu_csc_blk { | 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 | * struct dpu_pp_blk : Pixel processing sub-blk information | 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 | * @version: HW Algorithm version | 273 | * @version: HW Algorithm version |
| 283 | */ | 274 | */ |
| 284 | struct dpu_pp_blk { | 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 | u32 version; | 279 | u32 version; |
| 287 | }; | 280 | }; |
| 288 | 281 | ||
| 289 | /** | 282 | /** |
| 290 | * struct dpu_dsc_blk - DSC Encoder sub-blk information | 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 | struct dpu_dsc_blk { | 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 | * @max_mixer_width max layer mixer line width support. | 338 | * @max_mixer_width max layer mixer line width support. |
| 342 | * @max_mixer_blendstages max layer mixer blend stages or | 339 | * @max_mixer_blendstages max layer mixer blend stages or |
| 343 | * supported z order | 340 | * supported z order |
| 344 | * @qseed_type qseed2 or qseed3 support. | ||
| 345 | * @has_src_split source split feature status | 341 | * @has_src_split source split feature status |
| 346 | * @has_dim_layer dim layer feature status | 342 | * @has_dim_layer dim layer feature status |
| 347 | * @has_idle_pc indicate if idle power collapse feature is supported | 343 | * @has_idle_pc indicate if idle power collapse feature is supported |
| @@ -354,7 +350,6 @@ struct dpu_rotation_cfg { · 6 unmodified lines | |||
| 354 | struct dpu_caps { | 350 | struct dpu_caps { |
| 355 | u32 max_mixer_width; | 351 | u32 max_mixer_width; |
| 356 | u32 max_mixer_blendstages; | 352 | u32 max_mixer_blendstages; |
| 357 | u32 qseed_type; | ||
| 358 | bool has_src_split; | 353 | bool has_src_split; |
| 359 | bool has_dim_layer; | 354 | bool has_dim_layer; |
| 360 | bool has_idle_pc; | 355 | bool has_idle_pc; |
| @@ -371,7 +366,6 @@ struct dpu_caps { · 10 unmodified lines | |||
| 371 | * common: Pointer to common configurations shared by sub blocks | 366 | * common: Pointer to common configurations shared by sub blocks |
| 372 | * @maxdwnscale: max downscale ratio supported(without DECIMATION) | 367 | * @maxdwnscale: max downscale ratio supported(without DECIMATION) |
| 373 | * @maxupscale: maxupscale ratio supported | 368 | * @maxupscale: maxupscale ratio supported |
| 374 | * @smart_dma_priority: hw priority of rect1 of multirect pipe | ||
| 375 | * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps | 369 | * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps |
| 376 | * @qseed_ver: qseed version | 370 | * @qseed_ver: qseed version |
| 377 | * @scaler_blk: | 371 | * @scaler_blk: |
| @@ -385,7 +379,6 @@ struct dpu_caps { · 7 unmodified lines | |||
| 385 | struct dpu_sspp_sub_blks { | 379 | struct dpu_sspp_sub_blks { |
| 386 | u32 maxdwnscale; | 380 | u32 maxdwnscale; |
| 387 | u32 maxupscale; | 381 | u32 maxupscale; |
| 388 | u32 smart_dma_priority; | ||
| 389 | u32 max_per_pipe_bw; | 382 | u32 max_per_pipe_bw; |
| 390 | u32 qseed_ver; | 383 | u32 qseed_ver; |
| 391 | struct dpu_scaler_blk scaler_blk; | 384 | struct dpu_scaler_blk scaler_blk; |
| @@ -689,6 +682,17 @@ struct dpu_vbif_cfg { · 297 unmodified lines | |||
| 689 | u32 memtype[MAX_XIN_COUNT]; | 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 | * Define CDP use cases | 697 | * Define CDP use cases |
| 694 | * @DPU_PERF_CDP_UDAGE_RT: real-time use cases | 698 | * @DPU_PERF_CDP_UDAGE_RT: real-time use cases |
| @@ -812,6 +816,8 @@ struct dpu_mdss_cfg { · 117 unmodified lines | |||
| 812 | u32 wb_count; | 816 | u32 wb_count; |
| 813 | const struct dpu_wb_cfg *wb; | 817 | const struct dpu_wb_cfg *wb; |
| 814 | 818 | ||
| 819 | const struct dpu_cdm_cfg *cdm; | ||
| 820 | |||
| 815 | u32 ad_count; | 821 | u32 ad_count; |
| 816 | 822 | ||
| 817 | u32 dspp_count; | 823 | u32 dspp_count; |
| @@ -827,6 +833,7 @@ struct dpu_mdss_cfg { · 9 unmodified lines | |||
| 827 | 833 | ||
| 828 | extern const struct dpu_mdss_cfg dpu_msm8998_cfg; | 834 | extern const struct dpu_mdss_cfg dpu_msm8998_cfg; |
| 829 | extern const struct dpu_mdss_cfg dpu_sdm845_cfg; | 835 | extern const struct dpu_mdss_cfg dpu_sdm845_cfg; |
| 836 | extern const struct dpu_mdss_cfg dpu_sdm670_cfg; | ||
| 830 | extern const struct dpu_mdss_cfg dpu_sm8150_cfg; | 837 | extern const struct dpu_mdss_cfg dpu_sm8150_cfg; |
| 831 | extern const struct dpu_mdss_cfg dpu_sc8180x_cfg; | 838 | extern const struct dpu_mdss_cfg dpu_sc8180x_cfg; |
| 832 | extern const struct dpu_mdss_cfg dpu_sm8250_cfg; | 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 | extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg; | 848 | extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg; |
| 842 | extern const struct dpu_mdss_cfg dpu_sm8450_cfg; | 849 | extern const struct dpu_mdss_cfg dpu_sm8450_cfg; |
| 843 | extern const struct dpu_mdss_cfg dpu_sm8550_cfg; | 850 | extern const struct dpu_mdss_cfg dpu_sm8550_cfg; |
| 851 | extern const struct dpu_mdss_cfg dpu_sm8650_cfg; | ||
| 844 | 852 | ||
| 845 | #endif /* _DPU_HW_CATALOG_H */ | 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 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
| 7 | |||
| 8 | #include <drm/drm_managed.h> | ||
| 9 | |||
| 7 | #include "dpu_hwio.h" | 10 | #include "dpu_hwio.h" |
| 8 | #include "dpu_hw_ctl.h" | 11 | #include "dpu_hw_ctl.h" |
| 9 | #include "dpu_kms.h" | 12 | #include "dpu_kms.h" |
| @@ -29,11 +32,13 @@ · 19 unmodified lines | |||
| 29 | #define CTL_DSC_ACTIVE 0x0E8 | 32 | #define CTL_DSC_ACTIVE 0x0E8 |
| 30 | #define CTL_WB_ACTIVE 0x0EC | 33 | #define CTL_WB_ACTIVE 0x0EC |
| 31 | #define CTL_INTF_ACTIVE 0x0F4 | 34 | #define CTL_INTF_ACTIVE 0x0F4 |
| 35 | #define CTL_CDM_ACTIVE 0x0F8 | ||
| 32 | #define CTL_FETCH_PIPE_ACTIVE 0x0FC | 36 | #define CTL_FETCH_PIPE_ACTIVE 0x0FC |
| 33 | #define CTL_MERGE_3D_FLUSH 0x100 | 37 | #define CTL_MERGE_3D_FLUSH 0x100 |
| 34 | #define CTL_DSC_FLUSH 0x104 | 38 | #define CTL_DSC_FLUSH 0x104 |
| 35 | #define CTL_WB_FLUSH 0x108 | 39 | #define CTL_WB_FLUSH 0x108 |
| 36 | #define CTL_INTF_FLUSH 0x110 | 40 | #define CTL_INTF_FLUSH 0x110 |
| 41 | #define CTL_CDM_FLUSH 0x114 | ||
| 37 | #define CTL_INTF_MASTER 0x134 | 42 | #define CTL_INTF_MASTER 0x134 |
| 38 | #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) | 43 | #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) |
| 39 | 44 | ||
| @@ -43,6 +48,7 @@ · 3 unmodified lines | |||
| 43 | #define DPU_REG_RESET_TIMEOUT_US 2000 | 48 | #define DPU_REG_RESET_TIMEOUT_US 2000 |
| 44 | #define MERGE_3D_IDX 23 | 49 | #define MERGE_3D_IDX 23 |
| 45 | #define DSC_IDX 22 | 50 | #define DSC_IDX 22 |
| 51 | #define CDM_IDX 26 | ||
| 46 | #define INTF_IDX 31 | 52 | #define INTF_IDX 31 |
| 47 | #define WB_IDX 16 | 53 | #define WB_IDX 16 |
| 48 | #define DSPP_IDX 29 /* From DPU hw rev 7.x.x */ | 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 | ctx->pending_wb_flush_mask = 0; | 110 | ctx->pending_wb_flush_mask = 0; |
| 105 | ctx->pending_merge_3d_flush_mask = 0; | 111 | ctx->pending_merge_3d_flush_mask = 0; |
| 106 | ctx->pending_dsc_flush_mask = 0; | 112 | ctx->pending_dsc_flush_mask = 0; |
| 113 | ctx->pending_cdm_flush_mask = 0; | ||
| 107 | 114 | ||
| 108 | memset(ctx->pending_dspp_flush_mask, 0, | 115 | memset(ctx->pending_dspp_flush_mask, 0, |
| 109 | sizeof(ctx->pending_dspp_flush_mask)); | 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 | DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, | 155 | DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, |
| 149 | ctx->pending_dsc_flush_mask); | 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 | DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); | 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 | static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, | 300 | static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, |
| 283 | enum dpu_wb wb) | 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 | ctx->pending_flush_mask |= BIT(DSC_IDX); | 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 | static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, | 334 | static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, |
| 311 | enum dpu_dspp dspp, u32 dspp_sub_blk) | 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 | if (cfg->dsc) | 565 | if (cfg->dsc) |
| 542 | DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); | 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 | static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, | 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 | u32 wb_active = 0; | 610 | u32 wb_active = 0; |
| 584 | u32 merge3d_active = 0; | 611 | u32 merge3d_active = 0; |
| 585 | u32 dsc_active; | 612 | u32 dsc_active; |
| 613 | u32 cdm_active; | ||
| 586 | 614 | ||
| 587 | /* | 615 | /* |
| 588 | * This API resets each portion of the CTL path namely, | 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 | dsc_active &= ~cfg->dsc; | 646 | dsc_active &= ~cfg->dsc; |
| 619 | DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); | 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 | static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, | 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 | ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; | 685 | ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; |
| 652 | ops->update_pending_flush_dsc = | 686 | ops->update_pending_flush_dsc = |
| 653 | dpu_hw_ctl_update_pending_flush_dsc_v1; | 687 | dpu_hw_ctl_update_pending_flush_dsc_v1; |
| 688 | ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1; | ||
| 654 | } else { | 689 | } else { |
| 655 | ops->trigger_flush = dpu_hw_ctl_trigger_flush; | 690 | ops->trigger_flush = dpu_hw_ctl_trigger_flush; |
| 656 | ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; | 691 | ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; |
| 657 | ops->update_pending_flush_intf = | 692 | ops->update_pending_flush_intf = |
| 658 | dpu_hw_ctl_update_pending_flush_intf; | 693 | dpu_hw_ctl_update_pending_flush_intf; |
| 659 | ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb; | 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 | ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; | 697 | ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; |
| 662 | ops->update_pending_flush = dpu_hw_ctl_update_pending_flush; | 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 | ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; | 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, | 719 | struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, |
| 684 | void __iomem *addr, | 720 | const struct dpu_ctl_cfg *cfg, |
| 685 | u32 mixer_count, | 721 | void __iomem *addr, |
| 686 | const struct dpu_lm_cfg *mixer) | 722 | u32 mixer_count, |
| 723 | const struct dpu_lm_cfg *mixer) | ||
| 687 | { | 724 | { |
| 688 | struct dpu_hw_ctl *c; | 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 | if (!c) | 728 | if (!c) |
| 692 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * @mode_3d: 3d mux configuration | 39 | * @mode_3d: 3d mux configuration |
| 40 | * @merge_3d: 3d merge block used | 40 | * @merge_3d: 3d merge block used |
| 41 | * @intf_mode_sel: Interface mode, cmd / vid | 41 | * @intf_mode_sel: Interface mode, cmd / vid |
| 42 | * @cdm: CDM block used | ||
| 42 | * @stream_sel: Stream selection for multi-stream interfaces | 43 | * @stream_sel: Stream selection for multi-stream interfaces |
| 43 | * @dsc: DSC BIT masks used | 44 | * @dsc: DSC BIT masks used |
| 44 | */ | 45 | */ |
| @@ -48,6 +49,7 @@ struct dpu_hw_intf_cfg { · 3 unmodified lines | |||
| 48 | enum dpu_3d_blend_mode mode_3d; | 49 | enum dpu_3d_blend_mode mode_3d; |
| 49 | enum dpu_merge_3d merge_3d; | 50 | enum dpu_merge_3d merge_3d; |
| 50 | enum dpu_ctl_mode_sel intf_mode_sel; | 51 | enum dpu_ctl_mode_sel intf_mode_sel; |
| 52 | enum dpu_cdm cdm; | ||
| 51 | int stream_sel; | 53 | int stream_sel; |
| 52 | unsigned int dsc; | 54 | unsigned int dsc; |
| 53 | }; | 55 | }; |
| @@ -166,6 +168,14 @@ struct dpu_hw_ctl_ops { · 112 unmodified lines | |||
| 166 | void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx, | 168 | void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx, |
| 167 | enum dpu_dsc blk); | 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 | * Write the value of the pending_flush_mask to hardware | 180 | * Write the value of the pending_flush_mask to hardware |
| 171 | * @ctx : ctl path ctx pointer | 181 | * @ctx : ctl path ctx pointer |
| @@ -239,6 +249,7 @@ struct dpu_hw_ctl_ops { · 67 unmodified lines | |||
| 239 | * @pending_intf_flush_mask: pending INTF flush | 249 | * @pending_intf_flush_mask: pending INTF flush |
| 240 | * @pending_wb_flush_mask: pending WB flush | 250 | * @pending_wb_flush_mask: pending WB flush |
| 241 | * @pending_dsc_flush_mask: pending DSC flush | 251 | * @pending_dsc_flush_mask: pending DSC flush |
| 252 | * @pending_cdm_flush_mask: pending CDM flush | ||
| 242 | * @ops: operation list | 253 | * @ops: operation list |
| 243 | */ | 254 | */ |
| 244 | struct dpu_hw_ctl { | 255 | struct dpu_hw_ctl { |
| @@ -256,6 +267,7 @@ struct dpu_hw_ctl { · 11 unmodified lines | |||
| 256 | u32 pending_merge_3d_flush_mask; | 267 | u32 pending_merge_3d_flush_mask; |
| 257 | u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0]; | 268 | u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0]; |
| 258 | u32 pending_dsc_flush_mask; | 269 | u32 pending_dsc_flush_mask; |
| 270 | u32 pending_cdm_flush_mask; | ||
| 259 | 271 | ||
| 260 | /* ops */ | 272 | /* ops */ |
| 261 | struct dpu_hw_ctl_ops ops; | 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 | * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. | 287 | * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object. |
| 276 | * Should be called before accessing any ctl_path register. | 288 | * Should be called before accessing any ctl_path register. |
| 289 | * @dev: Corresponding device for devres management | ||
| 277 | * @cfg: ctl_path catalog entry for which driver object is required | 290 | * @cfg: ctl_path catalog entry for which driver object is required |
| 278 | * @addr: mapped register io address of MDP | 291 | * @addr: mapped register io address of MDP |
| 279 | * @mixer_count: Number of mixers in @mixer | 292 | * @mixer_count: Number of mixers in @mixer |
| 280 | * @mixer: Pointer to an array of Layer Mixers defined in the catalog | 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, | 295 | struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev, |
| 283 | void __iomem *addr, | 296 | const struct dpu_ctl_cfg *cfg, |
| 284 | u32 mixer_count, | 297 | void __iomem *addr, |
| 285 | const struct dpu_lm_cfg *mixer); | 298 | u32 mixer_count, |
| 286 | 299 | const struct dpu_lm_cfg *mixer); | |
| 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); | ||
| 292 | 300 | ||
| 293 | #endif /*_DPU_HW_CTL_H */ | 301 | #endif /*_DPU_HW_CTL_H */ |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | |||
| 3 | * Copyright (c) 2020-2022, Linaro Limited | 3 | * Copyright (c) 2020-2022, Linaro Limited |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <drm/drm_managed.h> | ||
| 7 | |||
| 6 | #include <drm/display/drm_dsc_helper.h> | 8 | #include <drm/display/drm_dsc_helper.h> |
| 7 | 9 | ||
| 8 | #include "dpu_kms.h" | 10 | #include "dpu_kms.h" |
| @@ -188,12 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, · 179 unmodified lines | |||
| 188 | ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk; | 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 | void __iomem *addr) | 195 | void __iomem *addr) |
| 193 | { | 196 | { |
| 194 | struct dpu_hw_dsc *c; | 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 | if (!c) | 200 | if (!c) |
| 198 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_dsc_init() - Initializes the DSC hw driver object. | 66 | * dpu_hw_dsc_init() - Initializes the DSC hw driver object. |
| 67 | * @dev: Corresponding device for devres management | ||
| 67 | * @cfg: DSC catalog entry for which driver object is required | 68 | * @cfg: DSC catalog entry for which driver object is required |
| 68 | * @addr: Mapped register io address of MDP | 69 | * @addr: Mapped register io address of MDP |
| 69 | * Return: Error code or allocated dpu_hw_dsc context | 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 | struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev, |
| 72 | void __iomem *addr); | 73 | const struct dpu_dsc_cfg *cfg, |
| 74 | void __iomem *addr); | ||
| 73 | 75 | ||
| 74 | /** | 76 | /** |
| 75 | * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object | 77 | * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object |
| 78 | * @dev: Corresponding device for devres management | ||
| 76 | * @cfg: DSC catalog entry for which driver object is required | 79 | * @cfg: DSC catalog entry for which driver object is required |
| 77 | * @addr: Mapped register io address of MDP | 80 | * @addr: Mapped register io address of MDP |
| 78 | * Returns: Error code or allocated dpu_hw_dsc context | 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 | void __iomem *addr); | 85 | void __iomem *addr); |
| 82 | 86 | ||
| 83 | /** | 87 | /** |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | |||
| 4 | * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved | 4 | * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <drm/drm_managed.h> | ||
| 8 | |||
| 7 | #include <drm/display/drm_dsc_helper.h> | 9 | #include <drm/display/drm_dsc_helper.h> |
| 8 | 10 | ||
| 9 | #include "dpu_kms.h" | 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 | ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2; | 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 | void __iomem *addr) | 374 | void __iomem *addr) |
| 372 | { | 375 | { |
| 373 | struct dpu_hw_dsc *c; | 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 | if (!c) | 379 | if (!c) |
| 377 | return ERR_PTR(-ENOMEM); | 380 | return ERR_PTR(-ENOMEM); |
| 378 | 381 | ||
| @@ -2,6 +2,8 @@ · 1 unmodified line | |||
| 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <drm/drm_managed.h> | ||
| 6 | |||
| 5 | #include "dpu_hwio.h" | 7 | #include "dpu_hwio.h" |
| 6 | #include "dpu_hw_catalog.h" | 8 | #include "dpu_hw_catalog.h" |
| 7 | #include "dpu_hw_lm.h" | 9 | #include "dpu_hw_lm.h" |
| @@ -68,15 +70,16 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c, · 60 unmodified lines | |||
| 68 | c->ops.setup_pcc = dpu_setup_dspp_pcc; | 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, | 73 | struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, |
| 72 | void __iomem *addr) | 74 | const struct dpu_dspp_cfg *cfg, |
| 75 | void __iomem *addr) | ||
| 73 | { | 76 | { |
| 74 | struct dpu_hw_dspp *c; | 77 | struct dpu_hw_dspp *c; |
| 75 | 78 | ||
| 76 | if (!addr) | 79 | if (!addr) |
| 77 | return ERR_PTR(-EINVAL); | 80 | return ERR_PTR(-EINVAL); |
| 78 | 81 | ||
| 79 | c = kzalloc(sizeof(*c), GFP_KERNEL); | 82 | c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); |
| 80 | if (!c) | 83 | if (!c) |
| 81 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. | 82 | * dpu_hw_dspp_init() - Initializes the DSPP hw driver object. |
| 83 | * should be called once before accessing every DSPP. | 83 | * should be called once before accessing every DSPP. |
| 84 | * @dev: Corresponding device for devres management | ||
| 84 | * @cfg: DSPP catalog entry for which driver object is required | 85 | * @cfg: DSPP catalog entry for which driver object is required |
| 85 | * @addr: Mapped register io address of MDP | 86 | * @addr: Mapped register io address of MDP |
| 86 | * Return: pointer to structure or ERR_PTR | 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 | struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev, |
| 89 | void __iomem *addr); | 90 | const struct dpu_dspp_cfg *cfg, |
| 90 | 91 | void __iomem *addr); | |
| 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); | ||
| 96 | 92 | ||
| 97 | #endif /*_DPU_HW_DSPP_H */ | 93 | #endif /*_DPU_HW_DSPP_H */ |
| 98 | 94 | ||
| @@ -6,6 +6,8 @@ · 5 unmodified lines | |||
| 6 | #include <linux/debugfs.h> | 6 | #include <linux/debugfs.h> |
| 7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
| 8 | 8 | ||
| 9 | #include <drm/drm_managed.h> | ||
| 10 | |||
| 9 | #include "dpu_core_irq.h" | 11 | #include "dpu_core_irq.h" |
| 10 | #include "dpu_kms.h" | 12 | #include "dpu_kms.h" |
| 11 | #include "dpu_hw_interrupts.h" | 13 | #include "dpu_hw_interrupts.h" |
| @@ -472,8 +474,9 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, · 460 unmodified lines | |||
| 472 | return intr_status; | 474 | return intr_status; |
| 473 | } | 475 | } |
| 474 | 476 | ||
| 475 | struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, | 477 | struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, |
| 476 | const struct dpu_mdss_cfg *m) | 478 | void __iomem *addr, |
| 479 | const struct dpu_mdss_cfg *m) | ||
| 477 | { | 480 | { |
| 478 | struct dpu_hw_intr *intr; | 481 | struct dpu_hw_intr *intr; |
| 479 | unsigned int i; | 482 | unsigned int i; |
| @@ -481,7 +484,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, · 1 unmodified line | |||
| 481 | if (!addr || !m) | 484 | if (!addr || !m) |
| 482 | return ERR_PTR(-EINVAL); | 485 | return ERR_PTR(-EINVAL); |
| 483 | 486 | ||
| 484 | intr = kzalloc(sizeof(*intr), GFP_KERNEL); | 487 | intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL); |
| 485 | if (!intr) | 488 | if (!intr) |
| 486 | return ERR_PTR(-ENOMEM); | 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 | return intr; | 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 | int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, | 518 | int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, |
| 521 | unsigned int irq_idx, | 519 | unsigned int irq_idx, |
| 522 | void (*irq_cb)(void *arg), | 520 | void (*irq_cb)(void *arg), |
| @@ -70,15 +70,12 @@ struct dpu_hw_intr { · 69 unmodified lines | |||
| 70 | 70 | ||
| 71 | /** | 71 | /** |
| 72 | * dpu_hw_intr_init(): Initializes the interrupts hw object | 72 | * dpu_hw_intr_init(): Initializes the interrupts hw object |
| 73 | * @dev: Corresponding device for devres management | ||
| 73 | * @addr: mapped register io address of MDP | 74 | * @addr: mapped register io address of MDP |
| 74 | * @m: pointer to MDSS catalog data | 75 | * @m: pointer to MDSS catalog data |
| 75 | */ | 76 | */ |
| 76 | struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, | 77 | struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev, |
| 77 | const struct dpu_mdss_cfg *m); | 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 | #endif | 81 | #endif |
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | 3 | * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. |
| 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 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 | #include <linux/iopoll.h> | 13 | #include <linux/iopoll.h> |
| 14 | 14 | ||
| 15 | #include <drm/drm_managed.h> | ||
| 16 | |||
| 15 | #define INTF_TIMING_ENGINE_EN 0x000 | 17 | #define INTF_TIMING_ENGINE_EN 0x000 |
| 16 | #define INTF_CONFIG 0x004 | 18 | #define INTF_CONFIG 0x004 |
| 17 | #define INTF_HSYNC_CTL 0x008 | 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 | return DPU_REG_READ(c, INTF_LINE_COUNT); | 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 | static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) | 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 | DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2); | 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, | 532 | struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, |
| 531 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | 533 | const struct dpu_intf_cfg *cfg, |
| 534 | void __iomem *addr, | ||
| 535 | const struct dpu_mdss_version *mdss_rev) | ||
| 532 | { | 536 | { |
| 533 | struct dpu_hw_intf *c; | 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 | return NULL; | 541 | return NULL; |
| 538 | } | 542 | } |
| 539 | 543 | ||
| 540 | c = kzalloc(sizeof(*c), GFP_KERNEL); | 544 | c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); |
| 541 | if (!c) | 545 | if (!c) |
| 542 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | /* SPDX-License-Identifier: GPL-2.0-only */ | 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 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 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 | void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, | 96 | void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, |
| 97 | const enum dpu_pingpong pp); | 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 | int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); | 99 | int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); |
| 100 | 100 | ||
| 101 | // Tearcheck on INTF since DPU 5.0.0 | 101 | // Tearcheck on INTF since DPU 5.0.0 |
| @@ -131,17 +131,14 @@ struct dpu_hw_intf { · 29 unmodified lines | |||
| 131 | /** | 131 | /** |
| 132 | * dpu_hw_intf_init() - Initializes the INTF driver for the passed | 132 | * dpu_hw_intf_init() - Initializes the INTF driver for the passed |
| 133 | * interface catalog entry. | 133 | * interface catalog entry. |
| 134 | * @dev: Corresponding device for devres management | ||
| 134 | * @cfg: interface catalog entry for which driver object is required | 135 | * @cfg: interface catalog entry for which driver object is required |
| 135 | * @addr: mapped register io address of MDP | 136 | * @addr: mapped register io address of MDP |
| 136 | * @mdss_rev: dpu core's major and minor versions | 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 | struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev, |
| 139 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | 140 | const struct dpu_intf_cfg *cfg, |
| 140 | 141 | void __iomem *addr, | |
| 141 | /** | 142 | const struct dpu_mdss_version *mdss_rev); |
| 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); | ||
| 146 | 143 | ||
| 147 | #endif /*_DPU_HW_INTF_H */ | 144 | #endif /*_DPU_HW_INTF_H */ |
| @@ -1,9 +1,11 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 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 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <drm/drm_managed.h> | ||
| 8 | |||
| 7 | #include "dpu_kms.h" | 9 | #include "dpu_kms.h" |
| 8 | #include "dpu_hw_catalog.h" | 10 | #include "dpu_hw_catalog.h" |
| 9 | #include "dpu_hwio.h" | 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 | static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) | 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 | ops->collect_misr = dpu_hw_lm_collect_misr; | 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, | 161 | struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, |
| 160 | void __iomem *addr) | 162 | const struct dpu_lm_cfg *cfg, |
| 163 | void __iomem *addr) | ||
| 161 | { | 164 | { |
| 162 | struct dpu_hw_mixer *c; | 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 | return NULL; | 169 | return NULL; |
| 167 | } | 170 | } |
| 168 | 171 | ||
| 169 | c = kzalloc(sizeof(*c), GFP_KERNEL); | 172 | c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); |
| 170 | if (!c) | 173 | if (!c) |
| 171 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. | ||
| 3 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. | 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 | * setup_misr: Enable/disable MISR | 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 | * collect_misr: Read MISR signature | 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 | * dpu_hw_lm_init() - Initializes the mixer hw driver object. | 97 | * dpu_hw_lm_init() - Initializes the mixer hw driver object. |
| 97 | * should be called once before accessing every mixer. | 98 | * should be called once before accessing every mixer. |
| 99 | * @dev: Corresponding device for devres management | ||
| 98 | * @cfg: mixer catalog entry for which driver object is required | 100 | * @cfg: mixer catalog entry for which driver object is required |
| 99 | * @addr: mapped register io address of MDP | 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, | 103 | struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev, |
| 102 | void __iomem *addr); | 104 | const struct dpu_lm_cfg *cfg, |
| 103 | 105 | void __iomem *addr); | |
| 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); | ||
| 109 | 106 | ||
| 110 | #endif /*_DPU_HW_LM_H */ | 107 | #endif /*_DPU_HW_LM_H */ |
| @@ -98,6 +98,7 @@ enum dpu_hw_blk_type { · 97 unmodified lines | |||
| 98 | DPU_HW_BLK_DSPP, | 98 | DPU_HW_BLK_DSPP, |
| 99 | DPU_HW_BLK_MERGE_3D, | 99 | DPU_HW_BLK_MERGE_3D, |
| 100 | DPU_HW_BLK_DSC, | 100 | DPU_HW_BLK_DSC, |
| 101 | DPU_HW_BLK_CDM, | ||
| 101 | DPU_HW_BLK_MAX, | 102 | DPU_HW_BLK_MAX, |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| @@ -185,6 +186,11 @@ enum dpu_dsc { · 81 unmodified lines | |||
| 185 | DSC_MAX | 186 | DSC_MAX |
| 186 | }; | 187 | }; |
| 187 | 188 | ||
| 189 | enum dpu_cdm { | ||
| 190 | CDM_0 = 1, | ||
| 191 | CDM_MAX | ||
| 192 | }; | ||
| 193 | |||
| 188 | enum dpu_pingpong { | 194 | enum dpu_pingpong { |
| 189 | PINGPONG_NONE, | 195 | PINGPONG_NONE, |
| 190 | PINGPONG_0, | 196 | PINGPONG_0, |
| @@ -195,6 +201,8 @@ enum dpu_pingpong { · 4 unmodified lines | |||
| 195 | PINGPONG_5, | 201 | PINGPONG_5, |
| 196 | PINGPONG_6, | 202 | PINGPONG_6, |
| 197 | PINGPONG_7, | 203 | PINGPONG_7, |
| 204 | PINGPONG_8, | ||
| 205 | PINGPONG_9, | ||
| 198 | PINGPONG_S0, | 206 | PINGPONG_S0, |
| 199 | PINGPONG_MAX | 207 | PINGPONG_MAX |
| 200 | }; | 208 | }; |
| @@ -204,6 +212,7 @@ enum dpu_merge_3d { · 3 unmodified lines | |||
| 204 | MERGE_3D_1, | 212 | MERGE_3D_1, |
| 205 | MERGE_3D_2, | 213 | MERGE_3D_2, |
| 206 | MERGE_3D_3, | 214 | MERGE_3D_3, |
| 215 | MERGE_3D_4, | ||
| 207 | MERGE_3D_MAX | 216 | MERGE_3D_MAX |
| 208 | }; | 217 | }; |
| 209 | 218 | ||
| @@ -458,6 +467,7 @@ struct dpu_mdss_color { · 248 unmodified lines | |||
| 458 | #define DPU_DBG_MASK_ROT (1 << 9) | 467 | #define DPU_DBG_MASK_ROT (1 << 9) |
| 459 | #define DPU_DBG_MASK_DSPP (1 << 10) | 468 | #define DPU_DBG_MASK_DSPP (1 << 10) |
| 460 | #define DPU_DBG_MASK_DSC (1 << 11) | 469 | #define DPU_DBG_MASK_DSC (1 << 11) |
| 470 | #define DPU_DBG_MASK_CDM (1 << 12) | ||
| 461 | 471 | ||
| 462 | /** | 472 | /** |
| 463 | * struct dpu_hw_tear_check - Struct contains parameters to configure | 473 | * struct dpu_hw_tear_check - Struct contains parameters to configure |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <linux/iopoll.h> | 5 | #include <linux/iopoll.h> |
| 6 | 6 | ||
| 7 | #include <drm/drm_managed.h> | ||
| 8 | |||
| 7 | #include "dpu_hw_mdss.h" | 9 | #include "dpu_hw_mdss.h" |
| 8 | #include "dpu_hwio.h" | 10 | #include "dpu_hwio.h" |
| 9 | #include "dpu_hw_catalog.h" | 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 | c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode; | 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, | 42 | struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, |
| 41 | void __iomem *addr) | 43 | const struct dpu_merge_3d_cfg *cfg, |
| 44 | void __iomem *addr) | ||
| 42 | { | 45 | { |
| 43 | struct dpu_hw_merge_3d *c; | 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 | if (!c) | 49 | if (!c) |
| 47 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed | 49 | * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed |
| 50 | * merge3d catalog entry. | 50 | * merge3d catalog entry. |
| 51 | * @dev: Corresponding device for devres management | ||
| 51 | * @cfg: Pingpong catalog entry for which driver object is required | 52 | * @cfg: Pingpong catalog entry for which driver object is required |
| 52 | * @addr: Mapped register io address of MDP | 53 | * @addr: Mapped register io address of MDP |
| 53 | * Return: Error code or allocated dpu_hw_merge_3d context | 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 | struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev, |
| 56 | void __iomem *addr); | 57 | const struct dpu_merge_3d_cfg *cfg, |
| 57 | 58 | void __iomem *addr); | |
| 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); | ||
| 64 | 59 | ||
| 65 | #endif /*_DPU_HW_MERGE3D_H */ | 60 | #endif /*_DPU_HW_MERGE3D_H */ |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <linux/iopoll.h> | 5 | #include <linux/iopoll.h> |
| 6 | 6 | ||
| 7 | #include <drm/drm_managed.h> | ||
| 8 | |||
| 7 | #include "dpu_hw_mdss.h" | 9 | #include "dpu_hw_mdss.h" |
| 8 | #include "dpu_hwio.h" | 10 | #include "dpu_hwio.h" |
| 9 | #include "dpu_hw_catalog.h" | 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 | return 0; | 283 | return 0; |
| 282 | } | 284 | } |
| 283 | 285 | ||
| 284 | struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, | 286 | struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, |
| 285 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | 287 | const struct dpu_pingpong_cfg *cfg, |
| 288 | void __iomem *addr, | ||
| 289 | const struct dpu_mdss_version *mdss_rev) | ||
| 286 | { | 290 | { |
| 287 | struct dpu_hw_pingpong *c; | 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 | if (!c) | 294 | if (!c) |
| 291 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed | 122 | * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed |
| 123 | * pingpong catalog entry. | 123 | * pingpong catalog entry. |
| 124 | * @dev: Corresponding device for devres management | ||
| 124 | * @cfg: Pingpong catalog entry for which driver object is required | 125 | * @cfg: Pingpong catalog entry for which driver object is required |
| 125 | * @addr: Mapped register io address of MDP | 126 | * @addr: Mapped register io address of MDP |
| 126 | * @mdss_rev: dpu core's major and minor versions | 127 | * @mdss_rev: dpu core's major and minor versions |
| 127 | * Return: Error code or allocated dpu_hw_pingpong context | 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 | struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev, |
| 130 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | 131 | const struct dpu_pingpong_cfg *cfg, |
| 131 | 132 | void __iomem *addr, | |
| 132 | /** | 133 | const struct dpu_mdss_version *mdss_rev); |
| 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); | ||
| 138 | 134 | ||
| 139 | #endif /*_DPU_HW_PINGPONG_H */ | 135 | #endif /*_DPU_HW_PINGPONG_H */ |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include "msm_mdss.h" | 11 | #include "msm_mdss.h" |
| 12 | 12 | ||
| 13 | #include <drm/drm_file.h> | 13 | #include <drm/drm_file.h> |
| 14 | #include <drm/drm_managed.h> | ||
| 14 | 15 | ||
| 15 | #define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087 | 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 | format); | 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 | * dpu_hw_sspp_setup_rects() | 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 | test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features)) | 606 | test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features)) |
| 615 | c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; | 607 | c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; |
| 616 | 608 | ||
| 617 | if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) || | 609 | if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, &features)) |
| 618 | test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) || | ||
| 619 | test_bit(DPU_SSPP_SCALER_QSEED4, &features)) { | ||
| 620 | c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3; | 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 | if (test_bit(DPU_SSPP_CDP, &features)) | 612 | if (test_bit(DPU_SSPP_CDP, &features)) |
| 625 | c->ops.setup_cdp = dpu_hw_sspp_setup_cdp; | 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 | cfg->len, | 642 | cfg->len, |
| 655 | kms); | 643 | kms); |
| 656 | 644 | ||
| 657 | if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) || | 645 | if (sblk->scaler_blk.len) |
| 658 | cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) || | ||
| 659 | cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) || | ||
| 660 | cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) | ||
| 661 | dpu_debugfs_create_regset32("scaler_blk", 0400, | 646 | dpu_debugfs_create_regset32("scaler_blk", 0400, |
| 662 | debugfs_root, | 647 | debugfs_root, |
| 663 | sblk->scaler_blk.base + cfg->base, | 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 | #endif | 671 | #endif |
| 687 | 672 | ||
| 688 | struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, | 673 | struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, |
| 689 | void __iomem *addr, const struct msm_mdss_data *mdss_data, | 674 | const struct dpu_sspp_cfg *cfg, |
| 690 | const struct dpu_mdss_version *mdss_rev) | 675 | void __iomem *addr, |
| 676 | const struct msm_mdss_data *mdss_data, | ||
| 677 | const struct dpu_mdss_version *mdss_rev) | ||
| 691 | { | 678 | { |
| 692 | struct dpu_hw_sspp *hw_pipe; | 679 | struct dpu_hw_sspp *hw_pipe; |
| 693 | 680 | ||
| 694 | if (!addr) | 681 | if (!addr) |
| 695 | return ERR_PTR(-EINVAL); | 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 | if (!hw_pipe) | 685 | if (!hw_pipe) |
| 699 | return ERR_PTR(-ENOMEM); | 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 | return hw_pipe; | 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 | #define DPU_SSPP_ROT_90 BIT(3) | 21 | #define DPU_SSPP_ROT_90 BIT(3) |
| 22 | #define DPU_SSPP_SOLID_FILL BIT(4) | 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 | * Component indices | 25 | * Component indices |
| 41 | */ | 26 | */ |
| @@ -296,12 +281,6 @@ struct dpu_hw_sspp_ops { · 254 unmodified lines | |||
| 296 | struct dpu_hw_scaler3_cfg *scaler3_cfg, | 281 | struct dpu_hw_scaler3_cfg *scaler3_cfg, |
| 297 | const struct dpu_format *format); | 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 | * setup_cdp - setup client driven prefetch | 285 | * setup_cdp - setup client driven prefetch |
| 307 | * @pipe: Pointer to software pipe context | 286 | * @pipe: Pointer to software pipe context |
| @@ -339,21 +318,17 @@ struct dpu_kms; · 31 unmodified lines | |||
| 339 | /** | 318 | /** |
| 340 | * dpu_hw_sspp_init() - Initializes the sspp hw driver object. | 319 | * dpu_hw_sspp_init() - Initializes the sspp hw driver object. |
| 341 | * Should be called once before accessing every pipe. | 320 | * Should be called once before accessing every pipe. |
| 321 | * @dev: Corresponding device for devres management | ||
| 342 | * @cfg: Pipe catalog entry for which driver object is required | 322 | * @cfg: Pipe catalog entry for which driver object is required |
| 343 | * @addr: Mapped register io address of MDP | 323 | * @addr: Mapped register io address of MDP |
| 344 | * @mdss_data: UBWC / MDSS configuration data | 324 | * @mdss_data: UBWC / MDSS configuration data |
| 345 | * @mdss_rev: dpu core's major and minor versions | 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, | 327 | struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev, |
| 348 | void __iomem *addr, const struct msm_mdss_data *mdss_data, | 328 | const struct dpu_sspp_cfg *cfg, |
| 349 | const struct dpu_mdss_version *mdss_rev); | 329 | void __iomem *addr, |
| 350 | 330 | const struct msm_mdss_data *mdss_data, | |
| 351 | /** | 331 | const struct dpu_mdss_version *mdss_rev); |
| 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); | ||
| 357 | 332 | ||
| 358 | int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, | 333 | int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, |
| 359 | struct dentry *entry); | 334 | struct dentry *entry); |
| @@ -2,6 +2,8 @@ · 1 unmodified line | |||
| 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <drm/drm_managed.h> | ||
| 6 | |||
| 5 | #include "dpu_hwio.h" | 7 | #include "dpu_hwio.h" |
| 6 | #include "dpu_hw_catalog.h" | 8 | #include "dpu_hw_catalog.h" |
| 7 | #include "dpu_hw_top.h" | 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 | ops->intf_audio_select = dpu_hw_intf_audio_select; | 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, | 252 | struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, |
| 251 | void __iomem *addr, | 253 | const struct dpu_mdp_cfg *cfg, |
| 252 | const struct dpu_mdss_cfg *m) | 254 | void __iomem *addr, |
| 255 | const struct dpu_mdss_cfg *m) | ||
| 253 | { | 256 | { |
| 254 | struct dpu_hw_mdp *mdp; | 257 | struct dpu_hw_mdp *mdp; |
| 255 | 258 | ||
| 256 | if (!addr) | 259 | if (!addr) |
| 257 | return ERR_PTR(-EINVAL); | 260 | return ERR_PTR(-EINVAL); |
| 258 | 261 | ||
| 259 | mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); | 262 | mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL); |
| 260 | if (!mdp) | 263 | if (!mdp) |
| 261 | return ERR_PTR(-ENOMEM); | 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 | return mdp; | 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 | * dpu_hw_mdptop_init - initializes the top driver for the passed config | 147 | * dpu_hw_mdptop_init - initializes the top driver for the passed config |
| 148 | * @dev: Corresponding device for devres management | ||
| 148 | * @cfg: MDP TOP configuration from catalog | 149 | * @cfg: MDP TOP configuration from catalog |
| 149 | * @addr: Mapped register io address of MDP | 150 | * @addr: Mapped register io address of MDP |
| 150 | * @m: Pointer to mdss catalog data | 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 | struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev, |
| 153 | void __iomem *addr, | 154 | const struct dpu_mdp_cfg *cfg, |
| 154 | const struct dpu_mdss_cfg *m); | 155 | void __iomem *addr, |
| 156 | const struct dpu_mdss_cfg *m); | ||
| 155 | 157 | ||
| 156 | void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); | 158 | void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp); |
| 157 | 159 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. | 3 | * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. |
| 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 5 | */ | 5 | */ |
| 6 | #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ | 6 | #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ |
| @@ -381,12 +381,6 @@ end: · 374 unmodified lines | |||
| 381 | DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode); | 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 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, | 384 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, |
| 391 | u32 csc_reg_off, | 385 | u32 csc_reg_off, |
| 392 | const struct dpu_csc_cfg *data, bool csc10) | 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 | cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); | 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 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, | 481 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, |
| 485 | u32 misr_ctrl_offset, | 482 | u32 misr_ctrl_offset, u8 input_sel) |
| 486 | bool enable, u32 frame_count) | ||
| 487 | { | 483 | { |
| 488 | u32 config = 0; | 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 | /* Clear old MISR value (in case it's read before a new value is calculated)*/ | 488 | /* Clear old MISR value (in case it's read before a new value is calculated)*/ |
| 493 | wmb(); | 489 | wmb(); |
| 494 | 490 | ||
| 495 | if (enable) { | 491 | config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | |
| 496 | config = (frame_count & MISR_FRAME_COUNT_MASK) | | 492 | ((input_sel & 0xF) << 24); |
| 497 | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; | 493 | DPU_REG_WRITE(c, misr_ctrl_offset, config); |
| 498 | |||
| 499 | DPU_REG_WRITE(c, misr_ctrl_offset, config); | ||
| 500 | } else { | ||
| 501 | DPU_REG_WRITE(c, misr_ctrl_offset, 0); | ||
| 502 | } | ||
| 503 | |||
| 504 | } | 494 | } |
| 505 | 495 | ||
| 506 | int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, | 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 | return clk_forced_on; | 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 | /* SPDX-License-Identifier: GPL-2.0-only */ | 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 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| @@ -13,12 +13,18 @@ · 6 unmodified lines | |||
| 13 | #include "dpu_hw_catalog.h" | 13 | #include "dpu_hw_catalog.h" |
| 14 | 14 | ||
| 15 | #define REG_MASK(n) ((BIT(n)) - 1) | 15 | #define REG_MASK(n) ((BIT(n)) - 1) |
| 16 | #define MISR_FRAME_COUNT_MASK 0xFF | 16 | #define MISR_FRAME_COUNT 0x1 |
| 17 | #define MISR_CTRL_ENABLE BIT(8) | 17 | #define MISR_CTRL_ENABLE BIT(8) |
| 18 | #define MISR_CTRL_STATUS BIT(9) | 18 | #define MISR_CTRL_STATUS BIT(9) |
| 19 | #define MISR_CTRL_STATUS_CLEAR BIT(10) | 19 | #define MISR_CTRL_STATUS_CLEAR BIT(10) |
| 20 | #define MISR_CTRL_FREE_RUN_MASK BIT(31) | 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 | * This is the common struct maintained by each sub block | 29 | * This is the common struct maintained by each sub block |
| 24 | * for mapping the register offsets in this block to the | 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 | u32 scaler_offset, u32 scaler_version, | 346 | u32 scaler_offset, u32 scaler_version, |
| 341 | const struct dpu_format *format); | 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 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, | 349 | void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, |
| 347 | u32 csc_reg_off, | 350 | u32 csc_reg_off, |
| 348 | const struct dpu_csc_cfg *data, bool csc10); | 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 | const struct dpu_hw_qos_cfg *cfg); | 361 | const struct dpu_hw_qos_cfg *cfg); |
| 359 | 362 | ||
| 360 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, | 363 | void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, |
| 361 | u32 misr_ctrl_offset, | 364 | u32 misr_ctrl_offset, u8 input_sel); |
| 362 | bool enable, | ||
| 363 | u32 frame_count); | ||
| 364 | 365 | ||
| 365 | int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, | 366 | int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, |
| 366 | u32 misr_ctrl_offset, | 367 | u32 misr_ctrl_offset, |
| @@ -2,6 +2,8 @@ · 1 unmodified line | |||
| 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. | 2 | /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <drm/drm_managed.h> | ||
| 6 | |||
| 5 | #include "dpu_hwio.h" | 7 | #include "dpu_hwio.h" |
| 6 | #include "dpu_hw_catalog.h" | 8 | #include "dpu_hw_catalog.h" |
| 7 | #include "dpu_hw_vbif.h" | 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 | ops->set_write_gather_en = dpu_hw_set_write_gather_en; | 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, | 216 | struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, |
| 215 | void __iomem *addr) | 217 | const struct dpu_vbif_cfg *cfg, |
| 218 | void __iomem *addr) | ||
| 216 | { | 219 | { |
| 217 | struct dpu_hw_vbif *c; | 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 | if (!c) | 223 | if (!c) |
| 221 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed | 109 | * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed |
| 110 | * VBIF catalog entry. | 110 | * VBIF catalog entry. |
| 111 | * @dev: Corresponding device for devres management | ||
| 111 | * @cfg: VBIF catalog entry for which driver object is required | 112 | * @cfg: VBIF catalog entry for which driver object is required |
| 112 | * @addr: Mapped register io address of MDSS | 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 | struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev, |
| 115 | void __iomem *addr); | 116 | const struct dpu_vbif_cfg *cfg, |
| 116 | 117 | void __iomem *addr); | |
| 117 | void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif); | ||
| 118 | 118 | ||
| 119 | #endif /*_DPU_HW_VBIF_H */ | 119 | #endif /*_DPU_HW_VBIF_H */ |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | |||
| 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved | 3 | * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <drm/drm_managed.h> | ||
| 7 | |||
| 6 | #include "dpu_hw_mdss.h" | 8 | #include "dpu_hw_mdss.h" |
| 7 | #include "dpu_hwio.h" | 9 | #include "dpu_hwio.h" |
| 8 | #include "dpu_hw_catalog.h" | 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 | dst_format |= BIT(14); /* DST_ALPHA_X */ | 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 | pattern = (fmt->element[3] << 24) | | 95 | pattern = (fmt->element[3] << 24) | |
| 91 | (fmt->element[2] << 16) | | 96 | (fmt->element[2] << 16) | |
| 92 | (fmt->element[1] << 8) | | 97 | (fmt->element[1] << 8) | |
| @@ -208,15 +213,17 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, · 115 unmodified lines | |||
| 208 | ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl; | 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, | 216 | struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, |
| 212 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev) | 217 | const struct dpu_wb_cfg *cfg, |
| 218 | void __iomem *addr, | ||
| 219 | const struct dpu_mdss_version *mdss_rev) | ||
| 213 | { | 220 | { |
| 214 | struct dpu_hw_wb *c; | 221 | struct dpu_hw_wb *c; |
| 215 | 222 | ||
| 216 | if (!addr) | 223 | if (!addr) |
| 217 | return ERR_PTR(-EINVAL); | 224 | return ERR_PTR(-EINVAL); |
| 218 | 225 | ||
| 219 | c = kzalloc(sizeof(*c), GFP_KERNEL); | 226 | c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL); |
| 220 | if (!c) | 227 | if (!c) |
| 221 | return ERR_PTR(-ENOMEM); | 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 | return c; | 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 | * dpu_hw_wb_init() - Initializes the writeback hw driver object. | 78 | * dpu_hw_wb_init() - Initializes the writeback hw driver object. |
| 79 | * @dev: Corresponding device for devres management | ||
| 79 | * @cfg: wb_path catalog entry for which driver object is required | 80 | * @cfg: wb_path catalog entry for which driver object is required |
| 80 | * @addr: mapped register io address of MDP | 81 | * @addr: mapped register io address of MDP |
| 81 | * @mdss_rev: dpu core's major and minor versions | 82 | * @mdss_rev: dpu core's major and minor versions |
| 82 | * Return: Error code or allocated dpu_hw_wb context | 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 | struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev, |
| 85 | void __iomem *addr, const struct dpu_mdss_version *mdss_rev); | 86 | const struct dpu_wb_cfg *cfg, |
| 86 | 87 | void __iomem *addr, | |
| 87 | /** | 88 | const struct dpu_mdss_version *mdss_rev); |
| 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); | ||
| 92 | 89 | ||
| 93 | #endif /*_DPU_HW_WB_H */ | 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 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); | 274 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); |
| 275 | void *p = dpu_hw_util_get_log_mask_ptr(); | 275 | void *p = dpu_hw_util_get_log_mask_ptr(); |
| 276 | struct dentry *entry; | 276 | struct dentry *entry; |
| 277 | struct drm_device *dev; | ||
| 278 | struct msm_drm_private *priv; | ||
| 279 | int i; | ||
| 280 | 277 | ||
| 281 | if (!p) | 278 | if (!p) |
| 282 | return -EINVAL; | 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 | if (minor->type != DRM_MINOR_PRIMARY) | 282 | if (minor->type != DRM_MINOR_PRIMARY) |
| 286 | return 0; | 283 | return 0; |
| 287 | 284 | ||
| 288 | dev = dpu_kms->dev; | ||
| 289 | priv = dev->dev_private; | ||
| 290 | |||
| 291 | entry = debugfs_create_dir("debug", minor->debugfs_root); | 285 | entry = debugfs_create_dir("debug", minor->debugfs_root); |
| 292 | 286 | ||
| 293 | debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, entry, p); | 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 | dpu_debugfs_core_irq_init(dpu_kms, entry); | 291 | dpu_debugfs_core_irq_init(dpu_kms, entry); |
| 298 | dpu_debugfs_sspp_init(dpu_kms, entry); | 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 | return dpu_core_perf_debugfs_init(dpu_kms, entry); | 294 | return dpu_core_perf_debugfs_init(dpu_kms, entry); |
| 306 | } | 295 | } |
| 307 | #endif | 296 | #endif |
| @@ -597,7 +586,6 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, · 289 unmodified lines | |||
| 597 | rc = msm_dp_modeset_init(priv->dp[i], dev, encoder); | 586 | rc = msm_dp_modeset_init(priv->dp[i], dev, encoder); |
| 598 | if (rc) { | 587 | if (rc) { |
| 599 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); | 588 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); |
| 600 | drm_encoder_cleanup(encoder); | ||
| 601 | return rc; | 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 | rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); | 618 | rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); |
| 631 | if (rc) { | 619 | if (rc) { |
| 632 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); | 620 | DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc); |
| 633 | drm_encoder_cleanup(encoder); | ||
| 634 | return rc; | 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 | n_formats); | 649 | n_formats); |
| 663 | if (rc) { | 650 | if (rc) { |
| 664 | DPU_ERROR("dpu_writeback_init, rc = %d\n", rc); | 651 | DPU_ERROR("dpu_writeback_init, rc = %d\n", rc); |
| 665 | drm_encoder_cleanup(encoder); | ||
| 666 | return rc; | 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 | int i; | 793 | int i; |
| 808 | 794 | ||
| 809 | if (dpu_kms->hw_intr) | ||
| 810 | dpu_hw_intr_destroy(dpu_kms->hw_intr); | ||
| 811 | dpu_kms->hw_intr = NULL; | 795 | dpu_kms->hw_intr = NULL; |
| 812 | 796 | ||
| 813 | /* safe to call these more than once during shutdown */ | 797 | /* safe to call these more than once during shutdown */ |
| 814 | _dpu_kms_mmu_destroy(dpu_kms); | 798 | _dpu_kms_mmu_destroy(dpu_kms); |
| 815 | 799 | ||
| 816 | if (dpu_kms->catalog) { | 800 | for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { |
| 817 | for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { | 801 | dpu_kms->hw_vbif[i] = NULL; |
| 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 | } | ||
| 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 | dpu_kms->catalog = NULL; | 804 | dpu_kms->catalog = NULL; |
| 830 | 805 | ||
| 831 | if (dpu_kms->hw_mdp) | ||
| 832 | dpu_hw_mdp_destroy(dpu_kms->hw_mdp); | ||
| 833 | dpu_kms->hw_mdp = NULL; | 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 | struct msm_drm_private *priv; | 830 | struct msm_drm_private *priv; |
| 858 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); | 831 | struct dpu_kms *dpu_kms = to_dpu_kms(kms); |
| 859 | int i; | ||
| 860 | 832 | ||
| 861 | if (!dpu_kms || !dpu_kms->dev) | 833 | if (!dpu_kms || !dpu_kms->dev) |
| 862 | return -EINVAL; | 834 | return -EINVAL; |
| @@ -865,9 +837,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) · 2 unmodified lines | |||
| 865 | if (!priv) | 837 | if (!priv) |
| 866 | return -EINVAL; | 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 | return 0; | 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 | pm_runtime_put_sync(&dpu_kms->pdev->dev); | 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 | if (!dpu_kms->catalog) { | 1051 | if (!dpu_kms->catalog) { |
| 1079 | DPU_ERROR("device config not known!\n"); | 1052 | DPU_ERROR("device config not known!\n"); |
| 1080 | rc = -EINVAL; | 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 | rc = _dpu_kms_mmu_init(dpu_kms); | 1061 | rc = _dpu_kms_mmu_init(dpu_kms); |
| 1089 | if (rc) { | 1062 | if (rc) { |
| 1090 | DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc); | 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 | dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent); | 1067 | dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent); |
| 1095 | if (IS_ERR(dpu_kms->mdss)) { | 1068 | if (IS_ERR(dpu_kms->mdss)) { |
| 1096 | rc = PTR_ERR(dpu_kms->mdss); | 1069 | rc = PTR_ERR(dpu_kms->mdss); |
| 1097 | DPU_ERROR("failed to get MDSS data: %d\n", rc); | 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 | if (!dpu_kms->mdss) { | 1074 | if (!dpu_kms->mdss) { |
| 1102 | rc = -EINVAL; | 1075 | rc = -EINVAL; |
| 1103 | DPU_ERROR("NULL MDSS data\n"); | 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 | if (rc) { | 1081 | if (rc) { |
| 1109 | DPU_ERROR("rm init failed: %d\n", rc); | 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; | 1086 | dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev, |
| 1114 | 1087 | dpu_kms->catalog->mdp, | |
| 1115 | dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp, | ||
| 1116 | dpu_kms->mmio, | 1088 | dpu_kms->mmio, |
| 1117 | dpu_kms->catalog); | 1089 | dpu_kms->catalog); |
| 1118 | if (IS_ERR(dpu_kms->hw_mdp)) { | 1090 | if (IS_ERR(dpu_kms->hw_mdp)) { |
| 1119 | rc = PTR_ERR(dpu_kms->hw_mdp); | 1091 | rc = PTR_ERR(dpu_kms->hw_mdp); |
| 1120 | DPU_ERROR("failed to get hw_mdp: %d\n", rc); | 1092 | DPU_ERROR("failed to get hw_mdp: %d\n", rc); |
| 1121 | dpu_kms->hw_mdp = NULL; | 1093 | dpu_kms->hw_mdp = NULL; |
| 1122 | goto power_error; | 1094 | goto err_pm_put; |
| 1123 | } | 1095 | } |
| 1124 | 1096 | ||
| 1125 | for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { | 1097 | for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { |
| 1126 | struct dpu_hw_vbif *hw; | 1098 | struct dpu_hw_vbif *hw; |
| 1127 | const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i]; | 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 | if (IS_ERR(hw)) { | 1102 | if (IS_ERR(hw)) { |
| 1131 | rc = PTR_ERR(hw); | 1103 | rc = PTR_ERR(hw); |
| 1132 | DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc); | 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 | dpu_kms->hw_vbif[vbif->id] = hw; | 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 | rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); | 1118 | rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate); |
| 1147 | if (rc) { | 1119 | if (rc) { |
| 1148 | DPU_ERROR("failed to init perf %d\n", rc); | 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); | 1124 | dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog); |
| 1153 | if (IS_ERR_OR_NULL(dpu_kms->hw_intr)) { | 1125 | if (IS_ERR(dpu_kms->hw_intr)) { |
| 1154 | rc = PTR_ERR(dpu_kms->hw_intr); | 1126 | rc = PTR_ERR(dpu_kms->hw_intr); |
| 1155 | DPU_ERROR("hw_intr init failed: %d\n", rc); | 1127 | DPU_ERROR("hw_intr init failed: %d\n", rc); |
| 1156 | dpu_kms->hw_intr = NULL; | 1128 | dpu_kms->hw_intr = NULL; |
| 1157 | goto hw_intr_init_err; | 1129 | goto err_pm_put; |
| 1158 | } | 1130 | } |
| 1159 | 1131 | ||
| 1160 | dev->mode_config.min_width = 0; | 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 | rc = _dpu_kms_drm_obj_init(dpu_kms); | 1151 | rc = _dpu_kms_drm_obj_init(dpu_kms); |
| 1180 | if (rc) { | 1152 | if (rc) { |
| 1181 | DPU_ERROR("modeset init failed: %d\n", rc); | 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 | dpu_vbif_init_memtypes(dpu_kms); | 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 | return 0; | 1161 | return 0; |
| 1190 | 1162 | ||
| 1191 | drm_obj_init_err: | 1163 | err_pm_put: |
| 1192 | hw_intr_init_err: | ||
| 1193 | perf_err: | ||
| 1194 | power_error: | ||
| 1195 | pm_runtime_put_sync(&dpu_kms->pdev->dev); | 1164 | pm_runtime_put_sync(&dpu_kms->pdev->dev); |
| 1196 | error: | 1165 | error: |
| 1197 | _dpu_kms_hw_destroy(dpu_kms); | 1166 | _dpu_kms_hw_destroy(dpu_kms); |
| @@ -1349,6 +1318,7 @@ static const struct dev_pm_ops dpu_pm_ops = { · 151 unmodified lines | |||
| 1349 | static const struct of_device_id dpu_dt_match[] = { | 1318 | static const struct of_device_id dpu_dt_match[] = { |
| 1350 | { .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, }, | 1319 | { .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, }, |
| 1351 | { .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, }, | 1320 | { .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, }, |
| 1321 | { .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, }, | ||
| 1352 | { .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, }, | 1322 | { .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, }, |
| 1353 | { .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, }, | 1323 | { .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, }, |
| 1354 | { .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, }, | 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 | { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, }, | 1333 | { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, }, |
| 1364 | { .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, }, | 1334 | { .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, }, |
| 1365 | { .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, }, | 1335 | { .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, }, |
| 1336 | { .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, }, | ||
| 1366 | {} | 1337 | {} |
| 1367 | }; | 1338 | }; |
| 1368 | MODULE_DEVICE_TABLE(of, dpu_dt_match); | 1339 | MODULE_DEVICE_TABLE(of, dpu_dt_match); |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | |||
| 51 | } while (0) | 51 | } while (0) |
| 52 | 52 | ||
| 53 | #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) | 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 | * ktime_compare_safe - compare two ktime structures | 57 | * ktime_compare_safe - compare two ktime structures |
| @@ -88,7 +89,6 @@ struct dpu_kms { · 31 unmodified lines | |||
| 88 | struct drm_private_obj global_state; | 89 | struct drm_private_obj global_state; |
| 89 | 90 | ||
| 90 | struct dpu_rm rm; | 91 | struct dpu_rm rm; |
| 91 | bool rm_init; | ||
| 92 | 92 | ||
| 93 | struct dpu_hw_vbif *hw_vbif[VBIF_MAX]; | 93 | struct dpu_hw_vbif *hw_vbif[VBIF_MAX]; |
| 94 | struct dpu_hw_mdp *hw_mdp; | 94 | struct dpu_hw_mdp *hw_mdp; |
| @@ -136,6 +136,7 @@ struct dpu_global_state { · 41 unmodified lines | |||
| 136 | uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; | 136 | uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; |
| 137 | uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; | 137 | uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; |
| 138 | uint32_t dsc_to_enc_id[DSC_MAX - DSC_0]; | 138 | uint32_t dsc_to_enc_id[DSC_MAX - DSC_0]; |
| 139 | uint32_t cdm_to_enc_id; | ||
| 139 | }; | 140 | }; |
| 140 | 141 | ||
| 141 | struct dpu_global_state | 142 | struct dpu_global_state |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include "dpu_kms.h" | 21 | #include "dpu_kms.h" |
| 22 | #include "dpu_formats.h" | 22 | #include "dpu_formats.h" |
| 23 | #include "dpu_hw_sspp.h" | 23 | #include "dpu_hw_sspp.h" |
| 24 | #include "dpu_hw_util.h" | ||
| 24 | #include "dpu_trace.h" | 25 | #include "dpu_trace.h" |
| 25 | #include "dpu_crtc.h" | 26 | #include "dpu_crtc.h" |
| 26 | #include "dpu_vbif.h" | 27 | #include "dpu_vbif.h" |
| @@ -78,8 +79,6 @@ static const uint32_t qcom_compressed_supported_formats[] = { · 51 unmodified lines | |||
| 78 | struct dpu_plane { | 79 | struct dpu_plane { |
| 79 | struct drm_plane base; | 80 | struct drm_plane base; |
| 80 | 81 | ||
| 81 | struct mutex lock; | ||
| 82 | |||
| 83 | enum dpu_sspp pipe; | 82 | enum dpu_sspp pipe; |
| 84 | 83 | ||
| 85 | uint32_t color_fill; | 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 | scale_cfg->src_height[i] /= chroma_subsmpl_v; | 469 | scale_cfg->src_height[i] /= chroma_subsmpl_v; |
| 471 | } | 470 | } |
| 472 | 471 | ||
| 473 | if (pipe_hw->cap->features & | 472 | if (pipe_hw->cap->sblk->scaler_blk.version >= 0x3000) { |
| 474 | BIT(DPU_SSPP_SCALER_QSEED4)) { | ||
| 475 | scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H; | 473 | scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H; |
| 476 | scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V; | 474 | scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V; |
| 477 | } else { | 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 | static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, | 512 | static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe, |
| 545 | const struct dpu_format *fmt) | 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 | min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; | 742 | min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; |
| 775 | 743 | ||
| 776 | if (DPU_FORMAT_IS_YUV(fmt) && | 744 | if (DPU_FORMAT_IS_YUV(fmt) && |
| 777 | (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) || | 745 | (!pipe->sspp->cap->sblk->scaler_blk.len || |
| 778 | !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) { | 746 | !pipe->sspp->cap->sblk->csc_blk.len)) { |
| 779 | DPU_DEBUG_PLANE(pdpu, | 747 | DPU_DEBUG_PLANE(pdpu, |
| 780 | "plane doesn't have scaler/csc for yuv\n"); | 748 | "plane doesn't have scaler/csc for yuv\n"); |
| 781 | return -EINVAL; | 749 | return -EINVAL; |
| @@ -824,6 +792,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, · 42 unmodified lines | |||
| 824 | plane); | 792 | plane); |
| 825 | int ret = 0, min_scale; | 793 | int ret = 0, min_scale; |
| 826 | struct dpu_plane *pdpu = to_dpu_plane(plane); | 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 | struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); | 797 | struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state); |
| 828 | struct dpu_sw_pipe *pipe = &pstate->pipe; | 798 | struct dpu_sw_pipe *pipe = &pstate->pipe; |
| 829 | struct dpu_sw_pipe *r_pipe = &pstate->r_pipe; | 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 | max_linewidth = pdpu->catalog->caps->max_linewidth; | 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 | * In parallel multirect case only the half of the usual width | 868 | * In parallel multirect case only the half of the usual width |
| 898 | * is supported for tiled formats. If we are here, we know that | 869 | * is supported for tiled formats. If we are here, we know that |
| 899 | * full width is more than max_linewidth, thus each rect is | 870 | * full width is more than max_linewidth, thus each rect is |
| 900 | * wider than allowed. | 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 | DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n", | 875 | DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n", |
| 904 | DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); | 876 | DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth); |
| 905 | return -E2BIG; | 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 | static void dpu_plane_destroy_state(struct drm_plane *plane, | 1188 | static void dpu_plane_destroy_state(struct drm_plane *plane, |
| 1240 | struct drm_plane_state *state) | 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 | static const struct drm_plane_funcs dpu_plane_funcs = { | 1354 | static const struct drm_plane_funcs dpu_plane_funcs = { |
| 1406 | .update_plane = drm_atomic_helper_update_plane, | 1355 | .update_plane = drm_atomic_helper_update_plane, |
| 1407 | .disable_plane = drm_atomic_helper_disable_plane, | 1356 | .disable_plane = drm_atomic_helper_disable_plane, |
| 1408 | .destroy = dpu_plane_destroy, | ||
| 1409 | .reset = dpu_plane_reset, | 1357 | .reset = dpu_plane_reset, |
| 1410 | .atomic_duplicate_state = dpu_plane_duplicate_state, | 1358 | .atomic_duplicate_state = dpu_plane_duplicate_state, |
| 1411 | .atomic_destroy_state = dpu_plane_destroy_state, | 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 | struct dpu_hw_sspp *pipe_hw; | 1381 | struct dpu_hw_sspp *pipe_hw; |
| 1434 | uint32_t num_formats; | 1382 | uint32_t num_formats; |
| 1435 | uint32_t supported_rotations; | 1383 | uint32_t supported_rotations; |
| 1436 | int ret = -EINVAL; | 1384 | int ret; |
| 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; | ||
| 1449 | 1385 | ||
| 1450 | /* initialize underlying h/w driver */ | 1386 | /* initialize underlying h/w driver */ |
| 1451 | pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe); | 1387 | pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe); |
| 1452 | if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { | 1388 | if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) { |
| 1453 | DPU_ERROR("[%u]SSPP is invalid\n", pipe); | 1389 | DPU_ERROR("[%u]SSPP is invalid\n", pipe); |
| 1454 | goto clean_plane; | 1390 | return ERR_PTR(-EINVAL); |
| 1455 | } | 1391 | } |
| 1456 | 1392 | ||
| 1457 | format_list = pipe_hw->cap->sblk->format_list; | 1393 | format_list = pipe_hw->cap->sblk->format_list; |
| 1458 | num_formats = pipe_hw->cap->sblk->num_formats; | 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 | format_list, num_formats, | 1398 | format_list, num_formats, |
| 1462 | supported_format_modifiers, type, NULL); | 1399 | supported_format_modifiers, type, NULL); |
| 1463 | if (ret) | 1400 | if (IS_ERR(pdpu)) |
| 1464 | goto clean_plane; | 1401 | return ERR_CAST(pdpu); |
| 1402 | |||
| 1403 | /* cache local stuff for later */ | ||
| 1404 | plane = &pdpu->base; | ||
| 1405 | pdpu->pipe = pipe; | ||
| 1465 | 1406 | ||
| 1466 | pdpu->catalog = kms->catalog; | 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 | /* success! finalize initialization */ | 1429 | /* success! finalize initialization */ |
| 1489 | drm_plane_helper_add(plane, &dpu_plane_helper_funcs); | 1430 | drm_plane_helper_add(plane, &dpu_plane_helper_funcs); |
| 1490 | 1431 | ||
| 1491 | mutex_init(&pdpu->lock); | ||
| 1492 | |||
| 1493 | DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, | 1432 | DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name, |
| 1494 | pipe, plane->base.id); | 1433 | pipe, plane->base.id); |
| 1495 | return plane; | 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 | #include "dpu_kms.h" | 8 | #include "dpu_kms.h" |
| 9 | #include "dpu_hw_lm.h" | 9 | #include "dpu_hw_lm.h" |
| 10 | #include "dpu_hw_ctl.h" | 10 | #include "dpu_hw_ctl.h" |
| 11 | #include "dpu_hw_cdm.h" | ||
| 11 | #include "dpu_hw_pingpong.h" | 12 | #include "dpu_hw_pingpong.h" |
| 12 | #include "dpu_hw_sspp.h" | 13 | #include "dpu_hw_sspp.h" |
| 13 | #include "dpu_hw_intf.h" | 14 | #include "dpu_hw_intf.h" |
| @@ -34,72 +35,8 @@ struct dpu_rm_requirements { · 20 unmodified lines | |||
| 34 | struct msm_display_topology topology; | 35 | struct msm_display_topology topology; |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | int dpu_rm_destroy(struct dpu_rm *rm) | 38 | int dpu_rm_init(struct drm_device *dev, |
| 38 | { | 39 | struct dpu_rm *rm, |
| 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, | ||
| 103 | const struct dpu_mdss_cfg *cat, | 40 | const struct dpu_mdss_cfg *cat, |
| 104 | const struct msm_mdss_data *mdss_data, | 41 | const struct msm_mdss_data *mdss_data, |
| 105 | void __iomem *mmio) | 42 | void __iomem *mmio) |
| @@ -119,7 +56,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 13 unmodified lines | |||
| 119 | struct dpu_hw_mixer *hw; | 56 | struct dpu_hw_mixer *hw; |
| 120 | const struct dpu_lm_cfg *lm = &cat->mixer[i]; | 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 | if (IS_ERR(hw)) { | 60 | if (IS_ERR(hw)) { |
| 124 | rc = PTR_ERR(hw); | 61 | rc = PTR_ERR(hw); |
| 125 | DPU_ERROR("failed lm object creation: err %d\n", rc); | 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 | struct dpu_hw_merge_3d *hw; | 69 | struct dpu_hw_merge_3d *hw; |
| 133 | const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i]; | 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 | if (IS_ERR(hw)) { | 73 | if (IS_ERR(hw)) { |
| 137 | rc = PTR_ERR(hw); | 74 | rc = PTR_ERR(hw); |
| 138 | DPU_ERROR("failed merge_3d object creation: err %d\n", | 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 | struct dpu_hw_pingpong *hw; | 83 | struct dpu_hw_pingpong *hw; |
| 147 | const struct dpu_pingpong_cfg *pp = &cat->pingpong[i]; | 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 | if (IS_ERR(hw)) { | 87 | if (IS_ERR(hw)) { |
| 151 | rc = PTR_ERR(hw); | 88 | rc = PTR_ERR(hw); |
| 152 | DPU_ERROR("failed pingpong object creation: err %d\n", | 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 | struct dpu_hw_intf *hw; | 99 | struct dpu_hw_intf *hw; |
| 163 | const struct dpu_intf_cfg *intf = &cat->intf[i]; | 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 | if (IS_ERR(hw)) { | 103 | if (IS_ERR(hw)) { |
| 167 | rc = PTR_ERR(hw); | 104 | rc = PTR_ERR(hw); |
| 168 | DPU_ERROR("failed intf object creation: err %d\n", rc); | 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 | struct dpu_hw_wb *hw; | 112 | struct dpu_hw_wb *hw; |
| 176 | const struct dpu_wb_cfg *wb = &cat->wb[i]; | 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 | if (IS_ERR(hw)) { | 116 | if (IS_ERR(hw)) { |
| 180 | rc = PTR_ERR(hw); | 117 | rc = PTR_ERR(hw); |
| 181 | DPU_ERROR("failed wb object creation: err %d\n", rc); | 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 | struct dpu_hw_ctl *hw; | 125 | struct dpu_hw_ctl *hw; |
| 189 | const struct dpu_ctl_cfg *ctl = &cat->ctl[i]; | 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 | if (IS_ERR(hw)) { | 129 | if (IS_ERR(hw)) { |
| 193 | rc = PTR_ERR(hw); | 130 | rc = PTR_ERR(hw); |
| 194 | DPU_ERROR("failed ctl object creation: err %d\n", rc); | 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 | struct dpu_hw_dspp *hw; | 138 | struct dpu_hw_dspp *hw; |
| 202 | const struct dpu_dspp_cfg *dspp = &cat->dspp[i]; | 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 | if (IS_ERR(hw)) { | 142 | if (IS_ERR(hw)) { |
| 206 | rc = PTR_ERR(hw); | 143 | rc = PTR_ERR(hw); |
| 207 | DPU_ERROR("failed dspp object creation: err %d\n", rc); | 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 | const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; | 152 | const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; |
| 216 | 153 | ||
| 217 | if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features)) | 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 | else | 156 | else |
| 220 | hw = dpu_hw_dsc_init(dsc, mmio); | 157 | hw = dpu_hw_dsc_init(dev, dsc, mmio); |
| 221 | 158 | ||
| 222 | if (IS_ERR(hw)) { | 159 | if (IS_ERR(hw)) { |
| 223 | rc = PTR_ERR(hw); | 160 | rc = PTR_ERR(hw); |
| @@ -231,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 7 unmodified lines | |||
| 231 | struct dpu_hw_sspp *hw; | 168 | struct dpu_hw_sspp *hw; |
| 232 | const struct dpu_sspp_cfg *sspp = &cat->sspp[i]; | 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 | if (IS_ERR(hw)) { | 172 | if (IS_ERR(hw)) { |
| 236 | rc = PTR_ERR(hw); | 173 | rc = PTR_ERR(hw); |
| 237 | DPU_ERROR("failed sspp object creation: err %d\n", rc); | 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 | rm->hw_sspp[sspp->id - SSPP_NONE] = hw; | 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 | return 0; | 192 | return 0; |
| 244 | 193 | ||
| 245 | fail: | 194 | fail: |
| 246 | dpu_rm_destroy(rm); | ||
| 247 | |||
| 248 | return rc ? rc : -EFAULT; | 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 | return 0; | 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 | static int _dpu_rm_make_reservation( | 458 | static int _dpu_rm_make_reservation( |
| 492 | struct dpu_rm *rm, | 459 | struct dpu_rm *rm, |
| 493 | struct dpu_global_state *global_state, | 460 | struct dpu_global_state *global_state, |
| @@ -513,6 +480,14 @@ static int _dpu_rm_make_reservation( · 19 unmodified lines | |||
| 513 | if (ret) | 480 | if (ret) |
| 514 | return ret; | 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 | return ret; | 491 | return ret; |
| 517 | } | 492 | } |
| 518 | 493 | ||
| @@ -523,9 +498,9 @@ static int _dpu_rm_populate_requirements( · 4 unmodified lines | |||
| 523 | { | 498 | { |
| 524 | reqs->topology = req_topology; | 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 | reqs->topology.num_lm, reqs->topology.num_dsc, | 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 | return 0; | 505 | return 0; |
| 531 | } | 506 | } |
| @@ -554,6 +529,7 @@ void dpu_rm_release(struct dpu_global_state *global_state, · 22 unmodified lines | |||
| 554 | ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id); | 529 | ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id); |
| 555 | _dpu_rm_clear_mapping(global_state->dspp_to_enc_id, | 530 | _dpu_rm_clear_mapping(global_state->dspp_to_enc_id, |
| 556 | ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id); | 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 | int dpu_rm_reserve( | 535 | int dpu_rm_reserve( |
| @@ -627,6 +603,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, · 67 unmodified lines | |||
| 627 | hw_to_enc_id = global_state->dsc_to_enc_id; | 603 | hw_to_enc_id = global_state->dsc_to_enc_id; |
| 628 | max_blks = ARRAY_SIZE(rm->dsc_blks); | 604 | max_blks = ARRAY_SIZE(rm->dsc_blks); |
| 629 | break; | 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 | default: | 611 | default: |
| 631 | DPU_ERROR("blk type %d not managed by rm\n", type); | 612 | DPU_ERROR("blk type %d not managed by rm\n", type); |
| 632 | return 0; | 613 | return 0; |
| @@ -22,6 +22,7 @@ struct dpu_global_state; · 21 unmodified lines | |||
| 22 | * @hw_wb: array of wb hardware resources | 22 | * @hw_wb: array of wb hardware resources |
| 23 | * @dspp_blks: array of dspp hardware resources | 23 | * @dspp_blks: array of dspp hardware resources |
| 24 | * @hw_sspp: array of sspp hardware resources | 24 | * @hw_sspp: array of sspp hardware resources |
| 25 | * @cdm_blk: cdm hardware resource | ||
| 25 | */ | 26 | */ |
| 26 | struct dpu_rm { | 27 | struct dpu_rm { |
| 27 | struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; | 28 | struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0]; |
| @@ -33,29 +34,25 @@ struct dpu_rm { · 5 unmodified lines | |||
| 33 | struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; | 34 | struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; |
| 34 | struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; | 35 | struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; |
| 35 | struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE]; | 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 | * dpu_rm_init - Read hardware catalog and create reservation tracking objects | 41 | * dpu_rm_init - Read hardware catalog and create reservation tracking objects |
| 40 | * for all HW blocks. | 42 | * for all HW blocks. |
| 43 | * @dev: Corresponding device for devres management | ||
| 41 | * @rm: DPU Resource Manager handle | 44 | * @rm: DPU Resource Manager handle |
| 42 | * @cat: Pointer to hardware catalog | 45 | * @cat: Pointer to hardware catalog |
| 43 | * @mdss_data: Pointer to MDSS / UBWC configuration | 46 | * @mdss_data: Pointer to MDSS / UBWC configuration |
| 44 | * @mmio: mapped register io address of MDP | 47 | * @mmio: mapped register io address of MDP |
| 45 | * @Return: 0 on Success otherwise -ERROR | 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 | const struct dpu_mdss_cfg *cat, | 52 | const struct dpu_mdss_cfg *cat, |
| 49 | const struct msm_mdss_data *mdss_data, | 53 | const struct msm_mdss_data *mdss_data, |
| 50 | void __iomem *mmio); | 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 | * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze | 57 | * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze |
| 61 | * the use connections and user requirements, specified through related | 58 | * the use connections and user requirements, specified through related |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <drm/drm_crtc.h> | 7 | #include <drm/drm_crtc.h> |
| 8 | #include <drm/drm_flip_work.h> | 8 | #include <drm/drm_flip_work.h> |
| 9 | #include <drm/drm_managed.h> | ||
| 9 | #include <drm/drm_mode.h> | 10 | #include <drm/drm_mode.h> |
| 10 | #include <drm/drm_probe_helper.h> | 11 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | 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 | drm_gem_object_put(val); | 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 | /* statically (for now) map planes to mixer stage (z-order): */ | 127 | /* statically (for now) map planes to mixer stage (z-order): */ |
| 137 | static const int idxs[] = { | 128 | static const int idxs[] = { |
| 138 | [VG1] = 1, | 129 | [VG1] = 1, |
| @@ -269,6 +260,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, · 130 unmodified lines | |||
| 269 | { | 260 | { |
| 270 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 261 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 271 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | 262 | struct mdp4_kms *mdp4_kms = get_kms(crtc); |
| 263 | unsigned long flags; | ||
| 272 | 264 | ||
| 273 | DBG("%s", mdp4_crtc->name); | 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 | mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); | 273 | mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); |
| 282 | mdp4_disable(mdp4_kms); | 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 | mdp4_crtc->enabled = false; | 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 | static const struct drm_crtc_funcs mdp4_crtc_funcs = { | 476 | static const struct drm_crtc_funcs mdp4_crtc_funcs = { |
| 477 | .set_config = drm_atomic_helper_set_config, | 477 | .set_config = drm_atomic_helper_set_config, |
| 478 | .destroy = mdp4_crtc_destroy, | ||
| 479 | .page_flip = drm_atomic_helper_page_flip, | 478 | .page_flip = drm_atomic_helper_page_flip, |
| 480 | .cursor_set = mdp4_crtc_cursor_set, | 479 | .cursor_set = mdp4_crtc_cursor_set, |
| 481 | .cursor_move = mdp4_crtc_cursor_move, | 480 | .cursor_move = mdp4_crtc_cursor_move, |
| @@ -616,6 +615,13 @@ static const char *dma_names[] = { · 134 unmodified lines | |||
| 616 | "DMA_P", "DMA_S", "DMA_E", | 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 | /* initialize crtc */ | 625 | /* initialize crtc */ |
| 620 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, | 626 | struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, |
| 621 | struct drm_plane *plane, int id, int ovlp_id, | 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 | struct drm_crtc *crtc = NULL; | 630 | struct drm_crtc *crtc = NULL; |
| 625 | struct mdp4_crtc *mdp4_crtc; | 631 | struct mdp4_crtc *mdp4_crtc; |
| 632 | int ret; | ||
| 626 | 633 | ||
| 627 | mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL); | 634 | mdp4_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp4_crtc, base, |
| 628 | if (!mdp4_crtc) | 635 | plane, NULL, |
| 629 | return ERR_PTR(-ENOMEM); | 636 | &mdp4_crtc_funcs, NULL); |
| 637 | if (IS_ERR(mdp4_crtc)) | ||
| 638 | return ERR_CAST(mdp4_crtc); | ||
| 630 | 639 | ||
| 631 | crtc = &mdp4_crtc->base; | 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 | drm_flip_work_init(&mdp4_crtc->unref_cursor_work, | 658 | drm_flip_work_init(&mdp4_crtc->unref_cursor_work, |
| 650 | "unref cursor", unref_cursor_worker); | 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 | drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); | 664 | drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs); |
| 655 | 665 | ||
| 656 | return crtc; | 666 | return crtc; |
| @@ -26,18 +26,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 25 unmodified lines | |||
| 26 | return to_mdp4_kms(to_mdp_kms(priv->kms)); | 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 | static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder, | 29 | static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder, |
| 42 | struct drm_display_mode *mode, | 30 | struct drm_display_mode *mode, |
| 43 | struct drm_display_mode *adjusted_mode) | 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 | /* initialize encoder */ | 136 | /* initialize encoder */ |
| 149 | struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev) | 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 | struct mdp4_dsi_encoder *mdp4_dsi_encoder; | 140 | struct mdp4_dsi_encoder *mdp4_dsi_encoder; |
| 153 | int ret; | ||
| 154 | 141 | ||
| 155 | mdp4_dsi_encoder = kzalloc(sizeof(*mdp4_dsi_encoder), GFP_KERNEL); | 142 | mdp4_dsi_encoder = drmm_encoder_alloc(dev, struct mdp4_dsi_encoder, base, |
| 156 | if (!mdp4_dsi_encoder) { | 143 | NULL, DRM_MODE_ENCODER_DSI, NULL); |
| 157 | ret = -ENOMEM; | 144 | if (IS_ERR(mdp4_dsi_encoder)) |
| 158 | goto fail; | 145 | return ERR_CAST(mdp4_dsi_encoder); |
| 159 | } | ||
| 160 | 146 | ||
| 161 | encoder = &mdp4_dsi_encoder->base; | 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 | drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs); | 149 | drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs); |
| 166 | 150 | ||
| 167 | return encoder; | 151 | return encoder; |
| 168 | |||
| 169 | fail: | ||
| 170 | if (encoder) | ||
| 171 | mdp4_dsi_encoder_destroy(encoder); | ||
| 172 | |||
| 173 | return ERR_PTR(ret); | ||
| 174 | } | 152 | } |
| 175 | #endif /* CONFIG_DRM_MSM_DSI */ | 153 | #endif /* CONFIG_DRM_MSM_DSI */ |
| @@ -25,17 +25,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 24 unmodified lines | |||
| 25 | return to_mdp4_kms(to_mdp_kms(priv->kms)); | 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 | static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, | 28 | static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, |
| 40 | struct drm_display_mode *mode, | 29 | struct drm_display_mode *mode, |
| 41 | struct drm_display_mode *adjusted_mode) | 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 | /* initialize encoder */ | 162 | /* initialize encoder */ |
| 174 | struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev) | 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 | struct mdp4_dtv_encoder *mdp4_dtv_encoder; | 166 | struct mdp4_dtv_encoder *mdp4_dtv_encoder; |
| 178 | int ret; | ||
| 179 | 167 | ||
| 180 | mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL); | 168 | mdp4_dtv_encoder = drmm_encoder_alloc(dev, struct mdp4_dtv_encoder, base, |
| 181 | if (!mdp4_dtv_encoder) { | 169 | NULL, DRM_MODE_ENCODER_TMDS, NULL); |
| 182 | ret = -ENOMEM; | 170 | if (IS_ERR(mdp4_dtv_encoder)) |
| 183 | goto fail; | 171 | return ERR_CAST(mdp4_dtv_encoder); |
| 184 | } | ||
| 185 | 172 | ||
| 186 | encoder = &mdp4_dtv_encoder->base; | 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 | drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs); | 175 | drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs); |
| 191 | 176 | ||
| 192 | mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk"); | 177 | mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk"); |
| 193 | if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) { | 178 | if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) { |
| 194 | DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n"); | 179 | DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n"); |
| 195 | ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk); | 180 | return ERR_CAST(mdp4_dtv_encoder->hdmi_clk); |
| 196 | goto fail; | ||
| 197 | } | 181 | } |
| 198 | 182 | ||
| 199 | mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk"); | 183 | mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk"); |
| 200 | if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) { | 184 | if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) { |
| 201 | DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n"); | 185 | DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n"); |
| 202 | ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk); | 186 | return ERR_CAST(mdp4_dtv_encoder->mdp_clk); |
| 203 | goto fail; | ||
| 204 | } | 187 | } |
| 205 | 188 | ||
| 206 | return encoder; | 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 | struct drm_panel *panel; | 18 | struct drm_panel *panel; |
| 19 | struct clk *lcdc_clk; | 19 | struct clk *lcdc_clk; |
| 20 | unsigned long int pixclock; | 20 | unsigned long int pixclock; |
| 21 | struct regulator *regs[3]; | 21 | struct regulator_bulk_data regs[3]; |
| 22 | bool enabled; | 22 | bool enabled; |
| 23 | uint32_t bsc; | 23 | uint32_t bsc; |
| 24 | }; | 24 | }; |
| @@ -30,18 +30,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 5 unmodified lines | |||
| 30 | return to_mdp4_kms(to_mdp_kms(priv->kms)); | 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 | /* this should probably be a helper: */ | 33 | /* this should probably be a helper: */ |
| 46 | static struct drm_connector *get_connector(struct drm_encoder *encoder) | 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 | static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) | 260 | static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) |
| 273 | { | 261 | { |
| 274 | struct drm_device *dev = encoder->dev; | ||
| 275 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = | 262 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = |
| 276 | to_mdp4_lcdc_encoder(encoder); | 263 | to_mdp4_lcdc_encoder(encoder); |
| 277 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | 264 | struct mdp4_kms *mdp4_kms = get_kms(encoder); |
| 278 | struct drm_panel *panel; | 265 | struct drm_panel *panel; |
| 279 | int i, ret; | ||
| 280 | 266 | ||
| 281 | if (WARN_ON(!mdp4_lcdc_encoder->enabled)) | 267 | if (WARN_ON(!mdp4_lcdc_encoder->enabled)) |
| 282 | return; | 268 | return; |
| @@ -301,11 +287,8 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) · 18 unmodified lines | |||
| 301 | 287 | ||
| 302 | clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); | 288 | clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); |
| 303 | 289 | ||
| 304 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | 290 | regulator_bulk_disable(ARRAY_SIZE(mdp4_lcdc_encoder->regs), |
| 305 | ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); | 291 | mdp4_lcdc_encoder->regs); |
| 306 | if (ret) | ||
| 307 | DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret); | ||
| 308 | } | ||
| 309 | 292 | ||
| 310 | mdp4_lcdc_encoder->enabled = false; | 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 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | 302 | struct mdp4_kms *mdp4_kms = get_kms(encoder); |
| 320 | struct drm_panel *panel; | 303 | struct drm_panel *panel; |
| 321 | uint32_t config; | 304 | uint32_t config; |
| 322 | int i, ret; | 305 | int ret; |
| 323 | 306 | ||
| 324 | if (WARN_ON(mdp4_lcdc_encoder->enabled)) | 307 | if (WARN_ON(mdp4_lcdc_encoder->enabled)) |
| 325 | return; | 308 | return; |
| @@ -339,11 +322,10 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · 13 unmodified lines | |||
| 339 | mdp4_crtc_set_config(encoder->crtc, config); | 322 | mdp4_crtc_set_config(encoder->crtc, config); |
| 340 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); | 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++) { | 325 | ret = regulator_bulk_enable(ARRAY_SIZE(mdp4_lcdc_encoder->regs), |
| 343 | ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); | 326 | mdp4_lcdc_encoder->regs); |
| 344 | if (ret) | 327 | if (ret) |
| 345 | DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret); | 328 | DRM_DEV_ERROR(dev->dev, "failed to enable regulators: %d\n", ret); |
| 346 | } | ||
| 347 | 329 | ||
| 348 | DBG("setting lcdc_clk=%lu", pc); | 330 | DBG("setting lcdc_clk=%lu", pc); |
| 349 | ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); | 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 | struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, | 365 | struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, |
| 384 | struct device_node *panel_node) | 366 | struct device_node *panel_node) |
| 385 | { | 367 | { |
| 386 | struct drm_encoder *encoder = NULL; | 368 | struct drm_encoder *encoder; |
| 387 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; | 369 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder; |
| 388 | struct regulator *reg; | ||
| 389 | int ret; | 370 | int ret; |
| 390 | 371 | ||
| 391 | mdp4_lcdc_encoder = kzalloc(sizeof(*mdp4_lcdc_encoder), GFP_KERNEL); | 372 | mdp4_lcdc_encoder = drmm_encoder_alloc(dev, struct mdp4_lcdc_encoder, base, |
| 392 | if (!mdp4_lcdc_encoder) { | 373 | NULL, DRM_MODE_ENCODER_LVDS, NULL); |
| 393 | ret = -ENOMEM; | 374 | if (IS_ERR(mdp4_lcdc_encoder)) |
| 394 | goto fail; | 375 | return ERR_CAST(mdp4_lcdc_encoder); |
| 395 | } | ||
| 396 | 376 | ||
| 397 | mdp4_lcdc_encoder->panel_node = panel_node; | 377 | mdp4_lcdc_encoder->panel_node = panel_node; |
| 398 | 378 | ||
| 399 | encoder = &mdp4_lcdc_encoder->base; | 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 | drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); | 381 | drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs); |
| 404 | 382 | ||
| 405 | /* TODO: do we need different pll in other cases? */ | 383 | /* TODO: do we need different pll in other cases? */ |
| 406 | mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); | 384 | mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); |
| 407 | if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { | 385 | if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { |
| 408 | DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); | 386 | DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); |
| 409 | ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk); | 387 | return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk); |
| 410 | goto fail; | ||
| 411 | } | 388 | } |
| 412 | 389 | ||
| 413 | /* TODO: different regulators in other cases? */ | 390 | /* TODO: different regulators in other cases? */ |
| 414 | reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v"); | 391 | mdp4_lcdc_encoder->regs[0].supply = "lvds-vccs-3p3v"; |
| 415 | if (IS_ERR(reg)) { | 392 | mdp4_lcdc_encoder->regs[1].supply = "lvds-vccs-3p3v"; |
| 416 | ret = PTR_ERR(reg); | 393 | mdp4_lcdc_encoder->regs[2].supply = "lvds-vdda"; |
| 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; | ||
| 429 | 394 | ||
| 430 | reg = devm_regulator_get(dev->dev, "lvds-vdda"); | 395 | ret = devm_regulator_bulk_get(dev->dev, |
| 431 | if (IS_ERR(reg)) { | 396 | ARRAY_SIZE(mdp4_lcdc_encoder->regs), |
| 432 | ret = PTR_ERR(reg); | 397 | mdp4_lcdc_encoder->regs); |
| 433 | DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret); | 398 | if (ret) |
| 434 | goto fail; | 399 | return ERR_PTR(ret); |
| 435 | } | ||
| 436 | mdp4_lcdc_encoder->regs[2] = reg; | ||
| 437 | 400 | ||
| 438 | return encoder; | 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 | return cfg_handler->revision; | 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 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, | 1353 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, |
| 1359 | uint32_t major, uint32_t minor) | 1354 | uint32_t major, uint32_t minor) |
| 1360 | { | 1355 | { |
| 1361 | struct drm_device *dev = mdp5_kms->dev; | 1356 | struct drm_device *dev = mdp5_kms->dev; |
| 1362 | struct mdp5_cfg_handler *cfg_handler; | 1357 | struct mdp5_cfg_handler *cfg_handler; |
| 1363 | const struct mdp5_cfg_handler *cfg_handlers; | 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 | if (unlikely(!cfg_handler)) { | 1362 | if (unlikely(!cfg_handler)) { |
| 1368 | ret = -ENOMEM; | 1363 | return ERR_PTR(-ENOMEM); |
| 1369 | goto fail; | ||
| 1370 | } | 1364 | } |
| 1371 | 1365 | ||
| 1372 | switch (major) { | 1366 | switch (major) { |
| @@ -1381,8 +1375,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 8 unmodified lines | |||
| 1381 | default: | 1375 | default: |
| 1382 | DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n", | 1376 | DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n", |
| 1383 | major, minor); | 1377 | major, minor); |
| 1384 | ret = -ENXIO; | 1378 | return ERR_PTR(-ENXIO); |
| 1385 | goto fail; | ||
| 1386 | } | 1379 | } |
| 1387 | 1380 | ||
| 1388 | /* only after mdp5_cfg global pointer's init can we access the hw */ | 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 | if (unlikely(!mdp5_cfg)) { | 1389 | if (unlikely(!mdp5_cfg)) { |
| 1397 | DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n", | 1390 | DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n", |
| 1398 | major, minor); | 1391 | major, minor); |
| 1399 | ret = -ENXIO; | 1392 | return ERR_PTR(-ENXIO); |
| 1400 | goto fail; | ||
| 1401 | } | 1393 | } |
| 1402 | 1394 | ||
| 1403 | cfg_handler->revision = minor; | 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 | DBG("MDP5: %s hw config selected", mdp5_cfg->name); | 1398 | DBG("MDP5: %s hw config selected", mdp5_cfg->name); |
| 1407 | 1399 | ||
| 1408 | return cfg_handler; | 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 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, | 122 | struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, |
| 123 | uint32_t major, uint32_t minor); | 123 | uint32_t major, uint32_t minor); |
| 124 | void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd); | ||
| 125 | 124 | ||
| 126 | #endif /* __MDP5_CFG_H__ */ | 125 | #endif /* __MDP5_CFG_H__ */ |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <drm/drm_crtc.h> | 13 | #include <drm/drm_crtc.h> |
| 14 | #include <drm/drm_flip_work.h> | 14 | #include <drm/drm_flip_work.h> |
| 15 | #include <drm/drm_fourcc.h> | 15 | #include <drm/drm_fourcc.h> |
| 16 | #include <drm/drm_managed.h> | ||
| 16 | #include <drm/drm_probe_helper.h> | 17 | #include <drm/drm_probe_helper.h> |
| 17 | #include <drm/drm_vblank.h> | 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 | drm_gem_object_put(val); | 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 | drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work); | 180 | drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work); |
| 181 | |||
| 182 | kfree(mdp5_crtc); | ||
| 183 | } | 181 | } |
| 184 | 182 | ||
| 185 | static inline u32 mdp5_lm_use_fg_alpha_mask(enum mdp_mixer_stage_id stage) | 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 | static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { | 1146 | static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = { |
| 1149 | .set_config = drm_atomic_helper_set_config, | 1147 | .set_config = drm_atomic_helper_set_config, |
| 1150 | .destroy = mdp5_crtc_destroy, | ||
| 1151 | .page_flip = drm_atomic_helper_page_flip, | 1148 | .page_flip = drm_atomic_helper_page_flip, |
| 1152 | .reset = mdp5_crtc_reset, | 1149 | .reset = mdp5_crtc_reset, |
| 1153 | .atomic_duplicate_state = mdp5_crtc_duplicate_state, | 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 | static const struct drm_crtc_funcs mdp5_crtc_funcs = { | 1159 | static const struct drm_crtc_funcs mdp5_crtc_funcs = { |
| 1163 | .set_config = drm_atomic_helper_set_config, | 1160 | .set_config = drm_atomic_helper_set_config, |
| 1164 | .destroy = mdp5_crtc_destroy, | ||
| 1165 | .page_flip = drm_atomic_helper_page_flip, | 1161 | .page_flip = drm_atomic_helper_page_flip, |
| 1166 | .reset = mdp5_crtc_reset, | 1162 | .reset = mdp5_crtc_reset, |
| 1167 | .atomic_duplicate_state = mdp5_crtc_duplicate_state, | 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 | struct drm_crtc *crtc = NULL; | 1324 | struct drm_crtc *crtc = NULL; |
| 1329 | struct mdp5_crtc *mdp5_crtc; | 1325 | struct mdp5_crtc *mdp5_crtc; |
| 1326 | int ret; | ||
| 1330 | 1327 | ||
| 1331 | mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL); | 1328 | mdp5_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp5_crtc, base, |
| 1332 | if (!mdp5_crtc) | 1329 | plane, cursor_plane, |
| 1333 | return ERR_PTR(-ENOMEM); | 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 | crtc = &mdp5_crtc->base; | 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 | mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true; | 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 | drm_flip_work_init(&mdp5_crtc->unref_cursor_work, | 1351 | drm_flip_work_init(&mdp5_crtc->unref_cursor_work, |
| 1355 | "unref cursor", unref_cursor_worker); | 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 | drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); | 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 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, | 684 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, |
| 690 | void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd) | 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 | unsigned long flags; | 692 | unsigned long flags; |
| 698 | int c, ret; | 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 | if (!ctl_mgr) { | 696 | if (!ctl_mgr) { |
| 702 | DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n"); | 697 | DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n"); |
| 703 | ret = -ENOMEM; | 698 | return ERR_PTR(-ENOMEM); |
| 704 | goto fail; | ||
| 705 | } | 699 | } |
| 706 | 700 | ||
| 707 | if (WARN_ON(ctl_cfg->count > MAX_CTL)) { | 701 | if (WARN_ON(ctl_cfg->count > MAX_CTL)) { |
| 708 | DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n", | 702 | DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n", |
| 709 | ctl_cfg->count); | 703 | ctl_cfg->count); |
| 710 | ret = -ENOSPC; | 704 | return ERR_PTR(-ENOSPC); |
| 711 | goto fail; | ||
| 712 | } | 705 | } |
| 713 | 706 | ||
| 714 | /* initialize the CTL manager: */ | 707 | /* initialize the CTL manager: */ |
| @@ -727,7 +720,7 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 12 unmodified lines | |||
| 727 | DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c); | 720 | DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c); |
| 728 | ret = -EINVAL; | 721 | ret = -EINVAL; |
| 729 | spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); | 722 | spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); |
| 730 | goto fail; | 723 | return ERR_PTR(ret); |
| 731 | } | 724 | } |
| 732 | ctl->ctlm = ctl_mgr; | 725 | ctl->ctlm = ctl_mgr; |
| 733 | ctl->id = c; | 726 | ctl->id = c; |
| @@ -755,10 +748,4 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 21 unmodified lines | |||
| 755 | DBG("Pool of %d CTLs created.", ctl_mgr->nctl); | 748 | DBG("Pool of %d CTLs created.", ctl_mgr->nctl); |
| 756 | 749 | ||
| 757 | return ctl_mgr; | 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 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, | 17 | struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, |
| 18 | void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd); | 18 | void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd); |
| 19 | void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctlm); | 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 | * CTL prototypes: | 22 | * CTL prototypes: |
| @@ -16,17 +16,6 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder) · 15 unmodified lines | |||
| 16 | return to_mdp5_kms(to_mdp_kms(priv->kms)); | 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 | static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, | 19 | static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder, |
| 31 | struct drm_display_mode *mode, | 20 | struct drm_display_mode *mode, |
| 32 | struct drm_display_mode *adjusted_mode) | 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 | struct mdp5_encoder *mdp5_encoder; | 331 | struct mdp5_encoder *mdp5_encoder; |
| 343 | int enc_type = (intf->type == INTF_DSI) ? | 332 | int enc_type = (intf->type == INTF_DSI) ? |
| 344 | DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS; | 333 | DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS; |
| 345 | int ret; | ||
| 346 | 334 | ||
| 347 | mdp5_encoder = kzalloc(sizeof(*mdp5_encoder), GFP_KERNEL); | 335 | mdp5_encoder = drmm_encoder_alloc(dev, struct mdp5_encoder, base, |
| 348 | if (!mdp5_encoder) { | 336 | NULL, enc_type, NULL); |
| 349 | ret = -ENOMEM; | 337 | if (IS_ERR(mdp5_encoder)) |
| 350 | goto fail; | 338 | return ERR_CAST(mdp5_encoder); |
| 351 | } | ||
| 352 | 339 | ||
| 353 | encoder = &mdp5_encoder->base; | 340 | encoder = &mdp5_encoder->base; |
| 354 | mdp5_encoder->ctl = ctl; | 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 | spin_lock_init(&mdp5_encoder->intf_lock); | 344 | spin_lock_init(&mdp5_encoder->intf_lock); |
| 358 | 345 | ||
| 359 | drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type, NULL); | ||
| 360 | |||
| 361 | drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); | 346 | drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs); |
| 362 | 347 | ||
| 363 | return encoder; | 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 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | 210 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); |
| 211 | struct msm_gem_address_space *aspace = kms->aspace; | 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 | if (aspace) { | 213 | if (aspace) { |
| 221 | aspace->mmu->funcs->detach(aspace->mmu); | 214 | aspace->mmu->funcs->detach(aspace->mmu); |
| @@ -623,18 +616,6 @@ fail: · 401 unmodified lines | |||
| 623 | 616 | ||
| 624 | static void mdp5_destroy(struct mdp5_kms *mdp5_kms) | 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 | if (mdp5_kms->rpm_enabled) | 619 | if (mdp5_kms->rpm_enabled) |
| 639 | pm_runtime_disable(&mdp5_kms->pdev->dev); | 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 | for (i = 0; i < cnt; i++) { | 633 | for (i = 0; i < cnt; i++) { |
| 653 | struct mdp5_hw_pipe *hwpipe; | 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 | if (IS_ERR(hwpipe)) { | 637 | if (IS_ERR(hwpipe)) { |
| 657 | ret = PTR_ERR(hwpipe); | 638 | ret = PTR_ERR(hwpipe); |
| 658 | DRM_DEV_ERROR(dev->dev, "failed to construct pipe for %s (%d)\n", | 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 | for (i = 0; i < hw_cfg->lm.count; i++) { | 705 | for (i = 0; i < hw_cfg->lm.count; i++) { |
| 725 | struct mdp5_hw_mixer *mixer; | 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 | if (IS_ERR(mixer)) { | 709 | if (IS_ERR(mixer)) { |
| 729 | ret = PTR_ERR(mixer); | 710 | ret = PTR_ERR(mixer); |
| 730 | DRM_DEV_ERROR(dev->dev, "failed to construct LM%d (%d)\n", | 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 | if (intf_types[i] == INTF_DISABLED) | 736 | if (intf_types[i] == INTF_DISABLED) |
| 756 | continue; | 737 | continue; |
| 757 | 738 | ||
| 758 | intf = kzalloc(sizeof(*intf), GFP_KERNEL); | 739 | intf = devm_kzalloc(dev->dev, sizeof(*intf), GFP_KERNEL); |
| 759 | if (!intf) { | 740 | if (!intf) { |
| 760 | DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i); | 741 | DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i); |
| 761 | return -ENOMEM; | 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 | return 0; | 140 | return 0; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer) | ||
| 144 | { | ||
| 145 | kfree(mixer); | ||
| 146 | } | ||
| 147 | |||
| 148 | static const char * const mixer_names[] = { | 143 | static const char * const mixer_names[] = { |
| 149 | "LM0", "LM1", "LM2", "LM3", "LM4", "LM5", | 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 | struct mdp5_hw_mixer *mixer; | 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 | if (!mixer) | 153 | if (!mixer) |
| 158 | return ERR_PTR(-ENOMEM); | 154 | return ERR_PTR(-ENOMEM); |
| 159 | 155 | ||
| @@ -25,8 +25,8 @@ struct mdp5_hw_mixer_state { · 24 unmodified lines | |||
| 25 | struct drm_crtc *hwmixer_to_crtc[8]; | 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); | 28 | struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev, |
| 29 | void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm); | 29 | const struct mdp5_lm_instance *lm); |
| 30 | int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, | 30 | int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, |
| 31 | uint32_t caps, struct mdp5_hw_mixer **mixer, | 31 | uint32_t caps, struct mdp5_hw_mixer **mixer, |
| 32 | struct mdp5_hw_mixer **r_mixer); | 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 | return 0; | 151 | return 0; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) | 154 | struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev, |
| 155 | { | 155 | enum mdp5_pipe pipe, |
| 156 | kfree(hwpipe); | ||
| 157 | } | ||
| 158 | |||
| 159 | struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, | ||
| 160 | uint32_t reg_offset, uint32_t caps) | 156 | uint32_t reg_offset, uint32_t caps) |
| 161 | { | 157 | { |
| 162 | struct mdp5_hw_pipe *hwpipe; | 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 | if (!hwpipe) | 161 | if (!hwpipe) |
| 166 | return ERR_PTR(-ENOMEM); | 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 | struct mdp5_hw_pipe **r_hwpipe); | 39 | struct mdp5_hw_pipe **r_hwpipe); |
| 40 | int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); | 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 | uint32_t reg_offset, uint32_t caps); | 44 | uint32_t reg_offset, uint32_t caps); |
| 44 | void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe); | ||
| 45 | 45 | ||
| 46 | #endif /* __MDP5_PIPE_H__ */ | 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 | drm_modeset_unlock(&mdp5_kms->glob_state_lock); | 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 | struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_block *cfg) | 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 | struct mdp5_smp_state *state; | 377 | struct mdp5_smp_state *state; |
| 381 | struct mdp5_global_state *global_state; | 378 | struct mdp5_global_state *global_state; |
| 382 | struct mdp5_smp *smp; | 379 | struct mdp5_smp *smp; |
| 383 | int ret; | ||
| 384 | 380 | ||
| 385 | smp = kzalloc(sizeof(*smp), GFP_KERNEL); | 381 | smp = devm_kzalloc(dev->dev, sizeof(*smp), GFP_KERNEL); |
| 386 | if (unlikely(!smp)) { | 382 | if (unlikely(!smp)) |
| 387 | ret = -ENOMEM; | 383 | return ERR_PTR(-ENOMEM); |
| 388 | goto fail; | ||
| 389 | } | ||
| 390 | 384 | ||
| 391 | smp->dev = mdp5_kms->dev; | 385 | smp->dev = mdp5_kms->dev; |
| 392 | smp->blk_cnt = cfg->mmb_count; | 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 | memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved)); | 394 | memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved)); |
| 401 | 395 | ||
| 402 | return smp; | 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 | struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, | 69 | struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, |
| 70 | const struct mdp5_smp_block *cfg); | 70 | const struct mdp5_smp_block *cfg); |
| 71 | void mdp5_smp_destroy(struct mdp5_smp *smp); | ||
| 72 | 71 | ||
| 73 | void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p); | 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 | return -EINVAL; | 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 | mutex_lock(&aux->mutex); | 298 | mutex_lock(&aux->mutex); |
| 295 | if (!aux->initted) { | 299 | if (!aux->initted) { |
| 296 | ret = -EIO; | 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 | exit: | 369 | exit: |
| 366 | mutex_unlock(&aux->mutex); | 370 | mutex_unlock(&aux->mutex); |
| 371 | pm_runtime_put_sync(dp_aux->dev); | ||
| 367 | 372 | ||
| 368 | return ret; | 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 | int dp_aux_register(struct drm_dp_aux *dp_aux) | 480 | int dp_aux_register(struct drm_dp_aux *dp_aux) |
| 476 | { | 481 | { |
| 477 | struct dp_aux_private *aux; | ||
| 478 | int ret; | 482 | int ret; |
| 479 | 483 | ||
| 480 | if (!dp_aux) { | 484 | if (!dp_aux) { |
| @@ -482,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux) · 1 unmodified line | |||
| 482 | return -EINVAL; | 486 | return -EINVAL; |
| 483 | } | 487 | } |
| 484 | 488 | ||
| 485 | aux = container_of(dp_aux, struct dp_aux_private, dp_aux); | 489 | ret = drm_dp_aux_register(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); | ||
| 491 | if (ret) { | 490 | if (ret) { |
| 492 | DRM_ERROR("%s: failed to register drm aux: %d\n", __func__, | 491 | DRM_ERROR("%s: failed to register drm aux: %d\n", __func__, |
| 493 | ret); | 492 | ret); |
| @@ -502,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux) · 8 unmodified lines | |||
| 502 | drm_dp_aux_unregister(dp_aux); | 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 | struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, | 519 | struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, |
| 506 | bool is_edp) | 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 | aux->catalog = catalog; | 539 | aux->catalog = catalog; |
| 526 | aux->retry_cnt = 0; | 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 | return &aux->dp_aux; | 553 | return &aux->dp_aux; |
| 529 | } | 554 | } |
| 530 | 555 | ||
| @@ -19,13 +19,9 @@ · 18 unmodified lines | |||
| 19 | #define DEBUG_NAME "msm_dp" | 19 | #define DEBUG_NAME "msm_dp" |
| 20 | 20 | ||
| 21 | struct dp_debug_private { | 21 | struct dp_debug_private { |
| 22 | struct dentry *root; | ||
| 23 | |||
| 24 | struct dp_link *link; | 22 | struct dp_link *link; |
| 25 | struct dp_panel *panel; | 23 | struct dp_panel *panel; |
| 26 | struct drm_connector *connector; | 24 | struct drm_connector *connector; |
| 27 | struct device *dev; | ||
| 28 | struct drm_device *drm_dev; | ||
| 29 | 25 | ||
| 30 | struct dp_debug dp_debug; | 26 | struct dp_debug dp_debug; |
| 31 | }; | 27 | }; |
| @@ -204,35 +200,33 @@ static const struct file_operations test_active_fops = { · 172 unmodified lines | |||
| 204 | .write = dp_test_active_write | 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 | struct dp_debug_private *debug = container_of(dp_debug, | 205 | struct dp_debug_private *debug = container_of(dp_debug, |
| 211 | struct dp_debug_private, dp_debug); | 206 | struct dp_debug_private, dp_debug); |
| 212 | 207 | ||
| 213 | snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name); | 208 | debugfs_create_file("dp_debug", 0444, root, |
| 214 | |||
| 215 | debug->root = debugfs_create_dir(path, minor->debugfs_root); | ||
| 216 | |||
| 217 | debugfs_create_file("dp_debug", 0444, debug->root, | ||
| 218 | debug, &dp_debug_fops); | 209 | debug, &dp_debug_fops); |
| 219 | 210 | ||
| 220 | debugfs_create_file("msm_dp_test_active", 0444, | 211 | if (!is_edp) { |
| 221 | debug->root, | 212 | debugfs_create_file("msm_dp_test_active", 0444, |
| 222 | debug, &test_active_fops); | 213 | root, |
| 214 | debug, &test_active_fops); | ||
| 223 | 215 | ||
| 224 | debugfs_create_file("msm_dp_test_data", 0444, | 216 | debugfs_create_file("msm_dp_test_data", 0444, |
| 225 | debug->root, | 217 | root, |
| 226 | debug, &dp_test_data_fops); | 218 | debug, &dp_test_data_fops); |
| 227 | 219 | ||
| 228 | debugfs_create_file("msm_dp_test_type", 0444, | 220 | debugfs_create_file("msm_dp_test_type", 0444, |
| 229 | debug->root, | 221 | root, |
| 230 | debug, &dp_test_type_fops); | 222 | debug, &dp_test_type_fops); |
| 223 | } | ||
| 231 | } | 224 | } |
| 232 | 225 | ||
| 233 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, | 226 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 234 | struct dp_link *link, | 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 | struct dp_debug_private *debug; | 231 | struct dp_debug_private *debug; |
| 238 | struct dp_debug *dp_debug; | 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 | debug->dp_debug.debug_en = false; | 247 | debug->dp_debug.debug_en = false; |
| 254 | debug->link = link; | 248 | debug->link = link; |
| 255 | debug->panel = panel; | 249 | debug->panel = panel; |
| 256 | debug->dev = dev; | ||
| 257 | debug->drm_dev = minor->dev; | ||
| 258 | debug->connector = connector; | ||
| 259 | 250 | ||
| 260 | dp_debug = &debug->dp_debug; | 251 | dp_debug = &debug->dp_debug; |
| 261 | dp_debug->vdisplay = 0; | 252 | dp_debug->vdisplay = 0; |
| 262 | dp_debug->hdisplay = 0; | 253 | dp_debug->hdisplay = 0; |
| 263 | dp_debug->vrefresh = 0; | 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 | return dp_debug; | 258 | return dp_debug; |
| 268 | error: | 259 | error: |
| 269 | return ERR_PTR(rc); | 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 | * @panel: instance of panel module | 34 | * @panel: instance of panel module |
| 35 | * @link: instance of link module | 35 | * @link: instance of link module |
| 36 | * @connector: double pointer to display connector | 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 | * return: pointer to allocated debug module data | 39 | * return: pointer to allocated debug module data |
| 39 | * | 40 | * |
| 40 | * This function sets up the debug module and provides a way | 41 | * This function sets up the debug module and provides a way |
| @@ -43,31 +44,21 @@ struct dp_debug { · 2 unmodified lines | |||
| 43 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, | 44 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 44 | struct dp_link *link, | 45 | struct dp_link *link, |
| 45 | struct drm_connector *connector, | 46 | struct drm_connector *connector, |
| 46 | struct drm_minor *minor); | 47 | struct dentry *root, |
| 47 | 48 | bool is_edp); | |
| 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); | ||
| 56 | 49 | ||
| 57 | #else | 50 | #else |
| 58 | 51 | ||
| 59 | static inline | 52 | static inline |
| 60 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, | 53 | struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, |
| 61 | struct dp_link *link, | 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 | return ERR_PTR(-EINVAL); | 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 | #endif /* defined(CONFIG_DEBUG_FS) */ | 62 | #endif /* defined(CONFIG_DEBUG_FS) */ |
| 72 | 63 | ||
| 73 | #endif /* _DP_DEBUG_H_ */ | 64 | #endif /* _DP_DEBUG_H_ */ |
| @@ -49,13 +49,11 @@ enum { · 48 unmodified lines | |||
| 49 | ST_CONNECTED, | 49 | ST_CONNECTED, |
| 50 | ST_DISCONNECT_PENDING, | 50 | ST_DISCONNECT_PENDING, |
| 51 | ST_DISPLAY_OFF, | 51 | ST_DISPLAY_OFF, |
| 52 | ST_SUSPENDED, | ||
| 53 | }; | 52 | }; |
| 54 | 53 | ||
| 55 | enum { | 54 | enum { |
| 56 | EV_NO_EVENT, | 55 | EV_NO_EVENT, |
| 57 | /* hpd events */ | 56 | /* hpd events */ |
| 58 | EV_HPD_INIT_SETUP, | ||
| 59 | EV_HPD_PLUG_INT, | 57 | EV_HPD_PLUG_INT, |
| 60 | EV_IRQ_HPD_INT, | 58 | EV_IRQ_HPD_INT, |
| 61 | EV_HPD_UNPLUG_INT, | 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 | static const struct of_device_id dp_dt_match[] = { | 176 | static const struct of_device_id dp_dt_match[] = { |
| 174 | { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, | 177 | { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, |
| 175 | { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, | 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 | { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, | 183 | { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, |
| 181 | { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, | 184 | { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, |
| 182 | { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs }, | 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 | dp->dp_display.drm_dev = drm; | 279 | dp->dp_display.drm_dev = drm; |
| 276 | priv->dp[dp->id] = &dp->dp_display; | 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 | dp->drm_dev = drm; | 284 | dp->drm_dev = drm; |
| @@ -290,11 +289,6 @@ static int dp_display_bind(struct device *dev, struct device *master, · 4 unmodified lines | |||
| 290 | goto end; | 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 | rc = dp_register_audio_driver(dev, dp->audio); | 293 | rc = dp_register_audio_driver(dev, dp->audio); |
| 300 | if (rc) { | 294 | if (rc) { |
| @@ -319,15 +313,10 @@ static void dp_display_unbind(struct device *dev, struct device *master, · 18 unmodified lines | |||
| 319 | struct dp_display_private *dp = dev_get_dp_display_private(dev); | 313 | struct dp_display_private *dp = dev_get_dp_display_private(dev); |
| 320 | struct msm_drm_private *priv = dev_get_drvdata(master); | 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 | kthread_stop(dp->ev_tsk); | 316 | kthread_stop(dp->ev_tsk); |
| 327 | 317 | ||
| 328 | of_dp_aux_depopulate_bus(dp->aux); | 318 | of_dp_aux_depopulate_bus(dp->aux); |
| 329 | 319 | ||
| 330 | dp_power_client_deinit(dp->power); | ||
| 331 | dp_unregister_audio_driver(dev, dp->audio); | 320 | dp_unregister_audio_driver(dev, dp->audio); |
| 332 | dp_aux_unregister(dp->aux); | 321 | dp_aux_unregister(dp->aux); |
| 333 | dp->drm_dev = NULL; | 322 | dp->drm_dev = NULL; |
| @@ -340,27 +329,10 @@ static const struct component_ops dp_display_comp_ops = { · 6 unmodified lines | |||
| 340 | .unbind = dp_display_unbind, | 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 | static int dp_display_send_hpd_notification(struct dp_display_private *dp, | 332 | static int dp_display_send_hpd_notification(struct dp_display_private *dp, |
| 356 | bool hpd) | 333 | bool hpd) |
| 357 | { | 334 | { |
| 358 | if ((hpd && dp->dp_display.is_connected) || | 335 | struct drm_bridge *bridge = dp->dp_display.bridge; |
| 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 | } | ||
| 364 | 336 | ||
| 365 | /* reset video pattern flag on disconnect */ | 337 | /* reset video pattern flag on disconnect */ |
| 366 | if (!hpd) { | 338 | if (!hpd) { |
| @@ -372,11 +344,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, · 5 unmodified lines | |||
| 372 | dp->panel->downstream_ports); | 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 | drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n", | 349 | drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n", |
| 378 | dp->dp_display.connector_type, hpd); | 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 | return 0; | 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 | u32 state; | 548 | u32 state; |
| 577 | int ret; | 549 | int ret; |
| 550 | struct platform_device *pdev = dp->dp_display.pdev; | ||
| 578 | 551 | ||
| 579 | mutex_lock(&dp->event_mutex); | 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 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", | 555 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", |
| 583 | dp->dp_display.connector_type, state); | 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 | mutex_unlock(&dp->event_mutex); | 559 | mutex_unlock(&dp->event_mutex); |
| 587 | return 0; | 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 | return 0; | 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 | if (ret) { /* link train failed */ | 583 | if (ret) { /* link train failed */ |
| 604 | dp->hpd_state = ST_DISCONNECTED; | 584 | dp->hpd_state = ST_DISCONNECTED; |
| 605 | } else { | 585 | } else { |
| @@ -631,6 +611,7 @@ static void dp_display_handle_plugged_change(struct msm_dp *dp_display, · 25 unmodified lines | |||
| 631 | static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) | 611 | static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) |
| 632 | { | 612 | { |
| 633 | u32 state; | 613 | u32 state; |
| 614 | struct platform_device *pdev = dp->dp_display.pdev; | ||
| 634 | 615 | ||
| 635 | mutex_lock(&dp->event_mutex); | 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 | dp->dp_display.connector_type, state); | 662 | dp->dp_display.connector_type, state); |
| 682 | 663 | ||
| 683 | /* uevent will complete disconnection part */ | 664 | /* uevent will complete disconnection part */ |
| 665 | pm_runtime_put_sync(&pdev->dev); | ||
| 684 | mutex_unlock(&dp->event_mutex); | 666 | mutex_unlock(&dp->event_mutex); |
| 685 | return 0; | 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 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", | 678 | drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", |
| 697 | dp->dp_display.connector_type, state); | 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 | mutex_unlock(&dp->event_mutex); | 682 | mutex_unlock(&dp->event_mutex); |
| 701 | return 0; | 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 | static void dp_display_deinit_sub_modules(struct dp_display_private *dp) | 703 | static void dp_display_deinit_sub_modules(struct dp_display_private *dp) |
| 722 | { | 704 | { |
| 723 | dp_debug_put(dp->debug); | ||
| 724 | dp_audio_put(dp->audio); | 705 | dp_audio_put(dp->audio); |
| 725 | dp_panel_put(dp->panel); | 706 | dp_panel_put(dp->panel); |
| 726 | dp_aux_put(dp->aux); | 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 | dp_display->plugged_cb = fn; | 900 | dp_display->plugged_cb = fn; |
| 920 | dp_display->codec_dev = codec_dev; | 901 | dp_display->codec_dev = codec_dev; |
| 921 | plugged = dp_display->is_connected; | 902 | plugged = dp_display->link_ready; |
| 922 | dp_display_handle_plugged_change(dp_display, plugged); | 903 | dp_display_handle_plugged_change(dp_display, plugged); |
| 923 | 904 | ||
| 924 | return 0; | 905 | return 0; |
| @@ -1108,9 +1089,6 @@ static int hpd_event_thread(void *data) · 183 unmodified lines | |||
| 1108 | spin_unlock_irqrestore(&dp_priv->event_lock, flag); | 1089 | spin_unlock_irqrestore(&dp_priv->event_lock, flag); |
| 1109 | 1090 | ||
| 1110 | switch (todo->event_id) { | 1091 | switch (todo->event_id) { |
| 1111 | case EV_HPD_INIT_SETUP: | ||
| 1112 | dp_display_host_init(dp_priv); | ||
| 1113 | break; | ||
| 1114 | case EV_HPD_PLUG_INT: | 1092 | case EV_HPD_PLUG_INT: |
| 1115 | dp_hpd_plug_handle(dp_priv, todo->data); | 1093 | dp_hpd_plug_handle(dp_priv, todo->data); |
| 1116 | break; | 1094 | break; |
| @@ -1189,27 +1167,21 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) · 72 unmodified lines | |||
| 1189 | return ret; | 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 | int rc = 0; | 1172 | int rc = 0; |
| 1195 | struct dp_display_private *dp; | 1173 | struct platform_device *pdev = dp->dp_display.pdev; |
| 1196 | |||
| 1197 | if (!dp_display) { | ||
| 1198 | DRM_ERROR("invalid input\n"); | ||
| 1199 | return -EINVAL; | ||
| 1200 | } | ||
| 1201 | 1174 | ||
| 1202 | dp = container_of(dp_display, struct dp_display_private, dp_display); | 1175 | dp->irq = platform_get_irq(pdev, 0); |
| 1203 | 1176 | if (dp->irq < 0) { | |
| 1204 | dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0); | ||
| 1205 | if (!dp->irq) { | ||
| 1206 | DRM_ERROR("failed to get irq\n"); | 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, | 1181 | rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler, |
| 1211 | dp_display_irq_handler, | 1182 | IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN, |
| 1212 | IRQF_TRIGGER_HIGH, "dp_display_isr", dp); | 1183 | "dp_display_isr", dp); |
| 1184 | |||
| 1213 | if (rc < 0) { | 1185 | if (rc < 0) { |
| 1214 | DRM_ERROR("failed to request IRQ%u: %d\n", | 1186 | DRM_ERROR("failed to request IRQ%u: %d\n", |
| 1215 | dp->irq, rc); | 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 | return NULL; | 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 | static int dp_display_probe(struct platform_device *pdev) | 1236 | static int dp_display_probe(struct platform_device *pdev) |
| 1242 | { | 1237 | { |
| 1243 | int rc = 0; | 1238 | int rc = 0; |
| @@ -1271,6 +1266,18 @@ static int dp_display_probe(struct platform_device *pdev) · 27 unmodified lines | |||
| 1271 | return -EPROBE_DEFER; | 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 | /* setup event q */ | 1281 | /* setup event q */ |
| 1275 | mutex_init(&dp->event_mutex); | 1282 | mutex_init(&dp->event_mutex); |
| 1276 | init_waitqueue_head(&dp->event_q); | 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 | platform_set_drvdata(pdev, &dp->dp_display); | 1291 | platform_set_drvdata(pdev, &dp->dp_display); |
| 1285 | 1292 | ||
| 1286 | rc = component_add(&pdev->dev, &dp_display_comp_ops); | 1293 | rc = devm_pm_runtime_enable(&pdev->dev); |
| 1287 | if (rc) { | 1294 | if (rc) |
| 1288 | DRM_ERROR("component add failed, rc=%d\n", rc); | 1295 | goto err; |
| 1289 | dp_display_deinit_sub_modules(dp); | 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 | return rc; | 1313 | return rc; |
| 1314 | |||
| 1315 | err: | ||
| 1316 | dp_display_deinit_sub_modules(dp); | ||
| 1317 | return rc; | ||
| 1293 | } | 1318 | } |
| 1294 | 1319 | ||
| 1295 | static void dp_display_remove(struct platform_device *pdev) | 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 | component_del(&pdev->dev, &dp_display_comp_ops); | 1324 | component_del(&pdev->dev, &dp_display_comp_ops); |
| 1300 | dp_display_deinit_sub_modules(dp); | 1325 | dp_display_deinit_sub_modules(dp); |
| 1301 | |||
| 1302 | platform_set_drvdata(pdev, NULL); | 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); | 1331 | struct dp_display_private *dp = dev_get_dp_display_private(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); | ||
| 1329 | 1332 | ||
| 1330 | if (dp_catalog_link_is_connected(dp->catalog)) { | 1333 | disable_irq(dp->irq); |
| 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; | ||
| 1340 | 1334 | ||
| 1335 | if (dp->dp_display.is_edp) { | ||
| 1341 | dp_display_host_phy_exit(dp); | 1336 | dp_display_host_phy_exit(dp); |
| 1337 | dp_catalog_ctrl_hpd_disable(dp->catalog); | ||
| 1342 | } | 1338 | } |
| 1343 | 1339 | dp_display_host_deinit(dp); | |
| 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); | ||
| 1365 | 1340 | ||
| 1366 | return 0; | 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); | 1346 | struct dp_display_private *dp = dev_get_dp_display_private(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); | ||
| 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 | return 0; | 1363 | return 0; |
| 1403 | } | 1364 | } |
| 1404 | 1365 | ||
| 1405 | static const struct dev_pm_ops dp_pm_ops = { | 1366 | static const struct dev_pm_ops dp_pm_ops = { |
| 1406 | .suspend = dp_pm_suspend, | 1367 | SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL) |
| 1407 | .resume = dp_pm_resume, | 1368 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
| 1369 | pm_runtime_force_resume) | ||
| 1408 | }; | 1370 | }; |
| 1409 | 1371 | ||
| 1410 | static struct platform_driver dp_display_driver = { | 1372 | static struct platform_driver dp_display_driver = { |
| @@ -1434,19 +1396,6 @@ void __exit msm_dp_unregister(void) · 23 unmodified lines | |||
| 1434 | platform_driver_unregister(&dp_display_driver); | 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 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) | 1399 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) |
| 1451 | { | 1400 | { |
| 1452 | struct dp_display_private *dp; | 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 | return dp->wide_bus_en; | 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 | struct dp_display_private *dp; | 1410 | struct dp_display_private *dp; |
| 1462 | struct device *dev; | 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 | dp->debug = dp_debug_get(dev, dp->panel, | 1417 | dp->debug = dp_debug_get(dev, dp->panel, |
| 1469 | dp->link, dp->dp_display.connector, | 1418 | dp->link, dp->dp_display.connector, |
| 1470 | minor); | 1419 | root, is_edp); |
| 1471 | if (IS_ERR(dp->debug)) { | 1420 | if (IS_ERR(dp->debug)) { |
| 1472 | rc = PTR_ERR(dp->debug); | 1421 | rc = PTR_ERR(dp->debug); |
| 1473 | DRM_ERROR("failed to initialize debug, rc = %d\n", rc); | 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 | int rc; | 1429 | int rc; |
| 1481 | struct dp_display_private *dp_priv; | 1430 | struct dp_display_private *dp_priv; |
| 1482 | struct device_node *aux_bus; | ||
| 1483 | struct device *dev; | ||
| 1484 | 1431 | ||
| 1485 | dp_priv = container_of(dp, struct dp_display_private, dp_display); | 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 | * External bridges are mandatory for eDP interfaces: one has to | 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 | * For DisplayPort interfaces external bridges are optional, so | 1438 | * For DisplayPort interfaces external bridges are optional, so |
| 1515 | * silently ignore an error if one is not present (-ENODEV). | 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 | if (!dp->is_edp && rc == -ENODEV) | 1442 | if (!dp->is_edp && rc == -ENODEV) |
| 1519 | return 0; | 1443 | return 0; |
| 1520 | 1444 | ||
| 1521 | if (!rc) { | 1445 | if (!rc) |
| 1522 | dp->next_bridge = dp_priv->parser->next_bridge; | 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 | return rc; | 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 | dp_priv = container_of(dp_display, struct dp_display_private, dp_display); | 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 | ret = dp_bridge_init(dp_display, dev, encoder); | 1461 | ret = dp_bridge_init(dp_display, dev, encoder); |
| 1556 | if (ret) { | 1462 | if (ret) { |
| 1557 | DRM_DEV_ERROR(dev->dev, | 1463 | DRM_DEV_ERROR(dev->dev, |
| @@ -1593,6 +1499,11 @@ void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, · 35 unmodified lines | |||
| 1593 | dp_hpd_plug_handle(dp_display, 0); | 1499 | dp_hpd_plug_handle(dp_display, 0); |
| 1594 | 1500 | ||
| 1595 | mutex_lock(&dp_display->event_mutex); | 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 | state = dp_display->hpd_state; | 1508 | state = dp_display->hpd_state; |
| 1598 | if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) { | 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 | mutex_lock(&dp_display->event_mutex); | 1568 | mutex_lock(&dp_display->event_mutex); |
| 1658 | 1569 | ||
| 1659 | state = dp_display->hpd_state; | 1570 | state = dp_display->hpd_state; |
| 1660 | if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) { | 1571 | if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) |
| 1661 | mutex_unlock(&dp_display->event_mutex); | 1572 | drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n", |
| 1662 | return; | 1573 | dp->connector_type, state); |
| 1663 | } | ||
| 1664 | 1574 | ||
| 1665 | dp_display_disable(dp_display); | 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 | drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type); | 1585 | drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type); |
| 1586 | |||
| 1587 | pm_runtime_put_sync(&dp->pdev->dev); | ||
| 1676 | mutex_unlock(&dp_display->event_mutex); | 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 | struct msm_dp *dp_display = dp_bridge->dp_display; | 1623 | struct msm_dp *dp_display = dp_bridge->dp_display; |
| 1712 | struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display); | 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 | mutex_lock(&dp->event_mutex); | 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 | dp_catalog_ctrl_hpd_enable(dp->catalog); | 1641 | dp_catalog_ctrl_hpd_enable(dp->catalog); |
| 1716 | 1642 | ||
| 1717 | /* enable HDP interrupts */ | 1643 | /* enable HDP interrupts */ |
| @@ -1733,6 +1659,8 @@ void dp_bridge_hpd_disable(struct drm_bridge *bridge) · 15 unmodified lines | |||
| 1733 | dp_catalog_ctrl_hpd_disable(dp->catalog); | 1659 | dp_catalog_ctrl_hpd_disable(dp->catalog); |
| 1734 | 1660 | ||
| 1735 | dp_display->internal_hpd = false; | 1661 | dp_display->internal_hpd = false; |
| 1662 | |||
| 1663 | pm_runtime_put_sync(&dp_display->pdev->dev); | ||
| 1736 | mutex_unlock(&dp->event_mutex); | 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 | if (dp_display->internal_hpd) | 1675 | if (dp_display->internal_hpd) |
| 1748 | return; | 1676 | return; |
| 1749 | 1677 | ||
| 1750 | if (!dp->core_initialized) { | 1678 | if (!dp_display->link_ready && status == connector_status_connected) |
| 1751 | drm_dbg_dp(dp->drm_dev, "not initialized\n"); | ||
| 1752 | return; | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | if (!dp_display->is_connected && status == connector_status_connected) | ||
| 1756 | dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0); | 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 | dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0); | 1681 | dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0); |
| 1759 | } | 1682 | } |
| @@ -17,7 +17,7 @@ struct msm_dp { · 16 unmodified lines | |||
| 17 | struct drm_bridge *bridge; | 17 | struct drm_bridge *bridge; |
| 18 | struct drm_connector *connector; | 18 | struct drm_connector *connector; |
| 19 | struct drm_bridge *next_bridge; | 19 | struct drm_bridge *next_bridge; |
| 20 | bool is_connected; | 20 | bool link_ready; |
| 21 | bool audio_enabled; | 21 | bool audio_enabled; |
| 22 | bool power_on; | 22 | bool power_on; |
| 23 | unsigned int connector_type; | 23 | unsigned int connector_type; |
| @@ -36,11 +36,11 @@ struct msm_dp { · 12 unmodified lines | |||
| 36 | int dp_display_set_plugged_cb(struct msm_dp *dp_display, | 36 | int dp_display_set_plugged_cb(struct msm_dp *dp_display, |
| 37 | hdmi_codec_plugged_cb fn, struct device *codec_dev); | 37 | hdmi_codec_plugged_cb fn, struct device *codec_dev); |
| 38 | int dp_display_get_modes(struct msm_dp *dp_display); | 38 | int dp_display_get_modes(struct msm_dp *dp_display); |
| 39 | int dp_display_request_irq(struct msm_dp *dp_display); | ||
| 40 | bool dp_display_check_video_test(struct msm_dp *dp_display); | 39 | bool dp_display_check_video_test(struct msm_dp *dp_display); |
| 41 | int dp_display_get_test_bpp(struct msm_dp *dp_display); | 40 | int dp_display_get_test_bpp(struct msm_dp *dp_display); |
| 42 | void dp_display_signal_audio_start(struct msm_dp *dp_display); | 41 | void dp_display_signal_audio_start(struct msm_dp *dp_display); |
| 43 | void dp_display_signal_audio_complete(struct msm_dp *dp_display); | 42 | void dp_display_signal_audio_complete(struct msm_dp *dp_display); |
| 44 | void dp_display_set_psr(struct msm_dp *dp, bool enter); | 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 | #endif /* _DP_DISPLAY_H_ */ | 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 | dp = to_dp_bridge(bridge)->dp_display; | 25 | dp = to_dp_bridge(bridge)->dp_display; |
| 26 | 26 | ||
| 27 | drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", | 27 | drm_dbg_dp(dp->drm_dev, "link_ready = %s\n", |
| 28 | (dp->is_connected) ? "true" : "false"); | 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 | connector_status_disconnected; | 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 | dp = to_dp_bridge(bridge)->dp_display; | 41 | dp = to_dp_bridge(bridge)->dp_display; |
| 42 | 42 | ||
| 43 | drm_dbg_dp(dp->drm_dev, "is_connected = %s\n", | 43 | drm_dbg_dp(dp->drm_dev, "link_ready = %s\n", |
| 44 | (dp->is_connected) ? "true" : "false"); | 44 | (dp->link_ready) ? "true" : "false"); |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
| 47 | * There is no protection in the DRM framework to check if the display | 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 | * After that this piece of code can be removed. | 55 | * After that this piece of code can be removed. |
| 56 | */ | 56 | */ |
| 57 | if (bridge->ops & DRM_BRIDGE_OP_HPD) | 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 | return 0; | 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 | dp = to_dp_bridge(bridge)->dp_display; | 78 | dp = to_dp_bridge(bridge)->dp_display; |
| 79 | 79 | ||
| 80 | /* pluggable case assumes EDID is read when HPD */ | 80 | /* pluggable case assumes EDID is read when HPD */ |
| 81 | if (dp->is_connected) { | 81 | if (dp->link_ready) { |
| 82 | rc = dp_display_get_modes(dp); | 82 | rc = dp_display_get_modes(dp); |
| 83 | if (rc <= 0) { | 83 | if (rc <= 0) { |
| 84 | DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc); | 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 | return rc; | 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 | static const struct drm_bridge_funcs dp_bridge_ops = { | 100 | static const struct drm_bridge_funcs dp_bridge_ops = { |
| 94 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, | 101 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
| 95 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, | 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 | .hpd_enable = dp_bridge_hpd_enable, | 112 | .hpd_enable = dp_bridge_hpd_enable, |
| 106 | .hpd_disable = dp_bridge_hpd_disable, | 113 | .hpd_disable = dp_bridge_hpd_disable, |
| 107 | .hpd_notify = dp_bridge_hpd_notify, | 114 | .hpd_notify = dp_bridge_hpd_notify, |
| 115 | .debugfs_init = dp_bridge_debugfs_init, | ||
| 108 | }; | 116 | }; |
| 109 | 117 | ||
| 110 | static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge, | 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 | return MODE_OK; | 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 | static const struct drm_bridge_funcs edp_bridge_ops = { | 278 | static const struct drm_bridge_funcs edp_bridge_ops = { |
| 264 | .atomic_enable = edp_bridge_atomic_enable, | 279 | .atomic_enable = edp_bridge_atomic_enable, |
| 265 | .atomic_disable = edp_bridge_atomic_disable, | 280 | .atomic_disable = edp_bridge_atomic_disable, |
| @@ -270,6 +285,7 @@ static const struct drm_bridge_funcs edp_bridge_ops = { · 4 unmodified lines | |||
| 270 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, | 285 | .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, |
| 271 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, | 286 | .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, |
| 272 | .atomic_check = edp_bridge_atomic_check, | 287 | .atomic_check = edp_bridge_atomic_check, |
| 288 | .debugfs_init = edp_bridge_debugfs_init, | ||
| 273 | }; | 289 | }; |
| 274 | 290 | ||
| 275 | int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev, | 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 | power = container_of(dp_power, struct dp_power_private, dp_power); | 153 | power = container_of(dp_power, struct dp_power_private, dp_power); |
| 154 | 154 | ||
| 155 | pm_runtime_enable(power->dev); | ||
| 156 | |||
| 157 | return dp_power_clk_init(power); | 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 | int dp_power_init(struct dp_power *dp_power) | 158 | int dp_power_init(struct dp_power *dp_power) |
| 170 | { | 159 | { |
| 171 | int rc = 0; | 160 | return dp_power_clk_enable(dp_power, DP_CORE_PM, true); |
| 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; | ||
| 183 | } | 161 | } |
| 184 | 162 | ||
| 185 | int dp_power_deinit(struct dp_power *dp_power) | 163 | int dp_power_deinit(struct dp_power *dp_power) |
| 186 | { | 164 | { |
| 187 | struct dp_power_private *power; | 165 | return dp_power_clk_enable(dp_power, DP_CORE_PM, false); |
| 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; | ||
| 194 | } | 166 | } |
| 195 | 167 | ||
| 196 | struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser) | 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 | int dp_power_client_init(struct dp_power *power); | 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 | * dp_power_get() - configure and get the DisplayPort power module data | 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 | static const struct regulator_bulk_data sc7280_dsi_regulators[] = { | 208 | static const struct regulator_bulk_data sc7280_dsi_regulators[] = { |
| 194 | { .supply = "vdda", .init_load_uA = 8350 }, /* 1.2 V */ | 209 | { .supply = "vdda", .init_load_uA = 8350 }, /* 1.2 V */ |
| 195 | { .supply = "refgen" }, | 210 | { .supply = "refgen" }, |
| @@ -281,6 +296,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { · 85 unmodified lines | |||
| 281 | &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops}, | 296 | &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops}, |
| 282 | {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0, | 297 | {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0, |
| 283 | &sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops}, | 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 | const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor) | 303 | const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor) |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | |||
| 28 | #define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000 | 28 | #define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000 |
| 29 | #define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000 | 29 | #define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000 |
| 30 | #define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000 | 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 | #define MSM_DSI_V2_VER_MINOR_8064 0x0 | 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 | struct device *dev = &phy->pdev->dev; | 516 | struct device *dev = &phy->pdev->dev; |
| 517 | int ret; | 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 | ret = clk_prepare_enable(phy->ahb_clk); | 523 | ret = clk_prepare_enable(phy->ahb_clk); |
| 522 | if (ret) { | 524 | if (ret) { |
| @@ -585,6 +587,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { · 62 unmodified lines | |||
| 585 | .data = &dsi_phy_5nm_8450_cfgs }, | 587 | .data = &dsi_phy_5nm_8450_cfgs }, |
| 586 | { .compatible = "qcom,sm8550-dsi-phy-4nm", | 588 | { .compatible = "qcom,sm8550-dsi-phy-4nm", |
| 587 | .data = &dsi_phy_4nm_8550_cfgs }, | 589 | .data = &dsi_phy_4nm_8550_cfgs }, |
| 590 | { .compatible = "qcom,sm8650-dsi-phy-4nm", | ||
| 591 | .data = &dsi_phy_4nm_8650_cfgs }, | ||
| 588 | #endif | 592 | #endif |
| 589 | {} | 593 | {} |
| 590 | }; | 594 | }; |
| @@ -689,6 +693,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) · 98 unmodified lines | |||
| 689 | return dev_err_probe(dev, PTR_ERR(phy->ahb_clk), | 693 | return dev_err_probe(dev, PTR_ERR(phy->ahb_clk), |
| 690 | "Unable to get ahb clk\n"); | 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 | /* PLL init will call into clk_register which requires | 700 | /* PLL init will call into clk_register which requires |
| 693 | * register access, so we need to enable power and ahb clock. | 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 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs; | 62 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs; |
| 63 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs; | 63 | extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs; |
| 64 | extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs; | 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 | struct msm_dsi_dphy_timing { | 67 | struct msm_dsi_dphy_timing { |
| 67 | u32 clk_zero; | 68 | u32 clk_zero; |
| @@ -1121,6 +1121,10 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = { · 1120 unmodified lines | |||
| 1121 | { .supply = "vdds", .init_load_uA = 37550 }, | 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 | static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = { | 1128 | static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = { |
| 1125 | { .supply = "vdds", .init_load_uA = 97800 }, | 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 | .num_dsi_phy = 2, | 1285 | .num_dsi_phy = 2, |
| 1282 | .quirks = DSI_PHY_7NM_QUIRK_V5_2, | 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 | return ret; | 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 | struct drm_device *dev = minor->dev; | 309 | struct drm_device *dev = minor->dev; |
| 310 | struct msm_drm_private *priv = dev->dev_private; | 310 | struct msm_drm_private *priv = dev->dev_private; |
| 311 | struct dentry *gpu_devfreq; | 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 | debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, | 313 | debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, |
| 318 | dev, &msm_gpu_fops); | 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 | debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, | 316 | debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, |
| 329 | &priv->hangcheck_period); | 317 | &priv->hangcheck_period); |
| 330 | 318 | ||
| 331 | debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, | 319 | debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, |
| 332 | &priv->disable_err_irq); | 320 | &priv->disable_err_irq); |
| 333 | 321 | ||
| 334 | debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, | ||
| 335 | dev, &shrink_fops); | ||
| 336 | |||
| 337 | gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root); | 322 | gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root); |
| 338 | 323 | ||
| 339 | debugfs_create_bool("idle_clamp",0600, gpu_devfreq, | 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 | debugfs_create_u32("downdifferential",0600, gpu_devfreq, | 330 | debugfs_create_u32("downdifferential",0600, gpu_devfreq, |
| 346 | &priv->gpu_devfreq_config.downdifferential); | 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 | if (priv->kms && priv->kms->funcs->debugfs_init) | 357 | if (priv->kms && priv->kms->funcs->debugfs_init) |
| 349 | priv->kms->funcs->debugfs_init(priv->kms, minor); | 358 | priv->kms->funcs->debugfs_init(priv->kms, minor); |
| @@ -37,9 +37,10 @@ · 36 unmodified lines | |||
| 37 | * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN | 37 | * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN |
| 38 | * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT | 38 | * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT |
| 39 | * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST) | 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 | #define MSM_VERSION_MAJOR 1 | 42 | #define MSM_VERSION_MAJOR 1 |
| 42 | #define MSM_VERSION_MINOR 10 | 43 | #define MSM_VERSION_MINOR 12 |
| 43 | #define MSM_VERSION_PATCHLEVEL 0 | 44 | #define MSM_VERSION_PATCHLEVEL 0 |
| 44 | 45 | ||
| 45 | static void msm_deinit_vram(struct drm_device *ddev); | 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 | return msm_gem_set_iova(obj, ctx->aspace, iova); | 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 | static int msm_ioctl_gem_info(struct drm_device *dev, void *data, | 627 | static int msm_ioctl_gem_info(struct drm_device *dev, void *data, |
| 548 | struct drm_file *file) | 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 | break; | 646 | break; |
| 567 | case MSM_INFO_SET_NAME: | 647 | case MSM_INFO_SET_NAME: |
| 568 | case MSM_INFO_GET_NAME: | 648 | case MSM_INFO_GET_NAME: |
| 649 | case MSM_INFO_SET_METADATA: | ||
| 650 | case MSM_INFO_GET_METADATA: | ||
| 569 | break; | 651 | break; |
| 570 | default: | 652 | default: |
| 571 | return -EINVAL; | 653 | return -EINVAL; |
| @@ -618,7 +700,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 46 unmodified lines | |||
| 618 | break; | 700 | break; |
| 619 | case MSM_INFO_GET_NAME: | 701 | case MSM_INFO_GET_NAME: |
| 620 | if (args->value && (args->len < strlen(msm_obj->name))) { | 702 | if (args->value && (args->len < strlen(msm_obj->name))) { |
| 621 | ret = -EINVAL; | 703 | ret = -ETOOSMALL; |
| 622 | break; | 704 | break; |
| 623 | } | 705 | } |
| 624 | args->len = strlen(msm_obj->name); | 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 | ret = -EFAULT; | 710 | ret = -EFAULT; |
| 629 | } | 711 | } |
| 630 | break; | 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 | drm_gem_object_put(obj); | 723 | drm_gem_object_put(obj); |
| @@ -78,12 +78,10 @@ enum msm_dsi_controller { · 77 unmodified lines | |||
| 78 | * enum msm_event_wait - type of HW events to wait for | 78 | * enum msm_event_wait - type of HW events to wait for |
| 79 | * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW | 79 | * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW |
| 80 | * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel | 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 | enum msm_event_wait { | 82 | enum msm_event_wait { |
| 84 | MSM_ENC_COMMIT_DONE = 0, | 83 | MSM_ENC_COMMIT_DONE = 0, |
| 85 | MSM_ENC_TX_COMPLETE, | 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 | * @num_intf: number of interfaces the panel is mounted on | 90 | * @num_intf: number of interfaces the panel is mounted on |
| 93 | * @num_dspp: number of dspp blocks used | 91 | * @num_dspp: number of dspp blocks used |
| 94 | * @num_dsc: number of Display Stream Compression (DSC) blocks used | 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 | struct msm_display_topology { | 95 | struct msm_display_topology { |
| 97 | u32 num_lm; | 96 | u32 num_lm; |
| 98 | u32 num_intf; | 97 | u32 num_intf; |
| 99 | u32 num_dspp; | 98 | u32 num_dspp; |
| 100 | u32 num_dsc; | 99 | u32 num_dsc; |
| 100 | bool needs_cdm; | ||
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | /* Commit/Event thread specific structure */ | 103 | /* Commit/Event thread specific structure */ |
| @@ -386,10 +386,8 @@ int __init msm_dp_register(void); · 282 unmodified lines | |||
| 386 | void __exit msm_dp_unregister(void); | 386 | void __exit msm_dp_unregister(void); |
| 387 | int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, | 387 | int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, |
| 388 | struct drm_encoder *encoder); | 388 | struct drm_encoder *encoder); |
| 389 | void msm_dp_irq_postinstall(struct msm_dp *dp_display); | ||
| 390 | void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display); | 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 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display); | 391 | bool msm_dp_wide_bus_available(const struct msm_dp *dp_display); |
| 394 | 392 | ||
| 395 | #else | 393 | #else |
| @@ -407,19 +405,10 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display, · 11 unmodified lines | |||
| 407 | return -EINVAL; | 405 | return -EINVAL; |
| 408 | } | 406 | } |
| 409 | 407 | ||
| 410 | static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display) | ||
| 411 | { | ||
| 412 | } | ||
| 413 | |||
| 414 | static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display) | 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 | static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) | 412 | static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) |
| 424 | { | 413 | { |
| 425 | return false; | 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 | msm_gem_assert_locked(obj); | 227 | msm_gem_assert_locked(obj); |
| 228 | 228 | ||
| 229 | if (GEM_WARN_ON(msm_obj->madv > madv)) { | 229 | if (msm_obj->madv > madv) { |
| 230 | DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n", | 230 | DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n", |
| 231 | msm_obj->madv, madv); | 231 | msm_obj->madv, madv); |
| 232 | return ERR_PTR(-EBUSY); | 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 | drm_gem_object_release(obj); | 1059 | drm_gem_object_release(obj); |
| 1060 | 1060 | ||
| 1061 | kfree(msm_obj->metadata); | ||
| 1061 | kfree(msm_obj); | 1062 | kfree(msm_obj); |
| 1062 | } | 1063 | } |
| 1063 | 1064 | ||
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include <linux/kref.h> | 10 | #include <linux/kref.h> |
| 11 | #include <linux/dma-resv.h> | 11 | #include <linux/dma-resv.h> |
| 12 | #include "drm/drm_exec.h" | ||
| 12 | #include "drm/gpu_scheduler.h" | 13 | #include "drm/gpu_scheduler.h" |
| 13 | #include "msm_drv.h" | 14 | #include "msm_drv.h" |
| 14 | 15 | ||
| @@ -108,6 +109,10 @@ struct msm_gem_object { · 93 unmodified lines | |||
| 108 | 109 | ||
| 109 | char name[32]; /* Identifier to print for the debugfs files */ | 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 | * pin_count: Number of times the pages are pinned | 117 | * pin_count: Number of times the pages are pinned |
| 113 | * | 118 | * |
| @@ -254,7 +259,7 @@ struct msm_gem_submit { · 140 unmodified lines | |||
| 254 | struct msm_gpu *gpu; | 259 | struct msm_gpu *gpu; |
| 255 | struct msm_gem_address_space *aspace; | 260 | struct msm_gem_address_space *aspace; |
| 256 | struct list_head node; /* node in ring submit list */ | 261 | struct list_head node; /* node in ring submit list */ |
| 257 | struct ww_acquire_ctx ticket; | 262 | struct drm_exec exec; |
| 258 | uint32_t seqno; /* Sequence number of the submit on the ring */ | 263 | uint32_t seqno; /* Sequence number of the submit on the ring */ |
| 259 | 264 | ||
| 260 | /* Hw fence, which is created when the scheduler executes the job, and | 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 | int fence_id; /* key into queue->fence_idr */ | 275 | int fence_id; /* key into queue->fence_idr */ |
| 271 | struct msm_gpu_submitqueue *queue; | 276 | struct msm_gpu_submitqueue *queue; |
| 272 | struct pid *pid; /* submitting process */ | 277 | struct pid *pid; /* submitting process */ |
| 273 | bool fault_dumped; /* Limit devcoredump dumping to one per submit */ | 278 | bool bos_pinned : 1; |
| 274 | bool valid; /* true if no cmdstream patching needed */ | 279 | bool fault_dumped:1;/* Limit devcoredump dumping to one per submit */ |
| 275 | bool in_rb; /* "sudo" mode, copy cmds into RB */ | 280 | bool in_rb : 1; /* "sudo" mode, copy cmds into RB */ |
| 276 | struct msm_ringbuffer *ring; | 281 | struct msm_ringbuffer *ring; |
| 277 | unsigned int nr_cmds; | 282 | unsigned int nr_cmds; |
| 278 | unsigned int nr_bos; | 283 | unsigned int nr_bos; |
| @@ -287,10 +292,6 @@ struct msm_gem_submit { · 8 unmodified lines | |||
| 287 | struct drm_msm_gem_submit_reloc *relocs; | 292 | struct drm_msm_gem_submit_reloc *relocs; |
| 288 | } *cmd; /* array of size nr_cmds */ | 293 | } *cmd; /* array of size nr_cmds */ |
| 289 | struct { | 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 | uint32_t flags; | 295 | uint32_t flags; |
| 295 | union { | 296 | union { |
| 296 | struct drm_gem_object *obj; | 297 | struct drm_gem_object *obj; |
| @@ -75,7 +75,7 @@ static bool · 74 unmodified lines | |||
| 75 | wait_for_idle(struct drm_gem_object *obj) | 75 | wait_for_idle(struct drm_gem_object *obj) |
| 76 | { | 76 | { |
| 77 | enum dma_resv_usage usage = dma_resv_usage_rw(true); | 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 | static bool | 81 | static bool |
| @@ -17,6 +17,12 @@ · 16 unmodified lines | |||
| 17 | #include "msm_gem.h" | 17 | #include "msm_gem.h" |
| 18 | #include "msm_gpu_trace.h" | 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 | * Cmdstream submission: | 27 | * Cmdstream submission: |
| 22 | */ | 28 | */ |
| @@ -37,7 +43,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 14 unmodified lines | |||
| 37 | if (sz > SIZE_MAX) | 43 | if (sz > SIZE_MAX) |
| 38 | return ERR_PTR(-ENOMEM); | 44 | return ERR_PTR(-ENOMEM); |
| 39 | 45 | ||
| 40 | submit = kzalloc(sz, GFP_KERNEL); | 46 | submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); |
| 41 | if (!submit) | 47 | if (!submit) |
| 42 | return ERR_PTR(-ENOMEM); | 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 | if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || | 143 | if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || |
| 138 | !(submit_bo.flags & MANDATORY_FLAGS)) { | 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 | ret = -EINVAL; | 146 | ret = -EINVAL; |
| 141 | i = 0; | 147 | i = 0; |
| 142 | goto out; | 148 | goto out; |
| @@ -144,8 +150,6 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 1 unmodified line | |||
| 144 | 150 | ||
| 145 | submit->bos[i].handle = submit_bo.handle; | 151 | submit->bos[i].handle = submit_bo.handle; |
| 146 | submit->bos[i].flags = submit_bo.flags; | 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 | spin_lock(&file->table_lock); | 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 | obj = idr_find(&file->object_idr, submit->bos[i].handle); | 163 | obj = idr_find(&file->object_idr, submit->bos[i].handle); |
| 160 | if (!obj) { | 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 | ret = -EINVAL; | 166 | ret = -EINVAL; |
| 163 | goto out_unlock; | 167 | goto out_unlock; |
| 164 | } | 168 | } |
| @@ -202,13 +206,13 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 37 unmodified lines | |||
| 202 | case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: | 206 | case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: |
| 203 | break; | 207 | break; |
| 204 | default: | 208 | default: |
| 205 | DRM_ERROR("invalid type: %08x\n", submit_cmd.type); | 209 | SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type); |
| 206 | return -EINVAL; | 210 | return -EINVAL; |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 209 | if (submit_cmd.size % 4) { | 213 | if (submit_cmd.size % 4) { |
| 210 | DRM_ERROR("non-aligned cmdstream buffer size: %u\n", | 214 | SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n", |
| 211 | submit_cmd.size); | 215 | submit_cmd.size); |
| 212 | ret = -EINVAL; | 216 | ret = -EINVAL; |
| 213 | goto out; | 217 | goto out; |
| 214 | } | 218 | } |
| @@ -228,7 +232,7 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 13 unmodified lines | |||
| 228 | ret = -ENOMEM; | 232 | ret = -ENOMEM; |
| 229 | goto out; | 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 | if (!submit->cmd[i].relocs) { | 236 | if (!submit->cmd[i].relocs) { |
| 233 | ret = -ENOMEM; | 237 | ret = -ENOMEM; |
| 234 | goto out; | 238 | goto out; |
| @@ -244,101 +248,30 @@ out: · 9 unmodified lines | |||
| 244 | return ret; | 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 | /* This is where we make sure all the bo's are reserved and pin'd: */ | 251 | /* This is where we make sure all the bo's are reserved and pin'd: */ |
| 281 | static int submit_lock_objects(struct msm_gem_submit *submit) | 252 | static int submit_lock_objects(struct msm_gem_submit *submit) |
| 282 | { | 253 | { |
| 283 | int contended, slow_locked = -1, i, ret = 0; | 254 | int ret; |
| 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; | ||
| 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)) { | 258 | drm_exec_until_all_locked (&submit->exec) { |
| 295 | ret = dma_resv_lock_interruptible(obj->resv, | 259 | for (unsigned i = 0; i < submit->nr_bos; i++) { |
| 296 | &submit->ticket); | 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 | if (ret) | 263 | if (ret) |
| 298 | goto fail; | 264 | goto error; |
| 299 | submit->bos[i].flags |= BO_LOCKED; | ||
| 300 | } | 265 | } |
| 301 | } | 266 | } |
| 302 | 267 | ||
| 303 | ww_acquire_done(&submit->ticket); | ||
| 304 | |||
| 305 | return 0; | 268 | return 0; |
| 306 | 269 | ||
| 307 | fail: | 270 | error: |
| 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 | |||
| 338 | return ret; | 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 | int i, ret = 0; | 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 | struct drm_gem_object *obj = submit->bos[i].obj; | 279 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 347 | bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE; | 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 | /* Otherwise userspace can ask for implicit sync to be | 282 | /* Otherwise userspace can ask for implicit sync to be |
| 366 | * disabled on specific buffers. This is useful for internal | 283 | * disabled on specific buffers. This is useful for internal |
| 367 | * usermode driver managed buffers, suballocation, etc. | 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 | struct msm_drm_private *priv = submit->dev->dev_private; | 301 | struct msm_drm_private *priv = submit->dev->dev_private; |
| 385 | int i, ret = 0; | 302 | int i, ret = 0; |
| 386 | 303 | ||
| 387 | submit->valid = true; | ||
| 388 | |||
| 389 | for (i = 0; i < submit->nr_bos; i++) { | 304 | for (i = 0; i < submit->nr_bos; i++) { |
| 390 | struct drm_gem_object *obj = submit->bos[i].obj; | 305 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 391 | struct msm_gem_vma *vma; | 306 | struct msm_gem_vma *vma; |
| @@ -401,14 +316,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 9 unmodified lines | |||
| 401 | if (ret) | 316 | if (ret) |
| 402 | break; | 317 | break; |
| 403 | 318 | ||
| 404 | if (vma->iova == submit->bos[i].iova) { | 319 | submit->bos[i].iova = vma->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 | } | ||
| 412 | } | 320 | } |
| 413 | 321 | ||
| 414 | /* | 322 | /* |
| @@ -421,13 +329,28 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 6 unmodified lines | |||
| 421 | mutex_lock(&priv->lru.lock); | 329 | mutex_lock(&priv->lru.lock); |
| 422 | for (i = 0; i < submit->nr_bos; i++) { | 330 | for (i = 0; i < submit->nr_bos; i++) { |
| 423 | msm_gem_pin_obj_locked(submit->bos[i].obj); | 331 | msm_gem_pin_obj_locked(submit->bos[i].obj); |
| 424 | submit->bos[i].flags |= BO_PINNED; | ||
| 425 | } | 332 | } |
| 426 | mutex_unlock(&priv->lru.lock); | 333 | mutex_unlock(&priv->lru.lock); |
| 427 | 334 | ||
| 335 | submit->bos_pinned = true; | ||
| 336 | |||
| 428 | return ret; | 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 | static void submit_attach_object_fences(struct msm_gem_submit *submit) | 354 | static void submit_attach_object_fences(struct msm_gem_submit *submit) |
| 432 | { | 355 | { |
| 433 | int i; | 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 | static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, | 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 | if (idx >= submit->nr_bos) { | 373 | if (idx >= submit->nr_bos) { |
| 451 | DRM_ERROR("invalid buffer index: %u (out of %u)\n", | 374 | SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n", |
| 452 | idx, submit->nr_bos); | 375 | idx, submit->nr_bos); |
| 453 | return -EINVAL; | 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 | *obj = submit->bos[idx].obj; | 380 | *obj = submit->bos[idx].obj; |
| 458 | if (iova) | 381 | if (iova) |
| 459 | *iova = submit->bos[idx].iova; | 382 | *iova = submit->bos[idx].iova; |
| 460 | if (valid) | ||
| 461 | *valid = !!(submit->bos[idx].flags & BO_VALID); | ||
| 462 | 383 | ||
| 463 | return 0; | 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 | uint32_t *ptr; | 392 | uint32_t *ptr; |
| 472 | int ret = 0; | 393 | int ret = 0; |
| 473 | 394 | ||
| 474 | if (!nr_relocs) | ||
| 475 | return 0; | ||
| 476 | |||
| 477 | if (offset % 4) { | 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 | return -EINVAL; | 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 | struct drm_msm_gem_submit_reloc submit_reloc = relocs[i]; | 412 | struct drm_msm_gem_submit_reloc submit_reloc = relocs[i]; |
| 495 | uint32_t off; | 413 | uint32_t off; |
| 496 | uint64_t iova; | 414 | uint64_t iova; |
| 497 | bool valid; | ||
| 498 | 415 | ||
| 499 | if (submit_reloc.submit_offset % 4) { | 416 | if (submit_reloc.submit_offset % 4) { |
| 500 | DRM_ERROR("non-aligned reloc offset: %u\n", | 417 | SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n", |
| 501 | submit_reloc.submit_offset); | 418 | submit_reloc.submit_offset); |
| 502 | ret = -EINVAL; | 419 | ret = -EINVAL; |
| 503 | goto out; | 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 | if ((off >= (obj->size / 4)) || | 426 | if ((off >= (obj->size / 4)) || |
| 510 | (off < last_offset)) { | 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 | ret = -EINVAL; | 429 | ret = -EINVAL; |
| 513 | goto out; | 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 | if (ret) | 434 | if (ret) |
| 518 | goto out; | 435 | goto out; |
| 519 | 436 | ||
| 520 | if (valid) | ||
| 521 | continue; | ||
| 522 | |||
| 523 | iova += submit_reloc.reloc_offset; | 437 | iova += submit_reloc.reloc_offset; |
| 524 | 438 | ||
| 525 | if (submit_reloc.shift < 0) | 439 | if (submit_reloc.shift < 0) |
| @@ -544,18 +458,14 @@ out: · 18 unmodified lines | |||
| 544 | */ | 458 | */ |
| 545 | static void submit_cleanup(struct msm_gem_submit *submit, bool error) | 459 | static void submit_cleanup(struct msm_gem_submit *submit, bool error) |
| 546 | { | 460 | { |
| 547 | unsigned cleanup_flags = BO_LOCKED; | 461 | if (error) { |
| 548 | unsigned i; | 462 | submit_unpin_objects(submit); |
| 549 | 463 | /* job wasn't enqueued to scheduler, so early retirement: */ | |
| 550 | if (error) | 464 | msm_submit_retire(submit); |
| 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); | ||
| 558 | } | 465 | } |
| 466 | |||
| 467 | if (submit->exec.objects) | ||
| 468 | drm_exec_fini(&submit->exec); | ||
| 559 | } | 469 | } |
| 560 | 470 | ||
| 561 | void msm_submit_retire(struct msm_gem_submit *submit) | 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 | struct msm_submit_post_dep *post_deps = NULL; | 659 | struct msm_submit_post_dep *post_deps = NULL; |
| 750 | struct drm_syncobj **syncobjs_to_reset = NULL; | 660 | struct drm_syncobj **syncobjs_to_reset = NULL; |
| 751 | int out_fence_fd = -1; | 661 | int out_fence_fd = -1; |
| 752 | bool has_ww_ticket = false; | ||
| 753 | unsigned i; | 662 | unsigned i; |
| 754 | int ret; | 663 | int ret; |
| 755 | 664 | ||
| @@ -855,15 +764,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 99 unmodified lines | |||
| 855 | goto out; | 764 | goto out; |
| 856 | 765 | ||
| 857 | /* copy_*_user while holding a ww ticket upsets lockdep */ | 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 | ret = submit_lock_objects(submit); | 767 | ret = submit_lock_objects(submit); |
| 861 | if (ret) | 768 | if (ret) |
| 862 | goto out; | 769 | goto out; |
| 863 | 770 | ||
| 864 | ret = submit_fence_sync(submit, !!(args->flags & MSM_SUBMIT_NO_IMPLICIT)); | 771 | if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) { |
| 865 | if (ret) | 772 | ret = submit_fence_sync(submit); |
| 866 | goto out; | 773 | if (ret) |
| 774 | goto out; | ||
| 775 | } | ||
| 867 | 776 | ||
| 868 | ret = submit_pin_objects(submit); | 777 | ret = submit_pin_objects(submit); |
| 869 | if (ret) | 778 | if (ret) |
| @@ -873,32 +782,27 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 3 unmodified lines | |||
| 873 | struct drm_gem_object *obj; | 782 | struct drm_gem_object *obj; |
| 874 | uint64_t iova; | 783 | uint64_t iova; |
| 875 | 784 | ||
| 876 | ret = submit_bo(submit, submit->cmd[i].idx, | 785 | ret = submit_bo(submit, submit->cmd[i].idx, &obj, &iova); |
| 877 | &obj, &iova, NULL); | ||
| 878 | if (ret) | 786 | if (ret) |
| 879 | goto out; | 787 | goto out; |
| 880 | 788 | ||
| 881 | if (!submit->cmd[i].size || | 789 | if (!submit->cmd[i].size || |
| 882 | ((submit->cmd[i].size + submit->cmd[i].offset) > | 790 | ((submit->cmd[i].size + submit->cmd[i].offset) > |
| 883 | obj->size / 4)) { | 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 | ret = -EINVAL; | 793 | ret = -EINVAL; |
| 886 | goto out; | 794 | goto out; |
| 887 | } | 795 | } |
| 888 | 796 | ||
| 889 | submit->cmd[i].iova = iova + (submit->cmd[i].offset * 4); | 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 | continue; | 800 | continue; |
| 893 | 801 | ||
| 894 | if (!gpu->allow_relocs) { | 802 | if (!gpu->allow_relocs) { |
| 895 | if (submit->cmd[i].nr_relocs) { | 803 | SUBMIT_ERROR(submit, "relocs not allowed\n"); |
| 896 | DRM_ERROR("relocs not allowed\n"); | 804 | ret = -EINVAL; |
| 897 | ret = -EINVAL; | 805 | goto out; |
| 898 | goto out; | ||
| 899 | } | ||
| 900 | |||
| 901 | continue; | ||
| 902 | } | 806 | } |
| 903 | 807 | ||
| 904 | ret = submit_reloc(submit, obj, submit->cmd[i].offset * 4, | 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 | submit_attach_object_fences(submit); | 884 | submit_attach_object_fences(submit); |
| 978 | 885 | ||
| 979 | /* The scheduler owns a ref now: */ | 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 | out: | 901 | out: |
| 995 | submit_cleanup(submit, !!ret); | 902 | submit_cleanup(submit, !!ret); |
| 996 | if (has_ww_ticket) | ||
| 997 | ww_acquire_fini(&submit->ticket); | ||
| 998 | out_unlock: | 903 | out_unlock: |
| 999 | mutex_unlock(&queue->lock); | 904 | mutex_unlock(&queue->lock); |
| 1000 | out_post_unlock: | 905 | out_post_unlock: |
| @@ -292,8 +292,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, · 291 unmodified lines | |||
| 292 | /* Set the active crash state to be dumped on failure */ | 292 | /* Set the active crash state to be dumped on failure */ |
| 293 | gpu->crashstate = state; | 293 | gpu->crashstate = state; |
| 294 | 294 | ||
| 295 | /* FIXME: Release the crashstate if this errors out? */ | 295 | dev_coredumpm(&gpu->pdev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL, |
| 296 | dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL, | ||
| 297 | msm_gpu_devcoredump_read, msm_gpu_devcoredump_free); | 296 | msm_gpu_devcoredump_read, msm_gpu_devcoredump_free); |
| 298 | } | 297 | } |
| 299 | #else | 298 | #else |
| @@ -366,29 +365,31 @@ static void recover_worker(struct kthread_work *work) · 66 unmodified lines | |||
| 366 | DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name); | 365 | DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name); |
| 367 | 366 | ||
| 368 | submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); | 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) { | 376 | /* Increment the fault counts */ |
| 378 | DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", | 377 | submit->queue->faults++; |
| 379 | gpu->name, comm, cmd); | 378 | if (submit->aspace) |
| 379 | submit->aspace->faults++; | ||
| 380 | 380 | ||
| 381 | msm_rd_dump_submit(priv->hangrd, submit, | 381 | get_comm_cmdline(submit, &comm, &cmd); |
| 382 | "offending task: %s (%s)", comm, cmd); | 382 | |
| 383 | } else { | 383 | if (comm && cmd) { |
| 384 | msm_rd_dump_submit(priv->hangrd, submit, NULL); | 384 | DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", |
| 385 | } | 385 | gpu->name, comm, cmd); |
| 386 | |||
| 387 | msm_rd_dump_submit(priv->hangrd, submit, | ||
| 388 | "offending task: %s (%s)", comm, cmd); | ||
| 386 | } else { | 389 | } else { |
| 387 | /* | 390 | DRM_DEV_ERROR(dev->dev, "%s: offending task: unknown\n", gpu->name); |
| 388 | * We couldn't attribute this fault to any particular context, | 391 | |
| 389 | * so increment the global fault count instead. | 392 | msm_rd_dump_submit(priv->hangrd, submit, NULL); |
| 390 | */ | ||
| 391 | gpu->global_faults++; | ||
| 392 | } | 393 | } |
| 393 | 394 | ||
| 394 | /* Record the crash state */ | 395 | /* Record the crash state */ |
| @@ -441,6 +442,7 @@ static void recover_worker(struct kthread_work *work) · 46 unmodified lines | |||
| 441 | 442 | ||
| 442 | pm_runtime_put(&gpu->pdev->dev); | 443 | pm_runtime_put(&gpu->pdev->dev); |
| 443 | 444 | ||
| 445 | out_unlock: | ||
| 444 | mutex_unlock(&gpu->lock); | 446 | mutex_unlock(&gpu->lock); |
| 445 | 447 | ||
| 446 | msm_gpu_retire(gpu); | 448 | msm_gpu_retire(gpu); |
| @@ -28,6 +28,8 @@ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | #define MIN_IB_BW 400000000UL /* Min ib vote 400MB */ | 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 | struct msm_mdss { | 33 | struct msm_mdss { |
| 32 | struct device *dev; | 34 | struct device *dev; |
| 33 | 35 | ||
| @@ -40,8 +42,9 @@ struct msm_mdss { · 6 unmodified lines | |||
| 40 | struct irq_domain *domain; | 42 | struct irq_domain *domain; |
| 41 | } irq_controller; | 43 | } irq_controller; |
| 42 | const struct msm_mdss_data *mdss_data; | 44 | const struct msm_mdss_data *mdss_data; |
| 43 | struct icc_path *path[2]; | 45 | struct icc_path *mdp_path[2]; |
| 44 | u32 num_paths; | 46 | u32 num_mdp_paths; |
| 47 | struct icc_path *reg_bus_path; | ||
| 45 | }; | 48 | }; |
| 46 | 49 | ||
| 47 | static int msm_mdss_parse_data_bus_icc_path(struct device *dev, | 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 | struct icc_path *path0; | 53 | struct icc_path *path0; |
| 51 | struct icc_path *path1; | 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 | if (IS_ERR_OR_NULL(path0)) | 58 | if (IS_ERR_OR_NULL(path0)) |
| 55 | return PTR_ERR_OR_ZERO(path0); | 59 | return PTR_ERR_OR_ZERO(path0); |
| 56 | 60 | ||
| 57 | msm_mdss->path[0] = path0; | 61 | msm_mdss->mdp_path[0] = path0; |
| 58 | msm_mdss->num_paths = 1; | 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 | if (!IS_ERR_OR_NULL(path1)) { | 65 | if (!IS_ERR_OR_NULL(path1)) { |
| 62 | msm_mdss->path[1] = path1; | 66 | msm_mdss->mdp_path[1] = path1; |
| 63 | msm_mdss->num_paths++; | 67 | msm_mdss->num_mdp_paths++; |
| 64 | } | 68 | } |
| 65 | 69 | ||
| 66 | return 0; | 70 | reg_bus_path = of_icc_get(dev, "cpu-cfg"); |
| 67 | } | 71 | if (!IS_ERR_OR_NULL(reg_bus_path)) |
| 68 | 72 | msm_mdss->reg_bus_path = reg_bus_path; | |
| 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; | ||
| 81 | 73 | ||
| 82 | for (i = 0; i < msm_mdss->num_paths; i++) | 74 | return 0; |
| 83 | icc_set_bw(msm_mdss->path[i], 0, Bps_to_icc(bw)); | ||
| 84 | } | 75 | } |
| 85 | 76 | ||
| 86 | static void msm_mdss_irq(struct irq_desc *desc) | 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 | static int msm_mdss_enable(struct msm_mdss *msm_mdss) | 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 | * Several components have AXI clocks that can only be turned on if | 233 | * Several components have AXI clocks that can only be turned on if |
| 243 | * the interconnect is enabled (non-zero bandwidth). Let's make sure | 234 | * the interconnect is enabled (non-zero bandwidth). Let's make sure |
| 244 | * that the interconnects are at least at a minimum amount. | 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 | ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks); | 247 | ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks); |
| 249 | if (ret) { | 248 | if (ret) { |
| @@ -295,8 +294,15 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) · 45 unmodified lines | |||
| 295 | 294 | ||
| 296 | static int msm_mdss_disable(struct msm_mdss *msm_mdss) | 295 | static int msm_mdss_disable(struct msm_mdss *msm_mdss) |
| 297 | { | 296 | { |
| 297 | int i; | ||
| 298 | |||
| 298 | clk_bulk_disable_unprepare(msm_mdss->num_clocks, msm_mdss->clocks); | 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 | return 0; | 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 | if (!msm_mdss) | 390 | if (!msm_mdss) |
| 385 | return ERR_PTR(-ENOMEM); | 391 | return ERR_PTR(-ENOMEM); |
| 386 | 392 | ||
| 393 | msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev); | ||
| 394 | |||
| 387 | msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss"); | 395 | msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss"); |
| 388 | if (IS_ERR(msm_mdss->mmio)) | 396 | if (IS_ERR(msm_mdss->mmio)) |
| 389 | return ERR_CAST(msm_mdss->mmio); | 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 | dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio); | 399 | dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio); |
| 392 | 400 | ||
| 393 | ret = msm_mdss_parse_data_bus_icc_path(&pdev->dev, msm_mdss); | 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 | if (ret) | 402 | if (ret) |
| 398 | return ERR_PTR(ret); | 403 | return ERR_PTR(ret); |
| 399 | 404 | ||
| @@ -477,8 +482,6 @@ static int mdss_probe(struct platform_device *pdev) · 77 unmodified lines | |||
| 477 | if (IS_ERR(mdss)) | 482 | if (IS_ERR(mdss)) |
| 478 | return PTR_ERR(mdss); | 483 | return PTR_ERR(mdss); |
| 479 | 484 | ||
| 480 | mdss->mdss_data = of_device_get_match_data(&pdev->dev); | ||
| 481 | |||
| 482 | platform_set_drvdata(pdev, mdss); | 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 | .ubwc_enc_version = UBWC_1_0, | 513 | .ubwc_enc_version = UBWC_1_0, |
| 511 | .ubwc_dec_version = UBWC_1_0, | 514 | .ubwc_dec_version = UBWC_1_0, |
| 512 | .highest_bank_bit = 2, | 515 | .highest_bank_bit = 2, |
| 516 | .reg_bus_bw = 76800, | ||
| 513 | }; | 517 | }; |
| 514 | 518 | ||
| 515 | static const struct msm_mdss_data qcm2290_data = { | 519 | static const struct msm_mdss_data qcm2290_data = { |
| 516 | /* no UBWC */ | 520 | /* no UBWC */ |
| 517 | .highest_bank_bit = 0x2, | 521 | .highest_bank_bit = 0x2, |
| 522 | .reg_bus_bw = 76800, | ||
| 518 | }; | 523 | }; |
| 519 | 524 | ||
| 520 | static const struct msm_mdss_data sc7180_data = { | 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 | .ubwc_dec_version = UBWC_2_0, | 527 | .ubwc_dec_version = UBWC_2_0, |
| 523 | .ubwc_static = 0x1e, | 528 | .ubwc_static = 0x1e, |
| 524 | .highest_bank_bit = 0x3, | 529 | .highest_bank_bit = 0x3, |
| 530 | .reg_bus_bw = 76800, | ||
| 525 | }; | 531 | }; |
| 526 | 532 | ||
| 527 | static const struct msm_mdss_data sc7280_data = { | 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 | .ubwc_static = 1, | 537 | .ubwc_static = 1, |
| 532 | .highest_bank_bit = 1, | 538 | .highest_bank_bit = 1, |
| 533 | .macrotile_mode = 1, | 539 | .macrotile_mode = 1, |
| 540 | .reg_bus_bw = 74000, | ||
| 534 | }; | 541 | }; |
| 535 | 542 | ||
| 536 | static const struct msm_mdss_data sc8180x_data = { | 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 | .ubwc_dec_version = UBWC_3_0, | 545 | .ubwc_dec_version = UBWC_3_0, |
| 539 | .highest_bank_bit = 3, | 546 | .highest_bank_bit = 3, |
| 540 | .macrotile_mode = 1, | 547 | .macrotile_mode = 1, |
| 548 | .reg_bus_bw = 76800, | ||
| 541 | }; | 549 | }; |
| 542 | 550 | ||
| 543 | static const struct msm_mdss_data sc8280xp_data = { | 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 | .ubwc_dec_version = UBWC_4_0, | 553 | .ubwc_dec_version = UBWC_4_0, |
| 546 | .ubwc_swizzle = 6, | 554 | .ubwc_swizzle = 6, |
| 547 | .ubwc_static = 1, | 555 | .ubwc_static = 1, |
| 548 | .highest_bank_bit = 2, | 556 | .highest_bank_bit = 3, |
| 549 | .macrotile_mode = 1, | 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 | static const struct msm_mdss_data sdm845_data = { | 567 | static const struct msm_mdss_data sdm845_data = { |
| 553 | .ubwc_enc_version = UBWC_2_0, | 568 | .ubwc_enc_version = UBWC_2_0, |
| 554 | .ubwc_dec_version = UBWC_2_0, | 569 | .ubwc_dec_version = UBWC_2_0, |
| 555 | .highest_bank_bit = 2, | 570 | .highest_bank_bit = 2, |
| 571 | .reg_bus_bw = 76800, | ||
| 556 | }; | 572 | }; |
| 557 | 573 | ||
| 558 | static const struct msm_mdss_data sm6350_data = { | 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 | .ubwc_swizzle = 6, | 577 | .ubwc_swizzle = 6, |
| 562 | .ubwc_static = 0x1e, | 578 | .ubwc_static = 0x1e, |
| 563 | .highest_bank_bit = 1, | 579 | .highest_bank_bit = 1, |
| 580 | .reg_bus_bw = 76800, | ||
| 564 | }; | 581 | }; |
| 565 | 582 | ||
| 566 | static const struct msm_mdss_data sm8150_data = { | 583 | static const struct msm_mdss_data sm8150_data = { |
| 567 | .ubwc_enc_version = UBWC_3_0, | 584 | .ubwc_enc_version = UBWC_3_0, |
| 568 | .ubwc_dec_version = UBWC_3_0, | 585 | .ubwc_dec_version = UBWC_3_0, |
| 569 | .highest_bank_bit = 2, | 586 | .highest_bank_bit = 2, |
| 587 | .reg_bus_bw = 76800, | ||
| 570 | }; | 588 | }; |
| 571 | 589 | ||
| 572 | static const struct msm_mdss_data sm6115_data = { | 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 | .ubwc_swizzle = 7, | 593 | .ubwc_swizzle = 7, |
| 576 | .ubwc_static = 0x11f, | 594 | .ubwc_static = 0x11f, |
| 577 | .highest_bank_bit = 0x1, | 595 | .highest_bank_bit = 0x1, |
| 596 | .reg_bus_bw = 76800, | ||
| 578 | }; | 597 | }; |
| 579 | 598 | ||
| 580 | static const struct msm_mdss_data sm6125_data = { | 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 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ | 611 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ |
| 593 | .highest_bank_bit = 3, | 612 | .highest_bank_bit = 3, |
| 594 | .macrotile_mode = 1, | 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 | static const struct msm_mdss_data sm8550_data = { | 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 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ | 633 | /* TODO: highest_bank_bit = 2 for LP_DDR4 */ |
| 603 | .highest_bank_bit = 3, | 634 | .highest_bank_bit = 3, |
| 604 | .macrotile_mode = 1, | 635 | .macrotile_mode = 1, |
| 636 | .reg_bus_bw = 57000, | ||
| 605 | }; | 637 | }; |
| 606 | static const struct of_device_id mdss_dt_match[] = { | 638 | static const struct of_device_id mdss_dt_match[] = { |
| 607 | { .compatible = "qcom,mdss" }, | 639 | { .compatible = "qcom,mdss" }, |
| 608 | { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data }, | 640 | { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data }, |
| 609 | { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data }, | 641 | { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data }, |
| 642 | { .compatible = "qcom,sdm670-mdss", .data = &sdm670_data }, | ||
| 610 | { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data }, | 643 | { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data }, |
| 611 | { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, | 644 | { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data }, |
| 612 | { .compatible = "qcom,sc7280-mdss", .data = &sc7280_data }, | 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 | { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data }, | 651 | { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data }, |
| 619 | { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data }, | 652 | { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data }, |
| 620 | { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, | 653 | { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, |
| 621 | { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, | 654 | { .compatible = "qcom,sm8350-mdss", .data = &sm8350_data }, |
| 622 | { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data }, | 655 | { .compatible = "qcom,sm8450-mdss", .data = &sm8350_data }, |
| 623 | { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, | 656 | { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, |
| 657 | { .compatible = "qcom,sm8650-mdss", .data = &sm8550_data}, | ||
| 624 | {} | 658 | {} |
| 625 | }; | 659 | }; |
| 626 | MODULE_DEVICE_TABLE(of, mdss_dt_match); | 660 | MODULE_DEVICE_TABLE(of, mdss_dt_match); |
| @@ -14,6 +14,7 @@ struct msm_mdss_data { · 13 unmodified lines | |||
| 14 | u32 ubwc_static; | 14 | u32 ubwc_static; |
| 15 | u32 highest_bank_bit; | 15 | u32 highest_bank_bit; |
| 16 | u32 macrotile_mode; | 16 | u32 macrotile_mode; |
| 17 | u32 reg_bus_bw; | ||
| 17 | }; | 18 | }; |
| 18 | 19 | ||
| 19 | #define UBWC_1_0 0x10000000 | 20 | #define UBWC_1_0 0x10000000 |
| @@ -270,6 +270,9 @@ int msm_rd_debugfs_init(struct drm_minor *minor) · 269 unmodified lines | |||
| 270 | struct msm_rd_state *rd; | 270 | struct msm_rd_state *rd; |
| 271 | int ret; | 271 | int ret; |
| 272 | 272 | ||
| 273 | if (!priv->gpu_pdev) | ||
| 274 | return 0; | ||
| 275 | |||
| 273 | /* only create on first minor: */ | 276 | /* only create on first minor: */ |
| 274 | if (priv->rd) | 277 | if (priv->rd) |
| 275 | return 0; | 278 | return 0; |
| @@ -29,9 +29,10 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job) · 28 unmodified lines | |||
| 29 | struct drm_gem_object *obj = submit->bos[i].obj; | 29 | struct drm_gem_object *obj = submit->bos[i].obj; |
| 30 | 30 | ||
| 31 | msm_gem_unpin_active(obj); | 31 | msm_gem_unpin_active(obj); |
| 32 | submit->bos[i].flags &= ~BO_PINNED; | ||
| 33 | } | 32 | } |
| 34 | 33 | ||
| 34 | submit->bos_pinned = false; | ||
| 35 | |||
| 35 | mutex_unlock(&priv->lru.lock); | 36 | mutex_unlock(&priv->lru.lock); |
| 36 | 37 | ||
| 37 | msm_gpu_submit(gpu, submit); | 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 | drm_exec_until_all_locked(exec) { | 1351 | drm_exec_until_all_locked(exec) { |
| 1352 | ret = bind_lock_validate(job, exec, vme->num_fences); | 1352 | ret = bind_lock_validate(job, exec, vme->num_fences); |
| 1353 | drm_exec_retry_on_contention(exec); | 1353 | drm_exec_retry_on_contention(exec); |
| @@ -46,7 +46,7 @@ static void sanitycheck(struct kunit *test) · 45 unmodified lines | |||
| 46 | { | 46 | { |
| 47 | struct drm_exec exec; | 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 | drm_exec_fini(&exec); | 50 | drm_exec_fini(&exec); |
| 51 | KUNIT_SUCCEED(test); | 51 | KUNIT_SUCCEED(test); |
| 52 | } | 52 | } |
| @@ -60,7 +60,7 @@ static void test_lock(struct kunit *test) · 7 unmodified lines | |||
| 60 | 60 | ||
| 61 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); | 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 | drm_exec_until_all_locked(&exec) { | 64 | drm_exec_until_all_locked(&exec) { |
| 65 | ret = drm_exec_lock_obj(&exec, &gobj); | 65 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 66 | drm_exec_retry_on_contention(&exec); | 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 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); | 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 | drm_exec_until_all_locked(&exec) { | 84 | drm_exec_until_all_locked(&exec) { |
| 85 | ret = drm_exec_lock_obj(&exec, &gobj); | 85 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 86 | drm_exec_retry_on_contention(&exec); | 86 | drm_exec_retry_on_contention(&exec); |
| @@ -107,7 +107,7 @@ static void test_duplicates(struct kunit *test) · 20 unmodified lines | |||
| 107 | 107 | ||
| 108 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); | 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 | drm_exec_until_all_locked(&exec) { | 111 | drm_exec_until_all_locked(&exec) { |
| 112 | ret = drm_exec_lock_obj(&exec, &gobj); | 112 | ret = drm_exec_lock_obj(&exec, &gobj); |
| 113 | drm_exec_retry_on_contention(&exec); | 113 | drm_exec_retry_on_contention(&exec); |
| @@ -134,7 +134,7 @@ static void test_prepare(struct kunit *test) · 20 unmodified lines | |||
| 134 | 134 | ||
| 135 | drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE); | 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 | drm_exec_until_all_locked(&exec) { | 138 | drm_exec_until_all_locked(&exec) { |
| 139 | ret = drm_exec_prepare_obj(&exec, &gobj, 1); | 139 | ret = drm_exec_prepare_obj(&exec, &gobj, 1); |
| 140 | drm_exec_retry_on_contention(&exec); | 140 | drm_exec_retry_on_contention(&exec); |
| @@ -159,7 +159,7 @@ static void test_prepare_array(struct kunit *test) · 18 unmodified lines | |||
| 159 | drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE); | 159 | drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE); |
| 160 | drm_gem_private_object_init(priv->drm, &gobj2, PAGE_SIZE); | 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 | drm_exec_until_all_locked(&exec) | 163 | drm_exec_until_all_locked(&exec) |
| 164 | ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array), | 164 | ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array), |
| 165 | 1); | 165 | 1); |
| @@ -174,14 +174,14 @@ static void test_multiple_loops(struct kunit *test) · 8 unmodified lines | |||
| 174 | { | 174 | { |
| 175 | struct drm_exec exec; | 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 | drm_exec_until_all_locked(&exec) | 178 | drm_exec_until_all_locked(&exec) |
| 179 | { | 179 | { |
| 180 | break; | 180 | break; |
| 181 | } | 181 | } |
| 182 | drm_exec_fini(&exec); | 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 | drm_exec_until_all_locked(&exec) | 185 | drm_exec_until_all_locked(&exec) |
| 186 | { | 186 | { |
| 187 | break; | 187 | break; |
| @@ -135,7 +135,7 @@ static inline bool drm_exec_is_contended(struct drm_exec *exec) · 134 unmodified lines | |||
| 135 | return !!exec->contended; | 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 | void drm_exec_fini(struct drm_exec *exec); | 139 | void drm_exec_fini(struct drm_exec *exec); |
| 140 | bool drm_exec_cleanup(struct drm_exec *exec); | 140 | bool drm_exec_cleanup(struct drm_exec *exec); |
| 141 | int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj); | 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 | #define MSM_PARAM_CMDLINE 0x0d /* WO: override for task cmdline */ | 86 | #define MSM_PARAM_CMDLINE 0x0d /* WO: override for task cmdline */ |
| 87 | #define MSM_PARAM_VA_START 0x0e /* RO: start of valid GPU iova range */ | 87 | #define MSM_PARAM_VA_START 0x0e /* RO: start of valid GPU iova range */ |
| 88 | #define MSM_PARAM_VA_SIZE 0x0f /* RO: size of valid GPU iova range (bytes) */ | 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 | /* For backwards compat. The original support for preemption was based on | 91 | /* For backwards compat. The original support for preemption was based on |
| 91 | * a single ring per priority level so # of priority levels equals the # | 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 | #define MSM_INFO_GET_NAME 0x03 /* get debug name, returned by pointer */ | 140 | #define MSM_INFO_GET_NAME 0x03 /* get debug name, returned by pointer */ |
| 140 | #define MSM_INFO_SET_IOVA 0x04 /* set the iova, passed by value */ | 141 | #define MSM_INFO_SET_IOVA 0x04 /* set the iova, passed by value */ |
| 141 | #define MSM_INFO_GET_FLAGS 0x05 /* get the MSM_BO_x flags */ | 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 | struct drm_msm_gem_info { | 146 | struct drm_msm_gem_info { |
| 144 | __u32 handle; /* in */ | 147 | __u32 handle; /* in */ |