History

Merge tag 'drm-msm-next-2023-12-15' of https://gitlab.freedesktop.org/drm/msm into drm-next

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

Dave Airlie committed 2 years ago

Commit 22a2dec2 parents d2be61f d4ca26a144 files · +3631 −2023Browse files

Unified · Split

144 files
  1. Documentation/devicetree/bindings/display/msm/dp-controller.yaml +2 −0
  2. Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml +3 −0
  3. Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml +1 −0
  4. Documentation/devicetree/bindings/display/msm/mdss-common.yaml +14 −4
  5. Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml +15 −6
  6. Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml +10 −4
  7. Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml +10 −4
  8. Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml +292 −0
  9. Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml +3 −1
  10. Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml +10 −0
  11. Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml +6 −2
  12. Documentation/devicetree/bindings/display/msm/qcom,sm6350-mdss.yaml +6 −2
  13. Documentation/devicetree/bindings/display/msm/qcom,sm6375-mdss.yaml +6 −2
  14. Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml +3 −3
  15. Documentation/devicetree/bindings/display/msm/qcom,sm8250-mdss.yaml +10 −0
  16. Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml +8 −5
  17. Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml +127 −0
  18. Documentation/devicetree/bindings/display/msm/qcom,sm8650-mdss.yaml +328 −0
  19. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +4 −4
  20. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +1 −1
  21. drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +2 −2
  22. drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +2 −2
  23. drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +2 −2
  24. drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c +2 −2
  25. drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c +2 −2
  26. drivers/gpu/drm/amd/amdkfd/kfd_svm.c +1 −1
  27. drivers/gpu/drm/ci/build.sh +3 −0
  28. drivers/gpu/drm/drm_exec.c +10 −3
  29. drivers/gpu/drm/drm_gpuvm.c +2 −2
  30. drivers/gpu/drm/imagination/pvr_job.c +1 −1
  31. drivers/gpu/drm/msm/Kconfig +2 −0
  32. drivers/gpu/drm/msm/Makefile +1 −0
  33. drivers/gpu/drm/msm/adreno/a5xx_gpu.c +12 −9
  34. drivers/gpu/drm/msm/adreno/a6xx_gpu.c +69 −53
  35. drivers/gpu/drm/msm/adreno/adreno_device.c +1 −1
  36. drivers/gpu/drm/msm/adreno/adreno_gpu.c +3 −0
  37. drivers/gpu/drm/msm/adreno/adreno_gpu.h +9 −0
  38. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h +457 −0
  39. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +8 −9
  40. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h +8 −9
  41. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h +104 −0
  42. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h +8 −9
  43. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +9 −9
  44. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h +4 −4
  45. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +16 −16
  46. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +8 −9
  47. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h +3 −4
  48. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h +5 −6
  49. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h +2 −2
  50. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h +3 −4
  51. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +34 −17
  52. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +8 −8
  53. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +12 −13
  54. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +34 −17
  55. drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +16 −17
  56. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +9 −20
  57. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +76 −110
  58. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +14 −7
  59. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +26 −49
  60. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +30 −25
  61. drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +109 −21
  62. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +127 −96
  63. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +40 −32
  64. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +247 −0
  65. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h +142 −0
  66. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +42 −10
  67. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +18 −10
  68. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +5 −7
  69. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +7 −3
  70. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c +5 −2
  71. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c +6 −10
  72. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h +4 −8
  73. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +6 −8
  74. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h +4 −7
  75. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +10 −12
  76. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +7 −10
  77. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +9 −11
  78. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +6 −9
  79. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +10 −0
  80. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c +6 −8
  81. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h +4 −9
  82. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +7 −8
  83. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +5 −9
  84. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +9 −28
  85. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +6 −31
  86. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +7 −10
  87. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +5 −3
  88. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +52 −18
  89. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +9 −8
  90. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c +6 −8
  91. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h +4 −4
  92. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +10 −8
  93. drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h +5 −8
  94. drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +25 −54
  95. drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +2 −1
  96. drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +20 −85
  97. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +61 −80
  98. drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +5 −8
  99. drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +26 −16
  100. drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c +5 −27
  101. drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c +7 −30
  102. drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +22 −65
  103. drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +5 −19
  104. drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h +0 −1
  105. drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +15 −15
  106. drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +4 −17
  107. drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.h +0 −1
  108. drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c +4 −25
  109. drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +3 −22
  110. drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c +3 −7
  111. drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h +2 −2
  112. drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +3 −7
  113. drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h +2 −2
  114. drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c +4 −15
  115. drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.h +0 −1
  116. drivers/gpu/drm/msm/dp/dp_aux.c +32 −7
  117. drivers/gpu/drm/msm/dp/dp_debug.c +16 −53
  118. drivers/gpu/drm/msm/dp/dp_debug.h +7 −16
  119. drivers/gpu/drm/msm/dp/dp_display.c +146 −223
  120. drivers/gpu/drm/msm/dp/dp_display.h +2 −2
  121. drivers/gpu/drm/msm/dp/dp_drm.c +23 −7
  122. drivers/gpu/drm/msm/dp/dp_power.c +2 −30
  123. drivers/gpu/drm/msm/dp/dp_power.h +0 −11
  124. drivers/gpu/drm/msm/dsi/dsi_cfg.c +17 −0
  125. drivers/gpu/drm/msm/dsi/dsi_cfg.h +1 −0
  126. drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +9 −1
  127. drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +1 −0
  128. drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +27 −0
  129. drivers/gpu/drm/msm/msm_debugfs.c +25 −16
  130. drivers/gpu/drm/msm/msm_drv.c +92 −2
  131. drivers/gpu/drm/msm/msm_drv.h +2 −13
  132. drivers/gpu/drm/msm/msm_gem.c +4 −3
  133. drivers/gpu/drm/msm/msm_gem.h +9 −8
  134. drivers/gpu/drm/msm/msm_gem_shrinker.c +1 −1
  135. drivers/gpu/drm/msm/msm_gem_submit.c +69 −164
  136. drivers/gpu/drm/msm/msm_gpu.c +23 −21
  137. drivers/gpu/drm/msm/msm_mdss.c +70 −36
  138. drivers/gpu/drm/msm/msm_mdss.h +1 −0
  139. drivers/gpu/drm/msm/msm_rd.c +3 −0
  140. drivers/gpu/drm/msm/msm_ringbuffer.c +2 −1
  141. drivers/gpu/drm/nouveau/nouveau_uvmm.c +1 −1
  142. drivers/gpu/drm/tests/drm_exec_test.c +8 −8
  143. include/drm/drm_exec.h +1 −1
  144. include/uapi/drm/msm_drm.h +3 −0
Documentation/devicetree/bindings/display/msm/dp-controller.yaml+2−0
@@ -26,8 +26,10 @@ properties: · 25 unmodified lines
2626 - qcom,sc8280xp-edp
2727 - qcom,sdm845-dp
2828 - qcom,sm8350-dp
29+ - qcom,sm8650-dp
2930 - items:
3031 - enum:
32+ - qcom,sm8150-dp
3133 - qcom,sm8250-dp
3234 - qcom,sm8450-dp
3335 - qcom,sm8550-dp
Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml+3−0
@@ -25,6 +25,7 @@ properties: · 24 unmodified lines
2525 - qcom,sc7180-dsi-ctrl
2626 - qcom,sc7280-dsi-ctrl
2727 - qcom,sdm660-dsi-ctrl
28+ - qcom,sdm670-dsi-ctrl
2829 - qcom,sdm845-dsi-ctrl
2930 - qcom,sm6115-dsi-ctrl
3031 - qcom,sm6125-dsi-ctrl
@@ -35,6 +36,7 @@ properties: · 4 unmodified lines
3536 - qcom,sm8350-dsi-ctrl
3637 - qcom,sm8450-dsi-ctrl
3738 - qcom,sm8550-dsi-ctrl
39+ - qcom,sm8650-dsi-ctrl
3840 - const: qcom,mdss-dsi-ctrl
3941 - enum:
4042 - qcom,dsi-ctrl-6g-qcm2290
@@ -333,6 +335,7 @@ allOf: · 292 unmodified lines
333335 - qcom,sm8350-dsi-ctrl
334336 - qcom,sm8450-dsi-ctrl
335337 - qcom,sm8550-dsi-ctrl
338+ - qcom,sm8650-dsi-ctrl
336339 then:
337340 properties:
338341 clocks:
Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml+1−0
@@ -22,6 +22,7 @@ properties: · 21 unmodified lines
2222 - qcom,sm8350-dsi-phy-5nm
2323 - qcom,sm8450-dsi-phy-5nm
2424 - qcom,sm8550-dsi-phy-4nm
25+ - qcom,sm8650-dsi-phy-4nm
2526
2627 reg:
2728 items:
Documentation/devicetree/bindings/display/msm/mdss-common.yaml+14−4
@@ -61,17 +61,27 @@ properties: · 60 unmodified lines
6161
6262 ranges: true
6363
64+ # This is not a perfect description, but it's impossible to discern and match
65+ # the entries like we do with interconnect-names
6466 interconnects:
6567 minItems: 1
6668 items:
6769 - description: Interconnect path from mdp0 (or a single mdp) port to the data bus
6870 - description: Interconnect path from mdp1 port to the data bus
71+ - description: Interconnect path from CPU to the reg bus
6972
7073 interconnect-names:
71− minItems: 1
72− items:
73− - const: mdp0-mem
74− - const: mdp1-mem
74+ oneOf:
75+ - minItems: 1
76+ items:
77+ - const: mdp0-mem
78+ - const: cpu-cfg
79+
80+ - minItems: 2
81+ items:
82+ - const: mdp0-mem
83+ - const: mdp1-mem
84+ - const: cpu-cfg
7585
7686 resets:
7787 items:
Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.yaml+15−6
@@ -36,10 +36,14 @@ properties: · 35 unmodified lines
3636 maxItems: 2
3737
3838 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
4042
4143 interconnect-names:
42− maxItems: 1
44+ items:
45+ - const: mdp0-mem
46+ - const: cpu-cfg
4347
4448 patternProperties:
4549 "^display-controller@[0-9a-f]+$":
@@ -56,7 +60,9 @@ patternProperties: · 10 unmodified lines
5660
5761 properties:
5862 compatible:
59− const: qcom,dsi-ctrl-6g-qcm2290
63+ items:
64+ - const: qcom,qcm2290-dsi-ctrl
65+ - const: qcom,mdss-dsi-ctrl
6066
6167 "^phy@[0-9a-f]+$":
6268 type: object
@@ -96,8 +102,10 @@ examples: · 33 unmodified lines
96102 interrupt-controller;
97103 #interrupt-cells = <1>;
98104
99− interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>;
100− interconnect-names = "mdp0-mem";
105+ interconnects = <&mmrt_virt MASTER_MDP0 &bimc SLAVE_EBI1>,
106+ <&bimc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
107+ interconnect-names = "mdp0-mem",
108+ "cpu-cfg";
101109
102110 iommus = <&apps_smmu 0x420 0x2>,
103111 <&apps_smmu 0x421 0x0>;
@@ -136,7 +144,8 @@ examples: · 32 unmodified lines
136144 };
137145
138146 dsi@5e94000 {
139− compatible = "qcom,dsi-ctrl-6g-qcm2290";
147+ compatible = "qcom,qcm2290-dsi-ctrl",
148+ "qcom,mdss-dsi-ctrl";
140149 reg = <0x05e94000 0x400>;
141150 reg-names = "dsi_ctrl";
142151
Documentation/devicetree/bindings/display/msm/qcom,sc7180-mdss.yaml+10−4
@@ -36,10 +36,14 @@ properties: · 35 unmodified lines
3636 maxItems: 1
3737
3838 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
4042
4143 interconnect-names:
42− maxItems: 1
44+ items:
45+ - const: mdp0-mem
46+ - const: cpu-cfg
4347
4448 patternProperties:
4549 "^display-controller@[0-9a-f]+$":
@@ -106,8 +110,10 @@ examples: · 60 unmodified lines
106110 interrupt-controller;
107111 #interrupt-cells = <1>;
108112
109− interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
110− interconnect-names = "mdp0-mem";
113+ interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>,
114+ <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
115+ interconnect-names = "mdp0-mem",
116+ "cpu-cfg";
111117
112118 iommus = <&apps_smmu 0x800 0x2>;
113119 ranges;
Documentation/devicetree/bindings/display/msm/qcom,sc7280-mdss.yaml+10−4
@@ -36,10 +36,14 @@ properties: · 35 unmodified lines
3636 maxItems: 1
3737
3838 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
4042
4143 interconnect-names:
42− maxItems: 1
44+ items:
45+ - const: mdp0-mem
46+ - const: cpu-cfg
4347
4448 patternProperties:
4549 "^display-controller@[0-9a-f]+$":
@@ -118,8 +122,10 @@ examples: · 72 unmodified lines
118122 interrupt-controller;
119123 #interrupt-cells = <1>;
120124
121− interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>;
122− interconnect-names = "mdp0-mem";
125+ interconnects = <&mmss_noc MASTER_MDP0 &mc_virt SLAVE_EBI1>,
126+ <&gem_noc MASTER_APPSS_PROC &cnoc2 SLAVE_DISPLAY_CFG>;
127+ interconnect-names = "mdp0-mem",
128+ "cpu-cfg";
123129
124130 iommus = <&apps_smmu 0x900 0x402>;
125131 ranges;
Documentation/devicetree/bindings/display/msm/qcom,sdm670-mdss.yaml+292−0
@@ -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+...
Documentation/devicetree/bindings/display/msm/qcom,sdm845-dpu.yaml+3−1
@@ -13,7 +13,9 @@ $ref: /schemas/display/msm/dpu-common.yaml# · 12 unmodified lines
1313
1414 properties:
1515 compatible:
16− const: qcom,sdm845-dpu
16+ enum:
17+ - qcom,sdm670-dpu
18+ - qcom,sdm845-dpu
1719
1820 reg:
1921 items:
Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml+10−0
@@ -29,6 +29,16 @@ properties: · 28 unmodified lines
2929 iommus:
3030 maxItems: 2
3131
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+
3242 patternProperties:
3343 "^display-controller@[0-9a-f]+$":
3444 type: object
Documentation/devicetree/bindings/display/msm/qcom,sm6125-mdss.yaml+6−2
@@ -35,10 +35,14 @@ properties: · 34 unmodified lines
3535 maxItems: 1
3636
3737 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
3941
4042 interconnect-names:
41− maxItems: 2
43+ items:
44+ - const: mdp0-mem
45+ - const: cpu-cfg
4246
4347 patternProperties:
4448 "^display-controller@[0-9a-f]+$":
Documentation/devicetree/bindings/display/msm/qcom,sm6350-mdss.yaml+6−2
@@ -35,10 +35,14 @@ properties: · 34 unmodified lines
3535 maxItems: 1
3636
3737 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
3941
4042 interconnect-names:
41− maxItems: 2
43+ items:
44+ - const: mdp0-mem
45+ - const: cpu-cfg
4246
4347 patternProperties:
4448 "^display-controller@[0-9a-f]+$":
Documentation/devicetree/bindings/display/msm/qcom,sm6375-mdss.yaml+6−2
@@ -35,10 +35,14 @@ properties: · 34 unmodified lines
3535 maxItems: 1
3636
3737 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
3941
4042 interconnect-names:
41− maxItems: 2
43+ items:
44+ - const: mdp0-mem
45+ - const: cpu-cfg
4246
4347 patternProperties:
4448 "^display-controller@[0-9a-f]+$":
Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml+3−3
@@ -69,7 +69,7 @@ patternProperties: · 68 unmodified lines
6969
7070 properties:
7171 compatible:
72− const: qcom,dsi-phy-7nm
72+ const: qcom,dsi-phy-7nm-8150
7373
7474 unevaluatedProperties: false
7575
@@ -247,7 +247,7 @@ examples: · 171 unmodified lines
247247 };
248248
249249 dsi0_phy: phy@ae94400 {
250− compatible = "qcom,dsi-phy-7nm";
250+ compatible = "qcom,dsi-phy-7nm-8150";
251251 reg = <0x0ae94400 0x200>,
252252 <0x0ae94600 0x280>,
253253 <0x0ae94900 0x260>;
@@ -318,7 +318,7 @@ examples: · 64 unmodified lines
318318 };
319319
320320 dsi1_phy: phy@ae96400 {
321− compatible = "qcom,dsi-phy-7nm";
321+ compatible = "qcom,dsi-phy-7nm-8150";
322322 reg = <0x0ae96400 0x200>,
323323 <0x0ae96600 0x280>,
324324 <0x0ae96900 0x260>;
Documentation/devicetree/bindings/display/msm/qcom,sm8250-mdss.yaml+10−0
@@ -52,6 +52,16 @@ patternProperties: · 51 unmodified lines
5252 compatible:
5353 const: qcom,sm8250-dpu
5454
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+
5565 "^dsi@[0-9a-f]+$":
5666 type: object
5767 additionalProperties: true
Documentation/devicetree/bindings/display/msm/qcom,sm8450-mdss.yaml+8−5
@@ -30,10 +30,10 @@ properties: · 29 unmodified lines
3030 maxItems: 1
3131
3232 interconnects:
33− maxItems: 2
33+ maxItems: 3
3434
3535 interconnect-names:
36− maxItems: 2
36+ maxItems: 3
3737
3838 patternProperties:
3939 "^display-controller@[0-9a-f]+$":
@@ -91,9 +91,12 @@ examples: · 51 unmodified lines
9191 reg = <0x0ae00000 0x1000>;
9292 reg-names = "mdss";
9393
94− interconnects = <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>,
95− <&mmss_noc MASTER_MDP_DISP 0 &mc_virt SLAVE_EBI1_DISP 0>;
96− interconnect-names = "mdp0-mem", "mdp1-mem";
94+ interconnects = <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>,
95+ <&mmss_noc MASTER_MDP_DISP &mc_virt SLAVE_EBI1_DISP>,
96+ <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_DISPLAY_CFG>;
97+ interconnect-names = "mdp0-mem",
98+ "mdp1-mem",
99+ "cpu-cfg";
97100
98101 resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
99102
Documentation/devicetree/bindings/display/msm/qcom,sm8650-dpu.yaml+127−0
@@ -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+...
Documentation/devicetree/bindings/display/msm/qcom,sm8650-mdss.yaml+328−0
@@ -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+...
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c+4−4
@@ -1147,7 +1147,7 @@ static int reserve_bo_and_vm(struct kgd_mem *mem, · 1146 unmodified lines
11471147
11481148 ctx->n_vms = 1;
11491149 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);
11511151 drm_exec_until_all_locked(&ctx->exec) {
11521152 ret = amdgpu_vm_lock_pd(vm, &ctx->exec, 2);
11531153 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
11861186 int ret;
11871187
11881188 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);
11901190 drm_exec_until_all_locked(&ctx->exec) {
11911191 ctx->n_vms = 0;
11921192 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
25952595
25962596 amdgpu_sync_create(&sync);
25972597
2598− drm_exec_init(&exec, 0);
2598+ drm_exec_init(&exec, 0, 0);
25992599 /* Reserve all BOs and page tables for validation */
26002600 drm_exec_until_all_locked(&exec) {
26012601 /* 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
28532853
28542854 mutex_lock(&process_info->lock);
28552855
2856− drm_exec_init(&exec, 0);
2856+ drm_exec_init(&exec, 0, 0);
28572857 drm_exec_until_all_locked(&exec) {
28582858 list_for_each_entry(peer_vm, &process_info->vm_list_head,
28592859 vm_list_node) {
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+1−1
@@ -66,7 +66,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, · 65 unmodified lines
6666
6767 amdgpu_sync_create(&p->sync);
6868 drm_exec_init(&p->exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
69− DRM_EXEC_IGNORE_DUPLICATES);
69+ DRM_EXEC_IGNORE_DUPLICATES, 0);
7070 return 0;
7171 }
7272
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c+2−2
@@ -70,7 +70,7 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 69 unmodified lines
7070 struct drm_exec exec;
7171 int r;
7272
73− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
73+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
7474 drm_exec_until_all_locked(&exec) {
7575 r = amdgpu_vm_lock_pd(vm, &exec, 0);
7676 if (likely(!r))
@@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 33 unmodified lines
110110 struct drm_exec exec;
111111 int r;
112112
113− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
113+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
114114 drm_exec_until_all_locked(&exec) {
115115 r = amdgpu_vm_lock_pd(vm, &exec, 0);
116116 if (likely(!r))
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c+2−2
@@ -203,7 +203,7 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj, · 202 unmodified lines
203203 struct drm_exec exec;
204204 long r;
205205
206− drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES);
206+ drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
207207 drm_exec_until_all_locked(&exec) {
208208 r = drm_exec_prepare_obj(&exec, &bo->tbo.base, 1);
209209 drm_exec_retry_on_contention(&exec);
@@ -739,7 +739,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, · 529 unmodified lines
739739 }
740740
741741 drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
742− DRM_EXEC_IGNORE_DUPLICATES);
742+ DRM_EXEC_IGNORE_DUPLICATES, 0);
743743 drm_exec_until_all_locked(&exec) {
744744 if (gobj) {
745745 r = drm_exec_lock_obj(&exec, gobj);
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c+2−2
@@ -1183,7 +1183,7 @@ int amdgpu_mes_ctx_map_meta_data(struct amdgpu_device *adev, · 1182 unmodified lines
11831183
11841184 amdgpu_sync_create(&sync);
11851185
1186− drm_exec_init(&exec, 0);
1186+ drm_exec_init(&exec, 0, 0);
11871187 drm_exec_until_all_locked(&exec) {
11881188 r = drm_exec_lock_obj(&exec,
11891189 &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
12541254 struct drm_exec exec;
12551255 long r;
12561256
1257− drm_exec_init(&exec, 0);
1257+ drm_exec_init(&exec, 0, 0);
12581258 drm_exec_until_all_locked(&exec) {
12591259 r = drm_exec_lock_obj(&exec,
12601260 &ctx_data->meta_data_obj->tbo.base);
drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c+2−2
@@ -61,7 +61,7 @@ int amdgpu_seq64_map(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 60 unmodified lines
6161 if (!bo)
6262 return -EINVAL;
6363
64− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
64+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
6565 drm_exec_until_all_locked(&exec) {
6666 r = amdgpu_vm_lock_pd(vm, &exec, 0);
6767 if (likely(!r))
@@ -122,7 +122,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv) · 54 unmodified lines
122122
123123 vm = &fpriv->vm;
124124
125− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
125+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
126126 drm_exec_until_all_locked(&exec) {
127127 r = amdgpu_vm_lock_pd(vm, &exec, 0);
128128 if (likely(!r))
drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c+2−2
@@ -86,7 +86,7 @@ static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 85 unmodified lines
8686
8787 amdgpu_sync_create(&sync);
8888
89− drm_exec_init(&exec, 0);
89+ drm_exec_init(&exec, 0, 0);
9090 drm_exec_until_all_locked(&exec) {
9191 r = drm_exec_lock_obj(&exec, &bo->tbo.base);
9292 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
149149 struct drm_exec exec;
150150 long r;
151151
152− drm_exec_init(&exec, 0);
152+ drm_exec_init(&exec, 0, 0);
153153 drm_exec_until_all_locked(&exec) {
154154 r = drm_exec_lock_obj(&exec, &bo->tbo.base);
155155 drm_exec_retry_on_contention(&exec);
drivers/gpu/drm/amd/amdkfd/kfd_svm.c+1−1
@@ -1481,7 +1481,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx, bool intr) · 1480 unmodified lines
14811481 uint32_t gpuidx;
14821482 int r;
14831483
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);
14851485 drm_exec_until_all_locked(&ctx->exec) {
14861486 for_each_set_bit(gpuidx, ctx->bitmap, MAX_GPU_INSTANCE) {
14871487 pdd = kfd_process_device_from_gpuidx(ctx->process, gpuidx);
drivers/gpu/drm/ci/build.sh+3−0
@@ -58,6 +58,9 @@ git config --global user.email "fdo@example.com" · 57 unmodified lines
5858 git config --global user.name "freedesktop.org CI"
5959 git config --global pull.rebase true
6060
61+# cleanup git state on the worker
62+rm -rf .git/rebase-merge
63+
6164 # Try to merge fixes from target repo
6265 if [ "$(git ls-remote --exit-code --heads ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes)" ]; then
6366 git pull ${UPSTREAM_REPO} ${TARGET_BRANCH}-external-fixes
drivers/gpu/drm/drm_exec.c+10−3
@@ -69,16 +69,23 @@ static void drm_exec_unlock_all(struct drm_exec *exec) · 68 unmodified lines
6969 * drm_exec_init - initialize a drm_exec object
7070 * @exec: the drm_exec object to initialize
7171 * @flags: controls locking behavior, see DRM_EXEC_* defines
72+ * @nr: the initial # of objects
7273 *
7374 * 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.
7478 */
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)
7680 {
81+ if (!nr)
82+ nr = PAGE_SIZE / sizeof(void *);
83+
7784 exec->flags = flags;
78− exec->objects = kmalloc(PAGE_SIZE, GFP_KERNEL);
85+ exec->objects = kvmalloc_array(nr, sizeof(void *), GFP_KERNEL);
7986
8087 /* 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;
8289 exec->num_objects = 0;
8390 exec->contended = DRM_EXEC_DUMMY;
8491 exec->prelocked = NULL;
drivers/gpu/drm/drm_gpuvm.c+2−2
@@ -1250,7 +1250,7 @@ drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec) · 1249 unmodified lines
12501250 unsigned int num_fences = vm_exec->num_fences;
12511251 int ret;
12521252
1253− drm_exec_init(exec, vm_exec->flags);
1253+ drm_exec_init(exec, vm_exec->flags, 0);
12541254
12551255 drm_exec_until_all_locked(exec) {
12561256 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
13411341 struct drm_exec *exec = &vm_exec->exec;
13421342 int ret;
13431343
1344− drm_exec_init(exec, vm_exec->flags);
1344+ drm_exec_init(exec, vm_exec->flags, 0);
13451345
13461346 drm_exec_until_all_locked(exec) {
13471347 ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
drivers/gpu/drm/imagination/pvr_job.c+1−1
@@ -746,7 +746,7 @@ pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file, · 745 unmodified lines
746746 if (err)
747747 goto out_job_data_cleanup;
748748
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);
750750
751751 xa_init_flags(&signal_array, XA_FLAGS_ALLOC);
752752
drivers/gpu/drm/msm/Kconfig+2−0
@@ -6,6 +6,7 @@ config DRM_MSM · 5 unmodified lines
66 depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
77 depends on COMMON_CLK
88 depends on IOMMU_SUPPORT
9+ depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
910 depends on QCOM_OCMEM || QCOM_OCMEM=n
1011 depends on QCOM_LLCC || QCOM_LLCC=n
1112 depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
@@ -16,6 +17,7 @@ config DRM_MSM · 4 unmodified lines
1617 select DRM_DP_AUX_BUS
1718 select DRM_DISPLAY_DP_HELPER
1819 select DRM_DISPLAY_HELPER
20+ select DRM_EXEC
1921 select DRM_KMS_HELPER
2022 select DRM_PANEL
2123 select DRM_BRIDGE
drivers/gpu/drm/msm/Makefile+1−0
@@ -63,6 +63,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ · 62 unmodified lines
6363 disp/dpu1/dpu_encoder_phys_wb.o \
6464 disp/dpu1/dpu_formats.o \
6565 disp/dpu1/dpu_hw_catalog.o \
66+ disp/dpu1/dpu_hw_cdm.o \
6667 disp/dpu1/dpu_hw_ctl.o \
6768 disp/dpu1/dpu_hw_dsc.o \
6869 disp/dpu1/dpu_hw_dsc_1_2.o \
drivers/gpu/drm/msm/adreno/a5xx_gpu.c+12−9
@@ -684,7 +684,7 @@ static int a5xx_hw_init(struct msm_gpu *gpu) · 683 unmodified lines
684684 {
685685 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
686686 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
687− u32 regbit;
687+ u32 hbb;
688688 int ret;
689689
690690 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
820820
821821 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
822822
823− /* Set the highest bank bit */
824− if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
825− regbit = 2;
826− else
827− regbit = 1;
823+ BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
824+ hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
828825
829− gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, regbit << 7);
830− gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, regbit << 1);
826+ gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7);
827+ gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1);
831828
832829 if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
833830 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);
835832
836833 /* Disable All flat shading optimization (ALLFLATOPTDIS) */
837834 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
17851782 /* Set up the preemption specific bits and pieces for each ringbuffer */
17861783 a5xx_preempt_init(gpu);
17871784
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+
17881791 return gpu;
17891792 }
drivers/gpu/drm/msm/adreno/a6xx_gpu.c+69−53
@@ -1270,87 +1270,92 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) · 1269 unmodified lines
12701270 gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
12711271 }
12721272
1273−static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
1273+static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
12741274 {
1275− struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
12761275 /* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
1277− u32 rgb565_predicator = 0;
1276+ gpu->ubwc_config.rgb565_predicator = 0;
12781277 /* Unknown, introduced with A650 family */
1279− u32 uavflagprd_inv = 0;
1278+ gpu->ubwc_config.uavflagprd_inv = 0;
12801279 /* Whether the minimum access length is 64 bits */
1281− u32 min_acc_len = 0;
1280+ gpu->ubwc_config.min_acc_len = 0;
12821281 /* Entirely magic, per-GPU-gen value */
1283− u32 ubwc_mode = 0;
1282+ gpu->ubwc_config.ubwc_mode = 0;
12841283 /*
12851284 * The Highest Bank Bit value represents the bit of the highest DDR bank.
1286− * We then subtract 13 from it (13 is the minimum value allowed by hw) and
1287− * write the lowest two bits of the remaining value as hbb_lo and the
1288− * one above it as hbb_hi to the hardware. This should ideally use DRAM
1289− * type detection.
1285+ * This should ideally use DRAM type detection.
12901286 */
1291− u32 hbb_hi = 0;
1292− u32 hbb_lo = 2;
1293− /* Unknown, introduced with A640/680 */
1294− u32 amsbc = 0;
1287+ gpu->ubwc_config.highest_bank_bit = 15;
12951288
1296− if (adreno_is_a610(adreno_gpu)) {
1297− /* HBB = 14 */
1298− hbb_lo = 1;
1299− min_acc_len = 1;
1300− ubwc_mode = 1;
1289+ if (adreno_is_a610(gpu)) {
1290+ gpu->ubwc_config.highest_bank_bit = 14;
1291+ gpu->ubwc_config.min_acc_len = 1;
1292+ gpu->ubwc_config.ubwc_mode = 1;
13011293 }
13021294
13031295 /* a618 is using the hw default values */
1304− if (adreno_is_a618(adreno_gpu))
1296+ if (adreno_is_a618(gpu))
13051297 return;
13061298
1307− if (adreno_is_a619_holi(adreno_gpu))
1308− hbb_lo = 0;
1299+ if (adreno_is_a619_holi(gpu))
1300+ gpu->ubwc_config.highest_bank_bit = 13;
13091301
1310− if (adreno_is_a640_family(adreno_gpu))
1311− amsbc = 1;
1302+ if (adreno_is_a640_family(gpu))
1303+ gpu->ubwc_config.amsbc = 1;
13121304
1313− if (adreno_is_a650(adreno_gpu) ||
1314− adreno_is_a660(adreno_gpu) ||
1315− adreno_is_a730(adreno_gpu) ||
1316− adreno_is_a740_family(adreno_gpu)) {
1305+ if (adreno_is_a650(gpu) ||
1306+ adreno_is_a660(gpu) ||
1307+ adreno_is_a690(gpu) ||
1308+ adreno_is_a730(gpu) ||
1309+ adreno_is_a740_family(gpu)) {
13171310 /* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
1318− hbb_lo = 3;
1319− amsbc = 1;
1320− rgb565_predicator = 1;
1321− uavflagprd_inv = 2;
1311+ gpu->ubwc_config.highest_bank_bit = 16;
1312+ gpu->ubwc_config.amsbc = 1;
1313+ gpu->ubwc_config.rgb565_predicator = 1;
1314+ gpu->ubwc_config.uavflagprd_inv = 2;
13221315 }
13231316
1324− if (adreno_is_a690(adreno_gpu)) {
1325− hbb_lo = 2;
1326− amsbc = 1;
1327− rgb565_predicator = 1;
1328− uavflagprd_inv = 2;
1317+ if (adreno_is_7c3(gpu)) {
1318+ gpu->ubwc_config.highest_bank_bit = 14;
1319+ gpu->ubwc_config.amsbc = 1;
1320+ gpu->ubwc_config.rgb565_predicator = 1;
1321+ gpu->ubwc_config.uavflagprd_inv = 2;
13291322 }
1323+}
13301324
1331− if (adreno_is_7c3(adreno_gpu)) {
1332− hbb_lo = 1;
1333− amsbc = 1;
1334− rgb565_predicator = 1;
1335− uavflagprd_inv = 2;
1336− }
1325+static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
1326+{
1327+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
1328+ /*
1329+ * We subtract 13 from the highest bank bit (13 is the minimum value
1330+ * allowed by hw) and write the lowest two bits of the remaining value
1331+ * as hbb_lo and the one above it as hbb_hi to the hardware.
1332+ */
1333+ BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
1334+ u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
1335+ u32 hbb_hi = hbb >> 2;
1336+ u32 hbb_lo = hbb & 3;
13371337
13381338 gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
1339− rgb565_predicator << 11 | hbb_hi << 10 | amsbc << 4 |
1340− min_acc_len << 3 | hbb_lo << 1 | ubwc_mode);
1339+ adreno_gpu->ubwc_config.rgb565_predicator << 11 |
1340+ hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
1341+ adreno_gpu->ubwc_config.min_acc_len << 3 |
1342+ hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
13411343
13421344 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);
13441347
13451348 gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
1346− uavflagprd_inv << 4 | min_acc_len << 3 |
1347− hbb_lo << 1 | ubwc_mode);
1349+ adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
1350+ adreno_gpu->ubwc_config.min_acc_len << 3 |
1351+ hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
13481352
13491353 if (adreno_is_a7xx(adreno_gpu))
13501354 gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
13511355 FIELD_PREP(GENMASK(8, 5), hbb_lo));
13521356
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);
13541359 }
13551360
13561361 static int a6xx_cp_init(struct msm_gpu *gpu)
@@ -1741,7 +1746,9 @@ static int hw_init(struct msm_gpu *gpu) · 384 unmodified lines
17411746 /* Setting the primFifo thresholds default values,
17421747 * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
17431748 */
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))
17451752 gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
17461753 else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu))
17471754 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
17751782 if (adreno_is_a730(adreno_gpu) ||
17761783 adreno_is_a740_family(adreno_gpu))
17771784 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);
17781787 else if (adreno_is_a619(adreno_gpu))
17791788 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
17801789 else if (adreno_is_a610(adreno_gpu))
@@ -1782,7 +1791,7 @@ static int hw_init(struct msm_gpu *gpu) · 1 unmodified line
17821791 else
17831792 gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
17841793
1785− gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, 1);
1794+ gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1);
17861795
17871796 /* Set weights for bicubic filtering */
17881797 if (adreno_is_a650_family(adreno_gpu)) {
@@ -1808,12 +1817,17 @@ static int hw_init(struct msm_gpu *gpu) · 19 unmodified lines
18081817 a6xx_set_cp_protect(gpu);
18091818
18101819 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);
18121824 gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
18131825 }
18141826
1827+ if (adreno_is_a690(adreno_gpu))
1828+ gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90);
18151829 /* Set dualQ + disable afull for A660 GPU */
1816− if (adreno_is_a660(adreno_gpu))
1830+ else if (adreno_is_a660(adreno_gpu))
18171831 gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906);
18181832 else if (adreno_is_a7xx(adreno_gpu))
18191833 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
29082922 msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
29092923 a6xx_fault_handler);
29102924
2925+ a6xx_calc_ubwc_config(adreno_gpu);
2926+
29112927 return gpu;
29122928 }
drivers/gpu/drm/msm/adreno/adreno_device.c+1−1
@@ -464,7 +464,7 @@ static const struct adreno_info gpulist[] = { · 463 unmodified lines
464464 { 190, 1 },
465465 ),
466466 }, {
467− .chip_ids = ADRENO_CHIP_IDS(0x06080000),
467+ .chip_ids = ADRENO_CHIP_IDS(0x06080001),
468468 .family = ADRENO_6XX_GEN2,
469469 .revn = 680,
470470 .fw = {
drivers/gpu/drm/msm/adreno/adreno_gpu.c+3−0
@@ -373,6 +373,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, · 372 unmodified lines
373373 return -EINVAL;
374374 *value = ctx->aspace->va_size;
375375 return 0;
376+ case MSM_PARAM_HIGHEST_BANK_BIT:
377+ *value = adreno_gpu->ubwc_config.highest_bank_bit;
378+ return 0;
376379 default:
377380 DBG("%s: invalid param: %u", gpu->name, param);
378381 return -EINVAL;
drivers/gpu/drm/msm/adreno/adreno_gpu.h+9−0
@@ -165,6 +165,15 @@ struct adreno_gpu { · 164 unmodified lines
165165 /* firmware: */
166166 const struct firmware *fw[ADRENO_FW_MAX];
167167
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+
168177 /*
169178 * Register offsets are different between some GPUs.
170179 * GPU specific offsets will be exported by GPU specific
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h+457−0
@@ -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
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h+8−9
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps msm8998_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0x7,
13− .qseed_type = DPU_SSPP_SCALER_QSEED3,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -70,7 +69,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 53 unmodified lines
7069 .name = "sspp_0", .id = SSPP_VIG0,
7170 .base = 0x4000, .len = 0x1ac,
7271 .features = VIG_MSM8998_MASK,
73− .sblk = &msm8998_vig_sblk_0,
72+ .sblk = &dpu_vig_sblk_qseed3_1_2,
7473 .xin_id = 0,
7574 .type = SSPP_TYPE_VIG,
7675 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -78,7 +77,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
7877 .name = "sspp_1", .id = SSPP_VIG1,
7978 .base = 0x6000, .len = 0x1ac,
8079 .features = VIG_MSM8998_MASK,
81− .sblk = &msm8998_vig_sblk_1,
80+ .sblk = &dpu_vig_sblk_qseed3_1_2,
8281 .xin_id = 4,
8382 .type = SSPP_TYPE_VIG,
8483 .clk_ctrl = DPU_CLK_CTRL_VIG1,
@@ -86,7 +85,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
8685 .name = "sspp_2", .id = SSPP_VIG2,
8786 .base = 0x8000, .len = 0x1ac,
8887 .features = VIG_MSM8998_MASK,
89− .sblk = &msm8998_vig_sblk_2,
88+ .sblk = &dpu_vig_sblk_qseed3_1_2,
9089 .xin_id = 8,
9190 .type = SSPP_TYPE_VIG,
9291 .clk_ctrl = DPU_CLK_CTRL_VIG2,
@@ -94,7 +93,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
9493 .name = "sspp_3", .id = SSPP_VIG3,
9594 .base = 0xa000, .len = 0x1ac,
9695 .features = VIG_MSM8998_MASK,
97− .sblk = &msm8998_vig_sblk_3,
96+ .sblk = &dpu_vig_sblk_qseed3_1_2,
9897 .xin_id = 12,
9998 .type = SSPP_TYPE_VIG,
10099 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -102,7 +101,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
102101 .name = "sspp_8", .id = SSPP_DMA0,
103102 .base = 0x24000, .len = 0x1ac,
104103 .features = DMA_MSM8998_MASK,
105− .sblk = &sdm845_dma_sblk_0,
104+ .sblk = &dpu_dma_sblk,
106105 .xin_id = 1,
107106 .type = SSPP_TYPE_DMA,
108107 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -110,7 +109,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
110109 .name = "sspp_9", .id = SSPP_DMA1,
111110 .base = 0x26000, .len = 0x1ac,
112111 .features = DMA_MSM8998_MASK,
113− .sblk = &sdm845_dma_sblk_1,
112+ .sblk = &dpu_dma_sblk,
114113 .xin_id = 5,
115114 .type = SSPP_TYPE_DMA,
116115 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -118,7 +117,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
118117 .name = "sspp_10", .id = SSPP_DMA2,
119118 .base = 0x28000, .len = 0x1ac,
120119 .features = DMA_CURSOR_MSM8998_MASK,
121− .sblk = &sdm845_dma_sblk_2,
120+ .sblk = &dpu_dma_sblk,
122121 .xin_id = 9,
123122 .type = SSPP_TYPE_DMA,
124123 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -126,7 +125,7 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = { · 1 unmodified line
126125 .name = "sspp_11", .id = SSPP_DMA3,
127126 .base = 0x2a000, .len = 0x1ac,
128127 .features = DMA_CURSOR_MSM8998_MASK,
129− .sblk = &sdm845_dma_sblk_3,
128+ .sblk = &dpu_dma_sblk,
130129 .xin_id = 13,
131130 .type = SSPP_TYPE_DMA,
132131 .clk_ctrl = DPU_CLK_CTRL_DMA3,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h+8−9
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sdm845_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED3,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 51 unmodified lines
6867 .name = "sspp_0", .id = SSPP_VIG0,
6968 .base = 0x4000, .len = 0x1c8,
7069 .features = VIG_SDM845_MASK_SDMA,
71− .sblk = &sdm845_vig_sblk_0,
70+ .sblk = &dpu_vig_sblk_qseed3_1_3,
7271 .xin_id = 0,
7372 .type = SSPP_TYPE_VIG,
7473 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
7675 .name = "sspp_1", .id = SSPP_VIG1,
7776 .base = 0x6000, .len = 0x1c8,
7877 .features = VIG_SDM845_MASK_SDMA,
79− .sblk = &sdm845_vig_sblk_1,
78+ .sblk = &dpu_vig_sblk_qseed3_1_3,
8079 .xin_id = 4,
8180 .type = SSPP_TYPE_VIG,
8281 .clk_ctrl = DPU_CLK_CTRL_VIG1,
@@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
8483 .name = "sspp_2", .id = SSPP_VIG2,
8584 .base = 0x8000, .len = 0x1c8,
8685 .features = VIG_SDM845_MASK_SDMA,
87− .sblk = &sdm845_vig_sblk_2,
86+ .sblk = &dpu_vig_sblk_qseed3_1_3,
8887 .xin_id = 8,
8988 .type = SSPP_TYPE_VIG,
9089 .clk_ctrl = DPU_CLK_CTRL_VIG2,
@@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
9291 .name = "sspp_3", .id = SSPP_VIG3,
9392 .base = 0xa000, .len = 0x1c8,
9493 .features = VIG_SDM845_MASK_SDMA,
95− .sblk = &sdm845_vig_sblk_3,
94+ .sblk = &dpu_vig_sblk_qseed3_1_3,
9695 .xin_id = 12,
9796 .type = SSPP_TYPE_VIG,
9897 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
10099 .name = "sspp_8", .id = SSPP_DMA0,
101100 .base = 0x24000, .len = 0x1c8,
102101 .features = DMA_SDM845_MASK_SDMA,
103− .sblk = &sdm845_dma_sblk_0,
102+ .sblk = &dpu_dma_sblk,
104103 .xin_id = 1,
105104 .type = SSPP_TYPE_DMA,
106105 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
108107 .name = "sspp_9", .id = SSPP_DMA1,
109108 .base = 0x26000, .len = 0x1c8,
110109 .features = DMA_SDM845_MASK_SDMA,
111− .sblk = &sdm845_dma_sblk_1,
110+ .sblk = &dpu_dma_sblk,
112111 .xin_id = 5,
113112 .type = SSPP_TYPE_DMA,
114113 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
116115 .name = "sspp_10", .id = SSPP_DMA2,
117116 .base = 0x28000, .len = 0x1c8,
118117 .features = DMA_CURSOR_SDM845_MASK_SDMA,
119− .sblk = &sdm845_dma_sblk_2,
118+ .sblk = &dpu_dma_sblk,
120119 .xin_id = 9,
121120 .type = SSPP_TYPE_DMA,
122121 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sdm845_sspp[] = { · 1 unmodified line
124123 .name = "sspp_11", .id = SSPP_DMA3,
125124 .base = 0x2a000, .len = 0x1c8,
126125 .features = DMA_CURSOR_SDM845_MASK_SDMA,
127− .sblk = &sdm845_dma_sblk_3,
126+ .sblk = &dpu_dma_sblk,
128127 .xin_id = 13,
129128 .type = SSPP_TYPE_DMA,
130129 .clk_ctrl = DPU_CLK_CTRL_DMA3,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h+104−0
@@ -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
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h+8−9
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm8150_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED3,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 60 unmodified lines
7776 .name = "sspp_0", .id = SSPP_VIG0,
7877 .base = 0x4000, .len = 0x1f0,
7978 .features = VIG_SDM845_MASK,
80− .sblk = &sdm845_vig_sblk_0,
79+ .sblk = &dpu_vig_sblk_qseed3_1_4,
8180 .xin_id = 0,
8281 .type = SSPP_TYPE_VIG,
8382 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -85,7 +84,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
8584 .name = "sspp_1", .id = SSPP_VIG1,
8685 .base = 0x6000, .len = 0x1f0,
8786 .features = VIG_SDM845_MASK,
88− .sblk = &sdm845_vig_sblk_1,
87+ .sblk = &dpu_vig_sblk_qseed3_1_4,
8988 .xin_id = 4,
9089 .type = SSPP_TYPE_VIG,
9190 .clk_ctrl = DPU_CLK_CTRL_VIG1,
@@ -93,7 +92,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
9392 .name = "sspp_2", .id = SSPP_VIG2,
9493 .base = 0x8000, .len = 0x1f0,
9594 .features = VIG_SDM845_MASK,
96− .sblk = &sdm845_vig_sblk_2,
95+ .sblk = &dpu_vig_sblk_qseed3_1_4,
9796 .xin_id = 8,
9897 .type = SSPP_TYPE_VIG,
9998 .clk_ctrl = DPU_CLK_CTRL_VIG2,
@@ -101,7 +100,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
101100 .name = "sspp_3", .id = SSPP_VIG3,
102101 .base = 0xa000, .len = 0x1f0,
103102 .features = VIG_SDM845_MASK,
104− .sblk = &sdm845_vig_sblk_3,
103+ .sblk = &dpu_vig_sblk_qseed3_1_4,
105104 .xin_id = 12,
106105 .type = SSPP_TYPE_VIG,
107106 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -109,7 +108,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
109108 .name = "sspp_8", .id = SSPP_DMA0,
110109 .base = 0x24000, .len = 0x1f0,
111110 .features = DMA_SDM845_MASK,
112− .sblk = &sdm845_dma_sblk_0,
111+ .sblk = &dpu_dma_sblk,
113112 .xin_id = 1,
114113 .type = SSPP_TYPE_DMA,
115114 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -117,7 +116,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
117116 .name = "sspp_9", .id = SSPP_DMA1,
118117 .base = 0x26000, .len = 0x1f0,
119118 .features = DMA_SDM845_MASK,
120− .sblk = &sdm845_dma_sblk_1,
119+ .sblk = &dpu_dma_sblk,
121120 .xin_id = 5,
122121 .type = SSPP_TYPE_DMA,
123122 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -125,7 +124,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
125124 .name = "sspp_10", .id = SSPP_DMA2,
126125 .base = 0x28000, .len = 0x1f0,
127126 .features = DMA_CURSOR_SDM845_MASK,
128− .sblk = &sdm845_dma_sblk_2,
127+ .sblk = &dpu_dma_sblk,
129128 .xin_id = 9,
130129 .type = SSPP_TYPE_DMA,
131130 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -133,7 +132,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = { · 1 unmodified line
133132 .name = "sspp_11", .id = SSPP_DMA3,
134133 .base = 0x2a000, .len = 0x1f0,
135134 .features = DMA_CURSOR_SDM845_MASK,
136− .sblk = &sdm845_dma_sblk_3,
135+ .sblk = &dpu_dma_sblk,
137136 .xin_id = 13,
138137 .type = SSPP_TYPE_DMA,
139138 .clk_ctrl = DPU_CLK_CTRL_DMA3,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h+9−9
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sc8180x_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED3,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 59 unmodified lines
7675 .name = "sspp_0", .id = SSPP_VIG0,
7776 .base = 0x4000, .len = 0x1f0,
7877 .features = VIG_SDM845_MASK,
79− .sblk = &sdm845_vig_sblk_0,
78+ .sblk = &dpu_vig_sblk_qseed3_1_4,
8079 .xin_id = 0,
8180 .type = SSPP_TYPE_VIG,
8281 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
8483 .name = "sspp_1", .id = SSPP_VIG1,
8584 .base = 0x6000, .len = 0x1f0,
8685 .features = VIG_SDM845_MASK,
87− .sblk = &sdm845_vig_sblk_1,
86+ .sblk = &dpu_vig_sblk_qseed3_1_4,
8887 .xin_id = 4,
8988 .type = SSPP_TYPE_VIG,
9089 .clk_ctrl = DPU_CLK_CTRL_VIG1,
@@ -92,7 +91,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
9291 .name = "sspp_2", .id = SSPP_VIG2,
9392 .base = 0x8000, .len = 0x1f0,
9493 .features = VIG_SDM845_MASK,
95− .sblk = &sdm845_vig_sblk_2,
94+ .sblk = &dpu_vig_sblk_qseed3_1_4,
9695 .xin_id = 8,
9796 .type = SSPP_TYPE_VIG,
9897 .clk_ctrl = DPU_CLK_CTRL_VIG2,
@@ -100,7 +99,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
10099 .name = "sspp_3", .id = SSPP_VIG3,
101100 .base = 0xa000, .len = 0x1f0,
102101 .features = VIG_SDM845_MASK,
103− .sblk = &sdm845_vig_sblk_3,
102+ .sblk = &dpu_vig_sblk_qseed3_1_4,
104103 .xin_id = 12,
105104 .type = SSPP_TYPE_VIG,
106105 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
108107 .name = "sspp_8", .id = SSPP_DMA0,
109108 .base = 0x24000, .len = 0x1f0,
110109 .features = DMA_SDM845_MASK,
111− .sblk = &sdm845_dma_sblk_0,
110+ .sblk = &dpu_dma_sblk,
112111 .xin_id = 1,
113112 .type = SSPP_TYPE_DMA,
114113 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
116115 .name = "sspp_9", .id = SSPP_DMA1,
117116 .base = 0x26000, .len = 0x1f0,
118117 .features = DMA_SDM845_MASK,
119− .sblk = &sdm845_dma_sblk_1,
118+ .sblk = &dpu_dma_sblk,
120119 .xin_id = 5,
121120 .type = SSPP_TYPE_DMA,
122121 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
124123 .name = "sspp_10", .id = SSPP_DMA2,
125124 .base = 0x28000, .len = 0x1f0,
126125 .features = DMA_CURSOR_SDM845_MASK,
127− .sblk = &sdm845_dma_sblk_2,
126+ .sblk = &dpu_dma_sblk,
128127 .xin_id = 9,
129128 .type = SSPP_TYPE_DMA,
130129 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = { · 1 unmodified line
132131 .name = "sspp_11", .id = SSPP_DMA3,
133132 .base = 0x2a000, .len = 0x1f0,
134133 .features = DMA_CURSOR_SDM845_MASK,
135− .sblk = &sdm845_dma_sblk_3,
134+ .sblk = &dpu_dma_sblk,
136135 .xin_id = 13,
137136 .type = SSPP_TYPE_DMA,
138137 .clk_ctrl = DPU_CLK_CTRL_DMA3,
@@ -367,6 +366,7 @@ static const struct dpu_perf_cfg sc8180x_perf_data = { · 228 unmodified lines
367366 .min_llcc_ib = 800000,
368367 .min_dram_ib = 800000,
369368 .danger_lut_tbl = {0xf, 0xffff, 0x0},
369+ .safe_lut_tbl = {0xfff0, 0xf000, 0xffff},
370370 .qos_lut_tbl = {
371371 {.nentry = ARRAY_SIZE(sc7180_qos_linear),
372372 .entries = sc7180_qos_linear
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_4_sm6125.h+4−4
@@ -68,8 +68,8 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 67 unmodified lines
6868 {
6969 .name = "sspp_0", .id = SSPP_VIG0,
7070 .base = 0x4000, .len = 0x1f0,
71− .features = VIG_SM6125_MASK,
72− .sblk = &sm6125_vig_sblk_0,
71+ .features = VIG_SDM845_MASK,
72+ .sblk = &dpu_vig_sblk_qseed3_2_4,
7373 .xin_id = 0,
7474 .type = SSPP_TYPE_VIG,
7575 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line
7777 .name = "sspp_8", .id = SSPP_DMA0,
7878 .base = 0x24000, .len = 0x1f0,
7979 .features = DMA_SDM845_MASK,
80− .sblk = &sdm845_dma_sblk_0,
80+ .sblk = &dpu_dma_sblk,
8181 .xin_id = 1,
8282 .type = SSPP_TYPE_DMA,
8383 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm6125_sspp[] = { · 1 unmodified line
8585 .name = "sspp_9", .id = SSPP_DMA1,
8686 .base = 0x26000, .len = 0x1f0,
8787 .features = DMA_SDM845_MASK,
88− .sblk = &sdm845_dma_sblk_1,
88+ .sblk = &dpu_dma_sblk,
8989 .xin_id = 5,
9090 .type = SSPP_TYPE_DMA,
9191 .clk_ctrl = DPU_CLK_CTRL_DMA1,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h+16−16
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm8250_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -32,7 +31,7 @@ static const struct dpu_mdp_cfg sm8250_mdp = { · 15 unmodified lines
3231 [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
3332 [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
3433 [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 },
3635 },
3736 };
3837
@@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 36 unmodified lines
7574 {
7675 .name = "sspp_0", .id = SSPP_VIG0,
7776 .base = 0x4000, .len = 0x1f8,
78− .features = VIG_SC7180_MASK_SDMA,
79− .sblk = &sm8250_vig_sblk_0,
77+ .features = VIG_SDM845_MASK_SDMA,
78+ .sblk = &dpu_vig_sblk_qseed3_3_0,
8079 .xin_id = 0,
8180 .type = SSPP_TYPE_VIG,
8281 .clk_ctrl = DPU_CLK_CTRL_VIG0,
8382 }, {
8483 .name = "sspp_1", .id = SSPP_VIG1,
8584 .base = 0x6000, .len = 0x1f8,
86− .features = VIG_SC7180_MASK_SDMA,
87− .sblk = &sm8250_vig_sblk_1,
85+ .features = VIG_SDM845_MASK_SDMA,
86+ .sblk = &dpu_vig_sblk_qseed3_3_0,
8887 .xin_id = 4,
8988 .type = SSPP_TYPE_VIG,
9089 .clk_ctrl = DPU_CLK_CTRL_VIG1,
9190 }, {
9291 .name = "sspp_2", .id = SSPP_VIG2,
9392 .base = 0x8000, .len = 0x1f8,
94− .features = VIG_SC7180_MASK_SDMA,
95− .sblk = &sm8250_vig_sblk_2,
93+ .features = VIG_SDM845_MASK_SDMA,
94+ .sblk = &dpu_vig_sblk_qseed3_3_0,
9695 .xin_id = 8,
9796 .type = SSPP_TYPE_VIG,
9897 .clk_ctrl = DPU_CLK_CTRL_VIG2,
9998 }, {
10099 .name = "sspp_3", .id = SSPP_VIG3,
101100 .base = 0xa000, .len = 0x1f8,
102− .features = VIG_SC7180_MASK_SDMA,
103− .sblk = &sm8250_vig_sblk_3,
101+ .features = VIG_SDM845_MASK_SDMA,
102+ .sblk = &dpu_vig_sblk_qseed3_3_0,
104103 .xin_id = 12,
105104 .type = SSPP_TYPE_VIG,
106105 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line
108107 .name = "sspp_8", .id = SSPP_DMA0,
109108 .base = 0x24000, .len = 0x1f8,
110109 .features = DMA_SDM845_MASK_SDMA,
111− .sblk = &sdm845_dma_sblk_0,
110+ .sblk = &dpu_dma_sblk,
112111 .xin_id = 1,
113112 .type = SSPP_TYPE_DMA,
114113 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line
116115 .name = "sspp_9", .id = SSPP_DMA1,
117116 .base = 0x26000, .len = 0x1f8,
118117 .features = DMA_SDM845_MASK_SDMA,
119− .sblk = &sdm845_dma_sblk_1,
118+ .sblk = &dpu_dma_sblk,
120119 .xin_id = 5,
121120 .type = SSPP_TYPE_DMA,
122121 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line
124123 .name = "sspp_10", .id = SSPP_DMA2,
125124 .base = 0x28000, .len = 0x1f8,
126125 .features = DMA_CURSOR_SDM845_MASK_SDMA,
127− .sblk = &sdm845_dma_sblk_2,
126+ .sblk = &dpu_dma_sblk,
128127 .xin_id = 9,
129128 .type = SSPP_TYPE_DMA,
130129 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sm8250_sspp[] = { · 1 unmodified line
132131 .name = "sspp_11", .id = SSPP_DMA3,
133132 .base = 0x2a000, .len = 0x1f8,
134133 .features = DMA_CURSOR_SDM845_MASK_SDMA,
135− .sblk = &sdm845_dma_sblk_3,
134+ .sblk = &dpu_dma_sblk,
136135 .xin_id = 13,
137136 .type = SSPP_TYPE_DMA,
138137 .clk_ctrl = DPU_CLK_CTRL_DMA3,
@@ -337,8 +336,8 @@ static const struct dpu_wb_cfg sm8250_wb[] = { · 198 unmodified lines
337336 .name = "wb_2", .id = WB_2,
338337 .base = 0x65000, .len = 0x2c8,
339338 .features = WB_SM8250_MASK,
340− .format_list = wb2_formats,
341− .num_formats = ARRAY_SIZE(wb2_formats),
339+ .format_list = wb2_formats_rgb_yuv,
340+ .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
342341 .clk_ctrl = DPU_CLK_CTRL_WB2,
343342 .xin_id = 6,
344343 .vbif_idx = VBIF_RT,
@@ -385,6 +384,7 @@ const struct dpu_mdss_cfg dpu_sm8250_cfg = { · 40 unmodified lines
385384 .mdss_ver = &sm8250_mdss_ver,
386385 .caps = &sm8250_dpu_caps,
387386 .mdp = &sm8250_mdp,
387+ .cdm = &sc7280_cdm,
388388 .ctl_count = ARRAY_SIZE(sm8250_ctl),
389389 .ctl = sm8250_ctl,
390390 .sspp_count = ARRAY_SIZE(sm8250_sspp),
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h+8−9
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sc7180_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0x9,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_dim_layer = true,
1514 .has_idle_pc = true,
1615 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
@@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7180_mdp = { · 8 unmodified lines
2524 [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
2625 [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
2726 [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 },
2928 },
3029 };
3130
@@ -52,8 +51,8 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 20 unmodified lines
5251 {
5352 .name = "sspp_0", .id = SSPP_VIG0,
5453 .base = 0x4000, .len = 0x1f8,
55− .features = VIG_SC7180_MASK,
56− .sblk = &sc7180_vig_sblk_0,
54+ .features = VIG_SDM845_MASK,
55+ .sblk = &dpu_vig_sblk_qseed3_3_0,
5756 .xin_id = 0,
5857 .type = SSPP_TYPE_VIG,
5958 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -61,7 +60,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line
6160 .name = "sspp_8", .id = SSPP_DMA0,
6261 .base = 0x24000, .len = 0x1f8,
6362 .features = DMA_SDM845_MASK,
64− .sblk = &sdm845_dma_sblk_0,
63+ .sblk = &dpu_dma_sblk,
6564 .xin_id = 1,
6665 .type = SSPP_TYPE_DMA,
6766 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -69,7 +68,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line
6968 .name = "sspp_9", .id = SSPP_DMA1,
7069 .base = 0x26000, .len = 0x1f8,
7170 .features = DMA_CURSOR_SDM845_MASK,
72− .sblk = &sdm845_dma_sblk_1,
71+ .sblk = &dpu_dma_sblk,
7372 .xin_id = 5,
7473 .type = SSPP_TYPE_DMA,
7574 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -77,7 +76,7 @@ static const struct dpu_sspp_cfg sc7180_sspp[] = { · 1 unmodified line
7776 .name = "sspp_10", .id = SSPP_DMA2,
7877 .base = 0x28000, .len = 0x1f8,
7978 .features = DMA_CURSOR_SDM845_MASK,
80− .sblk = &sdm845_dma_sblk_2,
79+ .sblk = &dpu_dma_sblk,
8180 .xin_id = 9,
8281 .type = SSPP_TYPE_DMA,
8382 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -158,8 +157,8 @@ static const struct dpu_wb_cfg sc7180_wb[] = { · 74 unmodified lines
158157 .name = "wb_2", .id = WB_2,
159158 .base = 0x65000, .len = 0x2c8,
160159 .features = WB_SM8250_MASK,
161− .format_list = wb2_formats,
162− .num_formats = ARRAY_SIZE(wb2_formats),
160+ .format_list = wb2_formats_rgb,
161+ .num_formats = ARRAY_SIZE(wb2_formats_rgb),
163162 .clk_ctrl = DPU_CLK_CTRL_WB2,
164163 .xin_id = 6,
165164 .vbif_idx = VBIF_RT,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h+3−4
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm6115_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
1212 .max_mixer_blendstages = 0x4,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_dim_layer = true,
1514 .has_idle_pc = true,
1615 .max_linewidth = 2160,
@@ -39,8 +38,8 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 22 unmodified lines
3938 {
4039 .name = "sspp_0", .id = SSPP_VIG0,
4140 .base = 0x4000, .len = 0x1f8,
42− .features = VIG_SC7180_MASK,
43− .sblk = &sm6115_vig_sblk_0,
41+ .features = VIG_SDM845_MASK,
42+ .sblk = &dpu_vig_sblk_qseed3_3_0,
4443 .xin_id = 0,
4544 .type = SSPP_TYPE_VIG,
4645 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -48,7 +47,7 @@ static const struct dpu_sspp_cfg sm6115_sspp[] = { · 1 unmodified line
4847 .name = "sspp_8", .id = SSPP_DMA0,
4948 .base = 0x24000, .len = 0x1f8,
5049 .features = DMA_SDM845_MASK,
51− .sblk = &sdm845_dma_sblk_0,
50+ .sblk = &dpu_dma_sblk,
5251 .xin_id = 1,
5352 .type = SSPP_TYPE_DMA,
5453 .clk_ctrl = DPU_CLK_CTRL_DMA0,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_4_sm6350.h+5−6
@@ -11,7 +11,6 @@ · 10 unmodified lines
1111 static const struct dpu_caps sm6350_dpu_caps = {
1212 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1313 .max_mixer_blendstages = 0x7,
14− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1514 .has_src_split = true,
1615 .has_dim_layer = true,
1716 .has_idle_pc = true,
@@ -59,8 +58,8 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 41 unmodified lines
5958 {
6059 .name = "sspp_0", .id = SSPP_VIG0,
6160 .base = 0x4000, .len = 0x1f8,
62− .features = VIG_SC7180_MASK,
63− .sblk = &sc7180_vig_sblk_0,
61+ .features = VIG_SDM845_MASK,
62+ .sblk = &dpu_vig_sblk_qseed3_3_0,
6463 .xin_id = 0,
6564 .type = SSPP_TYPE_VIG,
6665 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -68,7 +67,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line
6867 .name = "sspp_8", .id = SSPP_DMA0,
6968 .base = 0x24000, .len = 0x1f8,
7069 .features = DMA_SDM845_MASK,
71− .sblk = &sdm845_dma_sblk_0,
70+ .sblk = &dpu_dma_sblk,
7271 .xin_id = 1,
7372 .type = SSPP_TYPE_DMA,
7473 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -76,7 +75,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line
7675 .name = "sspp_9", .id = SSPP_DMA1,
7776 .base = 0x26000, .len = 0x1f8,
7877 .features = DMA_CURSOR_SDM845_MASK,
79− .sblk = &sdm845_dma_sblk_1,
78+ .sblk = &dpu_dma_sblk,
8079 .xin_id = 5,
8180 .type = SSPP_TYPE_DMA,
8281 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -84,7 +83,7 @@ static const struct dpu_sspp_cfg sm6350_sspp[] = { · 1 unmodified line
8483 .name = "sspp_10", .id = SSPP_DMA2,
8584 .base = 0x28000, .len = 0x1f8,
8685 .features = DMA_CURSOR_SDM845_MASK,
87− .sblk = &sdm845_dma_sblk_2,
86+ .sblk = &dpu_dma_sblk,
8887 .xin_id = 9,
8988 .type = SSPP_TYPE_DMA,
9089 .clk_ctrl = DPU_CLK_CTRL_DMA2,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h+2−2
@@ -39,7 +39,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 38 unmodified lines
3939 .name = "sspp_0", .id = SSPP_VIG0,
4040 .base = 0x4000, .len = 0x1f8,
4141 .features = VIG_QCM2290_MASK,
42− .sblk = &qcm2290_vig_sblk_0,
42+ .sblk = &dpu_vig_sblk_noscale,
4343 .xin_id = 0,
4444 .type = SSPP_TYPE_VIG,
4545 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -47,7 +47,7 @@ static const struct dpu_sspp_cfg qcm2290_sspp[] = { · 1 unmodified line
4747 .name = "sspp_8", .id = SSPP_DMA0,
4848 .base = 0x24000, .len = 0x1f8,
4949 .features = DMA_SDM845_MASK,
50− .sblk = &qcm2290_dma_sblk_0,
50+ .sblk = &dpu_dma_sblk,
5151 .xin_id = 1,
5252 .type = SSPP_TYPE_DMA,
5353 .clk_ctrl = DPU_CLK_CTRL_DMA0,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_9_sm6375.h+3−4
@@ -11,7 +11,6 @@ · 10 unmodified lines
1111 static const struct dpu_caps sm6375_dpu_caps = {
1212 .max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
1313 .max_mixer_blendstages = 0x4,
14− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
1716 .max_linewidth = 2160,
@@ -40,8 +39,8 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 22 unmodified lines
4039 {
4140 .name = "sspp_0", .id = SSPP_VIG0,
4241 .base = 0x4000, .len = 0x1f8,
43− .features = VIG_SC7180_MASK,
44− .sblk = &sm6115_vig_sblk_0,
42+ .features = VIG_SDM845_MASK,
43+ .sblk = &dpu_vig_sblk_qseed3_3_0,
4544 .xin_id = 0,
4645 .type = SSPP_TYPE_VIG,
4746 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -49,7 +48,7 @@ static const struct dpu_sspp_cfg sm6375_sspp[] = { · 1 unmodified line
4948 .name = "sspp_8", .id = SSPP_DMA0,
5049 .base = 0x24000, .len = 0x1f8,
5150 .features = DMA_SDM845_MASK,
52− .sblk = &sdm845_dma_sblk_0,
51+ .sblk = &dpu_dma_sblk,
5352 .xin_id = 1,
5453 .type = SSPP_TYPE_DMA,
5554 .clk_ctrl = DPU_CLK_CTRL_DMA0,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h+34−17
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm8350_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -31,6 +30,7 @@ static const struct dpu_mdp_cfg sm8350_mdp = { · 14 unmodified lines
3130 [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
3231 [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
3332 [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
33+ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
3434 [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
3535 },
3636 };
@@ -74,64 +74,64 @@ static const struct dpu_sspp_cfg sm8350_sspp[] = { · 37 unmodified lines
7474 {
7575 .name = "sspp_0", .id = SSPP_VIG0,
7676 .base = 0x4000, .len = 0x1f8,
77− .features = VIG_SC7180_MASK,
78− .sblk = &sm8250_vig_sblk_0,
77+ .features = VIG_SDM845_MASK_SDMA,
78+ .sblk = &dpu_vig_sblk_qseed3_3_0,
7979 .xin_id = 0,
8080 .type = SSPP_TYPE_VIG,
8181 .clk_ctrl = DPU_CLK_CTRL_VIG0,
8282 }, {
8383 .name = "sspp_1", .id = SSPP_VIG1,
8484 .base = 0x6000, .len = 0x1f8,
85− .features = VIG_SC7180_MASK,
86− .sblk = &sm8250_vig_sblk_1,
85+ .features = VIG_SDM845_MASK_SDMA,
86+ .sblk = &dpu_vig_sblk_qseed3_3_0,
8787 .xin_id = 4,
8888 .type = SSPP_TYPE_VIG,
8989 .clk_ctrl = DPU_CLK_CTRL_VIG1,
9090 }, {
9191 .name = "sspp_2", .id = SSPP_VIG2,
9292 .base = 0x8000, .len = 0x1f8,
93− .features = VIG_SC7180_MASK,
94− .sblk = &sm8250_vig_sblk_2,
93+ .features = VIG_SDM845_MASK_SDMA,
94+ .sblk = &dpu_vig_sblk_qseed3_3_0,
9595 .xin_id = 8,
9696 .type = SSPP_TYPE_VIG,
9797 .clk_ctrl = DPU_CLK_CTRL_VIG2,
9898 }, {
9999 .name = "sspp_3", .id = SSPP_VIG3,
100100 .base = 0xa000, .len = 0x1f8,
101− .features = VIG_SC7180_MASK,
102− .sblk = &sm8250_vig_sblk_3,
101+ .features = VIG_SDM845_MASK_SDMA,
102+ .sblk = &dpu_vig_sblk_qseed3_3_0,
103103 .xin_id = 12,
104104 .type = SSPP_TYPE_VIG,
105105 .clk_ctrl = DPU_CLK_CTRL_VIG3,
106106 }, {
107107 .name = "sspp_8", .id = SSPP_DMA0,
108108 .base = 0x24000, .len = 0x1f8,
109− .features = DMA_SDM845_MASK,
110− .sblk = &sdm845_dma_sblk_0,
109+ .features = DMA_SDM845_MASK_SDMA,
110+ .sblk = &dpu_dma_sblk,
111111 .xin_id = 1,
112112 .type = SSPP_TYPE_DMA,
113113 .clk_ctrl = DPU_CLK_CTRL_DMA0,
114114 }, {
115115 .name = "sspp_9", .id = SSPP_DMA1,
116116 .base = 0x26000, .len = 0x1f8,
117− .features = DMA_SDM845_MASK,
118− .sblk = &sdm845_dma_sblk_1,
117+ .features = DMA_SDM845_MASK_SDMA,
118+ .sblk = &dpu_dma_sblk,
119119 .xin_id = 5,
120120 .type = SSPP_TYPE_DMA,
121121 .clk_ctrl = DPU_CLK_CTRL_DMA1,
122122 }, {
123123 .name = "sspp_10", .id = SSPP_DMA2,
124124 .base = 0x28000, .len = 0x1f8,
125− .features = DMA_CURSOR_SDM845_MASK,
126− .sblk = &sdm845_dma_sblk_2,
125+ .features = DMA_CURSOR_SDM845_MASK_SDMA,
126+ .sblk = &dpu_dma_sblk,
127127 .xin_id = 9,
128128 .type = SSPP_TYPE_DMA,
129129 .clk_ctrl = DPU_CLK_CTRL_DMA2,
130130 }, {
131131 .name = "sspp_11", .id = SSPP_DMA3,
132132 .base = 0x2a000, .len = 0x1f8,
133− .features = DMA_CURSOR_SDM845_MASK,
134− .sblk = &sdm845_dma_sblk_3,
133+ .features = DMA_CURSOR_SDM845_MASK_SDMA,
134+ .sblk = &dpu_dma_sblk,
135135 .xin_id = 13,
136136 .type = SSPP_TYPE_DMA,
137137 .clk_ctrl = DPU_CLK_CTRL_DMA3,
@@ -298,6 +298,21 @@ static const struct dpu_dsc_cfg sm8350_dsc[] = { · 160 unmodified lines
298298 },
299299 };
300300
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+
301316 static const struct dpu_intf_cfg sm8350_intf[] = {
302317 {
303318 .name = "intf_0", .id = INTF_0,
@@ -393,6 +408,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { · 89 unmodified lines
393408 .dsc = sm8350_dsc,
394409 .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
395410 .merge_3d = sm8350_merge_3d,
411+ .wb_count = ARRAY_SIZE(sm8350_wb),
412+ .wb = sm8350_wb,
396413 .intf_count = ARRAY_SIZE(sm8350_intf),
397414 .intf = sm8350_intf,
398415 .vbif_count = ARRAY_SIZE(sdm845_vbif),
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h+8−8
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sc7280_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0x7,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_dim_layer = true,
1514 .has_idle_pc = true,
1615 .max_linewidth = 2400,
@@ -25,7 +24,7 @@ static const struct dpu_mdp_cfg sc7280_mdp = { · 8 unmodified lines
2524 [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
2625 [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
2726 [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 },
2928 },
3029 };
3130
@@ -58,7 +57,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 26 unmodified lines
5857 .name = "sspp_0", .id = SSPP_VIG0,
5958 .base = 0x4000, .len = 0x1f8,
6059 .features = VIG_SC7280_MASK_SDMA,
61− .sblk = &sc7280_vig_sblk_0,
60+ .sblk = &dpu_vig_sblk_qseed3_3_0_rot_v2,
6261 .xin_id = 0,
6362 .type = SSPP_TYPE_VIG,
6463 .clk_ctrl = DPU_CLK_CTRL_VIG0,
@@ -66,7 +65,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line
6665 .name = "sspp_8", .id = SSPP_DMA0,
6766 .base = 0x24000, .len = 0x1f8,
6867 .features = DMA_SDM845_MASK_SDMA,
69− .sblk = &sdm845_dma_sblk_0,
68+ .sblk = &dpu_dma_sblk,
7069 .xin_id = 1,
7170 .type = SSPP_TYPE_DMA,
7271 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -74,7 +73,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line
7473 .name = "sspp_9", .id = SSPP_DMA1,
7574 .base = 0x26000, .len = 0x1f8,
7675 .features = DMA_CURSOR_SDM845_MASK_SDMA,
77− .sblk = &sdm845_dma_sblk_1,
76+ .sblk = &dpu_dma_sblk,
7877 .xin_id = 5,
7978 .type = SSPP_TYPE_DMA,
8079 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -82,7 +81,7 @@ static const struct dpu_sspp_cfg sc7280_sspp[] = { · 1 unmodified line
8281 .name = "sspp_10", .id = SSPP_DMA2,
8382 .base = 0x28000, .len = 0x1f8,
8483 .features = DMA_CURSOR_SDM845_MASK_SDMA,
85− .sblk = &sdm845_dma_sblk_2,
84+ .sblk = &dpu_dma_sblk,
8685 .xin_id = 9,
8786 .type = SSPP_TYPE_DMA,
8887 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -170,8 +169,8 @@ static const struct dpu_wb_cfg sc7280_wb[] = { · 81 unmodified lines
170169 .name = "wb_2", .id = WB_2,
171170 .base = 0x65000, .len = 0x2c8,
172171 .features = WB_SM8250_MASK,
173− .format_list = wb2_formats,
174− .num_formats = ARRAY_SIZE(wb2_formats),
172+ .format_list = wb2_formats_rgb_yuv,
173+ .num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
175174 .clk_ctrl = DPU_CLK_CTRL_WB2,
176175 .xin_id = 6,
177176 .vbif_idx = VBIF_RT,
@@ -249,6 +248,7 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { · 71 unmodified lines
249248 .mdss_ver = &sc7280_mdss_ver,
250249 .caps = &sc7280_dpu_caps,
251250 .mdp = &sc7280_mdp,
251+ .cdm = &sc7280_cdm,
252252 .ctl_count = ARRAY_SIZE(sc7280_ctl),
253253 .ctl = sc7280_ctl,
254254 .sspp_count = ARRAY_SIZE(sc7280_sspp),
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h+12−13
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sc8280xp_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 11,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -75,32 +74,32 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 58 unmodified lines
7574 {
7675 .name = "sspp_0", .id = SSPP_VIG0,
7776 .base = 0x4000, .len = 0x2ac,
78− .features = VIG_SC7180_MASK,
79− .sblk = &sm8250_vig_sblk_0,
77+ .features = VIG_SDM845_MASK,
78+ .sblk = &dpu_vig_sblk_qseed3_3_0,
8079 .xin_id = 0,
8180 .type = SSPP_TYPE_VIG,
8281 .clk_ctrl = DPU_CLK_CTRL_VIG0,
8382 }, {
8483 .name = "sspp_1", .id = SSPP_VIG1,
8584 .base = 0x6000, .len = 0x2ac,
86− .features = VIG_SC7180_MASK,
87− .sblk = &sm8250_vig_sblk_1,
85+ .features = VIG_SDM845_MASK,
86+ .sblk = &dpu_vig_sblk_qseed3_3_0,
8887 .xin_id = 4,
8988 .type = SSPP_TYPE_VIG,
9089 .clk_ctrl = DPU_CLK_CTRL_VIG1,
9190 }, {
9291 .name = "sspp_2", .id = SSPP_VIG2,
9392 .base = 0x8000, .len = 0x2ac,
94− .features = VIG_SC7180_MASK,
95− .sblk = &sm8250_vig_sblk_2,
93+ .features = VIG_SDM845_MASK,
94+ .sblk = &dpu_vig_sblk_qseed3_3_0,
9695 .xin_id = 8,
9796 .type = SSPP_TYPE_VIG,
9897 .clk_ctrl = DPU_CLK_CTRL_VIG2,
9998 }, {
10099 .name = "sspp_3", .id = SSPP_VIG3,
101100 .base = 0xa000, .len = 0x2ac,
102− .features = VIG_SC7180_MASK,
103− .sblk = &sm8250_vig_sblk_3,
101+ .features = VIG_SDM845_MASK,
102+ .sblk = &dpu_vig_sblk_qseed3_3_0,
104103 .xin_id = 12,
105104 .type = SSPP_TYPE_VIG,
106105 .clk_ctrl = DPU_CLK_CTRL_VIG3,
@@ -108,7 +107,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line
108107 .name = "sspp_8", .id = SSPP_DMA0,
109108 .base = 0x24000, .len = 0x2ac,
110109 .features = DMA_SDM845_MASK,
111− .sblk = &sdm845_dma_sblk_0,
110+ .sblk = &dpu_dma_sblk,
112111 .xin_id = 1,
113112 .type = SSPP_TYPE_DMA,
114113 .clk_ctrl = DPU_CLK_CTRL_DMA0,
@@ -116,7 +115,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line
116115 .name = "sspp_9", .id = SSPP_DMA1,
117116 .base = 0x26000, .len = 0x2ac,
118117 .features = DMA_SDM845_MASK,
119− .sblk = &sdm845_dma_sblk_1,
118+ .sblk = &dpu_dma_sblk,
120119 .xin_id = 5,
121120 .type = SSPP_TYPE_DMA,
122121 .clk_ctrl = DPU_CLK_CTRL_DMA1,
@@ -124,7 +123,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line
124123 .name = "sspp_10", .id = SSPP_DMA2,
125124 .base = 0x28000, .len = 0x2ac,
126125 .features = DMA_CURSOR_SDM845_MASK,
127− .sblk = &sdm845_dma_sblk_2,
126+ .sblk = &dpu_dma_sblk,
128127 .xin_id = 9,
129128 .type = SSPP_TYPE_DMA,
130129 .clk_ctrl = DPU_CLK_CTRL_DMA2,
@@ -132,7 +131,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { · 1 unmodified line
132131 .name = "sspp_11", .id = SSPP_DMA3,
133132 .base = 0x2a000, .len = 0x2ac,
134133 .features = DMA_CURSOR_SDM845_MASK,
135− .sblk = &sdm845_dma_sblk_3,
134+ .sblk = &dpu_dma_sblk,
136135 .xin_id = 13,
137136 .type = SSPP_TYPE_DMA,
138137 .clk_ctrl = DPU_CLK_CTRL_DMA3,
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h+34−17
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm8450_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -32,6 +31,7 @@ static const struct dpu_mdp_cfg sm8450_mdp = { · 15 unmodified lines
3231 [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
3332 [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
3433 [DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
34+ [DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
3535 [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
3636 },
3737 };
@@ -75,64 +75,64 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = { · 37 unmodified lines
7575 {
7676 .name = "sspp_0", .id = SSPP_VIG0,
7777 .base = 0x4000, .len = 0x32c,
78− .features = VIG_SC7180_MASK,
79− .sblk = &sm8250_vig_sblk_0,
78+ .features = VIG_SDM845_MASK_SDMA,
79+ .sblk = &dpu_vig_sblk_qseed3_3_1,
8080 .xin_id = 0,
8181 .type = SSPP_TYPE_VIG,
8282 .clk_ctrl = DPU_CLK_CTRL_VIG0,
8383 }, {
8484 .name = "sspp_1", .id = SSPP_VIG1,
8585 .base = 0x6000, .len = 0x32c,
86− .features = VIG_SC7180_MASK,
87− .sblk = &sm8250_vig_sblk_1,
86+ .features = VIG_SDM845_MASK_SDMA,
87+ .sblk = &dpu_vig_sblk_qseed3_3_1,
8888 .xin_id = 4,
8989 .type = SSPP_TYPE_VIG,
9090 .clk_ctrl = DPU_CLK_CTRL_VIG1,
9191 }, {
9292 .name = "sspp_2", .id = SSPP_VIG2,
9393 .base = 0x8000, .len = 0x32c,
94− .features = VIG_SC7180_MASK,
95− .sblk = &sm8250_vig_sblk_2,
94+ .features = VIG_SDM845_MASK_SDMA,
95+ .sblk = &dpu_vig_sblk_qseed3_3_1,
9696 .xin_id = 8,
9797 .type = SSPP_TYPE_VIG,
9898 .clk_ctrl = DPU_CLK_CTRL_VIG2,
9999 }, {
100100 .name = "sspp_3", .id = SSPP_VIG3,
101101 .base = 0xa000, .len = 0x32c,
102− .features = VIG_SC7180_MASK,
103− .sblk = &sm8250_vig_sblk_3,
102+ .features = VIG_SDM845_MASK_SDMA,
103+ .sblk = &dpu_vig_sblk_qseed3_3_1,
104104 .xin_id = 12,
105105 .type = SSPP_TYPE_VIG,
106106 .clk_ctrl = DPU_CLK_CTRL_VIG3,
107107 }, {
108108 .name = "sspp_8", .id = SSPP_DMA0,
109109 .base = 0x24000, .len = 0x32c,
110− .features = DMA_SDM845_MASK,
111− .sblk = &sdm845_dma_sblk_0,
110+ .features = DMA_SDM845_MASK_SDMA,
111+ .sblk = &dpu_dma_sblk,
112112 .xin_id = 1,
113113 .type = SSPP_TYPE_DMA,
114114 .clk_ctrl = DPU_CLK_CTRL_DMA0,
115115 }, {
116116 .name = "sspp_9", .id = SSPP_DMA1,
117117 .base = 0x26000, .len = 0x32c,
118− .features = DMA_SDM845_MASK,
119− .sblk = &sdm845_dma_sblk_1,
118+ .features = DMA_SDM845_MASK_SDMA,
119+ .sblk = &dpu_dma_sblk,
120120 .xin_id = 5,
121121 .type = SSPP_TYPE_DMA,
122122 .clk_ctrl = DPU_CLK_CTRL_DMA1,
123123 }, {
124124 .name = "sspp_10", .id = SSPP_DMA2,
125125 .base = 0x28000, .len = 0x32c,
126− .features = DMA_CURSOR_SDM845_MASK,
127− .sblk = &sdm845_dma_sblk_2,
126+ .features = DMA_CURSOR_SDM845_MASK_SDMA,
127+ .sblk = &dpu_dma_sblk,
128128 .xin_id = 9,
129129 .type = SSPP_TYPE_DMA,
130130 .clk_ctrl = DPU_CLK_CTRL_DMA2,
131131 }, {
132132 .name = "sspp_11", .id = SSPP_DMA3,
133133 .base = 0x2a000, .len = 0x32c,
134− .features = DMA_CURSOR_SDM845_MASK,
135− .sblk = &sdm845_dma_sblk_3,
134+ .features = DMA_CURSOR_SDM845_MASK_SDMA,
135+ .sblk = &dpu_dma_sblk,
136136 .xin_id = 13,
137137 .type = SSPP_TYPE_DMA,
138138 .clk_ctrl = DPU_CLK_CTRL_DMA3,
@@ -316,6 +316,21 @@ static const struct dpu_dsc_cfg sm8450_dsc[] = { · 177 unmodified lines
316316 },
317317 };
318318
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+
319334 static const struct dpu_intf_cfg sm8450_intf[] = {
320335 {
321336 .name = "intf_0", .id = INTF_0,
@@ -411,6 +426,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = { · 89 unmodified lines
411426 .dsc = sm8450_dsc,
412427 .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d),
413428 .merge_3d = sm8450_merge_3d,
429+ .wb_count = ARRAY_SIZE(sm8450_wb),
430+ .wb = sm8450_wb,
414431 .intf_count = ARRAY_SIZE(sm8450_intf),
415432 .intf = sm8450_intf,
416433 .vbif_count = ARRAY_SIZE(sdm845_vbif),
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h+16−17
@@ -10,7 +10,6 @@ · 9 unmodified lines
1010 static const struct dpu_caps sm8550_dpu_caps = {
1111 .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
1212 .max_mixer_blendstages = 0xb,
13− .qseed_type = DPU_SSPP_SCALER_QSEED4,
1413 .has_src_split = true,
1514 .has_dim_layer = true,
1615 .has_idle_pc = true,
@@ -67,71 +66,71 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = { · 50 unmodified lines
6766 {
6867 .name = "sspp_0", .id = SSPP_VIG0,
6968 .base = 0x4000, .len = 0x344,
70− .features = VIG_SC7180_MASK,
71− .sblk = &sm8550_vig_sblk_0,
69+ .features = VIG_SDM845_MASK,
70+ .sblk = &dpu_vig_sblk_qseed3_3_2,
7271 .xin_id = 0,
7372 .type = SSPP_TYPE_VIG,
7473 }, {
7574 .name = "sspp_1", .id = SSPP_VIG1,
7675 .base = 0x6000, .len = 0x344,
77− .features = VIG_SC7180_MASK,
78− .sblk = &sm8550_vig_sblk_1,
76+ .features = VIG_SDM845_MASK,
77+ .sblk = &dpu_vig_sblk_qseed3_3_2,
7978 .xin_id = 4,
8079 .type = SSPP_TYPE_VIG,
8180 }, {
8281 .name = "sspp_2", .id = SSPP_VIG2,
8382 .base = 0x8000, .len = 0x344,
84− .features = VIG_SC7180_MASK,
85− .sblk = &sm8550_vig_sblk_2,
83+ .features = VIG_SDM845_MASK,
84+ .sblk = &dpu_vig_sblk_qseed3_3_2,
8685 .xin_id = 8,
8786 .type = SSPP_TYPE_VIG,
8887 }, {
8988 .name = "sspp_3", .id = SSPP_VIG3,
9089 .base = 0xa000, .len = 0x344,
91− .features = VIG_SC7180_MASK,
92− .sblk = &sm8550_vig_sblk_3,
90+ .features = VIG_SDM845_MASK,
91+ .sblk = &dpu_vig_sblk_qseed3_3_2,
9392 .xin_id = 12,
9493 .type = SSPP_TYPE_VIG,
9594 }, {
9695 .name = "sspp_8", .id = SSPP_DMA0,
9796 .base = 0x24000, .len = 0x344,
9897 .features = DMA_SDM845_MASK,
99− .sblk = &sdm845_dma_sblk_0,
98+ .sblk = &dpu_dma_sblk,
10099 .xin_id = 1,
101100 .type = SSPP_TYPE_DMA,
102101 }, {
103102 .name = "sspp_9", .id = SSPP_DMA1,
104103 .base = 0x26000, .len = 0x344,
105104 .features = DMA_SDM845_MASK,
106− .sblk = &sdm845_dma_sblk_1,
105+ .sblk = &dpu_dma_sblk,
107106 .xin_id = 5,
108107 .type = SSPP_TYPE_DMA,
109108 }, {
110109 .name = "sspp_10", .id = SSPP_DMA2,
111110 .base = 0x28000, .len = 0x344,
112111 .features = DMA_SDM845_MASK,
113− .sblk = &sdm845_dma_sblk_2,
112+ .sblk = &dpu_dma_sblk,
114113 .xin_id = 9,
115114 .type = SSPP_TYPE_DMA,
116115 }, {
117116 .name = "sspp_11", .id = SSPP_DMA3,
118117 .base = 0x2a000, .len = 0x344,
119118 .features = DMA_SDM845_MASK,
120− .sblk = &sdm845_dma_sblk_3,
119+ .sblk = &dpu_dma_sblk,
121120 .xin_id = 13,
122121 .type = SSPP_TYPE_DMA,
123122 }, {
124123 .name = "sspp_12", .id = SSPP_DMA4,
125124 .base = 0x2c000, .len = 0x344,
126125 .features = DMA_CURSOR_SDM845_MASK,
127− .sblk = &sm8550_dma_sblk_4,
126+ .sblk = &dpu_dma_sblk,
128127 .xin_id = 14,
129128 .type = SSPP_TYPE_DMA,
130129 }, {
131130 .name = "sspp_13", .id = SSPP_DMA5,
132131 .base = 0x2e000, .len = 0x344,
133132 .features = DMA_CURSOR_SDM845_MASK,
134− .sblk = &sm8550_dma_sblk_5,
133+ .sblk = &dpu_dma_sblk,
135134 .xin_id = 15,
136135 .type = SSPP_TYPE_DMA,
137136 },
@@ -316,8 +315,8 @@ static const struct dpu_wb_cfg sm8550_wb[] = { · 178 unmodified lines
316315 .name = "wb_2", .id = WB_2,
317316 .base = 0x65000, .len = 0x2c8,
318317 .features = WB_SM8250_MASK,
319− .format_list = wb2_formats,
320− .num_formats = ARRAY_SIZE(wb2_formats),
318+ .format_list = wb2_formats_rgb,
319+ .num_formats = ARRAY_SIZE(wb2_formats_rgb),
321320 .xin_id = 6,
322321 .vbif_idx = VBIF_RT,
323322 .maxlinewidth = 4096,
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+9−20
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
55 * Copyright (C) 2013 Red Hat
66 * 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
5151 return to_dpu_kms(priv->kms);
5252 }
5353
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−
6554 static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
6655 {
6756 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
125114 continue;
126115
127116 /* 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);
129118 }
130119 }
131120
@@ -1435,7 +1424,6 @@ static int dpu_crtc_late_register(struct drm_crtc *crtc) · 1303 unmodified lines
14351424
14361425 static const struct drm_crtc_funcs dpu_crtc_funcs = {
14371426 .set_config = drm_atomic_helper_set_config,
1438− .destroy = dpu_crtc_destroy,
14391427 .page_flip = drm_atomic_helper_page_flip,
14401428 .reset = dpu_crtc_reset,
14411429 .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
14691457 struct dpu_crtc *dpu_crtc;
14701458 int i, ret;
14711459
1472− dpu_crtc = kzalloc(sizeof(*dpu_crtc), GFP_KERNEL);
1473− if (!dpu_crtc)
1474− return ERR_PTR(-ENOMEM);
1460+ dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base,
1461+ plane, cursor,
1462+ &dpu_crtc_funcs,
1463+ NULL);
1464+
1465+ if (IS_ERR(dpu_crtc))
1466+ return ERR_CAST(dpu_crtc);
14751467
14761468 crtc = &dpu_crtc->base;
14771469 crtc->dev = dev;
@@ -1491,9 +1483,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, · 13 unmodified lines
14911483 dpu_crtc_frame_event_work);
14921484 }
14931485
1494− drm_crtc_init_with_planes(dev, crtc, plane, cursor, &dpu_crtc_funcs,
1495− NULL);
1496−
14971486 drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
14981487
14991488 if (dpu_kms->catalog->dspp_count)
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c+76−110
@@ -2,7 +2,7 @@ · 1 unmodified line
22 /*
33 * Copyright (C) 2013 Red Hat
44 * 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.
66 *
77 * Author: Rob Clark <robdclark@gmail.com>
88 */
@@ -16,6 +16,7 @@ · 7 unmodified lines
1616 #include <drm/drm_crtc.h>
1717 #include <drm/drm_file.h>
1818 #include <drm/drm_probe_helper.h>
19+#include <drm/drm_framebuffer.h>
1920
2021 #include "msm_drv.h"
2122 #include "dpu_kms.h"
@@ -26,6 +27,7 @@ · 4 unmodified lines
2627 #include "dpu_hw_dspp.h"
2728 #include "dpu_hw_dsc.h"
2829 #include "dpu_hw_merge3d.h"
30+#include "dpu_hw_cdm.h"
2931 #include "dpu_formats.h"
3032 #include "dpu_encoder_phys.h"
3133 #include "dpu_crtc.h"
@@ -39,6 +41,9 @@ · 7 unmodified lines
3941 #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\
4042 (e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
4143
44+#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\
45+ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
46+
4247 /*
4348 * Two to anticipate panels that can do cmd/vid dynamic switching
4449 * plan is to create all possible physical encoder types, and switch between
@@ -151,6 +156,8 @@ enum dpu_enc_rc_states { · 106 unmodified lines
151156 * @crtc_frame_event_cb: callback handler for frame event
152157 * @crtc_frame_event_cb_data: callback handler private data
153158 * @frame_done_timeout_ms: frame done timeout in ms
159+ * @frame_done_timeout_cnt: atomic counter tracking the number of frame
160+ * done timeouts
154161 * @frame_done_timer: watchdog timer for frame done event
155162 * @disp_info: local copy of msm_display_info struct
156163 * @idle_pc_supported: indicate if idle power collaps is supported
@@ -184,13 +191,13 @@ struct dpu_encoder_virt { · 27 unmodified lines
184191 struct drm_crtc *crtc;
185192 struct drm_connector *connector;
186193
187− struct dentry *debugfs_root;
188194 struct mutex enc_lock;
189195 DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
190196 void (*crtc_frame_event_cb)(void *, u32 event);
191197 void *crtc_frame_event_cb_data;
192198
193199 atomic_t frame_done_timeout_ms;
200+ atomic_t frame_done_timeout_cnt;
194201 struct timer_list frame_done_timer;
195202
196203 struct msm_display_info disp_info;
@@ -255,7 +262,7 @@ void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc) · 58 unmodified lines
255262 if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr)
256263 continue;
257264
258− phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1);
265+ phys->hw_intf->ops.setup_misr(phys->hw_intf);
259266 }
260267 }
261268
@@ -439,41 +446,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc) · 177 unmodified lines
439446 return linecount;
440447 }
441448
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−
477449 void dpu_encoder_helper_split_config(
478450 struct dpu_encoder_phys *phys_enc,
479451 enum dpu_intf interface)
@@ -614,6 +586,7 @@ static int dpu_encoder_virt_atomic_check( · 134 unmodified lines
614586 struct drm_display_mode *adj_mode;
615587 struct msm_display_topology topology;
616588 struct dpu_global_state *global_state;
589+ struct drm_framebuffer *fb;
617590 struct drm_dsc_config *dsc;
618591 int i = 0;
619592 int ret = 0;
@@ -654,6 +627,22 @@ static int dpu_encoder_virt_atomic_check( · 34 unmodified lines
654627
655628 topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
656629
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+
657646 /*
658647 * Release and Allocate resources on every modeset
659648 * 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
10941083
10951084 dpu_enc->dsc_mask = dsc_mask;
10961085
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+
10971095 cstate = to_dpu_crtc_state(crtc_state);
10981096
10991097 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
12041202
12051203 dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);
12061204
1205+ atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
1206+
12071207 if (disp_info->intf_type == INTF_DP)
12081208 dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]);
12091209 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
20802080 phys_enc->hw_pp->merge_3d->idx);
20812081 }
20822082
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+
20832092 if (dpu_enc->dsc) {
20842093 dpu_encoder_unprep_dsc(dpu_enc);
20852094 dpu_enc->dsc = NULL;
@@ -2108,18 +2117,20 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) · 22 unmodified lines
21082117 #ifdef CONFIG_DEBUG_FS
21092118 static int _dpu_encoder_status_show(struct seq_file *s, void *data)
21102119 {
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);
21122122 int i;
21132123
21142124 mutex_lock(&dpu_enc->enc_lock);
21152125 for (i = 0; i < dpu_enc->num_phys_encs; i++) {
21162126 struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
21172127
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",
21192129 phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1,
21202130 phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1,
21212131 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));
21232134
21242135 seq_printf(s, "mode: %s\n", dpu_encoder_helper_get_intf_type(phys->intf_mode));
21252136 }
@@ -2130,49 +2141,18 @@ static int _dpu_encoder_status_show(struct seq_file *s, void *data) · 4 unmodified lines
21302141
21312142 DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status);
21322143
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)
21342145 {
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−
21502146 /* don't error check these */
21512147 debugfs_create_file("status", 0600,
2152− dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops);
2153−
2154− return 0;
2148+ root, drm_enc, &_dpu_encoder_status_fops);
21552149 }
21562150 #else
2157−static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
2158−{
2159− return 0;
2160−}
2151+#define dpu_encoder_debugfs_init NULL
21612152 #endif
21622153
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−
21752154 static int dpu_encoder_virt_add_phys_encs(
2155+ struct drm_device *dev,
21762156 struct msm_display_info *disp_info,
21772157 struct dpu_encoder_virt *dpu_enc,
21782158 struct dpu_enc_phys_init_params *params)
@@ -2194,7 +2174,7 @@ static int dpu_encoder_virt_add_phys_encs( · 15 unmodified lines
21942174
21952175
21962176 if (disp_info->intf_type == INTF_WB) {
2197− enc = dpu_encoder_phys_wb_init(params);
2177+ enc = dpu_encoder_phys_wb_init(dev, params);
21982178
21992179 if (IS_ERR(enc)) {
22002180 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
22052185 dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
22062186 ++dpu_enc->num_phys_encs;
22072187 } else if (disp_info->is_cmd_mode) {
2208− enc = dpu_encoder_phys_cmd_init(params);
2188+ enc = dpu_encoder_phys_cmd_init(dev, params);
22092189
22102190 if (IS_ERR(enc)) {
22112191 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
22162196 dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
22172197 ++dpu_enc->num_phys_encs;
22182198 } else {
2219− enc = dpu_encoder_phys_vid_init(params);
2199+ enc = dpu_encoder_phys_vid_init(dev, params);
22202200
22212201 if (IS_ERR(enc)) {
22222202 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
23052285 break;
23062286 }
23072287
2308− ret = dpu_encoder_virt_add_phys_encs(disp_info,
2288+ ret = dpu_encoder_virt_add_phys_encs(dpu_kms->dev, disp_info,
23092289 dpu_enc, &phys_params);
23102290 if (ret) {
23112291 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
23392319 return;
23402320 }
23412321
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);
23432326
23442327 event = DPU_ENCODER_FRAME_EVENT_ERROR;
23452328 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
23542337 };
23552338
23562339 static const struct drm_encoder_funcs dpu_encoder_funcs = {
2357− .destroy = dpu_encoder_destroy,
2358− .late_register = dpu_encoder_late_register,
2359− .early_unregister = dpu_encoder_early_unregister,
2340+ .debugfs_init = dpu_encoder_debugfs_init,
23602341 };
23612342
23622343 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
23652346 {
23662347 struct msm_drm_private *priv = dev->dev_private;
23672348 struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
2368− struct drm_encoder *drm_enc = NULL;
2369− struct dpu_encoder_virt *dpu_enc = NULL;
2370− int ret = 0;
2371−
2372− dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL);
2373− if (!dpu_enc)
2374− return ERR_PTR(-ENOMEM);
2349+ struct dpu_encoder_virt *dpu_enc;
2350+ int ret;
23752351
2376− ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
2377− drm_enc_mode, NULL);
2378− if (ret) {
2379− devm_kfree(dev->dev, dpu_enc);
2380− return ERR_PTR(ret);
2381− }
2352+ dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base,
2353+ &dpu_encoder_funcs, drm_enc_mode, NULL);
2354+ if (IS_ERR(dpu_enc))
2355+ return ERR_CAST(dpu_enc);
23822356
23832357 drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
23842358
@@ -2388,10 +2362,13 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 3 unmodified lines
23882362 mutex_init(&dpu_enc->rc_lock);
23892363
23902364 ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info);
2391− if (ret)
2392− goto fail;
2365+ if (ret) {
2366+ DPU_ERROR("failed to setup encoder\n");
2367+ return ERR_PTR(-ENOMEM);
2368+ }
23932369
23942370 atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
2371+ atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
23952372 timer_setup(&dpu_enc->frame_done_timer,
23962373 dpu_encoder_frame_done_timeout, 0);
23972374
@@ -2404,13 +2381,6 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, · 6 unmodified lines
24042381 DPU_DEBUG_ENC(dpu_enc, "created\n");
24052382
24062383 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);
24142384 }
24152385
24162386 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
24372407 case MSM_ENC_TX_COMPLETE:
24382408 fn_wait = phys->ops.wait_for_tx_complete;
24392409 break;
2440− case MSM_ENC_VBLANK:
2441− fn_wait = phys->ops.wait_for_vblank;
2442− break;
24432410 default:
24442411 DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
24452412 event);
@@ -2497,7 +2464,6 @@ void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc, · 51 unmodified lines
24972464 phys_enc->enc_spinlock = p->enc_spinlock;
24982465 phys_enc->enable_state = DPU_ENC_DISABLED;
24992466
2500− atomic_set(&phys_enc->vblank_refcount, 0);
25012467 atomic_set(&phys_enc->pending_kickoff_cnt, 0);
25022468 atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
25032469
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h+14−7
@@ -14,8 +14,10 @@ · 13 unmodified lines
1414 #include "dpu_hw_intf.h"
1515 #include "dpu_hw_wb.h"
1616 #include "dpu_hw_pingpong.h"
17+#include "dpu_hw_cdm.h"
1718 #include "dpu_hw_ctl.h"
1819 #include "dpu_hw_top.h"
20+#include "dpu_hw_util.h"
1921 #include "dpu_encoder.h"
2022 #include "dpu_crtc.h"
2123
@@ -72,7 +74,6 @@ struct dpu_encoder_phys; · 50 unmodified lines
7274 * @enable: DRM Call. Enable a DRM mode.
7375 * @disable: DRM Call. Disable mode.
7476 * @atomic_check: DRM Call. Atomic check new DRM state.
75− * @destroy: DRM Call. Destroy and release resources.
7677 * @control_vblank_irq Register/Deregister for VBLANK IRQ
7778 * @wait_for_commit_done: Wait for hardware to have flushed the
7879 * current pending frames to hardware
@@ -102,11 +103,9 @@ struct dpu_encoder_phys_ops { · 23 unmodified lines
102103 int (*atomic_check)(struct dpu_encoder_phys *encoder,
103104 struct drm_crtc_state *crtc_state,
104105 struct drm_connector_state *conn_state);
105− void (*destroy)(struct dpu_encoder_phys *encoder);
106106 int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
107107 int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
108108 int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
109− int (*wait_for_vblank)(struct dpu_encoder_phys *phys_enc);
110109 void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc);
111110 void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
112111 void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
@@ -153,8 +152,10 @@ enum dpu_intr_idx { · 40 unmodified lines
153152 * @hw_pp: Hardware interface to the ping pong registers
154153 * @hw_intf: Hardware interface to the intf registers
155154 * @hw_wb: Hardware interface to the wb registers
155+ * @hw_cdm: Hardware interface to the CDM registers
156156 * @dpu_kms: Pointer to the dpu_kms top level
157157 * @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
158159 * @enabled: Whether the encoder has enabled and running a mode
159160 * @split_role: Role to play in a split-panel configuration
160161 * @intf_mode: Interface mode
@@ -181,13 +182,15 @@ struct dpu_encoder_phys { · 20 unmodified lines
181182 struct dpu_hw_pingpong *hw_pp;
182183 struct dpu_hw_intf *hw_intf;
183184 struct dpu_hw_wb *hw_wb;
185+ struct dpu_hw_cdm *hw_cdm;
184186 struct dpu_kms *dpu_kms;
185187 struct drm_display_mode cached_mode;
188+ struct mutex vblank_ctl_lock;
186189 enum dpu_enc_split_role split_role;
187190 enum dpu_intf_mode intf_mode;
188191 spinlock_t *enc_spinlock;
189192 enum dpu_enc_enable_state enable_state;
190− atomic_t vblank_refcount;
193+ int vblank_refcount;
191194 atomic_t vsync_cnt;
192195 atomic_t underrun_cnt;
193196 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
210213 * @wbirq_refcount: Reference count of writeback interrupt
211214 * @wb_done_timeout_cnt: number of wb done irq timeout errors
212215 * @wb_cfg: writeback block config to store fb related details
216+ * @cdm_cfg: cdm block config needed to store writeback block's CDM configuration
213217 * @wb_conn: backpointer to writeback connector
214218 * @wb_job: backpointer to current writeback job
215219 * @dest: dpu buffer layout for current writeback output buffer
@@ -219,6 +223,7 @@ struct dpu_encoder_phys_wb { · 3 unmodified lines
219223 atomic_t wbirq_refcount;
220224 int wb_done_timeout_cnt;
221225 struct dpu_hw_wb_cfg wb_cfg;
226+ struct dpu_hw_cdm_cfg cdm_cfg;
222227 struct drm_writeback_connector *wb_conn;
223228 struct drm_writeback_job *wb_job;
224229 struct dpu_hw_fmt_layout dest;
@@ -281,22 +286,24 @@ struct dpu_encoder_wait_info { · 56 unmodified lines
281286 * @p: Pointer to init params structure
282287 * Return: Error code or newly allocated encoder
283288 */
284−struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
289+struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
285290 struct dpu_enc_phys_init_params *p);
286291
287292 /**
288293 * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder
294+ * @dev: Corresponding device for devres management
289295 * @p: Pointer to init params structure
290296 * Return: Error code or newly allocated encoder
291297 */
292−struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
298+struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
293299 struct dpu_enc_phys_init_params *p);
294300
295301 /**
296302 * dpu_encoder_phys_wb_init - initialize writeback encoder
303+ * @dev: Corresponding device for devres management
297304 * @init: Pointer to init info structure with initialization params
298305 */
299−struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
306+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
300307 struct dpu_enc_phys_init_params *p);
301308
302309 /**
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c+26−49
@@ -13,6 +13,8 @@ · 12 unmodified lines
1313 #include "dpu_trace.h"
1414 #include "disp/msm_disp_snapshot.h"
1515
16+#include <drm/drm_managed.h>
17+
1618 #define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
1719 (e) && (e)->base.parent ? \
1820 (e)->base.parent->base.id : -1, \
@@ -244,7 +246,8 @@ static int dpu_encoder_phys_cmd_control_vblank_irq( · 225 unmodified lines
244246 return -EINVAL;
245247 }
246248
247− refcount = atomic_read(&phys_enc->vblank_refcount);
249+ mutex_lock(&phys_enc->vblank_ctl_lock);
250+ refcount = phys_enc->vblank_refcount;
248251
249252 /* Slave encoders don't report vblank */
250253 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
260263 phys_enc->hw_pp->idx - PINGPONG_0,
261264 enable ? "true" : "false", refcount);
262265
263− if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
264− ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
265− phys_enc->irq[INTR_IDX_RDPTR],
266− dpu_encoder_phys_cmd_te_rd_ptr_irq,
267− phys_enc);
268− else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
269− ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
270− phys_enc->irq[INTR_IDX_RDPTR]);
266+ if (enable) {
267+ if (phys_enc->vblank_refcount == 0)
268+ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
269+ phys_enc->irq[INTR_IDX_RDPTR],
270+ dpu_encoder_phys_cmd_te_rd_ptr_irq,
271+ phys_enc);
272+ if (!ret)
273+ phys_enc->vblank_refcount++;
274+ } else if (!enable) {
275+ if (phys_enc->vblank_refcount == 1)
276+ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
277+ phys_enc->irq[INTR_IDX_RDPTR]);
278+ if (!ret)
279+ phys_enc->vblank_refcount--;
280+ }
271281
272282 end:
283+ mutex_unlock(&phys_enc->vblank_ctl_lock);
273284 if (ret) {
274285 DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
275286 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
285296 {
286297 trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
287298 phys_enc->hw_pp->idx - PINGPONG_0,
288− enable, atomic_read(&phys_enc->vblank_refcount));
299+ enable, phys_enc->vblank_refcount);
289300
290301 if (enable) {
291302 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
558569 phys_enc->enable_state = DPU_ENC_DISABLED;
559570 }
560571
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−
569572 static void dpu_encoder_phys_cmd_prepare_for_kickoff(
570573 struct dpu_encoder_phys *phys_enc)
571574 {
@@ -681,33 +684,6 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done( · 109 unmodified lines
681684 return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
682685 }
683686
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−
711687 static void dpu_encoder_phys_cmd_handle_post_kickoff(
712688 struct dpu_encoder_phys *phys_enc)
713689 {
@@ -731,12 +707,10 @@ static void dpu_encoder_phys_cmd_init_ops( · 17 unmodified lines
731707 ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
732708 ops->enable = dpu_encoder_phys_cmd_enable;
733709 ops->disable = dpu_encoder_phys_cmd_disable;
734− ops->destroy = dpu_encoder_phys_cmd_destroy;
735710 ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
736711 ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
737712 ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
738713 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;
740714 ops->trigger_start = dpu_encoder_phys_cmd_trigger_start;
741715 ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush;
742716 ops->irq_control = dpu_encoder_phys_cmd_irq_control;
@@ -746,7 +720,7 @@ static void dpu_encoder_phys_cmd_init_ops( · 3 unmodified lines
746720 ops->get_line_count = dpu_encoder_phys_cmd_get_line_count;
747721 }
748722
749−struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
723+struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
750724 struct dpu_enc_phys_init_params *p)
751725 {
752726 struct dpu_encoder_phys *phys_enc = NULL;
@@ -754,7 +728,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( · 1 unmodified line
754728
755729 DPU_DEBUG("intf\n");
756730
757− cmd_enc = kzalloc(sizeof(*cmd_enc), GFP_KERNEL);
731+ cmd_enc = drmm_kzalloc(dev, sizeof(*cmd_enc), GFP_KERNEL);
758732 if (!cmd_enc) {
759733 DPU_ERROR("failed to allocate\n");
760734 return ERR_PTR(-ENOMEM);
@@ -763,6 +737,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( · 2 unmodified lines
763737
764738 dpu_encoder_phys_init(phys_enc, p);
765739
740+ mutex_init(&phys_enc->vblank_ctl_lock);
741+ phys_enc->vblank_refcount = 0;
742+
766743 dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
767744 phys_enc->intf_mode = INTF_MODE_CMD;
768745 cmd_enc->stream_sel = 0;
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c+30−25
@@ -11,6 +11,8 @@ · 10 unmodified lines
1111 #include "dpu_trace.h"
1212 #include "disp/msm_disp_snapshot.h"
1313
14+#include <drm/drm_managed.h>
15+
1416 #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
1517 (e) && (e)->parent ? \
1618 (e)->parent->base.id : -1, \
@@ -364,7 +366,8 @@ static int dpu_encoder_phys_vid_control_vblank_irq( · 347 unmodified lines
364366 int ret = 0;
365367 int refcount;
366368
367− refcount = atomic_read(&phys_enc->vblank_refcount);
369+ mutex_lock(&phys_enc->vblank_ctl_lock);
370+ refcount = phys_enc->vblank_refcount;
368371
369372 /* Slave encoders don't report vblank */
370373 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
377380 }
378381
379382 DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
380− atomic_read(&phys_enc->vblank_refcount));
383+ refcount);
381384
382− if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
383− ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
384− phys_enc->irq[INTR_IDX_VSYNC],
385− dpu_encoder_phys_vid_vblank_irq,
386− phys_enc);
387− else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
388− ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
389− phys_enc->irq[INTR_IDX_VSYNC]);
385+ if (enable) {
386+ if (phys_enc->vblank_refcount == 0)
387+ ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
388+ phys_enc->irq[INTR_IDX_VSYNC],
389+ dpu_encoder_phys_vid_vblank_irq,
390+ phys_enc);
391+ if (!ret)
392+ phys_enc->vblank_refcount++;
393+ } else if (!enable) {
394+ if (phys_enc->vblank_refcount == 1)
395+ ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
396+ phys_enc->irq[INTR_IDX_VSYNC]);
397+ if (!ret)
398+ phys_enc->vblank_refcount--;
399+ }
390400
391401 end:
402+ mutex_unlock(&phys_enc->vblank_ctl_lock);
392403 if (ret) {
393404 DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
394405 DRMID(phys_enc->parent),
@@ -438,13 +449,7 @@ skip_flush: · 43 unmodified lines
438449 phys_enc->enable_state = DPU_ENC_ENABLING;
439450 }
440451
441−static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc)
442−{
443− DPU_DEBUG_VIDENC(phys_enc, "\n");
444− kfree(phys_enc);
445−}
446−
447−static int dpu_encoder_phys_vid_wait_for_vblank(
452+static int dpu_encoder_phys_vid_wait_for_tx_complete(
448453 struct dpu_encoder_phys *phys_enc)
449454 {
450455 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
558563 * scanout buffer) don't latch properly..
559564 */
560565 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);
562567 if (ret) {
563568 atomic_set(&phys_enc->pending_kickoff_cnt, 0);
564569 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
578583 spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
579584 dpu_encoder_phys_inc_pending(phys_enc);
580585 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);
582587 if (ret) {
583588 atomic_set(&phys_enc->pending_kickoff_cnt, 0);
584589 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
618623 trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
619624 phys_enc->hw_intf->idx - INTF_0,
620625 enable,
621− atomic_read(&phys_enc->vblank_refcount));
626+ phys_enc->vblank_refcount);
622627
623628 if (enable) {
624629 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
681686 ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set;
682687 ops->enable = dpu_encoder_phys_vid_enable;
683688 ops->disable = dpu_encoder_phys_vid_disable;
684− ops->destroy = dpu_encoder_phys_vid_destroy;
685689 ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
686690 ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done;
687− ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
688− ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_vblank;
691+ ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_tx_complete;
689692 ops->irq_control = dpu_encoder_phys_vid_irq_control;
690693 ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff;
691694 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
694697 ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count;
695698 }
696699
697−struct dpu_encoder_phys *dpu_encoder_phys_vid_init(
700+struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
698701 struct dpu_enc_phys_init_params *p)
699702 {
700703 struct dpu_encoder_phys *phys_enc = NULL;
@@ -704,7 +707,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( · 3 unmodified lines
704707 return ERR_PTR(-EINVAL);
705708 }
706709
707− phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL);
710+ phys_enc = drmm_kzalloc(dev, sizeof(*phys_enc), GFP_KERNEL);
708711 if (!phys_enc) {
709712 DPU_ERROR("failed to create encoder due to memory allocation error\n");
710713 return ERR_PTR(-ENOMEM);
@@ -713,6 +716,8 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( · 2 unmodified lines
713716 DPU_DEBUG_VIDENC(phys_enc, "\n");
714717
715718 dpu_encoder_phys_init(phys_enc, p);
719+ mutex_init(&phys_enc->vblank_ctl_lock);
720+ phys_enc->vblank_refcount = 0;
716721
717722 dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
718723 phys_enc->intf_mode = INTF_MODE_VIDEO;
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c+109−21
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/debugfs.h>
99
1010 #include <drm/drm_framebuffer.h>
11+#include <drm/drm_managed.h>
1112
1213 #include "dpu_encoder_phys.h"
1314 #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
206207 }
207208
208209 /**
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
210211 * @phys_enc:Pointer to physical encoder
211212 */
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)
213214 {
214215 struct dpu_hw_wb *hw_wb;
215216 struct dpu_hw_ctl *ctl;
217+ struct dpu_hw_cdm *hw_cdm;
216218
217219 if (!phys_enc) {
218220 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
221223
222224 hw_wb = phys_enc->hw_wb;
223225 ctl = phys_enc->hw_ctl;
226+ hw_cdm = phys_enc->hw_cdm;
224227
225228 if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) &&
226229 (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
237240 if (mode_3d && hw_pp && hw_pp->merge_3d)
238241 intf_cfg.merge_3d = hw_pp->merge_3d->idx;
239242
243+ if (hw_cdm)
244+ intf_cfg.cdm = hw_cdm->idx;
245+
240246 if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)
241247 phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
242248 mode_3d);
@@ -258,6 +264,96 @@ static void dpu_encoder_phys_wb_setup_cdp(struct dpu_encoder_phys *phys_enc) · 15 unmodified lines
258264 }
259265 }
260266
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+
261357 /**
262358 * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states
263359 * @phys_enc: Pointer to physical encoder
@@ -307,7 +403,7 @@ static int dpu_encoder_phys_wb_atomic_check( · 43 unmodified lines
307403 return -EINVAL;
308404 }
309405
310− return 0;
406+ return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state);
311407 }
312408
313409
@@ -320,6 +416,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 6 unmodified lines
320416 struct dpu_hw_wb *hw_wb;
321417 struct dpu_hw_ctl *hw_ctl;
322418 struct dpu_hw_pingpong *hw_pp;
419+ struct dpu_hw_cdm *hw_cdm;
323420 u32 pending_flush = 0;
324421
325422 if (!phys_enc)
@@ -328,6 +425,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines
328425 hw_wb = phys_enc->hw_wb;
329426 hw_pp = phys_enc->hw_pp;
330427 hw_ctl = phys_enc->hw_ctl;
428+ hw_cdm = phys_enc->hw_cdm;
331429
332430 DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
333431
@@ -343,6 +441,9 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 9 unmodified lines
343441 hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
344442 hw_pp->merge_3d->idx);
345443
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+
346447 if (hw_ctl->ops.get_pending_flush)
347448 pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl);
348449
@@ -374,8 +475,9 @@ static void dpu_encoder_phys_wb_setup( · 25 unmodified lines
374475
375476 dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
376477
377− dpu_encoder_phys_wb_setup_cdp(phys_enc);
478+ dpu_encoder_helper_phys_setup_cdm(phys_enc);
378479
480+ dpu_encoder_phys_wb_setup_ctl(phys_enc);
379481 }
380482
381483 /**
@@ -580,20 +682,6 @@ static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc) · 198 unmodified lines
580682 phys_enc->enable_state = DPU_ENC_DISABLED;
581683 }
582684
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−
597685 static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc,
598686 struct drm_writeback_job *job)
599687 {
@@ -689,7 +777,6 @@ static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops) · 89 unmodified lines
689777 ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set;
690778 ops->enable = dpu_encoder_phys_wb_enable;
691779 ops->disable = dpu_encoder_phys_wb_disable;
692− ops->destroy = dpu_encoder_phys_wb_destroy;
693780 ops->atomic_check = dpu_encoder_phys_wb_atomic_check;
694781 ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done;
695782 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
705792
706793 /**
707794 * dpu_encoder_phys_wb_init - initialize writeback encoder
795+ * @dev: Corresponding device for devres management
708796 * @p: Pointer to init info structure with initialization params
709797 */
710−struct dpu_encoder_phys *dpu_encoder_phys_wb_init(
798+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
711799 struct dpu_enc_phys_init_params *p)
712800 {
713801 struct dpu_encoder_phys *phys_enc = NULL;
@@ -720,7 +808,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_wb_init( · 6 unmodified lines
720808 return ERR_PTR(-EINVAL);
721809 }
722810
723− wb_enc = kzalloc(sizeof(*wb_enc), GFP_KERNEL);
811+ wb_enc = drmm_kzalloc(dev, sizeof(*wb_enc), GFP_KERNEL);
724812 if (!wb_enc) {
725813 DPU_ERROR("failed to allocate wb phys_enc enc\n");
726814 return ERR_PTR(-ENOMEM);
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c+127−96
@@ -22,23 +22,14 @@ · 21 unmodified lines
2222 BIT(DPU_SSPP_CSC_10BIT))
2323
2424 #define VIG_MSM8998_MASK \
25− (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
25+ (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
2626
2727 #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))
2929
3030 #define VIG_SDM845_MASK_SDMA \
3131 (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
3232
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−
4233 #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
4334
4435 #define DMA_MSM8998_MASK \
@@ -47,7 +38,7 @@ · 2 unmodified lines
4738 BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
4839
4940 #define VIG_SC7280_MASK \
50− (VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
41+ (VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
5142
5243 #define VIG_SC7280_MASK_SDMA \
5344 (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
@@ -211,7 +202,7 @@ static const u32 rotation_v2_formats[] = { · 157 unmodified lines
211202 /* TODO add formats after validation */
212203 };
213204
214−static const uint32_t wb2_formats[] = {
205+static const u32 wb2_formats_rgb[] = {
215206 DRM_FORMAT_RGB565,
216207 DRM_FORMAT_BGR565,
217208 DRM_FORMAT_RGB888,
@@ -245,21 +236,56 @@ static const uint32_t wb2_formats[] = { · 27 unmodified lines
245236 DRM_FORMAT_XBGR4444,
246237 };
247238
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+
248274 /*************************************************************
249275 * SSPP sub blocks config
250276 *************************************************************/
251277
278+#define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min))
279+
252280 /* SSPP common configuration */
253−#define _VIG_SBLK(sdma_pri, qseed_ver) \
281+#define _VIG_SBLK(scaler_ver) \
254282 { \
255283 .maxdwnscale = MAX_DOWNSCALE_RATIO, \
256284 .maxupscale = MAX_UPSCALE_RATIO, \
257− .smart_dma_priority = sdma_pri, \
258285 .scaler_blk = {.name = "scaler", \
259− .id = qseed_ver, \
286+ .version = scaler_ver, \
260287 .base = 0xa00, .len = 0xa0,}, \
261288 .csc_blk = {.name = "csc", \
262− .id = DPU_SSPP_CSC_10BIT, \
263289 .base = 0x1a00, .len = 0x100,}, \
264290 .format_list = plane_formats_yuv, \
265291 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
@@ -268,16 +294,14 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines
268294 .rotation_cfg = NULL, \
269295 }
270296
271−#define _VIG_SBLK_ROT(sdma_pri, qseed_ver, rot_cfg) \
297+#define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \
272298 { \
273299 .maxdwnscale = MAX_DOWNSCALE_RATIO, \
274300 .maxupscale = MAX_UPSCALE_RATIO, \
275− .smart_dma_priority = sdma_pri, \
276301 .scaler_blk = {.name = "scaler", \
277− .id = qseed_ver, \
302+ .version = scaler_ver, \
278303 .base = 0xa00, .len = 0xa0,}, \
279304 .csc_blk = {.name = "csc", \
280− .id = DPU_SSPP_CSC_10BIT, \
281305 .base = 0x1a00, .len = 0x100,}, \
282306 .format_list = plane_formats_yuv, \
283307 .num_formats = ARRAY_SIZE(plane_formats_yuv), \
@@ -286,91 +310,64 @@ static const uint32_t wb2_formats[] = { · 2 unmodified lines
286310 .rotation_cfg = rot_cfg, \
287311 }
288312
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() \
290324 { \
291325 .maxdwnscale = SSPP_UNITY_SCALE, \
292326 .maxupscale = SSPP_UNITY_SCALE, \
293− .smart_dma_priority = sdma_pri, \
294327 .format_list = plane_formats, \
295328 .num_formats = ARRAY_SIZE(plane_formats), \
296329 .virt_format_list = plane_formats, \
297330 .virt_num_formats = ARRAY_SIZE(plane_formats), \
298331 }
299332
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−
309333 static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
310334 .rot_maxheight = 1088,
311335 .rot_num_formats = ARRAY_SIZE(rotation_v2_formats),
312336 .rot_format_list = rotation_v2_formats,
313337 };
314338
315−static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 =
316− _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED3);
317−static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 =
318− _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED3);
319−static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 =
320− _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED3);
321−static const struct dpu_sspp_sub_blks sdm845_vig_sblk_3 =
322− _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED3);
323−
324−static const struct dpu_sspp_sub_blks sdm845_dma_sblk_0 = _DMA_SBLK(1);
325−static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK(2);
326−static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK(3);
327−static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK(4);
328−
329−static const struct dpu_sspp_sub_blks sc7180_vig_sblk_0 =
330− _VIG_SBLK(4, DPU_SSPP_SCALER_QSEED4);
331−
332−static const struct dpu_sspp_sub_blks sc7280_vig_sblk_0 =
333− _VIG_SBLK_ROT(4, DPU_SSPP_SCALER_QSEED4, &dpu_rot_sc7280_cfg_v2);
334−
335−static const struct dpu_sspp_sub_blks sm6115_vig_sblk_0 =
336− _VIG_SBLK(2, DPU_SSPP_SCALER_QSEED4);
337−
338−static const struct dpu_sspp_sub_blks sm6125_vig_sblk_0 =
339− _VIG_SBLK(3, DPU_SSPP_SCALER_QSEED3LITE);
340−
341−static const struct dpu_sspp_sub_blks sm8250_vig_sblk_0 =
342− _VIG_SBLK(5, DPU_SSPP_SCALER_QSEED4);
343−static const struct dpu_sspp_sub_blks sm8250_vig_sblk_1 =
344− _VIG_SBLK(6, DPU_SSPP_SCALER_QSEED4);
345−static const struct dpu_sspp_sub_blks sm8250_vig_sblk_2 =
346− _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4);
347−static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 =
348− _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4);
349−
350−static const struct dpu_sspp_sub_blks sm8550_vig_sblk_0 =
351− _VIG_SBLK(7, DPU_SSPP_SCALER_QSEED4);
352−static const struct dpu_sspp_sub_blks sm8550_vig_sblk_1 =
353− _VIG_SBLK(8, DPU_SSPP_SCALER_QSEED4);
354−static const struct dpu_sspp_sub_blks sm8550_vig_sblk_2 =
355− _VIG_SBLK(9, DPU_SSPP_SCALER_QSEED4);
356−static const struct dpu_sspp_sub_blks sm8550_vig_sblk_3 =
357− _VIG_SBLK(10, DPU_SSPP_SCALER_QSEED4);
358−static const struct dpu_sspp_sub_blks sm8550_dma_sblk_4 = _DMA_SBLK(5);
359−static const struct dpu_sspp_sub_blks sm8550_dma_sblk_5 = _DMA_SBLK(6);
360−
361−#define _VIG_SBLK_NOSCALE(sdma_pri) \
362− { \
363− .maxdwnscale = SSPP_UNITY_SCALE, \
364− .maxupscale = SSPP_UNITY_SCALE, \
365− .smart_dma_priority = sdma_pri, \
366− .format_list = plane_formats_yuv, \
367− .num_formats = ARRAY_SIZE(plane_formats_yuv), \
368− .virt_format_list = plane_formats, \
369− .virt_num_formats = ARRAY_SIZE(plane_formats), \
370− }
339+static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale =
340+ _VIG_SBLK_NOSCALE();
341+
342+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_2 =
343+ _VIG_SBLK(SSPP_SCALER_VER(1, 2));
344+
345+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_3 =
346+ _VIG_SBLK(SSPP_SCALER_VER(1, 3));
347+
348+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_4 =
349+ _VIG_SBLK(SSPP_SCALER_VER(1, 4));
350+
351+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_2_4 =
352+ _VIG_SBLK(SSPP_SCALER_VER(2, 4));
353+
354+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0 =
355+ _VIG_SBLK(SSPP_SCALER_VER(3, 0));
356+
357+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0_rot_v2 =
358+ _VIG_SBLK_ROT(SSPP_SCALER_VER(3, 0),
359+ &dpu_rot_sc7280_cfg_v2);
360+
361+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_1 =
362+ _VIG_SBLK(SSPP_SCALER_VER(3, 1));
363+
364+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 =
365+ _VIG_SBLK(SSPP_SCALER_VER(3, 2));
366+
367+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 =
368+ _VIG_SBLK(SSPP_SCALER_VER(3, 3));
371369
372−static const struct dpu_sspp_sub_blks qcm2290_vig_sblk_0 = _VIG_SBLK_NOSCALE(2);
373−static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = _DMA_SBLK(1);
370+static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
374371
375372 /*************************************************************
376373 * MIXER sub blocks config
@@ -422,12 +419,12 @@ static const struct dpu_lm_sub_blks qcm2290_lm_sblk = { · 45 unmodified lines
422419 * DSPP sub blocks config
423420 *************************************************************/
424421 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,
426423 .len = 0x90, .version = 0x10007},
427424 };
428425
429426 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,
431428 .len = 0x90, .version = 0x40000},
432429 };
433430
@@ -435,19 +432,19 @@ static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = { · 1 unmodified line
435432 * PINGPONG sub blocks config
436433 *************************************************************/
437434 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,
439436 .version = 0x1},
440− .dither = {.name = "dither", .id = DPU_PINGPONG_DITHER, .base = 0x30e0,
437+ .dither = {.name = "dither", .base = 0x30e0,
441438 .len = 0x20, .version = 0x10000},
442439 };
443440
444441 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,
446443 .len = 0x20, .version = 0x10000},
447444 };
448445
449446 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,
451448 .len = 0x20, .version = 0x20000},
452449 };
453450
@@ -464,6 +461,16 @@ static const struct dpu_dsc_sub_blks dsc_sblk_1 = { · 10 unmodified lines
464461 .ctl = {.name = "ctl", .base = 0xF80, .len = 0x10},
465462 };
466463
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+
467474 /*************************************************************
468475 * VBIF sub blocks config
469476 *************************************************************/
@@ -472,6 +479,7 @@ static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2}; · 2 unmodified lines
472479 static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1};
473480 static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
474481 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};
475483
476484 static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = {
477485 {
@@ -558,6 +566,26 @@ static const struct dpu_vbif_cfg sm8550_vbif[] = { · 80 unmodified lines
558566 },
559567 };
560568
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+
561589 /*************************************************************
562590 * PERF data config
563591 *************************************************************/
@@ -654,6 +682,7 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { · 90 unmodified lines
654682 #include "catalog/dpu_3_0_msm8998.h"
655683
656684 #include "catalog/dpu_4_0_sdm845.h"
685+#include "catalog/dpu_4_1_sdm670.h"
657686
658687 #include "catalog/dpu_5_0_sm8150.h"
659688 #include "catalog/dpu_5_1_sc8180x.h"
@@ -673,3 +702,5 @@ static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = { · 13 unmodified lines
673702 #include "catalog/dpu_8_1_sm8450.h"
674703
675704 #include "catalog/dpu_9_0_sm8550.h"
705+
706+#include "catalog/dpu_10_0_sm8650.h"
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h+40−32
@@ -51,9 +51,7 @@ enum { · 50 unmodified lines
5151 /**
5252 * SSPP sub-blocks/features
5353 * @DPU_SSPP_SCALER_QSEED2, QSEED2 algorithm support
54− * @DPU_SSPP_SCALER_QSEED3, QSEED3 alogorithm support
55− * @DPU_SSPP_SCALER_QSEED3LITE, QSEED3 Lite alogorithm support
56− * @DPU_SSPP_SCALER_QSEED4, QSEED4 algorithm support
54+ * @DPU_SSPP_SCALER_QSEED3_COMPATIBLE, QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4)
5755 * @DPU_SSPP_SCALER_RGB, RGB Scaler, supported by RGB pipes
5856 * @DPU_SSPP_CSC, Support of Color space converion
5957 * @DPU_SSPP_CSC_10BIT, Support of 10-bit Color space conversion
@@ -71,9 +69,7 @@ enum { · 11 unmodified lines
7169 */
7270 enum {
7371 DPU_SSPP_SCALER_QSEED2 = 0x1,
74− DPU_SSPP_SCALER_QSEED3,
75− DPU_SSPP_SCALER_QSEED3LITE,
76− DPU_SSPP_SCALER_QSEED4,
72+ DPU_SSPP_SCALER_QSEED3_COMPATIBLE,
7773 DPU_SSPP_SCALER_RGB,
7874 DPU_SSPP_CSC,
7975 DPU_SSPP_CSC_10BIT,
@@ -248,50 +244,51 @@ enum { · 168 unmodified lines
248244 u32 len; \
249245 unsigned long features
250246
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−
265247 /**
266248 * struct dpu_scaler_blk: Scaler information
267− * @info: HW register and features supported by this sub-blk
268− * @version: qseed block revision
249+ * @name: string name for debug purposes
250+ * @base: offset of this sub-block relative to the block offset
251+ * @len: register block length of this sub-block
252+ * @version: qseed block revision, on QSEED3+ platforms this is the value of
253+ * scaler_blk.base + QSEED3_HW_VERSION registers.
269254 */
270255 struct dpu_scaler_blk {
271− DPU_HW_SUBBLK_INFO;
256+ char name[DPU_HW_BLK_NAME_LEN];
257+ u32 base;
258+ u32 len;
272259 u32 version;
273260 };
274261
275262 struct dpu_csc_blk {
276− DPU_HW_SUBBLK_INFO;
263+ char name[DPU_HW_BLK_NAME_LEN];
264+ u32 base;
265+ u32 len;
277266 };
278267
279268 /**
280269 * 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
282273 * @version: HW Algorithm version
283274 */
284275 struct dpu_pp_blk {
285− DPU_HW_SUBBLK_INFO;
276+ char name[DPU_HW_BLK_NAME_LEN];
277+ u32 base;
278+ u32 len;
286279 u32 version;
287280 };
288281
289282 /**
290283 * 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
292287 */
293288 struct dpu_dsc_blk {
294− DPU_HW_SUBBLK_INFO;
289+ char name[DPU_HW_BLK_NAME_LEN];
290+ u32 base;
291+ u32 len;
295292 };
296293
297294 /**
@@ -341,7 +338,6 @@ struct dpu_rotation_cfg { · 43 unmodified lines
341338 * @max_mixer_width max layer mixer line width support.
342339 * @max_mixer_blendstages max layer mixer blend stages or
343340 * supported z order
344− * @qseed_type qseed2 or qseed3 support.
345341 * @has_src_split source split feature status
346342 * @has_dim_layer dim layer feature status
347343 * @has_idle_pc indicate if idle power collapse feature is supported
@@ -354,7 +350,6 @@ struct dpu_rotation_cfg { · 6 unmodified lines
354350 struct dpu_caps {
355351 u32 max_mixer_width;
356352 u32 max_mixer_blendstages;
357− u32 qseed_type;
358353 bool has_src_split;
359354 bool has_dim_layer;
360355 bool has_idle_pc;
@@ -371,7 +366,6 @@ struct dpu_caps { · 10 unmodified lines
371366 * common: Pointer to common configurations shared by sub blocks
372367 * @maxdwnscale: max downscale ratio supported(without DECIMATION)
373368 * @maxupscale: maxupscale ratio supported
374− * @smart_dma_priority: hw priority of rect1 of multirect pipe
375369 * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps
376370 * @qseed_ver: qseed version
377371 * @scaler_blk:
@@ -385,7 +379,6 @@ struct dpu_caps { · 7 unmodified lines
385379 struct dpu_sspp_sub_blks {
386380 u32 maxdwnscale;
387381 u32 maxupscale;
388− u32 smart_dma_priority;
389382 u32 max_per_pipe_bw;
390383 u32 qseed_ver;
391384 struct dpu_scaler_blk scaler_blk;
@@ -689,6 +682,17 @@ struct dpu_vbif_cfg { · 297 unmodified lines
689682 u32 memtype[MAX_XIN_COUNT];
690683 };
691684
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+
692696 /**
693697 * Define CDP use cases
694698 * @DPU_PERF_CDP_UDAGE_RT: real-time use cases
@@ -812,6 +816,8 @@ struct dpu_mdss_cfg { · 117 unmodified lines
812816 u32 wb_count;
813817 const struct dpu_wb_cfg *wb;
814818
819+ const struct dpu_cdm_cfg *cdm;
820+
815821 u32 ad_count;
816822
817823 u32 dspp_count;
@@ -827,6 +833,7 @@ struct dpu_mdss_cfg { · 9 unmodified lines
827833
828834 extern const struct dpu_mdss_cfg dpu_msm8998_cfg;
829835 extern const struct dpu_mdss_cfg dpu_sdm845_cfg;
836+extern const struct dpu_mdss_cfg dpu_sdm670_cfg;
830837 extern const struct dpu_mdss_cfg dpu_sm8150_cfg;
831838 extern const struct dpu_mdss_cfg dpu_sc8180x_cfg;
832839 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
841848 extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg;
842849 extern const struct dpu_mdss_cfg dpu_sm8450_cfg;
843850 extern const struct dpu_mdss_cfg dpu_sm8550_cfg;
851+extern const struct dpu_mdss_cfg dpu_sm8650_cfg;
844852
845853 #endif /* _DPU_HW_CATALOG_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c+247−0
@@ -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+}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h+142−0
@@ -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 */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c+42−10
@@ -4,6 +4,9 @@ · 3 unmodified lines
44 */
55
66 #include <linux/delay.h>
7+
8+#include <drm/drm_managed.h>
9+
710 #include "dpu_hwio.h"
811 #include "dpu_hw_ctl.h"
912 #include "dpu_kms.h"
@@ -29,11 +32,13 @@ · 19 unmodified lines
2932 #define CTL_DSC_ACTIVE 0x0E8
3033 #define CTL_WB_ACTIVE 0x0EC
3134 #define CTL_INTF_ACTIVE 0x0F4
35+#define CTL_CDM_ACTIVE 0x0F8
3236 #define CTL_FETCH_PIPE_ACTIVE 0x0FC
3337 #define CTL_MERGE_3D_FLUSH 0x100
3438 #define CTL_DSC_FLUSH 0x104
3539 #define CTL_WB_FLUSH 0x108
3640 #define CTL_INTF_FLUSH 0x110
41+#define CTL_CDM_FLUSH 0x114
3742 #define CTL_INTF_MASTER 0x134
3843 #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4))
3944
@@ -43,6 +48,7 @@ · 3 unmodified lines
4348 #define DPU_REG_RESET_TIMEOUT_US 2000
4449 #define MERGE_3D_IDX 23
4550 #define DSC_IDX 22
51+#define CDM_IDX 26
4652 #define INTF_IDX 31
4753 #define WB_IDX 16
4854 #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
104110 ctx->pending_wb_flush_mask = 0;
105111 ctx->pending_merge_3d_flush_mask = 0;
106112 ctx->pending_dsc_flush_mask = 0;
113+ ctx->pending_cdm_flush_mask = 0;
107114
108115 memset(ctx->pending_dspp_flush_mask, 0,
109116 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
148155 DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
149156 ctx->pending_dsc_flush_mask);
150157
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+
151162 DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
152163 }
153164
@@ -279,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx, · 125 unmodified lines
279290 }
280291 }
281292
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+
282300 static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
283301 enum dpu_wb wb)
284302 {
@@ -307,6 +325,12 @@ static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, · 22 unmodified lines
307325 ctx->pending_flush_mask |= BIT(DSC_IDX);
308326 }
309327
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+
310334 static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
311335 enum dpu_dspp dspp, u32 dspp_sub_blk)
312336 {
@@ -540,6 +564,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, · 227 unmodified lines
540564
541565 if (cfg->dsc)
542566 DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
567+
568+ if (cfg->cdm)
569+ DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
543570 }
544571
545572 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
583610 u32 wb_active = 0;
584611 u32 merge3d_active = 0;
585612 u32 dsc_active;
613+ u32 cdm_active;
586614
587615 /*
588616 * 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
618646 dsc_active &= ~cfg->dsc;
619647 DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
620648 }
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+ }
621655 }
622656
623657 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
651685 ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
652686 ops->update_pending_flush_dsc =
653687 dpu_hw_ctl_update_pending_flush_dsc_v1;
688+ ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1;
654689 } else {
655690 ops->trigger_flush = dpu_hw_ctl_trigger_flush;
656691 ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
657692 ops->update_pending_flush_intf =
658693 dpu_hw_ctl_update_pending_flush_intf;
659694 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;
660696 }
661697 ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
662698 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
680716 ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
681717 };
682718
683−struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
684− void __iomem *addr,
685− u32 mixer_count,
686− const struct dpu_lm_cfg *mixer)
719+struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
720+ const struct dpu_ctl_cfg *cfg,
721+ void __iomem *addr,
722+ u32 mixer_count,
723+ const struct dpu_lm_cfg *mixer)
687724 {
688725 struct dpu_hw_ctl *c;
689726
690− c = kzalloc(sizeof(*c), GFP_KERNEL);
727+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
691728 if (!c)
692729 return ERR_PTR(-ENOMEM);
693730
@@ -702,8 +739,3 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg, · 8 unmodified lines
702739
703740 return c;
704741 }
705−
706−void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx)
707−{
708− kfree(ctx);
709−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h+18−10
@@ -39,6 +39,7 @@ struct dpu_hw_stage_cfg { · 38 unmodified lines
3939 * @mode_3d: 3d mux configuration
4040 * @merge_3d: 3d merge block used
4141 * @intf_mode_sel: Interface mode, cmd / vid
42+ * @cdm: CDM block used
4243 * @stream_sel: Stream selection for multi-stream interfaces
4344 * @dsc: DSC BIT masks used
4445 */
@@ -48,6 +49,7 @@ struct dpu_hw_intf_cfg { · 3 unmodified lines
4849 enum dpu_3d_blend_mode mode_3d;
4950 enum dpu_merge_3d merge_3d;
5051 enum dpu_ctl_mode_sel intf_mode_sel;
52+ enum dpu_cdm cdm;
5153 int stream_sel;
5254 unsigned int dsc;
5355 };
@@ -166,6 +168,14 @@ struct dpu_hw_ctl_ops { · 112 unmodified lines
166168 void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx,
167169 enum dpu_dsc blk);
168170
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+
169179 /**
170180 * Write the value of the pending_flush_mask to hardware
171181 * @ctx : ctl path ctx pointer
@@ -239,6 +249,7 @@ struct dpu_hw_ctl_ops { · 67 unmodified lines
239249 * @pending_intf_flush_mask: pending INTF flush
240250 * @pending_wb_flush_mask: pending WB flush
241251 * @pending_dsc_flush_mask: pending DSC flush
252+ * @pending_cdm_flush_mask: pending CDM flush
242253 * @ops: operation list
243254 */
244255 struct dpu_hw_ctl {
@@ -256,6 +267,7 @@ struct dpu_hw_ctl { · 11 unmodified lines
256267 u32 pending_merge_3d_flush_mask;
257268 u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
258269 u32 pending_dsc_flush_mask;
270+ u32 pending_cdm_flush_mask;
259271
260272 /* ops */
261273 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
274286 /**
275287 * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object.
276288 * Should be called before accessing any ctl_path register.
289+ * @dev: Corresponding device for devres management
277290 * @cfg: ctl_path catalog entry for which driver object is required
278291 * @addr: mapped register io address of MDP
279292 * @mixer_count: Number of mixers in @mixer
280293 * @mixer: Pointer to an array of Layer Mixers defined in the catalog
281294 */
282−struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
283− void __iomem *addr,
284− u32 mixer_count,
285− const struct dpu_lm_cfg *mixer);
286−
287−/**
288− * dpu_hw_ctl_destroy(): Destroys ctl driver context
289− * should be called to free the context
290− */
291−void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx);
295+struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
296+ const struct dpu_ctl_cfg *cfg,
297+ void __iomem *addr,
298+ u32 mixer_count,
299+ const struct dpu_lm_cfg *mixer);
292300
293301 #endif /*_DPU_HW_CTL_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c+5−7
@@ -3,6 +3,8 @@ · 2 unmodified lines
33 * Copyright (c) 2020-2022, Linaro Limited
44 */
55
6+#include <drm/drm_managed.h>
7+
68 #include <drm/display/drm_dsc_helper.h>
79
810 #include "dpu_kms.h"
@@ -188,12 +190,13 @@ static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops, · 179 unmodified lines
188190 ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
189191 };
190192
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,
192195 void __iomem *addr)
193196 {
194197 struct dpu_hw_dsc *c;
195198
196− c = kzalloc(sizeof(*c), GFP_KERNEL);
199+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
197200 if (!c)
198201 return ERR_PTR(-ENOMEM);
199202
@@ -206,8 +209,3 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, · 6 unmodified lines
206209
207210 return c;
208211 }
209−
210−void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc)
211−{
212− kfree(dsc);
213−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h+7−3
@@ -64,20 +64,24 @@ struct dpu_hw_dsc { · 63 unmodified lines
6464
6565 /**
6666 * dpu_hw_dsc_init() - Initializes the DSC hw driver object.
67+ * @dev: Corresponding device for devres management
6768 * @cfg: DSC catalog entry for which driver object is required
6869 * @addr: Mapped register io address of MDP
6970 * Return: Error code or allocated dpu_hw_dsc context
7071 */
71−struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
72− void __iomem *addr);
72+struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev,
73+ const struct dpu_dsc_cfg *cfg,
74+ void __iomem *addr);
7375
7476 /**
7577 * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object
78+ * @dev: Corresponding device for devres management
7679 * @cfg: DSC catalog entry for which driver object is required
7780 * @addr: Mapped register io address of MDP
7881 * Returns: Error code or allocated dpu_hw_dsc context
7982 */
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,
8185 void __iomem *addr);
8286
8387 /**
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c+5−2
@@ -4,6 +4,8 @@ · 3 unmodified lines
44 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
55 */
66
7+#include <drm/drm_managed.h>
8+
79 #include <drm/display/drm_dsc_helper.h>
810
911 #include "dpu_kms.h"
@@ -367,12 +369,13 @@ static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops, · 357 unmodified lines
367369 ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
368370 }
369371
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,
371374 void __iomem *addr)
372375 {
373376 struct dpu_hw_dsc *c;
374377
375− c = kzalloc(sizeof(*c), GFP_KERNEL);
378+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
376379 if (!c)
377380 return ERR_PTR(-ENOMEM);
378381
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c+6−10
@@ -2,6 +2,8 @@ · 1 unmodified line
22 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
33 */
44
5+#include <drm/drm_managed.h>
6+
57 #include "dpu_hwio.h"
68 #include "dpu_hw_catalog.h"
79 #include "dpu_hw_lm.h"
@@ -68,15 +70,16 @@ static void _setup_dspp_ops(struct dpu_hw_dspp *c, · 60 unmodified lines
6870 c->ops.setup_pcc = dpu_setup_dspp_pcc;
6971 }
7072
71−struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
72− void __iomem *addr)
73+struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
74+ const struct dpu_dspp_cfg *cfg,
75+ void __iomem *addr)
7376 {
7477 struct dpu_hw_dspp *c;
7578
7679 if (!addr)
7780 return ERR_PTR(-EINVAL);
7881
79− c = kzalloc(sizeof(*c), GFP_KERNEL);
82+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
8083 if (!c)
8184 return ERR_PTR(-ENOMEM);
8285
@@ -90,10 +93,3 @@ struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg, · 7 unmodified lines
9093
9194 return c;
9295 }
93−
94−void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp)
95−{
96− kfree(dspp);
97−}
98−
99−
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.h+4−8
@@ -81,18 +81,14 @@ static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw) · 80 unmodified lines
8181 /**
8282 * dpu_hw_dspp_init() - Initializes the DSPP hw driver object.
8383 * should be called once before accessing every DSPP.
84+ * @dev: Corresponding device for devres management
8485 * @cfg: DSPP catalog entry for which driver object is required
8586 * @addr: Mapped register io address of MDP
8687 * Return: pointer to structure or ERR_PTR
8788 */
88−struct dpu_hw_dspp *dpu_hw_dspp_init(const struct dpu_dspp_cfg *cfg,
89− void __iomem *addr);
90−
91−/**
92− * dpu_hw_dspp_destroy(): Destroys DSPP driver context
93− * @dspp: Pointer to DSPP driver context
94− */
95−void dpu_hw_dspp_destroy(struct dpu_hw_dspp *dspp);
89+struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
90+ const struct dpu_dspp_cfg *cfg,
91+ void __iomem *addr);
9692
9793 #endif /*_DPU_HW_DSPP_H */
9894
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c+6−8
@@ -6,6 +6,8 @@ · 5 unmodified lines
66 #include <linux/debugfs.h>
77 #include <linux/slab.h>
88
9+#include <drm/drm_managed.h>
10+
911 #include "dpu_core_irq.h"
1012 #include "dpu_kms.h"
1113 #include "dpu_hw_interrupts.h"
@@ -472,8 +474,9 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, · 460 unmodified lines
472474 return intr_status;
473475 }
474476
475−struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
476− const struct dpu_mdss_cfg *m)
477+struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
478+ void __iomem *addr,
479+ const struct dpu_mdss_cfg *m)
477480 {
478481 struct dpu_hw_intr *intr;
479482 unsigned int i;
@@ -481,7 +484,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, · 1 unmodified line
481484 if (!addr || !m)
482485 return ERR_PTR(-EINVAL);
483486
484− intr = kzalloc(sizeof(*intr), GFP_KERNEL);
487+ intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
485488 if (!intr)
486489 return ERR_PTR(-ENOMEM);
487490
@@ -512,11 +515,6 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, · 24 unmodified lines
512515 return intr;
513516 }
514517
515−void dpu_hw_intr_destroy(struct dpu_hw_intr *intr)
516−{
517− kfree(intr);
518−}
519−
520518 int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms,
521519 unsigned int irq_idx,
522520 void (*irq_cb)(void *arg),
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h+4−7
@@ -70,15 +70,12 @@ struct dpu_hw_intr { · 69 unmodified lines
7070
7171 /**
7272 * dpu_hw_intr_init(): Initializes the interrupts hw object
73+ * @dev: Corresponding device for devres management
7374 * @addr: mapped register io address of MDP
7475 * @m: pointer to MDSS catalog data
7576 */
76−struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
77− const struct dpu_mdss_cfg *m);
77+struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
78+ void __iomem *addr,
79+ const struct dpu_mdss_cfg *m);
7880
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);
8481 #endif
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c+10−12
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
55 */
66
@@ -12,6 +12,8 @@ · 5 unmodified lines
1212
1313 #include <linux/iopoll.h>
1414
15+#include <drm/drm_managed.h>
16+
1517 #define INTF_TIMING_ENGINE_EN 0x000
1618 #define INTF_CONFIG 0x004
1719 #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
318320 return DPU_REG_READ(c, INTF_LINE_COUNT);
319321 }
320322
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)
322324 {
323− dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count);
325+ dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1);
324326 }
325327
326328 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
527529 DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2);
528530 }
529531
530−struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
531− void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
532+struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
533+ const struct dpu_intf_cfg *cfg,
534+ void __iomem *addr,
535+ const struct dpu_mdss_version *mdss_rev)
532536 {
533537 struct dpu_hw_intf *c;
534538
@@ -537,7 +541,7 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, · 2 unmodified lines
537541 return NULL;
538542 }
539543
540− c = kzalloc(sizeof(*c), GFP_KERNEL);
544+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
541545 if (!c)
542546 return ERR_PTR(-ENOMEM);
543547
@@ -581,9 +585,3 @@ struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg, · 37 unmodified lines
581585
582586 return c;
583587 }
584−
585−void dpu_hw_intf_destroy(struct dpu_hw_intf *intf)
586−{
587− kfree(intf);
588−}
589−
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h+7−10
@@ -1,6 +1,6 @@
11 /* SPDX-License-Identifier: GPL-2.0-only */
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
55 */
66
@@ -95,7 +95,7 @@ struct dpu_hw_intf_ops { · 88 unmodified lines
9595
9696 void (*bind_pingpong_blk)(struct dpu_hw_intf *intf,
9797 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);
9999 int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value);
100100
101101 // Tearcheck on INTF since DPU 5.0.0
@@ -131,17 +131,14 @@ struct dpu_hw_intf { · 29 unmodified lines
131131 /**
132132 * dpu_hw_intf_init() - Initializes the INTF driver for the passed
133133 * interface catalog entry.
134+ * @dev: Corresponding device for devres management
134135 * @cfg: interface catalog entry for which driver object is required
135136 * @addr: mapped register io address of MDP
136137 * @mdss_rev: dpu core's major and minor versions
137138 */
138−struct dpu_hw_intf *dpu_hw_intf_init(const struct dpu_intf_cfg *cfg,
139− void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
140−
141−/**
142− * dpu_hw_intf_destroy(): Destroys INTF driver context
143− * @intf: Pointer to INTF driver context
144− */
145−void dpu_hw_intf_destroy(struct dpu_hw_intf *intf);
139+struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
140+ const struct dpu_intf_cfg *cfg,
141+ void __iomem *addr,
142+ const struct dpu_mdss_version *mdss_rev);
146143
147144 #endif /*_DPU_HW_INTF_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c+9−11
@@ -1,9 +1,11 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
55 */
66
7+#include <drm/drm_managed.h>
8+
79 #include "dpu_kms.h"
810 #include "dpu_hw_catalog.h"
911 #include "dpu_hwio.h"
@@ -81,9 +83,9 @@ static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx, · 71 unmodified lines
8183 }
8284 }
8385
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)
8587 {
86− dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count);
88+ dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0);
8789 }
8890
8991 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
156158 ops->collect_misr = dpu_hw_lm_collect_misr;
157159 }
158160
159−struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
160− void __iomem *addr)
161+struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
162+ const struct dpu_lm_cfg *cfg,
163+ void __iomem *addr)
161164 {
162165 struct dpu_hw_mixer *c;
163166
@@ -166,7 +169,7 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, · 2 unmodified lines
166169 return NULL;
167170 }
168171
169− c = kzalloc(sizeof(*c), GFP_KERNEL);
172+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
170173 if (!c)
171174 return ERR_PTR(-ENOMEM);
172175
@@ -180,8 +183,3 @@ struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg, · 7 unmodified lines
180183
181184 return c;
182185 }
183−
184−void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm)
185−{
186− kfree(lm);
187−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h+6−9
@@ -1,5 +1,6 @@
11 /* SPDX-License-Identifier: GPL-2.0-only */
22 /*
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
34 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
45 */
56
@@ -57,7 +58,7 @@ struct dpu_hw_lm_ops { · 51 unmodified lines
5758 /**
5859 * setup_misr: Enable/disable MISR
5960 */
60− void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count);
61+ void (*setup_misr)(struct dpu_hw_mixer *ctx);
6162
6263 /**
6364 * 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
9596 /**
9697 * dpu_hw_lm_init() - Initializes the mixer hw driver object.
9798 * should be called once before accessing every mixer.
99+ * @dev: Corresponding device for devres management
98100 * @cfg: mixer catalog entry for which driver object is required
99101 * @addr: mapped register io address of MDP
100102 */
101−struct dpu_hw_mixer *dpu_hw_lm_init(const struct dpu_lm_cfg *cfg,
102− void __iomem *addr);
103−
104−/**
105− * dpu_hw_lm_destroy(): Destroys layer mixer driver context
106− * @lm: Pointer to LM driver context
107− */
108−void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm);
103+struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
104+ const struct dpu_lm_cfg *cfg,
105+ void __iomem *addr);
109106
110107 #endif /*_DPU_HW_LM_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h+10−0
@@ -98,6 +98,7 @@ enum dpu_hw_blk_type { · 97 unmodified lines
9898 DPU_HW_BLK_DSPP,
9999 DPU_HW_BLK_MERGE_3D,
100100 DPU_HW_BLK_DSC,
101+ DPU_HW_BLK_CDM,
101102 DPU_HW_BLK_MAX,
102103 };
103104
@@ -185,6 +186,11 @@ enum dpu_dsc { · 81 unmodified lines
185186 DSC_MAX
186187 };
187188
189+enum dpu_cdm {
190+ CDM_0 = 1,
191+ CDM_MAX
192+};
193+
188194 enum dpu_pingpong {
189195 PINGPONG_NONE,
190196 PINGPONG_0,
@@ -195,6 +201,8 @@ enum dpu_pingpong { · 4 unmodified lines
195201 PINGPONG_5,
196202 PINGPONG_6,
197203 PINGPONG_7,
204+ PINGPONG_8,
205+ PINGPONG_9,
198206 PINGPONG_S0,
199207 PINGPONG_MAX
200208 };
@@ -204,6 +212,7 @@ enum dpu_merge_3d { · 3 unmodified lines
204212 MERGE_3D_1,
205213 MERGE_3D_2,
206214 MERGE_3D_3,
215+ MERGE_3D_4,
207216 MERGE_3D_MAX
208217 };
209218
@@ -458,6 +467,7 @@ struct dpu_mdss_color { · 248 unmodified lines
458467 #define DPU_DBG_MASK_ROT (1 << 9)
459468 #define DPU_DBG_MASK_DSPP (1 << 10)
460469 #define DPU_DBG_MASK_DSC (1 << 11)
470+#define DPU_DBG_MASK_CDM (1 << 12)
461471
462472 /**
463473 * struct dpu_hw_tear_check - Struct contains parameters to configure
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.c+6−8
@@ -4,6 +4,8 @@ · 3 unmodified lines
44
55 #include <linux/iopoll.h>
66
7+#include <drm/drm_managed.h>
8+
79 #include "dpu_hw_mdss.h"
810 #include "dpu_hwio.h"
911 #include "dpu_hw_catalog.h"
@@ -37,12 +39,13 @@ static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c, · 27 unmodified lines
3739 c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode;
3840 };
3941
40−struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg,
41− void __iomem *addr)
42+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
43+ const struct dpu_merge_3d_cfg *cfg,
44+ void __iomem *addr)
4245 {
4346 struct dpu_hw_merge_3d *c;
4447
45− c = kzalloc(sizeof(*c), GFP_KERNEL);
48+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
4649 if (!c)
4750 return ERR_PTR(-ENOMEM);
4851
@@ -55,8 +58,3 @@ struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg, · 6 unmodified lines
5558
5659 return c;
5760 }
58−
59−void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *hw)
60−{
61− kfree(hw);
62−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_merge3d.h+4−9
@@ -48,18 +48,13 @@ static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw) · 47 unmodified lines
4848 /**
4949 * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed
5050 * merge3d catalog entry.
51+ * @dev: Corresponding device for devres management
5152 * @cfg: Pingpong catalog entry for which driver object is required
5253 * @addr: Mapped register io address of MDP
5354 * Return: Error code or allocated dpu_hw_merge_3d context
5455 */
55−struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(const struct dpu_merge_3d_cfg *cfg,
56− void __iomem *addr);
57−
58−/**
59− * dpu_hw_merge_3d_destroy - destroys merge_3d driver context
60− * should be called to free the context
61− * @pp: Pointer to PP driver context returned by dpu_hw_merge_3d_init
62− */
63−void dpu_hw_merge_3d_destroy(struct dpu_hw_merge_3d *pp);
56+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
57+ const struct dpu_merge_3d_cfg *cfg,
58+ void __iomem *addr);
6459
6560 #endif /*_DPU_HW_MERGE3D_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c+7−8
@@ -4,6 +4,8 @@ · 3 unmodified lines
44
55 #include <linux/iopoll.h>
66
7+#include <drm/drm_managed.h>
8+
79 #include "dpu_hw_mdss.h"
810 #include "dpu_hwio.h"
911 #include "dpu_hw_catalog.h"
@@ -281,12 +283,14 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp) · 271 unmodified lines
281283 return 0;
282284 }
283285
284−struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
285− void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
286+struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
287+ const struct dpu_pingpong_cfg *cfg,
288+ void __iomem *addr,
289+ const struct dpu_mdss_version *mdss_rev)
286290 {
287291 struct dpu_hw_pingpong *c;
288292
289− c = kzalloc(sizeof(*c), GFP_KERNEL);
293+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
290294 if (!c)
291295 return ERR_PTR(-ENOMEM);
292296
@@ -317,8 +321,3 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg, · 24 unmodified lines
317321
318322 return c;
319323 }
320−
321−void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp)
322−{
323− kfree(pp);
324−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h+5−9
@@ -121,19 +121,15 @@ static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) · 120 unmodified lines
121121 /**
122122 * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed
123123 * pingpong catalog entry.
124+ * @dev: Corresponding device for devres management
124125 * @cfg: Pingpong catalog entry for which driver object is required
125126 * @addr: Mapped register io address of MDP
126127 * @mdss_rev: dpu core's major and minor versions
127128 * Return: Error code or allocated dpu_hw_pingpong context
128129 */
129−struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
130− void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
131−
132−/**
133− * dpu_hw_pingpong_destroy - destroys pingpong driver context
134− * should be called to free the context
135− * @pp: Pointer to PP driver context returned by dpu_hw_pingpong_init
136− */
137−void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp);
130+struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
131+ const struct dpu_pingpong_cfg *cfg,
132+ void __iomem *addr,
133+ const struct dpu_mdss_version *mdss_rev);
138134
139135 #endif /*_DPU_HW_PINGPONG_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c+9−28
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include "msm_mdss.h"
1212
1313 #include <drm/drm_file.h>
14+#include <drm/drm_managed.h>
1415
1516 #define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087
1617
@@ -395,15 +396,6 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx, · 378 unmodified lines
395396 format);
396397 }
397398
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−
407399 /*
408400 * dpu_hw_sspp_setup_rects()
409401 */
@@ -614,12 +606,8 @@ static void _setup_layer_ops(struct dpu_hw_sspp *c, · 204 unmodified lines
614606 test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
615607 c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
616608
617− if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
618− test_bit(DPU_SSPP_SCALER_QSEED3LITE, &features) ||
619− test_bit(DPU_SSPP_SCALER_QSEED4, &features)) {
609+ if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, &features))
620610 c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3;
621− c->ops.get_scaler_ver = _dpu_hw_sspp_get_scaler3_ver;
622− }
623611
624612 if (test_bit(DPU_SSPP_CDP, &features))
625613 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
654642 cfg->len,
655643 kms);
656644
657− if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) ||
658− cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) ||
659− cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) ||
660− cfg->features & BIT(DPU_SSPP_SCALER_QSEED4))
645+ if (sblk->scaler_blk.len)
661646 dpu_debugfs_create_regset32("scaler_blk", 0400,
662647 debugfs_root,
663648 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
685670 }
686671 #endif
687672
688−struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg,
689− void __iomem *addr, const struct msm_mdss_data *mdss_data,
690− const struct dpu_mdss_version *mdss_rev)
673+struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
674+ const struct dpu_sspp_cfg *cfg,
675+ void __iomem *addr,
676+ const struct msm_mdss_data *mdss_data,
677+ const struct dpu_mdss_version *mdss_rev)
691678 {
692679 struct dpu_hw_sspp *hw_pipe;
693680
694681 if (!addr)
695682 return ERR_PTR(-EINVAL);
696683
697− hw_pipe = kzalloc(sizeof(*hw_pipe), GFP_KERNEL);
684+ hw_pipe = drmm_kzalloc(dev, sizeof(*hw_pipe), GFP_KERNEL);
698685 if (!hw_pipe)
699686 return ERR_PTR(-ENOMEM);
700687
@@ -709,9 +696,3 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg, · 8 unmodified lines
709696
710697 return hw_pipe;
711698 }
712−
713−void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
714−{
715− kfree(ctx);
716−}
717−
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h+6−31
@@ -21,21 +21,6 @@ struct dpu_hw_sspp; · 20 unmodified lines
2121 #define DPU_SSPP_ROT_90 BIT(3)
2222 #define DPU_SSPP_SOLID_FILL BIT(4)
2323
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−
3924 /**
4025 * Component indices
4126 */
@@ -296,12 +281,6 @@ struct dpu_hw_sspp_ops { · 254 unmodified lines
296281 struct dpu_hw_scaler3_cfg *scaler3_cfg,
297282 const struct dpu_format *format);
298283
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−
305284 /**
306285 * setup_cdp - setup client driven prefetch
307286 * @pipe: Pointer to software pipe context
@@ -339,21 +318,17 @@ struct dpu_kms; · 31 unmodified lines
339318 /**
340319 * dpu_hw_sspp_init() - Initializes the sspp hw driver object.
341320 * Should be called once before accessing every pipe.
321+ * @dev: Corresponding device for devres management
342322 * @cfg: Pipe catalog entry for which driver object is required
343323 * @addr: Mapped register io address of MDP
344324 * @mdss_data: UBWC / MDSS configuration data
345325 * @mdss_rev: dpu core's major and minor versions
346326 */
347−struct dpu_hw_sspp *dpu_hw_sspp_init(const struct dpu_sspp_cfg *cfg,
348− void __iomem *addr, const struct msm_mdss_data *mdss_data,
349− const struct dpu_mdss_version *mdss_rev);
350−
351−/**
352− * dpu_hw_sspp_destroy(): Destroys SSPP driver context
353− * should be called during Hw pipe cleanup.
354− * @ctx: Pointer to SSPP driver context returned by dpu_hw_sspp_init
355− */
356−void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
327+struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
328+ const struct dpu_sspp_cfg *cfg,
329+ void __iomem *addr,
330+ const struct msm_mdss_data *mdss_data,
331+ const struct dpu_mdss_version *mdss_rev);
357332
358333 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
359334 struct dentry *entry);
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c+7−10
@@ -2,6 +2,8 @@ · 1 unmodified line
22 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
33 */
44
5+#include <drm/drm_managed.h>
6+
57 #include "dpu_hwio.h"
68 #include "dpu_hw_catalog.h"
79 #include "dpu_hw_top.h"
@@ -247,16 +249,17 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, · 239 unmodified lines
247249 ops->intf_audio_select = dpu_hw_intf_audio_select;
248250 }
249251
250−struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg,
251− void __iomem *addr,
252− const struct dpu_mdss_cfg *m)
252+struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
253+ const struct dpu_mdp_cfg *cfg,
254+ void __iomem *addr,
255+ const struct dpu_mdss_cfg *m)
253256 {
254257 struct dpu_hw_mdp *mdp;
255258
256259 if (!addr)
257260 return ERR_PTR(-EINVAL);
258261
259− mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
262+ mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
260263 if (!mdp)
261264 return ERR_PTR(-ENOMEM);
262265
@@ -271,9 +274,3 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg, · 8 unmodified lines
271274
272275 return mdp;
273276 }
274−
275−void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp)
276−{
277− kfree(mdp);
278−}
279−
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h+5−3
@@ -145,13 +145,15 @@ struct dpu_hw_mdp { · 144 unmodified lines
145145
146146 /**
147147 * dpu_hw_mdptop_init - initializes the top driver for the passed config
148+ * @dev: Corresponding device for devres management
148149 * @cfg: MDP TOP configuration from catalog
149150 * @addr: Mapped register io address of MDP
150151 * @m: Pointer to mdss catalog data
151152 */
152−struct dpu_hw_mdp *dpu_hw_mdptop_init(const struct dpu_mdp_cfg *cfg,
153− void __iomem *addr,
154− const struct dpu_mdss_cfg *m);
153+struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
154+ const struct dpu_mdp_cfg *cfg,
155+ void __iomem *addr,
156+ const struct dpu_mdss_cfg *m);
155157
156158 void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp);
157159
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c+52−18
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0-only
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
55 */
66 #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
@@ -381,12 +381,6 @@ end: · 374 unmodified lines
381381 DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode);
382382 }
383383
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−
390384 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
391385 u32 csc_reg_off,
392386 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
481475 cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0);
482476 }
483477
478+/*
479+ * note: Aside from encoders, input_sel should be set to 0x0 by default
480+ */
484481 void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
485− u32 misr_ctrl_offset,
486− bool enable, u32 frame_count)
482+ u32 misr_ctrl_offset, u8 input_sel)
487483 {
488484 u32 config = 0;
489485
@@ -492,15 +488,9 @@ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, · 2 unmodified lines
492488 /* Clear old MISR value (in case it's read before a new value is calculated)*/
493489 wmb();
494490
495− if (enable) {
496− config = (frame_count & MISR_FRAME_COUNT_MASK) |
497− MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK;
498−
499− DPU_REG_WRITE(c, misr_ctrl_offset, config);
500− } else {
501− DPU_REG_WRITE(c, misr_ctrl_offset, 0);
502− }
503−
491+ config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK |
492+ ((input_sel & 0xF) << 24);
493+ DPU_REG_WRITE(c, misr_ctrl_offset, config);
504494 }
505495
506496 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
567557
568558 return clk_forced_on;
569559 }
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+};
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h+9−8
@@ -1,6 +1,6 @@
11 /* SPDX-License-Identifier: GPL-2.0-only */
22 /*
3− * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
3+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
44 * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
55 */
66
@@ -13,12 +13,18 @@ · 6 unmodified lines
1313 #include "dpu_hw_catalog.h"
1414
1515 #define REG_MASK(n) ((BIT(n)) - 1)
16−#define MISR_FRAME_COUNT_MASK 0xFF
16+#define MISR_FRAME_COUNT 0x1
1717 #define MISR_CTRL_ENABLE BIT(8)
1818 #define MISR_CTRL_STATUS BIT(9)
1919 #define MISR_CTRL_STATUS_CLEAR BIT(10)
2020 #define MISR_CTRL_FREE_RUN_MASK BIT(31)
2121
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+
2228 /*
2329 * This is the common struct maintained by each sub block
2430 * 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
340346 u32 scaler_offset, u32 scaler_version,
341347 const struct dpu_format *format);
342348
343−u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
344− u32 scaler_offset);
345−
346349 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
347350 u32 csc_reg_off,
348351 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
358361 const struct dpu_hw_qos_cfg *cfg);
359362
360363 void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
361− u32 misr_ctrl_offset,
362− bool enable,
363− u32 frame_count);
364+ u32 misr_ctrl_offset, u8 input_sel);
364365
365366 int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c,
366367 u32 misr_ctrl_offset,
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c+6−8
@@ -2,6 +2,8 @@ · 1 unmodified line
22 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
33 */
44
5+#include <drm/drm_managed.h>
6+
57 #include "dpu_hwio.h"
68 #include "dpu_hw_catalog.h"
79 #include "dpu_hw_vbif.h"
@@ -211,12 +213,13 @@ static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops, · 203 unmodified lines
211213 ops->set_write_gather_en = dpu_hw_set_write_gather_en;
212214 }
213215
214−struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg,
215− void __iomem *addr)
216+struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
217+ const struct dpu_vbif_cfg *cfg,
218+ void __iomem *addr)
216219 {
217220 struct dpu_hw_vbif *c;
218221
219− c = kzalloc(sizeof(*c), GFP_KERNEL);
222+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
220223 if (!c)
221224 return ERR_PTR(-ENOMEM);
222225
@@ -234,8 +237,3 @@ struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg, · 11 unmodified lines
234237
235238 return c;
236239 }
237−
238−void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif)
239−{
240− kfree(vbif);
241−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h+4−4
@@ -108,12 +108,12 @@ struct dpu_hw_vbif { · 107 unmodified lines
108108 /**
109109 * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed
110110 * VBIF catalog entry.
111+ * @dev: Corresponding device for devres management
111112 * @cfg: VBIF catalog entry for which driver object is required
112113 * @addr: Mapped register io address of MDSS
113114 */
114−struct dpu_hw_vbif *dpu_hw_vbif_init(const struct dpu_vbif_cfg *cfg,
115− void __iomem *addr);
116−
117−void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif);
115+struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
116+ const struct dpu_vbif_cfg *cfg,
117+ void __iomem *addr);
118118
119119 #endif /*_DPU_HW_VBIF_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c+10−8
@@ -3,6 +3,8 @@ · 2 unmodified lines
33 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
44 */
55
6+#include <drm/drm_managed.h>
7+
68 #include "dpu_hw_mdss.h"
79 #include "dpu_hwio.h"
810 #include "dpu_hw_catalog.h"
@@ -87,6 +89,9 @@ static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, · 78 unmodified lines
8789 dst_format |= BIT(14); /* DST_ALPHA_X */
8890 }
8991
92+ if (DPU_FORMAT_IS_YUV(fmt))
93+ dst_format |= BIT(15);
94+
9095 pattern = (fmt->element[3] << 24) |
9196 (fmt->element[2] << 16) |
9297 (fmt->element[1] << 8) |
@@ -208,15 +213,17 @@ static void _setup_wb_ops(struct dpu_hw_wb_ops *ops, · 115 unmodified lines
208213 ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl;
209214 }
210215
211−struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg,
212− void __iomem *addr, const struct dpu_mdss_version *mdss_rev)
216+struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
217+ const struct dpu_wb_cfg *cfg,
218+ void __iomem *addr,
219+ const struct dpu_mdss_version *mdss_rev)
213220 {
214221 struct dpu_hw_wb *c;
215222
216223 if (!addr)
217224 return ERR_PTR(-EINVAL);
218225
219− c = kzalloc(sizeof(*c), GFP_KERNEL);
226+ c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
220227 if (!c)
221228 return ERR_PTR(-ENOMEM);
222229
@@ -230,8 +237,3 @@ struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg, · 7 unmodified lines
230237
231238 return c;
232239 }
233−
234−void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb)
235−{
236− kfree(hw_wb);
237−}
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h+5−8
@@ -76,18 +76,15 @@ struct dpu_hw_wb { · 75 unmodified lines
7676
7777 /**
7878 * dpu_hw_wb_init() - Initializes the writeback hw driver object.
79+ * @dev: Corresponding device for devres management
7980 * @cfg: wb_path catalog entry for which driver object is required
8081 * @addr: mapped register io address of MDP
8182 * @mdss_rev: dpu core's major and minor versions
8283 * Return: Error code or allocated dpu_hw_wb context
8384 */
84−struct dpu_hw_wb *dpu_hw_wb_init(const struct dpu_wb_cfg *cfg,
85− void __iomem *addr, const struct dpu_mdss_version *mdss_rev);
86−
87−/**
88− * dpu_hw_wb_destroy(): Destroy writeback hw driver object.
89− * @hw_wb: Pointer to writeback hw driver object
90− */
91−void dpu_hw_wb_destroy(struct dpu_hw_wb *hw_wb);
85+struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
86+ const struct dpu_wb_cfg *cfg,
87+ void __iomem *addr,
88+ const struct dpu_mdss_version *mdss_rev);
9289
9390 #endif /*_DPU_HW_WB_H */
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c+25−54
@@ -274,9 +274,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) · 273 unmodified lines
274274 struct dpu_kms *dpu_kms = to_dpu_kms(kms);
275275 void *p = dpu_hw_util_get_log_mask_ptr();
276276 struct dentry *entry;
277− struct drm_device *dev;
278− struct msm_drm_private *priv;
279− int i;
280277
281278 if (!p)
282279 return -EINVAL;
@@ -285,9 +282,6 @@ static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) · 2 unmodified lines
285282 if (minor->type != DRM_MINOR_PRIMARY)
286283 return 0;
287284
288− dev = dpu_kms->dev;
289− priv = dev->dev_private;
290−
291285 entry = debugfs_create_dir("debug", minor->debugfs_root);
292286
293287 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
297291 dpu_debugfs_core_irq_init(dpu_kms, entry);
298292 dpu_debugfs_sspp_init(dpu_kms, entry);
299293
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−
305294 return dpu_core_perf_debugfs_init(dpu_kms, entry);
306295 }
307296 #endif
@@ -597,7 +586,6 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, · 289 unmodified lines
597586 rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
598587 if (rc) {
599588 DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
600− drm_encoder_cleanup(encoder);
601589 return rc;
602590 }
603591 }
@@ -630,7 +618,6 @@ static int _dpu_kms_initialize_hdmi(struct drm_device *dev, · 26 unmodified lines
630618 rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
631619 if (rc) {
632620 DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
633− drm_encoder_cleanup(encoder);
634621 return rc;
635622 }
636623
@@ -662,7 +649,6 @@ static int _dpu_kms_initialize_writeback(struct drm_device *dev, · 25 unmodified lines
662649 n_formats);
663650 if (rc) {
664651 DPU_ERROR("dpu_writeback_init, rc = %d\n", rc);
665− drm_encoder_cleanup(encoder);
666652 return rc;
667653 }
668654
@@ -806,30 +792,17 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) · 137 unmodified lines
806792 {
807793 int i;
808794
809− if (dpu_kms->hw_intr)
810− dpu_hw_intr_destroy(dpu_kms->hw_intr);
811795 dpu_kms->hw_intr = NULL;
812796
813797 /* safe to call these more than once during shutdown */
814798 _dpu_kms_mmu_destroy(dpu_kms);
815799
816− if (dpu_kms->catalog) {
817− for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
818− if (dpu_kms->hw_vbif[i]) {
819− dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]);
820− dpu_kms->hw_vbif[i] = NULL;
821− }
822− }
800+ for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
801+ dpu_kms->hw_vbif[i] = NULL;
823802 }
824803
825− if (dpu_kms->rm_init)
826− dpu_rm_destroy(&dpu_kms->rm);
827− dpu_kms->rm_init = false;
828−
829804 dpu_kms->catalog = NULL;
830805
831− if (dpu_kms->hw_mdp)
832− dpu_hw_mdp_destroy(dpu_kms->hw_mdp);
833806 dpu_kms->hw_mdp = NULL;
834807 }
835808
@@ -856,7 +829,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) · 20 unmodified lines
856829 {
857830 struct msm_drm_private *priv;
858831 struct dpu_kms *dpu_kms = to_dpu_kms(kms);
859− int i;
860832
861833 if (!dpu_kms || !dpu_kms->dev)
862834 return -EINVAL;
@@ -865,9 +837,6 @@ static int dpu_irq_postinstall(struct msm_kms *kms) · 2 unmodified lines
865837 if (!priv)
866838 return -EINVAL;
867839
868− for (i = 0; i < ARRAY_SIZE(priv->dp); i++)
869− msm_dp_irq_postinstall(priv->dp[i]);
870−
871840 return 0;
872841 }
873842
@@ -975,6 +944,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k · 101 unmodified lines
975944 }
976945 }
977946
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+
978951 pm_runtime_put_sync(&dpu_kms->pdev->dev);
979952 }
980953
@@ -1078,7 +1051,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 97 unmodified lines
10781051 if (!dpu_kms->catalog) {
10791052 DPU_ERROR("device config not known!\n");
10801053 rc = -EINVAL;
1081− goto power_error;
1054+ goto err_pm_put;
10821055 }
10831056
10841057 /*
@@ -1088,49 +1061,48 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 3 unmodified lines
10881061 rc = _dpu_kms_mmu_init(dpu_kms);
10891062 if (rc) {
10901063 DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc);
1091− goto power_error;
1064+ goto err_pm_put;
10921065 }
10931066
10941067 dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent);
10951068 if (IS_ERR(dpu_kms->mdss)) {
10961069 rc = PTR_ERR(dpu_kms->mdss);
10971070 DPU_ERROR("failed to get MDSS data: %d\n", rc);
1098− goto power_error;
1071+ goto err_pm_put;
10991072 }
11001073
11011074 if (!dpu_kms->mdss) {
11021075 rc = -EINVAL;
11031076 DPU_ERROR("NULL MDSS data\n");
1104− goto power_error;
1077+ goto err_pm_put;
11051078 }
11061079
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);
11081081 if (rc) {
11091082 DPU_ERROR("rm init failed: %d\n", rc);
1110− goto power_error;
1083+ goto err_pm_put;
11111084 }
11121085
1113− dpu_kms->rm_init = true;
1114−
1115− dpu_kms->hw_mdp = dpu_hw_mdptop_init(dpu_kms->catalog->mdp,
1086+ dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev,
1087+ dpu_kms->catalog->mdp,
11161088 dpu_kms->mmio,
11171089 dpu_kms->catalog);
11181090 if (IS_ERR(dpu_kms->hw_mdp)) {
11191091 rc = PTR_ERR(dpu_kms->hw_mdp);
11201092 DPU_ERROR("failed to get hw_mdp: %d\n", rc);
11211093 dpu_kms->hw_mdp = NULL;
1122− goto power_error;
1094+ goto err_pm_put;
11231095 }
11241096
11251097 for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
11261098 struct dpu_hw_vbif *hw;
11271099 const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i];
11281100
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]);
11301102 if (IS_ERR(hw)) {
11311103 rc = PTR_ERR(hw);
11321104 DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc);
1133− goto power_error;
1105+ goto err_pm_put;
11341106 }
11351107
11361108 dpu_kms->hw_vbif[vbif->id] = hw;
@@ -1146,15 +1118,15 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 9 unmodified lines
11461118 rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate);
11471119 if (rc) {
11481120 DPU_ERROR("failed to init perf %d\n", rc);
1149− goto perf_err;
1121+ goto err_pm_put;
11501122 }
11511123
1152− dpu_kms->hw_intr = dpu_hw_intr_init(dpu_kms->mmio, dpu_kms->catalog);
1153− if (IS_ERR_OR_NULL(dpu_kms->hw_intr)) {
1124+ dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog);
1125+ if (IS_ERR(dpu_kms->hw_intr)) {
11541126 rc = PTR_ERR(dpu_kms->hw_intr);
11551127 DPU_ERROR("hw_intr init failed: %d\n", rc);
11561128 dpu_kms->hw_intr = NULL;
1157− goto hw_intr_init_err;
1129+ goto err_pm_put;
11581130 }
11591131
11601132 dev->mode_config.min_width = 0;
@@ -1179,7 +1151,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 18 unmodified lines
11791151 rc = _dpu_kms_drm_obj_init(dpu_kms);
11801152 if (rc) {
11811153 DPU_ERROR("modeset init failed: %d\n", rc);
1182− goto drm_obj_init_err;
1154+ goto err_pm_put;
11831155 }
11841156
11851157 dpu_vbif_init_memtypes(dpu_kms);
@@ -1188,10 +1160,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) · 2 unmodified lines
11881160
11891161 return 0;
11901162
1191−drm_obj_init_err:
1192−hw_intr_init_err:
1193−perf_err:
1194−power_error:
1163+err_pm_put:
11951164 pm_runtime_put_sync(&dpu_kms->pdev->dev);
11961165 error:
11971166 _dpu_kms_hw_destroy(dpu_kms);
@@ -1349,6 +1318,7 @@ static const struct dev_pm_ops dpu_pm_ops = { · 151 unmodified lines
13491318 static const struct of_device_id dpu_dt_match[] = {
13501319 { .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, },
13511320 { .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, },
1321+ { .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, },
13521322 { .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, },
13531323 { .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, },
13541324 { .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, },
@@ -1363,6 +1333,7 @@ static const struct of_device_id dpu_dt_match[] = { · 8 unmodified lines
13631333 { .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, },
13641334 { .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, },
13651335 { .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, },
1336+ { .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, },
13661337 {}
13671338 };
13681339 MODULE_DEVICE_TABLE(of, dpu_dt_match);
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h+2−1
@@ -51,6 +51,7 @@ · 50 unmodified lines
5151 } while (0)
5252
5353 #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__)
5455
5556 /**
5657 * ktime_compare_safe - compare two ktime structures
@@ -88,7 +89,6 @@ struct dpu_kms { · 31 unmodified lines
8889 struct drm_private_obj global_state;
8990
9091 struct dpu_rm rm;
91− bool rm_init;
9292
9393 struct dpu_hw_vbif *hw_vbif[VBIF_MAX];
9494 struct dpu_hw_mdp *hw_mdp;
@@ -136,6 +136,7 @@ struct dpu_global_state { · 41 unmodified lines
136136 uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
137137 uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
138138 uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
139+ uint32_t cdm_to_enc_id;
139140 };
140141
141142 struct dpu_global_state
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c+20−85
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 #include "dpu_kms.h"
2222 #include "dpu_formats.h"
2323 #include "dpu_hw_sspp.h"
24+#include "dpu_hw_util.h"
2425 #include "dpu_trace.h"
2526 #include "dpu_crtc.h"
2627 #include "dpu_vbif.h"
@@ -78,8 +79,6 @@ static const uint32_t qcom_compressed_supported_formats[] = { · 51 unmodified lines
7879 struct dpu_plane {
7980 struct drm_plane base;
8081
81− struct mutex lock;
82−
8382 enum dpu_sspp pipe;
8483
8584 uint32_t color_fill;
@@ -470,8 +469,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw, · 384 unmodified lines
470469 scale_cfg->src_height[i] /= chroma_subsmpl_v;
471470 }
472471
473− if (pipe_hw->cap->features &
474− BIT(DPU_SSPP_SCALER_QSEED4)) {
472+ if (pipe_hw->cap->sblk->scaler_blk.version >= 0x3000) {
475473 scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
476474 scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
477475 } else {
@@ -511,36 +509,6 @@ static void _dpu_plane_setup_pixel_ext(struct dpu_hw_scaler3_cfg *scale_cfg, · 33 unmodified lines
511509 }
512510 }
513511
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−
544512 static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
545513 const struct dpu_format *fmt)
546514 {
@@ -774,8 +742,8 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu, · 227 unmodified lines
774742 min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
775743
776744 if (DPU_FORMAT_IS_YUV(fmt) &&
777− (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
778− !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
745+ (!pipe->sspp->cap->sblk->scaler_blk.len ||
746+ !pipe->sspp->cap->sblk->csc_blk.len)) {
779747 DPU_DEBUG_PLANE(pdpu,
780748 "plane doesn't have scaler/csc for yuv\n");
781749 return -EINVAL;
@@ -824,6 +792,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, · 42 unmodified lines
824792 plane);
825793 int ret = 0, min_scale;
826794 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;
827797 struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
828798 struct dpu_sw_pipe *pipe = &pstate->pipe;
829799 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
892862
893863 max_linewidth = pdpu->catalog->caps->max_linewidth;
894864
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) {
896867 /*
897868 * In parallel multirect case only the half of the usual width
898869 * is supported for tiled formats. If we are here, we know that
899870 * full width is more than max_linewidth, thus each rect is
900871 * wider than allowed.
901872 */
902− if (DPU_FORMAT_IS_UBWC(fmt)) {
873+ if (DPU_FORMAT_IS_UBWC(fmt) &&
874+ drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
903875 DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n",
904876 DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
905877 return -E2BIG;
@@ -1213,29 +1185,6 @@ static void dpu_plane_atomic_update(struct drm_plane *plane, · 307 unmodified lines
12131185 }
12141186 }
12151187
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−
12391188 static void dpu_plane_destroy_state(struct drm_plane *plane,
12401189 struct drm_plane_state *state)
12411190 {
@@ -1405,7 +1354,6 @@ static bool dpu_plane_format_mod_supported(struct drm_plane *plane, · 163 unmodified lines
14051354 static const struct drm_plane_funcs dpu_plane_funcs = {
14061355 .update_plane = drm_atomic_helper_update_plane,
14071356 .disable_plane = drm_atomic_helper_disable_plane,
1408− .destroy = dpu_plane_destroy,
14091357 .reset = dpu_plane_reset,
14101358 .atomic_duplicate_state = dpu_plane_duplicate_state,
14111359 .atomic_destroy_state = dpu_plane_destroy_state,
@@ -1433,35 +1381,28 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 21 unmodified lines
14331381 struct dpu_hw_sspp *pipe_hw;
14341382 uint32_t num_formats;
14351383 uint32_t supported_rotations;
1436− int ret = -EINVAL;
1437−
1438− /* create and zero local structure */
1439− pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL);
1440− if (!pdpu) {
1441− DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe);
1442− ret = -ENOMEM;
1443− return ERR_PTR(ret);
1444− }
1445−
1446− /* cache local stuff for later */
1447− plane = &pdpu->base;
1448− pdpu->pipe = pipe;
1384+ int ret;
14491385
14501386 /* initialize underlying h/w driver */
14511387 pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
14521388 if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
14531389 DPU_ERROR("[%u]SSPP is invalid\n", pipe);
1454− goto clean_plane;
1390+ return ERR_PTR(-EINVAL);
14551391 }
14561392
14571393 format_list = pipe_hw->cap->sblk->format_list;
14581394 num_formats = pipe_hw->cap->sblk->num_formats;
14591395
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,
14611398 format_list, num_formats,
14621399 supported_format_modifiers, type, NULL);
1463− if (ret)
1464− goto clean_plane;
1400+ if (IS_ERR(pdpu))
1401+ return ERR_CAST(pdpu);
1402+
1403+ /* cache local stuff for later */
1404+ plane = &pdpu->base;
1405+ pdpu->pipe = pipe;
14651406
14661407 pdpu->catalog = kms->catalog;
14671408
@@ -1488,13 +1429,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, · 20 unmodified lines
14881429 /* success! finalize initialization */
14891430 drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
14901431
1491− mutex_init(&pdpu->lock);
1492−
14931432 DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
14941433 pipe, plane->base.id);
14951434 return plane;
1496−
1497−clean_plane:
1498− kfree(pdpu);
1499− return ERR_PTR(ret);
15001435 }
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c+61−80
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include "dpu_kms.h"
99 #include "dpu_hw_lm.h"
1010 #include "dpu_hw_ctl.h"
11+#include "dpu_hw_cdm.h"
1112 #include "dpu_hw_pingpong.h"
1213 #include "dpu_hw_sspp.h"
1314 #include "dpu_hw_intf.h"
@@ -34,72 +35,8 @@ struct dpu_rm_requirements { · 20 unmodified lines
3435 struct msm_display_topology topology;
3536 };
3637
37−int dpu_rm_destroy(struct dpu_rm *rm)
38−{
39− int i;
40−
41− for (i = 0; i < ARRAY_SIZE(rm->dspp_blks); i++) {
42− struct dpu_hw_dspp *hw;
43−
44− if (rm->dspp_blks[i]) {
45− hw = to_dpu_hw_dspp(rm->dspp_blks[i]);
46− dpu_hw_dspp_destroy(hw);
47− }
48− }
49− for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) {
50− struct dpu_hw_pingpong *hw;
51−
52− if (rm->pingpong_blks[i]) {
53− hw = to_dpu_hw_pingpong(rm->pingpong_blks[i]);
54− dpu_hw_pingpong_destroy(hw);
55− }
56− }
57− for (i = 0; i < ARRAY_SIZE(rm->merge_3d_blks); i++) {
58− struct dpu_hw_merge_3d *hw;
59−
60− if (rm->merge_3d_blks[i]) {
61− hw = to_dpu_hw_merge_3d(rm->merge_3d_blks[i]);
62− dpu_hw_merge_3d_destroy(hw);
63− }
64− }
65− for (i = 0; i < ARRAY_SIZE(rm->mixer_blks); i++) {
66− struct dpu_hw_mixer *hw;
67−
68− if (rm->mixer_blks[i]) {
69− hw = to_dpu_hw_mixer(rm->mixer_blks[i]);
70− dpu_hw_lm_destroy(hw);
71− }
72− }
73− for (i = 0; i < ARRAY_SIZE(rm->ctl_blks); i++) {
74− struct dpu_hw_ctl *hw;
75−
76− if (rm->ctl_blks[i]) {
77− hw = to_dpu_hw_ctl(rm->ctl_blks[i]);
78− dpu_hw_ctl_destroy(hw);
79− }
80− }
81− for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++)
82− dpu_hw_intf_destroy(rm->hw_intf[i]);
83−
84− for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) {
85− struct dpu_hw_dsc *hw;
86−
87− if (rm->dsc_blks[i]) {
88− hw = to_dpu_hw_dsc(rm->dsc_blks[i]);
89− dpu_hw_dsc_destroy(hw);
90− }
91− }
92−
93− for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
94− dpu_hw_wb_destroy(rm->hw_wb[i]);
95−
96− for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
97− dpu_hw_sspp_destroy(rm->hw_sspp[i]);
98−
99− return 0;
100−}
101−
102−int dpu_rm_init(struct dpu_rm *rm,
38+int dpu_rm_init(struct drm_device *dev,
39+ struct dpu_rm *rm,
10340 const struct dpu_mdss_cfg *cat,
10441 const struct msm_mdss_data *mdss_data,
10542 void __iomem *mmio)
@@ -119,7 +56,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 13 unmodified lines
11956 struct dpu_hw_mixer *hw;
12057 const struct dpu_lm_cfg *lm = &cat->mixer[i];
12158
122− hw = dpu_hw_lm_init(lm, mmio);
59+ hw = dpu_hw_lm_init(dev, lm, mmio);
12360 if (IS_ERR(hw)) {
12461 rc = PTR_ERR(hw);
12562 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
13269 struct dpu_hw_merge_3d *hw;
13370 const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i];
13471
135− hw = dpu_hw_merge_3d_init(merge_3d, mmio);
72+ hw = dpu_hw_merge_3d_init(dev, merge_3d, mmio);
13673 if (IS_ERR(hw)) {
13774 rc = PTR_ERR(hw);
13875 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
14683 struct dpu_hw_pingpong *hw;
14784 const struct dpu_pingpong_cfg *pp = &cat->pingpong[i];
14885
149− hw = dpu_hw_pingpong_init(pp, mmio, cat->mdss_ver);
86+ hw = dpu_hw_pingpong_init(dev, pp, mmio, cat->mdss_ver);
15087 if (IS_ERR(hw)) {
15188 rc = PTR_ERR(hw);
15289 DPU_ERROR("failed pingpong object creation: err %d\n",
@@ -162,7 +99,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 9 unmodified lines
16299 struct dpu_hw_intf *hw;
163100 const struct dpu_intf_cfg *intf = &cat->intf[i];
164101
165− hw = dpu_hw_intf_init(intf, mmio, cat->mdss_ver);
102+ hw = dpu_hw_intf_init(dev, intf, mmio, cat->mdss_ver);
166103 if (IS_ERR(hw)) {
167104 rc = PTR_ERR(hw);
168105 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
175112 struct dpu_hw_wb *hw;
176113 const struct dpu_wb_cfg *wb = &cat->wb[i];
177114
178− hw = dpu_hw_wb_init(wb, mmio, cat->mdss_ver);
115+ hw = dpu_hw_wb_init(dev, wb, mmio, cat->mdss_ver);
179116 if (IS_ERR(hw)) {
180117 rc = PTR_ERR(hw);
181118 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
188125 struct dpu_hw_ctl *hw;
189126 const struct dpu_ctl_cfg *ctl = &cat->ctl[i];
190127
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);
192129 if (IS_ERR(hw)) {
193130 rc = PTR_ERR(hw);
194131 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
201138 struct dpu_hw_dspp *hw;
202139 const struct dpu_dspp_cfg *dspp = &cat->dspp[i];
203140
204− hw = dpu_hw_dspp_init(dspp, mmio);
141+ hw = dpu_hw_dspp_init(dev, dspp, mmio);
205142 if (IS_ERR(hw)) {
206143 rc = PTR_ERR(hw);
207144 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
215152 const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
216153
217154 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);
219156 else
220− hw = dpu_hw_dsc_init(dsc, mmio);
157+ hw = dpu_hw_dsc_init(dev, dsc, mmio);
221158
222159 if (IS_ERR(hw)) {
223160 rc = PTR_ERR(hw);
@@ -231,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm, · 7 unmodified lines
231168 struct dpu_hw_sspp *hw;
232169 const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
233170
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);
235172 if (IS_ERR(hw)) {
236173 rc = PTR_ERR(hw);
237174 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
240177 rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
241178 }
242179
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+
243192 return 0;
244193
245194 fail:
246− dpu_rm_destroy(rm);
247−
248195 return rc ? rc : -EFAULT;
249196 }
250197
@@ -488,6 +435,26 @@ static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, · 237 unmodified lines
488435 return 0;
489436 }
490437
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+
491458 static int _dpu_rm_make_reservation(
492459 struct dpu_rm *rm,
493460 struct dpu_global_state *global_state,
@@ -513,6 +480,14 @@ static int _dpu_rm_make_reservation( · 19 unmodified lines
513480 if (ret)
514481 return ret;
515482
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+
516491 return ret;
517492 }
518493
@@ -523,9 +498,9 @@ static int _dpu_rm_populate_requirements( · 4 unmodified lines
523498 {
524499 reqs->topology = req_topology;
525500
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",
527502 reqs->topology.num_lm, reqs->topology.num_dsc,
528− reqs->topology.num_intf);
503+ reqs->topology.num_intf, reqs->topology.needs_cdm);
529504
530505 return 0;
531506 }
@@ -554,6 +529,7 @@ void dpu_rm_release(struct dpu_global_state *global_state, · 22 unmodified lines
554529 ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
555530 _dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
556531 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);
557533 }
558534
559535 int dpu_rm_reserve(
@@ -627,6 +603,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, · 67 unmodified lines
627603 hw_to_enc_id = global_state->dsc_to_enc_id;
628604 max_blks = ARRAY_SIZE(rm->dsc_blks);
629605 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;
630611 default:
631612 DPU_ERROR("blk type %d not managed by rm\n", type);
632613 return 0;
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h+5−8
@@ -22,6 +22,7 @@ struct dpu_global_state; · 21 unmodified lines
2222 * @hw_wb: array of wb hardware resources
2323 * @dspp_blks: array of dspp hardware resources
2424 * @hw_sspp: array of sspp hardware resources
25+ * @cdm_blk: cdm hardware resource
2526 */
2627 struct dpu_rm {
2728 struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -33,29 +34,25 @@ struct dpu_rm { · 5 unmodified lines
3334 struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
3435 struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
3536 struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
37+ struct dpu_hw_blk *cdm_blk;
3638 };
3739
3840 /**
3941 * dpu_rm_init - Read hardware catalog and create reservation tracking objects
4042 * for all HW blocks.
43+ * @dev: Corresponding device for devres management
4144 * @rm: DPU Resource Manager handle
4245 * @cat: Pointer to hardware catalog
4346 * @mdss_data: Pointer to MDSS / UBWC configuration
4447 * @mmio: mapped register io address of MDP
4548 * @Return: 0 on Success otherwise -ERROR
4649 */
47−int dpu_rm_init(struct dpu_rm *rm,
50+int dpu_rm_init(struct drm_device *dev,
51+ struct dpu_rm *rm,
4852 const struct dpu_mdss_cfg *cat,
4953 const struct msm_mdss_data *mdss_data,
5054 void __iomem *mmio);
5155
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−
5956 /**
6057 * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze
6158 * the use connections and user requirements, specified through related
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c+26−16
@@ -6,6 +6,7 @@ · 5 unmodified lines
66
77 #include <drm/drm_crtc.h>
88 #include <drm/drm_flip_work.h>
9+#include <drm/drm_managed.h>
910 #include <drm/drm_mode.h>
1011 #include <drm/drm_probe_helper.h>
1112 #include <drm/drm_vblank.h>
@@ -123,16 +124,6 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) · 111 unmodified lines
123124 drm_gem_object_put(val);
124125 }
125126
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−
136127 /* statically (for now) map planes to mixer stage (z-order): */
137128 static const int idxs[] = {
138129 [VG1] = 1,
@@ -269,6 +260,7 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, · 130 unmodified lines
269260 {
270261 struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
271262 struct mdp4_kms *mdp4_kms = get_kms(crtc);
263+ unsigned long flags;
272264
273265 DBG("%s", mdp4_crtc->name);
274266
@@ -281,6 +273,14 @@ static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc, · 6 unmodified lines
281273 mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err);
282274 mdp4_disable(mdp4_kms);
283275
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+
284284 mdp4_crtc->enabled = false;
285285 }
286286
@@ -475,7 +475,6 @@ static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) · 188 unmodified lines
475475
476476 static const struct drm_crtc_funcs mdp4_crtc_funcs = {
477477 .set_config = drm_atomic_helper_set_config,
478− .destroy = mdp4_crtc_destroy,
479478 .page_flip = drm_atomic_helper_page_flip,
480479 .cursor_set = mdp4_crtc_cursor_set,
481480 .cursor_move = mdp4_crtc_cursor_move,
@@ -616,6 +615,13 @@ static const char *dma_names[] = { · 134 unmodified lines
616615 "DMA_P", "DMA_S", "DMA_E",
617616 };
618617
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+
619625 /* initialize crtc */
620626 struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
621627 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
623629 {
624630 struct drm_crtc *crtc = NULL;
625631 struct mdp4_crtc *mdp4_crtc;
632+ int ret;
626633
627− mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL);
628− if (!mdp4_crtc)
629− return ERR_PTR(-ENOMEM);
634+ mdp4_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp4_crtc, base,
635+ plane, NULL,
636+ &mdp4_crtc_funcs, NULL);
637+ if (IS_ERR(mdp4_crtc))
638+ return ERR_CAST(mdp4_crtc);
630639
631640 crtc = &mdp4_crtc->base;
632641
@@ -648,9 +657,10 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, · 15 unmodified lines
648657
649658 drm_flip_work_init(&mdp4_crtc->unref_cursor_work,
650659 "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);
651663
652− drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp4_crtc_funcs,
653− NULL);
654664 drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
655665
656666 return crtc;
drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c+5−27
@@ -26,18 +26,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 25 unmodified lines
2626 return to_mdp4_kms(to_mdp_kms(priv->kms));
2727 }
2828
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−
4129 static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder,
4230 struct drm_display_mode *mode,
4331 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
148136 /* initialize encoder */
149137 struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
150138 {
151− struct drm_encoder *encoder = NULL;
139+ struct drm_encoder *encoder;
152140 struct mdp4_dsi_encoder *mdp4_dsi_encoder;
153− int ret;
154141
155− mdp4_dsi_encoder = kzalloc(sizeof(*mdp4_dsi_encoder), GFP_KERNEL);
156− if (!mdp4_dsi_encoder) {
157− ret = -ENOMEM;
158− goto fail;
159− }
142+ mdp4_dsi_encoder = drmm_encoder_alloc(dev, struct mdp4_dsi_encoder, base,
143+ NULL, DRM_MODE_ENCODER_DSI, NULL);
144+ if (IS_ERR(mdp4_dsi_encoder))
145+ return ERR_CAST(mdp4_dsi_encoder);
160146
161147 encoder = &mdp4_dsi_encoder->base;
162148
163− drm_encoder_init(dev, encoder, &mdp4_dsi_encoder_funcs,
164− DRM_MODE_ENCODER_DSI, NULL);
165149 drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs);
166150
167151 return encoder;
168−
169−fail:
170− if (encoder)
171− mdp4_dsi_encoder_destroy(encoder);
172−
173− return ERR_PTR(ret);
174152 }
175153 #endif /* CONFIG_DRM_MSM_DSI */
drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c+7−30
@@ -25,17 +25,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 24 unmodified lines
2525 return to_mdp4_kms(to_mdp_kms(priv->kms));
2626 }
2727
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−
3928 static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
4029 struct drm_display_mode *mode,
4130 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
173162 /* initialize encoder */
174163 struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev)
175164 {
176− struct drm_encoder *encoder = NULL;
165+ struct drm_encoder *encoder;
177166 struct mdp4_dtv_encoder *mdp4_dtv_encoder;
178− int ret;
179167
180− mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL);
181− if (!mdp4_dtv_encoder) {
182− ret = -ENOMEM;
183− goto fail;
184− }
168+ mdp4_dtv_encoder = drmm_encoder_alloc(dev, struct mdp4_dtv_encoder, base,
169+ NULL, DRM_MODE_ENCODER_TMDS, NULL);
170+ if (IS_ERR(mdp4_dtv_encoder))
171+ return ERR_CAST(mdp4_dtv_encoder);
185172
186173 encoder = &mdp4_dtv_encoder->base;
187174
188− drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs,
189− DRM_MODE_ENCODER_TMDS, NULL);
190175 drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs);
191176
192177 mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk");
193178 if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) {
194179 DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n");
195− ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk);
196− goto fail;
180+ return ERR_CAST(mdp4_dtv_encoder->hdmi_clk);
197181 }
198182
199183 mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk");
200184 if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) {
201185 DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n");
202− ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk);
203− goto fail;
186+ return ERR_CAST(mdp4_dtv_encoder->mdp_clk);
204187 }
205188
206189 return encoder;
207−
208−fail:
209− if (encoder)
210− mdp4_dtv_encoder_destroy(encoder);
211−
212− return ERR_PTR(ret);
213190 }
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c+22−65
@@ -18,7 +18,7 @@ struct mdp4_lcdc_encoder { · 17 unmodified lines
1818 struct drm_panel *panel;
1919 struct clk *lcdc_clk;
2020 unsigned long int pixclock;
21− struct regulator *regs[3];
21+ struct regulator_bulk_data regs[3];
2222 bool enabled;
2323 uint32_t bsc;
2424 };
@@ -30,18 +30,6 @@ static struct mdp4_kms *get_kms(struct drm_encoder *encoder) · 5 unmodified lines
3030 return to_mdp4_kms(to_mdp_kms(priv->kms));
3131 }
3232
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−
4533 /* this should probably be a helper: */
4634 static struct drm_connector *get_connector(struct drm_encoder *encoder)
4735 {
@@ -271,12 +259,10 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder, · 223 unmodified lines
271259
272260 static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
273261 {
274− struct drm_device *dev = encoder->dev;
275262 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
276263 to_mdp4_lcdc_encoder(encoder);
277264 struct mdp4_kms *mdp4_kms = get_kms(encoder);
278265 struct drm_panel *panel;
279− int i, ret;
280266
281267 if (WARN_ON(!mdp4_lcdc_encoder->enabled))
282268 return;
@@ -301,11 +287,8 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) · 18 unmodified lines
301287
302288 clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk);
303289
304− for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
305− ret = regulator_disable(mdp4_lcdc_encoder->regs[i]);
306− if (ret)
307− DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret);
308− }
290+ regulator_bulk_disable(ARRAY_SIZE(mdp4_lcdc_encoder->regs),
291+ mdp4_lcdc_encoder->regs);
309292
310293 mdp4_lcdc_encoder->enabled = false;
311294 }
@@ -319,7 +302,7 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · 7 unmodified lines
319302 struct mdp4_kms *mdp4_kms = get_kms(encoder);
320303 struct drm_panel *panel;
321304 uint32_t config;
322− int i, ret;
305+ int ret;
323306
324307 if (WARN_ON(mdp4_lcdc_encoder->enabled))
325308 return;
@@ -339,11 +322,10 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · 13 unmodified lines
339322 mdp4_crtc_set_config(encoder->crtc, config);
340323 mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
341324
342− for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) {
343− ret = regulator_enable(mdp4_lcdc_encoder->regs[i]);
344− if (ret)
345− DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret);
346− }
325+ ret = regulator_bulk_enable(ARRAY_SIZE(mdp4_lcdc_encoder->regs),
326+ mdp4_lcdc_encoder->regs);
327+ if (ret)
328+ DRM_DEV_ERROR(dev->dev, "failed to enable regulators: %d\n", ret);
347329
348330 DBG("setting lcdc_clk=%lu", pc);
349331 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
383365 struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
384366 struct device_node *panel_node)
385367 {
386− struct drm_encoder *encoder = NULL;
368+ struct drm_encoder *encoder;
387369 struct mdp4_lcdc_encoder *mdp4_lcdc_encoder;
388− struct regulator *reg;
389370 int ret;
390371
391− mdp4_lcdc_encoder = kzalloc(sizeof(*mdp4_lcdc_encoder), GFP_KERNEL);
392− if (!mdp4_lcdc_encoder) {
393− ret = -ENOMEM;
394− goto fail;
395− }
372+ mdp4_lcdc_encoder = drmm_encoder_alloc(dev, struct mdp4_lcdc_encoder, base,
373+ NULL, DRM_MODE_ENCODER_LVDS, NULL);
374+ if (IS_ERR(mdp4_lcdc_encoder))
375+ return ERR_CAST(mdp4_lcdc_encoder);
396376
397377 mdp4_lcdc_encoder->panel_node = panel_node;
398378
399379 encoder = &mdp4_lcdc_encoder->base;
400380
401− drm_encoder_init(dev, encoder, &mdp4_lcdc_encoder_funcs,
402− DRM_MODE_ENCODER_LVDS, NULL);
403381 drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs);
404382
405383 /* TODO: do we need different pll in other cases? */
406384 mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev);
407385 if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {
408386 DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");
409− ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk);
410− goto fail;
387+ return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk);
411388 }
412389
413390 /* TODO: different regulators in other cases? */
414− reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v");
415− if (IS_ERR(reg)) {
416− ret = PTR_ERR(reg);
417− DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret);
418− goto fail;
419− }
420− mdp4_lcdc_encoder->regs[0] = reg;
421−
422− reg = devm_regulator_get(dev->dev, "lvds-pll-vdda");
423− if (IS_ERR(reg)) {
424− ret = PTR_ERR(reg);
425− DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret);
426− goto fail;
427− }
428− mdp4_lcdc_encoder->regs[1] = reg;
391+ mdp4_lcdc_encoder->regs[0].supply = "lvds-vccs-3p3v";
392+ mdp4_lcdc_encoder->regs[1].supply = "lvds-vccs-3p3v";
393+ mdp4_lcdc_encoder->regs[2].supply = "lvds-vdda";
429394
430− reg = devm_regulator_get(dev->dev, "lvds-vdda");
431− if (IS_ERR(reg)) {
432− ret = PTR_ERR(reg);
433− DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret);
434− goto fail;
435− }
436− mdp4_lcdc_encoder->regs[2] = reg;
395+ ret = devm_regulator_bulk_get(dev->dev,
396+ ARRAY_SIZE(mdp4_lcdc_encoder->regs),
397+ mdp4_lcdc_encoder->regs);
398+ if (ret)
399+ return ERR_PTR(ret);
437400
438401 return encoder;
439−
440−fail:
441− if (encoder)
442− mdp4_lcdc_encoder_destroy(encoder);
443−
444− return ERR_PTR(ret);
445402 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c+5−19
@@ -1350,23 +1350,17 @@ int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler) · 1349 unmodified lines
13501350 return cfg_handler->revision;
13511351 }
13521352
1353−void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_handler)
1354−{
1355− kfree(cfg_handler);
1356−}
1357−
13581353 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
13591354 uint32_t major, uint32_t minor)
13601355 {
13611356 struct drm_device *dev = mdp5_kms->dev;
13621357 struct mdp5_cfg_handler *cfg_handler;
13631358 const struct mdp5_cfg_handler *cfg_handlers;
1364− int i, ret = 0, num_handlers;
1359+ int i, num_handlers;
13651360
1366− cfg_handler = kzalloc(sizeof(*cfg_handler), GFP_KERNEL);
1361+ cfg_handler = devm_kzalloc(dev->dev, sizeof(*cfg_handler), GFP_KERNEL);
13671362 if (unlikely(!cfg_handler)) {
1368− ret = -ENOMEM;
1369− goto fail;
1363+ return ERR_PTR(-ENOMEM);
13701364 }
13711365
13721366 switch (major) {
@@ -1381,8 +1375,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 8 unmodified lines
13811375 default:
13821376 DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n",
13831377 major, minor);
1384− ret = -ENXIO;
1385− goto fail;
1378+ return ERR_PTR(-ENXIO);
13861379 }
13871380
13881381 /* 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
13961389 if (unlikely(!mdp5_cfg)) {
13971390 DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
13981391 major, minor);
1399− ret = -ENXIO;
1400− goto fail;
1392+ return ERR_PTR(-ENXIO);
14011393 }
14021394
14031395 cfg_handler->revision = minor;
@@ -1406,10 +1398,4 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, · 2 unmodified lines
14061398 DBG("MDP5: %s hw config selected", mdp5_cfg->name);
14071399
14081400 return cfg_handler;
1409−
1410−fail:
1411− if (cfg_handler)
1412− mdp5_cfg_destroy(cfg_handler);
1413−
1414− return ERR_PTR(ret);
14151401 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h+0−1
@@ -121,6 +121,5 @@ int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd); · 120 unmodified lines
121121
122122 struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
123123 uint32_t major, uint32_t minor);
124−void mdp5_cfg_destroy(struct mdp5_cfg_handler *cfg_hnd);
125124
126125 #endif /* __MDP5_CFG_H__ */
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c+15−15
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include <drm/drm_crtc.h>
1414 #include <drm/drm_flip_work.h>
1515 #include <drm/drm_fourcc.h>
16+#include <drm/drm_managed.h>
1617 #include <drm/drm_probe_helper.h>
1718 #include <drm/drm_vblank.h>
1819
@@ -172,14 +173,11 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) · 153 unmodified lines
172173 drm_gem_object_put(val);
173174 }
174175
175−static void mdp5_crtc_destroy(struct drm_crtc *crtc)
176+static void mdp5_crtc_flip_cleanup(struct drm_device *dev, void *ptr)
176177 {
177− struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
178+ struct mdp5_crtc *mdp5_crtc = ptr;
178179
179− drm_crtc_cleanup(crtc);
180180 drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work);
181−
182− kfree(mdp5_crtc);
183181 }
184182
185183 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
11471145
11481146 static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
11491147 .set_config = drm_atomic_helper_set_config,
1150− .destroy = mdp5_crtc_destroy,
11511148 .page_flip = drm_atomic_helper_page_flip,
11521149 .reset = mdp5_crtc_reset,
11531150 .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
11611158
11621159 static const struct drm_crtc_funcs mdp5_crtc_funcs = {
11631160 .set_config = drm_atomic_helper_set_config,
1164− .destroy = mdp5_crtc_destroy,
11651161 .page_flip = drm_atomic_helper_page_flip,
11661162 .reset = mdp5_crtc_reset,
11671163 .atomic_duplicate_state = mdp5_crtc_duplicate_state,
@@ -1327,10 +1323,16 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, · 159 unmodified lines
13271323 {
13281324 struct drm_crtc *crtc = NULL;
13291325 struct mdp5_crtc *mdp5_crtc;
1326+ int ret;
13301327
1331− mdp5_crtc = kzalloc(sizeof(*mdp5_crtc), GFP_KERNEL);
1332− if (!mdp5_crtc)
1333− return ERR_PTR(-ENOMEM);
1328+ mdp5_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp5_crtc, base,
1329+ plane, cursor_plane,
1330+ cursor_plane ?
1331+ &mdp5_crtc_no_lm_cursor_funcs :
1332+ &mdp5_crtc_funcs,
1333+ NULL);
1334+ if (IS_ERR(mdp5_crtc))
1335+ return ERR_CAST(mdp5_crtc);
13341336
13351337 crtc = &mdp5_crtc->base;
13361338
@@ -1346,13 +1348,11 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, · 9 unmodified lines
13461348
13471349 mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true;
13481350
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−
13541351 drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
13551352 "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);
13561356
13571357 drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs);
13581358
drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c+4−17
@@ -681,11 +681,6 @@ void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctl_mgr) · 680 unmodified lines
681681 }
682682 }
683683
684−void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctl_mgr)
685−{
686− kfree(ctl_mgr);
687−}
688−
689684 struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev,
690685 void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd)
691686 {
@@ -697,18 +692,16 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 5 unmodified lines
697692 unsigned long flags;
698693 int c, ret;
699694
700− ctl_mgr = kzalloc(sizeof(*ctl_mgr), GFP_KERNEL);
695+ ctl_mgr = devm_kzalloc(dev->dev, sizeof(*ctl_mgr), GFP_KERNEL);
701696 if (!ctl_mgr) {
702697 DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n");
703− ret = -ENOMEM;
704− goto fail;
698+ return ERR_PTR(-ENOMEM);
705699 }
706700
707701 if (WARN_ON(ctl_cfg->count > MAX_CTL)) {
708702 DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n",
709703 ctl_cfg->count);
710− ret = -ENOSPC;
711− goto fail;
704+ return ERR_PTR(-ENOSPC);
712705 }
713706
714707 /* initialize the CTL manager: */
@@ -727,7 +720,7 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 12 unmodified lines
727720 DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c);
728721 ret = -EINVAL;
729722 spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags);
730− goto fail;
723+ return ERR_PTR(ret);
731724 }
732725 ctl->ctlm = ctl_mgr;
733726 ctl->id = c;
@@ -755,10 +748,4 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, · 21 unmodified lines
755748 DBG("Pool of %d CTLs created.", ctl_mgr->nctl);
756749
757750 return ctl_mgr;
758−
759−fail:
760− if (ctl_mgr)
761− mdp5_ctlm_destroy(ctl_mgr);
762−
763− return ERR_PTR(ret);
764751 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.h+0−1
@@ -17,7 +17,6 @@ struct mdp5_ctl_manager; · 16 unmodified lines
1717 struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev,
1818 void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd);
1919 void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctlm);
20−void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm);
2120
2221 /*
2322 * CTL prototypes:
drivers/gpu/drm/msm/disp/mdp5/mdp5_encoder.c+4−25
@@ -16,17 +16,6 @@ static struct mdp5_kms *get_kms(struct drm_encoder *encoder) · 15 unmodified lines
1616 return to_mdp5_kms(to_mdp_kms(priv->kms));
1717 }
1818
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−
3019 static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
3120 struct drm_display_mode *mode,
3221 struct drm_display_mode *adjusted_mode)
@@ -342,13 +331,11 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, · 309 unmodified lines
342331 struct mdp5_encoder *mdp5_encoder;
343332 int enc_type = (intf->type == INTF_DSI) ?
344333 DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS;
345− int ret;
346334
347− mdp5_encoder = kzalloc(sizeof(*mdp5_encoder), GFP_KERNEL);
348− if (!mdp5_encoder) {
349− ret = -ENOMEM;
350− goto fail;
351− }
335+ mdp5_encoder = drmm_encoder_alloc(dev, struct mdp5_encoder, base,
336+ NULL, enc_type, NULL);
337+ if (IS_ERR(mdp5_encoder))
338+ return ERR_CAST(mdp5_encoder);
352339
353340 encoder = &mdp5_encoder->base;
354341 mdp5_encoder->ctl = ctl;
@@ -356,15 +343,7 @@ struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, · 1 unmodified line
356343
357344 spin_lock_init(&mdp5_encoder->intf_lock);
358345
359− drm_encoder_init(dev, encoder, &mdp5_encoder_funcs, enc_type, NULL);
360−
361346 drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs);
362347
363348 return encoder;
364−
365−fail:
366− if (encoder)
367− mdp5_encoder_destroy(encoder);
368−
369− return ERR_PTR(ret);
370349 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c+3−22
@@ -209,13 +209,6 @@ static void mdp5_kms_destroy(struct msm_kms *kms) · 208 unmodified lines
209209 {
210210 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
211211 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]);
219212
220213 if (aspace) {
221214 aspace->mmu->funcs->detach(aspace->mmu);
@@ -623,18 +616,6 @@ fail: · 401 unmodified lines
623616
624617 static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
625618 {
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−
638619 if (mdp5_kms->rpm_enabled)
639620 pm_runtime_disable(&mdp5_kms->pdev->dev);
640621
@@ -652,7 +633,7 @@ static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt, · 11 unmodified lines
652633 for (i = 0; i < cnt; i++) {
653634 struct mdp5_hw_pipe *hwpipe;
654635
655− hwpipe = mdp5_pipe_init(pipes[i], offsets[i], caps);
636+ hwpipe = mdp5_pipe_init(dev, pipes[i], offsets[i], caps);
656637 if (IS_ERR(hwpipe)) {
657638 ret = PTR_ERR(hwpipe);
658639 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
724705 for (i = 0; i < hw_cfg->lm.count; i++) {
725706 struct mdp5_hw_mixer *mixer;
726707
727− mixer = mdp5_mixer_init(&hw_cfg->lm.instances[i]);
708+ mixer = mdp5_mixer_init(dev, &hw_cfg->lm.instances[i]);
728709 if (IS_ERR(mixer)) {
729710 ret = PTR_ERR(mixer);
730711 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
755736 if (intf_types[i] == INTF_DISABLED)
756737 continue;
757738
758− intf = kzalloc(sizeof(*intf), GFP_KERNEL);
739+ intf = devm_kzalloc(dev->dev, sizeof(*intf), GFP_KERNEL);
759740 if (!intf) {
760741 DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i);
761742 return -ENOMEM;
drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c+3−7
@@ -140,20 +140,16 @@ int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) · 139 unmodified lines
140140 return 0;
141141 }
142142
143−void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer)
144−{
145− kfree(mixer);
146−}
147−
148143 static const char * const mixer_names[] = {
149144 "LM0", "LM1", "LM2", "LM3", "LM4", "LM5",
150145 };
151146
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)
153149 {
154150 struct mdp5_hw_mixer *mixer;
155151
156− mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
152+ mixer = devm_kzalloc(dev->dev, sizeof(*mixer), GFP_KERNEL);
157153 if (!mixer)
158154 return ERR_PTR(-ENOMEM);
159155
drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h+2−2
@@ -25,8 +25,8 @@ struct mdp5_hw_mixer_state { · 24 unmodified lines
2525 struct drm_crtc *hwmixer_to_crtc[8];
2626 };
2727
28−struct mdp5_hw_mixer *mdp5_mixer_init(const struct mdp5_lm_instance *lm);
29−void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm);
28+struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev,
29+ const struct mdp5_lm_instance *lm);
3030 int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
3131 uint32_t caps, struct mdp5_hw_mixer **mixer,
3232 struct mdp5_hw_mixer **r_mixer);
drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c+3−7
@@ -151,17 +151,13 @@ int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) · 150 unmodified lines
151151 return 0;
152152 }
153153
154−void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe)
155−{
156− kfree(hwpipe);
157−}
158−
159−struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe,
154+struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev,
155+ enum mdp5_pipe pipe,
160156 uint32_t reg_offset, uint32_t caps)
161157 {
162158 struct mdp5_hw_pipe *hwpipe;
163159
164− hwpipe = kzalloc(sizeof(*hwpipe), GFP_KERNEL);
160+ hwpipe = devm_kzalloc(dev->dev, sizeof(*hwpipe), GFP_KERNEL);
165161 if (!hwpipe)
166162 return ERR_PTR(-ENOMEM);
167163
drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h+2−2
@@ -39,8 +39,8 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, · 38 unmodified lines
3939 struct mdp5_hw_pipe **r_hwpipe);
4040 int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
4141
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,
4344 uint32_t reg_offset, uint32_t caps);
44−void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe);
4545
4646 #endif /* __MDP5_PIPE_H__ */
drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c+4−15
@@ -370,23 +370,17 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p) · 369 unmodified lines
370370 drm_modeset_unlock(&mdp5_kms->glob_state_lock);
371371 }
372372
373−void mdp5_smp_destroy(struct mdp5_smp *smp)
374−{
375− kfree(smp);
376−}
377373
378374 struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_block *cfg)
379375 {
376+ struct drm_device *dev = mdp5_kms->dev;
380377 struct mdp5_smp_state *state;
381378 struct mdp5_global_state *global_state;
382379 struct mdp5_smp *smp;
383− int ret;
384380
385− smp = kzalloc(sizeof(*smp), GFP_KERNEL);
386− if (unlikely(!smp)) {
387− ret = -ENOMEM;
388− goto fail;
389− }
381+ smp = devm_kzalloc(dev->dev, sizeof(*smp), GFP_KERNEL);
382+ if (unlikely(!smp))
383+ return ERR_PTR(-ENOMEM);
390384
391385 smp->dev = mdp5_kms->dev;
392386 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
400394 memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved));
401395
402396 return smp;
403−fail:
404− if (smp)
405− mdp5_smp_destroy(smp);
406−
407− return ERR_PTR(ret);
408397 }
drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.h+0−1
@@ -68,7 +68,6 @@ struct mdp5_smp; · 67 unmodified lines
6868
6969 struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms,
7070 const struct mdp5_smp_block *cfg);
71−void mdp5_smp_destroy(struct mdp5_smp *smp);
7271
7372 void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p);
7473
drivers/gpu/drm/msm/dp/dp_aux.c+32−7
@@ -291,6 +291,10 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 290 unmodified lines
291291 return -EINVAL;
292292 }
293293
294+ ret = pm_runtime_resume_and_get(dp_aux->dev);
295+ if (ret)
296+ return ret;
297+
294298 mutex_lock(&aux->mutex);
295299 if (!aux->initted) {
296300 ret = -EIO;
@@ -364,6 +368,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, · 67 unmodified lines
364368
365369 exit:
366370 mutex_unlock(&aux->mutex);
371+ pm_runtime_put_sync(dp_aux->dev);
367372
368373 return ret;
369374 }
@@ -474,7 +479,6 @@ void dp_aux_deinit(struct drm_dp_aux *dp_aux) · 104 unmodified lines
474479
475480 int dp_aux_register(struct drm_dp_aux *dp_aux)
476481 {
477− struct dp_aux_private *aux;
478482 int ret;
479483
480484 if (!dp_aux) {
@@ -482,12 +486,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux) · 1 unmodified line
482486 return -EINVAL;
483487 }
484488
485− aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
486−
487− aux->dp_aux.name = "dpu_dp_aux";
488− aux->dp_aux.dev = aux->dev;
489− aux->dp_aux.transfer = dp_aux_transfer;
490− ret = drm_dp_aux_register(&aux->dp_aux);
489+ ret = drm_dp_aux_register(dp_aux);
491490 if (ret) {
492491 DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
493492 ret);
@@ -502,6 +501,21 @@ void dp_aux_unregister(struct drm_dp_aux *dp_aux) · 8 unmodified lines
502501 drm_dp_aux_unregister(dp_aux);
503502 }
504503
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+
505519 struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
506520 bool is_edp)
507521 {
@@ -525,6 +539,17 @@ struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog, · 17 unmodified lines
525539 aux->catalog = catalog;
526540 aux->retry_cnt = 0;
527541
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+
528553 return &aux->dp_aux;
529554 }
530555
drivers/gpu/drm/msm/dp/dp_debug.c+16−53
@@ -19,13 +19,9 @@ · 18 unmodified lines
1919 #define DEBUG_NAME "msm_dp"
2020
2121 struct dp_debug_private {
22− struct dentry *root;
23−
2422 struct dp_link *link;
2523 struct dp_panel *panel;
2624 struct drm_connector *connector;
27− struct device *dev;
28− struct drm_device *drm_dev;
2925
3026 struct dp_debug dp_debug;
3127 };
@@ -204,35 +200,33 @@ static const struct file_operations test_active_fops = { · 172 unmodified lines
204200 .write = dp_test_active_write
205201 };
206202
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)
208204 {
209− char path[64];
210205 struct dp_debug_private *debug = container_of(dp_debug,
211206 struct dp_debug_private, dp_debug);
212207
213− snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name);
214−
215− debug->root = debugfs_create_dir(path, minor->debugfs_root);
216−
217− debugfs_create_file("dp_debug", 0444, debug->root,
208+ debugfs_create_file("dp_debug", 0444, root,
218209 debug, &dp_debug_fops);
219210
220− debugfs_create_file("msm_dp_test_active", 0444,
221− debug->root,
222− debug, &test_active_fops);
211+ if (!is_edp) {
212+ debugfs_create_file("msm_dp_test_active", 0444,
213+ root,
214+ debug, &test_active_fops);
223215
224− debugfs_create_file("msm_dp_test_data", 0444,
225− debug->root,
226− debug, &dp_test_data_fops);
216+ debugfs_create_file("msm_dp_test_data", 0444,
217+ root,
218+ debug, &dp_test_data_fops);
227219
228− debugfs_create_file("msm_dp_test_type", 0444,
229− debug->root,
230− debug, &dp_test_type_fops);
220+ debugfs_create_file("msm_dp_test_type", 0444,
221+ root,
222+ debug, &dp_test_type_fops);
223+ }
231224 }
232225
233226 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
234227 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)
236230 {
237231 struct dp_debug_private *debug;
238232 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
253247 debug->dp_debug.debug_en = false;
254248 debug->link = link;
255249 debug->panel = panel;
256− debug->dev = dev;
257− debug->drm_dev = minor->dev;
258− debug->connector = connector;
259250
260251 dp_debug = &debug->dp_debug;
261252 dp_debug->vdisplay = 0;
262253 dp_debug->hdisplay = 0;
263254 dp_debug->vrefresh = 0;
264255
265− dp_debug_init(dp_debug, minor);
256+ dp_debug_init(dp_debug, root, is_edp);
266257
267258 return dp_debug;
268259 error:
269260 return ERR_PTR(rc);
270261 }
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−}
drivers/gpu/drm/msm/dp/dp_debug.h+7−16
@@ -34,7 +34,8 @@ struct dp_debug { · 33 unmodified lines
3434 * @panel: instance of panel module
3535 * @link: instance of link module
3636 * @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
3839 * return: pointer to allocated debug module data
3940 *
4041 * This function sets up the debug module and provides a way
@@ -43,31 +44,21 @@ struct dp_debug { · 2 unmodified lines
4344 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
4445 struct dp_link *link,
4546 struct drm_connector *connector,
46− struct drm_minor *minor);
47−
48−/**
49− * dp_debug_put()
50− *
51− * Cleans up dp_debug instance
52− *
53− * @dp_debug: instance of dp_debug
54− */
55−void dp_debug_put(struct dp_debug *dp_debug);
47+ struct dentry *root,
48+ bool is_edp);
5649
5750 #else
5851
5952 static inline
6053 struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
6154 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)
6358 {
6459 return ERR_PTR(-EINVAL);
6560 }
6661
67−static inline void dp_debug_put(struct dp_debug *dp_debug)
68−{
69−}
70−
7162 #endif /* defined(CONFIG_DEBUG_FS) */
7263
7364 #endif /* _DP_DEBUG_H_ */
drivers/gpu/drm/msm/dp/dp_display.c+146−223
@@ -49,13 +49,11 @@ enum { · 48 unmodified lines
4949 ST_CONNECTED,
5050 ST_DISCONNECT_PENDING,
5151 ST_DISPLAY_OFF,
52− ST_SUSPENDED,
5352 };
5453
5554 enum {
5655 EV_NO_EVENT,
5756 /* hpd events */
58− EV_HPD_INIT_SETUP,
5957 EV_HPD_PLUG_INT,
6058 EV_IRQ_HPD_INT,
6159 EV_HPD_UNPLUG_INT,
@@ -170,6 +168,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = { · 108 unmodified lines
170168 {}
171169 };
172170
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+
173176 static const struct of_device_id dp_dt_match[] = {
174177 { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
175178 { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
@@ -180,6 +183,7 @@ static const struct of_device_id dp_dt_match[] = { · 4 unmodified lines
180183 { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
181184 { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
182185 { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
186+ { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },
183187 {}
184188 };
185189
@@ -275,11 +279,6 @@ static int dp_display_bind(struct device *dev, struct device *master, · 89 unmodified lines
275279 dp->dp_display.drm_dev = drm;
276280 priv->dp[dp->id] = &dp->dp_display;
277281
278− rc = dp->parser->parse(dp->parser);
279− if (rc) {
280− DRM_ERROR("device tree parsing failed\n");
281− goto end;
282− }
283282
284283
285284 dp->drm_dev = drm;
@@ -290,11 +289,6 @@ static int dp_display_bind(struct device *dev, struct device *master, · 4 unmodified lines
290289 goto end;
291290 }
292291
293− rc = dp_power_client_init(dp->power);
294− if (rc) {
295− DRM_ERROR("Power client create failed\n");
296− goto end;
297− }
298292
299293 rc = dp_register_audio_driver(dev, dp->audio);
300294 if (rc) {
@@ -319,15 +313,10 @@ static void dp_display_unbind(struct device *dev, struct device *master, · 18 unmodified lines
319313 struct dp_display_private *dp = dev_get_dp_display_private(dev);
320314 struct msm_drm_private *priv = dev_get_drvdata(master);
321315
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−
326316 kthread_stop(dp->ev_tsk);
327317
328318 of_dp_aux_depopulate_bus(dp->aux);
329319
330− dp_power_client_deinit(dp->power);
331320 dp_unregister_audio_driver(dev, dp->audio);
332321 dp_aux_unregister(dp->aux);
333322 dp->drm_dev = NULL;
@@ -340,27 +329,10 @@ static const struct component_ops dp_display_comp_ops = { · 6 unmodified lines
340329 .unbind = dp_display_unbind,
341330 };
342331
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−
355332 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
356333 bool hpd)
357334 {
358− if ((hpd && dp->dp_display.is_connected) ||
359− (!hpd && !dp->dp_display.is_connected)) {
360− drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
361− (hpd ? "on" : "off"));
362− return 0;
363− }
335+ struct drm_bridge *bridge = dp->dp_display.bridge;
364336
365337 /* reset video pattern flag on disconnect */
366338 if (!hpd) {
@@ -372,11 +344,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, · 5 unmodified lines
372344 dp->panel->downstream_ports);
373345 }
374346
375− dp->dp_display.is_connected = hpd;
347+ dp->dp_display.link_ready = hpd;
376348
377349 drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
378350 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);
380352
381353 return 0;
382354 }
@@ -575,6 +547,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 192 unmodified lines
575547 {
576548 u32 state;
577549 int ret;
550+ struct platform_device *pdev = dp->dp_display.pdev;
578551
579552 mutex_lock(&dp->event_mutex);
580553
@@ -582,7 +555,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 1 unmodified line
582555 drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
583556 dp->dp_display.connector_type, state);
584557
585− if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
558+ if (state == ST_DISPLAY_OFF) {
586559 mutex_unlock(&dp->event_mutex);
587560 return 0;
588561 }
@@ -599,7 +572,14 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 10 unmodified lines
599572 return 0;
600573 }
601574
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);
603583 if (ret) { /* link train failed */
604584 dp->hpd_state = ST_DISCONNECTED;
605585 } else {
@@ -631,6 +611,7 @@ static void dp_display_handle_plugged_change(struct msm_dp *dp_display, · 25 unmodified lines
631611 static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
632612 {
633613 u32 state;
614+ struct platform_device *pdev = dp->dp_display.pdev;
634615
635616 mutex_lock(&dp->event_mutex);
636617
@@ -681,6 +662,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) · 44 unmodified lines
681662 dp->dp_display.connector_type, state);
682663
683664 /* uevent will complete disconnection part */
665+ pm_runtime_put_sync(&pdev->dev);
684666 mutex_unlock(&dp->event_mutex);
685667 return 0;
686668 }
@@ -696,7 +678,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 9 unmodified lines
696678 drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
697679 dp->dp_display.connector_type, state);
698680
699− if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
681+ if (state == ST_DISPLAY_OFF) {
700682 mutex_unlock(&dp->event_mutex);
701683 return 0;
702684 }
@@ -720,7 +702,6 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data) · 17 unmodified lines
720702
721703 static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
722704 {
723− dp_debug_put(dp->debug);
724705 dp_audio_put(dp->audio);
725706 dp_panel_put(dp->panel);
726707 dp_aux_put(dp->aux);
@@ -918,7 +899,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display, · 191 unmodified lines
918899
919900 dp_display->plugged_cb = fn;
920901 dp_display->codec_dev = codec_dev;
921− plugged = dp_display->is_connected;
902+ plugged = dp_display->link_ready;
922903 dp_display_handle_plugged_change(dp_display, plugged);
923904
924905 return 0;
@@ -1108,9 +1089,6 @@ static int hpd_event_thread(void *data) · 183 unmodified lines
11081089 spin_unlock_irqrestore(&dp_priv->event_lock, flag);
11091090
11101091 switch (todo->event_id) {
1111− case EV_HPD_INIT_SETUP:
1112− dp_display_host_init(dp_priv);
1113− break;
11141092 case EV_HPD_PLUG_INT:
11151093 dp_hpd_plug_handle(dp_priv, todo->data);
11161094 break;
@@ -1189,27 +1167,21 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) · 72 unmodified lines
11891167 return ret;
11901168 }
11911169
1192−int dp_display_request_irq(struct msm_dp *dp_display)
1170+static int dp_display_request_irq(struct dp_display_private *dp)
11931171 {
11941172 int rc = 0;
1195− struct dp_display_private *dp;
1196−
1197− if (!dp_display) {
1198− DRM_ERROR("invalid input\n");
1199− return -EINVAL;
1200− }
1173+ struct platform_device *pdev = dp->dp_display.pdev;
12011174
1202− dp = container_of(dp_display, struct dp_display_private, dp_display);
1203−
1204− dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0);
1205− if (!dp->irq) {
1175+ dp->irq = platform_get_irq(pdev, 0);
1176+ if (dp->irq < 0) {
12061177 DRM_ERROR("failed to get irq\n");
1207− return -EINVAL;
1178+ return dp->irq;
12081179 }
12091180
1210− rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
1211− dp_display_irq_handler,
1212− IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
1181+ rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler,
1182+ IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,
1183+ "dp_display_isr", dp);
1184+
12131185 if (rc < 0) {
12141186 DRM_ERROR("failed to request IRQ%u: %d\n",
12151187 dp->irq, rc);
@@ -1238,6 +1210,29 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde · 22 unmodified lines
12381210 return NULL;
12391211 }
12401212
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+
12411236 static int dp_display_probe(struct platform_device *pdev)
12421237 {
12431238 int rc = 0;
@@ -1271,6 +1266,18 @@ static int dp_display_probe(struct platform_device *pdev) · 27 unmodified lines
12711266 return -EPROBE_DEFER;
12721267 }
12731268
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+
12741281 /* setup event q */
12751282 mutex_init(&dp->event_mutex);
12761283 init_waitqueue_head(&dp->event_q);
@@ -1283,13 +1290,31 @@ static int dp_display_probe(struct platform_device *pdev) · 6 unmodified lines
12831290
12841291 platform_set_drvdata(pdev, &dp->dp_display);
12851292
1286− rc = component_add(&pdev->dev, &dp_display_comp_ops);
1287− if (rc) {
1288− DRM_ERROR("component add failed, rc=%d\n", rc);
1289− dp_display_deinit_sub_modules(dp);
1293+ rc = devm_pm_runtime_enable(&pdev->dev);
1294+ if (rc)
1295+ goto err;
1296+
1297+ rc = dp_display_request_irq(dp);
1298+ if (rc)
1299+ goto err;
1300+
1301+ if (dp->dp_display.is_edp) {
1302+ rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);
1303+ if (rc) {
1304+ DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
1305+ goto err;
1306+ }
1307+ } else {
1308+ rc = dp_display_probe_tail(&pdev->dev);
1309+ if (rc)
1310+ goto err;
12901311 }
12911312
12921313 return rc;
1314+
1315+err:
1316+ dp_display_deinit_sub_modules(dp);
1317+ return rc;
12931318 }
12941319
12951320 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
12981323
12991324 component_del(&pdev->dev, &dp_display_comp_ops);
13001325 dp_display_deinit_sub_modules(dp);
1301−
13021326 platform_set_drvdata(pdev, NULL);
13031327 }
13041328
1305−static int dp_pm_resume(struct device *dev)
1329+static int dp_pm_runtime_suspend(struct device *dev)
13061330 {
1307− struct platform_device *pdev = to_platform_device(dev);
1308− struct msm_dp *dp_display = platform_get_drvdata(pdev);
1309− struct dp_display_private *dp;
1310− int sink_count = 0;
1311−
1312− dp = container_of(dp_display, struct dp_display_private, dp_display);
1313−
1314− mutex_lock(&dp->event_mutex);
1315−
1316− drm_dbg_dp(dp->drm_dev,
1317− "Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n",
1318− dp->dp_display.connector_type, dp->core_initialized,
1319− dp->phy_initialized, dp_display->power_on);
1320−
1321− /* start from disconnected state */
1322− dp->hpd_state = ST_DISCONNECTED;
1323−
1324− /* turn on dp ctrl/phy */
1325− dp_display_host_init(dp);
1326−
1327− if (dp_display->is_edp)
1328− dp_catalog_ctrl_hpd_enable(dp->catalog);
1331+ struct dp_display_private *dp = dev_get_dp_display_private(dev);
13291332
1330− if (dp_catalog_link_is_connected(dp->catalog)) {
1331− /*
1332− * set sink to normal operation mode -- D0
1333− * before dpcd read
1334− */
1335− dp_display_host_phy_init(dp);
1336− dp_link_psm_config(dp->link, &dp->panel->link_info, false);
1337− sink_count = drm_dp_read_sink_count(dp->aux);
1338− if (sink_count < 0)
1339− sink_count = 0;
1333+ disable_irq(dp->irq);
13401334
1335+ if (dp->dp_display.is_edp) {
13411336 dp_display_host_phy_exit(dp);
1337+ dp_catalog_ctrl_hpd_disable(dp->catalog);
13421338 }
1343−
1344− dp->link->sink_count = sink_count;
1345− /*
1346− * can not declared display is connected unless
1347− * HDMI cable is plugged in and sink_count of
1348− * dongle become 1
1349− * also only signal audio when disconnected
1350− */
1351− if (dp->link->sink_count) {
1352− dp->dp_display.is_connected = true;
1353− } else {
1354− dp->dp_display.is_connected = false;
1355− dp_display_handle_plugged_change(dp_display, false);
1356− }
1357−
1358− drm_dbg_dp(dp->drm_dev,
1359− "After, type=%d sink=%d conn=%d core_init=%d phy_init=%d power=%d\n",
1360− dp->dp_display.connector_type, dp->link->sink_count,
1361− dp->dp_display.is_connected, dp->core_initialized,
1362− dp->phy_initialized, dp_display->power_on);
1363−
1364− mutex_unlock(&dp->event_mutex);
1339+ dp_display_host_deinit(dp);
13651340
13661341 return 0;
13671342 }
13681343
1369−static int dp_pm_suspend(struct device *dev)
1344+static int dp_pm_runtime_resume(struct device *dev)
13701345 {
1371− struct platform_device *pdev = to_platform_device(dev);
1372− struct msm_dp *dp_display = platform_get_drvdata(pdev);
1373− struct dp_display_private *dp;
1374−
1375− dp = container_of(dp_display, struct dp_display_private, dp_display);
1376−
1377− mutex_lock(&dp->event_mutex);
1378−
1379− drm_dbg_dp(dp->drm_dev,
1380− "Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n",
1381− dp->dp_display.connector_type, dp->core_initialized,
1382− dp->phy_initialized, dp_display->power_on);
1383−
1384− /* mainlink enabled */
1385− if (dp_power_clk_status(dp->power, DP_CTRL_PM))
1386− dp_ctrl_off_link_stream(dp->ctrl);
1387−
1388− dp_display_host_phy_exit(dp);
1389−
1390− /* host_init will be called at pm_resume */
1391− dp_display_host_deinit(dp);
1392−
1393− dp->hpd_state = ST_SUSPENDED;
1394−
1395− drm_dbg_dp(dp->drm_dev,
1396− "After, type=%d core_inited=%d phy_inited=%d power_on=%d\n",
1397− dp->dp_display.connector_type, dp->core_initialized,
1398− dp->phy_initialized, dp_display->power_on);
1346+ struct dp_display_private *dp = dev_get_dp_display_private(dev);
13991347
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+ }
14011361
1362+ enable_irq(dp->irq);
14021363 return 0;
14031364 }
14041365
14051366 static const struct dev_pm_ops dp_pm_ops = {
1406− .suspend = dp_pm_suspend,
1407− .resume = dp_pm_resume,
1367+ SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL)
1368+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1369+ pm_runtime_force_resume)
14081370 };
14091371
14101372 static struct platform_driver dp_display_driver = {
@@ -1434,19 +1396,6 @@ void __exit msm_dp_unregister(void) · 23 unmodified lines
14341396 platform_driver_unregister(&dp_display_driver);
14351397 }
14361398
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−
14501399 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
14511400 {
14521401 struct dp_display_private *dp;
@@ -1456,7 +1405,7 @@ bool msm_dp_wide_bus_available(const struct msm_dp *dp_display) · 3 unmodified lines
14561405 return dp->wide_bus_en;
14571406 }
14581407
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)
14601409 {
14611410 struct dp_display_private *dp;
14621411 struct device *dev;
@@ -1467,7 +1416,7 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) · 4 unmodified lines
14671416
14681417 dp->debug = dp_debug_get(dev, dp->panel,
14691418 dp->link, dp->dp_display.connector,
1470− minor);
1419+ root, is_edp);
14711420 if (IS_ERR(dp->debug)) {
14721421 rc = PTR_ERR(dp->debug);
14731422 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
14791428 {
14801429 int rc;
14811430 struct dp_display_private *dp_priv;
1482− struct device_node *aux_bus;
1483− struct device *dev;
14841431
14851432 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− }
15091433
15101434 /*
15111435 * 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
15141438 * For DisplayPort interfaces external bridges are optional, so
15151439 * silently ignore an error if one is not present (-ENODEV).
15161440 */
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);
15181442 if (!dp->is_edp && rc == -ENODEV)
15191443 return 0;
15201444
1521− if (!rc) {
1445+ if (!rc)
15221446 dp->next_bridge = dp_priv->parser->next_bridge;
1523− return 0;
1524− }
15251447
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− }
15321448 return rc;
15331449 }
15341450
@@ -1542,16 +1458,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, · 7 unmodified lines
15421458
15431459 dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
15441460
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−
15551461 ret = dp_bridge_init(dp_display, dev, encoder);
15561462 if (ret) {
15571463 DRM_DEV_ERROR(dev->dev,
@@ -1593,6 +1499,11 @@ void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge, · 35 unmodified lines
15931499 dp_hpd_plug_handle(dp_display, 0);
15941500
15951501 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+ }
15961507
15971508 state = dp_display->hpd_state;
15981509 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
16571568 mutex_lock(&dp_display->event_mutex);
16581569
16591570 state = dp_display->hpd_state;
1660− if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) {
1661− mutex_unlock(&dp_display->event_mutex);
1662− return;
1663− }
1571+ if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED)
1572+ drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
1573+ dp->connector_type, state);
16641574
16651575 dp_display_disable(dp_display);
16661576
@@ -1673,6 +1583,8 @@ void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge, · 6 unmodified lines
16731583 }
16741584
16751585 drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
1586+
1587+ pm_runtime_put_sync(&dp->pdev->dev);
16761588 mutex_unlock(&dp_display->event_mutex);
16771589 }
16781590
@@ -1711,7 +1623,21 @@ void dp_bridge_hpd_enable(struct drm_bridge *bridge) · 32 unmodified lines
17111623 struct msm_dp *dp_display = dp_bridge->dp_display;
17121624 struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
17131625
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+ */
17141634 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+
17151641 dp_catalog_ctrl_hpd_enable(dp->catalog);
17161642
17171643 /* enable HDP interrupts */
@@ -1733,6 +1659,8 @@ void dp_bridge_hpd_disable(struct drm_bridge *bridge) · 15 unmodified lines
17331659 dp_catalog_ctrl_hpd_disable(dp->catalog);
17341660
17351661 dp_display->internal_hpd = false;
1662+
1663+ pm_runtime_put_sync(&dp_display->pdev->dev);
17361664 mutex_unlock(&dp->event_mutex);
17371665 }
17381666
@@ -1747,13 +1675,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge, · 8 unmodified lines
17471675 if (dp_display->internal_hpd)
17481676 return;
17491677
1750− if (!dp->core_initialized) {
1751− drm_dbg_dp(dp->drm_dev, "not initialized\n");
1752− return;
1753− }
1754−
1755− if (!dp_display->is_connected && status == connector_status_connected)
1678+ if (!dp_display->link_ready && status == connector_status_connected)
17561679 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)
17581681 dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
17591682 }
drivers/gpu/drm/msm/dp/dp_display.h+2−2
@@ -17,7 +17,7 @@ struct msm_dp { · 16 unmodified lines
1717 struct drm_bridge *bridge;
1818 struct drm_connector *connector;
1919 struct drm_bridge *next_bridge;
20− bool is_connected;
20+ bool link_ready;
2121 bool audio_enabled;
2222 bool power_on;
2323 unsigned int connector_type;
@@ -36,11 +36,11 @@ struct msm_dp { · 12 unmodified lines
3636 int dp_display_set_plugged_cb(struct msm_dp *dp_display,
3737 hdmi_codec_plugged_cb fn, struct device *codec_dev);
3838 int dp_display_get_modes(struct msm_dp *dp_display);
39−int dp_display_request_irq(struct msm_dp *dp_display);
4039 bool dp_display_check_video_test(struct msm_dp *dp_display);
4140 int dp_display_get_test_bpp(struct msm_dp *dp_display);
4241 void dp_display_signal_audio_start(struct msm_dp *dp_display);
4342 void dp_display_signal_audio_complete(struct msm_dp *dp_display);
4443 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);
4545
4646 #endif /* _DP_DISPLAY_H_ */
drivers/gpu/drm/msm/dp/dp_drm.c+23−7
@@ -24,10 +24,10 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge) · 23 unmodified lines
2424
2525 dp = to_dp_bridge(bridge)->dp_display;
2626
27− drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
28− (dp->is_connected) ? "true" : "false");
27+ drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
28+ (dp->link_ready) ? "true" : "false");
2929
30− return (dp->is_connected) ? connector_status_connected :
30+ return (dp->link_ready) ? connector_status_connected :
3131 connector_status_disconnected;
3232 }
3333
@@ -40,8 +40,8 @@ static int dp_bridge_atomic_check(struct drm_bridge *bridge, · 6 unmodified lines
4040
4141 dp = to_dp_bridge(bridge)->dp_display;
4242
43− drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
44− (dp->is_connected) ? "true" : "false");
43+ drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
44+ (dp->link_ready) ? "true" : "false");
4545
4646 /*
4747 * 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
5555 * After that this piece of code can be removed.
5656 */
5757 if (bridge->ops & DRM_BRIDGE_OP_HPD)
58− return (dp->is_connected) ? 0 : -ENOTCONN;
58+ return (dp->link_ready) ? 0 : -ENOTCONN;
5959
6060 return 0;
6161 }
@@ -78,7 +78,7 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector * · 16 unmodified lines
7878 dp = to_dp_bridge(bridge)->dp_display;
7979
8080 /* pluggable case assumes EDID is read when HPD */
81− if (dp->is_connected) {
81+ if (dp->link_ready) {
8282 rc = dp_display_get_modes(dp);
8383 if (rc <= 0) {
8484 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
9090 return rc;
9191 }
9292
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+
93100 static const struct drm_bridge_funcs dp_bridge_ops = {
94101 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
95102 .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
105112 .hpd_enable = dp_bridge_hpd_enable,
106113 .hpd_disable = dp_bridge_hpd_disable,
107114 .hpd_notify = dp_bridge_hpd_notify,
115+ .debugfs_init = dp_bridge_debugfs_init,
108116 };
109117
110118 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
260268 return MODE_OK;
261269 }
262270
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+
263278 static const struct drm_bridge_funcs edp_bridge_ops = {
264279 .atomic_enable = edp_bridge_atomic_enable,
265280 .atomic_disable = edp_bridge_atomic_disable,
@@ -270,6 +285,7 @@ static const struct drm_bridge_funcs edp_bridge_ops = { · 4 unmodified lines
270285 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
271286 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
272287 .atomic_check = edp_bridge_atomic_check,
288+ .debugfs_init = edp_bridge_debugfs_init,
273289 };
274290
275291 int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
drivers/gpu/drm/msm/dp/dp_power.c+2−30
@@ -152,45 +152,17 @@ int dp_power_client_init(struct dp_power *dp_power) · 151 unmodified lines
152152
153153 power = container_of(dp_power, struct dp_power_private, dp_power);
154154
155− pm_runtime_enable(power->dev);
156−
157155 return dp_power_clk_init(power);
158156 }
159157
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−
169158 int dp_power_init(struct dp_power *dp_power)
170159 {
171− int rc = 0;
172− struct dp_power_private *power = NULL;
173−
174− power = container_of(dp_power, struct dp_power_private, dp_power);
175−
176− pm_runtime_get_sync(power->dev);
177−
178− rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true);
179− if (rc)
180− pm_runtime_put_sync(power->dev);
181−
182− return rc;
160+ return dp_power_clk_enable(dp_power, DP_CORE_PM, true);
183161 }
184162
185163 int dp_power_deinit(struct dp_power *dp_power)
186164 {
187− struct dp_power_private *power;
188−
189− power = container_of(dp_power, struct dp_power_private, dp_power);
190−
191− dp_power_clk_enable(dp_power, DP_CORE_PM, false);
192− pm_runtime_put_sync(power->dev);
193− return 0;
165+ return dp_power_clk_enable(dp_power, DP_CORE_PM, false);
194166 }
195167
196168 struct dp_power *dp_power_get(struct device *dev, struct dp_parser *parser)
drivers/gpu/drm/msm/dp/dp_power.h+0−11
@@ -80,17 +80,6 @@ int dp_power_clk_enable(struct dp_power *power, enum dp_pm_type pm_type, · 79 unmodified lines
8080 */
8181 int dp_power_client_init(struct dp_power *power);
8282
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−
9483 /**
9584 * dp_power_get() - configure and get the DisplayPort power module data
9685 *
drivers/gpu/drm/msm/dsi/dsi_cfg.c+17−0
@@ -190,6 +190,21 @@ static const struct msm_dsi_config sm8550_dsi_cfg = { · 189 unmodified lines
190190 },
191191 };
192192
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+
193208 static const struct regulator_bulk_data sc7280_dsi_regulators[] = {
194209 { .supply = "vdda", .init_load_uA = 8350 }, /* 1.2 V */
195210 { .supply = "refgen" },
@@ -281,6 +296,8 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = { · 85 unmodified lines
281296 &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
282297 {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
283298 &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},
284301 };
285302
286303 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
drivers/gpu/drm/msm/dsi/dsi_cfg.h+1−0
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 #define MSM_DSI_6G_VER_MINOR_V2_5_0 0x20050000
2929 #define MSM_DSI_6G_VER_MINOR_V2_6_0 0x20060000
3030 #define MSM_DSI_6G_VER_MINOR_V2_7_0 0x20070000
31+#define MSM_DSI_6G_VER_MINOR_V2_8_0 0x20080000
3132
3233 #define MSM_DSI_V2_VER_MINOR_8064 0x0
3334
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c+9−1
@@ -516,7 +516,9 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) · 515 unmodified lines
516516 struct device *dev = &phy->pdev->dev;
517517 int ret;
518518
519− pm_runtime_get_sync(dev);
519+ ret = pm_runtime_resume_and_get(dev);
520+ if (ret)
521+ return ret;
520522
521523 ret = clk_prepare_enable(phy->ahb_clk);
522524 if (ret) {
@@ -585,6 +587,8 @@ static const struct of_device_id dsi_phy_dt_match[] = { · 62 unmodified lines
585587 .data = &dsi_phy_5nm_8450_cfgs },
586588 { .compatible = "qcom,sm8550-dsi-phy-4nm",
587589 .data = &dsi_phy_4nm_8550_cfgs },
590+ { .compatible = "qcom,sm8650-dsi-phy-4nm",
591+ .data = &dsi_phy_4nm_8650_cfgs },
588592 #endif
589593 {}
590594 };
@@ -689,6 +693,10 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) · 98 unmodified lines
689693 return dev_err_probe(dev, PTR_ERR(phy->ahb_clk),
690694 "Unable to get ahb clk\n");
691695
696+ ret = devm_pm_runtime_enable(&pdev->dev);
697+ if (ret)
698+ return ret;
699+
692700 /* PLL init will call into clk_register which requires
693701 * register access, so we need to enable power and ahb clock.
694702 */
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h+1−0
@@ -62,6 +62,7 @@ extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs; · 61 unmodified lines
6262 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
6363 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
6464 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;
6566
6667 struct msm_dsi_dphy_timing {
6768 u32 clk_zero;
drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c+27−0
@@ -1121,6 +1121,10 @@ static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = { · 1120 unmodified lines
11211121 { .supply = "vdds", .init_load_uA = 37550 },
11221122 };
11231123
1124+static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {
1125+ { .supply = "vdds", .init_load_uA = 98000 },
1126+};
1127+
11241128 static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = {
11251129 { .supply = "vdds", .init_load_uA = 97800 },
11261130 };
@@ -1281,3 +1285,26 @@ const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = { · 154 unmodified lines
12811285 .num_dsi_phy = 2,
12821286 .quirks = DSI_PHY_7NM_QUIRK_V5_2,
12831287 };
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+};
drivers/gpu/drm/msm/msm_debugfs.c+25−16
@@ -304,36 +304,21 @@ int msm_debugfs_late_init(struct drm_device *dev) · 303 unmodified lines
304304 return ret;
305305 }
306306
307−void msm_debugfs_init(struct drm_minor *minor)
307+static void msm_debugfs_gpu_init(struct drm_minor *minor)
308308 {
309309 struct drm_device *dev = minor->dev;
310310 struct msm_drm_private *priv = dev->dev_private;
311311 struct dentry *gpu_devfreq;
312312
313− drm_debugfs_create_files(msm_debugfs_list,
314− ARRAY_SIZE(msm_debugfs_list),
315− minor->debugfs_root, minor);
316−
317313 debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
318314 dev, &msm_gpu_fops);
319315
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−
328316 debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root,
329317 &priv->hangcheck_period);
330318
331319 debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root,
332320 &priv->disable_err_irq);
333321
334− debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
335− dev, &shrink_fops);
336−
337322 gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root);
338323
339324 debugfs_create_bool("idle_clamp",0600, gpu_devfreq,
@@ -344,6 +329,30 @@ void msm_debugfs_init(struct drm_minor *minor) · 4 unmodified lines
344329
345330 debugfs_create_u32("downdifferential",0600, gpu_devfreq,
346331 &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);
347356
348357 if (priv->kms && priv->kms->funcs->debugfs_init)
349358 priv->kms->funcs->debugfs_init(priv->kms, minor);
drivers/gpu/drm/msm/msm_drv.c+92−2
@@ -37,9 +37,10 @@ · 36 unmodified lines
3737 * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
3838 * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT
3939 * - 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
4041 */
4142 #define MSM_VERSION_MAJOR 1
42−#define MSM_VERSION_MINOR 10
43+#define MSM_VERSION_MINOR 12
4344 #define MSM_VERSION_PATCHLEVEL 0
4445
4546 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
544545 return msm_gem_set_iova(obj, ctx->aspace, iova);
545546 }
546547
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+
547627 static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
548628 struct drm_file *file)
549629 {
@@ -566,6 +646,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 16 unmodified lines
566646 break;
567647 case MSM_INFO_SET_NAME:
568648 case MSM_INFO_GET_NAME:
649+ case MSM_INFO_SET_METADATA:
650+ case MSM_INFO_GET_METADATA:
569651 break;
570652 default:
571653 return -EINVAL;
@@ -618,7 +700,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, · 46 unmodified lines
618700 break;
619701 case MSM_INFO_GET_NAME:
620702 if (args->value && (args->len < strlen(msm_obj->name))) {
621− ret = -EINVAL;
703+ ret = -ETOOSMALL;
622704 break;
623705 }
624706 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
628710 ret = -EFAULT;
629711 }
630712 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;
631721 }
632722
633723 drm_gem_object_put(obj);
drivers/gpu/drm/msm/msm_drv.h+2−13
@@ -78,12 +78,10 @@ enum msm_dsi_controller { · 77 unmodified lines
7878 * enum msm_event_wait - type of HW events to wait for
7979 * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
8080 * @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)
8281 */
8382 enum msm_event_wait {
8483 MSM_ENC_COMMIT_DONE = 0,
8584 MSM_ENC_TX_COMPLETE,
86− MSM_ENC_VBLANK,
8785 };
8886
8987 /**
@@ -92,12 +90,14 @@ enum msm_event_wait { · 2 unmodified lines
9290 * @num_intf: number of interfaces the panel is mounted on
9391 * @num_dspp: number of dspp blocks used
9492 * @num_dsc: number of Display Stream Compression (DSC) blocks used
93+ * @needs_cdm: indicates whether cdm block is needed for this display topology
9594 */
9695 struct msm_display_topology {
9796 u32 num_lm;
9897 u32 num_intf;
9998 u32 num_dspp;
10099 u32 num_dsc;
100+ bool needs_cdm;
101101 };
102102
103103 /* Commit/Event thread specific structure */
@@ -386,10 +386,8 @@ int __init msm_dp_register(void); · 282 unmodified lines
386386 void __exit msm_dp_unregister(void);
387387 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
388388 struct drm_encoder *encoder);
389−void msm_dp_irq_postinstall(struct msm_dp *dp_display);
390389 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
391390
392−void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor);
393391 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
394392
395393 #else
@@ -407,19 +405,10 @@ static inline int msm_dp_modeset_init(struct msm_dp *dp_display, · 11 unmodified lines
407405 return -EINVAL;
408406 }
409407
410−static inline void msm_dp_irq_postinstall(struct msm_dp *dp_display)
411−{
412−}
413−
414408 static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display)
415409 {
416410 }
417411
418−static inline void msm_dp_debugfs_init(struct msm_dp *dp_display,
419− struct drm_minor *minor)
420−{
421−}
422−
423412 static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
424413 {
425414 return false;
drivers/gpu/drm/msm/msm_gem.c+4−3
@@ -226,9 +226,9 @@ static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj, · 225 unmodified lines
226226
227227 msm_gem_assert_locked(obj);
228228
229− if (GEM_WARN_ON(msm_obj->madv > madv)) {
230− DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n",
231− msm_obj->madv, madv);
229+ if (msm_obj->madv > madv) {
230+ DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n",
231+ msm_obj->madv, madv);
232232 return ERR_PTR(-EBUSY);
233233 }
234234
@@ -1058,6 +1058,7 @@ static void msm_gem_free_object(struct drm_gem_object *obj) · 823 unmodified lines
10581058
10591059 drm_gem_object_release(obj);
10601060
1061+ kfree(msm_obj->metadata);
10611062 kfree(msm_obj);
10621063 }
10631064
drivers/gpu/drm/msm/msm_gem.h+9−8
@@ -9,6 +9,7 @@ · 8 unmodified lines
99
1010 #include <linux/kref.h>
1111 #include <linux/dma-resv.h>
12+#include "drm/drm_exec.h"
1213 #include "drm/gpu_scheduler.h"
1314 #include "msm_drv.h"
1415
@@ -108,6 +109,10 @@ struct msm_gem_object { · 93 unmodified lines
108109
109110 char name[32]; /* Identifier to print for the debugfs files */
110111
112+ /* userspace metadata backchannel */
113+ void *metadata;
114+ u32 metadata_size;
115+
111116 /**
112117 * pin_count: Number of times the pages are pinned
113118 *
@@ -254,7 +259,7 @@ struct msm_gem_submit { · 140 unmodified lines
254259 struct msm_gpu *gpu;
255260 struct msm_gem_address_space *aspace;
256261 struct list_head node; /* node in ring submit list */
257− struct ww_acquire_ctx ticket;
262+ struct drm_exec exec;
258263 uint32_t seqno; /* Sequence number of the submit on the ring */
259264
260265 /* Hw fence, which is created when the scheduler executes the job, and
@@ -270,9 +275,9 @@ struct msm_gem_submit { · 9 unmodified lines
270275 int fence_id; /* key into queue->fence_idr */
271276 struct msm_gpu_submitqueue *queue;
272277 struct pid *pid; /* submitting process */
273− bool fault_dumped; /* Limit devcoredump dumping to one per submit */
274− bool valid; /* true if no cmdstream patching needed */
275− bool in_rb; /* "sudo" mode, copy cmds into RB */
278+ bool bos_pinned : 1;
279+ bool fault_dumped:1;/* Limit devcoredump dumping to one per submit */
280+ bool in_rb : 1; /* "sudo" mode, copy cmds into RB */
276281 struct msm_ringbuffer *ring;
277282 unsigned int nr_cmds;
278283 unsigned int nr_bos;
@@ -287,10 +292,6 @@ struct msm_gem_submit { · 8 unmodified lines
287292 struct drm_msm_gem_submit_reloc *relocs;
288293 } *cmd; /* array of size nr_cmds */
289294 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 */
294295 uint32_t flags;
295296 union {
296297 struct drm_gem_object *obj;
drivers/gpu/drm/msm/msm_gem_shrinker.c+1−1
@@ -75,7 +75,7 @@ static bool · 74 unmodified lines
7575 wait_for_idle(struct drm_gem_object *obj)
7676 {
7777 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;
7979 }
8080
8181 static bool
drivers/gpu/drm/msm/msm_gem_submit.c+69−164
@@ -17,6 +17,12 @@ · 16 unmodified lines
1717 #include "msm_gem.h"
1818 #include "msm_gpu_trace.h"
1919
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+
2026 /*
2127 * Cmdstream submission:
2228 */
@@ -37,7 +43,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, · 14 unmodified lines
3743 if (sz > SIZE_MAX)
3844 return ERR_PTR(-ENOMEM);
3945
40− submit = kzalloc(sz, GFP_KERNEL);
46+ submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
4147 if (!submit)
4248 return ERR_PTR(-ENOMEM);
4349
@@ -136,7 +142,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 92 unmodified lines
136142
137143 if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) ||
138144 !(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);
140146 ret = -EINVAL;
141147 i = 0;
142148 goto out;
@@ -144,8 +150,6 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 1 unmodified line
144150
145151 submit->bos[i].handle = submit_bo.handle;
146152 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;
149153 }
150154
151155 spin_lock(&file->table_lock);
@@ -158,7 +162,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, · 6 unmodified lines
158162 */
159163 obj = idr_find(&file->object_idr, submit->bos[i].handle);
160164 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);
162166 ret = -EINVAL;
163167 goto out_unlock;
164168 }
@@ -202,13 +206,13 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 37 unmodified lines
202206 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
203207 break;
204208 default:
205− DRM_ERROR("invalid type: %08x\n", submit_cmd.type);
209+ SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type);
206210 return -EINVAL;
207211 }
208212
209213 if (submit_cmd.size % 4) {
210− DRM_ERROR("non-aligned cmdstream buffer size: %u\n",
211− submit_cmd.size);
214+ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n",
215+ submit_cmd.size);
212216 ret = -EINVAL;
213217 goto out;
214218 }
@@ -228,7 +232,7 @@ static int submit_lookup_cmds(struct msm_gem_submit *submit, · 13 unmodified lines
228232 ret = -ENOMEM;
229233 goto out;
230234 }
231− submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL);
235+ submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);
232236 if (!submit->cmd[i].relocs) {
233237 ret = -ENOMEM;
234238 goto out;
@@ -244,101 +248,30 @@ out: · 9 unmodified lines
244248 return ret;
245249 }
246250
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−
280251 /* This is where we make sure all the bo's are reserved and pin'd: */
281252 static int submit_lock_objects(struct msm_gem_submit *submit)
282253 {
283− int contended, slow_locked = -1, i, ret = 0;
284−
285−retry:
286− for (i = 0; i < submit->nr_bos; i++) {
287− struct drm_gem_object *obj = submit->bos[i].obj;
288−
289− if (slow_locked == i)
290− slow_locked = -1;
254+ int ret;
291255
292− contended = i;
256+ drm_exec_init(&submit->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, submit->nr_bos);
293257
294− if (!(submit->bos[i].flags & BO_LOCKED)) {
295− ret = dma_resv_lock_interruptible(obj->resv,
296− &submit->ticket);
258+ drm_exec_until_all_locked (&submit->exec) {
259+ for (unsigned i = 0; i < submit->nr_bos; i++) {
260+ struct drm_gem_object *obj = submit->bos[i].obj;
261+ ret = drm_exec_prepare_obj(&submit->exec, obj, 1);
262+ drm_exec_retry_on_contention(&submit->exec);
297263 if (ret)
298− goto fail;
299− submit->bos[i].flags |= BO_LOCKED;
264+ goto error;
300265 }
301266 }
302267
303− ww_acquire_done(&submit->ticket);
304−
305268 return 0;
306269
307−fail:
308− if (ret == -EALREADY) {
309− DRM_ERROR("handle %u at index %u already on submit list\n",
310− submit->bos[i].handle, i);
311− ret = -EINVAL;
312− }
313−
314− for (; i >= 0; i--)
315− submit_unlock_unpin_bo(submit, i);
316−
317− if (slow_locked > 0)
318− submit_unlock_unpin_bo(submit, slow_locked);
319−
320− if (ret == -EDEADLK) {
321− struct drm_gem_object *obj = submit->bos[contended].obj;
322− /* we lost out in a seqno race, lock and retry.. */
323− ret = dma_resv_lock_slow_interruptible(obj->resv,
324− &submit->ticket);
325− if (!ret) {
326− submit->bos[contended].flags |= BO_LOCKED;
327− slow_locked = contended;
328− goto retry;
329− }
330−
331− /* Not expecting -EALREADY here, if the bo was already
332− * locked, we should have gotten -EALREADY already from
333− * the dma_resv_lock_interruptable() call.
334− */
335− WARN_ON_ONCE(ret == -EALREADY);
336− }
337−
270+error:
338271 return ret;
339272 }
340273
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)
342275 {
343276 int i, ret = 0;
344277
@@ -346,22 +279,6 @@ static int submit_fence_sync(struct msm_gem_submit *submit, bool no_implicit) · 1 unmodified line
346279 struct drm_gem_object *obj = submit->bos[i].obj;
347280 bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE;
348281
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−
365282 /* Otherwise userspace can ask for implicit sync to be
366283 * disabled on specific buffers. This is useful for internal
367284 * usermode driver managed buffers, suballocation, etc.
@@ -384,8 +301,6 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 16 unmodified lines
384301 struct msm_drm_private *priv = submit->dev->dev_private;
385302 int i, ret = 0;
386303
387− submit->valid = true;
388−
389304 for (i = 0; i < submit->nr_bos; i++) {
390305 struct drm_gem_object *obj = submit->bos[i].obj;
391306 struct msm_gem_vma *vma;
@@ -401,14 +316,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 9 unmodified lines
401316 if (ret)
402317 break;
403318
404− if (vma->iova == submit->bos[i].iova) {
405− submit->bos[i].flags |= BO_VALID;
406− } else {
407− submit->bos[i].iova = vma->iova;
408− /* iova changed, so address in cmdstream is not valid: */
409− submit->bos[i].flags &= ~BO_VALID;
410− submit->valid = false;
411− }
319+ submit->bos[i].iova = vma->iova;
412320 }
413321
414322 /*
@@ -421,13 +329,28 @@ static int submit_pin_objects(struct msm_gem_submit *submit) · 6 unmodified lines
421329 mutex_lock(&priv->lru.lock);
422330 for (i = 0; i < submit->nr_bos; i++) {
423331 msm_gem_pin_obj_locked(submit->bos[i].obj);
424− submit->bos[i].flags |= BO_PINNED;
425332 }
426333 mutex_unlock(&priv->lru.lock);
427334
335+ submit->bos_pinned = true;
336+
428337 return ret;
429338 }
430339
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+
431354 static void submit_attach_object_fences(struct msm_gem_submit *submit)
432355 {
433356 int i;
@@ -445,11 +368,11 @@ static void submit_attach_object_fences(struct msm_gem_submit *submit) · 11 unmodified lines
445368 }
446369
447370 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)
449372 {
450373 if (idx >= submit->nr_bos) {
451− DRM_ERROR("invalid buffer index: %u (out of %u)\n",
452− idx, submit->nr_bos);
374+ SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n",
375+ idx, submit->nr_bos);
453376 return -EINVAL;
454377 }
455378
@@ -457,8 +380,6 @@ static int submit_bo(struct msm_gem_submit *submit, uint32_t idx, · 1 unmodified line
457380 *obj = submit->bos[idx].obj;
458381 if (iova)
459382 *iova = submit->bos[idx].iova;
460− if (valid)
461− *valid = !!(submit->bos[idx].flags & BO_VALID);
462383
463384 return 0;
464385 }
@@ -471,11 +392,8 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 6 unmodified lines
471392 uint32_t *ptr;
472393 int ret = 0;
473394
474− if (!nr_relocs)
475− return 0;
476−
477395 if (offset % 4) {
478− DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset);
396+ SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", offset);
479397 return -EINVAL;
480398 }
481399
@@ -494,11 +412,10 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 12 unmodified lines
494412 struct drm_msm_gem_submit_reloc submit_reloc = relocs[i];
495413 uint32_t off;
496414 uint64_t iova;
497− bool valid;
498415
499416 if (submit_reloc.submit_offset % 4) {
500− DRM_ERROR("non-aligned reloc offset: %u\n",
501− submit_reloc.submit_offset);
417+ SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n",
418+ submit_reloc.submit_offset);
502419 ret = -EINVAL;
503420 goto out;
504421 }
@@ -508,18 +425,15 @@ static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *ob · 3 unmodified lines
508425
509426 if ((off >= (obj->size / 4)) ||
510427 (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);
512429 ret = -EINVAL;
513430 goto out;
514431 }
515432
516− ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid);
433+ ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova);
517434 if (ret)
518435 goto out;
519436
520− if (valid)
521− continue;
522−
523437 iova += submit_reloc.reloc_offset;
524438
525439 if (submit_reloc.shift < 0)
@@ -544,18 +458,14 @@ out: · 18 unmodified lines
544458 */
545459 static void submit_cleanup(struct msm_gem_submit *submit, bool error)
546460 {
547− unsigned cleanup_flags = BO_LOCKED;
548− unsigned i;
549−
550− if (error)
551− cleanup_flags |= BO_PINNED;
552−
553− for (i = 0; i < submit->nr_bos; i++) {
554− struct drm_gem_object *obj = submit->bos[i].obj;
555− submit_cleanup_bo(submit, i, cleanup_flags);
556− if (error)
557− drm_gem_object_put(obj);
461+ if (error) {
462+ submit_unpin_objects(submit);
463+ /* job wasn't enqueued to scheduler, so early retirement: */
464+ msm_submit_retire(submit);
558465 }
466+
467+ if (submit->exec.objects)
468+ drm_exec_fini(&submit->exec);
559469 }
560470
561471 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
749659 struct msm_submit_post_dep *post_deps = NULL;
750660 struct drm_syncobj **syncobjs_to_reset = NULL;
751661 int out_fence_fd = -1;
752− bool has_ww_ticket = false;
753662 unsigned i;
754663 int ret;
755664
@@ -855,15 +764,15 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 99 unmodified lines
855764 goto out;
856765
857766 /* copy_*_user while holding a ww ticket upsets lockdep */
858− ww_acquire_init(&submit->ticket, &reservation_ww_class);
859− has_ww_ticket = true;
860767 ret = submit_lock_objects(submit);
861768 if (ret)
862769 goto out;
863770
864− ret = submit_fence_sync(submit, !!(args->flags & MSM_SUBMIT_NO_IMPLICIT));
865− if (ret)
866− goto out;
771+ if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) {
772+ ret = submit_fence_sync(submit);
773+ if (ret)
774+ goto out;
775+ }
867776
868777 ret = submit_pin_objects(submit);
869778 if (ret)
@@ -873,32 +782,27 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 3 unmodified lines
873782 struct drm_gem_object *obj;
874783 uint64_t iova;
875784
876− ret = submit_bo(submit, submit->cmd[i].idx,
877− &obj, &iova, NULL);
785+ ret = submit_bo(submit, submit->cmd[i].idx, &obj, &iova);
878786 if (ret)
879787 goto out;
880788
881789 if (!submit->cmd[i].size ||
882790 ((submit->cmd[i].size + submit->cmd[i].offset) >
883791 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);
885793 ret = -EINVAL;
886794 goto out;
887795 }
888796
889797 submit->cmd[i].iova = iova + (submit->cmd[i].offset * 4);
890798
891− if (submit->valid)
799+ if (likely(!submit->cmd[i].nr_relocs))
892800 continue;
893801
894802 if (!gpu->allow_relocs) {
895− if (submit->cmd[i].nr_relocs) {
896− DRM_ERROR("relocs not allowed\n");
897− ret = -EINVAL;
898− goto out;
899− }
900−
901− continue;
803+ SUBMIT_ERROR(submit, "relocs not allowed\n");
804+ ret = -EINVAL;
805+ goto out;
902806 }
903807
904808 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
974878 }
975879 }
976880
881+ if (ret)
882+ goto out;
883+
977884 submit_attach_object_fences(submit);
978885
979886 /* The scheduler owns a ref now: */
@@ -993,8 +900,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, · 13 unmodified lines
993900
994901 out:
995902 submit_cleanup(submit, !!ret);
996− if (has_ww_ticket)
997− ww_acquire_fini(&submit->ticket);
998903 out_unlock:
999904 mutex_unlock(&queue->lock);
1000905 out_post_unlock:
drivers/gpu/drm/msm/msm_gpu.c+23−21
@@ -292,8 +292,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, · 291 unmodified lines
292292 /* Set the active crash state to be dumped on failure */
293293 gpu->crashstate = state;
294294
295− /* FIXME: Release the crashstate if this errors out? */
296− dev_coredumpm(gpu->dev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL,
295+ dev_coredumpm(&gpu->pdev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL,
297296 msm_gpu_devcoredump_read, msm_gpu_devcoredump_free);
298297 }
299298 #else
@@ -366,29 +365,31 @@ static void recover_worker(struct kthread_work *work) · 66 unmodified lines
366365 DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name);
367366
368367 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++;
374368
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;
376375
377− if (comm && cmd) {
378− DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n",
379− gpu->name, comm, cmd);
376+ /* Increment the fault counts */
377+ submit->queue->faults++;
378+ if (submit->aspace)
379+ submit->aspace->faults++;
380380
381− msm_rd_dump_submit(priv->hangrd, submit,
382− "offending task: %s (%s)", comm, cmd);
383− } else {
384− msm_rd_dump_submit(priv->hangrd, submit, NULL);
385− }
381+ get_comm_cmdline(submit, &comm, &cmd);
382+
383+ if (comm && cmd) {
384+ DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n",
385+ gpu->name, comm, cmd);
386+
387+ msm_rd_dump_submit(priv->hangrd, submit,
388+ "offending task: %s (%s)", comm, cmd);
386389 } else {
387− /*
388− * We couldn't attribute this fault to any particular context,
389− * so increment the global fault count instead.
390− */
391− gpu->global_faults++;
390+ DRM_DEV_ERROR(dev->dev, "%s: offending task: unknown\n", gpu->name);
391+
392+ msm_rd_dump_submit(priv->hangrd, submit, NULL);
392393 }
393394
394395 /* Record the crash state */
@@ -441,6 +442,7 @@ static void recover_worker(struct kthread_work *work) · 46 unmodified lines
441442
442443 pm_runtime_put(&gpu->pdev->dev);
443444
445+out_unlock:
444446 mutex_unlock(&gpu->lock);
445447
446448 msm_gpu_retire(gpu);
drivers/gpu/drm/msm/msm_mdss.c+70−36
@@ -28,6 +28,8 @@ · 27 unmodified lines
2828
2929 #define MIN_IB_BW 400000000UL /* Min ib vote 400MB */
3030
31+#define DEFAULT_REG_BW 153600 /* Used in mdss fbdev driver */
32+
3133 struct msm_mdss {
3234 struct device *dev;
3335
@@ -40,8 +42,9 @@ struct msm_mdss { · 6 unmodified lines
4042 struct irq_domain *domain;
4143 } irq_controller;
4244 const struct msm_mdss_data *mdss_data;
43− struct icc_path *path[2];
44− u32 num_paths;
45+ struct icc_path *mdp_path[2];
46+ u32 num_mdp_paths;
47+ struct icc_path *reg_bus_path;
4548 };
4649
4750 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
4952 {
5053 struct icc_path *path0;
5154 struct icc_path *path1;
55+ struct icc_path *reg_bus_path;
5256
53− path0 = of_icc_get(dev, "mdp0-mem");
57+ path0 = devm_of_icc_get(dev, "mdp0-mem");
5458 if (IS_ERR_OR_NULL(path0))
5559 return PTR_ERR_OR_ZERO(path0);
5660
57− msm_mdss->path[0] = path0;
58− msm_mdss->num_paths = 1;
61+ msm_mdss->mdp_path[0] = path0;
62+ msm_mdss->num_mdp_paths = 1;
5963
60− path1 = of_icc_get(dev, "mdp1-mem");
64+ path1 = devm_of_icc_get(dev, "mdp1-mem");
6165 if (!IS_ERR_OR_NULL(path1)) {
62− msm_mdss->path[1] = path1;
63− msm_mdss->num_paths++;
66+ msm_mdss->mdp_path[1] = path1;
67+ msm_mdss->num_mdp_paths++;
6468 }
6569
66− return 0;
67−}
68−
69−static void msm_mdss_put_icc_path(void *data)
70−{
71− struct msm_mdss *msm_mdss = data;
72− int i;
73−
74− for (i = 0; i < msm_mdss->num_paths; i++)
75− icc_put(msm_mdss->path[i]);
76−}
77−
78−static void msm_mdss_icc_request_bw(struct msm_mdss *msm_mdss, unsigned long bw)
79−{
80− int i;
70+ reg_bus_path = of_icc_get(dev, "cpu-cfg");
71+ if (!IS_ERR_OR_NULL(reg_bus_path))
72+ msm_mdss->reg_bus_path = reg_bus_path;
8173
82− for (i = 0; i < msm_mdss->num_paths; i++)
83− icc_set_bw(msm_mdss->path[i], 0, Bps_to_icc(bw));
74+ return 0;
8475 }
8576
8677 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
236227
237228 static int msm_mdss_enable(struct msm_mdss *msm_mdss)
238229 {
239− int ret;
230+ int ret, i;
240231
241232 /*
242233 * Several components have AXI clocks that can only be turned on if
243234 * the interconnect is enabled (non-zero bandwidth). Let's make sure
244235 * that the interconnects are at least at a minimum amount.
245236 */
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);
247246
248247 ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks);
249248 if (ret) {
@@ -295,8 +294,15 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) · 45 unmodified lines
295294
296295 static int msm_mdss_disable(struct msm_mdss *msm_mdss)
297296 {
297+ int i;
298+
298299 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);
300306
301307 return 0;
302308 }
@@ -384,6 +390,8 @@ static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5 · 81 unmodified lines
384390 if (!msm_mdss)
385391 return ERR_PTR(-ENOMEM);
386392
393+ msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev);
394+
387395 msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss");
388396 if (IS_ERR(msm_mdss->mmio))
389397 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
391399 dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio);
392400
393401 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);
397402 if (ret)
398403 return ERR_PTR(ret);
399404
@@ -477,8 +482,6 @@ static int mdss_probe(struct platform_device *pdev) · 77 unmodified lines
477482 if (IS_ERR(mdss))
478483 return PTR_ERR(mdss);
479484
480− mdss->mdss_data = of_device_get_match_data(&pdev->dev);
481−
482485 platform_set_drvdata(pdev, mdss);
483486
484487 /*
@@ -510,11 +513,13 @@ static const struct msm_mdss_data msm8998_data = { · 25 unmodified lines
510513 .ubwc_enc_version = UBWC_1_0,
511514 .ubwc_dec_version = UBWC_1_0,
512515 .highest_bank_bit = 2,
516+ .reg_bus_bw = 76800,
513517 };
514518
515519 static const struct msm_mdss_data qcm2290_data = {
516520 /* no UBWC */
517521 .highest_bank_bit = 0x2,
522+ .reg_bus_bw = 76800,
518523 };
519524
520525 static const struct msm_mdss_data sc7180_data = {
@@ -522,6 +527,7 @@ static const struct msm_mdss_data sc7180_data = { · 1 unmodified line
522527 .ubwc_dec_version = UBWC_2_0,
523528 .ubwc_static = 0x1e,
524529 .highest_bank_bit = 0x3,
530+ .reg_bus_bw = 76800,
525531 };
526532
527533 static const struct msm_mdss_data sc7280_data = {
@@ -531,6 +537,7 @@ static const struct msm_mdss_data sc7280_data = { · 3 unmodified lines
531537 .ubwc_static = 1,
532538 .highest_bank_bit = 1,
533539 .macrotile_mode = 1,
540+ .reg_bus_bw = 74000,
534541 };
535542
536543 static const struct msm_mdss_data sc8180x_data = {
@@ -538,6 +545,7 @@ static const struct msm_mdss_data sc8180x_data = { · 1 unmodified line
538545 .ubwc_dec_version = UBWC_3_0,
539546 .highest_bank_bit = 3,
540547 .macrotile_mode = 1,
548+ .reg_bus_bw = 76800,
541549 };
542550
543551 static const struct msm_mdss_data sc8280xp_data = {
@@ -545,14 +553,22 @@ static const struct msm_mdss_data sc8280xp_data = { · 1 unmodified line
545553 .ubwc_dec_version = UBWC_4_0,
546554 .ubwc_swizzle = 6,
547555 .ubwc_static = 1,
548− .highest_bank_bit = 2,
556+ .highest_bank_bit = 3,
549557 .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,
550565 };
551566
552567 static const struct msm_mdss_data sdm845_data = {
553568 .ubwc_enc_version = UBWC_2_0,
554569 .ubwc_dec_version = UBWC_2_0,
555570 .highest_bank_bit = 2,
571+ .reg_bus_bw = 76800,
556572 };
557573
558574 static const struct msm_mdss_data sm6350_data = {
@@ -561,12 +577,14 @@ static const struct msm_mdss_data sm6350_data = { · 2 unmodified lines
561577 .ubwc_swizzle = 6,
562578 .ubwc_static = 0x1e,
563579 .highest_bank_bit = 1,
580+ .reg_bus_bw = 76800,
564581 };
565582
566583 static const struct msm_mdss_data sm8150_data = {
567584 .ubwc_enc_version = UBWC_3_0,
568585 .ubwc_dec_version = UBWC_3_0,
569586 .highest_bank_bit = 2,
587+ .reg_bus_bw = 76800,
570588 };
571589
572590 static const struct msm_mdss_data sm6115_data = {
@@ -575,6 +593,7 @@ static const struct msm_mdss_data sm6115_data = { · 2 unmodified lines
575593 .ubwc_swizzle = 7,
576594 .ubwc_static = 0x11f,
577595 .highest_bank_bit = 0x1,
596+ .reg_bus_bw = 76800,
578597 };
579598
580599 static const struct msm_mdss_data sm6125_data = {
@@ -592,6 +611,18 @@ static const struct msm_mdss_data sm8250_data = { · 11 unmodified lines
592611 /* TODO: highest_bank_bit = 2 for LP_DDR4 */
593612 .highest_bank_bit = 3,
594613 .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,
595626 };
596627
597628 static const struct msm_mdss_data sm8550_data = {
@@ -602,11 +633,13 @@ static const struct msm_mdss_data sm8550_data = { · 4 unmodified lines
602633 /* TODO: highest_bank_bit = 2 for LP_DDR4 */
603634 .highest_bank_bit = 3,
604635 .macrotile_mode = 1,
636+ .reg_bus_bw = 57000,
605637 };
606638 static const struct of_device_id mdss_dt_match[] = {
607639 { .compatible = "qcom,mdss" },
608640 { .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },
609641 { .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },
642+ { .compatible = "qcom,sdm670-mdss", .data = &sdm670_data },
610643 { .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },
611644 { .compatible = "qcom,sc7180-mdss", .data = &sc7180_data },
612645 { .compatible = "qcom,sc7280-mdss", .data = &sc7280_data },
@@ -618,9 +651,10 @@ static const struct of_device_id mdss_dt_match[] = { · 5 unmodified lines
618651 { .compatible = "qcom,sm6375-mdss", .data = &sm6350_data },
619652 { .compatible = "qcom,sm8150-mdss", .data = &sm8150_data },
620653 { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
621− { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data },
622− { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data },
654+ { .compatible = "qcom,sm8350-mdss", .data = &sm8350_data },
655+ { .compatible = "qcom,sm8450-mdss", .data = &sm8350_data },
623656 { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
657+ { .compatible = "qcom,sm8650-mdss", .data = &sm8550_data},
624658 {}
625659 };
626660 MODULE_DEVICE_TABLE(of, mdss_dt_match);
drivers/gpu/drm/msm/msm_mdss.h+1−0
@@ -14,6 +14,7 @@ struct msm_mdss_data { · 13 unmodified lines
1414 u32 ubwc_static;
1515 u32 highest_bank_bit;
1616 u32 macrotile_mode;
17+ u32 reg_bus_bw;
1718 };
1819
1920 #define UBWC_1_0 0x10000000
drivers/gpu/drm/msm/msm_rd.c+3−0
@@ -270,6 +270,9 @@ int msm_rd_debugfs_init(struct drm_minor *minor) · 269 unmodified lines
270270 struct msm_rd_state *rd;
271271 int ret;
272272
273+ if (!priv->gpu_pdev)
274+ return 0;
275+
273276 /* only create on first minor: */
274277 if (priv->rd)
275278 return 0;
drivers/gpu/drm/msm/msm_ringbuffer.c+2−1
@@ -29,9 +29,10 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job) · 28 unmodified lines
2929 struct drm_gem_object *obj = submit->bos[i].obj;
3030
3131 msm_gem_unpin_active(obj);
32− submit->bos[i].flags &= ~BO_PINNED;
3332 }
3433
34+ submit->bos_pinned = false;
35+
3536 mutex_unlock(&priv->lru.lock);
3637
3738 msm_gpu_submit(gpu, submit);
drivers/gpu/drm/nouveau/nouveau_uvmm.c+1−1
@@ -1347,7 +1347,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job, · 1346 unmodified lines
13471347 }
13481348 }
13491349
1350− drm_exec_init(exec, vme->flags);
1350+ drm_exec_init(exec, vme->flags, 0);
13511351 drm_exec_until_all_locked(exec) {
13521352 ret = bind_lock_validate(job, exec, vme->num_fences);
13531353 drm_exec_retry_on_contention(exec);
drivers/gpu/drm/tests/drm_exec_test.c+8−8
@@ -46,7 +46,7 @@ static void sanitycheck(struct kunit *test) · 45 unmodified lines
4646 {
4747 struct drm_exec exec;
4848
49− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
49+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
5050 drm_exec_fini(&exec);
5151 KUNIT_SUCCEED(test);
5252 }
@@ -60,7 +60,7 @@ static void test_lock(struct kunit *test) · 7 unmodified lines
6060
6161 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);
6262
63− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
63+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
6464 drm_exec_until_all_locked(&exec) {
6565 ret = drm_exec_lock_obj(&exec, &gobj);
6666 drm_exec_retry_on_contention(&exec);
@@ -80,7 +80,7 @@ static void test_lock_unlock(struct kunit *test) · 13 unmodified lines
8080
8181 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);
8282
83− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
83+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
8484 drm_exec_until_all_locked(&exec) {
8585 ret = drm_exec_lock_obj(&exec, &gobj);
8686 drm_exec_retry_on_contention(&exec);
@@ -107,7 +107,7 @@ static void test_duplicates(struct kunit *test) · 20 unmodified lines
107107
108108 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);
109109
110− drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES);
110+ drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
111111 drm_exec_until_all_locked(&exec) {
112112 ret = drm_exec_lock_obj(&exec, &gobj);
113113 drm_exec_retry_on_contention(&exec);
@@ -134,7 +134,7 @@ static void test_prepare(struct kunit *test) · 20 unmodified lines
134134
135135 drm_gem_private_object_init(priv->drm, &gobj, PAGE_SIZE);
136136
137− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
137+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
138138 drm_exec_until_all_locked(&exec) {
139139 ret = drm_exec_prepare_obj(&exec, &gobj, 1);
140140 drm_exec_retry_on_contention(&exec);
@@ -159,7 +159,7 @@ static void test_prepare_array(struct kunit *test) · 18 unmodified lines
159159 drm_gem_private_object_init(priv->drm, &gobj1, PAGE_SIZE);
160160 drm_gem_private_object_init(priv->drm, &gobj2, PAGE_SIZE);
161161
162− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
162+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
163163 drm_exec_until_all_locked(&exec)
164164 ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array),
165165 1);
@@ -174,14 +174,14 @@ static void test_multiple_loops(struct kunit *test) · 8 unmodified lines
174174 {
175175 struct drm_exec exec;
176176
177− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
177+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
178178 drm_exec_until_all_locked(&exec)
179179 {
180180 break;
181181 }
182182 drm_exec_fini(&exec);
183183
184− drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
184+ drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
185185 drm_exec_until_all_locked(&exec)
186186 {
187187 break;
include/drm/drm_exec.h+1−1
@@ -135,7 +135,7 @@ static inline bool drm_exec_is_contended(struct drm_exec *exec) · 134 unmodified lines
135135 return !!exec->contended;
136136 }
137137
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);
139139 void drm_exec_fini(struct drm_exec *exec);
140140 bool drm_exec_cleanup(struct drm_exec *exec);
141141 int drm_exec_lock_obj(struct drm_exec *exec, struct drm_gem_object *obj);
include/uapi/drm/msm_drm.h+3−0
@@ -86,6 +86,7 @@ struct drm_msm_timespec { · 85 unmodified lines
8686 #define MSM_PARAM_CMDLINE 0x0d /* WO: override for task cmdline */
8787 #define MSM_PARAM_VA_START 0x0e /* RO: start of valid GPU iova range */
8888 #define MSM_PARAM_VA_SIZE 0x0f /* RO: size of valid GPU iova range (bytes) */
89+#define MSM_PARAM_HIGHEST_BANK_BIT 0x10 /* RO */
8990
9091 /* For backwards compat. The original support for preemption was based on
9192 * a single ring per priority level so # of priority levels equals the #
@@ -139,6 +140,8 @@ struct drm_msm_gem_new { · 47 unmodified lines
139140 #define MSM_INFO_GET_NAME 0x03 /* get debug name, returned by pointer */
140141 #define MSM_INFO_SET_IOVA 0x04 /* set the iova, passed by value */
141142 #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 */
142145
143146 struct drm_msm_gem_info {
144147 __u32 handle; /* in */