History

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

drm-misc-next for 6.2: UAPI Changes: - Documentation for page-flip flags Cross-subsystem Changes: - dma-buf: Add unlocked variant of vmapping and attachment-mapping functions Core Changes: - atomic-helpers: CRTC primary plane test fixes - connector: TV API consistency improvements, cmdline parsing improvements - crtc-helpers: Introduce drm_crtc_helper_atomic_check() helper - edid: Fixes for HFVSDB parsing, - fourcc: Addition of the Vivante tiled modifier - makefile: Sort and reorganize the objects files - mode_config: Remove fb_base from drm_mode_config_funcs - sched: Add a module parameter to change the scheduling policy, refcounting fix for fences - tests: Sort the Kunit tests in the Makefile, improvements to the DP-MST tests - ttm: Remove unnecessary drm_mm_clean() call Driver Changes: - New driver: ofdrm - Move all drivers to a common dma-buf locking convention - bridge: - adv7533: Remove dynamic lane switching - it6505: Runtime PM support - ps8640: Handle AUX defer messages - tc358775: Drop soft-reset over I2C - ast: Atomic Gamma LUT Support, Convert to SHMEM, various improvements - lcdif: Support for YUV planes - mgag200: Fix PLL Setup on some revisions - udl: Modesetting improvements, hot-unplug support - vc4: Fix support for PAL-M Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 4 years ago

Commit b837d3d2 parents 247f34f 7c99616110 files · +3849 −1353Browse files

Unified · Split

110 files
  1. Documentation/driver-api/dma-buf.rst +6 −0
  2. MAINTAINERS +1 −0
  3. drivers/dma-buf/dma-buf.c +185 −31
  4. drivers/gpu/drm/Makefile +77 −30
  5. drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +0 −2
  6. drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +0 −2
  7. drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +0 −2
  8. drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +0 −1
  9. drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +0 −2
  10. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +0 −2
  11. drivers/gpu/drm/armada/armada_gem.c +4 −4
  12. drivers/gpu/drm/ast/Kconfig +1 −3
  13. drivers/gpu/drm/ast/ast_drv.c +2 −2
  14. drivers/gpu/drm/ast/ast_drv.h +18 −16
  15. drivers/gpu/drm/ast/ast_main.c +2 −3
  16. drivers/gpu/drm/ast/ast_mm.c +7 −7
  17. drivers/gpu/drm/ast/ast_mode.c +265 −234
  18. drivers/gpu/drm/bridge/adv7511/adv7511.h +2 −1
  19. drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +14 −4
  20. drivers/gpu/drm/bridge/adv7511/adv7533.c +13 −12
  21. drivers/gpu/drm/bridge/ite-it6505.c +48 −10
  22. drivers/gpu/drm/bridge/parade-ps8640.c +8 −1
  23. drivers/gpu/drm/bridge/tc358775.c +1 −1
  24. drivers/gpu/drm/display/Makefile +8 −6
  25. drivers/gpu/drm/drm_atomic_helper.c +18 −42
  26. drivers/gpu/drm/drm_atomic_state_helper.c +3 −3
  27. drivers/gpu/drm/drm_atomic_uapi.c +4 −0
  28. drivers/gpu/drm/drm_client.c +2 −2
  29. drivers/gpu/drm/drm_crtc_helper.c +26 −0
  30. drivers/gpu/drm/drm_edid.c +222 −124
  31. drivers/gpu/drm/drm_format_helper.c +10 −0
  32. drivers/gpu/drm/drm_gem.c +24 −0
  33. drivers/gpu/drm/drm_gem_dma_helper.c +3 −3
  34. drivers/gpu/drm/drm_gem_framebuffer_helper.c +3 −3
  35. drivers/gpu/drm/drm_gem_ttm_helper.c +1 −8
  36. drivers/gpu/drm/drm_modes.c +11 −7
  37. drivers/gpu/drm/drm_plane_helper.c +3 −1
  38. drivers/gpu/drm/drm_prime.c +3 −3
  39. drivers/gpu/drm/drm_simple_kms_helper.c +5 −1
  40. drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +1 −1
  41. drivers/gpu/drm/gma500/framebuffer.c +3 −3
  42. drivers/gpu/drm/gma500/psb_drv.h +1 −0
  43. drivers/gpu/drm/gud/gud_connector.c +1 −1
  44. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +3 −13
  45. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +0 −3
  46. drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +1 −1
  47. drivers/gpu/drm/i915/gem/i915_gem_object.c +14 −0
  48. drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c +8 −8
  49. drivers/gpu/drm/lima/lima_sched.c +2 −2
  50. drivers/gpu/drm/mgag200/mgag200_g200se.c +2 −1
  51. drivers/gpu/drm/mgag200/mgag200_mode.c +5 −6
  52. drivers/gpu/drm/msm/msm_fbdev.c +0 −2
  53. drivers/gpu/drm/mxsfb/lcdif_kms.c +216 −23
  54. drivers/gpu/drm/mxsfb/lcdif_regs.h +20 −17
  55. drivers/gpu/drm/nouveau/dispnv50/disp.c +2 −2
  56. drivers/gpu/drm/nouveau/nouveau_display.c +0 −1
  57. drivers/gpu/drm/nouveau/nv04_fbcon.c +4 −2
  58. drivers/gpu/drm/omapdrm/omap_fbdev.c +0 −2
  59. drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c +2 −2
  60. drivers/gpu/drm/panel/panel-samsung-db7430.c +7 −0
  61. drivers/gpu/drm/panel/panel-tpo-tpg110.c +7 −0
  62. drivers/gpu/drm/panel/panel-widechips-ws2401.c +7 −0
  63. drivers/gpu/drm/panfrost/panfrost_dump.c +2 −2
  64. drivers/gpu/drm/panfrost/panfrost_perfcnt.c +3 −3
  65. drivers/gpu/drm/qxl/qxl_display.c +0 −2
  66. drivers/gpu/drm/qxl/qxl_object.c +9 −8
  67. drivers/gpu/drm/qxl/qxl_prime.c +2 −2
  68. drivers/gpu/drm/radeon/radeon_display.c +0 −2
  69. drivers/gpu/drm/radeon/radeon_fb.c +1 −1
  70. drivers/gpu/drm/scheduler/sched_entity.c +25 −1
  71. drivers/gpu/drm/scheduler/sched_main.c +93 −3
  72. drivers/gpu/drm/solomon/ssd130x.c +13 −22
  73. drivers/gpu/drm/tegra/fb.c +0 −1
  74. drivers/gpu/drm/tegra/gem.c +9 −8
  75. drivers/gpu/drm/tests/Makefile +11 −3
  76. drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +295 −150
  77. drivers/gpu/drm/tiny/Kconfig +13 −0
  78. drivers/gpu/drm/tiny/Makefile +1 −0
  79. drivers/gpu/drm/tiny/bochs.c +0 −1
  80. drivers/gpu/drm/tiny/ofdrm.c +1424 −0
  81. drivers/gpu/drm/tiny/simpledrm.c +2 −14
  82. drivers/gpu/drm/ttm/ttm_range_manager.c +0 −1
  83. drivers/gpu/drm/udl/Makefile +1 −1
  84. drivers/gpu/drm/udl/udl_connector.c +0 −139
  85. drivers/gpu/drm/udl/udl_connector.h +0 −15
  86. drivers/gpu/drm/udl/udl_drv.h +18 −24
  87. drivers/gpu/drm/udl/udl_modeset.c +363 −203
  88. drivers/gpu/drm/udl/udl_proto.h +68 −0
  89. drivers/gpu/drm/udl/udl_transfer.c +4 −3
  90. drivers/gpu/drm/vc4/vc4_hdmi.c +1 −1
  91. drivers/gpu/drm/vc4/vc4_vec.c +4 −4
  92. drivers/infiniband/core/umem_dmabuf.c +4 −3
  93. drivers/media/common/videobuf2/videobuf2-dma-contig.c +7 −15
  94. drivers/media/common/videobuf2/videobuf2-dma-sg.c +5 −14
  95. drivers/media/common/videobuf2/videobuf2-vmalloc.c +4 −13
  96. drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c +3 −3
  97. drivers/misc/fastrpc.c +3 −3
  98. drivers/video/fbdev/Kconfig +1 −0
  99. drivers/xen/gntdev-dmabuf.c +4 −4
  100. include/drm/drm_atomic_helper.h +1 −2
  101. include/drm/drm_atomic_state_helper.h +1 −1
  102. include/drm/drm_connector.h +3 −1
  103. include/drm/drm_crtc_helper.h +2 −0
  104. include/drm/drm_edid.h +9 −5
  105. include/drm/drm_gem.h +3 −0
  106. include/drm/drm_mode_config.h +0 −2
  107. include/drm/gpu_scheduler.h +32 −0
  108. include/linux/dma-buf.h +8 −9
  109. include/uapi/drm/drm_fourcc.h +29 −0
  110. include/uapi/drm/drm_mode.h +62 −1
Documentation/driver-api/dma-buf.rst+6−0
@@ -119,6 +119,12 @@ DMA Buffer ioctls · 118 unmodified lines
119119
120120 .. kernel-doc:: include/uapi/linux/dma-buf.h
121121
122+DMA-BUF locking convention
123+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124+
125+.. kernel-doc:: drivers/dma-buf/dma-buf.c
126+ :doc: locking convention
127+
122128 Kernel Functions and Structures Reference
123129 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124130
MAINTAINERS+1−0
@@ -6692,6 +6692,7 @@ L: dri-devel@lists.freedesktop.org · 6691 unmodified lines
66926692 S: Maintained
66936693 T: git git://anongit.freedesktop.org/drm/drm-misc
66946694 F: drivers/gpu/drm/drm_aperture.c
6695+F: drivers/gpu/drm/tiny/ofdrm.c
66956696 F: drivers/gpu/drm/tiny/simpledrm.c
66966697 F: drivers/video/aperture.c
66976698 F: include/drm/drm_aperture.h
drivers/dma-buf/dma-buf.c+185−31
@@ -657,7 +657,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) · 656 unmodified lines
657657
658658 dmabuf->file = file;
659659
660− mutex_init(&dmabuf->lock);
661660 INIT_LIST_HEAD(&dmabuf->attachments);
662661
663662 mutex_lock(&db_list.lock);
@@ -795,6 +794,70 @@ static struct sg_table * __map_dma_buf(struct dma_buf_attachment *attach, · 131 unmodified lines
795794 return sg_table;
796795 }
797796
797+/**
798+ * DOC: locking convention
799+ *
800+ * In order to avoid deadlock situations between dma-buf exports and importers,
801+ * all dma-buf API users must follow the common dma-buf locking convention.
802+ *
803+ * Convention for importers
804+ *
805+ * 1. Importers must hold the dma-buf reservation lock when calling these
806+ * functions:
807+ *
808+ * - dma_buf_pin()
809+ * - dma_buf_unpin()
810+ * - dma_buf_map_attachment()
811+ * - dma_buf_unmap_attachment()
812+ * - dma_buf_vmap()
813+ * - dma_buf_vunmap()
814+ *
815+ * 2. Importers must not hold the dma-buf reservation lock when calling these
816+ * functions:
817+ *
818+ * - dma_buf_attach()
819+ * - dma_buf_dynamic_attach()
820+ * - dma_buf_detach()
821+ * - dma_buf_export(
822+ * - dma_buf_fd()
823+ * - dma_buf_get()
824+ * - dma_buf_put()
825+ * - dma_buf_mmap()
826+ * - dma_buf_begin_cpu_access()
827+ * - dma_buf_end_cpu_access()
828+ * - dma_buf_map_attachment_unlocked()
829+ * - dma_buf_unmap_attachment_unlocked()
830+ * - dma_buf_vmap_unlocked()
831+ * - dma_buf_vunmap_unlocked()
832+ *
833+ * Convention for exporters
834+ *
835+ * 1. These &dma_buf_ops callbacks are invoked with unlocked dma-buf
836+ * reservation and exporter can take the lock:
837+ *
838+ * - &dma_buf_ops.attach()
839+ * - &dma_buf_ops.detach()
840+ * - &dma_buf_ops.release()
841+ * - &dma_buf_ops.begin_cpu_access()
842+ * - &dma_buf_ops.end_cpu_access()
843+ *
844+ * 2. These &dma_buf_ops callbacks are invoked with locked dma-buf
845+ * reservation and exporter can't take the lock:
846+ *
847+ * - &dma_buf_ops.pin()
848+ * - &dma_buf_ops.unpin()
849+ * - &dma_buf_ops.map_dma_buf()
850+ * - &dma_buf_ops.unmap_dma_buf()
851+ * - &dma_buf_ops.mmap()
852+ * - &dma_buf_ops.vmap()
853+ * - &dma_buf_ops.vunmap()
854+ *
855+ * 3. Exporters must hold the dma-buf reservation lock when calling these
856+ * functions:
857+ *
858+ * - dma_buf_move_notify()
859+ */
860+
798861 /**
799862 * dma_buf_dynamic_attach - Add the device to dma_buf's attachments list
800863 * @dmabuf: [in] buffer to attach device to.
@@ -859,8 +922,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, · 58 unmodified lines
859922 dma_buf_is_dynamic(dmabuf)) {
860923 struct sg_table *sgt;
861924
925+ dma_resv_lock(attach->dmabuf->resv, NULL);
862926 if (dma_buf_is_dynamic(attach->dmabuf)) {
863− dma_resv_lock(attach->dmabuf->resv, NULL);
864927 ret = dmabuf->ops->pin(attach);
865928 if (ret)
866929 goto err_unlock;
@@ -873,8 +936,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, · 6 unmodified lines
873936 ret = PTR_ERR(sgt);
874937 goto err_unpin;
875938 }
876− if (dma_buf_is_dynamic(attach->dmabuf))
877− dma_resv_unlock(attach->dmabuf->resv);
939+ dma_resv_unlock(attach->dmabuf->resv);
878940 attach->sgt = sgt;
879941 attach->dir = DMA_BIDIRECTIONAL;
880942 }
@@ -890,8 +952,7 @@ err_unpin: · 9 unmodified lines
890952 dmabuf->ops->unpin(attach);
891953
892954 err_unlock:
893− if (dma_buf_is_dynamic(attach->dmabuf))
894− dma_resv_unlock(attach->dmabuf->resv);
955+ dma_resv_unlock(attach->dmabuf->resv);
895956
896957 dma_buf_detach(dmabuf, attach);
897958 return ERR_PTR(ret);
@@ -937,21 +998,19 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) · 39 unmodified lines
937998 if (WARN_ON(!dmabuf || !attach))
938999 return;
9391000
1001+ dma_resv_lock(attach->dmabuf->resv, NULL);
1002+
9401003 if (attach->sgt) {
941− if (dma_buf_is_dynamic(attach->dmabuf))
942− dma_resv_lock(attach->dmabuf->resv, NULL);
9431004
9441005 __unmap_dma_buf(attach, attach->sgt, attach->dir);
9451006
946− if (dma_buf_is_dynamic(attach->dmabuf)) {
1007+ if (dma_buf_is_dynamic(attach->dmabuf))
9471008 dmabuf->ops->unpin(attach);
948− dma_resv_unlock(attach->dmabuf->resv);
949− }
9501009 }
951−
952− dma_resv_lock(dmabuf->resv, NULL);
9531010 list_del(&attach->node);
1011+
9541012 dma_resv_unlock(dmabuf->resv);
1013+
9551014 if (dmabuf->ops->detach)
9561015 dmabuf->ops->detach(dmabuf, attach);
9571016
@@ -1042,8 +1101,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 84 unmodified lines
10421101 if (WARN_ON(!attach || !attach->dmabuf))
10431102 return ERR_PTR(-EINVAL);
10441103
1045− if (dma_buf_attachment_is_dynamic(attach))
1046− dma_resv_assert_held(attach->dmabuf->resv);
1104+ dma_resv_assert_held(attach->dmabuf->resv);
10471105
10481106 if (attach->sgt) {
10491107 /*
@@ -1058,7 +1116,6 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 8 unmodified lines
10581116 }
10591117
10601118 if (dma_buf_is_dynamic(attach->dmabuf)) {
1061− dma_resv_assert_held(attach->dmabuf->resv);
10621119 if (!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) {
10631120 r = attach->dmabuf->ops->pin(attach);
10641121 if (r)
@@ -1100,6 +1157,34 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 35 unmodified lines
11001157 }
11011158 EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment, DMA_BUF);
11021159
1160+/**
1161+ * dma_buf_map_attachment_unlocked - Returns the scatterlist table of the attachment;
1162+ * mapped into _device_ address space. Is a wrapper for map_dma_buf() of the
1163+ * dma_buf_ops.
1164+ * @attach: [in] attachment whose scatterlist is to be returned
1165+ * @direction: [in] direction of DMA transfer
1166+ *
1167+ * Unlocked variant of dma_buf_map_attachment().
1168+ */
1169+struct sg_table *
1170+dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
1171+ enum dma_data_direction direction)
1172+{
1173+ struct sg_table *sg_table;
1174+
1175+ might_sleep();
1176+
1177+ if (WARN_ON(!attach || !attach->dmabuf))
1178+ return ERR_PTR(-EINVAL);
1179+
1180+ dma_resv_lock(attach->dmabuf->resv, NULL);
1181+ sg_table = dma_buf_map_attachment(attach, direction);
1182+ dma_resv_unlock(attach->dmabuf->resv);
1183+
1184+ return sg_table;
1185+}
1186+EXPORT_SYMBOL_NS_GPL(dma_buf_map_attachment_unlocked, DMA_BUF);
1187+
11031188 /**
11041189 * dma_buf_unmap_attachment - unmaps and decreases usecount of the buffer;might
11051190 * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
@@ -1119,15 +1204,11 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, · 13 unmodified lines
11191204 if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
11201205 return;
11211206
1122− if (dma_buf_attachment_is_dynamic(attach))
1123− dma_resv_assert_held(attach->dmabuf->resv);
1207+ dma_resv_assert_held(attach->dmabuf->resv);
11241208
11251209 if (attach->sgt == sg_table)
11261210 return;
11271211
1128− if (dma_buf_is_dynamic(attach->dmabuf))
1129− dma_resv_assert_held(attach->dmabuf->resv);
1130−
11311212 __unmap_dma_buf(attach, sg_table, direction);
11321213
11331214 if (dma_buf_is_dynamic(attach->dmabuf) &&
@@ -1136,6 +1217,31 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, · 2 unmodified lines
11361217 }
11371218 EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment, DMA_BUF);
11381219
1220+/**
1221+ * dma_buf_unmap_attachment_unlocked - unmaps and decreases usecount of the buffer;might
1222+ * deallocate the scatterlist associated. Is a wrapper for unmap_dma_buf() of
1223+ * dma_buf_ops.
1224+ * @attach: [in] attachment to unmap buffer from
1225+ * @sg_table: [in] scatterlist info of the buffer to unmap
1226+ * @direction: [in] direction of DMA transfer
1227+ *
1228+ * Unlocked variant of dma_buf_unmap_attachment().
1229+ */
1230+void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
1231+ struct sg_table *sg_table,
1232+ enum dma_data_direction direction)
1233+{
1234+ might_sleep();
1235+
1236+ if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
1237+ return;
1238+
1239+ dma_resv_lock(attach->dmabuf->resv, NULL);
1240+ dma_buf_unmap_attachment(attach, sg_table, direction);
1241+ dma_resv_unlock(attach->dmabuf->resv);
1242+}
1243+EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_attachment_unlocked, DMA_BUF);
1244+
11391245 /**
11401246 * dma_buf_move_notify - notify attachments that DMA-buf is moving
11411247 *
@@ -1347,6 +1453,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF); · 205 unmodified lines
13471453 int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
13481454 unsigned long pgoff)
13491455 {
1456+ int ret;
1457+
13501458 if (WARN_ON(!dmabuf || !vma))
13511459 return -EINVAL;
13521460
@@ -1367,7 +1475,11 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, · 14 unmodified lines
13671475 vma_set_file(vma, dmabuf->file);
13681476 vma->vm_pgoff = pgoff;
13691477
1370− return dmabuf->ops->mmap(dmabuf, vma);
1478+ dma_resv_lock(dmabuf->resv, NULL);
1479+ ret = dmabuf->ops->mmap(dmabuf, vma);
1480+ dma_resv_unlock(dmabuf->resv);
1481+
1482+ return ret;
13711483 }
13721484 EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF);
13731485
@@ -1390,41 +1502,67 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, DMA_BUF); · 16 unmodified lines
13901502 int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
13911503 {
13921504 struct iosys_map ptr;
1393− int ret = 0;
1505+ int ret;
13941506
13951507 iosys_map_clear(map);
13961508
13971509 if (WARN_ON(!dmabuf))
13981510 return -EINVAL;
13991511
1512+ dma_resv_assert_held(dmabuf->resv);
1513+
14001514 if (!dmabuf->ops->vmap)
14011515 return -EINVAL;
14021516
1403− mutex_lock(&dmabuf->lock);
14041517 if (dmabuf->vmapping_counter) {
14051518 dmabuf->vmapping_counter++;
14061519 BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
14071520 *map = dmabuf->vmap_ptr;
1408− goto out_unlock;
1521+ return 0;
14091522 }
14101523
14111524 BUG_ON(iosys_map_is_set(&dmabuf->vmap_ptr));
14121525
14131526 ret = dmabuf->ops->vmap(dmabuf, &ptr);
14141527 if (WARN_ON_ONCE(ret))
1415− goto out_unlock;
1528+ return ret;
14161529
14171530 dmabuf->vmap_ptr = ptr;
14181531 dmabuf->vmapping_counter = 1;
14191532
14201533 *map = dmabuf->vmap_ptr;
14211534
1422−out_unlock:
1423− mutex_unlock(&dmabuf->lock);
1424− return ret;
1535+ return 0;
14251536 }
14261537 EXPORT_SYMBOL_NS_GPL(dma_buf_vmap, DMA_BUF);
14271538
1539+/**
1540+ * dma_buf_vmap_unlocked - Create virtual mapping for the buffer object into kernel
1541+ * address space. Same restrictions as for vmap and friends apply.
1542+ * @dmabuf: [in] buffer to vmap
1543+ * @map: [out] returns the vmap pointer
1544+ *
1545+ * Unlocked version of dma_buf_vmap()
1546+ *
1547+ * Returns 0 on success, or a negative errno code otherwise.
1548+ */
1549+int dma_buf_vmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map)
1550+{
1551+ int ret;
1552+
1553+ iosys_map_clear(map);
1554+
1555+ if (WARN_ON(!dmabuf))
1556+ return -EINVAL;
1557+
1558+ dma_resv_lock(dmabuf->resv, NULL);
1559+ ret = dma_buf_vmap(dmabuf, map);
1560+ dma_resv_unlock(dmabuf->resv);
1561+
1562+ return ret;
1563+}
1564+EXPORT_SYMBOL_NS_GPL(dma_buf_vmap_unlocked, DMA_BUF);
1565+
14281566 /**
14291567 * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap.
14301568 * @dmabuf: [in] buffer to vunmap
@@ -1435,20 +1573,36 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) · 4 unmodified lines
14351573 if (WARN_ON(!dmabuf))
14361574 return;
14371575
1576+ dma_resv_assert_held(dmabuf->resv);
1577+
14381578 BUG_ON(iosys_map_is_null(&dmabuf->vmap_ptr));
14391579 BUG_ON(dmabuf->vmapping_counter == 0);
14401580 BUG_ON(!iosys_map_is_equal(&dmabuf->vmap_ptr, map));
14411581
1442− mutex_lock(&dmabuf->lock);
14431582 if (--dmabuf->vmapping_counter == 0) {
14441583 if (dmabuf->ops->vunmap)
14451584 dmabuf->ops->vunmap(dmabuf, map);
14461585 iosys_map_clear(&dmabuf->vmap_ptr);
14471586 }
1448− mutex_unlock(&dmabuf->lock);
14491587 }
14501588 EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap, DMA_BUF);
14511589
1590+/**
1591+ * dma_buf_vunmap_unlocked - Unmap a vmap obtained by dma_buf_vmap.
1592+ * @dmabuf: [in] buffer to vunmap
1593+ * @map: [in] vmap pointer to vunmap
1594+ */
1595+void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map)
1596+{
1597+ if (WARN_ON(!dmabuf))
1598+ return;
1599+
1600+ dma_resv_lock(dmabuf->resv, NULL);
1601+ dma_buf_vunmap(dmabuf, map);
1602+ dma_resv_unlock(dmabuf->resv);
1603+}
1604+EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF);
1605+
14521606 #ifdef CONFIG_DEBUG_FS
14531607 static int dma_buf_debug_show(struct seq_file *s, void *unused)
14541608 {
drivers/gpu/drm/Makefile+77−30
@@ -5,32 +5,71 @@ · 4 unmodified lines
55
66 CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
77
8−drm-y := drm_aperture.o drm_auth.o drm_cache.o \
9− drm_file.o drm_gem.o drm_ioctl.o \
10− drm_drv.o \
11− drm_sysfs.o drm_mm.o \
12− drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o drm_displayid.o \
13− drm_trace_points.o drm_prime.o \
14− drm_vma_manager.o \
15− drm_modeset_lock.o drm_atomic.o drm_bridge.o \
16− drm_framebuffer.o drm_connector.o drm_blend.o \
17− drm_encoder.o drm_mode_object.o drm_property.o \
18− drm_plane.o drm_color_mgmt.o drm_print.o \
19− drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
20− drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
21− drm_client_modeset.o drm_atomic_uapi.o \
22− drm_managed.o drm_vblank_work.o
23−drm-$(CONFIG_DRM_LEGACY) += drm_agpsupport.o drm_bufs.o drm_context.o drm_dma.o \
24− drm_hashtab.o drm_irq.o drm_legacy_misc.o drm_lock.o \
25− drm_memory.o drm_scatter.o drm_vm.o
8+drm-y := \
9+ drm_aperture.o \
10+ drm_atomic.o \
11+ drm_atomic_uapi.o \
12+ drm_auth.o \
13+ drm_blend.o \
14+ drm_bridge.o \
15+ drm_cache.o \
16+ drm_client.o \
17+ drm_client_modeset.o \
18+ drm_color_mgmt.o \
19+ drm_connector.o \
20+ drm_crtc.o \
21+ drm_displayid.o \
22+ drm_drv.o \
23+ drm_dumb_buffers.o \
24+ drm_edid.o \
25+ drm_encoder.o \
26+ drm_file.o \
27+ drm_fourcc.o \
28+ drm_framebuffer.o \
29+ drm_gem.o \
30+ drm_ioctl.o \
31+ drm_lease.o \
32+ drm_managed.o \
33+ drm_mm.o \
34+ drm_mode_config.o \
35+ drm_mode_object.o \
36+ drm_modes.o \
37+ drm_modeset_lock.o \
38+ drm_plane.o \
39+ drm_prime.o \
40+ drm_print.o \
41+ drm_property.o \
42+ drm_syncobj.o \
43+ drm_sysfs.o \
44+ drm_trace_points.o \
45+ drm_vblank.o \
46+ drm_vblank_work.o \
47+ drm_vma_manager.o \
48+ drm_writeback.o
49+drm-$(CONFIG_DRM_LEGACY) += \
50+ drm_agpsupport.o \
51+ drm_bufs.o \
52+ drm_context.o \
53+ drm_dma.o \
54+ drm_hashtab.o \
55+ drm_irq.o \
56+ drm_legacy_misc.o \
57+ drm_lock.o \
58+ drm_memory.o \
59+ drm_scatter.o \
60+ drm_vm.o
2661 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
2762 drm-$(CONFIG_COMPAT) += drm_ioc32.o
2863 drm-$(CONFIG_DRM_PANEL) += drm_panel.o
2964 drm-$(CONFIG_OF) += drm_of.o
3065 drm-$(CONFIG_PCI) += drm_pci.o
31−drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
66+drm-$(CONFIG_DEBUG_FS) += \
67+ drm_debugfs.o \
68+ drm_debugfs_crc.o
3269 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
33−drm-$(CONFIG_DRM_PRIVACY_SCREEN) += drm_privacy_screen.o drm_privacy_screen_x86.o
70+drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \
71+ drm_privacy_screen.o \
72+ drm_privacy_screen_x86.o
3473 obj-$(CONFIG_DRM) += drm.o
3574
3675 obj-$(CONFIG_DRM_NOMODESET) += drm_nomodeset.o
@@ -59,16 +98,24 @@ obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o · 22 unmodified lines
5998 # Modesetting helpers
6099 #
61100
62−drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
63− drm_encoder_slave.o drm_flip_work.o \
64− drm_probe_helper.o \
65− drm_plane_helper.o drm_atomic_helper.o \
66− drm_kms_helper_common.o \
67− drm_simple_kms_helper.o drm_modeset_helper.o \
68− drm_gem_atomic_helper.o \
69− drm_gem_framebuffer_helper.o \
70− drm_atomic_state_helper.o drm_damage_helper.o \
71− drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
101+drm_kms_helper-y := \
102+ drm_atomic_helper.o \
103+ drm_atomic_state_helper.o \
104+ drm_bridge_connector.o \
105+ drm_crtc_helper.o \
106+ drm_damage_helper.o \
107+ drm_encoder_slave.o \
108+ drm_flip_work.o \
109+ drm_format_helper.o \
110+ drm_gem_atomic_helper.o \
111+ drm_gem_framebuffer_helper.o \
112+ drm_kms_helper_common.o \
113+ drm_modeset_helper.o \
114+ drm_plane_helper.o \
115+ drm_probe_helper.o \
116+ drm_rect.o \
117+ drm_self_refresh_helper.o \
118+ drm_simple_kms_helper.o
72119 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
73120 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
74121 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c+0−2
@@ -498,8 +498,6 @@ static int amdgpu_vkms_sw_init(void *handle) · 497 unmodified lines
498498 adev_to_drm(adev)->mode_config.preferred_depth = 24;
499499 adev_to_drm(adev)->mode_config.prefer_shadow = 1;
500500
501− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
502−
503501 r = amdgpu_display_modeset_create_props(adev);
504502 if (r)
505503 return r;
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c+0−2
@@ -2800,8 +2800,6 @@ static int dce_v10_0_sw_init(void *handle) · 2799 unmodified lines
28002800
28012801 adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
28022802
2803− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
2804−
28052803 r = amdgpu_display_modeset_create_props(adev);
28062804 if (r)
28072805 return r;
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c+0−2
@@ -2918,8 +2918,6 @@ static int dce_v11_0_sw_init(void *handle) · 2917 unmodified lines
29182918
29192919 adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
29202920
2921− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
2922−
29232921 r = amdgpu_display_modeset_create_props(adev);
29242922 if (r)
29252923 return r;
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c+0−1
@@ -2675,7 +2675,6 @@ static int dce_v6_0_sw_init(void *handle) · 2674 unmodified lines
26752675 adev_to_drm(adev)->mode_config.preferred_depth = 24;
26762676 adev_to_drm(adev)->mode_config.prefer_shadow = 1;
26772677 adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
2678− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
26792678
26802679 r = amdgpu_display_modeset_create_props(adev);
26812680 if (r)
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c+0−2
@@ -2701,8 +2701,6 @@ static int dce_v8_0_sw_init(void *handle) · 2700 unmodified lines
27012701
27022702 adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
27032703
2704− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
2705−
27062704 r = amdgpu_display_modeset_create_props(adev);
27072705 if (r)
27082706 return r;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+0−2
@@ -3816,8 +3816,6 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) · 3815 unmodified lines
38163816 /* indicates support for immediate flip */
38173817 adev_to_drm(adev)->mode_config.async_page_flip = true;
38183818
3819− adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
3820−
38213819 state = kzalloc(sizeof(*state), GFP_KERNEL);
38223820 if (!state)
38233821 return -ENOMEM;
drivers/gpu/drm/armada/armada_gem.c+4−4
@@ -66,8 +66,8 @@ void armada_gem_free_object(struct drm_gem_object *obj) · 65 unmodified lines
6666 if (dobj->obj.import_attach) {
6767 /* We only ever display imported data */
6868 if (dobj->sgt)
69− dma_buf_unmap_attachment(dobj->obj.import_attach,
70− dobj->sgt, DMA_TO_DEVICE);
69+ dma_buf_unmap_attachment_unlocked(dobj->obj.import_attach,
70+ dobj->sgt, DMA_TO_DEVICE);
7171 drm_prime_gem_destroy(&dobj->obj, NULL);
7272 }
7373
@@ -539,8 +539,8 @@ int armada_gem_map_import(struct armada_gem_object *dobj) · 465 unmodified lines
539539 {
540540 int ret;
541541
542− dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach,
543− DMA_TO_DEVICE);
542+ dobj->sgt = dma_buf_map_attachment_unlocked(dobj->obj.import_attach,
543+ DMA_TO_DEVICE);
544544 if (IS_ERR(dobj->sgt)) {
545545 ret = PTR_ERR(dobj->sgt);
546546 dobj->sgt = NULL;
drivers/gpu/drm/ast/Kconfig+1−3
@@ -2,10 +2,8 @@ · 1 unmodified line
22 config DRM_AST
33 tristate "AST server chips"
44 depends on DRM && PCI && MMU
5+ select DRM_GEM_SHMEM_HELPER
56 select DRM_KMS_HELPER
6− select DRM_VRAM_HELPER
7− select DRM_TTM
8− select DRM_TTM_HELPER
97 help
108 Say yes for experimental AST GPU driver. Do not enable
119 this driver without having a working -modesetting,
drivers/gpu/drm/ast/ast_drv.c+2−2
@@ -33,7 +33,7 @@ · 32 unmodified lines
3333 #include <drm/drm_atomic_helper.h>
3434 #include <drm/drm_crtc_helper.h>
3535 #include <drm/drm_drv.h>
36−#include <drm/drm_gem_vram_helper.h>
36+#include <drm/drm_gem_shmem_helper.h>
3737 #include <drm/drm_module.h>
3838 #include <drm/drm_probe_helper.h>
3939
@@ -63,7 +63,7 @@ static const struct drm_driver ast_driver = { · 23 unmodified lines
6363 .minor = DRIVER_MINOR,
6464 .patchlevel = DRIVER_PATCHLEVEL,
6565
66− DRM_GEM_VRAM_DRIVER
66+ DRM_GEM_SHMEM_DRIVER_OPS
6767 };
6868
6969 /*
drivers/gpu/drm/ast/ast_drv.h+18−16
@@ -87,7 +87,7 @@ enum ast_tx_chip { · 86 unmodified lines
8787 #define AST_DRAM_8Gx16 8
8888
8989 /*
90− * Cursor plane
90+ * Hardware cursor
9191 */
9292
9393 #define AST_MAX_HWC_WIDTH 64
@@ -96,8 +96,6 @@ enum ast_tx_chip { · 2 unmodified lines
9696 #define AST_HWC_SIZE (AST_MAX_HWC_WIDTH * AST_MAX_HWC_HEIGHT * 2)
9797 #define AST_HWC_SIGNATURE_SIZE 32
9898
99−#define AST_DEFAULT_HWC_NUM 2
100−
10199 /* define for signature structure */
102100 #define AST_HWC_SIGNATURE_CHECKSUM 0x00
103101 #define AST_HWC_SIGNATURE_SizeX 0x04
@@ -107,22 +105,21 @@ enum ast_tx_chip { · 3 unmodified lines
107105 #define AST_HWC_SIGNATURE_HOTSPOTX 0x14
108106 #define AST_HWC_SIGNATURE_HOTSPOTY 0x18
109107
110−struct ast_cursor_plane {
111− struct drm_plane base;
108+/*
109+ * Planes
110+ */
112111
113− struct {
114− struct drm_gem_vram_object *gbo;
115− struct iosys_map map;
116− u64 off;
117− } hwc[AST_DEFAULT_HWC_NUM];
112+struct ast_plane {
113+ struct drm_plane base;
118114
119− unsigned int next_hwc_index;
115+ void __iomem *vaddr;
116+ u64 offset;
117+ unsigned long size;
120118 };
121119
122−static inline struct ast_cursor_plane *
123−to_ast_cursor_plane(struct drm_plane *plane)
120+static inline struct ast_plane *to_ast_plane(struct drm_plane *plane)
124121 {
125− return container_of(plane, struct ast_cursor_plane, base);
122+ return container_of(plane, struct ast_plane, base);
126123 }
127124
128125 /*
@@ -175,8 +172,13 @@ struct ast_private { · 46 unmodified lines
175172 uint32_t dram_type;
176173 uint32_t mclk;
177174
178− struct drm_plane primary_plane;
179− struct ast_cursor_plane cursor_plane;
175+ void __iomem *vram;
176+ unsigned long vram_base;
177+ unsigned long vram_size;
178+ unsigned long vram_fb_available;
179+
180+ struct ast_plane primary_plane;
181+ struct ast_plane cursor_plane;
180182 struct drm_crtc crtc;
181183 struct {
182184 struct {
drivers/gpu/drm/ast/ast_main.c+2−3
@@ -32,7 +32,6 @@ · 31 unmodified lines
3232 #include <drm/drm_crtc_helper.h>
3333 #include <drm/drm_drv.h>
3434 #include <drm/drm_gem.h>
35−#include <drm/drm_gem_vram_helper.h>
3635 #include <drm/drm_managed.h>
3736
3837 #include "ast_drv.h"
@@ -461,8 +460,8 @@ struct ast_private *ast_device_create(const struct drm_driver *drv, · 422 unmodified lines
461460
462461 /* map reserved buffer */
463462 ast->dp501_fw_buf = NULL;
464− if (dev->vram_mm->vram_size < pci_resource_len(pdev, 0)) {
465− ast->dp501_fw_buf = pci_iomap_range(pdev, 0, dev->vram_mm->vram_size, 0);
463+ if (ast->vram_size < pci_resource_len(pdev, 0)) {
464+ ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0);
466465 if (!ast->dp501_fw_buf)
467466 drm_info(dev, "failed to map reserved buffer!\n");
468467 }
drivers/gpu/drm/ast/ast_mm.c+7−7
@@ -28,7 +28,6 @@ · 27 unmodified lines
2828
2929 #include <linux/pci.h>
3030
31−#include <drm/drm_gem_vram_helper.h>
3231 #include <drm/drm_managed.h>
3332 #include <drm/drm_print.h>
3433
@@ -80,7 +79,6 @@ int ast_mm_init(struct ast_private *ast) · 45 unmodified lines
8079 struct pci_dev *pdev = to_pci_dev(dev->dev);
8180 resource_size_t base, size;
8281 u32 vram_size;
83− int ret;
8482
8583 base = pci_resource_start(pdev, 0);
8684 size = pci_resource_len(pdev, 0);
@@ -91,11 +89,13 @@ int ast_mm_init(struct ast_private *ast) · 4 unmodified lines
9189
9290 vram_size = ast_get_vram_size(ast);
9391
94− ret = drmm_vram_helper_init(dev, base, vram_size);
95− if (ret) {
96− drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
97− return ret;
98− }
92+ ast->vram = devm_ioremap_wc(dev->dev, base, vram_size);
93+ if (!ast->vram)
94+ return -ENOMEM;
95+
96+ ast->vram_base = base;
97+ ast->vram_size = vram_size;
98+ ast->vram_fb_available = vram_size;
9999
100100 return 0;
101101 }
drivers/gpu/drm/ast/ast_mode.c+265−234
@@ -36,11 +36,13 @@ · 35 unmodified lines
3636 #include <drm/drm_atomic_state_helper.h>
3737 #include <drm/drm_crtc.h>
3838 #include <drm/drm_crtc_helper.h>
39+#include <drm/drm_damage_helper.h>
3940 #include <drm/drm_edid.h>
41+#include <drm/drm_format_helper.h>
4042 #include <drm/drm_fourcc.h>
4143 #include <drm/drm_gem_atomic_helper.h>
4244 #include <drm/drm_gem_framebuffer_helper.h>
43−#include <drm/drm_gem_vram_helper.h>
45+#include <drm/drm_gem_shmem_helper.h>
4446 #include <drm/drm_managed.h>
4547 #include <drm/drm_probe_helper.h>
4648 #include <drm/drm_simple_kms_helper.h>
@@ -48,6 +50,8 @@ · 1 unmodified line
4850 #include "ast_drv.h"
4951 #include "ast_tables.h"
5052
53+#define AST_LUT_SIZE 256
54+
5155 static inline void ast_load_palette_index(struct ast_private *ast,
5256 u8 index, u8 red, u8 green,
5357 u8 blue)
@@ -62,20 +66,46 @@ static inline void ast_load_palette_index(struct ast_private *ast, · 8 unmodified lines
6266 ast_io_read8(ast, AST_IO_SEQ_PORT);
6367 }
6468
65−static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc)
69+static void ast_crtc_set_gamma_linear(struct ast_private *ast,
70+ const struct drm_format_info *format)
6671 {
67− u16 *r, *g, *b;
6872 int i;
6973
70− if (!crtc->enabled)
71− return;
74+ switch (format->format) {
75+ case DRM_FORMAT_C8: /* In this case, gamma table is used as color palette */
76+ case DRM_FORMAT_RGB565:
77+ case DRM_FORMAT_XRGB8888:
78+ for (i = 0; i < AST_LUT_SIZE; i++)
79+ ast_load_palette_index(ast, i, i, i, i);
80+ break;
81+ default:
82+ drm_warn_once(&ast->base, "Unsupported format %p4cc for gamma correction\n",
83+ &format->format);
84+ break;
85+ }
86+}
7287
73− r = crtc->gamma_store;
74− g = r + crtc->gamma_size;
75− b = g + crtc->gamma_size;
88+static void ast_crtc_set_gamma(struct ast_private *ast,
89+ const struct drm_format_info *format,
90+ struct drm_color_lut *lut)
91+{
92+ int i;
7693
77− for (i = 0; i < 256; i++)
78− ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8);
94+ switch (format->format) {
95+ case DRM_FORMAT_C8: /* In this case, gamma table is used as color palette */
96+ case DRM_FORMAT_RGB565:
97+ case DRM_FORMAT_XRGB8888:
98+ for (i = 0; i < AST_LUT_SIZE; i++)
99+ ast_load_palette_index(ast, i,
100+ lut[i].red >> 8,
101+ lut[i].green >> 8,
102+ lut[i].blue >> 8);
103+ break;
104+ default:
105+ drm_warn_once(&ast->base, "Unsupported format %p4cc for gamma correction\n",
106+ &format->format);
107+ break;
108+ }
79109 }
80110
81111 static bool ast_get_vbios_mode_info(const struct drm_format_info *format,
@@ -537,6 +567,29 @@ static void ast_wait_for_vretrace(struct ast_private *ast) · 455 unmodified lines
537567 } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout));
538568 }
539569
570+/*
571+ * Planes
572+ */
573+
574+static int ast_plane_init(struct drm_device *dev, struct ast_plane *ast_plane,
575+ void __iomem *vaddr, u64 offset, unsigned long size,
576+ uint32_t possible_crtcs,
577+ const struct drm_plane_funcs *funcs,
578+ const uint32_t *formats, unsigned int format_count,
579+ const uint64_t *format_modifiers,
580+ enum drm_plane_type type)
581+{
582+ struct drm_plane *plane = &ast_plane->base;
583+
584+ ast_plane->vaddr = vaddr;
585+ ast_plane->offset = offset;
586+ ast_plane->size = size;
587+
588+ return drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
589+ formats, format_count, format_modifiers,
590+ type, NULL);
591+}
592+
540593 /*
541594 * Primary plane
542595 */
@@ -550,52 +603,62 @@ static const uint32_t ast_primary_plane_formats[] = { · 7 unmodified lines
550603 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane,
551604 struct drm_atomic_state *state)
552605 {
553− struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
554− plane);
555− struct drm_crtc_state *crtc_state;
556− struct ast_crtc_state *ast_crtc_state;
606+ struct drm_device *dev = plane->dev;
607+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
608+ struct drm_crtc_state *new_crtc_state = NULL;
609+ struct ast_crtc_state *new_ast_crtc_state;
557610 int ret;
558611
559− if (!new_plane_state->crtc)
560− return 0;
561−
562− crtc_state = drm_atomic_get_new_crtc_state(state,
563− new_plane_state->crtc);
612+ if (new_plane_state->crtc)
613+ new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc);
564614
565− ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
615+ ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
566616 DRM_PLANE_NO_SCALING,
567617 DRM_PLANE_NO_SCALING,
568618 false, true);
569− if (ret)
619+ if (ret) {
570620 return ret;
621+ } else if (!new_plane_state->visible) {
622+ if (drm_WARN_ON(dev, new_plane_state->crtc)) /* cannot legally happen */
623+ return -EINVAL;
624+ else
625+ return 0;
626+ }
571627
572− if (!new_plane_state->visible)
573− return 0;
574−
575− ast_crtc_state = to_ast_crtc_state(crtc_state);
628+ new_ast_crtc_state = to_ast_crtc_state(new_crtc_state);
576629
577− ast_crtc_state->format = new_plane_state->fb->format;
630+ new_ast_crtc_state->format = new_plane_state->fb->format;
578631
579632 return 0;
580633 }
581634
582−static void
583−ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
584− struct drm_atomic_state *state)
635+static void ast_handle_damage(struct ast_plane *ast_plane, struct iosys_map *src,
636+ struct drm_framebuffer *fb,
637+ const struct drm_rect *clip)
638+{
639+ struct iosys_map dst = IOSYS_MAP_INIT_VADDR(ast_plane->vaddr);
640+
641+ iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));
642+ drm_fb_memcpy(&dst, fb->pitches, src, fb, clip);
643+}
644+
645+static void ast_primary_plane_helper_atomic_update(struct drm_plane *plane,
646+ struct drm_atomic_state *state)
585647 {
586− struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
587− plane);
588648 struct drm_device *dev = plane->dev;
589649 struct ast_private *ast = to_ast_private(dev);
590− struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
591− plane);
592− struct drm_gem_vram_object *gbo;
593− s64 gpu_addr;
594− struct drm_framebuffer *fb = new_state->fb;
595− struct drm_framebuffer *old_fb = old_state->fb;
650+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
651+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
652+ struct drm_framebuffer *fb = plane_state->fb;
653+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
654+ struct drm_framebuffer *old_fb = old_plane_state->fb;
655+ struct ast_plane *ast_plane = to_ast_plane(plane);
656+ struct drm_rect damage;
657+ struct drm_atomic_helper_damage_iter iter;
596658
597659 if (!old_fb || (fb->format != old_fb->format)) {
598− struct drm_crtc_state *crtc_state = new_state->crtc->state;
660+ struct drm_crtc *crtc = plane_state->crtc;
661+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
599662 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
600663 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
601664
@@ -603,20 +666,28 @@ ast_primary_plane_helper_atomic_update(struct drm_plane *plane, · 1 unmodified line
603666 ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info);
604667 }
605668
606− gbo = drm_gem_vram_of_gem(fb->obj[0]);
607− gpu_addr = drm_gem_vram_offset(gbo);
608− if (drm_WARN_ON_ONCE(dev, gpu_addr < 0))
609− return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
610−
611− ast_set_offset_reg(ast, fb);
612− ast_set_start_address_crt1(ast, (u32)gpu_addr);
669+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
670+ drm_atomic_for_each_plane_damage(&iter, &damage) {
671+ ast_handle_damage(ast_plane, shadow_plane_state->data, fb, &damage);
672+ }
613673
614− ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
674+ /*
675+ * Some BMCs stop scanning out the video signal after the driver
676+ * reprogrammed the offset or scanout address. This stalls display
677+ * output for several seconds and makes the display unusable.
678+ * Therefore only update the offset if it changes and reprogram the
679+ * address after enabling the plane.
680+ */
681+ if (!old_fb || old_fb->pitches[0] != fb->pitches[0])
682+ ast_set_offset_reg(ast, fb);
683+ if (!old_fb) {
684+ ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
685+ ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00);
686+ }
615687 }
616688
617−static void
618−ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
619− struct drm_atomic_state *state)
689+static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
690+ struct drm_atomic_state *state)
620691 {
621692 struct ast_private *ast = to_ast_private(plane->dev);
622693
@@ -624,7 +695,7 @@ ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, · 1 unmodified line
624695 }
625696
626697 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
627− DRM_GEM_VRAM_PLANE_HELPER_FUNCS,
698+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
628699 .atomic_check = ast_primary_plane_helper_atomic_check,
629700 .atomic_update = ast_primary_plane_helper_atomic_update,
630701 .atomic_disable = ast_primary_plane_helper_atomic_disable,
@@ -634,27 +705,30 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = { · 3 unmodified lines
634705 .update_plane = drm_atomic_helper_update_plane,
635706 .disable_plane = drm_atomic_helper_disable_plane,
636707 .destroy = drm_plane_cleanup,
637− .reset = drm_atomic_helper_plane_reset,
638− .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
639− .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
708+ DRM_GEM_SHADOW_PLANE_FUNCS,
640709 };
641710
642711 static int ast_primary_plane_init(struct ast_private *ast)
643712 {
644713 struct drm_device *dev = &ast->base;
645− struct drm_plane *primary_plane = &ast->primary_plane;
714+ struct ast_plane *ast_primary_plane = &ast->primary_plane;
715+ struct drm_plane *primary_plane = &ast_primary_plane->base;
716+ void __iomem *vaddr = ast->vram;
717+ u64 offset = ast->vram_base;
718+ unsigned long cursor_size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
719+ unsigned long size = ast->vram_fb_available - cursor_size;
646720 int ret;
647721
648− ret = drm_universal_plane_init(dev, primary_plane, 0x01,
649− &ast_primary_plane_funcs,
650− ast_primary_plane_formats,
651− ARRAY_SIZE(ast_primary_plane_formats),
652− NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
722+ ret = ast_plane_init(dev, ast_primary_plane, vaddr, offset, size,
723+ 0x01, &ast_primary_plane_funcs,
724+ ast_primary_plane_formats, ARRAY_SIZE(ast_primary_plane_formats),
725+ NULL, DRM_PLANE_TYPE_PRIMARY);
653726 if (ret) {
654− drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret);
727+ drm_err(dev, "ast_plane_init() failed: %d\n", ret);
655728 return ret;
656729 }
657730 drm_plane_helper_add(primary_plane, &ast_primary_plane_helper_funcs);
731+ drm_plane_enable_fb_damage_clips(primary_plane);
658732
659733 return 0;
660734 }
@@ -774,99 +848,79 @@ static const uint32_t ast_cursor_plane_formats[] = { · 113 unmodified lines
774848 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane,
775849 struct drm_atomic_state *state)
776850 {
777− struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
778− plane);
779− struct drm_framebuffer *fb = new_plane_state->fb;
780− struct drm_crtc_state *crtc_state;
851+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane);
852+ struct drm_framebuffer *new_fb = new_plane_state->fb;
853+ struct drm_crtc_state *new_crtc_state = NULL;
781854 int ret;
782855
783− if (!new_plane_state->crtc)
784− return 0;
785−
786− crtc_state = drm_atomic_get_new_crtc_state(state,
787− new_plane_state->crtc);
856+ if (new_plane_state->crtc)
857+ new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc);
788858
789− ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
859+ ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
790860 DRM_PLANE_NO_SCALING,
791861 DRM_PLANE_NO_SCALING,
792862 true, true);
793− if (ret)
863+ if (ret || !new_plane_state->visible)
794864 return ret;
795865
796− if (!new_plane_state->visible)
797− return 0;
798−
799− if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT)
866+ if (new_fb->width > AST_MAX_HWC_WIDTH || new_fb->height > AST_MAX_HWC_HEIGHT)
800867 return -EINVAL;
801868
802869 return 0;
803870 }
804871
805−static void
806−ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
807− struct drm_atomic_state *state)
872+static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
873+ struct drm_atomic_state *state)
808874 {
809− struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
810− struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state,
811− plane);
812− struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
813− plane);
814− struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
815− struct drm_framebuffer *fb = new_state->fb;
875+ struct ast_plane *ast_plane = to_ast_plane(plane);
876+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
877+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
878+ struct drm_framebuffer *fb = plane_state->fb;
879+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
816880 struct ast_private *ast = to_ast_private(plane->dev);
817− struct iosys_map dst_map =
818− ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].map;
819− u64 dst_off =
820− ast_cursor_plane->hwc[ast_cursor_plane->next_hwc_index].off;
821881 struct iosys_map src_map = shadow_plane_state->data[0];
882+ struct drm_rect damage;
883+ const u8 *src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
884+ u64 dst_off = ast_plane->offset;
885+ u8 __iomem *dst = ast_plane->vaddr; /* TODO: Use mapping abstraction properly */
886+ u8 __iomem *sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
822887 unsigned int offset_x, offset_y;
823888 u16 x, y;
824889 u8 x_offset, y_offset;
825− u8 __iomem *dst;
826− u8 __iomem *sig;
827− const u8 *src;
828−
829− src = src_map.vaddr; /* TODO: Use mapping abstraction properly */
830− dst = dst_map.vaddr_iomem; /* TODO: Use mapping abstraction properly */
831− sig = dst + AST_HWC_SIZE; /* TODO: Use mapping abstraction properly */
832890
833891 /*
834− * Do data transfer to HW cursor BO. If a new cursor image was installed,
835− * point the scanout engine to dst_gbo's offset and page-flip the HWC buffers.
892+ * Do data transfer to hardware buffer and point the scanout
893+ * engine to the offset.
836894 */
837895
838− ast_update_cursor_image(dst, src, fb->width, fb->height);
839−
840− if (new_state->fb != old_state->fb) {
896+ if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &damage)) {
897+ ast_update_cursor_image(dst, src, fb->width, fb->height);
841898 ast_set_cursor_base(ast, dst_off);
842−
843− ++ast_cursor_plane->next_hwc_index;
844− ast_cursor_plane->next_hwc_index %= ARRAY_SIZE(ast_cursor_plane->hwc);
845899 }
846900
847901 /*
848902 * Update location in HWC signature and registers.
849903 */
850904
851− writel(new_state->crtc_x, sig + AST_HWC_SIGNATURE_X);
852− writel(new_state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
905+ writel(plane_state->crtc_x, sig + AST_HWC_SIGNATURE_X);
906+ writel(plane_state->crtc_y, sig + AST_HWC_SIGNATURE_Y);
853907
854908 offset_x = AST_MAX_HWC_WIDTH - fb->width;
855909 offset_y = AST_MAX_HWC_HEIGHT - fb->height;
856910
857− if (new_state->crtc_x < 0) {
858− x_offset = (-new_state->crtc_x) + offset_x;
911+ if (plane_state->crtc_x < 0) {
912+ x_offset = (-plane_state->crtc_x) + offset_x;
859913 x = 0;
860914 } else {
861915 x_offset = offset_x;
862− x = new_state->crtc_x;
916+ x = plane_state->crtc_x;
863917 }
864− if (new_state->crtc_y < 0) {
865− y_offset = (-new_state->crtc_y) + offset_y;
918+ if (plane_state->crtc_y < 0) {
919+ y_offset = (-plane_state->crtc_y) + offset_y;
866920 y = 0;
867921 } else {
868922 y_offset = offset_y;
869− y = new_state->crtc_y;
923+ y = plane_state->crtc_y;
870924 }
871925
872926 ast_set_cursor_location(ast, x, y, x_offset, y_offset);
@@ -875,9 +929,8 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, · 2 unmodified lines
875929 ast_set_cursor_enabled(ast, true);
876930 }
877931
878−static void
879−ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
880− struct drm_atomic_state *state)
932+static void ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane,
933+ struct drm_atomic_state *state)
881934 {
882935 struct ast_private *ast = to_ast_private(plane->dev);
883936
@@ -891,41 +944,22 @@ static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { · 7 unmodified lines
891944 .atomic_disable = ast_cursor_plane_helper_atomic_disable,
892945 };
893946
894−static void ast_cursor_plane_destroy(struct drm_plane *plane)
895−{
896− struct ast_cursor_plane *ast_cursor_plane = to_ast_cursor_plane(plane);
897− size_t i;
898− struct drm_gem_vram_object *gbo;
899− struct iosys_map map;
900−
901− for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
902− gbo = ast_cursor_plane->hwc[i].gbo;
903− map = ast_cursor_plane->hwc[i].map;
904− drm_gem_vram_vunmap(gbo, &map);
905− drm_gem_vram_unpin(gbo);
906− drm_gem_vram_put(gbo);
907− }
908−
909− drm_plane_cleanup(plane);
910−}
911−
912947 static const struct drm_plane_funcs ast_cursor_plane_funcs = {
913948 .update_plane = drm_atomic_helper_update_plane,
914949 .disable_plane = drm_atomic_helper_disable_plane,
915− .destroy = ast_cursor_plane_destroy,
950+ .destroy = drm_plane_cleanup,
916951 DRM_GEM_SHADOW_PLANE_FUNCS,
917952 };
918953
919954 static int ast_cursor_plane_init(struct ast_private *ast)
920955 {
921956 struct drm_device *dev = &ast->base;
922− struct ast_cursor_plane *ast_cursor_plane = &ast->cursor_plane;
957+ struct ast_plane *ast_cursor_plane = &ast->cursor_plane;
923958 struct drm_plane *cursor_plane = &ast_cursor_plane->base;
924− size_t size, i;
925− struct drm_gem_vram_object *gbo;
926− struct iosys_map map;
959+ size_t size;
960+ void __iomem *vaddr;
961+ u64 offset;
927962 int ret;
928− s64 off;
929963
930964 /*
931965 * Allocate backing storage for cursors. The BOs are permanently
@@ -934,60 +968,26 @@ static int ast_cursor_plane_init(struct ast_private *ast) · 2 unmodified lines
934968
935969 size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
936970
937− for (i = 0; i < ARRAY_SIZE(ast_cursor_plane->hwc); ++i) {
938− gbo = drm_gem_vram_create(dev, size, 0);
939− if (IS_ERR(gbo)) {
940− ret = PTR_ERR(gbo);
941− goto err_hwc;
942− }
943− ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
944− DRM_GEM_VRAM_PL_FLAG_TOPDOWN);
945− if (ret)
946− goto err_drm_gem_vram_put;
947− ret = drm_gem_vram_vmap(gbo, &map);
948− if (ret)
949− goto err_drm_gem_vram_unpin;
950− off = drm_gem_vram_offset(gbo);
951− if (off < 0) {
952− ret = off;
953− goto err_drm_gem_vram_vunmap;
954− }
955− ast_cursor_plane->hwc[i].gbo = gbo;
956− ast_cursor_plane->hwc[i].map = map;
957− ast_cursor_plane->hwc[i].off = off;
958− }
971+ if (ast->vram_fb_available < size)
972+ return -ENOMEM;
959973
960− /*
961− * Create the cursor plane. The plane's destroy callback will release
962− * the backing storages' BO memory.
963− */
974+ vaddr = ast->vram + ast->vram_fb_available - size;
975+ offset = ast->vram_base + ast->vram_fb_available - size;
964976
965− ret = drm_universal_plane_init(dev, cursor_plane, 0x01,
966− &ast_cursor_plane_funcs,
967− ast_cursor_plane_formats,
968− ARRAY_SIZE(ast_cursor_plane_formats),
969− NULL, DRM_PLANE_TYPE_CURSOR, NULL);
977+ ret = ast_plane_init(dev, ast_cursor_plane, vaddr, offset, size,
978+ 0x01, &ast_cursor_plane_funcs,
979+ ast_cursor_plane_formats, ARRAY_SIZE(ast_cursor_plane_formats),
980+ NULL, DRM_PLANE_TYPE_CURSOR);
970981 if (ret) {
971− drm_err(dev, "drm_universal_plane failed(): %d\n", ret);
972− goto err_hwc;
982+ drm_err(dev, "ast_plane_init() failed: %d\n", ret);
983+ return ret;
973984 }
974985 drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
986+ drm_plane_enable_fb_damage_clips(cursor_plane);
975987
976− return 0;
988+ ast->vram_fb_available -= size;
977989
978−err_hwc:
979− while (i) {
980− --i;
981− gbo = ast_cursor_plane->hwc[i].gbo;
982− map = ast_cursor_plane->hwc[i].map;
983−err_drm_gem_vram_vunmap:
984− drm_gem_vram_vunmap(gbo, &map);
985−err_drm_gem_vram_unpin:
986− drm_gem_vram_unpin(gbo);
987−err_drm_gem_vram_put:
988− drm_gem_vram_put(gbo);
989− }
990− return ret;
990+ return 0;
991991 }
992992
993993 /*
@@ -1026,9 +1026,11 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) · 32 unmodified lines
10261026
10271027 ast_set_color_reg(ast, format);
10281028 ast_set_vbios_color_reg(ast, format, vbios_mode_info);
1029+ if (crtc->state->gamma_lut)
1030+ ast_crtc_set_gamma(ast, format, crtc->state->gamma_lut->data);
1031+ else
1032+ ast_crtc_set_gamma_linear(ast, format);
10291033 }
1030−
1031− ast_crtc_load_lut(ast, crtc);
10321034 break;
10331035 case DRM_MODE_DPMS_STANDBY:
10341036 case DRM_MODE_DPMS_SUSPEND:
@@ -1123,47 +1125,50 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, · 88 unmodified lines
11231125 struct drm_atomic_state *state)
11241126 {
11251127 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1128+ struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
1129+ struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
11261130 struct drm_device *dev = crtc->dev;
11271131 struct ast_crtc_state *ast_state;
11281132 const struct drm_format_info *format;
11291133 bool succ;
11301134 int ret;
11311135
1132− ret = drm_atomic_helper_check_crtc_state(crtc_state, false);
1136+ if (!crtc_state->enable)
1137+ return 0;
1138+
1139+ ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state);
11331140 if (ret)
11341141 return ret;
11351142
1136− if (!crtc_state->enable)
1137− goto out;
1138−
11391143 ast_state = to_ast_crtc_state(crtc_state);
11401144
11411145 format = ast_state->format;
11421146 if (drm_WARN_ON_ONCE(dev, !format))
11431147 return -EINVAL; /* BUG: We didn't set format in primary check(). */
11441148
1149+ /*
1150+ * The gamma LUT has to be reloaded after changing the primary
1151+ * plane's color format.
1152+ */
1153+ if (old_ast_crtc_state->format != format)
1154+ crtc_state->color_mgmt_changed = true;
1155+
1156+ if (crtc_state->color_mgmt_changed && crtc_state->gamma_lut) {
1157+ if (crtc_state->gamma_lut->length !=
1158+ AST_LUT_SIZE * sizeof(struct drm_color_lut)) {
1159+ drm_err(dev, "Wrong size for gamma_lut %zu\n",
1160+ crtc_state->gamma_lut->length);
1161+ return -EINVAL;
1162+ }
1163+ }
1164+
11451165 succ = ast_get_vbios_mode_info(format, &crtc_state->mode,
11461166 &crtc_state->adjusted_mode,
11471167 &ast_state->vbios_mode_info);
11481168 if (!succ)
11491169 return -EINVAL;
11501170
1151−out:
1152− return drm_atomic_add_affected_planes(state, crtc);
1153−}
1154−
1155−static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
1156−{
1157− struct drm_device *dev = crtc->dev;
1158− struct ast_private *ast = to_ast_private(dev);
1159−
1160− /*
1161− * Concurrent operations could possibly trigger a call to
1162− * drm_connector_helper_funcs.get_modes by trying to read the
1163− * display modes. Protect access to I/O registers by acquiring
1164− * the I/O-register lock. Released in atomic_flush().
1165− */
1166− mutex_lock(&ast->ioregs_lock);
1171+ return 0;
11671172 }
11681173
11691174 static void
@@ -1172,35 +1177,34 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, · 2 unmodified lines
11721177 {
11731178 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
11741179 crtc);
1175− struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1176− crtc);
11771180 struct drm_device *dev = crtc->dev;
11781181 struct ast_private *ast = to_ast_private(dev);
11791182 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
1180− struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
11811183 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
11821184
11831185 /*
11841186 * The gamma LUT has to be reloaded after changing the primary
11851187 * plane's color format.
11861188 */
1187− if (old_ast_crtc_state->format != ast_crtc_state->format)
1188− ast_crtc_load_lut(ast, crtc);
1189+ if (crtc_state->enable && crtc_state->color_mgmt_changed) {
1190+ if (crtc_state->gamma_lut)
1191+ ast_crtc_set_gamma(ast,
1192+ ast_crtc_state->format,
1193+ crtc_state->gamma_lut->data);
1194+ else
1195+ ast_crtc_set_gamma_linear(ast, ast_crtc_state->format);
1196+ }
11891197
11901198 //Set Aspeed Display-Port
11911199 if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
11921200 ast_dp_set_mode(crtc, vbios_mode_info);
1193−
1194− mutex_unlock(&ast->ioregs_lock);
11951201 }
11961202
1197−static void
1198−ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
1199− struct drm_atomic_state *state)
1203+static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
12001204 {
12011205 struct drm_device *dev = crtc->dev;
12021206 struct ast_private *ast = to_ast_private(dev);
1203− struct drm_crtc_state *crtc_state = crtc->state;
1207+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
12041208 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
12051209 struct ast_vbios_mode_info *vbios_mode_info =
12061210 &ast_crtc_state->vbios_mode_info;
@@ -1217,12 +1221,9 @@ ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 10 unmodified lines
12171221 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
12181222 }
12191223
1220−static void
1221−ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
1222− struct drm_atomic_state *state)
1224+static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
12231225 {
1224− struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
1225− crtc);
1226+ struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
12261227 struct drm_device *dev = crtc->dev;
12271228 struct ast_private *ast = to_ast_private(dev);
12281229
@@ -1250,7 +1251,6 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, · 21 unmodified lines
12501251 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
12511252 .mode_valid = ast_crtc_helper_mode_valid,
12521253 .atomic_check = ast_crtc_helper_atomic_check,
1253− .atomic_begin = ast_crtc_helper_atomic_begin,
12541254 .atomic_flush = ast_crtc_helper_atomic_flush,
12551255 .atomic_enable = ast_crtc_helper_atomic_enable,
12561256 .atomic_disable = ast_crtc_helper_atomic_disable,
@@ -1317,13 +1317,15 @@ static int ast_crtc_init(struct drm_device *dev) · 60 unmodified lines
13171317 struct drm_crtc *crtc = &ast->crtc;
13181318 int ret;
13191319
1320− ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
1320+ ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane.base,
13211321 &ast->cursor_plane.base, &ast_crtc_funcs,
13221322 NULL);
13231323 if (ret)
13241324 return ret;
13251325
1326− drm_mode_crtc_set_gamma_size(crtc, 256);
1326+ drm_mode_crtc_set_gamma_size(crtc, AST_LUT_SIZE);
1327+ drm_crtc_enable_color_mgmt(crtc, 0, false, AST_LUT_SIZE);
1328+
13271329 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
13281330
13291331 return 0;
@@ -1718,13 +1720,46 @@ static int ast_astdp_output_init(struct ast_private *ast) · 388 unmodified lines
17181720 * Mode config
17191721 */
17201722
1723+static void ast_mode_config_helper_atomic_commit_tail(struct drm_atomic_state *state)
1724+{
1725+ struct ast_private *ast = to_ast_private(state->dev);
1726+
1727+ /*
1728+ * Concurrent operations could possibly trigger a call to
1729+ * drm_connector_helper_funcs.get_modes by trying to read the
1730+ * display modes. Protect access to I/O registers by acquiring
1731+ * the I/O-register lock. Released in atomic_flush().
1732+ */
1733+ mutex_lock(&ast->ioregs_lock);
1734+ drm_atomic_helper_commit_tail_rpm(state);
1735+ mutex_unlock(&ast->ioregs_lock);
1736+}
1737+
17211738 static const struct drm_mode_config_helper_funcs ast_mode_config_helper_funcs = {
1722− .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
1739+ .atomic_commit_tail = ast_mode_config_helper_atomic_commit_tail,
17231740 };
17241741
1742+static enum drm_mode_status ast_mode_config_mode_valid(struct drm_device *dev,
1743+ const struct drm_display_mode *mode)
1744+{
1745+ static const unsigned long max_bpp = 4; /* DRM_FORMAT_XRGB8888 */
1746+ struct ast_private *ast = to_ast_private(dev);
1747+ unsigned long fbsize, fbpages, max_fbpages;
1748+
1749+ max_fbpages = (ast->vram_fb_available) >> PAGE_SHIFT;
1750+
1751+ fbsize = mode->hdisplay * mode->vdisplay * max_bpp;
1752+ fbpages = DIV_ROUND_UP(fbsize, PAGE_SIZE);
1753+
1754+ if (fbpages > max_fbpages)
1755+ return MODE_MEM;
1756+
1757+ return MODE_OK;
1758+}
1759+
17251760 static const struct drm_mode_config_funcs ast_mode_config_funcs = {
1726− .fb_create = drm_gem_fb_create,
1727− .mode_valid = drm_vram_helper_mode_valid,
1761+ .fb_create = drm_gem_fb_create_with_dirty,
1762+ .mode_valid = ast_mode_config_mode_valid,
17281763 .atomic_check = drm_atomic_helper_check,
17291764 .atomic_commit = drm_atomic_helper_commit,
17301765 };
@@ -1732,7 +1767,6 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = { · 1 unmodified line
17321767 int ast_mode_config_init(struct ast_private *ast)
17331768 {
17341769 struct drm_device *dev = &ast->base;
1735− struct pci_dev *pdev = to_pci_dev(dev->dev);
17361770 int ret;
17371771
17381772 ret = drmm_mode_config_init(dev);
@@ -1743,8 +1777,6 @@ int ast_mode_config_init(struct ast_private *ast) · 4 unmodified lines
17431777 dev->mode_config.min_width = 0;
17441778 dev->mode_config.min_height = 0;
17451779 dev->mode_config.preferred_depth = 24;
1746− dev->mode_config.prefer_shadow = 1;
1747− dev->mode_config.fb_base = pci_resource_start(pdev, 0);
17481780
17491781 if (ast->chip == AST2100 ||
17501782 ast->chip == AST2200 ||
@@ -1761,7 +1793,6 @@ int ast_mode_config_init(struct ast_private *ast) · 10 unmodified lines
17611793
17621794 dev->mode_config.helper_private = &ast_mode_config_helper_funcs;
17631795
1764−
17651796 ret = ast_primary_plane_init(ast);
17661797 if (ret)
17671798 return ret;
drivers/gpu/drm/bridge/adv7511/adv7511.h+2−1
@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) · 401 unmodified lines
402402
403403 void adv7533_dsi_power_on(struct adv7511 *adv);
404404 void adv7533_dsi_power_off(struct adv7511 *adv);
405−void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode);
405+enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
406+ const struct drm_display_mode *mode);
406407 int adv7533_patch_registers(struct adv7511 *adv);
407408 int adv7533_patch_cec_registers(struct adv7511 *adv);
408409 int adv7533_attach_dsi(struct adv7511 *adv);
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c+14−4
@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) · 696 unmodified lines
697697 }
698698
699699 static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
700− struct drm_display_mode *mode)
700+ const struct drm_display_mode *mode)
701701 {
702702 if (mode->clock > 165000)
703703 return MODE_CLOCK_HIGH;
@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511, · 87 unmodified lines
791791 regmap_update_bits(adv7511->regmap, 0x17,
792792 0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
793793
794− if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
795− adv7533_mode_set(adv7511, adj_mode);
796−
797794 drm_mode_copy(&adv7511->curr_mode, adj_mode);
798795
799796 /*
@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge, · 113 unmodified lines
913910 adv7511_mode_set(adv, mode, adj_mode);
914911 }
915912
913+static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
914+ const struct drm_display_info *info,
915+ const struct drm_display_mode *mode)
916+{
917+ struct adv7511 *adv = bridge_to_adv7511(bridge);
918+
919+ if (adv->type == ADV7533 || adv->type == ADV7535)
920+ return adv7533_mode_valid(adv, mode);
921+ else
922+ return adv7511_mode_valid(adv, mode);
923+}
924+
916925 static int adv7511_bridge_attach(struct drm_bridge *bridge,
917926 enum drm_bridge_attach_flags flags)
918927 {
@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = { · 41 unmodified lines
960969 .enable = adv7511_bridge_enable,
961970 .disable = adv7511_bridge_disable,
962971 .mode_set = adv7511_bridge_mode_set,
972+ .mode_valid = adv7511_bridge_mode_valid,
963973 .attach = adv7511_bridge_attach,
964974 .detect = adv7511_bridge_detect,
965975 .get_edid = adv7511_bridge_get_edid,
drivers/gpu/drm/bridge/adv7511/adv7533.c+13−12
@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv) · 99 unmodified lines
100100 regmap_write(adv->regmap_cec, 0x27, 0x0b);
101101 }
102102
103−void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode)
103+enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
104+ const struct drm_display_mode *mode)
104105 {
106+ int lanes;
105107 struct mipi_dsi_device *dsi = adv->dsi;
106− int lanes, ret;
107−
108− if (adv->num_dsi_lanes != 4)
109− return;
110108
111109 if (mode->clock > 80000)
112110 lanes = 4;
113111 else
114112 lanes = 3;
115113
116− if (lanes != dsi->lanes) {
117− mipi_dsi_detach(dsi);
118− dsi->lanes = lanes;
119− ret = mipi_dsi_attach(dsi);
120− if (ret)
121− dev_err(&dsi->dev, "failed to change host lanes\n");
122− }
114+ /*
115+ * TODO: add support for dynamic switching of lanes
116+ * by using the bridge pre_enable() op . Till then filter
117+ * out the modes which shall need different number of lanes
118+ * than what was configured in the device tree.
119+ */
120+ if (lanes != dsi->lanes)
121+ return MODE_BAD;
122+
123+ return MODE_OK;
123124 }
124125
125126 int adv7533_patch_registers(struct adv7511 *adv)
drivers/gpu/drm/bridge/ite-it6505.c+48−10
@@ -421,6 +421,7 @@ struct it6505 { · 420 unmodified lines
421421 struct notifier_block event_nb;
422422 struct extcon_dev *extcon;
423423 struct work_struct extcon_wq;
424+ int extcon_state;
424425 enum drm_connector_status connector_status;
425426 enum link_train_status link_state;
426427 struct work_struct link_works;
@@ -2685,31 +2686,41 @@ static void it6505_extcon_work(struct work_struct *work) · 2258 unmodified lines
26852686 {
26862687 struct it6505 *it6505 = container_of(work, struct it6505, extcon_wq);
26872688 struct device *dev = &it6505->client->dev;
2688− int state = extcon_get_state(it6505->extcon, EXTCON_DISP_DP);
2689− unsigned int pwroffretry = 0;
2689+ int state, ret;
26902690
26912691 if (it6505->enable_drv_hold)
26922692 return;
26932693
26942694 mutex_lock(&it6505->extcon_lock);
26952695
2696+ state = extcon_get_state(it6505->extcon, EXTCON_DISP_DP);
26962697 DRM_DEV_DEBUG_DRIVER(dev, "EXTCON_DISP_DP = 0x%02x", state);
2697− if (state > 0) {
2698+
2699+ if (state == it6505->extcon_state || unlikely(state < 0))
2700+ goto unlock;
2701+ it6505->extcon_state = state;
2702+ if (state) {
26982703 DRM_DEV_DEBUG_DRIVER(dev, "start to power on");
26992704 msleep(100);
2700− it6505_poweron(it6505);
2705+ ret = pm_runtime_get_sync(dev);
2706+
2707+ /*
2708+ * On system resume, extcon_work can be triggered before
2709+ * pm_runtime_force_resume re-enables runtime power management.
2710+ * Handling the error here to make sure the bridge is powered on.
2711+ */
2712+ if (ret)
2713+ it6505_poweron(it6505);
27012714 } else {
27022715 DRM_DEV_DEBUG_DRIVER(dev, "start to power off");
2703− while (it6505_poweroff(it6505) && pwroffretry++ < 5) {
2704− DRM_DEV_DEBUG_DRIVER(dev, "power off fail %d times",
2705− pwroffretry);
2706− }
2716+ pm_runtime_put_sync(dev);
27072717
27082718 drm_helper_hpd_irq_event(it6505->bridge.dev);
27092719 memset(it6505->dpcd, 0, sizeof(it6505->dpcd));
27102720 DRM_DEV_DEBUG_DRIVER(dev, "power off it6505 success!");
27112721 }
27122722
2723+unlock:
27132724 mutex_unlock(&it6505->extcon_lock);
27142725 }
27152726
@@ -2980,6 +2991,28 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge, · 264 unmodified lines
29802991 }
29812992 }
29822993
2994+static void it6505_bridge_atomic_pre_enable(struct drm_bridge *bridge,
2995+ struct drm_bridge_state *old_state)
2996+{
2997+ struct it6505 *it6505 = bridge_to_it6505(bridge);
2998+ struct device *dev = &it6505->client->dev;
2999+
3000+ DRM_DEV_DEBUG_DRIVER(dev, "start");
3001+
3002+ pm_runtime_get_sync(dev);
3003+}
3004+
3005+static void it6505_bridge_atomic_post_disable(struct drm_bridge *bridge,
3006+ struct drm_bridge_state *old_state)
3007+{
3008+ struct it6505 *it6505 = bridge_to_it6505(bridge);
3009+ struct device *dev = &it6505->client->dev;
3010+
3011+ DRM_DEV_DEBUG_DRIVER(dev, "start");
3012+
3013+ pm_runtime_put_sync(dev);
3014+}
3015+
29833016 static enum drm_connector_status
29843017 it6505_bridge_detect(struct drm_bridge *bridge)
29853018 {
@@ -3014,6 +3047,8 @@ static const struct drm_bridge_funcs it6505_bridge_funcs = { · 28 unmodified lines
30143047 .mode_valid = it6505_bridge_mode_valid,
30153048 .atomic_enable = it6505_bridge_atomic_enable,
30163049 .atomic_disable = it6505_bridge_atomic_disable,
3050+ .atomic_pre_enable = it6505_bridge_atomic_pre_enable,
3051+ .atomic_post_disable = it6505_bridge_atomic_post_disable,
30173052 .detect = it6505_bridge_detect,
30183053 .get_edid = it6505_bridge_get_edid,
30193054 };
@@ -3032,8 +3067,10 @@ static __maybe_unused int it6505_bridge_suspend(struct device *dev) · 12 unmodified lines
30323067 return it6505_poweroff(it6505);
30333068 }
30343069
3035−static SIMPLE_DEV_PM_OPS(it6505_bridge_pm_ops, it6505_bridge_suspend,
3036− it6505_bridge_resume);
3070+static const struct dev_pm_ops it6505_bridge_pm_ops = {
3071+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
3072+ SET_RUNTIME_PM_OPS(it6505_bridge_suspend, it6505_bridge_resume, NULL)
3073+};
30373074
30383075 static int it6505_init_pdata(struct it6505 *it6505)
30393076 {
@@ -3315,6 +3352,7 @@ static int it6505_i2c_probe(struct i2c_client *client, · 275 unmodified lines
33153352
33163353 DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev));
33173354 debugfs_init(it6505);
3355+ pm_runtime_enable(dev);
33183356
33193357 it6505->bridge.funcs = &it6505_bridge_funcs;
33203358 it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
drivers/gpu/drm/bridge/parade-ps8640.c+8−1
@@ -286,7 +286,6 @@ static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux, · 285 unmodified lines
286286 }
287287
288288 switch (data & SWAUX_STATUS_MASK) {
289− /* Ignore the DEFER cases as they are already handled in hardware */
290289 case SWAUX_STATUS_NACK:
291290 case SWAUX_STATUS_I2C_NACK:
292291 /*
@@ -303,6 +302,14 @@ static ssize_t ps8640_aux_transfer_msg(struct drm_dp_aux *aux, · 10 unmodified lines
303302 case SWAUX_STATUS_ACKM:
304303 len = data & SWAUX_M_MASK;
305304 break;
305+ case SWAUX_STATUS_DEFER:
306+ case SWAUX_STATUS_I2C_DEFER:
307+ if (is_native_aux)
308+ msg->reply |= DP_AUX_NATIVE_REPLY_DEFER;
309+ else
310+ msg->reply |= DP_AUX_I2C_REPLY_DEFER;
311+ len = data & SWAUX_M_MASK;
312+ break;
306313 case SWAUX_STATUS_INVALID:
307314 return -EOPNOTSUPP;
308315 case SWAUX_STATUS_TIMEOUT:
drivers/gpu/drm/bridge/tc358775.c+1−1
@@ -408,7 +408,7 @@ static void tc_bridge_enable(struct drm_bridge *bridge) · 407 unmodified lines
408408 (val >> 8) & 0xFF, val & 0xFF);
409409
410410 d2l_write(tc->i2c, SYSRST, SYS_RST_REG | SYS_RST_DSIRX | SYS_RST_BM |
411− SYS_RST_LCD | SYS_RST_I2CM | SYS_RST_I2CS);
411+ SYS_RST_LCD | SYS_RST_I2CM);
412412 usleep_range(30000, 40000);
413413
414414 d2l_write(tc->i2c, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
drivers/gpu/drm/display/Makefile+8−6
@@ -3,13 +3,15 @@ · 2 unmodified lines
33 obj-$(CONFIG_DRM_DP_AUX_BUS) += drm_dp_aux_bus.o
44
55 drm_display_helper-y := drm_display_helper_mod.o
6−drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += drm_dp_dual_mode_helper.o \
7− drm_dp_helper.o \
8− drm_dp_mst_topology.o \
9− drm_dsc_helper.o
6+drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \
7+ drm_dp_dual_mode_helper.o \
8+ drm_dp_helper.o \
9+ drm_dp_mst_topology.o \
10+ drm_dsc_helper.o
1011 drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o
11−drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += drm_hdmi_helper.o \
12− drm_scdc_helper.o
12+drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \
13+ drm_hdmi_helper.o \
14+ drm_scdc_helper.o
1315 drm_display_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
1416 drm_display_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
1517
drivers/gpu/drm/drm_atomic_helper.c+18−42
@@ -924,59 +924,35 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, · 923 unmodified lines
924924 EXPORT_SYMBOL(drm_atomic_helper_check_plane_state);
925925
926926 /**
927− * drm_atomic_helper_check_crtc_state() - Check CRTC state for validity
927+ * drm_atomic_helper_check_crtc_primary_plane() - Check CRTC state for primary plane
928928 * @crtc_state: CRTC state to check
929− * @can_disable_primary_planes: can the CRTC be enabled without a primary plane?
930929 *
931− * Checks that a desired CRTC update is valid. Drivers that provide
932− * their own CRTC handling rather than helper-provided implementations may
933− * still wish to call this function to avoid duplication of error checking
934− * code.
935− *
936− * Note that @can_disable_primary_planes only tests if the CRTC can be
937− * enabled without a primary plane. To test if a primary plane can be updated
938− * without a CRTC, use drm_atomic_helper_check_plane_state() in the plane's
939− * atomic check.
930+ * Checks that a CRTC has at least one primary plane attached to it, which is
931+ * a requirement on some hardware. Note that this only involves the CRTC side
932+ * of the test. To test if the primary plane is visible or if it can be updated
933+ * without the CRTC being enabled, use drm_atomic_helper_check_plane_state() in
934+ * the plane's atomic check.
940935 *
941936 * RETURNS:
942− * Zero if update appears valid, error code on failure
937+ * 0 if a primary plane is attached to the CRTC, or an error code otherwise
943938 */
944−int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
945− bool can_disable_primary_planes)
939+int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state)
946940 {
947− struct drm_device *dev = crtc_state->crtc->dev;
948− struct drm_atomic_state *state = crtc_state->state;
949−
950− if (!crtc_state->enable)
951− return 0;
941+ struct drm_crtc *crtc = crtc_state->crtc;
942+ struct drm_device *dev = crtc->dev;
943+ struct drm_plane *plane;
952944
953945 /* needs at least one primary plane to be enabled */
954− if (!can_disable_primary_planes) {
955− bool has_primary_plane = false;
956− struct drm_plane *plane;
957−
958− drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
959− struct drm_plane_state *plane_state;
960−
961− if (plane->type != DRM_PLANE_TYPE_PRIMARY)
962− continue;
963− plane_state = drm_atomic_get_plane_state(state, plane);
964− if (IS_ERR(plane_state))
965− return PTR_ERR(plane_state);
966− if (plane_state->fb && plane_state->crtc) {
967− has_primary_plane = true;
968− break;
969− }
970− }
971− if (!has_primary_plane) {
972− drm_dbg_kms(dev, "Cannot enable CRTC without a primary plane.\n");
973− return -EINVAL;
974− }
946+ drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
947+ if (plane->type == DRM_PLANE_TYPE_PRIMARY)
948+ return 0;
975949 }
976950
977− return 0;
951+ drm_dbg_atomic(dev, "[CRTC:%d:%s] primary plane missing\n", crtc->base.id, crtc->name);
952+
953+ return -EINVAL;
978954 }
979−EXPORT_SYMBOL(drm_atomic_helper_check_crtc_state);
955+EXPORT_SYMBOL(drm_atomic_helper_check_crtc_primary_plane);
980956
981957 /**
982958 * drm_atomic_helper_check_planes - validate state object for planes changes
drivers/gpu/drm/drm_atomic_state_helper.c+3−3
@@ -464,12 +464,12 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector) · 463 unmodified lines
464464 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
465465
466466 /**
467− * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
467+ * drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
468468 * @connector: DRM connector
469469 *
470470 * Resets the TV-related properties attached to a connector.
471471 */
472−void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
472+void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)
473473 {
474474 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
475475 struct drm_connector_state *state = connector->state;
@@ -479,7 +479,7 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) · 3 unmodified lines
479479 state->tv.margins.top = cmdline->tv_margins.top;
480480 state->tv.margins.bottom = cmdline->tv_margins.bottom;
481481 }
482−EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
482+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
483483
484484 /**
485485 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
drivers/gpu/drm/drm_atomic_uapi.c+4−0
@@ -687,6 +687,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, · 686 unmodified lines
687687 */
688688 return -EINVAL;
689689 } else if (property == config->tv_select_subconnector_property) {
690+ state->tv.select_subconnector = val;
691+ } else if (property == config->tv_subconnector_property) {
690692 state->tv.subconnector = val;
691693 } else if (property == config->tv_left_margin_property) {
692694 state->tv.margins.left = val;
@@ -795,6 +797,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, · 102 unmodified lines
795797 else
796798 *val = connector->dpms;
797799 } else if (property == config->tv_select_subconnector_property) {
800+ *val = state->tv.select_subconnector;
801+ } else if (property == config->tv_subconnector_property) {
798802 *val = state->tv.subconnector;
799803 } else if (property == config->tv_left_margin_property) {
800804 *val = state->tv.margins.left;
drivers/gpu/drm/drm_client.c+2−2
@@ -323,7 +323,7 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer, · 322 unmodified lines
323323 * fd_install step out of the driver backend hooks, to make that
324324 * final step optional for internal users.
325325 */
326− ret = drm_gem_vmap(buffer->gem, map);
326+ ret = drm_gem_vmap_unlocked(buffer->gem, map);
327327 if (ret)
328328 return ret;
329329
@@ -345,7 +345,7 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer) · 15 unmodified lines
345345 {
346346 struct iosys_map *map = &buffer->map;
347347
348− drm_gem_vunmap(buffer->gem, map);
348+ drm_gem_vunmap_unlocked(buffer->gem, map);
349349 }
350350 EXPORT_SYMBOL(drm_client_buffer_vunmap);
351351
drivers/gpu/drm/drm_crtc_helper.c+26−0
@@ -434,6 +434,32 @@ done: · 433 unmodified lines
434434 }
435435 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
436436
437+/**
438+ * drm_crtc_helper_atomic_check() - Helper to check CRTC atomic-state
439+ * @crtc: CRTC to check
440+ * @state: atomic state object
441+ *
442+ * Provides a default CRTC-state check handler for CRTCs that only have
443+ * one primary plane attached to it.
444+ *
445+ * This is often the case for the CRTC of simple framebuffers. See also
446+ * drm_plane_helper_atomic_check() for the respective plane-state check
447+ * helper function.
448+ *
449+ * RETURNS:
450+ * Zero on success, or an errno code otherwise.
451+ */
452+int drm_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
453+{
454+ struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
455+
456+ if (!new_crtc_state->enable)
457+ return 0;
458+
459+ return drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
460+}
461+EXPORT_SYMBOL(drm_crtc_helper_atomic_check);
462+
437463 static void
438464 drm_crtc_helper_disable(struct drm_crtc *crtc)
439465 {
drivers/gpu/drm/drm_edid.c+222−124
@@ -1572,15 +1572,6 @@ struct drm_edid { · 1571 unmodified lines
15721572 const struct edid *edid;
15731573 };
15741574
1575−static bool version_greater(const struct drm_edid *drm_edid,
1576− u8 version, u8 revision)
1577−{
1578− const struct edid *edid = drm_edid->edid;
1579−
1580− return edid->version > version ||
1581− (edid->version == version && edid->revision > revision);
1582−}
1583−
15841575 static int edid_hfeeodb_extension_block_count(const struct edid *edid);
15851576
15861577 static int edid_hfeeodb_block_count(const struct edid *edid)
@@ -2984,7 +2975,7 @@ is_rb(const struct detailed_timing *descriptor, void *data) · 1397 unmodified lines
29842975 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.formula.cvt.flags) != 15);
29852976
29862977 if (descriptor->data.other_data.data.range.flags == DRM_EDID_CVT_SUPPORT_FLAG &&
2987− descriptor->data.other_data.data.range.formula.cvt.flags & 0x10)
2978+ descriptor->data.other_data.data.range.formula.cvt.flags & DRM_EDID_CVT_FLAGS_REDUCED_BLANKING)
29882979 *res = true;
29892980 }
29902981
@@ -3012,7 +3003,7 @@ find_gtf2(const struct detailed_timing *descriptor, void *data) · 21 unmodified lines
30123003
30133004 BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.flags) != 10);
30143005
3015− if (descriptor->data.other_data.data.range.flags == 0x02)
3006+ if (descriptor->data.other_data.data.range.flags == DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG)
30163007 *res = descriptor;
30173008 }
30183009
@@ -3077,20 +3068,53 @@ drm_gtf2_2j(const struct drm_edid *drm_edid) · 58 unmodified lines
30773068 return descriptor ? descriptor->data.other_data.data.range.formula.gtf2.j : 0;
30783069 }
30793070
3071+static void
3072+get_timing_level(const struct detailed_timing *descriptor, void *data)
3073+{
3074+ int *res = data;
3075+
3076+ if (!is_display_descriptor(descriptor, EDID_DETAIL_MONITOR_RANGE))
3077+ return;
3078+
3079+ BUILD_BUG_ON(offsetof(typeof(*descriptor), data.other_data.data.range.flags) != 10);
3080+
3081+ switch (descriptor->data.other_data.data.range.flags) {
3082+ case DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG:
3083+ *res = LEVEL_GTF;
3084+ break;
3085+ case DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG:
3086+ *res = LEVEL_GTF2;
3087+ break;
3088+ case DRM_EDID_CVT_SUPPORT_FLAG:
3089+ *res = LEVEL_CVT;
3090+ break;
3091+ default:
3092+ break;
3093+ }
3094+}
3095+
30803096 /* Get standard timing level (CVT/GTF/DMT). */
30813097 static int standard_timing_level(const struct drm_edid *drm_edid)
30823098 {
30833099 const struct edid *edid = drm_edid->edid;
30843100
3085− if (edid->revision >= 2) {
3086− if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
3087− return LEVEL_CVT;
3088− if (drm_gtf2_hbreak(drm_edid))
3089− return LEVEL_GTF2;
3090− if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
3091− return LEVEL_GTF;
3101+ if (edid->revision >= 4) {
3102+ /*
3103+ * If the range descriptor doesn't
3104+ * indicate otherwise default to CVT
3105+ */
3106+ int ret = LEVEL_CVT;
3107+
3108+ drm_for_each_detailed_block(drm_edid, get_timing_level, &ret);
3109+
3110+ return ret;
3111+ } else if (edid->revision >= 3 && drm_gtf2_hbreak(drm_edid)) {
3112+ return LEVEL_GTF2;
3113+ } else if (edid->revision >= 2) {
3114+ return LEVEL_GTF;
3115+ } else {
3116+ return LEVEL_DMT;
30923117 }
3093− return LEVEL_DMT;
30943118 }
30953119
30963120 /*
@@ -3113,6 +3137,35 @@ static int drm_mode_hsync(const struct drm_display_mode *mode) · 16 unmodified lines
31133137 return DIV_ROUND_CLOSEST(mode->clock, mode->htotal);
31143138 }
31153139
3140+static struct drm_display_mode *
3141+drm_gtf2_mode(struct drm_device *dev,
3142+ const struct drm_edid *drm_edid,
3143+ int hsize, int vsize, int vrefresh_rate)
3144+{
3145+ struct drm_display_mode *mode;
3146+
3147+ /*
3148+ * This is potentially wrong if there's ever a monitor with
3149+ * more than one ranges section, each claiming a different
3150+ * secondary GTF curve. Please don't do that.
3151+ */
3152+ mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
3153+ if (!mode)
3154+ return NULL;
3155+
3156+ if (drm_mode_hsync(mode) > drm_gtf2_hbreak(drm_edid)) {
3157+ drm_mode_destroy(dev, mode);
3158+ mode = drm_gtf_mode_complex(dev, hsize, vsize,
3159+ vrefresh_rate, 0, 0,
3160+ drm_gtf2_m(drm_edid),
3161+ drm_gtf2_2c(drm_edid),
3162+ drm_gtf2_k(drm_edid),
3163+ drm_gtf2_2j(drm_edid));
3164+ }
3165+
3166+ return mode;
3167+}
3168+
31163169 /*
31173170 * Take the standard timing params (in this case width, aspect, and refresh)
31183171 * and convert them into a real mode using CVT/GTF/DMT.
@@ -3201,23 +3254,7 @@ static struct drm_display_mode *drm_mode_std(struct drm_connector *connector, · 82 unmodified lines
32013254 mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
32023255 break;
32033256 case LEVEL_GTF2:
3204− /*
3205− * This is potentially wrong if there's ever a monitor with
3206− * more than one ranges section, each claiming a different
3207− * secondary GTF curve. Please don't do that.
3208− */
3209− mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
3210− if (!mode)
3211− return NULL;
3212− if (drm_mode_hsync(mode) > drm_gtf2_hbreak(drm_edid)) {
3213− drm_mode_destroy(dev, mode);
3214− mode = drm_gtf_mode_complex(dev, hsize, vsize,
3215− vrefresh_rate, 0, 0,
3216− drm_gtf2_m(drm_edid),
3217− drm_gtf2_2c(drm_edid),
3218− drm_gtf2_k(drm_edid),
3219− drm_gtf2_2j(drm_edid));
3220− }
3257+ mode = drm_gtf2_mode(dev, drm_edid, hsize, vsize, vrefresh_rate);
32213258 break;
32223259 case LEVEL_CVT:
32233260 mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
@@ -3415,7 +3452,7 @@ range_pixel_clock(const struct edid *edid, const u8 *t) · 191 unmodified lines
34153452 return 0;
34163453
34173454 /* 1.4 with CVT support gives us real precision, yay */
3418− if (edid->revision >= 4 && t[10] == 0x04)
3455+ if (edid->revision >= 4 && t[10] == DRM_EDID_CVT_SUPPORT_FLAG)
34193456 return (t[9] * 10000) - ((t[12] >> 2) * 250);
34203457
34213458 /* 1.3 is pathetic, so fuzz up a bit */
@@ -3441,7 +3478,7 @@ static bool mode_in_range(const struct drm_display_mode *mode, · 19 unmodified lines
34413478 return false;
34423479
34433480 /* 1.4 max horizontal check */
3444− if (edid->revision >= 4 && t[10] == 0x04)
3481+ if (edid->revision >= 4 && t[10] == DRM_EDID_CVT_SUPPORT_FLAG)
34453482 if (t[13] && mode->hdisplay > 8 * (t[13] + (256 * (t[12]&0x3))))
34463483 return false;
34473484
@@ -3533,6 +3570,35 @@ static int drm_gtf_modes_for_range(struct drm_connector *connector, · 85 unmodified lines
35333570 return modes;
35343571 }
35353572
3573+static int drm_gtf2_modes_for_range(struct drm_connector *connector,
3574+ const struct drm_edid *drm_edid,
3575+ const struct detailed_timing *timing)
3576+{
3577+ int i, modes = 0;
3578+ struct drm_display_mode *newmode;
3579+ struct drm_device *dev = connector->dev;
3580+
3581+ for (i = 0; i < ARRAY_SIZE(extra_modes); i++) {
3582+ const struct minimode *m = &extra_modes[i];
3583+
3584+ newmode = drm_gtf2_mode(dev, drm_edid, m->w, m->h, m->r);
3585+ if (!newmode)
3586+ return modes;
3587+
3588+ drm_mode_fixup_1366x768(newmode);
3589+ if (!mode_in_range(newmode, drm_edid, timing) ||
3590+ !valid_inferred_mode(connector, newmode)) {
3591+ drm_mode_destroy(dev, newmode);
3592+ continue;
3593+ }
3594+
3595+ drm_mode_probed_add(connector, newmode);
3596+ modes++;
3597+ }
3598+
3599+ return modes;
3600+}
3601+
35363602 static int drm_cvt_modes_for_range(struct drm_connector *connector,
35373603 const struct drm_edid *drm_edid,
35383604 const struct detailed_timing *timing)
@@ -3577,25 +3643,29 @@ do_inferred_modes(const struct detailed_timing *timing, void *c) · 38 unmodified lines
35773643 closure->drm_edid,
35783644 timing);
35793645
3580− if (!version_greater(closure->drm_edid, 1, 1))
3646+ if (closure->drm_edid->edid->revision < 2)
35813647 return; /* GTF not defined yet */
35823648
35833649 switch (range->flags) {
3584− case 0x02: /* secondary gtf, XXX could do more */
3585− case 0x00: /* default gtf */
3650+ case DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG:
3651+ closure->modes += drm_gtf2_modes_for_range(closure->connector,
3652+ closure->drm_edid,
3653+ timing);
3654+ break;
3655+ case DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG:
35863656 closure->modes += drm_gtf_modes_for_range(closure->connector,
35873657 closure->drm_edid,
35883658 timing);
35893659 break;
3590− case 0x04: /* cvt, only in 1.4+ */
3591− if (!version_greater(closure->drm_edid, 1, 3))
3660+ case DRM_EDID_CVT_SUPPORT_FLAG:
3661+ if (closure->drm_edid->edid->revision < 4)
35923662 break;
35933663
35943664 closure->modes += drm_cvt_modes_for_range(closure->connector,
35953665 closure->drm_edid,
35963666 timing);
35973667 break;
3598− case 0x01: /* just the ranges, no formula */
3668+ case DRM_EDID_RANGE_LIMITS_ONLY_FLAG:
35993669 default:
36003670 break;
36013671 }
@@ -3609,7 +3679,7 @@ static int add_inferred_modes(struct drm_connector *connector, · 7 unmodified lines
36093679 .drm_edid = drm_edid,
36103680 };
36113681
3612− if (version_greater(drm_edid, 1, 0))
3682+ if (drm_edid->edid->revision >= 1)
36133683 drm_for_each_detailed_block(drm_edid, do_inferred_modes, &closure);
36143684
36153685 return closure.modes;
@@ -3686,7 +3756,7 @@ static int add_established_modes(struct drm_connector *connector, · 70 unmodified lines
36863756 }
36873757 }
36883758
3689− if (version_greater(drm_edid, 1, 0))
3759+ if (edid->revision >= 1)
36903760 drm_for_each_detailed_block(drm_edid, do_established_modes,
36913761 &closure);
36923762
@@ -3741,7 +3811,7 @@ static int add_standard_modes(struct drm_connector *connector, · 48 unmodified lines
37413811 }
37423812 }
37433813
3744− if (version_greater(drm_edid, 1, 0))
3814+ if (drm_edid->edid->revision >= 1)
37453815 drm_for_each_detailed_block(drm_edid, do_standard_modes,
37463816 &closure);
37473817
@@ -3821,7 +3891,7 @@ add_cvt_modes(struct drm_connector *connector, const struct drm_edid *drm_edid) · 73 unmodified lines
38213891 .drm_edid = drm_edid,
38223892 };
38233893
3824− if (version_greater(drm_edid, 1, 2))
3894+ if (drm_edid->edid->revision >= 3)
38253895 drm_for_each_detailed_block(drm_edid, do_cvt_mode, &closure);
38263896
38273897 /* XXX should also look for CVT codes in VTB blocks */
@@ -3873,13 +3943,14 @@ static int add_detailed_modes(struct drm_connector *connector, · 45 unmodified lines
38733943 struct detailed_mode_closure closure = {
38743944 .connector = connector,
38753945 .drm_edid = drm_edid,
3876− .preferred = true,
38773946 .quirks = quirks,
38783947 };
38793948
3880− if (closure.preferred && !version_greater(drm_edid, 1, 3))
3949+ if (drm_edid->edid->revision >= 4)
3950+ closure.preferred = true; /* first detailed timing is always preferred */
3951+ else
38813952 closure.preferred =
3882− (drm_edid->edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING);
3953+ drm_edid->edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING;
38833954
38843955 drm_for_each_detailed_block(drm_edid, do_detailed_mode, &closure);
38853956
@@ -5752,12 +5823,87 @@ static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector, · 1866 unmodified lines
57525823 hdmi->y420_dc_modes = dc_mask;
57535824 }
57545825
5826+static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
5827+ const u8 *hf_scds)
5828+{
5829+ hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
5830+
5831+ if (!hdmi_dsc->v_1p2)
5832+ return;
5833+
5834+ hdmi_dsc->native_420 = hf_scds[11] & DRM_EDID_DSC_NATIVE_420;
5835+ hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
5836+
5837+ if (hf_scds[11] & DRM_EDID_DSC_16BPC)
5838+ hdmi_dsc->bpc_supported = 16;
5839+ else if (hf_scds[11] & DRM_EDID_DSC_12BPC)
5840+ hdmi_dsc->bpc_supported = 12;
5841+ else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
5842+ hdmi_dsc->bpc_supported = 10;
5843+ else
5844+ /* Supports min 8 BPC if DSC 1.2 is supported*/
5845+ hdmi_dsc->bpc_supported = 8;
5846+
5847+ if (cea_db_payload_len(hf_scds) >= 12 && hf_scds[12]) {
5848+ u8 dsc_max_slices;
5849+ u8 dsc_max_frl_rate;
5850+
5851+ dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
5852+ drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
5853+ &hdmi_dsc->max_frl_rate_per_lane);
5854+
5855+ dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
5856+
5857+ switch (dsc_max_slices) {
5858+ case 1:
5859+ hdmi_dsc->max_slices = 1;
5860+ hdmi_dsc->clk_per_slice = 340;
5861+ break;
5862+ case 2:
5863+ hdmi_dsc->max_slices = 2;
5864+ hdmi_dsc->clk_per_slice = 340;
5865+ break;
5866+ case 3:
5867+ hdmi_dsc->max_slices = 4;
5868+ hdmi_dsc->clk_per_slice = 340;
5869+ break;
5870+ case 4:
5871+ hdmi_dsc->max_slices = 8;
5872+ hdmi_dsc->clk_per_slice = 340;
5873+ break;
5874+ case 5:
5875+ hdmi_dsc->max_slices = 8;
5876+ hdmi_dsc->clk_per_slice = 400;
5877+ break;
5878+ case 6:
5879+ hdmi_dsc->max_slices = 12;
5880+ hdmi_dsc->clk_per_slice = 400;
5881+ break;
5882+ case 7:
5883+ hdmi_dsc->max_slices = 16;
5884+ hdmi_dsc->clk_per_slice = 400;
5885+ break;
5886+ case 0:
5887+ default:
5888+ hdmi_dsc->max_slices = 0;
5889+ hdmi_dsc->clk_per_slice = 0;
5890+ }
5891+ }
5892+
5893+ if (cea_db_payload_len(hf_scds) >= 13 && hf_scds[13])
5894+ hdmi_dsc->total_chunk_kbytes = hf_scds[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
5895+}
5896+
57555897 /* Sink Capability Data Structure */
57565898 static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
57575899 const u8 *hf_scds)
57585900 {
57595901 struct drm_display_info *display = &connector->display_info;
57605902 struct drm_hdmi_info *hdmi = &display->hdmi;
5903+ struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
5904+ int max_tmds_clock = 0;
5905+ u8 max_frl_rate = 0;
5906+ bool dsc_support = false;
57615907
57625908 display->has_hdmi_infoframe = true;
57635909
@@ -5777,14 +5923,13 @@ static void drm_parse_hdmi_forum_scds(struct drm_connector *connector, · 13 unmodified lines
57775923 */
57785924
57795925 if (hf_scds[5]) {
5780− /* max clock is 5000 KHz times block value */
5781− u32 max_tmds_clock = hf_scds[5] * 5000;
57825926 struct drm_scdc *scdc = &hdmi->scdc;
57835927
5928+ /* max clock is 5000 KHz times block value */
5929+ max_tmds_clock = hf_scds[5] * 5000;
5930+
57845931 if (max_tmds_clock > 340000) {
57855932 display->max_tmds_clock = max_tmds_clock;
5786− DRM_DEBUG_KMS("HF-VSDB: max TMDS clock %d kHz\n",
5787− display->max_tmds_clock);
57885933 }
57895934
57905935 if (scdc->supported) {
@@ -5797,74 +5942,21 @@ static void drm_parse_hdmi_forum_scds(struct drm_connector *connector, · 6 unmodified lines
57975942 }
57985943
57995944 if (hf_scds[7]) {
5800− u8 max_frl_rate;
5801− u8 dsc_max_frl_rate;
5802− u8 dsc_max_slices;
5803− struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
5804−
5805− DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
58065945 max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
58075946 drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
58085947 &hdmi->max_frl_rate_per_lane);
5809− hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
5810−
5811− if (hdmi_dsc->v_1p2) {
5812− hdmi_dsc->native_420 = hf_scds[11] & DRM_EDID_DSC_NATIVE_420;
5813− hdmi_dsc->all_bpp = hf_scds[11] & DRM_EDID_DSC_ALL_BPP;
5814−
5815− if (hf_scds[11] & DRM_EDID_DSC_16BPC)
5816− hdmi_dsc->bpc_supported = 16;
5817− else if (hf_scds[11] & DRM_EDID_DSC_12BPC)
5818− hdmi_dsc->bpc_supported = 12;
5819− else if (hf_scds[11] & DRM_EDID_DSC_10BPC)
5820− hdmi_dsc->bpc_supported = 10;
5821− else
5822− hdmi_dsc->bpc_supported = 0;
5823−
5824− dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
5825− drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
5826− &hdmi_dsc->max_frl_rate_per_lane);
5827− hdmi_dsc->total_chunk_kbytes = hf_scds[13] & DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
5828−
5829− dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
5830− switch (dsc_max_slices) {
5831− case 1:
5832− hdmi_dsc->max_slices = 1;
5833− hdmi_dsc->clk_per_slice = 340;
5834− break;
5835− case 2:
5836− hdmi_dsc->max_slices = 2;
5837− hdmi_dsc->clk_per_slice = 340;
5838− break;
5839− case 3:
5840− hdmi_dsc->max_slices = 4;
5841− hdmi_dsc->clk_per_slice = 340;
5842− break;
5843− case 4:
5844− hdmi_dsc->max_slices = 8;
5845− hdmi_dsc->clk_per_slice = 340;
5846− break;
5847− case 5:
5848− hdmi_dsc->max_slices = 8;
5849− hdmi_dsc->clk_per_slice = 400;
5850− break;
5851− case 6:
5852− hdmi_dsc->max_slices = 12;
5853− hdmi_dsc->clk_per_slice = 400;
5854− break;
5855− case 7:
5856− hdmi_dsc->max_slices = 16;
5857− hdmi_dsc->clk_per_slice = 400;
5858− break;
5859− case 0:
5860− default:
5861− hdmi_dsc->max_slices = 0;
5862− hdmi_dsc->clk_per_slice = 0;
5863− }
5864− }
58655948 }
58665949
58675950 drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
5951+
5952+ if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11]) {
5953+ drm_parse_dsc_info(hdmi_dsc, hf_scds);
5954+ dsc_support = true;
5955+ }
5956+
5957+ drm_dbg_kms(connector->dev,
5958+ "HF-VSDB: max TMDS clock: %d KHz, HDMI 2.1 support: %s, DSC 1.2 support: %s\n",
5959+ max_tmds_clock, str_yes_no(max_frl_rate), str_yes_no(dsc_support));
58685960 }
58695961
58705962 static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
@@ -6033,10 +6125,13 @@ void get_monitor_range(const struct detailed_timing *timing, void *c) · 162 unmodified lines
60336125 return;
60346126
60356127 /*
6036− * Check for flag range limits only. If flag == 1 then
6037− * no additional timing information provided.
6038− * Default GTF, GTF Secondary curve and CVT are not
6039− * supported
6128+ * These limits are used to determine the VRR refresh
6129+ * rate range. Only the "range limits only" variant
6130+ * of the range descriptor seems to guarantee that
6131+ * any and all timings are accepted by the sink, as
6132+ * opposed to just timings conforming to the indicated
6133+ * formula (GTF/GTF2/CVT). Thus other variants of the
6134+ * range descriptor are not accepted here.
60406135 */
60416136 if (range->flags != DRM_EDID_RANGE_LIMITS_ONLY_FLAG)
60426137 return;
@@ -6061,7 +6156,10 @@ static void drm_get_monitor_range(struct drm_connector *connector, · 18 unmodified lines
60616156 .drm_edid = drm_edid,
60626157 };
60636158
6064− if (!version_greater(drm_edid, 1, 1))
6159+ if (drm_edid->edid->revision < 4)
6160+ return;
6161+
6162+ if (!(drm_edid->edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ))
60656163 return;
60666164
60676165 drm_for_each_detailed_block(drm_edid, get_monitor_range, &closure);
@@ -6390,7 +6488,7 @@ static int _drm_edid_connector_update(struct drm_connector *connector, · 322 unmodified lines
63906488 num_modes += add_cea_modes(connector, drm_edid);
63916489 num_modes += add_alternate_cea_modes(connector, drm_edid);
63926490 num_modes += add_displayid_detailed_modes(connector, drm_edid);
6393− if (drm_edid->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
6491+ if (drm_edid->edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ)
63946492 num_modes += add_inferred_modes(connector, drm_edid);
63956493
63966494 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
@@ -6837,7 +6935,7 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, · 440 unmodified lines
68376935 * by non-zero YQ when receiving RGB. There doesn't seem to be any
68386936 * good way to tell which version of CEA-861 the sink supports, so
68396937 * we limit non-zero YQ to HDMI 2.0 sinks only as HDMI 2.0 is based
6840− * on on CEA-861-F.
6938+ * on CEA-861-F.
68416939 */
68426940 if (!is_hdmi2_sink(connector) ||
68436941 rgb_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED)
drivers/gpu/drm/drm_format_helper.c+10−0
@@ -660,6 +660,11 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d · 659 unmodified lines
660660 drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, false);
661661 return 0;
662662 }
663+ } else if (dst_format == (DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN)) {
664+ if (fb_format == DRM_FORMAT_RGB565) {
665+ drm_fb_swab(dst, dst_pitch, src, fb, clip, false);
666+ return 0;
667+ }
663668 } else if (dst_format == DRM_FORMAT_RGB888) {
664669 if (fb_format == DRM_FORMAT_XRGB8888) {
665670 drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip);
@@ -678,6 +683,11 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d · 12 unmodified lines
678683 drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip);
679684 return 0;
680685 }
686+ } else if (dst_format == DRM_FORMAT_BGRX8888) {
687+ if (fb_format == DRM_FORMAT_XRGB8888) {
688+ drm_fb_swab(dst, dst_pitch, src, fb, clip, false);
689+ return 0;
690+ }
681691 }
682692
683693 drm_warn_once(fb->dev, "No conversion helper from %p4cc to %p4cc found.\n",
drivers/gpu/drm/drm_gem.c+24−0
@@ -1158,6 +1158,8 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) · 1157 unmodified lines
11581158 {
11591159 int ret;
11601160
1161+ dma_resv_assert_held(obj->resv);
1162+
11611163 if (!obj->funcs->vmap)
11621164 return -EOPNOTSUPP;
11631165
@@ -1173,6 +1175,8 @@ EXPORT_SYMBOL(drm_gem_vmap); · 9 unmodified lines
11731175
11741176 void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
11751177 {
1178+ dma_resv_assert_held(obj->resv);
1179+
11761180 if (iosys_map_is_null(map))
11771181 return;
11781182
@@ -1184,6 +1188,26 @@ void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map) · 5 unmodified lines
11841188 }
11851189 EXPORT_SYMBOL(drm_gem_vunmap);
11861190
1191+int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
1192+{
1193+ int ret;
1194+
1195+ dma_resv_lock(obj->resv, NULL);
1196+ ret = drm_gem_vmap(obj, map);
1197+ dma_resv_unlock(obj->resv);
1198+
1199+ return ret;
1200+}
1201+EXPORT_SYMBOL(drm_gem_vmap_unlocked);
1202+
1203+void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
1204+{
1205+ dma_resv_lock(obj->resv, NULL);
1206+ drm_gem_vunmap(obj, map);
1207+ dma_resv_unlock(obj->resv);
1208+}
1209+EXPORT_SYMBOL(drm_gem_vunmap_unlocked);
1210+
11871211 /**
11881212 * drm_gem_lock_reservations - Sets up the ww context and acquires
11891213 * the lock on an array of GEM objects.
drivers/gpu/drm/drm_gem_dma_helper.c+3−3
@@ -230,7 +230,7 @@ void drm_gem_dma_free(struct drm_gem_dma_object *dma_obj) · 229 unmodified lines
230230
231231 if (gem_obj->import_attach) {
232232 if (dma_obj->vaddr)
233− dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map);
233+ dma_buf_vunmap_unlocked(gem_obj->import_attach->dmabuf, &map);
234234 drm_prime_gem_destroy(gem_obj, dma_obj->sgt);
235235 } else if (dma_obj->vaddr) {
236236 if (dma_obj->map_noncoherent)
@@ -581,7 +581,7 @@ drm_gem_dma_prime_import_sg_table_vmap(struct drm_device *dev, · 344 unmodified lines
581581 struct iosys_map map;
582582 int ret;
583583
584− ret = dma_buf_vmap(attach->dmabuf, &map);
584+ ret = dma_buf_vmap_unlocked(attach->dmabuf, &map);
585585 if (ret) {
586586 DRM_ERROR("Failed to vmap PRIME buffer\n");
587587 return ERR_PTR(ret);
@@ -589,7 +589,7 @@ drm_gem_dma_prime_import_sg_table_vmap(struct drm_device *dev, · 1 unmodified line
589589
590590 obj = drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
591591 if (IS_ERR(obj)) {
592− dma_buf_vunmap(attach->dmabuf, &map);
592+ dma_buf_vunmap_unlocked(attach->dmabuf, &map);
593593 return obj;
594594 }
595595
drivers/gpu/drm/drm_gem_framebuffer_helper.c+3−3
@@ -354,7 +354,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, · 353 unmodified lines
354354 ret = -EINVAL;
355355 goto err_drm_gem_vunmap;
356356 }
357− ret = drm_gem_vmap(obj, &map[i]);
357+ ret = drm_gem_vmap_unlocked(obj, &map[i]);
358358 if (ret)
359359 goto err_drm_gem_vunmap;
360360 }
@@ -376,7 +376,7 @@ err_drm_gem_vunmap: · 15 unmodified lines
376376 obj = drm_gem_fb_get_obj(fb, i);
377377 if (!obj)
378378 continue;
379− drm_gem_vunmap(obj, &map[i]);
379+ drm_gem_vunmap_unlocked(obj, &map[i]);
380380 }
381381 return ret;
382382 }
@@ -403,7 +403,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map) · 20 unmodified lines
403403 continue;
404404 if (iosys_map_is_null(&map[i]))
405405 continue;
406− drm_gem_vunmap(obj, &map[i]);
406+ drm_gem_vunmap_unlocked(obj, &map[i]);
407407 }
408408 }
409409 EXPORT_SYMBOL(drm_gem_fb_vunmap);
drivers/gpu/drm/drm_gem_ttm_helper.c+1−8
@@ -64,13 +64,8 @@ int drm_gem_ttm_vmap(struct drm_gem_object *gem, · 63 unmodified lines
6464 struct iosys_map *map)
6565 {
6666 struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
67− int ret;
68−
69− dma_resv_lock(gem->resv, NULL);
70− ret = ttm_bo_vmap(bo, map);
71− dma_resv_unlock(gem->resv);
7267
73− return ret;
68+ return ttm_bo_vmap(bo, map);
7469 }
7570 EXPORT_SYMBOL(drm_gem_ttm_vmap);
7671
@@ -87,9 +82,7 @@ void drm_gem_ttm_vunmap(struct drm_gem_object *gem, · 10 unmodified lines
8782 {
8883 struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
8984
90− dma_resv_lock(gem->resv, NULL);
9185 ttm_bo_vunmap(bo, map);
92− dma_resv_unlock(gem->resv);
9386 }
9487 EXPORT_SYMBOL(drm_gem_ttm_vunmap);
9588
drivers/gpu/drm/drm_modes.c+11−7
@@ -1801,20 +1801,24 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, · 1800 unmodified lines
18011801
18021802 name = mode_option;
18031803
1804+ /* Locate the start of named options */
1805+ options_ptr = strchr(name, ',');
1806+ if (options_ptr)
1807+ options_off = options_ptr - name;
1808+ else
1809+ options_off = strlen(name);
1810+
18041811 /* Try to locate the bpp and refresh specifiers, if any */
1805− bpp_ptr = strchr(name, '-');
1812+ bpp_ptr = strnchr(name, options_off, '-');
1813+ while (bpp_ptr && !isdigit(bpp_ptr[1]))
1814+ bpp_ptr = strnchr(bpp_ptr + 1, options_off, '-');
18061815 if (bpp_ptr)
18071816 bpp_off = bpp_ptr - name;
18081817
1809− refresh_ptr = strchr(name, '@');
1818+ refresh_ptr = strnchr(name, options_off, '@');
18101819 if (refresh_ptr)
18111820 refresh_off = refresh_ptr - name;
18121821
1813− /* Locate the start of named options */
1814− options_ptr = strchr(name, ',');
1815− if (options_ptr)
1816− options_off = options_ptr - name;
1817−
18181822 /* Locate the end of the name / resolution, and parse it */
18191823 if (bpp_ptr) {
18201824 mode_end = bpp_off;
drivers/gpu/drm/drm_plane_helper.c+3−1
@@ -298,7 +298,9 @@ EXPORT_SYMBOL(drm_plane_helper_destroy); · 297 unmodified lines
298298 * scale and positioning are not expected to change since the plane is always
299299 * a fullscreen scanout buffer.
300300 *
301− * This is often the case for the primary plane of simple framebuffers.
301+ * This is often the case for the primary plane of simple framebuffers. See
302+ * also drm_crtc_helper_atomic_check() for the respective CRTC-state check
303+ * helper function.
302304 *
303305 * RETURNS:
304306 * Zero on success, or an errno code otherwise.
drivers/gpu/drm/drm_prime.c+3−3
@@ -940,7 +940,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, · 939 unmodified lines
940940
941941 get_dma_buf(dma_buf);
942942
943− sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
943+ sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
944944 if (IS_ERR(sgt)) {
945945 ret = PTR_ERR(sgt);
946946 goto fail_detach;
@@ -958,7 +958,7 @@ struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev, · 11 unmodified lines
958958 return obj;
959959
960960 fail_unmap:
961− dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
961+ dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
962962 fail_detach:
963963 dma_buf_detach(dma_buf, attach);
964964 dma_buf_put(dma_buf);
@@ -1056,7 +1056,7 @@ void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) · 91 unmodified lines
10561056
10571057 attach = obj->import_attach;
10581058 if (sg)
1059− dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
1059+ dma_buf_unmap_attachment_unlocked(attach, sg, DMA_BIDIRECTIONAL);
10601060 dma_buf = attach->dmabuf;
10611061 dma_buf_detach(attach->dmabuf, attach);
10621062 /* remove the reference */
drivers/gpu/drm/drm_simple_kms_helper.c+5−1
@@ -102,10 +102,14 @@ static int drm_simple_kms_crtc_check(struct drm_crtc *crtc, · 101 unmodified lines
102102 struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
103103 int ret;
104104
105− ret = drm_atomic_helper_check_crtc_state(crtc_state, false);
105+ if (!crtc_state->enable)
106+ goto out;
107+
108+ ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state);
106109 if (ret)
107110 return ret;
108111
112+out:
109113 return drm_atomic_add_affected_planes(state, crtc);
110114 }
111115
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c+1−1
@@ -65,7 +65,7 @@ static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) · 64 unmodified lines
6565 struct iosys_map map = IOSYS_MAP_INIT_VADDR(etnaviv_obj->vaddr);
6666
6767 if (etnaviv_obj->vaddr)
68− dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, &map);
68+ dma_buf_vunmap_unlocked(etnaviv_obj->base.import_attach->dmabuf, &map);
6969
7070 /* Don't drop the pages for imported dmabuf, as they are not
7171 * ours, just free the array we allocated:
drivers/gpu/drm/gma500/framebuffer.c+3−3
@@ -286,7 +286,7 @@ static int psbfb_create(struct drm_fb_helper *fb_helper, · 285 unmodified lines
286286
287287 info->fbops = &psbfb_unaccel_ops;
288288
289− info->fix.smem_start = dev->mode_config.fb_base;
289+ info->fix.smem_start = dev_priv->fb_base;
290290 info->fix.smem_len = size;
291291 info->fix.ywrapstep = 0;
292292 info->fix.ypanstep = 0;
@@ -296,7 +296,7 @@ static int psbfb_create(struct drm_fb_helper *fb_helper, · 3 unmodified lines
296296 info->screen_size = size;
297297
298298 if (dev_priv->gtt.stolen_size) {
299− info->apertures->ranges[0].base = dev->mode_config.fb_base;
299+ info->apertures->ranges[0].base = dev_priv->fb_base;
300300 info->apertures->ranges[0].size = dev_priv->gtt.stolen_size;
301301 }
302302
@@ -527,7 +527,7 @@ void psb_modeset_init(struct drm_device *dev) · 224 unmodified lines
527527
528528 /* set memory base */
529529 /* Oaktrail and Poulsbo should use BAR 2*/
530− pci_read_config_dword(pdev, PSB_BSM, (u32 *)&(dev->mode_config.fb_base));
530+ pci_read_config_dword(pdev, PSB_BSM, (u32 *)&(dev_priv->fb_base));
531531
532532 /* num pipes is 2 for PSB but 1 for Mrst */
533533 for (i = 0; i < dev_priv->num_pipe; i++)
drivers/gpu/drm/gma500/psb_drv.h+1−0
@@ -523,6 +523,7 @@ struct drm_psb_private { · 522 unmodified lines
523523 uint32_t blc_adj2;
524524
525525 struct drm_fb_helper *fb_helper;
526+ resource_size_t fb_base;
526527
527528 bool dsr_enable;
528529 u32 dsr_fb_update;
drivers/gpu/drm/gud/gud_connector.c+1−1
@@ -355,7 +355,7 @@ static void gud_connector_reset(struct drm_connector *connector) · 354 unmodified lines
355355 drm_atomic_helper_connector_reset(connector);
356356 connector->state->tv = gconn->initial_tv_state;
357357 /* Set margins from command line */
358− drm_atomic_helper_connector_tv_reset(connector);
358+ drm_atomic_helper_connector_tv_margins_reset(connector);
359359 if (gconn->initial_brightness >= 0)
360360 connector->state->tv.brightness = gconn->initial_brightness;
361361 }
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c+3−13
@@ -105,7 +105,6 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) · 104 unmodified lines
105105 dev->mode_config.max_width = 1920;
106106 dev->mode_config.max_height = 1200;
107107
108− dev->mode_config.fb_base = priv->fb_base;
109108 dev->mode_config.preferred_depth = 32;
110109 dev->mode_config.prefer_shadow = 1;
111110
@@ -212,7 +211,7 @@ static int hibmc_hw_map(struct hibmc_drm_private *priv) · 100 unmodified lines
212211 {
213212 struct drm_device *dev = &priv->dev;
214213 struct pci_dev *pdev = to_pci_dev(dev->dev);
215− resource_size_t addr, size, ioaddr, iosize;
214+ resource_size_t ioaddr, iosize;
216215
217216 ioaddr = pci_resource_start(pdev, 1);
218217 iosize = pci_resource_len(pdev, 1);
@@ -222,16 +221,6 @@ static int hibmc_hw_map(struct hibmc_drm_private *priv) · 3 unmodified lines
222221 return -ENOMEM;
223222 }
224223
225− addr = pci_resource_start(pdev, 0);
226− size = pci_resource_len(pdev, 0);
227− priv->fb_map = devm_ioremap(dev->dev, addr, size);
228− if (!priv->fb_map) {
229− drm_err(dev, "Cannot map framebuffer\n");
230− return -ENOMEM;
231− }
232− priv->fb_base = addr;
233− priv->fb_size = size;
234−
235224 return 0;
236225 }
237226
@@ -271,7 +260,8 @@ static int hibmc_load(struct drm_device *dev) · 33 unmodified lines
271260 if (ret)
272261 goto err;
273262
274− ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), priv->fb_size);
263+ ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0),
264+ pci_resource_len(pdev, 0));
275265 if (ret) {
276266 drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
277267 goto err;
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h+0−3
@@ -32,9 +32,6 @@ struct hibmc_connector { · 31 unmodified lines
3232 struct hibmc_drm_private {
3333 /* hw */
3434 void __iomem *mmio;
35− void __iomem *fb_map;
36− resource_size_t fb_base;
37− resource_size_t fb_size;
3835
3936 /* drm */
4037 struct drm_device dev;
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c+1−1
@@ -72,7 +72,7 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, · 71 unmodified lines
7272 struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
7373 void *vaddr;
7474
75− vaddr = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
75+ vaddr = i915_gem_object_pin_map(obj, I915_MAP_WB);
7676 if (IS_ERR(vaddr))
7777 return PTR_ERR(vaddr);
7878
drivers/gpu/drm/i915/gem/i915_gem_object.c+14−0
@@ -290,7 +290,21 @@ void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj) · 289 unmodified lines
290290 __i915_gem_object_free_mmaps(obj);
291291
292292 atomic_set(&obj->mm.pages_pin_count, 0);
293+
294+ /*
295+ * dma_buf_unmap_attachment() requires reservation to be
296+ * locked. The imported GEM shouldn't share reservation lock
297+ * and ttm_bo_cleanup_memtype_use() shouldn't be invoked for
298+ * dma-buf, so it's safe to take the lock.
299+ */
300+ if (obj->base.import_attach)
301+ i915_gem_object_lock(obj, NULL);
302+
293303 __i915_gem_object_put_pages(obj);
304+
305+ if (obj->base.import_attach)
306+ i915_gem_object_unlock(obj);
307+
294308 GEM_BUG_ON(i915_gem_object_has_pages(obj));
295309 }
296310
drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c+8−8
@@ -213,7 +213,7 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915, · 212 unmodified lines
213213 goto out_import;
214214 }
215215
216− st = dma_buf_map_attachment(import_attach, DMA_BIDIRECTIONAL);
216+ st = dma_buf_map_attachment_unlocked(import_attach, DMA_BIDIRECTIONAL);
217217 if (IS_ERR(st)) {
218218 err = PTR_ERR(st);
219219 goto out_detach;
@@ -226,7 +226,7 @@ static int igt_dmabuf_import_same_driver(struct drm_i915_private *i915, · 6 unmodified lines
226226 timeout = -ETIME;
227227 }
228228 err = timeout > 0 ? 0 : timeout;
229− dma_buf_unmap_attachment(import_attach, st, DMA_BIDIRECTIONAL);
229+ dma_buf_unmap_attachment_unlocked(import_attach, st, DMA_BIDIRECTIONAL);
230230 out_detach:
231231 dma_buf_detach(dmabuf, import_attach);
232232 out_import:
@@ -296,7 +296,7 @@ static int igt_dmabuf_import(void *arg) · 63 unmodified lines
296296 goto out_obj;
297297 }
298298
299− err = dma_buf_vmap(dmabuf, &map);
299+ err = dma_buf_vmap_unlocked(dmabuf, &map);
300300 dma_map = err ? NULL : map.vaddr;
301301 if (!dma_map) {
302302 pr_err("dma_buf_vmap failed\n");
@@ -337,7 +337,7 @@ static int igt_dmabuf_import(void *arg) · 34 unmodified lines
337337
338338 err = 0;
339339 out_dma_map:
340− dma_buf_vunmap(dmabuf, &map);
340+ dma_buf_vunmap_unlocked(dmabuf, &map);
341341 out_obj:
342342 i915_gem_object_put(obj);
343343 out_dmabuf:
@@ -358,7 +358,7 @@ static int igt_dmabuf_import_ownership(void *arg) · 14 unmodified lines
358358 if (IS_ERR(dmabuf))
359359 return PTR_ERR(dmabuf);
360360
361− err = dma_buf_vmap(dmabuf, &map);
361+ err = dma_buf_vmap_unlocked(dmabuf, &map);
362362 ptr = err ? NULL : map.vaddr;
363363 if (!ptr) {
364364 pr_err("dma_buf_vmap failed\n");
@@ -367,7 +367,7 @@ static int igt_dmabuf_import_ownership(void *arg) · 2 unmodified lines
367367 }
368368
369369 memset(ptr, 0xc5, PAGE_SIZE);
370− dma_buf_vunmap(dmabuf, &map);
370+ dma_buf_vunmap_unlocked(dmabuf, &map);
371371
372372 obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
373373 if (IS_ERR(obj)) {
@@ -418,7 +418,7 @@ static int igt_dmabuf_export_vmap(void *arg) · 44 unmodified lines
418418 }
419419 i915_gem_object_put(obj);
420420
421− err = dma_buf_vmap(dmabuf, &map);
421+ err = dma_buf_vmap_unlocked(dmabuf, &map);
422422 ptr = err ? NULL : map.vaddr;
423423 if (!ptr) {
424424 pr_err("dma_buf_vmap failed\n");
@@ -435,7 +435,7 @@ static int igt_dmabuf_export_vmap(void *arg) · 10 unmodified lines
435435 memset(ptr, 0xc5, dmabuf->size);
436436
437437 err = 0;
438− dma_buf_vunmap(dmabuf, &map);
438+ dma_buf_vunmap_unlocked(dmabuf, &map);
439439 out:
440440 dma_buf_put(dmabuf);
441441 return err;
drivers/gpu/drm/lima/lima_sched.c+2−2
@@ -371,7 +371,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) · 370 unmodified lines
371371 } else {
372372 buffer_chunk->size = lima_bo_size(bo);
373373
374− ret = drm_gem_shmem_vmap(&bo->base, &map);
374+ ret = drm_gem_vmap_unlocked(&bo->base.base, &map);
375375 if (ret) {
376376 kvfree(et);
377377 goto out;
@@ -379,7 +379,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task) · 1 unmodified line
379379
380380 memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);
381381
382− drm_gem_shmem_vunmap(&bo->base, &map);
382+ drm_gem_vunmap_unlocked(&bo->base.base, &map);
383383 }
384384
385385 buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
drivers/gpu/drm/mgag200/mgag200_g200se.c+2−1
@@ -284,7 +284,8 @@ static void mgag200_g200se_04_pixpllc_atomic_update(struct drm_crtc *crtc, · 283 unmodified lines
284284 pixpllcp = pixpllc->p - 1;
285285 pixpllcs = pixpllc->s;
286286
287− xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
287+ // For G200SE A, BIT(7) should be set unconditionally.
288+ xpixpllcm = BIT(7) | pixpllcm;
288289 xpixpllcn = pixpllcn;
289290 xpixpllcp = (pixpllcs << 3) | pixpllcp;
290291
drivers/gpu/drm/mgag200/mgag200_mode.c+5−6
@@ -579,13 +579,13 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st · 578 unmodified lines
579579 struct drm_property_blob *new_gamma_lut = new_crtc_state->gamma_lut;
580580 int ret;
581581
582− ret = drm_atomic_helper_check_crtc_state(new_crtc_state, false);
583− if (ret)
584− return ret;
585−
586582 if (!new_crtc_state->enable)
587583 return 0;
588584
585+ ret = drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
586+ if (ret)
587+ return ret;
588+
589589 if (new_crtc_state->mode_changed) {
590590 if (funcs->pixpllc_atomic_check) {
591591 ret = funcs->pixpllc_atomic_check(crtc, new_state);
@@ -601,7 +601,7 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st · 9 unmodified lines
601601 }
602602 }
603603
604− return drm_atomic_add_affected_planes(new_state, crtc);
604+ return 0;
605605 }
606606
607607 void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state)
@@ -824,7 +824,6 @@ int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_avail · 216 unmodified lines
824824 dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
825825 dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
826826 dev->mode_config.preferred_depth = 24;
827− dev->mode_config.fb_base = mdev->vram_res->start;
828827 dev->mode_config.funcs = &mgag200_mode_config_funcs;
829828 dev->mode_config.helper_private = &mgag200_mode_config_helper_funcs;
830829
drivers/gpu/drm/msm/msm_fbdev.c+0−2
@@ -109,8 +109,6 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, · 108 unmodified lines
109109
110110 drm_fb_helper_fill_info(fbi, helper, sizes);
111111
112− dev->mode_config.fb_base = paddr;
113−
114112 fbi->screen_base = msm_gem_get_vaddr(bo);
115113 if (IS_ERR(fbi->screen_base)) {
116114 ret = PTR_ERR(fbi->screen_base);
drivers/gpu/drm/mxsfb/lcdif_kms.c+216−23
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #include <drm/drm_atomic.h>
1616 #include <drm/drm_atomic_helper.h>
1717 #include <drm/drm_bridge.h>
18+#include <drm/drm_color_mgmt.h>
1819 #include <drm/drm_crtc.h>
1920 #include <drm/drm_encoder.h>
2021 #include <drm/drm_fb_dma_helper.h>
@@ -31,13 +32,126 @@ · 10 unmodified lines
3132 /* -----------------------------------------------------------------------------
3233 * CRTC
3334 */
35+
36+/*
37+ * For conversion from YCbCr to RGB, the CSC operates as follows:
38+ *
39+ * |R| |A1 A2 A3| |Y + D1|
40+ * |G| = |B1 B2 B3| * |Cb + D2|
41+ * |B| |C1 C2 C3| |Cr + D3|
42+ *
43+ * The A, B and C coefficients are expressed as Q2.8 fixed point values, and
44+ * the D coefficients as Q0.8. Despite the reference manual stating the
45+ * opposite, the D1, D2 and D3 offset values are added to Y, Cb and Cr, not
46+ * subtracted. They must thus be programmed with negative values.
47+ */
48+static const u32 lcdif_yuv2rgb_coeffs[3][2][6] = {
49+ [DRM_COLOR_YCBCR_BT601] = {
50+ [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
51+ /*
52+ * BT.601 limited range:
53+ *
54+ * |R| |1.1644 0.0000 1.5960| |Y - 16 |
55+ * |G| = |1.1644 -0.3917 -0.8129| * |Cb - 128|
56+ * |B| |1.1644 2.0172 0.0000| |Cr - 128|
57+ */
58+ CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
59+ CSC0_COEF1_A3(0x199) | CSC0_COEF1_B1(0x12a),
60+ CSC0_COEF2_B2(0x79c) | CSC0_COEF2_B3(0x730),
61+ CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x204),
62+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
63+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
64+ },
65+ [DRM_COLOR_YCBCR_FULL_RANGE] = {
66+ /*
67+ * BT.601 full range:
68+ *
69+ * |R| |1.0000 0.0000 1.4020| |Y - 0 |
70+ * |G| = |1.0000 -0.3441 -0.7141| * |Cb - 128|
71+ * |B| |1.0000 1.7720 0.0000| |Cr - 128|
72+ */
73+ CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
74+ CSC0_COEF1_A3(0x167) | CSC0_COEF1_B1(0x100),
75+ CSC0_COEF2_B2(0x7a8) | CSC0_COEF2_B3(0x749),
76+ CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1c6),
77+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
78+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
79+ },
80+ },
81+ [DRM_COLOR_YCBCR_BT709] = {
82+ [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
83+ /*
84+ * Rec.709 limited range:
85+ *
86+ * |R| |1.1644 0.0000 1.7927| |Y - 16 |
87+ * |G| = |1.1644 -0.2132 -0.5329| * |Cb - 128|
88+ * |B| |1.1644 2.1124 0.0000| |Cr - 128|
89+ */
90+ CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
91+ CSC0_COEF1_A3(0x1cb) | CSC0_COEF1_B1(0x12a),
92+ CSC0_COEF2_B2(0x7c9) | CSC0_COEF2_B3(0x778),
93+ CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x21d),
94+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
95+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
96+ },
97+ [DRM_COLOR_YCBCR_FULL_RANGE] = {
98+ /*
99+ * Rec.709 full range:
100+ *
101+ * |R| |1.0000 0.0000 1.5748| |Y - 0 |
102+ * |G| = |1.0000 -0.1873 -0.4681| * |Cb - 128|
103+ * |B| |1.0000 1.8556 0.0000| |Cr - 128|
104+ */
105+ CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
106+ CSC0_COEF1_A3(0x193) | CSC0_COEF1_B1(0x100),
107+ CSC0_COEF2_B2(0x7d0) | CSC0_COEF2_B3(0x788),
108+ CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1db),
109+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
110+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
111+ },
112+ },
113+ [DRM_COLOR_YCBCR_BT2020] = {
114+ [DRM_COLOR_YCBCR_LIMITED_RANGE] = {
115+ /*
116+ * BT.2020 limited range:
117+ *
118+ * |R| |1.1644 0.0000 1.6787| |Y - 16 |
119+ * |G| = |1.1644 -0.1874 -0.6505| * |Cb - 128|
120+ * |B| |1.1644 2.1418 0.0000| |Cr - 128|
121+ */
122+ CSC0_COEF0_A1(0x12a) | CSC0_COEF0_A2(0x000),
123+ CSC0_COEF1_A3(0x1ae) | CSC0_COEF1_B1(0x12a),
124+ CSC0_COEF2_B2(0x7d0) | CSC0_COEF2_B3(0x759),
125+ CSC0_COEF3_C1(0x12a) | CSC0_COEF3_C2(0x224),
126+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x1f0),
127+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
128+ },
129+ [DRM_COLOR_YCBCR_FULL_RANGE] = {
130+ /*
131+ * BT.2020 full range:
132+ *
133+ * |R| |1.0000 0.0000 1.4746| |Y - 0 |
134+ * |G| = |1.0000 -0.1646 -0.5714| * |Cb - 128|
135+ * |B| |1.0000 1.8814 0.0000| |Cr - 128|
136+ */
137+ CSC0_COEF0_A1(0x100) | CSC0_COEF0_A2(0x000),
138+ CSC0_COEF1_A3(0x179) | CSC0_COEF1_B1(0x100),
139+ CSC0_COEF2_B2(0x7d6) | CSC0_COEF2_B3(0x76e),
140+ CSC0_COEF3_C1(0x100) | CSC0_COEF3_C2(0x1e2),
141+ CSC0_COEF4_C3(0x000) | CSC0_COEF4_D1(0x000),
142+ CSC0_COEF5_D2(0x180) | CSC0_COEF5_D3(0x180),
143+ },
144+ },
145+};
146+
34147 static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
148+ struct drm_plane_state *plane_state,
35149 const u32 bus_format)
36150 {
37151 struct drm_device *drm = lcdif->drm;
38− const u32 format = lcdif->crtc.primary->state->fb->format->format;
39−
40− writel(CSC0_CTRL_BYPASS, lcdif->base + LCDC_V8_CSC0_CTRL);
152+ const u32 format = plane_state->fb->format->format;
153+ bool in_yuv = false;
154+ bool out_yuv = false;
41155
42156 switch (bus_format) {
43157 case MEDIA_BUS_FMT_RGB565_1X16:
@@ -51,24 +165,7 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif, · 7 unmodified lines
51165 case MEDIA_BUS_FMT_UYVY8_1X16:
52166 writel(DISP_PARA_LINE_PATTERN_UYVY_H,
53167 lcdif->base + LCDC_V8_DISP_PARA);
54−
55− /* CSC: BT.601 Full Range RGB to YCbCr coefficients. */
56− writel(CSC0_COEF0_A2(0x096) | CSC0_COEF0_A1(0x04c),
57− lcdif->base + LCDC_V8_CSC0_COEF0);
58− writel(CSC0_COEF1_B1(0x7d5) | CSC0_COEF1_A3(0x01d),
59− lcdif->base + LCDC_V8_CSC0_COEF1);
60− writel(CSC0_COEF2_B3(0x080) | CSC0_COEF2_B2(0x7ac),
61− lcdif->base + LCDC_V8_CSC0_COEF2);
62− writel(CSC0_COEF3_C2(0x795) | CSC0_COEF3_C1(0x080),
63− lcdif->base + LCDC_V8_CSC0_COEF3);
64− writel(CSC0_COEF4_D1(0x000) | CSC0_COEF4_C3(0x7ec),
65− lcdif->base + LCDC_V8_CSC0_COEF4);
66− writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080),
67− lcdif->base + LCDC_V8_CSC0_COEF5);
68−
69− writel(CSC0_CTRL_CSC_MODE_RGB2YCbCr,
70− lcdif->base + LCDC_V8_CSC0_CTRL);
71−
168+ out_yuv = true;
72169 break;
73170 default:
74171 dev_err(drm->dev, "Unknown media bus format 0x%x\n", bus_format);
@@ -76,6 +173,7 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif, · 1 unmodified line
76173 }
77174
78175 switch (format) {
176+ /* RGB Formats */
79177 case DRM_FORMAT_RGB565:
80178 writel(CTRLDESCL0_5_BPP_16_RGB565,
81179 lcdif->base + LCDC_V8_CTRLDESCL0_5);
@@ -100,10 +198,84 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif, · 18 unmodified lines
100198 writel(CTRLDESCL0_5_BPP_32_ARGB8888,
101199 lcdif->base + LCDC_V8_CTRLDESCL0_5);
102200 break;
201+
202+ /* YUV Formats */
203+ case DRM_FORMAT_YUYV:
204+ writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_VY2UY1,
205+ lcdif->base + LCDC_V8_CTRLDESCL0_5);
206+ in_yuv = true;
207+ break;
208+ case DRM_FORMAT_YVYU:
209+ writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_UY2VY1,
210+ lcdif->base + LCDC_V8_CTRLDESCL0_5);
211+ in_yuv = true;
212+ break;
213+ case DRM_FORMAT_UYVY:
214+ writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2VY1U,
215+ lcdif->base + LCDC_V8_CTRLDESCL0_5);
216+ in_yuv = true;
217+ break;
218+ case DRM_FORMAT_VYUY:
219+ writel(CTRLDESCL0_5_BPP_YCbCr422 | CTRLDESCL0_5_YUV_FORMAT_Y2UY1V,
220+ lcdif->base + LCDC_V8_CTRLDESCL0_5);
221+ in_yuv = true;
222+ break;
223+
103224 default:
104225 dev_err(drm->dev, "Unknown pixel format 0x%x\n", format);
105226 break;
106227 }
228+
229+ /*
230+ * The CSC differentiates between "YCbCr" and "YUV", but the reference
231+ * manual doesn't detail how they differ. Experiments showed that the
232+ * luminance value is unaffected, only the calculations involving chroma
233+ * values differ. The YCbCr mode behaves as expected, with chroma values
234+ * being offset by 128. The YUV mode isn't fully understood.
235+ */
236+ if (!in_yuv && out_yuv) {
237+ /* RGB -> YCbCr */
238+ writel(CSC0_CTRL_CSC_MODE_RGB2YCbCr,
239+ lcdif->base + LCDC_V8_CSC0_CTRL);
240+
241+ /*
242+ * CSC: BT.601 Limited Range RGB to YCbCr coefficients.
243+ *
244+ * |Y | | 0.2568 0.5041 0.0979| |R| |16 |
245+ * |Cb| = |-0.1482 -0.2910 0.4392| * |G| + |128|
246+ * |Cr| | 0.4392 0.4392 -0.3678| |B| |128|
247+ */
248+ writel(CSC0_COEF0_A2(0x081) | CSC0_COEF0_A1(0x041),
249+ lcdif->base + LCDC_V8_CSC0_COEF0);
250+ writel(CSC0_COEF1_B1(0x7db) | CSC0_COEF1_A3(0x019),
251+ lcdif->base + LCDC_V8_CSC0_COEF1);
252+ writel(CSC0_COEF2_B3(0x070) | CSC0_COEF2_B2(0x7b6),
253+ lcdif->base + LCDC_V8_CSC0_COEF2);
254+ writel(CSC0_COEF3_C2(0x7a2) | CSC0_COEF3_C1(0x070),
255+ lcdif->base + LCDC_V8_CSC0_COEF3);
256+ writel(CSC0_COEF4_D1(0x010) | CSC0_COEF4_C3(0x7ee),
257+ lcdif->base + LCDC_V8_CSC0_COEF4);
258+ writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080),
259+ lcdif->base + LCDC_V8_CSC0_COEF5);
260+ } else if (in_yuv && !out_yuv) {
261+ /* YCbCr -> RGB */
262+ const u32 *coeffs =
263+ lcdif_yuv2rgb_coeffs[plane_state->color_encoding]
264+ [plane_state->color_range];
265+
266+ writel(CSC0_CTRL_CSC_MODE_YCbCr2RGB,
267+ lcdif->base + LCDC_V8_CSC0_CTRL);
268+
269+ writel(coeffs[0], lcdif->base + LCDC_V8_CSC0_COEF0);
270+ writel(coeffs[1], lcdif->base + LCDC_V8_CSC0_COEF1);
271+ writel(coeffs[2], lcdif->base + LCDC_V8_CSC0_COEF2);
272+ writel(coeffs[3], lcdif->base + LCDC_V8_CSC0_COEF3);
273+ writel(coeffs[4], lcdif->base + LCDC_V8_CSC0_COEF4);
274+ writel(coeffs[5], lcdif->base + LCDC_V8_CSC0_COEF5);
275+ } else {
276+ /* RGB -> RGB, YCbCr -> YCbCr: bypass colorspace converter. */
277+ writel(CSC0_CTRL_BYPASS, lcdif->base + LCDC_V8_CSC0_CTRL);
278+ }
107279 }
108280
109281 static void lcdif_set_mode(struct lcdif_drm_private *lcdif, u32 bus_flags)
@@ -188,6 +360,7 @@ static void lcdif_reset_block(struct lcdif_drm_private *lcdif) · 78 unmodified lines
188360 }
189361
190362 static void lcdif_crtc_mode_set_nofb(struct lcdif_drm_private *lcdif,
363+ struct drm_plane_state *plane_state,
191364 struct drm_bridge_state *bridge_state,
192365 const u32 bus_format)
193366 {
@@ -210,7 +383,7 @@ static void lcdif_crtc_mode_set_nofb(struct lcdif_drm_private *lcdif, · 16 unmodified lines
210383 /* Mandatory eLCDIF reset as per the Reference Manual */
211384 lcdif_reset_block(lcdif);
212385
213− lcdif_set_formats(lcdif, bus_format);
386+ lcdif_set_formats(lcdif, plane_state, bus_format);
214387
215388 lcdif_set_mode(lcdif, bus_flags);
216389 }
@@ -293,7 +466,7 @@ static void lcdif_crtc_atomic_enable(struct drm_crtc *crtc, · 76 unmodified lines
293466
294467 pm_runtime_get_sync(drm->dev);
295468
296− lcdif_crtc_mode_set_nofb(lcdif, bridge_state, bus_format);
469+ lcdif_crtc_mode_set_nofb(lcdif, new_pstate, bridge_state, bus_format);
297470
298471 /* Write cur_buf as well to avoid an initial corrupt frame */
299472 paddr = drm_fb_dma_get_gem_addr(new_pstate->fb, new_pstate, 0);
@@ -437,12 +610,19 @@ static const struct drm_plane_funcs lcdif_plane_funcs = { · 137 unmodified lines
437610 };
438611
439612 static const u32 lcdif_primary_plane_formats[] = {
613+ /* RGB */
440614 DRM_FORMAT_RGB565,
441615 DRM_FORMAT_RGB888,
442616 DRM_FORMAT_XBGR8888,
443617 DRM_FORMAT_XRGB1555,
444618 DRM_FORMAT_XRGB4444,
445619 DRM_FORMAT_XRGB8888,
620+
621+ /* Packed YCbCr */
622+ DRM_FORMAT_YUYV,
623+ DRM_FORMAT_YVYU,
624+ DRM_FORMAT_UYVY,
625+ DRM_FORMAT_VYUY,
446626 };
447627
448628 static const u64 lcdif_modifiers[] = {
@@ -456,6 +636,11 @@ static const u64 lcdif_modifiers[] = { · 7 unmodified lines
456636
457637 int lcdif_kms_init(struct lcdif_drm_private *lcdif)
458638 {
639+ const u32 supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) |
640+ BIT(DRM_COLOR_YCBCR_BT709) |
641+ BIT(DRM_COLOR_YCBCR_BT2020);
642+ const u32 supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
643+ BIT(DRM_COLOR_YCBCR_FULL_RANGE);
459644 struct drm_encoder *encoder = &lcdif->encoder;
460645 struct drm_crtc *crtc = &lcdif->crtc;
461646 int ret;
@@ -471,6 +656,14 @@ int lcdif_kms_init(struct lcdif_drm_private *lcdif) · 9 unmodified lines
471656 if (ret)
472657 return ret;
473658
659+ ret = drm_plane_create_color_properties(&lcdif->planes.primary,
660+ supported_encodings,
661+ supported_ranges,
662+ DRM_COLOR_YCBCR_BT601,
663+ DRM_COLOR_YCBCR_LIMITED_RANGE);
664+ if (ret)
665+ return ret;
666+
474667 drm_crtc_helper_add(crtc, &lcdif_crtc_helper_funcs);
475668 ret = drm_crtc_init_with_planes(lcdif->drm, crtc,
476669 &lcdif->planes.primary, NULL,
drivers/gpu/drm/mxsfb/lcdif_regs.h+20−17
@@ -130,7 +130,7 @@ · 129 unmodified lines
130130 #define CTRL_FETCH_START_OPTION_BPV BIT(9)
131131 #define CTRL_FETCH_START_OPTION_RESV GENMASK(9, 8)
132132 #define CTRL_FETCH_START_OPTION_MASK GENMASK(9, 8)
133−#define CTRL_NEG BIT(4)
133+#define CTRL_NEG BIT(4)
134134 #define CTRL_INV_PXCK BIT(3)
135135 #define CTRL_INV_DE BIT(2)
136136 #define CTRL_INV_VS BIT(1)
@@ -138,9 +138,9 @@ · 1 unmodified line
138138
139139 #define DISP_PARA_DISP_ON BIT(31)
140140 #define DISP_PARA_SWAP_EN BIT(30)
141−#define DISP_PARA_LINE_PATTERN_UYVY_H (GENMASK(29, 28) | BIT(26))
142−#define DISP_PARA_LINE_PATTERN_RGB565 GENMASK(28, 26)
143−#define DISP_PARA_LINE_PATTERN_RGB888 0
141+#define DISP_PARA_LINE_PATTERN_UYVY_H (0xd << 26)
142+#define DISP_PARA_LINE_PATTERN_RGB565 (0x7 << 26)
143+#define DISP_PARA_LINE_PATTERN_RGB888 (0x0 << 26)
144144 #define DISP_PARA_LINE_PATTERN_MASK GENMASK(29, 26)
145145 #define DISP_PARA_DISP_MODE_MASK GENMASK(25, 24)
146146 #define DISP_PARA_BGND_R_MASK GENMASK(23, 16)
@@ -186,7 +186,7 @@ · 39 unmodified lines
186186 #define INT_ENABLE_D1_PLANE_PANIC_EN BIT(0)
187187
188188 #define CTRLDESCL0_1_HEIGHT(n) (((n) & 0xffff) << 16)
189−#define CTRLDESCL0_1_HEIGHT_MASK GENMASK(31, 16)
189+#define CTRLDESCL0_1_HEIGHT_MASK GENMASK(31, 16)
190190 #define CTRLDESCL0_1_WIDTH(n) ((n) & 0xffff)
191191 #define CTRLDESCL0_1_WIDTH_MASK GENMASK(15, 0)
192192
@@ -198,21 +198,24 @@ · 5 unmodified lines
198198
199199 #define CTRLDESCL0_5_EN BIT(31)
200200 #define CTRLDESCL0_5_SHADOW_LOAD_EN BIT(30)
201−#define CTRLDESCL0_5_BPP_16_RGB565 BIT(26)
202−#define CTRLDESCL0_5_BPP_16_ARGB1555 (BIT(26) | BIT(24))
203−#define CTRLDESCL0_5_BPP_16_ARGB4444 (BIT(26) | BIT(25))
204−#define CTRLDESCL0_5_BPP_YCbCr422 (BIT(26) | BIT(25) | BIT(24))
205−#define CTRLDESCL0_5_BPP_24_RGB888 BIT(27)
206−#define CTRLDESCL0_5_BPP_32_ARGB8888 (BIT(27) | BIT(24))
207−#define CTRLDESCL0_5_BPP_32_ABGR8888 (BIT(27) | BIT(25))
201+#define CTRLDESCL0_5_BPP_16_RGB565 (0x4 << 24)
202+#define CTRLDESCL0_5_BPP_16_ARGB1555 (0x5 << 24)
203+#define CTRLDESCL0_5_BPP_16_ARGB4444 (0x6 << 24)
204+#define CTRLDESCL0_5_BPP_YCbCr422 (0x7 << 24)
205+#define CTRLDESCL0_5_BPP_24_RGB888 (0x8 << 24)
206+#define CTRLDESCL0_5_BPP_32_ARGB8888 (0x9 << 24)
207+#define CTRLDESCL0_5_BPP_32_ABGR8888 (0xa << 24)
208208 #define CTRLDESCL0_5_BPP_MASK GENMASK(27, 24)
209−#define CTRLDESCL0_5_YUV_FORMAT_Y2VY1U 0
210−#define CTRLDESCL0_5_YUV_FORMAT_Y2UY1V BIT(14)
211−#define CTRLDESCL0_5_YUV_FORMAT_VY2UY1 BIT(15)
212−#define CTRLDESCL0_5_YUV_FORMAT_UY2VY1 (BIT(15) | BIT(14))
209+#define CTRLDESCL0_5_YUV_FORMAT_Y2VY1U (0x0 << 14)
210+#define CTRLDESCL0_5_YUV_FORMAT_Y2UY1V (0x1 << 14)
211+#define CTRLDESCL0_5_YUV_FORMAT_VY2UY1 (0x2 << 14)
212+#define CTRLDESCL0_5_YUV_FORMAT_UY2VY1 (0x3 << 14)
213213 #define CTRLDESCL0_5_YUV_FORMAT_MASK GENMASK(15, 14)
214214
215−#define CSC0_CTRL_CSC_MODE_RGB2YCbCr GENMASK(2, 1)
215+#define CSC0_CTRL_CSC_MODE_YUV2RGB (0x0 << 1)
216+#define CSC0_CTRL_CSC_MODE_YCbCr2RGB (0x1 << 1)
217+#define CSC0_CTRL_CSC_MODE_RGB2YUV (0x2 << 1)
218+#define CSC0_CTRL_CSC_MODE_RGB2YCbCr (0x3 << 1)
216219 #define CSC0_CTRL_CSC_MODE_MASK GENMASK(2, 1)
217220 #define CSC0_CTRL_BYPASS BIT(0)
218221
drivers/gpu/drm/nouveau/dispnv50/disp.c+2−2
@@ -131,7 +131,7 @@ nv50_dmac_kick(struct nvif_push *push) · 130 unmodified lines
131131 {
132132 struct nv50_dmac *dmac = container_of(push, typeof(*dmac), _push);
133133
134− dmac->cur = push->cur - (u32 *)dmac->_push.mem.object.map.ptr;
134+ dmac->cur = push->cur - (u32 __iomem *)dmac->_push.mem.object.map.ptr;
135135 if (dmac->put != dmac->cur) {
136136 /* Push buffer fetches are not coherent with BAR1, we need to ensure
137137 * writes have been flushed right through to VRAM before writing PUT.
@@ -194,7 +194,7 @@ nv50_dmac_wait(struct nvif_push *push, u32 size) · 56 unmodified lines
194194 if (WARN_ON(size > dmac->max))
195195 return -EINVAL;
196196
197− dmac->cur = push->cur - (u32 *)dmac->_push.mem.object.map.ptr;
197+ dmac->cur = push->cur - (u32 __iomem *)dmac->_push.mem.object.map.ptr;
198198 if (dmac->cur + size >= dmac->max) {
199199 int ret = nv50_dmac_wind(dmac);
200200 if (ret)
drivers/gpu/drm/nouveau/nouveau_display.c+0−1
@@ -672,7 +672,6 @@ nouveau_display_create(struct drm_device *dev) · 671 unmodified lines
672672 drm_mode_create_dvi_i_properties(dev);
673673
674674 dev->mode_config.funcs = &nouveau_mode_config_funcs;
675− dev->mode_config.fb_base = device->func->resource_addr(device, 1);
676675
677676 dev->mode_config.min_width = 0;
678677 dev->mode_config.min_height = 0;
drivers/gpu/drm/nouveau/nv04_fbcon.c+4−2
@@ -137,6 +137,8 @@ nv04_fbcon_accel_init(struct fb_info *info) · 136 unmodified lines
137137 struct nouveau_channel *chan = drm->channel;
138138 struct nvif_device *device = &drm->client.device;
139139 struct nvif_push *push = chan->chan.push;
140+ struct nvkm_device *nvkm_device = nvxx_device(&drm->client.device);
141+ resource_size_t fb_base = nvkm_device->func->resource_addr(nvkm_device, 1);
140142 int surface_fmt, pattern_fmt, rect_fmt;
141143 int ret;
142144
@@ -210,8 +212,8 @@ nv04_fbcon_accel_init(struct fb_info *info) · 67 unmodified lines
210212 0x0188, chan->vram.handle);
211213 PUSH_NVSQ(push, NV042, 0x0300, surface_fmt,
212214 0x0304, info->fix.line_length | (info->fix.line_length << 16),
213− 0x0308, info->fix.smem_start - dev->mode_config.fb_base,
214− 0x030c, info->fix.smem_start - dev->mode_config.fb_base);
215+ 0x0308, info->fix.smem_start - fb_base,
216+ 0x030c, info->fix.smem_start - fb_base);
215217
216218 PUSH_NVSQ(push, NV043, 0x0000, nfbdev->rop.handle);
217219 PUSH_NVSQ(push, NV043, 0x0300, 0x55);
drivers/gpu/drm/omapdrm/omap_fbdev.c+0−2
@@ -177,8 +177,6 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, · 176 unmodified lines
177177
178178 drm_fb_helper_fill_info(fbi, helper, sizes);
179179
180− dev->mode_config.fb_base = dma_addr;
181−
182180 fbi->screen_buffer = omap_gem_vaddr(fbdev->bo);
183181 fbi->screen_size = fbdev->bo->size;
184182 fbi->fix.smem_start = dma_addr;
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c+2−2
@@ -125,7 +125,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, · 124 unmodified lines
125125
126126 get_dma_buf(dma_buf);
127127
128− sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE);
128+ sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
129129 if (IS_ERR(sgt)) {
130130 ret = PTR_ERR(sgt);
131131 goto fail_detach;
@@ -142,7 +142,7 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, · 10 unmodified lines
142142 return obj;
143143
144144 fail_unmap:
145− dma_buf_unmap_attachment(attach, sgt, DMA_TO_DEVICE);
145+ dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_TO_DEVICE);
146146 fail_detach:
147147 dma_buf_detach(dma_buf, attach);
148148 dma_buf_put(dma_buf);
drivers/gpu/drm/panel/panel-samsung-db7430.c+7−0
@@ -331,9 +331,16 @@ static const struct of_device_id db7430_match[] = { · 330 unmodified lines
331331 };
332332 MODULE_DEVICE_TABLE(of, db7430_match);
333333
334+static const struct spi_device_id db7430_ids[] = {
335+ { "lms397kf04" },
336+ { },
337+};
338+MODULE_DEVICE_TABLE(spi, db7430_ids);
339+
334340 static struct spi_driver db7430_driver = {
335341 .probe = db7430_probe,
336342 .remove = db7430_remove,
343+ .id_table = db7430_ids,
337344 .driver = {
338345 .name = "db7430-panel",
339346 .of_match_table = db7430_match,
drivers/gpu/drm/panel/panel-tpo-tpg110.c+7−0
@@ -463,9 +463,16 @@ static const struct of_device_id tpg110_match[] = { · 462 unmodified lines
463463 };
464464 MODULE_DEVICE_TABLE(of, tpg110_match);
465465
466+static const struct spi_device_id tpg110_ids[] = {
467+ { "tpg110" },
468+ { },
469+};
470+MODULE_DEVICE_TABLE(spi, tpg110_ids);
471+
466472 static struct spi_driver tpg110_driver = {
467473 .probe = tpg110_probe,
468474 .remove = tpg110_remove,
475+ .id_table = tpg110_ids,
469476 .driver = {
470477 .name = "tpo-tpg110-panel",
471478 .of_match_table = tpg110_match,
drivers/gpu/drm/panel/panel-widechips-ws2401.c+7−0
@@ -425,9 +425,16 @@ static const struct of_device_id ws2401_match[] = { · 424 unmodified lines
425425 };
426426 MODULE_DEVICE_TABLE(of, ws2401_match);
427427
428+static const struct spi_device_id ws2401_ids[] = {
429+ { "lms380kf01" },
430+ { },
431+};
432+MODULE_DEVICE_TABLE(spi, ws2401_ids);
433+
428434 static struct spi_driver ws2401_driver = {
429435 .probe = ws2401_probe,
430436 .remove = ws2401_remove,
437+ .id_table = ws2401_ids,
431438 .driver = {
432439 .name = "ws2401-panel",
433440 .of_match_table = ws2401_match,
drivers/gpu/drm/panfrost/panfrost_dump.c+2−2
@@ -209,7 +209,7 @@ void panfrost_core_dump(struct panfrost_job *job) · 208 unmodified lines
209209 goto dump_header;
210210 }
211211
212− ret = drm_gem_shmem_vmap(&bo->base, &map);
212+ ret = drm_gem_vmap_unlocked(&bo->base.base, &map);
213213 if (ret) {
214214 dev_err(pfdev->dev, "Panfrost Dump: couldn't map Buffer Object\n");
215215 iter.hdr->bomap.valid = 0;
@@ -236,7 +236,7 @@ void panfrost_core_dump(struct panfrost_job *job) · 20 unmodified lines
236236 vaddr = map.vaddr;
237237 memcpy(iter.data, vaddr, bo->base.base.size);
238238
239− drm_gem_shmem_vunmap(&bo->base, &map);
239+ drm_gem_vunmap_unlocked(&bo->base.base, &map);
240240
241241 iter.hdr->bomap.valid = 1;
242242
drivers/gpu/drm/panfrost/panfrost_perfcnt.c+3−3
@@ -106,7 +106,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, · 105 unmodified lines
106106 goto err_close_bo;
107107 }
108108
109− ret = drm_gem_shmem_vmap(bo, &map);
109+ ret = drm_gem_vmap_unlocked(&bo->base, &map);
110110 if (ret)
111111 goto err_put_mapping;
112112 perfcnt->buf = map.vaddr;
@@ -165,7 +165,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, · 52 unmodified lines
165165 return 0;
166166
167167 err_vunmap:
168− drm_gem_shmem_vunmap(bo, &map);
168+ drm_gem_vunmap_unlocked(&bo->base, &map);
169169 err_put_mapping:
170170 panfrost_gem_mapping_put(perfcnt->mapping);
171171 err_close_bo:
@@ -195,7 +195,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, · 23 unmodified lines
195195 GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF));
196196
197197 perfcnt->user = NULL;
198− drm_gem_shmem_vunmap(&perfcnt->mapping->obj->base, &map);
198+ drm_gem_vunmap_unlocked(&perfcnt->mapping->obj->base.base, &map);
199199 perfcnt->buf = NULL;
200200 panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv);
201201 panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu);
drivers/gpu/drm/qxl/qxl_display.c+0−2
@@ -1261,8 +1261,6 @@ int qxl_modeset_init(struct qxl_device *qdev) · 1260 unmodified lines
12611261 qdev->ddev.mode_config.max_width = 8192;
12621262 qdev->ddev.mode_config.max_height = 8192;
12631263
1264− qdev->ddev.mode_config.fb_base = qdev->vram_base;
1265−
12661264 drm_mode_create_suggested_offset_properties(&qdev->ddev);
12671265 qxl_mode_create_hotplug_mode_update_property(qdev);
12681266
drivers/gpu/drm/qxl/qxl_object.c+9−8
@@ -168,9 +168,16 @@ int qxl_bo_vmap_locked(struct qxl_bo *bo, struct iosys_map *map) · 167 unmodified lines
168168 bo->map_count++;
169169 goto out;
170170 }
171− r = ttm_bo_vmap(&bo->tbo, &bo->map);
171+
172+ r = __qxl_bo_pin(bo);
172173 if (r)
173174 return r;
175+
176+ r = ttm_bo_vmap(&bo->tbo, &bo->map);
177+ if (r) {
178+ __qxl_bo_unpin(bo);
179+ return r;
180+ }
174181 bo->map_count = 1;
175182
176183 /* TODO: Remove kptr in favor of map everywhere. */
@@ -192,12 +199,6 @@ int qxl_bo_vmap(struct qxl_bo *bo, struct iosys_map *map) · 15 unmodified lines
192199 if (r)
193200 return r;
194201
195− r = __qxl_bo_pin(bo);
196− if (r) {
197− qxl_bo_unreserve(bo);
198− return r;
199− }
200−
201202 r = qxl_bo_vmap_locked(bo, map);
202203 qxl_bo_unreserve(bo);
203204 return r;
@@ -247,6 +248,7 @@ void qxl_bo_vunmap_locked(struct qxl_bo *bo) · 43 unmodified lines
247248 return;
248249 bo->kptr = NULL;
249250 ttm_bo_vunmap(&bo->tbo, &bo->map);
251+ __qxl_bo_unpin(bo);
250252 }
251253
252254 int qxl_bo_vunmap(struct qxl_bo *bo)
@@ -258,7 +260,6 @@ int qxl_bo_vunmap(struct qxl_bo *bo) · 5 unmodified lines
258260 return r;
259261
260262 qxl_bo_vunmap_locked(bo);
261− __qxl_bo_unpin(bo);
262263 qxl_bo_unreserve(bo);
263264 return 0;
264265 }
drivers/gpu/drm/qxl/qxl_prime.c+2−2
@@ -59,7 +59,7 @@ int qxl_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) · 58 unmodified lines
5959 struct qxl_bo *bo = gem_to_qxl_bo(obj);
6060 int ret;
6161
62− ret = qxl_bo_vmap(bo, map);
62+ ret = qxl_bo_vmap_locked(bo, map);
6363 if (ret < 0)
6464 return ret;
6565
@@ -71,5 +71,5 @@ void qxl_gem_prime_vunmap(struct drm_gem_object *obj, · 5 unmodified lines
7171 {
7272 struct qxl_bo *bo = gem_to_qxl_bo(obj);
7373
74− qxl_bo_vunmap(bo);
74+ qxl_bo_vunmap_locked(bo);
7575 }
drivers/gpu/drm/radeon/radeon_display.c+0−2
@@ -1604,8 +1604,6 @@ int radeon_modeset_init(struct radeon_device *rdev) · 1603 unmodified lines
16041604
16051605 rdev->ddev->mode_config.fb_modifiers_not_supported = true;
16061606
1607− rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
1608−
16091607 ret = radeon_modeset_create_props(rdev);
16101608 if (ret) {
16111609 return ret;
drivers/gpu/drm/radeon/radeon_fb.c+1−1
@@ -276,7 +276,7 @@ static int radeonfb_create(struct drm_fb_helper *helper, · 275 unmodified lines
276276 drm_fb_helper_fill_info(info, &rfbdev->helper, sizes);
277277
278278 /* setup aperture base/size for vesafb takeover */
279− info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
279+ info->apertures->ranges[0].base = rdev->mc.aper_base;
280280 info->apertures->ranges[0].size = rdev->mc.aper_size;
281281
282282 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
drivers/gpu/drm/scheduler/sched_entity.c+25−1
@@ -73,6 +73,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity, · 72 unmodified lines
7373 entity->priority = priority;
7474 entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
7575 entity->last_scheduled = NULL;
76+ RB_CLEAR_NODE(&entity->rb_tree_node);
7677
7778 if(num_sched_list)
7879 entity->rq = &sched_list[0]->sched_rq[entity->priority];
@@ -207,6 +208,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, · 128 unmodified lines
207208 struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
208209 finish_cb);
209210
211+ dma_fence_put(f);
210212 INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
211213 schedule_work(&job->work);
212214 }
@@ -234,8 +236,10 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity) · 21 unmodified lines
234236 struct drm_sched_fence *s_fence = job->s_fence;
235237
236238 /* Wait for all dependencies to avoid data corruptions */
237− while ((f = drm_sched_job_dependency(job, entity)))
239+ while ((f = drm_sched_job_dependency(job, entity))) {
238240 dma_fence_wait(f, false);
241+ dma_fence_put(f);
242+ }
239243
240244 drm_sched_fence_scheduled(s_fence);
241245 dma_fence_set_error(&s_fence->finished, -ESRCH);
@@ -250,6 +254,7 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity) · 8 unmodified lines
250254 continue;
251255 }
252256
257+ dma_fence_get(entity->last_scheduled);
253258 r = dma_fence_add_callback(entity->last_scheduled,
254259 &job->finish_cb,
255260 drm_sched_entity_kill_jobs_cb);
@@ -444,6 +449,19 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity) · 188 unmodified lines
444449 smp_wmb();
445450
446451 spsc_queue_pop(&entity->job_queue);
452+
453+ /*
454+ * Update the entity's location in the min heap according to
455+ * the timestamp of the next job, if any.
456+ */
457+ if (drm_sched_policy == DRM_SCHED_POLICY_FIFO) {
458+ struct drm_sched_job *next;
459+
460+ next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
461+ if (next)
462+ drm_sched_rq_update_fifo(entity, next->submit_ts);
463+ }
464+
447465 return sched_job;
448466 }
449467
@@ -508,6 +526,7 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) · 58 unmodified lines
508526 atomic_inc(entity->rq->sched->score);
509527 WRITE_ONCE(entity->last_user, current->group_leader);
510528 first = spsc_queue_push(&entity->job_queue, &sched_job->queue_node);
529+ sched_job->submit_ts = ktime_get();
511530
512531 /* first job wakes up scheduler */
513532 if (first) {
@@ -519,8 +538,13 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job) · 5 unmodified lines
519538 DRM_ERROR("Trying to push to a killed entity\n");
520539 return;
521540 }
541+
522542 drm_sched_rq_add_entity(entity->rq, entity);
523543 spin_unlock(&entity->rq_lock);
544+
545+ if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
546+ drm_sched_rq_update_fifo(entity, sched_job->submit_ts);
547+
524548 drm_sched_wakeup(entity->rq->sched);
525549 }
526550 }
drivers/gpu/drm/scheduler/sched_main.c+93−3
@@ -62,6 +62,55 @@ · 61 unmodified lines
6262 #define to_drm_sched_job(sched_job) \
6363 container_of((sched_job), struct drm_sched_job, queue_node)
6464
65+int drm_sched_policy = DRM_SCHED_POLICY_RR;
66+
67+/**
68+ * DOC: sched_policy (int)
69+ * Used to override default entities scheduling policy in a run queue.
70+ */
71+MODULE_PARM_DESC(sched_policy, "Specify schedule policy for entities on a runqueue, " __stringify(DRM_SCHED_POLICY_RR) " = Round Robin (default), " __stringify(DRM_SCHED_POLICY_FIFO) " = use FIFO.");
72+module_param_named(sched_policy, drm_sched_policy, int, 0444);
73+
74+static __always_inline bool drm_sched_entity_compare_before(struct rb_node *a,
75+ const struct rb_node *b)
76+{
77+ struct drm_sched_entity *ent_a = rb_entry((a), struct drm_sched_entity, rb_tree_node);
78+ struct drm_sched_entity *ent_b = rb_entry((b), struct drm_sched_entity, rb_tree_node);
79+
80+ return ktime_before(ent_a->oldest_job_waiting, ent_b->oldest_job_waiting);
81+}
82+
83+static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *entity)
84+{
85+ struct drm_sched_rq *rq = entity->rq;
86+
87+ if (!RB_EMPTY_NODE(&entity->rb_tree_node)) {
88+ rb_erase_cached(&entity->rb_tree_node, &rq->rb_tree_root);
89+ RB_CLEAR_NODE(&entity->rb_tree_node);
90+ }
91+}
92+
93+void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts)
94+{
95+ /*
96+ * Both locks need to be grabbed, one to protect from entity->rq change
97+ * for entity from within concurrent drm_sched_entity_select_rq and the
98+ * other to update the rb tree structure.
99+ */
100+ spin_lock(&entity->rq_lock);
101+ spin_lock(&entity->rq->lock);
102+
103+ drm_sched_rq_remove_fifo_locked(entity);
104+
105+ entity->oldest_job_waiting = ts;
106+
107+ rb_add_cached(&entity->rb_tree_node, &entity->rq->rb_tree_root,
108+ drm_sched_entity_compare_before);
109+
110+ spin_unlock(&entity->rq->lock);
111+ spin_unlock(&entity->rq_lock);
112+}
113+
65114 /**
66115 * drm_sched_rq_init - initialize a given run queue struct
67116 *
@@ -75,6 +124,7 @@ static void drm_sched_rq_init(struct drm_gpu_scheduler *sched, · 7 unmodified lines
75124 {
76125 spin_lock_init(&rq->lock);
77126 INIT_LIST_HEAD(&rq->entities);
127+ rq->rb_tree_root = RB_ROOT_CACHED;
78128 rq->current_entity = NULL;
79129 rq->sched = sched;
80130 }
@@ -92,9 +142,12 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq, · 11 unmodified lines
92142 {
93143 if (!list_empty(&entity->list))
94144 return;
145+
95146 spin_lock(&rq->lock);
147+
96148 atomic_inc(rq->sched->score);
97149 list_add_tail(&entity->list, &rq->entities);
150+
98151 spin_unlock(&rq->lock);
99152 }
100153
@@ -111,23 +164,30 @@ void drm_sched_rq_remove_entity(struct drm_sched_rq *rq, · 10 unmodified lines
111164 {
112165 if (list_empty(&entity->list))
113166 return;
167+
114168 spin_lock(&rq->lock);
169+
115170 atomic_dec(rq->sched->score);
116171 list_del_init(&entity->list);
172+
117173 if (rq->current_entity == entity)
118174 rq->current_entity = NULL;
175+
176+ if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
177+ drm_sched_rq_remove_fifo_locked(entity);
178+
119179 spin_unlock(&rq->lock);
120180 }
121181
122182 /**
123− * drm_sched_rq_select_entity - Select an entity which could provide a job to run
183+ * drm_sched_rq_select_entity_rr - Select an entity which could provide a job to run
124184 *
125185 * @rq: scheduler run queue to check.
126186 *
127187 * Try to find a ready entity, returns NULL if none found.
128188 */
129189 static struct drm_sched_entity *
130−drm_sched_rq_select_entity(struct drm_sched_rq *rq)
190+drm_sched_rq_select_entity_rr(struct drm_sched_rq *rq)
131191 {
132192 struct drm_sched_entity *entity;
133193
@@ -163,6 +223,34 @@ drm_sched_rq_select_entity(struct drm_sched_rq *rq) · 29 unmodified lines
163223 return NULL;
164224 }
165225
226+/**
227+ * drm_sched_rq_select_entity_fifo - Select an entity which provides a job to run
228+ *
229+ * @rq: scheduler run queue to check.
230+ *
231+ * Find oldest waiting ready entity, returns NULL if none found.
232+ */
233+static struct drm_sched_entity *
234+drm_sched_rq_select_entity_fifo(struct drm_sched_rq *rq)
235+{
236+ struct rb_node *rb;
237+
238+ spin_lock(&rq->lock);
239+ for (rb = rb_first_cached(&rq->rb_tree_root); rb; rb = rb_next(rb)) {
240+ struct drm_sched_entity *entity;
241+
242+ entity = rb_entry(rb, struct drm_sched_entity, rb_tree_node);
243+ if (drm_sched_entity_is_ready(entity)) {
244+ rq->current_entity = entity;
245+ reinit_completion(&entity->entity_idle);
246+ break;
247+ }
248+ }
249+ spin_unlock(&rq->lock);
250+
251+ return rb ? rb_entry(rb, struct drm_sched_entity, rb_tree_node) : NULL;
252+}
253+
166254 /**
167255 * drm_sched_job_done - complete a job
168256 * @s_job: pointer to the job which is done
@@ -803,7 +891,9 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched) · 634 unmodified lines
803891
804892 /* Kernel run queue has higher priority than normal run queue*/
805893 for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
806− entity = drm_sched_rq_select_entity(&sched->sched_rq[i]);
894+ entity = drm_sched_policy == DRM_SCHED_POLICY_FIFO ?
895+ drm_sched_rq_select_entity_fifo(&sched->sched_rq[i]) :
896+ drm_sched_rq_select_entity_rr(&sched->sched_rq[i]);
807897 if (entity)
808898 break;
809899 }
drivers/gpu/drm/solomon/ssd130x.c+13−22
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020
2121 #include <drm/drm_atomic.h>
2222 #include <drm/drm_atomic_helper.h>
23+#include <drm/drm_crtc_helper.h>
2324 #include <drm/drm_damage_helper.h>
2425 #include <drm/drm_edid.h>
2526 #include <drm/drm_fb_helper.h>
@@ -578,21 +579,24 @@ static void ssd130x_primary_plane_helper_atomic_update(struct drm_plane *plane, · 552 unmodified lines
578579 struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
579580 struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
580581 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
582+ struct drm_atomic_helper_damage_iter iter;
581583 struct drm_device *drm = plane->dev;
582− struct drm_rect src_clip, dst_clip;
584+ struct drm_rect dst_clip;
585+ struct drm_rect damage;
583586 int idx;
584587
585− if (!drm_atomic_helper_damage_merged(old_plane_state, plane_state, &src_clip))
588+ if (!drm_dev_enter(drm, &idx))
586589 return;
587590
588− dst_clip = plane_state->dst;
589− if (!drm_rect_intersect(&dst_clip, &src_clip))
590− return;
591+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
592+ drm_atomic_for_each_plane_damage(&iter, &damage) {
593+ dst_clip = plane_state->dst;
591594
592− if (!drm_dev_enter(drm, &idx))
593− return;
595+ if (!drm_rect_intersect(&dst_clip, &damage))
596+ continue;
594597
595− ssd130x_fb_blit_rect(plane_state->fb, &shadow_plane_state->data[0], &dst_clip);
598+ ssd130x_fb_blit_rect(plane_state->fb, &shadow_plane_state->data[0], &dst_clip);
599+ }
596600
597601 drm_dev_exit(idx);
598602 }
@@ -642,19 +646,6 @@ static enum drm_mode_status ssd130x_crtc_helper_mode_valid(struct drm_crtc *crtc · 43 unmodified lines
642646 return MODE_OK;
643647 }
644648
645−static int ssd130x_crtc_helper_atomic_check(struct drm_crtc *crtc,
646− struct drm_atomic_state *new_state)
647−{
648− struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc);
649− int ret;
650−
651− ret = drm_atomic_helper_check_crtc_state(new_crtc_state, false);
652− if (ret)
653− return ret;
654−
655− return drm_atomic_add_affected_planes(new_state, crtc);
656−}
657−
658649 /*
659650 * The CRTC is always enabled. Screen updates are performed by
660651 * the primary plane's atomic_update function. Disabling clears
@@ -662,7 +653,7 @@ static int ssd130x_crtc_helper_atomic_check(struct drm_crtc *crtc, · 1 unmodified line
662653 */
663654 static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = {
664655 .mode_valid = ssd130x_crtc_helper_mode_valid,
665− .atomic_check = ssd130x_crtc_helper_atomic_check,
656+ .atomic_check = drm_crtc_helper_atomic_check,
666657 };
667658
668659 static void ssd130x_crtc_reset(struct drm_crtc *crtc)
drivers/gpu/drm/tegra/fb.c+0−1
@@ -280,7 +280,6 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, · 279 unmodified lines
280280 }
281281 }
282282
283− drm->mode_config.fb_base = (resource_size_t)bo->iova;
284283 info->screen_base = (void __iomem *)bo->vaddr + offset;
285284 info->screen_size = size;
286285 info->fix.smem_start = (unsigned long)(bo->iova + offset);
drivers/gpu/drm/tegra/gem.c+9−8
@@ -84,7 +84,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ · 83 unmodified lines
8484 goto free;
8585 }
8686
87− map->sgt = dma_buf_map_attachment(map->attach, direction);
87+ map->sgt = dma_buf_map_attachment_unlocked(map->attach, direction);
8888 if (IS_ERR(map->sgt)) {
8989 dma_buf_detach(buf, map->attach);
9090 err = PTR_ERR(map->sgt);
@@ -160,7 +160,8 @@ free: · 69 unmodified lines
160160 static void tegra_bo_unpin(struct host1x_bo_mapping *map)
161161 {
162162 if (map->attach) {
163− dma_buf_unmap_attachment(map->attach, map->sgt, map->direction);
163+ dma_buf_unmap_attachment_unlocked(map->attach, map->sgt,
164+ map->direction);
164165 dma_buf_detach(map->attach->dmabuf, map->attach);
165166 } else {
166167 dma_unmap_sgtable(map->dev, map->sgt, map->direction, 0);
@@ -181,7 +182,7 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) · 14 unmodified lines
181182 if (obj->vaddr) {
182183 return obj->vaddr;
183184 } else if (obj->gem.import_attach) {
184− ret = dma_buf_vmap(obj->gem.import_attach->dmabuf, &map);
185+ ret = dma_buf_vmap_unlocked(obj->gem.import_attach->dmabuf, &map);
185186 return ret ? NULL : map.vaddr;
186187 } else {
187188 return vmap(obj->pages, obj->num_pages, VM_MAP,
@@ -197,7 +198,7 @@ static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) · 9 unmodified lines
197198 if (obj->vaddr)
198199 return;
199200 else if (obj->gem.import_attach)
200− dma_buf_vunmap(obj->gem.import_attach->dmabuf, &map);
201+ dma_buf_vunmap_unlocked(obj->gem.import_attach->dmabuf, &map);
201202 else
202203 vunmap(addr);
203204 }
@@ -461,7 +462,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, · 257 unmodified lines
461462
462463 get_dma_buf(buf);
463464
464− bo->sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE);
465+ bo->sgt = dma_buf_map_attachment_unlocked(attach, DMA_TO_DEVICE);
465466 if (IS_ERR(bo->sgt)) {
466467 err = PTR_ERR(bo->sgt);
467468 goto detach;
@@ -479,7 +480,7 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, · 11 unmodified lines
479480
480481 detach:
481482 if (!IS_ERR_OR_NULL(bo->sgt))
482− dma_buf_unmap_attachment(attach, bo->sgt, DMA_TO_DEVICE);
483+ dma_buf_unmap_attachment_unlocked(attach, bo->sgt, DMA_TO_DEVICE);
483484
484485 dma_buf_detach(buf, attach);
485486 dma_buf_put(buf);
@@ -508,8 +509,8 @@ void tegra_bo_free_object(struct drm_gem_object *gem) · 22 unmodified lines
508509 tegra_bo_iommu_unmap(tegra, bo);
509510
510511 if (gem->import_attach) {
511− dma_buf_unmap_attachment(gem->import_attach, bo->sgt,
512− DMA_TO_DEVICE);
512+ dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt,
513+ DMA_TO_DEVICE);
513514 drm_prime_gem_destroy(gem, NULL);
514515 } else {
515516 tegra_bo_free(gem->dev, bo);
drivers/gpu/drm/tests/Makefile+11−3
@@ -1,5 +1,13 @@
11 # SPDX-License-Identifier: GPL-2.0
22
3−obj-$(CONFIG_DRM_KUNIT_TEST) += drm_format_helper_test.o drm_damage_helper_test.o \
4− drm_cmdline_parser_test.o drm_rect_test.o drm_format_test.o drm_plane_helper_test.o \
5− drm_dp_mst_helper_test.o drm_framebuffer_test.o drm_buddy_test.o drm_mm_test.o
3+obj-$(CONFIG_DRM_KUNIT_TEST) += \
4+ drm_buddy_test.o \
5+ drm_cmdline_parser_test.o \
6+ drm_damage_helper_test.o \
7+ drm_dp_mst_helper_test.o \
8+ drm_format_helper_test.o \
9+ drm_format_test.o \
10+ drm_framebuffer_test.o \
11+ drm_mm_test.o \
12+ drm_plane_helper_test.o \
13+ drm_rect_test.o
drivers/gpu/drm/tests/drm_dp_mst_helper_test.c+295−150
@@ -5,44 +5,280 @@ · 4 unmodified lines
55 * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net>
66 */
77
8−#define PREFIX_STR "[drm_dp_mst_helper]"
9−
108 #include <kunit/test.h>
119
12−#include <linux/random.h>
13−
1410 #include <drm/display/drm_dp_mst_helper.h>
1511 #include <drm/drm_print.h>
1612
1713 #include "../display/drm_dp_mst_topology_internal.h"
1814
15+struct drm_dp_mst_calc_pbn_mode_test {
16+ const int clock;
17+ const int bpp;
18+ const bool dsc;
19+ const int expected;
20+};
21+
22+static const struct drm_dp_mst_calc_pbn_mode_test drm_dp_mst_calc_pbn_mode_cases[] = {
23+ {
24+ .clock = 154000,
25+ .bpp = 30,
26+ .dsc = false,
27+ .expected = 689
28+ },
29+ {
30+ .clock = 234000,
31+ .bpp = 30,
32+ .dsc = false,
33+ .expected = 1047
34+ },
35+ {
36+ .clock = 297000,
37+ .bpp = 24,
38+ .dsc = false,
39+ .expected = 1063
40+ },
41+ {
42+ .clock = 332880,
43+ .bpp = 24,
44+ .dsc = true,
45+ .expected = 50
46+ },
47+ {
48+ .clock = 324540,
49+ .bpp = 24,
50+ .dsc = true,
51+ .expected = 49
52+ },
53+};
54+
1955 static void drm_test_dp_mst_calc_pbn_mode(struct kunit *test)
2056 {
21− int pbn, i;
22− const struct {
23− int rate;
24− int bpp;
25− int expected;
26− bool dsc;
27− } test_params[] = {
28− { 154000, 30, 689, false },
29− { 234000, 30, 1047, false },
30− { 297000, 24, 1063, false },
31− { 332880, 24, 50, true },
32− { 324540, 24, 49, true },
33− };
57+ const struct drm_dp_mst_calc_pbn_mode_test *params = test->param_value;
3458
35− for (i = 0; i < ARRAY_SIZE(test_params); i++) {
36− pbn = drm_dp_calc_pbn_mode(test_params[i].rate,
37− test_params[i].bpp,
38− test_params[i].dsc);
39− KUNIT_EXPECT_EQ_MSG(test, pbn, test_params[i].expected,
40− "Expected PBN %d for clock %d bpp %d, got %d\n",
41− test_params[i].expected, test_params[i].rate,
42− test_params[i].bpp, pbn);
43− }
59+ KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp, params->dsc),
60+ params->expected);
4461 }
4562
63+static void dp_mst_calc_pbn_mode_desc(const struct drm_dp_mst_calc_pbn_mode_test *t, char *desc)
64+{
65+ sprintf(desc, "Clock %d BPP %d DSC %s", t->clock, t->bpp, t->dsc ? "enabled" : "disabled");
66+}
67+
68+KUNIT_ARRAY_PARAM(drm_dp_mst_calc_pbn_mode, drm_dp_mst_calc_pbn_mode_cases,
69+ dp_mst_calc_pbn_mode_desc);
70+
71+static u8 data[] = { 0xff, 0x00, 0xdd };
72+
73+struct drm_dp_mst_sideband_msg_req_test {
74+ const char *desc;
75+ const struct drm_dp_sideband_msg_req_body in;
76+};
77+
78+static const struct drm_dp_mst_sideband_msg_req_test drm_dp_mst_sideband_msg_req_cases[] = {
79+ {
80+ .desc = "DP_ENUM_PATH_RESOURCES with port number",
81+ .in = {
82+ .req_type = DP_ENUM_PATH_RESOURCES,
83+ .u.port_num.port_number = 5,
84+ },
85+ },
86+ {
87+ .desc = "DP_POWER_UP_PHY with port number",
88+ .in = {
89+ .req_type = DP_POWER_UP_PHY,
90+ .u.port_num.port_number = 5,
91+ },
92+ },
93+ {
94+ .desc = "DP_POWER_DOWN_PHY with port number",
95+ .in = {
96+ .req_type = DP_POWER_DOWN_PHY,
97+ .u.port_num.port_number = 5,
98+ },
99+ },
100+ {
101+ .desc = "DP_ALLOCATE_PAYLOAD with SDP stream sinks",
102+ .in = {
103+ .req_type = DP_ALLOCATE_PAYLOAD,
104+ .u.allocate_payload.number_sdp_streams = 3,
105+ .u.allocate_payload.sdp_stream_sink = { 1, 2, 3 },
106+ },
107+ },
108+ {
109+ .desc = "DP_ALLOCATE_PAYLOAD with port number",
110+ .in = {
111+ .req_type = DP_ALLOCATE_PAYLOAD,
112+ .u.allocate_payload.port_number = 0xf,
113+ },
114+ },
115+ {
116+ .desc = "DP_ALLOCATE_PAYLOAD with VCPI",
117+ .in = {
118+ .req_type = DP_ALLOCATE_PAYLOAD,
119+ .u.allocate_payload.vcpi = 0x7f,
120+ },
121+ },
122+ {
123+ .desc = "DP_ALLOCATE_PAYLOAD with PBN",
124+ .in = {
125+ .req_type = DP_ALLOCATE_PAYLOAD,
126+ .u.allocate_payload.pbn = U16_MAX,
127+ },
128+ },
129+ {
130+ .desc = "DP_QUERY_PAYLOAD with port number",
131+ .in = {
132+ .req_type = DP_QUERY_PAYLOAD,
133+ .u.query_payload.port_number = 0xf,
134+ },
135+ },
136+ {
137+ .desc = "DP_QUERY_PAYLOAD with VCPI",
138+ .in = {
139+ .req_type = DP_QUERY_PAYLOAD,
140+ .u.query_payload.vcpi = 0x7f,
141+ },
142+ },
143+ {
144+ .desc = "DP_REMOTE_DPCD_READ with port number",
145+ .in = {
146+ .req_type = DP_REMOTE_DPCD_READ,
147+ .u.dpcd_read.port_number = 0xf,
148+ },
149+ },
150+ {
151+ .desc = "DP_REMOTE_DPCD_READ with DPCD address",
152+ .in = {
153+ .req_type = DP_REMOTE_DPCD_READ,
154+ .u.dpcd_read.dpcd_address = 0xfedcb,
155+ },
156+ },
157+ {
158+ .desc = "DP_REMOTE_DPCD_READ with max number of bytes",
159+ .in = {
160+ .req_type = DP_REMOTE_DPCD_READ,
161+ .u.dpcd_read.num_bytes = U8_MAX,
162+ },
163+ },
164+ {
165+ .desc = "DP_REMOTE_DPCD_WRITE with port number",
166+ .in = {
167+ .req_type = DP_REMOTE_DPCD_WRITE,
168+ .u.dpcd_write.port_number = 0xf,
169+ },
170+ },
171+ {
172+ .desc = "DP_REMOTE_DPCD_WRITE with DPCD address",
173+ .in = {
174+ .req_type = DP_REMOTE_DPCD_WRITE,
175+ .u.dpcd_write.dpcd_address = 0xfedcb,
176+ },
177+ },
178+ {
179+ .desc = "DP_REMOTE_DPCD_WRITE with data array",
180+ .in = {
181+ .req_type = DP_REMOTE_DPCD_WRITE,
182+ .u.dpcd_write.num_bytes = ARRAY_SIZE(data),
183+ .u.dpcd_write.bytes = data,
184+ },
185+ },
186+ {
187+ .desc = "DP_REMOTE_I2C_READ with port number",
188+ .in = {
189+ .req_type = DP_REMOTE_I2C_READ,
190+ .u.i2c_read.port_number = 0xf,
191+ },
192+ },
193+ {
194+ .desc = "DP_REMOTE_I2C_READ with I2C device ID",
195+ .in = {
196+ .req_type = DP_REMOTE_I2C_READ,
197+ .u.i2c_read.read_i2c_device_id = 0x7f,
198+ },
199+ },
200+ {
201+ .desc = "DP_REMOTE_I2C_READ with transactions array",
202+ .in = {
203+ .req_type = DP_REMOTE_I2C_READ,
204+ .u.i2c_read.num_transactions = 3,
205+ .u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3,
206+ .u.i2c_read.transactions = {
207+ { .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7f,
208+ .i2c_transaction_delay = 0xf, },
209+ { .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7e,
210+ .i2c_transaction_delay = 0xe, },
211+ { .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7d,
212+ .i2c_transaction_delay = 0xd, },
213+ },
214+ },
215+ },
216+ {
217+ .desc = "DP_REMOTE_I2C_WRITE with port number",
218+ .in = {
219+ .req_type = DP_REMOTE_I2C_WRITE,
220+ .u.i2c_write.port_number = 0xf,
221+ },
222+ },
223+ {
224+ .desc = "DP_REMOTE_I2C_WRITE with I2C device ID",
225+ .in = {
226+ .req_type = DP_REMOTE_I2C_WRITE,
227+ .u.i2c_write.write_i2c_device_id = 0x7f,
228+ },
229+ },
230+ {
231+ .desc = "DP_REMOTE_I2C_WRITE with data array",
232+ .in = {
233+ .req_type = DP_REMOTE_I2C_WRITE,
234+ .u.i2c_write.num_bytes = ARRAY_SIZE(data),
235+ .u.i2c_write.bytes = data,
236+ },
237+ },
238+ {
239+ .desc = "DP_QUERY_STREAM_ENC_STATUS with stream ID",
240+ .in = {
241+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
242+ .u.enc_status.stream_id = 1,
243+ },
244+ },
245+ {
246+ .desc = "DP_QUERY_STREAM_ENC_STATUS with client ID",
247+ .in = {
248+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
249+ .u.enc_status.client_id = { 0x4f, 0x7f, 0xb4, 0x00, 0x8c, 0x0d, 0x67 },
250+ },
251+ },
252+ {
253+ .desc = "DP_QUERY_STREAM_ENC_STATUS with stream event",
254+ .in = {
255+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
256+ .u.enc_status.stream_event = 3,
257+ },
258+ },
259+ {
260+ .desc = "DP_QUERY_STREAM_ENC_STATUS with valid stream event",
261+ .in = {
262+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
263+ .u.enc_status.valid_stream_event = 0,
264+ },
265+ },
266+ {
267+ .desc = "DP_QUERY_STREAM_ENC_STATUS with stream behavior",
268+ .in = {
269+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
270+ .u.enc_status.stream_behavior = 3,
271+ },
272+ },
273+ {
274+ .desc = "DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior",
275+ .in = {
276+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
277+ .u.enc_status.valid_stream_behavior = 1,
278+ }
279+ },
280+};
281+
46282 static bool
47283 sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
48284 const struct drm_dp_sideband_msg_req_body *out)
@@ -118,41 +354,41 @@ sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in, · 69 unmodified lines
118354 return true;
119355 }
120356
121−static bool
122−sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
357+static void drm_test_dp_mst_msg_printf(struct drm_printer *p, struct va_format *vaf)
123358 {
359+ struct kunit *test = p->arg;
360+
361+ kunit_err(test, "%pV", vaf);
362+}
363+
364+static void drm_test_dp_mst_sideband_msg_req_decode(struct kunit *test)
365+{
366+ const struct drm_dp_mst_sideband_msg_req_test *params = test->param_value;
367+ const struct drm_dp_sideband_msg_req_body *in = &params->in;
124368 struct drm_dp_sideband_msg_req_body *out;
125− struct drm_printer p = drm_err_printer(PREFIX_STR);
126369 struct drm_dp_sideband_msg_tx *txmsg;
127− int i, ret;
128− bool result = true;
370+ struct drm_printer p = {
371+ .printfn = drm_test_dp_mst_msg_printf,
372+ .arg = test
373+ };
374+ int i;
129375
130− out = kzalloc(sizeof(*out), GFP_KERNEL);
131− if (!out)
132− return false;
376+ out = kunit_kzalloc(test, sizeof(*out), GFP_KERNEL);
377+ KUNIT_ASSERT_NOT_NULL(test, out);
133378
134− txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
135− if (!txmsg) {
136− kfree(out);
137− return false;
138− }
379+ txmsg = kunit_kzalloc(test, sizeof(*txmsg), GFP_KERNEL);
380+ KUNIT_ASSERT_NOT_NULL(test, txmsg);
139381
140382 drm_dp_encode_sideband_req(in, txmsg);
141− ret = drm_dp_decode_sideband_req(txmsg, out);
142− if (ret < 0) {
143− drm_printf(&p, "Failed to decode sideband request: %d\n",
144− ret);
145− result = false;
146− goto out;
147− }
383+ KUNIT_EXPECT_GE_MSG(test, drm_dp_decode_sideband_req(txmsg, out), 0,
384+ "Failed to decode sideband request");
148385
149386 if (!sideband_msg_req_equal(in, out)) {
150− drm_printf(&p, "Encode/decode failed, expected:\n");
387+ KUNIT_FAIL(test, "Encode/decode failed");
388+ kunit_err(test, "Expected:");
151389 drm_dp_dump_sideband_msg_req_body(in, 1, &p);
152− drm_printf(&p, "Got:\n");
390+ kunit_err(test, "Got:");
153391 drm_dp_dump_sideband_msg_req_body(out, 1, &p);
154− result = false;
155− goto out;
156392 }
157393
158394 switch (in->req_type) {
@@ -167,112 +403,21 @@ sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) · 8 unmodified lines
167403 kfree(out->u.i2c_write.bytes);
168404 break;
169405 }
170−
171− /* Clear everything but the req_type for the input */
172− memset(&in->u, 0, sizeof(in->u));
173−
174−out:
175− kfree(out);
176− kfree(txmsg);
177− return result;
178406 }
179407
180−static void drm_test_dp_mst_sideband_msg_req_decode(struct kunit *test)
408+static void
409+drm_dp_mst_sideband_msg_req_desc(const struct drm_dp_mst_sideband_msg_req_test *t, char *desc)
181410 {
182− struct drm_dp_sideband_msg_req_body in = { 0 };
183− u8 data[] = { 0xff, 0x0, 0xdd };
184− int i;
185−
186− in.req_type = DP_ENUM_PATH_RESOURCES;
187− in.u.port_num.port_number = 5;
188− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
189−
190− in.req_type = DP_POWER_UP_PHY;
191− in.u.port_num.port_number = 5;
192− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
193−
194− in.req_type = DP_POWER_DOWN_PHY;
195− in.u.port_num.port_number = 5;
196− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
197−
198− in.req_type = DP_ALLOCATE_PAYLOAD;
199− in.u.allocate_payload.number_sdp_streams = 3;
200− for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++)
201− in.u.allocate_payload.sdp_stream_sink[i] = i + 1;
202− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
203− in.u.allocate_payload.port_number = 0xf;
204− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
205− in.u.allocate_payload.vcpi = 0x7f;
206− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
207− in.u.allocate_payload.pbn = U16_MAX;
208− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
209−
210− in.req_type = DP_QUERY_PAYLOAD;
211− in.u.query_payload.port_number = 0xf;
212− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
213− in.u.query_payload.vcpi = 0x7f;
214− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
215−
216− in.req_type = DP_REMOTE_DPCD_READ;
217− in.u.dpcd_read.port_number = 0xf;
218− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
219− in.u.dpcd_read.dpcd_address = 0xfedcb;
220− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
221− in.u.dpcd_read.num_bytes = U8_MAX;
222− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
223−
224− in.req_type = DP_REMOTE_DPCD_WRITE;
225− in.u.dpcd_write.port_number = 0xf;
226− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
227− in.u.dpcd_write.dpcd_address = 0xfedcb;
228− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
229− in.u.dpcd_write.num_bytes = ARRAY_SIZE(data);
230− in.u.dpcd_write.bytes = data;
231− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
232−
233− in.req_type = DP_REMOTE_I2C_READ;
234− in.u.i2c_read.port_number = 0xf;
235− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
236− in.u.i2c_read.read_i2c_device_id = 0x7f;
237− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
238− in.u.i2c_read.num_transactions = 3;
239− in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3;
240− for (i = 0; i < in.u.i2c_read.num_transactions; i++) {
241− in.u.i2c_read.transactions[i].bytes = data;
242− in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data);
243− in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i;
244− in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i;
245− }
246− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
247−
248− in.req_type = DP_REMOTE_I2C_WRITE;
249− in.u.i2c_write.port_number = 0xf;
250− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
251− in.u.i2c_write.write_i2c_device_id = 0x7f;
252− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
253− in.u.i2c_write.num_bytes = ARRAY_SIZE(data);
254− in.u.i2c_write.bytes = data;
255− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
256−
257− in.req_type = DP_QUERY_STREAM_ENC_STATUS;
258− in.u.enc_status.stream_id = 1;
259− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
260− get_random_bytes(in.u.enc_status.client_id,
261− sizeof(in.u.enc_status.client_id));
262− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
263− in.u.enc_status.stream_event = 3;
264− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
265− in.u.enc_status.valid_stream_event = 0;
266− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
267− in.u.enc_status.stream_behavior = 3;
268− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
269− in.u.enc_status.valid_stream_behavior = 1;
270− KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
411+ strcpy(desc, t->desc);
271412 }
272413
414+KUNIT_ARRAY_PARAM(drm_dp_mst_sideband_msg_req, drm_dp_mst_sideband_msg_req_cases,
415+ drm_dp_mst_sideband_msg_req_desc);
416+
273417 static struct kunit_case drm_dp_mst_helper_tests[] = {
274− KUNIT_CASE(drm_test_dp_mst_calc_pbn_mode),
275− KUNIT_CASE(drm_test_dp_mst_sideband_msg_req_decode),
418+ KUNIT_CASE_PARAM(drm_test_dp_mst_calc_pbn_mode, drm_dp_mst_calc_pbn_mode_gen_params),
419+ KUNIT_CASE_PARAM(drm_test_dp_mst_sideband_msg_req_decode,
420+ drm_dp_mst_sideband_msg_req_gen_params),
276421 { }
277422 };
278423
drivers/gpu/drm/tiny/Kconfig+13−0
@@ -51,6 +51,19 @@ config DRM_GM12U320 · 50 unmodified lines
5151 This is a KMS driver for projectors which use the GM12U320 chipset
5252 for video transfer over USB2/3, such as the Acer C120 mini projector.
5353
54+config DRM_OFDRM
55+ tristate "Open Firmware display driver"
56+ depends on DRM && OF && (PPC || COMPILE_TEST)
57+ select APERTURE_HELPERS
58+ select DRM_GEM_SHMEM_HELPER
59+ select DRM_KMS_HELPER
60+ help
61+ DRM driver for Open Firmware framebuffers.
62+
63+ This driver assumes that the display hardware has been initialized
64+ by the Open Firmware before the kernel boots. Scanout buffer, size,
65+ and display format must be provided via device tree.
66+
5467 config DRM_PANEL_MIPI_DBI
5568 tristate "DRM support for MIPI DBI compatible panels"
5669 depends on DRM && SPI
drivers/gpu/drm/tiny/Makefile+1−0
@@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_ARCPGU) += arcpgu.o · 3 unmodified lines
44 obj-$(CONFIG_DRM_BOCHS) += bochs.o
55 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o
66 obj-$(CONFIG_DRM_GM12U320) += gm12u320.o
7+obj-$(CONFIG_DRM_OFDRM) += ofdrm.o
78 obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o
89 obj-$(CONFIG_DRM_SIMPLEDRM) += simpledrm.o
910 obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o
drivers/gpu/drm/tiny/bochs.c+0−1
@@ -543,7 +543,6 @@ static int bochs_kms_init(struct bochs_device *bochs) · 542 unmodified lines
543543 bochs->dev->mode_config.max_width = 8192;
544544 bochs->dev->mode_config.max_height = 8192;
545545
546− bochs->dev->mode_config.fb_base = bochs->fb_base;
547546 bochs->dev->mode_config.preferred_depth = 24;
548547 bochs->dev->mode_config.prefer_shadow = 0;
549548 bochs->dev->mode_config.prefer_shadow_fbdev = 1;
drivers/gpu/drm/tiny/ofdrm.c+1424−0
@@ -0,0 +1,1424 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+
3+#include <linux/of_address.h>
4+#include <linux/pci.h>
5+#include <linux/platform_device.h>
6+
7+#include <drm/drm_aperture.h>
8+#include <drm/drm_atomic.h>
9+#include <drm/drm_atomic_state_helper.h>
10+#include <drm/drm_connector.h>
11+#include <drm/drm_damage_helper.h>
12+#include <drm/drm_device.h>
13+#include <drm/drm_drv.h>
14+#include <drm/drm_fb_helper.h>
15+#include <drm/drm_format_helper.h>
16+#include <drm/drm_framebuffer.h>
17+#include <drm/drm_gem_atomic_helper.h>
18+#include <drm/drm_gem_framebuffer_helper.h>
19+#include <drm/drm_gem_shmem_helper.h>
20+#include <drm/drm_managed.h>
21+#include <drm/drm_modeset_helper_vtables.h>
22+#include <drm/drm_plane_helper.h>
23+#include <drm/drm_probe_helper.h>
24+#include <drm/drm_simple_kms_helper.h>
25+
26+#define DRIVER_NAME "ofdrm"
27+#define DRIVER_DESC "DRM driver for OF platform devices"
28+#define DRIVER_DATE "20220501"
29+#define DRIVER_MAJOR 1
30+#define DRIVER_MINOR 0
31+
32+#define PCI_VENDOR_ID_ATI_R520 0x7100
33+#define PCI_VENDOR_ID_ATI_R600 0x9400
34+
35+#define OFDRM_GAMMA_LUT_SIZE 256
36+
37+/* Definitions used by the Avivo palette */
38+#define AVIVO_DC_LUT_RW_SELECT 0x6480
39+#define AVIVO_DC_LUT_RW_MODE 0x6484
40+#define AVIVO_DC_LUT_RW_INDEX 0x6488
41+#define AVIVO_DC_LUT_SEQ_COLOR 0x648c
42+#define AVIVO_DC_LUT_PWL_DATA 0x6490
43+#define AVIVO_DC_LUT_30_COLOR 0x6494
44+#define AVIVO_DC_LUT_READ_PIPE_SELECT 0x6498
45+#define AVIVO_DC_LUT_WRITE_EN_MASK 0x649c
46+#define AVIVO_DC_LUT_AUTOFILL 0x64a0
47+#define AVIVO_DC_LUTA_CONTROL 0x64c0
48+#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4
49+#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN 0x64c8
50+#define AVIVO_DC_LUTA_BLACK_OFFSET_RED 0x64cc
51+#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0
52+#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4
53+#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
54+#define AVIVO_DC_LUTB_CONTROL 0x6cc0
55+#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE 0x6cc4
56+#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN 0x6cc8
57+#define AVIVO_DC_LUTB_BLACK_OFFSET_RED 0x6ccc
58+#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE 0x6cd0
59+#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN 0x6cd4
60+#define AVIVO_DC_LUTB_WHITE_OFFSET_RED 0x6cd8
61+
62+enum ofdrm_model {
63+ OFDRM_MODEL_UNKNOWN,
64+ OFDRM_MODEL_MACH64, /* ATI Mach64 */
65+ OFDRM_MODEL_RAGE128, /* ATI Rage128 */
66+ OFDRM_MODEL_RAGE_M3A, /* ATI Rage Mobility M3 Head A */
67+ OFDRM_MODEL_RAGE_M3B, /* ATI Rage Mobility M3 Head B */
68+ OFDRM_MODEL_RADEON, /* ATI Radeon */
69+ OFDRM_MODEL_GXT2000, /* IBM GXT2000 */
70+ OFDRM_MODEL_AVIVO, /* ATI R5xx */
71+ OFDRM_MODEL_QEMU, /* QEMU VGA */
72+};
73+
74+/*
75+ * Helpers for display nodes
76+ */
77+
78+static int display_get_validated_int(struct drm_device *dev, const char *name, uint32_t value)
79+{
80+ if (value > INT_MAX) {
81+ drm_err(dev, "invalid framebuffer %s of %u\n", name, value);
82+ return -EINVAL;
83+ }
84+ return (int)value;
85+}
86+
87+static int display_get_validated_int0(struct drm_device *dev, const char *name, uint32_t value)
88+{
89+ if (!value) {
90+ drm_err(dev, "invalid framebuffer %s of %u\n", name, value);
91+ return -EINVAL;
92+ }
93+ return display_get_validated_int(dev, name, value);
94+}
95+
96+static const struct drm_format_info *display_get_validated_format(struct drm_device *dev,
97+ u32 depth, bool big_endian)
98+{
99+ const struct drm_format_info *info;
100+ u32 format;
101+
102+ switch (depth) {
103+ case 8:
104+ format = drm_mode_legacy_fb_format(8, 8);
105+ break;
106+ case 15:
107+ case 16:
108+ format = drm_mode_legacy_fb_format(16, depth);
109+ break;
110+ case 32:
111+ format = drm_mode_legacy_fb_format(32, 24);
112+ break;
113+ default:
114+ drm_err(dev, "unsupported framebuffer depth %u\n", depth);
115+ return ERR_PTR(-EINVAL);
116+ }
117+
118+ /*
119+ * DRM formats assume little-endian byte order. Update the format
120+ * if the scanout buffer uses big-endian ordering.
121+ */
122+ if (big_endian) {
123+ switch (format) {
124+ case DRM_FORMAT_XRGB8888:
125+ format = DRM_FORMAT_BGRX8888;
126+ break;
127+ case DRM_FORMAT_ARGB8888:
128+ format = DRM_FORMAT_BGRA8888;
129+ break;
130+ case DRM_FORMAT_RGB565:
131+ format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN;
132+ break;
133+ case DRM_FORMAT_XRGB1555:
134+ format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN;
135+ break;
136+ default:
137+ break;
138+ }
139+ }
140+
141+ info = drm_format_info(format);
142+ if (!info) {
143+ drm_err(dev, "cannot find framebuffer format for depth %u\n", depth);
144+ return ERR_PTR(-EINVAL);
145+ }
146+
147+ return info;
148+}
149+
150+static int display_read_u32_of(struct drm_device *dev, struct device_node *of_node,
151+ const char *name, u32 *value)
152+{
153+ int ret = of_property_read_u32(of_node, name, value);
154+
155+ if (ret)
156+ drm_err(dev, "cannot parse framebuffer %s: error %d\n", name, ret);
157+ return ret;
158+}
159+
160+static bool display_get_big_endian_of(struct drm_device *dev, struct device_node *of_node)
161+{
162+ bool big_endian;
163+
164+#ifdef __BIG_ENDIAN
165+ big_endian = true;
166+ if (of_get_property(of_node, "little-endian", NULL))
167+ big_endian = false;
168+#else
169+ big_endian = false;
170+ if (of_get_property(of_node, "big-endian", NULL))
171+ big_endian = true;
172+#endif
173+
174+ return big_endian;
175+}
176+
177+static int display_get_width_of(struct drm_device *dev, struct device_node *of_node)
178+{
179+ u32 width;
180+ int ret = display_read_u32_of(dev, of_node, "width", &width);
181+
182+ if (ret)
183+ return ret;
184+ return display_get_validated_int0(dev, "width", width);
185+}
186+
187+static int display_get_height_of(struct drm_device *dev, struct device_node *of_node)
188+{
189+ u32 height;
190+ int ret = display_read_u32_of(dev, of_node, "height", &height);
191+
192+ if (ret)
193+ return ret;
194+ return display_get_validated_int0(dev, "height", height);
195+}
196+
197+static int display_get_depth_of(struct drm_device *dev, struct device_node *of_node)
198+{
199+ u32 depth;
200+ int ret = display_read_u32_of(dev, of_node, "depth", &depth);
201+
202+ if (ret)
203+ return ret;
204+ return display_get_validated_int0(dev, "depth", depth);
205+}
206+
207+static int display_get_linebytes_of(struct drm_device *dev, struct device_node *of_node)
208+{
209+ u32 linebytes;
210+ int ret = display_read_u32_of(dev, of_node, "linebytes", &linebytes);
211+
212+ if (ret)
213+ return ret;
214+ return display_get_validated_int(dev, "linebytes", linebytes);
215+}
216+
217+static u64 display_get_address_of(struct drm_device *dev, struct device_node *of_node)
218+{
219+ u32 address;
220+ int ret;
221+
222+ /*
223+ * Not all devices provide an address property, it's not
224+ * a bug if this fails. The driver will try to find the
225+ * framebuffer base address from the device's memory regions.
226+ */
227+ ret = of_property_read_u32(of_node, "address", &address);
228+ if (ret)
229+ return OF_BAD_ADDR;
230+
231+ return address;
232+}
233+
234+static bool is_avivo(__be32 vendor, __be32 device)
235+{
236+ /* This will match most R5xx */
237+ return (vendor == PCI_VENDOR_ID_ATI) &&
238+ ((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) ||
239+ (PCI_VENDOR_ID_ATI_R600 >= 0x9400));
240+}
241+
242+static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node)
243+{
244+ enum ofdrm_model model = OFDRM_MODEL_UNKNOWN;
245+
246+ if (of_node_name_prefix(of_node, "ATY,Rage128")) {
247+ model = OFDRM_MODEL_RAGE128;
248+ } else if (of_node_name_prefix(of_node, "ATY,RageM3pA") ||
249+ of_node_name_prefix(of_node, "ATY,RageM3p12A")) {
250+ model = OFDRM_MODEL_RAGE_M3A;
251+ } else if (of_node_name_prefix(of_node, "ATY,RageM3pB")) {
252+ model = OFDRM_MODEL_RAGE_M3B;
253+ } else if (of_node_name_prefix(of_node, "ATY,Rage6")) {
254+ model = OFDRM_MODEL_RADEON;
255+ } else if (of_node_name_prefix(of_node, "ATY,")) {
256+ return OFDRM_MODEL_MACH64;
257+ } else if (of_device_is_compatible(of_node, "pci1014,b7") ||
258+ of_device_is_compatible(of_node, "pci1014,21c")) {
259+ model = OFDRM_MODEL_GXT2000;
260+ } else if (of_node_name_prefix(of_node, "vga,Display-")) {
261+ struct device_node *of_parent;
262+ const __be32 *vendor_p, *device_p;
263+
264+ /* Look for AVIVO initialized by SLOF */
265+ of_parent = of_get_parent(of_node);
266+ vendor_p = of_get_property(of_parent, "vendor-id", NULL);
267+ device_p = of_get_property(of_parent, "device-id", NULL);
268+ if (vendor_p && device_p && is_avivo(*vendor_p, *device_p))
269+ model = OFDRM_MODEL_AVIVO;
270+ of_node_put(of_parent);
271+ } else if (of_device_is_compatible(of_node, "qemu,std-vga")) {
272+ model = OFDRM_MODEL_QEMU;
273+ }
274+
275+ return model;
276+}
277+
278+/*
279+ * Open Firmware display device
280+ */
281+
282+struct ofdrm_device;
283+
284+struct ofdrm_device_funcs {
285+ void __iomem *(*cmap_ioremap)(struct ofdrm_device *odev,
286+ struct device_node *of_node,
287+ u64 fb_bas);
288+ void (*cmap_write)(struct ofdrm_device *odev, unsigned char index,
289+ unsigned char r, unsigned char g, unsigned char b);
290+};
291+
292+struct ofdrm_device {
293+ struct drm_device dev;
294+ struct platform_device *pdev;
295+
296+ const struct ofdrm_device_funcs *funcs;
297+
298+ /* firmware-buffer settings */
299+ struct iosys_map screen_base;
300+ struct drm_display_mode mode;
301+ const struct drm_format_info *format;
302+ unsigned int pitch;
303+
304+ /* colormap */
305+ void __iomem *cmap_base;
306+
307+ /* modesetting */
308+ uint32_t formats[8];
309+ struct drm_plane primary_plane;
310+ struct drm_crtc crtc;
311+ struct drm_encoder encoder;
312+ struct drm_connector connector;
313+};
314+
315+static struct ofdrm_device *ofdrm_device_of_dev(struct drm_device *dev)
316+{
317+ return container_of(dev, struct ofdrm_device, dev);
318+}
319+
320+/*
321+ * Hardware
322+ */
323+
324+#if defined(CONFIG_PCI)
325+static struct pci_dev *display_get_pci_dev_of(struct drm_device *dev, struct device_node *of_node)
326+{
327+ const __be32 *vendor_p, *device_p;
328+ u32 vendor, device;
329+ struct pci_dev *pcidev;
330+
331+ vendor_p = of_get_property(of_node, "vendor-id", NULL);
332+ if (!vendor_p)
333+ return ERR_PTR(-ENODEV);
334+ vendor = be32_to_cpup(vendor_p);
335+
336+ device_p = of_get_property(of_node, "device-id", NULL);
337+ if (!device_p)
338+ return ERR_PTR(-ENODEV);
339+ device = be32_to_cpup(device_p);
340+
341+ pcidev = pci_get_device(vendor, device, NULL);
342+ if (!pcidev)
343+ return ERR_PTR(-ENODEV);
344+
345+ return pcidev;
346+}
347+
348+static void ofdrm_pci_release(void *data)
349+{
350+ struct pci_dev *pcidev = data;
351+
352+ pci_disable_device(pcidev);
353+}
354+
355+static int ofdrm_device_init_pci(struct ofdrm_device *odev)
356+{
357+ struct drm_device *dev = &odev->dev;
358+ struct platform_device *pdev = to_platform_device(dev->dev);
359+ struct device_node *of_node = pdev->dev.of_node;
360+ struct pci_dev *pcidev;
361+ int ret;
362+
363+ /*
364+ * Never use pcim_ or other managed helpers on the returned PCI
365+ * device. Otherwise, probing the native driver will fail for
366+ * resource conflicts. PCI-device management has to be tied to
367+ * the lifetime of the platform device until the native driver
368+ * takes over.
369+ */
370+ pcidev = display_get_pci_dev_of(dev, of_node);
371+ if (IS_ERR(pcidev))
372+ return 0; /* no PCI device found; ignore the error */
373+
374+ ret = pci_enable_device(pcidev);
375+ if (ret) {
376+ drm_err(dev, "pci_enable_device(%s) failed: %d\n",
377+ dev_name(&pcidev->dev), ret);
378+ return ret;
379+ }
380+ ret = devm_add_action_or_reset(&pdev->dev, ofdrm_pci_release, pcidev);
381+ if (ret)
382+ return ret;
383+
384+ return 0;
385+}
386+#else
387+static int ofdrm_device_init_pci(struct ofdrm_device *odev)
388+{
389+ return 0;
390+}
391+#endif
392+
393+/*
394+ * OF display settings
395+ */
396+
397+static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,
398+ struct resource *fb_res)
399+{
400+ struct platform_device *pdev = to_platform_device(odev->dev.dev);
401+ struct resource *res, *max_res = NULL;
402+ u32 i;
403+
404+ for (i = 0; pdev->num_resources; ++i) {
405+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
406+ if (!res)
407+ break; /* all resources processed */
408+ if (resource_size(res) < resource_size(fb_res))
409+ continue; /* resource too small */
410+ if (fb_res->start && resource_contains(res, fb_res))
411+ return res; /* resource contains framebuffer */
412+ if (!max_res || resource_size(res) > resource_size(max_res))
413+ max_res = res; /* store largest resource as fallback */
414+ }
415+
416+ return max_res;
417+}
418+
419+/*
420+ * Colormap / Palette
421+ */
422+
423+static void __iomem *get_cmap_address_of(struct ofdrm_device *odev, struct device_node *of_node,
424+ int bar_no, unsigned long offset, unsigned long size)
425+{
426+ struct drm_device *dev = &odev->dev;
427+ const __be32 *addr_p;
428+ u64 max_size, address;
429+ unsigned int flags;
430+ void __iomem *mem;
431+
432+ addr_p = of_get_pci_address(of_node, bar_no, &max_size, &flags);
433+ if (!addr_p)
434+ addr_p = of_get_address(of_node, bar_no, &max_size, &flags);
435+ if (!addr_p)
436+ return ERR_PTR(-ENODEV);
437+
438+ if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
439+ return ERR_PTR(-ENODEV);
440+
441+ if ((offset + size) >= max_size)
442+ return ERR_PTR(-ENODEV);
443+
444+ address = of_translate_address(of_node, addr_p);
445+ if (address == OF_BAD_ADDR)
446+ return ERR_PTR(-ENODEV);
447+
448+ mem = devm_ioremap(dev->dev, address + offset, size);
449+ if (!mem)
450+ return ERR_PTR(-ENOMEM);
451+
452+ return mem;
453+}
454+
455+static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
456+ struct device_node *of_node,
457+ u64 fb_base)
458+{
459+ struct drm_device *dev = &odev->dev;
460+ u64 address;
461+ void __iomem *cmap_base;
462+
463+ address = fb_base & 0xff000000ul;
464+ address += 0x7ff000;
465+
466+ cmap_base = devm_ioremap(dev->dev, address, 0x1000);
467+ if (!cmap_base)
468+ return ERR_PTR(-ENOMEM);
469+
470+ return cmap_base;
471+}
472+
473+static void ofdrm_mach64_cmap_write(struct ofdrm_device *odev, unsigned char index,
474+ unsigned char r, unsigned char g, unsigned char b)
475+{
476+ void __iomem *addr = odev->cmap_base + 0xcc0;
477+ void __iomem *data = odev->cmap_base + 0xcc0 + 1;
478+
479+ writeb(index, addr);
480+ writeb(r, data);
481+ writeb(g, data);
482+ writeb(b, data);
483+}
484+
485+static void __iomem *ofdrm_rage128_cmap_ioremap(struct ofdrm_device *odev,
486+ struct device_node *of_node,
487+ u64 fb_base)
488+{
489+ return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
490+}
491+
492+static void ofdrm_rage128_cmap_write(struct ofdrm_device *odev, unsigned char index,
493+ unsigned char r, unsigned char g, unsigned char b)
494+{
495+ void __iomem *addr = odev->cmap_base + 0xb0;
496+ void __iomem *data = odev->cmap_base + 0xb4;
497+ u32 color = (r << 16) | (g << 8) | b;
498+
499+ writeb(index, addr);
500+ writel(color, data);
501+}
502+
503+static void __iomem *ofdrm_rage_m3a_cmap_ioremap(struct ofdrm_device *odev,
504+ struct device_node *of_node,
505+ u64 fb_base)
506+{
507+ return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
508+}
509+
510+static void ofdrm_rage_m3a_cmap_write(struct ofdrm_device *odev, unsigned char index,
511+ unsigned char r, unsigned char g, unsigned char b)
512+{
513+ void __iomem *dac_ctl = odev->cmap_base + 0x58;
514+ void __iomem *addr = odev->cmap_base + 0xb0;
515+ void __iomem *data = odev->cmap_base + 0xb4;
516+ u32 color = (r << 16) | (g << 8) | b;
517+ u32 val;
518+
519+ /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
520+ val = readl(dac_ctl);
521+ val &= ~0x20;
522+ writel(val, dac_ctl);
523+
524+ /* Set color at palette index */
525+ writeb(index, addr);
526+ writel(color, data);
527+}
528+
529+static void __iomem *ofdrm_rage_m3b_cmap_ioremap(struct ofdrm_device *odev,
530+ struct device_node *of_node,
531+ u64 fb_base)
532+{
533+ return get_cmap_address_of(odev, of_node, 2, 0, 0x1fff);
534+}
535+
536+static void ofdrm_rage_m3b_cmap_write(struct ofdrm_device *odev, unsigned char index,
537+ unsigned char r, unsigned char g, unsigned char b)
538+{
539+ void __iomem *dac_ctl = odev->cmap_base + 0x58;
540+ void __iomem *addr = odev->cmap_base + 0xb0;
541+ void __iomem *data = odev->cmap_base + 0xb4;
542+ u32 color = (r << 16) | (g << 8) | b;
543+ u32 val;
544+
545+ /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
546+ val = readl(dac_ctl);
547+ val |= 0x20;
548+ writel(val, dac_ctl);
549+
550+ /* Set color at palette index */
551+ writeb(index, addr);
552+ writel(color, data);
553+}
554+
555+static void __iomem *ofdrm_radeon_cmap_ioremap(struct ofdrm_device *odev,
556+ struct device_node *of_node,
557+ u64 fb_base)
558+{
559+ return get_cmap_address_of(odev, of_node, 1, 0, 0x1fff);
560+}
561+
562+static void __iomem *ofdrm_gxt2000_cmap_ioremap(struct ofdrm_device *odev,
563+ struct device_node *of_node,
564+ u64 fb_base)
565+{
566+ return get_cmap_address_of(odev, of_node, 0, 0x6000, 0x1000);
567+}
568+
569+static void ofdrm_gxt2000_cmap_write(struct ofdrm_device *odev, unsigned char index,
570+ unsigned char r, unsigned char g, unsigned char b)
571+{
572+ void __iomem *data = ((unsigned int __iomem *)odev->cmap_base) + index;
573+ u32 color = (r << 16) | (g << 8) | b;
574+
575+ writel(color, data);
576+}
577+
578+static void __iomem *ofdrm_avivo_cmap_ioremap(struct ofdrm_device *odev,
579+ struct device_node *of_node,
580+ u64 fb_base)
581+{
582+ struct device_node *of_parent;
583+ void __iomem *cmap_base;
584+
585+ of_parent = of_get_parent(of_node);
586+ cmap_base = get_cmap_address_of(odev, of_parent, 0, 0, 0x10000);
587+ of_node_put(of_parent);
588+
589+ return cmap_base;
590+}
591+
592+static void ofdrm_avivo_cmap_write(struct ofdrm_device *odev, unsigned char index,
593+ unsigned char r, unsigned char g, unsigned char b)
594+{
595+ void __iomem *lutsel = odev->cmap_base + AVIVO_DC_LUT_RW_SELECT;
596+ void __iomem *addr = odev->cmap_base + AVIVO_DC_LUT_RW_INDEX;
597+ void __iomem *data = odev->cmap_base + AVIVO_DC_LUT_30_COLOR;
598+ u32 color = (r << 22) | (g << 12) | (b << 2);
599+
600+ /* Write to both LUTs for now */
601+
602+ writel(1, lutsel);
603+ writeb(index, addr);
604+ writel(color, data);
605+
606+ writel(0, lutsel);
607+ writeb(index, addr);
608+ writel(color, data);
609+}
610+
611+static void __iomem *ofdrm_qemu_cmap_ioremap(struct ofdrm_device *odev,
612+ struct device_node *of_node,
613+ u64 fb_base)
614+{
615+ static const __be32 io_of_addr[3] = {
616+ cpu_to_be32(0x01000000),
617+ cpu_to_be32(0x00),
618+ cpu_to_be32(0x00),
619+ };
620+
621+ struct drm_device *dev = &odev->dev;
622+ u64 address;
623+ void __iomem *cmap_base;
624+
625+ address = of_translate_address(of_node, io_of_addr);
626+ if (address == OF_BAD_ADDR)
627+ return ERR_PTR(-ENODEV);
628+
629+ cmap_base = devm_ioremap(dev->dev, address + 0x3c8, 2);
630+ if (!cmap_base)
631+ return ERR_PTR(-ENOMEM);
632+
633+ return cmap_base;
634+}
635+
636+static void ofdrm_qemu_cmap_write(struct ofdrm_device *odev, unsigned char index,
637+ unsigned char r, unsigned char g, unsigned char b)
638+{
639+ void __iomem *addr = odev->cmap_base;
640+ void __iomem *data = odev->cmap_base + 1;
641+
642+ writeb(index, addr);
643+ writeb(r, data);
644+ writeb(g, data);
645+ writeb(b, data);
646+}
647+
648+static void ofdrm_device_set_gamma_linear(struct ofdrm_device *odev,
649+ const struct drm_format_info *format)
650+{
651+ struct drm_device *dev = &odev->dev;
652+ int i;
653+
654+ switch (format->format) {
655+ case DRM_FORMAT_RGB565:
656+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
657+ /* Use better interpolation, to take 32 values from 0 to 255 */
658+ for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
659+ unsigned char r = i * 8 + i / 4;
660+ unsigned char g = i * 4 + i / 16;
661+ unsigned char b = i * 8 + i / 4;
662+
663+ odev->funcs->cmap_write(odev, i, r, g, b);
664+ }
665+ /* Green has one more bit, so add padding with 0 for red and blue. */
666+ for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
667+ unsigned char r = 0;
668+ unsigned char g = i * 4 + i / 16;
669+ unsigned char b = 0;
670+
671+ odev->funcs->cmap_write(odev, i, r, g, b);
672+ }
673+ break;
674+ case DRM_FORMAT_XRGB8888:
675+ case DRM_FORMAT_BGRX8888:
676+ for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++)
677+ odev->funcs->cmap_write(odev, i, i, i, i);
678+ break;
679+ default:
680+ drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
681+ &format->format);
682+ break;
683+ }
684+}
685+
686+static void ofdrm_device_set_gamma(struct ofdrm_device *odev,
687+ const struct drm_format_info *format,
688+ struct drm_color_lut *lut)
689+{
690+ struct drm_device *dev = &odev->dev;
691+ int i;
692+
693+ switch (format->format) {
694+ case DRM_FORMAT_RGB565:
695+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
696+ /* Use better interpolation, to take 32 values from lut[0] to lut[255] */
697+ for (i = 0; i < OFDRM_GAMMA_LUT_SIZE / 8; i++) {
698+ unsigned char r = lut[i * 8 + i / 4].red >> 8;
699+ unsigned char g = lut[i * 4 + i / 16].green >> 8;
700+ unsigned char b = lut[i * 8 + i / 4].blue >> 8;
701+
702+ odev->funcs->cmap_write(odev, i, r, g, b);
703+ }
704+ /* Green has one more bit, so add padding with 0 for red and blue. */
705+ for (i = OFDRM_GAMMA_LUT_SIZE / 8; i < OFDRM_GAMMA_LUT_SIZE / 4; i++) {
706+ unsigned char r = 0;
707+ unsigned char g = lut[i * 4 + i / 16].green >> 8;
708+ unsigned char b = 0;
709+
710+ odev->funcs->cmap_write(odev, i, r, g, b);
711+ }
712+ break;
713+ case DRM_FORMAT_XRGB8888:
714+ case DRM_FORMAT_BGRX8888:
715+ for (i = 0; i < OFDRM_GAMMA_LUT_SIZE; i++) {
716+ unsigned char r = lut[i].red >> 8;
717+ unsigned char g = lut[i].green >> 8;
718+ unsigned char b = lut[i].blue >> 8;
719+
720+ odev->funcs->cmap_write(odev, i, r, g, b);
721+ }
722+ break;
723+ default:
724+ drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
725+ &format->format);
726+ break;
727+ }
728+}
729+
730+/*
731+ * Modesetting
732+ */
733+
734+struct ofdrm_crtc_state {
735+ struct drm_crtc_state base;
736+
737+ /* Primary-plane format; required for color mgmt. */
738+ const struct drm_format_info *format;
739+};
740+
741+static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state *base)
742+{
743+ return container_of(base, struct ofdrm_crtc_state, base);
744+}
745+
746+static void ofdrm_crtc_state_destroy(struct ofdrm_crtc_state *ofdrm_crtc_state)
747+{
748+ __drm_atomic_helper_crtc_destroy_state(&ofdrm_crtc_state->base);
749+ kfree(ofdrm_crtc_state);
750+}
751+
752+/*
753+ * Support all formats of OF display and maybe more; in order
754+ * of preference. The display's update function will do any
755+ * conversion necessary.
756+ *
757+ * TODO: Add blit helpers for remaining formats and uncomment
758+ * constants.
759+ */
760+static const uint32_t ofdrm_primary_plane_formats[] = {
761+ DRM_FORMAT_XRGB8888,
762+ DRM_FORMAT_RGB565,
763+ //DRM_FORMAT_XRGB1555,
764+ //DRM_FORMAT_C8,
765+ /* Big-endian formats below */
766+ DRM_FORMAT_BGRX8888,
767+ DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN,
768+};
769+
770+static const uint64_t ofdrm_primary_plane_format_modifiers[] = {
771+ DRM_FORMAT_MOD_LINEAR,
772+ DRM_FORMAT_MOD_INVALID
773+};
774+
775+static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
776+ struct drm_atomic_state *new_state)
777+{
778+ struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
779+ struct drm_framebuffer *new_fb = new_plane_state->fb;
780+ struct drm_crtc *new_crtc = new_plane_state->crtc;
781+ struct drm_crtc_state *new_crtc_state = NULL;
782+ struct ofdrm_crtc_state *new_ofdrm_crtc_state;
783+ int ret;
784+
785+ if (new_crtc)
786+ new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
787+
788+ ret = drm_atomic_helper_check_plane_state(new_plane_state, new_crtc_state,
789+ DRM_PLANE_NO_SCALING,
790+ DRM_PLANE_NO_SCALING,
791+ false, false);
792+ if (ret)
793+ return ret;
794+ else if (!new_plane_state->visible)
795+ return 0;
796+
797+ new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
798+
799+ new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
800+ new_ofdrm_crtc_state->format = new_fb->format;
801+
802+ return 0;
803+}
804+
805+static void ofdrm_primary_plane_helper_atomic_update(struct drm_plane *plane,
806+ struct drm_atomic_state *state)
807+{
808+ struct drm_device *dev = plane->dev;
809+ struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
810+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
811+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
812+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
813+ struct drm_framebuffer *fb = plane_state->fb;
814+ unsigned int dst_pitch = odev->pitch;
815+ const struct drm_format_info *dst_format = odev->format;
816+ struct drm_atomic_helper_damage_iter iter;
817+ struct drm_rect damage;
818+ int ret, idx;
819+
820+ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
821+ if (ret)
822+ return;
823+
824+ if (!drm_dev_enter(dev, &idx))
825+ goto out_drm_gem_fb_end_cpu_access;
826+
827+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
828+ drm_atomic_for_each_plane_damage(&iter, &damage) {
829+ struct iosys_map dst = odev->screen_base;
830+ struct drm_rect dst_clip = plane_state->dst;
831+
832+ if (!drm_rect_intersect(&dst_clip, &damage))
833+ continue;
834+
835+ iosys_map_incr(&dst, drm_fb_clip_offset(dst_pitch, dst_format, &dst_clip));
836+ drm_fb_blit(&dst, &dst_pitch, dst_format->format, shadow_plane_state->data, fb,
837+ &damage);
838+ }
839+
840+ drm_dev_exit(idx);
841+out_drm_gem_fb_end_cpu_access:
842+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
843+}
844+
845+static void ofdrm_primary_plane_helper_atomic_disable(struct drm_plane *plane,
846+ struct drm_atomic_state *state)
847+{
848+ struct drm_device *dev = plane->dev;
849+ struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
850+ struct iosys_map dst = odev->screen_base;
851+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
852+ void __iomem *dst_vmap = dst.vaddr_iomem; /* TODO: Use mapping abstraction */
853+ unsigned int dst_pitch = odev->pitch;
854+ const struct drm_format_info *dst_format = odev->format;
855+ struct drm_rect dst_clip;
856+ unsigned long lines, linepixels, i;
857+ int idx;
858+
859+ drm_rect_init(&dst_clip,
860+ plane_state->src_x >> 16, plane_state->src_y >> 16,
861+ plane_state->src_w >> 16, plane_state->src_h >> 16);
862+
863+ lines = drm_rect_height(&dst_clip);
864+ linepixels = drm_rect_width(&dst_clip);
865+
866+ if (!drm_dev_enter(dev, &idx))
867+ return;
868+
869+ /* Clear buffer to black if disabled */
870+ dst_vmap += drm_fb_clip_offset(dst_pitch, dst_format, &dst_clip);
871+ for (i = 0; i < lines; ++i) {
872+ memset_io(dst_vmap, 0, linepixels * dst_format->cpp[0]);
873+ dst_vmap += dst_pitch;
874+ }
875+
876+ drm_dev_exit(idx);
877+}
878+
879+static const struct drm_plane_helper_funcs ofdrm_primary_plane_helper_funcs = {
880+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
881+ .atomic_check = ofdrm_primary_plane_helper_atomic_check,
882+ .atomic_update = ofdrm_primary_plane_helper_atomic_update,
883+ .atomic_disable = ofdrm_primary_plane_helper_atomic_disable,
884+};
885+
886+static const struct drm_plane_funcs ofdrm_primary_plane_funcs = {
887+ .update_plane = drm_atomic_helper_update_plane,
888+ .disable_plane = drm_atomic_helper_disable_plane,
889+ .destroy = drm_plane_cleanup,
890+ DRM_GEM_SHADOW_PLANE_FUNCS,
891+};
892+
893+static enum drm_mode_status ofdrm_crtc_helper_mode_valid(struct drm_crtc *crtc,
894+ const struct drm_display_mode *mode)
895+{
896+ struct ofdrm_device *odev = ofdrm_device_of_dev(crtc->dev);
897+
898+ return drm_crtc_helper_mode_valid_fixed(crtc, mode, &odev->mode);
899+}
900+
901+static int ofdrm_crtc_helper_atomic_check(struct drm_crtc *crtc,
902+ struct drm_atomic_state *new_state)
903+{
904+ static const size_t gamma_lut_length = OFDRM_GAMMA_LUT_SIZE * sizeof(struct drm_color_lut);
905+
906+ struct drm_device *dev = crtc->dev;
907+ struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc);
908+ int ret;
909+
910+ if (!new_crtc_state->enable)
911+ return 0;
912+
913+ ret = drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
914+ if (ret)
915+ return ret;
916+
917+ if (new_crtc_state->color_mgmt_changed) {
918+ struct drm_property_blob *gamma_lut = new_crtc_state->gamma_lut;
919+
920+ if (gamma_lut && (gamma_lut->length != gamma_lut_length)) {
921+ drm_dbg(dev, "Incorrect gamma_lut length %zu\n", gamma_lut->length);
922+ return -EINVAL;
923+ }
924+ }
925+
926+ return 0;
927+}
928+
929+static void ofdrm_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state)
930+{
931+ struct ofdrm_device *odev = ofdrm_device_of_dev(crtc->dev);
932+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
933+ struct ofdrm_crtc_state *ofdrm_crtc_state = to_ofdrm_crtc_state(crtc_state);
934+
935+ if (crtc_state->enable && crtc_state->color_mgmt_changed) {
936+ const struct drm_format_info *format = ofdrm_crtc_state->format;
937+
938+ if (crtc_state->gamma_lut)
939+ ofdrm_device_set_gamma(odev, format, crtc_state->gamma_lut->data);
940+ else
941+ ofdrm_device_set_gamma_linear(odev, format);
942+ }
943+}
944+
945+/*
946+ * The CRTC is always enabled. Screen updates are performed by
947+ * the primary plane's atomic_update function. Disabling clears
948+ * the screen in the primary plane's atomic_disable function.
949+ */
950+static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {
951+ .mode_valid = ofdrm_crtc_helper_mode_valid,
952+ .atomic_check = ofdrm_crtc_helper_atomic_check,
953+ .atomic_flush = ofdrm_crtc_helper_atomic_flush,
954+};
955+
956+static void ofdrm_crtc_reset(struct drm_crtc *crtc)
957+{
958+ struct ofdrm_crtc_state *ofdrm_crtc_state =
959+ kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
960+
961+ if (crtc->state)
962+ ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
963+
964+ if (ofdrm_crtc_state)
965+ __drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
966+ else
967+ __drm_atomic_helper_crtc_reset(crtc, NULL);
968+}
969+
970+static struct drm_crtc_state *ofdrm_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
971+{
972+ struct drm_device *dev = crtc->dev;
973+ struct drm_crtc_state *crtc_state = crtc->state;
974+ struct ofdrm_crtc_state *new_ofdrm_crtc_state;
975+ struct ofdrm_crtc_state *ofdrm_crtc_state;
976+
977+ if (drm_WARN_ON(dev, !crtc_state))
978+ return NULL;
979+
980+ new_ofdrm_crtc_state = kzalloc(sizeof(*new_ofdrm_crtc_state), GFP_KERNEL);
981+ if (!new_ofdrm_crtc_state)
982+ return NULL;
983+
984+ ofdrm_crtc_state = to_ofdrm_crtc_state(crtc_state);
985+
986+ __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ofdrm_crtc_state->base);
987+ new_ofdrm_crtc_state->format = ofdrm_crtc_state->format;
988+
989+ return &new_ofdrm_crtc_state->base;
990+}
991+
992+static void ofdrm_crtc_atomic_destroy_state(struct drm_crtc *crtc,
993+ struct drm_crtc_state *crtc_state)
994+{
995+ ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc_state));
996+}
997+
998+static const struct drm_crtc_funcs ofdrm_crtc_funcs = {
999+ .reset = ofdrm_crtc_reset,
1000+ .destroy = drm_crtc_cleanup,
1001+ .set_config = drm_atomic_helper_set_config,
1002+ .page_flip = drm_atomic_helper_page_flip,
1003+ .atomic_duplicate_state = ofdrm_crtc_atomic_duplicate_state,
1004+ .atomic_destroy_state = ofdrm_crtc_atomic_destroy_state,
1005+};
1006+
1007+static int ofdrm_connector_helper_get_modes(struct drm_connector *connector)
1008+{
1009+ struct ofdrm_device *odev = ofdrm_device_of_dev(connector->dev);
1010+
1011+ return drm_connector_helper_get_modes_fixed(connector, &odev->mode);
1012+}
1013+
1014+static const struct drm_connector_helper_funcs ofdrm_connector_helper_funcs = {
1015+ .get_modes = ofdrm_connector_helper_get_modes,
1016+};
1017+
1018+static const struct drm_connector_funcs ofdrm_connector_funcs = {
1019+ .reset = drm_atomic_helper_connector_reset,
1020+ .fill_modes = drm_helper_probe_single_connector_modes,
1021+ .destroy = drm_connector_cleanup,
1022+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1023+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1024+};
1025+
1026+static const struct drm_mode_config_funcs ofdrm_mode_config_funcs = {
1027+ .fb_create = drm_gem_fb_create_with_dirty,
1028+ .atomic_check = drm_atomic_helper_check,
1029+ .atomic_commit = drm_atomic_helper_commit,
1030+};
1031+
1032+/*
1033+ * Init / Cleanup
1034+ */
1035+
1036+static const struct ofdrm_device_funcs ofdrm_unknown_device_funcs = {
1037+};
1038+
1039+static const struct ofdrm_device_funcs ofdrm_mach64_device_funcs = {
1040+ .cmap_ioremap = ofdrm_mach64_cmap_ioremap,
1041+ .cmap_write = ofdrm_mach64_cmap_write,
1042+};
1043+
1044+static const struct ofdrm_device_funcs ofdrm_rage128_device_funcs = {
1045+ .cmap_ioremap = ofdrm_rage128_cmap_ioremap,
1046+ .cmap_write = ofdrm_rage128_cmap_write,
1047+};
1048+
1049+static const struct ofdrm_device_funcs ofdrm_rage_m3a_device_funcs = {
1050+ .cmap_ioremap = ofdrm_rage_m3a_cmap_ioremap,
1051+ .cmap_write = ofdrm_rage_m3a_cmap_write,
1052+};
1053+
1054+static const struct ofdrm_device_funcs ofdrm_rage_m3b_device_funcs = {
1055+ .cmap_ioremap = ofdrm_rage_m3b_cmap_ioremap,
1056+ .cmap_write = ofdrm_rage_m3b_cmap_write,
1057+};
1058+
1059+static const struct ofdrm_device_funcs ofdrm_radeon_device_funcs = {
1060+ .cmap_ioremap = ofdrm_radeon_cmap_ioremap,
1061+ .cmap_write = ofdrm_rage128_cmap_write, /* same as Rage128 */
1062+};
1063+
1064+static const struct ofdrm_device_funcs ofdrm_gxt2000_device_funcs = {
1065+ .cmap_ioremap = ofdrm_gxt2000_cmap_ioremap,
1066+ .cmap_write = ofdrm_gxt2000_cmap_write,
1067+};
1068+
1069+static const struct ofdrm_device_funcs ofdrm_avivo_device_funcs = {
1070+ .cmap_ioremap = ofdrm_avivo_cmap_ioremap,
1071+ .cmap_write = ofdrm_avivo_cmap_write,
1072+};
1073+
1074+static const struct ofdrm_device_funcs ofdrm_qemu_device_funcs = {
1075+ .cmap_ioremap = ofdrm_qemu_cmap_ioremap,
1076+ .cmap_write = ofdrm_qemu_cmap_write,
1077+};
1078+
1079+static struct drm_display_mode ofdrm_mode(unsigned int width, unsigned int height)
1080+{
1081+ /*
1082+ * Assume a monitor resolution of 96 dpi to
1083+ * get a somewhat reasonable screen size.
1084+ */
1085+ const struct drm_display_mode mode = {
1086+ DRM_MODE_INIT(60, width, height,
1087+ DRM_MODE_RES_MM(width, 96ul),
1088+ DRM_MODE_RES_MM(height, 96ul))
1089+ };
1090+
1091+ return mode;
1092+}
1093+
1094+static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
1095+ struct platform_device *pdev)
1096+{
1097+ struct device_node *of_node = pdev->dev.of_node;
1098+ struct ofdrm_device *odev;
1099+ struct drm_device *dev;
1100+ enum ofdrm_model model;
1101+ bool big_endian;
1102+ int width, height, depth, linebytes;
1103+ const struct drm_format_info *format;
1104+ u64 address;
1105+ resource_size_t fb_size, fb_base, fb_pgbase, fb_pgsize;
1106+ struct resource *res, *mem;
1107+ void __iomem *screen_base;
1108+ struct drm_plane *primary_plane;
1109+ struct drm_crtc *crtc;
1110+ struct drm_encoder *encoder;
1111+ struct drm_connector *connector;
1112+ unsigned long max_width, max_height;
1113+ size_t nformats;
1114+ int ret;
1115+
1116+ odev = devm_drm_dev_alloc(&pdev->dev, drv, struct ofdrm_device, dev);
1117+ if (IS_ERR(odev))
1118+ return ERR_CAST(odev);
1119+ dev = &odev->dev;
1120+ platform_set_drvdata(pdev, dev);
1121+
1122+ ret = ofdrm_device_init_pci(odev);
1123+ if (ret)
1124+ return ERR_PTR(ret);
1125+
1126+ /*
1127+ * OF display-node settings
1128+ */
1129+
1130+ model = display_get_model_of(dev, of_node);
1131+ drm_dbg(dev, "detected model %d\n", model);
1132+
1133+ switch (model) {
1134+ case OFDRM_MODEL_UNKNOWN:
1135+ odev->funcs = &ofdrm_unknown_device_funcs;
1136+ break;
1137+ case OFDRM_MODEL_MACH64:
1138+ odev->funcs = &ofdrm_mach64_device_funcs;
1139+ break;
1140+ case OFDRM_MODEL_RAGE128:
1141+ odev->funcs = &ofdrm_rage128_device_funcs;
1142+ break;
1143+ case OFDRM_MODEL_RAGE_M3A:
1144+ odev->funcs = &ofdrm_rage_m3a_device_funcs;
1145+ break;
1146+ case OFDRM_MODEL_RAGE_M3B:
1147+ odev->funcs = &ofdrm_rage_m3b_device_funcs;
1148+ break;
1149+ case OFDRM_MODEL_RADEON:
1150+ odev->funcs = &ofdrm_radeon_device_funcs;
1151+ break;
1152+ case OFDRM_MODEL_GXT2000:
1153+ odev->funcs = &ofdrm_gxt2000_device_funcs;
1154+ break;
1155+ case OFDRM_MODEL_AVIVO:
1156+ odev->funcs = &ofdrm_avivo_device_funcs;
1157+ break;
1158+ case OFDRM_MODEL_QEMU:
1159+ odev->funcs = &ofdrm_qemu_device_funcs;
1160+ break;
1161+ }
1162+
1163+ big_endian = display_get_big_endian_of(dev, of_node);
1164+
1165+ width = display_get_width_of(dev, of_node);
1166+ if (width < 0)
1167+ return ERR_PTR(width);
1168+ height = display_get_height_of(dev, of_node);
1169+ if (height < 0)
1170+ return ERR_PTR(height);
1171+ depth = display_get_depth_of(dev, of_node);
1172+ if (depth < 0)
1173+ return ERR_PTR(depth);
1174+ linebytes = display_get_linebytes_of(dev, of_node);
1175+ if (linebytes < 0)
1176+ return ERR_PTR(linebytes);
1177+
1178+ format = display_get_validated_format(dev, depth, big_endian);
1179+ if (IS_ERR(format))
1180+ return ERR_CAST(format);
1181+ if (!linebytes) {
1182+ linebytes = drm_format_info_min_pitch(format, 0, width);
1183+ if (drm_WARN_ON(dev, !linebytes))
1184+ return ERR_PTR(-EINVAL);
1185+ }
1186+
1187+ fb_size = linebytes * height;
1188+
1189+ /*
1190+ * Try to figure out the address of the framebuffer. Unfortunately, Open
1191+ * Firmware doesn't provide a standard way to do so. All we can do is a
1192+ * dodgy heuristic that happens to work in practice.
1193+ *
1194+ * On most machines, the "address" property contains what we need, though
1195+ * not on Matrox cards found in IBM machines. What appears to give good
1196+ * results is to go through the PCI ranges and pick one that encloses the
1197+ * "address" property. If none match, we pick the largest.
1198+ */
1199+ address = display_get_address_of(dev, of_node);
1200+ if (address != OF_BAD_ADDR) {
1201+ struct resource fb_res = DEFINE_RES_MEM(address, fb_size);
1202+
1203+ res = ofdrm_find_fb_resource(odev, &fb_res);
1204+ if (!res)
1205+ return ERR_PTR(-EINVAL);
1206+ if (resource_contains(res, &fb_res))
1207+ fb_base = address;
1208+ else
1209+ fb_base = res->start;
1210+ } else {
1211+ struct resource fb_res = DEFINE_RES_MEM(0u, fb_size);
1212+
1213+ res = ofdrm_find_fb_resource(odev, &fb_res);
1214+ if (!res)
1215+ return ERR_PTR(-EINVAL);
1216+ fb_base = res->start;
1217+ }
1218+
1219+ /*
1220+ * I/O resources
1221+ */
1222+
1223+ fb_pgbase = round_down(fb_base, PAGE_SIZE);
1224+ fb_pgsize = fb_base - fb_pgbase + round_up(fb_size, PAGE_SIZE);
1225+
1226+ ret = devm_aperture_acquire_from_firmware(dev, fb_pgbase, fb_pgsize);
1227+ if (ret) {
1228+ drm_err(dev, "could not acquire memory range %pr: error %d\n", &res, ret);
1229+ return ERR_PTR(ret);
1230+ }
1231+
1232+ mem = devm_request_mem_region(&pdev->dev, fb_pgbase, fb_pgsize, drv->name);
1233+ if (!mem) {
1234+ drm_warn(dev, "could not acquire memory region %pr\n", &res);
1235+ return ERR_PTR(-ENOMEM);
1236+ }
1237+
1238+ screen_base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
1239+ if (!screen_base)
1240+ return ERR_PTR(-ENOMEM);
1241+
1242+ if (odev->funcs->cmap_ioremap) {
1243+ void __iomem *cmap_base = odev->funcs->cmap_ioremap(odev, of_node, fb_base);
1244+
1245+ if (IS_ERR(cmap_base)) {
1246+ /* Don't fail; continue without colormap */
1247+ drm_warn(dev, "could not find colormap: error %ld\n", PTR_ERR(cmap_base));
1248+ } else {
1249+ odev->cmap_base = cmap_base;
1250+ }
1251+ }
1252+
1253+ /*
1254+ * Firmware framebuffer
1255+ */
1256+
1257+ iosys_map_set_vaddr_iomem(&odev->screen_base, screen_base);
1258+ odev->mode = ofdrm_mode(width, height);
1259+ odev->format = format;
1260+ odev->pitch = linebytes;
1261+
1262+ drm_dbg(dev, "display mode={" DRM_MODE_FMT "}\n", DRM_MODE_ARG(&odev->mode));
1263+ drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, linebytes=%d byte\n",
1264+ &format->format, width, height, linebytes);
1265+
1266+ /*
1267+ * Mode-setting pipeline
1268+ */
1269+
1270+ ret = drmm_mode_config_init(dev);
1271+ if (ret)
1272+ return ERR_PTR(ret);
1273+
1274+ max_width = max_t(unsigned long, width, DRM_SHADOW_PLANE_MAX_WIDTH);
1275+ max_height = max_t(unsigned long, height, DRM_SHADOW_PLANE_MAX_HEIGHT);
1276+
1277+ dev->mode_config.min_width = width;
1278+ dev->mode_config.max_width = max_width;
1279+ dev->mode_config.min_height = height;
1280+ dev->mode_config.max_height = max_height;
1281+ dev->mode_config.funcs = &ofdrm_mode_config_funcs;
1282+ switch (depth) {
1283+ case 32:
1284+ dev->mode_config.preferred_depth = 24;
1285+ break;
1286+ default:
1287+ dev->mode_config.preferred_depth = depth;
1288+ break;
1289+ }
1290+ dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
1291+
1292+ /* Primary plane */
1293+
1294+ nformats = drm_fb_build_fourcc_list(dev, &format->format, 1,
1295+ ofdrm_primary_plane_formats,
1296+ ARRAY_SIZE(ofdrm_primary_plane_formats),
1297+ odev->formats, ARRAY_SIZE(odev->formats));
1298+
1299+ primary_plane = &odev->primary_plane;
1300+ ret = drm_universal_plane_init(dev, primary_plane, 0, &ofdrm_primary_plane_funcs,
1301+ odev->formats, nformats,
1302+ ofdrm_primary_plane_format_modifiers,
1303+ DRM_PLANE_TYPE_PRIMARY, NULL);
1304+ if (ret)
1305+ return ERR_PTR(ret);
1306+ drm_plane_helper_add(primary_plane, &ofdrm_primary_plane_helper_funcs);
1307+ drm_plane_enable_fb_damage_clips(primary_plane);
1308+
1309+ /* CRTC */
1310+
1311+ crtc = &odev->crtc;
1312+ ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,
1313+ &ofdrm_crtc_funcs, NULL);
1314+ if (ret)
1315+ return ERR_PTR(ret);
1316+ drm_crtc_helper_add(crtc, &ofdrm_crtc_helper_funcs);
1317+
1318+ if (odev->cmap_base) {
1319+ drm_mode_crtc_set_gamma_size(crtc, OFDRM_GAMMA_LUT_SIZE);
1320+ drm_crtc_enable_color_mgmt(crtc, 0, false, OFDRM_GAMMA_LUT_SIZE);
1321+ }
1322+
1323+ /* Encoder */
1324+
1325+ encoder = &odev->encoder;
1326+ ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_NONE);
1327+ if (ret)
1328+ return ERR_PTR(ret);
1329+ encoder->possible_crtcs = drm_crtc_mask(crtc);
1330+
1331+ /* Connector */
1332+
1333+ connector = &odev->connector;
1334+ ret = drm_connector_init(dev, connector, &ofdrm_connector_funcs,
1335+ DRM_MODE_CONNECTOR_Unknown);
1336+ if (ret)
1337+ return ERR_PTR(ret);
1338+ drm_connector_helper_add(connector, &ofdrm_connector_helper_funcs);
1339+ drm_connector_set_panel_orientation_with_quirk(connector,
1340+ DRM_MODE_PANEL_ORIENTATION_UNKNOWN,
1341+ width, height);
1342+
1343+ ret = drm_connector_attach_encoder(connector, encoder);
1344+ if (ret)
1345+ return ERR_PTR(ret);
1346+
1347+ drm_mode_config_reset(dev);
1348+
1349+ return odev;
1350+}
1351+
1352+/*
1353+ * DRM driver
1354+ */
1355+
1356+DEFINE_DRM_GEM_FOPS(ofdrm_fops);
1357+
1358+static struct drm_driver ofdrm_driver = {
1359+ DRM_GEM_SHMEM_DRIVER_OPS,
1360+ .name = DRIVER_NAME,
1361+ .desc = DRIVER_DESC,
1362+ .date = DRIVER_DATE,
1363+ .major = DRIVER_MAJOR,
1364+ .minor = DRIVER_MINOR,
1365+ .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1366+ .fops = &ofdrm_fops,
1367+};
1368+
1369+/*
1370+ * Platform driver
1371+ */
1372+
1373+static int ofdrm_probe(struct platform_device *pdev)
1374+{
1375+ struct ofdrm_device *odev;
1376+ struct drm_device *dev;
1377+ int ret;
1378+
1379+ odev = ofdrm_device_create(&ofdrm_driver, pdev);
1380+ if (IS_ERR(odev))
1381+ return PTR_ERR(odev);
1382+ dev = &odev->dev;
1383+
1384+ ret = drm_dev_register(dev, 0);
1385+ if (ret)
1386+ return ret;
1387+
1388+ /*
1389+ * FIXME: 24-bit color depth does not work reliably with a 32-bpp
1390+ * value. Force the bpp value of the scanout buffer's format.
1391+ */
1392+ drm_fbdev_generic_setup(dev, drm_format_info_bpp(odev->format, 0));
1393+
1394+ return 0;
1395+}
1396+
1397+static int ofdrm_remove(struct platform_device *pdev)
1398+{
1399+ struct drm_device *dev = platform_get_drvdata(pdev);
1400+
1401+ drm_dev_unplug(dev);
1402+
1403+ return 0;
1404+}
1405+
1406+static const struct of_device_id ofdrm_of_match_display[] = {
1407+ { .compatible = "display", },
1408+ { },
1409+};
1410+MODULE_DEVICE_TABLE(of, ofdrm_of_match_display);
1411+
1412+static struct platform_driver ofdrm_platform_driver = {
1413+ .driver = {
1414+ .name = "of-display",
1415+ .of_match_table = ofdrm_of_match_display,
1416+ },
1417+ .probe = ofdrm_probe,
1418+ .remove = ofdrm_remove,
1419+};
1420+
1421+module_platform_driver(ofdrm_platform_driver);
1422+
1423+MODULE_DESCRIPTION(DRIVER_DESC);
1424+MODULE_LICENSE("GPL");
drivers/gpu/drm/tiny/simpledrm.c+2−14
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <drm/drm_atomic.h>
1212 #include <drm/drm_atomic_state_helper.h>
1313 #include <drm/drm_connector.h>
14+#include <drm/drm_crtc_helper.h>
1415 #include <drm/drm_damage_helper.h>
1516 #include <drm/drm_device.h>
1617 #include <drm/drm_drv.h>
@@ -545,19 +546,6 @@ static enum drm_mode_status simpledrm_crtc_helper_mode_valid(struct drm_crtc *cr · 528 unmodified lines
545546 return drm_crtc_helper_mode_valid_fixed(crtc, mode, &sdev->mode);
546547 }
547548
548−static int simpledrm_crtc_helper_atomic_check(struct drm_crtc *crtc,
549− struct drm_atomic_state *new_state)
550−{
551− struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc);
552− int ret;
553−
554− ret = drm_atomic_helper_check_crtc_state(new_crtc_state, false);
555− if (ret)
556− return ret;
557−
558− return drm_atomic_add_affected_planes(new_state, crtc);
559−}
560−
561549 /*
562550 * The CRTC is always enabled. Screen updates are performed by
563551 * the primary plane's atomic_update function. Disabling clears
@@ -565,7 +553,7 @@ static int simpledrm_crtc_helper_atomic_check(struct drm_crtc *crtc, · 1 unmodified line
565553 */
566554 static const struct drm_crtc_helper_funcs simpledrm_crtc_helper_funcs = {
567555 .mode_valid = simpledrm_crtc_helper_mode_valid,
568− .atomic_check = simpledrm_crtc_helper_atomic_check,
556+ .atomic_check = drm_crtc_helper_atomic_check,
569557 };
570558
571559 static const struct drm_crtc_funcs simpledrm_crtc_funcs = {
drivers/gpu/drm/ttm/ttm_range_manager.c+0−1
@@ -229,7 +229,6 @@ int ttm_range_man_fini_nocheck(struct ttm_device *bdev, · 228 unmodified lines
229229 return ret;
230230
231231 spin_lock(&rman->lock);
232− drm_mm_clean(mm);
233232 drm_mm_takedown(mm);
234233 spin_unlock(&rman->lock);
235234
drivers/gpu/drm/udl/Makefile+1−1
@@ -1,4 +1,4 @@
11 # SPDX-License-Identifier: GPL-2.0-only
2−udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_main.o udl_transfer.o
2+udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o
33
44 obj-$(CONFIG_DRM_UDL) := udl.o
drivers/gpu/drm/udl/udl_connector.c+0−139
@@ -1,139 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-only
2−/*
3− * Copyright (C) 2012 Red Hat
4− * based in parts on udlfb.c:
5− * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
6− * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
7− * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
8− */
9−
10−#include <drm/drm_atomic_state_helper.h>
11−#include <drm/drm_edid.h>
12−#include <drm/drm_crtc_helper.h>
13−#include <drm/drm_probe_helper.h>
14−
15−#include "udl_connector.h"
16−#include "udl_drv.h"
17−
18−static int udl_get_edid_block(void *data, u8 *buf, unsigned int block,
19− size_t len)
20−{
21− int ret, i;
22− u8 *read_buff;
23− struct udl_device *udl = data;
24− struct usb_device *udev = udl_to_usb_device(udl);
25−
26− read_buff = kmalloc(2, GFP_KERNEL);
27− if (!read_buff)
28− return -1;
29−
30− for (i = 0; i < len; i++) {
31− int bval = (i + block * EDID_LENGTH) << 8;
32− ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
33− 0x02, (0x80 | (0x02 << 5)), bval,
34− 0xA1, read_buff, 2, 1000);
35− if (ret < 1) {
36− DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret);
37− kfree(read_buff);
38− return -1;
39− }
40− buf[i] = read_buff[1];
41− }
42−
43− kfree(read_buff);
44− return 0;
45−}
46−
47−static int udl_get_modes(struct drm_connector *connector)
48−{
49− struct udl_drm_connector *udl_connector =
50− container_of(connector,
51− struct udl_drm_connector,
52− connector);
53−
54− drm_connector_update_edid_property(connector, udl_connector->edid);
55− if (udl_connector->edid)
56− return drm_add_edid_modes(connector, udl_connector->edid);
57− return 0;
58−}
59−
60−static enum drm_mode_status udl_mode_valid(struct drm_connector *connector,
61− struct drm_display_mode *mode)
62−{
63− struct udl_device *udl = to_udl(connector->dev);
64− if (!udl->sku_pixel_limit)
65− return 0;
66−
67− if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
68− return MODE_VIRTUAL_Y;
69−
70− return 0;
71−}
72−
73−static enum drm_connector_status
74−udl_detect(struct drm_connector *connector, bool force)
75−{
76− struct udl_device *udl = to_udl(connector->dev);
77− struct udl_drm_connector *udl_connector =
78− container_of(connector,
79− struct udl_drm_connector,
80− connector);
81−
82− /* cleanup previous edid */
83− if (udl_connector->edid != NULL) {
84− kfree(udl_connector->edid);
85− udl_connector->edid = NULL;
86− }
87−
88− udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl);
89− if (!udl_connector->edid)
90− return connector_status_disconnected;
91−
92− return connector_status_connected;
93−}
94−
95−static void udl_connector_destroy(struct drm_connector *connector)
96−{
97− struct udl_drm_connector *udl_connector =
98− container_of(connector,
99− struct udl_drm_connector,
100− connector);
101−
102− drm_connector_cleanup(connector);
103− kfree(udl_connector->edid);
104− kfree(connector);
105−}
106−
107−static const struct drm_connector_helper_funcs udl_connector_helper_funcs = {
108− .get_modes = udl_get_modes,
109− .mode_valid = udl_mode_valid,
110−};
111−
112−static const struct drm_connector_funcs udl_connector_funcs = {
113− .reset = drm_atomic_helper_connector_reset,
114− .detect = udl_detect,
115− .fill_modes = drm_helper_probe_single_connector_modes,
116− .destroy = udl_connector_destroy,
117− .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
118− .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
119−};
120−
121−struct drm_connector *udl_connector_init(struct drm_device *dev)
122−{
123− struct udl_drm_connector *udl_connector;
124− struct drm_connector *connector;
125−
126− udl_connector = kzalloc(sizeof(struct udl_drm_connector), GFP_KERNEL);
127− if (!udl_connector)
128− return ERR_PTR(-ENOMEM);
129−
130− connector = &udl_connector->connector;
131− drm_connector_init(dev, connector, &udl_connector_funcs,
132− DRM_MODE_CONNECTOR_VGA);
133− drm_connector_helper_add(connector, &udl_connector_helper_funcs);
134−
135− connector->polled = DRM_CONNECTOR_POLL_HPD |
136− DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
137−
138− return connector;
139−}
drivers/gpu/drm/udl/udl_connector.h+0−15
@@ -1,15 +0,0 @@
1−#ifndef __UDL_CONNECTOR_H__
2−#define __UDL_CONNECTOR_H__
3−
4−#include <drm/drm_crtc.h>
5−
6−struct edid;
7−
8−struct udl_drm_connector {
9− struct drm_connector connector;
10− /* last udl_detect edid */
11− struct edid *edid;
12−};
13−
14−
15−#endif //__UDL_CONNECTOR_H__
drivers/gpu/drm/udl/udl_drv.h+18−24
@@ -14,10 +14,13 @@ · 13 unmodified lines
1414 #include <linux/mm_types.h>
1515 #include <linux/usb.h>
1616
17+#include <drm/drm_connector.h>
18+#include <drm/drm_crtc.h>
1719 #include <drm/drm_device.h>
20+#include <drm/drm_encoder.h>
1821 #include <drm/drm_framebuffer.h>
1922 #include <drm/drm_gem.h>
20−#include <drm/drm_simple_kms_helper.h>
23+#include <drm/drm_plane.h>
2124
2225 struct drm_mode_create_dumb;
2326
@@ -46,21 +49,31 @@ struct urb_list { · 22 unmodified lines
4649 size_t size;
4750 };
4851
52+struct udl_connector {
53+ struct drm_connector connector;
54+ /* last udl_detect edid */
55+ struct edid *edid;
56+};
57+
58+static inline struct udl_connector *to_udl_connector(struct drm_connector *connector)
59+{
60+ return container_of(connector, struct udl_connector, connector);
61+}
62+
4963 struct udl_device {
5064 struct drm_device drm;
5165 struct device *dev;
5266 struct device *dmadev;
5367
54− struct drm_simple_display_pipe display_pipe;
68+ struct drm_plane primary_plane;
69+ struct drm_crtc crtc;
70+ struct drm_encoder encoder;
5571
5672 struct mutex gem_lock;
5773
5874 int sku_pixel_limit;
5975
6076 struct urb_list urbs;
61−
62− char mode_buf[1024];
63− uint32_t mode_buf_len;
6477 };
6578
6679 #define to_udl(x) container_of(x, struct udl_device, drm)
@@ -89,23 +102,4 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, · 22 unmodified lines
89102 int udl_drop_usb(struct drm_device *dev);
90103 int udl_select_std_channel(struct udl_device *udl);
91104
92−#define CMD_WRITE_RAW8 "\xAF\x60" /**< 8 bit raw write command. */
93−#define CMD_WRITE_RL8 "\xAF\x61" /**< 8 bit run length command. */
94−#define CMD_WRITE_COPY8 "\xAF\x62" /**< 8 bit copy command. */
95−#define CMD_WRITE_RLX8 "\xAF\x63" /**< 8 bit extended run length command. */
96−
97−#define CMD_WRITE_RAW16 "\xAF\x68" /**< 16 bit raw write command. */
98−#define CMD_WRITE_RL16 "\xAF\x69" /**< 16 bit run length command. */
99−#define CMD_WRITE_COPY16 "\xAF\x6A" /**< 16 bit copy command. */
100−#define CMD_WRITE_RLX16 "\xAF\x6B" /**< 16 bit extended run length command. */
101−
102−/* On/Off for driving the DisplayLink framebuffer to the display */
103−#define UDL_REG_BLANK_MODE 0x1f
104−
105−#define UDL_BLANK_MODE_ON 0x00 /* hsync and vsync on, visible */
106−#define UDL_BLANK_MODE_BLANKED 0x01 /* hsync and vsync on, blanked */
107−#define UDL_BLANK_MODE_VSYNC_OFF 0x03 /* vsync off, blanked */
108−#define UDL_BLANK_MODE_HSYNC_OFF 0x05 /* hsync off, blanked */
109−#define UDL_BLANK_MODE_POWERDOWN 0x07 /* powered off; requires modeset */
110−
111105 #endif
drivers/gpu/drm/udl/udl_modeset.c+363−203
@@ -8,70 +8,91 @@ · 7 unmodified lines
88 * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
99 */
1010
11+#include <linux/bitfield.h>
12+
13+#include <drm/drm_atomic.h>
1114 #include <drm/drm_atomic_helper.h>
1215 #include <drm/drm_crtc_helper.h>
1316 #include <drm/drm_damage_helper.h>
17+#include <drm/drm_drv.h>
18+#include <drm/drm_edid.h>
1419 #include <drm/drm_fourcc.h>
1520 #include <drm/drm_gem_atomic_helper.h>
1621 #include <drm/drm_gem_framebuffer_helper.h>
1722 #include <drm/drm_gem_shmem_helper.h>
1823 #include <drm/drm_modeset_helper_vtables.h>
24+#include <drm/drm_plane_helper.h>
25+#include <drm/drm_probe_helper.h>
1926 #include <drm/drm_vblank.h>
2027
2128 #include "udl_drv.h"
22−
23−#define UDL_COLOR_DEPTH_16BPP 0
29+#include "udl_proto.h"
2430
2531 /*
26− * All DisplayLink bulk operations start with 0xAF, followed by specific code
27− * All operations are written to buffers which then later get sent to device
32+ * All DisplayLink bulk operations start with 0xaf (UDL_MSG_BULK), followed by
33+ * a specific command code. All operations are written to a command buffer, which
34+ * the driver sends to the device.
2835 */
2936 static char *udl_set_register(char *buf, u8 reg, u8 val)
3037 {
31− *buf++ = 0xAF;
32− *buf++ = 0x20;
38+ *buf++ = UDL_MSG_BULK;
39+ *buf++ = UDL_CMD_WRITEREG;
3340 *buf++ = reg;
3441 *buf++ = val;
42+
3543 return buf;
3644 }
3745
3846 static char *udl_vidreg_lock(char *buf)
3947 {
40− return udl_set_register(buf, 0xFF, 0x00);
48+ return udl_set_register(buf, UDL_REG_VIDREG, UDL_VIDREG_LOCK);
4149 }
4250
4351 static char *udl_vidreg_unlock(char *buf)
4452 {
45− return udl_set_register(buf, 0xFF, 0xFF);
53+ return udl_set_register(buf, UDL_REG_VIDREG, UDL_VIDREG_UNLOCK);
4654 }
4755
4856 static char *udl_set_blank_mode(char *buf, u8 mode)
4957 {
50− return udl_set_register(buf, UDL_REG_BLANK_MODE, mode);
58+ return udl_set_register(buf, UDL_REG_BLANKMODE, mode);
5159 }
5260
5361 static char *udl_set_color_depth(char *buf, u8 selection)
5462 {
55− return udl_set_register(buf, 0x00, selection);
63+ return udl_set_register(buf, UDL_REG_COLORDEPTH, selection);
5664 }
5765
58−static char *udl_set_base16bpp(char *wrptr, u32 base)
66+static char *udl_set_base16bpp(char *buf, u32 base)
5967 {
60− /* the base pointer is 16 bits wide, 0x20 is hi byte. */
61− wrptr = udl_set_register(wrptr, 0x20, base >> 16);
62− wrptr = udl_set_register(wrptr, 0x21, base >> 8);
63− return udl_set_register(wrptr, 0x22, base);
68+ /* the base pointer is 24 bits wide, 0x20 is hi byte. */
69+ u8 reg20 = FIELD_GET(UDL_BASE_ADDR2_MASK, base);
70+ u8 reg21 = FIELD_GET(UDL_BASE_ADDR1_MASK, base);
71+ u8 reg22 = FIELD_GET(UDL_BASE_ADDR0_MASK, base);
72+
73+ buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR2, reg20);
74+ buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR1, reg21);
75+ buf = udl_set_register(buf, UDL_REG_BASE16BPP_ADDR0, reg22);
76+
77+ return buf;
6478 }
6579
6680 /*
6781 * DisplayLink HW has separate 16bpp and 8bpp framebuffers.
6882 * In 24bpp modes, the low 323 RGB bits go in the 8bpp framebuffer
6983 */
70−static char *udl_set_base8bpp(char *wrptr, u32 base)
84+static char *udl_set_base8bpp(char *buf, u32 base)
7185 {
72− wrptr = udl_set_register(wrptr, 0x26, base >> 16);
73− wrptr = udl_set_register(wrptr, 0x27, base >> 8);
74− return udl_set_register(wrptr, 0x28, base);
86+ /* the base pointer is 24 bits wide, 0x26 is hi byte. */
87+ u8 reg26 = FIELD_GET(UDL_BASE_ADDR2_MASK, base);
88+ u8 reg27 = FIELD_GET(UDL_BASE_ADDR1_MASK, base);
89+ u8 reg28 = FIELD_GET(UDL_BASE_ADDR0_MASK, base);
90+
91+ buf = udl_set_register(buf, UDL_REG_BASE8BPP_ADDR2, reg26);
92+ buf = udl_set_register(buf, UDL_REG_BASE8BPP_ADDR1, reg27);
93+ buf = udl_set_register(buf, UDL_REG_BASE8BPP_ADDR0, reg28);
94+
95+ return buf;
7596 }
7697
7798 static char *udl_set_register_16(char *wrptr, u8 reg, u16 value)
@@ -122,84 +143,46 @@ static char *udl_set_register_lfsr16(char *wrptr, u8 reg, u16 value) · 44 unmodified lines
122143 }
123144
124145 /*
125− * This takes a standard fbdev screeninfo struct and all of its monitor mode
126− * details and converts them into the DisplayLink equivalent register commands.
127− ERR(vreg(dev, 0x00, (color_depth == 16) ? 0 : 1));
128− ERR(vreg_lfsr16(dev, 0x01, xDisplayStart));
129− ERR(vreg_lfsr16(dev, 0x03, xDisplayEnd));
130− ERR(vreg_lfsr16(dev, 0x05, yDisplayStart));
131− ERR(vreg_lfsr16(dev, 0x07, yDisplayEnd));
132− ERR(vreg_lfsr16(dev, 0x09, xEndCount));
133− ERR(vreg_lfsr16(dev, 0x0B, hSyncStart));
134− ERR(vreg_lfsr16(dev, 0x0D, hSyncEnd));
135− ERR(vreg_big_endian(dev, 0x0F, hPixels));
136− ERR(vreg_lfsr16(dev, 0x11, yEndCount));
137− ERR(vreg_lfsr16(dev, 0x13, vSyncStart));
138− ERR(vreg_lfsr16(dev, 0x15, vSyncEnd));
139− ERR(vreg_big_endian(dev, 0x17, vPixels));
140− ERR(vreg_little_endian(dev, 0x1B, pixelClock5KHz));
141−
142− ERR(vreg(dev, 0x1F, 0));
143−
144− ERR(vbuf(dev, WRITE_VIDREG_UNLOCK, DSIZEOF(WRITE_VIDREG_UNLOCK)));
146+ * Takes a DRM display mode and converts it into the DisplayLink
147+ * equivalent register commands.
145148 */
146−static char *udl_set_vid_cmds(char *wrptr, struct drm_display_mode *mode)
149+static char *udl_set_display_mode(char *buf, struct drm_display_mode *mode)
147150 {
148− u16 xds, yds;
149− u16 xde, yde;
150− u16 yec;
151−
152− /* x display start */
153− xds = mode->crtc_htotal - mode->crtc_hsync_start;
154− wrptr = udl_set_register_lfsr16(wrptr, 0x01, xds);
155− /* x display end */
156− xde = xds + mode->crtc_hdisplay;
157− wrptr = udl_set_register_lfsr16(wrptr, 0x03, xde);
158−
159− /* y display start */
160− yds = mode->crtc_vtotal - mode->crtc_vsync_start;
161− wrptr = udl_set_register_lfsr16(wrptr, 0x05, yds);
162− /* y display end */
163− yde = yds + mode->crtc_vdisplay;
164− wrptr = udl_set_register_lfsr16(wrptr, 0x07, yde);
165−
166− /* x end count is active + blanking - 1 */
167− wrptr = udl_set_register_lfsr16(wrptr, 0x09,
168− mode->crtc_htotal - 1);
151+ u16 reg01 = mode->crtc_htotal - mode->crtc_hsync_start;
152+ u16 reg03 = reg01 + mode->crtc_hdisplay;
153+ u16 reg05 = mode->crtc_vtotal - mode->crtc_vsync_start;
154+ u16 reg07 = reg05 + mode->crtc_vdisplay;
155+ u16 reg09 = mode->crtc_htotal - 1;
156+ u16 reg0b = 1; /* libdlo hardcodes hsync start to 1 */
157+ u16 reg0d = mode->crtc_hsync_end - mode->crtc_hsync_start + 1;
158+ u16 reg0f = mode->hdisplay;
159+ u16 reg11 = mode->crtc_vtotal;
160+ u16 reg13 = 0; /* libdlo hardcodes vsync start to 0 */
161+ u16 reg15 = mode->crtc_vsync_end - mode->crtc_vsync_start;
162+ u16 reg17 = mode->crtc_vdisplay;
163+ u16 reg1b = mode->clock / 5;
164+
165+ buf = udl_set_register_lfsr16(buf, UDL_REG_XDISPLAYSTART, reg01);
166+ buf = udl_set_register_lfsr16(buf, UDL_REG_XDISPLAYEND, reg03);
167+ buf = udl_set_register_lfsr16(buf, UDL_REG_YDISPLAYSTART, reg05);
168+ buf = udl_set_register_lfsr16(buf, UDL_REG_YDISPLAYEND, reg07);
169+ buf = udl_set_register_lfsr16(buf, UDL_REG_XENDCOUNT, reg09);
170+ buf = udl_set_register_lfsr16(buf, UDL_REG_HSYNCSTART, reg0b);
171+ buf = udl_set_register_lfsr16(buf, UDL_REG_HSYNCEND, reg0d);
172+ buf = udl_set_register_16(buf, UDL_REG_HPIXELS, reg0f);
173+ buf = udl_set_register_lfsr16(buf, UDL_REG_YENDCOUNT, reg11);
174+ buf = udl_set_register_lfsr16(buf, UDL_REG_VSYNCSTART, reg13);
175+ buf = udl_set_register_lfsr16(buf, UDL_REG_VSYNCEND, reg15);
176+ buf = udl_set_register_16(buf, UDL_REG_VPIXELS, reg17);
177+ buf = udl_set_register_16be(buf, UDL_REG_PIXELCLOCK5KHZ, reg1b);
169178
170− /* libdlo hardcodes hsync start to 1 */
171− wrptr = udl_set_register_lfsr16(wrptr, 0x0B, 1);
172−
173− /* hsync end is width of sync pulse + 1 */
174− wrptr = udl_set_register_lfsr16(wrptr, 0x0D,
175− mode->crtc_hsync_end - mode->crtc_hsync_start + 1);
176−
177− /* hpixels is active pixels */
178− wrptr = udl_set_register_16(wrptr, 0x0F, mode->hdisplay);
179−
180− /* yendcount is vertical active + vertical blanking */
181− yec = mode->crtc_vtotal;
182− wrptr = udl_set_register_lfsr16(wrptr, 0x11, yec);
183−
184− /* libdlo hardcodes vsync start to 0 */
185− wrptr = udl_set_register_lfsr16(wrptr, 0x13, 0);
186−
187− /* vsync end is width of vsync pulse */
188− wrptr = udl_set_register_lfsr16(wrptr, 0x15, mode->crtc_vsync_end - mode->crtc_vsync_start);
189−
190− /* vpixels is active pixels */
191− wrptr = udl_set_register_16(wrptr, 0x17, mode->crtc_vdisplay);
192−
193− wrptr = udl_set_register_16be(wrptr, 0x1B,
194− mode->clock / 5);
195−
196− return wrptr;
179+ return buf;
197180 }
198181
199182 static char *udl_dummy_render(char *wrptr)
200183 {
201− *wrptr++ = 0xAF;
202− *wrptr++ = 0x6A; /* copy */
184+ *wrptr++ = UDL_MSG_BULK;
185+ *wrptr++ = UDL_CMD_WRITECOPY16;
203186 *wrptr++ = 0x00; /* from addr */
204187 *wrptr++ = 0x00;
205188 *wrptr++ = 0x00;
@@ -210,31 +193,6 @@ static char *udl_dummy_render(char *wrptr) · 4 unmodified lines
210193 return wrptr;
211194 }
212195
213−static int udl_crtc_write_mode_to_hw(struct drm_crtc *crtc)
214−{
215− struct drm_device *dev = crtc->dev;
216− struct udl_device *udl = to_udl(dev);
217− struct urb *urb;
218− char *buf;
219− int retval;
220−
221− if (udl->mode_buf_len == 0) {
222− DRM_ERROR("No mode set\n");
223− return -EINVAL;
224− }
225−
226− urb = udl_get_urb(dev);
227− if (!urb)
228− return -ENOMEM;
229−
230− buf = (char *)urb->transfer_buffer;
231−
232− memcpy(buf, udl->mode_buf, udl->mode_buf_len);
233− retval = udl_submit_urb(dev, urb, udl->mode_buf_len);
234− DRM_DEBUG("write mode info %d\n", udl->mode_buf_len);
235− return retval;
236−}
237−
238196 static long udl_log_cpp(unsigned int cpp)
239197 {
240198 if (WARN_ON(!is_power_of_2(cpp)))
@@ -258,15 +216,9 @@ static int udl_handle_damage(struct drm_framebuffer *fb, · 17 unmodified lines
258216 return ret;
259217 log_bpp = ret;
260218
261− ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
262− if (ret)
263− return ret;
264−
265219 urb = udl_get_urb(dev);
266− if (!urb) {
267− ret = -ENOMEM;
268− goto out_drm_gem_fb_end_cpu_access;
269− }
220+ if (!urb)
221+ return -ENOMEM;
270222 cmd = urb->transfer_buffer;
271223
272224 for (i = clip->y1; i < clip->y2; i++) {
@@ -278,145 +230,339 @@ static int udl_handle_damage(struct drm_framebuffer *fb, · 5 unmodified lines
278230 &cmd, byte_offset, dev_byte_offset,
279231 byte_width);
280232 if (ret)
281− goto out_drm_gem_fb_end_cpu_access;
233+ return ret;
282234 }
283235
284236 if (cmd > (char *)urb->transfer_buffer) {
285237 /* Send partial buffer remaining before exiting */
286238 int len;
287239 if (cmd < (char *)urb->transfer_buffer + urb->transfer_buffer_length)
288− *cmd++ = 0xAF;
240+ *cmd++ = UDL_MSG_BULK;
289241 len = cmd - (char *)urb->transfer_buffer;
290242 ret = udl_submit_urb(dev, urb, len);
291243 } else {
292244 udl_urb_completion(urb);
293245 }
294246
295− ret = 0;
296−
297−out_drm_gem_fb_end_cpu_access:
298− drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
299− return ret;
247+ return 0;
300248 }
301249
302250 /*
303− * Simple display pipeline
251+ * Primary plane
304252 */
305253
306−static const uint32_t udl_simple_display_pipe_formats[] = {
254+static const uint32_t udl_primary_plane_formats[] = {
307255 DRM_FORMAT_RGB565,
308256 DRM_FORMAT_XRGB8888,
309257 };
310258
311−static enum drm_mode_status
312−udl_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
313− const struct drm_display_mode *mode)
259+static const uint64_t udl_primary_plane_fmtmods[] = {
260+ DRM_FORMAT_MOD_LINEAR,
261+ DRM_FORMAT_MOD_INVALID
262+};
263+
264+static void udl_primary_plane_helper_atomic_update(struct drm_plane *plane,
265+ struct drm_atomic_state *state)
314266 {
315− return MODE_OK;
267+ struct drm_device *dev = plane->dev;
268+ struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
269+ struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
270+ struct drm_framebuffer *fb = plane_state->fb;
271+ struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
272+ struct drm_atomic_helper_damage_iter iter;
273+ struct drm_rect damage;
274+ int ret, idx;
275+
276+ if (!fb)
277+ return; /* no framebuffer; plane is disabled */
278+
279+ ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
280+ if (ret)
281+ return;
282+
283+ if (!drm_dev_enter(dev, &idx))
284+ goto out_drm_gem_fb_end_cpu_access;
285+
286+ drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
287+ drm_atomic_for_each_plane_damage(&iter, &damage) {
288+ udl_handle_damage(fb, &shadow_plane_state->data[0], &damage);
289+ }
290+
291+ drm_dev_exit(idx);
292+
293+out_drm_gem_fb_end_cpu_access:
294+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
295+}
296+
297+static const struct drm_plane_helper_funcs udl_primary_plane_helper_funcs = {
298+ DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
299+ .atomic_check = drm_plane_helper_atomic_check,
300+ .atomic_update = udl_primary_plane_helper_atomic_update,
301+};
302+
303+static const struct drm_plane_funcs udl_primary_plane_funcs = {
304+ .update_plane = drm_atomic_helper_update_plane,
305+ .disable_plane = drm_atomic_helper_disable_plane,
306+ .destroy = drm_plane_cleanup,
307+ DRM_GEM_SHADOW_PLANE_FUNCS,
308+};
309+
310+/*
311+ * CRTC
312+ */
313+
314+static int udl_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
315+{
316+ struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
317+
318+ if (!new_crtc_state->enable)
319+ return 0;
320+
321+ return drm_atomic_helper_check_crtc_primary_plane(new_crtc_state);
316322 }
317323
318−static void
319−udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
320− struct drm_crtc_state *crtc_state,
321− struct drm_plane_state *plane_state)
324+static void udl_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
322325 {
323− struct drm_crtc *crtc = &pipe->crtc;
324326 struct drm_device *dev = crtc->dev;
325− struct drm_framebuffer *fb = plane_state->fb;
326− struct udl_device *udl = to_udl(dev);
327+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
327328 struct drm_display_mode *mode = &crtc_state->mode;
328− struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
329− struct drm_rect clip = DRM_RECT_INIT(0, 0, fb->width, fb->height);
329+ struct urb *urb;
330330 char *buf;
331− char *wrptr;
332− int color_depth = UDL_COLOR_DEPTH_16BPP;
331+ int idx;
333332
334− buf = (char *)udl->mode_buf;
333+ if (!drm_dev_enter(dev, &idx))
334+ return;
335335
336− /* This first section has to do with setting the base address on the
337− * controller associated with the display. There are 2 base
338− * pointers, currently, we only use the 16 bpp segment.
339− */
340− wrptr = udl_vidreg_lock(buf);
341− wrptr = udl_set_color_depth(wrptr, color_depth);
336+ urb = udl_get_urb(dev);
337+ if (!urb)
338+ goto out;
339+
340+ buf = (char *)urb->transfer_buffer;
341+ buf = udl_vidreg_lock(buf);
342+ buf = udl_set_color_depth(buf, UDL_COLORDEPTH_16BPP);
342343 /* set base for 16bpp segment to 0 */
343− wrptr = udl_set_base16bpp(wrptr, 0);
344+ buf = udl_set_base16bpp(buf, 0);
344345 /* set base for 8bpp segment to end of fb */
345− wrptr = udl_set_base8bpp(wrptr, 2 * mode->vdisplay * mode->hdisplay);
346−
347− wrptr = udl_set_vid_cmds(wrptr, mode);
348− wrptr = udl_set_blank_mode(wrptr, UDL_BLANK_MODE_ON);
349− wrptr = udl_vidreg_unlock(wrptr);
350−
351− wrptr = udl_dummy_render(wrptr);
352−
353− udl->mode_buf_len = wrptr - buf;
346+ buf = udl_set_base8bpp(buf, 2 * mode->vdisplay * mode->hdisplay);
347+ buf = udl_set_display_mode(buf, mode);
348+ buf = udl_set_blank_mode(buf, UDL_BLANKMODE_ON);
349+ buf = udl_vidreg_unlock(buf);
350+ buf = udl_dummy_render(buf);
354351
355− udl_handle_damage(fb, &shadow_plane_state->data[0], &clip);
352+ udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer);
356353
357− /* enable display */
358− udl_crtc_write_mode_to_hw(crtc);
354+out:
355+ drm_dev_exit(idx);
359356 }
360357
361−static void
362−udl_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
358+static void udl_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
363359 {
364− struct drm_crtc *crtc = &pipe->crtc;
365360 struct drm_device *dev = crtc->dev;
366361 struct urb *urb;
367362 char *buf;
363+ int idx;
364+
365+ if (!drm_dev_enter(dev, &idx))
366+ return;
368367
369368 urb = udl_get_urb(dev);
370369 if (!urb)
371− return;
370+ goto out;
372371
373372 buf = (char *)urb->transfer_buffer;
374373 buf = udl_vidreg_lock(buf);
375− buf = udl_set_blank_mode(buf, UDL_BLANK_MODE_POWERDOWN);
374+ buf = udl_set_blank_mode(buf, UDL_BLANKMODE_POWERDOWN);
376375 buf = udl_vidreg_unlock(buf);
377376 buf = udl_dummy_render(buf);
378377
379378 udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer);
379+
380+out:
381+ drm_dev_exit(idx);
382+}
383+
384+static const struct drm_crtc_helper_funcs udl_crtc_helper_funcs = {
385+ .atomic_check = udl_crtc_helper_atomic_check,
386+ .atomic_enable = udl_crtc_helper_atomic_enable,
387+ .atomic_disable = udl_crtc_helper_atomic_disable,
388+};
389+
390+static const struct drm_crtc_funcs udl_crtc_funcs = {
391+ .reset = drm_atomic_helper_crtc_reset,
392+ .destroy = drm_crtc_cleanup,
393+ .set_config = drm_atomic_helper_set_config,
394+ .page_flip = drm_atomic_helper_page_flip,
395+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
396+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
397+};
398+
399+/*
400+ * Encoder
401+ */
402+
403+static const struct drm_encoder_funcs udl_encoder_funcs = {
404+ .destroy = drm_encoder_cleanup,
405+};
406+
407+/*
408+ * Connector
409+ */
410+
411+static int udl_connector_helper_get_modes(struct drm_connector *connector)
412+{
413+ struct udl_connector *udl_connector = to_udl_connector(connector);
414+
415+ drm_connector_update_edid_property(connector, udl_connector->edid);
416+ if (udl_connector->edid)
417+ return drm_add_edid_modes(connector, udl_connector->edid);
418+
419+ return 0;
380420 }
381421
382−static void
383−udl_simple_display_pipe_update(struct drm_simple_display_pipe *pipe,
384− struct drm_plane_state *old_plane_state)
422+static const struct drm_connector_helper_funcs udl_connector_helper_funcs = {
423+ .get_modes = udl_connector_helper_get_modes,
424+};
425+
426+static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
385427 {
386− struct drm_plane_state *state = pipe->plane.state;
387− struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
388− struct drm_framebuffer *fb = state->fb;
389− struct drm_rect rect;
428+ struct udl_device *udl = data;
429+ struct drm_device *dev = &udl->drm;
430+ struct usb_device *udev = udl_to_usb_device(udl);
431+ u8 *read_buff;
432+ int ret;
433+ size_t i;
390434
391− if (!fb)
392− return;
435+ read_buff = kmalloc(2, GFP_KERNEL);
436+ if (!read_buff)
437+ return -ENOMEM;
438+
439+ for (i = 0; i < len; i++) {
440+ int bval = (i + block * EDID_LENGTH) << 8;
441+
442+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
443+ 0x02, (0x80 | (0x02 << 5)), bval,
444+ 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT);
445+ if (ret < 0) {
446+ drm_err(dev, "Read EDID byte %zu failed err %x\n", i, ret);
447+ goto err_kfree;
448+ } else if (ret < 1) {
449+ ret = -EIO;
450+ drm_err(dev, "Read EDID byte %zu failed\n", i);
451+ goto err_kfree;
452+ }
453+
454+ buf[i] = read_buff[1];
455+ }
456+
457+ kfree(read_buff);
458+
459+ return 0;
460+
461+err_kfree:
462+ kfree(read_buff);
463+ return ret;
464+}
465+
466+static enum drm_connector_status udl_connector_detect(struct drm_connector *connector, bool force)
467+{
468+ struct drm_device *dev = connector->dev;
469+ struct udl_device *udl = to_udl(dev);
470+ struct udl_connector *udl_connector = to_udl_connector(connector);
471+ enum drm_connector_status status = connector_status_disconnected;
472+ int idx;
473+
474+ /* cleanup previous EDID */
475+ kfree(udl_connector->edid);
476+ udl_connector->edid = NULL;
477+
478+ if (!drm_dev_enter(dev, &idx))
479+ return connector_status_disconnected;
480+
481+ udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl);
482+ if (udl_connector->edid)
483+ status = connector_status_connected;
484+
485+ drm_dev_exit(idx);
486+
487+ return status;
488+}
393489
394− if (drm_atomic_helper_damage_merged(old_plane_state, state, &rect))
395− udl_handle_damage(fb, &shadow_plane_state->data[0], &rect);
490+static void udl_connector_destroy(struct drm_connector *connector)
491+{
492+ struct udl_connector *udl_connector = to_udl_connector(connector);
493+
494+ drm_connector_cleanup(connector);
495+ kfree(udl_connector->edid);
496+ kfree(udl_connector);
396497 }
397498
398−static const struct drm_simple_display_pipe_funcs udl_simple_display_pipe_funcs = {
399− .mode_valid = udl_simple_display_pipe_mode_valid,
400− .enable = udl_simple_display_pipe_enable,
401− .disable = udl_simple_display_pipe_disable,
402− .update = udl_simple_display_pipe_update,
403− DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
499+static const struct drm_connector_funcs udl_connector_funcs = {
500+ .reset = drm_atomic_helper_connector_reset,
501+ .detect = udl_connector_detect,
502+ .fill_modes = drm_helper_probe_single_connector_modes,
503+ .destroy = udl_connector_destroy,
504+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
505+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
404506 };
405507
508+struct drm_connector *udl_connector_init(struct drm_device *dev)
509+{
510+ struct udl_connector *udl_connector;
511+ struct drm_connector *connector;
512+ int ret;
513+
514+ udl_connector = kzalloc(sizeof(*udl_connector), GFP_KERNEL);
515+ if (!udl_connector)
516+ return ERR_PTR(-ENOMEM);
517+
518+ connector = &udl_connector->connector;
519+ ret = drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_VGA);
520+ if (ret)
521+ goto err_kfree;
522+
523+ drm_connector_helper_add(connector, &udl_connector_helper_funcs);
524+
525+ connector->polled = DRM_CONNECTOR_POLL_HPD |
526+ DRM_CONNECTOR_POLL_CONNECT |
527+ DRM_CONNECTOR_POLL_DISCONNECT;
528+
529+ return connector;
530+
531+err_kfree:
532+ kfree(udl_connector);
533+ return ERR_PTR(ret);
534+}
535+
406536 /*
407537 * Modesetting
408538 */
409539
410−static const struct drm_mode_config_funcs udl_mode_funcs = {
540+static enum drm_mode_status udl_mode_config_mode_valid(struct drm_device *dev,
541+ const struct drm_display_mode *mode)
542+{
543+ struct udl_device *udl = to_udl(dev);
544+
545+ if (udl->sku_pixel_limit) {
546+ if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
547+ return MODE_MEM;
548+ }
549+
550+ return MODE_OK;
551+}
552+
553+static const struct drm_mode_config_funcs udl_mode_config_funcs = {
411554 .fb_create = drm_gem_fb_create_with_dirty,
555+ .mode_valid = udl_mode_config_mode_valid,
412556 .atomic_check = drm_atomic_helper_check,
413557 .atomic_commit = drm_atomic_helper_commit,
414558 };
415559
416560 int udl_modeset_init(struct drm_device *dev)
417561 {
418− size_t format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
419562 struct udl_device *udl = to_udl(dev);
563+ struct drm_plane *primary_plane;
564+ struct drm_crtc *crtc;
565+ struct drm_encoder *encoder;
420566 struct drm_connector *connector;
421567 int ret;
422568
@@ -426,28 +572,42 @@ int udl_modeset_init(struct drm_device *dev) · 3 unmodified lines
426572
427573 dev->mode_config.min_width = 640;
428574 dev->mode_config.min_height = 480;
429−
430575 dev->mode_config.max_width = 2048;
431576 dev->mode_config.max_height = 2048;
432−
433− dev->mode_config.prefer_shadow = 0;
434577 dev->mode_config.preferred_depth = 16;
578+ dev->mode_config.funcs = &udl_mode_config_funcs;
579+
580+ primary_plane = &udl->primary_plane;
581+ ret = drm_universal_plane_init(dev, primary_plane, 0,
582+ &udl_primary_plane_funcs,
583+ udl_primary_plane_formats,
584+ ARRAY_SIZE(udl_primary_plane_formats),
585+ udl_primary_plane_fmtmods,
586+ DRM_PLANE_TYPE_PRIMARY, NULL);
587+ if (ret)
588+ return ret;
589+ drm_plane_helper_add(primary_plane, &udl_primary_plane_helper_funcs);
590+ drm_plane_enable_fb_damage_clips(primary_plane);
435591
436− dev->mode_config.funcs = &udl_mode_funcs;
592+ crtc = &udl->crtc;
593+ ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL,
594+ &udl_crtc_funcs, NULL);
595+ if (ret)
596+ return ret;
597+ drm_crtc_helper_add(crtc, &udl_crtc_helper_funcs);
598+
599+ encoder = &udl->encoder;
600+ ret = drm_encoder_init(dev, encoder, &udl_encoder_funcs, DRM_MODE_ENCODER_DAC, NULL);
601+ if (ret)
602+ return ret;
603+ encoder->possible_crtcs = drm_crtc_mask(crtc);
437604
438605 connector = udl_connector_init(dev);
439606 if (IS_ERR(connector))
440607 return PTR_ERR(connector);
441−
442− format_count = ARRAY_SIZE(udl_simple_display_pipe_formats);
443−
444− ret = drm_simple_display_pipe_init(dev, &udl->display_pipe,
445− &udl_simple_display_pipe_funcs,
446− udl_simple_display_pipe_formats,
447− format_count, NULL, connector);
608+ ret = drm_connector_attach_encoder(connector, encoder);
448609 if (ret)
449610 return ret;
450− drm_plane_enable_fb_damage_clips(&udl->display_pipe.plane);
451611
452612 drm_mode_config_reset(dev);
453613
drivers/gpu/drm/udl/udl_proto.h+68−0
@@ -0,0 +1,68 @@
1+/* SPDX-License-Identifier: GPL-2.0-only */
2+
3+#ifndef UDL_PROTO_H
4+#define UDL_PROTO_H
5+
6+#include <linux/bits.h>
7+
8+#define UDL_MSG_BULK 0xaf
9+
10+/* Register access */
11+#define UDL_CMD_WRITEREG 0x20 /* See register constants below */
12+
13+/* Framebuffer access */
14+#define UDL_CMD_WRITERAW8 0x60 /* 8 bit raw write command. */
15+#define UDL_CMD_WRITERL8 0x61 /* 8 bit run length command. */
16+#define UDL_CMD_WRITECOPY8 0x62 /* 8 bit copy command. */
17+#define UDL_CMD_WRITERLX8 0x63 /* 8 bit extended run length command. */
18+#define UDL_CMD_WRITERAW16 0x68 /* 16 bit raw write command. */
19+#define UDL_CMD_WRITERL16 0x69 /* 16 bit run length command. */
20+#define UDL_CMD_WRITECOPY16 0x6a /* 16 bit copy command. */
21+#define UDL_CMD_WRITERLX16 0x6b /* 16 bit extended run length command. */
22+
23+/* Color depth */
24+#define UDL_REG_COLORDEPTH 0x00
25+#define UDL_COLORDEPTH_16BPP 0
26+#define UDL_COLORDEPTH_24BPP 1
27+
28+/* Display-mode settings */
29+#define UDL_REG_XDISPLAYSTART 0x01
30+#define UDL_REG_XDISPLAYEND 0x03
31+#define UDL_REG_YDISPLAYSTART 0x05
32+#define UDL_REG_YDISPLAYEND 0x07
33+#define UDL_REG_XENDCOUNT 0x09
34+#define UDL_REG_HSYNCSTART 0x0b
35+#define UDL_REG_HSYNCEND 0x0d
36+#define UDL_REG_HPIXELS 0x0f
37+#define UDL_REG_YENDCOUNT 0x11
38+#define UDL_REG_VSYNCSTART 0x13
39+#define UDL_REG_VSYNCEND 0x15
40+#define UDL_REG_VPIXELS 0x17
41+#define UDL_REG_PIXELCLOCK5KHZ 0x1b
42+
43+/* On/Off for driving the DisplayLink framebuffer to the display */
44+#define UDL_REG_BLANKMODE 0x1f
45+#define UDL_BLANKMODE_ON 0x00 /* hsync and vsync on, visible */
46+#define UDL_BLANKMODE_BLANKED 0x01 /* hsync and vsync on, blanked */
47+#define UDL_BLANKMODE_VSYNC_OFF 0x03 /* vsync off, blanked */
48+#define UDL_BLANKMODE_HSYNC_OFF 0x05 /* hsync off, blanked */
49+#define UDL_BLANKMODE_POWERDOWN 0x07 /* powered off; requires modeset */
50+
51+/* Framebuffer address */
52+#define UDL_REG_BASE16BPP_ADDR2 0x20
53+#define UDL_REG_BASE16BPP_ADDR1 0x21
54+#define UDL_REG_BASE16BPP_ADDR0 0x22
55+#define UDL_REG_BASE8BPP_ADDR2 0x26
56+#define UDL_REG_BASE8BPP_ADDR1 0x27
57+#define UDL_REG_BASE8BPP_ADDR0 0x28
58+
59+#define UDL_BASE_ADDR0_MASK GENMASK(7, 0)
60+#define UDL_BASE_ADDR1_MASK GENMASK(15, 8)
61+#define UDL_BASE_ADDR2_MASK GENMASK(23, 16)
62+
63+/* Lock/unlock video registers */
64+#define UDL_REG_VIDREG 0xff
65+#define UDL_VIDREG_LOCK 0x00
66+#define UDL_VIDREG_UNLOCK 0xff
67+
68+#endif
drivers/gpu/drm/udl/udl_transfer.c+4−3
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <asm/unaligned.h>
1111
1212 #include "udl_drv.h"
13+#include "udl_proto.h"
1314
1415 #define MAX_CMD_PIXELS 255
1516
@@ -89,8 +90,8 @@ static void udl_compress_hline16( · 73 unmodified lines
8990 const u8 *cmd_pixel_start, *cmd_pixel_end = NULL;
9091 uint16_t pixel_val16;
9192
92− *cmd++ = 0xaf;
93− *cmd++ = 0x6b;
93+ *cmd++ = UDL_MSG_BULK;
94+ *cmd++ = UDL_CMD_WRITERLX16;
9495 *cmd++ = (uint8_t) ((dev_addr >> 16) & 0xFF);
9596 *cmd++ = (uint8_t) ((dev_addr >> 8) & 0xFF);
9697 *cmd++ = (uint8_t) ((dev_addr) & 0xFF);
@@ -152,7 +153,7 @@ static void udl_compress_hline16( · 55 unmodified lines
152153 if (cmd_buffer_end <= MIN_RLX_CMD_BYTES + cmd) {
153154 /* Fill leftover bytes with no-ops */
154155 if (cmd_buffer_end > cmd)
155− memset(cmd, 0xAF, cmd_buffer_end - cmd);
156+ memset(cmd, UDL_MSG_BULK, cmd_buffer_end - cmd);
156157 cmd = (uint8_t *) cmd_buffer_end;
157158 }
158159
drivers/gpu/drm/vc4/vc4_hdmi.c+1−1
@@ -542,7 +542,7 @@ static void vc4_hdmi_connector_reset(struct drm_connector *connector) · 541 unmodified lines
542542 new_state->base.max_bpc = 8;
543543 new_state->base.max_requested_bpc = 8;
544544 new_state->output_format = VC4_HDMI_OUTPUT_RGB;
545− drm_atomic_helper_connector_tv_reset(connector);
545+ drm_atomic_helper_connector_tv_margins_reset(connector);
546546 }
547547
548548 static struct drm_connector_state *
drivers/gpu/drm/vc4/vc4_vec.c+4−4
@@ -69,6 +69,7 @@ · 68 unmodified lines
6969 #define VEC_CONFIG0_STD_MASK GENMASK(1, 0)
7070 #define VEC_CONFIG0_NTSC_STD 0
7171 #define VEC_CONFIG0_PAL_BDGHI_STD 1
72+#define VEC_CONFIG0_PAL_M_STD 2
7273 #define VEC_CONFIG0_PAL_N_STD 3
7374
7475 #define VEC_SCHPH 0x108
@@ -255,10 +256,9 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { · 180 unmodified lines
255256 .config1 = VEC_CONFIG1_C_CVBS_CVBS,
256257 },
257258 [VC4_VEC_TV_MODE_PAL_M] = {
258− .mode = &pal_mode,
259− .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
260− .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
261− .custom_freq = 0x223b61d1,
259+ .mode = &ntsc_mode,
260+ .config0 = VEC_CONFIG0_PAL_M_STD,
261+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
262262 },
263263 };
264264
drivers/infiniband/core/umem_dmabuf.c+4−3
@@ -26,7 +26,8 @@ int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf) · 25 unmodified lines
2626 if (umem_dmabuf->sgt)
2727 goto wait_fence;
2828
29− sgt = dma_buf_map_attachment(umem_dmabuf->attach, DMA_BIDIRECTIONAL);
29+ sgt = dma_buf_map_attachment_unlocked(umem_dmabuf->attach,
30+ DMA_BIDIRECTIONAL);
3031 if (IS_ERR(sgt))
3132 return PTR_ERR(sgt);
3233
@@ -102,8 +103,8 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf) · 69 unmodified lines
102103 umem_dmabuf->last_sg_trim = 0;
103104 }
104105
105− dma_buf_unmap_attachment(umem_dmabuf->attach, umem_dmabuf->sgt,
106− DMA_BIDIRECTIONAL);
106+ dma_buf_unmap_attachment_unlocked(umem_dmabuf->attach, umem_dmabuf->sgt,
107+ DMA_BIDIRECTIONAL);
107108
108109 umem_dmabuf->sgt = NULL;
109110 }
drivers/media/common/videobuf2/videobuf2-dma-contig.c+7−15
@@ -101,7 +101,7 @@ static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) · 100 unmodified lines
101101 if (buf->db_attach) {
102102 struct iosys_map map;
103103
104− if (!dma_buf_vmap(buf->db_attach->dmabuf, &map))
104+ if (!dma_buf_vmap_unlocked(buf->db_attach->dmabuf, &map))
105105 buf->vaddr = map.vaddr;
106106
107107 return buf->vaddr;
@@ -382,18 +382,12 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( · 274 unmodified lines
382382 struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
383383 {
384384 struct vb2_dc_attachment *attach = db_attach->priv;
385− /* stealing dmabuf mutex to serialize map/unmap operations */
386− struct mutex *lock = &db_attach->dmabuf->lock;
387385 struct sg_table *sgt;
388386
389− mutex_lock(lock);
390−
391387 sgt = &attach->sgt;
392388 /* return previously mapped sg table */
393− if (attach->dma_dir == dma_dir) {
394− mutex_unlock(lock);
389+ if (attach->dma_dir == dma_dir)
395390 return sgt;
396− }
397391
398392 /* release any previous cache */
399393 if (attach->dma_dir != DMA_NONE) {
@@ -409,14 +403,11 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( · 9 unmodified lines
409403 if (dma_map_sgtable(db_attach->dev, sgt, dma_dir,
410404 DMA_ATTR_SKIP_CPU_SYNC)) {
411405 pr_err("failed to map scatterlist\n");
412− mutex_unlock(lock);
413406 return ERR_PTR(-EIO);
414407 }
415408
416409 attach->dma_dir = dma_dir;
417410
418− mutex_unlock(lock);
419−
420411 return sgt;
421412 }
422413
@@ -711,7 +702,7 @@ static int vb2_dc_map_dmabuf(void *mem_priv) · 288 unmodified lines
711702 }
712703
713704 /* get the associated scatterlist for this buffer */
714− sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
705+ sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
715706 if (IS_ERR(sgt)) {
716707 pr_err("Error getting dmabuf scatterlist\n");
717708 return -EINVAL;
@@ -722,7 +713,8 @@ static int vb2_dc_map_dmabuf(void *mem_priv) · 4 unmodified lines
722713 if (contig_size < buf->size) {
723714 pr_err("contiguous chunk is too small %lu/%lu\n",
724715 contig_size, buf->size);
725− dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
716+ dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt,
717+ buf->dma_dir);
726718 return -EFAULT;
727719 }
728720
@@ -750,10 +742,10 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv) · 21 unmodified lines
750742 }
751743
752744 if (buf->vaddr) {
753− dma_buf_vunmap(buf->db_attach->dmabuf, &map);
745+ dma_buf_vunmap_unlocked(buf->db_attach->dmabuf, &map);
754746 buf->vaddr = NULL;
755747 }
756− dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
748+ dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, buf->dma_dir);
757749
758750 buf->dma_addr = 0;
759751 buf->dma_sgt = NULL;
drivers/media/common/videobuf2/videobuf2-dma-sg.c+5−14
@@ -309,7 +309,7 @@ static void *vb2_dma_sg_vaddr(struct vb2_buffer *vb, void *buf_priv) · 308 unmodified lines
309309
310310 if (!buf->vaddr) {
311311 if (buf->db_attach) {
312− ret = dma_buf_vmap(buf->db_attach->dmabuf, &map);
312+ ret = dma_buf_vmap_unlocked(buf->db_attach->dmabuf, &map);
313313 buf->vaddr = ret ? NULL : map.vaddr;
314314 } else {
315315 buf->vaddr = vm_map_ram(buf->pages, buf->num_pages, -1);
@@ -424,18 +424,12 @@ static struct sg_table *vb2_dma_sg_dmabuf_ops_map( · 108 unmodified lines
424424 struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
425425 {
426426 struct vb2_dma_sg_attachment *attach = db_attach->priv;
427− /* stealing dmabuf mutex to serialize map/unmap operations */
428− struct mutex *lock = &db_attach->dmabuf->lock;
429427 struct sg_table *sgt;
430428
431− mutex_lock(lock);
432−
433429 sgt = &attach->sgt;
434430 /* return previously mapped sg table */
435− if (attach->dma_dir == dma_dir) {
436− mutex_unlock(lock);
431+ if (attach->dma_dir == dma_dir)
437432 return sgt;
438− }
439433
440434 /* release any previous cache */
441435 if (attach->dma_dir != DMA_NONE) {
@@ -446,14 +440,11 @@ static struct sg_table *vb2_dma_sg_dmabuf_ops_map( · 4 unmodified lines
446440 /* mapping to the client with new direction */
447441 if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, 0)) {
448442 pr_err("failed to map scatterlist\n");
449− mutex_unlock(lock);
450443 return ERR_PTR(-EIO);
451444 }
452445
453446 attach->dma_dir = dma_dir;
454447
455− mutex_unlock(lock);
456−
457448 return sgt;
458449 }
459450
@@ -565,7 +556,7 @@ static int vb2_dma_sg_map_dmabuf(void *mem_priv) · 105 unmodified lines
565556 }
566557
567558 /* get the associated scatterlist for this buffer */
568− sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
559+ sgt = dma_buf_map_attachment_unlocked(buf->db_attach, buf->dma_dir);
569560 if (IS_ERR(sgt)) {
570561 pr_err("Error getting dmabuf scatterlist\n");
571562 return -EINVAL;
@@ -594,10 +585,10 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv) · 22 unmodified lines
594585 }
595586
596587 if (buf->vaddr) {
597− dma_buf_vunmap(buf->db_attach->dmabuf, &map);
588+ dma_buf_vunmap_unlocked(buf->db_attach->dmabuf, &map);
598589 buf->vaddr = NULL;
599590 }
600− dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
591+ dma_buf_unmap_attachment_unlocked(buf->db_attach, sgt, buf->dma_dir);
601592
602593 buf->dma_sgt = NULL;
603594 }
drivers/media/common/videobuf2/videobuf2-vmalloc.c+4−13
@@ -267,18 +267,12 @@ static struct sg_table *vb2_vmalloc_dmabuf_ops_map( · 266 unmodified lines
267267 struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
268268 {
269269 struct vb2_vmalloc_attachment *attach = db_attach->priv;
270− /* stealing dmabuf mutex to serialize map/unmap operations */
271− struct mutex *lock = &db_attach->dmabuf->lock;
272270 struct sg_table *sgt;
273271
274− mutex_lock(lock);
275−
276272 sgt = &attach->sgt;
277273 /* return previously mapped sg table */
278− if (attach->dma_dir == dma_dir) {
279− mutex_unlock(lock);
274+ if (attach->dma_dir == dma_dir)
280275 return sgt;
281− }
282276
283277 /* release any previous cache */
284278 if (attach->dma_dir != DMA_NONE) {
@@ -289,14 +283,11 @@ static struct sg_table *vb2_vmalloc_dmabuf_ops_map( · 4 unmodified lines
289283 /* mapping to the client with new direction */
290284 if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, 0)) {
291285 pr_err("failed to map scatterlist\n");
292− mutex_unlock(lock);
293286 return ERR_PTR(-EIO);
294287 }
295288
296289 attach->dma_dir = dma_dir;
297290
298− mutex_unlock(lock);
299−
300291 return sgt;
301292 }
302293
@@ -376,7 +367,7 @@ static int vb2_vmalloc_map_dmabuf(void *mem_priv) · 73 unmodified lines
376367 struct iosys_map map;
377368 int ret;
378369
379− ret = dma_buf_vmap(buf->dbuf, &map);
370+ ret = dma_buf_vmap_unlocked(buf->dbuf, &map);
380371 if (ret)
381372 return -EFAULT;
382373 buf->vaddr = map.vaddr;
@@ -389,7 +380,7 @@ static void vb2_vmalloc_unmap_dmabuf(void *mem_priv) · 6 unmodified lines
389380 struct vb2_vmalloc_buf *buf = mem_priv;
390381 struct iosys_map map = IOSYS_MAP_INIT_VADDR(buf->vaddr);
391382
392− dma_buf_vunmap(buf->dbuf, &map);
383+ dma_buf_vunmap_unlocked(buf->dbuf, &map);
393384 buf->vaddr = NULL;
394385 }
395386
@@ -399,7 +390,7 @@ static void vb2_vmalloc_detach_dmabuf(void *mem_priv) · 3 unmodified lines
399390 struct iosys_map map = IOSYS_MAP_INIT_VADDR(buf->vaddr);
400391
401392 if (buf->vaddr)
402− dma_buf_vunmap(buf->dbuf, &map);
393+ dma_buf_vunmap_unlocked(buf->dbuf, &map);
403394
404395 kfree(buf);
405396 }
drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c+3−3
@@ -38,7 +38,7 @@ static void tegra_vde_release_entry(struct tegra_vde_cache_entry *entry) · 37 unmodified lines
3838 if (entry->vde->domain)
3939 tegra_vde_iommu_unmap(entry->vde, entry->iova);
4040
41− dma_buf_unmap_attachment(entry->a, entry->sgt, entry->dma_dir);
41+ dma_buf_unmap_attachment_unlocked(entry->a, entry->sgt, entry->dma_dir);
4242 dma_buf_detach(dmabuf, entry->a);
4343 dma_buf_put(dmabuf);
4444
@@ -102,7 +102,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde, · 57 unmodified lines
102102 goto err_unlock;
103103 }
104104
105− sgt = dma_buf_map_attachment(attachment, dma_dir);
105+ sgt = dma_buf_map_attachment_unlocked(attachment, dma_dir);
106106 if (IS_ERR(sgt)) {
107107 dev_err(dev, "Failed to get dmabufs sg_table\n");
108108 err = PTR_ERR(sgt);
@@ -152,7 +152,7 @@ ref: · 43 unmodified lines
152152 err_free:
153153 kfree(entry);
154154 err_unmap:
155− dma_buf_unmap_attachment(attachment, sgt, dma_dir);
155+ dma_buf_unmap_attachment_unlocked(attachment, sgt, dma_dir);
156156 err_detach:
157157 dma_buf_detach(dmabuf, attachment);
158158 err_unlock:
drivers/misc/fastrpc.c+3−3
@@ -310,8 +310,8 @@ static void fastrpc_free_map(struct kref *ref) · 309 unmodified lines
310310 return;
311311 }
312312 }
313− dma_buf_unmap_attachment(map->attach, map->table,
314− DMA_BIDIRECTIONAL);
313+ dma_buf_unmap_attachment_unlocked(map->attach, map->table,
314+ DMA_BIDIRECTIONAL);
315315 dma_buf_detach(map->buf, map->attach);
316316 dma_buf_put(map->buf);
317317 }
@@ -726,7 +726,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, · 408 unmodified lines
726726 goto attach_err;
727727 }
728728
729− map->table = dma_buf_map_attachment(map->attach, DMA_BIDIRECTIONAL);
729+ map->table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
730730 if (IS_ERR(map->table)) {
731731 err = PTR_ERR(map->table);
732732 goto map_err;
drivers/video/fbdev/Kconfig+1−0
@@ -455,6 +455,7 @@ config FB_ATARI · 454 unmodified lines
455455 config FB_OF
456456 bool "Open Firmware frame buffer device support"
457457 depends on (FB = y) && PPC && (!PPC_PSERIES || PCI)
458+ depends on !DRM_OFDRM
458459 select APERTURE_HELPERS
459460 select FB_CFB_FILLRECT
460461 select FB_CFB_COPYAREA
drivers/xen/gntdev-dmabuf.c+4−4
@@ -600,7 +600,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, · 599 unmodified lines
600600
601601 gntdev_dmabuf->u.imp.attach = attach;
602602
603− sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
603+ sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL);
604604 if (IS_ERR(sgt)) {
605605 ret = ERR_CAST(sgt);
606606 goto fail_detach;
@@ -658,7 +658,7 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev, · 51 unmodified lines
658658 fail_end_access:
659659 dmabuf_imp_end_foreign_access(gntdev_dmabuf->u.imp.refs, count);
660660 fail_unmap:
661− dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
661+ dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL);
662662 fail_detach:
663663 dma_buf_detach(dma_buf, attach);
664664 fail_free_obj:
@@ -708,8 +708,8 @@ static int dmabuf_imp_release(struct gntdev_dmabuf_priv *priv, u32 fd) · 43 unmodified lines
708708 attach = gntdev_dmabuf->u.imp.attach;
709709
710710 if (gntdev_dmabuf->u.imp.sgt)
711− dma_buf_unmap_attachment(attach, gntdev_dmabuf->u.imp.sgt,
712− DMA_BIDIRECTIONAL);
711+ dma_buf_unmap_attachment_unlocked(attach, gntdev_dmabuf->u.imp.sgt,
712+ DMA_BIDIRECTIONAL);
713713 dma_buf = attach->dmabuf;
714714 dma_buf_detach(attach->dmabuf, attach);
715715 dma_buf_put(dma_buf);
include/drm/drm_atomic_helper.h+1−2
@@ -58,10 +58,9 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state, · 57 unmodified lines
5858 int max_scale,
5959 bool can_position,
6060 bool can_update_disabled);
61−int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
62− bool can_disable_primary_plane);
6361 int drm_atomic_helper_check_planes(struct drm_device *dev,
6462 struct drm_atomic_state *state);
63+int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state);
6564 int drm_atomic_helper_check(struct drm_device *dev,
6665 struct drm_atomic_state *state);
6766 void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
include/drm/drm_atomic_state_helper.h+1−1
@@ -70,7 +70,7 @@ void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_ · 69 unmodified lines
7070 void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
7171 struct drm_connector_state *conn_state);
7272 void drm_atomic_helper_connector_reset(struct drm_connector *connector);
73−void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
73+void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
7474 void
7575 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
7676 struct drm_connector_state *state);
include/drm/drm_connector.h+3−1
@@ -692,7 +692,8 @@ struct drm_connector_tv_margins { · 691 unmodified lines
692692
693693 /**
694694 * struct drm_tv_connector_state - TV connector related states
695− * @subconnector: selected subconnector
695+ * @select_subconnector: selected subconnector
696+ * @subconnector: detected subconnector
696697 * @margins: TV margins
697698 * @mode: TV mode
698699 * @brightness: brightness in percent
@@ -703,6 +704,7 @@ struct drm_connector_tv_margins { · 4 unmodified lines
703704 * @hue: hue in percent
704705 */
705706 struct drm_tv_connector_state {
707+ enum drm_mode_subconnector select_subconnector;
706708 enum drm_mode_subconnector subconnector;
707709 struct drm_connector_tv_margins margins;
708710 unsigned int mode;
include/drm/drm_crtc_helper.h+2−0
@@ -50,6 +50,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, · 49 unmodified lines
5050 struct drm_display_mode *mode,
5151 int x, int y,
5252 struct drm_framebuffer *old_fb);
53+int drm_crtc_helper_atomic_check(struct drm_crtc *crtc,
54+ struct drm_atomic_state *state);
5355 bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
5456 bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
5557
include/drm/drm_edid.h+9−5
@@ -97,10 +97,13 @@ struct detailed_data_string { · 96 unmodified lines
9797 #define DRM_EDID_RANGE_OFFSET_MIN_HFREQ (1 << 2) /* 1.4 */
9898 #define DRM_EDID_RANGE_OFFSET_MAX_HFREQ (1 << 3) /* 1.4 */
9999
100−#define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG 0x00
101−#define DRM_EDID_RANGE_LIMITS_ONLY_FLAG 0x01
102−#define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02
103−#define DRM_EDID_CVT_SUPPORT_FLAG 0x04
100+#define DRM_EDID_DEFAULT_GTF_SUPPORT_FLAG 0x00 /* 1.3 */
101+#define DRM_EDID_RANGE_LIMITS_ONLY_FLAG 0x01 /* 1.4 */
102+#define DRM_EDID_SECONDARY_GTF_SUPPORT_FLAG 0x02 /* 1.3 */
103+#define DRM_EDID_CVT_SUPPORT_FLAG 0x04 /* 1.4 */
104+
105+#define DRM_EDID_CVT_FLAGS_STANDARD_BLANKING (1 << 3)
106+#define DRM_EDID_CVT_FLAGS_REDUCED_BLANKING (1 << 4)
104107
105108 struct detailed_data_monitor_range {
106109 u8 min_vfreq;
@@ -206,7 +209,8 @@ struct detailed_timing { · 99 unmodified lines
206209 #define DRM_EDID_DIGITAL_TYPE_DP (5 << 0) /* 1.4 */
207210 #define DRM_EDID_DIGITAL_DFP_1_X (1 << 0) /* 1.3 */
208211
209−#define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0)
212+#define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0) /* 1.2 */
213+#define DRM_EDID_FEATURE_CONTINUOUS_FREQ (1 << 0) /* 1.4 */
210214 #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1)
211215 #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2)
212216 /* If analog */
include/drm/drm_gem.h+3−0
@@ -457,6 +457,9 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj); · 456 unmodified lines
457457 void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
458458 bool dirty, bool accessed);
459459
460+int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
461+void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
462+
460463 int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
461464 int count, struct drm_gem_object ***objs_out);
462465 struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
include/drm/drm_mode_config.h+0−2
@@ -345,7 +345,6 @@ struct drm_mode_config_funcs { · 344 unmodified lines
345345 * @max_width: maximum fb pixel width on this device
346346 * @max_height: maximum fb pixel height on this device
347347 * @funcs: core driver provided mode setting functions
348− * @fb_base: base address of the framebuffer
349348 * @poll_enabled: track polling support for this device
350349 * @poll_running: track polling status for this device
351350 * @delayed_event: track delayed poll uevent deliver for this device
@@ -542,7 +541,6 @@ struct drm_mode_config { · 190 unmodified lines
542541 int min_width, min_height;
543542 int max_width, max_height;
544543 const struct drm_mode_config_funcs *funcs;
545− resource_size_t fb_base;
546544
547545 /* output poll support */
548546 bool poll_enabled;
include/drm/gpu_scheduler.h+32−0
@@ -59,6 +59,12 @@ enum drm_sched_priority { · 58 unmodified lines
5959 DRM_SCHED_PRIORITY_UNSET = -2
6060 };
6161
62+/* Used to chose between FIFO and RR jobs scheduling */
63+extern int drm_sched_policy;
64+
65+#define DRM_SCHED_POLICY_RR 0
66+#define DRM_SCHED_POLICY_FIFO 1
67+
6268 /**
6369 * struct drm_sched_entity - A wrapper around a job queue (typically
6470 * attached to the DRM file_priv).
@@ -205,6 +211,21 @@ struct drm_sched_entity { · 140 unmodified lines
205211 * drm_sched_entity_fini().
206212 */
207213 struct completion entity_idle;
214+
215+ /**
216+ * @oldest_job_waiting:
217+ *
218+ * Marks earliest job waiting in SW queue
219+ */
220+ ktime_t oldest_job_waiting;
221+
222+ /**
223+ * @rb_tree_node:
224+ *
225+ * The node used to insert this entity into time based priority queue
226+ */
227+ struct rb_node rb_tree_node;
228+
208229 };
209230
210231 /**
@@ -214,6 +235,7 @@ struct drm_sched_entity { · 3 unmodified lines
214235 * @sched: the scheduler to which this rq belongs to.
215236 * @entities: list of the entities to be scheduled.
216237 * @current_entity: the entity which is to be scheduled.
238+ * @rb_tree_root: root of time based priory queue of entities for FIFO scheduling
217239 *
218240 * Run queue is a set of entities scheduling command submissions for
219241 * one specific ring. It implements the scheduling policy that selects
@@ -224,6 +246,7 @@ struct drm_sched_rq { · 4 unmodified lines
224246 struct drm_gpu_scheduler *sched;
225247 struct list_head entities;
226248 struct drm_sched_entity *current_entity;
249+ struct rb_root_cached rb_tree_root;
227250 };
228251
229252 /**
@@ -323,6 +346,13 @@ struct drm_sched_job { · 93 unmodified lines
323346
324347 /** @last_dependency: tracks @dependencies as they signal */
325348 unsigned long last_dependency;
349+
350+ /**
351+ * @submit_ts:
352+ *
353+ * When the job was pushed into the entity queue.
354+ */
355+ ktime_t submit_ts;
326356 };
327357
328358 static inline bool drm_sched_invalidate_job(struct drm_sched_job *s_job,
@@ -512,6 +542,8 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq, · 183 unmodified lines
512542 void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
513543 struct drm_sched_entity *entity);
514544
545+void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts);
546+
515547 int drm_sched_entity_init(struct drm_sched_entity *entity,
516548 enum drm_sched_priority priority,
517549 struct drm_gpu_scheduler **sched_list,
include/linux/dma-buf.h+8−9
@@ -326,15 +326,6 @@ struct dma_buf { · 325 unmodified lines
326326 /** @ops: dma_buf_ops associated with this buffer object. */
327327 const struct dma_buf_ops *ops;
328328
329− /**
330− * @lock:
331− *
332− * Used internally to serialize list manipulation, attach/detach and
333− * vmap/unmap. Note that in many cases this is superseeded by
334− * dma_resv_lock() on @resv.
335− */
336− struct mutex lock;
337−
338329 /**
339330 * @vmapping_counter:
340331 *
@@ -627,9 +618,17 @@ int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, · 286 unmodified lines
627618 enum dma_data_direction dir);
628619 int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
629620 enum dma_data_direction dir);
621+struct sg_table *
622+dma_buf_map_attachment_unlocked(struct dma_buf_attachment *attach,
623+ enum dma_data_direction direction);
624+void dma_buf_unmap_attachment_unlocked(struct dma_buf_attachment *attach,
625+ struct sg_table *sg_table,
626+ enum dma_data_direction direction);
630627
631628 int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
632629 unsigned long);
633630 int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_map *map);
634631 void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map);
632+int dma_buf_vmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map);
633+void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map);
635634 #endif /* __DMA_BUF_H__ */
include/uapi/drm/drm_fourcc.h+29−0
@@ -744,6 +744,35 @@ extern "C" { · 743 unmodified lines
744744 */
745745 #define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4)
746746
747+/*
748+ * Vivante TS (tile-status) buffer modifiers. They can be combined with all of
749+ * the color buffer tiling modifiers defined above. When TS is present it's a
750+ * separate buffer containing the clear/compression status of each tile. The
751+ * modifiers are defined as VIVANTE_MOD_TS_c_s, where c is the color buffer
752+ * tile size in bytes covered by one entry in the status buffer and s is the
753+ * number of status bits per entry.
754+ * We reserve the top 8 bits of the Vivante modifier space for tile status
755+ * clear/compression modifiers, as future cores might add some more TS layout
756+ * variations.
757+ */
758+#define VIVANTE_MOD_TS_64_4 (1ULL << 48)
759+#define VIVANTE_MOD_TS_64_2 (2ULL << 48)
760+#define VIVANTE_MOD_TS_128_4 (3ULL << 48)
761+#define VIVANTE_MOD_TS_256_4 (4ULL << 48)
762+#define VIVANTE_MOD_TS_MASK (0xfULL << 48)
763+
764+/*
765+ * Vivante compression modifiers. Those depend on a TS modifier being present
766+ * as the TS bits get reinterpreted as compression tags instead of simple
767+ * clear markers when compression is enabled.
768+ */
769+#define VIVANTE_MOD_COMP_DEC400 (1ULL << 52)
770+#define VIVANTE_MOD_COMP_MASK (0xfULL << 52)
771+
772+/* Masking out the extension bits will yield the base modifier. */
773+#define VIVANTE_MOD_EXT_MASK (VIVANTE_MOD_TS_MASK | \
774+ VIVANTE_MOD_COMP_MASK)
775+
747776 /* NVIDIA frame buffer modifiers */
748777
749778 /*
include/uapi/drm/drm_mode.h+62−1
@@ -935,12 +935,31 @@ struct hdr_output_metadata { · 934 unmodified lines
935935 };
936936 };
937937
938+/**
939+ * DRM_MODE_PAGE_FLIP_EVENT
940+ *
941+ * Request that the kernel sends back a vblank event (see
942+ * struct drm_event_vblank) with the &DRM_EVENT_FLIP_COMPLETE type when the
943+ * page-flip is done.
944+ */
938945 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
946+/**
947+ * DRM_MODE_PAGE_FLIP_ASYNC
948+ *
949+ * Request that the page-flip is performed as soon as possible, ie. with no
950+ * delay due to waiting for vblank. This may cause tearing to be visible on
951+ * the screen.
952+ */
939953 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
940954 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
941955 #define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
942956 #define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
943957 DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
958+/**
959+ * DRM_MODE_PAGE_FLIP_FLAGS
960+ *
961+ * Bitmask of flags suitable for &drm_mode_crtc_page_flip_target.flags.
962+ */
944963 #define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
945964 DRM_MODE_PAGE_FLIP_ASYNC | \
946965 DRM_MODE_PAGE_FLIP_TARGET)
@@ -1034,11 +1053,53 @@ struct drm_mode_destroy_dumb { · 87 unmodified lines
10341053 __u32 handle;
10351054 };
10361055
1037−/* page-flip flags are valid, plus: */
1056+/**
1057+ * DRM_MODE_ATOMIC_TEST_ONLY
1058+ *
1059+ * Do not apply the atomic commit, instead check whether the hardware supports
1060+ * this configuration.
1061+ *
1062+ * See &drm_mode_config_funcs.atomic_check for more details on test-only
1063+ * commits.
1064+ */
10381065 #define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
1066+/**
1067+ * DRM_MODE_ATOMIC_NONBLOCK
1068+ *
1069+ * Do not block while applying the atomic commit. The &DRM_IOCTL_MODE_ATOMIC
1070+ * IOCTL returns immediately instead of waiting for the changes to be applied
1071+ * in hardware. Note, the driver will still check that the update can be
1072+ * applied before retuning.
1073+ */
10391074 #define DRM_MODE_ATOMIC_NONBLOCK 0x0200
1075+/**
1076+ * DRM_MODE_ATOMIC_ALLOW_MODESET
1077+ *
1078+ * Allow the update to result in temporary or transient visible artifacts while
1079+ * the update is being applied. Applying the update may also take significantly
1080+ * more time than a page flip. All visual artifacts will disappear by the time
1081+ * the update is completed, as signalled through the vblank event's timestamp
1082+ * (see struct drm_event_vblank).
1083+ *
1084+ * This flag must be set when the KMS update might cause visible artifacts.
1085+ * Without this flag such KMS update will return a EINVAL error. What kind of
1086+ * update may cause visible artifacts depends on the driver and the hardware.
1087+ * User-space that needs to know beforehand if an update might cause visible
1088+ * artifacts can use &DRM_MODE_ATOMIC_TEST_ONLY without
1089+ * &DRM_MODE_ATOMIC_ALLOW_MODESET to see if it fails.
1090+ *
1091+ * To the best of the driver's knowledge, visual artifacts are guaranteed to
1092+ * not appear when this flag is not set. Some sinks might display visual
1093+ * artifacts outside of the driver's control.
1094+ */
10401095 #define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
10411096
1097+/**
1098+ * DRM_MODE_ATOMIC_FLAGS
1099+ *
1100+ * Bitfield of flags accepted by the &DRM_IOCTL_MODE_ATOMIC IOCTL in
1101+ * &drm_mode_atomic.flags.
1102+ */
10421103 #define DRM_MODE_ATOMIC_FLAGS (\
10431104 DRM_MODE_PAGE_FLIP_EVENT |\
10441105 DRM_MODE_PAGE_FLIP_ASYNC |\