History

Merge tag 'drm-misc-next-2022-01-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

[airlied: add two missing Kconfig] drm-misc-next for v5.18: UAPI Changes: - Fix invalid IN_FORMATS blob when plane->format_mod_supported is NULL. Cross-subsystem Changes: - Assorted dt bindings updates. - Fix vga16fb vga checking on x86. - Fix extra semicolon in rwsem.h's _down_write_nest_lock. - Assorted small fixes to agp and fbdev drivers. - Fix oops in creating a udmabuf with 0 pages. - Hot-unplug firmware fb devices on forced removal - Reqquest memory region in simplefb and simpledrm, and don't make the ioresource as busy. Core Changes: - Mock a drm_plane in drm-plane-helper selftest. - Assorted bug fixes to device logging, dbi. - Use DP helper for sink count in mst. - Assorted documentation fixes. - Assorted small fixes. - Move DP headers to drm/dp, and add a drm dp helper module. - Move the buddy allocator from i915 to common drm. - Add simple pci and platform module init macros to remove a lot of boilerplate from some drivers. - Support microsoft extension for HMDs and specialized monitors. - Improve edid parser's deep color handling. - Add type 7 timing support to edid parser. - Add a weak backpointer to the ttm_bo from ttm_resource - Add 3 eDP panels. Driver Changes: - Add support for HDMI and JZ4780 to ingenic. - Add support for higher DP/eDP bitrates to nouveau. - Assorted driver fixes to tilcdc, vmwgfx, sn65dsi83, meson, stm, panfrost, v3d, gma500, vc4, virtio, mgag200, ast, radeon, amdgpu, nouveau, various bridge drivers. - Convert and revert exynos dsi support to bridge driver. - Add vcc supply regulator support for sn65dsi83. - More conversion of bridge/chipone-icn6211 to atomic. - Remove conflicting fb's from stm, and add support for new hw version. - Add device link in parade-ps8640 to fix suspend/resume. - Update Boe-tv110c9m init sequence. - Add wide screen support to AST2600. - Fix omapdrm implicit dma_buf fencing. - Add support for multiple overlay planes to vkms. - Convert bridge/anx7625 to atomic, add HDCP support, add eld support for audio, and fix HPD. - Add driver for ChromeOS privacy screen. - Handover display from firmware to vc4 more gracefully, and support nomodeset. - Add flexible and ycbcr pixel formats to stm/ltdc. - Convert exynos mipi dsi to atomic. - Add initial dual core group GPUs support to panfrost. - No longer add exclusive fence in amdgpu as shared fence. - Add CSC and full range supoprt to vc4. - Shutdown the display on system shutdown and unbind. - Add Multi-Inno Technology MI0700S4T-6 simple panel. Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 4 years ago

Commit 53dbee42 parents 26291c5 a5d092d233 files · +5377 −2613Browse files

Unified · Split

233 files
  1. Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml +1 −0
  2. Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml +4 −1
  3. Documentation/devicetree/bindings/display/panel/panel-simple.yaml +2 −0
  4. Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml +9 −2
  5. Documentation/gpu/drm-internals.rst +6 −0
  6. Documentation/gpu/drm-kms-helpers.rst +13 −13
  7. Documentation/gpu/drm-kms.rst +3 −3
  8. Documentation/gpu/drm-mm.rst +1 −1
  9. Documentation/gpu/todo.rst +15 −0
  10. Documentation/gpu/vkms.rst +0 −2
  11. drivers/char/agp/ati-agp.c +6 −2
  12. drivers/char/agp/backend.c +2 −0
  13. drivers/char/agp/frontend.c +3 −1
  14. drivers/char/agp/nvidia-agp.c +2 −1
  15. drivers/char/agp/sworks-agp.c +1 −4
  16. drivers/char/agp/via-agp.c +0 −3
  17. drivers/dma-buf/dma-resv.c +17 −29
  18. drivers/dma-buf/st-dma-resv.c +5 −21
  19. drivers/dma-buf/udmabuf.c +4 −0
  20. drivers/firmware/sysfb_simplefb.c +1 −1
  21. drivers/gpu/drm/Kconfig +15 −0
  22. drivers/gpu/drm/Makefile +6 −8
  23. drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +2 −2
  24. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +1 −4
  25. drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +4 −2
  26. drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +0 −6
  27. drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +4 −1
  28. drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +1 −1
  29. drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +2 −2
  30. drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c +2 −1
  31. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +5 −5
  32. drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +4 −1
  33. drivers/gpu/drm/amd/amdgpu/atombios_dp.c +1 −1
  34. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 −2
  35. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +1 −1
  36. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +2 −2
  37. drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c +1 −1
  38. drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +1 −1
  39. drivers/gpu/drm/amd/display/dc/os_types.h +1 −1
  40. drivers/gpu/drm/amd/display/include/dpcd_defs.h +1 −1
  41. drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h +1 −1
  42. drivers/gpu/drm/arm/display/komeda/d71/d71_component.c +6 −6
  43. drivers/gpu/drm/arm/display/komeda/komeda_drv.c +2 −1
  44. drivers/gpu/drm/arm/hdlcd_drv.c +2 −1
  45. drivers/gpu/drm/arm/malidp_drv.c +2 −1
  46. drivers/gpu/drm/ast/ast_drv.c +2 −16
  47. drivers/gpu/drm/ast/ast_main.c +2 −0
  48. drivers/gpu/drm/ast/ast_mode.c +4 −1
  49. drivers/gpu/drm/bridge/Kconfig +5 −0
  50. drivers/gpu/drm/bridge/adv7511/adv7511.h +1 −0
  51. drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +23 −8
  52. drivers/gpu/drm/bridge/adv7511/adv7533.c +1 −1
  53. drivers/gpu/drm/bridge/analogix/Kconfig +2 −0
  54. drivers/gpu/drm/bridge/analogix/analogix-anx6345.c +1 −1
  55. drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +1 −1
  56. drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.c +1 −1
  57. drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +2 −2
  58. drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +1 −1
  59. drivers/gpu/drm/bridge/analogix/anx7625.c +421 −19
  60. drivers/gpu/drm/bridge/analogix/anx7625.h +73 −7
  61. drivers/gpu/drm/bridge/cadence/Kconfig +1 −0
  62. drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +10 −10
  63. drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +1 −1
  64. drivers/gpu/drm/bridge/chipone-icn6211.c +26 −13
  65. drivers/gpu/drm/bridge/ite-it66121.c +0 −3
  66. drivers/gpu/drm/bridge/lontium-lt9611.c +2 −2
  67. drivers/gpu/drm/bridge/lontium-lt9611uxc.c +2 −2
  68. drivers/gpu/drm/bridge/nwl-dsi.c +3 −5
  69. drivers/gpu/drm/bridge/parade-ps8640.c +28 −5
  70. drivers/gpu/drm/bridge/sii902x.c +99 −30
  71. drivers/gpu/drm/bridge/sil-sii8620.c +1 −1
  72. drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +8 −8
  73. drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +17 −8
  74. drivers/gpu/drm/bridge/tc358767.c +1 −1
  75. drivers/gpu/drm/bridge/tc358775.c +2 −2
  76. drivers/gpu/drm/bridge/ti-sn65dsi83.c +43 −10
  77. drivers/gpu/drm/bridge/ti-sn65dsi86.c +2 −2
  78. drivers/gpu/drm/dp/Makefile +9 −0
  79. drivers/gpu/drm/dp/drm_dp.c +3 −3
  80. drivers/gpu/drm/dp/drm_dp_aux_bus.c +2 −2
  81. drivers/gpu/drm/dp/drm_dp_aux_dev.c +3 −3
  82. drivers/gpu/drm/dp/drm_dp_cec.c +1 −1
  83. drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c +1 −1
  84. drivers/gpu/drm/dp/drm_dp_helper_internal.h +33 −0
  85. drivers/gpu/drm/dp/drm_dp_helper_mod.c +22 −0
  86. drivers/gpu/drm/dp/drm_dp_mst_topology.c +4 −4
  87. drivers/gpu/drm/dp/drm_dp_mst_topology_internal.h +1 −1
  88. drivers/gpu/drm/drm_buddy.c +535 −0
  89. drivers/gpu/drm/drm_color_mgmt.c +4 −0
  90. drivers/gpu/drm/drm_crtc_helper_internal.h +0 −27
  91. drivers/gpu/drm/drm_dsc.c +1 −1
  92. drivers/gpu/drm/drm_edid.c +68 −36
  93. drivers/gpu/drm/drm_kms_helper_common.c +0 −14
  94. drivers/gpu/drm/drm_plane.c +2 −7
  95. drivers/gpu/drm/drm_privacy_screen.c +4 −1
  96. drivers/gpu/drm/drm_privacy_screen_x86.c +17 −0
  97. drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +1 −2
  98. drivers/gpu/drm/exynos/Kconfig +1 −0
  99. drivers/gpu/drm/exynos/exynos_drm_dsi.c +12 −1
  100. drivers/gpu/drm/gma500/cdv_intel_dp.c +4 −10
  101. drivers/gpu/drm/gma500/gma_display.c +2 −4
  102. drivers/gpu/drm/gma500/intel_bios.c +1 −1
  103. drivers/gpu/drm/gma500/mmu.c +4 −4
  104. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +2 −1
  105. drivers/gpu/drm/i915/Kconfig +2 −0
  106. drivers/gpu/drm/i915/Makefile +0 −1
  107. drivers/gpu/drm/i915/display/intel_bios.c +1 −1
  108. drivers/gpu/drm/i915/display/intel_display.c +1 −1
  109. drivers/gpu/drm/i915/display/intel_display_types.h +2 −2
  110. drivers/gpu/drm/i915/display/intel_dp.c +1 −1
  111. drivers/gpu/drm/i915/display/intel_dp_hdcp.c +2 −2
  112. drivers/gpu/drm/i915/display/intel_dp_link_training.h +1 −1
  113. drivers/gpu/drm/i915/display/intel_hdmi.c +3 −3
  114. drivers/gpu/drm/i915/display/intel_lspcon.c +2 −2
  115. drivers/gpu/drm/i915/i915_buddy.c +0 −466
  116. drivers/gpu/drm/i915/i915_buddy.h +0 −143
  117. drivers/gpu/drm/i915/i915_module.c +0 −3
  118. drivers/gpu/drm/i915/i915_scatterlist.c +5 −6
  119. drivers/gpu/drm/i915/i915_ttm_buddy_manager.c +20 −17
  120. drivers/gpu/drm/i915/i915_ttm_buddy_manager.h +2 −2
  121. drivers/gpu/drm/i915/selftests/i915_buddy.c +0 −787
  122. drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +0 −1
  123. drivers/gpu/drm/i915/selftests/intel_memory_region.c +7 −6
  124. drivers/gpu/drm/imx/dcss/dcss-drv.c +2 −1
  125. drivers/gpu/drm/ingenic/ingenic-drm-drv.c +59 −3
  126. drivers/gpu/drm/ingenic/ingenic-drm.h +38 −0
  127. drivers/gpu/drm/meson/meson_drv.c +13 −12
  128. drivers/gpu/drm/meson/meson_osd_afbcd.c +27 −14
  129. drivers/gpu/drm/meson/meson_osd_afbcd.h +1 −0
  130. drivers/gpu/drm/mgag200/mgag200_mode.c +4 −1
  131. drivers/gpu/drm/msm/Kconfig +1 −0
  132. drivers/gpu/drm/msm/dp/dp_audio.c +1 −1
  133. drivers/gpu/drm/msm/dp/dp_aux.h +1 −1
  134. drivers/gpu/drm/msm/dp/dp_catalog.c +1 −1
  135. drivers/gpu/drm/msm/dp/dp_ctrl.c +1 −1
  136. drivers/gpu/drm/msm/edp/edp.h +77 −0
  137. drivers/gpu/drm/msm/edp/edp_ctrl.c +1373 −0
  138. drivers/gpu/drm/mxsfb/mxsfb_drv.c +9 −0
  139. drivers/gpu/drm/nouveau/Kconfig +1 −0
  140. drivers/gpu/drm/nouveau/dispnv50/disp.c +1 −1
  141. drivers/gpu/drm/nouveau/nouveau_connector.h +1 −1
  142. drivers/gpu/drm/nouveau/nouveau_dp.c +16 −1
  143. drivers/gpu/drm/nouveau/nouveau_encoder.h +2 −2
  144. drivers/gpu/drm/nouveau/nouveau_mem.c +2 −1
  145. drivers/gpu/drm/nouveau/nouveau_mem.h +2 −1
  146. drivers/gpu/drm/nouveau/nouveau_ttm.c +7 −6
  147. drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +224 −93
  148. drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h +29 −6
  149. drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c +12 −1
  150. drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c +4 −0
  151. drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c +13 −1
  152. drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c +15 −3
  153. drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c +5 −4
  154. drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +1 −0
  155. drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +4 −4
  156. drivers/gpu/drm/panel/panel-edp.c +19 −2
  157. drivers/gpu/drm/panel/panel-samsung-atna33xc20.c +2 −2
  158. drivers/gpu/drm/panel/panel-simple.c +33 −0
  159. drivers/gpu/drm/panfrost/panfrost_features.h +7 −205
  160. drivers/gpu/drm/panfrost/panfrost_gpu.c +26 −6
  161. drivers/gpu/drm/radeon/atombios_dp.c +1 −1
  162. drivers/gpu/drm/radeon/radeon_connectors.c +2 −2
  163. drivers/gpu/drm/radeon/radeon_dp_mst.c +1 −1
  164. drivers/gpu/drm/radeon/radeon_mode.h +2 −2
  165. drivers/gpu/drm/radeon/radeon_ttm.c +2 −2
  166. drivers/gpu/drm/rockchip/Kconfig +2 −0
  167. drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +2 −2
  168. drivers/gpu/drm/rockchip/cdn-dp-core.c +1 −1
  169. drivers/gpu/drm/rockchip/cdn-dp-core.h +1 −1
  170. drivers/gpu/drm/rockchip/rockchip_lvds.c +1 −1
  171. drivers/gpu/drm/rockchip/rockchip_rgb.c +1 −1
  172. drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c +5 −3
  173. drivers/gpu/drm/selftests/test-drm_plane_helper.c +4 −0
  174. drivers/gpu/drm/stm/drv.c +5 −0
  175. drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +106 −8
  176. drivers/gpu/drm/stm/ltdc.c +647 −163
  177. drivers/gpu/drm/stm/ltdc.h +10 −2
  178. drivers/gpu/drm/tegra/Kconfig +1 −0
  179. drivers/gpu/drm/tegra/dp.c +1 −1
  180. drivers/gpu/drm/tegra/dpaux.c +1 −1
  181. drivers/gpu/drm/tegra/sor.c +1 −1
  182. drivers/gpu/drm/tilcdc/tilcdc_drv.c +1 −3
  183. drivers/gpu/drm/tiny/bochs.c +2 −18
  184. drivers/gpu/drm/tiny/cirrus.c +2 −15
  185. drivers/gpu/drm/tiny/simpledrm.c +17 −5
  186. drivers/gpu/drm/ttm/ttm_bo_util.c +5 −2
  187. drivers/gpu/drm/ttm/ttm_range_manager.c +3 −1
  188. drivers/gpu/drm/ttm/ttm_resource.c +35 −0
  189. drivers/gpu/drm/ttm/ttm_sys_manager.c +2 −1
  190. drivers/gpu/drm/v3d/v3d_drv.c +6 −2
  191. drivers/gpu/drm/vc4/vc4_bo.c +0 −2
  192. drivers/gpu/drm/vc4/vc4_drv.c +29 −4
  193. drivers/gpu/drm/vc4/vc4_hdmi.c +78 −54
  194. drivers/gpu/drm/vc4/vc4_hdmi.h +3 −2
  195. drivers/gpu/drm/vc4/vc4_regs.h +3 −0
  196. drivers/gpu/drm/virtio/virtgpu_gem.c +3 −0
  197. drivers/gpu/drm/vkms/vkms_drv.h +2 −0
  198. drivers/gpu/drm/vkms/vkms_output.c +22 −7
  199. drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +3 −1
  200. drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c +2 −1
  201. drivers/gpu/drm/xlnx/Kconfig +1 −0
  202. drivers/gpu/drm/xlnx/zynqmp_dp.c +1 −1
  203. drivers/platform/chrome/Kconfig +11 −0
  204. drivers/platform/chrome/Makefile +1 −0
  205. drivers/platform/chrome/chromeos_privacy_screen.c +153 −0
  206. drivers/platform/x86/thinkpad_acpi.c +1 −1
  207. drivers/video/fbdev/asiliantfb.c +1 −1
  208. drivers/video/fbdev/core/fbmem.c +26 −3
  209. drivers/video/fbdev/s3c-fb.c +1 −1
  210. drivers/video/fbdev/simplefb.c +45 −20
  211. drivers/video/fbdev/vga16fb.c +5 −0
  212. include/drm/bridge/dw_mipi_dsi.h +3 −1
  213. include/drm/dp/drm_dp_aux_bus.h +0 −0
  214. include/drm/dp/drm_dp_dual_mode_helper.h +0 −0
  215. include/drm/dp/drm_dp_helper.h +2 −5
  216. include/drm/dp/drm_dp_mst_helper.h +1 −1
  217. include/drm/drm_buddy.h +150 −0
  218. include/drm/drm_connector.h +12 −6
  219. include/drm/drm_crtc.h +10 −0
  220. include/drm/drm_dsc.h +1 −1
  221. include/drm/drm_edid.h +2 −2
  222. include/drm/drm_mipi_dbi.h +1 −1
  223. include/drm/drm_modeset_lock.h +1 −0
  224. include/drm/drm_module.h +125 −0
  225. include/drm/drm_plane.h +1 −1
  226. include/drm/drm_privacy_screen_driver.h +12 −1
  227. include/drm/ttm/ttm_resource.h +16 −7
  228. include/linux/dma-buf-map.h +2 −2
  229. include/linux/dma-resv.h +2 −2
  230. include/linux/fb.h +1 −0
  231. include/linux/rwsem.h +1 −1
  232. include/soc/bcm2835/raspberrypi-firmware.h +1 −0
  233. include/uapi/drm/panfrost_drm.h +2 −2
Documentation/devicetree/bindings/display/bridge/lvds-codec.yaml+1−0
@@ -39,6 +39,7 @@ properties: · 38 unmodified lines
3939 - const: lvds-encoder # Generic LVDS encoder compatible fallback
4040 - items:
4141 - enum:
42+ - ti,ds90cf364a # For the DS90CF364A FPD-Link LVDS Receiver
4243 - ti,ds90cf384a # For the DS90CF384A FPD-Link LVDS Receiver
4344 - const: lvds-decoder # Generic LVDS decoders compatible fallback
4445 - enum:
Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml+4−1
@@ -32,6 +32,9 @@ properties: · 31 unmodified lines
3232 maxItems: 1
3333 description: GPIO specifier for bridge_en pin (active high).
3434
35+ vcc-supply:
36+ description: A 1.8V power supply (see regulator/regulator.yaml).
37+
3538 ports:
3639 $ref: /schemas/graph.yaml#/properties/ports
3740
@@ -91,7 +94,6 @@ properties: · 53 unmodified lines
9194 required:
9295 - compatible
9396 - reg
94− - enable-gpios
9597 - ports
9698
9799 allOf:
@@ -133,6 +135,7 @@ examples: · 35 unmodified lines
133135 reg = <0x2d>;
134136
135137 enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
138+ vcc-supply = <&reg_sn65dsi83_1v8>;
136139
137140 ports {
138141 #address-cells = <1>;
Documentation/devicetree/bindings/display/panel/panel-simple.yaml+2−0
@@ -222,6 +222,8 @@ properties: · 221 unmodified lines
222222 - logictechno,lttd800480070-l6wh-rt
223223 # Mitsubishi "AA070MC01 7.0" WVGA TFT LCD panel
224224 - mitsubishi,aa070mc01-ca1
225+ # Multi-Inno Technology Co.,Ltd MI0700S4T-6 7" 800x480 TFT Resistive Touch Module
226+ - multi-inno,mi0700s4t-6
225227 # Multi-Inno Technology Co.,Ltd MI1010AIT-1CP 10.1" 1280x800 LVDS IPS Cap Touch Mod.
226228 - multi-inno,mi1010ait-1cp
227229 # NEC LCD Technologies, Ltd. 12.1" WXGA (1280x800) LVDS TFT LCD panel
Documentation/devicetree/bindings/display/panel/sony,acx424akp.yaml+9−2
@@ -4,7 +4,12 @@ · 3 unmodified lines
44 $id: http://devicetree.org/schemas/display/panel/sony,acx424akp.yaml#
55 $schema: http://devicetree.org/meta-schemas/core.yaml#
66
7−title: Sony ACX424AKP 4" 480x864 AMOLED panel
7+title: Sony ACX424AKP/ACX424AKM 4" 480x864/480x854 AMOLED panel
8+
9+description: The Sony ACX424AKP and ACX424AKM are panels built around
10+ the Novatek NT35560 display controller. The only difference is that
11+ the AKM is configured to use 10 pixels less in the Y axis than the
12+ AKP.
813
914 maintainers:
1015 - Linus Walleij <linus.walleij@linaro.org>
@@ -14,7 +19,9 @@ allOf: · 3 unmodified lines
1419
1520 properties:
1621 compatible:
17− const: sony,acx424akp
22+ enum:
23+ - sony,acx424akp
24+ - sony,acx424akm
1825 reg: true
1926 reset-gpios: true
2027 vddi-supply:
Documentation/gpu/drm-internals.rst+6−0
@@ -75,6 +75,12 @@ update it, its value is mostly useless. The DRM core prints it to the · 74 unmodified lines
7575 kernel log at initialization time and passes it to userspace through the
7676 DRM_IOCTL_VERSION ioctl.
7777
78+Module Initialization
79+---------------------
80+
81+.. kernel-doc:: include/drm/drm_module.h
82+ :doc: overview
83+
7884 Managing Ownership of the Framebuffer Aperture
7985 ----------------------------------------------
8086
Documentation/gpu/drm-kms-helpers.rst+13−13
@@ -232,34 +232,34 @@ HDCP Helper Functions Reference · 231 unmodified lines
232232 Display Port Helper Functions Reference
233233 =======================================
234234
235−.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
235+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp.c
236236 :doc: dp helpers
237237
238−.. kernel-doc:: include/drm/drm_dp_helper.h
238+.. kernel-doc:: include/drm/dp/drm_dp_helper.h
239239 :internal:
240240
241−.. kernel-doc:: drivers/gpu/drm/drm_dp_helper.c
241+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp.c
242242 :export:
243243
244244 Display Port CEC Helper Functions Reference
245245 ===========================================
246246
247−.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
247+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_cec.c
248248 :doc: dp cec helpers
249249
250−.. kernel-doc:: drivers/gpu/drm/drm_dp_cec.c
250+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_cec.c
251251 :export:
252252
253253 Display Port Dual Mode Adaptor Helper Functions Reference
254254 =========================================================
255255
256−.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
256+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
257257 :doc: dp dual mode helpers
258258
259−.. kernel-doc:: include/drm/drm_dp_dual_mode_helper.h
259+.. kernel-doc:: include/drm/dp/drm_dp_dual_mode_helper.h
260260 :internal:
261261
262−.. kernel-doc:: drivers/gpu/drm/drm_dp_dual_mode_helper.c
262+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
263263 :export:
264264
265265 Display Port MST Helpers
@@ -268,19 +268,19 @@ Display Port MST Helpers · 2 unmodified lines
268268 Overview
269269 --------
270270
271−.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
271+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
272272 :doc: dp mst helper
273273
274−.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
274+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
275275 :doc: Branch device and port refcounting
276276
277277 Functions Reference
278278 -------------------
279279
280−.. kernel-doc:: include/drm/drm_dp_mst_helper.h
280+.. kernel-doc:: include/drm/dp/drm_dp_mst_helper.h
281281 :internal:
282282
283−.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
283+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
284284 :export:
285285
286286 Topology Lifetime Internals
@@ -289,7 +289,7 @@ Topology Lifetime Internals · 2 unmodified lines
289289 These functions aren't exported to drivers, but are documented here to help make
290290 the MST topology helpers easier to understand
291291
292−.. kernel-doc:: drivers/gpu/drm/drm_dp_mst_topology.c
292+.. kernel-doc:: drivers/gpu/drm/dp/drm_dp_mst_topology.c
293293 :functions: drm_dp_mst_topology_try_get_mstb drm_dp_mst_topology_get_mstb
294294 drm_dp_mst_topology_put_mstb
295295 drm_dp_mst_topology_try_get_port drm_dp_mst_topology_get_port
Documentation/gpu/drm-kms.rst+3−3
@@ -423,12 +423,12 @@ Connector Functions Reference · 422 unmodified lines
423423 Writeback Connectors
424424 --------------------
425425
426−.. kernel-doc:: include/drm/drm_writeback.h
427− :internal:
428−
429426 .. kernel-doc:: drivers/gpu/drm/drm_writeback.c
430427 :doc: overview
431428
429+.. kernel-doc:: include/drm/drm_writeback.h
430+ :internal:
431+
432432 .. kernel-doc:: drivers/gpu/drm/drm_writeback.c
433433 :export:
434434
Documentation/gpu/drm-mm.rst+1−1
@@ -8,7 +8,7 @@ the very dynamic nature of many of that data, managing graphics memory · 7 unmodified lines
88 efficiently is thus crucial for the graphics stack and plays a central
99 role in the DRM infrastructure.
1010
11−The DRM core includes two memory managers, namely Translation Table Maps
11+The DRM core includes two memory managers, namely Translation Table Manager
1212 (TTM) and Graphics Execution Manager (GEM). TTM was the first DRM memory
1313 manager to be developed and tried to be a one-size-fits-them all
1414 solution. It provides a single userspace API to accommodate the need of
Documentation/gpu/todo.rst+15−0
@@ -467,6 +467,21 @@ Contact: Thomas Zimmermann <tzimmermann@suse.de> · 466 unmodified lines
467467
468468 Level: Intermediate
469469
470+Request memory regions in all drivers
471+-------------------------------------
472+
473+Go through all drivers and add code to request the memory regions that the
474+driver uses. This requires adding calls to request_mem_region(),
475+pci_request_region() or similar functions. Use helpers for managed cleanup
476+where possible.
477+
478+Drivers are pretty bad at doing this and there used to be conflicts among
479+DRM and fbdev drivers. Still, it's the correct thing to do.
480+
481+Contact: Thomas Zimmermann <tzimmermann@suse.de>
482+
483+Level: Starter
484+
470485
471486 Core refactorings
472487 =================
Documentation/gpu/vkms.rst+0−2
@@ -124,8 +124,6 @@ Add Plane Features · 123 unmodified lines
124124
125125 There's lots of plane features we could add support for:
126126
127−- Multiple overlay planes. [Good to get started]
128−
129127 - Clearing primary plane: clear primary plane before plane composition (at the
130128 start) for correctness of pixel blend ops. It also guarantees alpha channel
131129 is cleared in the target buffer for stable crc. [Good to get started]
drivers/char/agp/ati-agp.c+6−2
@@ -55,7 +55,7 @@ static struct _ati_generic_private { · 54 unmodified lines
5555
5656 static int ati_create_page_map(struct ati_page_map *page_map)
5757 {
58− int i, err = 0;
58+ int i, err;
5959
6060 page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
6161 if (page_map->real == NULL)
@@ -63,6 +63,10 @@ static int ati_create_page_map(struct ati_page_map *page_map) · 1 unmodified line
6363
6464 set_memory_uc((unsigned long)page_map->real, 1);
6565 err = map_page_into_agp(virt_to_page(page_map->real));
66+ if (err) {
67+ free_page((unsigned long)page_map->real);
68+ return err;
69+ }
6670 page_map->remapped = page_map->real;
6771
6872 for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
@@ -303,7 +307,7 @@ static int ati_insert_memory(struct agp_memory * mem, · 234 unmodified lines
303307 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
304308 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
305309 cur_gatt = GET_GATT(addr);
306− writel(agp_bridge->driver->mask_memory(agp_bridge,
310+ writel(agp_bridge->driver->mask_memory(agp_bridge,
307311 page_to_phys(mem->pages[i]),
308312 mem->type),
309313 cur_gatt+GET_GATT_OFF(addr));
drivers/char/agp/backend.c+2−0
@@ -62,6 +62,7 @@ EXPORT_SYMBOL(agp_find_bridge); · 61 unmodified lines
6262
6363 /**
6464 * agp_backend_acquire - attempt to acquire an agp backend.
65+ * @pdev: the PCI device
6566 *
6667 */
6768 struct agp_bridge_data *agp_backend_acquire(struct pci_dev *pdev)
@@ -83,6 +84,7 @@ EXPORT_SYMBOL(agp_backend_acquire); · 15 unmodified lines
8384
8485 /**
8586 * agp_backend_release - release the lock on the agp backend.
87+ * @bridge: the AGP backend to release
8688 *
8789 * The caller must insure that the graphics aperture translation table
8890 * is read for use by another entity.
drivers/char/agp/frontend.c+3−1
@@ -39,7 +39,9 @@ · 38 unmodified lines
3939 #include <linux/fs.h>
4040 #include <linux/sched.h>
4141 #include <linux/uaccess.h>
42+
4243 #include "agp.h"
44+#include "compat_ioctl.h"
4345
4446 struct agp_front_data agp_fe;
4547
@@ -1017,7 +1019,7 @@ static long agp_ioctl(struct file *file, · 971 unmodified lines
10171019 case AGPIOC_UNBIND:
10181020 ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg);
10191021 break;
1020−
1022+
10211023 case AGPIOC_CHIPSET_FLUSH:
10221024 break;
10231025 }
drivers/char/agp/nvidia-agp.c+2−1
@@ -261,7 +261,8 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type · 260 unmodified lines
261261 static void nvidia_tlbflush(struct agp_memory *mem)
262262 {
263263 unsigned long end;
264− u32 wbc_reg, temp;
264+ u32 wbc_reg;
265+ u32 __maybe_unused temp;
265266 int i;
266267
267268 /* flush chipset */
drivers/char/agp/sworks-agp.c+1−4
@@ -262,13 +262,10 @@ static void serverworks_tlbflush(struct agp_memory *temp) · 261 unmodified lines
262262
263263 static int serverworks_configure(void)
264264 {
265− struct aper_size_info_lvl2 *current_size;
266265 u32 temp;
267266 u8 enable_reg;
268267 u16 cap_reg;
269268
270− current_size = A_SIZE_LVL2(agp_bridge->current_size);
271−
272269 /* Get the memory mapped registers */
273270 pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp);
274271 temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
@@ -350,7 +347,7 @@ static int serverworks_insert_memory(struct agp_memory *mem, · 75 unmodified lines
350347 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
351348 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
352349 cur_gatt = SVRWRKS_GET_GATT(addr);
353− writel(agp_bridge->driver->mask_memory(agp_bridge,
350+ writel(agp_bridge->driver->mask_memory(agp_bridge,
354351 page_to_phys(mem->pages[i]), mem->type),
355352 cur_gatt+GET_GATT_OFF(addr));
356353 }
drivers/char/agp/via-agp.c+0−3
@@ -128,9 +128,6 @@ static int via_fetch_size_agp3(void) · 127 unmodified lines
128128 static int via_configure_agp3(void)
129129 {
130130 u32 temp;
131− struct aper_size_info_16 *current_size;
132−
133− current_size = A_SIZE_16(agp_bridge->current_size);
134131
135132 /* address to map to */
136133 agp_bridge->gart_bus_addr = pci_bus_address(agp_bridge->dev,
drivers/dma-buf/dma-resv.c+17−29
@@ -542,57 +542,45 @@ EXPORT_SYMBOL(dma_resv_copy_fences); · 541 unmodified lines
542542 * dma_resv_get_fences - Get an object's shared and exclusive
543543 * fences without update side lock held
544544 * @obj: the reservation object
545− * @fence_excl: the returned exclusive fence (or NULL)
546− * @shared_count: the number of shared fences returned
547− * @shared: the array of shared fence ptrs returned (array is krealloc'd to
548− * the required size, and must be freed by caller)
545+ * @write: true if we should return all fences
546+ * @num_fences: the number of fences returned
547+ * @fences: the array of fence ptrs returned (array is krealloc'd to the
548+ * required size, and must be freed by caller)
549549 *
550− * Retrieve all fences from the reservation object. If the pointer for the
551− * exclusive fence is not specified the fence is put into the array of the
552− * shared fences as well. Returns either zero or -ENOMEM.
550+ * Retrieve all fences from the reservation object.
551+ * Returns either zero or -ENOMEM.
553552 */
554−int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **fence_excl,
555− unsigned int *shared_count, struct dma_fence ***shared)
553+int dma_resv_get_fences(struct dma_resv *obj, bool write,
554+ unsigned int *num_fences, struct dma_fence ***fences)
556555 {
557556 struct dma_resv_iter cursor;
558557 struct dma_fence *fence;
559558
560− *shared_count = 0;
561− *shared = NULL;
559+ *num_fences = 0;
560+ *fences = NULL;
562561
563− if (fence_excl)
564− *fence_excl = NULL;
565−
566− dma_resv_iter_begin(&cursor, obj, true);
562+ dma_resv_iter_begin(&cursor, obj, write);
567563 dma_resv_for_each_fence_unlocked(&cursor, fence) {
568564
569565 if (dma_resv_iter_is_restarted(&cursor)) {
570566 unsigned int count;
571567
572− while (*shared_count)
573− dma_fence_put((*shared)[--(*shared_count)]);
574−
575− if (fence_excl)
576− dma_fence_put(*fence_excl);
568+ while (*num_fences)
569+ dma_fence_put((*fences)[--(*num_fences)]);
577570
578− count = cursor.shared_count;
579− count += fence_excl ? 0 : 1;
571+ count = cursor.shared_count + 1;
580572
581573 /* Eventually re-allocate the array */
582− *shared = krealloc_array(*shared, count,
574+ *fences = krealloc_array(*fences, count,
583575 sizeof(void *),
584576 GFP_KERNEL);
585− if (count && !*shared) {
577+ if (count && !*fences) {
586578 dma_resv_iter_end(&cursor);
587579 return -ENOMEM;
588580 }
589581 }
590582
591− dma_fence_get(fence);
592− if (dma_resv_iter_is_exclusive(&cursor) && fence_excl)
593− *fence_excl = fence;
594− else
595− (*shared)[(*shared_count)++] = fence;
583+ (*fences)[(*num_fences)++] = dma_fence_get(fence);
596584 }
597585 dma_resv_iter_end(&cursor);
598586
drivers/dma-buf/st-dma-resv.c+5−21
@@ -275,7 +275,7 @@ static int test_shared_for_each_unlocked(void *arg) · 274 unmodified lines
275275
276276 static int test_get_fences(void *arg, bool shared)
277277 {
278− struct dma_fence *f, *excl = NULL, **fences = NULL;
278+ struct dma_fence *f, **fences = NULL;
279279 struct dma_resv resv;
280280 int r, i;
281281
@@ -304,35 +304,19 @@ static int test_get_fences(void *arg, bool shared) · 22 unmodified lines
304304 }
305305 dma_resv_unlock(&resv);
306306
307− r = dma_resv_get_fences(&resv, &excl, &i, &fences);
307+ r = dma_resv_get_fences(&resv, shared, &i, &fences);
308308 if (r) {
309309 pr_err("get_fences failed\n");
310310 goto err_free;
311311 }
312312
313− if (shared) {
314− if (excl != NULL) {
315− pr_err("get_fences returned unexpected excl fence\n");
316− goto err_free;
317− }
318− if (i != 1 || fences[0] != f) {
319− pr_err("get_fences returned unexpected shared fence\n");
320− goto err_free;
321− }
322− } else {
323− if (excl != f) {
324− pr_err("get_fences returned unexpected excl fence\n");
325− goto err_free;
326− }
327− if (i != 0) {
328− pr_err("get_fences returned unexpected shared fence\n");
329− goto err_free;
330− }
313+ if (i != 1 || fences[0] != f) {
314+ pr_err("get_fences returned unexpected fence\n");
315+ goto err_free;
331316 }
332317
333318 dma_fence_signal(f);
334319 err_free:
335− dma_fence_put(excl);
336320 while (i--)
337321 dma_fence_put(fences[i]);
338322 kfree(fences);
drivers/dma-buf/udmabuf.c+4−0
@@ -190,6 +190,10 @@ static long udmabuf_create(struct miscdevice *device, · 189 unmodified lines
190190 if (ubuf->pagecount > pglimit)
191191 goto err;
192192 }
193+
194+ if (!ubuf->pagecount)
195+ goto err;
196+
193197 ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->pages),
194198 GFP_KERNEL);
195199 if (!ubuf->pages) {
drivers/firmware/sysfb_simplefb.c+1−1
@@ -99,7 +99,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si, · 98 unmodified lines
9999
100100 /* setup IORESOURCE_MEM as framebuffer memory */
101101 memset(&res, 0, sizeof(res));
102− res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
102+ res.flags = IORESOURCE_MEM;
103103 res.name = simplefb_resname;
104104 res.start = base;
105105 res.end = res.start + length - 1;
drivers/gpu/drm/Kconfig+15−0
@@ -68,6 +68,7 @@ config DRM_DEBUG_SELFTEST · 67 unmodified lines
6868 depends on DRM
6969 depends on DEBUG_KERNEL
7070 select PRIME_NUMBERS
71+ select DRM_DP_HELPER
7172 select DRM_LIB_RANDOM
7273 select DRM_KMS_HELPER
7374 select DRM_EXPORT_FOR_TESTS if m
@@ -80,6 +81,12 @@ config DRM_DEBUG_SELFTEST · 6 unmodified lines
8081
8182 If in doubt, say "N".
8283
84+config DRM_DP_HELPER
85+ tristate
86+ depends on DRM
87+ help
88+ DRM helpers for DisplayPort.
89+
8390 config DRM_KMS_HELPER
8491 tristate
8592 depends on DRM
@@ -198,6 +205,12 @@ config DRM_TTM · 112 unmodified lines
198205 GPU memory types. Will be enabled automatically if a device driver
199206 uses it.
200207
208+config DRM_BUDDY
209+ tristate
210+ depends on DRM
211+ help
212+ A page based buddy allocator
213+
201214 config DRM_VRAM_HELPER
202215 tristate
203216 depends on DRM
@@ -236,6 +249,7 @@ config DRM_RADEON · 32 unmodified lines
236249 depends on DRM && PCI && MMU
237250 depends on AGP || !AGP
238251 select FW_LOADER
252+ select DRM_DP_HELPER
239253 select DRM_KMS_HELPER
240254 select DRM_TTM
241255 select DRM_TTM_HELPER
@@ -256,6 +270,7 @@ config DRM_AMDGPU · 14 unmodified lines
256270 tristate "AMD GPU"
257271 depends on DRM && PCI && MMU
258272 select FW_LOADER
273+ select DRM_DP_HELPER
259274 select DRM_KMS_HELPER
260275 select DRM_SCHED
261276 select DRM_TTM
drivers/gpu/drm/Makefile+6−8
@@ -31,8 +31,6 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o · 30 unmodified lines
3131 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
3232 drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o drm_privacy_screen_x86.o
3333
34−obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o
35−
3634 obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
3735
3836 drm_cma_helper-y := drm_gem_cma_helper.o
@@ -42,27 +40,26 @@ obj-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_cma_helper.o · 3 unmodified lines
4240 drm_shmem_helper-y := drm_gem_shmem_helper.o
4341 obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
4442
43+obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o
44+
4545 drm_vram_helper-y := drm_gem_vram_helper.o
4646 obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
4747
4848 drm_ttm_helper-y := drm_gem_ttm_helper.o
4949 obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
5050
51−drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
51+drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
5252 drm_dsc.o drm_encoder_slave.o drm_flip_work.o drm_hdcp.o \
5353 drm_probe_helper.o \
54− drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
55− drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
54+ drm_plane_helper.o drm_atomic_helper.o \
55+ drm_kms_helper_common.o \
5656 drm_simple_kms_helper.o drm_modeset_helper.o \
5757 drm_scdc_helper.o drm_gem_atomic_helper.o \
5858 drm_gem_framebuffer_helper.o \
5959 drm_atomic_state_helper.o drm_damage_helper.o \
6060 drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
61−
6261 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
6362 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
64−drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
65−drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
6663
6764 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
6865 obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
@@ -72,6 +69,7 @@ obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o · 3 unmodified lines
7269 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
7370 obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
7471 obj-y += arm/
72+obj-y += dp/
7573 obj-$(CONFIG_DRM_TTM) += ttm/
7674 obj-$(CONFIG_DRM_SCHED) += scheduler/
7775 obj-$(CONFIG_DRM_TDFX) += tdfx/
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c+2−2
@@ -26,7 +26,7 @@ · 25 unmodified lines
2626
2727 #include <drm/drm_edid.h>
2828 #include <drm/drm_fb_helper.h>
29−#include <drm/drm_dp_helper.h>
29+#include <drm/dp/drm_dp_helper.h>
3030 #include <drm/drm_probe_helper.h>
3131 #include <drm/amdgpu_drm.h>
3232 #include "amdgpu.h"
@@ -175,7 +175,7 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector) · 142 unmodified lines
175175
176176 /* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
177177 if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
178− if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
178+ if ((connector->display_info.edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30) &&
179179 (mode_clock * 5/4 <= max_tmds_clock))
180180 bpc = 10;
181181 else
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+1−4
@@ -1274,14 +1274,11 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 1273 unmodified lines
12741274 /*
12751275 * Work around dma_resv shortcommings by wrapping up the
12761276 * submission in a dma_fence_chain and add it as exclusive
1277− * fence, but first add the submission as shared fence to make
1278− * sure that shared fences never signal before the exclusive
1279− * one.
1277+ * fence.
12801278 */
12811279 dma_fence_chain_init(chain, dma_resv_excl_fence(resv),
12821280 dma_fence_get(p->fence), 1);
12831281
1284− dma_resv_add_shared_fence(resv, p->fence);
12851282 rcu_assign_pointer(resv->fence_excl, &chain->base);
12861283 e->chain = NULL;
12871284 }
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c+4−2
@@ -200,8 +200,10 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, · 199 unmodified lines
200200 goto unpin;
201201 }
202202
203− r = dma_resv_get_fences(new_abo->tbo.base.resv, NULL,
204− &work->shared_count, &work->shared);
203+ /* TODO: Unify this with other drivers */
204+ r = dma_resv_get_fences(new_abo->tbo.base.resv, true,
205+ &work->shared_count,
206+ &work->shared);
205207 if (unlikely(r != 0)) {
206208 DRM_ERROR("failed to get fences for buffer\n");
207209 goto unpin;
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c+0−6
@@ -226,12 +226,6 @@ static void amdgpu_gem_object_close(struct drm_gem_object *obj, · 225 unmodified lines
226226 if (!amdgpu_vm_ready(vm))
227227 goto out_unlock;
228228
229− fence = dma_resv_excl_fence(bo->tbo.base.resv);
230− if (fence) {
231− amdgpu_bo_fence(bo, fence, true);
232− fence = NULL;
233− }
234−
235229 r = amdgpu_vm_clear_freed(adev, vm, &fence);
236230 if (r || !fence)
237231 goto out_unlock;
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c+4−1
@@ -167,6 +167,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, · 166 unmodified lines
167167 return 0;
168168
169169 err_free:
170+ ttm_resource_fini(man, &node->base.base);
170171 kfree(node);
171172
172173 err_out:
@@ -198,6 +199,7 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man, · 25 unmodified lines
198199 if (!(res->placement & TTM_PL_FLAG_TEMPORARY))
199200 atomic64_sub(res->num_pages, &mgr->used);
200201
202+ ttm_resource_fini(man, res);
201203 kfree(node);
202204 }
203205
@@ -286,7 +288,8 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size) · 82 unmodified lines
286288 man->use_tt = true;
287289 man->func = &amdgpu_gtt_mgr_func;
288290
289− ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
291+ ttm_resource_manager_init(man, &adev->mman.bdev,
292+ gtt_size >> PAGE_SHIFT);
290293
291294 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
292295 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c+1−1
@@ -112,7 +112,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv, · 111 unmodified lines
112112 unsigned count;
113113 int r;
114114
115− r = dma_resv_get_fences(resv, NULL, &count, &fences);
115+ r = dma_resv_get_fences(resv, true, &count, &fences);
116116 if (r)
117117 goto fallback;
118118
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h+2−2
@@ -33,7 +33,7 @@ · 32 unmodified lines
3333 #include <drm/drm_crtc.h>
3434 #include <drm/drm_edid.h>
3535 #include <drm/drm_encoder.h>
36−#include <drm/drm_dp_helper.h>
36+#include <drm/dp/drm_dp_helper.h>
3737 #include <drm/drm_fixed.h>
3838 #include <drm/drm_crtc_helper.h>
3939 #include <drm/drm_fb_helper.h>
@@ -44,7 +44,7 @@ · 4 unmodified lines
4444 #include <linux/hrtimer.h>
4545 #include "amdgpu_irq.h"
4646
47−#include <drm/drm_dp_mst_helper.h>
47+#include <drm/dp/drm_dp_mst_helper.h>
4848 #include "modules/inc/mod_freesync.h"
4949 #include "amdgpu_dm_irq_params.h"
5050
drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c+2−1
@@ -95,6 +95,7 @@ static void amdgpu_preempt_mgr_del(struct ttm_resource_manager *man, · 94 unmodified lines
9595 struct amdgpu_preempt_mgr *mgr = to_preempt_mgr(man);
9696
9797 atomic64_sub(res->num_pages, &mgr->used);
98+ ttm_resource_fini(man, res);
9899 kfree(res);
99100 }
100101
@@ -152,7 +153,7 @@ int amdgpu_preempt_mgr_init(struct amdgpu_device *adev) · 51 unmodified lines
152153 man->use_tt = true;
153154 man->func = &amdgpu_preempt_mgr_func;
154155
155− ttm_resource_manager_init(man, (1 << 30));
156+ ttm_resource_manager_init(man, &adev->mman.bdev, (1 << 30));
156157
157158 atomic64_set(&mgr->used, 0);
158159
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+5−5
@@ -2087,7 +2087,7 @@ static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused) · 2086 unmodified lines
20872087 TTM_PL_VRAM);
20882088 struct drm_printer p = drm_seq_file_printer(m);
20892089
2090− man->func->debug(man, &p);
2090+ ttm_resource_manager_debug(man, &p);
20912091 return 0;
20922092 }
20932093
@@ -2105,7 +2105,7 @@ static int amdgpu_mm_tt_table_show(struct seq_file *m, void *unused) · 11 unmodified lines
21052105 TTM_PL_TT);
21062106 struct drm_printer p = drm_seq_file_printer(m);
21072107
2108− man->func->debug(man, &p);
2108+ ttm_resource_manager_debug(man, &p);
21092109 return 0;
21102110 }
21112111
@@ -2116,7 +2116,7 @@ static int amdgpu_mm_gds_table_show(struct seq_file *m, void *unused) · 4 unmodified lines
21162116 AMDGPU_PL_GDS);
21172117 struct drm_printer p = drm_seq_file_printer(m);
21182118
2119− man->func->debug(man, &p);
2119+ ttm_resource_manager_debug(man, &p);
21202120 return 0;
21212121 }
21222122
@@ -2127,7 +2127,7 @@ static int amdgpu_mm_gws_table_show(struct seq_file *m, void *unused) · 4 unmodified lines
21272127 AMDGPU_PL_GWS);
21282128 struct drm_printer p = drm_seq_file_printer(m);
21292129
2130− man->func->debug(man, &p);
2130+ ttm_resource_manager_debug(man, &p);
21312131 return 0;
21322132 }
21332133
@@ -2138,7 +2138,7 @@ static int amdgpu_mm_oa_table_show(struct seq_file *m, void *unused) · 4 unmodified lines
21382138 AMDGPU_PL_OA);
21392139 struct drm_printer p = drm_seq_file_printer(m);
21402140
2141− man->func->debug(man, &p);
2141+ ttm_resource_manager_debug(man, &p);
21422142 return 0;
21432143 }
21442144
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c+4−1
@@ -472,6 +472,7 @@ error_free: · 471 unmodified lines
472472 while (i--)
473473 drm_mm_remove_node(&node->mm_nodes[i]);
474474 spin_unlock(&mgr->lock);
475+ ttm_resource_fini(man, &node->base);
475476 kvfree(node);
476477
477478 error_sub:
@@ -511,6 +512,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man, · 33 unmodified lines
511512 atomic64_sub(usage, &mgr->usage);
512513 atomic64_sub(vis_usage, &mgr->vis_usage);
513514
515+ ttm_resource_fini(man, res);
514516 kvfree(node);
515517 }
516518
@@ -689,7 +691,8 @@ int amdgpu_vram_mgr_init(struct amdgpu_device *adev) · 172 unmodified lines
689691 struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
690692 struct ttm_resource_manager *man = &mgr->manager;
691693
692− ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
694+ ttm_resource_manager_init(man, &adev->mman.bdev,
695+ adev->gmc.real_vram_size >> PAGE_SHIFT);
693696
694697 man->func = &amdgpu_vram_mgr_func;
695698
drivers/gpu/drm/amd/amdgpu/atombios_dp.c+1−1
@@ -34,7 +34,7 @@ · 33 unmodified lines
3434 #include "atombios_dp.h"
3535 #include "amdgpu_connectors.h"
3636 #include "amdgpu_atombios.h"
37−#include <drm/drm_dp_helper.h>
37+#include <drm/dp/drm_dp_helper.h>
3838
3939 /* move these to drm_dp_helper.c/h */
4040 #define DP_LINK_CONFIGURATION_SIZE 9
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+2−2
@@ -76,7 +76,7 @@ · 75 unmodified lines
7676 #include <drm/drm_atomic.h>
7777 #include <drm/drm_atomic_uapi.h>
7878 #include <drm/drm_atomic_helper.h>
79−#include <drm/drm_dp_mst_helper.h>
79+#include <drm/dp/drm_dp_mst_helper.h>
8080 #include <drm/drm_fb_helper.h>
8181 #include <drm/drm_fourcc.h>
8282 #include <drm/drm_edid.h>
@@ -5856,7 +5856,7 @@ static void fill_stream_properties_from_drm_display_mode( · 5773 unmodified lines
58565856 else if (drm_mode_is_420_also(info, mode_in)
58575857 && aconnector->force_yuv420_output)
58585858 timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
5859− else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)
5859+ else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
58605860 && stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
58615861 timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
58625862 else
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h+1−1
@@ -29,7 +29,7 @@ · 28 unmodified lines
2929 #include <drm/drm_atomic.h>
3030 #include <drm/drm_connector.h>
3131 #include <drm/drm_crtc.h>
32−#include <drm/drm_dp_mst_helper.h>
32+#include <drm/dp/drm_dp_mst_helper.h>
3333 #include <drm/drm_plane.h>
3434
3535 /*
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c+2−2
@@ -25,8 +25,8 @@ · 24 unmodified lines
2525
2626 #include <drm/drm_atomic.h>
2727 #include <drm/drm_atomic_helper.h>
28−#include <drm/drm_dp_mst_helper.h>
29−#include <drm/drm_dp_helper.h>
28+#include <drm/dp/drm_dp_mst_helper.h>
29+#include <drm/dp/drm_dp_helper.h>
3030 #include "dm_services.h"
3131 #include "amdgpu.h"
3232 #include "amdgpu_dm.h"
drivers/gpu/drm/amd/display/dc/core/dc_link_dpcd.c+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727 #include <dc_link.h>
2828 #include <inc/link_hwss.h>
2929 #include <inc/link_dpcd.h>
30−#include "drm/drm_dp_helper.h"
30+#include <drm/dp/drm_dp_helper.h>
3131 #include <dc_dp_types.h>
3232 #include "dm_helpers.h"
3333
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c+1−1
@@ -25,7 +25,7 @@ · 24 unmodified lines
2525 #include <drm/drm_dsc.h>
2626 #include "dc_hw_types.h"
2727 #include "dsc.h"
28−#include <drm/drm_dp_helper.h>
28+#include <drm/dp/drm_dp_helper.h>
2929 #include "dc.h"
3030 #include "rc_calc.h"
3131 #include "fixed31_32.h"
drivers/gpu/drm/amd/display/dc/os_types.h+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
3636 #include <asm/byteorder.h>
3737
3838 #include <drm/drm_print.h>
39−#include <drm/drm_dp_helper.h>
39+#include <drm/dp/drm_dp_helper.h>
4040
4141 #include "cgs_common.h"
4242
drivers/gpu/drm/amd/display/include/dpcd_defs.h+1−1
@@ -26,7 +26,7 @@ · 25 unmodified lines
2626 #ifndef __DAL_DPCD_DEFS_H__
2727 #define __DAL_DPCD_DEFS_H__
2828
29−#include <drm/drm_dp_helper.h>
29+#include <drm/dp/drm_dp_helper.h>
3030 #ifndef DP_SINK_HW_REVISION_START // can remove this once the define gets into linux drm_dp_helper.h
3131 #define DP_SINK_HW_REVISION_START 0x409
3232 #endif
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
3030 #include "hdcp_log.h"
3131
3232 #include <drm/drm_hdcp.h>
33−#include <drm/drm_dp_helper.h>
33+#include <drm/dp/drm_dp_helper.h>
3434
3535 enum mod_hdcp_trans_input_result {
3636 UNKNOWN = 0,
drivers/gpu/drm/arm/display/komeda/d71/d71_component.c+6−6
@@ -1078,11 +1078,11 @@ static void d71_improc_update(struct komeda_component *c, · 1077 unmodified lines
10781078 mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
10791079
10801080 /* config color format */
1081− if (st->color_format == DRM_COLOR_FORMAT_YCRCB420)
1081+ if (st->color_format == DRM_COLOR_FORMAT_YCBCR420)
10821082 ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
1083− else if (st->color_format == DRM_COLOR_FORMAT_YCRCB422)
1083+ else if (st->color_format == DRM_COLOR_FORMAT_YCBCR422)
10841084 ctrl |= IPS_CTRL_YUV | IPS_CTRL_CHD422;
1085− else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
1085+ else if (st->color_format == DRM_COLOR_FORMAT_YCBCR444)
10861086 ctrl |= IPS_CTRL_YUV;
10871087
10881088 malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
@@ -1144,11 +1144,11 @@ static int d71_improc_init(struct d71_dev *d71, · 55 unmodified lines
11441144 improc = to_improc(c);
11451145 improc->supported_color_depths = BIT(8) | BIT(10);
11461146 improc->supported_color_formats = DRM_COLOR_FORMAT_RGB444 |
1147− DRM_COLOR_FORMAT_YCRCB444 |
1148− DRM_COLOR_FORMAT_YCRCB422;
1147+ DRM_COLOR_FORMAT_YCBCR444 |
1148+ DRM_COLOR_FORMAT_YCBCR422;
11491149 value = malidp_read32(reg, BLK_INFO);
11501150 if (value & IPS_INFO_CHD420)
1151− improc->supported_color_formats |= DRM_COLOR_FORMAT_YCRCB420;
1151+ improc->supported_color_formats |= DRM_COLOR_FORMAT_YCBCR420;
11521152
11531153 improc->supports_csc = true;
11541154 improc->supports_gamma = true;
drivers/gpu/drm/arm/display/komeda/komeda_drv.c+2−1
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/platform_device.h>
1010 #include <linux/component.h>
1111 #include <linux/pm_runtime.h>
12+#include <drm/drm_module.h>
1213 #include <drm/drm_of.h>
1314 #include "komeda_dev.h"
1415 #include "komeda_kms.h"
@@ -198,7 +199,7 @@ static struct platform_driver komeda_platform_driver = { · 183 unmodified lines
198199 },
199200 };
200201
201−module_platform_driver(komeda_platform_driver);
202+drm_module_platform_driver(komeda_platform_driver);
202203
203204 MODULE_AUTHOR("James.Qian.Wang <james.qian.wang@arm.com>");
204205 MODULE_DESCRIPTION("Komeda KMS driver");
drivers/gpu/drm/arm/hdlcd_drv.c+2−1
@@ -30,6 +30,7 @@ · 29 unmodified lines
3030 #include <drm/drm_gem_cma_helper.h>
3131 #include <drm/drm_gem_framebuffer_helper.h>
3232 #include <drm/drm_modeset_helper.h>
33+#include <drm/drm_module.h>
3334 #include <drm/drm_of.h>
3435 #include <drm/drm_probe_helper.h>
3536 #include <drm/drm_vblank.h>
@@ -434,7 +435,7 @@ static struct platform_driver hdlcd_platform_driver = { · 398 unmodified lines
434435 },
435436 };
436437
437−module_platform_driver(hdlcd_platform_driver);
438+drm_module_platform_driver(hdlcd_platform_driver);
438439
439440 MODULE_AUTHOR("Liviu Dudau");
440441 MODULE_DESCRIPTION("ARM HDLCD DRM driver");
drivers/gpu/drm/arm/malidp_drv.c+2−1
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include <drm/drm_gem_cma_helper.h>
2626 #include <drm/drm_gem_framebuffer_helper.h>
2727 #include <drm/drm_modeset_helper.h>
28+#include <drm/drm_module.h>
2829 #include <drm/drm_of.h>
2930 #include <drm/drm_probe_helper.h>
3031 #include <drm/drm_vblank.h>
@@ -1008,7 +1009,7 @@ static struct platform_driver malidp_platform_driver = { · 977 unmodified lines
10081009 },
10091010 };
10101011
1011−module_platform_driver(malidp_platform_driver);
1012+drm_module_platform_driver(malidp_platform_driver);
10121013
10131014 MODULE_AUTHOR("Liviu Dudau <Liviu.Dudau@arm.com>");
10141015 MODULE_DESCRIPTION("ARM Mali DP DRM driver");
drivers/gpu/drm/ast/ast_drv.c+2−16
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include <drm/drm_crtc_helper.h>
3535 #include <drm/drm_drv.h>
3636 #include <drm/drm_gem_vram_helper.h>
37+#include <drm/drm_module.h>
3738 #include <drm/drm_probe_helper.h>
3839
3940 #include "ast_drv.h"
@@ -230,22 +231,7 @@ static struct pci_driver ast_pci_driver = { · 190 unmodified lines
230231 .driver.pm = &ast_pm_ops,
231232 };
232233
233−static int __init ast_init(void)
234−{
235− if (drm_firmware_drivers_only() && ast_modeset == -1)
236− return -EINVAL;
237−
238− if (ast_modeset == 0)
239− return -EINVAL;
240− return pci_register_driver(&ast_pci_driver);
241−}
242−static void __exit ast_exit(void)
243−{
244− pci_unregister_driver(&ast_pci_driver);
245−}
246−
247−module_init(ast_init);
248−module_exit(ast_exit);
234+drm_module_pci_driver_if_modeset(ast_pci_driver, ast_modeset);
249235
250236 MODULE_AUTHOR(DRIVER_AUTHOR);
251237 MODULE_DESCRIPTION(DRIVER_DESC);
drivers/gpu/drm/ast/ast_main.c+2−0
@@ -209,6 +209,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) · 208 unmodified lines
209209 if (ast->chip == AST2500 &&
210210 scu_rev == 0x100) /* ast2510 */
211211 ast->support_wide_screen = true;
212+ if (ast->chip == AST2600) /* ast2600 */
213+ ast->support_wide_screen = true;
212214 }
213215 break;
214216 }
drivers/gpu/drm/ast/ast_mode.c+4−1
@@ -471,7 +471,10 @@ static void ast_set_color_reg(struct ast_private *ast, · 470 unmodified lines
471471 static void ast_set_crtthd_reg(struct ast_private *ast)
472472 {
473473 /* Set Threshold */
474− if (ast->chip == AST2300 || ast->chip == AST2400 ||
474+ if (ast->chip == AST2600) {
475+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0);
476+ ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0);
477+ } else if (ast->chip == AST2300 || ast->chip == AST2400 ||
475478 ast->chip == AST2500) {
476479 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78);
477480 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60);
drivers/gpu/drm/bridge/Kconfig+5−0
@@ -30,6 +30,7 @@ config DRM_CDNS_DSI · 29 unmodified lines
3030 config DRM_CHIPONE_ICN6211
3131 tristate "Chipone ICN6211 MIPI-DSI/RGB Converter bridge"
3232 depends on OF
33+ depends on DRM_KMS_HELPER
3334 select DRM_MIPI_DSI
3435 select DRM_PANEL_BRIDGE
3536 help
@@ -183,6 +184,7 @@ config DRM_PARADE_PS8640 · 147 unmodified lines
183184 tristate "Parade PS8640 MIPI DSI to eDP Converter"
184185 depends on OF
185186 select DRM_DP_AUX_BUS
187+ select DRM_DP_HELPER
186188 select DRM_KMS_HELPER
187189 select DRM_MIPI_DSI
188190 select DRM_PANEL
@@ -253,6 +255,7 @@ config DRM_TOSHIBA_TC358764 · 64 unmodified lines
253255 config DRM_TOSHIBA_TC358767
254256 tristate "Toshiba TC358767 eDP bridge"
255257 depends on OF
258+ select DRM_DP_HELPER
256259 select DRM_KMS_HELPER
257260 select REGMAP_I2C
258261 select DRM_PANEL
@@ -272,6 +275,7 @@ config DRM_TOSHIBA_TC358768 · 13 unmodified lines
272275 config DRM_TOSHIBA_TC358775
273276 tristate "Toshiba TC358775 DSI/LVDS bridge"
274277 depends on OF
278+ select DRM_DP_HELPER
275279 select DRM_KMS_HELPER
276280 select REGMAP_I2C
277281 select DRM_PANEL
@@ -299,6 +303,7 @@ config DRM_TI_SN65DSI83 · 21 unmodified lines
299303 config DRM_TI_SN65DSI86
300304 tristate "TI SN65DSI86 DSI to eDP bridge"
301305 depends on OF
306+ select DRM_DP_HELPER
302307 select DRM_KMS_HELPER
303308 select REGMAP_I2C
304309 select DRM_PANEL
drivers/gpu/drm/bridge/adv7511/adv7511.h+1−0
@@ -169,6 +169,7 @@ · 168 unmodified lines
169169 #define ADV7511_PACKET_ENABLE_SPARE2 BIT(1)
170170 #define ADV7511_PACKET_ENABLE_SPARE1 BIT(0)
171171
172+#define ADV7535_REG_POWER2_HPD_OVERRIDE BIT(6)
172173 #define ADV7511_REG_POWER2_HPD_SRC_MASK 0xc0
173174 #define ADV7511_REG_POWER2_HPD_SRC_BOTH 0x00
174175 #define ADV7511_REG_POWER2_HPD_SRC_HPD 0x40
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c+23−8
@@ -223,7 +223,7 @@ static void adv7511_set_config_csc(struct adv7511 *adv7511, · 222 unmodified lines
223223 config.csc_coefficents = adv7511_csc_ycbcr_to_rgb;
224224
225225 if ((connector->display_info.color_formats &
226− DRM_COLOR_FORMAT_YCRCB422) &&
226+ DRM_COLOR_FORMAT_YCBCR422) &&
227227 config.hdmi_mode) {
228228 config.csc_enable = false;
229229 config.avi_infoframe.colorspace =
@@ -351,11 +351,17 @@ static void __adv7511_power_on(struct adv7511 *adv7511) · 121 unmodified lines
351351 * from standby or are enabled. When the HPD goes low the adv7511 is
352352 * reset and the outputs are disabled which might cause the monitor to
353353 * go to standby again. To avoid this we ignore the HPD pin for the
354− * first few seconds after enabling the output.
354+ * first few seconds after enabling the output. On the other hand
355+ * adv7535 require to enable HPD Override bit for proper HPD.
355356 */
356− regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
357− ADV7511_REG_POWER2_HPD_SRC_MASK,
358− ADV7511_REG_POWER2_HPD_SRC_NONE);
357+ if (adv7511->type == ADV7535)
358+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
359+ ADV7535_REG_POWER2_HPD_OVERRIDE,
360+ ADV7535_REG_POWER2_HPD_OVERRIDE);
361+ else
362+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
363+ ADV7511_REG_POWER2_HPD_SRC_MASK,
364+ ADV7511_REG_POWER2_HPD_SRC_NONE);
359365 }
360366
361367 static void adv7511_power_on(struct adv7511 *adv7511)
@@ -375,6 +381,10 @@ static void adv7511_power_on(struct adv7511 *adv7511) · 13 unmodified lines
375381 static void __adv7511_power_off(struct adv7511 *adv7511)
376382 {
377383 /* TODO: setup additional power down modes */
384+ if (adv7511->type == ADV7535)
385+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
386+ ADV7535_REG_POWER2_HPD_OVERRIDE, 0);
387+
378388 regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
379389 ADV7511_POWER_POWER_DOWN,
380390 ADV7511_POWER_POWER_DOWN);
@@ -672,9 +682,14 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) · 291 unmodified lines
672682 status = connector_status_disconnected;
673683 } else {
674684 /* Renable HPD sensing */
675− regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
676− ADV7511_REG_POWER2_HPD_SRC_MASK,
677− ADV7511_REG_POWER2_HPD_SRC_BOTH);
685+ if (adv7511->type == ADV7535)
686+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
687+ ADV7535_REG_POWER2_HPD_OVERRIDE,
688+ ADV7535_REG_POWER2_HPD_OVERRIDE);
689+ else
690+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2,
691+ ADV7511_REG_POWER2_HPD_SRC_MASK,
692+ ADV7511_REG_POWER2_HPD_SRC_BOTH);
678693 }
679694
680695 adv7511->status = status;
drivers/gpu/drm/bridge/adv7511/adv7533.c+1−1
@@ -29,7 +29,7 @@ static void adv7511_dsi_config_timing_gen(struct adv7511 *adv) · 28 unmodified lines
2929 struct mipi_dsi_device *dsi = adv->dsi;
3030 struct drm_display_mode *mode = &adv->curr_mode;
3131 unsigned int hsw, hfp, hbp, vsw, vfp, vbp;
32− u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */
32+ static const u8 clock_div_by_lanes[] = { 6, 4, 3 }; /* 2, 3, 4 lanes */
3333
3434 hsw = mode->hsync_end - mode->hsync_start;
3535 hfp = mode->hsync_start - mode->hdisplay;
drivers/gpu/drm/bridge/analogix/Kconfig+2−0
@@ -3,6 +3,7 @@ config DRM_ANALOGIX_ANX6345 · 2 unmodified lines
33 tristate "Analogix ANX6345 bridge"
44 depends on OF
55 select DRM_ANALOGIX_DP
6+ select DRM_DP_HELPER
67 select DRM_KMS_HELPER
78 select REGMAP_I2C
89 help
@@ -14,6 +15,7 @@ config DRM_ANALOGIX_ANX6345 · 5 unmodified lines
1415 config DRM_ANALOGIX_ANX78XX
1516 tristate "Analogix ANX78XX bridge"
1617 select DRM_ANALOGIX_DP
18+ select DRM_DP_HELPER
1719 select DRM_KMS_HELPER
1820 select REGMAP_I2C
1921 help
drivers/gpu/drm/bridge/analogix/analogix-anx6345.c+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 #include <drm/drm_bridge.h>
2323 #include <drm/drm_crtc.h>
2424 #include <drm/drm_crtc_helper.h>
25−#include <drm/drm_dp_helper.h>
25+#include <drm/dp/drm_dp_helper.h>
2626 #include <drm/drm_edid.h>
2727 #include <drm/drm_of.h>
2828 #include <drm/drm_panel.h>
drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
2121 #include <drm/drm_atomic_helper.h>
2222 #include <drm/drm_bridge.h>
2323 #include <drm/drm_crtc.h>
24−#include <drm/drm_dp_helper.h>
24+#include <drm/dp/drm_dp_helper.h>
2525 #include <drm/drm_edid.h>
2626 #include <drm/drm_print.h>
2727 #include <drm/drm_probe_helper.h>
drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.c+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88 #include <linux/regmap.h>
99
1010 #include <drm/drm.h>
11−#include <drm/drm_dp_helper.h>
11+#include <drm/dp/drm_dp_helper.h>
1212 #include <drm/drm_print.h>
1313
1414 #include "analogix-i2c-dptx.h"
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c+2−2
@@ -1537,9 +1537,9 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, · 1536 unmodified lines
15371537 video->color_depth = COLOR_8;
15381538 break;
15391539 }
1540− if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
1540+ if (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
15411541 video->color_space = COLOR_YCBCR444;
1542− else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
1542+ else if (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
15431543 video->color_space = COLOR_YCBCR422;
15441544 else
15451545 video->color_space = COLOR_RGB;
drivers/gpu/drm/bridge/analogix/analogix_dp_core.h+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
1010 #define _ANALOGIX_DP_CORE_H
1111
1212 #include <drm/drm_crtc.h>
13−#include <drm/drm_dp_helper.h>
13+#include <drm/dp/drm_dp_helper.h>
1414
1515 #define DP_TIMEOUT_LOOP_COUNT 100
1616 #define MAX_CR_LOOP 5
drivers/gpu/drm/bridge/analogix/anx7625.c+421−19
@@ -24,8 +24,9 @@ · 23 unmodified lines
2424 #include <drm/drm_atomic_helper.h>
2525 #include <drm/drm_bridge.h>
2626 #include <drm/drm_crtc_helper.h>
27−#include <drm/drm_dp_helper.h>
27+#include <drm/dp/drm_dp_helper.h>
2828 #include <drm/drm_edid.h>
29+#include <drm/drm_hdcp.h>
2930 #include <drm/drm_mipi_dsi.h>
3031 #include <drm/drm_of.h>
3132 #include <drm/drm_panel.h>
@@ -213,6 +214,65 @@ static int wait_aux_op_finish(struct anx7625_data *ctx) · 181 unmodified lines
213214 return 0;
214215 }
215216
217+static int anx7625_aux_dpcd_read(struct anx7625_data *ctx,
218+ u32 address, u8 len, u8 *buf)
219+{
220+ struct device *dev = &ctx->client->dev;
221+ int ret;
222+ u8 addrh, addrm, addrl;
223+ u8 cmd;
224+
225+ if (len > MAX_DPCD_BUFFER_SIZE) {
226+ dev_err(dev, "exceed aux buffer len.\n");
227+ return -EINVAL;
228+ }
229+
230+ addrl = address & 0xFF;
231+ addrm = (address >> 8) & 0xFF;
232+ addrh = (address >> 16) & 0xFF;
233+
234+ cmd = DPCD_CMD(len, DPCD_READ);
235+ cmd = ((len - 1) << 4) | 0x09;
236+
237+ /* Set command and length */
238+ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
239+ AP_AUX_COMMAND, cmd);
240+
241+ /* Set aux access address */
242+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
243+ AP_AUX_ADDR_7_0, addrl);
244+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
245+ AP_AUX_ADDR_15_8, addrm);
246+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
247+ AP_AUX_ADDR_19_16, addrh);
248+
249+ /* Enable aux access */
250+ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client,
251+ AP_AUX_CTRL_STATUS, AP_AUX_CTRL_OP_EN);
252+
253+ if (ret < 0) {
254+ dev_err(dev, "cannot access aux related register.\n");
255+ return -EIO;
256+ }
257+
258+ usleep_range(2000, 2100);
259+
260+ ret = wait_aux_op_finish(ctx);
261+ if (ret) {
262+ dev_err(dev, "aux IO error: wait aux op finish.\n");
263+ return ret;
264+ }
265+
266+ ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client,
267+ AP_AUX_BUFF_START, len, buf);
268+ if (ret < 0) {
269+ dev_err(dev, "read dpcd register failed\n");
270+ return -EIO;
271+ }
272+
273+ return 0;
274+}
275+
216276 static int anx7625_video_mute_control(struct anx7625_data *ctx,
217277 u8 status)
218278 {
@@ -669,6 +729,165 @@ static int anx7625_dpi_config(struct anx7625_data *ctx) · 450 unmodified lines
669729 return ret;
670730 }
671731
732+static int anx7625_read_flash_status(struct anx7625_data *ctx)
733+{
734+ return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, R_RAM_CTRL);
735+}
736+
737+static int anx7625_hdcp_key_probe(struct anx7625_data *ctx)
738+{
739+ int ret, val;
740+ struct device *dev = &ctx->client->dev;
741+ u8 ident[FLASH_BUF_LEN];
742+
743+ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
744+ FLASH_ADDR_HIGH, 0x91);
745+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
746+ FLASH_ADDR_LOW, 0xA0);
747+ if (ret < 0) {
748+ dev_err(dev, "IO error : set key flash address.\n");
749+ return ret;
750+ }
751+
752+ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
753+ FLASH_LEN_HIGH, (FLASH_BUF_LEN - 1) >> 8);
754+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
755+ FLASH_LEN_LOW, (FLASH_BUF_LEN - 1) & 0xFF);
756+ if (ret < 0) {
757+ dev_err(dev, "IO error : set key flash len.\n");
758+ return ret;
759+ }
760+
761+ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
762+ R_FLASH_RW_CTRL, FLASH_READ);
763+ ret |= readx_poll_timeout(anx7625_read_flash_status,
764+ ctx, val,
765+ ((val & FLASH_DONE) || (val < 0)),
766+ 2000,
767+ 2000 * 150);
768+ if (ret) {
769+ dev_err(dev, "flash read access fail!\n");
770+ return -EIO;
771+ }
772+
773+ ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client,
774+ FLASH_BUF_BASE_ADDR,
775+ FLASH_BUF_LEN, ident);
776+ if (ret < 0) {
777+ dev_err(dev, "read flash data fail!\n");
778+ return -EIO;
779+ }
780+
781+ if (ident[29] == 0xFF && ident[30] == 0xFF && ident[31] == 0xFF)
782+ return -EINVAL;
783+
784+ return 0;
785+}
786+
787+static int anx7625_hdcp_key_load(struct anx7625_data *ctx)
788+{
789+ int ret;
790+ struct device *dev = &ctx->client->dev;
791+
792+ /* Select HDCP 1.4 KEY */
793+ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
794+ R_BOOT_RETRY, 0x12);
795+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
796+ FLASH_ADDR_HIGH, HDCP14KEY_START_ADDR >> 8);
797+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
798+ FLASH_ADDR_LOW, HDCP14KEY_START_ADDR & 0xFF);
799+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
800+ R_RAM_LEN_H, HDCP14KEY_SIZE >> 12);
801+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
802+ R_RAM_LEN_L, HDCP14KEY_SIZE >> 4);
803+
804+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
805+ R_RAM_ADDR_H, 0);
806+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
807+ R_RAM_ADDR_L, 0);
808+ /* Enable HDCP 1.4 KEY load */
809+ ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
810+ R_RAM_CTRL, DECRYPT_EN | LOAD_START);
811+ dev_dbg(dev, "load HDCP 1.4 key done\n");
812+ return ret;
813+}
814+
815+static int anx7625_hdcp_disable(struct anx7625_data *ctx)
816+{
817+ int ret;
818+ struct device *dev = &ctx->client->dev;
819+
820+ dev_dbg(dev, "disable HDCP 1.4\n");
821+
822+ /* Disable HDCP */
823+ ret = anx7625_write_and(ctx, ctx->i2c.rx_p1_client, 0xee, 0x9f);
824+ /* Try auth flag */
825+ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xec, 0x10);
826+ /* Interrupt for DRM */
827+ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xff, 0x01);
828+ if (ret < 0)
829+ dev_err(dev, "fail to disable HDCP\n");
830+
831+ return anx7625_write_and(ctx, ctx->i2c.tx_p0_client,
832+ TX_HDCP_CTRL0, ~HARD_AUTH_EN & 0xFF);
833+}
834+
835+static int anx7625_hdcp_enable(struct anx7625_data *ctx)
836+{
837+ u8 bcap;
838+ int ret;
839+ struct device *dev = &ctx->client->dev;
840+
841+ ret = anx7625_hdcp_key_probe(ctx);
842+ if (ret) {
843+ dev_dbg(dev, "no key found, not to do hdcp\n");
844+ return ret;
845+ }
846+
847+ /* Read downstream capability */
848+ anx7625_aux_dpcd_read(ctx, 0x68028, 1, &bcap);
849+ if (!(bcap & 0x01)) {
850+ pr_warn("downstream not support HDCP 1.4, cap(%x).\n", bcap);
851+ return 0;
852+ }
853+
854+ dev_dbg(dev, "enable HDCP 1.4\n");
855+
856+ /* First clear HDCP state */
857+ ret = anx7625_reg_write(ctx, ctx->i2c.tx_p0_client,
858+ TX_HDCP_CTRL0,
859+ KSVLIST_VLD | BKSV_SRM_PASS | RE_AUTHEN);
860+ usleep_range(1000, 1100);
861+ /* Second clear HDCP state */
862+ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p0_client,
863+ TX_HDCP_CTRL0,
864+ KSVLIST_VLD | BKSV_SRM_PASS | RE_AUTHEN);
865+
866+ /* Set time for waiting KSVR */
867+ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p0_client,
868+ SP_TX_WAIT_KSVR_TIME, 0xc8);
869+ /* Set time for waiting R0 */
870+ ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p0_client,
871+ SP_TX_WAIT_R0_TIME, 0xb0);
872+ ret |= anx7625_hdcp_key_load(ctx);
873+ if (ret) {
874+ pr_warn("prepare HDCP key failed.\n");
875+ return ret;
876+ }
877+
878+ ret = anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xee, 0x20);
879+
880+ /* Try auth flag */
881+ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xec, 0x10);
882+ /* Interrupt for DRM */
883+ ret |= anx7625_write_or(ctx, ctx->i2c.rx_p1_client, 0xff, 0x01);
884+ if (ret < 0)
885+ dev_err(dev, "fail to enable HDCP\n");
886+
887+ return anx7625_write_or(ctx, ctx->i2c.tx_p0_client,
888+ TX_HDCP_CTRL0, HARD_AUTH_EN);
889+}
890+
672891 static void anx7625_dp_start(struct anx7625_data *ctx)
673892 {
674893 int ret;
@@ -679,6 +898,9 @@ static void anx7625_dp_start(struct anx7625_data *ctx) · 4 unmodified lines
679898 return;
680899 }
681900
901+ /* Disable HDCP */
902+ anx7625_write_and(ctx, ctx->i2c.rx_p1_client, 0xee, 0x9f);
903+
682904 if (ctx->pdata.is_dpi)
683905 ret = anx7625_dpi_config(ctx);
684906 else
@@ -686,6 +908,10 @@ static void anx7625_dp_start(struct anx7625_data *ctx) · 1 unmodified line
686908
687909 if (ret < 0)
688910 DRM_DEV_ERROR(dev, "MIPI phy setup error.\n");
911+
912+ ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
913+
914+ ctx->dp_en = 1;
689915 }
690916
691917 static void anx7625_dp_stop(struct anx7625_data *ctx)
@@ -705,6 +931,10 @@ static void anx7625_dp_stop(struct anx7625_data *ctx) · 13 unmodified lines
705931 ret |= anx7625_video_mute_control(ctx, 1);
706932 if (ret < 0)
707933 DRM_DEV_ERROR(dev, "IO error : mute video fail\n");
934+
935+ ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
936+
937+ ctx->dp_en = 0;
708938 }
709939
710940 static int sp_tx_rst_aux(struct anx7625_data *ctx)
@@ -1098,9 +1328,18 @@ static void anx7625_init_gpio(struct anx7625_data *platform) · 387 unmodified lines
10981328 /* Gpio for chip power enable */
10991329 platform->pdata.gpio_p_on =
11001330 devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
1331+ if (IS_ERR_OR_NULL(platform->pdata.gpio_p_on)) {
1332+ DRM_DEV_DEBUG_DRIVER(dev, "no enable gpio found\n");
1333+ platform->pdata.gpio_p_on = NULL;
1334+ }
1335+
11011336 /* Gpio for chip reset */
11021337 platform->pdata.gpio_reset =
11031338 devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1339+ if (IS_ERR_OR_NULL(platform->pdata.gpio_reset)) {
1340+ DRM_DEV_DEBUG_DRIVER(dev, "no reset gpio found\n");
1341+ platform->pdata.gpio_reset = NULL;
1342+ }
11041343
11051344 if (platform->pdata.gpio_p_on && platform->pdata.gpio_reset) {
11061345 platform->pdata.low_power_mode = 1;
@@ -1601,9 +1840,27 @@ static int anx7625_audio_hook_plugged_cb(struct device *dev, void *data, · 494 unmodified lines
16011840 return 0;
16021841 }
16031842
1843+static int anx7625_audio_get_eld(struct device *dev, void *data,
1844+ u8 *buf, size_t len)
1845+{
1846+ struct anx7625_data *ctx = dev_get_drvdata(dev);
1847+
1848+ if (!ctx->connector) {
1849+ dev_err(dev, "connector not initial\n");
1850+ return -EINVAL;
1851+ }
1852+
1853+ dev_dbg(dev, "audio copy eld\n");
1854+ memcpy(buf, ctx->connector->eld,
1855+ min(sizeof(ctx->connector->eld), len));
1856+
1857+ return 0;
1858+}
1859+
16041860 static const struct hdmi_codec_ops anx7625_codec_ops = {
16051861 .hw_params = anx7625_audio_hw_params,
16061862 .audio_shutdown = anx7625_audio_shutdown,
1863+ .get_eld = anx7625_audio_get_eld,
16071864 .get_dai_id = anx7625_hdmi_i2s_get_dai_id,
16081865 .hook_plugged_cb = anx7625_audio_hook_plugged_cb,
16091866 };
@@ -1660,7 +1917,7 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) · 50 unmodified lines
16601917 host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node);
16611918 if (!host) {
16621919 DRM_DEV_ERROR(dev, "fail to find dsi host.\n");
1663− return -EINVAL;
1920+ return -EPROBE_DEFER;
16641921 }
16651922
16661923 dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
@@ -1688,6 +1945,83 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) · 21 unmodified lines
16881945 return 0;
16891946 }
16901947
1948+static void hdcp_check_work_func(struct work_struct *work)
1949+{
1950+ u8 status;
1951+ struct delayed_work *dwork;
1952+ struct anx7625_data *ctx;
1953+ struct device *dev;
1954+ struct drm_device *drm_dev;
1955+
1956+ dwork = to_delayed_work(work);
1957+ ctx = container_of(dwork, struct anx7625_data, hdcp_work);
1958+ dev = &ctx->client->dev;
1959+
1960+ if (!ctx->connector) {
1961+ dev_err(dev, "HDCP connector is null!");
1962+ return;
1963+ }
1964+
1965+ drm_dev = ctx->connector->dev;
1966+ drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL);
1967+ mutex_lock(&ctx->hdcp_wq_lock);
1968+
1969+ status = anx7625_reg_read(ctx, ctx->i2c.tx_p0_client, 0);
1970+ dev_dbg(dev, "sink HDCP status check: %.02x\n", status);
1971+ if (status & BIT(1)) {
1972+ ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_ENABLED;
1973+ drm_hdcp_update_content_protection(ctx->connector,
1974+ ctx->hdcp_cp);
1975+ dev_dbg(dev, "update CP to ENABLE\n");
1976+ }
1977+
1978+ mutex_unlock(&ctx->hdcp_wq_lock);
1979+ drm_modeset_unlock(&drm_dev->mode_config.connection_mutex);
1980+}
1981+
1982+static int anx7625_connector_atomic_check(struct anx7625_data *ctx,
1983+ struct drm_connector_state *state)
1984+{
1985+ struct device *dev = &ctx->client->dev;
1986+ int cp;
1987+
1988+ dev_dbg(dev, "hdcp state check\n");
1989+ cp = state->content_protection;
1990+
1991+ if (cp == ctx->hdcp_cp)
1992+ return 0;
1993+
1994+ if (cp == DRM_MODE_CONTENT_PROTECTION_DESIRED) {
1995+ if (ctx->dp_en) {
1996+ dev_dbg(dev, "enable HDCP\n");
1997+ anx7625_hdcp_enable(ctx);
1998+
1999+ queue_delayed_work(ctx->hdcp_workqueue,
2000+ &ctx->hdcp_work,
2001+ msecs_to_jiffies(2000));
2002+ }
2003+ }
2004+
2005+ if (cp == DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
2006+ if (ctx->hdcp_cp != DRM_MODE_CONTENT_PROTECTION_ENABLED) {
2007+ dev_err(dev, "current CP is not ENABLED\n");
2008+ return -EINVAL;
2009+ }
2010+ anx7625_hdcp_disable(ctx);
2011+ ctx->hdcp_cp = DRM_MODE_CONTENT_PROTECTION_UNDESIRED;
2012+ drm_hdcp_update_content_protection(ctx->connector,
2013+ ctx->hdcp_cp);
2014+ dev_dbg(dev, "update CP to UNDESIRE\n");
2015+ }
2016+
2017+ if (cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
2018+ dev_err(dev, "Userspace illegal set to PROTECTION ENABLE\n");
2019+ return -EINVAL;
2020+ }
2021+
2022+ return 0;
2023+}
2024+
16912025 static int anx7625_bridge_attach(struct drm_bridge *bridge,
16922026 enum drm_bridge_attach_flags flags)
16932027 {
@@ -1902,25 +2236,57 @@ static bool anx7625_bridge_mode_fixup(struct drm_bridge *bridge, · 208 unmodified lines
19022236 return true;
19032237 }
19042238
1905−static void anx7625_bridge_enable(struct drm_bridge *bridge)
2239+static int anx7625_bridge_atomic_check(struct drm_bridge *bridge,
2240+ struct drm_bridge_state *bridge_state,
2241+ struct drm_crtc_state *crtc_state,
2242+ struct drm_connector_state *conn_state)
2243+{
2244+ struct anx7625_data *ctx = bridge_to_anx7625(bridge);
2245+ struct device *dev = &ctx->client->dev;
2246+
2247+ dev_dbg(dev, "drm bridge atomic check\n");
2248+
2249+ anx7625_bridge_mode_fixup(bridge, &crtc_state->mode,
2250+ &crtc_state->adjusted_mode);
2251+
2252+ return anx7625_connector_atomic_check(ctx, conn_state);
2253+}
2254+
2255+static void anx7625_bridge_atomic_enable(struct drm_bridge *bridge,
2256+ struct drm_bridge_state *state)
19062257 {
19072258 struct anx7625_data *ctx = bridge_to_anx7625(bridge);
19082259 struct device *dev = &ctx->client->dev;
2260+ struct drm_connector *connector;
19092261
1910− DRM_DEV_DEBUG_DRIVER(dev, "drm enable\n");
2262+ dev_dbg(dev, "drm atomic enable\n");
2263+
2264+ if (!bridge->encoder) {
2265+ dev_err(dev, "Parent encoder object not found");
2266+ return;
2267+ }
2268+
2269+ connector = drm_atomic_get_new_connector_for_encoder(state->base.state,
2270+ bridge->encoder);
2271+ if (!connector)
2272+ return;
2273+
2274+ ctx->connector = connector;
19112275
19122276 pm_runtime_get_sync(dev);
19132277
19142278 anx7625_dp_start(ctx);
19152279 }
19162280
1917−static void anx7625_bridge_disable(struct drm_bridge *bridge)
2281+static void anx7625_bridge_atomic_disable(struct drm_bridge *bridge,
2282+ struct drm_bridge_state *old)
19182283 {
19192284 struct anx7625_data *ctx = bridge_to_anx7625(bridge);
19202285 struct device *dev = &ctx->client->dev;
19212286
1922− DRM_DEV_DEBUG_DRIVER(dev, "drm disable\n");
2287+ dev_dbg(dev, "drm atomic disable\n");
19232288
2289+ ctx->connector = NULL;
19242290 anx7625_dp_stop(ctx);
19252291
19262292 pm_runtime_put_sync(dev);
@@ -1950,11 +2316,14 @@ static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge, · 23 unmodified lines
19502316
19512317 static const struct drm_bridge_funcs anx7625_bridge_funcs = {
19522318 .attach = anx7625_bridge_attach,
1953− .disable = anx7625_bridge_disable,
19542319 .mode_valid = anx7625_bridge_mode_valid,
19552320 .mode_set = anx7625_bridge_mode_set,
1956− .mode_fixup = anx7625_bridge_mode_fixup,
1957− .enable = anx7625_bridge_enable,
2321+ .atomic_check = anx7625_bridge_atomic_check,
2322+ .atomic_enable = anx7625_bridge_atomic_enable,
2323+ .atomic_disable = anx7625_bridge_atomic_disable,
2324+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
2325+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
2326+ .atomic_reset = drm_atomic_helper_bridge_reset,
19582327 .detect = anx7625_bridge_detect,
19592328 .get_edid = anx7625_bridge_get_edid,
19602329 };
@@ -1962,40 +2331,54 @@ static const struct drm_bridge_funcs anx7625_bridge_funcs = { · 1 unmodified line
19622331 static int anx7625_register_i2c_dummy_clients(struct anx7625_data *ctx,
19632332 struct i2c_client *client)
19642333 {
2334+ int err = 0;
2335+
19652336 ctx->i2c.tx_p0_client = i2c_new_dummy_device(client->adapter,
19662337 TX_P0_ADDR >> 1);
1967− if (!ctx->i2c.tx_p0_client)
1968− return -ENOMEM;
2338+ if (IS_ERR(ctx->i2c.tx_p0_client))
2339+ return PTR_ERR(ctx->i2c.tx_p0_client);
19692340
19702341 ctx->i2c.tx_p1_client = i2c_new_dummy_device(client->adapter,
19712342 TX_P1_ADDR >> 1);
1972− if (!ctx->i2c.tx_p1_client)
2343+ if (IS_ERR(ctx->i2c.tx_p1_client)) {
2344+ err = PTR_ERR(ctx->i2c.tx_p1_client);
19732345 goto free_tx_p0;
2346+ }
19742347
19752348 ctx->i2c.tx_p2_client = i2c_new_dummy_device(client->adapter,
19762349 TX_P2_ADDR >> 1);
1977− if (!ctx->i2c.tx_p2_client)
2350+ if (IS_ERR(ctx->i2c.tx_p2_client)) {
2351+ err = PTR_ERR(ctx->i2c.tx_p2_client);
19782352 goto free_tx_p1;
2353+ }
19792354
19802355 ctx->i2c.rx_p0_client = i2c_new_dummy_device(client->adapter,
19812356 RX_P0_ADDR >> 1);
1982− if (!ctx->i2c.rx_p0_client)
2357+ if (IS_ERR(ctx->i2c.rx_p0_client)) {
2358+ err = PTR_ERR(ctx->i2c.rx_p0_client);
19832359 goto free_tx_p2;
2360+ }
19842361
19852362 ctx->i2c.rx_p1_client = i2c_new_dummy_device(client->adapter,
19862363 RX_P1_ADDR >> 1);
1987− if (!ctx->i2c.rx_p1_client)
2364+ if (IS_ERR(ctx->i2c.rx_p1_client)) {
2365+ err = PTR_ERR(ctx->i2c.rx_p1_client);
19882366 goto free_rx_p0;
2367+ }
19892368
19902369 ctx->i2c.rx_p2_client = i2c_new_dummy_device(client->adapter,
19912370 RX_P2_ADDR >> 1);
1992− if (!ctx->i2c.rx_p2_client)
2371+ if (IS_ERR(ctx->i2c.rx_p2_client)) {
2372+ err = PTR_ERR(ctx->i2c.rx_p2_client);
19932373 goto free_rx_p1;
2374+ }
19942375
19952376 ctx->i2c.tcpc_client = i2c_new_dummy_device(client->adapter,
19962377 TCPC_INTERFACE_ADDR >> 1);
1997− if (!ctx->i2c.tcpc_client)
2378+ if (IS_ERR(ctx->i2c.tcpc_client)) {
2379+ err = PTR_ERR(ctx->i2c.tcpc_client);
19982380 goto free_rx_p2;
2381+ }
19992382
20002383 return 0;
20012384
@@ -2012,7 +2395,7 @@ free_tx_p1: · 10 unmodified lines
20122395 free_tx_p0:
20132396 i2c_unregister_device(ctx->i2c.tx_p0_client);
20142397
2015− return -ENOMEM;
2398+ return err;
20162399 }
20172400
20182401 static void anx7625_unregister_i2c_dummy_clients(struct anx7625_data *ctx)
@@ -2134,6 +2517,15 @@ static int anx7625_i2c_probe(struct i2c_client *client, · 115 unmodified lines
21342517 anx7625_init_gpio(platform);
21352518
21362519 mutex_init(&platform->lock);
2520+ mutex_init(&platform->hdcp_wq_lock);
2521+
2522+ INIT_DELAYED_WORK(&platform->hdcp_work, hdcp_check_work_func);
2523+ platform->hdcp_workqueue = create_workqueue("hdcp workqueue");
2524+ if (!platform->hdcp_workqueue) {
2525+ dev_err(dev, "fail to create work queue\n");
2526+ ret = -ENOMEM;
2527+ goto free_platform;
2528+ }
21372529
21382530 platform->pdata.intp_irq = client->irq;
21392531 if (platform->pdata.intp_irq) {
@@ -2143,7 +2535,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, · 3 unmodified lines
21432535 if (!platform->workqueue) {
21442536 DRM_DEV_ERROR(dev, "fail to create work queue\n");
21452537 ret = -ENOMEM;
2146− goto free_platform;
2538+ goto free_hdcp_wq;
21472539 }
21482540
21492541 ret = devm_request_threaded_irq(dev, platform->pdata.intp_irq,
@@ -2213,6 +2605,10 @@ free_wq: · 63 unmodified lines
22132605 if (platform->workqueue)
22142606 destroy_workqueue(platform->workqueue);
22152607
2608+free_hdcp_wq:
2609+ if (platform->hdcp_workqueue)
2610+ destroy_workqueue(platform->hdcp_workqueue);
2611+
22162612 free_platform:
22172613 kfree(platform);
22182614
@@ -2228,6 +2624,12 @@ static int anx7625_i2c_remove(struct i2c_client *client) · 9 unmodified lines
22282624 if (platform->pdata.intp_irq)
22292625 destroy_workqueue(platform->workqueue);
22302626
2627+ if (platform->hdcp_workqueue) {
2628+ cancel_delayed_work(&platform->hdcp_work);
2629+ flush_workqueue(platform->workqueue);
2630+ destroy_workqueue(platform->workqueue);
2631+ }
2632+
22312633 if (!platform->pdata.low_power_mode)
22322634 pm_runtime_put_sync_suspend(&client->dev);
22332635
drivers/gpu/drm/bridge/analogix/anx7625.h+73−7
@@ -59,10 +59,23 @@ · 58 unmodified lines
5959
6060 /***************************************************************/
6161 /* Register definition of device address 0x70 */
62−#define I2C_ADDR_70_DPTX 0x70
63−
64−#define SP_TX_LINK_BW_SET_REG 0xA0
65−#define SP_TX_LANE_COUNT_SET_REG 0xA1
62+#define TX_HDCP_CTRL0 0x01
63+#define STORE_AN BIT(7)
64+#define RX_REPEATER BIT(6)
65+#define RE_AUTHEN BIT(5)
66+#define SW_AUTH_OK BIT(4)
67+#define HARD_AUTH_EN BIT(3)
68+#define ENC_EN BIT(2)
69+#define BKSV_SRM_PASS BIT(1)
70+#define KSVLIST_VLD BIT(0)
71+
72+#define SP_TX_WAIT_R0_TIME 0x40
73+#define SP_TX_WAIT_KSVR_TIME 0x42
74+#define SP_TX_SYS_CTRL1_REG 0x80
75+#define HDCP2TX_FW_EN BIT(4)
76+
77+#define SP_TX_LINK_BW_SET_REG 0xA0
78+#define SP_TX_LANE_COUNT_SET_REG 0xA1
6679
6780 #define M_VID_0 0xC0
6881 #define M_VID_1 0xC1
@@ -71,6 +84,12 @@ · 2 unmodified lines
7184 #define N_VID_1 0xC4
7285 #define N_VID_2 0xC5
7386
87+#define KEY_START_ADDR 0x9000
88+#define KEY_RESERVED 416
89+
90+#define HDCP14KEY_START_ADDR (KEY_START_ADDR + KEY_RESERVED)
91+#define HDCP14KEY_SIZE 624
92+
7493 /***************************************************************/
7594 /* Register definition of device address 0x72 */
7695 #define AUX_RST 0x04
@@ -155,9 +174,43 @@ · 78 unmodified lines
155174
156175 #define I2C_ADDR_7E_FLASH_CONTROLLER 0x7E
157176
177+#define R_BOOT_RETRY 0x00
178+#define R_RAM_ADDR_H 0x01
179+#define R_RAM_ADDR_L 0x02
180+#define R_RAM_LEN_H 0x03
181+#define R_RAM_LEN_L 0x04
158182 #define FLASH_LOAD_STA 0x05
159183 #define FLASH_LOAD_STA_CHK BIT(7)
160184
185+#define R_RAM_CTRL 0x05
186+/* bit positions */
187+#define FLASH_DONE BIT(7)
188+#define BOOT_LOAD_DONE BIT(6)
189+#define CRC_OK BIT(5)
190+#define LOAD_DONE BIT(4)
191+#define O_RW_DONE BIT(3)
192+#define FUSE_BUSY BIT(2)
193+#define DECRYPT_EN BIT(1)
194+#define LOAD_START BIT(0)
195+
196+#define FLASH_ADDR_HIGH 0x0F
197+#define FLASH_ADDR_LOW 0x10
198+#define FLASH_LEN_HIGH 0x31
199+#define FLASH_LEN_LOW 0x32
200+#define R_FLASH_RW_CTRL 0x33
201+/* bit positions */
202+#define READ_DELAY_SELECT BIT(7)
203+#define GENERAL_INSTRUCTION_EN BIT(6)
204+#define FLASH_ERASE_EN BIT(5)
205+#define RDID_READ_EN BIT(4)
206+#define REMS_READ_EN BIT(3)
207+#define WRITE_STATUS_EN BIT(2)
208+#define FLASH_READ BIT(1)
209+#define FLASH_WRITE BIT(0)
210+
211+#define FLASH_BUF_BASE_ADDR 0x60
212+#define FLASH_BUF_LEN 0x20
213+
161214 #define XTAL_FRQ_SEL 0x3F
162215 /* bit field positions */
163216 #define XTAL_FRQ_SEL_POS 5
@@ -184,10 +237,15 @@ · 20 unmodified lines
184237 #define AP_AUX_CTRL_ADDRONLY 0x20
185238
186239 #define AP_AUX_BUFF_START 0x15
187−#define PIXEL_CLOCK_L 0x25
188−#define PIXEL_CLOCK_H 0x26
240+#define PIXEL_CLOCK_L 0x25
241+#define PIXEL_CLOCK_H 0x26
242+
243+#define AP_AUX_COMMAND 0x27 /* com+len */
244+#define LENGTH_SHIFT 4
245+#define DPCD_READ 0x09
246+#define DPCD_WRITE 0x08
247+#define DPCD_CMD(len, cmd) ((((len) - 1) << LENGTH_SHIFT) | (cmd))
189248
190−#define AP_AUX_COMMAND 0x27 /* com+len */
191249 /* Bit 0&1: 3D video structure */
192250 /* 0x01: frame packing, 0x02:Line alternative, 0x03:Side-by-side(full) */
193251 #define AP_AV_STATUS 0x28
@@ -392,21 +450,29 @@ struct anx7625_data { · 198 unmodified lines
392450 struct platform_device *audio_pdev;
393451 int hpd_status;
394452 int hpd_high_cnt;
453+ int dp_en;
454+ int hdcp_cp;
395455 /* Lock for work queue */
396456 struct mutex lock;
397457 struct i2c_client *client;
398458 struct anx7625_i2c_client i2c;
399459 struct i2c_client *last_client;
460+ struct timer_list hdcp_timer;
400461 struct s_edid_data slimport_edid_p;
401462 struct device *codec_dev;
402463 hdmi_codec_plugged_cb plugged_cb;
403464 struct work_struct work;
404465 struct workqueue_struct *workqueue;
466+ struct delayed_work hdcp_work;
467+ struct workqueue_struct *hdcp_workqueue;
468+ /* Lock for hdcp work queue */
469+ struct mutex hdcp_wq_lock;
405470 char edid_block;
406471 struct display_timing dt;
407472 u8 display_timing_valid;
408473 struct drm_bridge bridge;
409474 u8 bridge_attached;
475+ struct drm_connector *connector;
410476 struct mipi_dsi_device *dsi;
411477 };
412478
drivers/gpu/drm/bridge/cadence/Kconfig+1−0
@@ -1,6 +1,7 @@
11 # SPDX-License-Identifier: GPL-2.0-only
22 config DRM_CDNS_MHDP8546
33 tristate "Cadence DPI/DP bridge"
4+ select DRM_DP_HELPER
45 select DRM_KMS_HELPER
56 select DRM_PANEL_BRIDGE
67 depends on OF
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c+10−10
@@ -41,7 +41,7 @@ · 40 unmodified lines
4141 #include <drm/drm_bridge.h>
4242 #include <drm/drm_connector.h>
4343 #include <drm/drm_crtc_helper.h>
44−#include <drm/drm_dp_helper.h>
44+#include <drm/dp/drm_dp_helper.h>
4545 #include <drm/drm_hdcp.h>
4646 #include <drm/drm_modeset_helper_vtables.h>
4747 #include <drm/drm_print.h>
@@ -1553,13 +1553,13 @@ static u32 cdns_mhdp_get_bpp(struct cdns_mhdp_display_fmt *fmt) · 1505 unmodified lines
15531553
15541554 switch (fmt->color_format) {
15551555 case DRM_COLOR_FORMAT_RGB444:
1556− case DRM_COLOR_FORMAT_YCRCB444:
1556+ case DRM_COLOR_FORMAT_YCBCR444:
15571557 bpp = fmt->bpc * 3;
15581558 break;
1559− case DRM_COLOR_FORMAT_YCRCB422:
1559+ case DRM_COLOR_FORMAT_YCBCR422:
15601560 bpp = fmt->bpc * 2;
15611561 break;
1562− case DRM_COLOR_FORMAT_YCRCB420:
1562+ case DRM_COLOR_FORMAT_YCBCR420:
15631563 bpp = fmt->bpc * 3 / 2;
15641564 break;
15651565 default:
@@ -1767,8 +1767,8 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, · 201 unmodified lines
17671767 * If YCBCR supported and stream not SD, use ITU709
17681768 * Need to handle ITU version with YCBCR420 when supported
17691769 */
1770− if ((pxlfmt == DRM_COLOR_FORMAT_YCRCB444 ||
1771− pxlfmt == DRM_COLOR_FORMAT_YCRCB422) && mode->crtc_vdisplay >= 720)
1770+ if ((pxlfmt == DRM_COLOR_FORMAT_YCBCR444 ||
1771+ pxlfmt == DRM_COLOR_FORMAT_YCBCR422) && mode->crtc_vdisplay >= 720)
17721772 misc0 = DP_YCBCR_COEFFICIENTS_ITU709;
17731773
17741774 bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
@@ -1778,15 +1778,15 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, · 3 unmodified lines
17781778 pxl_repr = CDNS_DP_FRAMER_RGB << CDNS_DP_FRAMER_PXL_FORMAT;
17791779 misc0 |= DP_COLOR_FORMAT_RGB;
17801780 break;
1781− case DRM_COLOR_FORMAT_YCRCB444:
1781+ case DRM_COLOR_FORMAT_YCBCR444:
17821782 pxl_repr = CDNS_DP_FRAMER_YCBCR444 << CDNS_DP_FRAMER_PXL_FORMAT;
17831783 misc0 |= DP_COLOR_FORMAT_YCbCr444 | DP_TEST_DYNAMIC_RANGE_CEA;
17841784 break;
1785− case DRM_COLOR_FORMAT_YCRCB422:
1785+ case DRM_COLOR_FORMAT_YCBCR422:
17861786 pxl_repr = CDNS_DP_FRAMER_YCBCR422 << CDNS_DP_FRAMER_PXL_FORMAT;
17871787 misc0 |= DP_COLOR_FORMAT_YCbCr422 | DP_TEST_DYNAMIC_RANGE_CEA;
17881788 break;
1789− case DRM_COLOR_FORMAT_YCRCB420:
1789+ case DRM_COLOR_FORMAT_YCBCR420:
17901790 pxl_repr = CDNS_DP_FRAMER_YCBCR420 << CDNS_DP_FRAMER_PXL_FORMAT;
17911791 break;
17921792 default:
@@ -1882,7 +1882,7 @@ static void cdns_mhdp_configure_video(struct cdns_mhdp_device *mhdp, · 89 unmodified lines
18821882 if (mhdp->display_fmt.y_only)
18831883 misc1 |= CDNS_DP_TEST_COLOR_FORMAT_RAW_Y_ONLY;
18841884 /* Use VSC SDP for Y420 */
1885− if (pxlfmt == DRM_COLOR_FORMAT_YCRCB420)
1885+ if (pxlfmt == DRM_COLOR_FORMAT_YCBCR420)
18861886 misc1 = CDNS_DP_TEST_VSC_SDP;
18871887
18881888 cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717
1818 #include <drm/drm_bridge.h>
1919 #include <drm/drm_connector.h>
20−#include <drm/drm_dp_helper.h>
20+#include <drm/dp/drm_dp_helper.h>
2121
2222 struct clk;
2323 struct device;
drivers/gpu/drm/bridge/chipone-icn6211.c+26−13
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 * Author: Jagan Teki <jagan@amarulasolutions.com>
55 */
66
7+#include <drm/drm_atomic_helper.h>
78 #include <drm/drm_of.h>
89 #include <drm/drm_print.h>
910 #include <drm/drm_mipi_dsi.h>
@@ -30,6 +31,7 @@ · 20 unmodified lines
3031 struct chipone {
3132 struct device *dev;
3233 struct drm_bridge bridge;
34+ struct drm_display_mode mode;
3335 struct drm_bridge *panel_bridge;
3436 struct gpio_desc *enable_gpio;
3537 struct regulator *vdd1;
@@ -42,11 +44,6 @@ static inline struct chipone *bridge_to_chipone(struct drm_bridge *bridge) · 6 unmodified lines
4244 return container_of(bridge, struct chipone, bridge);
4345 }
4446
45−static struct drm_display_mode *bridge_to_mode(struct drm_bridge *bridge)
46−{
47− return &bridge->encoder->crtc->state->adjusted_mode;
48−}
49−
5047 static inline int chipone_dsi_write(struct chipone *icn, const void *seq,
5148 size_t len)
5249 {
@@ -61,10 +58,11 @@ static inline int chipone_dsi_write(struct chipone *icn, const void *seq, · 8 unmodified lines
6158 chipone_dsi_write(icn, d, ARRAY_SIZE(d)); \
6259 }
6360
64−static void chipone_enable(struct drm_bridge *bridge)
61+static void chipone_atomic_enable(struct drm_bridge *bridge,
62+ struct drm_bridge_state *old_bridge_state)
6563 {
6664 struct chipone *icn = bridge_to_chipone(bridge);
67− struct drm_display_mode *mode = bridge_to_mode(bridge);
65+ struct drm_display_mode *mode = &icn->mode;
6866
6967 ICN6211_DSI(icn, 0x7a, 0xc1);
7068
@@ -114,7 +112,8 @@ static void chipone_enable(struct drm_bridge *bridge) · 43 unmodified lines
114112 usleep_range(10000, 11000);
115113 }
116114
117−static void chipone_pre_enable(struct drm_bridge *bridge)
115+static void chipone_atomic_pre_enable(struct drm_bridge *bridge,
116+ struct drm_bridge_state *old_bridge_state)
118117 {
119118 struct chipone *icn = bridge_to_chipone(bridge);
120119 int ret;
@@ -145,7 +144,8 @@ static void chipone_pre_enable(struct drm_bridge *bridge) · 24 unmodified lines
145144 usleep_range(10000, 11000);
146145 }
147146
148−static void chipone_post_disable(struct drm_bridge *bridge)
147+static void chipone_atomic_post_disable(struct drm_bridge *bridge,
148+ struct drm_bridge_state *old_bridge_state)
149149 {
150150 struct chipone *icn = bridge_to_chipone(bridge);
151151
@@ -161,6 +161,15 @@ static void chipone_post_disable(struct drm_bridge *bridge) · 9 unmodified lines
161161 gpiod_set_value(icn->enable_gpio, 0);
162162 }
163163
164+static void chipone_mode_set(struct drm_bridge *bridge,
165+ const struct drm_display_mode *mode,
166+ const struct drm_display_mode *adjusted_mode)
167+{
168+ struct chipone *icn = bridge_to_chipone(bridge);
169+
170+ drm_mode_copy(&icn->mode, adjusted_mode);
171+}
172+
164173 static int chipone_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags)
165174 {
166175 struct chipone *icn = bridge_to_chipone(bridge);
@@ -169,10 +178,14 @@ static int chipone_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flag · 2 unmodified lines
169178 }
170179
171180 static const struct drm_bridge_funcs chipone_bridge_funcs = {
172− .attach = chipone_attach,
173− .post_disable = chipone_post_disable,
174− .pre_enable = chipone_pre_enable,
175− .enable = chipone_enable,
181+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
182+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
183+ .atomic_reset = drm_atomic_helper_bridge_reset,
184+ .atomic_pre_enable = chipone_atomic_pre_enable,
185+ .atomic_enable = chipone_atomic_enable,
186+ .atomic_post_disable = chipone_atomic_post_disable,
187+ .mode_set = chipone_mode_set,
188+ .attach = chipone_attach,
176189 };
177190
178191 static int chipone_parse_dt(struct chipone *icn)
drivers/gpu/drm/bridge/ite-it66121.c+0−3
@@ -936,9 +936,6 @@ static int it66121_probe(struct i2c_client *client, · 935 unmodified lines
936936 return -EPROBE_DEFER;
937937 }
938938
939− if (!ctx->next_bridge)
940− return -EPROBE_DEFER;
941−
942939 i2c_set_clientdata(client, ctx);
943940 mutex_init(&ctx->lock);
944941
drivers/gpu/drm/bridge/lontium-lt9611.c+2−2
@@ -1090,7 +1090,7 @@ static int lt9611_probe(struct i2c_client *client, · 1089 unmodified lines
10901090 if (!lt9611)
10911091 return -ENOMEM;
10921092
1093− lt9611->dev = &client->dev;
1093+ lt9611->dev = dev;
10941094 lt9611->client = client;
10951095 lt9611->sleep = false;
10961096
@@ -1100,7 +1100,7 @@ static int lt9611_probe(struct i2c_client *client, · 3 unmodified lines
11001100 return PTR_ERR(lt9611->regmap);
11011101 }
11021102
1103− ret = lt9611_parse_dt(&client->dev, lt9611);
1103+ ret = lt9611_parse_dt(dev, lt9611);
11041104 if (ret) {
11051105 dev_err(dev, "failed to parse device tree\n");
11061106 return ret;
drivers/gpu/drm/bridge/lontium-lt9611uxc.c+2−2
@@ -860,7 +860,7 @@ static int lt9611uxc_probe(struct i2c_client *client, · 859 unmodified lines
860860 if (!lt9611uxc)
861861 return -ENOMEM;
862862
863− lt9611uxc->dev = &client->dev;
863+ lt9611uxc->dev = dev;
864864 lt9611uxc->client = client;
865865 mutex_init(&lt9611uxc->ocm_lock);
866866
@@ -870,7 +870,7 @@ static int lt9611uxc_probe(struct i2c_client *client, · 3 unmodified lines
870870 return PTR_ERR(lt9611uxc->regmap);
871871 }
872872
873− ret = lt9611uxc_parse_dt(&client->dev, lt9611uxc);
873+ ret = lt9611uxc_parse_dt(dev, lt9611uxc);
874874 if (ret) {
875875 dev_err(dev, "failed to parse device tree\n");
876876 return ret;
drivers/gpu/drm/bridge/nwl-dsi.c+3−5
@@ -65,7 +65,6 @@ struct nwl_dsi_transfer { · 64 unmodified lines
6565 struct nwl_dsi {
6666 struct drm_bridge bridge;
6767 struct mipi_dsi_host dsi_host;
68− struct drm_bridge *panel_bridge;
6968 struct device *dev;
7069 struct phy *phy;
7170 union phy_configure_opts phy_cfg;
@@ -924,13 +923,11 @@ static int nwl_dsi_bridge_attach(struct drm_bridge *bridge, · 852 unmodified lines
924923 if (IS_ERR(panel_bridge))
925924 return PTR_ERR(panel_bridge);
926925 }
927− dsi->panel_bridge = panel_bridge;
928926
929− if (!dsi->panel_bridge)
927+ if (!panel_bridge)
930928 return -EPROBE_DEFER;
931929
932− return drm_bridge_attach(bridge->encoder, dsi->panel_bridge, bridge,
933− flags);
930+ return drm_bridge_attach(bridge->encoder, panel_bridge, bridge, flags);
934931 }
935932
936933 static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
@@ -1206,6 +1203,7 @@ static int nwl_dsi_probe(struct platform_device *pdev) · 269 unmodified lines
12061203
12071204 ret = nwl_dsi_select_input(dsi);
12081205 if (ret < 0) {
1206+ pm_runtime_disable(dev);
12091207 mipi_dsi_host_unregister(&dsi->dsi_host);
12101208 return ret;
12111209 }
drivers/gpu/drm/bridge/parade-ps8640.c+28−5
@@ -14,8 +14,8 @@ · 13 unmodified lines
1414 #include <linux/regulator/consumer.h>
1515
1616 #include <drm/drm_bridge.h>
17−#include <drm/drm_dp_aux_bus.h>
18−#include <drm/drm_dp_helper.h>
17+#include <drm/dp/drm_dp_aux_bus.h>
18+#include <drm/dp/drm_dp_helper.h>
1919 #include <drm/drm_mipi_dsi.h>
2020 #include <drm/drm_of.h>
2121 #include <drm/drm_panel.h>
@@ -102,6 +102,7 @@ struct ps8640 { · 80 unmodified lines
102102 struct regulator_bulk_data supplies[2];
103103 struct gpio_desc *gpio_reset;
104104 struct gpio_desc *gpio_powerdown;
105+ struct device_link *link;
105106 bool pre_enabled;
106107 };
107108
@@ -456,14 +457,36 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge, · 348 unmodified lines
456457 return ret;
457458 }
458459
460+ ps_bridge->link = device_link_add(bridge->dev->dev, dev, DL_FLAG_STATELESS);
461+ if (!ps_bridge->link) {
462+ dev_err(dev, "failed to create device link");
463+ ret = -EINVAL;
464+ goto err_devlink;
465+ }
466+
459467 /* Attach the panel-bridge to the dsi bridge */
460− return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge,
461− &ps_bridge->bridge, flags);
468+ ret = drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge,
469+ &ps_bridge->bridge, flags);
470+ if (ret)
471+ goto err_bridge_attach;
472+
473+ return 0;
474+
475+err_bridge_attach:
476+ device_link_del(ps_bridge->link);
477+err_devlink:
478+ drm_dp_aux_unregister(&ps_bridge->aux);
479+
480+ return ret;
462481 }
463482
464483 static void ps8640_bridge_detach(struct drm_bridge *bridge)
465484 {
466− drm_dp_aux_unregister(&bridge_to_ps8640(bridge)->aux);
485+ struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
486+
487+ drm_dp_aux_unregister(&ps_bridge->aux);
488+ if (ps_bridge->link)
489+ device_link_del(ps_bridge->link);
467490 }
468491
469492 static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
drivers/gpu/drm/bridge/sii902x.c+99−30
@@ -166,10 +166,12 @@ struct sii902x { · 165 unmodified lines
166166 struct i2c_client *i2c;
167167 struct regmap *regmap;
168168 struct drm_bridge bridge;
169+ struct drm_bridge *next_bridge;
169170 struct drm_connector connector;
170171 struct gpio_desc *reset_gpio;
171172 struct i2c_mux_core *i2cmux;
172173 struct regulator_bulk_data supplies[2];
174+ bool sink_is_hdmi;
173175 /*
174176 * Mutex protects audio and video functions from interfering
175177 * each other, by keeping their i2c command sequences atomic.
@@ -245,10 +247,8 @@ static void sii902x_reset(struct sii902x *sii902x) · 69 unmodified lines
245247 gpiod_set_value(sii902x->reset_gpio, 0);
246248 }
247249
248−static enum drm_connector_status
249−sii902x_connector_detect(struct drm_connector *connector, bool force)
250+static enum drm_connector_status sii902x_detect(struct sii902x *sii902x)
250251 {
251− struct sii902x *sii902x = connector_to_sii902x(connector);
252252 unsigned int status;
253253
254254 mutex_lock(&sii902x->mutex);
@@ -261,6 +261,14 @@ sii902x_connector_detect(struct drm_connector *connector, bool force) · 6 unmodified lines
261261 connector_status_connected : connector_status_disconnected;
262262 }
263263
264+static enum drm_connector_status
265+sii902x_connector_detect(struct drm_connector *connector, bool force)
266+{
267+ struct sii902x *sii902x = connector_to_sii902x(connector);
268+
269+ return sii902x_detect(sii902x);
270+}
271+
264272 static const struct drm_connector_funcs sii902x_connector_funcs = {
265273 .detect = sii902x_connector_detect,
266274 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -270,42 +278,40 @@ static const struct drm_connector_funcs sii902x_connector_funcs = { · 3 unmodified lines
270278 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
271279 };
272280
273−static int sii902x_get_modes(struct drm_connector *connector)
281+static struct edid *sii902x_get_edid(struct sii902x *sii902x,
282+ struct drm_connector *connector)
274283 {
275− struct sii902x *sii902x = connector_to_sii902x(connector);
276− u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
277− u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
278284 struct edid *edid;
279− int num = 0, ret;
280285
281286 mutex_lock(&sii902x->mutex);
282287
283288 edid = drm_get_edid(connector, sii902x->i2cmux->adapter[0]);
284− drm_connector_update_edid_property(connector, edid);
285289 if (edid) {
286290 if (drm_detect_hdmi_monitor(edid))
287− output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
288−
289− num = drm_add_edid_modes(connector, edid);
290− kfree(edid);
291+ sii902x->sink_is_hdmi = true;
292+ else
293+ sii902x->sink_is_hdmi = false;
291294 }
292295
293− ret = drm_display_info_set_bus_formats(&connector->display_info,
294− &bus_format, 1);
295− if (ret)
296− goto error_out;
296+ mutex_unlock(&sii902x->mutex);
297297
298− ret = regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
299− SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
300− if (ret)
301− goto error_out;
298+ return edid;
299+}
302300
303− ret = num;
301+static int sii902x_get_modes(struct drm_connector *connector)
302+{
303+ struct sii902x *sii902x = connector_to_sii902x(connector);
304+ struct edid *edid;
305+ int num = 0;
304306
305−error_out:
306− mutex_unlock(&sii902x->mutex);
307+ edid = sii902x_get_edid(sii902x, connector);
308+ drm_connector_update_edid_property(connector, edid);
309+ if (edid) {
310+ num = drm_add_edid_modes(connector, edid);
311+ kfree(edid);
312+ }
307313
308− return ret;
314+ return num;
309315 }
310316
311317 static enum drm_mode_status sii902x_mode_valid(struct drm_connector *connector,
@@ -354,12 +360,16 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, · 42 unmodified lines
354360 const struct drm_display_mode *adj)
355361 {
356362 struct sii902x *sii902x = bridge_to_sii902x(bridge);
363+ u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
357364 struct regmap *regmap = sii902x->regmap;
358365 u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
359366 struct hdmi_avi_infoframe frame;
360367 u16 pixel_clock_10kHz = adj->clock / 10;
361368 int ret;
362369
370+ if (sii902x->sink_is_hdmi)
371+ output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
372+
363373 buf[0] = pixel_clock_10kHz & 0xff;
364374 buf[1] = pixel_clock_10kHz >> 8;
365375 buf[2] = drm_mode_vrefresh(adj);
@@ -375,6 +385,11 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, · 9 unmodified lines
375385
376386 mutex_lock(&sii902x->mutex);
377387
388+ ret = regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
389+ SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
390+ if (ret)
391+ goto out;
392+
378393 ret = regmap_bulk_write(regmap, SII902X_TPI_VIDEO_DATA, buf, 10);
379394 if (ret)
380395 goto out;
@@ -405,13 +420,13 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge, · 24 unmodified lines
405420 enum drm_bridge_attach_flags flags)
406421 {
407422 struct sii902x *sii902x = bridge_to_sii902x(bridge);
423+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
408424 struct drm_device *drm = bridge->dev;
409425 int ret;
410426
411− if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
412− DRM_ERROR("Fix bridge driver to make connector optional!");
413− return -EINVAL;
414− }
427+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
428+ return drm_bridge_attach(bridge->encoder, sii902x->next_bridge,
429+ bridge, flags);
415430
416431 drm_connector_helper_add(&sii902x->connector,
417432 &sii902x_connector_helper_funcs);
@@ -433,16 +448,38 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge, · 15 unmodified lines
433448 else
434449 sii902x->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
435450
451+ ret = drm_display_info_set_bus_formats(&sii902x->connector.display_info,
452+ &bus_format, 1);
453+ if (ret)
454+ return ret;
455+
436456 drm_connector_attach_encoder(&sii902x->connector, bridge->encoder);
437457
438458 return 0;
439459 }
440460
461+static enum drm_connector_status sii902x_bridge_detect(struct drm_bridge *bridge)
462+{
463+ struct sii902x *sii902x = bridge_to_sii902x(bridge);
464+
465+ return sii902x_detect(sii902x);
466+}
467+
468+static struct edid *sii902x_bridge_get_edid(struct drm_bridge *bridge,
469+ struct drm_connector *connector)
470+{
471+ struct sii902x *sii902x = bridge_to_sii902x(bridge);
472+
473+ return sii902x_get_edid(sii902x, connector);
474+}
475+
441476 static const struct drm_bridge_funcs sii902x_bridge_funcs = {
442477 .attach = sii902x_bridge_attach,
443478 .mode_set = sii902x_bridge_mode_set,
444479 .disable = sii902x_bridge_disable,
445480 .enable = sii902x_bridge_enable,
481+ .detect = sii902x_bridge_detect,
482+ .get_edid = sii902x_bridge_get_edid,
446483 };
447484
448485 static int sii902x_mute(struct sii902x *sii902x, bool mute)
@@ -829,8 +866,12 @@ static irqreturn_t sii902x_interrupt(int irq, void *data) · 380 unmodified lines
829866
830867 mutex_unlock(&sii902x->mutex);
831868
832− if ((status & SII902X_HOTPLUG_EVENT) && sii902x->bridge.dev)
869+ if ((status & SII902X_HOTPLUG_EVENT) && sii902x->bridge.dev) {
833870 drm_helper_hpd_irq_event(sii902x->bridge.dev);
871+ drm_bridge_hpd_notify(&sii902x->bridge, (status & SII902X_PLUGGED_STATUS)
872+ ? connector_status_connected
873+ : connector_status_disconnected);
874+ }
834875
835876 return IRQ_HANDLED;
836877 }
@@ -1001,6 +1042,11 @@ static int sii902x_init(struct sii902x *sii902x) · 164 unmodified lines
10011042 sii902x->bridge.funcs = &sii902x_bridge_funcs;
10021043 sii902x->bridge.of_node = dev->of_node;
10031044 sii902x->bridge.timings = &default_sii902x_timings;
1045+ sii902x->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID;
1046+
1047+ if (sii902x->i2c->irq > 0)
1048+ sii902x->bridge.ops |= DRM_BRIDGE_OP_HPD;
1049+
10041050 drm_bridge_add(&sii902x->bridge);
10051051
10061052 sii902x_audio_codec_init(sii902x, dev);
@@ -1022,6 +1068,7 @@ static int sii902x_probe(struct i2c_client *client, · 15 unmodified lines
10221068 const struct i2c_device_id *id)
10231069 {
10241070 struct device *dev = &client->dev;
1071+ struct device_node *endpoint;
10251072 struct sii902x *sii902x;
10261073 int ret;
10271074
@@ -1049,6 +1096,28 @@ static int sii902x_probe(struct i2c_client *client, · 21 unmodified lines
10491096 return PTR_ERR(sii902x->reset_gpio);
10501097 }
10511098
1099+ endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1);
1100+ if (endpoint) {
1101+ struct device_node *remote = of_graph_get_remote_port_parent(endpoint);
1102+
1103+ of_node_put(endpoint);
1104+ if (!remote) {
1105+ dev_err(dev, "Endpoint in port@1 unconnected\n");
1106+ return -ENODEV;
1107+ }
1108+
1109+ if (!of_device_is_available(remote)) {
1110+ dev_err(dev, "port@1 remote device is disabled\n");
1111+ of_node_put(remote);
1112+ return -ENODEV;
1113+ }
1114+
1115+ sii902x->next_bridge = of_drm_find_bridge(remote);
1116+ of_node_put(remote);
1117+ if (!sii902x->next_bridge)
1118+ return -EPROBE_DEFER;
1119+ }
1120+
10521121 mutex_init(&sii902x->mutex);
10531122
10541123 sii902x->supplies[0].supply = "iovcc";
drivers/gpu/drm/bridge/sil-sii8620.c+1−1
@@ -2120,7 +2120,7 @@ static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) · 2119 unmodified lines
21202120 if (ret) {
21212121 dev_err(ctx->dev, "Failed to register RC device\n");
21222122 ctx->error = ret;
2123− rc_free_device(ctx->rc_dev);
2123+ rc_free_device(rc_dev);
21242124 return;
21252125 }
21262126 ctx->rc_dev = rc_dev;
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c+8−8
@@ -2540,7 +2540,7 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, · 2539 unmodified lines
25402540 struct drm_display_mode *mode = &crtc_state->mode;
25412541 u8 max_bpc = conn_state->max_requested_bpc;
25422542 bool is_hdmi2_sink = info->hdmi.scdc.supported ||
2543− (info->color_formats & DRM_COLOR_FORMAT_YCRCB420);
2543+ (info->color_formats & DRM_COLOR_FORMAT_YCBCR420);
25442544 u32 *output_fmts;
25452545 unsigned int i = 0;
25462546
@@ -2594,36 +2594,36 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, · 47 unmodified lines
25942594 */
25952595
25962596 if (max_bpc >= 16 && info->bpc == 16) {
2597− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2597+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
25982598 output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
25992599
26002600 output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
26012601 }
26022602
26032603 if (max_bpc >= 12 && info->bpc >= 12) {
2604− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2604+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
26052605 output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
26062606
2607− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2607+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
26082608 output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
26092609
26102610 output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
26112611 }
26122612
26132613 if (max_bpc >= 10 && info->bpc >= 10) {
2614− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2614+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
26152615 output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
26162616
2617− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2617+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
26182618 output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
26192619
26202620 output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
26212621 }
26222622
2623− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
2623+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422)
26242624 output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
26252625
2626− if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
2626+ if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
26272627 output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
26282628
26292629 /* Default 8bit RGB fallback */
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c+17−8
@@ -871,7 +871,8 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi) · 870 unmodified lines
871871 dsi_write(dsi, DSI_INT_MSK1, 0);
872872 }
873873
874−static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
874+static void dw_mipi_dsi_bridge_post_atomic_disable(struct drm_bridge *bridge,
875+ struct drm_bridge_state *old_bridge_state)
875876 {
876877 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
877878 const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
@@ -978,7 +979,8 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge, · 100 unmodified lines
978979 dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
979980 }
980981
981−static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
982+static void dw_mipi_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
983+ struct drm_bridge_state *old_bridge_state)
982984 {
983985 struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
984986
@@ -998,7 +1000,10 @@ dw_mipi_dsi_bridge_mode_valid(struct drm_bridge *bridge, · 13 unmodified lines
9981000 enum drm_mode_status mode_status = MODE_OK;
9991001
10001002 if (pdata->mode_valid)
1001− mode_status = pdata->mode_valid(pdata->priv_data, mode);
1003+ mode_status = pdata->mode_valid(pdata->priv_data, mode,
1004+ dsi->mode_flags,
1005+ dw_mipi_dsi_get_lanes(dsi),
1006+ dsi->format);
10021007
10031008 return mode_status;
10041009 }
@@ -1032,11 +1037,14 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge, · 27 unmodified lines
10321037 }
10331038
10341039 static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
1035− .mode_set = dw_mipi_dsi_bridge_mode_set,
1036− .enable = dw_mipi_dsi_bridge_enable,
1037− .post_disable = dw_mipi_dsi_bridge_post_disable,
1038− .mode_valid = dw_mipi_dsi_bridge_mode_valid,
1039− .attach = dw_mipi_dsi_bridge_attach,
1040+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
1041+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
1042+ .atomic_reset = drm_atomic_helper_bridge_reset,
1043+ .atomic_enable = dw_mipi_dsi_bridge_atomic_enable,
1044+ .atomic_post_disable = dw_mipi_dsi_bridge_post_atomic_disable,
1045+ .mode_set = dw_mipi_dsi_bridge_mode_set,
1046+ .mode_valid = dw_mipi_dsi_bridge_mode_valid,
1047+ .attach = dw_mipi_dsi_bridge_attach,
10401048 };
10411049
10421050 #ifdef CONFIG_DEBUG_FS
@@ -1199,6 +1207,7 @@ __dw_mipi_dsi_probe(struct platform_device *pdev, · 156 unmodified lines
11991207 ret = mipi_dsi_host_register(&dsi->dsi_host);
12001208 if (ret) {
12011209 dev_err(dev, "Failed to register MIPI host: %d\n", ret);
1210+ pm_runtime_disable(dev);
12021211 dw_mipi_dsi_debugfs_remove(dsi);
12031212 return ERR_PTR(ret);
12041213 }
drivers/gpu/drm/bridge/tc358767.c+1−1
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727
2828 #include <drm/drm_atomic_helper.h>
2929 #include <drm/drm_bridge.h>
30−#include <drm/drm_dp_helper.h>
30+#include <drm/dp/drm_dp_helper.h>
3131 #include <drm/drm_edid.h>
3232 #include <drm/drm_of.h>
3333 #include <drm/drm_panel.h>
drivers/gpu/drm/bridge/tc358775.c+2−2
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 #include <drm/drm_atomic_helper.h>
2323 #include <drm/drm_bridge.h>
2424 #include <drm/drm_crtc_helper.h>
25−#include <drm/drm_dp_helper.h>
25+#include <drm/dp/drm_dp_helper.h>
2626 #include <drm/drm_mipi_dsi.h>
2727 #include <drm/drm_of.h>
2828 #include <drm/drm_panel.h>
@@ -241,7 +241,7 @@ static inline u32 TC358775_LVCFG_PCLKDIV(uint32_t val) · 212 unmodified lines
241241 }
242242
243243 #define TC358775_LVCFG_LVDLINK__MASK 0x00000002
244−#define TC358775_LVCFG_LVDLINK__SHIFT 0
244+#define TC358775_LVCFG_LVDLINK__SHIFT 1
245245 static inline u32 TC358775_LVCFG_LVDLINK(uint32_t val)
246246 {
247247 return ((val) << TC358775_LVCFG_LVDLINK__SHIFT) &
drivers/gpu/drm/bridge/ti-sn65dsi83.c+43−10
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 #include <linux/of_device.h>
3434 #include <linux/of_graph.h>
3535 #include <linux/regmap.h>
36+#include <linux/regulator/consumer.h>
3637
3738 #include <drm/drm_atomic_helper.h>
3839 #include <drm/drm_bridge.h>
@@ -143,6 +144,7 @@ struct sn65dsi83 { · 104 unmodified lines
143144 struct mipi_dsi_device *dsi;
144145 struct drm_bridge *panel_bridge;
145146 struct gpio_desc *enable_gpio;
147+ struct regulator *vcc;
146148 int dsi_lanes;
147149 bool lvds_dual_link;
148150 bool lvds_dual_link_even_odd_swap;
@@ -337,6 +339,12 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, · 188 unmodified lines
337339 u16 val;
338340 int ret;
339341
342+ ret = regulator_enable(ctx->vcc);
343+ if (ret) {
344+ dev_err(ctx->dev, "Failed to enable vcc: %d\n", ret);
345+ return;
346+ }
347+
340348 /* Deassert reset */
341349 gpiod_set_value(ctx->enable_gpio, 1);
342350 usleep_range(1000, 1100);
@@ -486,11 +494,16 @@ static void sn65dsi83_atomic_disable(struct drm_bridge *bridge, · 143 unmodified lines
486494 struct drm_bridge_state *old_bridge_state)
487495 {
488496 struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
497+ int ret;
489498
490499 /* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
491500 gpiod_set_value(ctx->enable_gpio, 0);
492501 usleep_range(10000, 11000);
493502
503+ ret = regulator_disable(ctx->vcc);
504+ if (ret)
505+ dev_err(ctx->dev, "Failed to disable vcc: %d\n", ret);
506+
494507 regcache_mark_dirty(ctx->regmap);
495508 }
496509
@@ -560,10 +573,14 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) · 63 unmodified lines
560573 ctx->host_node = of_graph_get_remote_port_parent(endpoint);
561574 of_node_put(endpoint);
562575
563− if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4)
564− return -EINVAL;
565− if (!ctx->host_node)
566− return -ENODEV;
576+ if (ctx->dsi_lanes < 0 || ctx->dsi_lanes > 4) {
577+ ret = -EINVAL;
578+ goto err_put_node;
579+ }
580+ if (!ctx->host_node) {
581+ ret = -ENODEV;
582+ goto err_put_node;
583+ }
567584
568585 ctx->lvds_dual_link = false;
569586 ctx->lvds_dual_link_even_odd_swap = false;
@@ -590,16 +607,27 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) · 20 unmodified lines
590607
591608 ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, &panel_bridge);
592609 if (ret < 0)
593− return ret;
610+ goto err_put_node;
594611 if (panel) {
595612 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
596− if (IS_ERR(panel_bridge))
597− return PTR_ERR(panel_bridge);
613+ if (IS_ERR(panel_bridge)) {
614+ ret = PTR_ERR(panel_bridge);
615+ goto err_put_node;
616+ }
598617 }
599618
600619 ctx->panel_bridge = panel_bridge;
601620
621+ ctx->vcc = devm_regulator_get(dev, "vcc");
622+ if (IS_ERR(ctx->vcc))
623+ return dev_err_probe(dev, PTR_ERR(ctx->vcc),
624+ "Failed to get supply 'vcc'\n");
625+
602626 return 0;
627+
628+err_put_node:
629+ of_node_put(ctx->host_node);
630+ return ret;
603631 }
604632
605633 static int sn65dsi83_host_attach(struct sn65dsi83 *ctx)
@@ -662,7 +690,8 @@ static int sn65dsi83_probe(struct i2c_client *client, · 56 unmodified lines
662690 }
663691
664692 /* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
665− ctx->enable_gpio = devm_gpiod_get(ctx->dev, "enable", GPIOD_OUT_LOW);
693+ ctx->enable_gpio = devm_gpiod_get_optional(ctx->dev, "enable",
694+ GPIOD_OUT_LOW);
666695 if (IS_ERR(ctx->enable_gpio))
667696 return PTR_ERR(ctx->enable_gpio);
668697
@@ -673,8 +702,10 @@ static int sn65dsi83_probe(struct i2c_client *client, · 4 unmodified lines
673702 return ret;
674703
675704 ctx->regmap = devm_regmap_init_i2c(client, &sn65dsi83_regmap_config);
676− if (IS_ERR(ctx->regmap))
677− return PTR_ERR(ctx->regmap);
705+ if (IS_ERR(ctx->regmap)) {
706+ ret = PTR_ERR(ctx->regmap);
707+ goto err_put_node;
708+ }
678709
679710 dev_set_drvdata(dev, ctx);
680711 i2c_set_clientdata(client, ctx);
@@ -691,6 +722,8 @@ static int sn65dsi83_probe(struct i2c_client *client, · 10 unmodified lines
691722
692723 err_remove_bridge:
693724 drm_bridge_remove(&ctx->bridge);
725+err_put_node:
726+ of_node_put(ctx->host_node);
694727 return ret;
695728 }
696729
drivers/gpu/drm/bridge/ti-sn65dsi86.c+2−2
@@ -26,8 +26,8 @@ · 25 unmodified lines
2626 #include <drm/drm_atomic.h>
2727 #include <drm/drm_atomic_helper.h>
2828 #include <drm/drm_bridge.h>
29−#include <drm/drm_dp_aux_bus.h>
30−#include <drm/drm_dp_helper.h>
29+#include <drm/dp/drm_dp_aux_bus.h>
30+#include <drm/dp/drm_dp_helper.h>
3131 #include <drm/drm_mipi_dsi.h>
3232 #include <drm/drm_of.h>
3333 #include <drm/drm_panel.h>
drivers/gpu/drm/dp/Makefile+9−0
@@ -0,0 +1,9 @@
1+# SPDX-License-Identifier: MIT
2+
3+obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o
4+
5+drm_dp_helper-y := drm_dp.o drm_dp_dual_mode_helper.o drm_dp_helper_mod.o drm_dp_mst_topology.o
6+drm_dp_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
7+drm_dp_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
8+
9+obj-$(CONFIG_DRM_DP_HELPER) += drm_dp_helper.o
drivers/gpu/drm/dp/drm_dp.crenamed from drivers/gpu/drm/drm_dp_helper.c+3−3
@@ -29,13 +29,13 @@ · 28 unmodified lines
2929 #include <linux/sched.h>
3030 #include <linux/seq_file.h>
3131
32−#include <drm/drm_dp_helper.h>
32+#include <drm/dp/drm_dp_helper.h>
3333 #include <drm/drm_print.h>
3434 #include <drm/drm_vblank.h>
35−#include <drm/drm_dp_mst_helper.h>
35+#include <drm/dp/drm_dp_mst_helper.h>
3636 #include <drm/drm_panel.h>
3737
38−#include "drm_crtc_helper_internal.h"
38+#include "drm_dp_helper_internal.h"
3939
4040 struct dp_aux_backlight {
4141 struct backlight_device *base;
drivers/gpu/drm/dp/drm_dp_aux_bus.crenamed from drivers/gpu/drm/drm_dp_aux_bus.c+2−2
@@ -19,8 +19,8 @@ · 18 unmodified lines
1919 #include <linux/pm_domain.h>
2020 #include <linux/pm_runtime.h>
2121
22−#include <drm/drm_dp_aux_bus.h>
23−#include <drm/drm_dp_helper.h>
22+#include <drm/dp/drm_dp_aux_bus.h>
23+#include <drm/dp/drm_dp_helper.h>
2424
2525 /**
2626 * dp_aux_ep_match() - The match function for the dp_aux_bus.
drivers/gpu/drm/dp/drm_dp_aux_dev.crenamed from drivers/gpu/drm/drm_dp_aux_dev.c+3−3
@@ -36,11 +36,11 @@ · 35 unmodified lines
3636 #include <linux/uio.h>
3737
3838 #include <drm/drm_crtc.h>
39−#include <drm/drm_dp_helper.h>
40−#include <drm/drm_dp_mst_helper.h>
39+#include <drm/dp/drm_dp_helper.h>
40+#include <drm/dp/drm_dp_mst_helper.h>
4141 #include <drm/drm_print.h>
4242
43−#include "drm_crtc_helper_internal.h"
43+#include "drm_dp_helper_internal.h"
4444
4545 struct drm_dp_aux_dev {
4646 unsigned index;
drivers/gpu/drm/dp/drm_dp_cec.crenamed from drivers/gpu/drm/drm_dp_cec.c+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313
1414 #include <drm/drm_connector.h>
1515 #include <drm/drm_device.h>
16−#include <drm/drm_dp_helper.h>
16+#include <drm/dp/drm_dp_helper.h>
1717
1818 /*
1919 * Unfortunately it turns out that we have a chicken-and-egg situation
drivers/gpu/drm/dp/drm_dp_dual_mode_helper.crenamed from drivers/gpu/drm/drm_dp_dual_mode_helper.c+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
2828 #include <linux/string.h>
2929
3030 #include <drm/drm_device.h>
31−#include <drm/drm_dp_dual_mode_helper.h>
31+#include <drm/dp/drm_dp_dual_mode_helper.h>
3232 #include <drm/drm_print.h>
3333
3434 /**
drivers/gpu/drm/dp/drm_dp_helper_internal.h+33−0
@@ -0,0 +1,33 @@
1+/* SPDX-License-Identifier: MIT */
2+
3+#ifndef DRM_DP_HELPER_INTERNAL_H
4+#define DRM_DP_HELPER_INTERNAL_H
5+
6+struct drm_dp_aux;
7+
8+#ifdef CONFIG_DRM_DP_AUX_CHARDEV
9+int drm_dp_aux_dev_init(void);
10+void drm_dp_aux_dev_exit(void);
11+int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
12+void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
13+#else
14+static inline int drm_dp_aux_dev_init(void)
15+{
16+ return 0;
17+}
18+
19+static inline void drm_dp_aux_dev_exit(void)
20+{
21+}
22+
23+static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
24+{
25+ return 0;
26+}
27+
28+static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
29+{
30+}
31+#endif
32+
33+#endif
drivers/gpu/drm/dp/drm_dp_helper_mod.c+22−0
@@ -0,0 +1,22 @@
1+// SPDX-License-Identifier: MIT
2+
3+#include <linux/module.h>
4+
5+#include "drm_dp_helper_internal.h"
6+
7+MODULE_DESCRIPTION("DRM DisplayPort helper");
8+MODULE_LICENSE("GPL and additional rights");
9+
10+static int __init drm_dp_helper_module_init(void)
11+{
12+ return drm_dp_aux_dev_init();
13+}
14+
15+static void __exit drm_dp_helper_module_exit(void)
16+{
17+ /* Call exit functions from specific dp helpers here */
18+ drm_dp_aux_dev_exit();
19+}
20+
21+module_init(drm_dp_helper_module_init);
22+module_exit(drm_dp_helper_module_exit);
drivers/gpu/drm/dp/drm_dp_mst_topology.crenamed from drivers/gpu/drm/drm_dp_mst_topology.c+4−4
@@ -38,14 +38,14 @@ · 37 unmodified lines
3838 #include <linux/math64.h>
3939 #endif
4040
41+#include <drm/dp/drm_dp_mst_helper.h>
4142 #include <drm/drm_atomic.h>
4243 #include <drm/drm_atomic_helper.h>
43−#include <drm/drm_dp_mst_helper.h>
4444 #include <drm/drm_drv.h>
4545 #include <drm/drm_print.h>
4646 #include <drm/drm_probe_helper.h>
4747
48−#include "drm_crtc_helper_internal.h"
48+#include "drm_dp_helper_internal.h"
4949 #include "drm_dp_mst_topology_internal.h"
5050
5151 /**
@@ -4196,7 +4196,7 @@ int drm_dp_mst_hpd_irq(struct drm_dp_mst_topology_mgr *mgr, u8 *esi, bool *handl · 4144 unmodified lines
41964196 int ret = 0;
41974197 int sc;
41984198 *handled = false;
4199− sc = esi[0] & 0x3f;
4199+ sc = DP_GET_SINK_COUNT(esi[0]);
42004200
42014201 if (sc != mgr->sink_count) {
42024202 mgr->sink_count = sc;
@@ -4811,7 +4811,7 @@ static void drm_dp_mst_dump_mstb(struct seq_file *m, · 608 unmodified lines
48114811
48124812 seq_printf(m, "%smstb - [%p]: num_ports: %d\n", prefix, mstb, mstb->num_ports);
48134813 list_for_each_entry(port, &mstb->ports, next) {
4814− seq_printf(m, "%sport %d - [%p] (%s - %s): ddps: %d, ldps: %d, sdp: %d/%d, fec: %s, conn: %p\n",
4814+ seq_printf(m, "%sport %d - [%p] (%s - %s): ddps: %d, ldps: %d, sdp: %d/%d, fec: %s, conn: %p\n",
48154815 prefix,
48164816 port->port_num,
48174817 port,
drivers/gpu/drm/dp/drm_dp_mst_topology_internal.hrenamed from drivers/gpu/drm/drm_dp_mst_topology_internal.h+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
1010 #ifndef _DRM_DP_MST_HELPER_INTERNAL_H_
1111 #define _DRM_DP_MST_HELPER_INTERNAL_H_
1212
13−#include <drm/drm_dp_mst_helper.h>
13+#include <drm/dp/drm_dp_mst_helper.h>
1414
1515 void
1616 drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
drivers/gpu/drm/drm_buddy.c+535−0
@@ -0,0 +1,535 @@
1+// SPDX-License-Identifier: MIT
2+/*
3+ * Copyright © 2021 Intel Corporation
4+ */
5+
6+#include <linux/kmemleak.h>
7+#include <linux/module.h>
8+#include <linux/sizes.h>
9+
10+#include <drm/drm_buddy.h>
11+
12+static struct kmem_cache *slab_blocks;
13+
14+static struct drm_buddy_block *drm_block_alloc(struct drm_buddy *mm,
15+ struct drm_buddy_block *parent,
16+ unsigned int order,
17+ u64 offset)
18+{
19+ struct drm_buddy_block *block;
20+
21+ BUG_ON(order > DRM_BUDDY_MAX_ORDER);
22+
23+ block = kmem_cache_zalloc(slab_blocks, GFP_KERNEL);
24+ if (!block)
25+ return NULL;
26+
27+ block->header = offset;
28+ block->header |= order;
29+ block->parent = parent;
30+
31+ BUG_ON(block->header & DRM_BUDDY_HEADER_UNUSED);
32+ return block;
33+}
34+
35+static void drm_block_free(struct drm_buddy *mm,
36+ struct drm_buddy_block *block)
37+{
38+ kmem_cache_free(slab_blocks, block);
39+}
40+
41+static void mark_allocated(struct drm_buddy_block *block)
42+{
43+ block->header &= ~DRM_BUDDY_HEADER_STATE;
44+ block->header |= DRM_BUDDY_ALLOCATED;
45+
46+ list_del(&block->link);
47+}
48+
49+static void mark_free(struct drm_buddy *mm,
50+ struct drm_buddy_block *block)
51+{
52+ block->header &= ~DRM_BUDDY_HEADER_STATE;
53+ block->header |= DRM_BUDDY_FREE;
54+
55+ list_add(&block->link,
56+ &mm->free_list[drm_buddy_block_order(block)]);
57+}
58+
59+static void mark_split(struct drm_buddy_block *block)
60+{
61+ block->header &= ~DRM_BUDDY_HEADER_STATE;
62+ block->header |= DRM_BUDDY_SPLIT;
63+
64+ list_del(&block->link);
65+}
66+
67+/**
68+ * drm_buddy_init - init memory manager
69+ *
70+ * @mm: DRM buddy manager to initialize
71+ * @size: size in bytes to manage
72+ * @chunk_size: minimum page size in bytes for our allocations
73+ *
74+ * Initializes the memory manager and its resources.
75+ *
76+ * Returns:
77+ * 0 on success, error code on failure.
78+ */
79+int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size)
80+{
81+ unsigned int i;
82+ u64 offset;
83+
84+ if (size < chunk_size)
85+ return -EINVAL;
86+
87+ if (chunk_size < PAGE_SIZE)
88+ return -EINVAL;
89+
90+ if (!is_power_of_2(chunk_size))
91+ return -EINVAL;
92+
93+ size = round_down(size, chunk_size);
94+
95+ mm->size = size;
96+ mm->avail = size;
97+ mm->chunk_size = chunk_size;
98+ mm->max_order = ilog2(size) - ilog2(chunk_size);
99+
100+ BUG_ON(mm->max_order > DRM_BUDDY_MAX_ORDER);
101+
102+ mm->free_list = kmalloc_array(mm->max_order + 1,
103+ sizeof(struct list_head),
104+ GFP_KERNEL);
105+ if (!mm->free_list)
106+ return -ENOMEM;
107+
108+ for (i = 0; i <= mm->max_order; ++i)
109+ INIT_LIST_HEAD(&mm->free_list[i]);
110+
111+ mm->n_roots = hweight64(size);
112+
113+ mm->roots = kmalloc_array(mm->n_roots,
114+ sizeof(struct drm_buddy_block *),
115+ GFP_KERNEL);
116+ if (!mm->roots)
117+ goto out_free_list;
118+
119+ offset = 0;
120+ i = 0;
121+
122+ /*
123+ * Split into power-of-two blocks, in case we are given a size that is
124+ * not itself a power-of-two.
125+ */
126+ do {
127+ struct drm_buddy_block *root;
128+ unsigned int order;
129+ u64 root_size;
130+
131+ root_size = rounddown_pow_of_two(size);
132+ order = ilog2(root_size) - ilog2(chunk_size);
133+
134+ root = drm_block_alloc(mm, NULL, order, offset);
135+ if (!root)
136+ goto out_free_roots;
137+
138+ mark_free(mm, root);
139+
140+ BUG_ON(i > mm->max_order);
141+ BUG_ON(drm_buddy_block_size(mm, root) < chunk_size);
142+
143+ mm->roots[i] = root;
144+
145+ offset += root_size;
146+ size -= root_size;
147+ i++;
148+ } while (size);
149+
150+ return 0;
151+
152+out_free_roots:
153+ while (i--)
154+ drm_block_free(mm, mm->roots[i]);
155+ kfree(mm->roots);
156+out_free_list:
157+ kfree(mm->free_list);
158+ return -ENOMEM;
159+}
160+EXPORT_SYMBOL(drm_buddy_init);
161+
162+/**
163+ * drm_buddy_fini - tear down the memory manager
164+ *
165+ * @mm: DRM buddy manager to free
166+ *
167+ * Cleanup memory manager resources and the freelist
168+ */
169+void drm_buddy_fini(struct drm_buddy *mm)
170+{
171+ int i;
172+
173+ for (i = 0; i < mm->n_roots; ++i) {
174+ WARN_ON(!drm_buddy_block_is_free(mm->roots[i]));
175+ drm_block_free(mm, mm->roots[i]);
176+ }
177+
178+ WARN_ON(mm->avail != mm->size);
179+
180+ kfree(mm->roots);
181+ kfree(mm->free_list);
182+}
183+EXPORT_SYMBOL(drm_buddy_fini);
184+
185+static int split_block(struct drm_buddy *mm,
186+ struct drm_buddy_block *block)
187+{
188+ unsigned int block_order = drm_buddy_block_order(block) - 1;
189+ u64 offset = drm_buddy_block_offset(block);
190+
191+ BUG_ON(!drm_buddy_block_is_free(block));
192+ BUG_ON(!drm_buddy_block_order(block));
193+
194+ block->left = drm_block_alloc(mm, block, block_order, offset);
195+ if (!block->left)
196+ return -ENOMEM;
197+
198+ block->right = drm_block_alloc(mm, block, block_order,
199+ offset + (mm->chunk_size << block_order));
200+ if (!block->right) {
201+ drm_block_free(mm, block->left);
202+ return -ENOMEM;
203+ }
204+
205+ mark_free(mm, block->left);
206+ mark_free(mm, block->right);
207+
208+ mark_split(block);
209+
210+ return 0;
211+}
212+
213+static struct drm_buddy_block *
214+get_buddy(struct drm_buddy_block *block)
215+{
216+ struct drm_buddy_block *parent;
217+
218+ parent = block->parent;
219+ if (!parent)
220+ return NULL;
221+
222+ if (parent->left == block)
223+ return parent->right;
224+
225+ return parent->left;
226+}
227+
228+static void __drm_buddy_free(struct drm_buddy *mm,
229+ struct drm_buddy_block *block)
230+{
231+ struct drm_buddy_block *parent;
232+
233+ while ((parent = block->parent)) {
234+ struct drm_buddy_block *buddy;
235+
236+ buddy = get_buddy(block);
237+
238+ if (!drm_buddy_block_is_free(buddy))
239+ break;
240+
241+ list_del(&buddy->link);
242+
243+ drm_block_free(mm, block);
244+ drm_block_free(mm, buddy);
245+
246+ block = parent;
247+ }
248+
249+ mark_free(mm, block);
250+}
251+
252+/**
253+ * drm_buddy_free_block - free a block
254+ *
255+ * @mm: DRM buddy manager
256+ * @block: block to be freed
257+ */
258+void drm_buddy_free_block(struct drm_buddy *mm,
259+ struct drm_buddy_block *block)
260+{
261+ BUG_ON(!drm_buddy_block_is_allocated(block));
262+ mm->avail += drm_buddy_block_size(mm, block);
263+ __drm_buddy_free(mm, block);
264+}
265+EXPORT_SYMBOL(drm_buddy_free_block);
266+
267+/**
268+ * drm_buddy_free_list - free blocks
269+ *
270+ * @mm: DRM buddy manager
271+ * @objects: input list head to free blocks
272+ */
273+void drm_buddy_free_list(struct drm_buddy *mm, struct list_head *objects)
274+{
275+ struct drm_buddy_block *block, *on;
276+
277+ list_for_each_entry_safe(block, on, objects, link) {
278+ drm_buddy_free_block(mm, block);
279+ cond_resched();
280+ }
281+ INIT_LIST_HEAD(objects);
282+}
283+EXPORT_SYMBOL(drm_buddy_free_list);
284+
285+/**
286+ * drm_buddy_alloc_blocks - allocate power-of-two blocks
287+ *
288+ * @mm: DRM buddy manager to allocate from
289+ * @order: size of the allocation
290+ *
291+ * The order value here translates to:
292+ *
293+ * 0 = 2^0 * mm->chunk_size
294+ * 1 = 2^1 * mm->chunk_size
295+ * 2 = 2^2 * mm->chunk_size
296+ *
297+ * Returns:
298+ * allocated ptr to the &drm_buddy_block on success
299+ */
300+struct drm_buddy_block *
301+drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned int order)
302+{
303+ struct drm_buddy_block *block = NULL;
304+ unsigned int i;
305+ int err;
306+
307+ for (i = order; i <= mm->max_order; ++i) {
308+ block = list_first_entry_or_null(&mm->free_list[i],
309+ struct drm_buddy_block,
310+ link);
311+ if (block)
312+ break;
313+ }
314+
315+ if (!block)
316+ return ERR_PTR(-ENOSPC);
317+
318+ BUG_ON(!drm_buddy_block_is_free(block));
319+
320+ while (i != order) {
321+ err = split_block(mm, block);
322+ if (unlikely(err))
323+ goto out_free;
324+
325+ /* Go low */
326+ block = block->left;
327+ i--;
328+ }
329+
330+ mark_allocated(block);
331+ mm->avail -= drm_buddy_block_size(mm, block);
332+ kmemleak_update_trace(block);
333+ return block;
334+
335+out_free:
336+ if (i != order)
337+ __drm_buddy_free(mm, block);
338+ return ERR_PTR(err);
339+}
340+EXPORT_SYMBOL(drm_buddy_alloc_blocks);
341+
342+static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2)
343+{
344+ return s1 <= e2 && e1 >= s2;
345+}
346+
347+static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2)
348+{
349+ return s1 <= s2 && e1 >= e2;
350+}
351+
352+/**
353+ * drm_buddy_alloc_range - allocate range
354+ *
355+ * @mm: DRM buddy manager to allocate from
356+ * @blocks: output list head to add allocated blocks
357+ * @start: start of the allowed range for this block
358+ * @size: size of the allocation
359+ *
360+ * Intended for pre-allocating portions of the address space, for example to
361+ * reserve a block for the initial framebuffer or similar, hence the expectation
362+ * here is that drm_buddy_alloc_blocks() is still the main vehicle for
363+ * allocations, so if that's not the case then the drm_mm range allocator is
364+ * probably a much better fit, and so you should probably go use that instead.
365+ *
366+ * Note that it's safe to chain together multiple alloc_ranges
367+ * with the same blocks list
368+ *
369+ * Returns:
370+ * 0 on success, error code on failure.
371+ */
372+int drm_buddy_alloc_range(struct drm_buddy *mm,
373+ struct list_head *blocks,
374+ u64 start, u64 size)
375+{
376+ struct drm_buddy_block *block;
377+ struct drm_buddy_block *buddy;
378+ LIST_HEAD(allocated);
379+ LIST_HEAD(dfs);
380+ u64 end;
381+ int err;
382+ int i;
383+
384+ if (size < mm->chunk_size)
385+ return -EINVAL;
386+
387+ if (!IS_ALIGNED(size | start, mm->chunk_size))
388+ return -EINVAL;
389+
390+ if (range_overflows(start, size, mm->size))
391+ return -EINVAL;
392+
393+ for (i = 0; i < mm->n_roots; ++i)
394+ list_add_tail(&mm->roots[i]->tmp_link, &dfs);
395+
396+ end = start + size - 1;
397+
398+ do {
399+ u64 block_start;
400+ u64 block_end;
401+
402+ block = list_first_entry_or_null(&dfs,
403+ struct drm_buddy_block,
404+ tmp_link);
405+ if (!block)
406+ break;
407+
408+ list_del(&block->tmp_link);
409+
410+ block_start = drm_buddy_block_offset(block);
411+ block_end = block_start + drm_buddy_block_size(mm, block) - 1;
412+
413+ if (!overlaps(start, end, block_start, block_end))
414+ continue;
415+
416+ if (drm_buddy_block_is_allocated(block)) {
417+ err = -ENOSPC;
418+ goto err_free;
419+ }
420+
421+ if (contains(start, end, block_start, block_end)) {
422+ if (!drm_buddy_block_is_free(block)) {
423+ err = -ENOSPC;
424+ goto err_free;
425+ }
426+
427+ mark_allocated(block);
428+ mm->avail -= drm_buddy_block_size(mm, block);
429+ list_add_tail(&block->link, &allocated);
430+ continue;
431+ }
432+
433+ if (!drm_buddy_block_is_split(block)) {
434+ err = split_block(mm, block);
435+ if (unlikely(err))
436+ goto err_undo;
437+ }
438+
439+ list_add(&block->right->tmp_link, &dfs);
440+ list_add(&block->left->tmp_link, &dfs);
441+ } while (1);
442+
443+ list_splice_tail(&allocated, blocks);
444+ return 0;
445+
446+err_undo:
447+ /*
448+ * We really don't want to leave around a bunch of split blocks, since
449+ * bigger is better, so make sure we merge everything back before we
450+ * free the allocated blocks.
451+ */
452+ buddy = get_buddy(block);
453+ if (buddy &&
454+ (drm_buddy_block_is_free(block) &&
455+ drm_buddy_block_is_free(buddy)))
456+ __drm_buddy_free(mm, block);
457+
458+err_free:
459+ drm_buddy_free_list(mm, &allocated);
460+ return err;
461+}
462+EXPORT_SYMBOL(drm_buddy_alloc_range);
463+
464+/**
465+ * drm_buddy_block_print - print block information
466+ *
467+ * @mm: DRM buddy manager
468+ * @block: DRM buddy block
469+ * @p: DRM printer to use
470+ */
471+void drm_buddy_block_print(struct drm_buddy *mm,
472+ struct drm_buddy_block *block,
473+ struct drm_printer *p)
474+{
475+ u64 start = drm_buddy_block_offset(block);
476+ u64 size = drm_buddy_block_size(mm, block);
477+
478+ drm_printf(p, "%#018llx-%#018llx: %llu\n", start, start + size, size);
479+}
480+EXPORT_SYMBOL(drm_buddy_block_print);
481+
482+/**
483+ * drm_buddy_print - print allocator state
484+ *
485+ * @mm: DRM buddy manager
486+ * @p: DRM printer to use
487+ */
488+void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p)
489+{
490+ int order;
491+
492+ drm_printf(p, "chunk_size: %lluKiB, total: %lluMiB, free: %lluMiB\n",
493+ mm->chunk_size >> 10, mm->size >> 20, mm->avail >> 20);
494+
495+ for (order = mm->max_order; order >= 0; order--) {
496+ struct drm_buddy_block *block;
497+ u64 count = 0, free;
498+
499+ list_for_each_entry(block, &mm->free_list[order], link) {
500+ BUG_ON(!drm_buddy_block_is_free(block));
501+ count++;
502+ }
503+
504+ drm_printf(p, "order-%d ", order);
505+
506+ free = count * (mm->chunk_size << order);
507+ if (free < SZ_1M)
508+ drm_printf(p, "free: %lluKiB", free >> 10);
509+ else
510+ drm_printf(p, "free: %lluMiB", free >> 20);
511+
512+ drm_printf(p, ", pages: %llu\n", count);
513+ }
514+}
515+EXPORT_SYMBOL(drm_buddy_print);
516+
517+static void drm_buddy_module_exit(void)
518+{
519+ kmem_cache_destroy(slab_blocks);
520+}
521+
522+static int __init drm_buddy_module_init(void)
523+{
524+ slab_blocks = KMEM_CACHE(drm_buddy_block, 0);
525+ if (!slab_blocks)
526+ return -ENOMEM;
527+
528+ return 0;
529+}
530+
531+module_init(drm_buddy_module_init);
532+module_exit(drm_buddy_module_exit);
533+
534+MODULE_DESCRIPTION("DRM Buddy Allocator");
535+MODULE_LICENSE("Dual MIT/GPL");
drivers/gpu/drm/drm_color_mgmt.c+4−0
@@ -82,6 +82,10 @@ · 81 unmodified lines
8282 * driver boot-up state too. Drivers can access this blob through
8383 * &drm_crtc_state.gamma_lut.
8484 *
85+ * Note that for mostly historical reasons stemming from Xorg heritage,
86+ * this is also used to store the color map (also sometimes color lut, CLUT
87+ * or color palette) for indexed formats like DRM_FORMAT_C8.
88+ *
8589 * “GAMMA_LUT_SIZE”:
8690 * Unsigned range property to give the size of the lookup table to be set
8791 * on the GAMMA_LUT property (the size depends on the underlying hardware).
drivers/gpu/drm/drm_crtc_helper_internal.h+0−27
@@ -28,36 +28,9 @@ · 27 unmodified lines
2828
2929 #include <drm/drm_connector.h>
3030 #include <drm/drm_crtc.h>
31−#include <drm/drm_dp_helper.h>
3231 #include <drm/drm_encoder.h>
3332 #include <drm/drm_modes.h>
3433
35−/* drm_dp_aux_dev.c */
36−#ifdef CONFIG_DRM_DP_AUX_CHARDEV
37−int drm_dp_aux_dev_init(void);
38−void drm_dp_aux_dev_exit(void);
39−int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
40−void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
41−#else
42−static inline int drm_dp_aux_dev_init(void)
43−{
44− return 0;
45−}
46−
47−static inline void drm_dp_aux_dev_exit(void)
48−{
49−}
50−
51−static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
52−{
53− return 0;
54−}
55−
56−static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
57−{
58−}
59−#endif
60−
6134 /* drm_probe_helper.c */
6235 enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
6336 const struct drm_display_mode *mode);
drivers/gpu/drm/drm_dsc.c+1−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
1212 #include <linux/errno.h>
1313 #include <linux/byteorder/generic.h>
1414 #include <drm/drm_print.h>
15−#include <drm/drm_dp_helper.h>
15+#include <drm/dp/drm_dp_helper.h>
1616 #include <drm/drm_dsc.h>
1717
1818 /**
drivers/gpu/drm/drm_edid.c+68−36
@@ -93,6 +93,8 @@ static int oui(u8 first, u8 second, u8 third) · 92 unmodified lines
9393 /* Non desktop display (i.e. HMD) */
9494 #define EDID_QUIRK_NON_DESKTOP (1 << 12)
9595
96+#define MICROSOFT_IEEE_OUI 0xca125c
97+
9698 struct detailed_mode_closure {
9799 struct drm_connector *connector;
98100 struct edid *edid;
@@ -212,9 +214,7 @@ static const struct edid_quirk { · 113 unmodified lines
212214
213215 /* Windows Mixed Reality Headsets */
214216 EDID_QUIRK('A', 'C', 'R', 0x7fce, EDID_QUIRK_NON_DESKTOP),
215− EDID_QUIRK('H', 'P', 'N', 0x3515, EDID_QUIRK_NON_DESKTOP),
216217 EDID_QUIRK('L', 'E', 'N', 0x0408, EDID_QUIRK_NON_DESKTOP),
217− EDID_QUIRK('L', 'E', 'N', 0xb800, EDID_QUIRK_NON_DESKTOP),
218218 EDID_QUIRK('F', 'U', 'J', 0x1970, EDID_QUIRK_NON_DESKTOP),
219219 EDID_QUIRK('D', 'E', 'L', 0x7fce, EDID_QUIRK_NON_DESKTOP),
220220 EDID_QUIRK('S', 'E', 'C', 0x144a, EDID_QUIRK_NON_DESKTOP),
@@ -3776,7 +3776,7 @@ static int do_y420vdb_modes(struct drm_connector *connector, · 3555 unmodified lines
37763776 }
37773777
37783778 if (modes > 0)
3779− info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
3779+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
37803780 return modes;
37813781 }
37823782
@@ -4222,6 +4222,17 @@ static bool cea_db_is_hdmi_forum_vsdb(const u8 *db) · 439 unmodified lines
42224222 return oui(db[3], db[2], db[1]) == HDMI_FORUM_IEEE_OUI;
42234223 }
42244224
4225+static bool cea_db_is_microsoft_vsdb(const u8 *db)
4226+{
4227+ if (cea_db_tag(db) != VENDOR_BLOCK)
4228+ return false;
4229+
4230+ if (cea_db_payload_len(db) != 21)
4231+ return false;
4232+
4233+ return oui(db[3], db[2], db[1]) == MICROSOFT_IEEE_OUI;
4234+}
4235+
42254236 static bool cea_db_is_vcdb(const u8 *db)
42264237 {
42274238 if (cea_db_tag(db) != USE_EXTENDED_TAG)
@@ -4279,7 +4290,7 @@ static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, · 51 unmodified lines
42794290 if (map_len == 0) {
42804291 /* All CEA modes support ycbcr420 sampling also.*/
42814292 hdmi->y420_cmdb_map = U64_MAX;
4282− info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
4293+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
42834294 return;
42844295 }
42854296
@@ -4302,7 +4313,7 @@ static void drm_parse_y420cmdb_bitmap(struct drm_connector *connector, · 16 unmodified lines
43024313 map |= (u64)db[2 + count] << (8 * count);
43034314
43044315 if (map)
4305− info->color_formats |= DRM_COLOR_FORMAT_YCRCB420;
4316+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR420;
43064317
43074318 hdmi->y420_cmdb_map = map;
43084319 }
@@ -5075,21 +5086,21 @@ static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector, · 766 unmodified lines
50755086
50765087 if (hdmi[6] & DRM_EDID_HDMI_DC_30) {
50775088 dc_bpc = 10;
5078− info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_30;
5089+ info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_30;
50795090 DRM_DEBUG("%s: HDMI sink does deep color 30.\n",
50805091 connector->name);
50815092 }
50825093
50835094 if (hdmi[6] & DRM_EDID_HDMI_DC_36) {
50845095 dc_bpc = 12;
5085− info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_36;
5096+ info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_36;
50865097 DRM_DEBUG("%s: HDMI sink does deep color 36.\n",
50875098 connector->name);
50885099 }
50895100
50905101 if (hdmi[6] & DRM_EDID_HDMI_DC_48) {
50915102 dc_bpc = 16;
5092− info->edid_hdmi_dc_modes |= DRM_EDID_HDMI_DC_48;
5103+ info->edid_hdmi_rgb444_dc_modes |= DRM_EDID_HDMI_DC_48;
50935104 DRM_DEBUG("%s: HDMI sink does deep color 48.\n",
50945105 connector->name);
50955106 }
@@ -5104,16 +5115,9 @@ static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector, · 8 unmodified lines
51045115 connector->name, dc_bpc);
51055116 info->bpc = dc_bpc;
51065117
5107− /*
5108− * Deep color support mandates RGB444 support for all video
5109− * modes and forbids YCRCB422 support for all video modes per
5110− * HDMI 1.3 spec.
5111− */
5112− info->color_formats = DRM_COLOR_FORMAT_RGB444;
5113−
51145118 /* YCRCB444 is optional according to spec. */
51155119 if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) {
5116− info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
5120+ info->edid_hdmi_ycbcr444_dc_modes = info->edid_hdmi_rgb444_dc_modes;
51175121 DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n",
51185122 connector->name);
51195123 }
@@ -5149,6 +5153,25 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db) · 29 unmodified lines
51495153 drm_parse_hdmi_deep_color_info(connector, db);
51505154 }
51515155
5156+/*
5157+ * See EDID extension for head-mounted and specialized monitors, specified at:
5158+ * https://docs.microsoft.com/en-us/windows-hardware/drivers/display/specialized-monitors-edid-extension
5159+ */
5160+static void drm_parse_microsoft_vsdb(struct drm_connector *connector,
5161+ const u8 *db)
5162+{
5163+ struct drm_display_info *info = &connector->display_info;
5164+ u8 version = db[4];
5165+ bool desktop_usage = db[5] & BIT(6);
5166+
5167+ /* Version 1 and 2 for HMDs, version 3 flags desktop usage explicitly */
5168+ if (version == 1 || version == 2 || (version == 3 && !desktop_usage))
5169+ info->non_desktop = true;
5170+
5171+ drm_dbg_kms(connector->dev, "HMD or specialized display VSDB version %u: 0x%02x\n",
5172+ version, db[5]);
5173+}
5174+
51525175 static void drm_parse_cea_ext(struct drm_connector *connector,
51535176 const struct edid *edid)
51545177 {
@@ -5165,9 +5188,9 @@ static void drm_parse_cea_ext(struct drm_connector *connector, · 10 unmodified lines
51655188 /* The existence of a CEA block should imply RGB support */
51665189 info->color_formats = DRM_COLOR_FORMAT_RGB444;
51675190 if (edid_ext[3] & EDID_CEA_YCRCB444)
5168− info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
5191+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR444;
51695192 if (edid_ext[3] & EDID_CEA_YCRCB422)
5170− info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
5193+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR422;
51715194
51725195 if (cea_db_offsets(edid_ext, &start, &end))
51735196 return;
@@ -5179,6 +5202,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector, · 5 unmodified lines
51795202 drm_parse_hdmi_vsdb_video(connector, db);
51805203 if (cea_db_is_hdmi_forum_vsdb(db))
51815204 drm_parse_hdmi_forum_vsdb(connector, db);
5205+ if (cea_db_is_microsoft_vsdb(db))
5206+ drm_parse_microsoft_vsdb(connector, db);
51825207 if (cea_db_is_y420cmdb(db))
51835208 drm_parse_y420cmdb_bitmap(connector, db);
51845209 if (cea_db_is_vcdb(db))
@@ -5333,17 +5358,13 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi · 148 unmodified lines
53335358 info->width_mm = edid->width_cm * 10;
53345359 info->height_mm = edid->height_cm * 10;
53355360
5336− info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
5337−
53385361 drm_get_monitor_range(connector, edid);
53395362
5340− DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
5341−
53425363 if (edid->revision < 3)
5343− return quirks;
5364+ goto out;
53445365
53455366 if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
5346− return quirks;
5367+ goto out;
53475368
53485369 drm_parse_cea_ext(connector, edid);
53495370
@@ -5363,7 +5384,7 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi · 13 unmodified lines
53635384
53645385 /* Only defined for 1.4 with digital displays */
53655386 if (edid->revision < 4)
5366− return quirks;
5387+ goto out;
53675388
53685389 switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
53695390 case DRM_EDID_DIGITAL_DEPTH_6:
@@ -5395,17 +5416,25 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi · 25 unmodified lines
53955416
53965417 info->color_formats |= DRM_COLOR_FORMAT_RGB444;
53975418 if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444)
5398− info->color_formats |= DRM_COLOR_FORMAT_YCRCB444;
5419+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR444;
53995420 if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422)
5400− info->color_formats |= DRM_COLOR_FORMAT_YCRCB422;
5421+ info->color_formats |= DRM_COLOR_FORMAT_YCBCR422;
54015422
54025423 drm_update_mso(connector, edid);
54035424
5425+out:
5426+ if (quirks & EDID_QUIRK_NON_DESKTOP) {
5427+ drm_dbg_kms(connector->dev, "Non-desktop display%s\n",
5428+ info->non_desktop ? " (redundant quirk)" : "");
5429+ info->non_desktop = true;
5430+ }
5431+
54045432 return quirks;
54055433 }
54065434
54075435 static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
5408− struct displayid_detailed_timings_1 *timings)
5436+ struct displayid_detailed_timings_1 *timings,
5437+ bool type_7)
54095438 {
54105439 struct drm_display_mode *mode;
54115440 unsigned pixel_clock = (timings->pixel_clock[0] |
@@ -5426,7 +5455,8 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d · 14 unmodified lines
54265455 if (!mode)
54275456 return NULL;
54285457
5429− mode->clock = pixel_clock * 10;
5458+ /* resolution is kHz for type VII, and 10 kHz for type I */
5459+ mode->clock = type_7 ? pixel_clock : pixel_clock * 10;
54305460 mode->hdisplay = hactive;
54315461 mode->hsync_start = mode->hdisplay + hsync;
54325462 mode->hsync_end = mode->hsync_start + hsync_width;
@@ -5457,6 +5487,7 @@ static int add_displayid_detailed_1_modes(struct drm_connector *connector, · 24 unmodified lines
54575487 int num_timings;
54585488 struct drm_display_mode *newmode;
54595489 int num_modes = 0;
5490+ bool type_7 = block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING;
54605491 /* blocks must be multiple of 20 bytes length */
54615492 if (block->num_bytes % 20)
54625493 return 0;
@@ -5465,7 +5496,7 @@ static int add_displayid_detailed_1_modes(struct drm_connector *connector, · 2 unmodified lines
54655496 for (i = 0; i < num_timings; i++) {
54665497 struct displayid_detailed_timings_1 *timings = &det->timings[i];
54675498
5468− newmode = drm_mode_displayid_detailed(connector->dev, timings);
5499+ newmode = drm_mode_displayid_detailed(connector->dev, timings, type_7);
54695500 if (!newmode)
54705501 continue;
54715502
@@ -5484,7 +5515,8 @@ static int add_displayid_detailed_modes(struct drm_connector *connector, · 12 unmodified lines
54845515
54855516 displayid_iter_edid_begin(edid, &iter);
54865517 displayid_iter_for_each(block, &iter) {
5487− if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING)
5518+ if (block->tag == DATA_BLOCK_TYPE_1_DETAILED_TIMING ||
5519+ block->tag == DATA_BLOCK_2_TYPE_7_DETAILED_TIMING)
54885520 num_modes += add_displayid_detailed_1_modes(connector, block);
54895521 }
54905522 displayid_iter_end(&iter);
@@ -5652,7 +5684,7 @@ static bool is_hdmi2_sink(const struct drm_connector *connector) · 161 unmodified lines
56525684 return true;
56535685
56545686 return connector->display_info.hdmi.scdc.supported ||
5655− connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
5687+ connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR420;
56565688 }
56575689
56585690 static inline bool is_eotf_supported(u8 output_eotf, u8 sink_eotf)
@@ -5891,13 +5923,13 @@ static const u32 hdmi_colorimetry_val[] = { · 232 unmodified lines
58915923 #undef ACE
58925924
58935925 /**
5894− * drm_hdmi_avi_infoframe_colorspace() - fill the HDMI AVI infoframe
5895− * colorspace information
5926+ * drm_hdmi_avi_infoframe_colorimetry() - fill the HDMI AVI infoframe
5927+ * colorimetry information
58965928 * @frame: HDMI AVI infoframe
58975929 * @conn_state: connector state
58985930 */
58995931 void
5900−drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
5932+drm_hdmi_avi_infoframe_colorimetry(struct hdmi_avi_infoframe *frame,
59015933 const struct drm_connector_state *conn_state)
59025934 {
59035935 u32 colorimetry_val;
@@ -5916,7 +5948,7 @@ drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame, · 12 unmodified lines
59165948 frame->extended_colorimetry = (colorimetry_val >> 2) &
59175949 EXTENDED_COLORIMETRY_MASK;
59185950 }
5919−EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorspace);
5951+EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorimetry);
59205952
59215953 /**
59225954 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe
drivers/gpu/drm/drm_kms_helper_common.c+0−14
@@ -61,17 +61,3 @@ MODULE_PARM_DESC(edid_firmware, · 60 unmodified lines
6161 "DEPRECATED. Use drm.edid_firmware module parameter instead.");
6262
6363 #endif
64−
65−static int __init drm_kms_helper_init(void)
66−{
67− return drm_dp_aux_dev_init();
68−}
69−
70−static void __exit drm_kms_helper_exit(void)
71−{
72− /* Call exit functions from specific kms helpers here */
73− drm_dp_aux_dev_exit();
74−}
75−
76−module_init(drm_kms_helper_init);
77−module_exit(drm_kms_helper_exit);
drivers/gpu/drm/drm_plane.c+2−7
@@ -202,17 +202,13 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane · 201 unmodified lines
202202
203203 memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
204204
205− /* If we can't determine support, just bail */
206− if (!plane->funcs->format_mod_supported)
207− goto done;
208−
209205 mod = modifiers_ptr(blob_data);
210206 for (i = 0; i < plane->modifier_count; i++) {
211207 for (j = 0; j < plane->format_count; j++) {
212− if (plane->funcs->format_mod_supported(plane,
208+ if (!plane->funcs->format_mod_supported ||
209+ plane->funcs->format_mod_supported(plane,
213210 plane->format_types[j],
214211 plane->modifiers[i])) {
215−
216212 mod->formats |= 1ULL << j;
217213 }
218214 }
@@ -223,7 +219,6 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane · 4 unmodified lines
223219 mod++;
224220 }
225221
226−done:
227222 drm_object_attach_property(&plane->base, config->modifiers_property,
228223 blob->base.id);
229224
drivers/gpu/drm/drm_privacy_screen.c+4−1
@@ -387,7 +387,8 @@ static void drm_privacy_screen_device_release(struct device *dev) · 386 unmodified lines
387387 * * An ERR_PTR(errno) on failure.
388388 */
389389 struct drm_privacy_screen *drm_privacy_screen_register(
390− struct device *parent, const struct drm_privacy_screen_ops *ops)
390+ struct device *parent, const struct drm_privacy_screen_ops *ops,
391+ void *data)
391392 {
392393 struct drm_privacy_screen *priv;
393394 int ret;
@@ -404,6 +405,7 @@ struct drm_privacy_screen *drm_privacy_screen_register( · 10 unmodified lines
404405 priv->dev.parent = parent;
405406 priv->dev.release = drm_privacy_screen_device_release;
406407 dev_set_name(&priv->dev, "privacy_screen-%s", dev_name(parent));
408+ priv->drvdata = data;
407409 priv->ops = ops;
408410
409411 priv->ops->get_hw_state(priv);
@@ -439,6 +441,7 @@ void drm_privacy_screen_unregister(struct drm_privacy_screen *priv) · 29 unmodified lines
439441 mutex_unlock(&drm_privacy_screen_devs_lock);
440442
441443 mutex_lock(&priv->lock);
444+ priv->drvdata = NULL;
442445 priv->ops = NULL;
443446 mutex_unlock(&priv->lock);
444447
drivers/gpu/drm/drm_privacy_screen_x86.c+17−0
@@ -50,6 +50,13 @@ static bool __init detect_thinkpad_privacy_screen(void) · 49 unmodified lines
5050 }
5151 #endif
5252
53+#if IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
54+static bool __init detect_chromeos_privacy_screen(void)
55+{
56+ return acpi_dev_present("GOOG0010", NULL, -1);
57+}
58+#endif
59+
5360 static const struct arch_init_data arch_init_data[] __initconst = {
5461 #if IS_ENABLED(CONFIG_THINKPAD_ACPI)
5562 {
@@ -61,6 +68,16 @@ static const struct arch_init_data arch_init_data[] __initconst = { · 5 unmodified lines
6168 .detect = detect_thinkpad_privacy_screen,
6269 },
6370 #endif
71+#if IS_ENABLED(CONFIG_CHROMEOS_PRIVACY_SCREEN)
72+ {
73+ .lookup = {
74+ .dev_id = NULL,
75+ .con_id = NULL,
76+ .provider = "privacy_screen-GOOG0010:00",
77+ },
78+ .detect = detect_chromeos_privacy_screen,
79+ },
80+#endif
6481 };
6582
6683 void __init drm_privacy_screen_lookup_init(void)
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c+1−2
@@ -189,8 +189,7 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) · 188 unmodified lines
189189 continue;
190190
191191 if (bo->flags & ETNA_SUBMIT_BO_WRITE) {
192− ret = dma_resv_get_fences(robj, NULL,
193− &bo->nr_shared,
192+ ret = dma_resv_get_fences(robj, true, &bo->nr_shared,
194193 &bo->shared);
195194 if (ret)
196195 return ret;
drivers/gpu/drm/exynos/Kconfig+1−0
@@ -66,6 +66,7 @@ config DRM_EXYNOS_DP · 65 unmodified lines
6666 bool "Exynos specific extensions for Analogix DP driver"
6767 depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON
6868 select DRM_ANALOGIX_DP
69+ select DRM_DP_HELPER
6970 default DRM_EXYNOS
7071 select DRM_PANEL
7172 help
drivers/gpu/drm/exynos/exynos_drm_dsi.c+12−1
@@ -258,6 +258,7 @@ struct exynos_dsi { · 257 unmodified lines
258258 struct list_head bridge_chain;
259259 struct drm_bridge *out_bridge;
260260 struct device *dev;
261+ struct drm_display_mode mode;
261262
262263 void __iomem *reg_base;
263264 struct phy *phy;
@@ -881,7 +882,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi) · 617 unmodified lines
881882
882883 static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
883884 {
884− struct drm_display_mode *m = &dsi->encoder.crtc->state->adjusted_mode;
885+ struct drm_display_mode *m = &dsi->mode;
885886 unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;
886887 u32 reg;
887888
@@ -1446,6 +1447,15 @@ static void exynos_dsi_disable(struct drm_encoder *encoder) · 558 unmodified lines
14461447 pm_runtime_put_sync(dsi->dev);
14471448 }
14481449
1450+static void exynos_dsi_mode_set(struct drm_encoder *encoder,
1451+ struct drm_display_mode *mode,
1452+ struct drm_display_mode *adjusted_mode)
1453+{
1454+ struct exynos_dsi *dsi = encoder_to_dsi(encoder);
1455+
1456+ drm_mode_copy(&dsi->mode, adjusted_mode);
1457+}
1458+
14491459 static enum drm_connector_status
14501460 exynos_dsi_detect(struct drm_connector *connector, bool force)
14511461 {
@@ -1513,6 +1523,7 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) · 61 unmodified lines
15131523 static const struct drm_encoder_helper_funcs exynos_dsi_encoder_helper_funcs = {
15141524 .enable = exynos_dsi_enable,
15151525 .disable = exynos_dsi_disable,
1526+ .mode_set = exynos_dsi_mode_set,
15161527 };
15171528
15181529 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
drivers/gpu/drm/gma500/cdv_intel_dp.c+4−10
@@ -31,7 +31,7 @@ · 30 unmodified lines
3131
3232 #include <drm/drm_crtc.h>
3333 #include <drm/drm_crtc_helper.h>
34−#include <drm/drm_dp_helper.h>
34+#include <drm/dp/drm_dp_helper.h>
3535 #include <drm/drm_simple_kms_helper.h>
3636
3737 #include "gma_display.h"
@@ -82,7 +82,6 @@ i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) · 44 unmodified lines
8282 {
8383 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
8484 int mode = MODE_I2C_START;
85− int ret;
8685
8786 if (reading)
8887 mode |= MODE_I2C_READ;
@@ -90,8 +89,7 @@ i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) · 1 unmodified line
9089 mode |= MODE_I2C_WRITE;
9190 algo_data->address = address;
9291 algo_data->running = true;
93− ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
94− return ret;
92+ return i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
9593 }
9694
9795 /*
@@ -122,13 +120,11 @@ static int · 24 unmodified lines
122120 i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
123121 {
124122 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
125− int ret;
126123
127124 if (!algo_data->running)
128125 return -EIO;
129126
130− ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
131− return ret;
127+ return i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
132128 }
133129
134130 /*
@@ -139,13 +135,11 @@ static int · 4 unmodified lines
139135 i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
140136 {
141137 struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
142− int ret;
143138
144139 if (!algo_data->running)
145140 return -EIO;
146141
147− ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
148− return ret;
142+ return i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
149143 }
150144
151145 static int
drivers/gpu/drm/gma500/gma_display.c+2−4
@@ -335,7 +335,7 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, · 334 unmodified lines
335335 struct psb_gem_object *pobj;
336336 struct psb_gem_object *cursor_pobj = gma_crtc->cursor_pobj;
337337 struct drm_gem_object *obj;
338− void *tmp_dst, *tmp_src;
338+ void *tmp_dst;
339339 int ret = 0, i, cursor_pages;
340340
341341 /* If we didn't get a handle then turn the cursor off */
@@ -400,9 +400,7 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, · 58 unmodified lines
400400 /* Copy the cursor to cursor mem */
401401 tmp_dst = dev_priv->vram_addr + cursor_pobj->offset;
402402 for (i = 0; i < cursor_pages; i++) {
403− tmp_src = kmap(pobj->pages[i]);
404− memcpy(tmp_dst, tmp_src, PAGE_SIZE);
405− kunmap(pobj->pages[i]);
403+ memcpy_from_page(tmp_dst, pobj->pages[i], 0, PAGE_SIZE);
406404 tmp_dst += PAGE_SIZE;
407405 }
408406
drivers/gpu/drm/gma500/intel_bios.c+1−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 * Eric Anholt <eric@anholt.net>
77 */
88 #include <drm/drm.h>
9−#include <drm/drm_dp_helper.h>
9+#include <drm/dp/drm_dp_helper.h>
1010
1111 #include "intel_bios.h"
1212 #include "psb_drv.h"
drivers/gpu/drm/gma500/mmu.c+4−4
@@ -184,17 +184,17 @@ struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, · 183 unmodified lines
184184 pd->invalid_pte = 0;
185185 }
186186
187− v = kmap(pd->dummy_pt);
187+ v = kmap_local_page(pd->dummy_pt);
188188 for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
189189 v[i] = pd->invalid_pte;
190190
191− kunmap(pd->dummy_pt);
191+ kunmap_local(v);
192192
193− v = kmap(pd->p);
193+ v = kmap_local_page(pd->p);
194194 for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
195195 v[i] = pd->invalid_pde;
196196
197− kunmap(pd->p);
197+ kunmap_local(v);
198198
199199 clear_page(kmap(pd->dummy_page));
200200 kunmap(pd->dummy_page);
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c+2−1
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <drm/drm_gem_framebuffer_helper.h>
2121 #include <drm/drm_gem_vram_helper.h>
2222 #include <drm/drm_managed.h>
23+#include <drm/drm_module.h>
2324 #include <drm/drm_vblank.h>
2425
2526 #include "hibmc_drm_drv.h"
@@ -379,7 +380,7 @@ static struct pci_driver hibmc_pci_driver = { · 353 unmodified lines
379380 .driver.pm = &hibmc_pm_ops,
380381 };
381382
382−module_pci_driver(hibmc_pci_driver);
383+drm_module_pci_driver(hibmc_pci_driver);
383384
384385 MODULE_DEVICE_TABLE(pci, hibmc_pci_table);
385386 MODULE_AUTHOR("RongrongZou <zourongrong@huawei.com>");
drivers/gpu/drm/i915/Kconfig+2−0
@@ -9,6 +9,7 @@ config DRM_I915 · 8 unmodified lines
99 # the shmem_readpage() which depends upon tmpfs
1010 select SHMEM
1111 select TMPFS
12+ select DRM_DP_HELPER
1213 select DRM_KMS_HELPER
1314 select DRM_PANEL
1415 select DRM_MIPI_DSI
@@ -27,6 +28,7 @@ config DRM_I915 · 12 unmodified lines
2728 select CEC_CORE if CEC_NOTIFIER
2829 select VMAP_PFN
2930 select DRM_TTM
31+ select DRM_BUDDY
3032 help
3133 Choose this option if you have a system that has "Intel Graphics
3234 Media Accelerator" or "HD Graphics" integrated graphics,
drivers/gpu/drm/i915/Makefile+0−1
@@ -161,7 +161,6 @@ gem-y += \ · 160 unmodified lines
161161 i915-y += \
162162 $(gem-y) \
163163 i915_active.o \
164− i915_buddy.o \
165164 i915_cmd_parser.o \
166165 i915_deps.o \
167166 i915_gem_evict.o \
drivers/gpu/drm/i915/display/intel_bios.c+1−1
@@ -25,7 +25,7 @@ · 24 unmodified lines
2525 *
2626 */
2727
28−#include <drm/drm_dp_helper.h>
28+#include <drm/dp/drm_dp_helper.h>
2929
3030 #include "display/intel_display.h"
3131 #include "display/intel_display_types.h"
drivers/gpu/drm/i915/display/intel_display.c+1−1
@@ -38,7 +38,7 @@ · 37 unmodified lines
3838 #include <drm/drm_atomic_helper.h>
3939 #include <drm/drm_atomic_uapi.h>
4040 #include <drm/drm_damage_helper.h>
41−#include <drm/drm_dp_helper.h>
41+#include <drm/dp/drm_dp_helper.h>
4242 #include <drm/drm_edid.h>
4343 #include <drm/drm_fourcc.h>
4444 #include <drm/drm_plane_helper.h>
drivers/gpu/drm/i915/display/intel_display_types.h+2−2
@@ -32,10 +32,10 @@ · 31 unmodified lines
3232 #include <linux/pwm.h>
3333 #include <linux/sched/clock.h>
3434
35+#include <drm/dp/drm_dp_dual_mode_helper.h>
36+#include <drm/dp/drm_dp_mst_helper.h>
3537 #include <drm/drm_atomic.h>
3638 #include <drm/drm_crtc.h>
37−#include <drm/drm_dp_dual_mode_helper.h>
38−#include <drm/drm_dp_mst_helper.h>
3939 #include <drm/drm_dsc.h>
4040 #include <drm/drm_encoder.h>
4141 #include <drm/drm_fb_helper.h>
drivers/gpu/drm/i915/display/intel_dp.c+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
3636
3737 #include <drm/drm_atomic_helper.h>
3838 #include <drm/drm_crtc.h>
39−#include <drm/drm_dp_helper.h>
39+#include <drm/dp/drm_dp_helper.h>
4040 #include <drm/drm_edid.h>
4141 #include <drm/drm_probe_helper.h>
4242
drivers/gpu/drm/i915/display/intel_dp_hdcp.c+2−2
@@ -6,8 +6,8 @@ · 5 unmodified lines
66 * Sean Paul <seanpaul@chromium.org>
77 */
88
9−#include <drm/drm_dp_helper.h>
10−#include <drm/drm_dp_mst_helper.h>
9+#include <drm/dp/drm_dp_helper.h>
10+#include <drm/dp/drm_dp_mst_helper.h>
1111 #include <drm/drm_hdcp.h>
1212 #include <drm/drm_print.h>
1313
drivers/gpu/drm/i915/display/intel_dp_link_training.h+1−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 #ifndef __INTEL_DP_LINK_TRAINING_H__
77 #define __INTEL_DP_LINK_TRAINING_H__
88
9−#include <drm/drm_dp_helper.h>
9+#include <drm/dp/drm_dp_helper.h>
1010
1111 struct intel_crtc_state;
1212 struct intel_dp;
drivers/gpu/drm/i915/display/intel_hdmi.c+3−3
@@ -730,7 +730,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, · 729 unmodified lines
730730 else
731731 frame->colorspace = HDMI_COLORSPACE_RGB;
732732
733− drm_hdmi_avi_infoframe_colorspace(frame, conn_state);
733+ drm_hdmi_avi_infoframe_colorimetry(frame, conn_state);
734734
735735 /* nonsense combination */
736736 drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range &&
@@ -1912,7 +1912,7 @@ static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector, · 1175 unmodified lines
19121912 if (ycbcr420_output)
19131913 return hdmi->y420_dc_modes & DRM_EDID_YCBCR420_DC_36;
19141914 else
1915− return info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36;
1915+ return info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36;
19161916 case 10:
19171917 if (!has_hdmi_sink)
19181918 return false;
@@ -1920,7 +1920,7 @@ static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector, · 1 unmodified line
19201920 if (ycbcr420_output)
19211921 return hdmi->y420_dc_modes & DRM_EDID_YCBCR420_DC_30;
19221922 else
1923− return info->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30;
1923+ return info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30;
19241924 case 8:
19251925 return true;
19261926 default:
drivers/gpu/drm/i915/display/intel_lspcon.c+2−2
@@ -24,7 +24,7 @@ · 23 unmodified lines
2424 */
2525
2626 #include <drm/drm_atomic_helper.h>
27−#include <drm/drm_dp_dual_mode_helper.h>
27+#include <drm/dp/drm_dp_dual_mode_helper.h>
2828 #include <drm/drm_edid.h>
2929
3030 #include "intel_de.h"
@@ -537,7 +537,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder, · 506 unmodified lines
537537 frame.avi.colorspace = HDMI_COLORSPACE_RGB;
538538
539539 /* Set the Colorspace as per the HDMI spec */
540− drm_hdmi_avi_infoframe_colorspace(&frame.avi, conn_state);
540+ drm_hdmi_avi_infoframe_colorimetry(&frame.avi, conn_state);
541541
542542 /* nonsense combination */
543543 drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range &&
drivers/gpu/drm/i915/i915_buddy.c+0−466
@@ -1,466 +0,0 @@
1−// SPDX-License-Identifier: MIT
2−/*
3− * Copyright © 2021 Intel Corporation
4− */
5−
6−#include <linux/kmemleak.h>
7−#include <linux/sizes.h>
8−
9−#include "i915_buddy.h"
10−
11−#include "i915_gem.h"
12−#include "i915_utils.h"
13−
14−static struct kmem_cache *slab_blocks;
15−
16−static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_mm *mm,
17− struct i915_buddy_block *parent,
18− unsigned int order,
19− u64 offset)
20−{
21− struct i915_buddy_block *block;
22−
23− GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER);
24−
25− block = kmem_cache_zalloc(slab_blocks, GFP_KERNEL);
26− if (!block)
27− return NULL;
28−
29− block->header = offset;
30− block->header |= order;
31− block->parent = parent;
32−
33− GEM_BUG_ON(block->header & I915_BUDDY_HEADER_UNUSED);
34− return block;
35−}
36−
37−static void i915_block_free(struct i915_buddy_mm *mm,
38− struct i915_buddy_block *block)
39−{
40− kmem_cache_free(slab_blocks, block);
41−}
42−
43−static void mark_allocated(struct i915_buddy_block *block)
44−{
45− block->header &= ~I915_BUDDY_HEADER_STATE;
46− block->header |= I915_BUDDY_ALLOCATED;
47−
48− list_del(&block->link);
49−}
50−
51−static void mark_free(struct i915_buddy_mm *mm,
52− struct i915_buddy_block *block)
53−{
54− block->header &= ~I915_BUDDY_HEADER_STATE;
55− block->header |= I915_BUDDY_FREE;
56−
57− list_add(&block->link,
58− &mm->free_list[i915_buddy_block_order(block)]);
59−}
60−
61−static void mark_split(struct i915_buddy_block *block)
62−{
63− block->header &= ~I915_BUDDY_HEADER_STATE;
64− block->header |= I915_BUDDY_SPLIT;
65−
66− list_del(&block->link);
67−}
68−
69−int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 chunk_size)
70−{
71− unsigned int i;
72− u64 offset;
73−
74− if (size < chunk_size)
75− return -EINVAL;
76−
77− if (chunk_size < PAGE_SIZE)
78− return -EINVAL;
79−
80− if (!is_power_of_2(chunk_size))
81− return -EINVAL;
82−
83− size = round_down(size, chunk_size);
84−
85− mm->size = size;
86− mm->avail = size;
87− mm->chunk_size = chunk_size;
88− mm->max_order = ilog2(size) - ilog2(chunk_size);
89−
90− GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER);
91−
92− mm->free_list = kmalloc_array(mm->max_order + 1,
93− sizeof(struct list_head),
94− GFP_KERNEL);
95− if (!mm->free_list)
96− return -ENOMEM;
97−
98− for (i = 0; i <= mm->max_order; ++i)
99− INIT_LIST_HEAD(&mm->free_list[i]);
100−
101− mm->n_roots = hweight64(size);
102−
103− mm->roots = kmalloc_array(mm->n_roots,
104− sizeof(struct i915_buddy_block *),
105− GFP_KERNEL);
106− if (!mm->roots)
107− goto out_free_list;
108−
109− offset = 0;
110− i = 0;
111−
112− /*
113− * Split into power-of-two blocks, in case we are given a size that is
114− * not itself a power-of-two.
115− */
116− do {
117− struct i915_buddy_block *root;
118− unsigned int order;
119− u64 root_size;
120−
121− root_size = rounddown_pow_of_two(size);
122− order = ilog2(root_size) - ilog2(chunk_size);
123−
124− root = i915_block_alloc(mm, NULL, order, offset);
125− if (!root)
126− goto out_free_roots;
127−
128− mark_free(mm, root);
129−
130− GEM_BUG_ON(i > mm->max_order);
131− GEM_BUG_ON(i915_buddy_block_size(mm, root) < chunk_size);
132−
133− mm->roots[i] = root;
134−
135− offset += root_size;
136− size -= root_size;
137− i++;
138− } while (size);
139−
140− return 0;
141−
142−out_free_roots:
143− while (i--)
144− i915_block_free(mm, mm->roots[i]);
145− kfree(mm->roots);
146−out_free_list:
147− kfree(mm->free_list);
148− return -ENOMEM;
149−}
150−
151−void i915_buddy_fini(struct i915_buddy_mm *mm)
152−{
153− int i;
154−
155− for (i = 0; i < mm->n_roots; ++i) {
156− GEM_WARN_ON(!i915_buddy_block_is_free(mm->roots[i]));
157− i915_block_free(mm, mm->roots[i]);
158− }
159−
160− GEM_WARN_ON(mm->avail != mm->size);
161−
162− kfree(mm->roots);
163− kfree(mm->free_list);
164−}
165−
166−static int split_block(struct i915_buddy_mm *mm,
167− struct i915_buddy_block *block)
168−{
169− unsigned int block_order = i915_buddy_block_order(block) - 1;
170− u64 offset = i915_buddy_block_offset(block);
171−
172− GEM_BUG_ON(!i915_buddy_block_is_free(block));
173− GEM_BUG_ON(!i915_buddy_block_order(block));
174−
175− block->left = i915_block_alloc(mm, block, block_order, offset);
176− if (!block->left)
177− return -ENOMEM;
178−
179− block->right = i915_block_alloc(mm, block, block_order,
180− offset + (mm->chunk_size << block_order));
181− if (!block->right) {
182− i915_block_free(mm, block->left);
183− return -ENOMEM;
184− }
185−
186− mark_free(mm, block->left);
187− mark_free(mm, block->right);
188−
189− mark_split(block);
190−
191− return 0;
192−}
193−
194−static struct i915_buddy_block *
195−get_buddy(struct i915_buddy_block *block)
196−{
197− struct i915_buddy_block *parent;
198−
199− parent = block->parent;
200− if (!parent)
201− return NULL;
202−
203− if (parent->left == block)
204− return parent->right;
205−
206− return parent->left;
207−}
208−
209−static void __i915_buddy_free(struct i915_buddy_mm *mm,
210− struct i915_buddy_block *block)
211−{
212− struct i915_buddy_block *parent;
213−
214− while ((parent = block->parent)) {
215− struct i915_buddy_block *buddy;
216−
217− buddy = get_buddy(block);
218−
219− if (!i915_buddy_block_is_free(buddy))
220− break;
221−
222− list_del(&buddy->link);
223−
224− i915_block_free(mm, block);
225− i915_block_free(mm, buddy);
226−
227− block = parent;
228− }
229−
230− mark_free(mm, block);
231−}
232−
233−void i915_buddy_free(struct i915_buddy_mm *mm,
234− struct i915_buddy_block *block)
235−{
236− GEM_BUG_ON(!i915_buddy_block_is_allocated(block));
237− mm->avail += i915_buddy_block_size(mm, block);
238− __i915_buddy_free(mm, block);
239−}
240−
241−void i915_buddy_free_list(struct i915_buddy_mm *mm, struct list_head *objects)
242−{
243− struct i915_buddy_block *block, *on;
244−
245− list_for_each_entry_safe(block, on, objects, link) {
246− i915_buddy_free(mm, block);
247− cond_resched();
248− }
249− INIT_LIST_HEAD(objects);
250−}
251−
252−/*
253− * Allocate power-of-two block. The order value here translates to:
254− *
255− * 0 = 2^0 * mm->chunk_size
256− * 1 = 2^1 * mm->chunk_size
257− * 2 = 2^2 * mm->chunk_size
258− * ...
259− */
260−struct i915_buddy_block *
261−i915_buddy_alloc(struct i915_buddy_mm *mm, unsigned int order)
262−{
263− struct i915_buddy_block *block = NULL;
264− unsigned int i;
265− int err;
266−
267− for (i = order; i <= mm->max_order; ++i) {
268− block = list_first_entry_or_null(&mm->free_list[i],
269− struct i915_buddy_block,
270− link);
271− if (block)
272− break;
273− }
274−
275− if (!block)
276− return ERR_PTR(-ENOSPC);
277−
278− GEM_BUG_ON(!i915_buddy_block_is_free(block));
279−
280− while (i != order) {
281− err = split_block(mm, block);
282− if (unlikely(err))
283− goto out_free;
284−
285− /* Go low */
286− block = block->left;
287− i--;
288− }
289−
290− mark_allocated(block);
291− mm->avail -= i915_buddy_block_size(mm, block);
292− kmemleak_update_trace(block);
293− return block;
294−
295−out_free:
296− if (i != order)
297− __i915_buddy_free(mm, block);
298− return ERR_PTR(err);
299−}
300−
301−static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2)
302−{
303− return s1 <= e2 && e1 >= s2;
304−}
305−
306−static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2)
307−{
308− return s1 <= s2 && e1 >= e2;
309−}
310−
311−/*
312− * Allocate range. Note that it's safe to chain together multiple alloc_ranges
313− * with the same blocks list.
314− *
315− * Intended for pre-allocating portions of the address space, for example to
316− * reserve a block for the initial framebuffer or similar, hence the expectation
317− * here is that i915_buddy_alloc() is still the main vehicle for
318− * allocations, so if that's not the case then the drm_mm range allocator is
319− * probably a much better fit, and so you should probably go use that instead.
320− */
321−int i915_buddy_alloc_range(struct i915_buddy_mm *mm,
322− struct list_head *blocks,
323− u64 start, u64 size)
324−{
325− struct i915_buddy_block *block;
326− struct i915_buddy_block *buddy;
327− LIST_HEAD(allocated);
328− LIST_HEAD(dfs);
329− u64 end;
330− int err;
331− int i;
332−
333− if (size < mm->chunk_size)
334− return -EINVAL;
335−
336− if (!IS_ALIGNED(size | start, mm->chunk_size))
337− return -EINVAL;
338−
339− if (range_overflows(start, size, mm->size))
340− return -EINVAL;
341−
342− for (i = 0; i < mm->n_roots; ++i)
343− list_add_tail(&mm->roots[i]->tmp_link, &dfs);
344−
345− end = start + size - 1;
346−
347− do {
348− u64 block_start;
349− u64 block_end;
350−
351− block = list_first_entry_or_null(&dfs,
352− struct i915_buddy_block,
353− tmp_link);
354− if (!block)
355− break;
356−
357− list_del(&block->tmp_link);
358−
359− block_start = i915_buddy_block_offset(block);
360− block_end = block_start + i915_buddy_block_size(mm, block) - 1;
361−
362− if (!overlaps(start, end, block_start, block_end))
363− continue;
364−
365− if (i915_buddy_block_is_allocated(block)) {
366− err = -ENOSPC;
367− goto err_free;
368− }
369−
370− if (contains(start, end, block_start, block_end)) {
371− if (!i915_buddy_block_is_free(block)) {
372− err = -ENOSPC;
373− goto err_free;
374− }
375−
376− mark_allocated(block);
377− mm->avail -= i915_buddy_block_size(mm, block);
378− list_add_tail(&block->link, &allocated);
379− continue;
380− }
381−
382− if (!i915_buddy_block_is_split(block)) {
383− err = split_block(mm, block);
384− if (unlikely(err))
385− goto err_undo;
386− }
387−
388− list_add(&block->right->tmp_link, &dfs);
389− list_add(&block->left->tmp_link, &dfs);
390− } while (1);
391−
392− list_splice_tail(&allocated, blocks);
393− return 0;
394−
395−err_undo:
396− /*
397− * We really don't want to leave around a bunch of split blocks, since
398− * bigger is better, so make sure we merge everything back before we
399− * free the allocated blocks.
400− */
401− buddy = get_buddy(block);
402− if (buddy &&
403− (i915_buddy_block_is_free(block) &&
404− i915_buddy_block_is_free(buddy)))
405− __i915_buddy_free(mm, block);
406−
407−err_free:
408− i915_buddy_free_list(mm, &allocated);
409− return err;
410−}
411−
412−void i915_buddy_block_print(struct i915_buddy_mm *mm,
413− struct i915_buddy_block *block,
414− struct drm_printer *p)
415−{
416− u64 start = i915_buddy_block_offset(block);
417− u64 size = i915_buddy_block_size(mm, block);
418−
419− drm_printf(p, "%#018llx-%#018llx: %llu\n", start, start + size, size);
420−}
421−
422−void i915_buddy_print(struct i915_buddy_mm *mm, struct drm_printer *p)
423−{
424− int order;
425−
426− drm_printf(p, "chunk_size: %lluKiB, total: %lluMiB, free: %lluMiB\n",
427− mm->chunk_size >> 10, mm->size >> 20, mm->avail >> 20);
428−
429− for (order = mm->max_order; order >= 0; order--) {
430− struct i915_buddy_block *block;
431− u64 count = 0, free;
432−
433− list_for_each_entry(block, &mm->free_list[order], link) {
434− GEM_BUG_ON(!i915_buddy_block_is_free(block));
435− count++;
436− }
437−
438− drm_printf(p, "order-%d ", order);
439−
440− free = count * (mm->chunk_size << order);
441− if (free < SZ_1M)
442− drm_printf(p, "free: %lluKiB", free >> 10);
443− else
444− drm_printf(p, "free: %lluMiB", free >> 20);
445−
446− drm_printf(p, ", pages: %llu\n", count);
447− }
448−}
449−
450−#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
451−#include "selftests/i915_buddy.c"
452−#endif
453−
454−void i915_buddy_module_exit(void)
455−{
456− kmem_cache_destroy(slab_blocks);
457−}
458−
459−int __init i915_buddy_module_init(void)
460−{
461− slab_blocks = KMEM_CACHE(i915_buddy_block, 0);
462− if (!slab_blocks)
463− return -ENOMEM;
464−
465− return 0;
466−}
drivers/gpu/drm/i915/i915_buddy.h+0−143
@@ -1,143 +0,0 @@
1−/* SPDX-License-Identifier: MIT */
2−/*
3− * Copyright © 2021 Intel Corporation
4− */
5−
6−#ifndef __I915_BUDDY_H__
7−#define __I915_BUDDY_H__
8−
9−#include <linux/bitops.h>
10−#include <linux/list.h>
11−#include <linux/slab.h>
12−
13−#include <drm/drm_print.h>
14−
15−struct i915_buddy_block {
16−#define I915_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
17−#define I915_BUDDY_HEADER_STATE GENMASK_ULL(11, 10)
18−#define I915_BUDDY_ALLOCATED (1 << 10)
19−#define I915_BUDDY_FREE (2 << 10)
20−#define I915_BUDDY_SPLIT (3 << 10)
21−/* Free to be used, if needed in the future */
22−#define I915_BUDDY_HEADER_UNUSED GENMASK_ULL(9, 6)
23−#define I915_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0)
24− u64 header;
25−
26− struct i915_buddy_block *left;
27− struct i915_buddy_block *right;
28− struct i915_buddy_block *parent;
29−
30− void *private; /* owned by creator */
31−
32− /*
33− * While the block is allocated by the user through i915_buddy_alloc*,
34− * the user has ownership of the link, for example to maintain within
35− * a list, if so desired. As soon as the block is freed with
36− * i915_buddy_free* ownership is given back to the mm.
37− */
38− struct list_head link;
39− struct list_head tmp_link;
40−};
41−
42−/* Order-zero must be at least PAGE_SIZE */
43−#define I915_BUDDY_MAX_ORDER (63 - PAGE_SHIFT)
44−
45−/*
46− * Binary Buddy System.
47− *
48− * Locking should be handled by the user, a simple mutex around
49− * i915_buddy_alloc* and i915_buddy_free* should suffice.
50− */
51−struct i915_buddy_mm {
52− /* Maintain a free list for each order. */
53− struct list_head *free_list;
54−
55− /*
56− * Maintain explicit binary tree(s) to track the allocation of the
57− * address space. This gives us a simple way of finding a buddy block
58− * and performing the potentially recursive merge step when freeing a
59− * block. Nodes are either allocated or free, in which case they will
60− * also exist on the respective free list.
61− */
62− struct i915_buddy_block **roots;
63−
64− /*
65− * Anything from here is public, and remains static for the lifetime of
66− * the mm. Everything above is considered do-not-touch.
67− */
68− unsigned int n_roots;
69− unsigned int max_order;
70−
71− /* Must be at least PAGE_SIZE */
72− u64 chunk_size;
73− u64 size;
74− u64 avail;
75−};
76−
77−static inline u64
78−i915_buddy_block_offset(struct i915_buddy_block *block)
79−{
80− return block->header & I915_BUDDY_HEADER_OFFSET;
81−}
82−
83−static inline unsigned int
84−i915_buddy_block_order(struct i915_buddy_block *block)
85−{
86− return block->header & I915_BUDDY_HEADER_ORDER;
87−}
88−
89−static inline unsigned int
90−i915_buddy_block_state(struct i915_buddy_block *block)
91−{
92− return block->header & I915_BUDDY_HEADER_STATE;
93−}
94−
95−static inline bool
96−i915_buddy_block_is_allocated(struct i915_buddy_block *block)
97−{
98− return i915_buddy_block_state(block) == I915_BUDDY_ALLOCATED;
99−}
100−
101−static inline bool
102−i915_buddy_block_is_free(struct i915_buddy_block *block)
103−{
104− return i915_buddy_block_state(block) == I915_BUDDY_FREE;
105−}
106−
107−static inline bool
108−i915_buddy_block_is_split(struct i915_buddy_block *block)
109−{
110− return i915_buddy_block_state(block) == I915_BUDDY_SPLIT;
111−}
112−
113−static inline u64
114−i915_buddy_block_size(struct i915_buddy_mm *mm,
115− struct i915_buddy_block *block)
116−{
117− return mm->chunk_size << i915_buddy_block_order(block);
118−}
119−
120−int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 chunk_size);
121−
122−void i915_buddy_fini(struct i915_buddy_mm *mm);
123−
124−struct i915_buddy_block *
125−i915_buddy_alloc(struct i915_buddy_mm *mm, unsigned int order);
126−
127−int i915_buddy_alloc_range(struct i915_buddy_mm *mm,
128− struct list_head *blocks,
129− u64 start, u64 size);
130−
131−void i915_buddy_free(struct i915_buddy_mm *mm, struct i915_buddy_block *block);
132−
133−void i915_buddy_free_list(struct i915_buddy_mm *mm, struct list_head *objects);
134−
135−void i915_buddy_print(struct i915_buddy_mm *mm, struct drm_printer *p);
136−void i915_buddy_block_print(struct i915_buddy_mm *mm,
137− struct i915_buddy_block *block,
138− struct drm_printer *p);
139−
140−void i915_buddy_module_exit(void);
141−int i915_buddy_module_init(void);
142−
143−#endif
drivers/gpu/drm/i915/i915_module.c+0−3
@@ -9,7 +9,6 @@ · 8 unmodified lines
99 #include "gem/i915_gem_context.h"
1010 #include "gem/i915_gem_object.h"
1111 #include "i915_active.h"
12−#include "i915_buddy.h"
1312 #include "i915_params.h"
1413 #include "i915_pci.h"
1514 #include "i915_perf.h"
@@ -50,8 +49,6 @@ static const struct { · 34 unmodified lines
5049 { .init = i915_check_nomodeset },
5150 { .init = i915_active_module_init,
5251 .exit = i915_active_module_exit },
53− { .init = i915_buddy_module_init,
54− .exit = i915_buddy_module_exit },
5552 { .init = i915_context_module_init,
5653 .exit = i915_context_module_exit },
5754 { .init = i915_gem_context_module_init,
drivers/gpu/drm/i915/i915_scatterlist.c+5−6
@@ -5,10 +5,9 @@ · 4 unmodified lines
55 */
66
77 #include "i915_scatterlist.h"
8−
9−#include "i915_buddy.h"
108 #include "i915_ttm_buddy_manager.h"
119
10+#include <drm/drm_buddy.h>
1211 #include <drm/drm_mm.h>
1312
1413 #include <linux/slab.h>
@@ -153,9 +152,9 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res, · 138 unmodified lines
153152 struct i915_ttm_buddy_resource *bman_res = to_ttm_buddy_resource(res);
154153 const u64 size = res->num_pages << PAGE_SHIFT;
155154 const u64 max_segment = rounddown(UINT_MAX, PAGE_SIZE);
156− struct i915_buddy_mm *mm = bman_res->mm;
155+ struct drm_buddy *mm = bman_res->mm;
157156 struct list_head *blocks = &bman_res->blocks;
158− struct i915_buddy_block *block;
157+ struct drm_buddy_block *block;
159158 struct i915_refct_sgt *rsgt;
160159 struct scatterlist *sg;
161160 struct sg_table *st;
@@ -181,8 +180,8 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res, · 19 unmodified lines
181180 list_for_each_entry(block, blocks, link) {
182181 u64 block_size, offset;
183182
184− block_size = min_t(u64, size, i915_buddy_block_size(mm, block));
185− offset = i915_buddy_block_offset(block);
183+ block_size = min_t(u64, size, drm_buddy_block_size(mm, block));
184+ offset = drm_buddy_block_offset(block);
186185
187186 while (block_size) {
188187 u64 len;
drivers/gpu/drm/i915/i915_ttm_buddy_manager.c+20−17
@@ -8,14 +8,15 @@ · 7 unmodified lines
88 #include <drm/ttm/ttm_bo_driver.h>
99 #include <drm/ttm/ttm_placement.h>
1010
11+#include <drm/drm_buddy.h>
12+
1113 #include "i915_ttm_buddy_manager.h"
1214
13−#include "i915_buddy.h"
1415 #include "i915_gem.h"
1516
1617 struct i915_ttm_buddy_manager {
1718 struct ttm_resource_manager manager;
18− struct i915_buddy_mm mm;
19+ struct drm_buddy mm;
1920 struct list_head reserved;
2021 struct mutex lock;
2122 u64 default_page_size;
@@ -34,7 +35,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, · 12 unmodified lines
3435 {
3536 struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
3637 struct i915_ttm_buddy_resource *bman_res;
37− struct i915_buddy_mm *mm = &bman->mm;
38+ struct drm_buddy *mm = &bman->mm;
3839 unsigned long n_pages;
3940 unsigned int min_order;
4041 u64 min_page_size;
@@ -73,7 +74,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, · 32 unmodified lines
7374 n_pages = size >> ilog2(mm->chunk_size);
7475
7576 do {
76− struct i915_buddy_block *block;
77+ struct drm_buddy_block *block;
7778 unsigned int order;
7879
7980 order = fls(n_pages) - 1;
@@ -82,7 +83,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, · 2 unmodified lines
8283
8384 do {
8485 mutex_lock(&bman->lock);
85− block = i915_buddy_alloc(mm, order);
86+ block = drm_buddy_alloc_blocks(mm, order);
8687 mutex_unlock(&bman->lock);
8788 if (!IS_ERR(block))
8889 break;
@@ -106,9 +107,10 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, · 17 unmodified lines
106107
107108 err_free_blocks:
108109 mutex_lock(&bman->lock);
109− i915_buddy_free_list(mm, &bman_res->blocks);
110+ drm_buddy_free_list(mm, &bman_res->blocks);
110111 mutex_unlock(&bman->lock);
111112 err_free_res:
113+ ttm_resource_fini(man, &bman_res->base);
112114 kfree(bman_res);
113115 return err;
114116 }
@@ -120,9 +122,10 @@ static void i915_ttm_buddy_man_free(struct ttm_resource_manager *man, · 5 unmodified lines
120122 struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
121123
122124 mutex_lock(&bman->lock);
123− i915_buddy_free_list(&bman->mm, &bman_res->blocks);
125+ drm_buddy_free_list(&bman->mm, &bman_res->blocks);
124126 mutex_unlock(&bman->lock);
125127
128+ ttm_resource_fini(man, res);
126129 kfree(bman_res);
127130 }
128131
@@ -130,17 +133,17 @@ static void i915_ttm_buddy_man_debug(struct ttm_resource_manager *man, · 1 unmodified line
130133 struct drm_printer *printer)
131134 {
132135 struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
133− struct i915_buddy_block *block;
136+ struct drm_buddy_block *block;
134137
135138 mutex_lock(&bman->lock);
136139 drm_printf(printer, "default_page_size: %lluKiB\n",
137140 bman->default_page_size >> 10);
138141
139− i915_buddy_print(&bman->mm, printer);
142+ drm_buddy_print(&bman->mm, printer);
140143
141144 drm_printf(printer, "reserved:\n");
142145 list_for_each_entry(block, &bman->reserved, link)
143− i915_buddy_block_print(&bman->mm, block, printer);
146+ drm_buddy_block_print(&bman->mm, block, printer);
144147 mutex_unlock(&bman->lock);
145148 }
146149
@@ -190,7 +193,7 @@ int i915_ttm_buddy_man_init(struct ttm_device *bdev, · 43 unmodified lines
190193 if (!bman)
191194 return -ENOMEM;
192195
193− err = i915_buddy_init(&bman->mm, size, chunk_size);
196+ err = drm_buddy_init(&bman->mm, size, chunk_size);
194197 if (err)
195198 goto err_free_bman;
196199
@@ -202,7 +205,7 @@ int i915_ttm_buddy_man_init(struct ttm_device *bdev, · 5 unmodified lines
202205 man = &bman->manager;
203206 man->use_tt = use_tt;
204207 man->func = &i915_ttm_buddy_manager_func;
205− ttm_resource_manager_init(man, bman->mm.size >> PAGE_SHIFT);
208+ ttm_resource_manager_init(man, bdev, bman->mm.size >> PAGE_SHIFT);
206209
207210 ttm_resource_manager_set_used(man, true);
208211 ttm_set_driver_manager(bdev, type, man);
@@ -228,7 +231,7 @@ int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type) · 19 unmodified lines
228231 {
229232 struct ttm_resource_manager *man = ttm_manager_type(bdev, type);
230233 struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
231− struct i915_buddy_mm *mm = &bman->mm;
234+ struct drm_buddy *mm = &bman->mm;
232235 int ret;
233236
234237 ttm_resource_manager_set_used(man, false);
@@ -240,8 +243,8 @@ int i915_ttm_buddy_man_fini(struct ttm_device *bdev, unsigned int type) · 5 unmodified lines
240243 ttm_set_driver_manager(bdev, type, NULL);
241244
242245 mutex_lock(&bman->lock);
243− i915_buddy_free_list(mm, &bman->reserved);
244− i915_buddy_fini(mm);
246+ drm_buddy_free_list(mm, &bman->reserved);
247+ drm_buddy_fini(mm);
245248 mutex_unlock(&bman->lock);
246249
247250 ttm_resource_manager_cleanup(man);
@@ -264,11 +267,11 @@ int i915_ttm_buddy_man_reserve(struct ttm_resource_manager *man, · 16 unmodified lines
264267 u64 start, u64 size)
265268 {
266269 struct i915_ttm_buddy_manager *bman = to_buddy_manager(man);
267− struct i915_buddy_mm *mm = &bman->mm;
270+ struct drm_buddy *mm = &bman->mm;
268271 int ret;
269272
270273 mutex_lock(&bman->lock);
271− ret = i915_buddy_alloc_range(mm, &bman->reserved, start, size);
274+ ret = drm_buddy_alloc_range(mm, &bman->reserved, start, size);
272275 mutex_unlock(&bman->lock);
273276
274277 return ret;
drivers/gpu/drm/i915/i915_ttm_buddy_manager.h+2−2
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313
1414 struct ttm_device;
1515 struct ttm_resource_manager;
16−struct i915_buddy_mm;
16+struct drm_buddy;
1717
1818 /**
1919 * struct i915_ttm_buddy_resource
@@ -28,7 +28,7 @@ struct i915_buddy_mm; · 8 unmodified lines
2828 struct i915_ttm_buddy_resource {
2929 struct ttm_resource base;
3030 struct list_head blocks;
31− struct i915_buddy_mm *mm;
31+ struct drm_buddy *mm;
3232 };
3333
3434 /**
drivers/gpu/drm/i915/selftests/i915_buddy.c+0−787
@@ -1,787 +0,0 @@
1−// SPDX-License-Identifier: MIT
2−/*
3− * Copyright © 2019 Intel Corporation
4− */
5−
6−#include <linux/prime_numbers.h>
7−
8−#include "../i915_selftest.h"
9−#include "i915_random.h"
10−
11−static void __igt_dump_block(struct i915_buddy_mm *mm,
12− struct i915_buddy_block *block,
13− bool buddy)
14−{
15− pr_err("block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%s buddy=%s\n",
16− block->header,
17− i915_buddy_block_state(block),
18− i915_buddy_block_order(block),
19− i915_buddy_block_offset(block),
20− i915_buddy_block_size(mm, block),
21− yesno(!block->parent),
22− yesno(buddy));
23−}
24−
25−static void igt_dump_block(struct i915_buddy_mm *mm,
26− struct i915_buddy_block *block)
27−{
28− struct i915_buddy_block *buddy;
29−
30− __igt_dump_block(mm, block, false);
31−
32− buddy = get_buddy(block);
33− if (buddy)
34− __igt_dump_block(mm, buddy, true);
35−}
36−
37−static int igt_check_block(struct i915_buddy_mm *mm,
38− struct i915_buddy_block *block)
39−{
40− struct i915_buddy_block *buddy;
41− unsigned int block_state;
42− u64 block_size;
43− u64 offset;
44− int err = 0;
45−
46− block_state = i915_buddy_block_state(block);
47−
48− if (block_state != I915_BUDDY_ALLOCATED &&
49− block_state != I915_BUDDY_FREE &&
50− block_state != I915_BUDDY_SPLIT) {
51− pr_err("block state mismatch\n");
52− err = -EINVAL;
53− }
54−
55− block_size = i915_buddy_block_size(mm, block);
56− offset = i915_buddy_block_offset(block);
57−
58− if (block_size < mm->chunk_size) {
59− pr_err("block size smaller than min size\n");
60− err = -EINVAL;
61− }
62−
63− if (!is_power_of_2(block_size)) {
64− pr_err("block size not power of two\n");
65− err = -EINVAL;
66− }
67−
68− if (!IS_ALIGNED(block_size, mm->chunk_size)) {
69− pr_err("block size not aligned to min size\n");
70− err = -EINVAL;
71− }
72−
73− if (!IS_ALIGNED(offset, mm->chunk_size)) {
74− pr_err("block offset not aligned to min size\n");
75− err = -EINVAL;
76− }
77−
78− if (!IS_ALIGNED(offset, block_size)) {
79− pr_err("block offset not aligned to block size\n");
80− err = -EINVAL;
81− }
82−
83− buddy = get_buddy(block);
84−
85− if (!buddy && block->parent) {
86− pr_err("buddy has gone fishing\n");
87− err = -EINVAL;
88− }
89−
90− if (buddy) {
91− if (i915_buddy_block_offset(buddy) != (offset ^ block_size)) {
92− pr_err("buddy has wrong offset\n");
93− err = -EINVAL;
94− }
95−
96− if (i915_buddy_block_size(mm, buddy) != block_size) {
97− pr_err("buddy size mismatch\n");
98− err = -EINVAL;
99− }
100−
101− if (i915_buddy_block_state(buddy) == block_state &&
102− block_state == I915_BUDDY_FREE) {
103− pr_err("block and its buddy are free\n");
104− err = -EINVAL;
105− }
106− }
107−
108− return err;
109−}
110−
111−static int igt_check_blocks(struct i915_buddy_mm *mm,
112− struct list_head *blocks,
113− u64 expected_size,
114− bool is_contiguous)
115−{
116− struct i915_buddy_block *block;
117− struct i915_buddy_block *prev;
118− u64 total;
119− int err = 0;
120−
121− block = NULL;
122− prev = NULL;
123− total = 0;
124−
125− list_for_each_entry(block, blocks, link) {
126− err = igt_check_block(mm, block);
127−
128− if (!i915_buddy_block_is_allocated(block)) {
129− pr_err("block not allocated\n"),
130− err = -EINVAL;
131− }
132−
133− if (is_contiguous && prev) {
134− u64 prev_block_size;
135− u64 prev_offset;
136− u64 offset;
137−
138− prev_offset = i915_buddy_block_offset(prev);
139− prev_block_size = i915_buddy_block_size(mm, prev);
140− offset = i915_buddy_block_offset(block);
141−
142− if (offset != (prev_offset + prev_block_size)) {
143− pr_err("block offset mismatch\n");
144− err = -EINVAL;
145− }
146− }
147−
148− if (err)
149− break;
150−
151− total += i915_buddy_block_size(mm, block);
152− prev = block;
153− }
154−
155− if (!err) {
156− if (total != expected_size) {
157− pr_err("size mismatch, expected=%llx, found=%llx\n",
158− expected_size, total);
159− err = -EINVAL;
160− }
161− return err;
162− }
163−
164− if (prev) {
165− pr_err("prev block, dump:\n");
166− igt_dump_block(mm, prev);
167− }
168−
169− pr_err("bad block, dump:\n");
170− igt_dump_block(mm, block);
171−
172− return err;
173−}
174−
175−static int igt_check_mm(struct i915_buddy_mm *mm)
176−{
177− struct i915_buddy_block *root;
178− struct i915_buddy_block *prev;
179− unsigned int i;
180− u64 total;
181− int err = 0;
182−
183− if (!mm->n_roots) {
184− pr_err("n_roots is zero\n");
185− return -EINVAL;
186− }
187−
188− if (mm->n_roots != hweight64(mm->size)) {
189− pr_err("n_roots mismatch, n_roots=%u, expected=%lu\n",
190− mm->n_roots, hweight64(mm->size));
191− return -EINVAL;
192− }
193−
194− root = NULL;
195− prev = NULL;
196− total = 0;
197−
198− for (i = 0; i < mm->n_roots; ++i) {
199− struct i915_buddy_block *block;
200− unsigned int order;
201−
202− root = mm->roots[i];
203− if (!root) {
204− pr_err("root(%u) is NULL\n", i);
205− err = -EINVAL;
206− break;
207− }
208−
209− err = igt_check_block(mm, root);
210−
211− if (!i915_buddy_block_is_free(root)) {
212− pr_err("root not free\n");
213− err = -EINVAL;
214− }
215−
216− order = i915_buddy_block_order(root);
217−
218− if (!i) {
219− if (order != mm->max_order) {
220− pr_err("max order root missing\n");
221− err = -EINVAL;
222− }
223− }
224−
225− if (prev) {
226− u64 prev_block_size;
227− u64 prev_offset;
228− u64 offset;
229−
230− prev_offset = i915_buddy_block_offset(prev);
231− prev_block_size = i915_buddy_block_size(mm, prev);
232− offset = i915_buddy_block_offset(root);
233−
234− if (offset != (prev_offset + prev_block_size)) {
235− pr_err("root offset mismatch\n");
236− err = -EINVAL;
237− }
238− }
239−
240− block = list_first_entry_or_null(&mm->free_list[order],
241− struct i915_buddy_block,
242− link);
243− if (block != root) {
244− pr_err("root mismatch at order=%u\n", order);
245− err = -EINVAL;
246− }
247−
248− if (err)
249− break;
250−
251− prev = root;
252− total += i915_buddy_block_size(mm, root);
253− }
254−
255− if (!err) {
256− if (total != mm->size) {
257− pr_err("expected mm size=%llx, found=%llx\n", mm->size,
258− total);
259− err = -EINVAL;
260− }
261− return err;
262− }
263−
264− if (prev) {
265− pr_err("prev root(%u), dump:\n", i - 1);
266− igt_dump_block(mm, prev);
267− }
268−
269− if (root) {
270− pr_err("bad root(%u), dump:\n", i);
271− igt_dump_block(mm, root);
272− }
273−
274− return err;
275−}
276−
277−static void igt_mm_config(u64 *size, u64 *chunk_size)
278−{
279− I915_RND_STATE(prng);
280− u32 s, ms;
281−
282− /* Nothing fancy, just try to get an interesting bit pattern */
283−
284− prandom_seed_state(&prng, i915_selftest.random_seed);
285−
286− /* Let size be a random number of pages up to 8 GB (2M pages) */
287− s = 1 + i915_prandom_u32_max_state((BIT(33 - 12)) - 1, &prng);
288− /* Let the chunk size be a random power of 2 less than size */
289− ms = BIT(i915_prandom_u32_max_state(ilog2(s), &prng));
290− /* Round size down to the chunk size */
291− s &= -ms;
292−
293− /* Convert from pages to bytes */
294− *chunk_size = (u64)ms << 12;
295− *size = (u64)s << 12;
296−}
297−
298−static int igt_buddy_alloc_smoke(void *arg)
299−{
300− struct i915_buddy_mm mm;
301− IGT_TIMEOUT(end_time);
302− I915_RND_STATE(prng);
303− u64 chunk_size;
304− u64 mm_size;
305− int *order;
306− int err, i;
307−
308− igt_mm_config(&mm_size, &chunk_size);
309−
310− pr_info("buddy_init with size=%llx, chunk_size=%llx\n", mm_size, chunk_size);
311−
312− err = i915_buddy_init(&mm, mm_size, chunk_size);
313− if (err) {
314− pr_err("buddy_init failed(%d)\n", err);
315− return err;
316− }
317−
318− order = i915_random_order(mm.max_order + 1, &prng);
319− if (!order)
320− goto out_fini;
321−
322− for (i = 0; i <= mm.max_order; ++i) {
323− struct i915_buddy_block *block;
324− int max_order = order[i];
325− bool timeout = false;
326− LIST_HEAD(blocks);
327− int order;
328− u64 total;
329−
330− err = igt_check_mm(&mm);
331− if (err) {
332− pr_err("pre-mm check failed, abort\n");
333− break;
334− }
335−
336− pr_info("filling from max_order=%u\n", max_order);
337−
338− order = max_order;
339− total = 0;
340−
341− do {
342−retry:
343− block = i915_buddy_alloc(&mm, order);
344− if (IS_ERR(block)) {
345− err = PTR_ERR(block);
346− if (err == -ENOMEM) {
347− pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
348− order);
349− } else {
350− if (order--) {
351− err = 0;
352− goto retry;
353− }
354−
355− pr_err("buddy_alloc with order=%d failed(%d)\n",
356− order, err);
357− }
358−
359− break;
360− }
361−
362− list_add_tail(&block->link, &blocks);
363−
364− if (i915_buddy_block_order(block) != order) {
365− pr_err("buddy_alloc order mismatch\n");
366− err = -EINVAL;
367− break;
368− }
369−
370− total += i915_buddy_block_size(&mm, block);
371−
372− if (__igt_timeout(end_time, NULL)) {
373− timeout = true;
374− break;
375− }
376− } while (total < mm.size);
377−
378− if (!err)
379− err = igt_check_blocks(&mm, &blocks, total, false);
380−
381− i915_buddy_free_list(&mm, &blocks);
382−
383− if (!err) {
384− err = igt_check_mm(&mm);
385− if (err)
386− pr_err("post-mm check failed\n");
387− }
388−
389− if (err || timeout)
390− break;
391−
392− cond_resched();
393− }
394−
395− if (err == -ENOMEM)
396− err = 0;
397−
398− kfree(order);
399−out_fini:
400− i915_buddy_fini(&mm);
401−
402− return err;
403−}
404−
405−static int igt_buddy_alloc_pessimistic(void *arg)
406−{
407− const unsigned int max_order = 16;
408− struct i915_buddy_block *block, *bn;
409− struct i915_buddy_mm mm;
410− unsigned int order;
411− LIST_HEAD(blocks);
412− int err;
413−
414− /*
415− * Create a pot-sized mm, then allocate one of each possible
416− * order within. This should leave the mm with exactly one
417− * page left.
418− */
419−
420− err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE);
421− if (err) {
422− pr_err("buddy_init failed(%d)\n", err);
423− return err;
424− }
425− GEM_BUG_ON(mm.max_order != max_order);
426−
427− for (order = 0; order < max_order; order++) {
428− block = i915_buddy_alloc(&mm, order);
429− if (IS_ERR(block)) {
430− pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
431− order);
432− err = PTR_ERR(block);
433− goto err;
434− }
435−
436− list_add_tail(&block->link, &blocks);
437− }
438−
439− /* And now the last remaining block available */
440− block = i915_buddy_alloc(&mm, 0);
441− if (IS_ERR(block)) {
442− pr_info("buddy_alloc hit -ENOMEM on final alloc\n");
443− err = PTR_ERR(block);
444− goto err;
445− }
446− list_add_tail(&block->link, &blocks);
447−
448− /* Should be completely full! */
449− for (order = max_order; order--; ) {
450− block = i915_buddy_alloc(&mm, order);
451− if (!IS_ERR(block)) {
452− pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!",
453− order);
454− list_add_tail(&block->link, &blocks);
455− err = -EINVAL;
456− goto err;
457− }
458− }
459−
460− block = list_last_entry(&blocks, typeof(*block), link);
461− list_del(&block->link);
462− i915_buddy_free(&mm, block);
463−
464− /* As we free in increasing size, we make available larger blocks */
465− order = 1;
466− list_for_each_entry_safe(block, bn, &blocks, link) {
467− list_del(&block->link);
468− i915_buddy_free(&mm, block);
469−
470− block = i915_buddy_alloc(&mm, order);
471− if (IS_ERR(block)) {
472− pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n",
473− order);
474− err = PTR_ERR(block);
475− goto err;
476− }
477− i915_buddy_free(&mm, block);
478− order++;
479− }
480−
481− /* To confirm, now the whole mm should be available */
482− block = i915_buddy_alloc(&mm, max_order);
483− if (IS_ERR(block)) {
484− pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n",
485− max_order);
486− err = PTR_ERR(block);
487− goto err;
488− }
489− i915_buddy_free(&mm, block);
490−
491−err:
492− i915_buddy_free_list(&mm, &blocks);
493− i915_buddy_fini(&mm);
494− return err;
495−}
496−
497−static int igt_buddy_alloc_optimistic(void *arg)
498−{
499− const int max_order = 16;
500− struct i915_buddy_block *block;
501− struct i915_buddy_mm mm;
502− LIST_HEAD(blocks);
503− int order;
504− int err;
505−
506− /*
507− * Create a mm with one block of each order available, and
508− * try to allocate them all.
509− */
510−
511− err = i915_buddy_init(&mm,
512− PAGE_SIZE * ((1 << (max_order + 1)) - 1),
513− PAGE_SIZE);
514− if (err) {
515− pr_err("buddy_init failed(%d)\n", err);
516− return err;
517− }
518− GEM_BUG_ON(mm.max_order != max_order);
519−
520− for (order = 0; order <= max_order; order++) {
521− block = i915_buddy_alloc(&mm, order);
522− if (IS_ERR(block)) {
523− pr_info("buddy_alloc hit -ENOMEM with order=%d\n",
524− order);
525− err = PTR_ERR(block);
526− goto err;
527− }
528−
529− list_add_tail(&block->link, &blocks);
530− }
531−
532− /* Should be completely full! */
533− block = i915_buddy_alloc(&mm, 0);
534− if (!IS_ERR(block)) {
535− pr_info("buddy_alloc unexpectedly succeeded, it should be full!");
536− list_add_tail(&block->link, &blocks);
537− err = -EINVAL;
538− goto err;
539− }
540−
541−err:
542− i915_buddy_free_list(&mm, &blocks);
543− i915_buddy_fini(&mm);
544− return err;
545−}
546−
547−static int igt_buddy_alloc_pathological(void *arg)
548−{
549− const int max_order = 16;
550− struct i915_buddy_block *block;
551− struct i915_buddy_mm mm;
552− LIST_HEAD(blocks);
553− LIST_HEAD(holes);
554− int order, top;
555− int err;
556−
557− /*
558− * Create a pot-sized mm, then allocate one of each possible
559− * order within. This should leave the mm with exactly one
560− * page left. Free the largest block, then whittle down again.
561− * Eventually we will have a fully 50% fragmented mm.
562− */
563−
564− err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE);
565− if (err) {
566− pr_err("buddy_init failed(%d)\n", err);
567− return err;
568− }
569− GEM_BUG_ON(mm.max_order != max_order);
570−
571− for (top = max_order; top; top--) {
572− /* Make room by freeing the largest allocated block */
573− block = list_first_entry_or_null(&blocks, typeof(*block), link);
574− if (block) {
575− list_del(&block->link);
576− i915_buddy_free(&mm, block);
577− }
578−
579− for (order = top; order--; ) {
580− block = i915_buddy_alloc(&mm, order);
581− if (IS_ERR(block)) {
582− pr_info("buddy_alloc hit -ENOMEM with order=%d, top=%d\n",
583− order, top);
584− err = PTR_ERR(block);
585− goto err;
586− }
587− list_add_tail(&block->link, &blocks);
588− }
589−
590− /* There should be one final page for this sub-allocation */
591− block = i915_buddy_alloc(&mm, 0);
592− if (IS_ERR(block)) {
593− pr_info("buddy_alloc hit -ENOMEM for hole\n");
594− err = PTR_ERR(block);
595− goto err;
596− }
597− list_add_tail(&block->link, &holes);
598−
599− block = i915_buddy_alloc(&mm, top);
600− if (!IS_ERR(block)) {
601− pr_info("buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!",
602− top, max_order);
603− list_add_tail(&block->link, &blocks);
604− err = -EINVAL;
605− goto err;
606− }
607− }
608−
609− i915_buddy_free_list(&mm, &holes);
610−
611− /* Nothing larger than blocks of chunk_size now available */
612− for (order = 1; order <= max_order; order++) {
613− block = i915_buddy_alloc(&mm, order);
614− if (!IS_ERR(block)) {
615− pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!",
616− order);
617− list_add_tail(&block->link, &blocks);
618− err = -EINVAL;
619− goto err;
620− }
621− }
622−
623−err:
624− list_splice_tail(&holes, &blocks);
625− i915_buddy_free_list(&mm, &blocks);
626− i915_buddy_fini(&mm);
627− return err;
628−}
629−
630−static int igt_buddy_alloc_range(void *arg)
631−{
632− struct i915_buddy_mm mm;
633− unsigned long page_num;
634− LIST_HEAD(blocks);
635− u64 chunk_size;
636− u64 offset;
637− u64 size;
638− u64 rem;
639− int err;
640−
641− igt_mm_config(&size, &chunk_size);
642−
643− pr_info("buddy_init with size=%llx, chunk_size=%llx\n", size, chunk_size);
644−
645− err = i915_buddy_init(&mm, size, chunk_size);
646− if (err) {
647− pr_err("buddy_init failed(%d)\n", err);
648− return err;
649− }
650−
651− err = igt_check_mm(&mm);
652− if (err) {
653− pr_err("pre-mm check failed, abort, abort, abort!\n");
654− goto err_fini;
655− }
656−
657− rem = mm.size;
658− offset = 0;
659−
660− for_each_prime_number_from(page_num, 1, ULONG_MAX - 1) {
661− struct i915_buddy_block *block;
662− LIST_HEAD(tmp);
663−
664− size = min(page_num * mm.chunk_size, rem);
665−
666− err = i915_buddy_alloc_range(&mm, &tmp, offset, size);
667− if (err) {
668− if (err == -ENOMEM) {
669− pr_info("alloc_range hit -ENOMEM with size=%llx\n",
670− size);
671− } else {
672− pr_err("alloc_range with offset=%llx, size=%llx failed(%d)\n",
673− offset, size, err);
674− }
675−
676− break;
677− }
678−
679− block = list_first_entry_or_null(&tmp,
680− struct i915_buddy_block,
681− link);
682− if (!block) {
683− pr_err("alloc_range has no blocks\n");
684− err = -EINVAL;
685− break;
686− }
687−
688− if (i915_buddy_block_offset(block) != offset) {
689− pr_err("alloc_range start offset mismatch, found=%llx, expected=%llx\n",
690− i915_buddy_block_offset(block), offset);
691− err = -EINVAL;
692− }
693−
694− if (!err)
695− err = igt_check_blocks(&mm, &tmp, size, true);
696−
697− list_splice_tail(&tmp, &blocks);
698−
699− if (err)
700− break;
701−
702− offset += size;
703−
704− rem -= size;
705− if (!rem)
706− break;
707−
708− cond_resched();
709− }
710−
711− if (err == -ENOMEM)
712− err = 0;
713−
714− i915_buddy_free_list(&mm, &blocks);
715−
716− if (!err) {
717− err = igt_check_mm(&mm);
718− if (err)
719− pr_err("post-mm check failed\n");
720− }
721−
722−err_fini:
723− i915_buddy_fini(&mm);
724−
725− return err;
726−}
727−
728−static int igt_buddy_alloc_limit(void *arg)
729−{
730− struct i915_buddy_block *block;
731− struct i915_buddy_mm mm;
732− const u64 size = U64_MAX;
733− int err;
734−
735− err = i915_buddy_init(&mm, size, PAGE_SIZE);
736− if (err)
737− return err;
738−
739− if (mm.max_order != I915_BUDDY_MAX_ORDER) {
740− pr_err("mm.max_order(%d) != %d\n",
741− mm.max_order, I915_BUDDY_MAX_ORDER);
742− err = -EINVAL;
743− goto out_fini;
744− }
745−
746− block = i915_buddy_alloc(&mm, mm.max_order);
747− if (IS_ERR(block)) {
748− err = PTR_ERR(block);
749− goto out_fini;
750− }
751−
752− if (i915_buddy_block_order(block) != mm.max_order) {
753− pr_err("block order(%d) != %d\n",
754− i915_buddy_block_order(block), mm.max_order);
755− err = -EINVAL;
756− goto out_free;
757− }
758−
759− if (i915_buddy_block_size(&mm, block) !=
760− BIT_ULL(mm.max_order) * PAGE_SIZE) {
761− pr_err("block size(%llu) != %llu\n",
762− i915_buddy_block_size(&mm, block),
763− BIT_ULL(mm.max_order) * PAGE_SIZE);
764− err = -EINVAL;
765− goto out_free;
766− }
767−
768−out_free:
769− i915_buddy_free(&mm, block);
770−out_fini:
771− i915_buddy_fini(&mm);
772− return err;
773−}
774−
775−int i915_buddy_mock_selftests(void)
776−{
777− static const struct i915_subtest tests[] = {
778− SUBTEST(igt_buddy_alloc_pessimistic),
779− SUBTEST(igt_buddy_alloc_optimistic),
780− SUBTEST(igt_buddy_alloc_pathological),
781− SUBTEST(igt_buddy_alloc_smoke),
782− SUBTEST(igt_buddy_alloc_range),
783− SUBTEST(igt_buddy_alloc_limit),
784− };
785−
786− return i915_subtests(tests, NULL);
787−}
drivers/gpu/drm/i915/selftests/i915_mock_selftests.h+0−1
@@ -33,4 +33,3 @@ selftest(evict, i915_gem_evict_mock_selftests) · 32 unmodified lines
3333 selftest(gtt, i915_gem_gtt_mock_selftests)
3434 selftest(hugepages, i915_gem_huge_page_mock_selftests)
3535 selftest(memory_region, intel_memory_region_mock_selftests)
36−selftest(buddy, i915_buddy_mock_selftests)
drivers/gpu/drm/i915/selftests/intel_memory_region.c+7−6
@@ -6,6 +6,8 @@ · 5 unmodified lines
66 #include <linux/prime_numbers.h>
77 #include <linux/sort.h>
88
9+#include <drm/drm_buddy.h>
10+
911 #include "../i915_selftest.h"
1012
1113 #include "mock_drm.h"
@@ -20,7 +22,6 @@ · 8 unmodified lines
2022 #include "gt/intel_engine_pm.h"
2123 #include "gt/intel_engine_user.h"
2224 #include "gt/intel_gt.h"
23−#include "i915_buddy.h"
2425 #include "gt/intel_migrate.h"
2526 #include "i915_memcpy.h"
2627 #include "i915_ttm_buddy_manager.h"
@@ -369,7 +370,7 @@ static int igt_mock_splintered_region(void *arg) · 342 unmodified lines
369370 struct drm_i915_private *i915 = mem->i915;
370371 struct i915_ttm_buddy_resource *res;
371372 struct drm_i915_gem_object *obj;
372− struct i915_buddy_mm *mm;
373+ struct drm_buddy *mm;
373374 unsigned int expected_order;
374375 LIST_HEAD(objects);
375376 u64 size;
@@ -454,8 +455,8 @@ static int igt_mock_max_segment(void *arg) · 78 unmodified lines
454455 struct drm_i915_private *i915 = mem->i915;
455456 struct i915_ttm_buddy_resource *res;
456457 struct drm_i915_gem_object *obj;
457− struct i915_buddy_block *block;
458− struct i915_buddy_mm *mm;
458+ struct drm_buddy_block *block;
459+ struct drm_buddy *mm;
459460 struct list_head *blocks;
460461 struct scatterlist *sg;
461462 LIST_HEAD(objects);
@@ -485,8 +486,8 @@ static int igt_mock_max_segment(void *arg) · 23 unmodified lines
485486 mm = res->mm;
486487 size = 0;
487488 list_for_each_entry(block, blocks, link) {
488− if (i915_buddy_block_size(mm, block) > size)
489− size = i915_buddy_block_size(mm, block);
489+ if (drm_buddy_block_size(mm, block) > size)
490+ size = drm_buddy_block_size(mm, block);
490491 }
491492 if (size < max_segment) {
492493 pr_err("%s: Failed to create a huge contiguous block [> %u], largest block %lld\n",
drivers/gpu/drm/imx/dcss/dcss-drv.c+2−1
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/module.h>
77 #include <linux/kernel.h>
88 #include <linux/platform_device.h>
9+#include <drm/drm_module.h>
910 #include <drm/drm_of.h>
1011
1112 #include "dcss-dev.h"
@@ -131,7 +132,7 @@ static struct platform_driver dcss_platform_driver = { · 119 unmodified lines
131132 },
132133 };
133134
134−module_platform_driver(dcss_platform_driver);
135+drm_module_platform_driver(dcss_platform_driver);
135136
136137 MODULE_AUTHOR("Laurentiu Palcu <laurentiu.palcu@nxp.com>");
137138 MODULE_DESCRIPTION("DCSS driver for i.MX8MQ");
drivers/gpu/drm/ingenic/ingenic-drm-drv.c+59−3
@@ -6,6 +6,7 @@ · 5 unmodified lines
66
77 #include "ingenic-drm.h"
88
9+#include <linux/bitfield.h>
910 #include <linux/component.h>
1011 #include <linux/clk.h>
1112 #include <linux/dma-mapping.h>
@@ -49,6 +50,11 @@ struct ingenic_dma_hwdesc { · 37 unmodified lines
4950 u32 addr;
5051 u32 id;
5152 u32 cmd;
53+ /* extended hw descriptor for jz4780 */
54+ u32 offsize;
55+ u32 pagewidth;
56+ u32 cpos;
57+ u32 dessize;
5258 } __aligned(16);
5359
5460 struct ingenic_dma_hwdescs {
@@ -60,6 +66,7 @@ struct jz_soc_info { · 5 unmodified lines
6066 bool needs_dev_clk;
6167 bool has_osd;
6268 bool map_noncoherent;
69+ bool use_extended_hwdesc;
6370 unsigned int max_width, max_height;
6471 const u32 *formats_f0, *formats_f1;
6572 unsigned int num_formats_f0, num_formats_f1;
@@ -173,7 +180,6 @@ static const struct regmap_config ingenic_drm_regmap_config = { · 107 unmodified lines
173180 .val_bits = 32,
174181 .reg_stride = 4,
175182
176− .max_register = JZ_REG_LCD_SIZE1,
177183 .writeable_reg = ingenic_drm_writeable_reg,
178184 };
179185
@@ -447,6 +453,9 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, · 267 unmodified lines
447453 if (!crtc)
448454 return 0;
449455
456+ if (plane == &priv->f0)
457+ return -EINVAL;
458+
450459 crtc_state = drm_atomic_get_existing_crtc_state(state,
451460 crtc);
452461 if (WARN_ON(!crtc_state))
@@ -663,6 +672,33 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, · 210 unmodified lines
663672 hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4);
664673 hwdesc->next = dma_hwdesc_addr(priv, next_id);
665674
675+ if (priv->soc_info->use_extended_hwdesc) {
676+ hwdesc->cmd |= JZ_LCD_CMD_FRM_ENABLE;
677+
678+ /* Extended 8-byte descriptor */
679+ hwdesc->cpos = 0;
680+ hwdesc->offsize = 0;
681+ hwdesc->pagewidth = 0;
682+
683+ switch (newstate->fb->format->format) {
684+ case DRM_FORMAT_XRGB1555:
685+ hwdesc->cpos |= JZ_LCD_CPOS_RGB555;
686+ fallthrough;
687+ case DRM_FORMAT_RGB565:
688+ hwdesc->cpos |= JZ_LCD_CPOS_BPP_15_16;
689+ break;
690+ case DRM_FORMAT_XRGB8888:
691+ hwdesc->cpos |= JZ_LCD_CPOS_BPP_18_24;
692+ break;
693+ }
694+ hwdesc->cpos |= (JZ_LCD_CPOS_COEFFICIENT_1 <<
695+ JZ_LCD_CPOS_COEFFICIENT_OFFSET);
696+ hwdesc->dessize =
697+ (0xff << JZ_LCD_DESSIZE_ALPHA_OFFSET) |
698+ FIELD_PREP(JZ_LCD_DESSIZE_HEIGHT_MASK, height - 1) |
699+ FIELD_PREP(JZ_LCD_DESSIZE_WIDTH_MASK, width - 1);
700+ }
701+
666702 if (drm_atomic_crtc_needs_modeset(crtc_state)) {
667703 fourcc = newstate->fb->format->format;
668704
@@ -694,6 +730,9 @@ static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder, · 25 unmodified lines
694730 | JZ_LCD_CFG_SPL_DISABLE | JZ_LCD_CFG_REV_DISABLE;
695731 }
696732
733+ if (priv->soc_info->use_extended_hwdesc)
734+ cfg |= JZ_LCD_CFG_DESCRIPTOR_8;
735+
697736 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
698737 cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW;
699738 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
@@ -1011,6 +1050,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) · 311 unmodified lines
10111050 struct ingenic_drm_bridge *ib;
10121051 struct drm_device *drm;
10131052 void __iomem *base;
1053+ struct resource *res;
1054+ struct regmap_config regmap_config;
10141055 long parent_rate;
10151056 unsigned int i, clone_mask = 0;
10161057 int ret, irq;
@@ -1056,14 +1097,16 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) · 39 unmodified lines
10561097 drm->mode_config.funcs = &ingenic_drm_mode_config_funcs;
10571098 drm->mode_config.helper_private = &ingenic_drm_mode_config_helpers;
10581099
1059− base = devm_platform_ioremap_resource(pdev, 0);
1100+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
10601101 if (IS_ERR(base)) {
10611102 dev_err(dev, "Failed to get memory resource\n");
10621103 return PTR_ERR(base);
10631104 }
10641105
1106+ regmap_config = ingenic_drm_regmap_config;
1107+ regmap_config.max_register = res->end - res->start;
10651108 priv->map = devm_regmap_init_mmio(dev, base,
1066− &ingenic_drm_regmap_config);
1109+ &regmap_config);
10671110 if (IS_ERR(priv->map)) {
10681111 dev_err(dev, "Failed to create regmap\n");
10691112 return PTR_ERR(priv->map);
@@ -1465,10 +1508,23 @@ static const struct jz_soc_info jz4770_soc_info = { · 395 unmodified lines
14651508 .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0),
14661509 };
14671510
1511+static const struct jz_soc_info jz4780_soc_info = {
1512+ .needs_dev_clk = true,
1513+ .has_osd = true,
1514+ .use_extended_hwdesc = true,
1515+ .max_width = 4096,
1516+ .max_height = 2048,
1517+ .formats_f1 = jz4770_formats_f1,
1518+ .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1),
1519+ .formats_f0 = jz4770_formats_f0,
1520+ .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0),
1521+};
1522+
14681523 static const struct of_device_id ingenic_drm_of_match[] = {
14691524 { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info },
14701525 { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info },
14711526 { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info },
1527+ { .compatible = "ingenic,jz4780-lcd", .data = &jz4780_soc_info },
14721528 { /* sentinel */ },
14731529 };
14741530 MODULE_DEVICE_TABLE(of, ingenic_drm_of_match);
drivers/gpu/drm/ingenic/ingenic-drm.h+38−0
@@ -44,8 +44,11 @@ · 43 unmodified lines
4444 #define JZ_REG_LCD_XYP1 0x124
4545 #define JZ_REG_LCD_SIZE0 0x128
4646 #define JZ_REG_LCD_SIZE1 0x12c
47+#define JZ_REG_LCD_PCFG 0x2c0
4748
4849 #define JZ_LCD_CFG_SLCD BIT(31)
50+#define JZ_LCD_CFG_DESCRIPTOR_8 BIT(28)
51+#define JZ_LCD_CFG_RECOVER_FIFO_UNDERRUN BIT(25)
4952 #define JZ_LCD_CFG_PS_DISABLE BIT(23)
5053 #define JZ_LCD_CFG_CLS_DISABLE BIT(22)
5154 #define JZ_LCD_CFG_SPL_DISABLE BIT(21)
@@ -63,6 +66,7 @@ · 11 unmodified lines
6366 #define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9)
6467 #define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8)
6568 #define JZ_LCD_CFG_18_BIT BIT(7)
69+#define JZ_LCD_CFG_24_BIT BIT(6)
6670 #define JZ_LCD_CFG_PDW (BIT(5) | BIT(4))
6771
6872 #define JZ_LCD_CFG_MODE_GENERIC_16BIT 0
@@ -132,6 +136,7 @@ · 63 unmodified lines
132136 #define JZ_LCD_CMD_SOF_IRQ BIT(31)
133137 #define JZ_LCD_CMD_EOF_IRQ BIT(30)
134138 #define JZ_LCD_CMD_ENABLE_PAL BIT(28)
139+#define JZ_LCD_CMD_FRM_ENABLE BIT(26)
135140
136141 #define JZ_LCD_SYNC_MASK 0x3ff
137142
@@ -153,6 +158,7 @@ · 15 unmodified lines
153158 #define JZ_LCD_RGBC_EVEN_BGR (0x5 << 0)
154159
155160 #define JZ_LCD_OSDC_OSDEN BIT(0)
161+#define JZ_LCD_OSDC_ALPHAEN BIT(2)
156162 #define JZ_LCD_OSDC_F0EN BIT(3)
157163 #define JZ_LCD_OSDC_F1EN BIT(4)
158164
@@ -176,6 +182,38 @@ · 17 unmodified lines
176182 #define JZ_LCD_SIZE01_WIDTH_LSB 0
177183 #define JZ_LCD_SIZE01_HEIGHT_LSB 16
178184
185+#define JZ_LCD_DESSIZE_ALPHA_OFFSET 24
186+#define JZ_LCD_DESSIZE_HEIGHT_MASK GENMASK(23, 12)
187+#define JZ_LCD_DESSIZE_WIDTH_MASK GENMASK(11, 0)
188+
189+#define JZ_LCD_CPOS_BPP_15_16 (4 << 27)
190+#define JZ_LCD_CPOS_BPP_18_24 (5 << 27)
191+#define JZ_LCD_CPOS_BPP_30 (7 << 27)
192+#define JZ_LCD_CPOS_RGB555 BIT(30)
193+#define JZ_LCD_CPOS_PREMULTIPLY_LCD BIT(26)
194+#define JZ_LCD_CPOS_COEFFICIENT_OFFSET 24
195+#define JZ_LCD_CPOS_COEFFICIENT_0 0
196+#define JZ_LCD_CPOS_COEFFICIENT_1 1
197+#define JZ_LCD_CPOS_COEFFICIENT_ALPHA1 2
198+#define JZ_LCD_CPOS_COEFFICIENT_1_ALPHA1 3
199+
200+#define JZ_LCD_RGBC_RGB_PADDING BIT(15)
201+#define JZ_LCD_RGBC_RGB_PADDING_FIRST BIT(14)
202+#define JZ_LCD_RGBC_422 BIT(8)
203+#define JZ_LCD_RGBC_RGB_FORMAT_ENABLE BIT(7)
204+
205+#define JZ_LCD_PCFG_PRI_MODE BIT(31)
206+#define JZ_LCD_PCFG_HP_BST_4 (0 << 28)
207+#define JZ_LCD_PCFG_HP_BST_8 (1 << 28)
208+#define JZ_LCD_PCFG_HP_BST_16 (2 << 28)
209+#define JZ_LCD_PCFG_HP_BST_32 (3 << 28)
210+#define JZ_LCD_PCFG_HP_BST_64 (4 << 28)
211+#define JZ_LCD_PCFG_HP_BST_16_CONT (5 << 28)
212+#define JZ_LCD_PCFG_HP_BST_DISABLE (7 << 28)
213+#define JZ_LCD_PCFG_THRESHOLD2_OFFSET 18
214+#define JZ_LCD_PCFG_THRESHOLD1_OFFSET 9
215+#define JZ_LCD_PCFG_THRESHOLD0_OFFSET 0
216+
179217 struct device;
180218 struct drm_plane;
181219 struct drm_plane_state;
drivers/gpu/drm/meson/meson_drv.c+13−12
@@ -302,42 +302,42 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) · 301 unmodified lines
302302 if (priv->afbcd.ops) {
303303 ret = priv->afbcd.ops->init(priv);
304304 if (ret)
305− return ret;
305+ goto free_drm;
306306 }
307307
308308 /* Encoder Initialization */
309309
310310 ret = meson_encoder_cvbs_init(priv);
311311 if (ret)
312− goto free_drm;
312+ goto exit_afbcd;
313313
314314 if (has_components) {
315315 ret = component_bind_all(drm->dev, drm);
316316 if (ret) {
317317 dev_err(drm->dev, "Couldn't bind all components\n");
318− goto free_drm;
318+ goto exit_afbcd;
319319 }
320320 }
321321
322322 ret = meson_encoder_hdmi_init(priv);
323323 if (ret)
324− goto free_drm;
324+ goto exit_afbcd;
325325
326326 ret = meson_plane_create(priv);
327327 if (ret)
328− goto free_drm;
328+ goto exit_afbcd;
329329
330330 ret = meson_overlay_create(priv);
331331 if (ret)
332− goto free_drm;
332+ goto exit_afbcd;
333333
334334 ret = meson_crtc_create(priv);
335335 if (ret)
336− goto free_drm;
336+ goto exit_afbcd;
337337
338338 ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
339339 if (ret)
340− goto free_drm;
340+ goto exit_afbcd;
341341
342342 drm_mode_config_reset(drm);
343343
@@ -355,6 +355,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) · 11 unmodified lines
355355
356356 uninstall_irq:
357357 free_irq(priv->vsync_irq, drm);
358+exit_afbcd:
359+ if (priv->afbcd.ops)
360+ priv->afbcd.ops->exit(priv);
358361 free_drm:
359362 drm_dev_put(drm);
360363
@@ -385,10 +388,8 @@ static void meson_drv_unbind(struct device *dev) · 24 unmodified lines
385388 free_irq(priv->vsync_irq, drm);
386389 drm_dev_put(drm);
387390
388− if (priv->afbcd.ops) {
389− priv->afbcd.ops->reset(priv);
390− meson_rdma_free(priv);
391− }
391+ if (priv->afbcd.ops)
392+ priv->afbcd.ops->exit(priv);
392393 }
393394
394395 static const struct component_master_ops meson_drv_master_ops = {
drivers/gpu/drm/meson/meson_osd_afbcd.c+27−14
@@ -79,11 +79,6 @@ static bool meson_gxm_afbcd_supported_fmt(u64 modifier, uint32_t format) · 78 unmodified lines
7979 return meson_gxm_afbcd_pixel_fmt(modifier, format) >= 0;
8080 }
8181
82−static int meson_gxm_afbcd_init(struct meson_drm *priv)
83−{
84− return 0;
85−}
86−
8782 static int meson_gxm_afbcd_reset(struct meson_drm *priv)
8883 {
8984 writel_relaxed(VIU_SW_RESET_OSD1_AFBCD,
@@ -93,6 +88,16 @@ static int meson_gxm_afbcd_reset(struct meson_drm *priv) · 3 unmodified lines
9388 return 0;
9489 }
9590
91+static int meson_gxm_afbcd_init(struct meson_drm *priv)
92+{
93+ return 0;
94+}
95+
96+static void meson_gxm_afbcd_exit(struct meson_drm *priv)
97+{
98+ meson_gxm_afbcd_reset(priv);
99+}
100+
96101 static int meson_gxm_afbcd_enable(struct meson_drm *priv)
97102 {
98103 writel_relaxed(FIELD_PREP(OSD1_AFBCD_ID_FIFO_THRD, 0x40) |
@@ -172,6 +177,7 @@ static int meson_gxm_afbcd_setup(struct meson_drm *priv) · 73 unmodified lines
172177
173178 struct meson_afbcd_ops meson_afbcd_gxm_ops = {
174179 .init = meson_gxm_afbcd_init,
180+ .exit = meson_gxm_afbcd_exit,
175181 .reset = meson_gxm_afbcd_reset,
176182 .enable = meson_gxm_afbcd_enable,
177183 .disable = meson_gxm_afbcd_disable,
@@ -269,6 +275,18 @@ static bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format) · 91 unmodified lines
269275 return meson_g12a_afbcd_pixel_fmt(modifier, format) >= 0;
270276 }
271277
278+static int meson_g12a_afbcd_reset(struct meson_drm *priv)
279+{
280+ meson_rdma_reset(priv);
281+
282+ meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
283+ VIU_SW_RESET_G12A_OSD1_AFBCD,
284+ VIU_SW_RESET);
285+ meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
286+
287+ return 0;
288+}
289+
272290 static int meson_g12a_afbcd_init(struct meson_drm *priv)
273291 {
274292 int ret;
@@ -286,16 +304,10 @@ static int meson_g12a_afbcd_init(struct meson_drm *priv) · 11 unmodified lines
286304 return 0;
287305 }
288306
289−static int meson_g12a_afbcd_reset(struct meson_drm *priv)
307+static void meson_g12a_afbcd_exit(struct meson_drm *priv)
290308 {
291− meson_rdma_reset(priv);
292−
293− meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
294− VIU_SW_RESET_G12A_OSD1_AFBCD,
295− VIU_SW_RESET);
296− meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
297−
298− return 0;
309+ meson_g12a_afbcd_reset(priv);
310+ meson_rdma_free(priv);
299311 }
300312
301313 static int meson_g12a_afbcd_enable(struct meson_drm *priv)
@@ -380,6 +392,7 @@ static int meson_g12a_afbcd_setup(struct meson_drm *priv) · 78 unmodified lines
380392
381393 struct meson_afbcd_ops meson_afbcd_g12a_ops = {
382394 .init = meson_g12a_afbcd_init,
395+ .exit = meson_g12a_afbcd_exit,
383396 .reset = meson_g12a_afbcd_reset,
384397 .enable = meson_g12a_afbcd_enable,
385398 .disable = meson_g12a_afbcd_disable,
drivers/gpu/drm/meson/meson_osd_afbcd.h+1−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414
1515 struct meson_afbcd_ops {
1616 int (*init)(struct meson_drm *priv);
17+ void (*exit)(struct meson_drm *priv);
1718 int (*reset)(struct meson_drm *priv);
1819 int (*enable)(struct meson_drm *priv);
1920 int (*disable)(struct meson_drm *priv);
drivers/gpu/drm/mgag200/mgag200_mode.c+4−1
@@ -529,7 +529,10 @@ static void mgag200_set_format_regs(struct mga_device *mdev, · 528 unmodified lines
529529 WREG_GFX(3, 0x00);
530530 WREG_GFX(4, 0x00);
531531 WREG_GFX(5, 0x40);
532− WREG_GFX(6, 0x05);
532+ /* GCTL6 should be 0x05, but we configure memmapsl to 0xb8000 (text mode),
533+ * so that it doesn't hang when running kexec/kdump on G200_SE rev42.
534+ */
535+ WREG_GFX(6, 0x0d);
533536 WREG_GFX(7, 0x0f);
534537 WREG_GFX(8, 0x0f);
535538
drivers/gpu/drm/msm/Kconfig+1−0
@@ -12,6 +12,7 @@ config DRM_MSM · 11 unmodified lines
1212 select IOMMU_IO_PGTABLE
1313 select QCOM_MDT_LOADER if ARCH_QCOM
1414 select REGULATOR
15+ select DRM_DP_HELPER
1516 select DRM_KMS_HELPER
1617 select DRM_PANEL
1718 select DRM_BRIDGE
drivers/gpu/drm/msm/dp/dp_audio.c+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88
99 #include <linux/of_platform.h>
1010
11−#include <drm/drm_dp_helper.h>
11+#include <drm/dp/drm_dp_helper.h>
1212 #include <drm/drm_edid.h>
1313
1414 #include "dp_catalog.h"
drivers/gpu/drm/msm/dp/dp_aux.h+1−1
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 #define _DP_AUX_H_
88
99 #include "dp_catalog.h"
10−#include <drm/drm_dp_helper.h>
10+#include <drm/dp/drm_dp_helper.h>
1111
1212 int dp_aux_register(struct drm_dp_aux *dp_aux);
1313 void dp_aux_unregister(struct drm_dp_aux *dp_aux);
drivers/gpu/drm/msm/dp/dp_catalog.c+1−1
@@ -10,7 +10,7 @@ · 9 unmodified lines
1010 #include <linux/phy/phy.h>
1111 #include <linux/phy/phy-dp.h>
1212 #include <linux/rational.h>
13−#include <drm/drm_dp_helper.h>
13+#include <drm/dp/drm_dp_helper.h>
1414 #include <drm/drm_print.h>
1515
1616 #include "dp_catalog.h"
drivers/gpu/drm/msm/dp/dp_ctrl.c+1−1
@@ -12,7 +12,7 @@ · 11 unmodified lines
1212 #include <linux/phy/phy-dp.h>
1313 #include <linux/pm_opp.h>
1414 #include <drm/drm_fixed.h>
15−#include <drm/drm_dp_helper.h>
15+#include <drm/dp/drm_dp_helper.h>
1616 #include <drm/drm_print.h>
1717
1818 #include "dp_reg.h"
drivers/gpu/drm/msm/edp/edp.h+77−0
@@ -0,0 +1,77 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+/*
3+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
4+ */
5+
6+#ifndef __EDP_CONNECTOR_H__
7+#define __EDP_CONNECTOR_H__
8+
9+#include <linux/i2c.h>
10+#include <linux/interrupt.h>
11+#include <linux/kernel.h>
12+#include <linux/platform_device.h>
13+#include <drm/dp/drm_dp_helper.h>
14+#include <drm/drm_bridge.h>
15+#include <drm/drm_crtc.h>
16+
17+#include "msm_drv.h"
18+
19+#define edp_read(offset) msm_readl((offset))
20+#define edp_write(offset, data) msm_writel((data), (offset))
21+
22+struct edp_ctrl;
23+struct edp_aux;
24+struct edp_phy;
25+
26+struct msm_edp {
27+ struct drm_device *dev;
28+ struct platform_device *pdev;
29+
30+ struct drm_connector *connector;
31+ struct drm_bridge *bridge;
32+
33+ /* the encoder we are hooked to (outside of eDP block) */
34+ struct drm_encoder *encoder;
35+
36+ struct edp_ctrl *ctrl;
37+
38+ int irq;
39+};
40+
41+/* eDP bridge */
42+struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp);
43+void edp_bridge_destroy(struct drm_bridge *bridge);
44+
45+/* eDP connector */
46+struct drm_connector *msm_edp_connector_init(struct msm_edp *edp);
47+
48+/* AUX */
49+void *msm_edp_aux_init(struct msm_edp *edp, void __iomem *regbase, struct drm_dp_aux **drm_aux);
50+void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux);
51+irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr);
52+void msm_edp_aux_ctrl(struct edp_aux *aux, int enable);
53+
54+/* Phy */
55+bool msm_edp_phy_ready(struct edp_phy *phy);
56+void msm_edp_phy_ctrl(struct edp_phy *phy, int enable);
57+void msm_edp_phy_vm_pe_init(struct edp_phy *phy);
58+void msm_edp_phy_vm_pe_cfg(struct edp_phy *phy, u32 v0, u32 v1);
59+void msm_edp_phy_lane_power_ctrl(struct edp_phy *phy, bool up, u32 max_lane);
60+void *msm_edp_phy_init(struct device *dev, void __iomem *regbase);
61+
62+/* Ctrl */
63+irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl);
64+void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on);
65+int msm_edp_ctrl_init(struct msm_edp *edp);
66+void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl);
67+bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl);
68+int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl,
69+ struct drm_connector *connector, struct edid **edid);
70+int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl,
71+ const struct drm_display_mode *mode,
72+ const struct drm_display_info *info);
73+/* @pixel_rate is in kHz */
74+bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl,
75+ u32 pixel_rate, u32 *pm, u32 *pn);
76+
77+#endif /* __EDP_CONNECTOR_H__ */
drivers/gpu/drm/msm/edp/edp_ctrl.c+1373−0
@@ -0,0 +1,1373 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+/*
3+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
4+ */
5+
6+#include <linux/clk.h>
7+#include <linux/gpio/consumer.h>
8+#include <linux/regulator/consumer.h>
9+#include <drm/dp/drm_dp_helper.h>
10+#include <drm/drm_crtc.h>
11+#include <drm/drm_edid.h>
12+
13+#include "edp.h"
14+#include "edp.xml.h"
15+
16+#define VDDA_UA_ON_LOAD 100000 /* uA units */
17+#define VDDA_UA_OFF_LOAD 100 /* uA units */
18+
19+#define DPCD_LINK_VOLTAGE_MAX 4
20+#define DPCD_LINK_PRE_EMPHASIS_MAX 4
21+
22+#define EDP_LINK_BW_MAX DP_LINK_BW_2_7
23+
24+/* Link training return value */
25+#define EDP_TRAIN_FAIL -1
26+#define EDP_TRAIN_SUCCESS 0
27+#define EDP_TRAIN_RECONFIG 1
28+
29+#define EDP_CLK_MASK_AHB BIT(0)
30+#define EDP_CLK_MASK_AUX BIT(1)
31+#define EDP_CLK_MASK_LINK BIT(2)
32+#define EDP_CLK_MASK_PIXEL BIT(3)
33+#define EDP_CLK_MASK_MDP_CORE BIT(4)
34+#define EDP_CLK_MASK_LINK_CHAN (EDP_CLK_MASK_LINK | EDP_CLK_MASK_PIXEL)
35+#define EDP_CLK_MASK_AUX_CHAN \
36+ (EDP_CLK_MASK_AHB | EDP_CLK_MASK_AUX | EDP_CLK_MASK_MDP_CORE)
37+#define EDP_CLK_MASK_ALL (EDP_CLK_MASK_AUX_CHAN | EDP_CLK_MASK_LINK_CHAN)
38+
39+#define EDP_BACKLIGHT_MAX 255
40+
41+#define EDP_INTR_STATUS1 \
42+ (EDP_INTERRUPT_REG_1_HPD | EDP_INTERRUPT_REG_1_AUX_I2C_DONE | \
43+ EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \
44+ EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \
45+ EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER | \
46+ EDP_INTERRUPT_REG_1_PLL_UNLOCK | EDP_INTERRUPT_REG_1_AUX_ERROR)
47+#define EDP_INTR_MASK1 (EDP_INTR_STATUS1 << 2)
48+#define EDP_INTR_STATUS2 \
49+ (EDP_INTERRUPT_REG_2_READY_FOR_VIDEO | \
50+ EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT | \
51+ EDP_INTERRUPT_REG_2_FRAME_END | EDP_INTERRUPT_REG_2_CRC_UPDATED)
52+#define EDP_INTR_MASK2 (EDP_INTR_STATUS2 << 2)
53+
54+struct edp_ctrl {
55+ struct platform_device *pdev;
56+
57+ void __iomem *base;
58+
59+ /* regulators */
60+ struct regulator *vdda_vreg; /* 1.8 V */
61+ struct regulator *lvl_vreg;
62+
63+ /* clocks */
64+ struct clk *aux_clk;
65+ struct clk *pixel_clk;
66+ struct clk *ahb_clk;
67+ struct clk *link_clk;
68+ struct clk *mdp_core_clk;
69+
70+ /* gpios */
71+ struct gpio_desc *panel_en_gpio;
72+ struct gpio_desc *panel_hpd_gpio;
73+
74+ /* completion and mutex */
75+ struct completion idle_comp;
76+ struct mutex dev_mutex; /* To protect device power status */
77+
78+ /* work queue */
79+ struct work_struct on_work;
80+ struct work_struct off_work;
81+ struct workqueue_struct *workqueue;
82+
83+ /* Interrupt register lock */
84+ spinlock_t irq_lock;
85+
86+ bool edp_connected;
87+ bool power_on;
88+
89+ /* edid raw data */
90+ struct edid *edid;
91+
92+ struct drm_dp_aux *drm_aux;
93+
94+ /* dpcd raw data */
95+ u8 dpcd[DP_RECEIVER_CAP_SIZE];
96+
97+ /* Link status */
98+ u8 link_rate;
99+ u8 lane_cnt;
100+ u8 v_level;
101+ u8 p_level;
102+
103+ /* Timing status */
104+ u8 interlaced;
105+ u32 pixel_rate; /* in kHz */
106+ u32 color_depth;
107+
108+ struct edp_aux *aux;
109+ struct edp_phy *phy;
110+};
111+
112+struct edp_pixel_clk_div {
113+ u32 rate; /* in kHz */
114+ u32 m;
115+ u32 n;
116+};
117+
118+#define EDP_PIXEL_CLK_NUM 8
119+static const struct edp_pixel_clk_div clk_divs[2][EDP_PIXEL_CLK_NUM] = {
120+ { /* Link clock = 162MHz, source clock = 810MHz */
121+ {119000, 31, 211}, /* WSXGA+ 1680x1050@60Hz CVT */
122+ {130250, 32, 199}, /* UXGA 1600x1200@60Hz CVT */
123+ {148500, 11, 60}, /* FHD 1920x1080@60Hz */
124+ {154000, 50, 263}, /* WUXGA 1920x1200@60Hz CVT */
125+ {209250, 31, 120}, /* QXGA 2048x1536@60Hz CVT */
126+ {268500, 119, 359}, /* WQXGA 2560x1600@60Hz CVT */
127+ {138530, 33, 193}, /* AUO B116HAN03.0 Panel */
128+ {141400, 48, 275}, /* AUO B133HTN01.2 Panel */
129+ },
130+ { /* Link clock = 270MHz, source clock = 675MHz */
131+ {119000, 52, 295}, /* WSXGA+ 1680x1050@60Hz CVT */
132+ {130250, 11, 57}, /* UXGA 1600x1200@60Hz CVT */
133+ {148500, 11, 50}, /* FHD 1920x1080@60Hz */
134+ {154000, 47, 206}, /* WUXGA 1920x1200@60Hz CVT */
135+ {209250, 31, 100}, /* QXGA 2048x1536@60Hz CVT */
136+ {268500, 107, 269}, /* WQXGA 2560x1600@60Hz CVT */
137+ {138530, 63, 307}, /* AUO B116HAN03.0 Panel */
138+ {141400, 53, 253}, /* AUO B133HTN01.2 Panel */
139+ },
140+};
141+
142+static int edp_clk_init(struct edp_ctrl *ctrl)
143+{
144+ struct platform_device *pdev = ctrl->pdev;
145+ int ret;
146+
147+ ctrl->aux_clk = msm_clk_get(pdev, "core");
148+ if (IS_ERR(ctrl->aux_clk)) {
149+ ret = PTR_ERR(ctrl->aux_clk);
150+ pr_err("%s: Can't find core clock, %d\n", __func__, ret);
151+ ctrl->aux_clk = NULL;
152+ return ret;
153+ }
154+
155+ ctrl->pixel_clk = msm_clk_get(pdev, "pixel");
156+ if (IS_ERR(ctrl->pixel_clk)) {
157+ ret = PTR_ERR(ctrl->pixel_clk);
158+ pr_err("%s: Can't find pixel clock, %d\n", __func__, ret);
159+ ctrl->pixel_clk = NULL;
160+ return ret;
161+ }
162+
163+ ctrl->ahb_clk = msm_clk_get(pdev, "iface");
164+ if (IS_ERR(ctrl->ahb_clk)) {
165+ ret = PTR_ERR(ctrl->ahb_clk);
166+ pr_err("%s: Can't find iface clock, %d\n", __func__, ret);
167+ ctrl->ahb_clk = NULL;
168+ return ret;
169+ }
170+
171+ ctrl->link_clk = msm_clk_get(pdev, "link");
172+ if (IS_ERR(ctrl->link_clk)) {
173+ ret = PTR_ERR(ctrl->link_clk);
174+ pr_err("%s: Can't find link clock, %d\n", __func__, ret);
175+ ctrl->link_clk = NULL;
176+ return ret;
177+ }
178+
179+ /* need mdp core clock to receive irq */
180+ ctrl->mdp_core_clk = msm_clk_get(pdev, "mdp_core");
181+ if (IS_ERR(ctrl->mdp_core_clk)) {
182+ ret = PTR_ERR(ctrl->mdp_core_clk);
183+ pr_err("%s: Can't find mdp_core clock, %d\n", __func__, ret);
184+ ctrl->mdp_core_clk = NULL;
185+ return ret;
186+ }
187+
188+ return 0;
189+}
190+
191+static int edp_clk_enable(struct edp_ctrl *ctrl, u32 clk_mask)
192+{
193+ int ret;
194+
195+ DBG("mask=%x", clk_mask);
196+ /* ahb_clk should be enabled first */
197+ if (clk_mask & EDP_CLK_MASK_AHB) {
198+ ret = clk_prepare_enable(ctrl->ahb_clk);
199+ if (ret) {
200+ pr_err("%s: Failed to enable ahb clk\n", __func__);
201+ goto f0;
202+ }
203+ }
204+ if (clk_mask & EDP_CLK_MASK_AUX) {
205+ ret = clk_set_rate(ctrl->aux_clk, 19200000);
206+ if (ret) {
207+ pr_err("%s: Failed to set rate aux clk\n", __func__);
208+ goto f1;
209+ }
210+ ret = clk_prepare_enable(ctrl->aux_clk);
211+ if (ret) {
212+ pr_err("%s: Failed to enable aux clk\n", __func__);
213+ goto f1;
214+ }
215+ }
216+ /* Need to set rate and enable link_clk prior to pixel_clk */
217+ if (clk_mask & EDP_CLK_MASK_LINK) {
218+ DBG("edp->link_clk, set_rate %ld",
219+ (unsigned long)ctrl->link_rate * 27000000);
220+ ret = clk_set_rate(ctrl->link_clk,
221+ (unsigned long)ctrl->link_rate * 27000000);
222+ if (ret) {
223+ pr_err("%s: Failed to set rate to link clk\n",
224+ __func__);
225+ goto f2;
226+ }
227+
228+ ret = clk_prepare_enable(ctrl->link_clk);
229+ if (ret) {
230+ pr_err("%s: Failed to enable link clk\n", __func__);
231+ goto f2;
232+ }
233+ }
234+ if (clk_mask & EDP_CLK_MASK_PIXEL) {
235+ DBG("edp->pixel_clk, set_rate %ld",
236+ (unsigned long)ctrl->pixel_rate * 1000);
237+ ret = clk_set_rate(ctrl->pixel_clk,
238+ (unsigned long)ctrl->pixel_rate * 1000);
239+ if (ret) {
240+ pr_err("%s: Failed to set rate to pixel clk\n",
241+ __func__);
242+ goto f3;
243+ }
244+
245+ ret = clk_prepare_enable(ctrl->pixel_clk);
246+ if (ret) {
247+ pr_err("%s: Failed to enable pixel clk\n", __func__);
248+ goto f3;
249+ }
250+ }
251+ if (clk_mask & EDP_CLK_MASK_MDP_CORE) {
252+ ret = clk_prepare_enable(ctrl->mdp_core_clk);
253+ if (ret) {
254+ pr_err("%s: Failed to enable mdp core clk\n", __func__);
255+ goto f4;
256+ }
257+ }
258+
259+ return 0;
260+
261+f4:
262+ if (clk_mask & EDP_CLK_MASK_PIXEL)
263+ clk_disable_unprepare(ctrl->pixel_clk);
264+f3:
265+ if (clk_mask & EDP_CLK_MASK_LINK)
266+ clk_disable_unprepare(ctrl->link_clk);
267+f2:
268+ if (clk_mask & EDP_CLK_MASK_AUX)
269+ clk_disable_unprepare(ctrl->aux_clk);
270+f1:
271+ if (clk_mask & EDP_CLK_MASK_AHB)
272+ clk_disable_unprepare(ctrl->ahb_clk);
273+f0:
274+ return ret;
275+}
276+
277+static void edp_clk_disable(struct edp_ctrl *ctrl, u32 clk_mask)
278+{
279+ if (clk_mask & EDP_CLK_MASK_MDP_CORE)
280+ clk_disable_unprepare(ctrl->mdp_core_clk);
281+ if (clk_mask & EDP_CLK_MASK_PIXEL)
282+ clk_disable_unprepare(ctrl->pixel_clk);
283+ if (clk_mask & EDP_CLK_MASK_LINK)
284+ clk_disable_unprepare(ctrl->link_clk);
285+ if (clk_mask & EDP_CLK_MASK_AUX)
286+ clk_disable_unprepare(ctrl->aux_clk);
287+ if (clk_mask & EDP_CLK_MASK_AHB)
288+ clk_disable_unprepare(ctrl->ahb_clk);
289+}
290+
291+static int edp_regulator_init(struct edp_ctrl *ctrl)
292+{
293+ struct device *dev = &ctrl->pdev->dev;
294+ int ret;
295+
296+ DBG("");
297+ ctrl->vdda_vreg = devm_regulator_get(dev, "vdda");
298+ ret = PTR_ERR_OR_ZERO(ctrl->vdda_vreg);
299+ if (ret) {
300+ pr_err("%s: Could not get vdda reg, ret = %d\n", __func__,
301+ ret);
302+ ctrl->vdda_vreg = NULL;
303+ return ret;
304+ }
305+ ctrl->lvl_vreg = devm_regulator_get(dev, "lvl-vdd");
306+ ret = PTR_ERR_OR_ZERO(ctrl->lvl_vreg);
307+ if (ret) {
308+ pr_err("%s: Could not get lvl-vdd reg, ret = %d\n", __func__,
309+ ret);
310+ ctrl->lvl_vreg = NULL;
311+ return ret;
312+ }
313+
314+ return 0;
315+}
316+
317+static int edp_regulator_enable(struct edp_ctrl *ctrl)
318+{
319+ int ret;
320+
321+ ret = regulator_set_load(ctrl->vdda_vreg, VDDA_UA_ON_LOAD);
322+ if (ret < 0) {
323+ pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__);
324+ goto vdda_set_fail;
325+ }
326+
327+ ret = regulator_enable(ctrl->vdda_vreg);
328+ if (ret) {
329+ pr_err("%s: Failed to enable vdda_vreg regulator.\n", __func__);
330+ goto vdda_enable_fail;
331+ }
332+
333+ ret = regulator_enable(ctrl->lvl_vreg);
334+ if (ret) {
335+ pr_err("Failed to enable lvl-vdd reg regulator, %d", ret);
336+ goto lvl_enable_fail;
337+ }
338+
339+ DBG("exit");
340+ return 0;
341+
342+lvl_enable_fail:
343+ regulator_disable(ctrl->vdda_vreg);
344+vdda_enable_fail:
345+ regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
346+vdda_set_fail:
347+ return ret;
348+}
349+
350+static void edp_regulator_disable(struct edp_ctrl *ctrl)
351+{
352+ regulator_disable(ctrl->lvl_vreg);
353+ regulator_disable(ctrl->vdda_vreg);
354+ regulator_set_load(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD);
355+}
356+
357+static int edp_gpio_config(struct edp_ctrl *ctrl)
358+{
359+ struct device *dev = &ctrl->pdev->dev;
360+ int ret;
361+
362+ ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd", GPIOD_IN);
363+ if (IS_ERR(ctrl->panel_hpd_gpio)) {
364+ ret = PTR_ERR(ctrl->panel_hpd_gpio);
365+ ctrl->panel_hpd_gpio = NULL;
366+ pr_err("%s: cannot get panel-hpd-gpios, %d\n", __func__, ret);
367+ return ret;
368+ }
369+
370+ ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en", GPIOD_OUT_LOW);
371+ if (IS_ERR(ctrl->panel_en_gpio)) {
372+ ret = PTR_ERR(ctrl->panel_en_gpio);
373+ ctrl->panel_en_gpio = NULL;
374+ pr_err("%s: cannot get panel-en-gpios, %d\n", __func__, ret);
375+ return ret;
376+ }
377+
378+ DBG("gpio on");
379+
380+ return 0;
381+}
382+
383+static void edp_ctrl_irq_enable(struct edp_ctrl *ctrl, int enable)
384+{
385+ unsigned long flags;
386+
387+ DBG("%d", enable);
388+ spin_lock_irqsave(&ctrl->irq_lock, flags);
389+ if (enable) {
390+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, EDP_INTR_MASK1);
391+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, EDP_INTR_MASK2);
392+ } else {
393+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, 0x0);
394+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, 0x0);
395+ }
396+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
397+ DBG("exit");
398+}
399+
400+static void edp_fill_link_cfg(struct edp_ctrl *ctrl)
401+{
402+ u32 prate;
403+ u32 lrate;
404+ u32 bpp;
405+ u8 max_lane = drm_dp_max_lane_count(ctrl->dpcd);
406+ u8 lane;
407+
408+ prate = ctrl->pixel_rate;
409+ bpp = ctrl->color_depth * 3;
410+
411+ /*
412+ * By default, use the maximum link rate and minimum lane count,
413+ * so that we can do rate down shift during link training.
414+ */
415+ ctrl->link_rate = ctrl->dpcd[DP_MAX_LINK_RATE];
416+
417+ prate *= bpp;
418+ prate /= 8; /* in kByte */
419+
420+ lrate = 270000; /* in kHz */
421+ lrate *= ctrl->link_rate;
422+ lrate /= 10; /* in kByte, 10 bits --> 8 bits */
423+
424+ for (lane = 1; lane <= max_lane; lane <<= 1) {
425+ if (lrate >= prate)
426+ break;
427+ lrate <<= 1;
428+ }
429+
430+ ctrl->lane_cnt = lane;
431+ DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt);
432+}
433+
434+static void edp_config_ctrl(struct edp_ctrl *ctrl)
435+{
436+ u32 data;
437+ enum edp_color_depth depth;
438+
439+ data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1);
440+
441+ if (drm_dp_enhanced_frame_cap(ctrl->dpcd))
442+ data |= EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
443+
444+ depth = EDP_6BIT;
445+ if (ctrl->color_depth == 8)
446+ depth = EDP_8BIT;
447+
448+ data |= EDP_CONFIGURATION_CTRL_COLOR(depth);
449+
450+ if (!ctrl->interlaced) /* progressive */
451+ data |= EDP_CONFIGURATION_CTRL_PROGRESSIVE;
452+
453+ data |= (EDP_CONFIGURATION_CTRL_SYNC_CLK |
454+ EDP_CONFIGURATION_CTRL_STATIC_MVID);
455+
456+ edp_write(ctrl->base + REG_EDP_CONFIGURATION_CTRL, data);
457+}
458+
459+static void edp_state_ctrl(struct edp_ctrl *ctrl, u32 state)
460+{
461+ edp_write(ctrl->base + REG_EDP_STATE_CTRL, state);
462+ /* Make sure H/W status is set */
463+ wmb();
464+}
465+
466+static int edp_lane_set_write(struct edp_ctrl *ctrl,
467+ u8 voltage_level, u8 pre_emphasis_level)
468+{
469+ int i;
470+ u8 buf[4];
471+
472+ if (voltage_level >= DPCD_LINK_VOLTAGE_MAX)
473+ voltage_level |= 0x04;
474+
475+ if (pre_emphasis_level >= DPCD_LINK_PRE_EMPHASIS_MAX)
476+ pre_emphasis_level |= 0x04;
477+
478+ pre_emphasis_level <<= 3;
479+
480+ for (i = 0; i < 4; i++)
481+ buf[i] = voltage_level | pre_emphasis_level;
482+
483+ DBG("%s: p|v=0x%x", __func__, voltage_level | pre_emphasis_level);
484+ if (drm_dp_dpcd_write(ctrl->drm_aux, 0x103, buf, 4) < 4) {
485+ pr_err("%s: Set sw/pe to panel failed\n", __func__);
486+ return -ENOLINK;
487+ }
488+
489+ return 0;
490+}
491+
492+static int edp_train_pattern_set_write(struct edp_ctrl *ctrl, u8 pattern)
493+{
494+ u8 p = pattern;
495+
496+ DBG("pattern=%x", p);
497+ if (drm_dp_dpcd_write(ctrl->drm_aux,
498+ DP_TRAINING_PATTERN_SET, &p, 1) < 1) {
499+ pr_err("%s: Set training pattern to panel failed\n", __func__);
500+ return -ENOLINK;
501+ }
502+
503+ return 0;
504+}
505+
506+static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl,
507+ const u8 *link_status)
508+{
509+ int i;
510+ u8 max = 0;
511+ u8 data;
512+
513+ /* use the max level across lanes */
514+ for (i = 0; i < ctrl->lane_cnt; i++) {
515+ data = drm_dp_get_adjust_request_voltage(link_status, i);
516+ DBG("lane=%d req_voltage_swing=0x%x", i, data);
517+ if (max < data)
518+ max = data;
519+ }
520+
521+ ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
522+
523+ /* use the max level across lanes */
524+ max = 0;
525+ for (i = 0; i < ctrl->lane_cnt; i++) {
526+ data = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
527+ DBG("lane=%d req_pre_emphasis=0x%x", i, data);
528+ if (max < data)
529+ max = data;
530+ }
531+
532+ ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
533+ DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level);
534+}
535+
536+static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train)
537+{
538+ int cnt = 10;
539+ u32 data;
540+ u32 shift = train - 1;
541+
542+ DBG("train=%d", train);
543+
544+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift);
545+ while (--cnt) {
546+ data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY);
547+ if (data & (EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY << shift))
548+ break;
549+ }
550+
551+ if (cnt == 0)
552+ pr_err("%s: set link_train=%d failed\n", __func__, train);
553+}
554+
555+static const u8 vm_pre_emphasis[4][4] = {
556+ {0x03, 0x06, 0x09, 0x0C}, /* pe0, 0 db */
557+ {0x03, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */
558+ {0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */
559+ {0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */
560+};
561+
562+/* voltage swing, 0.2v and 1.0v are not support */
563+static const u8 vm_voltage_swing[4][4] = {
564+ {0x14, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */
565+ {0x18, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */
566+ {0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */
567+ {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */
568+};
569+
570+static int edp_voltage_pre_emphasise_set(struct edp_ctrl *ctrl)
571+{
572+ u32 value0;
573+ u32 value1;
574+
575+ DBG("v=%d p=%d", ctrl->v_level, ctrl->p_level);
576+
577+ value0 = vm_pre_emphasis[(int)(ctrl->v_level)][(int)(ctrl->p_level)];
578+ value1 = vm_voltage_swing[(int)(ctrl->v_level)][(int)(ctrl->p_level)];
579+
580+ /* Configure host and panel only if both values are allowed */
581+ if (value0 != 0xFF && value1 != 0xFF) {
582+ msm_edp_phy_vm_pe_cfg(ctrl->phy, value0, value1);
583+ return edp_lane_set_write(ctrl, ctrl->v_level, ctrl->p_level);
584+ }
585+
586+ return -EINVAL;
587+}
588+
589+static int edp_start_link_train_1(struct edp_ctrl *ctrl)
590+{
591+ u8 link_status[DP_LINK_STATUS_SIZE];
592+ u8 old_v_level;
593+ int tries;
594+ int ret;
595+ int rlen;
596+
597+ DBG("");
598+
599+ edp_host_train_set(ctrl, DP_TRAINING_PATTERN_1);
600+ ret = edp_voltage_pre_emphasise_set(ctrl);
601+ if (ret)
602+ return ret;
603+ ret = edp_train_pattern_set_write(ctrl,
604+ DP_TRAINING_PATTERN_1 | DP_RECOVERED_CLOCK_OUT_EN);
605+ if (ret)
606+ return ret;
607+
608+ tries = 0;
609+ old_v_level = ctrl->v_level;
610+ while (1) {
611+ drm_dp_link_train_clock_recovery_delay(ctrl->drm_aux, ctrl->dpcd);
612+
613+ rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status);
614+ if (rlen < DP_LINK_STATUS_SIZE) {
615+ pr_err("%s: read link status failed\n", __func__);
616+ return -ENOLINK;
617+ }
618+ if (drm_dp_clock_recovery_ok(link_status, ctrl->lane_cnt)) {
619+ ret = 0;
620+ break;
621+ }
622+
623+ if (ctrl->v_level == DPCD_LINK_VOLTAGE_MAX) {
624+ ret = -1;
625+ break;
626+ }
627+
628+ if (old_v_level == ctrl->v_level) {
629+ tries++;
630+ if (tries >= 5) {
631+ ret = -1;
632+ break;
633+ }
634+ } else {
635+ tries = 0;
636+ old_v_level = ctrl->v_level;
637+ }
638+
639+ edp_sink_train_set_adjust(ctrl, link_status);
640+ ret = edp_voltage_pre_emphasise_set(ctrl);
641+ if (ret)
642+ return ret;
643+ }
644+
645+ return ret;
646+}
647+
648+static int edp_start_link_train_2(struct edp_ctrl *ctrl)
649+{
650+ u8 link_status[DP_LINK_STATUS_SIZE];
651+ int tries = 0;
652+ int ret;
653+ int rlen;
654+
655+ DBG("");
656+
657+ edp_host_train_set(ctrl, DP_TRAINING_PATTERN_2);
658+ ret = edp_voltage_pre_emphasise_set(ctrl);
659+ if (ret)
660+ return ret;
661+
662+ ret = edp_train_pattern_set_write(ctrl,
663+ DP_TRAINING_PATTERN_2 | DP_RECOVERED_CLOCK_OUT_EN);
664+ if (ret)
665+ return ret;
666+
667+ while (1) {
668+ drm_dp_link_train_channel_eq_delay(ctrl->drm_aux, ctrl->dpcd);
669+
670+ rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status);
671+ if (rlen < DP_LINK_STATUS_SIZE) {
672+ pr_err("%s: read link status failed\n", __func__);
673+ return -ENOLINK;
674+ }
675+ if (drm_dp_channel_eq_ok(link_status, ctrl->lane_cnt)) {
676+ ret = 0;
677+ break;
678+ }
679+
680+ tries++;
681+ if (tries > 10) {
682+ ret = -1;
683+ break;
684+ }
685+
686+ edp_sink_train_set_adjust(ctrl, link_status);
687+ ret = edp_voltage_pre_emphasise_set(ctrl);
688+ if (ret)
689+ return ret;
690+ }
691+
692+ return ret;
693+}
694+
695+static int edp_link_rate_down_shift(struct edp_ctrl *ctrl)
696+{
697+ u32 prate, lrate, bpp;
698+ u8 rate, lane, max_lane;
699+ int changed = 0;
700+
701+ rate = ctrl->link_rate;
702+ lane = ctrl->lane_cnt;
703+ max_lane = drm_dp_max_lane_count(ctrl->dpcd);
704+
705+ bpp = ctrl->color_depth * 3;
706+ prate = ctrl->pixel_rate;
707+ prate *= bpp;
708+ prate /= 8; /* in kByte */
709+
710+ if (rate > DP_LINK_BW_1_62 && rate <= EDP_LINK_BW_MAX) {
711+ rate -= 4; /* reduce rate */
712+ changed++;
713+ }
714+
715+ if (changed) {
716+ if (lane >= 1 && lane < max_lane)
717+ lane <<= 1; /* increase lane */
718+
719+ lrate = 270000; /* in kHz */
720+ lrate *= rate;
721+ lrate /= 10; /* kByte, 10 bits --> 8 bits */
722+ lrate *= lane;
723+
724+ DBG("new lrate=%u prate=%u(kHz) rate=%d lane=%d p=%u b=%d",
725+ lrate, prate, rate, lane,
726+ ctrl->pixel_rate,
727+ bpp);
728+
729+ if (lrate > prate) {
730+ ctrl->link_rate = rate;
731+ ctrl->lane_cnt = lane;
732+ DBG("new rate=%d %d", rate, lane);
733+ return 0;
734+ }
735+ }
736+
737+ return -EINVAL;
738+}
739+
740+static int edp_clear_training_pattern(struct edp_ctrl *ctrl)
741+{
742+ int ret;
743+
744+ ret = edp_train_pattern_set_write(ctrl, 0);
745+
746+ drm_dp_link_train_channel_eq_delay(ctrl->drm_aux, ctrl->dpcd);
747+
748+ return ret;
749+}
750+
751+static int edp_do_link_train(struct edp_ctrl *ctrl)
752+{
753+ u8 values[2];
754+ int ret;
755+
756+ DBG("");
757+ /*
758+ * Set the current link rate and lane cnt to panel. They may have been
759+ * adjusted and the values are different from them in DPCD CAP
760+ */
761+ values[0] = ctrl->lane_cnt;
762+ values[1] = ctrl->link_rate;
763+
764+ if (drm_dp_enhanced_frame_cap(ctrl->dpcd))
765+ values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
766+
767+ if (drm_dp_dpcd_write(ctrl->drm_aux, DP_LINK_BW_SET, values,
768+ sizeof(values)) < 0)
769+ return EDP_TRAIN_FAIL;
770+
771+ ctrl->v_level = 0; /* start from default level */
772+ ctrl->p_level = 0;
773+
774+ edp_state_ctrl(ctrl, 0);
775+ if (edp_clear_training_pattern(ctrl))
776+ return EDP_TRAIN_FAIL;
777+
778+ ret = edp_start_link_train_1(ctrl);
779+ if (ret < 0) {
780+ if (edp_link_rate_down_shift(ctrl) == 0) {
781+ DBG("link reconfig");
782+ ret = EDP_TRAIN_RECONFIG;
783+ goto clear;
784+ } else {
785+ pr_err("%s: Training 1 failed", __func__);
786+ ret = EDP_TRAIN_FAIL;
787+ goto clear;
788+ }
789+ }
790+ DBG("Training 1 completed successfully");
791+
792+ edp_state_ctrl(ctrl, 0);
793+ if (edp_clear_training_pattern(ctrl))
794+ return EDP_TRAIN_FAIL;
795+
796+ ret = edp_start_link_train_2(ctrl);
797+ if (ret < 0) {
798+ if (edp_link_rate_down_shift(ctrl) == 0) {
799+ DBG("link reconfig");
800+ ret = EDP_TRAIN_RECONFIG;
801+ goto clear;
802+ } else {
803+ pr_err("%s: Training 2 failed", __func__);
804+ ret = EDP_TRAIN_FAIL;
805+ goto clear;
806+ }
807+ }
808+ DBG("Training 2 completed successfully");
809+
810+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO);
811+clear:
812+ edp_clear_training_pattern(ctrl);
813+
814+ return ret;
815+}
816+
817+static void edp_clock_synchrous(struct edp_ctrl *ctrl, int sync)
818+{
819+ u32 data;
820+ enum edp_color_depth depth;
821+
822+ data = edp_read(ctrl->base + REG_EDP_MISC1_MISC0);
823+
824+ if (sync)
825+ data |= EDP_MISC1_MISC0_SYNC;
826+ else
827+ data &= ~EDP_MISC1_MISC0_SYNC;
828+
829+ /* only legacy rgb mode supported */
830+ depth = EDP_6BIT; /* Default */
831+ if (ctrl->color_depth == 8)
832+ depth = EDP_8BIT;
833+ else if (ctrl->color_depth == 10)
834+ depth = EDP_10BIT;
835+ else if (ctrl->color_depth == 12)
836+ depth = EDP_12BIT;
837+ else if (ctrl->color_depth == 16)
838+ depth = EDP_16BIT;
839+
840+ data |= EDP_MISC1_MISC0_COLOR(depth);
841+
842+ edp_write(ctrl->base + REG_EDP_MISC1_MISC0, data);
843+}
844+
845+static int edp_sw_mvid_nvid(struct edp_ctrl *ctrl, u32 m, u32 n)
846+{
847+ u32 n_multi, m_multi = 5;
848+
849+ if (ctrl->link_rate == DP_LINK_BW_1_62) {
850+ n_multi = 1;
851+ } else if (ctrl->link_rate == DP_LINK_BW_2_7) {
852+ n_multi = 2;
853+ } else {
854+ pr_err("%s: Invalid link rate, %d\n", __func__,
855+ ctrl->link_rate);
856+ return -EINVAL;
857+ }
858+
859+ edp_write(ctrl->base + REG_EDP_SOFTWARE_MVID, m * m_multi);
860+ edp_write(ctrl->base + REG_EDP_SOFTWARE_NVID, n * n_multi);
861+
862+ return 0;
863+}
864+
865+static void edp_mainlink_ctrl(struct edp_ctrl *ctrl, int enable)
866+{
867+ u32 data = 0;
868+
869+ edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, EDP_MAINLINK_CTRL_RESET);
870+ /* Make sure fully reset */
871+ wmb();
872+ usleep_range(500, 1000);
873+
874+ if (enable)
875+ data |= EDP_MAINLINK_CTRL_ENABLE;
876+
877+ edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, data);
878+}
879+
880+static void edp_ctrl_phy_aux_enable(struct edp_ctrl *ctrl, int enable)
881+{
882+ if (enable) {
883+ edp_regulator_enable(ctrl);
884+ edp_clk_enable(ctrl, EDP_CLK_MASK_AUX_CHAN);
885+ msm_edp_phy_ctrl(ctrl->phy, 1);
886+ msm_edp_aux_ctrl(ctrl->aux, 1);
887+ gpiod_set_value(ctrl->panel_en_gpio, 1);
888+ } else {
889+ gpiod_set_value(ctrl->panel_en_gpio, 0);
890+ msm_edp_aux_ctrl(ctrl->aux, 0);
891+ msm_edp_phy_ctrl(ctrl->phy, 0);
892+ edp_clk_disable(ctrl, EDP_CLK_MASK_AUX_CHAN);
893+ edp_regulator_disable(ctrl);
894+ }
895+}
896+
897+static void edp_ctrl_link_enable(struct edp_ctrl *ctrl, int enable)
898+{
899+ u32 m, n;
900+
901+ if (enable) {
902+ /* Enable link channel clocks */
903+ edp_clk_enable(ctrl, EDP_CLK_MASK_LINK_CHAN);
904+
905+ msm_edp_phy_lane_power_ctrl(ctrl->phy, true, ctrl->lane_cnt);
906+
907+ msm_edp_phy_vm_pe_init(ctrl->phy);
908+
909+ /* Make sure phy is programed */
910+ wmb();
911+ msm_edp_phy_ready(ctrl->phy);
912+
913+ edp_config_ctrl(ctrl);
914+ msm_edp_ctrl_pixel_clock_valid(ctrl, ctrl->pixel_rate, &m, &n);
915+ edp_sw_mvid_nvid(ctrl, m, n);
916+ edp_mainlink_ctrl(ctrl, 1);
917+ } else {
918+ edp_mainlink_ctrl(ctrl, 0);
919+
920+ msm_edp_phy_lane_power_ctrl(ctrl->phy, false, 0);
921+ edp_clk_disable(ctrl, EDP_CLK_MASK_LINK_CHAN);
922+ }
923+}
924+
925+static int edp_ctrl_training(struct edp_ctrl *ctrl)
926+{
927+ int ret;
928+
929+ /* Do link training only when power is on */
930+ if (!ctrl->power_on)
931+ return -EINVAL;
932+
933+train_start:
934+ ret = edp_do_link_train(ctrl);
935+ if (ret == EDP_TRAIN_RECONFIG) {
936+ /* Re-configure main link */
937+ edp_ctrl_irq_enable(ctrl, 0);
938+ edp_ctrl_link_enable(ctrl, 0);
939+ msm_edp_phy_ctrl(ctrl->phy, 0);
940+
941+ /* Make sure link is fully disabled */
942+ wmb();
943+ usleep_range(500, 1000);
944+
945+ msm_edp_phy_ctrl(ctrl->phy, 1);
946+ edp_ctrl_link_enable(ctrl, 1);
947+ edp_ctrl_irq_enable(ctrl, 1);
948+ goto train_start;
949+ }
950+
951+ return ret;
952+}
953+
954+static void edp_ctrl_on_worker(struct work_struct *work)
955+{
956+ struct edp_ctrl *ctrl = container_of(
957+ work, struct edp_ctrl, on_work);
958+ u8 value;
959+ int ret;
960+
961+ mutex_lock(&ctrl->dev_mutex);
962+
963+ if (ctrl->power_on) {
964+ DBG("already on");
965+ goto unlock_ret;
966+ }
967+
968+ edp_ctrl_phy_aux_enable(ctrl, 1);
969+ edp_ctrl_link_enable(ctrl, 1);
970+
971+ edp_ctrl_irq_enable(ctrl, 1);
972+
973+ /* DP_SET_POWER register is only available on DPCD v1.1 and later */
974+ if (ctrl->dpcd[DP_DPCD_REV] >= 0x11) {
975+ ret = drm_dp_dpcd_readb(ctrl->drm_aux, DP_SET_POWER, &value);
976+ if (ret < 0)
977+ goto fail;
978+
979+ value &= ~DP_SET_POWER_MASK;
980+ value |= DP_SET_POWER_D0;
981+
982+ ret = drm_dp_dpcd_writeb(ctrl->drm_aux, DP_SET_POWER, value);
983+ if (ret < 0)
984+ goto fail;
985+
986+ /*
987+ * According to the DP 1.1 specification, a "Sink Device must
988+ * exit the power saving state within 1 ms" (Section 2.5.3.1,
989+ * Table 5-52, "Sink Control Field" (register 0x600).
990+ */
991+ usleep_range(1000, 2000);
992+ }
993+
994+ ctrl->power_on = true;
995+
996+ /* Start link training */
997+ ret = edp_ctrl_training(ctrl);
998+ if (ret != EDP_TRAIN_SUCCESS)
999+ goto fail;
1000+
1001+ DBG("DONE");
1002+ goto unlock_ret;
1003+
1004+fail:
1005+ edp_ctrl_irq_enable(ctrl, 0);
1006+ edp_ctrl_link_enable(ctrl, 0);
1007+ edp_ctrl_phy_aux_enable(ctrl, 0);
1008+ ctrl->power_on = false;
1009+unlock_ret:
1010+ mutex_unlock(&ctrl->dev_mutex);
1011+}
1012+
1013+static void edp_ctrl_off_worker(struct work_struct *work)
1014+{
1015+ struct edp_ctrl *ctrl = container_of(
1016+ work, struct edp_ctrl, off_work);
1017+ unsigned long time_left;
1018+
1019+ mutex_lock(&ctrl->dev_mutex);
1020+
1021+ if (!ctrl->power_on) {
1022+ DBG("already off");
1023+ goto unlock_ret;
1024+ }
1025+
1026+ reinit_completion(&ctrl->idle_comp);
1027+ edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE);
1028+
1029+ time_left = wait_for_completion_timeout(&ctrl->idle_comp,
1030+ msecs_to_jiffies(500));
1031+ if (!time_left)
1032+ DBG("%s: idle pattern timedout\n", __func__);
1033+
1034+ edp_state_ctrl(ctrl, 0);
1035+
1036+ /* DP_SET_POWER register is only available on DPCD v1.1 and later */
1037+ if (ctrl->dpcd[DP_DPCD_REV] >= 0x11) {
1038+ u8 value;
1039+ int ret;
1040+
1041+ ret = drm_dp_dpcd_readb(ctrl->drm_aux, DP_SET_POWER, &value);
1042+ if (ret > 0) {
1043+ value &= ~DP_SET_POWER_MASK;
1044+ value |= DP_SET_POWER_D3;
1045+
1046+ drm_dp_dpcd_writeb(ctrl->drm_aux, DP_SET_POWER, value);
1047+ }
1048+ }
1049+
1050+ edp_ctrl_irq_enable(ctrl, 0);
1051+
1052+ edp_ctrl_link_enable(ctrl, 0);
1053+
1054+ edp_ctrl_phy_aux_enable(ctrl, 0);
1055+
1056+ ctrl->power_on = false;
1057+
1058+unlock_ret:
1059+ mutex_unlock(&ctrl->dev_mutex);
1060+}
1061+
1062+irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl)
1063+{
1064+ u32 isr1, isr2, mask1, mask2;
1065+ u32 ack;
1066+
1067+ DBG("");
1068+ spin_lock(&ctrl->irq_lock);
1069+ isr1 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_1);
1070+ isr2 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_2);
1071+
1072+ mask1 = isr1 & EDP_INTR_MASK1;
1073+ mask2 = isr2 & EDP_INTR_MASK2;
1074+
1075+ isr1 &= ~mask1; /* remove masks bit */
1076+ isr2 &= ~mask2;
1077+
1078+ DBG("isr=%x mask=%x isr2=%x mask2=%x",
1079+ isr1, mask1, isr2, mask2);
1080+
1081+ ack = isr1 & EDP_INTR_STATUS1;
1082+ ack <<= 1; /* ack bits */
1083+ ack |= mask1;
1084+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, ack);
1085+
1086+ ack = isr2 & EDP_INTR_STATUS2;
1087+ ack <<= 1; /* ack bits */
1088+ ack |= mask2;
1089+ edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, ack);
1090+ spin_unlock(&ctrl->irq_lock);
1091+
1092+ if (isr1 & EDP_INTERRUPT_REG_1_HPD)
1093+ DBG("edp_hpd");
1094+
1095+ if (isr2 & EDP_INTERRUPT_REG_2_READY_FOR_VIDEO)
1096+ DBG("edp_video_ready");
1097+
1098+ if (isr2 & EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT) {
1099+ DBG("idle_patterns_sent");
1100+ complete(&ctrl->idle_comp);
1101+ }
1102+
1103+ msm_edp_aux_irq(ctrl->aux, isr1);
1104+
1105+ return IRQ_HANDLED;
1106+}
1107+
1108+void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on)
1109+{
1110+ if (on)
1111+ queue_work(ctrl->workqueue, &ctrl->on_work);
1112+ else
1113+ queue_work(ctrl->workqueue, &ctrl->off_work);
1114+}
1115+
1116+int msm_edp_ctrl_init(struct msm_edp *edp)
1117+{
1118+ struct edp_ctrl *ctrl = NULL;
1119+ struct device *dev;
1120+ int ret;
1121+
1122+ if (!edp) {
1123+ pr_err("%s: edp is NULL!\n", __func__);
1124+ return -EINVAL;
1125+ }
1126+
1127+ dev = &edp->pdev->dev;
1128+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
1129+ if (!ctrl)
1130+ return -ENOMEM;
1131+
1132+ edp->ctrl = ctrl;
1133+ ctrl->pdev = edp->pdev;
1134+
1135+ ctrl->base = msm_ioremap(ctrl->pdev, "edp", "eDP");
1136+ if (IS_ERR(ctrl->base))
1137+ return PTR_ERR(ctrl->base);
1138+
1139+ /* Get regulator, clock, gpio, pwm */
1140+ ret = edp_regulator_init(ctrl);
1141+ if (ret) {
1142+ pr_err("%s:regulator init fail\n", __func__);
1143+ return ret;
1144+ }
1145+ ret = edp_clk_init(ctrl);
1146+ if (ret) {
1147+ pr_err("%s:clk init fail\n", __func__);
1148+ return ret;
1149+ }
1150+ ret = edp_gpio_config(ctrl);
1151+ if (ret) {
1152+ pr_err("%s:failed to configure GPIOs: %d", __func__, ret);
1153+ return ret;
1154+ }
1155+
1156+ /* Init aux and phy */
1157+ ctrl->aux = msm_edp_aux_init(edp, ctrl->base, &ctrl->drm_aux);
1158+ if (!ctrl->aux || !ctrl->drm_aux) {
1159+ pr_err("%s:failed to init aux\n", __func__);
1160+ return -ENOMEM;
1161+ }
1162+
1163+ ctrl->phy = msm_edp_phy_init(dev, ctrl->base);
1164+ if (!ctrl->phy) {
1165+ pr_err("%s:failed to init phy\n", __func__);
1166+ ret = -ENOMEM;
1167+ goto err_destory_aux;
1168+ }
1169+
1170+ spin_lock_init(&ctrl->irq_lock);
1171+ mutex_init(&ctrl->dev_mutex);
1172+ init_completion(&ctrl->idle_comp);
1173+
1174+ /* setup workqueue */
1175+ ctrl->workqueue = alloc_ordered_workqueue("edp_drm_work", 0);
1176+ INIT_WORK(&ctrl->on_work, edp_ctrl_on_worker);
1177+ INIT_WORK(&ctrl->off_work, edp_ctrl_off_worker);
1178+
1179+ return 0;
1180+
1181+err_destory_aux:
1182+ msm_edp_aux_destroy(dev, ctrl->aux);
1183+ ctrl->aux = NULL;
1184+ return ret;
1185+}
1186+
1187+void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl)
1188+{
1189+ if (!ctrl)
1190+ return;
1191+
1192+ if (ctrl->workqueue) {
1193+ destroy_workqueue(ctrl->workqueue);
1194+ ctrl->workqueue = NULL;
1195+ }
1196+
1197+ if (ctrl->aux) {
1198+ msm_edp_aux_destroy(&ctrl->pdev->dev, ctrl->aux);
1199+ ctrl->aux = NULL;
1200+ }
1201+
1202+ kfree(ctrl->edid);
1203+ ctrl->edid = NULL;
1204+
1205+ mutex_destroy(&ctrl->dev_mutex);
1206+}
1207+
1208+bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl)
1209+{
1210+ mutex_lock(&ctrl->dev_mutex);
1211+ DBG("connect status = %d", ctrl->edp_connected);
1212+ if (ctrl->edp_connected) {
1213+ mutex_unlock(&ctrl->dev_mutex);
1214+ return true;
1215+ }
1216+
1217+ if (!ctrl->power_on) {
1218+ edp_ctrl_phy_aux_enable(ctrl, 1);
1219+ edp_ctrl_irq_enable(ctrl, 1);
1220+ }
1221+
1222+ if (drm_dp_dpcd_read(ctrl->drm_aux, DP_DPCD_REV, ctrl->dpcd,
1223+ DP_RECEIVER_CAP_SIZE) < DP_RECEIVER_CAP_SIZE) {
1224+ pr_err("%s: AUX channel is NOT ready\n", __func__);
1225+ memset(ctrl->dpcd, 0, DP_RECEIVER_CAP_SIZE);
1226+ } else {
1227+ ctrl->edp_connected = true;
1228+ }
1229+
1230+ if (!ctrl->power_on) {
1231+ edp_ctrl_irq_enable(ctrl, 0);
1232+ edp_ctrl_phy_aux_enable(ctrl, 0);
1233+ }
1234+
1235+ DBG("exit: connect status=%d", ctrl->edp_connected);
1236+
1237+ mutex_unlock(&ctrl->dev_mutex);
1238+
1239+ return ctrl->edp_connected;
1240+}
1241+
1242+int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl,
1243+ struct drm_connector *connector, struct edid **edid)
1244+{
1245+ mutex_lock(&ctrl->dev_mutex);
1246+
1247+ if (ctrl->edid) {
1248+ if (edid) {
1249+ DBG("Just return edid buffer");
1250+ *edid = ctrl->edid;
1251+ }
1252+ goto unlock_ret;
1253+ }
1254+
1255+ if (!ctrl->power_on) {
1256+ edp_ctrl_phy_aux_enable(ctrl, 1);
1257+ edp_ctrl_irq_enable(ctrl, 1);
1258+ }
1259+
1260+ /* Initialize link rate as panel max link rate */
1261+ ctrl->link_rate = ctrl->dpcd[DP_MAX_LINK_RATE];
1262+
1263+ ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc);
1264+ if (!ctrl->edid) {
1265+ pr_err("%s: edid read fail\n", __func__);
1266+ goto disable_ret;
1267+ }
1268+
1269+ if (edid)
1270+ *edid = ctrl->edid;
1271+
1272+disable_ret:
1273+ if (!ctrl->power_on) {
1274+ edp_ctrl_irq_enable(ctrl, 0);
1275+ edp_ctrl_phy_aux_enable(ctrl, 0);
1276+ }
1277+unlock_ret:
1278+ mutex_unlock(&ctrl->dev_mutex);
1279+ return 0;
1280+}
1281+
1282+int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl,
1283+ const struct drm_display_mode *mode,
1284+ const struct drm_display_info *info)
1285+{
1286+ u32 hstart_from_sync, vstart_from_sync;
1287+ u32 data;
1288+ int ret = 0;
1289+
1290+ mutex_lock(&ctrl->dev_mutex);
1291+ /*
1292+ * Need to keep color depth, pixel rate and
1293+ * interlaced information in ctrl context
1294+ */
1295+ ctrl->color_depth = info->bpc;
1296+ ctrl->pixel_rate = mode->clock;
1297+ ctrl->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1298+
1299+ /* Fill initial link config based on passed in timing */
1300+ edp_fill_link_cfg(ctrl);
1301+
1302+ if (edp_clk_enable(ctrl, EDP_CLK_MASK_AHB)) {
1303+ pr_err("%s, fail to prepare enable ahb clk\n", __func__);
1304+ ret = -EINVAL;
1305+ goto unlock_ret;
1306+ }
1307+ edp_clock_synchrous(ctrl, 1);
1308+
1309+ /* Configure eDP timing to HW */
1310+ edp_write(ctrl->base + REG_EDP_TOTAL_HOR_VER,
1311+ EDP_TOTAL_HOR_VER_HORIZ(mode->htotal) |
1312+ EDP_TOTAL_HOR_VER_VERT(mode->vtotal));
1313+
1314+ vstart_from_sync = mode->vtotal - mode->vsync_start;
1315+ hstart_from_sync = mode->htotal - mode->hsync_start;
1316+ edp_write(ctrl->base + REG_EDP_START_HOR_VER_FROM_SYNC,
1317+ EDP_START_HOR_VER_FROM_SYNC_HORIZ(hstart_from_sync) |
1318+ EDP_START_HOR_VER_FROM_SYNC_VERT(vstart_from_sync));
1319+
1320+ data = EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT(
1321+ mode->vsync_end - mode->vsync_start);
1322+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ(
1323+ mode->hsync_end - mode->hsync_start);
1324+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1325+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NVSYNC;
1326+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1327+ data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NHSYNC;
1328+ edp_write(ctrl->base + REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY, data);
1329+
1330+ edp_write(ctrl->base + REG_EDP_ACTIVE_HOR_VER,
1331+ EDP_ACTIVE_HOR_VER_HORIZ(mode->hdisplay) |
1332+ EDP_ACTIVE_HOR_VER_VERT(mode->vdisplay));
1333+
1334+ edp_clk_disable(ctrl, EDP_CLK_MASK_AHB);
1335+
1336+unlock_ret:
1337+ mutex_unlock(&ctrl->dev_mutex);
1338+ return ret;
1339+}
1340+
1341+bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl,
1342+ u32 pixel_rate, u32 *pm, u32 *pn)
1343+{
1344+ const struct edp_pixel_clk_div *divs;
1345+ u32 err = 1; /* 1% error tolerance */
1346+ u32 clk_err;
1347+ int i;
1348+
1349+ if (ctrl->link_rate == DP_LINK_BW_1_62) {
1350+ divs = clk_divs[0];
1351+ } else if (ctrl->link_rate == DP_LINK_BW_2_7) {
1352+ divs = clk_divs[1];
1353+ } else {
1354+ pr_err("%s: Invalid link rate,%d\n", __func__, ctrl->link_rate);
1355+ return false;
1356+ }
1357+
1358+ for (i = 0; i < EDP_PIXEL_CLK_NUM; i++) {
1359+ clk_err = abs(divs[i].rate - pixel_rate);
1360+ if ((divs[i].rate * err / 100) >= clk_err) {
1361+ if (pm)
1362+ *pm = divs[i].m;
1363+ if (pn)
1364+ *pn = divs[i].n;
1365+ return true;
1366+ }
1367+ }
1368+
1369+ DBG("pixel clock %d(kHz) not supported", pixel_rate);
1370+
1371+ return false;
1372+}
1373+
drivers/gpu/drm/mxsfb/mxsfb_drv.c+9−0
@@ -374,12 +374,20 @@ static int mxsfb_remove(struct platform_device *pdev) · 373 unmodified lines
374374 struct drm_device *drm = platform_get_drvdata(pdev);
375375
376376 drm_dev_unregister(drm);
377+ drm_atomic_helper_shutdown(drm);
377378 mxsfb_unload(drm);
378379 drm_dev_put(drm);
379380
380381 return 0;
381382 }
382383
384+static void mxsfb_shutdown(struct platform_device *pdev)
385+{
386+ struct drm_device *drm = platform_get_drvdata(pdev);
387+
388+ drm_atomic_helper_shutdown(drm);
389+}
390+
383391 #ifdef CONFIG_PM_SLEEP
384392 static int mxsfb_suspend(struct device *dev)
385393 {
@@ -403,6 +411,7 @@ static const struct dev_pm_ops mxsfb_pm_ops = { · 17 unmodified lines
403411 static struct platform_driver mxsfb_platform_driver = {
404412 .probe = mxsfb_probe,
405413 .remove = mxsfb_remove,
414+ .shutdown = mxsfb_shutdown,
406415 .driver = {
407416 .name = "mxsfb",
408417 .of_match_table = mxsfb_dt_ids,
drivers/gpu/drm/nouveau/Kconfig+1−0
@@ -4,6 +4,7 @@ config DRM_NOUVEAU · 3 unmodified lines
44 depends on DRM && PCI && MMU
55 select IOMMU_API
66 select FW_LOADER
7+ select DRM_DP_HELPER
78 select DRM_KMS_HELPER
89 select DRM_TTM
910 select DRM_TTM_HELPER
drivers/gpu/drm/nouveau/dispnv50/disp.c+1−1
@@ -35,7 +35,7 @@ · 34 unmodified lines
3535
3636 #include <drm/drm_atomic.h>
3737 #include <drm/drm_atomic_helper.h>
38−#include <drm/drm_dp_helper.h>
38+#include <drm/dp/drm_dp_helper.h>
3939 #include <drm/drm_edid.h>
4040 #include <drm/drm_fb_helper.h>
4141 #include <drm/drm_plane_helper.h>
drivers/gpu/drm/nouveau/nouveau_connector.h+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
3636 #include <drm/drm_crtc.h>
3737 #include <drm/drm_edid.h>
3838 #include <drm/drm_encoder.h>
39−#include <drm/drm_dp_helper.h>
39+#include <drm/dp/drm_dp_helper.h>
4040 #include <drm/drm_util.h>
4141
4242 #include "nouveau_crtc.h"
drivers/gpu/drm/nouveau/nouveau_dp.c+16−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 * Authors: Ben Skeggs
2323 */
2424
25−#include <drm/drm_dp_helper.h>
25+#include <drm/dp/drm_dp_helper.h>
2626
2727 #include "nouveau_drv.h"
2828 #include "nouveau_connector.h"
@@ -147,6 +147,21 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector, · 118 unmodified lines
147147 nv_encoder->dp.link_nr =
148148 dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
149149
150+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && dpcd[DP_DPCD_REV] >= 0x13) {
151+ struct drm_dp_aux *aux = &nv_connector->aux;
152+ int ret, i;
153+ u8 sink_rates[16];
154+
155+ ret = drm_dp_dpcd_read(aux, DP_SUPPORTED_LINK_RATES, sink_rates, sizeof(sink_rates));
156+ if (ret == sizeof(sink_rates)) {
157+ for (i = 0; i < ARRAY_SIZE(sink_rates); i += 2) {
158+ int val = ((sink_rates[i + 1] << 8) | sink_rates[i]) * 200 / 10;
159+ if (val && (i == 0 || val > nv_encoder->dp.link_bw))
160+ nv_encoder->dp.link_bw = val;
161+ }
162+ }
163+ }
164+
150165 NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n",
151166 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw,
152167 dpcd[DP_DPCD_REV]);
drivers/gpu/drm/nouveau/nouveau_encoder.h+2−2
@@ -30,8 +30,8 @@ · 29 unmodified lines
3030 #include <subdev/bios/dcb.h>
3131
3232 #include <drm/drm_encoder_slave.h>
33−#include <drm/drm_dp_helper.h>
34−#include <drm/drm_dp_mst_helper.h>
33+#include <drm/dp/drm_dp_helper.h>
34+#include <drm/dp/drm_dp_mst_helper.h>
3535 #include "dispnv04/disp.h"
3636 struct nv50_head_atom;
3737 struct nouveau_connector;
drivers/gpu/drm/nouveau/nouveau_mem.c+2−1
@@ -162,11 +162,12 @@ nouveau_mem_vram(struct ttm_resource *reg, bool contig, u8 page) · 161 unmodified lines
162162 }
163163
164164 void
165−nouveau_mem_del(struct ttm_resource *reg)
165+nouveau_mem_del(struct ttm_resource_manager *man, struct ttm_resource *reg)
166166 {
167167 struct nouveau_mem *mem = nouveau_mem(reg);
168168
169169 nouveau_mem_fini(mem);
170+ ttm_resource_fini(man, reg);
170171 kfree(mem);
171172 }
172173
drivers/gpu/drm/nouveau/nouveau_mem.h+2−1
@@ -23,7 +23,8 @@ nouveau_mem(struct ttm_resource *reg) · 22 unmodified lines
2323
2424 int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
2525 struct ttm_resource **);
26−void nouveau_mem_del(struct ttm_resource *);
26+void nouveau_mem_del(struct ttm_resource_manager *man,
27+ struct ttm_resource *);
2728 int nouveau_mem_vram(struct ttm_resource *, bool contig, u8 page);
2829 int nouveau_mem_host(struct ttm_resource *, struct ttm_tt *);
2930 void nouveau_mem_fini(struct nouveau_mem *);
drivers/gpu/drm/nouveau/nouveau_ttm.c+7−6
@@ -36,9 +36,10 @@ · 35 unmodified lines
3636 #include <core/tegra.h>
3737
3838 static void
39−nouveau_manager_del(struct ttm_resource_manager *man, struct ttm_resource *reg)
39+nouveau_manager_del(struct ttm_resource_manager *man,
40+ struct ttm_resource *reg)
4041 {
41− nouveau_mem_del(reg);
42+ nouveau_mem_del(man, reg);
4243 }
4344
4445 static int
@@ -62,7 +63,7 @@ nouveau_vram_manager_new(struct ttm_resource_manager *man, · 17 unmodified lines
6263
6364 ret = nouveau_mem_vram(*res, nvbo->contig, nvbo->page);
6465 if (ret) {
65− nouveau_mem_del(*res);
66+ nouveau_mem_del(man, *res);
6667 return ret;
6768 }
6869
@@ -118,7 +119,7 @@ nv04_gart_manager_new(struct ttm_resource_manager *man, · 49 unmodified lines
118119 ret = nvif_vmm_get(&mem->cli->vmm.vmm, PTES, false, 12, 0,
119120 (long)(*res)->num_pages << PAGE_SHIFT, &mem->vma[0]);
120121 if (ret) {
121− nouveau_mem_del(*res);
122+ nouveau_mem_del(man, *res);
122123 return ret;
123124 }
124125
@@ -163,7 +164,7 @@ nouveau_ttm_init_vram(struct nouveau_drm *drm) · 38 unmodified lines
163164
164165 man->func = &nouveau_vram_manager;
165166
166− ttm_resource_manager_init(man,
167+ ttm_resource_manager_init(man, &drm->ttm.bdev,
167168 drm->gem.vram_available >> PAGE_SHIFT);
168169 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, man);
169170 ttm_resource_manager_set_used(man, true);
@@ -210,7 +211,7 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm) · 40 unmodified lines
210211
211212 man->func = func;
212213 man->use_tt = true;
213− ttm_resource_manager_init(man, size_pages);
214+ ttm_resource_manager_init(man, &drm->ttm.bdev, size_pages);
214215 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, man);
215216 ttm_resource_manager_set_used(man, true);
216217 return 0;
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c+224−93
@@ -41,6 +41,10 @@ · 40 unmodified lines
4141
4242 struct lt_state {
4343 struct nvkm_dp *dp;
44+
45+ int repeaters;
46+ int repeater;
47+
4448 u8 stat[6];
4549 u8 conf[4];
4650 bool pc2;
@@ -52,14 +56,26 @@ static int · 5 unmodified lines
5256 nvkm_dp_train_sense(struct lt_state *lt, bool pc, u32 delay)
5357 {
5458 struct nvkm_dp *dp = lt->dp;
59+ u32 addr;
5560 int ret;
5661
57− if (dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL])
58− mdelay(dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL] * 4);
62+ usleep_range(delay, delay * 2);
63+
64+ if (lt->repeater)
65+ addr = DPCD_LTTPR_LANE0_1_STATUS(lt->repeater);
66+ else
67+ addr = DPCD_LS02;
68+
69+ ret = nvkm_rdaux(dp->aux, addr, &lt->stat[0], 3);
70+ if (ret)
71+ return ret;
72+
73+ if (lt->repeater)
74+ addr = DPCD_LTTPR_LANE0_1_ADJUST(lt->repeater);
5975 else
60− udelay(delay);
76+ addr = DPCD_LS06;
6177
62− ret = nvkm_rdaux(dp->aux, DPCD_LS02, lt->stat, 6);
78+ ret = nvkm_rdaux(dp->aux, addr, &lt->stat[4], 2);
6379 if (ret)
6480 return ret;
6581
@@ -85,6 +101,7 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc) · 19 unmodified lines
85101 struct nvbios_dpout info;
86102 struct nvbios_dpcfg ocfg;
87103 u8 ver, hdr, cnt, len;
104+ u32 addr;
88105 u32 data;
89106 int ret, i;
90107
@@ -113,6 +130,9 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc) · 22 unmodified lines
113130 OUTP_TRACE(&dp->outp, "config lane %d %02x %02x",
114131 i, lt->conf[i], lpc2);
115132
133+ if (lt->repeater != lt->repeaters)
134+ continue;
135+
116136 data = nvbios_dpout_match(bios, dp->outp.info.hasht,
117137 dp->outp.info.hashm,
118138 &ver, &hdr, &cnt, &len, &info);
@@ -129,7 +149,12 @@ nvkm_dp_train_drive(struct lt_state *lt, bool pc) · 10 unmodified lines
129149 ocfg.pe, ocfg.tx_pu);
130150 }
131151
132− ret = nvkm_wraux(dp->aux, DPCD_LC03(0), lt->conf, 4);
152+ if (lt->repeater)
153+ addr = DPCD_LTTPR_LANE0_SET(lt->repeater);
154+ else
155+ addr = DPCD_LC03(0);
156+
157+ ret = nvkm_wraux(dp->aux, addr, lt->conf, 4);
133158 if (ret)
134159 return ret;
135160
@@ -146,32 +171,59 @@ static void · 10 unmodified lines
146171 nvkm_dp_train_pattern(struct lt_state *lt, u8 pattern)
147172 {
148173 struct nvkm_dp *dp = lt->dp;
174+ u32 addr;
149175 u8 sink_tp;
150176
151177 OUTP_TRACE(&dp->outp, "training pattern %d", pattern);
152178 dp->outp.ior->func->dp.pattern(dp->outp.ior, pattern);
153179
154− nvkm_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1);
180+ if (lt->repeater)
181+ addr = DPCD_LTTPR_PATTERN_SET(lt->repeater);
182+ else
183+ addr = DPCD_LC02;
184+
185+ nvkm_rdaux(dp->aux, addr, &sink_tp, 1);
155186 sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET;
156− sink_tp |= pattern;
157− nvkm_wraux(dp->aux, DPCD_LC02, &sink_tp, 1);
187+ sink_tp |= (pattern != 4) ? pattern : 7;
188+
189+ if (pattern != 0)
190+ sink_tp |= DPCD_LC02_SCRAMBLING_DISABLE;
191+ else
192+ sink_tp &= ~DPCD_LC02_SCRAMBLING_DISABLE;
193+ nvkm_wraux(dp->aux, addr, &sink_tp, 1);
158194 }
159195
160196 static int
161197 nvkm_dp_train_eq(struct lt_state *lt)
162198 {
199+ struct nvkm_i2c_aux *aux = lt->dp->aux;
163200 bool eq_done = false, cr_done = true;
164− int tries = 0, i;
201+ int tries = 0, usec = 0, i;
202+ u8 data;
165203
166− if (lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
167− nvkm_dp_train_pattern(lt, 3);
168− else
169− nvkm_dp_train_pattern(lt, 2);
204+ if (lt->repeater) {
205+ if (!nvkm_rdaux(aux, DPCD_LTTPR_AUX_RD_INTERVAL(lt->repeater), &data, sizeof(data)))
206+ usec = (data & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
207+
208+ nvkm_dp_train_pattern(lt, 4);
209+ } else {
210+ if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x14 &&
211+ lt->dp->dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED)
212+ nvkm_dp_train_pattern(lt, 4);
213+ else
214+ if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] >= 0x12 &&
215+ lt->dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED)
216+ nvkm_dp_train_pattern(lt, 3);
217+ else
218+ nvkm_dp_train_pattern(lt, 2);
219+
220+ usec = (lt->dp->dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
221+ }
170222
171223 do {
172224 if ((tries &&
173225 nvkm_dp_train_drive(lt, lt->pc2)) ||
174− nvkm_dp_train_sense(lt, lt->pc2, 400))
226+ nvkm_dp_train_sense(lt, lt->pc2, usec ? usec : 400))
175227 break;
176228
177229 eq_done = !!(lt->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE);
@@ -193,13 +245,16 @@ nvkm_dp_train_cr(struct lt_state *lt) · 15 unmodified lines
193245 {
194246 bool cr_done = false, abort = false;
195247 int voltage = lt->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET;
196− int tries = 0, i;
248+ int tries = 0, usec = 0, i;
197249
198250 nvkm_dp_train_pattern(lt, 1);
199251
252+ if (lt->dp->dpcd[DPCD_RC00_DPCD_REV] < 0x14 && !lt->repeater)
253+ usec = (lt->dp->dpcd[DPCD_RC0E] & DPCD_RC0E_AUX_RD_INTERVAL) * 4000;
254+
200255 do {
201256 if (nvkm_dp_train_drive(lt, false) ||
202− nvkm_dp_train_sense(lt, false, 100))
257+ nvkm_dp_train_sense(lt, false, usec ? usec : 100))
203258 break;
204259
205260 cr_done = true;
@@ -223,7 +278,7 @@ nvkm_dp_train_cr(struct lt_state *lt) · 17 unmodified lines
223278 }
224279
225280 static int
226−nvkm_dp_train_links(struct nvkm_dp *dp)
281+nvkm_dp_train_links(struct nvkm_dp *dp, int rate)
227282 {
228283 struct nvkm_ior *ior = dp->outp.ior;
229284 struct nvkm_disp *disp = dp->outp.disp;
@@ -233,13 +288,15 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 3 unmodified lines
233288 .dp = dp,
234289 };
235290 u32 lnkcmp;
236− u8 sink[2];
291+ u8 sink[2], data;
237292 int ret;
238293
239294 OUTP_DBG(&dp->outp, "training %d x %d MB/s",
240295 ior->dp.nr, ior->dp.bw * 27);
241296
242297 /* Intersect misc. capabilities of the OR and sink. */
298+ if (disp->engine.subdev.device->chipset < 0x110)
299+ dp->dpcd[DPCD_RC03] &= ~DPCD_RC03_TPS4_SUPPORTED;
243300 if (disp->engine.subdev.device->chipset < 0xd0)
244301 dp->dpcd[DPCD_RC02] &= ~DPCD_RC02_TPS3_SUPPORTED;
245302 lt.pc2 = dp->dpcd[DPCD_RC02] & DPCD_RC02_TPS3_SUPPORTED;
@@ -287,8 +344,22 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 41 unmodified lines
287344
288345 ior->func->dp.power(ior, ior->dp.nr);
289346
347+ /* Select LTTPR non-transparent mode if we have a valid configuration,
348+ * use transparent mode otherwise.
349+ */
350+ if (dp->lttpr[0] >= 0x14) {
351+ data = DPCD_LTTPR_MODE_TRANSPARENT;
352+ nvkm_wraux(dp->aux, DPCD_LTTPR_MODE, &data, sizeof(data));
353+
354+ if (dp->lttprs) {
355+ data = DPCD_LTTPR_MODE_NON_TRANSPARENT;
356+ nvkm_wraux(dp->aux, DPCD_LTTPR_MODE, &data, sizeof(data));
357+ lt.repeaters = dp->lttprs;
358+ }
359+ }
360+
290361 /* Set desired link configuration on the sink. */
291− sink[0] = ior->dp.bw;
362+ sink[0] = (dp->rate[rate].dpcd < 0) ? ior->dp.bw : 0;
292363 sink[1] = ior->dp.nr;
293364 if (ior->dp.ef)
294365 sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
@@ -297,12 +368,33 @@ nvkm_dp_train_links(struct nvkm_dp *dp) · 2 unmodified lines
297368 if (ret)
298369 return ret;
299370
371+ if (dp->rate[rate].dpcd >= 0) {
372+ ret = nvkm_rdaux(dp->aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
373+ if (ret)
374+ return ret;
375+
376+ sink[0] &= ~DPCD_LC15_LINK_RATE_SET_MASK;
377+ sink[0] |= dp->rate[rate].dpcd;
378+
379+ ret = nvkm_wraux(dp->aux, DPCD_LC15_LINK_RATE_SET, &sink[0], sizeof(sink[0]));
380+ if (ret)
381+ return ret;
382+ }
383+
300384 /* Attempt to train the link in this configuration. */
301− memset(lt.stat, 0x00, sizeof(lt.stat));
302− ret = nvkm_dp_train_cr(&lt);
303− if (ret == 0)
304− ret = nvkm_dp_train_eq(&lt);
305− nvkm_dp_train_pattern(&lt, 0);
385+ for (lt.repeater = lt.repeaters; lt.repeater >= 0; lt.repeater--) {
386+ if (lt.repeater)
387+ OUTP_DBG(&dp->outp, "training LTTPR%d", lt.repeater);
388+ else
389+ OUTP_DBG(&dp->outp, "training sink");
390+
391+ memset(lt.stat, 0x00, sizeof(lt.stat));
392+ ret = nvkm_dp_train_cr(&lt);
393+ if (ret == 0)
394+ ret = nvkm_dp_train_eq(&lt);
395+ nvkm_dp_train_pattern(&lt, 0);
396+ }
397+
306398 return ret;
307399 }
308400
@@ -345,63 +437,13 @@ nvkm_dp_train_init(struct nvkm_dp *dp) · 36 unmodified lines
345437 }
346438 }
347439
348−static const struct dp_rates {
349− u32 rate;
350− u8 bw;
351− u8 nr;
352−} nvkm_dp_rates[] = {
353− { 2160000, 0x14, 4 },
354− { 1080000, 0x0a, 4 },
355− { 1080000, 0x14, 2 },
356− { 648000, 0x06, 4 },
357− { 540000, 0x0a, 2 },
358− { 540000, 0x14, 1 },
359− { 324000, 0x06, 2 },
360− { 270000, 0x0a, 1 },
361− { 162000, 0x06, 1 },
362− {}
363−};
364−
365440 static int
366441 nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
367442 {
368443 struct nvkm_ior *ior = dp->outp.ior;
369− const u8 sink_nr = dp->dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT;
370− const u8 sink_bw = dp->dpcd[DPCD_RC01_MAX_LINK_RATE];
371− const u8 outp_nr = dp->outp.info.dpconf.link_nr;
372− const u8 outp_bw = dp->outp.info.dpconf.link_bw;
373− const struct dp_rates *failsafe = NULL, *cfg;
374− int ret = -EINVAL;
444+ int ret = -EINVAL, nr, rate;
375445 u8 pwr;
376446
377− /* Find the lowest configuration of the OR that can support
378− * the required link rate.
379− *
380− * We will refuse to program the OR to lower rates, even if
381− * link training fails at higher rates (or even if the sink
382− * can't support the rate at all, though the DD is supposed
383− * to prevent such situations from happening).
384− *
385− * Attempting to do so can cause the entire display to hang,
386− * and it's better to have a failed modeset than that.
387− */
388− for (cfg = nvkm_dp_rates; cfg->rate; cfg++) {
389− if (cfg->nr <= outp_nr && cfg->bw <= outp_bw) {
390− /* Try to respect sink limits too when selecting
391− * lowest link configuration.
392− */
393− if (!failsafe ||
394− (cfg->nr <= sink_nr && cfg->bw <= sink_bw))
395− failsafe = cfg;
396− }
397−
398− if (failsafe && cfg[1].rate < dataKBps)
399− break;
400− }
401−
402− if (WARN_ON(!failsafe))
403− return ret;
404−
405447 /* Ensure sink is not in a low-power state. */
406448 if (!nvkm_rdaux(dp->aux, DPCD_SC00, &pwr, 1)) {
407449 if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
@@ -411,25 +453,22 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps) · 3 unmodified lines
411453 }
412454 }
413455
456+ ior->dp.mst = dp->lt.mst;
457+ ior->dp.ef = dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP;
458+ ior->dp.nr = 0;
459+
414460 /* Link training. */
415− OUTP_DBG(&dp->outp, "training (min: %d x %d MB/s)",
416− failsafe->nr, failsafe->bw * 27);
461+ OUTP_DBG(&dp->outp, "training");
417462 nvkm_dp_train_init(dp);
418− for (cfg = nvkm_dp_rates; ret < 0 && cfg <= failsafe; cfg++) {
419− /* Skip configurations not supported by both OR and sink. */
420− if ((cfg->nr > outp_nr || cfg->bw > outp_bw ||
421− cfg->nr > sink_nr || cfg->bw > sink_bw)) {
422− if (cfg != failsafe)
423− continue;
424− OUTP_ERR(&dp->outp, "link rate unsupported by sink");
463+ for (nr = dp->links; ret < 0 && nr; nr >>= 1) {
464+ for (rate = 0; ret < 0 && rate < dp->rates; rate++) {
465+ if (dp->rate[rate].rate * nr >= dataKBps || WARN_ON(!ior->dp.nr)) {
466+ /* Program selected link configuration. */
467+ ior->dp.bw = dp->rate[rate].rate / 27000;
468+ ior->dp.nr = nr;
469+ ret = nvkm_dp_train_links(dp, rate);
470+ }
425471 }
426− ior->dp.mst = dp->lt.mst;
427− ior->dp.ef = dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP;
428− ior->dp.bw = cfg->bw;
429− ior->dp.nr = cfg->nr;
430−
431− /* Program selected link configuration. */
432− ret = nvkm_dp_train_links(dp);
433472 }
434473 nvkm_dp_train_fini(dp);
435474 if (ret < 0)
@@ -526,6 +565,47 @@ done: · 90 unmodified lines
526565 return ret;
527566 }
528567
568+static bool
569+nvkm_dp_enable_supported_link_rates(struct nvkm_dp *dp)
570+{
571+ u8 sink_rates[DPCD_RC10_SUPPORTED_LINK_RATES__SIZE];
572+ int i, j, k;
573+
574+ if (dp->outp.conn->info.type != DCB_CONNECTOR_eDP ||
575+ dp->dpcd[DPCD_RC00_DPCD_REV] < 0x13 ||
576+ nvkm_rdaux(dp->aux, DPCD_RC10_SUPPORTED_LINK_RATES(0), sink_rates, sizeof(sink_rates)))
577+ return false;
578+
579+ for (i = 0; i < ARRAY_SIZE(sink_rates); i += 2) {
580+ const u32 rate = ((sink_rates[i + 1] << 8) | sink_rates[i]) * 200 / 10;
581+
582+ if (!rate || WARN_ON(dp->rates == ARRAY_SIZE(dp->rate)))
583+ break;
584+
585+ if (rate > dp->outp.info.dpconf.link_bw * 27000) {
586+ OUTP_DBG(&dp->outp, "rate %d !outp", rate);
587+ continue;
588+ }
589+
590+ for (j = 0; j < dp->rates; j++) {
591+ if (rate > dp->rate[j].rate) {
592+ for (k = dp->rates; k > j; k--)
593+ dp->rate[k] = dp->rate[k - 1];
594+ break;
595+ }
596+ }
597+
598+ dp->rate[j].dpcd = i / 2;
599+ dp->rate[j].rate = rate;
600+ dp->rates++;
601+ }
602+
603+ for (i = 0; i < dp->rates; i++)
604+ OUTP_DBG(&dp->outp, "link_rate[%d] = %d", dp->rate[i].dpcd, dp->rate[i].rate);
605+
606+ return dp->rates != 0;
607+}
608+
529609 static bool
530610 nvkm_dp_enable(struct nvkm_dp *dp, bool enable)
531611 {
@@ -538,9 +618,60 @@ nvkm_dp_enable(struct nvkm_dp *dp, bool enable) · 6 unmodified lines
538618 dp->present = true;
539619 }
540620
541− if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd,
542− sizeof(dp->dpcd)))
621+ /* Detect any LTTPRs before reading DPCD receiver caps. */
622+ if (!nvkm_rdaux(aux, DPCD_LTTPR_REV, dp->lttpr, sizeof(dp->lttpr)) &&
623+ dp->lttpr[0] >= 0x14 && dp->lttpr[2]) {
624+ switch (dp->lttpr[2]) {
625+ case 0x80: dp->lttprs = 1; break;
626+ case 0x40: dp->lttprs = 2; break;
627+ case 0x20: dp->lttprs = 3; break;
628+ case 0x10: dp->lttprs = 4; break;
629+ case 0x08: dp->lttprs = 5; break;
630+ case 0x04: dp->lttprs = 6; break;
631+ case 0x02: dp->lttprs = 7; break;
632+ case 0x01: dp->lttprs = 8; break;
633+ default:
634+ /* Unknown LTTPR count, we'll switch to transparent mode. */
635+ WARN_ON(1);
636+ dp->lttprs = 0;
637+ break;
638+ }
639+ } else {
640+ /* No LTTPR support, or zero LTTPR count - don't touch it at all. */
641+ memset(dp->lttpr, 0x00, sizeof(dp->lttpr));
642+ }
643+
644+ if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, dp->dpcd, sizeof(dp->dpcd))) {
645+ const u8 rates[] = { 0x1e, 0x14, 0x0a, 0x06, 0 };
646+ const u8 *rate;
647+ int rate_max;
648+
649+ dp->rates = 0;
650+ dp->links = dp->dpcd[DPCD_RC02] & DPCD_RC02_MAX_LANE_COUNT;
651+ dp->links = min(dp->links, dp->outp.info.dpconf.link_nr);
652+ if (dp->lttprs && dp->lttpr[4])
653+ dp->links = min_t(int, dp->links, dp->lttpr[4]);
654+
655+ rate_max = dp->dpcd[DPCD_RC01_MAX_LINK_RATE];
656+ rate_max = min(rate_max, dp->outp.info.dpconf.link_bw);
657+ if (dp->lttprs && dp->lttpr[1])
658+ rate_max = min_t(int, rate_max, dp->lttpr[1]);
659+
660+ if (!nvkm_dp_enable_supported_link_rates(dp)) {
661+ for (rate = rates; *rate; rate++) {
662+ if (*rate <= rate_max) {
663+ if (WARN_ON(dp->rates == ARRAY_SIZE(dp->rate)))
664+ break;
665+
666+ dp->rate[dp->rates].dpcd = -1;
667+ dp->rate[dp->rates].rate = *rate * 27000;
668+ dp->rates++;
669+ }
670+ }
671+ }
672+
543673 return true;
674+ }
544675 }
545676
546677 if (dp->present) {
drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h+29−6
@@ -9,10 +9,7 @@ · 8 unmodified lines
99 #include <subdev/bios/dp.h>
1010
1111 struct nvkm_dp {
12− union {
13− struct nvkm_outp base;
14− struct nvkm_outp outp;
15− };
12+ struct nvkm_outp outp;
1613
1714 struct nvbios_dpout info;
1815 u8 version;
@@ -21,8 +18,17 @@ struct nvkm_dp { · 2 unmodified lines
2118
2219 struct nvkm_notify hpd;
2320 bool present;
21+ u8 lttpr[6];
22+ u8 lttprs;
2423 u8 dpcd[16];
2524
25+ struct {
26+ int dpcd; /* -1, or index into SUPPORTED_LINK_RATES table */
27+ u32 rate;
28+ } rate[8];
29+ int rates;
30+ int links;
31+
2632 struct mutex mutex;
2733 struct {
2834 atomic_t done;
@@ -42,8 +48,12 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); · 13 unmodified lines
4248 #define DPCD_RC02_TPS3_SUPPORTED 0x40
4349 #define DPCD_RC02_MAX_LANE_COUNT 0x1f
4450 #define DPCD_RC03 0x00003
51+#define DPCD_RC03_TPS4_SUPPORTED 0x80
4552 #define DPCD_RC03_MAX_DOWNSPREAD 0x01
46−#define DPCD_RC0E_AUX_RD_INTERVAL 0x0000e
53+#define DPCD_RC0E 0x0000e
54+#define DPCD_RC0E_AUX_RD_INTERVAL 0x7f
55+#define DPCD_RC10_SUPPORTED_LINK_RATES(i) 0x00010
56+#define DPCD_RC10_SUPPORTED_LINK_RATES__SIZE 16
4757
4858 /* DPCD Link Configuration */
4959 #define DPCD_LC00_LINK_BW_SET 0x00100
@@ -51,7 +61,8 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); · 1 unmodified line
5161 #define DPCD_LC01_ENHANCED_FRAME_EN 0x80
5262 #define DPCD_LC01_LANE_COUNT_SET 0x1f
5363 #define DPCD_LC02 0x00102
54−#define DPCD_LC02_TRAINING_PATTERN_SET 0x03
64+#define DPCD_LC02_TRAINING_PATTERN_SET 0x0f
65+#define DPCD_LC02_SCRAMBLING_DISABLE 0x20
5566 #define DPCD_LC03(l) ((l) + 0x00103)
5667 #define DPCD_LC03_MAX_PRE_EMPHASIS_REACHED 0x20
5768 #define DPCD_LC03_PRE_EMPHASIS_SET 0x18
@@ -67,6 +78,8 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); · 9 unmodified lines
6778 #define DPCD_LC10_LANE3_POST_CURSOR2_SET 0x30
6879 #define DPCD_LC10_LANE2_MAX_POST_CURSOR2_REACHED 0x04
6980 #define DPCD_LC10_LANE2_POST_CURSOR2_SET 0x03
81+#define DPCD_LC15_LINK_RATE_SET 0x00115
82+#define DPCD_LC15_LINK_RATE_SET_MASK 0x07
7083
7184 /* DPCD Link/Sink Status */
7285 #define DPCD_LS02 0x00202
@@ -108,4 +121,14 @@ void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); · 35 unmodified lines
108121 #define DPCD_SC00_SET_POWER 0x03
109122 #define DPCD_SC00_SET_POWER_D0 0x01
110123 #define DPCD_SC00_SET_POWER_D3 0x03
124+
125+#define DPCD_LTTPR_REV 0xf0000
126+#define DPCD_LTTPR_MODE 0xf0003
127+#define DPCD_LTTPR_MODE_TRANSPARENT 0x55
128+#define DPCD_LTTPR_MODE_NON_TRANSPARENT 0xaa
129+#define DPCD_LTTPR_PATTERN_SET(i) ((i - 1) * 0x50 + 0xf0010)
130+#define DPCD_LTTPR_LANE0_SET(i) ((i - 1) * 0x50 + 0xf0011)
131+#define DPCD_LTTPR_AUX_RD_INTERVAL(i) ((i - 1) * 0x50 + 0xf0020)
132+#define DPCD_LTTPR_LANE0_1_STATUS(i) ((i - 1) * 0x50 + 0xf0030)
133+#define DPCD_LTTPR_LANE0_1_ADJUST(i) ((i - 1) * 0x50 + 0xf0033)
111134 #endif
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c+12−1
@@ -77,7 +77,18 @@ g94_sor_dp_pattern(struct nvkm_ior *sor, int pattern) · 76 unmodified lines
7777 {
7878 struct nvkm_device *device = sor->disp->engine.subdev.device;
7979 const u32 loff = nv50_sor_link(sor);
80− nvkm_mask(device, 0x61c10c + loff, 0x0f000000, pattern << 24);
80+ u32 data;
81+
82+ switch (pattern) {
83+ case 0: data = 0x00001000; break;
84+ case 1: data = 0x01000000; break;
85+ case 2: data = 0x02000000; break;
86+ default:
87+ WARN_ON(1);
88+ return;
89+ }
90+
91+ nvkm_mask(device, 0x61c10c + loff, 0x0f001000, data);
8192 }
8293
8394 void
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorga102.c+4−0
@@ -37,6 +37,10 @@ ga102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux) · 36 unmodified lines
3737 case 0x0a: clksor |= 0x00040000; break;
3838 case 0x14: clksor |= 0x00080000; break;
3939 case 0x1e: clksor |= 0x000c0000; break;
40+ case 0x08: clksor |= 0x00100000; break;
41+ case 0x09: clksor |= 0x00140000; break;
42+ case 0x0c: clksor |= 0x00180000; break;
43+ case 0x10: clksor |= 0x001c0000; break;
4044 default:
4145 WARN_ON(1);
4246 return -EINVAL;
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c+13−1
@@ -92,7 +92,19 @@ gf119_sor_dp_pattern(struct nvkm_ior *sor, int pattern) · 91 unmodified lines
9292 {
9393 struct nvkm_device *device = sor->disp->engine.subdev.device;
9494 const u32 soff = nv50_ior_base(sor);
95− nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
95+ u32 data;
96+
97+ switch (pattern) {
98+ case 0: data = 0x10101010; break;
99+ case 1: data = 0x01010101; break;
100+ case 2: data = 0x02020202; break;
101+ case 3: data = 0x03030303; break;
102+ default:
103+ WARN_ON(1);
104+ return;
105+ }
106+
107+ nvkm_mask(device, 0x61c110 + soff, 0x1f1f1f1f, data);
96108 }
97109
98110 int
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c+15−3
@@ -28,11 +28,23 @@ gm107_sor_dp_pattern(struct nvkm_ior *sor, int pattern) · 27 unmodified lines
2828 {
2929 struct nvkm_device *device = sor->disp->engine.subdev.device;
3030 const u32 soff = nv50_ior_base(sor);
31− const u32 data = 0x01010101 * pattern;
31+ u32 mask = 0x1f1f1f1f, data;
32+
33+ switch (pattern) {
34+ case 0: data = 0x10101010; break;
35+ case 1: data = 0x01010101; break;
36+ case 2: data = 0x02020202; break;
37+ case 3: data = 0x03030303; break;
38+ case 4: data = 0x1b1b1b1b; break;
39+ default:
40+ WARN_ON(1);
41+ return;
42+ }
43+
3244 if (sor->asy.link & 1)
33− nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
45+ nvkm_mask(device, 0x61c110 + soff, mask, data);
3446 else
35− nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
47+ nvkm_mask(device, 0x61c12c + soff, mask, data);
3648 }
3749
3850 static const struct nvkm_ior_func
drivers/gpu/drm/nouveau/nvkm/subdev/acr/hsfw.c+5−4
@@ -142,11 +142,12 @@ nvkm_acr_hsfw_load_bl(struct nvkm_acr *acr, const char *name, int ver, · 141 unmodified lines
142142
143143 hsfw->imem_size = desc->code_size;
144144 hsfw->imem_tag = desc->start_tag;
145− hsfw->imem = kmalloc(desc->code_size, GFP_KERNEL);
146− memcpy(hsfw->imem, data + desc->code_off, desc->code_size);
147−
145+ hsfw->imem = kmemdup(data + desc->code_off, desc->code_size, GFP_KERNEL);
148146 nvkm_firmware_put(fw);
149− return 0;
147+ if (!hsfw->imem)
148+ return -ENOMEM;
149+ else
150+ return 0;
150151 }
151152
152153 int
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c+1−0
@@ -93,6 +93,7 @@ struct dma_buf *omap_gem_prime_export(struct drm_gem_object *obj, int flags) · 92 unmodified lines
9393 exp_info.size = omap_gem_mmap_size(obj);
9494 exp_info.flags = flags;
9595 exp_info.priv = obj;
96+ exp_info.resv = obj->resv;
9697
9798 return drm_gem_dmabuf_export(obj->dev, &exp_info);
9899 }
drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c+4−4
@@ -86,7 +86,7 @@ static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = { · 85 unmodified lines
8686 _INIT_DCS_CMD(0x0F, 0x73),
8787 _INIT_DCS_CMD(0x95, 0xE6),
8888 _INIT_DCS_CMD(0x96, 0xF0),
89− _INIT_DCS_CMD(0x30, 0x11),
89+ _INIT_DCS_CMD(0x30, 0x00),
9090 _INIT_DCS_CMD(0x6D, 0x66),
9191 _INIT_DCS_CMD(0x75, 0xA2),
9292 _INIT_DCS_CMD(0x77, 0x3B),
@@ -112,17 +112,17 @@ static const struct panel_init_cmd boe_tv110c9m_init_cmd[] = { · 19 unmodified lines
112112 _INIT_DCS_CMD(0xB1, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
113113 _INIT_DCS_CMD(0xB2, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
114114
115− _INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
115+ _INIT_DCS_CMD(0xB3, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
116116 _INIT_DCS_CMD(0xB4, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
117117 _INIT_DCS_CMD(0xB5, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
118118 _INIT_DCS_CMD(0xB6, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
119− _INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
119+ _INIT_DCS_CMD(0xB7, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
120120
121121 _INIT_DCS_CMD(0xB8, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x45, 0x00, 0x65, 0x00, 0x81, 0x00, 0x99, 0x00, 0xAE, 0x00, 0xC1),
122122 _INIT_DCS_CMD(0xB9, 0x00, 0xD2, 0x01, 0x0B, 0x01, 0x34, 0x01, 0x76, 0x01, 0xA3, 0x01, 0xEF, 0x02, 0x27, 0x02, 0x29),
123123 _INIT_DCS_CMD(0xBA, 0x02, 0x5F, 0x02, 0x9E, 0x02, 0xC9, 0x03, 0x00, 0x03, 0x26, 0x03, 0x53, 0x03, 0x63, 0x03, 0x73),
124124
125− _INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xA7, 0x03, 0xCF, 0x03, 0xDE, 0x03, 0xE0),
125+ _INIT_DCS_CMD(0xBB, 0x03, 0x86, 0x03, 0x9A, 0x03, 0xAF, 0x03, 0xDF, 0x03, 0xF5, 0x03, 0xE0),
126126 _INIT_DCS_CMD(0xFF, 0x24),
127127 _INIT_DCS_CMD(0xFB, 0x01),
128128
drivers/gpu/drm/panel/panel-edp.c+19−2
@@ -36,8 +36,8 @@ · 35 unmodified lines
3636
3737 #include <drm/drm_crtc.h>
3838 #include <drm/drm_device.h>
39−#include <drm/drm_dp_aux_bus.h>
40−#include <drm/drm_dp_helper.h>
39+#include <drm/dp/drm_dp_aux_bus.h>
40+#include <drm/dp/drm_dp_helper.h>
4141 #include <drm/drm_panel.h>
4242
4343 /**
@@ -1745,6 +1745,19 @@ static const struct panel_delay delay_200_500_e50 = { · 1701 unmodified lines
17451745 .enable = 50,
17461746 };
17471747
1748+static const struct panel_delay delay_200_500_e80_d50 = {
1749+ .hpd_absent = 200,
1750+ .unprepare = 500,
1751+ .enable = 80,
1752+ .disable = 50,
1753+};
1754+
1755+static const struct panel_delay delay_100_500_e200 = {
1756+ .hpd_absent = 100,
1757+ .unprepare = 500,
1758+ .enable = 200,
1759+};
1760+
17481761 #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name) \
17491762 { \
17501763 .name = _name, \
@@ -1768,13 +1781,17 @@ static const struct edp_panel_entry edp_panels[] = { · 17 unmodified lines
17681781 EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"),
17691782 EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"),
17701783 EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"),
1784+ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"),
17711785
17721786 EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, &innolux_n116bca_ea1.delay, "N116BCA-EA1"),
17731787
17741788 EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010"),
1789+ EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007"),
17751790
17761791 EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10"),
17771792
1793+ EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D"),
1794+
17781795 { /* sentinal */ }
17791796 };
17801797
drivers/gpu/drm/panel/panel-samsung-atna33xc20.c+2−2
@@ -14,8 +14,8 @@ · 13 unmodified lines
1414 #include <linux/pm_runtime.h>
1515 #include <linux/regulator/consumer.h>
1616
17−#include <drm/drm_dp_aux_bus.h>
18−#include <drm/drm_dp_helper.h>
17+#include <drm/dp/drm_dp_aux_bus.h>
18+#include <drm/dp/drm_dp_helper.h>
1919 #include <drm/drm_edid.h>
2020 #include <drm/drm_panel.h>
2121
drivers/gpu/drm/panel/panel-simple.c+33−0
@@ -2525,6 +2525,36 @@ static const struct panel_desc mitsubishi_aa070mc01 = { · 2524 unmodified lines
25252525 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
25262526 };
25272527
2528+static const struct display_timing multi_inno_mi0700s4t_6_timing = {
2529+ .pixelclock = { 29000000, 33000000, 38000000 },
2530+ .hactive = { 800, 800, 800 },
2531+ .hfront_porch = { 180, 210, 240 },
2532+ .hback_porch = { 16, 16, 16 },
2533+ .hsync_len = { 30, 30, 30 },
2534+ .vactive = { 480, 480, 480 },
2535+ .vfront_porch = { 12, 22, 32 },
2536+ .vback_porch = { 10, 10, 10 },
2537+ .vsync_len = { 13, 13, 13 },
2538+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
2539+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE |
2540+ DISPLAY_FLAGS_SYNC_POSEDGE,
2541+};
2542+
2543+static const struct panel_desc multi_inno_mi0700s4t_6 = {
2544+ .timings = &multi_inno_mi0700s4t_6_timing,
2545+ .num_timings = 1,
2546+ .bpc = 8,
2547+ .size = {
2548+ .width = 154,
2549+ .height = 86,
2550+ },
2551+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
2552+ .bus_flags = DRM_BUS_FLAG_DE_HIGH |
2553+ DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
2554+ DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
2555+ .connector_type = DRM_MODE_CONNECTOR_DPI,
2556+};
2557+
25282558 static const struct display_timing multi_inno_mi1010ait_1cp_timing = {
25292559 .pixelclock = { 68900000, 70000000, 73400000 },
25302560 .hactive = { 1280, 1280, 1280 },
@@ -3871,6 +3901,9 @@ static const struct of_device_id platform_of_match[] = { · 1340 unmodified lines
38713901 }, {
38723902 .compatible = "mitsubishi,aa070mc01-ca1",
38733903 .data = &mitsubishi_aa070mc01,
3904+ }, {
3905+ .compatible = "multi-inno,mi0700s4t-6",
3906+ .data = &multi_inno_mi0700s4t_6,
38743907 }, {
38753908 .compatible = "multi-inno,mi1010ait-1cp",
38763909 .data = &multi_inno_mi1010ait_1cp,
drivers/gpu/drm/panfrost/panfrost_features.h+7−205
@@ -12,24 +12,6 @@ enum panfrost_hw_feature { · 11 unmodified lines
1212 HW_FEATURE_JOBCHAIN_DISAMBIGUATION,
1313 HW_FEATURE_PWRON_DURING_PWROFF_TRANS,
1414 HW_FEATURE_XAFFINITY,
15− HW_FEATURE_OUT_OF_ORDER_EXEC,
16− HW_FEATURE_MRT,
17− HW_FEATURE_BRNDOUT_CC,
18− HW_FEATURE_INTERPIPE_REG_ALIASING,
19− HW_FEATURE_LD_ST_TILEBUFFER,
20− HW_FEATURE_MSAA_16X,
21− HW_FEATURE_32_BIT_UNIFORM_ADDRESS,
22− HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL,
23− HW_FEATURE_OPTIMIZED_COVERAGE_MASK,
24− HW_FEATURE_T7XX_PAIRING_RULES,
25− HW_FEATURE_LD_ST_LEA_TEX,
26− HW_FEATURE_LINEAR_FILTER_FLOAT,
27− HW_FEATURE_WORKGROUP_ROUND_MULTIPLE_OF_4,
28− HW_FEATURE_IMAGES_IN_FRAGMENT_SHADERS,
29− HW_FEATURE_TEST4_DATUM_MODE,
30− HW_FEATURE_NEXT_INSTRUCTION_TYPE,
31− HW_FEATURE_BRNDOUT_KILL,
32− HW_FEATURE_WARPING,
3315 HW_FEATURE_V4,
3416 HW_FEATURE_FLUSH_REDUCTION,
3517 HW_FEATURE_PROTECTED_MODE,
@@ -42,128 +24,31 @@ enum panfrost_hw_feature { · 6 unmodified lines
4224 };
4325
4426 #define hw_features_t600 (\
45− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
46− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
4727 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
4828 BIT_ULL(HW_FEATURE_V4))
4929
50−#define hw_features_t620 (\
51− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
52− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
53− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
54− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
55− BIT_ULL(HW_FEATURE_V4))
56−
57−#define hw_features_t720 (\
58− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
59− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
60− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
61− BIT_ULL(HW_FEATURE_OPTIMIZED_COVERAGE_MASK) | \
62− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
63− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
64− BIT_ULL(HW_FEATURE_WORKGROUP_ROUND_MULTIPLE_OF_4) | \
65− BIT_ULL(HW_FEATURE_WARPING) | \
66− BIT_ULL(HW_FEATURE_V4))
30+#define hw_features_t620 hw_features_t600
6731
32+#define hw_features_t720 hw_features_t600
6833
6934 #define hw_features_t760 (\
7035 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
7136 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
7237 BIT_ULL(HW_FEATURE_XAFFINITY) | \
73− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
74− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
75− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
76− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
77− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
78− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
79− BIT_ULL(HW_FEATURE_MRT) | \
80− BIT_ULL(HW_FEATURE_MSAA_16X) | \
81− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
82− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
83− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
8438 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT))
8539
86−// T860
87−#define hw_features_t860 (\
88− BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
89− BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
90− BIT_ULL(HW_FEATURE_XAFFINITY) | \
91− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
92− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
93− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
94− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
95− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
96− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
97− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
98− BIT_ULL(HW_FEATURE_MRT) | \
99− BIT_ULL(HW_FEATURE_MSAA_16X) | \
100− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
101− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
102− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
103− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
104− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT))
40+#define hw_features_t860 hw_features_t760
10541
106−#define hw_features_t880 hw_features_t860
42+#define hw_features_t880 hw_features_t760
10743
108−#define hw_features_t830 (\
109− BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
110− BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
111− BIT_ULL(HW_FEATURE_XAFFINITY) | \
112− BIT_ULL(HW_FEATURE_WARPING) | \
113− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
114− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
115− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
116− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
117− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
118− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
119− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
120− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
121− BIT_ULL(HW_FEATURE_MRT) | \
122− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
123− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
124− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
125− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
126− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT))
44+#define hw_features_t830 hw_features_t760
12745
128−#define hw_features_t820 (\
129− BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
130− BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
131− BIT_ULL(HW_FEATURE_XAFFINITY) | \
132− BIT_ULL(HW_FEATURE_WARPING) | \
133− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
134− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
135− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
136− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
137− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
138− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
139− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
140− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
141− BIT_ULL(HW_FEATURE_MRT) | \
142− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
143− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
144− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
145− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
146− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT))
46+#define hw_features_t820 hw_features_t760
14747
14848 #define hw_features_g71 (\
14949 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
15050 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
15151 BIT_ULL(HW_FEATURE_XAFFINITY) | \
152− BIT_ULL(HW_FEATURE_WARPING) | \
153− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
154− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
155− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
156− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
157− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
158− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
159− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
160− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
161− BIT_ULL(HW_FEATURE_MRT) | \
162− BIT_ULL(HW_FEATURE_MSAA_16X) | \
163− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
164− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
165− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
166− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
16752 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
16853 BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
16954 BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
@@ -173,71 +58,18 @@ enum panfrost_hw_feature { · 3 unmodified lines
17358 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
17459 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
17560 BIT_ULL(HW_FEATURE_XAFFINITY) | \
176− BIT_ULL(HW_FEATURE_WARPING) | \
177− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
178− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
179− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
180− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
181− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
182− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
183− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
184− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
185− BIT_ULL(HW_FEATURE_MRT) | \
186− BIT_ULL(HW_FEATURE_MSAA_16X) | \
187− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
188− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
189− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
190− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
19161 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
19262 BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
19363 BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
19464 BIT_ULL(HW_FEATURE_PROTECTED_DEBUG_MODE) | \
19565 BIT_ULL(HW_FEATURE_COHERENCY_REG))
19666
197−#define hw_features_g51 (\
198− BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
199− BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
200− BIT_ULL(HW_FEATURE_XAFFINITY) | \
201− BIT_ULL(HW_FEATURE_WARPING) | \
202− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
203− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
204− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
205− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
206− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
207− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
208− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
209− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
210− BIT_ULL(HW_FEATURE_MRT) | \
211− BIT_ULL(HW_FEATURE_MSAA_16X) | \
212− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
213− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
214− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
215− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
216− BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
217− BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
218− BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
219− BIT_ULL(HW_FEATURE_PROTECTED_DEBUG_MODE) | \
220− BIT_ULL(HW_FEATURE_COHERENCY_REG))
67+#define hw_features_g51 hw_features_g72
22168
22269 #define hw_features_g52 (\
22370 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
22471 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
22572 BIT_ULL(HW_FEATURE_XAFFINITY) | \
226− BIT_ULL(HW_FEATURE_WARPING) | \
227− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
228− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
229− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
230− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
231− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
232− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
233− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
234− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
235− BIT_ULL(HW_FEATURE_MRT) | \
236− BIT_ULL(HW_FEATURE_MSAA_16X) | \
237− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
238− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
239− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
240− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
24173 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
24274 BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
24375 BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
@@ -248,21 +80,6 @@ enum panfrost_hw_feature { · 4 unmodified lines
24880 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
24981 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
25082 BIT_ULL(HW_FEATURE_XAFFINITY) | \
251− BIT_ULL(HW_FEATURE_WARPING) | \
252− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
253− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
254− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
255− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
256− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
257− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
258− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
259− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
260− BIT_ULL(HW_FEATURE_MRT) | \
261− BIT_ULL(HW_FEATURE_MSAA_16X) | \
262− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
263− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
264− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
265− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
26683 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
26784 BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
26885 BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
@@ -276,21 +93,6 @@ enum panfrost_hw_feature { · 7 unmodified lines
27693 BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
27794 BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
27895 BIT_ULL(HW_FEATURE_XAFFINITY) | \
279− BIT_ULL(HW_FEATURE_WARPING) | \
280− BIT_ULL(HW_FEATURE_INTERPIPE_REG_ALIASING) | \
281− BIT_ULL(HW_FEATURE_32_BIT_UNIFORM_ADDRESS) | \
282− BIT_ULL(HW_FEATURE_ATTR_AUTO_TYPE_INFERRAL) | \
283− BIT_ULL(HW_FEATURE_BRNDOUT_CC) | \
284− BIT_ULL(HW_FEATURE_BRNDOUT_KILL) | \
285− BIT_ULL(HW_FEATURE_LD_ST_LEA_TEX) | \
286− BIT_ULL(HW_FEATURE_LD_ST_TILEBUFFER) | \
287− BIT_ULL(HW_FEATURE_LINEAR_FILTER_FLOAT) | \
288− BIT_ULL(HW_FEATURE_MRT) | \
289− BIT_ULL(HW_FEATURE_MSAA_16X) | \
290− BIT_ULL(HW_FEATURE_NEXT_INSTRUCTION_TYPE) | \
291− BIT_ULL(HW_FEATURE_OUT_OF_ORDER_EXEC) | \
292− BIT_ULL(HW_FEATURE_T7XX_PAIRING_RULES) | \
293− BIT_ULL(HW_FEATURE_TEST4_DATUM_MODE) | \
29496 BIT_ULL(HW_FEATURE_THREAD_GROUP_SPLIT) | \
29597 BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
29698 BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
drivers/gpu/drm/panfrost/panfrost_gpu.c+26−6
@@ -320,19 +320,36 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev) · 319 unmodified lines
320320 {
321321 int ret;
322322 u32 val;
323+ u64 core_mask = U64_MAX;
323324
324325 panfrost_gpu_init_quirks(pfdev);
325326
326− /* Just turn on everything for now */
327− gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present);
327+ if (pfdev->features.l2_present != 1) {
328+ /*
329+ * Only support one core group now.
330+ * ~(l2_present - 1) unsets all bits in l2_present except
331+ * the bottom bit. (l2_present - 2) has all the bits in
332+ * the first core group set. AND them together to generate
333+ * a mask of cores in the first core group.
334+ */
335+ core_mask = ~(pfdev->features.l2_present - 1) &
336+ (pfdev->features.l2_present - 2);
337+ dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n",
338+ hweight64(core_mask),
339+ hweight64(pfdev->features.shader_present));
340+ }
341+ gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask);
328342 ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO,
329− val, val == pfdev->features.l2_present, 100, 20000);
343+ val, val == (pfdev->features.l2_present & core_mask),
344+ 100, 20000);
330345 if (ret)
331346 dev_err(pfdev->dev, "error powering up gpu L2");
332347
333− gpu_write(pfdev, SHADER_PWRON_LO, pfdev->features.shader_present);
348+ gpu_write(pfdev, SHADER_PWRON_LO,
349+ pfdev->features.shader_present & core_mask);
334350 ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_READY_LO,
335− val, val == pfdev->features.shader_present, 100, 20000);
351+ val, val == (pfdev->features.shader_present & core_mask),
352+ 100, 20000);
336353 if (ret)
337354 dev_err(pfdev->dev, "error powering up gpu shader");
338355
@@ -360,8 +377,11 @@ int panfrost_gpu_init(struct panfrost_device *pfdev) · 21 unmodified lines
360377
361378 panfrost_gpu_init_features(pfdev);
362379
363− dma_set_mask_and_coherent(pfdev->dev,
380+ err = dma_set_mask_and_coherent(pfdev->dev,
364381 DMA_BIT_MASK(FIELD_GET(0xff00, pfdev->features.mmu_features)));
382+ if (err)
383+ return err;
384+
365385 dma_set_max_seg_size(pfdev->dev, UINT_MAX);
366386
367387 irq = platform_get_irq_byname(to_platform_device(pfdev->dev), "gpu");
drivers/gpu/drm/radeon/atombios_dp.c+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
3030
3131 #include "atom.h"
3232 #include "atom-bits.h"
33−#include <drm/drm_dp_helper.h>
33+#include <drm/dp/drm_dp_helper.h>
3434
3535 /* move these to drm_dp_helper.c/h */
3636 #define DP_LINK_CONFIGURATION_SIZE 9
drivers/gpu/drm/radeon/radeon_connectors.c+2−2
@@ -27,7 +27,7 @@ · 26 unmodified lines
2727 #include <drm/drm_edid.h>
2828 #include <drm/drm_crtc_helper.h>
2929 #include <drm/drm_fb_helper.h>
30−#include <drm/drm_dp_mst_helper.h>
30+#include <drm/dp/drm_dp_mst_helper.h>
3131 #include <drm/drm_probe_helper.h>
3232 #include <drm/radeon_drm.h>
3333 #include "radeon.h"
@@ -204,7 +204,7 @@ int radeon_get_monitor_bpc(struct drm_connector *connector) · 170 unmodified lines
204204
205205 /* Check if bpc is within clock limit. Try to degrade gracefully otherwise */
206206 if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {
207− if ((connector->display_info.edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
207+ if ((connector->display_info.edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30) &&
208208 (mode_clock * 5/4 <= max_tmds_clock))
209209 bpc = 10;
210210 else
drivers/gpu/drm/radeon/radeon_dp_mst.c+1−1
@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: MIT
22
3−#include <drm/drm_dp_mst_helper.h>
3+#include <drm/dp/drm_dp_mst_helper.h>
44 #include <drm/drm_fb_helper.h>
55 #include <drm/drm_file.h>
66 #include <drm/drm_probe_helper.h>
drivers/gpu/drm/radeon/radeon_mode.h+2−2
@@ -33,8 +33,8 @@ · 32 unmodified lines
3333 #include <drm/drm_crtc.h>
3434 #include <drm/drm_edid.h>
3535 #include <drm/drm_encoder.h>
36−#include <drm/drm_dp_helper.h>
37−#include <drm/drm_dp_mst_helper.h>
36+#include <drm/dp/drm_dp_helper.h>
37+#include <drm/dp/drm_dp_mst_helper.h>
3838 #include <drm/drm_fixed.h>
3939 #include <drm/drm_crtc_helper.h>
4040 #include <linux/i2c.h>
drivers/gpu/drm/radeon/radeon_ttm.c+2−2
@@ -802,7 +802,7 @@ static int radeon_mm_vram_dump_table_show(struct seq_file *m, void *unused) · 801 unmodified lines
802802 TTM_PL_VRAM);
803803 struct drm_printer p = drm_seq_file_printer(m);
804804
805− man->func->debug(man, &p);
805+ ttm_resource_manager_debug(man, &p);
806806 return 0;
807807 }
808808
@@ -820,7 +820,7 @@ static int radeon_mm_gtt_dump_table_show(struct seq_file *m, void *unused) · 11 unmodified lines
820820 TTM_PL_TT);
821821 struct drm_printer p = drm_seq_file_printer(m);
822822
823− man->func->debug(man, &p);
823+ ttm_resource_manager_debug(man, &p);
824824 return 0;
825825 }
826826
drivers/gpu/drm/rockchip/Kconfig+2−0
@@ -2,11 +2,13 @@ · 1 unmodified line
22 config DRM_ROCKCHIP
33 tristate "DRM Support for Rockchip"
44 depends on DRM && ROCKCHIP_IOMMU
5+ select DRM_DP_HELPER
56 select DRM_GEM_CMA_HELPER
67 select DRM_KMS_HELPER
78 select DRM_PANEL
89 select VIDEOMODE_HELPERS
910 select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
11+ select DRM_DP_HELPER if ROCKCHIP_ANALOGIX_DP
1012 select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
1113 select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
1214 select GENERIC_PHY if ROCKCHIP_DW_MIPI_DSI
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c+2−2
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 #include <drm/drm_atomic.h>
2323 #include <drm/drm_atomic_helper.h>
2424 #include <drm/bridge/analogix_dp.h>
25−#include <drm/drm_dp_helper.h>
25+#include <drm/dp/drm_dp_helper.h>
2626 #include <drm/drm_of.h>
2727 #include <drm/drm_panel.h>
2828 #include <drm/drm_probe_helper.h>
@@ -117,7 +117,7 @@ static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, · 88 unmodified lines
117117 {
118118 struct drm_display_info *di = &connector->display_info;
119119 /* VOP couldn't output YUV video format for eDP rightly */
120− u32 mask = DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422;
120+ u32 mask = DRM_COLOR_FORMAT_YCBCR444 | DRM_COLOR_FORMAT_YCBCR422;
121121
122122 if ((di->color_formats & mask)) {
123123 DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
drivers/gpu/drm/rockchip/cdn-dp-core.c+1−1
@@ -16,7 +16,7 @@ · 15 unmodified lines
1616 #include <sound/hdmi-codec.h>
1717
1818 #include <drm/drm_atomic_helper.h>
19−#include <drm/drm_dp_helper.h>
19+#include <drm/dp/drm_dp_helper.h>
2020 #include <drm/drm_edid.h>
2121 #include <drm/drm_of.h>
2222 #include <drm/drm_probe_helper.h>
drivers/gpu/drm/rockchip/cdn-dp-core.h+1−1
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 #ifndef _CDN_DP_CORE_H
88 #define _CDN_DP_CORE_H
99
10−#include <drm/drm_dp_helper.h>
10+#include <drm/dp/drm_dp_helper.h>
1111 #include <drm/drm_panel.h>
1212 #include <drm/drm_probe_helper.h>
1313
drivers/gpu/drm/rockchip/rockchip_lvds.c+1−1
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #include <drm/drm_atomic_helper.h>
2121 #include <drm/drm_bridge.h>
2222 #include <drm/drm_bridge_connector.h>
23−#include <drm/drm_dp_helper.h>
23+#include <drm/dp/drm_dp_helper.h>
2424 #include <drm/drm_of.h>
2525 #include <drm/drm_panel.h>
2626 #include <drm/drm_probe_helper.h>
drivers/gpu/drm/rockchip/rockchip_rgb.c+1−1
@@ -11,7 +11,7 @@ · 10 unmodified lines
1111 #include <drm/drm_atomic_helper.h>
1212 #include <drm/drm_bridge.h>
1313 #include <drm/drm_bridge_connector.h>
14−#include <drm/drm_dp_helper.h>
14+#include <drm/dp/drm_dp_helper.h>
1515 #include <drm/drm_of.h>
1616 #include <drm/drm_panel.h>
1717 #include <drm/drm_probe_helper.h>
drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c+5−3
@@ -7,10 +7,10 @@ · 6 unmodified lines
77
88 #include <linux/random.h>
99
10−#include <drm/drm_dp_mst_helper.h>
10+#include <drm/dp/drm_dp_mst_helper.h>
1111 #include <drm/drm_print.h>
1212
13−#include "../drm_dp_mst_topology_internal.h"
13+#include "../dp/drm_dp_mst_topology_internal.h"
1414 #include "test-drm_modeset_common.h"
1515
1616 int igt_dp_mst_calc_pbn_mode(void *ignored)
@@ -131,8 +131,10 @@ sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) · 114 unmodified lines
131131 return false;
132132
133133 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
134− if (!txmsg)
134+ if (!txmsg) {
135+ kfree(out);
135136 return false;
137+ }
136138
137139 drm_dp_encode_sideband_req(in, txmsg);
138140 ret = drm_dp_decode_sideband_req(txmsg, out);
drivers/gpu/drm/selftests/test-drm_plane_helper.c+4−0
@@ -87,11 +87,15 @@ int igt_check_plane_state(void *ignored) · 86 unmodified lines
8787 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
8888 },
8989 };
90+ struct drm_plane plane = {
91+ .dev = NULL
92+ };
9093 struct drm_framebuffer fb = {
9194 .width = 2048,
9295 .height = 2048
9396 };
9497 struct drm_plane_state plane_state = {
98+ .plane = &plane,
9599 .crtc = ZERO_SIZE_PTR,
96100 .fb = &fb,
97101 .rotation = DRM_MODE_ROTATE_0
drivers/gpu/drm/stm/drv.c+5−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/of_platform.h>
1515 #include <linux/pm_runtime.h>
1616
17+#include <drm/drm_aperture.h>
1718 #include <drm/drm_atomic.h>
1819 #include <drm/drm_atomic_helper.h>
1920 #include <drm/drm_drv.h>
@@ -183,6 +184,10 @@ static int stm_drm_platform_probe(struct platform_device *pdev) · 163 unmodified lines
183184
184185 DRM_DEBUG("%s\n", __func__);
185186
187+ ret = drm_aperture_remove_framebuffers(false, &drv_driver);
188+ if (ret)
189+ return ret;
190+
186191 dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
187192
188193 ddev = drm_dev_alloc(&drv_driver, dev);
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c+106−8
@@ -247,14 +247,6 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, · 246 unmodified lines
247247 int ret, bpp;
248248 u32 val;
249249
250− /* Update lane capabilities according to hw version */
251− dsi->lane_min_kbps = LANE_MIN_KBPS;
252− dsi->lane_max_kbps = LANE_MAX_KBPS;
253− if (dsi->hw_version == HWVER_131) {
254− dsi->lane_min_kbps *= 2;
255− dsi->lane_max_kbps *= 2;
256− }
257−
258250 pll_in_khz = (unsigned int)(clk_get_rate(dsi->pllref_clk) / 1000);
259251
260252 /* Compute requested pll out */
@@ -330,6 +322,103 @@ dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, · 69 unmodified lines
330322 return 0;
331323 }
332324
325+#define CLK_TOLERANCE_HZ 50
326+
327+static enum drm_mode_status
328+dw_mipi_dsi_stm_mode_valid(void *priv_data,
329+ const struct drm_display_mode *mode,
330+ unsigned long mode_flags, u32 lanes, u32 format)
331+{
332+ struct dw_mipi_dsi_stm *dsi = priv_data;
333+ unsigned int idf, ndiv, odf, pll_in_khz, pll_out_khz;
334+ int ret, bpp;
335+
336+ bpp = mipi_dsi_pixel_format_to_bpp(format);
337+ if (bpp < 0)
338+ return MODE_BAD;
339+
340+ /* Compute requested pll out */
341+ pll_out_khz = mode->clock * bpp / lanes;
342+
343+ if (pll_out_khz > dsi->lane_max_kbps)
344+ return MODE_CLOCK_HIGH;
345+
346+ if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST) {
347+ /* Add 20% to pll out to be higher than pixel bw */
348+ pll_out_khz = (pll_out_khz * 12) / 10;
349+ } else {
350+ if (pll_out_khz < dsi->lane_min_kbps)
351+ return MODE_CLOCK_LOW;
352+ }
353+
354+ /* Compute best pll parameters */
355+ idf = 0;
356+ ndiv = 0;
357+ odf = 0;
358+ pll_in_khz = clk_get_rate(dsi->pllref_clk) / 1000;
359+ ret = dsi_pll_get_params(dsi, pll_in_khz, pll_out_khz, &idf, &ndiv, &odf);
360+ if (ret) {
361+ DRM_WARN("Warning dsi_pll_get_params(): bad params\n");
362+ return MODE_ERROR;
363+ }
364+
365+ if (!(mode_flags & MIPI_DSI_MODE_VIDEO_BURST)) {
366+ unsigned int px_clock_hz, target_px_clock_hz, lane_mbps;
367+ int dsi_short_packet_size_px, hfp, hsync, hbp, delay_to_lp;
368+ struct dw_mipi_dsi_dphy_timing dphy_timing;
369+
370+ /* Get the adjusted pll out value */
371+ pll_out_khz = dsi_pll_get_clkout_khz(pll_in_khz, idf, ndiv, odf);
372+
373+ px_clock_hz = DIV_ROUND_CLOSEST_ULL(1000ULL * pll_out_khz * lanes, bpp);
374+ target_px_clock_hz = mode->clock * 1000;
375+ /*
376+ * Filter modes according to the clock value, particularly useful for
377+ * hdmi modes that require precise pixel clocks.
378+ */
379+ if (px_clock_hz < target_px_clock_hz - CLK_TOLERANCE_HZ ||
380+ px_clock_hz > target_px_clock_hz + CLK_TOLERANCE_HZ)
381+ return MODE_CLOCK_RANGE;
382+
383+ /* sync packets are codes as DSI short packets (4 bytes) */
384+ dsi_short_packet_size_px = DIV_ROUND_UP(4 * BITS_PER_BYTE, bpp);
385+
386+ hfp = mode->hsync_start - mode->hdisplay;
387+ hsync = mode->hsync_end - mode->hsync_start;
388+ hbp = mode->htotal - mode->hsync_end;
389+
390+ /* hsync must be longer than 4 bytes HSS packets */
391+ if (hsync < dsi_short_packet_size_px)
392+ return MODE_HSYNC_NARROW;
393+
394+ if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
395+ /* HBP must be longer than 4 bytes HSE packets */
396+ if (hbp < dsi_short_packet_size_px)
397+ return MODE_HSYNC_NARROW;
398+ hbp -= dsi_short_packet_size_px;
399+ } else {
400+ /* With sync events HBP extends in the hsync */
401+ hbp += hsync - dsi_short_packet_size_px;
402+ }
403+
404+ lane_mbps = pll_out_khz / 1000;
405+ ret = dw_mipi_dsi_phy_get_timing(priv_data, lane_mbps, &dphy_timing);
406+ if (ret)
407+ return MODE_ERROR;
408+ /*
409+ * In non-burst mode DSI has to enter in LP during HFP
410+ * (horizontal front porch) or HBP (horizontal back porch) to
411+ * resync with LTDC pixel clock.
412+ */
413+ delay_to_lp = DIV_ROUND_UP((dphy_timing.data_hs2lp + dphy_timing.data_lp2hs) *
414+ lanes * BITS_PER_BYTE, bpp);
415+ if (hfp < delay_to_lp && hbp < delay_to_lp)
416+ return MODE_HSYNC;
417+ }
418+
419+ return MODE_OK;
420+}
421+
333422 static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = {
334423 .init = dw_mipi_dsi_phy_init,
335424 .power_on = dw_mipi_dsi_phy_power_on,
@@ -340,6 +429,7 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { · 4 unmodified lines
340429
341430 static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = {
342431 .max_data_lanes = 2,
432+ .mode_valid = dw_mipi_dsi_stm_mode_valid,
343433 .phy_ops = &dw_mipi_dsi_stm_phy_ops,
344434 };
345435
@@ -417,6 +507,14 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) · 71 unmodified lines
417507 goto err_dsi_probe;
418508 }
419509
510+ /* set lane capabilities according to hw version */
511+ dsi->lane_min_kbps = LANE_MIN_KBPS;
512+ dsi->lane_max_kbps = LANE_MAX_KBPS;
513+ if (dsi->hw_version == HWVER_131) {
514+ dsi->lane_min_kbps *= 2;
515+ dsi->lane_max_kbps *= 2;
516+ }
517+
420518 dw_mipi_dsi_stm_plat_data.base = dsi->base;
421519 dw_mipi_dsi_stm_plat_data.priv_data = dsi;
422520
drivers/gpu/drm/stm/ltdc.c+647−163
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #include <linux/pinctrl/consumer.h>
1919 #include <linux/platform_device.h>
2020 #include <linux/pm_runtime.h>
21+#include <linux/regmap.h>
2122 #include <linux/reset.h>
2223
2324 #include <drm/drm_atomic.h>
@@ -46,15 +47,15 @@ · 22 unmodified lines
4647 #define HWVER_10200 0x010200
4748 #define HWVER_10300 0x010300
4849 #define HWVER_20101 0x020101
50+#define HWVER_40100 0x040100
4951
5052 /*
5153 * The address of some registers depends on the HW version: such registers have
52− * an extra offset specified with reg_ofs.
54+ * an extra offset specified with layer_ofs.
5355 */
54−#define REG_OFS_NONE 0
55−#define REG_OFS_4 4 /* Insertion of "Layer Conf. 2" reg */
56−#define REG_OFS (ldev->caps.reg_ofs)
57−#define LAY_OFS 0x80 /* Register Offset between 2 layers */
56+#define LAY_OFS_0 0x80
57+#define LAY_OFS_1 0x100
58+#define LAY_OFS (ldev->caps.layer_ofs)
5859
5960 /* Global register offsets */
6061 #define LTDC_IDR 0x0000 /* IDentification */
@@ -75,29 +76,35 @@ · 14 unmodified lines
7576 #define LTDC_LIPCR 0x0040 /* Line Interrupt Position Conf. */
7677 #define LTDC_CPSR 0x0044 /* Current Position Status */
7778 #define LTDC_CDSR 0x0048 /* Current Display Status */
79+#define LTDC_EDCR 0x0060 /* External Display Control */
80+#define LTDC_FUT 0x0090 /* Fifo underrun Threshold */
7881
7982 /* Layer register offsets */
80−#define LTDC_L1LC1R (0x80) /* L1 Layer Configuration 1 */
81−#define LTDC_L1LC2R (0x84) /* L1 Layer Configuration 2 */
82−#define LTDC_L1CR (0x84 + REG_OFS)/* L1 Control */
83−#define LTDC_L1WHPCR (0x88 + REG_OFS)/* L1 Window Hor Position Config */
84−#define LTDC_L1WVPCR (0x8C + REG_OFS)/* L1 Window Vert Position Config */
85−#define LTDC_L1CKCR (0x90 + REG_OFS)/* L1 Color Keying Configuration */
86−#define LTDC_L1PFCR (0x94 + REG_OFS)/* L1 Pixel Format Configuration */
87−#define LTDC_L1CACR (0x98 + REG_OFS)/* L1 Constant Alpha Config */
88−#define LTDC_L1DCCR (0x9C + REG_OFS)/* L1 Default Color Configuration */
89−#define LTDC_L1BFCR (0xA0 + REG_OFS)/* L1 Blend Factors Configuration */
90−#define LTDC_L1FBBCR (0xA4 + REG_OFS)/* L1 FrameBuffer Bus Control */
91−#define LTDC_L1AFBCR (0xA8 + REG_OFS)/* L1 AuxFB Control */
92−#define LTDC_L1CFBAR (0xAC + REG_OFS)/* L1 Color FrameBuffer Address */
93−#define LTDC_L1CFBLR (0xB0 + REG_OFS)/* L1 Color FrameBuffer Length */
94−#define LTDC_L1CFBLNR (0xB4 + REG_OFS)/* L1 Color FrameBuffer Line Nb */
95−#define LTDC_L1AFBAR (0xB8 + REG_OFS)/* L1 AuxFB Address */
96−#define LTDC_L1AFBLR (0xBC + REG_OFS)/* L1 AuxFB Length */
97−#define LTDC_L1AFBLNR (0xC0 + REG_OFS)/* L1 AuxFB Line Number */
98−#define LTDC_L1CLUTWR (0xC4 + REG_OFS)/* L1 CLUT Write */
99−#define LTDC_L1YS1R (0xE0 + REG_OFS)/* L1 YCbCr Scale 1 */
100−#define LTDC_L1YS2R (0xE4 + REG_OFS)/* L1 YCbCr Scale 2 */
83+#define LTDC_L1C0R (ldev->caps.layer_regs[0]) /* L1 configuration 0 */
84+#define LTDC_L1C1R (ldev->caps.layer_regs[1]) /* L1 configuration 1 */
85+#define LTDC_L1RCR (ldev->caps.layer_regs[2]) /* L1 reload control */
86+#define LTDC_L1CR (ldev->caps.layer_regs[3]) /* L1 control register */
87+#define LTDC_L1WHPCR (ldev->caps.layer_regs[4]) /* L1 window horizontal position configuration */
88+#define LTDC_L1WVPCR (ldev->caps.layer_regs[5]) /* L1 window vertical position configuration */
89+#define LTDC_L1CKCR (ldev->caps.layer_regs[6]) /* L1 color keying configuration */
90+#define LTDC_L1PFCR (ldev->caps.layer_regs[7]) /* L1 pixel format configuration */
91+#define LTDC_L1CACR (ldev->caps.layer_regs[8]) /* L1 constant alpha configuration */
92+#define LTDC_L1DCCR (ldev->caps.layer_regs[9]) /* L1 default color configuration */
93+#define LTDC_L1BFCR (ldev->caps.layer_regs[10]) /* L1 blending factors configuration */
94+#define LTDC_L1BLCR (ldev->caps.layer_regs[11]) /* L1 burst length configuration */
95+#define LTDC_L1PCR (ldev->caps.layer_regs[12]) /* L1 planar configuration */
96+#define LTDC_L1CFBAR (ldev->caps.layer_regs[13]) /* L1 color frame buffer address */
97+#define LTDC_L1CFBLR (ldev->caps.layer_regs[14]) /* L1 color frame buffer length */
98+#define LTDC_L1CFBLNR (ldev->caps.layer_regs[15]) /* L1 color frame buffer line number */
99+#define LTDC_L1AFBA0R (ldev->caps.layer_regs[16]) /* L1 auxiliary frame buffer address 0 */
100+#define LTDC_L1AFBA1R (ldev->caps.layer_regs[17]) /* L1 auxiliary frame buffer address 1 */
101+#define LTDC_L1AFBLR (ldev->caps.layer_regs[18]) /* L1 auxiliary frame buffer length */
102+#define LTDC_L1AFBLNR (ldev->caps.layer_regs[19]) /* L1 auxiliary frame buffer line number */
103+#define LTDC_L1CLUTWR (ldev->caps.layer_regs[20]) /* L1 CLUT write */
104+#define LTDC_L1CYR0R (ldev->caps.layer_regs[21]) /* L1 Conversion YCbCr RGB 0 */
105+#define LTDC_L1CYR1R (ldev->caps.layer_regs[22]) /* L1 Conversion YCbCr RGB 1 */
106+#define LTDC_L1FPF0R (ldev->caps.layer_regs[23]) /* L1 Flexible Pixel Format 0 */
107+#define LTDC_L1FPF1R (ldev->caps.layer_regs[24]) /* L1 Flexible Pixel Format 1 */
101108
102109 /* Bit definitions */
103110 #define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
@@ -164,6 +171,10 @@ · 60 unmodified lines
164171 #define ISR_TERRIF BIT(2) /* Transfer ERRor Interrupt Flag */
165172 #define ISR_RRIF BIT(3) /* Register Reload Interrupt Flag */
166173
174+#define EDCR_OCYEN BIT(25) /* Output Conversion to YCbCr 422: ENable */
175+#define EDCR_OCYSEL BIT(26) /* Output Conversion to YCbCr 422: SELection of the CCIR */
176+#define EDCR_OCYCO BIT(27) /* Output Conversion to YCbCr 422: Chrominance Order */
177+
167178 #define LXCR_LEN BIT(0) /* Layer ENable */
168179 #define LXCR_COLKEN BIT(1) /* Color Keying Enable */
169180 #define LXCR_CLUTEN BIT(4) /* Color Look-Up Table ENable */
@@ -175,6 +186,7 @@ · 5 unmodified lines
175186 #define LXWVPCR_WVSPPOS GENMASK(26, 16) /* Window Vertical StoP POSition */
176187
177188 #define LXPFCR_PF GENMASK(2, 0) /* Pixel Format */
189+#define PF_FLEXIBLE 0x7 /* Flexible Pixel Format selected */
178190
179191 #define LXCACR_CONSTA GENMASK(7, 0) /* CONSTant Alpha */
180192
@@ -186,6 +198,25 @@ · 5 unmodified lines
186198
187199 #define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
188200
201+#define LXCR_C1R_YIA BIT(0) /* Ycbcr 422 Interleaved Ability */
202+#define LXCR_C1R_YSPA BIT(1) /* Ycbcr 420 Semi-Planar Ability */
203+#define LXCR_C1R_YFPA BIT(2) /* Ycbcr 420 Full-Planar Ability */
204+#define LXCR_C1R_SCA BIT(31) /* SCaling Ability*/
205+
206+#define LxPCR_YREN BIT(9) /* Y Rescale Enable for the color dynamic range */
207+#define LxPCR_OF BIT(8) /* Odd pixel First */
208+#define LxPCR_CBF BIT(7) /* CB component First */
209+#define LxPCR_YF BIT(6) /* Y component First */
210+#define LxPCR_YCM GENMASK(5, 4) /* Ycbcr Conversion Mode */
211+#define YCM_I 0x0 /* Interleaved 422 */
212+#define YCM_SP 0x1 /* Semi-Planar 420 */
213+#define YCM_FP 0x2 /* Full-Planar 420 */
214+#define LxPCR_YCEN BIT(3) /* YCbCr-to-RGB Conversion Enable */
215+
216+#define LXRCR_IMR BIT(0) /* IMmediate Reload */
217+#define LXRCR_VBR BIT(1) /* Vertical Blanking Reload */
218+#define LXRCR_GRMSK BIT(2) /* Global (centralized) Reload MaSKed */
219+
189220 #define CLUT_SIZE 256
190221
191222 #define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
@@ -201,8 +232,12 @@ enum ltdc_pix_fmt { · 9 unmodified lines
201232 /* RGB formats */
202233 PF_ARGB8888, /* ARGB [32 bits] */
203234 PF_RGBA8888, /* RGBA [32 bits] */
235+ PF_ABGR8888, /* ABGR [32 bits] */
236+ PF_BGRA8888, /* BGRA [32 bits] */
204237 PF_RGB888, /* RGB [24 bits] */
238+ PF_BGR888, /* BGR [24 bits] */
205239 PF_RGB565, /* RGB [16 bits] */
240+ PF_BGR565, /* BGR [16 bits] */
206241 PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
207242 PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
208243 /* Indexed formats */
@@ -234,36 +269,198 @@ static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = { · 25 unmodified lines
234269 PF_ARGB4444 /* 0x07 */
235270 };
236271
237−static const u64 ltdc_format_modifiers[] = {
238− DRM_FORMAT_MOD_LINEAR,
239− DRM_FORMAT_MOD_INVALID
272+static const enum ltdc_pix_fmt ltdc_pix_fmt_a2[NB_PF] = {
273+ PF_ARGB8888, /* 0x00 */
274+ PF_ABGR8888, /* 0x01 */
275+ PF_RGBA8888, /* 0x02 */
276+ PF_BGRA8888, /* 0x03 */
277+ PF_RGB565, /* 0x04 */
278+ PF_BGR565, /* 0x05 */
279+ PF_RGB888, /* 0x06 */
280+ PF_NONE /* 0x07 */
240281 };
241282
242−static inline u32 reg_read(void __iomem *base, u32 reg)
243−{
244− return readl_relaxed(base + reg);
245−}
283+static const u32 ltdc_drm_fmt_a0[] = {
284+ DRM_FORMAT_ARGB8888,
285+ DRM_FORMAT_XRGB8888,
286+ DRM_FORMAT_RGB888,
287+ DRM_FORMAT_RGB565,
288+ DRM_FORMAT_ARGB1555,
289+ DRM_FORMAT_XRGB1555,
290+ DRM_FORMAT_ARGB4444,
291+ DRM_FORMAT_XRGB4444,
292+ DRM_FORMAT_C8
293+};
246294
247−static inline void reg_write(void __iomem *base, u32 reg, u32 val)
248−{
249− writel_relaxed(val, base + reg);
250−}
295+static const u32 ltdc_drm_fmt_a1[] = {
296+ DRM_FORMAT_ARGB8888,
297+ DRM_FORMAT_XRGB8888,
298+ DRM_FORMAT_RGB888,
299+ DRM_FORMAT_RGB565,
300+ DRM_FORMAT_RGBA8888,
301+ DRM_FORMAT_RGBX8888,
302+ DRM_FORMAT_ARGB1555,
303+ DRM_FORMAT_XRGB1555,
304+ DRM_FORMAT_ARGB4444,
305+ DRM_FORMAT_XRGB4444,
306+ DRM_FORMAT_C8
307+};
251308
252−static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
253−{
254− reg_write(base, reg, reg_read(base, reg) | mask);
255−}
309+static const u32 ltdc_drm_fmt_a2[] = {
310+ DRM_FORMAT_ARGB8888,
311+ DRM_FORMAT_XRGB8888,
312+ DRM_FORMAT_ABGR8888,
313+ DRM_FORMAT_XBGR8888,
314+ DRM_FORMAT_RGBA8888,
315+ DRM_FORMAT_RGBX8888,
316+ DRM_FORMAT_BGRA8888,
317+ DRM_FORMAT_BGRX8888,
318+ DRM_FORMAT_RGB565,
319+ DRM_FORMAT_BGR565,
320+ DRM_FORMAT_RGB888,
321+ DRM_FORMAT_BGR888,
322+ DRM_FORMAT_ARGB1555,
323+ DRM_FORMAT_XRGB1555,
324+ DRM_FORMAT_ARGB4444,
325+ DRM_FORMAT_XRGB4444,
326+ DRM_FORMAT_C8
327+};
256328
257−static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
258−{
259− reg_write(base, reg, reg_read(base, reg) & ~mask);
260−}
329+static const u32 ltdc_drm_fmt_ycbcr_cp[] = {
330+ DRM_FORMAT_YUYV,
331+ DRM_FORMAT_YVYU,
332+ DRM_FORMAT_UYVY,
333+ DRM_FORMAT_VYUY
334+};
261335
262−static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
263− u32 val)
264−{
265− reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
266−}
336+static const u32 ltdc_drm_fmt_ycbcr_sp[] = {
337+ DRM_FORMAT_NV12,
338+ DRM_FORMAT_NV21
339+};
340+
341+static const u32 ltdc_drm_fmt_ycbcr_fp[] = {
342+ DRM_FORMAT_YUV420,
343+ DRM_FORMAT_YVU420
344+};
345+
346+/* Layer register offsets */
347+static const u32 ltdc_layer_regs_a0[] = {
348+ 0x80, /* L1 configuration 0 */
349+ 0x00, /* not available */
350+ 0x00, /* not available */
351+ 0x84, /* L1 control register */
352+ 0x88, /* L1 window horizontal position configuration */
353+ 0x8c, /* L1 window vertical position configuration */
354+ 0x90, /* L1 color keying configuration */
355+ 0x94, /* L1 pixel format configuration */
356+ 0x98, /* L1 constant alpha configuration */
357+ 0x9c, /* L1 default color configuration */
358+ 0xa0, /* L1 blending factors configuration */
359+ 0x00, /* not available */
360+ 0x00, /* not available */
361+ 0xac, /* L1 color frame buffer address */
362+ 0xb0, /* L1 color frame buffer length */
363+ 0xb4, /* L1 color frame buffer line number */
364+ 0x00, /* not available */
365+ 0x00, /* not available */
366+ 0x00, /* not available */
367+ 0x00, /* not available */
368+ 0xc4, /* L1 CLUT write */
369+ 0x00, /* not available */
370+ 0x00, /* not available */
371+ 0x00, /* not available */
372+ 0x00 /* not available */
373+};
374+
375+static const u32 ltdc_layer_regs_a1[] = {
376+ 0x80, /* L1 configuration 0 */
377+ 0x84, /* L1 configuration 1 */
378+ 0x00, /* L1 reload control */
379+ 0x88, /* L1 control register */
380+ 0x8c, /* L1 window horizontal position configuration */
381+ 0x90, /* L1 window vertical position configuration */
382+ 0x94, /* L1 color keying configuration */
383+ 0x98, /* L1 pixel format configuration */
384+ 0x9c, /* L1 constant alpha configuration */
385+ 0xa0, /* L1 default color configuration */
386+ 0xa4, /* L1 blending factors configuration */
387+ 0xa8, /* L1 burst length configuration */
388+ 0x00, /* not available */
389+ 0xac, /* L1 color frame buffer address */
390+ 0xb0, /* L1 color frame buffer length */
391+ 0xb4, /* L1 color frame buffer line number */
392+ 0xb8, /* L1 auxiliary frame buffer address 0 */
393+ 0xbc, /* L1 auxiliary frame buffer address 1 */
394+ 0xc0, /* L1 auxiliary frame buffer length */
395+ 0xc4, /* L1 auxiliary frame buffer line number */
396+ 0xc8, /* L1 CLUT write */
397+ 0x00, /* not available */
398+ 0x00, /* not available */
399+ 0x00, /* not available */
400+ 0x00 /* not available */
401+};
402+
403+static const u32 ltdc_layer_regs_a2[] = {
404+ 0x100, /* L1 configuration 0 */
405+ 0x104, /* L1 configuration 1 */
406+ 0x108, /* L1 reload control */
407+ 0x10c, /* L1 control register */
408+ 0x110, /* L1 window horizontal position configuration */
409+ 0x114, /* L1 window vertical position configuration */
410+ 0x118, /* L1 color keying configuration */
411+ 0x11c, /* L1 pixel format configuration */
412+ 0x120, /* L1 constant alpha configuration */
413+ 0x124, /* L1 default color configuration */
414+ 0x128, /* L1 blending factors configuration */
415+ 0x12c, /* L1 burst length configuration */
416+ 0x130, /* L1 planar configuration */
417+ 0x134, /* L1 color frame buffer address */
418+ 0x138, /* L1 color frame buffer length */
419+ 0x13c, /* L1 color frame buffer line number */
420+ 0x140, /* L1 auxiliary frame buffer address 0 */
421+ 0x144, /* L1 auxiliary frame buffer address 1 */
422+ 0x148, /* L1 auxiliary frame buffer length */
423+ 0x14c, /* L1 auxiliary frame buffer line number */
424+ 0x150, /* L1 CLUT write */
425+ 0x16c, /* L1 Conversion YCbCr RGB 0 */
426+ 0x170, /* L1 Conversion YCbCr RGB 1 */
427+ 0x174, /* L1 Flexible Pixel Format 0 */
428+ 0x178 /* L1 Flexible Pixel Format 1 */
429+};
430+
431+static const u64 ltdc_format_modifiers[] = {
432+ DRM_FORMAT_MOD_LINEAR,
433+ DRM_FORMAT_MOD_INVALID
434+};
435+
436+static const struct regmap_config stm32_ltdc_regmap_cfg = {
437+ .reg_bits = 32,
438+ .val_bits = 32,
439+ .reg_stride = sizeof(u32),
440+ .max_register = 0x400,
441+ .use_relaxed_mmio = true,
442+ .cache_type = REGCACHE_NONE,
443+};
444+
445+static const u32 ltdc_ycbcr2rgb_coeffs[DRM_COLOR_ENCODING_MAX][DRM_COLOR_RANGE_MAX][2] = {
446+ [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
447+ 0x02040199, /* (b_cb = 516 / r_cr = 409) */
448+ 0x006400D0 /* (g_cb = 100 / g_cr = 208) */
449+ },
450+ [DRM_COLOR_YCBCR_BT601][DRM_COLOR_YCBCR_FULL_RANGE] = {
451+ 0x01C60167, /* (b_cb = 454 / r_cr = 359) */
452+ 0x005800B7 /* (g_cb = 88 / g_cr = 183) */
453+ },
454+ [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_LIMITED_RANGE] = {
455+ 0x021D01CB, /* (b_cb = 541 / r_cr = 459) */
456+ 0x00370089 /* (g_cb = 55 / g_cr = 137) */
457+ },
458+ [DRM_COLOR_YCBCR_BT709][DRM_COLOR_YCBCR_FULL_RANGE] = {
459+ 0x01DB0193, /* (b_cb = 475 / r_cr = 403) */
460+ 0x00300078 /* (g_cb = 48 / g_cr = 120) */
461+ }
462+ /* BT2020 not supported */
463+};
267464
268465 static inline struct ltdc_device *crtc_to_ltdc(struct drm_crtc *crtc)
269466 {
@@ -289,16 +486,30 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt) · 19 unmodified lines
289486 case DRM_FORMAT_XRGB8888:
290487 pf = PF_ARGB8888;
291488 break;
489+ case DRM_FORMAT_ABGR8888:
490+ case DRM_FORMAT_XBGR8888:
491+ pf = PF_ABGR8888;
492+ break;
292493 case DRM_FORMAT_RGBA8888:
293494 case DRM_FORMAT_RGBX8888:
294495 pf = PF_RGBA8888;
295496 break;
497+ case DRM_FORMAT_BGRA8888:
498+ case DRM_FORMAT_BGRX8888:
499+ pf = PF_BGRA8888;
500+ break;
296501 case DRM_FORMAT_RGB888:
297502 pf = PF_RGB888;
298503 break;
504+ case DRM_FORMAT_BGR888:
505+ pf = PF_BGR888;
506+ break;
299507 case DRM_FORMAT_RGB565:
300508 pf = PF_RGB565;
301509 break;
510+ case DRM_FORMAT_BGR565:
511+ pf = PF_BGR565;
512+ break;
302513 case DRM_FORMAT_ARGB1555:
303514 case DRM_FORMAT_XRGB1555:
304515 pf = PF_ARGB1555;
@@ -319,49 +530,138 @@ static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt) · 14 unmodified lines
319530 return pf;
320531 }
321532
322−static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
533+static inline u32 ltdc_set_flexible_pixel_format(struct drm_plane *plane, enum ltdc_pix_fmt pix_fmt)
323534 {
324− switch (pf) {
325− case PF_ARGB8888:
326− return DRM_FORMAT_ARGB8888;
327− case PF_RGBA8888:
328− return DRM_FORMAT_RGBA8888;
329− case PF_RGB888:
330− return DRM_FORMAT_RGB888;
331− case PF_RGB565:
332− return DRM_FORMAT_RGB565;
535+ struct ltdc_device *ldev = plane_to_ltdc(plane);
536+ u32 lofs = plane->index * LAY_OFS, ret = PF_FLEXIBLE;
537+ int psize, alen, apos, rlen, rpos, glen, gpos, blen, bpos;
538+
539+ switch (pix_fmt) {
540+ case PF_BGR888:
541+ psize = 3;
542+ alen = 0; apos = 0; rlen = 8; rpos = 0;
543+ glen = 8; gpos = 8; blen = 8; bpos = 16;
544+ break;
333545 case PF_ARGB1555:
334− return DRM_FORMAT_ARGB1555;
546+ psize = 2;
547+ alen = 1; apos = 15; rlen = 5; rpos = 10;
548+ glen = 5; gpos = 5; blen = 5; bpos = 0;
549+ break;
335550 case PF_ARGB4444:
336− return DRM_FORMAT_ARGB4444;
551+ psize = 2;
552+ alen = 4; apos = 12; rlen = 4; rpos = 8;
553+ glen = 4; gpos = 4; blen = 4; bpos = 0;
554+ break;
337555 case PF_L8:
338− return DRM_FORMAT_C8;
339− case PF_AL44: /* No DRM support */
340− case PF_AL88: /* No DRM support */
341− case PF_NONE:
556+ psize = 1;
557+ alen = 0; apos = 0; rlen = 8; rpos = 0;
558+ glen = 8; gpos = 0; blen = 8; bpos = 0;
559+ break;
560+ case PF_AL44:
561+ psize = 1;
562+ alen = 4; apos = 4; rlen = 4; rpos = 0;
563+ glen = 4; gpos = 0; blen = 4; bpos = 0;
564+ break;
565+ case PF_AL88:
566+ psize = 2;
567+ alen = 8; apos = 8; rlen = 8; rpos = 0;
568+ glen = 8; gpos = 0; blen = 8; bpos = 0;
569+ break;
342570 default:
343− return 0;
571+ ret = NB_PF; /* error case, trace msg is handled by the caller */
572+ break;
344573 }
574+
575+ if (ret == PF_FLEXIBLE) {
576+ regmap_write(ldev->regmap, LTDC_L1FPF0R + lofs,
577+ (rlen << 14) + (rpos << 9) + (alen << 5) + apos);
578+
579+ regmap_write(ldev->regmap, LTDC_L1FPF1R + lofs,
580+ (psize << 18) + (blen << 14) + (bpos << 9) + (glen << 5) + gpos);
581+ }
582+
583+ return ret;
345584 }
346585
347−static inline u32 get_pixelformat_without_alpha(u32 drm)
586+/*
587+ * All non-alpha color formats derived from native alpha color formats are
588+ * either characterized by a FourCC format code
589+ */
590+static inline u32 is_xrgb(u32 drm)
348591 {
349− switch (drm) {
350− case DRM_FORMAT_ARGB4444:
351− return DRM_FORMAT_XRGB4444;
352− case DRM_FORMAT_RGBA4444:
353− return DRM_FORMAT_RGBX4444;
354− case DRM_FORMAT_ARGB1555:
355− return DRM_FORMAT_XRGB1555;
356− case DRM_FORMAT_RGBA5551:
357− return DRM_FORMAT_RGBX5551;
358− case DRM_FORMAT_ARGB8888:
359− return DRM_FORMAT_XRGB8888;
360− case DRM_FORMAT_RGBA8888:
361− return DRM_FORMAT_RGBX8888;
592+ return ((drm & 0xFF) == 'X' || ((drm >> 8) & 0xFF) == 'X');
593+}
594+
595+static inline void ltdc_set_ycbcr_config(struct drm_plane *plane, u32 drm_pix_fmt)
596+{
597+ struct ltdc_device *ldev = plane_to_ltdc(plane);
598+ struct drm_plane_state *state = plane->state;
599+ u32 lofs = plane->index * LAY_OFS;
600+ u32 val;
601+
602+ switch (drm_pix_fmt) {
603+ case DRM_FORMAT_YUYV:
604+ val = (YCM_I << 4) | LxPCR_YF | LxPCR_CBF;
605+ break;
606+ case DRM_FORMAT_YVYU:
607+ val = (YCM_I << 4) | LxPCR_YF;
608+ break;
609+ case DRM_FORMAT_UYVY:
610+ val = (YCM_I << 4) | LxPCR_CBF;
611+ break;
612+ case DRM_FORMAT_VYUY:
613+ val = (YCM_I << 4);
614+ break;
615+ case DRM_FORMAT_NV12:
616+ val = (YCM_SP << 4) | LxPCR_CBF;
617+ break;
618+ case DRM_FORMAT_NV21:
619+ val = (YCM_SP << 4);
620+ break;
621+ case DRM_FORMAT_YUV420:
622+ case DRM_FORMAT_YVU420:
623+ val = (YCM_FP << 4);
624+ break;
362625 default:
363− return 0;
626+ /* RGB or not a YCbCr supported format */
627+ break;
628+ }
629+
630+ /* Enable limited range */
631+ if (state->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE)
632+ val |= LxPCR_YREN;
633+
634+ /* enable ycbcr conversion */
635+ val |= LxPCR_YCEN;
636+
637+ regmap_write(ldev->regmap, LTDC_L1PCR + lofs, val);
638+}
639+
640+static inline void ltdc_set_ycbcr_coeffs(struct drm_plane *plane)
641+{
642+ struct ltdc_device *ldev = plane_to_ltdc(plane);
643+ struct drm_plane_state *state = plane->state;
644+ enum drm_color_encoding enc = state->color_encoding;
645+ enum drm_color_range ran = state->color_range;
646+ u32 lofs = plane->index * LAY_OFS;
647+
648+ if (enc != DRM_COLOR_YCBCR_BT601 && enc != DRM_COLOR_YCBCR_BT709) {
649+ DRM_ERROR("color encoding %d not supported, use bt601 by default\n", enc);
650+ /* set by default color encoding to DRM_COLOR_YCBCR_BT601 */
651+ enc = DRM_COLOR_YCBCR_BT601;
652+ }
653+
654+ if (ran != DRM_COLOR_YCBCR_LIMITED_RANGE && ran != DRM_COLOR_YCBCR_FULL_RANGE) {
655+ DRM_ERROR("color range %d not supported, use limited range by default\n", ran);
656+ /* set by default color range to DRM_COLOR_YCBCR_LIMITED_RANGE */
657+ ran = DRM_COLOR_YCBCR_LIMITED_RANGE;
364658 }
659+
660+ DRM_DEBUG_DRIVER("Color encoding=%d, range=%d\n", enc, ran);
661+ regmap_write(ldev->regmap, LTDC_L1CYR0R + lofs,
662+ ltdc_ycbcr2rgb_coeffs[enc][ran][0]);
663+ regmap_write(ldev->regmap, LTDC_L1CYR1R + lofs,
664+ ltdc_ycbcr2rgb_coeffs[enc][ran][1]);
365665 }
366666
367667 static irqreturn_t ltdc_irq_thread(int irq, void *arg)
@@ -390,9 +690,13 @@ static irqreturn_t ltdc_irq(int irq, void *arg) · 22 unmodified lines
390690 struct drm_device *ddev = arg;
391691 struct ltdc_device *ldev = ddev->dev_private;
392692
393− /* Read & Clear the interrupt status */
394− ldev->irq_status = reg_read(ldev->regs, LTDC_ISR);
395− reg_write(ldev->regs, LTDC_ICR, ldev->irq_status);
693+ /*
694+ * Read & Clear the interrupt status
695+ * In order to write / read registers in this critical section
696+ * very quickly, the regmap functions are not used.
697+ */
698+ ldev->irq_status = readl_relaxed(ldev->regs + LTDC_ISR);
699+ writel_relaxed(ldev->irq_status, ldev->regs + LTDC_ICR);
396700
397701 return IRQ_WAKE_THREAD;
398702 }
@@ -416,7 +720,7 @@ static void ltdc_crtc_update_clut(struct drm_crtc *crtc) · 17 unmodified lines
416720 for (i = 0; i < CLUT_SIZE; i++, lut++) {
417721 val = ((lut->red << 8) & 0xff0000) | (lut->green & 0xff00) |
418722 (lut->blue >> 8) | (i << 24);
419− reg_write(ldev->regs, LTDC_L1CLUTWR, val);
723+ regmap_write(ldev->regmap, LTDC_L1CLUTWR, val);
420724 }
421725 }
422726
@@ -431,13 +735,14 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, · 8 unmodified lines
431735 pm_runtime_get_sync(ddev->dev);
432736
433737 /* Sets the background color value */
434− reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
738+ regmap_write(ldev->regmap, LTDC_BCCR, BCCR_BCBLACK);
435739
436740 /* Enable IRQ */
437− reg_set(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
741+ regmap_set_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
438742
439743 /* Commit shadow registers = update planes at next vblank */
440− reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
744+ if (!ldev->caps.plane_reg_shadow)
745+ regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
441746
442747 drm_crtc_vblank_on(crtc);
443748 }
@@ -453,10 +758,11 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc, · 9 unmodified lines
453758 drm_crtc_vblank_off(crtc);
454759
455760 /* disable IRQ */
456− reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
761+ regmap_clear_bits(ldev->regmap, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
457762
458763 /* immediately commit disable of layers before switching off LTDC */
459− reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
764+ if (!ldev->caps.plane_reg_shadow)
765+ regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_IMR);
460766
461767 pm_runtime_put_sync(ddev->dev);
462768 }
@@ -533,6 +839,7 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) · 70 unmodified lines
533839 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
534840 u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
535841 u32 total_width, total_height;
842+ u32 bus_formats = MEDIA_BUS_FMT_RGB888_1X24;
536843 u32 bus_flags = 0;
537844 u32 val;
538845 int ret;
@@ -558,8 +865,11 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) · 19 unmodified lines
558865
559866 if (bridge && bridge->timings)
560867 bus_flags = bridge->timings->input_bus_flags;
561− else if (connector)
868+ else if (connector) {
562869 bus_flags = connector->display_info.bus_flags;
870+ if (connector->display_info.num_bus_formats)
871+ bus_formats = connector->display_info.bus_formats[0];
872+ }
563873
564874 if (!pm_runtime_active(ddev->dev)) {
565875 ret = pm_runtime_get_sync(ddev->dev);
@@ -604,26 +914,56 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) · 38 unmodified lines
604914 if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
605915 val |= GCR_PCPOL;
606916
607− reg_update_bits(ldev->regs, LTDC_GCR,
608− GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
917+ regmap_update_bits(ldev->regmap, LTDC_GCR,
918+ GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
609919
610920 /* Set Synchronization size */
611921 val = (hsync << 16) | vsync;
612− reg_update_bits(ldev->regs, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
922+ regmap_update_bits(ldev->regmap, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
613923
614924 /* Set Accumulated Back porch */
615925 val = (accum_hbp << 16) | accum_vbp;
616− reg_update_bits(ldev->regs, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
926+ regmap_update_bits(ldev->regmap, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
617927
618928 /* Set Accumulated Active Width */
619929 val = (accum_act_w << 16) | accum_act_h;
620− reg_update_bits(ldev->regs, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
930+ regmap_update_bits(ldev->regmap, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
621931
622932 /* Set total width & height */
623933 val = (total_width << 16) | total_height;
624− reg_update_bits(ldev->regs, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
934+ regmap_update_bits(ldev->regmap, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
625935
626− reg_write(ldev->regs, LTDC_LIPCR, (accum_act_h + 1));
936+ regmap_write(ldev->regmap, LTDC_LIPCR, (accum_act_h + 1));
937+
938+ /* Configure the output format (hw version dependent) */
939+ if (ldev->caps.ycbcr_output) {
940+ /* Input video dynamic_range & colorimetry */
941+ int vic = drm_match_cea_mode(mode);
942+ u32 val;
943+
944+ if (vic == 6 || vic == 7 || vic == 21 || vic == 22 ||
945+ vic == 2 || vic == 3 || vic == 17 || vic == 18)
946+ /* ITU-R BT.601 */
947+ val = 0;
948+ else
949+ /* ITU-R BT.709 */
950+ val = EDCR_OCYSEL;
951+
952+ switch (bus_formats) {
953+ case MEDIA_BUS_FMT_YUYV8_1X16:
954+ /* enable ycbcr output converter */
955+ regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | val);
956+ break;
957+ case MEDIA_BUS_FMT_YVYU8_1X16:
958+ /* enable ycbcr output converter & invert chrominance order */
959+ regmap_write(ldev->regmap, LTDC_EDCR, EDCR_OCYEN | EDCR_OCYCO | val);
960+ break;
961+ default:
962+ /* disable ycbcr output converter */
963+ regmap_write(ldev->regmap, LTDC_EDCR, 0);
964+ break;
965+ }
966+ }
627967 }
628968
629969 static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
@@ -638,7 +978,8 @@ static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc, · 8 unmodified lines
638978 ltdc_crtc_update_clut(crtc);
639979
640980 /* Commit shadow registers = update planes at next vblank */
641− reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
981+ if (!ldev->caps.plane_reg_shadow)
982+ regmap_set_bits(ldev->regmap, LTDC_SRCR, SRCR_VBR);
642983
643984 if (event) {
644985 crtc->state->event = NULL;
@@ -680,10 +1021,14 @@ static bool ltdc_crtc_get_scanout_position(struct drm_crtc *crtc, · 35 unmodified lines
6801021 * simplify the code and only test if line > vactive_end
6811022 */
6821023 if (pm_runtime_active(ddev->dev)) {
683− line = reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS;
684− vactive_start = reg_read(ldev->regs, LTDC_BPCR) & BPCR_AVBP;
685− vactive_end = reg_read(ldev->regs, LTDC_AWCR) & AWCR_AAH;
686− vtotal = reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH;
1024+ regmap_read(ldev->regmap, LTDC_CPSR, &line);
1025+ line &= CPSR_CYPOS;
1026+ regmap_read(ldev->regmap, LTDC_BPCR, &vactive_start);
1027+ vactive_start &= BPCR_AVBP;
1028+ regmap_read(ldev->regmap, LTDC_AWCR, &vactive_end);
1029+ vactive_end &= AWCR_AAH;
1030+ regmap_read(ldev->regmap, LTDC_TWCR, &vtotal);
1031+ vtotal &= TWCR_TOTALH;
6871032
6881033 if (line > vactive_end)
6891034 *vpos = line - vtotal - vactive_start;
@@ -719,7 +1064,7 @@ static int ltdc_crtc_enable_vblank(struct drm_crtc *crtc) · 29 unmodified lines
7191064 DRM_DEBUG_DRIVER("\n");
7201065
7211066 if (state->enable)
722− reg_set(ldev->regs, LTDC_IER, IER_LIE);
1067+ regmap_set_bits(ldev->regmap, LTDC_IER, IER_LIE);
7231068 else
7241069 return -EPERM;
7251070
@@ -731,7 +1076,7 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) · 5 unmodified lines
7311076 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
7321077
7331078 DRM_DEBUG_DRIVER("\n");
734− reg_clear(ldev->regs, LTDC_IER, IER_LIE);
1079+ regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE);
7351080 }
7361081
7371082 static const struct drm_crtc_funcs ltdc_crtc_funcs = {
@@ -789,7 +1134,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 51 unmodified lines
7891134 u32 y0 = newstate->crtc_y;
7901135 u32 y1 = newstate->crtc_y + newstate->crtc_h - 1;
7911136 u32 src_x, src_y, src_w, src_h;
792− u32 val, pitch_in_bytes, line_length, paddr, ahbp, avbp, bpcr;
1137+ u32 val, pitch_in_bytes, line_length, line_number, paddr, ahbp, avbp, bpcr;
7931138 enum ltdc_pix_fmt pf;
7941139
7951140 if (!newstate->crtc || !fb) {
@@ -809,19 +1154,20 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 13 unmodified lines
8091154 newstate->crtc_w, newstate->crtc_h,
8101155 newstate->crtc_x, newstate->crtc_y);
8111156
812− bpcr = reg_read(ldev->regs, LTDC_BPCR);
1157+ regmap_read(ldev->regmap, LTDC_BPCR, &bpcr);
1158+
8131159 ahbp = (bpcr & BPCR_AHBP) >> 16;
8141160 avbp = bpcr & BPCR_AVBP;
8151161
8161162 /* Configures the horizontal start and stop position */
8171163 val = ((x1 + 1 + ahbp) << 16) + (x0 + 1 + ahbp);
818− reg_update_bits(ldev->regs, LTDC_L1WHPCR + lofs,
819− LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS, val);
1164+ regmap_write_bits(ldev->regmap, LTDC_L1WHPCR + lofs,
1165+ LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS, val);
8201166
8211167 /* Configures the vertical start and stop position */
8221168 val = ((y1 + 1 + avbp) << 16) + (y0 + 1 + avbp);
823− reg_update_bits(ldev->regs, LTDC_L1WVPCR + lofs,
824− LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS, val);
1169+ regmap_write_bits(ldev->regmap, LTDC_L1WVPCR + lofs,
1170+ LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS, val);
8251171
8261172 /* Specifies the pixel format */
8271173 pf = to_ltdc_pixelformat(fb->format->format);
@@ -829,24 +1175,27 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 1 unmodified line
8291175 if (ldev->caps.pix_fmt_hw[val] == pf)
8301176 break;
8311177
1178+ /* Use the flexible color format feature if necessary and available */
1179+ if (ldev->caps.pix_fmt_flex && val == NB_PF)
1180+ val = ltdc_set_flexible_pixel_format(plane, pf);
1181+
8321182 if (val == NB_PF) {
8331183 DRM_ERROR("Pixel format %.4s not supported\n",
8341184 (char *)&fb->format->format);
8351185 val = 0; /* set by default ARGB 32 bits */
8361186 }
837− reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
1187+ regmap_write_bits(ldev->regmap, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
8381188
8391189 /* Configures the color frame buffer pitch in bytes & line length */
8401190 pitch_in_bytes = fb->pitches[0];
8411191 line_length = fb->format->cpp[0] *
8421192 (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
8431193 val = ((pitch_in_bytes << 16) | line_length);
844− reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
845− LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
1194+ regmap_write_bits(ldev->regmap, LTDC_L1CFBLR + lofs, LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
8461195
8471196 /* Specifies the constant alpha value */
8481197 val = newstate->alpha >> 8;
849− reg_update_bits(ldev->regs, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
1198+ regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, val);
8501199
8511200 /* Specifies the blending factors */
8521201 val = BF1_PAXCA | BF2_1PAXCA;
@@ -858,24 +1207,98 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 5 unmodified lines
8581207 plane->type != DRM_PLANE_TYPE_PRIMARY)
8591208 val = BF1_PAXCA | BF2_1PAXCA;
8601209
861− reg_update_bits(ldev->regs, LTDC_L1BFCR + lofs,
862− LXBFCR_BF2 | LXBFCR_BF1, val);
1210+ regmap_write_bits(ldev->regmap, LTDC_L1BFCR + lofs, LXBFCR_BF2 | LXBFCR_BF1, val);
8631211
8641212 /* Configures the frame buffer line number */
865− val = y1 - y0 + 1;
866− reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, val);
1213+ line_number = y1 - y0 + 1;
1214+ regmap_write_bits(ldev->regmap, LTDC_L1CFBLNR + lofs, LXCFBLNR_CFBLN, line_number);
8671215
8681216 /* Sets the FB address */
8691217 paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 0);
8701218
8711219 DRM_DEBUG_DRIVER("fb: phys 0x%08x", paddr);
872− reg_write(ldev->regs, LTDC_L1CFBAR + lofs, paddr);
1220+ regmap_write(ldev->regmap, LTDC_L1CFBAR + lofs, paddr);
1221+
1222+ if (ldev->caps.ycbcr_input) {
1223+ if (fb->format->is_yuv) {
1224+ switch (fb->format->format) {
1225+ case DRM_FORMAT_NV12:
1226+ case DRM_FORMAT_NV21:
1227+ /* Configure the auxiliary frame buffer address 0 & 1 */
1228+ paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1229+ regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1230+ regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr + 1);
1231+
1232+ /* Configure the buffer length */
1233+ val = ((pitch_in_bytes << 16) | line_length);
1234+ regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1235+
1236+ /* Configure the frame buffer line number */
1237+ val = (line_number >> 1);
1238+ regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1239+ break;
1240+ case DRM_FORMAT_YUV420:
1241+ /* Configure the auxiliary frame buffer address 0 */
1242+ paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1243+ regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1244+
1245+ /* Configure the auxiliary frame buffer address 1 */
1246+ paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 2);
1247+ regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr);
1248+
1249+ line_length = ((fb->format->cpp[0] * (x1 - x0 + 1)) >> 1) +
1250+ (ldev->caps.bus_width >> 3) - 1;
1251+
1252+ /* Configure the buffer length */
1253+ val = (((pitch_in_bytes >> 1) << 16) | line_length);
1254+ regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1255+
1256+ /* Configure the frame buffer line number */
1257+ val = (line_number >> 1);
1258+ regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1259+ break;
1260+ case DRM_FORMAT_YVU420:
1261+ /* Configure the auxiliary frame buffer address 0 */
1262+ paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 2);
1263+ regmap_write(ldev->regmap, LTDC_L1AFBA0R + lofs, paddr);
1264+
1265+ /* Configure the auxiliary frame buffer address 1 */
1266+ paddr = (u32)drm_fb_cma_get_gem_addr(fb, newstate, 1);
1267+ regmap_write(ldev->regmap, LTDC_L1AFBA1R + lofs, paddr);
1268+
1269+ line_length = ((fb->format->cpp[0] * (x1 - x0 + 1)) >> 1) +
1270+ (ldev->caps.bus_width >> 3) - 1;
1271+
1272+ /* Configure the buffer length */
1273+ val = (((pitch_in_bytes >> 1) << 16) | line_length);
1274+ regmap_write(ldev->regmap, LTDC_L1AFBLR + lofs, val);
1275+
1276+ /* Configure the frame buffer line number */
1277+ val = (line_number >> 1);
1278+ regmap_write(ldev->regmap, LTDC_L1AFBLNR + lofs, val);
1279+ break;
1280+ }
1281+
1282+ /* Configure YCbC conversion coefficient */
1283+ ltdc_set_ycbcr_coeffs(plane);
1284+
1285+ /* Configure YCbCr format and enable/disable conversion */
1286+ ltdc_set_ycbcr_config(plane, fb->format->format);
1287+ } else {
1288+ /* disable ycbcr conversion */
1289+ regmap_write(ldev->regmap, LTDC_L1PCR + lofs, 0);
1290+ }
1291+ }
8731292
8741293 /* Enable layer and CLUT if needed */
8751294 val = fb->format->format == DRM_FORMAT_C8 ? LXCR_CLUTEN : 0;
8761295 val |= LXCR_LEN;
877− reg_update_bits(ldev->regs, LTDC_L1CR + lofs,
878− LXCR_LEN | LXCR_CLUTEN, val);
1296+ regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN, val);
1297+
1298+ /* Commit shadow registers = update plane at next vblank */
1299+ if (ldev->caps.plane_reg_shadow)
1300+ regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
1301+ LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, LXRCR_VBR);
8791302
8801303 ldev->plane_fpsi[plane->index].counter++;
8811304
@@ -900,7 +1323,12 @@ static void ltdc_plane_atomic_disable(struct drm_plane *plane, · 18 unmodified lines
9001323 u32 lofs = plane->index * LAY_OFS;
9011324
9021325 /* disable layer */
903− reg_clear(ldev->regs, LTDC_L1CR + lofs, LXCR_LEN);
1326+ regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN, 0);
1327+
1328+ /* Commit shadow registers = update plane at next vblank */
1329+ if (ldev->caps.plane_reg_shadow)
1330+ regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
1331+ LXRCR_IMR | LXRCR_VBR | LXRCR_GRMSK, LXRCR_VBR);
9041332
9051333 DRM_DEBUG_DRIVER("CRTC:%d plane:%d\n",
9061334 oldstate->crtc->base.id, plane->base.id);
@@ -925,16 +1353,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p, · 18 unmodified lines
9251353 fpsi->counter = 0;
9261354 }
9271355
928−static bool ltdc_plane_format_mod_supported(struct drm_plane *plane,
929− u32 format,
930− u64 modifier)
931−{
932− if (modifier == DRM_FORMAT_MOD_LINEAR)
933− return true;
934−
935− return false;
936−}
937−
9381356 static const struct drm_plane_funcs ltdc_plane_funcs = {
9391357 .update_plane = drm_atomic_helper_update_plane,
9401358 .disable_plane = drm_atomic_helper_disable_plane,
@@ -943,7 +1361,6 @@ static const struct drm_plane_funcs ltdc_plane_funcs = { · 2 unmodified lines
9431361 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
9441362 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
9451363 .atomic_print_state = ltdc_plane_atomic_print_state,
946− .format_mod_supported = ltdc_plane_format_mod_supported,
9471364 };
9481365
9491366 static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
@@ -953,36 +1370,58 @@ static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = { · 3 unmodified lines
9531370 };
9541371
9551372 static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
956− enum drm_plane_type type)
1373+ enum drm_plane_type type,
1374+ int index)
9571375 {
9581376 unsigned long possible_crtcs = CRTC_MASK;
9591377 struct ltdc_device *ldev = ddev->dev_private;
9601378 struct device *dev = ddev->dev;
9611379 struct drm_plane *plane;
9621380 unsigned int i, nb_fmt = 0;
963− u32 formats[NB_PF * 2];
964− u32 drm_fmt, drm_fmt_no_alpha;
1381+ u32 *formats;
1382+ u32 drm_fmt;
9651383 const u64 *modifiers = ltdc_format_modifiers;
1384+ u32 lofs = index * LAY_OFS;
1385+ u32 val;
9661386 int ret;
9671387
968− /* Get supported pixel formats */
969− for (i = 0; i < NB_PF; i++) {
970− drm_fmt = to_drm_pixelformat(ldev->caps.pix_fmt_hw[i]);
971− if (!drm_fmt)
972− continue;
973− formats[nb_fmt++] = drm_fmt;
1388+ /* Allocate the biggest size according to supported color formats */
1389+ formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb +
1390+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp) +
1391+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) +
1392+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) *
1393+ sizeof(*formats), GFP_KERNEL);
9741394
975− /* Add the no-alpha related format if any & supported */
976− drm_fmt_no_alpha = get_pixelformat_without_alpha(drm_fmt);
977− if (!drm_fmt_no_alpha)
978− continue;
1395+ for (i = 0; i < ldev->caps.pix_fmt_nb; i++) {
1396+ drm_fmt = ldev->caps.pix_fmt_drm[i];
9791397
9801398 /* Manage hw-specific capabilities */
981− if (ldev->caps.non_alpha_only_l1 &&
982− type != DRM_PLANE_TYPE_PRIMARY)
983− continue;
1399+ if (ldev->caps.non_alpha_only_l1)
1400+ /* XR24 & RX24 like formats supported only on primary layer */
1401+ if (type != DRM_PLANE_TYPE_PRIMARY && is_xrgb(drm_fmt))
1402+ continue;
9841403
985− formats[nb_fmt++] = drm_fmt_no_alpha;
1404+ formats[nb_fmt++] = drm_fmt;
1405+ }
1406+
1407+ /* Add YCbCr supported pixel formats */
1408+ if (ldev->caps.ycbcr_input) {
1409+ regmap_read(ldev->regmap, LTDC_L1C1R + lofs, &val);
1410+ if (val & LXCR_C1R_YIA) {
1411+ memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_cp,
1412+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp) * sizeof(*formats));
1413+ nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_cp);
1414+ }
1415+ if (val & LXCR_C1R_YSPA) {
1416+ memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_sp,
1417+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) * sizeof(*formats));
1418+ nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp);
1419+ }
1420+ if (val & LXCR_C1R_YFPA) {
1421+ memcpy(&formats[nb_fmt], ltdc_drm_fmt_ycbcr_fp,
1422+ ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp) * sizeof(*formats));
1423+ nb_fmt += ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp);
1424+ }
9861425 }
9871426
9881427 plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
@@ -995,6 +1434,17 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, · 6 unmodified lines
9951434 if (ret < 0)
9961435 return NULL;
9971436
1437+ if (ldev->caps.ycbcr_input) {
1438+ if (val & (LXCR_C1R_YIA | LXCR_C1R_YSPA | LXCR_C1R_YFPA))
1439+ drm_plane_create_color_properties(plane,
1440+ BIT(DRM_COLOR_YCBCR_BT601) |
1441+ BIT(DRM_COLOR_YCBCR_BT709),
1442+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1443+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1444+ DRM_COLOR_YCBCR_BT601,
1445+ DRM_COLOR_YCBCR_LIMITED_RANGE);
1446+ }
1447+
9981448 drm_plane_helper_add(plane, &ltdc_plane_helper_funcs);
9991449
10001450 drm_plane_create_alpha_property(plane);
@@ -1020,7 +1470,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) · 19 unmodified lines
10201470 unsigned int i;
10211471 int ret;
10221472
1023− primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY);
1473+ primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY, 0);
10241474 if (!primary) {
10251475 DRM_ERROR("Can not create primary plane\n");
10261476 return -EINVAL;
@@ -1044,7 +1494,7 @@ static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc) · 17 unmodified lines
10441494
10451495 /* Add planes. Note : the first layer is used by primary plane */
10461496 for (i = 1; i < ldev->caps.nb_layers; i++) {
1047− overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY);
1497+ overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i);
10481498 if (!overlay) {
10491499 ret = -ENOMEM;
10501500 DRM_ERROR("Can not create overlay plane %d\n", i);
@@ -1068,7 +1518,7 @@ static void ltdc_encoder_disable(struct drm_encoder *encoder) · 17 unmodified lines
10681518 DRM_DEBUG_DRIVER("\n");
10691519
10701520 /* Disable LTDC */
1071− reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
1521+ regmap_clear_bits(ldev->regmap, LTDC_GCR, GCR_LTDCEN);
10721522
10731523 /* Set to sleep state the pinctrl whatever type of encoder */
10741524 pinctrl_pm_select_sleep_state(ddev->dev);
@@ -1082,7 +1532,7 @@ static void ltdc_encoder_enable(struct drm_encoder *encoder) · 7 unmodified lines
10821532 DRM_DEBUG_DRIVER("\n");
10831533
10841534 /* Enable LTDC */
1085− reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
1535+ regmap_set_bits(ldev->regmap, LTDC_GCR, GCR_LTDCEN);
10861536 }
10871537
10881538 static void ltdc_encoder_mode_set(struct drm_encoder *encoder,
@@ -1145,21 +1595,25 @@ static int ltdc_get_caps(struct drm_device *ddev) · 56 unmodified lines
11451595 * at least 1 layer must be managed & the number of layers
11461596 * must not exceed LTDC_MAX_LAYER
11471597 */
1148− lcr = reg_read(ldev->regs, LTDC_LCR);
1598+ regmap_read(ldev->regmap, LTDC_LCR, &lcr);
11491599
11501600 ldev->caps.nb_layers = clamp((int)lcr, 1, LTDC_MAX_LAYER);
11511601
11521602 /* set data bus width */
1153− gc2r = reg_read(ldev->regs, LTDC_GC2R);
1603+ regmap_read(ldev->regmap, LTDC_GC2R, &gc2r);
11541604 bus_width_log2 = (gc2r & GC2R_BW) >> 4;
11551605 ldev->caps.bus_width = 8 << bus_width_log2;
1156− ldev->caps.hw_version = reg_read(ldev->regs, LTDC_IDR);
1606+ regmap_read(ldev->regmap, LTDC_IDR, &ldev->caps.hw_version);
11571607
11581608 switch (ldev->caps.hw_version) {
11591609 case HWVER_10200:
11601610 case HWVER_10300:
1161− ldev->caps.reg_ofs = REG_OFS_NONE;
1611+ ldev->caps.layer_ofs = LAY_OFS_0;
1612+ ldev->caps.layer_regs = ltdc_layer_regs_a0;
11621613 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a0;
1614+ ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a0;
1615+ ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a0);
1616+ ldev->caps.pix_fmt_flex = false;
11631617 /*
11641618 * Hw older versions support non-alpha color formats derived
11651619 * from native alpha color formats only on the primary layer.
@@ -1172,13 +1626,37 @@ static int ltdc_get_caps(struct drm_device *ddev) · 6 unmodified lines
11721626 if (ldev->caps.hw_version == HWVER_10200)
11731627 ldev->caps.pad_max_freq_hz = 65000000;
11741628 ldev->caps.nb_irq = 2;
1629+ ldev->caps.ycbcr_input = false;
1630+ ldev->caps.ycbcr_output = false;
1631+ ldev->caps.plane_reg_shadow = false;
11751632 break;
11761633 case HWVER_20101:
1177− ldev->caps.reg_ofs = REG_OFS_4;
1634+ ldev->caps.layer_ofs = LAY_OFS_0;
1635+ ldev->caps.layer_regs = ltdc_layer_regs_a1;
11781636 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a1;
1637+ ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a1;
1638+ ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a1);
1639+ ldev->caps.pix_fmt_flex = false;
11791640 ldev->caps.non_alpha_only_l1 = false;
11801641 ldev->caps.pad_max_freq_hz = 150000000;
11811642 ldev->caps.nb_irq = 4;
1643+ ldev->caps.ycbcr_input = false;
1644+ ldev->caps.ycbcr_output = false;
1645+ ldev->caps.plane_reg_shadow = false;
1646+ break;
1647+ case HWVER_40100:
1648+ ldev->caps.layer_ofs = LAY_OFS_1;
1649+ ldev->caps.layer_regs = ltdc_layer_regs_a2;
1650+ ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a2;
1651+ ldev->caps.pix_fmt_drm = ltdc_drm_fmt_a2;
1652+ ldev->caps.pix_fmt_nb = ARRAY_SIZE(ltdc_drm_fmt_a2);
1653+ ldev->caps.pix_fmt_flex = true;
1654+ ldev->caps.non_alpha_only_l1 = false;
1655+ ldev->caps.pad_max_freq_hz = 90000000;
1656+ ldev->caps.nb_irq = 2;
1657+ ldev->caps.ycbcr_input = true;
1658+ ldev->caps.ycbcr_output = true;
1659+ ldev->caps.plane_reg_shadow = true;
11821660 break;
11831661 default:
11841662 return -ENODEV;
@@ -1296,9 +1774,15 @@ int ltdc_load(struct drm_device *ddev) · 111 unmodified lines
12961774 goto err;
12971775 }
12981776
1777+ ldev->regmap = devm_regmap_init_mmio(&pdev->dev, ldev->regs, &stm32_ltdc_regmap_cfg);
1778+ if (IS_ERR(ldev->regmap)) {
1779+ DRM_ERROR("Unable to regmap ltdc registers\n");
1780+ ret = PTR_ERR(ldev->regmap);
1781+ goto err;
1782+ }
1783+
12991784 /* Disable interrupts */
1300− reg_clear(ldev->regs, LTDC_IER,
1301− IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
1785+ regmap_clear_bits(ldev->regmap, LTDC_IER, IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
13021786
13031787 ret = ltdc_get_caps(ddev);
13041788 if (ret) {
drivers/gpu/drm/stm/ltdc.h+10−2
@@ -14,12 +14,19 @@ · 13 unmodified lines
1414 struct ltdc_caps {
1515 u32 hw_version; /* hardware version */
1616 u32 nb_layers; /* number of supported layers */
17− u32 reg_ofs; /* register offset for applicable regs */
17+ u32 layer_ofs; /* layer offset for applicable regs */
18+ const u32 *layer_regs; /* layer register offset */
1819 u32 bus_width; /* bus width (32 or 64 bits) */
19− const u32 *pix_fmt_hw; /* supported pixel formats */
20+ const u32 *pix_fmt_hw; /* supported hw pixel formats */
21+ const u32 *pix_fmt_drm; /* supported drm pixel formats */
22+ int pix_fmt_nb; /* number of pixel format */
23+ bool pix_fmt_flex; /* pixel format flexibility supported */
2024 bool non_alpha_only_l1; /* non-native no-alpha formats on layer 1 */
2125 int pad_max_freq_hz; /* max frequency supported by pad */
2226 int nb_irq; /* number of hardware interrupts */
27+ bool ycbcr_input; /* ycbcr input converter supported */
28+ bool ycbcr_output; /* ycbcr output converter supported */
29+ bool plane_reg_shadow; /* plane shadow registers ability */
2330 };
2431
2532 #define LTDC_MAX_LAYER 4
@@ -31,6 +38,7 @@ struct fps_info { · 5 unmodified lines
3138
3239 struct ltdc_device {
3340 void __iomem *regs;
41+ struct regmap *regmap;
3442 struct clk *pixel_clk; /* lcd pixel clock */
3543 struct mutex err_lock; /* protecting error_status */
3644 struct ltdc_caps caps;
drivers/gpu/drm/tegra/Kconfig+1−0
@@ -5,6 +5,7 @@ config DRM_TEGRA · 4 unmodified lines
55 depends on COMMON_CLK
66 depends on DRM
77 depends on OF
8+ select DRM_DP_HELPER
89 select DRM_KMS_HELPER
910 select DRM_MIPI_DSI
1011 select DRM_PANEL
drivers/gpu/drm/tegra/dp.c+1−1
@@ -5,7 +5,7 @@ · 4 unmodified lines
55 */
66
77 #include <drm/drm_crtc.h>
8−#include <drm/drm_dp_helper.h>
8+#include <drm/dp/drm_dp_helper.h>
99 #include <drm/drm_print.h>
1010
1111 #include "dp.h"
drivers/gpu/drm/tegra/dpaux.c+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 #include <linux/reset.h>
1919 #include <linux/workqueue.h>
2020
21−#include <drm/drm_dp_helper.h>
21+#include <drm/dp/drm_dp_helper.h>
2222 #include <drm/drm_panel.h>
2323
2424 #include "dp.h"
drivers/gpu/drm/tegra/sor.c+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818
1919 #include <drm/drm_atomic_helper.h>
2020 #include <drm/drm_debugfs.h>
21−#include <drm/drm_dp_helper.h>
21+#include <drm/dp/drm_dp_helper.h>
2222 #include <drm/drm_file.h>
2323 #include <drm/drm_panel.h>
2424 #include <drm/drm_scdc_helper.h>
drivers/gpu/drm/tilcdc/tilcdc_drv.c+1−3
@@ -60,8 +60,6 @@ void tilcdc_module_cleanup(struct tilcdc_module *mod) · 59 unmodified lines
6060 list_del(&mod->list);
6161 }
6262
63−static struct of_device_id tilcdc_of_match[];
64−
6563 static int tilcdc_atomic_check(struct drm_device *dev,
6664 struct drm_atomic_state *state)
6765 {
@@ -587,7 +585,7 @@ static int tilcdc_pdev_remove(struct platform_device *pdev) · 519 unmodified lines
587585 return 0;
588586 }
589587
590−static struct of_device_id tilcdc_of_match[] = {
588+static const struct of_device_id tilcdc_of_match[] = {
591589 { .compatible = "ti,am33xx-tilcdc", },
592590 { .compatible = "ti,da850-tilcdc", },
593591 { },
drivers/gpu/drm/tiny/bochs.c+2−18
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <drm/drm_gem_framebuffer_helper.h>
1111 #include <drm/drm_gem_vram_helper.h>
1212 #include <drm/drm_managed.h>
13+#include <drm/drm_module.h>
1314 #include <drm/drm_probe_helper.h>
1415 #include <drm/drm_simple_kms_helper.h>
1516
@@ -716,24 +717,7 @@ static struct pci_driver bochs_pci_driver = { · 700 unmodified lines
716717 /* ---------------------------------------------------------------------- */
717718 /* module init/exit */
718719
719−static int __init bochs_init(void)
720−{
721− if (drm_firmware_drivers_only() && bochs_modeset == -1)
722− return -EINVAL;
723−
724− if (bochs_modeset == 0)
725− return -EINVAL;
726−
727− return pci_register_driver(&bochs_pci_driver);
728−}
729−
730−static void __exit bochs_exit(void)
731−{
732− pci_unregister_driver(&bochs_pci_driver);
733−}
734−
735−module_init(bochs_init);
736−module_exit(bochs_exit);
720+drm_module_pci_driver_if_modeset(bochs_pci_driver, bochs_modeset);
737721
738722 MODULE_DEVICE_TABLE(pci, bochs_pci_tbl);
739723 MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
drivers/gpu/drm/tiny/cirrus.c+2−15
@@ -39,6 +39,7 @@ · 38 unmodified lines
3939 #include <drm/drm_ioctl.h>
4040 #include <drm/drm_managed.h>
4141 #include <drm/drm_modeset_helper_vtables.h>
42+#include <drm/drm_module.h>
4243 #include <drm/drm_probe_helper.h>
4344 #include <drm/drm_simple_kms_helper.h>
4445
@@ -633,21 +634,7 @@ static struct pci_driver cirrus_pci_driver = { · 588 unmodified lines
633634 .remove = cirrus_pci_remove,
634635 };
635636
636−static int __init cirrus_init(void)
637−{
638− if (drm_firmware_drivers_only())
639− return -EINVAL;
640−
641− return pci_register_driver(&cirrus_pci_driver);
642−}
643−
644−static void __exit cirrus_exit(void)
645−{
646− pci_unregister_driver(&cirrus_pci_driver);
647−}
648−
649−module_init(cirrus_init);
650−module_exit(cirrus_exit);
637+drm_module_pci_driver(cirrus_pci_driver)
651638
652639 MODULE_DEVICE_TABLE(pci, pciidlist);
653640 MODULE_LICENSE("GPL");
drivers/gpu/drm/tiny/simpledrm.c+17−5
@@ -526,21 +526,33 @@ static int simpledrm_device_init_mm(struct simpledrm_device *sdev) · 525 unmodified lines
526526 {
527527 struct drm_device *dev = &sdev->dev;
528528 struct platform_device *pdev = sdev->pdev;
529− struct resource *mem;
529+ struct resource *res, *mem;
530530 void __iomem *screen_base;
531531 int ret;
532532
533− mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
534− if (!mem)
533+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
534+ if (!res)
535535 return -EINVAL;
536536
537− ret = devm_aperture_acquire_from_firmware(dev, mem->start, resource_size(mem));
537+ ret = devm_aperture_acquire_from_firmware(dev, res->start, resource_size(res));
538538 if (ret) {
539539 drm_err(dev, "could not acquire memory range %pr: error %d\n",
540− mem, ret);
540+ res, ret);
541541 return ret;
542542 }
543543
544+ mem = devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
545+ sdev->dev.driver->name);
546+ if (!mem) {
547+ /*
548+ * We cannot make this fatal. Sometimes this comes from magic
549+ * spaces our resource handlers simply don't know about. Use
550+ * the I/O-memory resource as-is and try to map that instead.
551+ */
552+ drm_warn(dev, "could not acquire memory region %pr\n", res);
553+ mem = res;
554+ }
555+
544556 screen_base = devm_ioremap_wc(&pdev->dev, mem->start,
545557 resource_size(mem));
546558 if (!screen_base)
drivers/gpu/drm/ttm/ttm_bo_util.c+5−2
@@ -241,6 +241,11 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, · 240 unmodified lines
241241 if (bo->type != ttm_bo_type_sg)
242242 fbo->base.base.resv = &fbo->base.base._resv;
243243
244+ if (fbo->base.resource) {
245+ ttm_resource_set_bo(fbo->base.resource, &fbo->base);
246+ bo->resource = NULL;
247+ }
248+
244249 dma_resv_init(&fbo->base.base._resv);
245250 fbo->base.base.dev = NULL;
246251 ret = dma_resv_trylock(&fbo->base.base._resv);
@@ -509,7 +514,6 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo, · 262 unmodified lines
509514 ghost_obj->ttm = NULL;
510515 else
511516 bo->ttm = NULL;
512− bo->resource = NULL;
513517
514518 dma_resv_unlock(&ghost_obj->base._resv);
515519 ttm_bo_put(ghost_obj);
@@ -637,7 +641,6 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) · 121 unmodified lines
637641 dma_resv_unlock(&ghost->base._resv);
638642 ttm_bo_put(ghost);
639643 bo->ttm = ttm;
640− bo->resource = NULL;
641644 ttm_bo_assign_mem(bo, sys_res);
642645 return 0;
643646
drivers/gpu/drm/ttm/ttm_range_manager.c+3−1
@@ -89,6 +89,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man, · 88 unmodified lines
8989 spin_unlock(&rman->lock);
9090
9191 if (unlikely(ret)) {
92+ ttm_resource_fini(man, *res);
9293 kfree(node);
9394 return ret;
9495 }
@@ -108,6 +109,7 @@ static void ttm_range_man_free(struct ttm_resource_manager *man, · 13 unmodified lines
108109 drm_mm_remove_node(&node->mm_nodes[0]);
109110 spin_unlock(&rman->lock);
110111
112+ ttm_resource_fini(man, res);
111113 kfree(node);
112114 }
113115
@@ -156,7 +158,7 @@ int ttm_range_man_init_nocheck(struct ttm_device *bdev, · 42 unmodified lines
156158
157159 man->func = &ttm_range_manager_func;
158160
159− ttm_resource_manager_init(man, p_size);
161+ ttm_resource_manager_init(man, bdev, p_size);
160162
161163 drm_mm_init(&rman->mm, 0, p_size);
162164 spin_lock_init(&rman->lock);
drivers/gpu/drm/ttm/ttm_resource.c+35−0
@@ -29,6 +29,14 @@ · 28 unmodified lines
2929 #include <drm/ttm/ttm_resource.h>
3030 #include <drm/ttm/ttm_bo_driver.h>
3131
32+/**
33+ * ttm_resource_init - resource object constructure
34+ * @bo: buffer object this resources is allocated for
35+ * @place: placement of the resource
36+ * @res: the resource object to inistilize
37+ *
38+ * Initialize a new resource object. Counterpart of &ttm_resource_fini.
39+ */
3240 void ttm_resource_init(struct ttm_buffer_object *bo,
3341 const struct ttm_place *place,
3442 struct ttm_resource *res)
@@ -41,9 +49,25 @@ void ttm_resource_init(struct ttm_buffer_object *bo, · 6 unmodified lines
4149 res->bus.offset = 0;
4250 res->bus.is_iomem = false;
4351 res->bus.caching = ttm_cached;
52+ res->bo = bo;
4453 }
4554 EXPORT_SYMBOL(ttm_resource_init);
4655
56+/**
57+ * ttm_resource_fini - resource destructor
58+ * @man: the resource manager this resource belongs to
59+ * @res: the resource to clean up
60+ *
61+ * Should be used by resource manager backends to clean up the TTM resource
62+ * objects before freeing the underlying structure. Counterpart of
63+ * &ttm_resource_init
64+ */
65+void ttm_resource_fini(struct ttm_resource_manager *man,
66+ struct ttm_resource *res)
67+{
68+}
69+EXPORT_SYMBOL(ttm_resource_fini);
70+
4771 int ttm_resource_alloc(struct ttm_buffer_object *bo,
4872 const struct ttm_place *place,
4973 struct ttm_resource **res_ptr)
@@ -116,20 +140,31 @@ bool ttm_resource_compat(struct ttm_resource *res, · 66 unmodified lines
116140 }
117141 EXPORT_SYMBOL(ttm_resource_compat);
118142
143+void ttm_resource_set_bo(struct ttm_resource *res,
144+ struct ttm_buffer_object *bo)
145+{
146+ spin_lock(&bo->bdev->lru_lock);
147+ res->bo = bo;
148+ spin_unlock(&bo->bdev->lru_lock);
149+}
150+
119151 /**
120152 * ttm_resource_manager_init
121153 *
122154 * @man: memory manager object to init
155+ * @bdev: ttm device this manager belongs to
123156 * @p_size: size managed area in pages.
124157 *
125158 * Initialise core parts of a manager object.
126159 */
127160 void ttm_resource_manager_init(struct ttm_resource_manager *man,
161+ struct ttm_device *bdev,
128162 unsigned long p_size)
129163 {
130164 unsigned i;
131165
132166 spin_lock_init(&man->move_lock);
167+ man->bdev = bdev;
133168 man->size = p_size;
134169
135170 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
drivers/gpu/drm/ttm/ttm_sys_manager.c+2−1
@@ -23,6 +23,7 @@ static int ttm_sys_man_alloc(struct ttm_resource_manager *man, · 22 unmodified lines
2323 static void ttm_sys_man_free(struct ttm_resource_manager *man,
2424 struct ttm_resource *res)
2525 {
26+ ttm_resource_fini(man, res);
2627 kfree(res);
2728 }
2829
@@ -42,7 +43,7 @@ void ttm_sys_man_init(struct ttm_device *bdev) · 13 unmodified lines
4243 man->use_tt = true;
4344 man->func = &ttm_sys_manager_func;
4445
45− ttm_resource_manager_init(man, 0);
46+ ttm_resource_manager_init(man, bdev, 0);
4647 ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, man);
4748 ttm_resource_manager_set_used(man, true);
4849 }
drivers/gpu/drm/v3d/v3d_drv.c+6−2
@@ -219,6 +219,7 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) · 218 unmodified lines
219219 int ret;
220220 u32 mmu_debug;
221221 u32 ident1;
222+ u64 mask;
222223
223224 v3d = devm_drm_dev_alloc(dev, &v3d_drm_driver, struct v3d_dev, drm);
224225 if (IS_ERR(v3d))
@@ -237,8 +238,11 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) · 12 unmodified lines
237238 return ret;
238239
239240 mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
240− dma_set_mask_and_coherent(dev,
241− DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH)));
241+ mask = DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
242+ ret = dma_set_mask_and_coherent(dev, mask);
243+ if (ret)
244+ return ret;
245+
242246 v3d->va_width = 30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_VA_WIDTH);
243247
244248 ident1 = V3D_READ(V3D_HUB_IDENT1);
drivers/gpu/drm/vc4/vc4_bo.c+0−2
@@ -355,8 +355,6 @@ static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev, · 354 unmodified lines
355355 uint32_t page_index = bo_page_index(size);
356356 struct vc4_bo *bo = NULL;
357357
358− size = roundup(size, PAGE_SIZE);
359−
360358 mutex_lock(&vc4->bo_lock);
361359 if (page_index >= vc4->bo_cache.size_list_size)
362360 goto out;
drivers/gpu/drm/vc4/vc4_drv.c+29−4
@@ -37,6 +37,8 @@ · 36 unmodified lines
3737 #include <drm/drm_fb_helper.h>
3838 #include <drm/drm_vblank.h>
3939
40+#include <soc/bcm2835/raspberrypi-firmware.h>
41+
4042 #include "uapi/drm/vc4_drm.h"
4143
4244 #include "vc4_drv.h"
@@ -215,6 +217,7 @@ static void vc4_match_add_drivers(struct device *dev, · 172 unmodified lines
215217 static int vc4_drm_bind(struct device *dev)
216218 {
217219 struct platform_device *pdev = to_platform_device(dev);
220+ struct rpi_firmware *firmware = NULL;
218221 struct drm_device *drm;
219222 struct vc4_dev *vc4;
220223 struct device_node *node;
@@ -251,15 +254,34 @@ static int vc4_drm_bind(struct device *dev) · 30 unmodified lines
251254 if (ret)
252255 return ret;
253256
254− ret = component_bind_all(dev, drm);
257+ node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware");
258+ if (node) {
259+ firmware = rpi_firmware_get(node);
260+ of_node_put(node);
261+
262+ if (!firmware)
263+ return -EPROBE_DEFER;
264+ }
265+
266+ ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver);
255267 if (ret)
256268 return ret;
257269
258− ret = vc4_plane_create_additional_planes(drm);
270+ if (firmware) {
271+ ret = rpi_firmware_property(firmware,
272+ RPI_FIRMWARE_NOTIFY_DISPLAY_DONE,
273+ NULL, 0);
274+ if (ret)
275+ drm_warn(drm, "Couldn't stop firmware display driver: %d\n", ret);
276+
277+ rpi_firmware_put(firmware);
278+ }
279+
280+ ret = component_bind_all(dev, drm);
259281 if (ret)
260− goto unbind_all;
282+ return ret;
261283
262− ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver);
284+ ret = vc4_plane_create_additional_planes(drm);
263285 if (ret)
264286 goto unbind_all;
265287
@@ -357,6 +379,9 @@ static int __init vc4_drm_register(void) · 91 unmodified lines
357379 {
358380 int ret;
359381
382+ if (drm_firmware_drivers_only())
383+ return -ENODEV;
384+
360385 ret = platform_register_drivers(component_drivers,
361386 ARRAY_SIZE(component_drivers));
362387 if (ret)
drivers/gpu/drm/vc4/vc4_hdmi.c+78−54
@@ -104,6 +104,15 @@ static bool vc4_hdmi_mode_needs_scrambling(const struct drm_display_mode *mode) · 103 unmodified lines
104104 return (mode->clock * 1000) > HDMI_14_MAX_TMDS_CLK;
105105 }
106106
107+static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
108+ const struct drm_display_mode *mode)
109+{
110+ struct vc4_hdmi_encoder *vc4_encoder = &vc4_hdmi->encoder;
111+
112+ return !vc4_encoder->hdmi_monitor ||
113+ drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
114+}
115+
107116 static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
108117 {
109118 struct drm_info_node *node = (struct drm_info_node *)m->private;
@@ -481,7 +490,6 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, · 371 unmodified lines
481490 static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
482491 {
483492 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
484− struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
485493 struct drm_connector *connector = &vc4_hdmi->connector;
486494 struct drm_connector_state *cstate = connector->state;
487495 const struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
@@ -499,10 +507,10 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) · 11 unmodified lines
499507
500508 drm_hdmi_avi_infoframe_quant_range(&frame.avi,
501509 connector, mode,
502− vc4_encoder->limited_rgb_range ?
503− HDMI_QUANTIZATION_RANGE_LIMITED :
504− HDMI_QUANTIZATION_RANGE_FULL);
505− drm_hdmi_avi_infoframe_colorspace(&frame.avi, cstate);
510+ vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ?
511+ HDMI_QUANTIZATION_RANGE_FULL :
512+ HDMI_QUANTIZATION_RANGE_LIMITED);
513+ drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
506514 drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
507515
508516 vc4_hdmi_write_infoframe(encoder, &frame);
@@ -726,7 +734,9 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder) · 217 unmodified lines
726734 mutex_unlock(&vc4_hdmi->mutex);
727735 }
728736
729−static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
737+static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
738+ struct drm_connector_state *state,
739+ const struct drm_display_mode *mode)
730740 {
731741 unsigned long flags;
732742 u32 csc_ctl;
@@ -736,7 +746,7 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) · 3 unmodified lines
736746 csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
737747 VC4_HD_CSC_CTL_ORDER);
738748
739− if (enable) {
749+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
740750 /* CEA VICs other than #1 requre limited range RGB
741751 * output unless overridden by an AVI infoframe.
742752 * Apply a colorspace conversion to squash 0-255 down
@@ -766,44 +776,67 @@ static void vc4_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable) · 23 unmodified lines
766776 spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
767777 }
768778
769−static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, bool enable)
779+/*
780+ * If we need to output Full Range RGB, then use the unity matrix
781+ *
782+ * [ 1 0 0 0]
783+ * [ 0 1 0 0]
784+ * [ 0 0 1 0]
785+ *
786+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
787+ */
788+static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
789+ { 0x2000, 0x0000, 0x0000, 0x0000 },
790+ { 0x0000, 0x2000, 0x0000, 0x0000 },
791+ { 0x0000, 0x0000, 0x2000, 0x0000 },
792+};
793+
794+/*
795+ * CEA VICs other than #1 require limited range RGB output unless
796+ * overridden by an AVI infoframe. Apply a colorspace conversion to
797+ * squash 0-255 down to 16-235. The matrix here is:
798+ *
799+ * [ 0.8594 0 0 16]
800+ * [ 0 0.8594 0 16]
801+ * [ 0 0 0.8594 16]
802+ *
803+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
804+ */
805+static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
806+ { 0x1b80, 0x0000, 0x0000, 0x0400 },
807+ { 0x0000, 0x1b80, 0x0000, 0x0400 },
808+ { 0x0000, 0x0000, 0x1b80, 0x0400 },
809+};
810+
811+static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
812+ const u16 coeffs[3][4])
770813 {
771− unsigned long flags;
772− u32 csc_ctl;
814+ lockdep_assert_held(&vc4_hdmi->hw_lock);
815+
816+ HDMI_WRITE(HDMI_CSC_12_11, (coeffs[0][1] << 16) | coeffs[0][0]);
817+ HDMI_WRITE(HDMI_CSC_14_13, (coeffs[0][3] << 16) | coeffs[0][2]);
818+ HDMI_WRITE(HDMI_CSC_22_21, (coeffs[1][1] << 16) | coeffs[1][0]);
819+ HDMI_WRITE(HDMI_CSC_24_23, (coeffs[1][3] << 16) | coeffs[1][2]);
820+ HDMI_WRITE(HDMI_CSC_32_31, (coeffs[2][1] << 16) | coeffs[2][0]);
821+ HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
822+}
773823
774− csc_ctl = 0x07; /* RGB_CONVERT_MODE = custom matrix, || USE_RGB_TO_YCBCR */
824+static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
825+ struct drm_connector_state *state,
826+ const struct drm_display_mode *mode)
827+{
828+ unsigned long flags;
829+ u32 csc_ctl = VC5_MT_CP_CSC_CTL_ENABLE | VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
830+ VC5_MT_CP_CSC_CTL_MODE);
775831
776832 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
777833
778− if (enable) {
779− /* CEA VICs other than #1 requre limited range RGB
780− * output unless overridden by an AVI infoframe.
781− * Apply a colorspace conversion to squash 0-255 down
782− * to 16-235. The matrix here is:
783− *
784− * [ 0.8594 0 0 16]
785− * [ 0 0.8594 0 16]
786− * [ 0 0 0.8594 16]
787− * [ 0 0 0 1]
788− * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
789− */
790− HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x1b80);
791− HDMI_WRITE(HDMI_CSC_14_13, (0x0400 << 16) | 0x0000);
792− HDMI_WRITE(HDMI_CSC_22_21, (0x1b80 << 16) | 0x0000);
793− HDMI_WRITE(HDMI_CSC_24_23, (0x0400 << 16) | 0x0000);
794− HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
795− HDMI_WRITE(HDMI_CSC_34_33, (0x0400 << 16) | 0x1b80);
796− } else {
797− /* Still use the matrix for full range, but make it unity.
798− * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
799− */
800− HDMI_WRITE(HDMI_CSC_12_11, (0x0000 << 16) | 0x2000);
801− HDMI_WRITE(HDMI_CSC_14_13, (0x0000 << 16) | 0x0000);
802− HDMI_WRITE(HDMI_CSC_22_21, (0x2000 << 16) | 0x0000);
803− HDMI_WRITE(HDMI_CSC_24_23, (0x0000 << 16) | 0x0000);
804− HDMI_WRITE(HDMI_CSC_32_31, (0x0000 << 16) | 0x0000);
805− HDMI_WRITE(HDMI_CSC_34_33, (0x0000 << 16) | 0x2000);
806− }
834+ HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
835+
836+ if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
837+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
838+ else
839+ vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
807840
808841 HDMI_WRITE(HDMI_CSC_CTL, csc_ctl);
809842
@@ -889,7 +922,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi, · 79 unmodified lines
889922
890923 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
891924
892− HDMI_WRITE(HDMI_VEC_INTERFACE_XBAR, 0x354021);
893925 HDMI_WRITE(HDMI_HORZA,
894926 (vsync_pos ? VC5_HDMI_HORZA_VPOS : 0) |
895927 (hsync_pos ? VC5_HDMI_HORZA_HPOS : 0) |
@@ -1113,24 +1145,16 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, · 217 unmodified lines
11131145 struct drm_atomic_state *state)
11141146 {
11151147 struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
1148+ struct drm_connector *connector = &vc4_hdmi->connector;
11161149 struct drm_display_mode *mode = &vc4_hdmi->saved_adjusted_mode;
1117− struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
1150+ struct drm_connector_state *conn_state =
1151+ drm_atomic_get_new_connector_state(state, connector);
11181152 unsigned long flags;
11191153
11201154 mutex_lock(&vc4_hdmi->mutex);
11211155
1122− if (vc4_encoder->hdmi_monitor &&
1123− drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED) {
1124− if (vc4_hdmi->variant->csc_setup)
1125− vc4_hdmi->variant->csc_setup(vc4_hdmi, true);
1126−
1127− vc4_encoder->limited_rgb_range = true;
1128− } else {
1129− if (vc4_hdmi->variant->csc_setup)
1130− vc4_hdmi->variant->csc_setup(vc4_hdmi, false);
1131−
1132− vc4_encoder->limited_rgb_range = false;
1133− }
1156+ if (vc4_hdmi->variant->csc_setup)
1157+ vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode);
11341158
11351159 spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
11361160 HDMI_WRITE(HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
drivers/gpu/drm/vc4/vc4_hdmi.h+3−2
@@ -12,7 +12,6 @@ · 11 unmodified lines
1212 struct vc4_hdmi_encoder {
1313 struct vc4_encoder base;
1414 bool hdmi_monitor;
15− bool limited_rgb_range;
1615 };
1716
1817 static inline struct vc4_hdmi_encoder *
@@ -77,7 +76,9 @@ struct vc4_hdmi_variant { · 58 unmodified lines
7776 void (*reset)(struct vc4_hdmi *vc4_hdmi);
7877
7978 /* Callback to enable / disable the CSC */
80− void (*csc_setup)(struct vc4_hdmi *vc4_hdmi, bool enable);
79+ void (*csc_setup)(struct vc4_hdmi *vc4_hdmi,
80+ struct drm_connector_state *state,
81+ const struct drm_display_mode *mode);
8182
8283 /* Callback to configure the video timings in the HDMI block */
8384 void (*set_timings)(struct vc4_hdmi *vc4_hdmi,
drivers/gpu/drm/vc4/vc4_regs.h+3−0
@@ -774,6 +774,9 @@ enum { · 773 unmodified lines
774774 # define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
775775 # define VC4_HD_CSC_CTL_ENABLE BIT(0)
776776
777+# define VC5_MT_CP_CSC_CTL_ENABLE BIT(2)
778+# define VC5_MT_CP_CSC_CTL_MODE_MASK VC4_MASK(1, 0)
779+
777780 # define VC4_DVP_HT_CLOCK_STOP_PIXEL BIT(1)
778781
779782 /* HVS display list information. */
drivers/gpu/drm/virtio/virtgpu_gem.c+3−0
@@ -248,6 +248,9 @@ void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs) · 247 unmodified lines
248248 {
249249 u32 i;
250250
251+ if (!objs)
252+ return;
253+
251254 for (i = 0; i < objs->nents; i++)
252255 drm_gem_object_put(objs->objs[i]);
253256 virtio_gpu_array_free(objs);
drivers/gpu/drm/vkms/vkms_drv.h+2−0
@@ -20,6 +20,8 @@ · 19 unmodified lines
2020 #define XRES_MAX 8192
2121 #define YRES_MAX 8192
2222
23+#define NUM_OVERLAY_PLANES 8
24+
2325 struct vkms_writeback_job {
2426 struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
2527 struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
drivers/gpu/drm/vkms/vkms_output.c+22−7
@@ -32,6 +32,21 @@ static const struct drm_connector_helper_funcs vkms_conn_helper_funcs = { · 31 unmodified lines
3232 .get_modes = vkms_conn_get_modes,
3333 };
3434
35+static int vkms_add_overlay_plane(struct vkms_device *vkmsdev, int index,
36+ struct drm_crtc *crtc)
37+{
38+ struct vkms_plane *overlay;
39+
40+ overlay = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY, index);
41+ if (IS_ERR(overlay))
42+ return PTR_ERR(overlay);
43+
44+ if (!overlay->base.possible_crtcs)
45+ overlay->base.possible_crtcs = drm_crtc_mask(crtc);
46+
47+ return 0;
48+}
49+
3550 int vkms_output_init(struct vkms_device *vkmsdev, int index)
3651 {
3752 struct vkms_output *output = &vkmsdev->output;
@@ -39,21 +54,21 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index) · 1 unmodified line
3954 struct drm_connector *connector = &output->connector;
4055 struct drm_encoder *encoder = &output->encoder;
4156 struct drm_crtc *crtc = &output->crtc;
42− struct vkms_plane *primary, *cursor = NULL, *overlay = NULL;
57+ struct vkms_plane *primary, *cursor = NULL;
4358 int ret;
4459 int writeback;
60+ unsigned int n;
4561
4662 primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index);
4763 if (IS_ERR(primary))
4864 return PTR_ERR(primary);
4965
5066 if (vkmsdev->config->overlay) {
51− overlay = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY, index);
52− if (IS_ERR(overlay))
53− return PTR_ERR(overlay);
54−
55− if (!overlay->base.possible_crtcs)
56− overlay->base.possible_crtcs = drm_crtc_mask(crtc);
67+ for (n = 0; n < NUM_OVERLAY_PLANES; n++) {
68+ ret = vkms_add_overlay_plane(vkmsdev, index, crtc);
69+ if (ret)
70+ return ret;
71+ }
5772 }
5873
5974 if (vkmsdev->config->cursor) {
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c+3−1
@@ -117,6 +117,7 @@ nospace: · 116 unmodified lines
117117 gman->used_gmr_pages -= (*res)->num_pages;
118118 spin_unlock(&gman->lock);
119119 ida_free(&gman->gmr_ida, id);
120+ ttm_resource_fini(man, *res);
120121 kfree(*res);
121122 return -ENOSPC;
122123 }
@@ -130,6 +131,7 @@ static void vmw_gmrid_man_put_node(struct ttm_resource_manager *man, · 7 unmodified lines
130131 spin_lock(&gman->lock);
131132 gman->used_gmr_pages -= res->num_pages;
132133 spin_unlock(&gman->lock);
134+ ttm_resource_fini(man, res);
133135 kfree(res);
134136 }
135137
@@ -160,7 +162,7 @@ int vmw_gmrid_man_init(struct vmw_private *dev_priv, int type) · 24 unmodified lines
160162
161163 man->func = &vmw_gmrid_manager_func;
162164 man->use_tt = true;
163− ttm_resource_manager_init(man, 0);
165+ ttm_resource_manager_init(man, &dev_priv->bdev, 0);
164166 spin_lock_init(&gman->lock);
165167 gman->used_gmr_pages = 0;
166168 ida_init(&gman->gmr_ida);
drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c+2−1
@@ -49,6 +49,7 @@ static int vmw_sys_man_alloc(struct ttm_resource_manager *man, · 48 unmodified lines
4949 static void vmw_sys_man_free(struct ttm_resource_manager *man,
5050 struct ttm_resource *res)
5151 {
52+ ttm_resource_fini(man, res);
5253 kfree(res);
5354 }
5455
@@ -69,7 +70,7 @@ int vmw_sys_man_init(struct vmw_private *dev_priv) · 14 unmodified lines
6970 man->use_tt = true;
7071 man->func = &vmw_sys_manager_func;
7172
72− ttm_resource_manager_init(man, 0);
73+ ttm_resource_manager_init(man, bdev, 0);
7374 ttm_set_driver_manager(bdev, VMW_PL_SYSTEM, man);
7475 ttm_resource_manager_set_used(man, true);
7576 return 0;
drivers/gpu/drm/xlnx/Kconfig+1−0
@@ -6,6 +6,7 @@ config DRM_ZYNQMP_DPSUB · 5 unmodified lines
66 depends on PHY_XILINX_ZYNQMP
77 depends on XILINX_ZYNQMP_DPDMA
88 select DMA_ENGINE
9+ select DRM_DP_HELPER
910 select DRM_GEM_CMA_HELPER
1011 select DRM_KMS_HELPER
1112 select GENERIC_PHY
drivers/gpu/drm/xlnx/zynqmp_dp.c+1−1
@@ -13,7 +13,7 @@ · 12 unmodified lines
1313 #include <drm/drm_connector.h>
1414 #include <drm/drm_crtc.h>
1515 #include <drm/drm_device.h>
16−#include <drm/drm_dp_helper.h>
16+#include <drm/dp/drm_dp_helper.h>
1717 #include <drm/drm_edid.h>
1818 #include <drm/drm_encoder.h>
1919 #include <drm/drm_managed.h>
drivers/platform/chrome/Kconfig+11−0
@@ -243,6 +243,17 @@ config CROS_USBPD_NOTIFY · 242 unmodified lines
243243 To compile this driver as a module, choose M here: the
244244 module will be called cros_usbpd_notify.
245245
246+config CHROMEOS_PRIVACY_SCREEN
247+ tristate "ChromeOS Privacy Screen support"
248+ depends on ACPI
249+ depends on DRM
250+ select DRM_PRIVACY_SCREEN
251+ help
252+ This driver provides the support needed for the in-built electronic
253+ privacy screen that is present on some ChromeOS devices. When enabled,
254+ this should probably always be built into the kernel to avoid or
255+ minimize drm probe deferral.
256+
246257 source "drivers/platform/chrome/wilco_ec/Kconfig"
247258
248259 endif # CHROMEOS_PLATFORMS
drivers/platform/chrome/Makefile+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 CFLAGS_cros_ec_trace.o:= -I$(src)
55
66 obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
7+obj-$(CONFIG_CHROMEOS_PRIVACY_SCREEN) += chromeos_privacy_screen.o
78 obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
89 obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o
910 obj-$(CONFIG_CROS_EC) += cros_ec.o
drivers/platform/chrome/chromeos_privacy_screen.c+153−0
@@ -0,0 +1,153 @@
1+// SPDX-License-Identifier: GPL-2.0
2+
3+/*
4+ * ChromeOS Privacy Screen support
5+ *
6+ * Copyright (C) 2022 Google LLC
7+ *
8+ * This is the Chromeos privacy screen provider, present on certain chromebooks,
9+ * represented by a GOOG0010 device in the ACPI. This ACPI device, if present,
10+ * will cause the i915 drm driver to probe defer until this driver registers
11+ * the privacy-screen.
12+ */
13+
14+#include <linux/acpi.h>
15+#include <drm/drm_privacy_screen_driver.h>
16+
17+/*
18+ * The DSM (Device Specific Method) constants below are the agreed API with
19+ * the firmware team, on how to control privacy screen using ACPI methods.
20+ */
21+#define PRIV_SCRN_DSM_REVID 1 /* DSM version */
22+#define PRIV_SCRN_DSM_FN_GET_STATUS 1 /* Get privacy screen status */
23+#define PRIV_SCRN_DSM_FN_ENABLE 2 /* Enable privacy screen */
24+#define PRIV_SCRN_DSM_FN_DISABLE 3 /* Disable privacy screen */
25+
26+static const guid_t chromeos_privacy_screen_dsm_guid =
27+ GUID_INIT(0xc7033113, 0x8720, 0x4ceb,
28+ 0x90, 0x90, 0x9d, 0x52, 0xb3, 0xe5, 0x2d, 0x73);
29+
30+static void
31+chromeos_privacy_screen_get_hw_state(struct drm_privacy_screen
32+ *drm_privacy_screen)
33+{
34+ union acpi_object *obj;
35+ acpi_handle handle;
36+ struct device *privacy_screen =
37+ drm_privacy_screen_get_drvdata(drm_privacy_screen);
38+
39+ handle = acpi_device_handle(to_acpi_device(privacy_screen));
40+ obj = acpi_evaluate_dsm(handle, &chromeos_privacy_screen_dsm_guid,
41+ PRIV_SCRN_DSM_REVID,
42+ PRIV_SCRN_DSM_FN_GET_STATUS, NULL);
43+ if (!obj) {
44+ dev_err(privacy_screen,
45+ "_DSM failed to get privacy-screen state\n");
46+ return;
47+ }
48+
49+ if (obj->type != ACPI_TYPE_INTEGER)
50+ dev_err(privacy_screen,
51+ "Bad _DSM to get privacy-screen state\n");
52+ else if (obj->integer.value == 1)
53+ drm_privacy_screen->hw_state = drm_privacy_screen->sw_state =
54+ PRIVACY_SCREEN_ENABLED;
55+ else
56+ drm_privacy_screen->hw_state = drm_privacy_screen->sw_state =
57+ PRIVACY_SCREEN_DISABLED;
58+
59+ ACPI_FREE(obj);
60+}
61+
62+static int
63+chromeos_privacy_screen_set_sw_state(struct drm_privacy_screen
64+ *drm_privacy_screen,
65+ enum drm_privacy_screen_status state)
66+{
67+ union acpi_object *obj = NULL;
68+ acpi_handle handle;
69+ struct device *privacy_screen =
70+ drm_privacy_screen_get_drvdata(drm_privacy_screen);
71+
72+ handle = acpi_device_handle(to_acpi_device(privacy_screen));
73+
74+ if (state == PRIVACY_SCREEN_DISABLED) {
75+ obj = acpi_evaluate_dsm(handle,
76+ &chromeos_privacy_screen_dsm_guid,
77+ PRIV_SCRN_DSM_REVID,
78+ PRIV_SCRN_DSM_FN_DISABLE, NULL);
79+ } else if (state == PRIVACY_SCREEN_ENABLED) {
80+ obj = acpi_evaluate_dsm(handle,
81+ &chromeos_privacy_screen_dsm_guid,
82+ PRIV_SCRN_DSM_REVID,
83+ PRIV_SCRN_DSM_FN_ENABLE, NULL);
84+ } else {
85+ dev_err(privacy_screen,
86+ "Bad attempt to set privacy-screen status to %u\n",
87+ state);
88+ return -EINVAL;
89+ }
90+
91+ if (!obj) {
92+ dev_err(privacy_screen,
93+ "_DSM failed to set privacy-screen state\n");
94+ return -EIO;
95+ }
96+
97+ drm_privacy_screen->hw_state = drm_privacy_screen->sw_state = state;
98+ ACPI_FREE(obj);
99+ return 0;
100+}
101+
102+static const struct drm_privacy_screen_ops chromeos_privacy_screen_ops = {
103+ .get_hw_state = chromeos_privacy_screen_get_hw_state,
104+ .set_sw_state = chromeos_privacy_screen_set_sw_state,
105+};
106+
107+static int chromeos_privacy_screen_add(struct acpi_device *adev)
108+{
109+ struct drm_privacy_screen *drm_privacy_screen =
110+ drm_privacy_screen_register(&adev->dev,
111+ &chromeos_privacy_screen_ops,
112+ &adev->dev);
113+
114+ if (IS_ERR(drm_privacy_screen)) {
115+ dev_err(&adev->dev, "Error registering privacy-screen\n");
116+ return PTR_ERR(drm_privacy_screen);
117+ }
118+
119+ adev->driver_data = drm_privacy_screen;
120+ dev_info(&adev->dev, "registered privacy-screen '%s'\n",
121+ dev_name(&drm_privacy_screen->dev));
122+
123+ return 0;
124+}
125+
126+static int chromeos_privacy_screen_remove(struct acpi_device *adev)
127+{
128+ struct drm_privacy_screen *drm_privacy_screen = acpi_driver_data(adev);
129+
130+ drm_privacy_screen_unregister(drm_privacy_screen);
131+ return 0;
132+}
133+
134+static const struct acpi_device_id chromeos_privacy_screen_device_ids[] = {
135+ {"GOOG0010", 0}, /* Google's electronic privacy screen for eDP-1 */
136+ {}
137+};
138+MODULE_DEVICE_TABLE(acpi, chromeos_privacy_screen_device_ids);
139+
140+static struct acpi_driver chromeos_privacy_screen_driver = {
141+ .name = "chromeos_privacy_screen_driver",
142+ .class = "ChromeOS",
143+ .ids = chromeos_privacy_screen_device_ids,
144+ .ops = {
145+ .add = chromeos_privacy_screen_add,
146+ .remove = chromeos_privacy_screen_remove,
147+ },
148+};
149+
150+module_acpi_driver(chromeos_privacy_screen_driver);
151+MODULE_LICENSE("GPL v2");
152+MODULE_DESCRIPTION("ChromeOS ACPI Privacy Screen driver");
153+MODULE_AUTHOR("Rajat Jain <rajatja@google.com>");
drivers/platform/x86/thinkpad_acpi.c+1−1
@@ -9869,7 +9869,7 @@ static int tpacpi_lcdshadow_init(struct ibm_init_struct *iibm) · 9868 unmodified lines
98699869 return 0;
98709870
98719871 lcdshadow_dev = drm_privacy_screen_register(&tpacpi_pdev->dev,
9872− &lcdshadow_ops);
9872+ &lcdshadow_ops, NULL);
98739873 if (IS_ERR(lcdshadow_dev))
98749874 return PTR_ERR(lcdshadow_dev);
98759875
drivers/video/fbdev/asiliantfb.c+1−1
@@ -110,7 +110,7 @@ static const struct fb_ops asiliantfb_ops = { · 109 unmodified lines
110110 static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dclk2_div)
111111 {
112112 unsigned pixclock = *ppixclock;
113− unsigned Ftarget = 1000000 * (1000000 / pixclock);
113+ unsigned Ftarget;
114114 unsigned n;
115115 unsigned best_error = 0xffffffff;
116116 unsigned best_m = 0xffffffff,
drivers/video/fbdev/core/fbmem.c+26−3
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include <linux/init.h>
2626 #include <linux/linux_logo.h>
2727 #include <linux/proc_fs.h>
28+#include <linux/platform_device.h>
2829 #include <linux/seq_file.h>
2930 #include <linux/console.h>
3031 #include <linux/kmod.h>
@@ -1557,18 +1558,36 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a, · 1526 unmodified lines
15571558 /* check all firmware fbs and kick off if the base addr overlaps */
15581559 for_each_registered_fb(i) {
15591560 struct apertures_struct *gen_aper;
1561+ struct device *device;
15601562
15611563 if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
15621564 continue;
15631565
15641566 gen_aper = registered_fb[i]->apertures;
1567+ device = registered_fb[i]->device;
15651568 if (fb_do_apertures_overlap(gen_aper, a) ||
15661569 (primary && gen_aper && gen_aper->count &&
15671570 gen_aper->ranges[0].base == VGA_FB_PHYS)) {
15681571
15691572 printk(KERN_INFO "fb%d: switching to %s from %s\n",
15701573 i, name, registered_fb[i]->fix.id);
1571− do_unregister_framebuffer(registered_fb[i]);
1574+
1575+ /*
1576+ * If we kick-out a firmware driver, we also want to remove
1577+ * the underlying platform device, such as simple-framebuffer,
1578+ * VESA, EFI, etc. A native driver will then be able to
1579+ * allocate the memory range.
1580+ *
1581+ * If it's not a platform device, at least print a warning. A
1582+ * fix would add code to remove the device from the system.
1583+ */
1584+ if (dev_is_platform(device)) {
1585+ registered_fb[i]->forced_out = true;
1586+ platform_device_unregister(to_platform_device(device));
1587+ } else {
1588+ pr_warn("fb%d: cannot remove device\n", i);
1589+ do_unregister_framebuffer(registered_fb[i]);
1590+ }
15721591 }
15731592 }
15741593 }
@@ -1898,9 +1917,13 @@ EXPORT_SYMBOL(register_framebuffer); · 323 unmodified lines
18981917 void
18991918 unregister_framebuffer(struct fb_info *fb_info)
19001919 {
1901− mutex_lock(&registration_lock);
1920+ bool forced_out = fb_info->forced_out;
1921+
1922+ if (!forced_out)
1923+ mutex_lock(&registration_lock);
19021924 do_unregister_framebuffer(fb_info);
1903− mutex_unlock(&registration_lock);
1925+ if (!forced_out)
1926+ mutex_unlock(&registration_lock);
19041927 }
19051928 EXPORT_SYMBOL(unregister_framebuffer);
19061929
drivers/video/fbdev/s3c-fb.c+1−1
@@ -489,7 +489,7 @@ static int s3c_fb_set_par(struct fb_info *info) · 488 unmodified lines
489489 struct s3c_fb_win *win = info->par;
490490 struct s3c_fb *sfb = win->parent;
491491 void __iomem *regs = sfb->regs;
492− void __iomem *buf = regs;
492+ void __iomem *buf;
493493 int win_no = win->index;
494494 u32 alpha = 0;
495495 u32 data;
drivers/video/fbdev/simplefb.c+45−20
@@ -66,16 +66,36 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, · 65 unmodified lines
6666 return 0;
6767 }
6868
69−struct simplefb_par;
69+struct simplefb_par {
70+ u32 palette[PSEUDO_PALETTE_SIZE];
71+ struct resource *mem;
72+#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
73+ bool clks_enabled;
74+ unsigned int clk_count;
75+ struct clk **clks;
76+#endif
77+#if defined CONFIG_OF && defined CONFIG_REGULATOR
78+ bool regulators_enabled;
79+ u32 regulator_count;
80+ struct regulator **regulators;
81+#endif
82+};
83+
7084 static void simplefb_clocks_destroy(struct simplefb_par *par);
7185 static void simplefb_regulators_destroy(struct simplefb_par *par);
7286
7387 static void simplefb_destroy(struct fb_info *info)
7488 {
89+ struct simplefb_par *par = info->par;
90+ struct resource *mem = par->mem;
91+
7592 simplefb_regulators_destroy(info->par);
7693 simplefb_clocks_destroy(info->par);
7794 if (info->screen_base)
7895 iounmap(info->screen_base);
96+
97+ if (mem)
98+ release_mem_region(mem->start, resource_size(mem));
7999 }
80100
81101 static const struct fb_ops simplefb_ops = {
@@ -169,20 +189,6 @@ static int simplefb_parse_pd(struct platform_device *pdev, · 87 unmodified lines
169189 return 0;
170190 }
171191
172−struct simplefb_par {
173− u32 palette[PSEUDO_PALETTE_SIZE];
174−#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
175− bool clks_enabled;
176− unsigned int clk_count;
177− struct clk **clks;
178−#endif
179−#if defined CONFIG_OF && defined CONFIG_REGULATOR
180− bool regulators_enabled;
181− u32 regulator_count;
182− struct regulator **regulators;
183−#endif
184−};
185−
186192 #if defined CONFIG_OF && defined CONFIG_COMMON_CLK
187193 /*
188194 * Clock handling code.
@@ -405,7 +411,7 @@ static int simplefb_probe(struct platform_device *pdev) · 216 unmodified lines
405411 struct simplefb_params params;
406412 struct fb_info *info;
407413 struct simplefb_par *par;
408− struct resource *mem;
414+ struct resource *res, *mem;
409415
410416 /*
411417 * Generic drivers must not be registered if a framebuffer exists.
@@ -430,15 +436,28 @@ static int simplefb_probe(struct platform_device *pdev) · 18 unmodified lines
430436 if (ret)
431437 return ret;
432438
433− mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
434− if (!mem) {
439+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
440+ if (!res) {
435441 dev_err(&pdev->dev, "No memory resource\n");
436442 return -EINVAL;
437443 }
438444
445+ mem = request_mem_region(res->start, resource_size(res), "simplefb");
446+ if (!mem) {
447+ /*
448+ * We cannot make this fatal. Sometimes this comes from magic
449+ * spaces our resource handlers simply don't know about. Use
450+ * the I/O-memory resource as-is and try to map that instead.
451+ */
452+ dev_warn(&pdev->dev, "simplefb: cannot reserve video memory at %pR\n", res);
453+ mem = res;
454+ }
455+
439456 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
440− if (!info)
441− return -ENOMEM;
457+ if (!info) {
458+ ret = -ENOMEM;
459+ goto error_release_mem_region;
460+ }
442461 platform_set_drvdata(pdev, info);
443462
444463 par = info->par;
@@ -495,6 +514,9 @@ static int simplefb_probe(struct platform_device *pdev) · 50 unmodified lines
495514 info->var.xres, info->var.yres,
496515 info->var.bits_per_pixel, info->fix.line_length);
497516
517+ if (mem != res)
518+ par->mem = mem; /* release in clean-up handler */
519+
498520 ret = register_framebuffer(info);
499521 if (ret < 0) {
500522 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
@@ -513,6 +535,9 @@ error_unmap: · 12 unmodified lines
513535 iounmap(info->screen_base);
514536 error_fb_release:
515537 framebuffer_release(info);
538+error_release_mem_region:
539+ if (mem != res)
540+ release_mem_region(mem->start, resource_size(mem));
516541 return ret;
517542 }
518543
drivers/video/fbdev/vga16fb.c+5−0
@@ -1351,7 +1351,12 @@ static int vga16fb_probe(struct platform_device *dev) · 1350 unmodified lines
13511351 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
13521352 par = info->par;
13531353
1354+#if defined(CONFIG_X86)
1355+ par->isVGA = screen_info.orig_video_isVGA == VIDEO_TYPE_VGAC;
1356+#else
1357+ /* non-x86 architectures treat orig_video_isVGA as a boolean flag */
13541358 par->isVGA = screen_info.orig_video_isVGA;
1359+#endif
13551360 par->palette_blanked = 0;
13561361 par->vesa_blanked = 0;
13571362
include/drm/bridge/dw_mipi_dsi.h+3−1
@@ -51,7 +51,9 @@ struct dw_mipi_dsi_plat_data { · 50 unmodified lines
5151 unsigned int max_data_lanes;
5252
5353 enum drm_mode_status (*mode_valid)(void *priv_data,
54− const struct drm_display_mode *mode);
54+ const struct drm_display_mode *mode,
55+ unsigned long mode_flags,
56+ u32 lanes, u32 format);
5557
5658 const struct dw_mipi_dsi_phy_ops *phy_ops;
5759 const struct dw_mipi_dsi_host_ops *host_ops;
include/drm/dp/drm_dp_aux_bus.hrenamed from include/drm/drm_dp_aux_bus.h+0−0

File renamed without changes.

include/drm/dp/drm_dp_dual_mode_helper.hrenamed from include/drm/drm_dp_dual_mode_helper.h+0−0

File renamed without changes.

include/drm/dp/drm_dp_helper.hrenamed from include/drm/drm_dp_helper.h+2−5
@@ -1038,11 +1038,8 @@ struct drm_panel; · 1037 unmodified lines
10381038 #define DP_SIDEBAND_MSG_UP_REQ_BASE 0x1600 /* 1.2 MST */
10391039
10401040 /* DPRX Event Status Indicator */
1041−#define DP_SINK_COUNT_ESI 0x2002 /* 1.2 */
1042−/* 0-5 sink count */
1043−# define DP_SINK_COUNT_CP_READY (1 << 6)
1044−
1045−#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x2003 /* 1.2 */
1041+#define DP_SINK_COUNT_ESI 0x2002 /* same as 0x200 */
1042+#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x2003 /* same as 0x201 */
10461043
10471044 #define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 0x2004 /* 1.2 */
10481045 # define DP_RX_GTC_MSTR_REQ_STATUS_CHANGE (1 << 0)
include/drm/dp/drm_dp_mst_helper.hrenamed from include/drm/drm_dp_mst_helper.h+1−1
@@ -23,7 +23,7 @@ · 22 unmodified lines
2323 #define _DRM_DP_MST_HELPER_H_
2424
2525 #include <linux/types.h>
26−#include <drm/drm_dp_helper.h>
26+#include <drm/dp/drm_dp_helper.h>
2727 #include <drm/drm_atomic.h>
2828
2929 #if IS_ENABLED(CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS)
include/drm/drm_buddy.h+150−0
@@ -0,0 +1,150 @@
1+/* SPDX-License-Identifier: MIT */
2+/*
3+ * Copyright © 2021 Intel Corporation
4+ */
5+
6+#ifndef __DRM_BUDDY_H__
7+#define __DRM_BUDDY_H__
8+
9+#include <linux/bitops.h>
10+#include <linux/list.h>
11+#include <linux/slab.h>
12+#include <linux/sched.h>
13+
14+#include <drm/drm_print.h>
15+
16+#define range_overflows(start, size, max) ({ \
17+ typeof(start) start__ = (start); \
18+ typeof(size) size__ = (size); \
19+ typeof(max) max__ = (max); \
20+ (void)(&start__ == &size__); \
21+ (void)(&start__ == &max__); \
22+ start__ >= max__ || size__ > max__ - start__; \
23+})
24+
25+struct drm_buddy_block {
26+#define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
27+#define DRM_BUDDY_HEADER_STATE GENMASK_ULL(11, 10)
28+#define DRM_BUDDY_ALLOCATED (1 << 10)
29+#define DRM_BUDDY_FREE (2 << 10)
30+#define DRM_BUDDY_SPLIT (3 << 10)
31+/* Free to be used, if needed in the future */
32+#define DRM_BUDDY_HEADER_UNUSED GENMASK_ULL(9, 6)
33+#define DRM_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0)
34+ u64 header;
35+
36+ struct drm_buddy_block *left;
37+ struct drm_buddy_block *right;
38+ struct drm_buddy_block *parent;
39+
40+ void *private; /* owned by creator */
41+
42+ /*
43+ * While the block is allocated by the user through drm_buddy_alloc*,
44+ * the user has ownership of the link, for example to maintain within
45+ * a list, if so desired. As soon as the block is freed with
46+ * drm_buddy_free* ownership is given back to the mm.
47+ */
48+ struct list_head link;
49+ struct list_head tmp_link;
50+};
51+
52+/* Order-zero must be at least PAGE_SIZE */
53+#define DRM_BUDDY_MAX_ORDER (63 - PAGE_SHIFT)
54+
55+/*
56+ * Binary Buddy System.
57+ *
58+ * Locking should be handled by the user, a simple mutex around
59+ * drm_buddy_alloc* and drm_buddy_free* should suffice.
60+ */
61+struct drm_buddy {
62+ /* Maintain a free list for each order. */
63+ struct list_head *free_list;
64+
65+ /*
66+ * Maintain explicit binary tree(s) to track the allocation of the
67+ * address space. This gives us a simple way of finding a buddy block
68+ * and performing the potentially recursive merge step when freeing a
69+ * block. Nodes are either allocated or free, in which case they will
70+ * also exist on the respective free list.
71+ */
72+ struct drm_buddy_block **roots;
73+
74+ /*
75+ * Anything from here is public, and remains static for the lifetime of
76+ * the mm. Everything above is considered do-not-touch.
77+ */
78+ unsigned int n_roots;
79+ unsigned int max_order;
80+
81+ /* Must be at least PAGE_SIZE */
82+ u64 chunk_size;
83+ u64 size;
84+ u64 avail;
85+};
86+
87+static inline u64
88+drm_buddy_block_offset(struct drm_buddy_block *block)
89+{
90+ return block->header & DRM_BUDDY_HEADER_OFFSET;
91+}
92+
93+static inline unsigned int
94+drm_buddy_block_order(struct drm_buddy_block *block)
95+{
96+ return block->header & DRM_BUDDY_HEADER_ORDER;
97+}
98+
99+static inline unsigned int
100+drm_buddy_block_state(struct drm_buddy_block *block)
101+{
102+ return block->header & DRM_BUDDY_HEADER_STATE;
103+}
104+
105+static inline bool
106+drm_buddy_block_is_allocated(struct drm_buddy_block *block)
107+{
108+ return drm_buddy_block_state(block) == DRM_BUDDY_ALLOCATED;
109+}
110+
111+static inline bool
112+drm_buddy_block_is_free(struct drm_buddy_block *block)
113+{
114+ return drm_buddy_block_state(block) == DRM_BUDDY_FREE;
115+}
116+
117+static inline bool
118+drm_buddy_block_is_split(struct drm_buddy_block *block)
119+{
120+ return drm_buddy_block_state(block) == DRM_BUDDY_SPLIT;
121+}
122+
123+static inline u64
124+drm_buddy_block_size(struct drm_buddy *mm,
125+ struct drm_buddy_block *block)
126+{
127+ return mm->chunk_size << drm_buddy_block_order(block);
128+}
129+
130+int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size);
131+
132+void drm_buddy_fini(struct drm_buddy *mm);
133+
134+struct drm_buddy_block *
135+drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned int order);
136+
137+int drm_buddy_alloc_range(struct drm_buddy *mm,
138+ struct list_head *blocks,
139+ u64 start, u64 size);
140+
141+void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
142+
143+void drm_buddy_free_list(struct drm_buddy *mm, struct list_head *objects);
144+
145+void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p);
146+void drm_buddy_block_print(struct drm_buddy *mm,
147+ struct drm_buddy_block *block,
148+ struct drm_printer *p);
149+
150+#endif
include/drm/drm_connector.h+12−6
@@ -522,9 +522,9 @@ struct drm_display_info { · 521 unmodified lines
522522 enum subpixel_order subpixel_order;
523523
524524 #define DRM_COLOR_FORMAT_RGB444 (1<<0)
525−#define DRM_COLOR_FORMAT_YCRCB444 (1<<1)
526−#define DRM_COLOR_FORMAT_YCRCB422 (1<<2)
527−#define DRM_COLOR_FORMAT_YCRCB420 (1<<3)
525+#define DRM_COLOR_FORMAT_YCBCR444 (1<<1)
526+#define DRM_COLOR_FORMAT_YCBCR422 (1<<2)
527+#define DRM_COLOR_FORMAT_YCBCR420 (1<<3)
528528
529529 /**
530530 * @panel_orientation: Read only connector property for built-in panels,
@@ -592,10 +592,16 @@ struct drm_display_info { · 61 unmodified lines
592592 bool rgb_quant_range_selectable;
593593
594594 /**
595− * @edid_hdmi_dc_modes: Mask of supported hdmi deep color modes. Even
596− * more stuff redundant with @bus_formats.
595+ * @edid_hdmi_dc_rgb444_modes: Mask of supported hdmi deep color modes
596+ * in RGB 4:4:4. Even more stuff redundant with @bus_formats.
597597 */
598− u8 edid_hdmi_dc_modes;
598+ u8 edid_hdmi_rgb444_dc_modes;
599+
600+ /**
601+ * @edid_hdmi_dc_ycbcr444_modes: Mask of supported hdmi deep color
602+ * modes in YCbCr 4:4:4. Even more stuff redundant with @bus_formats.
603+ */
604+ u8 edid_hdmi_ycbcr444_dc_modes;
599605
600606 /**
601607 * @cea_rev: CEA revision of the HDMI sink.
include/drm/drm_crtc.h+10−0
@@ -285,6 +285,10 @@ struct drm_crtc_state { · 284 unmodified lines
285285 * Lookup table for converting pixel data after the color conversion
286286 * matrix @ctm. See drm_crtc_enable_color_mgmt(). The blob (if not
287287 * NULL) is an array of &struct drm_color_lut.
288+ *
289+ * Note that for mostly historical reasons stemming from Xorg heritage,
290+ * this is also used to store the color map (also sometimes color lut,
291+ * CLUT or color palette) for indexed formats like DRM_FORMAT_C8.
288292 */
289293 struct drm_property_blob *gamma_lut;
290294
@@ -1075,12 +1079,18 @@ struct drm_crtc { · 784 unmodified lines
10751079 /**
10761080 * @gamma_size: Size of legacy gamma ramp reported to userspace. Set up
10771081 * by calling drm_mode_crtc_set_gamma_size().
1082+ *
1083+ * Note that atomic drivers need to instead use
1084+ * &drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt().
10781085 */
10791086 uint32_t gamma_size;
10801087
10811088 /**
10821089 * @gamma_store: Gamma ramp values used by the legacy SETGAMMA and
10831090 * GETGAMMA IOCTls. Set up by calling drm_mode_crtc_set_gamma_size().
1091+ *
1092+ * Note that atomic drivers need to instead use
1093+ * &drm_crtc_state.gamma_lut. See drm_crtc_enable_color_mgmt().
10841094 */
10851095 uint16_t *gamma_store;
10861096
include/drm/drm_dsc.h+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88 #ifndef DRM_DSC_H_
99 #define DRM_DSC_H_
1010
11−#include <drm/drm_dp_helper.h>
11+#include <drm/dp/drm_dp_helper.h>
1212
1313 /* VESA Display Stream Compression DSC 1.2 constants */
1414 #define DSC_NUM_BUF_RANGES 15
include/drm/drm_edid.h+2−2
@@ -401,8 +401,8 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, · 400 unmodified lines
401401 const struct drm_display_mode *mode);
402402
403403 void
404−drm_hdmi_avi_infoframe_colorspace(struct hdmi_avi_infoframe *frame,
405− const struct drm_connector_state *conn_state);
404+drm_hdmi_avi_infoframe_colorimetry(struct hdmi_avi_infoframe *frame,
405+ const struct drm_connector_state *conn_state);
406406
407407 void
408408 drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
include/drm/drm_mipi_dbi.h+1−1
@@ -194,7 +194,7 @@ int mipi_dbi_buf_copy(void *dst, struct drm_framebuffer *fb, · 193 unmodified lines
194194 #ifdef CONFIG_DEBUG_FS
195195 void mipi_dbi_debugfs_init(struct drm_minor *minor);
196196 #else
197−#define mipi_dbi_debugfs_init NULL
197+static inline void mipi_dbi_debugfs_init(struct drm_minor *minor) {}
198198 #endif
199199
200200 #endif /* __LINUX_MIPI_DBI_H */
include/drm/drm_modeset_lock.h+1−0
@@ -34,6 +34,7 @@ struct drm_modeset_lock; · 33 unmodified lines
3434 * struct drm_modeset_acquire_ctx - locking context (see ww_acquire_ctx)
3535 * @ww_ctx: base acquire ctx
3636 * @contended: used internally for -EDEADLK handling
37+ * @stack_depot: used internally for contention debugging
3738 * @locked: list of held locks
3839 * @trylock_only: trylock mode used in atomic contexts/panic notifiers
3940 * @interruptible: whether interruptible locking should be used.
include/drm/drm_module.h+125−0
@@ -0,0 +1,125 @@
1+/* SPDX-License-Identifier: MIT */
2+
3+#ifndef DRM_MODULE_H
4+#define DRM_MODULE_H
5+
6+#include <linux/pci.h>
7+#include <linux/platform_device.h>
8+
9+#include <drm/drm_drv.h>
10+
11+/**
12+ * DOC: overview
13+ *
14+ * This library provides helpers registering DRM drivers during module
15+ * initialization and shutdown. The provided helpers act like bus-specific
16+ * module helpers, such as module_pci_driver(), but respect additional
17+ * parameters that control DRM driver registration.
18+ *
19+ * Below is an example of initializing a DRM driver for a device on the
20+ * PCI bus.
21+ *
22+ * .. code-block:: c
23+ *
24+ * struct pci_driver my_pci_drv = {
25+ * };
26+ *
27+ * drm_module_pci_driver(my_pci_drv);
28+ *
29+ * The generated code will test if DRM drivers are enabled and register
30+ * the PCI driver my_pci_drv. For more complex module initialization, you
31+ * can still use module_init() and module_exit() in your driver.
32+ */
33+
34+/*
35+ * PCI drivers
36+ */
37+
38+static inline int __init drm_pci_register_driver(struct pci_driver *pci_drv)
39+{
40+ if (drm_firmware_drivers_only())
41+ return -ENODEV;
42+
43+ return pci_register_driver(pci_drv);
44+}
45+
46+/**
47+ * drm_module_pci_driver - Register a DRM driver for PCI-based devices
48+ * @__pci_drv: the PCI driver structure
49+ *
50+ * Registers a DRM driver for devices on the PCI bus. The helper
51+ * macro behaves like module_pci_driver() but tests the state of
52+ * drm_firmware_drivers_only(). For more complex module initialization,
53+ * use module_init() and module_exit() directly.
54+ *
55+ * Each module may only use this macro once. Calling it replaces
56+ * module_init() and module_exit().
57+ */
58+#define drm_module_pci_driver(__pci_drv) \
59+ module_driver(__pci_drv, drm_pci_register_driver, pci_unregister_driver)
60+
61+static inline int __init
62+drm_pci_register_driver_if_modeset(struct pci_driver *pci_drv, int modeset)
63+{
64+ if (drm_firmware_drivers_only() && modeset == -1)
65+ return -ENODEV;
66+ if (modeset == 0)
67+ return -ENODEV;
68+
69+ return pci_register_driver(pci_drv);
70+}
71+
72+static inline void __exit
73+drm_pci_unregister_driver_if_modeset(struct pci_driver *pci_drv, int modeset)
74+{
75+ pci_unregister_driver(pci_drv);
76+}
77+
78+/**
79+ * drm_module_pci_driver_if_modeset - Register a DRM driver for PCI-based devices
80+ * @__pci_drv: the PCI driver structure
81+ * @__modeset: an additional parameter that disables the driver
82+ *
83+ * This macro is deprecated and only provided for existing drivers. For
84+ * new drivers, use drm_module_pci_driver().
85+ *
86+ * Registers a DRM driver for devices on the PCI bus. The helper macro
87+ * behaves like drm_module_pci_driver() with an additional driver-specific
88+ * flag. If __modeset is 0, the driver has been disabled, if __modeset is
89+ * -1 the driver state depends on the global DRM state. For all other
90+ * values, the PCI driver has been enabled. The default should be -1.
91+ */
92+#define drm_module_pci_driver_if_modeset(__pci_drv, __modeset) \
93+ module_driver(__pci_drv, drm_pci_register_driver_if_modeset, \
94+ drm_pci_unregister_driver_if_modeset, __modeset)
95+
96+/*
97+ * Platform drivers
98+ */
99+
100+static inline int __init
101+drm_platform_driver_register(struct platform_driver *platform_drv)
102+{
103+ if (drm_firmware_drivers_only())
104+ return -ENODEV;
105+
106+ return platform_driver_register(platform_drv);
107+}
108+
109+/**
110+ * drm_module_platform_driver - Register a DRM driver for platform devices
111+ * @__platform_drv: the platform driver structure
112+ *
113+ * Registers a DRM driver for devices on the platform bus. The helper
114+ * macro behaves like module_platform_driver() but tests the state of
115+ * drm_firmware_drivers_only(). For more complex module initialization,
116+ * use module_init() and module_exit() directly.
117+ *
118+ * Each module may only use this macro once. Calling it replaces
119+ * module_init() and module_exit().
120+ */
121+#define drm_module_platform_driver(__platform_drv) \
122+ module_driver(__platform_drv, drm_platform_driver_register, \
123+ platform_driver_unregister)
124+
125+#endif
include/drm/drm_plane.h+1−1
@@ -516,7 +516,7 @@ struct drm_plane_funcs { · 515 unmodified lines
516516 * This optional hook is used for the DRM to determine if the given
517517 * format/modifier combination is valid for the plane. This allows the
518518 * DRM to generate the correct format bitmask (which formats apply to
519− * which modifier), and to valdiate modifiers at atomic_check time.
519+ * which modifier), and to validate modifiers at atomic_check time.
520520 *
521521 * If not present, then any modifier in the plane's modifier
522522 * list is allowed with any of the plane's formats.
include/drm/drm_privacy_screen_driver.h+12−1
@@ -73,10 +73,21 @@ struct drm_privacy_screen { · 72 unmodified lines
7373 * for more info.
7474 */
7575 enum drm_privacy_screen_status hw_state;
76+ /**
77+ * @drvdata: Private data owned by the privacy screen provider
78+ */
79+ void *drvdata;
7680 };
7781
82+static inline
83+void *drm_privacy_screen_get_drvdata(struct drm_privacy_screen *priv)
84+{
85+ return priv->drvdata;
86+}
87+
7888 struct drm_privacy_screen *drm_privacy_screen_register(
79− struct device *parent, const struct drm_privacy_screen_ops *ops);
89+ struct device *parent, const struct drm_privacy_screen_ops *ops,
90+ void *data);
8091 void drm_privacy_screen_unregister(struct drm_privacy_screen *priv);
8192
8293 void drm_privacy_screen_call_notifier_chain(struct drm_privacy_screen *priv);
include/drm/ttm/ttm_resource.h+16−7
@@ -105,11 +105,11 @@ struct ttm_resource_manager_func { · 104 unmodified lines
105105 * @use_type: The memory type is enabled.
106106 * @use_tt: If a TT object should be used for the backing store.
107107 * @size: Size of the managed region.
108+ * @bdev: ttm device this manager belongs to
108109 * @func: structure pointer implementing the range manager. See above
109110 * @move_lock: lock for move fence
110− * static information. bdev::driver::io_mem_free is never used.
111− * @lru: The lru list for this memory type.
112111 * @move: The fence of the last pipelined move operation.
112+ * @lru: The lru list for this memory type.
113113 *
114114 * This structure is used to identify and manage memory types for a device.
115115 */
@@ -119,20 +119,21 @@ struct ttm_resource_manager { · 3 unmodified lines
119119 */
120120 bool use_type;
121121 bool use_tt;
122+ struct ttm_device *bdev;
122123 uint64_t size;
123124 const struct ttm_resource_manager_func *func;
124125 spinlock_t move_lock;
125126
126127 /*
127− * Protected by the global->lru_lock.
128+ * Protected by @move_lock.
128129 */
129−
130− struct list_head lru[TTM_MAX_BO_PRIORITY];
130+ struct dma_fence *move;
131131
132132 /*
133− * Protected by @move_lock.
133+ * Protected by the global->lru_lock.
134134 */
135− struct dma_fence *move;
135+
136+ struct list_head lru[TTM_MAX_BO_PRIORITY];
136137 };
137138
138139 /**
@@ -160,6 +161,7 @@ struct ttm_bus_placement { · 21 unmodified lines
160161 * @mem_type: Resource type of the allocation.
161162 * @placement: Placement flags.
162163 * @bus: Placement on io bus accessible to the CPU
164+ * @bo: weak reference to the BO, protected by ttm_device::lru_lock
163165 *
164166 * Structure indicating the placement and space resources used by a
165167 * buffer object.
@@ -170,6 +172,7 @@ struct ttm_resource { · 4 unmodified lines
170172 uint32_t mem_type;
171173 uint32_t placement;
172174 struct ttm_bus_placement bus;
175+ struct ttm_buffer_object *bo;
173176 };
174177
175178 /**
@@ -261,14 +264,20 @@ ttm_resource_manager_cleanup(struct ttm_resource_manager *man) · 85 unmodified lines
261264 void ttm_resource_init(struct ttm_buffer_object *bo,
262265 const struct ttm_place *place,
263266 struct ttm_resource *res);
267+void ttm_resource_fini(struct ttm_resource_manager *man,
268+ struct ttm_resource *res);
269+
264270 int ttm_resource_alloc(struct ttm_buffer_object *bo,
265271 const struct ttm_place *place,
266272 struct ttm_resource **res);
267273 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
268274 bool ttm_resource_compat(struct ttm_resource *res,
269275 struct ttm_placement *placement);
276+void ttm_resource_set_bo(struct ttm_resource *res,
277+ struct ttm_buffer_object *bo);
270278
271279 void ttm_resource_manager_init(struct ttm_resource_manager *man,
280+ struct ttm_device *bdev,
272281 unsigned long p_size);
273282
274283 int ttm_resource_manager_evict_all(struct ttm_device *bdev,
include/linux/dma-buf-map.h+2−2
@@ -52,13 +52,13 @@ · 51 unmodified lines
5252 *
5353 * struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(0xdeadbeaf);
5454 *
55− * dma_buf_map_set_vaddr(&map. 0xdeadbeaf);
55+ * dma_buf_map_set_vaddr(&map, 0xdeadbeaf);
5656 *
5757 * To set an address in I/O memory, use dma_buf_map_set_vaddr_iomem().
5858 *
5959 * .. code-block:: c
6060 *
61− * dma_buf_map_set_vaddr_iomem(&map. 0xdeadbeaf);
61+ * dma_buf_map_set_vaddr_iomem(&map, 0xdeadbeaf);
6262 *
6363 * Instances of struct dma_buf_map do not have to be cleaned up, but
6464 * can be cleared to NULL with dma_buf_map_clear(). Cleared mappings
include/linux/dma-resv.h+2−2
@@ -458,8 +458,8 @@ void dma_resv_fini(struct dma_resv *obj); · 457 unmodified lines
458458 int dma_resv_reserve_shared(struct dma_resv *obj, unsigned int num_fences);
459459 void dma_resv_add_shared_fence(struct dma_resv *obj, struct dma_fence *fence);
460460 void dma_resv_add_excl_fence(struct dma_resv *obj, struct dma_fence *fence);
461−int dma_resv_get_fences(struct dma_resv *obj, struct dma_fence **pfence_excl,
462− unsigned *pshared_count, struct dma_fence ***pshared);
461+int dma_resv_get_fences(struct dma_resv *obj, bool write,
462+ unsigned int *num_fences, struct dma_fence ***fences);
463463 int dma_resv_copy_fences(struct dma_resv *dst, struct dma_resv *src);
464464 long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr,
465465 unsigned long timeout);
include/linux/fb.h+1−0
@@ -502,6 +502,7 @@ struct fb_info { · 501 unmodified lines
502502 } *apertures;
503503
504504 bool skip_vt_switch; /* no VT switch on suspend/resume required */
505+ bool forced_out; /* set when being removed by another driver */
505506 };
506507
507508 static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
include/linux/rwsem.h+1−1
@@ -230,7 +230,7 @@ extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map * · 229 unmodified lines
230230 do { \
231231 typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
232232 _down_write_nest_lock(sem, &(nest_lock)->dep_map); \
233−} while (0);
233+} while (0)
234234
235235 /*
236236 * Take/release a lock when not the owner will release it.
include/soc/bcm2835/raspberrypi-firmware.h+1−0
@@ -91,6 +91,7 @@ enum rpi_firmware_property_tag { · 90 unmodified lines
9191 RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
9292 RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
9393 RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
94+ RPI_FIRMWARE_NOTIFY_DISPLAY_DONE = 0x00030066,
9495
9596 /* Dispmanx TAGS */
9697 RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
include/uapi/drm/panfrost_drm.h+2−2
@@ -84,14 +84,14 @@ struct drm_panfrost_wait_bo { · 83 unmodified lines
8484 __s64 timeout_ns; /* absolute */
8585 };
8686
87+/* Valid flags to pass to drm_panfrost_create_bo */
8788 #define PANFROST_BO_NOEXEC 1
8889 #define PANFROST_BO_HEAP 2
8990
9091 /**
9192 * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs.
9293 *
93− * There are currently no values for the flags argument, but it may be
94− * used in a future extension.
94+ * The flags argument is a bit mask of PANFROST_BO_* flags.
9595 */
9696 struct drm_panfrost_create_bo {
9797 __u32 size;