aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-05-17 22:57:06 -0400
committerDave Airlie <airlied@redhat.com>2017-05-17 22:57:06 -0400
commite98c58e55f68f8785aebfab1f8c9a03d8de0afe1 (patch)
tree8357e8fda6efb0867ac39fc6b9211a579721d00a /drivers
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
parent9cf8f5802f39d9991158b29033c852bccfc3a4d4 (diff)
Merge tag 'drm-misc-next-2017-05-16' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes: - Return -ENODEV instead of -ENXIO when creating cma fb w/o valid gem (Daniel) - Add aspect ratio and custom scaling propertis to connector state (Maarten) Cross-subsystem Changes: - None Core Changes: - Add Laurent as bridge reviewer and Andrzej as bridge maintainer (Archit) - Maintain new STM driver through -misc (Yannick) - Misc doc improvements (as is tradition) (Daniel) - Add driver-private objects to atomic state (Dhinakaran) - Deprecate preclose hook in modern drivers (use postclose) (Daniel) - Add hwmode to vblank struct. This fixes mode access in irq context and reduced a bunch of boilerplate (Daniel) Driver Changes: - vc4: Add out-fence support to vc4 V3D rendering (Eric) - stm: Add stm32f429 display hw and am-480272h3tmqw-t01h panel support (Yannick) - vc4: Remove 256MB cma limit from vc4 (Eric) - dw-hdmi: Disable audio when inactive, instead of always enabled (Romain) - zte: Add support for VGA to the ZTE driver (Shawn) - i915: Track DP MST bandwidth and check it in atomic_check (Dhinakaran) - vgem: Enable gem dmabuf import iface to facilitate ion testing (Laura) - vc4: Add support for Cygnus (new dt compat string + couple bug fixes) (Eric) - pl111: Add driver for pl111 CLCD display controller (Eric/Tom) - vgem: Subclass drm_device instead of standalone platform device (Chris) Cc: Archit Taneja <architt@codeaurora.org> Cc: Eric Anholt <eric@anholt.net> Cc: Yannick Fertre <yannick.fertre@st.com> Cc: Romain Perier <romain.perier@collabora.com> Cc: Navare, Manasi D <manasi.d.navare@intel.com> Cc: Shawn Guo <shawn.guo@linaro.org> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Cc: Laura Abbott <labbott@redhat.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Tom Cooksey <tom.cooksey@arm.com> Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> * tag 'drm-misc-next-2017-05-16' of git://anongit.freedesktop.org/git/drm-misc: (72 commits) drm: add missing declaration to drm_blend.h drm/dp: Wait up all outstanding tx waiters drm/dp: Read the tx msg state once after checking for an event drm/prime: Forward declare struct device drm/vblank: Lock down vblank->hwmode more drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos drm/vblank: Add FIXME comments about moving the vblank ts hooks drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool drm/vgem: Convert to a struct drm_device subclass gpu: drm: gma500: remove dead code drm/sti: Adjust two checks for null pointers in sti_hqvdp_probe() drm/sti: Fix typos in a comment line drm/sti: Fix a typo in a comment line drm/sti: Replace 17 seq_puts() calls by seq_putc() drm/sti: Reduce function calls for sequence output at five places drm/sti: use seq_puts to display a string drm: Nerf the preclose callback for modern drivers drm/exynos: Merge pre/postclose hooks drm/tegra: switch to postclose ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma-buf/dma-buf.c8
-rw-r--r--drivers/dma-buf/dma-fence.c5
-rw-r--r--drivers/dma-buf/sync_debug.c6
-rw-r--r--drivers/dma-buf/sync_file.c13
-rw-r--r--drivers/gpu/drm/Kconfig4
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c14
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c41
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h3
-rw-r--r--drivers/gpu/drm/bridge/sii902x.c6
-rw-r--r--drivers/gpu/drm/bridge/synopsys/dw-hdmi.c46
-rw-r--r--drivers/gpu/drm/drm_atomic.c87
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c12
-rw-r--r--drivers/gpu/drm/drm_color_mgmt.c9
-rw-r--r--drivers/gpu/drm/drm_connector.c64
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c164
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c29
-rw-r--r--drivers/gpu/drm/drm_file.c8
-rw-r--r--drivers/gpu/drm/drm_irq.c129
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c11
-rw-r--r--drivers/gpu/drm/drm_prime.c30
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
-rw-r--r--drivers/gpu/drm/gma500/mdfld_tpo_vid.c51
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c62
-rw-r--r--drivers/gpu/drm/i915/intel_display.c11
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c48
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c18
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c23
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c45
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c39
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c11
-rw-r--r--drivers/gpu/drm/pl111/Kconfig12
-rw-r--r--drivers/gpu/drm/pl111/Makefile5
-rw-r--r--drivers/gpu/drm/pl111/pl111_connector.c127
-rw-r--r--drivers/gpu/drm/pl111/pl111_display.c344
-rw-r--r--drivers/gpu/drm/pl111/pl111_drm.h56
-rw-r--r--drivers/gpu/drm/pl111/pl111_drv.c272
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c37
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h3
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c14
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h3
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c20
-rw-r--r--drivers/gpu/drm/selftests/test-drm_mm.c28
-rw-r--r--drivers/gpu/drm/sti/sti_cursor.c5
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c3
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c5
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c9
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c23
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c7
-rw-r--r--drivers/gpu/drm/sti/sti_mixer.c3
-rw-r--r--drivers/gpu/drm/sti/sti_tvout.c7
-rw-r--r--drivers/gpu/drm/sti/sti_vid.c5
-rw-r--r--drivers/gpu/drm/stm/Kconfig16
-rw-r--r--drivers/gpu/drm/stm/Makefile7
-rw-r--r--drivers/gpu/drm/stm/drv.c221
-rw-r--r--drivers/gpu/drm/stm/ltdc.c1160
-rw-r--r--drivers/gpu/drm/stm/ltdc.h40
-rw-r--r--drivers/gpu/drm/tegra/drm.c4
-rw-r--r--drivers/gpu/drm/vc4/Makefile1
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c37
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c34
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c6
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h70
-rw-r--r--drivers/gpu/drm/vc4/vc4_fence.c56
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c161
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c174
-rw-r--r--drivers/gpu/drm/vc4/vc4_irq.c65
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c10
-rw-r--r--drivers/gpu/drm/vc4/vc4_render_cl.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_v3d.c180
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c54
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.c194
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.h2
-rw-r--r--drivers/gpu/drm/zte/Makefile1
-rw-r--r--drivers/gpu/drm/zte/zx_common_regs.h31
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.c1
-rw-r--r--drivers/gpu/drm/zte/zx_drm_drv.h1
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c1
-rw-r--r--drivers/gpu/drm/zte/zx_plane_regs.h18
-rw-r--r--drivers/gpu/drm/zte/zx_vga.c531
-rw-r--r--drivers/gpu/drm/zte/zx_vga_regs.h36
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c36
-rw-r--r--drivers/gpu/drm/zte/zx_vou_regs.h12
87 files changed, 4409 insertions, 780 deletions
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 512bdbc23bbb..4a038dcf5361 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -558,8 +558,8 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
558 if (WARN_ON(!dmabuf || !dev)) 558 if (WARN_ON(!dmabuf || !dev))
559 return ERR_PTR(-EINVAL); 559 return ERR_PTR(-EINVAL);
560 560
561 attach = kzalloc(sizeof(struct dma_buf_attachment), GFP_KERNEL); 561 attach = kzalloc(sizeof(*attach), GFP_KERNEL);
562 if (attach == NULL) 562 if (!attach)
563 return ERR_PTR(-ENOMEM); 563 return ERR_PTR(-ENOMEM);
564 564
565 attach->dev = dev; 565 attach->dev = dev;
@@ -1122,9 +1122,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
1122 attach_count = 0; 1122 attach_count = 0;
1123 1123
1124 list_for_each_entry(attach_obj, &buf_obj->attachments, node) { 1124 list_for_each_entry(attach_obj, &buf_obj->attachments, node) {
1125 seq_puts(s, "\t"); 1125 seq_printf(s, "\t%s\n", dev_name(attach_obj->dev));
1126
1127 seq_printf(s, "%s\n", dev_name(attach_obj->dev));
1128 attach_count++; 1126 attach_count++;
1129 } 1127 }
1130 1128
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 0918d3f003d6..57da14c15987 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -402,6 +402,11 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
402 } 402 }
403 } 403 }
404 404
405 if (!timeout) {
406 ret = 0;
407 goto out;
408 }
409
405 cb.base.func = dma_fence_default_wait_cb; 410 cb.base.func = dma_fence_default_wait_cb;
406 cb.task = current; 411 cb.task = current;
407 list_add(&cb.base.node, &fence->cb_list); 412 list_add(&cb.base.node, &fence->cb_list);
diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c
index c769dc653b34..a0d780ab68c3 100644
--- a/drivers/dma-buf/sync_debug.c
+++ b/drivers/dma-buf/sync_debug.c
@@ -110,7 +110,7 @@ static void sync_print_fence(struct seq_file *s,
110 } 110 }
111 } 111 }
112 112
113 seq_puts(s, "\n"); 113 seq_putc(s, '\n');
114} 114}
115 115
116static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) 116static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
@@ -161,7 +161,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
161 sync_timeline_list); 161 sync_timeline_list);
162 162
163 sync_print_obj(s, obj); 163 sync_print_obj(s, obj);
164 seq_puts(s, "\n"); 164 seq_putc(s, '\n');
165 } 165 }
166 spin_unlock_irqrestore(&sync_timeline_list_lock, flags); 166 spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
167 167
@@ -173,7 +173,7 @@ static int sync_debugfs_show(struct seq_file *s, void *unused)
173 container_of(pos, struct sync_file, sync_file_list); 173 container_of(pos, struct sync_file, sync_file_list);
174 174
175 sync_print_sync_file(s, sync_file); 175 sync_print_sync_file(s, sync_file);
176 seq_puts(s, "\n"); 176 seq_putc(s, '\n');
177 } 177 }
178 spin_unlock_irqrestore(&sync_file_list_lock, flags); 178 spin_unlock_irqrestore(&sync_file_list_lock, flags);
179 return 0; 179 return 0;
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index 2321035f6204..dc89b1d484e8 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -41,8 +41,6 @@ static struct sync_file *sync_file_alloc(void)
41 if (IS_ERR(sync_file->file)) 41 if (IS_ERR(sync_file->file))
42 goto err; 42 goto err;
43 43
44 kref_init(&sync_file->kref);
45
46 init_waitqueue_head(&sync_file->wq); 44 init_waitqueue_head(&sync_file->wq);
47 45
48 INIT_LIST_HEAD(&sync_file->cb.node); 46 INIT_LIST_HEAD(&sync_file->cb.node);
@@ -277,22 +275,15 @@ err:
277 275
278} 276}
279 277
280static void sync_file_free(struct kref *kref) 278static int sync_file_release(struct inode *inode, struct file *file)
281{ 279{
282 struct sync_file *sync_file = container_of(kref, struct sync_file, 280 struct sync_file *sync_file = file->private_data;
283 kref);
284 281
285 if (test_bit(POLL_ENABLED, &sync_file->fence->flags)) 282 if (test_bit(POLL_ENABLED, &sync_file->fence->flags))
286 dma_fence_remove_callback(sync_file->fence, &sync_file->cb); 283 dma_fence_remove_callback(sync_file->fence, &sync_file->cb);
287 dma_fence_put(sync_file->fence); 284 dma_fence_put(sync_file->fence);
288 kfree(sync_file); 285 kfree(sync_file);
289}
290
291static int sync_file_release(struct inode *inode, struct file *file)
292{
293 struct sync_file *sync_file = file->private_data;
294 286
295 kref_put(&sync_file->kref, sync_file_free);
296 return 0; 287 return 0;
297} 288}
298 289
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 78d7fc0ebb57..83cb2a88c204 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -246,6 +246,8 @@ source "drivers/gpu/drm/fsl-dcu/Kconfig"
246 246
247source "drivers/gpu/drm/tegra/Kconfig" 247source "drivers/gpu/drm/tegra/Kconfig"
248 248
249source "drivers/gpu/drm/stm/Kconfig"
250
249source "drivers/gpu/drm/panel/Kconfig" 251source "drivers/gpu/drm/panel/Kconfig"
250 252
251source "drivers/gpu/drm/bridge/Kconfig" 253source "drivers/gpu/drm/bridge/Kconfig"
@@ -274,6 +276,8 @@ source "drivers/gpu/drm/meson/Kconfig"
274 276
275source "drivers/gpu/drm/tinydrm/Kconfig" 277source "drivers/gpu/drm/tinydrm/Kconfig"
276 278
279source "drivers/gpu/drm/pl111/Kconfig"
280
277# Keep legacy drivers last 281# Keep legacy drivers last
278 282
279menuconfig DRM_LEGACY 283menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 59f0f9b696eb..c156fecfb362 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_DRM_BOCHS) += bochs/
82obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/ 82obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
83obj-$(CONFIG_DRM_MSM) += msm/ 83obj-$(CONFIG_DRM_MSM) += msm/
84obj-$(CONFIG_DRM_TEGRA) += tegra/ 84obj-$(CONFIG_DRM_TEGRA) += tegra/
85obj-$(CONFIG_DRM_STM) += stm/
85obj-$(CONFIG_DRM_STI) += sti/ 86obj-$(CONFIG_DRM_STI) += sti/
86obj-$(CONFIG_DRM_IMX) += imx/ 87obj-$(CONFIG_DRM_IMX) += imx/
87obj-$(CONFIG_DRM_MEDIATEK) += mediatek/ 88obj-$(CONFIG_DRM_MEDIATEK) += mediatek/
@@ -96,3 +97,4 @@ obj-y += hisilicon/
96obj-$(CONFIG_DRM_ZTE) += zte/ 97obj-$(CONFIG_DRM_ZTE) += zte/
97obj-$(CONFIG_DRM_MXSFB) += mxsfb/ 98obj-$(CONFIG_DRM_MXSFB) += mxsfb/
98obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ 99obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
100obj-$(CONFIG_DRM_PL111) += pl111/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 833c3c16501a..67cdab9241a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1912,10 +1912,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon);
1912u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); 1912u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
1913int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); 1913int amdgpu_enable_vblank_kms(struct drm_device *dev, unsigned int pipe);
1914void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); 1914void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe);
1915int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
1916 int *max_error,
1917 struct timeval *vblank_time,
1918 unsigned flags);
1919long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd, 1915long amdgpu_kms_compat_ioctl(struct file *filp, unsigned int cmd,
1920 unsigned long arg); 1916 unsigned long arg);
1921 1917
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index f2d705e6a75a..5cb8f3e68447 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -715,6 +715,16 @@ static const struct file_operations amdgpu_driver_kms_fops = {
715#endif 715#endif
716}; 716};
717 717
718static bool
719amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
720 bool in_vblank_irq, int *vpos, int *hpos,
721 ktime_t *stime, ktime_t *etime,
722 const struct drm_display_mode *mode)
723{
724 return amdgpu_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
725 stime, etime, mode);
726}
727
718static struct drm_driver kms_driver = { 728static struct drm_driver kms_driver = {
719 .driver_features = 729 .driver_features =
720 DRIVER_USE_AGP | 730 DRIVER_USE_AGP |
@@ -729,8 +739,8 @@ static struct drm_driver kms_driver = {
729 .get_vblank_counter = amdgpu_get_vblank_counter_kms, 739 .get_vblank_counter = amdgpu_get_vblank_counter_kms,
730 .enable_vblank = amdgpu_enable_vblank_kms, 740 .enable_vblank = amdgpu_enable_vblank_kms,
731 .disable_vblank = amdgpu_disable_vblank_kms, 741 .disable_vblank = amdgpu_disable_vblank_kms,
732 .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, 742 .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
733 .get_scanout_position = amdgpu_get_crtc_scanoutpos, 743 .get_scanout_position = amdgpu_get_crtc_scanout_position,
734#if defined(CONFIG_DEBUG_FS) 744#if defined(CONFIG_DEBUG_FS)
735 .debugfs_init = amdgpu_debugfs_init, 745 .debugfs_init = amdgpu_debugfs_init,
736#endif 746#endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 96c341670782..dca4be970d13 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -945,47 +945,6 @@ void amdgpu_disable_vblank_kms(struct drm_device *dev, unsigned int pipe)
945 amdgpu_irq_put(adev, &adev->crtc_irq, idx); 945 amdgpu_irq_put(adev, &adev->crtc_irq, idx);
946} 946}
947 947
948/**
949 * amdgpu_get_vblank_timestamp_kms - get vblank timestamp
950 *
951 * @dev: drm dev pointer
952 * @crtc: crtc to get the timestamp for
953 * @max_error: max error
954 * @vblank_time: time value
955 * @flags: flags passed to the driver
956 *
957 * Gets the timestamp on the requested crtc based on the
958 * scanout position. (all asics).
959 * Returns postive status flags on success, negative error on failure.
960 */
961int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
962 int *max_error,
963 struct timeval *vblank_time,
964 unsigned flags)
965{
966 struct drm_crtc *crtc;
967 struct amdgpu_device *adev = dev->dev_private;
968
969 if (pipe >= dev->num_crtcs) {
970 DRM_ERROR("Invalid crtc %u\n", pipe);
971 return -EINVAL;
972 }
973
974 /* Get associated drm_crtc: */
975 crtc = &adev->mode_info.crtcs[pipe]->base;
976 if (!crtc) {
977 /* This can occur on driver load if some component fails to
978 * initialize completely and driver is unloaded */
979 DRM_ERROR("Uninitialized crtc %d\n", pipe);
980 return -EINVAL;
981 }
982
983 /* Helper routine in DRM core does all the work: */
984 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
985 vblank_time, flags,
986 &crtc->hwmode);
987}
988
989const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { 948const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
990 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 949 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_CREATE, amdgpu_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
991 DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 950 DRM_IOCTL_DEF_DRV(AMDGPU_CTX, amdgpu_ctx_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index dbd10618ec20..43a9d3aec6c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -534,6 +534,9 @@ struct amdgpu_framebuffer {
534 ((em) == ATOM_ENCODER_MODE_DP_MST)) 534 ((em) == ATOM_ENCODER_MODE_DP_MST))
535 535
536/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */ 536/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */
537#define DRM_SCANOUTPOS_VALID (1 << 0)
538#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1)
539#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
537#define USE_REAL_VBLANKSTART (1 << 30) 540#define USE_REAL_VBLANKSTART (1 << 30)
538#define GET_DISTANCE_TO_VBLANKSTART (1 << 31) 541#define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
539 542
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c
index 9126d0306ab5..9b87067c022c 100644
--- a/drivers/gpu/drm/bridge/sii902x.c
+++ b/drivers/gpu/drm/bridge/sii902x.c
@@ -160,7 +160,7 @@ static int sii902x_get_modes(struct drm_connector *connector)
160 time_before(jiffies, timeout)); 160 time_before(jiffies, timeout));
161 161
162 if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) { 162 if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
163 dev_err(&sii902x->i2c->dev, "failed to acquire the i2c bus"); 163 dev_err(&sii902x->i2c->dev, "failed to acquire the i2c bus\n");
164 return -ETIMEDOUT; 164 return -ETIMEDOUT;
165 } 165 }
166 166
@@ -202,7 +202,7 @@ static int sii902x_get_modes(struct drm_connector *connector)
202 202
203 if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ | 203 if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
204 SII902X_SYS_CTRL_DDC_BUS_GRTD)) { 204 SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
205 dev_err(&sii902x->i2c->dev, "failed to release the i2c bus"); 205 dev_err(&sii902x->i2c->dev, "failed to release the i2c bus\n");
206 return -ETIMEDOUT; 206 return -ETIMEDOUT;
207 } 207 }
208 208
@@ -298,7 +298,7 @@ static int sii902x_bridge_attach(struct drm_bridge *bridge)
298 298
299 if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) { 299 if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
300 dev_err(&sii902x->i2c->dev, 300 dev_err(&sii902x->i2c->dev,
301 "sii902x driver is only compatible with DRM devices supporting atomic updates"); 301 "sii902x driver is only compatible with DRM devices supporting atomic updates\n");
302 return -ENOTSUPP; 302 return -ENOTSUPP;
303 } 303 }
304 304
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 4e1f54a675d8..8737de8c1c52 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -173,6 +173,8 @@ struct dw_hdmi {
173 173
174 unsigned int reg_shift; 174 unsigned int reg_shift;
175 struct regmap *regm; 175 struct regmap *regm;
176 void (*enable_audio)(struct dw_hdmi *hdmi);
177 void (*disable_audio)(struct dw_hdmi *hdmi);
176}; 178};
177 179
178#define HDMI_IH_PHY_STAT0_RX_SENSE \ 180#define HDMI_IH_PHY_STAT0_RX_SENSE \
@@ -542,13 +544,41 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
542} 544}
543EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate); 545EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
544 546
547static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
548{
549 hdmi_modb(hdmi, enable ? 0 : HDMI_MC_CLKDIS_AUDCLK_DISABLE,
550 HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
551}
552
553static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
554{
555 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
556}
557
558static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi)
559{
560 hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
561}
562
563static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi)
564{
565 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
566 hdmi_enable_audio_clk(hdmi, true);
567}
568
569static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi)
570{
571 hdmi_enable_audio_clk(hdmi, false);
572}
573
545void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) 574void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
546{ 575{
547 unsigned long flags; 576 unsigned long flags;
548 577
549 spin_lock_irqsave(&hdmi->audio_lock, flags); 578 spin_lock_irqsave(&hdmi->audio_lock, flags);
550 hdmi->audio_enable = true; 579 hdmi->audio_enable = true;
551 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); 580 if (hdmi->enable_audio)
581 hdmi->enable_audio(hdmi);
552 spin_unlock_irqrestore(&hdmi->audio_lock, flags); 582 spin_unlock_irqrestore(&hdmi->audio_lock, flags);
553} 583}
554EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable); 584EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable);
@@ -559,7 +589,8 @@ void dw_hdmi_audio_disable(struct dw_hdmi *hdmi)
559 589
560 spin_lock_irqsave(&hdmi->audio_lock, flags); 590 spin_lock_irqsave(&hdmi->audio_lock, flags);
561 hdmi->audio_enable = false; 591 hdmi->audio_enable = false;
562 hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); 592 if (hdmi->disable_audio)
593 hdmi->disable_audio(hdmi);
563 spin_unlock_irqrestore(&hdmi->audio_lock, flags); 594 spin_unlock_irqrestore(&hdmi->audio_lock, flags);
564} 595}
565EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable); 596EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable);
@@ -1573,11 +1604,6 @@ static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
1573 HDMI_MC_FLOWCTRL); 1604 HDMI_MC_FLOWCTRL);
1574} 1605}
1575 1606
1576static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi)
1577{
1578 hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
1579}
1580
1581/* Workaround to clear the overflow condition */ 1607/* Workaround to clear the overflow condition */
1582static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) 1608static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1583{ 1609{
@@ -1691,7 +1717,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1691 1717
1692 /* HDMI Initialization Step E - Configure audio */ 1718 /* HDMI Initialization Step E - Configure audio */
1693 hdmi_clk_regenerator_update_pixel_clock(hdmi); 1719 hdmi_clk_regenerator_update_pixel_clock(hdmi);
1694 hdmi_enable_audio_clk(hdmi); 1720 hdmi_enable_audio_clk(hdmi, true);
1695 } 1721 }
1696 1722
1697 /* not for DVI mode */ 1723 /* not for DVI mode */
@@ -2403,6 +2429,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
2403 audio.irq = irq; 2429 audio.irq = irq;
2404 audio.hdmi = hdmi; 2430 audio.hdmi = hdmi;
2405 audio.eld = hdmi->connector.eld; 2431 audio.eld = hdmi->connector.eld;
2432 hdmi->enable_audio = dw_hdmi_ahb_audio_enable;
2433 hdmi->disable_audio = dw_hdmi_ahb_audio_disable;
2406 2434
2407 pdevinfo.name = "dw-hdmi-ahb-audio"; 2435 pdevinfo.name = "dw-hdmi-ahb-audio";
2408 pdevinfo.data = &audio; 2436 pdevinfo.data = &audio;
@@ -2415,6 +2443,8 @@ __dw_hdmi_probe(struct platform_device *pdev,
2415 audio.hdmi = hdmi; 2443 audio.hdmi = hdmi;
2416 audio.write = hdmi_writeb; 2444 audio.write = hdmi_writeb;
2417 audio.read = hdmi_readb; 2445 audio.read = hdmi_readb;
2446 hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
2447 hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
2418 2448
2419 pdevinfo.name = "dw-hdmi-i2s-audio"; 2449 pdevinfo.name = "dw-hdmi-i2s-audio";
2420 pdevinfo.data = &audio; 2450 pdevinfo.data = &audio;
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f32506a7c1d6..cdec19a86af3 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -57,6 +57,7 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
57 kfree(state->connectors); 57 kfree(state->connectors);
58 kfree(state->crtcs); 58 kfree(state->crtcs);
59 kfree(state->planes); 59 kfree(state->planes);
60 kfree(state->private_objs);
60} 61}
61EXPORT_SYMBOL(drm_atomic_state_default_release); 62EXPORT_SYMBOL(drm_atomic_state_default_release);
62 63
@@ -184,6 +185,17 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
184 state->planes[i].ptr = NULL; 185 state->planes[i].ptr = NULL;
185 state->planes[i].state = NULL; 186 state->planes[i].state = NULL;
186 } 187 }
188
189 for (i = 0; i < state->num_private_objs; i++) {
190 void *obj_state = state->private_objs[i].obj_state;
191
192 state->private_objs[i].funcs->destroy_state(obj_state);
193 state->private_objs[i].obj = NULL;
194 state->private_objs[i].obj_state = NULL;
195 state->private_objs[i].funcs = NULL;
196 }
197 state->num_private_objs = 0;
198
187} 199}
188EXPORT_SYMBOL(drm_atomic_state_default_clear); 200EXPORT_SYMBOL(drm_atomic_state_default_clear);
189 201
@@ -425,7 +437,7 @@ drm_atomic_replace_property_blob(struct drm_property_blob **blob,
425} 437}
426 438
427static int 439static int
428drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc, 440drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
429 struct drm_property_blob **blob, 441 struct drm_property_blob **blob,
430 uint64_t blob_id, 442 uint64_t blob_id,
431 ssize_t expected_size, 443 ssize_t expected_size,
@@ -434,7 +446,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc,
434 struct drm_property_blob *new_blob = NULL; 446 struct drm_property_blob *new_blob = NULL;
435 447
436 if (blob_id != 0) { 448 if (blob_id != 0) {
437 new_blob = drm_property_lookup_blob(crtc->dev, blob_id); 449 new_blob = drm_property_lookup_blob(dev, blob_id);
438 if (new_blob == NULL) 450 if (new_blob == NULL)
439 return -EINVAL; 451 return -EINVAL;
440 452
@@ -483,7 +495,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
483 drm_property_blob_put(mode); 495 drm_property_blob_put(mode);
484 return ret; 496 return ret;
485 } else if (property == config->degamma_lut_property) { 497 } else if (property == config->degamma_lut_property) {
486 ret = drm_atomic_replace_property_blob_from_id(crtc, 498 ret = drm_atomic_replace_property_blob_from_id(dev,
487 &state->degamma_lut, 499 &state->degamma_lut,
488 val, 500 val,
489 -1, 501 -1,
@@ -491,7 +503,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
491 state->color_mgmt_changed |= replaced; 503 state->color_mgmt_changed |= replaced;
492 return ret; 504 return ret;
493 } else if (property == config->ctm_property) { 505 } else if (property == config->ctm_property) {
494 ret = drm_atomic_replace_property_blob_from_id(crtc, 506 ret = drm_atomic_replace_property_blob_from_id(dev,
495 &state->ctm, 507 &state->ctm,
496 val, 508 val,
497 sizeof(struct drm_color_ctm), 509 sizeof(struct drm_color_ctm),
@@ -499,7 +511,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
499 state->color_mgmt_changed |= replaced; 511 state->color_mgmt_changed |= replaced;
500 return ret; 512 return ret;
501 } else if (property == config->gamma_lut_property) { 513 } else if (property == config->gamma_lut_property) {
502 ret = drm_atomic_replace_property_blob_from_id(crtc, 514 ret = drm_atomic_replace_property_blob_from_id(dev,
503 &state->gamma_lut, 515 &state->gamma_lut,
504 val, 516 val,
505 -1, 517 -1,
@@ -978,6 +990,59 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
978} 990}
979 991
980/** 992/**
993 * drm_atomic_get_private_obj_state - get private object state
994 * @state: global atomic state
995 * @obj: private object to get the state for
996 * @funcs: pointer to the struct of function pointers that identify the object
997 * type
998 *
999 * This function returns the private object state for the given private object,
1000 * allocating the state if needed. It does not grab any locks as the caller is
1001 * expected to care of any required locking.
1002 *
1003 * RETURNS:
1004 *
1005 * Either the allocated state or the error code encoded into a pointer.
1006 */
1007void *
1008drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
1009 const struct drm_private_state_funcs *funcs)
1010{
1011 int index, num_objs, i;
1012 size_t size;
1013 struct __drm_private_objs_state *arr;
1014
1015 for (i = 0; i < state->num_private_objs; i++)
1016 if (obj == state->private_objs[i].obj &&
1017 state->private_objs[i].obj_state)
1018 return state->private_objs[i].obj_state;
1019
1020 num_objs = state->num_private_objs + 1;
1021 size = sizeof(*state->private_objs) * num_objs;
1022 arr = krealloc(state->private_objs, size, GFP_KERNEL);
1023 if (!arr)
1024 return ERR_PTR(-ENOMEM);
1025
1026 state->private_objs = arr;
1027 index = state->num_private_objs;
1028 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
1029
1030 state->private_objs[index].obj_state = funcs->duplicate_state(state, obj);
1031 if (!state->private_objs[index].obj_state)
1032 return ERR_PTR(-ENOMEM);
1033
1034 state->private_objs[index].obj = obj;
1035 state->private_objs[index].funcs = funcs;
1036 state->num_private_objs = num_objs;
1037
1038 DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n",
1039 state->private_objs[index].obj_state, state);
1040
1041 return state->private_objs[index].obj_state;
1042}
1043EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
1044
1045/**
981 * drm_atomic_get_connector_state - get connector state 1046 * drm_atomic_get_connector_state - get connector state
982 * @state: global atomic state object 1047 * @state: global atomic state object
983 * @connector: connector to get state object for 1048 * @connector: connector to get state object for
@@ -1123,6 +1188,10 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
1123 */ 1188 */
1124 if (state->link_status != DRM_LINK_STATUS_GOOD) 1189 if (state->link_status != DRM_LINK_STATUS_GOOD)
1125 state->link_status = val; 1190 state->link_status = val;
1191 } else if (property == config->aspect_ratio_property) {
1192 state->picture_aspect_ratio = val;
1193 } else if (property == connector->scaling_mode_property) {
1194 state->scaling_mode = val;
1126 } else if (connector->funcs->atomic_set_property) { 1195 } else if (connector->funcs->atomic_set_property) {
1127 return connector->funcs->atomic_set_property(connector, 1196 return connector->funcs->atomic_set_property(connector,
1128 state, property, val); 1197 state, property, val);
@@ -1199,6 +1268,10 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
1199 *val = state->tv.hue; 1268 *val = state->tv.hue;
1200 } else if (property == config->link_status_property) { 1269 } else if (property == config->link_status_property) {
1201 *val = state->link_status; 1270 *val = state->link_status;
1271 } else if (property == config->aspect_ratio_property) {
1272 *val = state->picture_aspect_ratio;
1273 } else if (property == connector->scaling_mode_property) {
1274 *val = state->scaling_mode;
1202 } else if (connector->funcs->atomic_get_property) { 1275 } else if (connector->funcs->atomic_get_property) {
1203 return connector->funcs->atomic_get_property(connector, 1276 return connector->funcs->atomic_get_property(connector,
1204 state, property, val); 1277 state, property, val);
@@ -1618,7 +1691,7 @@ int drm_atomic_commit(struct drm_atomic_state *state)
1618 if (ret) 1691 if (ret)
1619 return ret; 1692 return ret;
1620 1693
1621 DRM_DEBUG_ATOMIC("commiting %p\n", state); 1694 DRM_DEBUG_ATOMIC("committing %p\n", state);
1622 1695
1623 return config->funcs->atomic_commit(state->dev, state, false); 1696 return config->funcs->atomic_commit(state->dev, state, false);
1624} 1697}
@@ -1647,7 +1720,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1647 if (ret) 1720 if (ret)
1648 return ret; 1721 return ret;
1649 1722
1650 DRM_DEBUG_ATOMIC("commiting %p nonblocking\n", state); 1723 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1651 1724
1652 return config->funcs->atomic_commit(state->dev, state, true); 1725 return config->funcs->atomic_commit(state->dev, state, true);
1653} 1726}
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 8be9719284b0..6426339427a4 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1070,8 +1070,8 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
1070 * 1070 *
1071 * Note that @pre_swap is needed since the point where we block for fences moves 1071 * Note that @pre_swap is needed since the point where we block for fences moves
1072 * around depending upon whether an atomic commit is blocking or 1072 * around depending upon whether an atomic commit is blocking or
1073 * non-blocking. For async commit all waiting needs to happen after 1073 * non-blocking. For non-blocking commit all waiting needs to happen after
1074 * drm_atomic_helper_swap_state() is called, but for synchronous commits we want 1074 * drm_atomic_helper_swap_state() is called, but for blocking commits we want
1075 * to wait **before** we do anything that can't be easily rolled back. That is 1075 * to wait **before** we do anything that can't be easily rolled back. That is
1076 * before we call drm_atomic_helper_swap_state(). 1076 * before we call drm_atomic_helper_swap_state().
1077 * 1077 *
@@ -2032,6 +2032,8 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2032 struct drm_plane *plane; 2032 struct drm_plane *plane;
2033 struct drm_plane_state *old_plane_state, *new_plane_state; 2033 struct drm_plane_state *old_plane_state, *new_plane_state;
2034 struct drm_crtc_commit *commit; 2034 struct drm_crtc_commit *commit;
2035 void *obj, *obj_state;
2036 const struct drm_private_state_funcs *funcs;
2035 2037
2036 if (stall) { 2038 if (stall) {
2037 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 2039 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
@@ -2092,6 +2094,9 @@ void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2092 state->planes[i].state = old_plane_state; 2094 state->planes[i].state = old_plane_state;
2093 plane->state = new_plane_state; 2095 plane->state = new_plane_state;
2094 } 2096 }
2097
2098 __for_each_private_obj(state, obj, obj_state, i, funcs)
2099 funcs->swap_state(obj, &state->private_objs[i].obj_state);
2095} 2100}
2096EXPORT_SYMBOL(drm_atomic_helper_swap_state); 2101EXPORT_SYMBOL(drm_atomic_helper_swap_state);
2097 2102
@@ -3517,7 +3522,8 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
3517 * 3522 *
3518 * Implements support for legacy gamma correction table for drivers 3523 * Implements support for legacy gamma correction table for drivers
3519 * that support color management through the DEGAMMA_LUT/GAMMA_LUT 3524 * that support color management through the DEGAMMA_LUT/GAMMA_LUT
3520 * properties. 3525 * properties. See drm_crtc_enable_color_mgmt() and the containing chapter for
3526 * how the atomic color management and gamma tables work.
3521 */ 3527 */
3522int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, 3528int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3523 u16 *red, u16 *green, u16 *blue, 3529 u16 *red, u16 *green, u16 *blue,
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 533f3a3e6877..3eda500fc005 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -43,7 +43,8 @@
43 * 43 *
44 * Setting this to NULL (blob property value set to 0) means a 44 * Setting this to NULL (blob property value set to 0) means a
45 * linear/pass-thru gamma table should be used. This is generally the 45 * linear/pass-thru gamma table should be used. This is generally the
46 * driver boot-up state too. 46 * driver boot-up state too. Drivers can access this blob through
47 * &drm_crtc_state.degamma_lut.
47 * 48 *
48 * “DEGAMMA_LUT_SIZE”: 49 * “DEGAMMA_LUT_SIZE”:
49 * Unsinged range property to give the size of the lookup table to be set 50 * Unsinged range property to give the size of the lookup table to be set
@@ -60,7 +61,8 @@
60 * 61 *
61 * Setting this to NULL (blob property value set to 0) means a 62 * Setting this to NULL (blob property value set to 0) means a
62 * unit/pass-thru matrix should be used. This is generally the driver 63 * unit/pass-thru matrix should be used. This is generally the driver
63 * boot-up state too. 64 * boot-up state too. Drivers can access the blob for the color conversion
65 * matrix through &drm_crtc_state.ctm.
64 * 66 *
65 * “GAMMA_LUT”: 67 * “GAMMA_LUT”:
66 * Blob property to set the gamma lookup table (LUT) mapping pixel data 68 * Blob property to set the gamma lookup table (LUT) mapping pixel data
@@ -72,7 +74,8 @@
72 * 74 *
73 * Setting this to NULL (blob property value set to 0) means a 75 * Setting this to NULL (blob property value set to 0) means a
74 * linear/pass-thru gamma table should be used. This is generally the 76 * linear/pass-thru gamma table should be used. This is generally the
75 * driver boot-up state too. 77 * driver boot-up state too. Drivers can access this blob through
78 * &drm_crtc_state.gamma_lut.
76 * 79 *
77 * “GAMMA_LUT_SIZE”: 80 * “GAMMA_LUT_SIZE”:
78 * Unsigned range property to give the size of the lookup table to be set 81 * Unsigned range property to give the size of the lookup table to be set
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 9f847615ac74..5cd61aff7857 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -941,6 +941,10 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
941 * 941 *
942 * Called by a driver the first time it's needed, must be attached to desired 942 * Called by a driver the first time it's needed, must be attached to desired
943 * connectors. 943 * connectors.
944 *
945 * Atomic drivers should use drm_connector_attach_scaling_mode_property()
946 * instead to correctly assign &drm_connector_state.picture_aspect_ratio
947 * in the atomic state.
944 */ 948 */
945int drm_mode_create_scaling_mode_property(struct drm_device *dev) 949int drm_mode_create_scaling_mode_property(struct drm_device *dev)
946{ 950{
@@ -961,6 +965,66 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev)
961EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); 965EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
962 966
963/** 967/**
968 * drm_connector_attach_scaling_mode_property - attach atomic scaling mode property
969 * @connector: connector to attach scaling mode property on.
970 * @scaling_mode_mask: or'ed mask of BIT(%DRM_MODE_SCALE_\*).
971 *
972 * This is used to add support for scaling mode to atomic drivers.
973 * The scaling mode will be set to &drm_connector_state.picture_aspect_ratio
974 * and can be used from &drm_connector_helper_funcs->atomic_check for validation.
975 *
976 * This is the atomic version of drm_mode_create_scaling_mode_property().
977 *
978 * Returns:
979 * Zero on success, negative errno on failure.
980 */
981int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
982 u32 scaling_mode_mask)
983{
984 struct drm_device *dev = connector->dev;
985 struct drm_property *scaling_mode_property;
986 int i, j = 0;
987 const unsigned valid_scaling_mode_mask =
988 (1U << ARRAY_SIZE(drm_scaling_mode_enum_list)) - 1;
989
990 if (WARN_ON(hweight32(scaling_mode_mask) < 2 ||
991 scaling_mode_mask & ~valid_scaling_mode_mask))
992 return -EINVAL;
993
994 scaling_mode_property =
995 drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
996 hweight32(scaling_mode_mask));
997
998 if (!scaling_mode_property)
999 return -ENOMEM;
1000
1001 for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) {
1002 int ret;
1003
1004 if (!(BIT(i) & scaling_mode_mask))
1005 continue;
1006
1007 ret = drm_property_add_enum(scaling_mode_property, j++,
1008 drm_scaling_mode_enum_list[i].type,
1009 drm_scaling_mode_enum_list[i].name);
1010
1011 if (ret) {
1012 drm_property_destroy(dev, scaling_mode_property);
1013
1014 return ret;
1015 }
1016 }
1017
1018 drm_object_attach_property(&connector->base,
1019 scaling_mode_property, 0);
1020
1021 connector->scaling_mode_property = scaling_mode_property;
1022
1023 return 0;
1024}
1025EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
1026
1027/**
964 * drm_mode_create_aspect_ratio_property - create aspect ratio property 1028 * drm_mode_create_aspect_ratio_property - create aspect ratio property
965 * @dev: DRM device 1029 * @dev: DRM device
966 * 1030 *
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index d3fc7e4e85b7..222eb1a8549b 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -737,16 +737,16 @@ static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr,
737static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr, 737static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr,
738 struct drm_dp_sideband_msg_tx *txmsg) 738 struct drm_dp_sideband_msg_tx *txmsg)
739{ 739{
740 bool ret; 740 unsigned int state;
741 741
742 /* 742 /*
743 * All updates to txmsg->state are protected by mgr->qlock, and the two 743 * All updates to txmsg->state are protected by mgr->qlock, and the two
744 * cases we check here are terminal states. For those the barriers 744 * cases we check here are terminal states. For those the barriers
745 * provided by the wake_up/wait_event pair are enough. 745 * provided by the wake_up/wait_event pair are enough.
746 */ 746 */
747 ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX || 747 state = READ_ONCE(txmsg->state);
748 txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT); 748 return (state == DRM_DP_SIDEBAND_TX_RX ||
749 return ret; 749 state == DRM_DP_SIDEBAND_TX_TIMEOUT);
750} 750}
751 751
752static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb, 752static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
@@ -855,7 +855,7 @@ static void drm_dp_destroy_mst_branch_device(struct kref *kref)
855 mutex_unlock(&mstb->mgr->qlock); 855 mutex_unlock(&mstb->mgr->qlock);
856 856
857 if (wake_tx) 857 if (wake_tx)
858 wake_up(&mstb->mgr->tx_waitq); 858 wake_up_all(&mstb->mgr->tx_waitq);
859 859
860 kref_put(kref, drm_dp_free_mst_branch_device); 860 kref_put(kref, drm_dp_free_mst_branch_device);
861} 861}
@@ -1510,7 +1510,7 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
1510 if (txmsg->seqno != -1) 1510 if (txmsg->seqno != -1)
1511 txmsg->dst->tx_slots[txmsg->seqno] = NULL; 1511 txmsg->dst->tx_slots[txmsg->seqno] = NULL;
1512 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT; 1512 txmsg->state = DRM_DP_SIDEBAND_TX_TIMEOUT;
1513 wake_up(&mgr->tx_waitq); 1513 wake_up_all(&mgr->tx_waitq);
1514 } 1514 }
1515} 1515}
1516 1516
@@ -2258,7 +2258,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
2258 mstb->tx_slots[slot] = NULL; 2258 mstb->tx_slots[slot] = NULL;
2259 mutex_unlock(&mgr->qlock); 2259 mutex_unlock(&mgr->qlock);
2260 2260
2261 wake_up(&mgr->tx_waitq); 2261 wake_up_all(&mgr->tx_waitq);
2262 } 2262 }
2263 return ret; 2263 return ret;
2264} 2264}
@@ -2498,6 +2498,81 @@ static int drm_dp_init_vcpi(struct drm_dp_mst_topology_mgr *mgr,
2498} 2498}
2499 2499
2500/** 2500/**
2501 * drm_dp_atomic_find_vcpi_slots() - Find and add vcpi slots to the state
2502 * @state: global atomic state
2503 * @mgr: MST topology manager for the port
2504 * @port: port to find vcpi slots for
2505 * @pbn: bandwidth required for the mode in PBN
2506 *
2507 * RETURNS:
2508 * Total slots in the atomic state assigned for this port or error
2509 */
2510int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
2511 struct drm_dp_mst_topology_mgr *mgr,
2512 struct drm_dp_mst_port *port, int pbn)
2513{
2514 struct drm_dp_mst_topology_state *topology_state;
2515 int req_slots;
2516
2517 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2518 if (topology_state == NULL)
2519 return -ENOMEM;
2520
2521 port = drm_dp_get_validated_port_ref(mgr, port);
2522 if (port == NULL)
2523 return -EINVAL;
2524 req_slots = DIV_ROUND_UP(pbn, mgr->pbn_div);
2525 DRM_DEBUG_KMS("vcpi slots req=%d, avail=%d\n",
2526 req_slots, topology_state->avail_slots);
2527
2528 if (req_slots > topology_state->avail_slots) {
2529 drm_dp_put_port(port);
2530 return -ENOSPC;
2531 }
2532
2533 topology_state->avail_slots -= req_slots;
2534 DRM_DEBUG_KMS("vcpi slots avail=%d", topology_state->avail_slots);
2535
2536 drm_dp_put_port(port);
2537 return req_slots;
2538}
2539EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
2540
2541/**
2542 * drm_dp_atomic_release_vcpi_slots() - Release allocated vcpi slots
2543 * @state: global atomic state
2544 * @mgr: MST topology manager for the port
2545 * @slots: number of vcpi slots to release
2546 *
2547 * RETURNS:
2548 * 0 if @slots were added back to &drm_dp_mst_topology_state->avail_slots or
2549 * negative error code
2550 */
2551int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
2552 struct drm_dp_mst_topology_mgr *mgr,
2553 int slots)
2554{
2555 struct drm_dp_mst_topology_state *topology_state;
2556
2557 topology_state = drm_atomic_get_mst_topology_state(state, mgr);
2558 if (topology_state == NULL)
2559 return -ENOMEM;
2560
2561 /* We cannot rely on port->vcpi.num_slots to update
2562 * topology_state->avail_slots as the port may not exist if the parent
2563 * branch device was unplugged. This should be fixed by tracking
2564 * per-port slot allocation in drm_dp_mst_topology_state instead of
2565 * depending on the caller to tell us how many slots to release.
2566 */
2567 topology_state->avail_slots += slots;
2568 DRM_DEBUG_KMS("vcpi slots released=%d, avail=%d\n",
2569 slots, topology_state->avail_slots);
2570
2571 return 0;
2572}
2573EXPORT_SYMBOL(drm_dp_atomic_release_vcpi_slots);
2574
2575/**
2501 * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel 2576 * drm_dp_mst_allocate_vcpi() - Allocate a virtual channel
2502 * @mgr: manager for this port 2577 * @mgr: manager for this port
2503 * @port: port to allocate a virtual channel for. 2578 * @port: port to allocate a virtual channel for.
@@ -2936,6 +3011,69 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
2936 (*mgr->cbs->hotplug)(mgr); 3011 (*mgr->cbs->hotplug)(mgr);
2937} 3012}
2938 3013
3014void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj)
3015{
3016 struct drm_dp_mst_topology_mgr *mgr = obj;
3017 struct drm_dp_mst_topology_state *new_mst_state;
3018
3019 if (WARN_ON(!mgr->state))
3020 return NULL;
3021
3022 new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL);
3023 if (new_mst_state)
3024 new_mst_state->state = state;
3025 return new_mst_state;
3026}
3027
3028void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
3029{
3030 struct drm_dp_mst_topology_mgr *mgr = obj;
3031 struct drm_dp_mst_topology_state **topology_state_ptr;
3032
3033 topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
3034
3035 mgr->state->state = (*topology_state_ptr)->state;
3036 swap(*topology_state_ptr, mgr->state);
3037 mgr->state->state = NULL;
3038}
3039
3040void drm_dp_mst_destroy_state(void *obj_state)
3041{
3042 kfree(obj_state);
3043}
3044
3045static const struct drm_private_state_funcs mst_state_funcs = {
3046 .duplicate_state = drm_dp_mst_duplicate_state,
3047 .swap_state = drm_dp_mst_swap_state,
3048 .destroy_state = drm_dp_mst_destroy_state,
3049};
3050
3051/**
3052 * drm_atomic_get_mst_topology_state: get MST topology state
3053 *
3054 * @state: global atomic state
3055 * @mgr: MST topology manager, also the private object in this case
3056 *
3057 * This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic
3058 * state vtable so that the private object state returned is that of a MST
3059 * topology object. Also, drm_atomic_get_private_obj_state() expects the caller
3060 * to care of the locking, so warn if don't hold the connection_mutex.
3061 *
3062 * RETURNS:
3063 *
3064 * The MST topology state or error pointer.
3065 */
3066struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
3067 struct drm_dp_mst_topology_mgr *mgr)
3068{
3069 struct drm_device *dev = mgr->dev;
3070
3071 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
3072 return drm_atomic_get_private_obj_state(state, mgr,
3073 &mst_state_funcs);
3074}
3075EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
3076
2939/** 3077/**
2940 * drm_dp_mst_topology_mgr_init - initialise a topology manager 3078 * drm_dp_mst_topology_mgr_init - initialise a topology manager
2941 * @mgr: manager struct to initialise 3079 * @mgr: manager struct to initialise
@@ -2980,6 +3118,15 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
2980 if (test_calc_pbn_mode() < 0) 3118 if (test_calc_pbn_mode() < 0)
2981 DRM_ERROR("MST PBN self-test failed\n"); 3119 DRM_ERROR("MST PBN self-test failed\n");
2982 3120
3121 mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL);
3122 if (mgr->state == NULL)
3123 return -ENOMEM;
3124 mgr->state->mgr = mgr;
3125
3126 /* max. time slots - one slot for MTP header */
3127 mgr->state->avail_slots = 63;
3128 mgr->funcs = &mst_state_funcs;
3129
2983 return 0; 3130 return 0;
2984} 3131}
2985EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init); 3132EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
@@ -3000,6 +3147,9 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr)
3000 mutex_unlock(&mgr->payload_lock); 3147 mutex_unlock(&mgr->payload_lock);
3001 mgr->dev = NULL; 3148 mgr->dev = NULL;
3002 mgr->aux = NULL; 3149 mgr->aux = NULL;
3150 kfree(mgr->state);
3151 mgr->state = NULL;
3152 mgr->funcs = NULL;
3003} 3153}
3004EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy); 3154EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
3005 3155
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 50abd1faf38f..53f9bdf470d7 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -189,7 +189,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
189 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); 189 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
190 if (!obj) { 190 if (!obj) {
191 dev_err(dev->dev, "Failed to lookup GEM object\n"); 191 dev_err(dev->dev, "Failed to lookup GEM object\n");
192 ret = -ENXIO; 192 ret = -ENOENT;
193 goto err_gem_object_put; 193 goto err_gem_object_put;
194 } 194 }
195 195
@@ -260,6 +260,33 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
260EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); 260EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
261 261
262/** 262/**
263 * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer
264 * @fb: The framebuffer
265 * @state: Which state of drm plane
266 * @plane: Which plane
267 * Return the CMA GEM address for given framebuffer.
268 *
269 * This function will usually be called from the PLANE callback functions.
270 */
271dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
272 struct drm_plane_state *state,
273 unsigned int plane)
274{
275 struct drm_fb_cma *fb_cma = to_fb_cma(fb);
276 dma_addr_t paddr;
277
278 if (plane >= 4)
279 return 0;
280
281 paddr = fb_cma->obj[plane]->paddr + fb->offsets[plane];
282 paddr += fb->format->cpp[plane] * (state->src_x >> 16);
283 paddr += fb->pitches[plane] * (state->src_y >> 16);
284
285 return paddr;
286}
287EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);
288
289/**
263 * drm_fb_cma_prepare_fb() - Prepare CMA framebuffer 290 * drm_fb_cma_prepare_fb() - Prepare CMA framebuffer
264 * @plane: Which plane 291 * @plane: Which plane
265 * @state: Plane state attach fence to 292 * @state: Plane state attach fence to
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 3783b659cd38..caad93dab54b 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -351,9 +351,8 @@ void drm_lastclose(struct drm_device * dev)
351 * 351 *
352 * This function must be used by drivers as their &file_operations.release 352 * This function must be used by drivers as their &file_operations.release
353 * method. It frees any resources associated with the open file, and calls the 353 * method. It frees any resources associated with the open file, and calls the
354 * &drm_driver.preclose and &drm_driver.lastclose driver callbacks. If this is 354 * &drm_driver.postclose driver callback. If this is the last open file for the
355 * the last open file for the DRM device also proceeds to call the 355 * DRM device also proceeds to call the &drm_driver.lastclose driver callback.
356 * &drm_driver.lastclose driver callback.
357 * 356 *
358 * RETURNS: 357 * RETURNS:
359 * 358 *
@@ -373,7 +372,8 @@ int drm_release(struct inode *inode, struct file *filp)
373 list_del(&file_priv->lhead); 372 list_del(&file_priv->lhead);
374 mutex_unlock(&dev->filelist_mutex); 373 mutex_unlock(&dev->filelist_mutex);
375 374
376 if (dev->driver->preclose) 375 if (drm_core_check_feature(dev, DRIVER_LEGACY) &&
376 dev->driver->preclose)
377 dev->driver->preclose(dev, file_priv); 377 dev->driver->preclose(dev, file_priv);
378 378
379 /* ======================================================== 379 /* ========================================================
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 8c866cac62dd..c7debaad67f8 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -54,7 +54,7 @@
54 54
55static bool 55static bool
56drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, 56drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
57 struct timeval *tvblank, unsigned flags); 57 struct timeval *tvblank, bool in_vblank_irq);
58 58
59static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ 59static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
60 60
@@ -138,7 +138,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
138 */ 138 */
139 do { 139 do {
140 cur_vblank = __get_vblank_counter(dev, pipe); 140 cur_vblank = __get_vblank_counter(dev, pipe);
141 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); 141 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
142 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); 142 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
143 143
144 /* 144 /*
@@ -171,7 +171,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
171 * device vblank fields. 171 * device vblank fields.
172 */ 172 */
173static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe, 173static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
174 unsigned long flags) 174 bool in_vblank_irq)
175{ 175{
176 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 176 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
177 u32 cur_vblank, diff; 177 u32 cur_vblank, diff;
@@ -194,7 +194,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
194 */ 194 */
195 do { 195 do {
196 cur_vblank = __get_vblank_counter(dev, pipe); 196 cur_vblank = __get_vblank_counter(dev, pipe);
197 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags); 197 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
198 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); 198 } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
199 199
200 if (dev->max_vblank_count != 0) { 200 if (dev->max_vblank_count != 0) {
@@ -214,13 +214,13 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
214 */ 214 */
215 diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns); 215 diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
216 216
217 if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ) 217 if (diff == 0 && in_vblank_irq)
218 DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored." 218 DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored."
219 " diff_ns = %lld, framedur_ns = %d)\n", 219 " diff_ns = %lld, framedur_ns = %d)\n",
220 pipe, (long long) diff_ns, framedur_ns); 220 pipe, (long long) diff_ns, framedur_ns);
221 } else { 221 } else {
222 /* some kind of default for drivers w/o accurate vbl timestamping */ 222 /* some kind of default for drivers w/o accurate vbl timestamping */
223 diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0; 223 diff = in_vblank_irq ? 1 : 0;
224 } 224 }
225 225
226 /* 226 /*
@@ -253,7 +253,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
253 * Otherwise reinitialize delayed at next vblank interrupt and assign 0 253 * Otherwise reinitialize delayed at next vblank interrupt and assign 0
254 * for now, to mark the vblanktimestamp as invalid. 254 * for now, to mark the vblanktimestamp as invalid.
255 */ 255 */
256 if (!rc && (flags & DRM_CALLED_FROM_VBLIRQ) == 0) 256 if (!rc && in_vblank_irq)
257 t_vblank = (struct timeval) {0, 0}; 257 t_vblank = (struct timeval) {0, 0};
258 258
259 store_vblank(dev, pipe, diff, &t_vblank, cur_vblank); 259 store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
@@ -291,7 +291,7 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc)
291 291
292 spin_lock_irqsave(&dev->vblank_time_lock, flags); 292 spin_lock_irqsave(&dev->vblank_time_lock, flags);
293 293
294 drm_update_vblank_count(dev, pipe, 0); 294 drm_update_vblank_count(dev, pipe, false);
295 vblank = drm_vblank_count(dev, pipe); 295 vblank = drm_vblank_count(dev, pipe);
296 296
297 spin_unlock_irqrestore(&dev->vblank_time_lock, flags); 297 spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
@@ -349,7 +349,7 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
349 * this time. This makes the count account for the entire time 349 * this time. This makes the count account for the entire time
350 * between drm_crtc_vblank_on() and drm_crtc_vblank_off(). 350 * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
351 */ 351 */
352 drm_update_vblank_count(dev, pipe, 0); 352 drm_update_vblank_count(dev, pipe, false);
353 353
354 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 354 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
355} 355}
@@ -684,6 +684,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
684 684
685 vblank->linedur_ns = linedur_ns; 685 vblank->linedur_ns = linedur_ns;
686 vblank->framedur_ns = framedur_ns; 686 vblank->framedur_ns = framedur_ns;
687 vblank->hwmode = *mode;
687 688
688 DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 689 DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
689 crtc->base.id, mode->crtc_htotal, 690 crtc->base.id, mode->crtc_htotal,
@@ -700,10 +701,10 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
700 * @max_error: Desired maximum allowable error in timestamps (nanosecs) 701 * @max_error: Desired maximum allowable error in timestamps (nanosecs)
701 * On return contains true maximum error of timestamp 702 * On return contains true maximum error of timestamp
702 * @vblank_time: Pointer to struct timeval which should receive the timestamp 703 * @vblank_time: Pointer to struct timeval which should receive the timestamp
703 * @flags: Flags to pass to driver: 704 * @in_vblank_irq:
704 * 0 = Default, 705 * True when called from drm_crtc_handle_vblank(). Some drivers
705 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler 706 * need to apply some workarounds for gpu-specific vblank irq quirks
706 * @mode: mode which defines the scanout timings 707 * if flag is set.
707 * 708 *
708 * Implements calculation of exact vblank timestamps from given drm_display_mode 709 * Implements calculation of exact vblank timestamps from given drm_display_mode
709 * timings and current video scanout position of a CRTC. This can be called from 710 * timings and current video scanout position of a CRTC. This can be called from
@@ -723,52 +724,62 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
723 * returns as no operation if a doublescan or interlaced video mode is 724 * returns as no operation if a doublescan or interlaced video mode is
724 * active. Higher level code is expected to handle this. 725 * active. Higher level code is expected to handle this.
725 * 726 *
726 * Returns: 727 * This function can be used to implement the &drm_driver.get_vblank_timestamp
727 * Negative value on error, failure or if not supported in current 728 * directly, if the driver implements the &drm_driver.get_scanout_position hook.
728 * video mode:
729 *
730 * -EINVAL Invalid CRTC.
731 * -EAGAIN Temporary unavailable, e.g., called before initial modeset.
732 * -ENOTSUPP Function not supported in current display mode.
733 * -EIO Failed, e.g., due to failed scanout position query.
734 * 729 *
735 * Returns or'ed positive status flags on success: 730 * Note that atomic drivers must call drm_calc_timestamping_constants() before
731 * enabling a CRTC. The atomic helpers already take care of that in
732 * drm_atomic_helper_update_legacy_modeset_state().
736 * 733 *
737 * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. 734 * Returns:
738 * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval.
739 * 735 *
736 * Returns true on success, and false on failure, i.e. when no accurate
737 * timestamp could be acquired.
740 */ 738 */
741int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, 739bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
742 unsigned int pipe, 740 unsigned int pipe,
743 int *max_error, 741 int *max_error,
744 struct timeval *vblank_time, 742 struct timeval *vblank_time,
745 unsigned flags, 743 bool in_vblank_irq)
746 const struct drm_display_mode *mode)
747{ 744{
748 struct timeval tv_etime; 745 struct timeval tv_etime;
749 ktime_t stime, etime; 746 ktime_t stime, etime;
750 unsigned int vbl_status; 747 bool vbl_status;
751 int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 748 struct drm_crtc *crtc;
749 const struct drm_display_mode *mode;
750 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
752 int vpos, hpos, i; 751 int vpos, hpos, i;
753 int delta_ns, duration_ns; 752 int delta_ns, duration_ns;
754 753
755 if (pipe >= dev->num_crtcs) { 754 if (!drm_core_check_feature(dev, DRIVER_MODESET))
755 return false;
756
757 crtc = drm_crtc_from_index(dev, pipe);
758
759 if (pipe >= dev->num_crtcs || !crtc) {
756 DRM_ERROR("Invalid crtc %u\n", pipe); 760 DRM_ERROR("Invalid crtc %u\n", pipe);
757 return -EINVAL; 761 return false;
758 } 762 }
759 763
760 /* Scanout position query not supported? Should not happen. */ 764 /* Scanout position query not supported? Should not happen. */
761 if (!dev->driver->get_scanout_position) { 765 if (!dev->driver->get_scanout_position) {
762 DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); 766 DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
763 return -EIO; 767 return false;
764 } 768 }
765 769
770 if (drm_drv_uses_atomic_modeset(dev))
771 mode = &vblank->hwmode;
772 else
773 mode = &crtc->hwmode;
774
766 /* If mode timing undefined, just return as no-op: 775 /* If mode timing undefined, just return as no-op:
767 * Happens during initial modesetting of a crtc. 776 * Happens during initial modesetting of a crtc.
768 */ 777 */
769 if (mode->crtc_clock == 0) { 778 if (mode->crtc_clock == 0) {
770 DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); 779 DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
771 return -EAGAIN; 780 WARN_ON_ONCE(drm_drv_uses_atomic_modeset(dev));
781
782 return false;
772 } 783 }
773 784
774 /* Get current scanout position with system timestamp. 785 /* Get current scanout position with system timestamp.
@@ -783,16 +794,17 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
783 * Get vertical and horizontal scanout position vpos, hpos, 794 * Get vertical and horizontal scanout position vpos, hpos,
784 * and bounding timestamps stime, etime, pre/post query. 795 * and bounding timestamps stime, etime, pre/post query.
785 */ 796 */
786 vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, 797 vbl_status = dev->driver->get_scanout_position(dev, pipe,
798 in_vblank_irq,
787 &vpos, &hpos, 799 &vpos, &hpos,
788 &stime, &etime, 800 &stime, &etime,
789 mode); 801 mode);
790 802
791 /* Return as no-op if scanout query unsupported or failed. */ 803 /* Return as no-op if scanout query unsupported or failed. */
792 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { 804 if (!vbl_status) {
793 DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", 805 DRM_DEBUG("crtc %u : scanoutpos query failed.\n",
794 pipe, vbl_status); 806 pipe);
795 return -EIO; 807 return false;
796 } 808 }
797 809
798 /* Compute uncertainty in timestamp of scanout position query. */ 810 /* Compute uncertainty in timestamp of scanout position query. */
@@ -830,13 +842,13 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
830 etime = ktime_sub_ns(etime, delta_ns); 842 etime = ktime_sub_ns(etime, delta_ns);
831 *vblank_time = ktime_to_timeval(etime); 843 *vblank_time = ktime_to_timeval(etime);
832 844
833 DRM_DEBUG_VBL("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", 845 DRM_DEBUG_VBL("crtc %u : v p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
834 pipe, vbl_status, hpos, vpos, 846 pipe, hpos, vpos,
835 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, 847 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
836 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, 848 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
837 duration_ns/1000, i); 849 duration_ns/1000, i);
838 850
839 return ret; 851 return true;
840} 852}
841EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); 853EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
842 854
@@ -854,9 +866,10 @@ static struct timeval get_drm_timestamp(void)
854 * @dev: DRM device 866 * @dev: DRM device
855 * @pipe: index of CRTC whose vblank timestamp to retrieve 867 * @pipe: index of CRTC whose vblank timestamp to retrieve
856 * @tvblank: Pointer to target struct timeval which should receive the timestamp 868 * @tvblank: Pointer to target struct timeval which should receive the timestamp
857 * @flags: Flags to pass to driver: 869 * @in_vblank_irq:
858 * 0 = Default, 870 * True when called from drm_crtc_handle_vblank(). Some drivers
859 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler 871 * need to apply some workarounds for gpu-specific vblank irq quirks
872 * if flag is set.
860 * 873 *
861 * Fetches the system timestamp corresponding to the time of the most recent 874 * Fetches the system timestamp corresponding to the time of the most recent
862 * vblank interval on specified CRTC. May call into kms-driver to 875 * vblank interval on specified CRTC. May call into kms-driver to
@@ -870,27 +883,25 @@ static struct timeval get_drm_timestamp(void)
870 */ 883 */
871static bool 884static bool
872drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe, 885drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
873 struct timeval *tvblank, unsigned flags) 886 struct timeval *tvblank, bool in_vblank_irq)
874{ 887{
875 int ret; 888 bool ret = false;
876 889
877 /* Define requested maximum error on timestamps (nanoseconds). */ 890 /* Define requested maximum error on timestamps (nanoseconds). */
878 int max_error = (int) drm_timestamp_precision * 1000; 891 int max_error = (int) drm_timestamp_precision * 1000;
879 892
880 /* Query driver if possible and precision timestamping enabled. */ 893 /* Query driver if possible and precision timestamping enabled. */
881 if (dev->driver->get_vblank_timestamp && (max_error > 0)) { 894 if (dev->driver->get_vblank_timestamp && (max_error > 0))
882 ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error, 895 ret = dev->driver->get_vblank_timestamp(dev, pipe, &max_error,
883 tvblank, flags); 896 tvblank, in_vblank_irq);
884 if (ret > 0)
885 return true;
886 }
887 897
888 /* GPU high precision timestamp query unsupported or failed. 898 /* GPU high precision timestamp query unsupported or failed.
889 * Return current monotonic/gettimeofday timestamp as best estimate. 899 * Return current monotonic/gettimeofday timestamp as best estimate.
890 */ 900 */
891 *tvblank = get_drm_timestamp(); 901 if (!ret)
902 *tvblank = get_drm_timestamp();
892 903
893 return false; 904 return ret;
894} 905}
895 906
896/** 907/**
@@ -1329,6 +1340,10 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
1329 send_vblank_event(dev, e, seq, &now); 1340 send_vblank_event(dev, e, seq, &now);
1330 } 1341 }
1331 spin_unlock_irqrestore(&dev->event_lock, irqflags); 1342 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1343
1344 /* Will be reset by the modeset helpers when re-enabling the crtc by
1345 * calling drm_calc_timestamping_constants(). */
1346 vblank->hwmode.crtc_clock = 0;
1332} 1347}
1333EXPORT_SYMBOL(drm_crtc_vblank_off); 1348EXPORT_SYMBOL(drm_crtc_vblank_off);
1334 1349
@@ -1760,7 +1775,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1760 return false; 1775 return false;
1761 } 1776 }
1762 1777
1763 drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ); 1778 drm_update_vblank_count(dev, pipe, true);
1764 1779
1765 spin_unlock(&dev->vblank_time_lock); 1780 spin_unlock(&dev->vblank_time_lock);
1766 1781
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index b84a295230fc..2c27f6f5a668 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -381,6 +381,7 @@ EXPORT_SYMBOL(drm_primary_helper_update);
381/** 381/**
382 * drm_primary_helper_disable() - Helper for primary plane disable 382 * drm_primary_helper_disable() - Helper for primary plane disable
383 * @plane: plane to disable 383 * @plane: plane to disable
384 * @ctx: lock acquire context, not used here
384 * 385 *
385 * Provides a default plane disable handler for primary planes. This is handler 386 * Provides a default plane disable handler for primary planes. This is handler
386 * is called in response to a userspace SetPlane operation on the plane with a 387 * is called in response to a userspace SetPlane operation on the plane with a
@@ -510,12 +511,10 @@ int drm_plane_helper_commit(struct drm_plane *plane,
510 if (plane_funcs->cleanup_fb) 511 if (plane_funcs->cleanup_fb)
511 plane_funcs->cleanup_fb(plane, plane_state); 512 plane_funcs->cleanup_fb(plane, plane_state);
512out: 513out:
513 if (plane_state) { 514 if (plane->funcs->atomic_destroy_state)
514 if (plane->funcs->atomic_destroy_state) 515 plane->funcs->atomic_destroy_state(plane, plane_state);
515 plane->funcs->atomic_destroy_state(plane, plane_state); 516 else
516 else 517 drm_atomic_helper_plane_destroy_state(plane, plane_state);
517 drm_atomic_helper_plane_destroy_state(plane, plane_state);
518 }
519 518
520 return ret; 519 return ret;
521} 520}
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 954eb848b5e2..22408badc617 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -595,15 +595,18 @@ out_unlock:
595EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); 595EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
596 596
597/** 597/**
598 * drm_gem_prime_import - helper library implementation of the import callback 598 * drm_gem_prime_import_dev - core implementation of the import callback
599 * @dev: drm_device to import into 599 * @dev: drm_device to import into
600 * @dma_buf: dma-buf object to import 600 * @dma_buf: dma-buf object to import
601 * @attach_dev: struct device to dma_buf attach
601 * 602 *
602 * This is the implementation of the gem_prime_import functions for GEM drivers 603 * This is the core of drm_gem_prime_import. It's designed to be called by
603 * using the PRIME helpers. 604 * drivers who want to use a different device structure than dev->dev for
605 * attaching via dma_buf.
604 */ 606 */
605struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev, 607struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
606 struct dma_buf *dma_buf) 608 struct dma_buf *dma_buf,
609 struct device *attach_dev)
607{ 610{
608 struct dma_buf_attachment *attach; 611 struct dma_buf_attachment *attach;
609 struct sg_table *sgt; 612 struct sg_table *sgt;
@@ -625,7 +628,7 @@ struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
625 if (!dev->driver->gem_prime_import_sg_table) 628 if (!dev->driver->gem_prime_import_sg_table)
626 return ERR_PTR(-EINVAL); 629 return ERR_PTR(-EINVAL);
627 630
628 attach = dma_buf_attach(dma_buf, dev->dev); 631 attach = dma_buf_attach(dma_buf, attach_dev);
629 if (IS_ERR(attach)) 632 if (IS_ERR(attach))
630 return ERR_CAST(attach); 633 return ERR_CAST(attach);
631 634
@@ -655,6 +658,21 @@ fail_detach:
655 658
656 return ERR_PTR(ret); 659 return ERR_PTR(ret);
657} 660}
661EXPORT_SYMBOL(drm_gem_prime_import_dev);
662
663/**
664 * drm_gem_prime_import - helper library implementation of the import callback
665 * @dev: drm_device to import into
666 * @dma_buf: dma-buf object to import
667 *
668 * This is the implementation of the gem_prime_import functions for GEM drivers
669 * using the PRIME helpers.
670 */
671struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
672 struct dma_buf *dma_buf)
673{
674 return drm_gem_prime_import_dev(dev, dma_buf, dev->dev);
675}
658EXPORT_SYMBOL(drm_gem_prime_import); 676EXPORT_SYMBOL(drm_gem_prime_import);
659 677
660/** 678/**
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 09d3c4c3c858..50294a7bd29d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -82,14 +82,9 @@ err_file_priv_free:
82 return ret; 82 return ret;
83} 83}
84 84
85static void exynos_drm_preclose(struct drm_device *dev,
86 struct drm_file *file)
87{
88 exynos_drm_subdrv_close(dev, file);
89}
90
91static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) 85static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
92{ 86{
87 exynos_drm_subdrv_close(dev, file);
93 kfree(file->driver_priv); 88 kfree(file->driver_priv);
94 file->driver_priv = NULL; 89 file->driver_priv = NULL;
95} 90}
@@ -145,7 +140,6 @@ static struct drm_driver exynos_drm_driver = {
145 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME 140 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME
146 | DRIVER_ATOMIC | DRIVER_RENDER, 141 | DRIVER_ATOMIC | DRIVER_RENDER,
147 .open = exynos_drm_open, 142 .open = exynos_drm_open,
148 .preclose = exynos_drm_preclose,
149 .lastclose = exynos_drm_lastclose, 143 .lastclose = exynos_drm_lastclose,
150 .postclose = exynos_drm_postclose, 144 .postclose = exynos_drm_postclose,
151 .gem_free_object_unlocked = exynos_drm_gem_free_object, 145 .gem_free_object_unlocked = exynos_drm_gem_free_object,
diff --git a/drivers/gpu/drm/gma500/mdfld_tpo_vid.c b/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
index d8d4170725b2..d40628e6810d 100644
--- a/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
+++ b/drivers/gpu/drm/gma500/mdfld_tpo_vid.c
@@ -32,53 +32,20 @@ static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev)
32 struct drm_display_mode *mode; 32 struct drm_display_mode *mode;
33 struct drm_psb_private *dev_priv = dev->dev_private; 33 struct drm_psb_private *dev_priv = dev->dev_private;
34 struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; 34 struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD;
35 bool use_gct = false;
36 35
37 mode = kzalloc(sizeof(*mode), GFP_KERNEL); 36 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
38 if (!mode) 37 if (!mode)
39 return NULL; 38 return NULL;
40 39
41 if (use_gct) { 40 mode->hdisplay = 864;
42 mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; 41 mode->vdisplay = 480;
43 mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; 42 mode->hsync_start = 873;
44 mode->hsync_start = mode->hdisplay + 43 mode->hsync_end = 876;
45 ((ti->hsync_offset_hi << 8) | 44 mode->htotal = 887;
46 ti->hsync_offset_lo); 45 mode->vsync_start = 487;
47 mode->hsync_end = mode->hsync_start + 46 mode->vsync_end = 490;
48 ((ti->hsync_pulse_width_hi << 8) | 47 mode->vtotal = 499;
49 ti->hsync_pulse_width_lo); 48 mode->clock = 33264;
50 mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) |
51 ti->hblank_lo);
52 mode->vsync_start =
53 mode->vdisplay + ((ti->vsync_offset_hi << 8) |
54 ti->vsync_offset_lo);
55 mode->vsync_end =
56 mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) |
57 ti->vsync_pulse_width_lo);
58 mode->vtotal = mode->vdisplay +
59 ((ti->vblank_hi << 8) | ti->vblank_lo);
60 mode->clock = ti->pixel_clock * 10;
61
62 dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
63 dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
64 dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
65 dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
66 dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
67 dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
68 dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
69 dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
70 dev_dbg(dev->dev, "clock is %d\n", mode->clock);
71 } else {
72 mode->hdisplay = 864;
73 mode->vdisplay = 480;
74 mode->hsync_start = 873;
75 mode->hsync_end = 876;
76 mode->htotal = 887;
77 mode->vsync_start = 487;
78 mode->vsync_end = 490;
79 mode->vtotal = 499;
80 mode->clock = 33264;
81 }
82 49
83 drm_mode_set_name(mode); 50 drm_mode_set_name(mode);
84 drm_mode_set_crtcinfo(mode, 0); 51 drm_mode_set_crtcinfo(mode, 0);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index fd97fe00cd0d..04493ef1d2f7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -720,9 +720,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
720 struct drm_i915_private *dev_priv = to_i915(dev); 720 struct drm_i915_private *dev_priv = to_i915(dev);
721 i915_reg_t high_frame, low_frame; 721 i915_reg_t high_frame, low_frame;
722 u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; 722 u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
723 struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, 723 const struct drm_display_mode *mode = &dev->vblank[pipe].hwmode;
724 pipe);
725 const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
726 unsigned long irqflags; 724 unsigned long irqflags;
727 725
728 htotal = mode->crtc_htotal; 726 htotal = mode->crtc_htotal;
@@ -779,13 +777,17 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
779{ 777{
780 struct drm_device *dev = crtc->base.dev; 778 struct drm_device *dev = crtc->base.dev;
781 struct drm_i915_private *dev_priv = to_i915(dev); 779 struct drm_i915_private *dev_priv = to_i915(dev);
782 const struct drm_display_mode *mode = &crtc->base.hwmode; 780 const struct drm_display_mode *mode;
781 struct drm_vblank_crtc *vblank;
783 enum pipe pipe = crtc->pipe; 782 enum pipe pipe = crtc->pipe;
784 int position, vtotal; 783 int position, vtotal;
785 784
786 if (!crtc->active) 785 if (!crtc->active)
787 return -1; 786 return -1;
788 787
788 vblank = &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
789 mode = &vblank->hwmode;
790
789 vtotal = mode->crtc_vtotal; 791 vtotal = mode->crtc_vtotal;
790 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 792 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
791 vtotal /= 2; 793 vtotal /= 2;
@@ -827,10 +829,10 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc)
827 return (position + crtc->scanline_offset) % vtotal; 829 return (position + crtc->scanline_offset) % vtotal;
828} 830}
829 831
830static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, 832static bool i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
831 unsigned int flags, int *vpos, int *hpos, 833 bool in_vblank_irq, int *vpos, int *hpos,
832 ktime_t *stime, ktime_t *etime, 834 ktime_t *stime, ktime_t *etime,
833 const struct drm_display_mode *mode) 835 const struct drm_display_mode *mode)
834{ 836{
835 struct drm_i915_private *dev_priv = to_i915(dev); 837 struct drm_i915_private *dev_priv = to_i915(dev);
836 struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv, 838 struct intel_crtc *intel_crtc = intel_get_crtc_for_pipe(dev_priv,
@@ -838,13 +840,12 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
838 int position; 840 int position;
839 int vbl_start, vbl_end, hsync_start, htotal, vtotal; 841 int vbl_start, vbl_end, hsync_start, htotal, vtotal;
840 bool in_vbl = true; 842 bool in_vbl = true;
841 int ret = 0;
842 unsigned long irqflags; 843 unsigned long irqflags;
843 844
844 if (WARN_ON(!mode->crtc_clock)) { 845 if (WARN_ON(!mode->crtc_clock)) {
845 DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " 846 DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
846 "pipe %c\n", pipe_name(pipe)); 847 "pipe %c\n", pipe_name(pipe));
847 return 0; 848 return false;
848 } 849 }
849 850
850 htotal = mode->crtc_htotal; 851 htotal = mode->crtc_htotal;
@@ -859,8 +860,6 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
859 vtotal /= 2; 860 vtotal /= 2;
860 } 861 }
861 862
862 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
863
864 /* 863 /*
865 * Lock uncore.lock, as we will do multiple timing critical raw 864 * Lock uncore.lock, as we will do multiple timing critical raw
866 * register reads, potentially with preemption disabled, so the 865 * register reads, potentially with preemption disabled, so the
@@ -944,11 +943,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
944 *hpos = position - (*vpos * htotal); 943 *hpos = position - (*vpos * htotal);
945 } 944 }
946 945
947 /* In vblank? */ 946 return true;
948 if (in_vbl)
949 ret |= DRM_SCANOUTPOS_IN_VBLANK;
950
951 return ret;
952} 947}
953 948
954int intel_get_crtc_scanline(struct intel_crtc *crtc) 949int intel_get_crtc_scanline(struct intel_crtc *crtc)
@@ -964,37 +959,6 @@ int intel_get_crtc_scanline(struct intel_crtc *crtc)
964 return position; 959 return position;
965} 960}
966 961
967static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
968 int *max_error,
969 struct timeval *vblank_time,
970 unsigned flags)
971{
972 struct drm_i915_private *dev_priv = to_i915(dev);
973 struct intel_crtc *crtc;
974
975 if (pipe >= INTEL_INFO(dev_priv)->num_pipes) {
976 DRM_ERROR("Invalid crtc %u\n", pipe);
977 return -EINVAL;
978 }
979
980 /* Get drm_crtc to timestamp: */
981 crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
982 if (crtc == NULL) {
983 DRM_ERROR("Invalid crtc %u\n", pipe);
984 return -EINVAL;
985 }
986
987 if (!crtc->base.hwmode.crtc_clock) {
988 DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
989 return -EBUSY;
990 }
991
992 /* Helper routine in DRM core does all the work: */
993 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
994 vblank_time, flags,
995 &crtc->base.hwmode);
996}
997
998static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) 962static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv)
999{ 963{
1000 u32 busy_up, busy_down, max_avg, min_avg; 964 u32 busy_up, busy_down, max_avg, min_avg;
@@ -4294,7 +4258,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
4294 4258
4295 dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; 4259 dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
4296 4260
4297 dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; 4261 dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
4298 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; 4262 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
4299 4263
4300 if (IS_CHERRYVIEW(dev_priv)) { 4264 if (IS_CHERRYVIEW(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3617927af269..2f2bb623cf5f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11444,12 +11444,6 @@ intel_modeset_update_crtc_state(struct drm_atomic_state *state)
11444 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { 11444 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
11445 to_intel_crtc(crtc)->config = to_intel_crtc_state(new_crtc_state); 11445 to_intel_crtc(crtc)->config = to_intel_crtc_state(new_crtc_state);
11446 11446
11447 /* Update hwmode for vblank functions */
11448 if (new_crtc_state->active)
11449 crtc->hwmode = new_crtc_state->adjusted_mode;
11450 else
11451 crtc->hwmode.crtc_clock = 0;
11452
11453 /* 11447 /*
11454 * Update legacy state to satisfy fbc code. This can 11448 * Update legacy state to satisfy fbc code. This can
11455 * be removed when fbc uses the atomic state. 11449 * be removed when fbc uses the atomic state.
@@ -15425,8 +15419,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15425 to_intel_crtc_state(crtc->base.state); 15419 to_intel_crtc_state(crtc->base.state);
15426 int pixclk = 0; 15420 int pixclk = 0;
15427 15421
15428 crtc->base.hwmode = crtc_state->base.adjusted_mode;
15429
15430 memset(&crtc->base.mode, 0, sizeof(crtc->base.mode)); 15422 memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
15431 if (crtc_state->base.active) { 15423 if (crtc_state->base.active) {
15432 intel_mode_from_pipe_config(&crtc->base.mode, crtc_state); 15424 intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
@@ -15456,7 +15448,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
15456 if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) 15448 if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
15457 pixclk = DIV_ROUND_UP(pixclk * 100, 95); 15449 pixclk = DIV_ROUND_UP(pixclk * 100, 95);
15458 15450
15459 drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode); 15451 drm_calc_timestamping_constants(&crtc->base,
15452 &crtc_state->base.adjusted_mode);
15460 update_scanline_offset(crtc); 15453 update_scanline_offset(crtc);
15461 } 15454 }
15462 15455
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index c1f62eb07c07..1dee9933005f 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -39,7 +39,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
39 struct intel_dp *intel_dp = &intel_dig_port->dp; 39 struct intel_dp *intel_dp = &intel_dig_port->dp;
40 struct intel_connector *connector = 40 struct intel_connector *connector =
41 to_intel_connector(conn_state->connector); 41 to_intel_connector(conn_state->connector);
42 struct drm_atomic_state *state; 42 struct drm_atomic_state *state = pipe_config->base.state;
43 int bpp; 43 int bpp;
44 int lane_count, slots; 44 int lane_count, slots;
45 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; 45 const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
@@ -57,20 +57,24 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
57 * seem to suggest we should do otherwise. 57 * seem to suggest we should do otherwise.
58 */ 58 */
59 lane_count = drm_dp_max_lane_count(intel_dp->dpcd); 59 lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
60
61 pipe_config->lane_count = lane_count; 60 pipe_config->lane_count = lane_count;
62 61
63 pipe_config->pipe_bpp = bpp; 62 pipe_config->pipe_bpp = bpp;
64 pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
65 63
66 state = pipe_config->base.state; 64 pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
67 65
68 if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port)) 66 if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port))
69 pipe_config->has_audio = true; 67 pipe_config->has_audio = true;
70 mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
71 68
69 mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
72 pipe_config->pbn = mst_pbn; 70 pipe_config->pbn = mst_pbn;
73 slots = drm_dp_find_vcpi_slots(&intel_dp->mst_mgr, mst_pbn); 71
72 slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
73 connector->port, mst_pbn);
74 if (slots < 0) {
75 DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
76 return false;
77 }
74 78
75 intel_link_compute_m_n(bpp, lane_count, 79 intel_link_compute_m_n(bpp, lane_count,
76 adjusted_mode->crtc_clock, 80 adjusted_mode->crtc_clock,
@@ -80,7 +84,38 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
80 pipe_config->dp_m_n.tu = slots; 84 pipe_config->dp_m_n.tu = slots;
81 85
82 return true; 86 return true;
87}
83 88
89static int intel_dp_mst_atomic_check(struct drm_connector *connector,
90 struct drm_connector_state *new_conn_state)
91{
92 struct drm_atomic_state *state = new_conn_state->state;
93 struct drm_connector_state *old_conn_state;
94 struct drm_crtc *old_crtc;
95 struct drm_crtc_state *crtc_state;
96 int slots, ret = 0;
97
98 old_conn_state = drm_atomic_get_old_connector_state(state, connector);
99 old_crtc = old_conn_state->crtc;
100 if (!old_crtc)
101 return ret;
102
103 crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
104 slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu;
105 if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) {
106 struct drm_dp_mst_topology_mgr *mgr;
107 struct drm_encoder *old_encoder;
108
109 old_encoder = old_conn_state->best_encoder;
110 mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr;
111
112 ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots);
113 if (ret)
114 DRM_DEBUG_KMS("failed releasing %d vcpi slots:%d\n", slots, ret);
115 else
116 to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0;
117 }
118 return ret;
84} 119}
85 120
86static void intel_mst_disable_dp(struct intel_encoder *encoder, 121static void intel_mst_disable_dp(struct intel_encoder *encoder,
@@ -387,6 +422,7 @@ static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_fun
387 .mode_valid = intel_dp_mst_mode_valid, 422 .mode_valid = intel_dp_mst_mode_valid,
388 .atomic_best_encoder = intel_mst_atomic_best_encoder, 423 .atomic_best_encoder = intel_mst_atomic_best_encoder,
389 .best_encoder = intel_mst_best_encoder, 424 .best_encoder = intel_mst_best_encoder,
425 .atomic_check = intel_dp_mst_atomic_check,
390}; 426};
391 427
392static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder) 428static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index aaee3949a422..48ea8d9d49fe 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -869,7 +869,6 @@ struct intel_hdmi {
869 bool has_audio; 869 bool has_audio;
870 enum hdmi_force_audio force_audio; 870 enum hdmi_force_audio force_audio;
871 bool rgb_quant_range_selectable; 871 bool rgb_quant_range_selectable;
872 enum hdmi_picture_aspect aspect_ratio;
873 struct intel_connector *attached_connector; 872 struct intel_connector *attached_connector;
874 void (*write_infoframe)(struct drm_encoder *encoder, 873 void (*write_infoframe)(struct drm_encoder *encoder,
875 const struct intel_crtc_state *crtc_state, 874 const struct intel_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1d623b5e09d6..c6b8207724fa 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1403,7 +1403,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
1403 } 1403 }
1404 1404
1405 /* Set user selected PAR to incoming mode's member */ 1405 /* Set user selected PAR to incoming mode's member */
1406 adjusted_mode->picture_aspect_ratio = intel_hdmi->aspect_ratio; 1406 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio;
1407 1407
1408 pipe_config->lane_count = 4; 1408 pipe_config->lane_count = 4;
1409 1409
@@ -1649,19 +1649,7 @@ intel_hdmi_set_property(struct drm_connector *connector,
1649 } 1649 }
1650 1650
1651 if (property == connector->dev->mode_config.aspect_ratio_property) { 1651 if (property == connector->dev->mode_config.aspect_ratio_property) {
1652 switch (val) { 1652 connector->state->picture_aspect_ratio = val;
1653 case DRM_MODE_PICTURE_ASPECT_NONE:
1654 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1655 break;
1656 case DRM_MODE_PICTURE_ASPECT_4_3:
1657 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
1658 break;
1659 case DRM_MODE_PICTURE_ASPECT_16_9:
1660 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
1661 break;
1662 default:
1663 return -EINVAL;
1664 }
1665 goto done; 1653 goto done;
1666 } 1654 }
1667 1655
@@ -1823,7 +1811,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
1823 intel_attach_broadcast_rgb_property(connector); 1811 intel_attach_broadcast_rgb_property(connector);
1824 intel_hdmi->color_range_auto = true; 1812 intel_hdmi->color_range_auto = true;
1825 intel_attach_aspect_ratio_property(connector); 1813 intel_attach_aspect_ratio_property(connector);
1826 intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; 1814 connector->state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
1827} 1815}
1828 1816
1829/* 1817/*
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 816a6f5a3fd9..ef6fa87b2f8a 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -107,11 +107,6 @@ struct intel_sdvo {
107 bool color_range_auto; 107 bool color_range_auto;
108 108
109 /** 109 /**
110 * HDMI user specified aspect ratio
111 */
112 enum hdmi_picture_aspect aspect_ratio;
113
114 /**
115 * This is set if we're going to treat the device as TV-out. 110 * This is set if we're going to treat the device as TV-out.
116 * 111 *
117 * While we have these nice friendly flags for output types that ought 112 * While we have these nice friendly flags for output types that ought
@@ -1186,7 +1181,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1186 1181
1187 /* Set user selected PAR to incoming mode's member */ 1182 /* Set user selected PAR to incoming mode's member */
1188 if (intel_sdvo->is_hdmi) 1183 if (intel_sdvo->is_hdmi)
1189 adjusted_mode->picture_aspect_ratio = intel_sdvo->aspect_ratio; 1184 adjusted_mode->picture_aspect_ratio = conn_state->picture_aspect_ratio;
1190 1185
1191 return true; 1186 return true;
1192} 1187}
@@ -2067,19 +2062,7 @@ intel_sdvo_set_property(struct drm_connector *connector,
2067 } 2062 }
2068 2063
2069 if (property == connector->dev->mode_config.aspect_ratio_property) { 2064 if (property == connector->dev->mode_config.aspect_ratio_property) {
2070 switch (val) { 2065 connector->state->picture_aspect_ratio = val;
2071 case DRM_MODE_PICTURE_ASPECT_NONE:
2072 intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
2073 break;
2074 case DRM_MODE_PICTURE_ASPECT_4_3:
2075 intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_4_3;
2076 break;
2077 case DRM_MODE_PICTURE_ASPECT_16_9:
2078 intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_16_9;
2079 break;
2080 default:
2081 return -EINVAL;
2082 }
2083 goto done; 2066 goto done;
2084 } 2067 }
2085 2068
@@ -2418,7 +2401,7 @@ intel_sdvo_add_hdmi_properties(struct intel_sdvo *intel_sdvo,
2418 intel_sdvo->color_range_auto = true; 2401 intel_sdvo->color_range_auto = true;
2419 } 2402 }
2420 intel_attach_aspect_ratio_property(&connector->base.base); 2403 intel_attach_aspect_ratio_property(&connector->base.base);
2421 intel_sdvo->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; 2404 connector->base.base.state->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
2422} 2405}
2423 2406
2424static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) 2407static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index d3d6b4cae1e6..e2b3346ead48 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -527,31 +527,28 @@ static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
527 return NULL; 527 return NULL;
528} 528}
529 529
530static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe, 530static bool mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
531 unsigned int flags, int *vpos, int *hpos, 531 bool in_vblank_irq, int *vpos, int *hpos,
532 ktime_t *stime, ktime_t *etime, 532 ktime_t *stime, ktime_t *etime,
533 const struct drm_display_mode *mode) 533 const struct drm_display_mode *mode)
534{ 534{
535 struct msm_drm_private *priv = dev->dev_private; 535 struct msm_drm_private *priv = dev->dev_private;
536 struct drm_crtc *crtc; 536 struct drm_crtc *crtc;
537 struct drm_encoder *encoder; 537 struct drm_encoder *encoder;
538 int line, vsw, vbp, vactive_start, vactive_end, vfp_end; 538 int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
539 int ret = 0;
540 539
541 crtc = priv->crtcs[pipe]; 540 crtc = priv->crtcs[pipe];
542 if (!crtc) { 541 if (!crtc) {
543 DRM_ERROR("Invalid crtc %d\n", pipe); 542 DRM_ERROR("Invalid crtc %d\n", pipe);
544 return 0; 543 return false;
545 } 544 }
546 545
547 encoder = get_encoder_from_crtc(crtc); 546 encoder = get_encoder_from_crtc(crtc);
548 if (!encoder) { 547 if (!encoder) {
549 DRM_ERROR("no encoder found for crtc %d\n", pipe); 548 DRM_ERROR("no encoder found for crtc %d\n", pipe);
550 return 0; 549 return false;
551 } 550 }
552 551
553 ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
554
555 vsw = mode->crtc_vsync_end - mode->crtc_vsync_start; 552 vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
556 vbp = mode->crtc_vtotal - mode->crtc_vsync_end; 553 vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
557 554
@@ -575,10 +572,8 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
575 572
576 if (line < vactive_start) { 573 if (line < vactive_start) {
577 line -= vactive_start; 574 line -= vactive_start;
578 ret |= DRM_SCANOUTPOS_IN_VBLANK;
579 } else if (line > vactive_end) { 575 } else if (line > vactive_end) {
580 line = line - vfp_end - vactive_start; 576 line = line - vfp_end - vactive_start;
581 ret |= DRM_SCANOUTPOS_IN_VBLANK;
582 } else { 577 } else {
583 line -= vactive_start; 578 line -= vactive_start;
584 } 579 }
@@ -589,31 +584,7 @@ static int mdp5_get_scanoutpos(struct drm_device *dev, unsigned int pipe,
589 if (etime) 584 if (etime)
590 *etime = ktime_get(); 585 *etime = ktime_get();
591 586
592 return ret; 587 return true;
593}
594
595static int mdp5_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe,
596 int *max_error,
597 struct timeval *vblank_time,
598 unsigned flags)
599{
600 struct msm_drm_private *priv = dev->dev_private;
601 struct drm_crtc *crtc;
602
603 if (pipe < 0 || pipe >= priv->num_crtcs) {
604 DRM_ERROR("Invalid crtc %d\n", pipe);
605 return -EINVAL;
606 }
607
608 crtc = priv->crtcs[pipe];
609 if (!crtc) {
610 DRM_ERROR("Invalid crtc %d\n", pipe);
611 return -EINVAL;
612 }
613
614 return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
615 vblank_time, flags,
616 &crtc->mode);
617} 588}
618 589
619static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe) 590static u32 mdp5_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
@@ -725,7 +696,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
725 dev->mode_config.max_width = 0xffff; 696 dev->mode_config.max_width = 0xffff;
726 dev->mode_config.max_height = 0xffff; 697 dev->mode_config.max_height = 0xffff;
727 698
728 dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp; 699 dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
729 dev->driver->get_scanout_position = mdp5_get_scanoutpos; 700 dev->driver->get_scanout_position = mdp5_get_scanoutpos;
730 dev->driver->get_vblank_counter = mdp5_get_vblank_counter; 701 dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
731 dev->max_vblank_count = 0xffffffff; 702 dev->max_vblank_count = 0xffffffff;
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 21b10f9840c9..6718c84fb862 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -98,7 +98,7 @@ calc(int blanks, int blanke, int total, int line)
98 return line; 98 return line;
99} 99}
100 100
101static int 101static bool
102nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 102nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
103 ktime_t *stime, ktime_t *etime) 103 ktime_t *stime, ktime_t *etime)
104{ 104{
@@ -111,16 +111,16 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
111 }; 111 };
112 struct nouveau_display *disp = nouveau_display(crtc->dev); 112 struct nouveau_display *disp = nouveau_display(crtc->dev);
113 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; 113 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
114 int ret, retry = 20; 114 int retry = 20;
115 bool ret = false;
115 116
116 do { 117 do {
117 ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); 118 ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
118 if (ret != 0) 119 if (ret != 0)
119 return 0; 120 return false;
120 121
121 if (args.scan.vline) { 122 if (args.scan.vline) {
122 ret |= DRM_SCANOUTPOS_ACCURATE; 123 ret = true;
123 ret |= DRM_SCANOUTPOS_VALID;
124 break; 124 break;
125 } 125 }
126 126
@@ -133,14 +133,12 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
133 if (stime) *stime = ns_to_ktime(args.scan.time[0]); 133 if (stime) *stime = ns_to_ktime(args.scan.time[0]);
134 if (etime) *etime = ns_to_ktime(args.scan.time[1]); 134 if (etime) *etime = ns_to_ktime(args.scan.time[1]);
135 135
136 if (*vpos < 0)
137 ret |= DRM_SCANOUTPOS_IN_VBLANK;
138 return ret; 136 return ret;
139} 137}
140 138
141int 139bool
142nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, 140nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe,
143 unsigned int flags, int *vpos, int *hpos, 141 bool in_vblank_irq, int *vpos, int *hpos,
144 ktime_t *stime, ktime_t *etime, 142 ktime_t *stime, ktime_t *etime,
145 const struct drm_display_mode *mode) 143 const struct drm_display_mode *mode)
146{ 144{
@@ -153,28 +151,7 @@ nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe,
153 } 151 }
154 } 152 }
155 153
156 return 0; 154 return false;
157}
158
159int
160nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe,
161 int *max_error, struct timeval *time, unsigned flags)
162{
163 struct drm_crtc *crtc;
164
165 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
166 if (nouveau_crtc(crtc)->index == pipe) {
167 struct drm_display_mode *mode;
168 if (drm_drv_uses_atomic_modeset(dev))
169 mode = &crtc->state->adjusted_mode;
170 else
171 mode = &crtc->hwmode;
172 return drm_calc_vbltimestamp_from_scanoutpos(dev,
173 pipe, max_error, time, flags, mode);
174 }
175 }
176
177 return -EINVAL;
178} 155}
179 156
180static void 157static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
index e1d772d39488..201aec2ea5b8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
@@ -68,11 +68,9 @@ int nouveau_display_suspend(struct drm_device *dev, bool runtime);
68void nouveau_display_resume(struct drm_device *dev, bool runtime); 68void nouveau_display_resume(struct drm_device *dev, bool runtime);
69int nouveau_display_vblank_enable(struct drm_device *, unsigned int); 69int nouveau_display_vblank_enable(struct drm_device *, unsigned int);
70void nouveau_display_vblank_disable(struct drm_device *, unsigned int); 70void nouveau_display_vblank_disable(struct drm_device *, unsigned int);
71int nouveau_display_scanoutpos(struct drm_device *, unsigned int, 71bool nouveau_display_scanoutpos(struct drm_device *, unsigned int,
72 unsigned int, int *, int *, ktime_t *, 72 bool, int *, int *, ktime_t *,
73 ktime_t *, const struct drm_display_mode *); 73 ktime_t *, const struct drm_display_mode *);
74int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *,
75 struct timeval *, unsigned);
76 74
77int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 75int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
78 struct drm_pending_vblank_event *event, 76 struct drm_pending_vblank_event *event,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 2b6ac24ce690..1f751a3f570c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -881,7 +881,7 @@ done:
881} 881}
882 882
883static void 883static void
884nouveau_drm_preclose(struct drm_device *dev, struct drm_file *fpriv) 884nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
885{ 885{
886 struct nouveau_cli *cli = nouveau_cli(fpriv); 886 struct nouveau_cli *cli = nouveau_cli(fpriv);
887 struct nouveau_drm *drm = nouveau_drm(dev); 887 struct nouveau_drm *drm = nouveau_drm(dev);
@@ -897,12 +897,6 @@ nouveau_drm_preclose(struct drm_device *dev, struct drm_file *fpriv)
897 list_del(&cli->head); 897 list_del(&cli->head);
898 mutex_unlock(&drm->client.mutex); 898 mutex_unlock(&drm->client.mutex);
899 899
900}
901
902static void
903nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
904{
905 struct nouveau_cli *cli = nouveau_cli(fpriv);
906 nouveau_cli_fini(cli); 900 nouveau_cli_fini(cli);
907 kfree(cli); 901 kfree(cli);
908 pm_runtime_mark_last_busy(dev->dev); 902 pm_runtime_mark_last_busy(dev->dev);
@@ -974,7 +968,6 @@ driver_stub = {
974 .load = nouveau_drm_load, 968 .load = nouveau_drm_load,
975 .unload = nouveau_drm_unload, 969 .unload = nouveau_drm_unload,
976 .open = nouveau_drm_open, 970 .open = nouveau_drm_open,
977 .preclose = nouveau_drm_preclose,
978 .postclose = nouveau_drm_postclose, 971 .postclose = nouveau_drm_postclose,
979 .lastclose = nouveau_vga_lastclose, 972 .lastclose = nouveau_vga_lastclose,
980 973
@@ -985,7 +978,7 @@ driver_stub = {
985 .enable_vblank = nouveau_display_vblank_enable, 978 .enable_vblank = nouveau_display_vblank_enable,
986 .disable_vblank = nouveau_display_vblank_disable, 979 .disable_vblank = nouveau_display_vblank_disable,
987 .get_scanout_position = nouveau_display_scanoutpos, 980 .get_scanout_position = nouveau_display_scanoutpos,
988 .get_vblank_timestamp = nouveau_display_vblstamp, 981 .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
989 982
990 .ioctls = nouveau_ioctls, 983 .ioctls = nouveau_ioctls,
991 .num_ioctls = ARRAY_SIZE(nouveau_ioctls), 984 .num_ioctls = ARRAY_SIZE(nouveau_ioctls),
diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
new file mode 100644
index 000000000000..ede49efd531f
--- /dev/null
+++ b/drivers/gpu/drm/pl111/Kconfig
@@ -0,0 +1,12 @@
1config DRM_PL111
2 tristate "DRM Support for PL111 CLCD Controller"
3 depends on DRM
4 depends on ARM || ARM64 || COMPILE_TEST
5 select DRM_KMS_HELPER
6 select DRM_KMS_CMA_HELPER
7 select DRM_GEM_CMA_HELPER
8 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
9 help
10 Choose this option for DRM support for the PL111 CLCD controller.
11 If M is selected the module will be called pl111_drm.
12
diff --git a/drivers/gpu/drm/pl111/Makefile b/drivers/gpu/drm/pl111/Makefile
new file mode 100644
index 000000000000..01caee727c13
--- /dev/null
+++ b/drivers/gpu/drm/pl111/Makefile
@@ -0,0 +1,5 @@
1pl111_drm-y += pl111_connector.o \
2 pl111_display.o \
3 pl111_drv.o
4
5obj-$(CONFIG_DRM_PL111) += pl111_drm.o
diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c
new file mode 100644
index 000000000000..3f213d7e7692
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_connector.c
@@ -0,0 +1,127 @@
1/*
2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
3 *
4 * Parts of this file were based on sources as follows:
5 *
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 *
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
13 * such GNU licence.
14 *
15 */
16
17/**
18 * pl111_drm_connector.c
19 * Implementation of the connector functions for PL111 DRM
20 */
21#include <linux/amba/clcd-regs.h>
22#include <linux/version.h>
23#include <linux/shmem_fs.h>
24#include <linux/dma-buf.h>
25
26#include <drm/drmP.h>
27#include <drm/drm_atomic_helper.h>
28#include <drm/drm_crtc_helper.h>
29#include <drm/drm_of.h>
30#include <drm/drm_panel.h>
31
32#include "pl111_drm.h"
33
34static void pl111_connector_destroy(struct drm_connector *connector)
35{
36 struct pl111_drm_connector *pl111_connector =
37 to_pl111_connector(connector);
38
39 if (pl111_connector->panel)
40 drm_panel_detach(pl111_connector->panel);
41
42 drm_connector_unregister(connector);
43 drm_connector_cleanup(connector);
44}
45
46static enum drm_connector_status pl111_connector_detect(struct drm_connector
47 *connector, bool force)
48{
49 struct pl111_drm_connector *pl111_connector =
50 to_pl111_connector(connector);
51
52 return (pl111_connector->panel ?
53 connector_status_connected :
54 connector_status_disconnected);
55}
56
57static int pl111_connector_helper_get_modes(struct drm_connector *connector)
58{
59 struct pl111_drm_connector *pl111_connector =
60 to_pl111_connector(connector);
61
62 if (!pl111_connector->panel)
63 return 0;
64
65 return drm_panel_get_modes(pl111_connector->panel);
66}
67
68const struct drm_connector_funcs connector_funcs = {
69 .fill_modes = drm_helper_probe_single_connector_modes,
70 .destroy = pl111_connector_destroy,
71 .detect = pl111_connector_detect,
72 .dpms = drm_atomic_helper_connector_dpms,
73 .reset = drm_atomic_helper_connector_reset,
74 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
75 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
76};
77
78const struct drm_connector_helper_funcs connector_helper_funcs = {
79 .get_modes = pl111_connector_helper_get_modes,
80};
81
82/* Walks the OF graph to find the panel node and then asks DRM to look
83 * up the panel.
84 */
85static struct drm_panel *pl111_get_panel(struct device *dev)
86{
87 struct device_node *endpoint, *panel_node;
88 struct device_node *np = dev->of_node;
89 struct drm_panel *panel;
90
91 endpoint = of_graph_get_next_endpoint(np, NULL);
92 if (!endpoint) {
93 dev_err(dev, "no endpoint to fetch panel\n");
94 return NULL;
95 }
96
97 /* don't proceed if we have an endpoint but no panel_node tied to it */
98 panel_node = of_graph_get_remote_port_parent(endpoint);
99 of_node_put(endpoint);
100 if (!panel_node) {
101 dev_err(dev, "no valid panel node\n");
102 return NULL;
103 }
104
105 panel = of_drm_find_panel(panel_node);
106 of_node_put(panel_node);
107
108 return panel;
109}
110
111int pl111_connector_init(struct drm_device *dev)
112{
113 struct pl111_drm_dev_private *priv = dev->dev_private;
114 struct pl111_drm_connector *pl111_connector = &priv->connector;
115 struct drm_connector *connector = &pl111_connector->connector;
116
117 drm_connector_init(dev, connector, &connector_funcs,
118 DRM_MODE_CONNECTOR_DPI);
119 drm_connector_helper_add(connector, &connector_helper_funcs);
120
121 pl111_connector->panel = pl111_get_panel(dev->dev);
122 if (pl111_connector->panel)
123 drm_panel_attach(pl111_connector->panel, connector);
124
125 return 0;
126}
127
diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
new file mode 100644
index 000000000000..39a5c33bce7d
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -0,0 +1,344 @@
1/*
2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
3 *
4 * Parts of this file were based on sources as follows:
5 *
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 *
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
13 * such GNU licence.
14 *
15 */
16
17#include <linux/amba/clcd-regs.h>
18#include <linux/clk.h>
19#include <linux/version.h>
20#include <linux/dma-buf.h>
21#include <linux/of_graph.h>
22
23#include <drm/drmP.h>
24#include <drm/drm_panel.h>
25#include <drm/drm_gem_cma_helper.h>
26#include <drm/drm_fb_cma_helper.h>
27
28#include "pl111_drm.h"
29
30irqreturn_t pl111_irq(int irq, void *data)
31{
32 struct pl111_drm_dev_private *priv = data;
33 u32 irq_stat;
34 irqreturn_t status = IRQ_NONE;
35
36 irq_stat = readl(priv->regs + CLCD_PL111_MIS);
37
38 if (!irq_stat)
39 return IRQ_NONE;
40
41 if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE) {
42 drm_crtc_handle_vblank(&priv->pipe.crtc);
43
44 status = IRQ_HANDLED;
45 }
46
47 /* Clear the interrupt once done */
48 writel(irq_stat, priv->regs + CLCD_PL111_ICR);
49
50 return status;
51}
52
53static u32 pl111_get_fb_offset(struct drm_plane_state *pstate)
54{
55 struct drm_framebuffer *fb = pstate->fb;
56 struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, 0);
57
58 return (obj->paddr +
59 fb->offsets[0] +
60 fb->format->cpp[0] * pstate->src_x +
61 fb->pitches[0] * pstate->src_y);
62}
63
64static int pl111_display_check(struct drm_simple_display_pipe *pipe,
65 struct drm_plane_state *pstate,
66 struct drm_crtc_state *cstate)
67{
68 const struct drm_display_mode *mode = &cstate->mode;
69 struct drm_framebuffer *old_fb = pipe->plane.state->fb;
70 struct drm_framebuffer *fb = pstate->fb;
71
72 if (mode->hdisplay % 16)
73 return -EINVAL;
74
75 if (fb) {
76 u32 offset = pl111_get_fb_offset(pstate);
77
78 /* FB base address must be dword aligned. */
79 if (offset & 3)
80 return -EINVAL;
81
82 /* There's no pitch register -- the mode's hdisplay
83 * controls it.
84 */
85 if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0])
86 return -EINVAL;
87
88 /* We can't change the FB format in a flicker-free
89 * manner (and only update it during CRTC enable).
90 */
91 if (old_fb && old_fb->format != fb->format)
92 cstate->mode_changed = true;
93 }
94
95 return 0;
96}
97
98static void pl111_display_enable(struct drm_simple_display_pipe *pipe,
99 struct drm_crtc_state *cstate)
100{
101 struct drm_crtc *crtc = &pipe->crtc;
102 struct drm_plane *plane = &pipe->plane;
103 struct drm_device *drm = crtc->dev;
104 struct pl111_drm_dev_private *priv = drm->dev_private;
105 const struct drm_display_mode *mode = &cstate->mode;
106 struct drm_framebuffer *fb = plane->state->fb;
107 struct drm_connector *connector = &priv->connector.connector;
108 u32 cntl;
109 u32 ppl, hsw, hfp, hbp;
110 u32 lpp, vsw, vfp, vbp;
111 u32 cpl;
112 int ret;
113
114 ret = clk_set_rate(priv->clk, mode->clock * 1000);
115 if (ret) {
116 dev_err(drm->dev,
117 "Failed to set pixel clock rate to %d: %d\n",
118 mode->clock * 1000, ret);
119 }
120
121 clk_prepare_enable(priv->clk);
122
123 ppl = (mode->hdisplay / 16) - 1;
124 hsw = mode->hsync_end - mode->hsync_start - 1;
125 hfp = mode->hsync_start - mode->hdisplay - 1;
126 hbp = mode->htotal - mode->hsync_end - 1;
127
128 lpp = mode->vdisplay - 1;
129 vsw = mode->vsync_end - mode->vsync_start - 1;
130 vfp = mode->vsync_start - mode->vdisplay;
131 vbp = mode->vtotal - mode->vsync_end;
132
133 cpl = mode->hdisplay - 1;
134
135 writel((ppl << 2) |
136 (hsw << 8) |
137 (hfp << 16) |
138 (hbp << 24),
139 priv->regs + CLCD_TIM0);
140 writel(lpp |
141 (vsw << 10) |
142 (vfp << 16) |
143 (vbp << 24),
144 priv->regs + CLCD_TIM1);
145 /* XXX: We currently always use CLCDCLK with no divisor. We
146 * could probably reduce power consumption by using HCLK
147 * (apb_pclk) with a divisor when it gets us near our target
148 * pixel clock.
149 */
150 writel(((mode->flags & DRM_MODE_FLAG_NHSYNC) ? TIM2_IHS : 0) |
151 ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? TIM2_IVS : 0) |
152 ((connector->display_info.bus_flags &
153 DRM_BUS_FLAG_DE_LOW) ? TIM2_IOE : 0) |
154 ((connector->display_info.bus_flags &
155 DRM_BUS_FLAG_PIXDATA_NEGEDGE) ? TIM2_IPC : 0) |
156 TIM2_BCD |
157 (cpl << 16),
158 priv->regs + CLCD_TIM2);
159 writel(0, priv->regs + CLCD_TIM3);
160
161 drm_panel_prepare(priv->connector.panel);
162
163 /* Enable and Power Up */
164 cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDPWR | CNTL_LCDVCOMP(1);
165
166 /* Note that the the hardware's format reader takes 'r' from
167 * the low bit, while DRM formats list channels from high bit
168 * to low bit as you read left to right.
169 */
170 switch (fb->format->format) {
171 case DRM_FORMAT_ABGR8888:
172 case DRM_FORMAT_XBGR8888:
173 cntl |= CNTL_LCDBPP24;
174 break;
175 case DRM_FORMAT_ARGB8888:
176 case DRM_FORMAT_XRGB8888:
177 cntl |= CNTL_LCDBPP24 | CNTL_BGR;
178 break;
179 case DRM_FORMAT_BGR565:
180 cntl |= CNTL_LCDBPP16_565;
181 break;
182 case DRM_FORMAT_RGB565:
183 cntl |= CNTL_LCDBPP16_565 | CNTL_BGR;
184 break;
185 case DRM_FORMAT_ABGR1555:
186 case DRM_FORMAT_XBGR1555:
187 cntl |= CNTL_LCDBPP16;
188 break;
189 case DRM_FORMAT_ARGB1555:
190 case DRM_FORMAT_XRGB1555:
191 cntl |= CNTL_LCDBPP16 | CNTL_BGR;
192 break;
193 case DRM_FORMAT_ABGR4444:
194 case DRM_FORMAT_XBGR4444:
195 cntl |= CNTL_LCDBPP16_444;
196 break;
197 case DRM_FORMAT_ARGB4444:
198 case DRM_FORMAT_XRGB4444:
199 cntl |= CNTL_LCDBPP16_444 | CNTL_BGR;
200 break;
201 default:
202 WARN_ONCE(true, "Unknown FB format 0x%08x\n",
203 fb->format->format);
204 break;
205 }
206
207 writel(cntl, priv->regs + CLCD_PL111_CNTL);
208
209 drm_panel_enable(priv->connector.panel);
210
211 drm_crtc_vblank_on(crtc);
212}
213
214void pl111_display_disable(struct drm_simple_display_pipe *pipe)
215{
216 struct drm_crtc *crtc = &pipe->crtc;
217 struct drm_device *drm = crtc->dev;
218 struct pl111_drm_dev_private *priv = drm->dev_private;
219
220 drm_crtc_vblank_off(crtc);
221
222 drm_panel_disable(priv->connector.panel);
223
224 /* Disable and Power Down */
225 writel(0, priv->regs + CLCD_PL111_CNTL);
226
227 drm_panel_unprepare(priv->connector.panel);
228
229 clk_disable_unprepare(priv->clk);
230}
231
232static void pl111_display_update(struct drm_simple_display_pipe *pipe,
233 struct drm_plane_state *old_pstate)
234{
235 struct drm_crtc *crtc = &pipe->crtc;
236 struct drm_device *drm = crtc->dev;
237 struct pl111_drm_dev_private *priv = drm->dev_private;
238 struct drm_pending_vblank_event *event = crtc->state->event;
239 struct drm_plane *plane = &pipe->plane;
240 struct drm_plane_state *pstate = plane->state;
241 struct drm_framebuffer *fb = pstate->fb;
242
243 if (fb) {
244 u32 addr = pl111_get_fb_offset(pstate);
245
246 writel(addr, priv->regs + CLCD_UBAS);
247 }
248
249 if (event) {
250 crtc->state->event = NULL;
251
252 spin_lock_irq(&crtc->dev->event_lock);
253 if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
254 drm_crtc_arm_vblank_event(crtc, event);
255 else
256 drm_crtc_send_vblank_event(crtc, event);
257 spin_unlock_irq(&crtc->dev->event_lock);
258 }
259}
260
261int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc)
262{
263 struct pl111_drm_dev_private *priv = drm->dev_private;
264
265 writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + CLCD_PL111_IENB);
266
267 return 0;
268}
269
270void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc)
271{
272 struct pl111_drm_dev_private *priv = drm->dev_private;
273
274 writel(0, priv->regs + CLCD_PL111_IENB);
275}
276
277static int pl111_display_prepare_fb(struct drm_simple_display_pipe *pipe,
278 struct drm_plane_state *plane_state)
279{
280 return drm_fb_cma_prepare_fb(&pipe->plane, plane_state);
281}
282
283const struct drm_simple_display_pipe_funcs pl111_display_funcs = {
284 .check = pl111_display_check,
285 .enable = pl111_display_enable,
286 .disable = pl111_display_disable,
287 .update = pl111_display_update,
288 .prepare_fb = pl111_display_prepare_fb,
289};
290
291int pl111_display_init(struct drm_device *drm)
292{
293 struct pl111_drm_dev_private *priv = drm->dev_private;
294 struct device *dev = drm->dev;
295 struct device_node *endpoint;
296 u32 tft_r0b0g0[3];
297 int ret;
298 static const u32 formats[] = {
299 DRM_FORMAT_ABGR8888,
300 DRM_FORMAT_XBGR8888,
301 DRM_FORMAT_ARGB8888,
302 DRM_FORMAT_XRGB8888,
303 DRM_FORMAT_BGR565,
304 DRM_FORMAT_RGB565,
305 DRM_FORMAT_ABGR1555,
306 DRM_FORMAT_XBGR1555,
307 DRM_FORMAT_ARGB1555,
308 DRM_FORMAT_XRGB1555,
309 DRM_FORMAT_ABGR4444,
310 DRM_FORMAT_XBGR4444,
311 DRM_FORMAT_ARGB4444,
312 DRM_FORMAT_XRGB4444,
313 };
314
315 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
316 if (!endpoint)
317 return -ENODEV;
318
319 if (of_property_read_u32_array(endpoint,
320 "arm,pl11x,tft-r0g0b0-pads",
321 tft_r0b0g0,
322 ARRAY_SIZE(tft_r0b0g0)) != 0) {
323 dev_err(dev, "arm,pl11x,tft-r0g0b0-pads should be 3 ints\n");
324 of_node_put(endpoint);
325 return -ENOENT;
326 }
327 of_node_put(endpoint);
328
329 if (tft_r0b0g0[0] != 0 ||
330 tft_r0b0g0[1] != 8 ||
331 tft_r0b0g0[2] != 16) {
332 dev_err(dev, "arm,pl11x,tft-r0g0b0-pads != [0,8,16] not yet supported\n");
333 return -EINVAL;
334 }
335
336 ret = drm_simple_display_pipe_init(drm, &priv->pipe,
337 &pl111_display_funcs,
338 formats, ARRAY_SIZE(formats),
339 &priv->connector.connector);
340 if (ret)
341 return ret;
342
343 return 0;
344}
diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h
new file mode 100644
index 000000000000..f381593921b7
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -0,0 +1,56 @@
1/*
2 *
3 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
4 *
5 *
6 * Parts of this file were based on sources as follows:
7 *
8 * Copyright (c) 2006-2008 Intel Corporation
9 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
10 * Copyright (C) 2011 Texas Instruments
11 *
12 * This program is free software and is provided to you under the terms of the
13 * GNU General Public License version 2 as published by the Free Software
14 * Foundation, and any use by you of this program is subject to the terms of
15 * such GNU licence.
16 *
17 */
18
19#ifndef _PL111_DRM_H_
20#define _PL111_DRM_H_
21
22#include <drm/drm_gem.h>
23#include <drm/drm_simple_kms_helper.h>
24
25#define CLCD_IRQ_NEXTBASE_UPDATE BIT(2)
26
27struct pl111_drm_connector {
28 struct drm_connector connector;
29 struct drm_panel *panel;
30};
31
32struct pl111_drm_dev_private {
33 struct drm_device *drm;
34
35 struct pl111_drm_connector connector;
36 struct drm_simple_display_pipe pipe;
37 struct drm_fbdev_cma *fbdev;
38
39 void *regs;
40 struct clk *clk;
41};
42
43#define to_pl111_connector(x) \
44 container_of(x, struct pl111_drm_connector, connector)
45
46int pl111_display_init(struct drm_device *dev);
47int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc);
48void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc);
49irqreturn_t pl111_irq(int irq, void *data);
50int pl111_connector_init(struct drm_device *dev);
51int pl111_encoder_init(struct drm_device *dev);
52int pl111_dumb_create(struct drm_file *file_priv,
53 struct drm_device *dev,
54 struct drm_mode_create_dumb *args);
55
56#endif /* _PL111_DRM_H_ */
diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c
new file mode 100644
index 000000000000..936403f65508
--- /dev/null
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -0,0 +1,272 @@
1/*
2 * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved.
3 *
4 * Parts of this file were based on sources as follows:
5 *
6 * Copyright (c) 2006-2008 Intel Corporation
7 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
8 * Copyright (C) 2011 Texas Instruments
9 *
10 * This program is free software and is provided to you under the terms of the
11 * GNU General Public License version 2 as published by the Free Software
12 * Foundation, and any use by you of this program is subject to the terms of
13 * such GNU licence.
14 *
15 */
16
17/**
18 * DOC: ARM PrimeCell PL111 CLCD Driver
19 *
20 * The PL111 is a simple LCD controller that can support TFT and STN
21 * displays. This driver exposes a standard KMS interface for them.
22 *
23 * This driver uses the same Device Tree binding as the fbdev CLCD
24 * driver. While the fbdev driver supports panels that may be
25 * connected to the CLCD internally to the CLCD driver, in DRM the
26 * panels get split out to drivers/gpu/drm/panels/. This means that,
27 * in converting from using fbdev to using DRM, you also need to write
28 * a panel driver (which may be as simple as an entry in
29 * panel-simple.c).
30 *
31 * The driver currently doesn't expose the cursor. The DRM API for
32 * cursors requires support for 64x64 ARGB8888 cursor images, while
33 * the hardware can only support 64x64 monochrome with masking
34 * cursors. While one could imagine trying to hack something together
35 * to look at the ARGB8888 and program reasonable in monochrome, we
36 * just don't expose the cursor at all instead, and leave cursor
37 * support to the X11 software cursor layer.
38 *
39 * TODO:
40 *
41 * - Fix race between setting plane base address and getting IRQ for
42 * vsync firing the pageflip completion.
43 *
44 * - Expose the correct set of formats we can support based on the
45 * "arm,pl11x,tft-r0g0b0-pads" DT property.
46 *
47 * - Use the "max-memory-bandwidth" DT property to filter the
48 * supported formats.
49 *
50 * - Read back hardware state at boot to skip reprogramming the
51 * hardware when doing a no-op modeset.
52 *
53 * - Use the internal clock divisor to reduce power consumption by
54 * using HCLK (apb_pclk) when appropriate.
55 */
56
57#include <linux/amba/bus.h>
58#include <linux/amba/clcd-regs.h>
59#include <linux/version.h>
60#include <linux/shmem_fs.h>
61#include <linux/dma-buf.h>
62#include <linux/module.h>
63#include <linux/slab.h>
64
65#include <drm/drmP.h>
66#include <drm/drm_atomic_helper.h>
67#include <drm/drm_crtc_helper.h>
68#include <drm/drm_gem_cma_helper.h>
69#include <drm/drm_fb_cma_helper.h>
70
71#include "pl111_drm.h"
72
73#define DRIVER_DESC "DRM module for PL111"
74
75struct drm_mode_config_funcs mode_config_funcs = {
76 .fb_create = drm_fb_cma_create,
77 .atomic_check = drm_atomic_helper_check,
78 .atomic_commit = drm_atomic_helper_commit,
79};
80
81static int pl111_modeset_init(struct drm_device *dev)
82{
83 struct drm_mode_config *mode_config;
84 struct pl111_drm_dev_private *priv = dev->dev_private;
85 int ret = 0;
86
87 drm_mode_config_init(dev);
88 mode_config = &dev->mode_config;
89 mode_config->funcs = &mode_config_funcs;
90 mode_config->min_width = 1;
91 mode_config->max_width = 1024;
92 mode_config->min_height = 1;
93 mode_config->max_height = 768;
94
95 ret = pl111_connector_init(dev);
96 if (ret) {
97 dev_err(dev->dev, "Failed to create pl111_drm_connector\n");
98 goto out_config;
99 }
100
101 /* Don't actually attach if we didn't find a drm_panel
102 * attached to us. This will allow a kernel to include both
103 * the fbdev pl111 driver and this one, and choose between
104 * them based on which subsystem has support for the panel.
105 */
106 if (!priv->connector.panel) {
107 dev_info(dev->dev,
108 "Disabling due to lack of DRM panel device.\n");
109 ret = -ENODEV;
110 goto out_config;
111 }
112
113 ret = pl111_display_init(dev);
114 if (ret != 0) {
115 dev_err(dev->dev, "Failed to init display\n");
116 goto out_config;
117 }
118
119 ret = drm_vblank_init(dev, 1);
120 if (ret != 0) {
121 dev_err(dev->dev, "Failed to init vblank\n");
122 goto out_config;
123 }
124
125 drm_mode_config_reset(dev);
126
127 priv->fbdev = drm_fbdev_cma_init(dev, 32,
128 dev->mode_config.num_connector);
129
130 drm_kms_helper_poll_init(dev);
131
132 goto finish;
133
134out_config:
135 drm_mode_config_cleanup(dev);
136finish:
137 return ret;
138}
139
140DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
141
142static void pl111_lastclose(struct drm_device *dev)
143{
144 struct pl111_drm_dev_private *priv = dev->dev_private;
145
146 drm_fbdev_cma_restore_mode(priv->fbdev);
147}
148
149static struct drm_driver pl111_drm_driver = {
150 .driver_features =
151 DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC,
152 .lastclose = pl111_lastclose,
153 .ioctls = NULL,
154 .fops = &drm_fops,
155 .name = "pl111",
156 .desc = DRIVER_DESC,
157 .date = "20170317",
158 .major = 1,
159 .minor = 0,
160 .patchlevel = 0,
161 .dumb_create = drm_gem_cma_dumb_create,
162 .dumb_destroy = drm_gem_dumb_destroy,
163 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
164 .gem_free_object = drm_gem_cma_free_object,
165 .gem_vm_ops = &drm_gem_cma_vm_ops,
166
167 .enable_vblank = pl111_enable_vblank,
168 .disable_vblank = pl111_disable_vblank,
169
170 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
171 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
172 .gem_prime_import = drm_gem_prime_import,
173 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
174 .gem_prime_export = drm_gem_prime_export,
175 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
176};
177
178#ifdef CONFIG_ARM_AMBA
179static int pl111_amba_probe(struct amba_device *amba_dev,
180 const struct amba_id *id)
181{
182 struct device *dev = &amba_dev->dev;
183 struct pl111_drm_dev_private *priv;
184 struct drm_device *drm;
185 int ret;
186
187 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
188 if (!priv)
189 return -ENOMEM;
190
191 drm = drm_dev_alloc(&pl111_drm_driver, dev);
192 if (IS_ERR(drm))
193 return PTR_ERR(drm);
194 amba_set_drvdata(amba_dev, drm);
195 priv->drm = drm;
196 drm->dev_private = priv;
197
198 priv->clk = devm_clk_get(dev, "clcdclk");
199 if (IS_ERR(priv->clk)) {
200 dev_err(dev, "CLCD: unable to get clk.\n");
201 ret = PTR_ERR(priv->clk);
202 goto dev_unref;
203 }
204
205 priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
206 if (!priv->regs) {
207 dev_err(dev, "%s failed mmio\n", __func__);
208 return -EINVAL;
209 }
210
211 /* turn off interrupts before requesting the irq */
212 writel(0, priv->regs + CLCD_PL111_IENB);
213
214 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
215 "pl111", priv);
216 if (ret != 0) {
217 dev_err(dev, "%s failed irq %d\n", __func__, ret);
218 return ret;
219 }
220
221 ret = pl111_modeset_init(drm);
222 if (ret != 0)
223 goto dev_unref;
224
225 ret = drm_dev_register(drm, 0);
226 if (ret < 0)
227 goto dev_unref;
228
229 return 0;
230
231dev_unref:
232 drm_dev_unref(drm);
233 return ret;
234}
235
236static int pl111_amba_remove(struct amba_device *amba_dev)
237{
238 struct drm_device *drm = amba_get_drvdata(amba_dev);
239 struct pl111_drm_dev_private *priv = drm->dev_private;
240
241 drm_dev_unregister(drm);
242 if (priv->fbdev)
243 drm_fbdev_cma_fini(priv->fbdev);
244 drm_mode_config_cleanup(drm);
245 drm_dev_unref(drm);
246
247 return 0;
248}
249
250static struct amba_id pl111_id_table[] = {
251 {
252 .id = 0x00041111,
253 .mask = 0x000fffff,
254 },
255 {0, 0},
256};
257
258static struct amba_driver pl111_amba_driver = {
259 .drv = {
260 .name = "drm-clcd-pl111",
261 },
262 .probe = pl111_amba_probe,
263 .remove = pl111_amba_remove,
264 .id_table = pl111_id_table,
265};
266
267module_amba_driver(pl111_amba_driver);
268#endif /* CONFIG_ARM_AMBA */
269
270MODULE_DESCRIPTION(DRIVER_DESC);
271MODULE_AUTHOR("ARM Ltd.");
272MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 93d45aa5c3d4..ef8a75940980 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -115,10 +115,6 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon);
115u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe); 115u32 radeon_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe);
116int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe); 116int radeon_enable_vblank_kms(struct drm_device *dev, unsigned int pipe);
117void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe); 117void radeon_disable_vblank_kms(struct drm_device *dev, unsigned int pipe);
118int radeon_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe,
119 int *max_error,
120 struct timeval *vblank_time,
121 unsigned flags);
122void radeon_driver_irq_preinstall_kms(struct drm_device *dev); 118void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
123int radeon_driver_irq_postinstall_kms(struct drm_device *dev); 119int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
124void radeon_driver_irq_uninstall_kms(struct drm_device *dev); 120void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
@@ -530,6 +526,16 @@ static const struct file_operations radeon_driver_kms_fops = {
530#endif 526#endif
531}; 527};
532 528
529static bool
530radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe,
531 bool in_vblank_irq, int *vpos, int *hpos,
532 ktime_t *stime, ktime_t *etime,
533 const struct drm_display_mode *mode)
534{
535 return radeon_get_crtc_scanoutpos(dev, pipe, 0, vpos, hpos,
536 stime, etime, mode);
537}
538
533static struct drm_driver kms_driver = { 539static struct drm_driver kms_driver = {
534 .driver_features = 540 .driver_features =
535 DRIVER_USE_AGP | 541 DRIVER_USE_AGP |
@@ -544,8 +550,8 @@ static struct drm_driver kms_driver = {
544 .get_vblank_counter = radeon_get_vblank_counter_kms, 550 .get_vblank_counter = radeon_get_vblank_counter_kms,
545 .enable_vblank = radeon_enable_vblank_kms, 551 .enable_vblank = radeon_enable_vblank_kms,
546 .disable_vblank = radeon_disable_vblank_kms, 552 .disable_vblank = radeon_disable_vblank_kms,
547 .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, 553 .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
548 .get_scanout_position = radeon_get_crtc_scanoutpos, 554 .get_scanout_position = radeon_get_crtc_scanout_position,
549 .irq_preinstall = radeon_driver_irq_preinstall_kms, 555 .irq_preinstall = radeon_driver_irq_preinstall_kms,
550 .irq_postinstall = radeon_driver_irq_postinstall_kms, 556 .irq_postinstall = radeon_driver_irq_postinstall_kms,
551 .irq_uninstall = radeon_driver_irq_uninstall_kms, 557 .irq_uninstall = radeon_driver_irq_uninstall_kms,
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index e3e7cb1d10a2..6a68d440bc44 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -858,43 +858,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
858 spin_unlock_irqrestore(&rdev->irq.lock, irqflags); 858 spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
859} 859}
860 860
861/**
862 * radeon_get_vblank_timestamp_kms - get vblank timestamp
863 *
864 * @dev: drm dev pointer
865 * @crtc: crtc to get the timestamp for
866 * @max_error: max error
867 * @vblank_time: time value
868 * @flags: flags passed to the driver
869 *
870 * Gets the timestamp on the requested crtc based on the
871 * scanout position. (all asics).
872 * Returns postive status flags on success, negative error on failure.
873 */
874int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
875 int *max_error,
876 struct timeval *vblank_time,
877 unsigned flags)
878{
879 struct drm_crtc *drmcrtc;
880 struct radeon_device *rdev = dev->dev_private;
881
882 if (crtc < 0 || crtc >= dev->num_crtcs) {
883 DRM_ERROR("Invalid crtc %d\n", crtc);
884 return -EINVAL;
885 }
886
887 /* Get associated drm_crtc: */
888 drmcrtc = &rdev->mode_info.crtcs[crtc]->base;
889 if (!drmcrtc)
890 return -EINVAL;
891
892 /* Helper routine in DRM core does all the work: */
893 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
894 vblank_time, flags,
895 &drmcrtc->hwmode);
896}
897
898const struct drm_ioctl_desc radeon_ioctls_kms[] = { 861const struct drm_ioctl_desc radeon_ioctls_kms[] = {
899 DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 862 DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
900 DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 863 DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index ad282648fc8b..00f5ec5c12c7 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -691,6 +691,9 @@ struct atom_voltage_table
691}; 691};
692 692
693/* Driver internal use only flags of radeon_get_crtc_scanoutpos() */ 693/* Driver internal use only flags of radeon_get_crtc_scanoutpos() */
694#define DRM_SCANOUTPOS_VALID (1 << 0)
695#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1)
696#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
694#define USE_REAL_VBLANKSTART (1 << 30) 697#define USE_REAL_VBLANKSTART (1 << 30)
695#define GET_DISTANCE_TO_VBLANKSTART (1 << 31) 698#define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
696 699
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d8fa7a9c9240..1bccd827d2e4 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -104,26 +104,18 @@ static void analogix_dp_psr_work(struct work_struct *work)
104{ 104{
105 struct rockchip_dp_device *dp = 105 struct rockchip_dp_device *dp =
106 container_of(work, typeof(*dp), psr_work); 106 container_of(work, typeof(*dp), psr_work);
107 struct drm_crtc *crtc = dp->encoder.crtc;
108 int psr_state = dp->psr_state;
109 int vact_end;
110 int ret; 107 int ret;
111 unsigned long flags; 108 unsigned long flags;
112 109
113 if (!crtc) 110 ret = rockchip_drm_wait_vact_end(dp->encoder.crtc,
114 return; 111 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
115
116 vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay;
117
118 ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
119 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
120 if (ret) { 112 if (ret) {
121 dev_err(dp->dev, "line flag interrupt did not arrive\n"); 113 dev_err(dp->dev, "line flag interrupt did not arrive\n");
122 return; 114 return;
123 } 115 }
124 116
125 spin_lock_irqsave(&dp->psr_lock, flags); 117 spin_lock_irqsave(&dp->psr_lock, flags);
126 if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) 118 if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
127 analogix_dp_enable_psr(dp->dev); 119 analogix_dp_enable_psr(dp->dev);
128 else 120 else
129 analogix_dp_disable_psr(dp->dev); 121 analogix_dp_disable_psr(dp->dev);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index a48fcce3f5f6..47905faf5586 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -62,8 +62,7 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
62 struct device *dev); 62 struct device *dev);
63void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, 63void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
64 struct device *dev); 64 struct device *dev);
65int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, 65int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout);
66 unsigned int mstimeout);
67 66
68extern struct platform_driver cdn_dp_driver; 67extern struct platform_driver cdn_dp_driver;
69extern struct platform_driver dw_hdmi_rockchip_pltfm_driver; 68extern struct platform_driver dw_hdmi_rockchip_pltfm_driver;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3f7a82d1e095..40a5e6ef6f2c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -468,7 +468,7 @@ static bool vop_line_flag_irq_is_enabled(struct vop *vop)
468 return !!line_flag_irq; 468 return !!line_flag_irq;
469} 469}
470 470
471static void vop_line_flag_irq_enable(struct vop *vop, int line_num) 471static void vop_line_flag_irq_enable(struct vop *vop)
472{ 472{
473 unsigned long flags; 473 unsigned long flags;
474 474
@@ -477,7 +477,6 @@ static void vop_line_flag_irq_enable(struct vop *vop, int line_num)
477 477
478 spin_lock_irqsave(&vop->irq_lock, flags); 478 spin_lock_irqsave(&vop->irq_lock, flags);
479 479
480 VOP_CTRL_SET(vop, line_flag_num[0], line_num);
481 VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1); 480 VOP_INTR_SET_TYPE(vop, clear, LINE_FLAG_INTR, 1);
482 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1); 481 VOP_INTR_SET_TYPE(vop, enable, LINE_FLAG_INTR, 1);
483 482
@@ -981,6 +980,8 @@ static void vop_crtc_enable(struct drm_crtc *crtc)
981 VOP_CTRL_SET(vop, vact_st_end, val); 980 VOP_CTRL_SET(vop, vact_st_end, val);
982 VOP_CTRL_SET(vop, vpost_st_end, val); 981 VOP_CTRL_SET(vop, vpost_st_end, val);
983 982
983 VOP_CTRL_SET(vop, line_flag_num[0], vact_end);
984
984 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000); 985 clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
985 986
986 VOP_CTRL_SET(vop, standby, 0); 987 VOP_CTRL_SET(vop, standby, 0);
@@ -1507,19 +1508,16 @@ static void vop_win_init(struct vop *vop)
1507} 1508}
1508 1509
1509/** 1510/**
1510 * rockchip_drm_wait_line_flag - acqiure the give line flag event 1511 * rockchip_drm_wait_vact_end
1511 * @crtc: CRTC to enable line flag 1512 * @crtc: CRTC to enable line flag
1512 * @line_num: interested line number
1513 * @mstimeout: millisecond for timeout 1513 * @mstimeout: millisecond for timeout
1514 * 1514 *
1515 * Driver would hold here until the interested line flag interrupt have 1515 * Wait for vact_end line flag irq or timeout.
1516 * happened or timeout to wait.
1517 * 1516 *
1518 * Returns: 1517 * Returns:
1519 * Zero on success, negative errno on failure. 1518 * Zero on success, negative errno on failure.
1520 */ 1519 */
1521int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, 1520int rockchip_drm_wait_vact_end(struct drm_crtc *crtc, unsigned int mstimeout)
1522 unsigned int mstimeout)
1523{ 1521{
1524 struct vop *vop = to_vop(crtc); 1522 struct vop *vop = to_vop(crtc);
1525 unsigned long jiffies_left; 1523 unsigned long jiffies_left;
@@ -1527,14 +1525,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
1527 if (!crtc || !vop->is_enabled) 1525 if (!crtc || !vop->is_enabled)
1528 return -ENODEV; 1526 return -ENODEV;
1529 1527
1530 if (line_num > crtc->mode.vtotal || mstimeout <= 0) 1528 if (mstimeout <= 0)
1531 return -EINVAL; 1529 return -EINVAL;
1532 1530
1533 if (vop_line_flag_irq_is_enabled(vop)) 1531 if (vop_line_flag_irq_is_enabled(vop))
1534 return -EBUSY; 1532 return -EBUSY;
1535 1533
1536 reinit_completion(&vop->line_flag_completion); 1534 reinit_completion(&vop->line_flag_completion);
1537 vop_line_flag_irq_enable(vop, line_num); 1535 vop_line_flag_irq_enable(vop);
1538 1536
1539 jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion, 1537 jiffies_left = wait_for_completion_timeout(&vop->line_flag_completion,
1540 msecs_to_jiffies(mstimeout)); 1538 msecs_to_jiffies(mstimeout));
@@ -1547,7 +1545,7 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
1547 1545
1548 return 0; 1546 return 0;
1549} 1547}
1550EXPORT_SYMBOL(rockchip_drm_wait_line_flag); 1548EXPORT_SYMBOL(rockchip_drm_wait_vact_end);
1551 1549
1552static int vop_bind(struct device *dev, struct device *master, void *data) 1550static int vop_bind(struct device *dev, struct device *master, void *data)
1553{ 1551{
diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c
index fa356f5dae27..dfdd858eda0a 100644
--- a/drivers/gpu/drm/selftests/test-drm_mm.c
+++ b/drivers/gpu/drm/selftests/test-drm_mm.c
@@ -514,6 +514,8 @@ static int igt_reserve(void *ignored)
514 ret = __igt_reserve(count, size + 1); 514 ret = __igt_reserve(count, size + 1);
515 if (ret) 515 if (ret)
516 return ret; 516 return ret;
517
518 cond_resched();
517 } 519 }
518 520
519 return 0; 521 return 0;
@@ -712,6 +714,10 @@ static int igt_insert(void *ignored)
712 return ret; 714 return ret;
713 715
714 ret = __igt_insert(count, size + 1, false); 716 ret = __igt_insert(count, size + 1, false);
717 if (ret)
718 return ret;
719
720 cond_resched();
715 } 721 }
716 722
717 return 0; 723 return 0;
@@ -741,6 +747,10 @@ static int igt_replace(void *ignored)
741 return ret; 747 return ret;
742 748
743 ret = __igt_insert(count, size + 1, true); 749 ret = __igt_insert(count, size + 1, true);
750 if (ret)
751 return ret;
752
753 cond_resched();
744 } 754 }
745 755
746 return 0; 756 return 0;
@@ -1011,6 +1021,8 @@ static int igt_insert_range(void *ignored)
1011 ret = __igt_insert_range(count, size, max/4+1, 3*max/4-1); 1021 ret = __igt_insert_range(count, size, max/4+1, 3*max/4-1);
1012 if (ret) 1022 if (ret)
1013 return ret; 1023 return ret;
1024
1025 cond_resched();
1014 } 1026 }
1015 1027
1016 return 0; 1028 return 0;
@@ -1056,6 +1068,7 @@ static int igt_align(void *ignored)
1056 drm_mm_for_each_node_safe(node, next, &mm) 1068 drm_mm_for_each_node_safe(node, next, &mm)
1057 drm_mm_remove_node(node); 1069 drm_mm_remove_node(node);
1058 DRM_MM_BUG_ON(!drm_mm_clean(&mm)); 1070 DRM_MM_BUG_ON(!drm_mm_clean(&mm));
1071 cond_resched();
1059 } 1072 }
1060 1073
1061 ret = 0; 1074 ret = 0;
@@ -1097,6 +1110,8 @@ static int igt_align_pot(int max)
1097 align, bit); 1110 align, bit);
1098 goto out; 1111 goto out;
1099 } 1112 }
1113
1114 cond_resched();
1100 } 1115 }
1101 1116
1102 ret = 0; 1117 ret = 0;
@@ -1471,6 +1486,8 @@ static int igt_evict(void *ignored)
1471 goto out; 1486 goto out;
1472 } 1487 }
1473 } 1488 }
1489
1490 cond_resched();
1474 } 1491 }
1475 1492
1476 ret = 0; 1493 ret = 0;
@@ -1566,6 +1583,8 @@ static int igt_evict_range(void *ignored)
1566 goto out; 1583 goto out;
1567 } 1584 }
1568 } 1585 }
1586
1587 cond_resched();
1569 } 1588 }
1570 1589
1571 ret = 0; 1590 ret = 0;
@@ -1683,6 +1702,7 @@ static int igt_topdown(void *ignored)
1683 drm_mm_for_each_node_safe(node, next, &mm) 1702 drm_mm_for_each_node_safe(node, next, &mm)
1684 drm_mm_remove_node(node); 1703 drm_mm_remove_node(node);
1685 DRM_MM_BUG_ON(!drm_mm_clean(&mm)); 1704 DRM_MM_BUG_ON(!drm_mm_clean(&mm));
1705 cond_resched();
1686 } 1706 }
1687 1707
1688 ret = 0; 1708 ret = 0;
@@ -1783,6 +1803,7 @@ static int igt_bottomup(void *ignored)
1783 drm_mm_for_each_node_safe(node, next, &mm) 1803 drm_mm_for_each_node_safe(node, next, &mm)
1784 drm_mm_remove_node(node); 1804 drm_mm_remove_node(node);
1785 DRM_MM_BUG_ON(!drm_mm_clean(&mm)); 1805 DRM_MM_BUG_ON(!drm_mm_clean(&mm));
1806 cond_resched();
1786 } 1807 }
1787 1808
1788 ret = 0; 1809 ret = 0;
@@ -1970,6 +1991,8 @@ static int igt_color(void *ignored)
1970 drm_mm_remove_node(node); 1991 drm_mm_remove_node(node);
1971 kfree(node); 1992 kfree(node);
1972 } 1993 }
1994
1995 cond_resched();
1973 } 1996 }
1974 1997
1975 ret = 0; 1998 ret = 0;
@@ -2047,6 +2070,7 @@ static int evict_color(struct drm_mm *mm,
2047 } 2070 }
2048 } 2071 }
2049 2072
2073 cond_resched();
2050 return 0; 2074 return 0;
2051} 2075}
2052 2076
@@ -2132,6 +2156,8 @@ static int igt_color_evict(void *ignored)
2132 goto out; 2156 goto out;
2133 } 2157 }
2134 } 2158 }
2159
2160 cond_resched();
2135 } 2161 }
2136 2162
2137 ret = 0; 2163 ret = 0;
@@ -2231,6 +2257,8 @@ static int igt_color_evict_range(void *ignored)
2231 goto out; 2257 goto out;
2232 } 2258 }
2233 } 2259 }
2260
2261 cond_resched();
2234 } 2262 }
2235 2263
2236 ret = 0; 2264 ret = 0;
diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c
index cca75bddb9ad..5b3a41f74f21 100644
--- a/drivers/gpu/drm/sti/sti_cursor.c
+++ b/drivers/gpu/drm/sti/sti_cursor.c
@@ -33,7 +33,7 @@
33#define STI_CURS_MAX_SIZE 128 33#define STI_CURS_MAX_SIZE 128
34 34
35/* 35/*
36 * pixmap dma buffer stucture 36 * pixmap dma buffer structure
37 * 37 *
38 * @paddr: physical address 38 * @paddr: physical address
39 * @size: buffer size 39 * @size: buffer size
@@ -121,8 +121,7 @@ static int cursor_dbg_show(struct seq_file *s, void *data)
121 cursor_dbg_cml(s, cursor, readl(cursor->regs + CUR_CML)); 121 cursor_dbg_cml(s, cursor, readl(cursor->regs + CUR_CML));
122 DBGFS_DUMP(CUR_AWS); 122 DBGFS_DUMP(CUR_AWS);
123 DBGFS_DUMP(CUR_AWE); 123 DBGFS_DUMP(CUR_AWE);
124 seq_puts(s, "\n"); 124 seq_putc(s, '\n');
125
126 return 0; 125 return 0;
127} 126}
128 127
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index bb23318a44b7..24ebc6b2f34d 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -186,8 +186,7 @@ static int dvo_dbg_show(struct seq_file *s, void *data)
186 DBGFS_DUMP(DVO_LUT_PROG_MID); 186 DBGFS_DUMP(DVO_LUT_PROG_MID);
187 DBGFS_DUMP(DVO_LUT_PROG_HIGH); 187 DBGFS_DUMP(DVO_LUT_PROG_HIGH);
188 dvo_dbg_awg_microcode(s, dvo->regs + DVO_DIGSYNC_INSTR_I); 188 dvo_dbg_awg_microcode(s, dvo->regs + DVO_DIGSYNC_INSTR_I);
189 seq_puts(s, "\n"); 189 seq_putc(s, '\n');
190
191 return 0; 190 return 0;
192} 191}
193 192
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c
index 88f16cdf6a4b..5ee0503945c8 100644
--- a/drivers/gpu/drm/sti/sti_gdp.c
+++ b/drivers/gpu/drm/sti/sti_gdp.c
@@ -149,7 +149,7 @@ static void gdp_dbg_ctl(struct seq_file *s, int val)
149 seq_puts(s, "\tColor:"); 149 seq_puts(s, "\tColor:");
150 for (i = 0; i < ARRAY_SIZE(gdp_format_to_str); i++) { 150 for (i = 0; i < ARRAY_SIZE(gdp_format_to_str); i++) {
151 if (gdp_format_to_str[i].format == (val & 0x1F)) { 151 if (gdp_format_to_str[i].format == (val & 0x1F)) {
152 seq_printf(s, gdp_format_to_str[i].name); 152 seq_puts(s, gdp_format_to_str[i].name);
153 break; 153 break;
154 } 154 }
155 } 155 }
@@ -266,8 +266,7 @@ static void gdp_node_dump_node(struct seq_file *s, struct sti_gdp_node *node)
266 seq_printf(s, "\n\tKEY2 0x%08X", node->gam_gdp_key2); 266 seq_printf(s, "\n\tKEY2 0x%08X", node->gam_gdp_key2);
267 seq_printf(s, "\n\tPPT 0x%08X", node->gam_gdp_ppt); 267 seq_printf(s, "\n\tPPT 0x%08X", node->gam_gdp_ppt);
268 gdp_dbg_ppt(s, node->gam_gdp_ppt); 268 gdp_dbg_ppt(s, node->gam_gdp_ppt);
269 seq_printf(s, "\n\tCML 0x%08X", node->gam_gdp_cml); 269 seq_printf(s, "\n\tCML 0x%08X\n", node->gam_gdp_cml);
270 seq_puts(s, "\n");
271} 270}
272 271
273static int gdp_node_dbg_show(struct seq_file *s, void *arg) 272static int gdp_node_dbg_show(struct seq_file *s, void *arg)
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index 0c0a75bc8bc3..d6ed909d9d75 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -320,8 +320,7 @@ static void hda_dbg_awg_microcode(struct seq_file *s, void __iomem *reg)
320{ 320{
321 unsigned int i; 321 unsigned int i;
322 322
323 seq_puts(s, "\n\n"); 323 seq_puts(s, "\n\n HDA AWG microcode:");
324 seq_puts(s, " HDA AWG microcode:");
325 for (i = 0; i < AWG_MAX_INST; i++) { 324 for (i = 0; i < AWG_MAX_INST; i++) {
326 if (i % 8 == 0) 325 if (i % 8 == 0)
327 seq_printf(s, "\n %04X:", i); 326 seq_printf(s, "\n %04X:", i);
@@ -333,8 +332,7 @@ static void hda_dbg_video_dacs_ctrl(struct seq_file *s, void __iomem *reg)
333{ 332{
334 u32 val = readl(reg); 333 u32 val = readl(reg);
335 334
336 seq_puts(s, "\n"); 335 seq_printf(s, "\n\n %-25s 0x%08X", "VIDEO_DACS_CONTROL", val);
337 seq_printf(s, "\n %-25s 0x%08X", "VIDEO_DACS_CONTROL", val);
338 seq_puts(s, "\tHD DACs "); 336 seq_puts(s, "\tHD DACs ");
339 seq_puts(s, val & DAC_CFG_HD_HZUVW_OFF_MASK ? "disabled" : "enabled"); 337 seq_puts(s, val & DAC_CFG_HD_HZUVW_OFF_MASK ? "disabled" : "enabled");
340} 338}
@@ -356,8 +354,7 @@ static int hda_dbg_show(struct seq_file *s, void *data)
356 hda_dbg_awg_microcode(s, hda->regs + HDA_SYNC_AWGI); 354 hda_dbg_awg_microcode(s, hda->regs + HDA_SYNC_AWGI);
357 if (hda->video_dacs_ctrl) 355 if (hda->video_dacs_ctrl)
358 hda_dbg_video_dacs_ctrl(s, hda->video_dacs_ctrl); 356 hda_dbg_video_dacs_ctrl(s, hda->video_dacs_ctrl);
359 seq_puts(s, "\n"); 357 seq_putc(s, '\n');
360
361 return 0; 358 return 0;
362} 359}
363 360
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 243905b6ae59..a59c95a8081b 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -592,7 +592,7 @@ static void hdmi_dbg_cfg(struct seq_file *s, int val)
592{ 592{
593 int tmp; 593 int tmp;
594 594
595 seq_puts(s, "\t"); 595 seq_putc(s, '\t');
596 tmp = val & HDMI_CFG_HDMI_NOT_DVI; 596 tmp = val & HDMI_CFG_HDMI_NOT_DVI;
597 DBGFS_PRINT_STR("mode:", tmp ? "HDMI" : "DVI"); 597 DBGFS_PRINT_STR("mode:", tmp ? "HDMI" : "DVI");
598 seq_puts(s, "\t\t\t\t\t"); 598 seq_puts(s, "\t\t\t\t\t");
@@ -616,7 +616,7 @@ static void hdmi_dbg_sta(struct seq_file *s, int val)
616{ 616{
617 int tmp; 617 int tmp;
618 618
619 seq_puts(s, "\t"); 619 seq_putc(s, '\t');
620 tmp = (val & HDMI_STA_DLL_LCK); 620 tmp = (val & HDMI_STA_DLL_LCK);
621 DBGFS_PRINT_STR("pll:", tmp ? "locked" : "not locked"); 621 DBGFS_PRINT_STR("pll:", tmp ? "locked" : "not locked");
622 seq_puts(s, "\t\t\t\t\t"); 622 seq_puts(s, "\t\t\t\t\t");
@@ -632,7 +632,7 @@ static void hdmi_dbg_sw_di_cfg(struct seq_file *s, int val)
632 "once every field", 632 "once every field",
633 "once every frame"}; 633 "once every frame"};
634 634
635 seq_puts(s, "\t"); 635 seq_putc(s, '\t');
636 tmp = (val & HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, 1)); 636 tmp = (val & HDMI_IFRAME_CFG_DI_N(HDMI_IFRAME_MASK, 1));
637 DBGFS_PRINT_STR("Data island 1:", en_di[tmp]); 637 DBGFS_PRINT_STR("Data island 1:", en_di[tmp]);
638 seq_puts(s, "\t\t\t\t\t"); 638 seq_puts(s, "\t\t\t\t\t");
@@ -664,16 +664,16 @@ static int hdmi_dbg_show(struct seq_file *s, void *data)
664 DBGFS_DUMP("\n", HDMI_STA); 664 DBGFS_DUMP("\n", HDMI_STA);
665 hdmi_dbg_sta(s, hdmi_read(hdmi, HDMI_STA)); 665 hdmi_dbg_sta(s, hdmi_read(hdmi, HDMI_STA));
666 DBGFS_DUMP("", HDMI_ACTIVE_VID_XMIN); 666 DBGFS_DUMP("", HDMI_ACTIVE_VID_XMIN);
667 seq_puts(s, "\t"); 667 seq_putc(s, '\t');
668 DBGFS_PRINT_INT("Xmin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMIN)); 668 DBGFS_PRINT_INT("Xmin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMIN));
669 DBGFS_DUMP("", HDMI_ACTIVE_VID_XMAX); 669 DBGFS_DUMP("", HDMI_ACTIVE_VID_XMAX);
670 seq_puts(s, "\t"); 670 seq_putc(s, '\t');
671 DBGFS_PRINT_INT("Xmax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMAX)); 671 DBGFS_PRINT_INT("Xmax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_XMAX));
672 DBGFS_DUMP("", HDMI_ACTIVE_VID_YMIN); 672 DBGFS_DUMP("", HDMI_ACTIVE_VID_YMIN);
673 seq_puts(s, "\t"); 673 seq_putc(s, '\t');
674 DBGFS_PRINT_INT("Ymin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMIN)); 674 DBGFS_PRINT_INT("Ymin:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMIN));
675 DBGFS_DUMP("", HDMI_ACTIVE_VID_YMAX); 675 DBGFS_DUMP("", HDMI_ACTIVE_VID_YMAX);
676 seq_puts(s, "\t"); 676 seq_putc(s, '\t');
677 DBGFS_PRINT_INT("Ymax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMAX)); 677 DBGFS_PRINT_INT("Ymax:", hdmi_read(hdmi, HDMI_ACTIVE_VID_YMAX));
678 DBGFS_DUMP("", HDMI_SW_DI_CFG); 678 DBGFS_DUMP("", HDMI_SW_DI_CFG);
679 hdmi_dbg_sw_di_cfg(s, hdmi_read(hdmi, HDMI_SW_DI_CFG)); 679 hdmi_dbg_sw_di_cfg(s, hdmi_read(hdmi, HDMI_SW_DI_CFG));
@@ -692,8 +692,7 @@ static int hdmi_dbg_show(struct seq_file *s, void *data)
692 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_AVI); 692 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_AVI);
693 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_AVI); 693 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_AVI);
694 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_AVI); 694 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_AVI);
695 seq_puts(s, "\n"); 695 seq_printf(s, "\n\n AUDIO Infoframe (Data Island slot N=%d):",
696 seq_printf(s, "\n AUDIO Infoframe (Data Island slot N=%d):",
697 HDMI_IFRAME_SLOT_AUDIO); 696 HDMI_IFRAME_SLOT_AUDIO);
698 DBGFS_DUMP_DI(HDMI_SW_DI_N_HEAD_WORD, HDMI_IFRAME_SLOT_AUDIO); 697 DBGFS_DUMP_DI(HDMI_SW_DI_N_HEAD_WORD, HDMI_IFRAME_SLOT_AUDIO);
699 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD0, HDMI_IFRAME_SLOT_AUDIO); 698 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD0, HDMI_IFRAME_SLOT_AUDIO);
@@ -703,8 +702,7 @@ static int hdmi_dbg_show(struct seq_file *s, void *data)
703 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_AUDIO); 702 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_AUDIO);
704 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_AUDIO); 703 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_AUDIO);
705 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_AUDIO); 704 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_AUDIO);
706 seq_puts(s, "\n"); 705 seq_printf(s, "\n\n VENDOR SPECIFIC Infoframe (Data Island slot N=%d):",
707 seq_printf(s, "\n VENDOR SPECIFIC Infoframe (Data Island slot N=%d):",
708 HDMI_IFRAME_SLOT_VENDOR); 706 HDMI_IFRAME_SLOT_VENDOR);
709 DBGFS_DUMP_DI(HDMI_SW_DI_N_HEAD_WORD, HDMI_IFRAME_SLOT_VENDOR); 707 DBGFS_DUMP_DI(HDMI_SW_DI_N_HEAD_WORD, HDMI_IFRAME_SLOT_VENDOR);
710 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD0, HDMI_IFRAME_SLOT_VENDOR); 708 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD0, HDMI_IFRAME_SLOT_VENDOR);
@@ -714,8 +712,7 @@ static int hdmi_dbg_show(struct seq_file *s, void *data)
714 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_VENDOR); 712 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD4, HDMI_IFRAME_SLOT_VENDOR);
715 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_VENDOR); 713 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD5, HDMI_IFRAME_SLOT_VENDOR);
716 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_VENDOR); 714 DBGFS_DUMP_DI(HDMI_SW_DI_N_PKT_WORD6, HDMI_IFRAME_SLOT_VENDOR);
717 seq_puts(s, "\n"); 715 seq_putc(s, '\n');
718
719 return 0; 716 return 0;
720} 717}
721 718
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c
index 66f843148ef7..a1c161f77804 100644
--- a/drivers/gpu/drm/sti/sti_hqvdp.c
+++ b/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -625,8 +625,7 @@ static int hqvdp_dbg_show(struct seq_file *s, void *data)
625 hqvdp_dbg_dump_cmd(s, (struct sti_hqvdp_cmd *)virt); 625 hqvdp_dbg_dump_cmd(s, (struct sti_hqvdp_cmd *)virt);
626 } 626 }
627 627
628 seq_puts(s, "\n"); 628 seq_putc(s, '\n');
629
630 return 0; 629 return 0;
631} 630}
632 631
@@ -1357,12 +1356,12 @@ static int sti_hqvdp_probe(struct platform_device *pdev)
1357 1356
1358 /* Get Memory resources */ 1357 /* Get Memory resources */
1359 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1358 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1360 if (res == NULL) { 1359 if (!res) {
1361 DRM_ERROR("Get memory resource failed\n"); 1360 DRM_ERROR("Get memory resource failed\n");
1362 return -ENXIO; 1361 return -ENXIO;
1363 } 1362 }
1364 hqvdp->regs = devm_ioremap(dev, res->start, resource_size(res)); 1363 hqvdp->regs = devm_ioremap(dev, res->start, resource_size(res));
1365 if (hqvdp->regs == NULL) { 1364 if (!hqvdp->regs) {
1366 DRM_ERROR("Register mapping failed\n"); 1365 DRM_ERROR("Register mapping failed\n");
1367 return -ENXIO; 1366 return -ENXIO;
1368 } 1367 }
diff --git a/drivers/gpu/drm/sti/sti_mixer.c b/drivers/gpu/drm/sti/sti_mixer.c
index 4ddc58f7fe2e..2bd1d46fe1cd 100644
--- a/drivers/gpu/drm/sti/sti_mixer.c
+++ b/drivers/gpu/drm/sti/sti_mixer.c
@@ -162,8 +162,7 @@ static int mixer_dbg_show(struct seq_file *s, void *arg)
162 DBGFS_DUMP(GAM_MIXER_MBP); 162 DBGFS_DUMP(GAM_MIXER_MBP);
163 DBGFS_DUMP(GAM_MIXER_MX0); 163 DBGFS_DUMP(GAM_MIXER_MX0);
164 mixer_dbg_mxn(s, mixer->regs + GAM_MIXER_MX0); 164 mixer_dbg_mxn(s, mixer->regs + GAM_MIXER_MX0);
165 seq_puts(s, "\n"); 165 seq_putc(s, '\n');
166
167 return 0; 166 return 0;
168} 167}
169 168
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c
index 8b8ea717c121..8959fcc743a8 100644
--- a/drivers/gpu/drm/sti/sti_tvout.c
+++ b/drivers/gpu/drm/sti/sti_tvout.c
@@ -459,7 +459,7 @@ static void tvout_dbg_vip(struct seq_file *s, int val)
459 "Aux (color matrix by-passed)", 459 "Aux (color matrix by-passed)",
460 "", "", "", "", "", "Force value"}; 460 "", "", "", "", "", "Force value"};
461 461
462 seq_puts(s, "\t"); 462 seq_putc(s, '\t');
463 mask = TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_R_SHIFT; 463 mask = TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_R_SHIFT;
464 r = (val & mask) >> TVO_VIP_REORDER_R_SHIFT; 464 r = (val & mask) >> TVO_VIP_REORDER_R_SHIFT;
465 mask = TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_G_SHIFT; 465 mask = TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_G_SHIFT;
@@ -558,8 +558,7 @@ static int tvout_dbg_show(struct seq_file *s, void *data)
558 DBGFS_DUMP(TVO_CSC_AUX_M6); 558 DBGFS_DUMP(TVO_CSC_AUX_M6);
559 DBGFS_DUMP(TVO_CSC_AUX_M7); 559 DBGFS_DUMP(TVO_CSC_AUX_M7);
560 DBGFS_DUMP(TVO_AUX_IN_VID_FORMAT); 560 DBGFS_DUMP(TVO_AUX_IN_VID_FORMAT);
561 seq_puts(s, "\n"); 561 seq_putc(s, '\n');
562
563 return 0; 562 return 0;
564} 563}
565 564
@@ -847,7 +846,7 @@ static int sti_tvout_probe(struct platform_device *pdev)
847 846
848 tvout->dev = dev; 847 tvout->dev = dev;
849 848
850 /* get Memory ressources */ 849 /* get memory resources */
851 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tvout-reg"); 850 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tvout-reg");
852 if (!res) { 851 if (!res) {
853 DRM_ERROR("Invalid glue resource\n"); 852 DRM_ERROR("Invalid glue resource\n");
diff --git a/drivers/gpu/drm/sti/sti_vid.c b/drivers/gpu/drm/sti/sti_vid.c
index 2ad59892b57e..577a3341d3c1 100644
--- a/drivers/gpu/drm/sti/sti_vid.c
+++ b/drivers/gpu/drm/sti/sti_vid.c
@@ -61,7 +61,7 @@
61static void vid_dbg_ctl(struct seq_file *s, int val) 61static void vid_dbg_ctl(struct seq_file *s, int val)
62{ 62{
63 val = val >> 30; 63 val = val >> 30;
64 seq_puts(s, "\t"); 64 seq_putc(s, '\t');
65 65
66 if (!(val & 1)) 66 if (!(val & 1))
67 seq_puts(s, "NOT "); 67 seq_puts(s, "NOT ");
@@ -114,8 +114,7 @@ static int vid_dbg_show(struct seq_file *s, void *arg)
114 DBGFS_DUMP(VID_BC); 114 DBGFS_DUMP(VID_BC);
115 DBGFS_DUMP(VID_TINT); 115 DBGFS_DUMP(VID_TINT);
116 DBGFS_DUMP(VID_CSAT); 116 DBGFS_DUMP(VID_CSAT);
117 seq_puts(s, "\n"); 117 seq_putc(s, '\n');
118
119 return 0; 118 return 0;
120} 119}
121 120
diff --git a/drivers/gpu/drm/stm/Kconfig b/drivers/gpu/drm/stm/Kconfig
new file mode 100644
index 000000000000..2c4817fb0890
--- /dev/null
+++ b/drivers/gpu/drm/stm/Kconfig
@@ -0,0 +1,16 @@
1config DRM_STM
2 tristate "DRM Support for STMicroelectronics SoC Series"
3 depends on DRM && (ARCH_STM32 || ARCH_MULTIPLATFORM)
4 select DRM_KMS_HELPER
5 select DRM_GEM_CMA_HELPER
6 select DRM_KMS_CMA_HELPER
7 select DRM_PANEL
8 select VIDEOMODE_HELPERS
9 select FB_PROVIDE_GET_FB_UNMAPPED_AREA
10 default y
11
12 help
13 Enable support for the on-chip display controller on
14 STMicroelectronics STM32 MCUs.
15 To compile this driver as a module, choose M here: the module
16 will be called stm-drm.
diff --git a/drivers/gpu/drm/stm/Makefile b/drivers/gpu/drm/stm/Makefile
new file mode 100644
index 000000000000..e114d45dbd42
--- /dev/null
+++ b/drivers/gpu/drm/stm/Makefile
@@ -0,0 +1,7 @@
1ccflags-y := -Iinclude/drm
2
3stm-drm-y := \
4 drv.o \
5 ltdc.o
6
7obj-$(CONFIG_DRM_STM) += stm-drm.o
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
new file mode 100644
index 000000000000..83ab48f1fd00
--- /dev/null
+++ b/drivers/gpu/drm/stm/drv.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2017
3 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com>
6 * Fabien Dessenne <fabien.dessenne@st.com>
7 * Mickael Reulier <mickael.reulier@st.com>
8 *
9 * License terms: GNU General Public License (GPL), version 2
10 */
11
12#include <linux/component.h>
13#include <linux/of_platform.h>
14
15#include <drm/drm_atomic.h>
16#include <drm/drm_atomic_helper.h>
17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_fb_cma_helper.h>
19#include <drm/drm_gem_cma_helper.h>
20
21#include "ltdc.h"
22
23#define DRIVER_NAME "stm"
24#define DRIVER_DESC "STMicroelectronics SoC DRM"
25#define DRIVER_DATE "20170330"
26#define DRIVER_MAJOR 1
27#define DRIVER_MINOR 0
28#define DRIVER_PATCH_LEVEL 0
29
30#define STM_MAX_FB_WIDTH 2048
31#define STM_MAX_FB_HEIGHT 2048 /* same as width to handle orientation */
32
33static void drv_output_poll_changed(struct drm_device *ddev)
34{
35 struct ltdc_device *ldev = ddev->dev_private;
36
37 drm_fbdev_cma_hotplug_event(ldev->fbdev);
38}
39
40static const struct drm_mode_config_funcs drv_mode_config_funcs = {
41 .fb_create = drm_fb_cma_create,
42 .output_poll_changed = drv_output_poll_changed,
43 .atomic_check = drm_atomic_helper_check,
44 .atomic_commit = drm_atomic_helper_commit,
45};
46
47static void drv_lastclose(struct drm_device *ddev)
48{
49 struct ltdc_device *ldev = ddev->dev_private;
50
51 DRM_DEBUG("%s\n", __func__);
52
53 drm_fbdev_cma_restore_mode(ldev->fbdev);
54}
55
56DEFINE_DRM_GEM_CMA_FOPS(drv_driver_fops);
57
58static struct drm_driver drv_driver = {
59 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
60 DRIVER_ATOMIC,
61 .lastclose = drv_lastclose,
62 .name = DRIVER_NAME,
63 .desc = DRIVER_DESC,
64 .date = DRIVER_DATE,
65 .major = DRIVER_MAJOR,
66 .minor = DRIVER_MINOR,
67 .patchlevel = DRIVER_PATCH_LEVEL,
68 .fops = &drv_driver_fops,
69 .dumb_create = drm_gem_cma_dumb_create,
70 .dumb_map_offset = drm_gem_cma_dumb_map_offset,
71 .dumb_destroy = drm_gem_dumb_destroy,
72 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
73 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
74 .gem_free_object_unlocked = drm_gem_cma_free_object,
75 .gem_vm_ops = &drm_gem_cma_vm_ops,
76 .gem_prime_export = drm_gem_prime_export,
77 .gem_prime_import = drm_gem_prime_import,
78 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
79 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
80 .gem_prime_vmap = drm_gem_cma_prime_vmap,
81 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
82 .gem_prime_mmap = drm_gem_cma_prime_mmap,
83 .enable_vblank = ltdc_crtc_enable_vblank,
84 .disable_vblank = ltdc_crtc_disable_vblank,
85};
86
87static int drv_load(struct drm_device *ddev)
88{
89 struct platform_device *pdev = to_platform_device(ddev->dev);
90 struct drm_fbdev_cma *fbdev;
91 struct ltdc_device *ldev;
92 int ret;
93
94 DRM_DEBUG("%s\n", __func__);
95
96 ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL);
97 if (!ldev)
98 return -ENOMEM;
99
100 ddev->dev_private = (void *)ldev;
101
102 drm_mode_config_init(ddev);
103
104 /*
105 * set max width and height as default value.
106 * this value would be used to check framebuffer size limitation
107 * at drm_mode_addfb().
108 */
109 ddev->mode_config.min_width = 0;
110 ddev->mode_config.min_height = 0;
111 ddev->mode_config.max_width = STM_MAX_FB_WIDTH;
112 ddev->mode_config.max_height = STM_MAX_FB_HEIGHT;
113 ddev->mode_config.funcs = &drv_mode_config_funcs;
114
115 ret = ltdc_load(ddev);
116 if (ret)
117 goto err;
118
119 drm_mode_config_reset(ddev);
120 drm_kms_helper_poll_init(ddev);
121
122 if (ddev->mode_config.num_connector) {
123 ldev = ddev->dev_private;
124 fbdev = drm_fbdev_cma_init(ddev, 16,
125 ddev->mode_config.num_connector);
126 if (IS_ERR(fbdev)) {
127 DRM_DEBUG("Warning: fails to create fbdev\n");
128 fbdev = NULL;
129 }
130 ldev->fbdev = fbdev;
131 }
132
133 platform_set_drvdata(pdev, ddev);
134
135 return 0;
136err:
137 drm_mode_config_cleanup(ddev);
138 return ret;
139}
140
141static void drv_unload(struct drm_device *ddev)
142{
143 struct ltdc_device *ldev = ddev->dev_private;
144
145 DRM_DEBUG("%s\n", __func__);
146
147 if (ldev->fbdev) {
148 drm_fbdev_cma_fini(ldev->fbdev);
149 ldev->fbdev = NULL;
150 }
151 drm_kms_helper_poll_fini(ddev);
152 ltdc_unload(ddev);
153 drm_mode_config_cleanup(ddev);
154}
155
156static int stm_drm_platform_probe(struct platform_device *pdev)
157{
158 struct device *dev = &pdev->dev;
159 struct drm_device *ddev;
160 int ret;
161
162 DRM_DEBUG("%s\n", __func__);
163
164 dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
165
166 ddev = drm_dev_alloc(&drv_driver, dev);
167 if (IS_ERR(ddev))
168 return PTR_ERR(ddev);
169
170 ret = drv_load(ddev);
171 if (ret)
172 goto err_unref;
173
174 ret = drm_dev_register(ddev, 0);
175 if (ret)
176 goto err_unref;
177
178 return 0;
179
180err_unref:
181 drm_dev_unref(ddev);
182
183 return ret;
184}
185
186static int stm_drm_platform_remove(struct platform_device *pdev)
187{
188 struct drm_device *ddev = platform_get_drvdata(pdev);
189
190 DRM_DEBUG("%s\n", __func__);
191
192 drm_dev_unregister(ddev);
193 drv_unload(ddev);
194 drm_dev_unref(ddev);
195
196 return 0;
197}
198
199static const struct of_device_id drv_dt_ids[] = {
200 { .compatible = "st,stm32-ltdc"},
201 { /* end node */ },
202};
203MODULE_DEVICE_TABLE(of, drv_dt_ids);
204
205static struct platform_driver stm_drm_platform_driver = {
206 .probe = stm_drm_platform_probe,
207 .remove = stm_drm_platform_remove,
208 .driver = {
209 .name = DRIVER_NAME,
210 .of_match_table = drv_dt_ids,
211 },
212};
213
214module_platform_driver(stm_drm_platform_driver);
215
216MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
217MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
218MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
219MODULE_AUTHOR("Mickael Reulier <mickael.reulier@st.com>");
220MODULE_DESCRIPTION("STMicroelectronics ST DRM LTDC driver");
221MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
new file mode 100644
index 000000000000..a40418cda74a
--- /dev/null
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -0,0 +1,1160 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2017
3 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com>
6 * Fabien Dessenne <fabien.dessenne@st.com>
7 * Mickael Reulier <mickael.reulier@st.com>
8 *
9 * License terms: GNU General Public License (GPL), version 2
10 */
11
12#include <linux/clk.h>
13#include <linux/component.h>
14#include <linux/of_address.h>
15#include <linux/of_graph.h>
16#include <linux/reset.h>
17
18#include <drm/drm_atomic.h>
19#include <drm/drm_atomic_helper.h>
20#include <drm/drm_crtc_helper.h>
21#include <drm/drm_fb_cma_helper.h>
22#include <drm/drm_gem_cma_helper.h>
23#include <drm/drm_of.h>
24#include <drm/drm_panel.h>
25#include <drm/drm_plane_helper.h>
26
27#include <video/videomode.h>
28
29#include "ltdc.h"
30
31#define NB_CRTC 1
32#define CRTC_MASK GENMASK(NB_CRTC - 1, 0)
33
34#define MAX_IRQ 4
35
36#define HWVER_10200 0x010200
37#define HWVER_10300 0x010300
38#define HWVER_20101 0x020101
39
40/*
41 * The address of some registers depends on the HW version: such registers have
42 * an extra offset specified with reg_ofs.
43 */
44#define REG_OFS_NONE 0
45#define REG_OFS_4 4 /* Insertion of "Layer Configuration 2" reg */
46#define REG_OFS (ldev->caps.reg_ofs)
47#define LAY_OFS 0x80 /* Register Offset between 2 layers */
48
49/* Global register offsets */
50#define LTDC_IDR 0x0000 /* IDentification */
51#define LTDC_LCR 0x0004 /* Layer Count */
52#define LTDC_SSCR 0x0008 /* Synchronization Size Configuration */
53#define LTDC_BPCR 0x000C /* Back Porch Configuration */
54#define LTDC_AWCR 0x0010 /* Active Width Configuration */
55#define LTDC_TWCR 0x0014 /* Total Width Configuration */
56#define LTDC_GCR 0x0018 /* Global Control */
57#define LTDC_GC1R 0x001C /* Global Configuration 1 */
58#define LTDC_GC2R 0x0020 /* Global Configuration 2 */
59#define LTDC_SRCR 0x0024 /* Shadow Reload Configuration */
60#define LTDC_GACR 0x0028 /* GAmma Correction */
61#define LTDC_BCCR 0x002C /* Background Color Configuration */
62#define LTDC_IER 0x0034 /* Interrupt Enable */
63#define LTDC_ISR 0x0038 /* Interrupt Status */
64#define LTDC_ICR 0x003C /* Interrupt Clear */
65#define LTDC_LIPCR 0x0040 /* Line Interrupt Position Configuration */
66#define LTDC_CPSR 0x0044 /* Current Position Status */
67#define LTDC_CDSR 0x0048 /* Current Display Status */
68
69/* Layer register offsets */
70#define LTDC_L1LC1R (0x0080) /* L1 Layer Configuration 1 */
71#define LTDC_L1LC2R (0x0084) /* L1 Layer Configuration 2 */
72#define LTDC_L1CR (0x0084 + REG_OFS) /* L1 Control */
73#define LTDC_L1WHPCR (0x0088 + REG_OFS) /* L1 Window Hor Position Config */
74#define LTDC_L1WVPCR (0x008C + REG_OFS) /* L1 Window Vert Position Config */
75#define LTDC_L1CKCR (0x0090 + REG_OFS) /* L1 Color Keying Configuration */
76#define LTDC_L1PFCR (0x0094 + REG_OFS) /* L1 Pixel Format Configuration */
77#define LTDC_L1CACR (0x0098 + REG_OFS) /* L1 Constant Alpha Config */
78#define LTDC_L1DCCR (0x009C + REG_OFS) /* L1 Default Color Configuration */
79#define LTDC_L1BFCR (0x00A0 + REG_OFS) /* L1 Blend Factors Configuration */
80#define LTDC_L1FBBCR (0x00A4 + REG_OFS) /* L1 FrameBuffer Bus Control */
81#define LTDC_L1AFBCR (0x00A8 + REG_OFS) /* L1 AuxFB Control */
82#define LTDC_L1CFBAR (0x00AC + REG_OFS) /* L1 Color FrameBuffer Address */
83#define LTDC_L1CFBLR (0x00B0 + REG_OFS) /* L1 Color FrameBuffer Length */
84#define LTDC_L1CFBLNR (0x00B4 + REG_OFS) /* L1 Color FrameBuffer Line Nb */
85#define LTDC_L1AFBAR (0x00B8 + REG_OFS) /* L1 AuxFB Address */
86#define LTDC_L1AFBLR (0x00BC + REG_OFS) /* L1 AuxFB Length */
87#define LTDC_L1AFBLNR (0x00C0 + REG_OFS) /* L1 AuxFB Line Number */
88#define LTDC_L1CLUTWR (0x00C4 + REG_OFS) /* L1 CLUT Write */
89#define LTDC_L1YS1R (0x00E0 + REG_OFS) /* L1 YCbCr Scale 1 */
90#define LTDC_L1YS2R (0x00E4 + REG_OFS) /* L1 YCbCr Scale 2 */
91
92/* Bit definitions */
93#define SSCR_VSH GENMASK(10, 0) /* Vertical Synchronization Height */
94#define SSCR_HSW GENMASK(27, 16) /* Horizontal Synchronization Width */
95
96#define BPCR_AVBP GENMASK(10, 0) /* Accumulated Vertical Back Porch */
97#define BPCR_AHBP GENMASK(27, 16) /* Accumulated Horizontal Back Porch */
98
99#define AWCR_AAH GENMASK(10, 0) /* Accumulated Active Height */
100#define AWCR_AAW GENMASK(27, 16) /* Accumulated Active Width */
101
102#define TWCR_TOTALH GENMASK(10, 0) /* TOTAL Height */
103#define TWCR_TOTALW GENMASK(27, 16) /* TOTAL Width */
104
105#define GCR_LTDCEN BIT(0) /* LTDC ENable */
106#define GCR_DEN BIT(16) /* Dither ENable */
107#define GCR_PCPOL BIT(28) /* Pixel Clock POLarity */
108#define GCR_DEPOL BIT(29) /* Data Enable POLarity */
109#define GCR_VSPOL BIT(30) /* Vertical Synchro POLarity */
110#define GCR_HSPOL BIT(31) /* Horizontal Synchro POLarity */
111
112#define GC1R_WBCH GENMASK(3, 0) /* Width of Blue CHannel output */
113#define GC1R_WGCH GENMASK(7, 4) /* Width of Green Channel output */
114#define GC1R_WRCH GENMASK(11, 8) /* Width of Red Channel output */
115#define GC1R_PBEN BIT(12) /* Precise Blending ENable */
116#define GC1R_DT GENMASK(15, 14) /* Dithering Technique */
117#define GC1R_GCT GENMASK(19, 17) /* Gamma Correction Technique */
118#define GC1R_SHREN BIT(21) /* SHadow Registers ENabled */
119#define GC1R_BCP BIT(22) /* Background Colour Programmable */
120#define GC1R_BBEN BIT(23) /* Background Blending ENabled */
121#define GC1R_LNIP BIT(24) /* Line Number IRQ Position */
122#define GC1R_TP BIT(25) /* Timing Programmable */
123#define GC1R_IPP BIT(26) /* IRQ Polarity Programmable */
124#define GC1R_SPP BIT(27) /* Sync Polarity Programmable */
125#define GC1R_DWP BIT(28) /* Dither Width Programmable */
126#define GC1R_STREN BIT(29) /* STatus Registers ENabled */
127#define GC1R_BMEN BIT(31) /* Blind Mode ENabled */
128
129#define GC2R_EDCA BIT(0) /* External Display Control Ability */
130#define GC2R_STSAEN BIT(1) /* Slave Timing Sync Ability ENabled */
131#define GC2R_DVAEN BIT(2) /* Dual-View Ability ENabled */
132#define GC2R_DPAEN BIT(3) /* Dual-Port Ability ENabled */
133#define GC2R_BW GENMASK(6, 4) /* Bus Width (log2 of nb of bytes) */
134#define GC2R_EDCEN BIT(7) /* External Display Control ENabled */
135
136#define SRCR_IMR BIT(0) /* IMmediate Reload */
137#define SRCR_VBR BIT(1) /* Vertical Blanking Reload */
138
139#define BCCR_BCBLACK 0x00 /* Background Color BLACK */
140#define BCCR_BCBLUE GENMASK(7, 0) /* Background Color BLUE */
141#define BCCR_BCGREEN GENMASK(15, 8) /* Background Color GREEN */
142#define BCCR_BCRED GENMASK(23, 16) /* Background Color RED */
143#define BCCR_BCWHITE GENMASK(23, 0) /* Background Color WHITE */
144
145#define IER_LIE BIT(0) /* Line Interrupt Enable */
146#define IER_FUIE BIT(1) /* Fifo Underrun Interrupt Enable */
147#define IER_TERRIE BIT(2) /* Transfer ERRor Interrupt Enable */
148#define IER_RRIE BIT(3) /* Register Reload Interrupt enable */
149
150#define ISR_LIF BIT(0) /* Line Interrupt Flag */
151#define ISR_FUIF BIT(1) /* Fifo Underrun Interrupt Flag */
152#define ISR_TERRIF BIT(2) /* Transfer ERRor Interrupt Flag */
153#define ISR_RRIF BIT(3) /* Register Reload Interrupt Flag */
154
155#define LXCR_LEN BIT(0) /* Layer ENable */
156#define LXCR_COLKEN BIT(1) /* Color Keying Enable */
157#define LXCR_CLUTEN BIT(4) /* Color Look-Up Table ENable */
158
159#define LXWHPCR_WHSTPOS GENMASK(11, 0) /* Window Horizontal StarT POSition */
160#define LXWHPCR_WHSPPOS GENMASK(27, 16) /* Window Horizontal StoP POSition */
161
162#define LXWVPCR_WVSTPOS GENMASK(10, 0) /* Window Vertical StarT POSition */
163#define LXWVPCR_WVSPPOS GENMASK(26, 16) /* Window Vertical StoP POSition */
164
165#define LXPFCR_PF GENMASK(2, 0) /* Pixel Format */
166
167#define LXCACR_CONSTA GENMASK(7, 0) /* CONSTant Alpha */
168
169#define LXBFCR_BF2 GENMASK(2, 0) /* Blending Factor 2 */
170#define LXBFCR_BF1 GENMASK(10, 8) /* Blending Factor 1 */
171
172#define LXCFBLR_CFBLL GENMASK(12, 0) /* Color Frame Buffer Line Length */
173#define LXCFBLR_CFBP GENMASK(28, 16) /* Color Frame Buffer Pitch in bytes */
174
175#define LXCFBLNR_CFBLN GENMASK(10, 0) /* Color Frame Buffer Line Number */
176
177#define HSPOL_AL 0 /* Horizontal Sync POLarity Active Low */
178#define VSPOL_AL 0 /* Vertical Sync POLarity Active Low */
179#define DEPOL_AL 0 /* Data Enable POLarity Active Low */
180#define PCPOL_IPC 0 /* Input Pixel Clock */
181#define HSPOL_AH GCR_HSPOL /* Horizontal Sync POLarity Active High */
182#define VSPOL_AH GCR_VSPOL /* Vertical Sync POLarity Active High */
183#define DEPOL_AH GCR_DEPOL /* Data Enable POLarity Active High */
184#define PCPOL_IIPC GCR_PCPOL /* Inverted Input Pixel Clock */
185#define CONSTA_MAX 0xFF /* CONSTant Alpha MAX= 1.0 */
186#define BF1_PAXCA 0x600 /* Pixel Alpha x Constant Alpha */
187#define BF1_CA 0x400 /* Constant Alpha */
188#define BF2_1PAXCA 0x007 /* 1 - (Pixel Alpha x Constant Alpha) */
189#define BF2_1CA 0x005 /* 1 - Constant Alpha */
190
191#define NB_PF 8 /* Max nb of HW pixel format */
192
193enum ltdc_pix_fmt {
194 PF_NONE,
195 /* RGB formats */
196 PF_ARGB8888, /* ARGB [32 bits] */
197 PF_RGBA8888, /* RGBA [32 bits] */
198 PF_RGB888, /* RGB [24 bits] */
199 PF_RGB565, /* RGB [16 bits] */
200 PF_ARGB1555, /* ARGB A:1 bit RGB:15 bits [16 bits] */
201 PF_ARGB4444, /* ARGB A:4 bits R/G/B: 4 bits each [16 bits] */
202 /* Indexed formats */
203 PF_L8, /* Indexed 8 bits [8 bits] */
204 PF_AL44, /* Alpha:4 bits + indexed 4 bits [8 bits] */
205 PF_AL88 /* Alpha:8 bits + indexed 8 bits [16 bits] */
206};
207
208/* The index gives the encoding of the pixel format for an HW version */
209static const enum ltdc_pix_fmt ltdc_pix_fmt_a0[NB_PF] = {
210 PF_ARGB8888, /* 0x00 */
211 PF_RGB888, /* 0x01 */
212 PF_RGB565, /* 0x02 */
213 PF_ARGB1555, /* 0x03 */
214 PF_ARGB4444, /* 0x04 */
215 PF_L8, /* 0x05 */
216 PF_AL44, /* 0x06 */
217 PF_AL88 /* 0x07 */
218};
219
220static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = {
221 PF_ARGB8888, /* 0x00 */
222 PF_RGB888, /* 0x01 */
223 PF_RGB565, /* 0x02 */
224 PF_RGBA8888, /* 0x03 */
225 PF_AL44, /* 0x04 */
226 PF_L8, /* 0x05 */
227 PF_ARGB1555, /* 0x06 */
228 PF_ARGB4444 /* 0x07 */
229};
230
231static inline u32 reg_read(void __iomem *base, u32 reg)
232{
233 return readl_relaxed(base + reg);
234}
235
236static inline void reg_write(void __iomem *base, u32 reg, u32 val)
237{
238 writel_relaxed(val, base + reg);
239}
240
241static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
242{
243 reg_write(base, reg, reg_read(base, reg) | mask);
244}
245
246static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
247{
248 reg_write(base, reg, reg_read(base, reg) & ~mask);
249}
250
251static inline void reg_update_bits(void __iomem *base, u32 reg, u32 mask,
252 u32 val)
253{
254 reg_write(base, reg, (reg_read(base, reg) & ~mask) | val);
255}
256
257static inline struct ltdc_device *crtc_to_ltdc(struct drm_crtc *crtc)
258{
259 return (struct ltdc_device *)crtc->dev->dev_private;
260}
261
262static inline struct ltdc_device *plane_to_ltdc(struct drm_plane *plane)
263{
264 return (struct ltdc_device *)plane->dev->dev_private;
265}
266
267static inline struct ltdc_device *encoder_to_ltdc(struct drm_encoder *enc)
268{
269 return (struct ltdc_device *)enc->dev->dev_private;
270}
271
272static inline struct ltdc_device *connector_to_ltdc(struct drm_connector *con)
273{
274 return (struct ltdc_device *)con->dev->dev_private;
275}
276
277static inline enum ltdc_pix_fmt to_ltdc_pixelformat(u32 drm_fmt)
278{
279 enum ltdc_pix_fmt pf;
280
281 switch (drm_fmt) {
282 case DRM_FORMAT_ARGB8888:
283 case DRM_FORMAT_XRGB8888:
284 pf = PF_ARGB8888;
285 break;
286 case DRM_FORMAT_RGBA8888:
287 case DRM_FORMAT_RGBX8888:
288 pf = PF_RGBA8888;
289 break;
290 case DRM_FORMAT_RGB888:
291 pf = PF_RGB888;
292 break;
293 case DRM_FORMAT_RGB565:
294 pf = PF_RGB565;
295 break;
296 case DRM_FORMAT_ARGB1555:
297 case DRM_FORMAT_XRGB1555:
298 pf = PF_ARGB1555;
299 break;
300 case DRM_FORMAT_ARGB4444:
301 case DRM_FORMAT_XRGB4444:
302 pf = PF_ARGB4444;
303 break;
304 case DRM_FORMAT_C8:
305 pf = PF_L8;
306 break;
307 default:
308 pf = PF_NONE;
309 break;
310 /* Note: There are no DRM_FORMAT for AL44 and AL88 */
311 }
312
313 return pf;
314}
315
316static inline u32 to_drm_pixelformat(enum ltdc_pix_fmt pf)
317{
318 switch (pf) {
319 case PF_ARGB8888:
320 return DRM_FORMAT_ARGB8888;
321 case PF_RGBA8888:
322 return DRM_FORMAT_RGBA8888;
323 case PF_RGB888:
324 return DRM_FORMAT_RGB888;
325 case PF_RGB565:
326 return DRM_FORMAT_RGB565;
327 case PF_ARGB1555:
328 return DRM_FORMAT_ARGB1555;
329 case PF_ARGB4444:
330 return DRM_FORMAT_ARGB4444;
331 case PF_L8:
332 return DRM_FORMAT_C8;
333 case PF_AL44: /* No DRM support */
334 case PF_AL88: /* No DRM support */
335 case PF_NONE:
336 default:
337 return 0;
338 }
339}
340
341static irqreturn_t ltdc_irq_thread(int irq, void *arg)
342{
343 struct drm_device *ddev = arg;
344 struct ltdc_device *ldev = ddev->dev_private;
345 struct drm_crtc *crtc = drm_crtc_from_index(ddev, 0);
346
347 /* Line IRQ : trigger the vblank event */
348 if (ldev->irq_status & ISR_LIF)
349 drm_crtc_handle_vblank(crtc);
350
351 /* Save FIFO Underrun & Transfer Error status */
352 mutex_lock(&ldev->err_lock);
353 if (ldev->irq_status & ISR_FUIF)
354 ldev->error_status |= ISR_FUIF;
355 if (ldev->irq_status & ISR_TERRIF)
356 ldev->error_status |= ISR_TERRIF;
357 mutex_unlock(&ldev->err_lock);
358
359 return IRQ_HANDLED;
360}
361
362static irqreturn_t ltdc_irq(int irq, void *arg)
363{
364 struct drm_device *ddev = arg;
365 struct ltdc_device *ldev = ddev->dev_private;
366
367 /* Read & Clear the interrupt status */
368 ldev->irq_status = reg_read(ldev->regs, LTDC_ISR);
369 reg_write(ldev->regs, LTDC_ICR, ldev->irq_status);
370
371 return IRQ_WAKE_THREAD;
372}
373
374/*
375 * DRM_CRTC
376 */
377
378static void ltdc_crtc_load_lut(struct drm_crtc *crtc)
379{
380 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
381 unsigned int i, lay;
382
383 for (lay = 0; lay < ldev->caps.nb_layers; lay++)
384 for (i = 0; i < 256; i++)
385 reg_write(ldev->regs, LTDC_L1CLUTWR + lay * LAY_OFS,
386 ldev->clut[i]);
387}
388
389static void ltdc_crtc_enable(struct drm_crtc *crtc)
390{
391 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
392
393 DRM_DEBUG_DRIVER("\n");
394
395 /* Sets the background color value */
396 reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK);
397
398 /* Enable IRQ */
399 reg_set(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
400
401 /* Immediately commit the planes */
402 reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
403
404 /* Enable LTDC */
405 reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
406
407 drm_crtc_vblank_on(crtc);
408}
409
410static void ltdc_crtc_disable(struct drm_crtc *crtc)
411{
412 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
413
414 DRM_DEBUG_DRIVER("\n");
415
416 drm_crtc_vblank_off(crtc);
417
418 /* disable LTDC */
419 reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN);
420
421 /* disable IRQ */
422 reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
423
424 /* immediately commit disable of layers before switching off LTDC */
425 reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
426}
427
428static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc)
429{
430 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
431 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
432 struct videomode vm;
433 int rate = mode->clock * 1000;
434 u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h;
435 u32 total_width, total_height;
436 u32 val;
437
438 drm_display_mode_to_videomode(mode, &vm);
439
440 DRM_DEBUG_DRIVER("CRTC:%d mode:%s\n", crtc->base.id, mode->name);
441 DRM_DEBUG_DRIVER("Video mode: %dx%d", vm.hactive, vm.vactive);
442 DRM_DEBUG_DRIVER(" hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
443 vm.hfront_porch, vm.hback_porch, vm.hsync_len,
444 vm.vfront_porch, vm.vback_porch, vm.vsync_len);
445
446 /* Convert video timings to ltdc timings */
447 hsync = vm.hsync_len - 1;
448 vsync = vm.vsync_len - 1;
449 accum_hbp = hsync + vm.hback_porch;
450 accum_vbp = vsync + vm.vback_porch;
451 accum_act_w = accum_hbp + vm.hactive;
452 accum_act_h = accum_vbp + vm.vactive;
453 total_width = accum_act_w + vm.hfront_porch;
454 total_height = accum_act_h + vm.vfront_porch;
455
456 clk_disable(ldev->pixel_clk);
457
458 if (clk_set_rate(ldev->pixel_clk, rate) < 0) {
459 DRM_ERROR("Cannot set rate (%dHz) for pixel clk\n", rate);
460 return;
461 }
462
463 clk_enable(ldev->pixel_clk);
464
465 /* Configures the HS, VS, DE and PC polarities. */
466 val = HSPOL_AL | HSPOL_AL | DEPOL_AL | PCPOL_IPC;
467
468 if (vm.flags & DISPLAY_FLAGS_HSYNC_HIGH)
469 val |= HSPOL_AH;
470
471 if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
472 val |= VSPOL_AH;
473
474 if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
475 val |= DEPOL_AH;
476
477 if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
478 val |= PCPOL_IIPC;
479
480 reg_update_bits(ldev->regs, LTDC_GCR,
481 GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
482
483 /* Set Synchronization size */
484 val = (hsync << 16) | vsync;
485 reg_update_bits(ldev->regs, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
486
487 /* Set Accumulated Back porch */
488 val = (accum_hbp << 16) | accum_vbp;
489 reg_update_bits(ldev->regs, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
490
491 /* Set Accumulated Active Width */
492 val = (accum_act_w << 16) | accum_act_h;
493 reg_update_bits(ldev->regs, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
494
495 /* Set total width & height */
496 val = (total_width << 16) | total_height;
497 reg_update_bits(ldev->regs, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
498
499 reg_write(ldev->regs, LTDC_LIPCR, (accum_act_h + 1));
500}
501
502static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc,
503 struct drm_crtc_state *old_crtc_state)
504{
505 struct ltdc_device *ldev = crtc_to_ltdc(crtc);
506 struct drm_pending_vblank_event *event = crtc->state->event;
507
508 DRM_DEBUG_ATOMIC("\n");
509
510 /* Commit shadow registers = update planes at next vblank */
511 reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
512
513 if (event) {
514 crtc->state->event = NULL;
515
516 spin_lock_irq(&crtc->dev->event_lock);
517 if (drm_crtc_vblank_get(crtc) == 0)
518 drm_crtc_arm_vblank_event(crtc, event);
519 else
520 drm_crtc_send_vblank_event(crtc, event);
521 spin_unlock_irq(&crtc->dev->event_lock);
522 }
523}
524
525static struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
526 .load_lut = ltdc_crtc_load_lut,
527 .enable = ltdc_crtc_enable,
528 .disable = ltdc_crtc_disable,
529 .mode_set_nofb = ltdc_crtc_mode_set_nofb,
530 .atomic_flush = ltdc_crtc_atomic_flush,
531};
532
533int ltdc_crtc_enable_vblank(struct drm_device *ddev, unsigned int pipe)
534{
535 struct ltdc_device *ldev = ddev->dev_private;
536
537 DRM_DEBUG_DRIVER("\n");
538 reg_set(ldev->regs, LTDC_IER, IER_LIE);
539
540 return 0;
541}
542
543void ltdc_crtc_disable_vblank(struct drm_device *ddev, unsigned int pipe)
544{
545 struct ltdc_device *ldev = ddev->dev_private;
546
547 DRM_DEBUG_DRIVER("\n");
548 reg_clear(ldev->regs, LTDC_IER, IER_LIE);
549}
550
551static struct drm_crtc_funcs ltdc_crtc_funcs = {
552 .destroy = drm_crtc_cleanup,
553 .set_config = drm_atomic_helper_set_config,
554 .page_flip = drm_atomic_helper_page_flip,
555 .reset = drm_atomic_helper_crtc_reset,
556 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
557 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
558};
559
560/*
561 * DRM_PLANE
562 */
563
564static int ltdc_plane_atomic_check(struct drm_plane *plane,
565 struct drm_plane_state *state)
566{
567 struct drm_framebuffer *fb = state->fb;
568 u32 src_x, src_y, src_w, src_h;
569
570 DRM_DEBUG_DRIVER("\n");
571
572 if (!fb)
573 return 0;
574
575 /* convert src_ from 16:16 format */
576 src_x = state->src_x >> 16;
577 src_y = state->src_y >> 16;
578 src_w = state->src_w >> 16;
579 src_h = state->src_h >> 16;
580
581 /* Reject scaling */
582 if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) {
583 DRM_ERROR("Scaling is not supported");
584 return -EINVAL;
585 }
586
587 return 0;
588}
589
590static void ltdc_plane_atomic_update(struct drm_plane *plane,
591 struct drm_plane_state *oldstate)
592{
593 struct ltdc_device *ldev = plane_to_ltdc(plane);
594 struct drm_plane_state *state = plane->state;
595 struct drm_framebuffer *fb = state->fb;
596 u32 lofs = plane->index * LAY_OFS;
597 u32 x0 = state->crtc_x;
598 u32 x1 = state->crtc_x + state->crtc_w - 1;
599 u32 y0 = state->crtc_y;
600 u32 y1 = state->crtc_y + state->crtc_h - 1;
601 u32 src_x, src_y, src_w, src_h;
602 u32 val, pitch_in_bytes, line_length, paddr, ahbp, avbp, bpcr;
603 enum ltdc_pix_fmt pf;
604
605 if (!state->crtc || !fb) {
606 DRM_DEBUG_DRIVER("fb or crtc NULL");
607 return;
608 }
609
610 /* convert src_ from 16:16 format */
611 src_x = state->src_x >> 16;
612 src_y = state->src_y >> 16;
613 src_w = state->src_w >> 16;
614 src_h = state->src_h >> 16;
615
616 DRM_DEBUG_DRIVER(
617 "plane:%d fb:%d (%dx%d)@(%d,%d) -> (%dx%d)@(%d,%d)\n",
618 plane->base.id, fb->base.id,
619 src_w, src_h, src_x, src_y,
620 state->crtc_w, state->crtc_h, state->crtc_x, state->crtc_y);
621
622 bpcr = reg_read(ldev->regs, LTDC_BPCR);
623 ahbp = (bpcr & BPCR_AHBP) >> 16;
624 avbp = bpcr & BPCR_AVBP;
625
626 /* Configures the horizontal start and stop position */
627 val = ((x1 + 1 + ahbp) << 16) + (x0 + 1 + ahbp);
628 reg_update_bits(ldev->regs, LTDC_L1WHPCR + lofs,
629 LXWHPCR_WHSTPOS | LXWHPCR_WHSPPOS, val);
630
631 /* Configures the vertical start and stop position */
632 val = ((y1 + 1 + avbp) << 16) + (y0 + 1 + avbp);
633 reg_update_bits(ldev->regs, LTDC_L1WVPCR + lofs,
634 LXWVPCR_WVSTPOS | LXWVPCR_WVSPPOS, val);
635
636 /* Specifies the pixel format */
637 pf = to_ltdc_pixelformat(fb->format->format);
638 for (val = 0; val < NB_PF; val++)
639 if (ldev->caps.pix_fmt_hw[val] == pf)
640 break;
641
642 if (val == NB_PF) {
643 DRM_ERROR("Pixel format %.4s not supported\n",
644 (char *)&fb->format->format);
645 val = 0; /* set by default ARGB 32 bits */
646 }
647 reg_update_bits(ldev->regs, LTDC_L1PFCR + lofs, LXPFCR_PF, val);
648
649 /* Configures the color frame buffer pitch in bytes & line length */
650 pitch_in_bytes = fb->pitches[0];
651 line_length = drm_format_plane_cpp(fb->format->format, 0) *
652 (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
653 val = ((pitch_in_bytes << 16) | line_length);
654 reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
655 LXCFBLR_CFBLL | LXCFBLR_CFBP, val);
656
657 /* Specifies the constant alpha value */
658 val = CONSTA_MAX;
659 reg_update_bits(ldev->regs, LTDC_L1CACR + lofs,
660 LXCACR_CONSTA, val);
661
662 /* Specifies the blending factors */
663 val = BF1_PAXCA | BF2_1PAXCA;
664 reg_update_bits(ldev->regs, LTDC_L1BFCR + lofs,
665 LXBFCR_BF2 | LXBFCR_BF1, val);
666
667 /* Configures the frame buffer line number */
668 val = y1 - y0 + 1;
669 reg_update_bits(ldev->regs, LTDC_L1CFBLNR + lofs,
670 LXCFBLNR_CFBLN, val);
671
672 /* Sets the FB address */
673 paddr = (u32)drm_fb_cma_get_gem_addr(fb, state, 0);
674
675 DRM_DEBUG_DRIVER("fb: phys 0x%08x", paddr);
676 reg_write(ldev->regs, LTDC_L1CFBAR + lofs, paddr);
677
678 /* Enable layer and CLUT if needed */
679 val = fb->format->format == DRM_FORMAT_C8 ? LXCR_CLUTEN : 0;
680 val |= LXCR_LEN;
681 reg_update_bits(ldev->regs, LTDC_L1CR + lofs,
682 LXCR_LEN | LXCR_CLUTEN, val);
683
684 mutex_lock(&ldev->err_lock);
685 if (ldev->error_status & ISR_FUIF) {
686 DRM_DEBUG_DRIVER("Fifo underrun\n");
687 ldev->error_status &= ~ISR_FUIF;
688 }
689 if (ldev->error_status & ISR_TERRIF) {
690 DRM_DEBUG_DRIVER("Transfer error\n");
691 ldev->error_status &= ~ISR_TERRIF;
692 }
693 mutex_unlock(&ldev->err_lock);
694}
695
696static void ltdc_plane_atomic_disable(struct drm_plane *plane,
697 struct drm_plane_state *oldstate)
698{
699 struct ltdc_device *ldev = plane_to_ltdc(plane);
700 u32 lofs = plane->index * LAY_OFS;
701
702 /* disable layer */
703 reg_clear(ldev->regs, LTDC_L1CR + lofs, LXCR_LEN);
704
705 DRM_DEBUG_DRIVER("CRTC:%d plane:%d\n",
706 oldstate->crtc->base.id, plane->base.id);
707}
708
709static struct drm_plane_funcs ltdc_plane_funcs = {
710 .update_plane = drm_atomic_helper_update_plane,
711 .disable_plane = drm_atomic_helper_disable_plane,
712 .destroy = drm_plane_cleanup,
713 .set_property = drm_atomic_helper_plane_set_property,
714 .reset = drm_atomic_helper_plane_reset,
715 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
716 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
717};
718
719static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
720 .atomic_check = ltdc_plane_atomic_check,
721 .atomic_update = ltdc_plane_atomic_update,
722 .atomic_disable = ltdc_plane_atomic_disable,
723};
724
725static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
726 enum drm_plane_type type)
727{
728 unsigned long possible_crtcs = CRTC_MASK;
729 struct ltdc_device *ldev = ddev->dev_private;
730 struct device *dev = ddev->dev;
731 struct drm_plane *plane;
732 unsigned int i, nb_fmt = 0;
733 u32 formats[NB_PF];
734 u32 drm_fmt;
735 int ret;
736
737 /* Get supported pixel formats */
738 for (i = 0; i < NB_PF; i++) {
739 drm_fmt = to_drm_pixelformat(ldev->caps.pix_fmt_hw[i]);
740 if (!drm_fmt)
741 continue;
742 formats[nb_fmt++] = drm_fmt;
743 }
744
745 plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
746 if (!plane)
747 return 0;
748
749 ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
750 &ltdc_plane_funcs, formats, nb_fmt,
751 type, NULL);
752 if (ret < 0)
753 return 0;
754
755 drm_plane_helper_add(plane, &ltdc_plane_helper_funcs);
756
757 DRM_DEBUG_DRIVER("plane:%d created\n", plane->base.id);
758
759 return plane;
760}
761
762static void ltdc_plane_destroy_all(struct drm_device *ddev)
763{
764 struct drm_plane *plane, *plane_temp;
765
766 list_for_each_entry_safe(plane, plane_temp,
767 &ddev->mode_config.plane_list, head)
768 drm_plane_cleanup(plane);
769}
770
771static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
772{
773 struct ltdc_device *ldev = ddev->dev_private;
774 struct drm_plane *primary, *overlay;
775 unsigned int i;
776 int res;
777
778 primary = ltdc_plane_create(ddev, DRM_PLANE_TYPE_PRIMARY);
779 if (!primary) {
780 DRM_ERROR("Can not create primary plane\n");
781 return -EINVAL;
782 }
783
784 res = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
785 &ltdc_crtc_funcs, NULL);
786 if (res) {
787 DRM_ERROR("Can not initialize CRTC\n");
788 goto cleanup;
789 }
790
791 drm_crtc_helper_add(crtc, &ltdc_crtc_helper_funcs);
792
793 DRM_DEBUG_DRIVER("CRTC:%d created\n", crtc->base.id);
794
795 /* Add planes. Note : the first layer is used by primary plane */
796 for (i = 1; i < ldev->caps.nb_layers; i++) {
797 overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY);
798 if (!overlay) {
799 res = -ENOMEM;
800 DRM_ERROR("Can not create overlay plane %d\n", i);
801 goto cleanup;
802 }
803 }
804
805 return 0;
806
807cleanup:
808 ltdc_plane_destroy_all(ddev);
809 return res;
810}
811
812/*
813 * DRM_ENCODER
814 */
815
816static void ltdc_rgb_encoder_enable(struct drm_encoder *encoder)
817{
818 struct ltdc_device *ldev = encoder_to_ltdc(encoder);
819
820 DRM_DEBUG_DRIVER("\n");
821
822 drm_panel_prepare(ldev->panel);
823 drm_panel_enable(ldev->panel);
824}
825
826static void ltdc_rgb_encoder_disable(struct drm_encoder *encoder)
827{
828 struct ltdc_device *ldev = encoder_to_ltdc(encoder);
829
830 DRM_DEBUG_DRIVER("\n");
831
832 drm_panel_disable(ldev->panel);
833 drm_panel_unprepare(ldev->panel);
834}
835
836static const struct drm_encoder_helper_funcs ltdc_rgb_encoder_helper_funcs = {
837 .enable = ltdc_rgb_encoder_enable,
838 .disable = ltdc_rgb_encoder_disable,
839};
840
841static const struct drm_encoder_funcs ltdc_rgb_encoder_funcs = {
842 .destroy = drm_encoder_cleanup,
843};
844
845static struct drm_encoder *ltdc_rgb_encoder_create(struct drm_device *ddev)
846{
847 struct drm_encoder *encoder;
848
849 encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
850 if (!encoder)
851 return NULL;
852
853 encoder->possible_crtcs = CRTC_MASK;
854 encoder->possible_clones = 0; /* No cloning support */
855
856 drm_encoder_init(ddev, encoder, &ltdc_rgb_encoder_funcs,
857 DRM_MODE_ENCODER_DPI, NULL);
858
859 drm_encoder_helper_add(encoder, &ltdc_rgb_encoder_helper_funcs);
860
861 DRM_DEBUG_DRIVER("RGB encoder:%d created\n", encoder->base.id);
862
863 return encoder;
864}
865
866/*
867 * DRM_CONNECTOR
868 */
869
870static int ltdc_rgb_connector_get_modes(struct drm_connector *connector)
871{
872 struct drm_device *ddev = connector->dev;
873 struct ltdc_device *ldev = ddev->dev_private;
874 int ret = 0;
875
876 DRM_DEBUG_DRIVER("\n");
877
878 if (ldev->panel)
879 ret = drm_panel_get_modes(ldev->panel);
880
881 return ret < 0 ? 0 : ret;
882}
883
884static struct drm_connector_helper_funcs ltdc_rgb_connector_helper_funcs = {
885 .get_modes = ltdc_rgb_connector_get_modes,
886};
887
888static enum drm_connector_status
889ltdc_rgb_connector_detect(struct drm_connector *connector, bool force)
890{
891 struct ltdc_device *ldev = connector_to_ltdc(connector);
892
893 return ldev->panel ? connector_status_connected :
894 connector_status_disconnected;
895}
896
897static void ltdc_rgb_connector_destroy(struct drm_connector *connector)
898{
899 DRM_DEBUG_DRIVER("\n");
900
901 drm_connector_unregister(connector);
902 drm_connector_cleanup(connector);
903}
904
905static const struct drm_connector_funcs ltdc_rgb_connector_funcs = {
906 .dpms = drm_atomic_helper_connector_dpms,
907 .fill_modes = drm_helper_probe_single_connector_modes,
908 .detect = ltdc_rgb_connector_detect,
909 .destroy = ltdc_rgb_connector_destroy,
910 .reset = drm_atomic_helper_connector_reset,
911 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
912 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
913};
914
915struct drm_connector *ltdc_rgb_connector_create(struct drm_device *ddev)
916{
917 struct drm_connector *connector;
918 int err;
919
920 connector = devm_kzalloc(ddev->dev, sizeof(*connector), GFP_KERNEL);
921 if (!connector) {
922 DRM_ERROR("Failed to allocate connector\n");
923 return NULL;
924 }
925
926 connector->polled = DRM_CONNECTOR_POLL_HPD;
927
928 err = drm_connector_init(ddev, connector, &ltdc_rgb_connector_funcs,
929 DRM_MODE_CONNECTOR_DPI);
930 if (err) {
931 DRM_ERROR("Failed to initialize connector\n");
932 return NULL;
933 }
934
935 drm_connector_helper_add(connector, &ltdc_rgb_connector_helper_funcs);
936
937 DRM_DEBUG_DRIVER("RGB connector:%d created\n", connector->base.id);
938
939 return connector;
940}
941
942static int ltdc_get_caps(struct drm_device *ddev)
943{
944 struct ltdc_device *ldev = ddev->dev_private;
945 u32 bus_width_log2, lcr, gc2r;
946
947 /* at least 1 layer must be managed */
948 lcr = reg_read(ldev->regs, LTDC_LCR);
949
950 ldev->caps.nb_layers = max_t(int, lcr, 1);
951
952 /* set data bus width */
953 gc2r = reg_read(ldev->regs, LTDC_GC2R);
954 bus_width_log2 = (gc2r & GC2R_BW) >> 4;
955 ldev->caps.bus_width = 8 << bus_width_log2;
956 ldev->caps.hw_version = reg_read(ldev->regs, LTDC_IDR);
957
958 switch (ldev->caps.hw_version) {
959 case HWVER_10200:
960 case HWVER_10300:
961 ldev->caps.reg_ofs = REG_OFS_NONE;
962 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a0;
963 break;
964 case HWVER_20101:
965 ldev->caps.reg_ofs = REG_OFS_4;
966 ldev->caps.pix_fmt_hw = ltdc_pix_fmt_a1;
967 break;
968 default:
969 return -ENODEV;
970 }
971
972 return 0;
973}
974
975static struct drm_panel *ltdc_get_panel(struct drm_device *ddev)
976{
977 struct device *dev = ddev->dev;
978 struct device_node *np = dev->of_node;
979 struct device_node *entity, *port = NULL;
980 struct drm_panel *panel = NULL;
981
982 DRM_DEBUG_DRIVER("\n");
983
984 /*
985 * Parse ltdc node to get remote port and find RGB panel / HDMI slave
986 * If a dsi or a bridge (hdmi, lvds...) is connected to ltdc,
987 * a remote port & RGB panel will not be found.
988 */
989 for_each_endpoint_of_node(np, entity) {
990 if (!of_device_is_available(entity))
991 continue;
992
993 port = of_graph_get_remote_port_parent(entity);
994 if (port) {
995 panel = of_drm_find_panel(port);
996 of_node_put(port);
997 if (panel) {
998 DRM_DEBUG_DRIVER("remote panel %s\n",
999 port->full_name);
1000 } else {
1001 DRM_DEBUG_DRIVER("panel missing\n");
1002 of_node_put(entity);
1003 }
1004 }
1005 }
1006
1007 return panel;
1008}
1009
1010int ltdc_load(struct drm_device *ddev)
1011{
1012 struct platform_device *pdev = to_platform_device(ddev->dev);
1013 struct ltdc_device *ldev = ddev->dev_private;
1014 struct device *dev = ddev->dev;
1015 struct device_node *np = dev->of_node;
1016 struct drm_encoder *encoder;
1017 struct drm_connector *connector = NULL;
1018 struct drm_crtc *crtc;
1019 struct reset_control *rstc;
1020 struct resource res;
1021 int irq, ret, i;
1022
1023 DRM_DEBUG_DRIVER("\n");
1024
1025 ldev->panel = ltdc_get_panel(ddev);
1026 if (!ldev->panel)
1027 return -EPROBE_DEFER;
1028
1029 rstc = of_reset_control_get(np, NULL);
1030
1031 mutex_init(&ldev->err_lock);
1032
1033 ldev->pixel_clk = devm_clk_get(dev, "lcd");
1034 if (IS_ERR(ldev->pixel_clk)) {
1035 DRM_ERROR("Unable to get lcd clock\n");
1036 return -ENODEV;
1037 }
1038
1039 if (clk_prepare_enable(ldev->pixel_clk)) {
1040 DRM_ERROR("Unable to prepare pixel clock\n");
1041 return -ENODEV;
1042 }
1043
1044 if (of_address_to_resource(np, 0, &res)) {
1045 DRM_ERROR("Unable to get resource\n");
1046 return -ENODEV;
1047 }
1048
1049 ldev->regs = devm_ioremap_resource(dev, &res);
1050 if (IS_ERR(ldev->regs)) {
1051 DRM_ERROR("Unable to get ltdc registers\n");
1052 return PTR_ERR(ldev->regs);
1053 }
1054
1055 for (i = 0; i < MAX_IRQ; i++) {
1056 irq = platform_get_irq(pdev, i);
1057 if (irq < 0)
1058 continue;
1059
1060 ret = devm_request_threaded_irq(dev, irq, ltdc_irq,
1061 ltdc_irq_thread, IRQF_ONESHOT,
1062 dev_name(dev), ddev);
1063 if (ret) {
1064 DRM_ERROR("Failed to register LTDC interrupt\n");
1065 return ret;
1066 }
1067 }
1068
1069 if (!IS_ERR(rstc))
1070 reset_control_deassert(rstc);
1071
1072 /* Disable interrupts */
1073 reg_clear(ldev->regs, LTDC_IER,
1074 IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
1075
1076 ret = ltdc_get_caps(ddev);
1077 if (ret) {
1078 DRM_ERROR("hardware identifier (0x%08x) not supported!\n",
1079 ldev->caps.hw_version);
1080 return ret;
1081 }
1082
1083 DRM_INFO("ltdc hw version 0x%08x - ready\n", ldev->caps.hw_version);
1084
1085 if (ldev->panel) {
1086 encoder = ltdc_rgb_encoder_create(ddev);
1087 if (!encoder) {
1088 DRM_ERROR("Failed to create RGB encoder\n");
1089 ret = -EINVAL;
1090 goto err;
1091 }
1092
1093 connector = ltdc_rgb_connector_create(ddev);
1094 if (!connector) {
1095 DRM_ERROR("Failed to create RGB connector\n");
1096 ret = -EINVAL;
1097 goto err;
1098 }
1099
1100 ret = drm_mode_connector_attach_encoder(connector, encoder);
1101 if (ret) {
1102 DRM_ERROR("Failed to attach connector to encoder\n");
1103 goto err;
1104 }
1105
1106 drm_panel_attach(ldev->panel, connector);
1107 }
1108
1109 crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
1110 if (!crtc) {
1111 DRM_ERROR("Failed to allocate crtc\n");
1112 ret = -ENOMEM;
1113 goto err;
1114 }
1115
1116 ret = ltdc_crtc_init(ddev, crtc);
1117 if (ret) {
1118 DRM_ERROR("Failed to init crtc\n");
1119 goto err;
1120 }
1121
1122 ret = drm_vblank_init(ddev, NB_CRTC);
1123 if (ret) {
1124 DRM_ERROR("Failed calling drm_vblank_init()\n");
1125 goto err;
1126 }
1127
1128 /* Allow usage of vblank without having to call drm_irq_install */
1129 ddev->irq_enabled = 1;
1130
1131 return 0;
1132err:
1133 if (ldev->panel)
1134 drm_panel_detach(ldev->panel);
1135
1136 clk_disable_unprepare(ldev->pixel_clk);
1137
1138 return ret;
1139}
1140
1141void ltdc_unload(struct drm_device *ddev)
1142{
1143 struct ltdc_device *ldev = ddev->dev_private;
1144
1145 DRM_DEBUG_DRIVER("\n");
1146
1147 drm_vblank_cleanup(ddev);
1148
1149 if (ldev->panel)
1150 drm_panel_detach(ldev->panel);
1151
1152 clk_disable_unprepare(ldev->pixel_clk);
1153}
1154
1155MODULE_AUTHOR("Philippe Cornu <philippe.cornu@st.com>");
1156MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
1157MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
1158MODULE_AUTHOR("Mickael Reulier <mickael.reulier@st.com>");
1159MODULE_DESCRIPTION("STMicroelectronics ST DRM LTDC driver");
1160MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h
new file mode 100644
index 000000000000..d7a9c736ac1e
--- /dev/null
+++ b/drivers/gpu/drm/stm/ltdc.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2017
3 *
4 * Authors: Philippe Cornu <philippe.cornu@st.com>
5 * Yannick Fertre <yannick.fertre@st.com>
6 * Fabien Dessenne <fabien.dessenne@st.com>
7 * Mickael Reulier <mickael.reulier@st.com>
8 *
9 * License terms: GNU General Public License (GPL), version 2
10 */
11
12#ifndef _LTDC_H_
13#define _LTDC_H_
14
15struct ltdc_caps {
16 u32 hw_version; /* hardware version */
17 u32 nb_layers; /* number of supported layers */
18 u32 reg_ofs; /* register offset for applicable regs */
19 u32 bus_width; /* bus width (32 or 64 bits) */
20 const u32 *pix_fmt_hw; /* supported pixel formats */
21};
22
23struct ltdc_device {
24 struct drm_fbdev_cma *fbdev;
25 void __iomem *regs;
26 struct clk *pixel_clk; /* lcd pixel clock */
27 struct drm_panel *panel;
28 struct mutex err_lock; /* protecting error_status */
29 struct ltdc_caps caps;
30 u32 clut[256]; /* color look up table */
31 u32 error_status;
32 u32 irq_status;
33};
34
35int ltdc_crtc_enable_vblank(struct drm_device *dev, unsigned int pipe);
36void ltdc_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe);
37int ltdc_load(struct drm_device *ddev);
38void ltdc_unload(struct drm_device *ddev);
39
40#endif
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 9a1e34e48f64..51c48a8e00ec 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -892,7 +892,7 @@ static int tegra_drm_context_cleanup(int id, void *p, void *data)
892 return 0; 892 return 0;
893} 893}
894 894
895static void tegra_drm_preclose(struct drm_device *drm, struct drm_file *file) 895static void tegra_drm_postclose(struct drm_device *drm, struct drm_file *file)
896{ 896{
897 struct tegra_drm_file *fpriv = file->driver_priv; 897 struct tegra_drm_file *fpriv = file->driver_priv;
898 898
@@ -960,7 +960,7 @@ static struct drm_driver tegra_drm_driver = {
960 .load = tegra_drm_load, 960 .load = tegra_drm_load,
961 .unload = tegra_drm_unload, 961 .unload = tegra_drm_unload,
962 .open = tegra_drm_open, 962 .open = tegra_drm_open,
963 .preclose = tegra_drm_preclose, 963 .postclose = tegra_drm_postclose,
964 .lastclose = tegra_drm_lastclose, 964 .lastclose = tegra_drm_lastclose,
965 965
966#if defined(CONFIG_DEBUG_FS) 966#if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
index 61f45d122bd0..ab687fba4916 100644
--- a/drivers/gpu/drm/vc4/Makefile
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -9,6 +9,7 @@ vc4-y := \
9 vc4_drv.o \ 9 vc4_drv.o \
10 vc4_dpi.o \ 10 vc4_dpi.o \
11 vc4_dsi.o \ 11 vc4_dsi.o \
12 vc4_fence.o \
12 vc4_kms.o \ 13 vc4_kms.o \
13 vc4_gem.o \ 14 vc4_gem.o \
14 vc4_hdmi.o \ 15 vc4_hdmi.o \
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index af29432a6471..80b2f9e55c5c 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -19,6 +19,8 @@
19 * rendering can return quickly. 19 * rendering can return quickly.
20 */ 20 */
21 21
22#include <linux/dma-buf.h>
23
22#include "vc4_drv.h" 24#include "vc4_drv.h"
23#include "uapi/drm/vc4_drm.h" 25#include "uapi/drm/vc4_drm.h"
24 26
@@ -88,6 +90,10 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
88 90
89 vc4->bo_stats.num_allocated--; 91 vc4->bo_stats.num_allocated--;
90 vc4->bo_stats.size_allocated -= obj->size; 92 vc4->bo_stats.size_allocated -= obj->size;
93
94 if (bo->resv == &bo->_resv)
95 reservation_object_fini(bo->resv);
96
91 drm_gem_cma_free_object(obj); 97 drm_gem_cma_free_object(obj);
92} 98}
93 99
@@ -244,8 +250,12 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
244 return ERR_PTR(-ENOMEM); 250 return ERR_PTR(-ENOMEM);
245 } 251 }
246 } 252 }
253 bo = to_vc4_bo(&cma_obj->base);
247 254
248 return to_vc4_bo(&cma_obj->base); 255 bo->resv = &bo->_resv;
256 reservation_object_init(bo->resv);
257
258 return bo;
249} 259}
250 260
251int vc4_dumb_create(struct drm_file *file_priv, 261int vc4_dumb_create(struct drm_file *file_priv,
@@ -369,6 +379,13 @@ static void vc4_bo_cache_time_timer(unsigned long data)
369 schedule_work(&vc4->bo_cache.time_work); 379 schedule_work(&vc4->bo_cache.time_work);
370} 380}
371 381
382struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj)
383{
384 struct vc4_bo *bo = to_vc4_bo(obj);
385
386 return bo->resv;
387}
388
372struct dma_buf * 389struct dma_buf *
373vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) 390vc4_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags)
374{ 391{
@@ -440,6 +457,24 @@ void *vc4_prime_vmap(struct drm_gem_object *obj)
440 return drm_gem_cma_prime_vmap(obj); 457 return drm_gem_cma_prime_vmap(obj);
441} 458}
442 459
460struct drm_gem_object *
461vc4_prime_import_sg_table(struct drm_device *dev,
462 struct dma_buf_attachment *attach,
463 struct sg_table *sgt)
464{
465 struct drm_gem_object *obj;
466 struct vc4_bo *bo;
467
468 obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
469 if (IS_ERR(obj))
470 return obj;
471
472 bo = to_vc4_bo(obj);
473 bo->resv = attach->dmabuf->resv;
474
475 return obj;
476}
477
443int vc4_create_bo_ioctl(struct drm_device *dev, void *data, 478int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
444 struct drm_file *file_priv) 479 struct drm_file *file_priv)
445{ 480{
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index d86c8cce3182..1b4dbe9e1c6d 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -151,10 +151,10 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
151} 151}
152#endif 152#endif
153 153
154int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, 154bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
155 unsigned int flags, int *vpos, int *hpos, 155 bool in_vblank_irq, int *vpos, int *hpos,
156 ktime_t *stime, ktime_t *etime, 156 ktime_t *stime, ktime_t *etime,
157 const struct drm_display_mode *mode) 157 const struct drm_display_mode *mode)
158{ 158{
159 struct vc4_dev *vc4 = to_vc4_dev(dev); 159 struct vc4_dev *vc4 = to_vc4_dev(dev);
160 struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id); 160 struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id);
@@ -162,7 +162,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
162 u32 val; 162 u32 val;
163 int fifo_lines; 163 int fifo_lines;
164 int vblank_lines; 164 int vblank_lines;
165 int ret = 0; 165 bool ret = false;
166 166
167 /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ 167 /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
168 168
@@ -198,7 +198,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
198 fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; 198 fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay;
199 199
200 if (fifo_lines > 0) 200 if (fifo_lines > 0)
201 ret |= DRM_SCANOUTPOS_VALID; 201 ret = true;
202 202
203 /* HVS more than fifo_lines into frame for compositing? */ 203 /* HVS more than fifo_lines into frame for compositing? */
204 if (*vpos > fifo_lines) { 204 if (*vpos > fifo_lines) {
@@ -216,7 +216,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
216 */ 216 */
217 *vpos -= fifo_lines + 1; 217 *vpos -= fifo_lines + 1;
218 218
219 ret |= DRM_SCANOUTPOS_ACCURATE;
220 return ret; 219 return ret;
221 } 220 }
222 221
@@ -229,10 +228,9 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
229 * We can't get meaningful readings wrt. scanline position of the PV 228 * We can't get meaningful readings wrt. scanline position of the PV
230 * and need to make things up in a approximative but consistent way. 229 * and need to make things up in a approximative but consistent way.
231 */ 230 */
232 ret |= DRM_SCANOUTPOS_IN_VBLANK;
233 vblank_lines = mode->vtotal - mode->vdisplay; 231 vblank_lines = mode->vtotal - mode->vdisplay;
234 232
235 if (flags & DRM_CALLED_FROM_VBLIRQ) { 233 if (in_vblank_irq) {
236 /* 234 /*
237 * Assume the irq handler got called close to first 235 * Assume the irq handler got called close to first
238 * line of vblank, so PV has about a full vblank 236 * line of vblank, so PV has about a full vblank
@@ -254,9 +252,10 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
254 * we are at the very beginning of vblank, as the hvs just 252 * we are at the very beginning of vblank, as the hvs just
255 * started refilling, and the stime and etime timestamps 253 * started refilling, and the stime and etime timestamps
256 * truly correspond to start of vblank. 254 * truly correspond to start of vblank.
255 *
256 * Unfortunately there's no way to report this to upper levels
257 * and make it more useful.
257 */ 258 */
258 if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL)
259 ret |= DRM_SCANOUTPOS_ACCURATE;
260 } else { 259 } else {
261 /* 260 /*
262 * No clue where we are inside vblank. Return a vpos of zero, 261 * No clue where we are inside vblank. Return a vpos of zero,
@@ -270,19 +269,6 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
270 return ret; 269 return ret;
271} 270}
272 271
273int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id,
274 int *max_error, struct timeval *vblank_time,
275 unsigned flags)
276{
277 struct drm_crtc *crtc = drm_crtc_from_index(dev, crtc_id);
278 struct drm_crtc_state *state = crtc->state;
279
280 /* Helper routine in DRM core does all the work: */
281 return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error,
282 vblank_time, flags,
283 &state->adjusted_mode);
284}
285
286static void vc4_crtc_destroy(struct drm_crtc *crtc) 272static void vc4_crtc_destroy(struct drm_crtc *crtc)
287{ 273{
288 drm_crtc_cleanup(crtc); 274 drm_crtc_cleanup(crtc);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 61e674baf3a6..863974942c66 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -154,7 +154,7 @@ static struct drm_driver vc4_drm_driver = {
154 .irq_uninstall = vc4_irq_uninstall, 154 .irq_uninstall = vc4_irq_uninstall,
155 155
156 .get_scanout_position = vc4_crtc_get_scanoutpos, 156 .get_scanout_position = vc4_crtc_get_scanoutpos,
157 .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, 157 .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos,
158 158
159#if defined(CONFIG_DEBUG_FS) 159#if defined(CONFIG_DEBUG_FS)
160 .debugfs_init = vc4_debugfs_init, 160 .debugfs_init = vc4_debugfs_init,
@@ -168,8 +168,9 @@ static struct drm_driver vc4_drm_driver = {
168 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 168 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
169 .gem_prime_import = drm_gem_prime_import, 169 .gem_prime_import = drm_gem_prime_import,
170 .gem_prime_export = vc4_prime_export, 170 .gem_prime_export = vc4_prime_export,
171 .gem_prime_res_obj = vc4_prime_res_obj,
171 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, 172 .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
172 .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, 173 .gem_prime_import_sg_table = vc4_prime_import_sg_table,
173 .gem_prime_vmap = vc4_prime_vmap, 174 .gem_prime_vmap = vc4_prime_vmap,
174 .gem_prime_vunmap = drm_gem_cma_prime_vunmap, 175 .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
175 .gem_prime_mmap = vc4_prime_mmap, 176 .gem_prime_mmap = vc4_prime_mmap,
@@ -334,6 +335,7 @@ static int vc4_platform_drm_remove(struct platform_device *pdev)
334 335
335static const struct of_device_id vc4_of_match[] = { 336static const struct of_device_id vc4_of_match[] = {
336 { .compatible = "brcm,bcm2835-vc4", }, 337 { .compatible = "brcm,bcm2835-vc4", },
338 { .compatible = "brcm,cygnus-vc4", },
337 {}, 339 {},
338}; 340};
339MODULE_DEVICE_TABLE(of, vc4_of_match); 341MODULE_DEVICE_TABLE(of, vc4_of_match);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index dffce6293d87..5ba281361fb7 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -8,7 +8,9 @@
8 8
9#include "drmP.h" 9#include "drmP.h"
10#include "drm_gem_cma_helper.h" 10#include "drm_gem_cma_helper.h"
11#include "drm_gem_cma_helper.h"
11 12
13#include <linux/reservation.h>
12#include <drm/drm_encoder.h> 14#include <drm/drm_encoder.h>
13 15
14struct vc4_dev { 16struct vc4_dev {
@@ -56,6 +58,8 @@ struct vc4_dev {
56 /* Protects bo_cache and the BO stats. */ 58 /* Protects bo_cache and the BO stats. */
57 struct mutex bo_lock; 59 struct mutex bo_lock;
58 60
61 uint64_t dma_fence_context;
62
59 /* Sequence number for the last job queued in bin_job_list. 63 /* Sequence number for the last job queued in bin_job_list.
60 * Starts at 0 (no jobs emitted). 64 * Starts at 0 (no jobs emitted).
61 */ 65 */
@@ -95,12 +99,23 @@ struct vc4_dev {
95 */ 99 */
96 struct list_head seqno_cb_list; 100 struct list_head seqno_cb_list;
97 101
98 /* The binner overflow memory that's currently set up in 102 /* The memory used for storing binner tile alloc, tile state,
99 * BPOA/BPOS registers. When overflow occurs and a new one is 103 * and overflow memory allocations. This is freed when V3D
100 * allocated, the previous one will be moved to 104 * powers down.
101 * vc4->current_exec's free list. 105 */
106 struct vc4_bo *bin_bo;
107
108 /* Size of blocks allocated within bin_bo. */
109 uint32_t bin_alloc_size;
110
111 /* Bitmask of the bin_alloc_size chunks in bin_bo that are
112 * used.
102 */ 113 */
103 struct vc4_bo *overflow_mem; 114 uint32_t bin_alloc_used;
115
116 /* Bitmask of the current bin_alloc used for overflow memory. */
117 uint32_t bin_alloc_overflow;
118
104 struct work_struct overflow_mem_work; 119 struct work_struct overflow_mem_work;
105 120
106 int power_refcount; 121 int power_refcount;
@@ -150,6 +165,10 @@ struct vc4_bo {
150 * DRM_IOCTL_VC4_CREATE_SHADER_BO. 165 * DRM_IOCTL_VC4_CREATE_SHADER_BO.
151 */ 166 */
152 struct vc4_validated_shader_info *validated_shader; 167 struct vc4_validated_shader_info *validated_shader;
168
169 /* normally (resv == &_resv) except for imported bo's */
170 struct reservation_object *resv;
171 struct reservation_object _resv;
153}; 172};
154 173
155static inline struct vc4_bo * 174static inline struct vc4_bo *
@@ -158,6 +177,19 @@ to_vc4_bo(struct drm_gem_object *bo)
158 return (struct vc4_bo *)bo; 177 return (struct vc4_bo *)bo;
159} 178}
160 179
180struct vc4_fence {
181 struct dma_fence base;
182 struct drm_device *dev;
183 /* vc4 seqno for signaled() test */
184 uint64_t seqno;
185};
186
187static inline struct vc4_fence *
188to_vc4_fence(struct dma_fence *fence)
189{
190 return (struct vc4_fence *)fence;
191}
192
161struct vc4_seqno_cb { 193struct vc4_seqno_cb {
162 struct work_struct work; 194 struct work_struct work;
163 uint64_t seqno; 195 uint64_t seqno;
@@ -168,6 +200,7 @@ struct vc4_v3d {
168 struct vc4_dev *vc4; 200 struct vc4_dev *vc4;
169 struct platform_device *pdev; 201 struct platform_device *pdev;
170 void __iomem *regs; 202 void __iomem *regs;
203 struct clk *clk;
171}; 204};
172 205
173struct vc4_hvs { 206struct vc4_hvs {
@@ -230,6 +263,8 @@ struct vc4_exec_info {
230 /* Latest write_seqno of any BO that binning depends on. */ 263 /* Latest write_seqno of any BO that binning depends on. */
231 uint64_t bin_dep_seqno; 264 uint64_t bin_dep_seqno;
232 265
266 struct dma_fence *fence;
267
233 /* Last current addresses the hardware was processing when the 268 /* Last current addresses the hardware was processing when the
234 * hangcheck timer checked on us. 269 * hangcheck timer checked on us.
235 */ 270 */
@@ -293,8 +328,12 @@ struct vc4_exec_info {
293 bool found_increment_semaphore_packet; 328 bool found_increment_semaphore_packet;
294 bool found_flush; 329 bool found_flush;
295 uint8_t bin_tiles_x, bin_tiles_y; 330 uint8_t bin_tiles_x, bin_tiles_y;
296 struct drm_gem_cma_object *tile_bo; 331 /* Physical address of the start of the tile alloc array
332 * (where each tile's binned CL will start)
333 */
297 uint32_t tile_alloc_offset; 334 uint32_t tile_alloc_offset;
335 /* Bitmask of which binner slots are freed when this job completes. */
336 uint32_t bin_slots;
298 337
299 /** 338 /**
300 * Computed addresses pointing into exec_bo where we start the 339 * Computed addresses pointing into exec_bo where we start the
@@ -436,7 +475,11 @@ int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
436int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, 475int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
437 struct drm_file *file_priv); 476 struct drm_file *file_priv);
438int vc4_mmap(struct file *filp, struct vm_area_struct *vma); 477int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
478struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj);
439int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 479int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
480struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev,
481 struct dma_buf_attachment *attach,
482 struct sg_table *sgt);
440void *vc4_prime_vmap(struct drm_gem_object *obj); 483void *vc4_prime_vmap(struct drm_gem_object *obj);
441void vc4_bo_cache_init(struct drm_device *dev); 484void vc4_bo_cache_init(struct drm_device *dev);
442void vc4_bo_cache_destroy(struct drm_device *dev); 485void vc4_bo_cache_destroy(struct drm_device *dev);
@@ -446,13 +489,10 @@ int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
446extern struct platform_driver vc4_crtc_driver; 489extern struct platform_driver vc4_crtc_driver;
447bool vc4_event_pending(struct drm_crtc *crtc); 490bool vc4_event_pending(struct drm_crtc *crtc);
448int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); 491int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
449int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, 492bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
450 unsigned int flags, int *vpos, int *hpos, 493 bool in_vblank_irq, int *vpos, int *hpos,
451 ktime_t *stime, ktime_t *etime, 494 ktime_t *stime, ktime_t *etime,
452 const struct drm_display_mode *mode); 495 const struct drm_display_mode *mode);
453int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id,
454 int *max_error, struct timeval *vblank_time,
455 unsigned flags);
456 496
457/* vc4_debugfs.c */ 497/* vc4_debugfs.c */
458int vc4_debugfs_init(struct drm_minor *minor); 498int vc4_debugfs_init(struct drm_minor *minor);
@@ -468,6 +508,9 @@ int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused);
468extern struct platform_driver vc4_dsi_driver; 508extern struct platform_driver vc4_dsi_driver;
469int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused); 509int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused);
470 510
511/* vc4_fence.c */
512extern const struct dma_fence_ops vc4_fence_ops;
513
471/* vc4_gem.c */ 514/* vc4_gem.c */
472void vc4_gem_init(struct drm_device *dev); 515void vc4_gem_init(struct drm_device *dev);
473void vc4_gem_destroy(struct drm_device *dev); 516void vc4_gem_destroy(struct drm_device *dev);
@@ -522,6 +565,7 @@ void vc4_plane_async_set_fb(struct drm_plane *plane,
522extern struct platform_driver vc4_v3d_driver; 565extern struct platform_driver vc4_v3d_driver;
523int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); 566int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused);
524int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); 567int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused);
568int vc4_v3d_get_bin_slot(struct vc4_dev *vc4);
525 569
526/* vc4_validate.c */ 570/* vc4_validate.c */
527int 571int
diff --git a/drivers/gpu/drm/vc4/vc4_fence.c b/drivers/gpu/drm/vc4/vc4_fence.c
new file mode 100644
index 000000000000..dbf5a5a5d5f5
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_fence.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright © 2017 Broadcom
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include "vc4_drv.h"
25
26static const char *vc4_fence_get_driver_name(struct dma_fence *fence)
27{
28 return "vc4";
29}
30
31static const char *vc4_fence_get_timeline_name(struct dma_fence *fence)
32{
33 return "vc4-v3d";
34}
35
36static bool vc4_fence_enable_signaling(struct dma_fence *fence)
37{
38 return true;
39}
40
41static bool vc4_fence_signaled(struct dma_fence *fence)
42{
43 struct vc4_fence *f = to_vc4_fence(fence);
44 struct vc4_dev *vc4 = to_vc4_dev(f->dev);
45
46 return vc4->finished_seqno >= f->seqno;
47}
48
49const struct dma_fence_ops vc4_fence_ops = {
50 .get_driver_name = vc4_fence_get_driver_name,
51 .get_timeline_name = vc4_fence_get_timeline_name,
52 .enable_signaling = vc4_fence_enable_signaling,
53 .signaled = vc4_fence_signaled,
54 .wait = dma_fence_default_wait,
55 .release = dma_fence_free,
56};
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index e9c381c42139..735412e3725a 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -463,6 +463,8 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
463 for (i = 0; i < exec->bo_count; i++) { 463 for (i = 0; i < exec->bo_count; i++) {
464 bo = to_vc4_bo(&exec->bo[i]->base); 464 bo = to_vc4_bo(&exec->bo[i]->base);
465 bo->seqno = seqno; 465 bo->seqno = seqno;
466
467 reservation_object_add_shared_fence(bo->resv, exec->fence);
466 } 468 }
467 469
468 list_for_each_entry(bo, &exec->unref_list, unref_head) { 470 list_for_each_entry(bo, &exec->unref_list, unref_head) {
@@ -472,7 +474,103 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
472 for (i = 0; i < exec->rcl_write_bo_count; i++) { 474 for (i = 0; i < exec->rcl_write_bo_count; i++) {
473 bo = to_vc4_bo(&exec->rcl_write_bo[i]->base); 475 bo = to_vc4_bo(&exec->rcl_write_bo[i]->base);
474 bo->write_seqno = seqno; 476 bo->write_seqno = seqno;
477
478 reservation_object_add_excl_fence(bo->resv, exec->fence);
479 }
480}
481
482static void
483vc4_unlock_bo_reservations(struct drm_device *dev,
484 struct vc4_exec_info *exec,
485 struct ww_acquire_ctx *acquire_ctx)
486{
487 int i;
488
489 for (i = 0; i < exec->bo_count; i++) {
490 struct vc4_bo *bo = to_vc4_bo(&exec->bo[i]->base);
491
492 ww_mutex_unlock(&bo->resv->lock);
493 }
494
495 ww_acquire_fini(acquire_ctx);
496}
497
498/* Takes the reservation lock on all the BOs being referenced, so that
499 * at queue submit time we can update the reservations.
500 *
501 * We don't lock the RCL the tile alloc/state BOs, or overflow memory
502 * (all of which are on exec->unref_list). They're entirely private
503 * to vc4, so we don't attach dma-buf fences to them.
504 */
505static int
506vc4_lock_bo_reservations(struct drm_device *dev,
507 struct vc4_exec_info *exec,
508 struct ww_acquire_ctx *acquire_ctx)
509{
510 int contended_lock = -1;
511 int i, ret;
512 struct vc4_bo *bo;
513
514 ww_acquire_init(acquire_ctx, &reservation_ww_class);
515
516retry:
517 if (contended_lock != -1) {
518 bo = to_vc4_bo(&exec->bo[contended_lock]->base);
519 ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
520 acquire_ctx);
521 if (ret) {
522 ww_acquire_done(acquire_ctx);
523 return ret;
524 }
525 }
526
527 for (i = 0; i < exec->bo_count; i++) {
528 if (i == contended_lock)
529 continue;
530
531 bo = to_vc4_bo(&exec->bo[i]->base);
532
533 ret = ww_mutex_lock_interruptible(&bo->resv->lock, acquire_ctx);
534 if (ret) {
535 int j;
536
537 for (j = 0; j < i; j++) {
538 bo = to_vc4_bo(&exec->bo[j]->base);
539 ww_mutex_unlock(&bo->resv->lock);
540 }
541
542 if (contended_lock != -1 && contended_lock >= i) {
543 bo = to_vc4_bo(&exec->bo[contended_lock]->base);
544
545 ww_mutex_unlock(&bo->resv->lock);
546 }
547
548 if (ret == -EDEADLK) {
549 contended_lock = i;
550 goto retry;
551 }
552
553 ww_acquire_done(acquire_ctx);
554 return ret;
555 }
475 } 556 }
557
558 ww_acquire_done(acquire_ctx);
559
560 /* Reserve space for our shared (read-only) fence references,
561 * before we commit the CL to the hardware.
562 */
563 for (i = 0; i < exec->bo_count; i++) {
564 bo = to_vc4_bo(&exec->bo[i]->base);
565
566 ret = reservation_object_reserve_shared(bo->resv);
567 if (ret) {
568 vc4_unlock_bo_reservations(dev, exec, acquire_ctx);
569 return ret;
570 }
571 }
572
573 return 0;
476} 574}
477 575
478/* Queues a struct vc4_exec_info for execution. If no job is 576/* Queues a struct vc4_exec_info for execution. If no job is
@@ -484,19 +582,34 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
484 * then bump the end address. That's a change for a later date, 582 * then bump the end address. That's a change for a later date,
485 * though. 583 * though.
486 */ 584 */
487static void 585static int
488vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec) 586vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
587 struct ww_acquire_ctx *acquire_ctx)
489{ 588{
490 struct vc4_dev *vc4 = to_vc4_dev(dev); 589 struct vc4_dev *vc4 = to_vc4_dev(dev);
491 uint64_t seqno; 590 uint64_t seqno;
492 unsigned long irqflags; 591 unsigned long irqflags;
592 struct vc4_fence *fence;
593
594 fence = kzalloc(sizeof(*fence), GFP_KERNEL);
595 if (!fence)
596 return -ENOMEM;
597 fence->dev = dev;
493 598
494 spin_lock_irqsave(&vc4->job_lock, irqflags); 599 spin_lock_irqsave(&vc4->job_lock, irqflags);
495 600
496 seqno = ++vc4->emit_seqno; 601 seqno = ++vc4->emit_seqno;
497 exec->seqno = seqno; 602 exec->seqno = seqno;
603
604 dma_fence_init(&fence->base, &vc4_fence_ops, &vc4->job_lock,
605 vc4->dma_fence_context, exec->seqno);
606 fence->seqno = exec->seqno;
607 exec->fence = &fence->base;
608
498 vc4_update_bo_seqnos(exec, seqno); 609 vc4_update_bo_seqnos(exec, seqno);
499 610
611 vc4_unlock_bo_reservations(dev, exec, acquire_ctx);
612
500 list_add_tail(&exec->head, &vc4->bin_job_list); 613 list_add_tail(&exec->head, &vc4->bin_job_list);
501 614
502 /* If no job was executing, kick ours off. Otherwise, it'll 615 /* If no job was executing, kick ours off. Otherwise, it'll
@@ -509,6 +622,8 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec)
509 } 622 }
510 623
511 spin_unlock_irqrestore(&vc4->job_lock, irqflags); 624 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
625
626 return 0;
512} 627}
513 628
514/** 629/**
@@ -705,8 +820,15 @@ static void
705vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) 820vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
706{ 821{
707 struct vc4_dev *vc4 = to_vc4_dev(dev); 822 struct vc4_dev *vc4 = to_vc4_dev(dev);
823 unsigned long irqflags;
708 unsigned i; 824 unsigned i;
709 825
826 /* If we got force-completed because of GPU reset rather than
827 * through our IRQ handler, signal the fence now.
828 */
829 if (exec->fence)
830 dma_fence_signal(exec->fence);
831
710 if (exec->bo) { 832 if (exec->bo) {
711 for (i = 0; i < exec->bo_count; i++) 833 for (i = 0; i < exec->bo_count; i++)
712 drm_gem_object_unreference_unlocked(&exec->bo[i]->base); 834 drm_gem_object_unreference_unlocked(&exec->bo[i]->base);
@@ -720,6 +842,11 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec)
720 drm_gem_object_unreference_unlocked(&bo->base.base); 842 drm_gem_object_unreference_unlocked(&bo->base.base);
721 } 843 }
722 844
845 /* Free up the allocation of any bin slots we used. */
846 spin_lock_irqsave(&vc4->job_lock, irqflags);
847 vc4->bin_alloc_used &= ~exec->bin_slots;
848 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
849
723 mutex_lock(&vc4->power_lock); 850 mutex_lock(&vc4->power_lock);
724 if (--vc4->power_refcount == 0) { 851 if (--vc4->power_refcount == 0) {
725 pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev); 852 pm_runtime_mark_last_busy(&vc4->v3d->pdev->dev);
@@ -874,6 +1001,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
874 struct vc4_dev *vc4 = to_vc4_dev(dev); 1001 struct vc4_dev *vc4 = to_vc4_dev(dev);
875 struct drm_vc4_submit_cl *args = data; 1002 struct drm_vc4_submit_cl *args = data;
876 struct vc4_exec_info *exec; 1003 struct vc4_exec_info *exec;
1004 struct ww_acquire_ctx acquire_ctx;
877 int ret = 0; 1005 int ret = 0;
878 1006
879 if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) { 1007 if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
@@ -888,13 +1016,16 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
888 } 1016 }
889 1017
890 mutex_lock(&vc4->power_lock); 1018 mutex_lock(&vc4->power_lock);
891 if (vc4->power_refcount++ == 0) 1019 if (vc4->power_refcount++ == 0) {
892 ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev); 1020 ret = pm_runtime_get_sync(&vc4->v3d->pdev->dev);
893 mutex_unlock(&vc4->power_lock); 1021 if (ret < 0) {
894 if (ret < 0) { 1022 mutex_unlock(&vc4->power_lock);
895 kfree(exec); 1023 vc4->power_refcount--;
896 return ret; 1024 kfree(exec);
1025 return ret;
1026 }
897 } 1027 }
1028 mutex_unlock(&vc4->power_lock);
898 1029
899 exec->args = args; 1030 exec->args = args;
900 INIT_LIST_HEAD(&exec->unref_list); 1031 INIT_LIST_HEAD(&exec->unref_list);
@@ -916,12 +1047,18 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
916 if (ret) 1047 if (ret)
917 goto fail; 1048 goto fail;
918 1049
1050 ret = vc4_lock_bo_reservations(dev, exec, &acquire_ctx);
1051 if (ret)
1052 goto fail;
1053
919 /* Clear this out of the struct we'll be putting in the queue, 1054 /* Clear this out of the struct we'll be putting in the queue,
920 * since it's part of our stack. 1055 * since it's part of our stack.
921 */ 1056 */
922 exec->args = NULL; 1057 exec->args = NULL;
923 1058
924 vc4_queue_submit(dev, exec); 1059 ret = vc4_queue_submit(dev, exec, &acquire_ctx);
1060 if (ret)
1061 goto fail;
925 1062
926 /* Return the seqno for our job. */ 1063 /* Return the seqno for our job. */
927 args->seqno = vc4->emit_seqno; 1064 args->seqno = vc4->emit_seqno;
@@ -939,6 +1076,8 @@ vc4_gem_init(struct drm_device *dev)
939{ 1076{
940 struct vc4_dev *vc4 = to_vc4_dev(dev); 1077 struct vc4_dev *vc4 = to_vc4_dev(dev);
941 1078
1079 vc4->dma_fence_context = dma_fence_context_alloc(1);
1080
942 INIT_LIST_HEAD(&vc4->bin_job_list); 1081 INIT_LIST_HEAD(&vc4->bin_job_list);
943 INIT_LIST_HEAD(&vc4->render_job_list); 1082 INIT_LIST_HEAD(&vc4->render_job_list);
944 INIT_LIST_HEAD(&vc4->job_done_list); 1083 INIT_LIST_HEAD(&vc4->job_done_list);
@@ -968,9 +1107,9 @@ vc4_gem_destroy(struct drm_device *dev)
968 /* V3D should already have disabled its interrupt and cleared 1107 /* V3D should already have disabled its interrupt and cleared
969 * the overflow allocation registers. Now free the object. 1108 * the overflow allocation registers. Now free the object.
970 */ 1109 */
971 if (vc4->overflow_mem) { 1110 if (vc4->bin_bo) {
972 drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base); 1111 drm_gem_object_put_unlocked(&vc4->bin_bo->base.base);
973 vc4->overflow_mem = NULL; 1112 vc4->bin_bo = NULL;
974 } 1113 }
975 1114
976 if (vc4->hang_state) 1115 if (vc4->hang_state)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index e9cbe269710b..3c2723f6345c 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -51,6 +51,7 @@
51#include "linux/of_address.h" 51#include "linux/of_address.h"
52#include "linux/of_gpio.h" 52#include "linux/of_gpio.h"
53#include "linux/of_platform.h" 53#include "linux/of_platform.h"
54#include "linux/pm_runtime.h"
54#include "linux/rational.h" 55#include "linux/rational.h"
55#include "sound/dmaengine_pcm.h" 56#include "sound/dmaengine_pcm.h"
56#include "sound/pcm_drm_eld.h" 57#include "sound/pcm_drm_eld.h"
@@ -449,13 +450,38 @@ static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
449 vc4_hdmi_set_spd_infoframe(encoder); 450 vc4_hdmi_set_spd_infoframe(encoder);
450} 451}
451 452
452static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder, 453static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
453 struct drm_display_mode *unadjusted_mode, 454{
454 struct drm_display_mode *mode) 455 struct drm_device *dev = encoder->dev;
456 struct vc4_dev *vc4 = to_vc4_dev(dev);
457 struct vc4_hdmi *hdmi = vc4->hdmi;
458 int ret;
459
460 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG, 0);
461
462 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
463 HD_WRITE(VC4_HD_VID_CTL,
464 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
465
466 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
467 udelay(1);
468 HD_WRITE(VC4_HD_M_CTL, 0);
469
470 clk_disable_unprepare(hdmi->hsm_clock);
471 clk_disable_unprepare(hdmi->pixel_clock);
472
473 ret = pm_runtime_put(&hdmi->pdev->dev);
474 if (ret < 0)
475 DRM_ERROR("Failed to release power domain: %d\n", ret);
476}
477
478static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
455{ 479{
480 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
456 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); 481 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
457 struct drm_device *dev = encoder->dev; 482 struct drm_device *dev = encoder->dev;
458 struct vc4_dev *vc4 = to_vc4_dev(dev); 483 struct vc4_dev *vc4 = to_vc4_dev(dev);
484 struct vc4_hdmi *hdmi = vc4->hdmi;
459 bool debug_dump_regs = false; 485 bool debug_dump_regs = false;
460 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; 486 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
461 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; 487 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
@@ -475,6 +501,64 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
475 interlaced, 501 interlaced,
476 VC4_HDMI_VERTB_VBP)); 502 VC4_HDMI_VERTB_VBP));
477 u32 csc_ctl; 503 u32 csc_ctl;
504 int ret;
505
506 ret = pm_runtime_get_sync(&hdmi->pdev->dev);
507 if (ret < 0) {
508 DRM_ERROR("Failed to retain power domain: %d\n", ret);
509 return;
510 }
511
512 /* This is the rate that is set by the firmware. The number
513 * needs to be a bit higher than the pixel clock rate
514 * (generally 148.5Mhz).
515 */
516 ret = clk_set_rate(hdmi->hsm_clock, 163682864);
517 if (ret) {
518 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
519 return;
520 }
521
522 ret = clk_set_rate(hdmi->pixel_clock,
523 mode->clock * 1000 *
524 ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
525 if (ret) {
526 DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
527 return;
528 }
529
530 ret = clk_prepare_enable(hdmi->pixel_clock);
531 if (ret) {
532 DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
533 return;
534 }
535
536 ret = clk_prepare_enable(hdmi->hsm_clock);
537 if (ret) {
538 DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
539 ret);
540 clk_disable_unprepare(hdmi->pixel_clock);
541 return;
542 }
543
544 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
545 udelay(1);
546 HD_WRITE(VC4_HD_M_CTL, 0);
547
548 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
549
550 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
551 VC4_HDMI_SW_RESET_HDMI |
552 VC4_HDMI_SW_RESET_FORMAT_DETECT);
553
554 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 0);
555
556 /* PHY should be in reset, like
557 * vc4_hdmi_encoder_disable() does.
558 */
559 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
560
561 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
478 562
479 if (debug_dump_regs) { 563 if (debug_dump_regs) {
480 DRM_INFO("HDMI regs before:\n"); 564 DRM_INFO("HDMI regs before:\n");
@@ -483,9 +567,6 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
483 567
484 HD_WRITE(VC4_HD_VID_CTL, 0); 568 HD_WRITE(VC4_HD_VID_CTL, 0);
485 569
486 clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000 *
487 ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
488
489 HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL, 570 HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
490 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) | 571 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
491 VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT | 572 VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
@@ -559,28 +640,6 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
559 DRM_INFO("HDMI regs after:\n"); 640 DRM_INFO("HDMI regs after:\n");
560 vc4_hdmi_dump_regs(dev); 641 vc4_hdmi_dump_regs(dev);
561 } 642 }
562}
563
564static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
565{
566 struct drm_device *dev = encoder->dev;
567 struct vc4_dev *vc4 = to_vc4_dev(dev);
568
569 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG, 0);
570
571 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
572 HD_WRITE(VC4_HD_VID_CTL,
573 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
574}
575
576static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
577{
578 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
579 struct drm_device *dev = encoder->dev;
580 struct vc4_dev *vc4 = to_vc4_dev(dev);
581 int ret;
582
583 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
584 643
585 HD_WRITE(VC4_HD_VID_CTL, 644 HD_WRITE(VC4_HD_VID_CTL,
586 HD_READ(VC4_HD_VID_CTL) | 645 HD_READ(VC4_HD_VID_CTL) |
@@ -646,7 +705,6 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
646} 705}
647 706
648static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = { 707static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
649 .mode_set = vc4_hdmi_encoder_mode_set,
650 .disable = vc4_hdmi_encoder_disable, 708 .disable = vc4_hdmi_encoder_disable,
651 .enable = vc4_hdmi_encoder_enable, 709 .enable = vc4_hdmi_encoder_enable,
652}; 710};
@@ -1147,33 +1205,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1147 return -EPROBE_DEFER; 1205 return -EPROBE_DEFER;
1148 } 1206 }
1149 1207
1150 /* Enable the clocks at startup. We can't quite recover from
1151 * turning off the pixel clock during disable/enables yet, so
1152 * it's always running.
1153 */
1154 ret = clk_prepare_enable(hdmi->pixel_clock);
1155 if (ret) {
1156 DRM_ERROR("Failed to turn on pixel clock: %d\n", ret);
1157 goto err_put_i2c;
1158 }
1159
1160 /* This is the rate that is set by the firmware. The number
1161 * needs to be a bit higher than the pixel clock rate
1162 * (generally 148.5Mhz).
1163 */
1164 ret = clk_set_rate(hdmi->hsm_clock, 163682864);
1165 if (ret) {
1166 DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
1167 goto err_unprepare_pix;
1168 }
1169
1170 ret = clk_prepare_enable(hdmi->hsm_clock);
1171 if (ret) {
1172 DRM_ERROR("Failed to turn on HDMI state machine clock: %d\n",
1173 ret);
1174 goto err_unprepare_pix;
1175 }
1176
1177 /* Only use the GPIO HPD pin if present in the DT, otherwise 1208 /* Only use the GPIO HPD pin if present in the DT, otherwise
1178 * we'll use the HDMI core's register. 1209 * we'll use the HDMI core's register.
1179 */ 1210 */
@@ -1185,7 +1216,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1185 &hpd_gpio_flags); 1216 &hpd_gpio_flags);
1186 if (hdmi->hpd_gpio < 0) { 1217 if (hdmi->hpd_gpio < 0) {
1187 ret = hdmi->hpd_gpio; 1218 ret = hdmi->hpd_gpio;
1188 goto err_unprepare_hsm; 1219 goto err_put_i2c;
1189 } 1220 }
1190 1221
1191 hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; 1222 hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
@@ -1193,25 +1224,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1193 1224
1194 vc4->hdmi = hdmi; 1225 vc4->hdmi = hdmi;
1195 1226
1196 /* HDMI core must be enabled. */ 1227 pm_runtime_enable(dev);
1197 if (!(HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE)) {
1198 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_SW_RST);
1199 udelay(1);
1200 HD_WRITE(VC4_HD_M_CTL, 0);
1201
1202 HD_WRITE(VC4_HD_M_CTL, VC4_HD_M_ENABLE);
1203
1204 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL,
1205 VC4_HDMI_SW_RESET_HDMI |
1206 VC4_HDMI_SW_RESET_FORMAT_DETECT);
1207
1208 HDMI_WRITE(VC4_HDMI_SW_RESET_CONTROL, 0);
1209
1210 /* PHY should be in reset, like
1211 * vc4_hdmi_encoder_disable() does.
1212 */
1213 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
1214 }
1215 1228
1216 drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs, 1229 drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
1217 DRM_MODE_ENCODER_TMDS, NULL); 1230 DRM_MODE_ENCODER_TMDS, NULL);
@@ -1231,10 +1244,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
1231 1244
1232err_destroy_encoder: 1245err_destroy_encoder:
1233 vc4_hdmi_encoder_destroy(hdmi->encoder); 1246 vc4_hdmi_encoder_destroy(hdmi->encoder);
1234err_unprepare_hsm: 1247 pm_runtime_disable(dev);
1235 clk_disable_unprepare(hdmi->hsm_clock);
1236err_unprepare_pix:
1237 clk_disable_unprepare(hdmi->pixel_clock);
1238err_put_i2c: 1248err_put_i2c:
1239 put_device(&hdmi->ddc->dev); 1249 put_device(&hdmi->ddc->dev);
1240 1250
@@ -1253,8 +1263,8 @@ static void vc4_hdmi_unbind(struct device *dev, struct device *master,
1253 vc4_hdmi_connector_destroy(hdmi->connector); 1263 vc4_hdmi_connector_destroy(hdmi->connector);
1254 vc4_hdmi_encoder_destroy(hdmi->encoder); 1264 vc4_hdmi_encoder_destroy(hdmi->encoder);
1255 1265
1256 clk_disable_unprepare(hdmi->pixel_clock); 1266 pm_runtime_disable(dev);
1257 clk_disable_unprepare(hdmi->hsm_clock); 1267
1258 put_device(&hdmi->ddc->dev); 1268 put_device(&hdmi->ddc->dev);
1259 1269
1260 vc4->hdmi = NULL; 1270 vc4->hdmi = NULL;
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index cdc6e6760705..7d7af3a93d94 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -59,50 +59,45 @@ vc4_overflow_mem_work(struct work_struct *work)
59{ 59{
60 struct vc4_dev *vc4 = 60 struct vc4_dev *vc4 =
61 container_of(work, struct vc4_dev, overflow_mem_work); 61 container_of(work, struct vc4_dev, overflow_mem_work);
62 struct drm_device *dev = vc4->dev; 62 struct vc4_bo *bo = vc4->bin_bo;
63 struct vc4_bo *bo; 63 int bin_bo_slot;
64 struct vc4_exec_info *exec;
65 unsigned long irqflags;
64 66
65 bo = vc4_bo_create(dev, 256 * 1024, true); 67 bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
66 if (IS_ERR(bo)) { 68 if (bin_bo_slot < 0) {
67 DRM_ERROR("Couldn't allocate binner overflow mem\n"); 69 DRM_ERROR("Couldn't allocate binner overflow mem\n");
68 return; 70 return;
69 } 71 }
70 72
71 /* If there's a job executing currently, then our previous 73 spin_lock_irqsave(&vc4->job_lock, irqflags);
72 * overflow allocation is getting used in that job and we need 74
73 * to queue it to be released when the job is done. But if no 75 if (vc4->bin_alloc_overflow) {
74 * job is executing at all, then we can free the old overflow 76 /* If we had overflow memory allocated previously,
75 * object direcctly. 77 * then that chunk will free when the current bin job
76 * 78 * is done. If we don't have a bin job running, then
77 * No lock necessary for this pointer since we're the only 79 * the chunk will be done whenever the list of render
78 * ones that update the pointer, and our workqueue won't 80 * jobs has drained.
79 * reenter. 81 */
80 */ 82 exec = vc4_first_bin_job(vc4);
81 if (vc4->overflow_mem) { 83 if (!exec)
82 struct vc4_exec_info *current_exec; 84 exec = vc4_last_render_job(vc4);
83 unsigned long irqflags; 85 if (exec) {
84 86 exec->bin_slots |= vc4->bin_alloc_overflow;
85 spin_lock_irqsave(&vc4->job_lock, irqflags); 87 } else {
86 current_exec = vc4_first_bin_job(vc4); 88 /* There's nothing queued in the hardware, so
87 if (!current_exec) 89 * the old slot is free immediately.
88 current_exec = vc4_last_render_job(vc4); 90 */
89 if (current_exec) { 91 vc4->bin_alloc_used &= ~vc4->bin_alloc_overflow;
90 vc4->overflow_mem->seqno = current_exec->seqno;
91 list_add_tail(&vc4->overflow_mem->unref_head,
92 &current_exec->unref_list);
93 vc4->overflow_mem = NULL;
94 } 92 }
95 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
96 } 93 }
94 vc4->bin_alloc_overflow = BIT(bin_bo_slot);
97 95
98 if (vc4->overflow_mem) 96 V3D_WRITE(V3D_BPOA, bo->base.paddr + bin_bo_slot * vc4->bin_alloc_size);
99 drm_gem_object_unreference_unlocked(&vc4->overflow_mem->base.base);
100 vc4->overflow_mem = bo;
101
102 V3D_WRITE(V3D_BPOA, bo->base.paddr);
103 V3D_WRITE(V3D_BPOS, bo->base.base.size); 97 V3D_WRITE(V3D_BPOS, bo->base.base.size);
104 V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM); 98 V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM);
105 V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM); 99 V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
100 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
106} 101}
107 102
108static void 103static void
@@ -142,6 +137,10 @@ vc4_irq_finish_render_job(struct drm_device *dev)
142 137
143 vc4->finished_seqno++; 138 vc4->finished_seqno++;
144 list_move_tail(&exec->head, &vc4->job_done_list); 139 list_move_tail(&exec->head, &vc4->job_done_list);
140 if (exec->fence) {
141 dma_fence_signal_locked(exec->fence);
142 exec->fence = NULL;
143 }
145 vc4_submit_next_render_job(dev); 144 vc4_submit_next_render_job(dev);
146 145
147 wake_up_all(&vc4->job_wait_queue); 146 wake_up_all(&vc4->job_wait_queue);
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index ad7925a9e0ea..237a504f11f0 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -230,10 +230,12 @@ int vc4_kms_load(struct drm_device *dev)
230 230
231 drm_mode_config_reset(dev); 231 drm_mode_config_reset(dev);
232 232
233 vc4->fbdev = drm_fbdev_cma_init(dev, 32, 233 if (dev->mode_config.num_connector) {
234 dev->mode_config.num_connector); 234 vc4->fbdev = drm_fbdev_cma_init(dev, 32,
235 if (IS_ERR(vc4->fbdev)) 235 dev->mode_config.num_connector);
236 vc4->fbdev = NULL; 236 if (IS_ERR(vc4->fbdev))
237 vc4->fbdev = NULL;
238 }
237 239
238 drm_kms_helper_poll_init(dev); 240 drm_kms_helper_poll_init(dev);
239 241
diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
index 4339471f517f..5dc19429d4ae 100644
--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -182,8 +182,7 @@ static void emit_tile(struct vc4_exec_info *exec,
182 182
183 if (has_bin) { 183 if (has_bin) {
184 rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST); 184 rcl_u8(setup, VC4_PACKET_BRANCH_TO_SUB_LIST);
185 rcl_u32(setup, (exec->tile_bo->paddr + 185 rcl_u32(setup, (exec->tile_alloc_offset +
186 exec->tile_alloc_offset +
187 (y * exec->bin_tiles_x + x) * 32)); 186 (y * exec->bin_tiles_x + x) * 32));
188 } 187 }
189 188
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 7cc346ad9b0b..c53afec34586 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -16,6 +16,7 @@
16 * this program. If not, see <http://www.gnu.org/licenses/>. 16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#include "linux/clk.h"
19#include "linux/component.h" 20#include "linux/component.h"
20#include "linux/pm_runtime.h" 21#include "linux/pm_runtime.h"
21#include "vc4_drv.h" 22#include "vc4_drv.h"
@@ -156,6 +157,144 @@ static void vc4_v3d_init_hw(struct drm_device *dev)
156 V3D_WRITE(V3D_VPMBASE, 0); 157 V3D_WRITE(V3D_VPMBASE, 0);
157} 158}
158 159
160int vc4_v3d_get_bin_slot(struct vc4_dev *vc4)
161{
162 struct drm_device *dev = vc4->dev;
163 unsigned long irqflags;
164 int slot;
165 uint64_t seqno = 0;
166 struct vc4_exec_info *exec;
167
168try_again:
169 spin_lock_irqsave(&vc4->job_lock, irqflags);
170 slot = ffs(~vc4->bin_alloc_used);
171 if (slot != 0) {
172 /* Switch from ffs() bit index to a 0-based index. */
173 slot--;
174 vc4->bin_alloc_used |= BIT(slot);
175 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
176 return slot;
177 }
178
179 /* Couldn't find an open slot. Wait for render to complete
180 * and try again.
181 */
182 exec = vc4_last_render_job(vc4);
183 if (exec)
184 seqno = exec->seqno;
185 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
186
187 if (seqno) {
188 int ret = vc4_wait_for_seqno(dev, seqno, ~0ull, true);
189
190 if (ret == 0)
191 goto try_again;
192
193 return ret;
194 }
195
196 return -ENOMEM;
197}
198
199/**
200 * vc4_allocate_bin_bo() - allocates the memory that will be used for
201 * tile binning.
202 *
203 * The binner has a limitation that the addresses in the tile state
204 * buffer that point into the tile alloc buffer or binner overflow
205 * memory only have 28 bits (256MB), and the top 4 on the bus for
206 * tile alloc references end up coming from the tile state buffer's
207 * address.
208 *
209 * To work around this, we allocate a single large buffer while V3D is
210 * in use, make sure that it has the top 4 bits constant across its
211 * entire extent, and then put the tile state, tile alloc, and binner
212 * overflow memory inside that buffer.
213 *
214 * This creates a limitation where we may not be able to execute a job
215 * if it doesn't fit within the buffer that we allocated up front.
216 * However, it turns out that 16MB is "enough for anybody", and
217 * real-world applications run into allocation failures from the
218 * overall CMA pool before they make scenes complicated enough to run
219 * out of bin space.
220 */
221int
222vc4_allocate_bin_bo(struct drm_device *drm)
223{
224 struct vc4_dev *vc4 = to_vc4_dev(drm);
225 struct vc4_v3d *v3d = vc4->v3d;
226 uint32_t size = 16 * 1024 * 1024;
227 int ret = 0;
228 struct list_head list;
229
230 /* We may need to try allocating more than once to get a BO
231 * that doesn't cross 256MB. Track the ones we've allocated
232 * that failed so far, so that we can free them when we've got
233 * one that succeeded (if we freed them right away, our next
234 * allocation would probably be the same chunk of memory).
235 */
236 INIT_LIST_HEAD(&list);
237
238 while (true) {
239 struct vc4_bo *bo = vc4_bo_create(drm, size, true);
240
241 if (IS_ERR(bo)) {
242 ret = PTR_ERR(bo);
243
244 dev_err(&v3d->pdev->dev,
245 "Failed to allocate memory for tile binning: "
246 "%d. You may need to enable CMA or give it "
247 "more memory.",
248 ret);
249 break;
250 }
251
252 /* Check if this BO won't trigger the addressing bug. */
253 if ((bo->base.paddr & 0xf0000000) ==
254 ((bo->base.paddr + bo->base.base.size - 1) & 0xf0000000)) {
255 vc4->bin_bo = bo;
256
257 /* Set up for allocating 512KB chunks of
258 * binner memory. The biggest allocation we
259 * need to do is for the initial tile alloc +
260 * tile state buffer. We can render to a
261 * maximum of ((2048*2048) / (32*32) = 4096
262 * tiles in a frame (until we do floating
263 * point rendering, at which point it would be
264 * 8192). Tile state is 48b/tile (rounded to
265 * a page), and tile alloc is 32b/tile
266 * (rounded to a page), plus a page of extra,
267 * for a total of 320kb for our worst-case.
268 * We choose 512kb so that it divides evenly
269 * into our 16MB, and the rest of the 512kb
270 * will be used as storage for the overflow
271 * from the initial 32b CL per bin.
272 */
273 vc4->bin_alloc_size = 512 * 1024;
274 vc4->bin_alloc_used = 0;
275 vc4->bin_alloc_overflow = 0;
276 WARN_ON_ONCE(sizeof(vc4->bin_alloc_used) * 8 !=
277 bo->base.base.size / vc4->bin_alloc_size);
278
279 break;
280 }
281
282 /* Put it on the list to free later, and try again. */
283 list_add(&bo->unref_head, &list);
284 }
285
286 /* Free all the BOs we allocated but didn't choose. */
287 while (!list_empty(&list)) {
288 struct vc4_bo *bo = list_last_entry(&list,
289 struct vc4_bo, unref_head);
290
291 list_del(&bo->unref_head);
292 drm_gem_object_put_unlocked(&bo->base.base);
293 }
294
295 return ret;
296}
297
159#ifdef CONFIG_PM 298#ifdef CONFIG_PM
160static int vc4_v3d_runtime_suspend(struct device *dev) 299static int vc4_v3d_runtime_suspend(struct device *dev)
161{ 300{
@@ -164,6 +303,11 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
164 303
165 vc4_irq_uninstall(vc4->dev); 304 vc4_irq_uninstall(vc4->dev);
166 305
306 drm_gem_object_put_unlocked(&vc4->bin_bo->base.base);
307 vc4->bin_bo = NULL;
308
309 clk_disable_unprepare(v3d->clk);
310
167 return 0; 311 return 0;
168} 312}
169 313
@@ -171,6 +315,15 @@ static int vc4_v3d_runtime_resume(struct device *dev)
171{ 315{
172 struct vc4_v3d *v3d = dev_get_drvdata(dev); 316 struct vc4_v3d *v3d = dev_get_drvdata(dev);
173 struct vc4_dev *vc4 = v3d->vc4; 317 struct vc4_dev *vc4 = v3d->vc4;
318 int ret;
319
320 ret = vc4_allocate_bin_bo(vc4->dev);
321 if (ret)
322 return ret;
323
324 ret = clk_prepare_enable(v3d->clk);
325 if (ret != 0)
326 return ret;
174 327
175 vc4_v3d_init_hw(vc4->dev); 328 vc4_v3d_init_hw(vc4->dev);
176 vc4_irq_postinstall(vc4->dev); 329 vc4_irq_postinstall(vc4->dev);
@@ -202,12 +355,38 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
202 vc4->v3d = v3d; 355 vc4->v3d = v3d;
203 v3d->vc4 = vc4; 356 v3d->vc4 = vc4;
204 357
358 v3d->clk = devm_clk_get(dev, NULL);
359 if (IS_ERR(v3d->clk)) {
360 int ret = PTR_ERR(v3d->clk);
361
362 if (ret == -ENOENT) {
363 /* bcm2835 didn't have a clock reference in the DT. */
364 ret = 0;
365 v3d->clk = NULL;
366 } else {
367 if (ret != -EPROBE_DEFER)
368 dev_err(dev, "Failed to get V3D clock: %d\n",
369 ret);
370 return ret;
371 }
372 }
373
205 if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) { 374 if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
206 DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n", 375 DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
207 V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0); 376 V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0);
208 return -EINVAL; 377 return -EINVAL;
209 } 378 }
210 379
380 ret = clk_prepare_enable(v3d->clk);
381 if (ret != 0)
382 return ret;
383
384 ret = vc4_allocate_bin_bo(drm);
385 if (ret) {
386 clk_disable_unprepare(v3d->clk);
387 return ret;
388 }
389
211 /* Reset the binner overflow address/size at setup, to be sure 390 /* Reset the binner overflow address/size at setup, to be sure
212 * we don't reuse an old one. 391 * we don't reuse an old one.
213 */ 392 */
@@ -271,6 +450,7 @@ static int vc4_v3d_dev_remove(struct platform_device *pdev)
271 450
272static const struct of_device_id vc4_v3d_dt_match[] = { 451static const struct of_device_id vc4_v3d_dt_match[] = {
273 { .compatible = "brcm,bcm2835-v3d" }, 452 { .compatible = "brcm,bcm2835-v3d" },
453 { .compatible = "brcm,cygnus-v3d" },
274 { .compatible = "brcm,vc4-v3d" }, 454 { .compatible = "brcm,vc4-v3d" },
275 {} 455 {}
276}; 456};
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index da6f1e138e8d..3de8f11595c0 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -348,10 +348,11 @@ static int
348validate_tile_binning_config(VALIDATE_ARGS) 348validate_tile_binning_config(VALIDATE_ARGS)
349{ 349{
350 struct drm_device *dev = exec->exec_bo->base.dev; 350 struct drm_device *dev = exec->exec_bo->base.dev;
351 struct vc4_bo *tile_bo; 351 struct vc4_dev *vc4 = to_vc4_dev(dev);
352 uint8_t flags; 352 uint8_t flags;
353 uint32_t tile_state_size, tile_alloc_size; 353 uint32_t tile_state_size;
354 uint32_t tile_count; 354 uint32_t tile_count, bin_addr;
355 int bin_slot;
355 356
356 if (exec->found_tile_binning_mode_config_packet) { 357 if (exec->found_tile_binning_mode_config_packet) {
357 DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); 358 DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
@@ -377,13 +378,28 @@ validate_tile_binning_config(VALIDATE_ARGS)
377 return -EINVAL; 378 return -EINVAL;
378 } 379 }
379 380
381 bin_slot = vc4_v3d_get_bin_slot(vc4);
382 if (bin_slot < 0) {
383 if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
384 DRM_ERROR("Failed to allocate binner memory: %d\n",
385 bin_slot);
386 }
387 return bin_slot;
388 }
389
390 /* The slot we allocated will only be used by this job, and is
391 * free when the job completes rendering.
392 */
393 exec->bin_slots |= BIT(bin_slot);
394 bin_addr = vc4->bin_bo->base.paddr + bin_slot * vc4->bin_alloc_size;
395
380 /* The tile state data array is 48 bytes per tile, and we put it at 396 /* The tile state data array is 48 bytes per tile, and we put it at
381 * the start of a BO containing both it and the tile alloc. 397 * the start of a BO containing both it and the tile alloc.
382 */ 398 */
383 tile_state_size = 48 * tile_count; 399 tile_state_size = 48 * tile_count;
384 400
385 /* Since the tile alloc array will follow us, align. */ 401 /* Since the tile alloc array will follow us, align. */
386 exec->tile_alloc_offset = roundup(tile_state_size, 4096); 402 exec->tile_alloc_offset = bin_addr + roundup(tile_state_size, 4096);
387 403
388 *(uint8_t *)(validated + 14) = 404 *(uint8_t *)(validated + 14) =
389 ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK | 405 ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK |
@@ -394,35 +410,13 @@ validate_tile_binning_config(VALIDATE_ARGS)
394 VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128, 410 VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128,
395 VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE)); 411 VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE));
396 412
397 /* Initial block size. */
398 tile_alloc_size = 32 * tile_count;
399
400 /*
401 * The initial allocation gets rounded to the next 256 bytes before
402 * the hardware starts fulfilling further allocations.
403 */
404 tile_alloc_size = roundup(tile_alloc_size, 256);
405
406 /* Add space for the extra allocations. This is what gets used first,
407 * before overflow memory. It must have at least 4096 bytes, but we
408 * want to avoid overflow memory usage if possible.
409 */
410 tile_alloc_size += 1024 * 1024;
411
412 tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size,
413 true);
414 exec->tile_bo = &tile_bo->base;
415 if (IS_ERR(exec->tile_bo))
416 return PTR_ERR(exec->tile_bo);
417 list_add_tail(&tile_bo->unref_head, &exec->unref_list);
418
419 /* tile alloc address. */ 413 /* tile alloc address. */
420 *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + 414 *(uint32_t *)(validated + 0) = exec->tile_alloc_offset;
421 exec->tile_alloc_offset);
422 /* tile alloc size. */ 415 /* tile alloc size. */
423 *(uint32_t *)(validated + 4) = tile_alloc_size; 416 *(uint32_t *)(validated + 4) = (bin_addr + vc4->bin_alloc_size -
417 exec->tile_alloc_offset);
424 /* tile state address. */ 418 /* tile state address. */
425 *(uint32_t *)(validated + 8) = exec->tile_bo->paddr; 419 *(uint32_t *)(validated + 8) = bin_addr;
426 420
427 return 0; 421 return 0;
428} 422}
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 9fee38a942c4..4b23ba049632 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -42,10 +42,20 @@
42#define DRIVER_MAJOR 1 42#define DRIVER_MAJOR 1
43#define DRIVER_MINOR 0 43#define DRIVER_MINOR 0
44 44
45static struct vgem_device {
46 struct drm_device drm;
47 struct platform_device *platform;
48} *vgem_device;
49
45static void vgem_gem_free_object(struct drm_gem_object *obj) 50static void vgem_gem_free_object(struct drm_gem_object *obj)
46{ 51{
47 struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj); 52 struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj);
48 53
54 drm_free_large(vgem_obj->pages);
55
56 if (obj->import_attach)
57 drm_prime_gem_destroy(obj, vgem_obj->table);
58
49 drm_gem_object_release(obj); 59 drm_gem_object_release(obj);
50 kfree(vgem_obj); 60 kfree(vgem_obj);
51} 61}
@@ -56,26 +66,49 @@ static int vgem_gem_fault(struct vm_fault *vmf)
56 struct drm_vgem_gem_object *obj = vma->vm_private_data; 66 struct drm_vgem_gem_object *obj = vma->vm_private_data;
57 /* We don't use vmf->pgoff since that has the fake offset */ 67 /* We don't use vmf->pgoff since that has the fake offset */
58 unsigned long vaddr = vmf->address; 68 unsigned long vaddr = vmf->address;
59 struct page *page; 69 int ret;
60 70 loff_t num_pages;
61 page = shmem_read_mapping_page(file_inode(obj->base.filp)->i_mapping, 71 pgoff_t page_offset;
62 (vaddr - vma->vm_start) >> PAGE_SHIFT); 72 page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT;
63 if (!IS_ERR(page)) { 73
64 vmf->page = page; 74 num_pages = DIV_ROUND_UP(obj->base.size, PAGE_SIZE);
65 return 0; 75
66 } else switch (PTR_ERR(page)) { 76 if (page_offset > num_pages)
67 case -ENOSPC: 77 return VM_FAULT_SIGBUS;
68 case -ENOMEM: 78
69 return VM_FAULT_OOM; 79 if (obj->pages) {
70 case -EBUSY: 80 get_page(obj->pages[page_offset]);
71 return VM_FAULT_RETRY; 81 vmf->page = obj->pages[page_offset];
72 case -EFAULT: 82 ret = 0;
73 case -EINVAL: 83 } else {
74 return VM_FAULT_SIGBUS; 84 struct page *page;
75 default: 85
76 WARN_ON_ONCE(PTR_ERR(page)); 86 page = shmem_read_mapping_page(
77 return VM_FAULT_SIGBUS; 87 file_inode(obj->base.filp)->i_mapping,
88 page_offset);
89 if (!IS_ERR(page)) {
90 vmf->page = page;
91 ret = 0;
92 } else switch (PTR_ERR(page)) {
93 case -ENOSPC:
94 case -ENOMEM:
95 ret = VM_FAULT_OOM;
96 break;
97 case -EBUSY:
98 ret = VM_FAULT_RETRY;
99 break;
100 case -EFAULT:
101 case -EINVAL:
102 ret = VM_FAULT_SIGBUS;
103 break;
104 default:
105 WARN_ON(PTR_ERR(page));
106 ret = VM_FAULT_SIGBUS;
107 break;
108 }
109
78 } 110 }
111 return ret;
79} 112}
80 113
81static const struct vm_operations_struct vgem_gem_vm_ops = { 114static const struct vm_operations_struct vgem_gem_vm_ops = {
@@ -112,12 +145,8 @@ static void vgem_postclose(struct drm_device *dev, struct drm_file *file)
112 kfree(vfile); 145 kfree(vfile);
113} 146}
114 147
115/* ioctls */ 148static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev,
116 149 unsigned long size)
117static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
118 struct drm_file *file,
119 unsigned int *handle,
120 unsigned long size)
121{ 150{
122 struct drm_vgem_gem_object *obj; 151 struct drm_vgem_gem_object *obj;
123 int ret; 152 int ret;
@@ -127,8 +156,31 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
127 return ERR_PTR(-ENOMEM); 156 return ERR_PTR(-ENOMEM);
128 157
129 ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE)); 158 ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE));
130 if (ret) 159 if (ret) {
131 goto err_free; 160 kfree(obj);
161 return ERR_PTR(ret);
162 }
163
164 return obj;
165}
166
167static void __vgem_gem_destroy(struct drm_vgem_gem_object *obj)
168{
169 drm_gem_object_release(&obj->base);
170 kfree(obj);
171}
172
173static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
174 struct drm_file *file,
175 unsigned int *handle,
176 unsigned long size)
177{
178 struct drm_vgem_gem_object *obj;
179 int ret;
180
181 obj = __vgem_gem_create(dev, size);
182 if (IS_ERR(obj))
183 return ERR_CAST(obj);
132 184
133 ret = drm_gem_handle_create(file, &obj->base, handle); 185 ret = drm_gem_handle_create(file, &obj->base, handle);
134 drm_gem_object_unreference_unlocked(&obj->base); 186 drm_gem_object_unreference_unlocked(&obj->base);
@@ -137,9 +189,8 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
137 189
138 return &obj->base; 190 return &obj->base;
139 191
140err_free:
141 kfree(obj);
142err: 192err:
193 __vgem_gem_destroy(obj);
143 return ERR_PTR(ret); 194 return ERR_PTR(ret);
144} 195}
145 196
@@ -256,6 +307,37 @@ static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
256 return st; 307 return st;
257} 308}
258 309
310static struct drm_gem_object* vgem_prime_import(struct drm_device *dev,
311 struct dma_buf *dma_buf)
312{
313 struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm);
314
315 return drm_gem_prime_import_dev(dev, dma_buf, &vgem->platform->dev);
316}
317
318static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev,
319 struct dma_buf_attachment *attach, struct sg_table *sg)
320{
321 struct drm_vgem_gem_object *obj;
322 int npages;
323
324 obj = __vgem_gem_create(dev, attach->dmabuf->size);
325 if (IS_ERR(obj))
326 return ERR_CAST(obj);
327
328 npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE;
329
330 obj->table = sg;
331 obj->pages = drm_malloc_ab(npages, sizeof(struct page *));
332 if (!obj->pages) {
333 __vgem_gem_destroy(obj);
334 return ERR_PTR(-ENOMEM);
335 }
336 drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL,
337 npages);
338 return &obj->base;
339}
340
259static void *vgem_prime_vmap(struct drm_gem_object *obj) 341static void *vgem_prime_vmap(struct drm_gem_object *obj)
260{ 342{
261 long n_pages = obj->size >> PAGE_SHIFT; 343 long n_pages = obj->size >> PAGE_SHIFT;
@@ -300,8 +382,19 @@ static int vgem_prime_mmap(struct drm_gem_object *obj,
300 return 0; 382 return 0;
301} 383}
302 384
385static void vgem_release(struct drm_device *dev)
386{
387 struct vgem_device *vgem = container_of(dev, typeof(*vgem), drm);
388
389 platform_device_unregister(vgem->platform);
390 drm_dev_fini(&vgem->drm);
391
392 kfree(vgem);
393}
394
303static struct drm_driver vgem_driver = { 395static struct drm_driver vgem_driver = {
304 .driver_features = DRIVER_GEM | DRIVER_PRIME, 396 .driver_features = DRIVER_GEM | DRIVER_PRIME,
397 .release = vgem_release,
305 .open = vgem_open, 398 .open = vgem_open,
306 .postclose = vgem_postclose, 399 .postclose = vgem_postclose,
307 .gem_free_object_unlocked = vgem_gem_free_object, 400 .gem_free_object_unlocked = vgem_gem_free_object,
@@ -314,8 +407,11 @@ static struct drm_driver vgem_driver = {
314 .dumb_map_offset = vgem_gem_dumb_map, 407 .dumb_map_offset = vgem_gem_dumb_map,
315 408
316 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 409 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
410 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
317 .gem_prime_pin = vgem_prime_pin, 411 .gem_prime_pin = vgem_prime_pin,
412 .gem_prime_import = vgem_prime_import,
318 .gem_prime_export = drm_gem_prime_export, 413 .gem_prime_export = drm_gem_prime_export,
414 .gem_prime_import_sg_table = vgem_prime_import_sg_table,
319 .gem_prime_get_sg_table = vgem_prime_get_sg_table, 415 .gem_prime_get_sg_table = vgem_prime_get_sg_table,
320 .gem_prime_vmap = vgem_prime_vmap, 416 .gem_prime_vmap = vgem_prime_vmap,
321 .gem_prime_vunmap = vgem_prime_vunmap, 417 .gem_prime_vunmap = vgem_prime_vunmap,
@@ -328,34 +424,48 @@ static struct drm_driver vgem_driver = {
328 .minor = DRIVER_MINOR, 424 .minor = DRIVER_MINOR,
329}; 425};
330 426
331static struct drm_device *vgem_device;
332
333static int __init vgem_init(void) 427static int __init vgem_init(void)
334{ 428{
335 int ret; 429 int ret;
336 430
337 vgem_device = drm_dev_alloc(&vgem_driver, NULL); 431 vgem_device = kzalloc(sizeof(*vgem_device), GFP_KERNEL);
338 if (IS_ERR(vgem_device)) { 432 if (!vgem_device)
339 ret = PTR_ERR(vgem_device); 433 return -ENOMEM;
340 goto out; 434
435 ret = drm_dev_init(&vgem_device->drm, &vgem_driver, NULL);
436 if (ret)
437 goto out_free;
438
439 vgem_device->platform =
440 platform_device_register_simple("vgem", -1, NULL, 0);
441 if (!vgem_device->platform) {
442 ret = -ENODEV;
443 goto out_fini;
341 } 444 }
342 445
343 ret = drm_dev_register(vgem_device, 0); 446 dma_coerce_mask_and_coherent(&vgem_device->platform->dev,
447 DMA_BIT_MASK(64));
448
449 /* Final step: expose the device/driver to userspace */
450 ret = drm_dev_register(&vgem_device->drm, 0);
344 if (ret) 451 if (ret)
345 goto out_unref; 452 goto out_unregister;
346 453
347 return 0; 454 return 0;
348 455
349out_unref: 456out_unregister:
350 drm_dev_unref(vgem_device); 457 platform_device_unregister(vgem_device->platform);
351out: 458out_fini:
459 drm_dev_fini(&vgem_device->drm);
460out_free:
461 kfree(vgem_device);
352 return ret; 462 return ret;
353} 463}
354 464
355static void __exit vgem_exit(void) 465static void __exit vgem_exit(void)
356{ 466{
357 drm_dev_unregister(vgem_device); 467 drm_dev_unregister(&vgem_device->drm);
358 drm_dev_unref(vgem_device); 468 drm_dev_unref(&vgem_device->drm);
359} 469}
360 470
361module_init(vgem_init); 471module_init(vgem_init);
diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h
index cb59c7ab98b9..1aae01419112 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.h
+++ b/drivers/gpu/drm/vgem/vgem_drv.h
@@ -43,6 +43,8 @@ struct vgem_file {
43#define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base) 43#define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base)
44struct drm_vgem_gem_object { 44struct drm_vgem_gem_object {
45 struct drm_gem_object base; 45 struct drm_gem_object base;
46 struct page **pages;
47 struct sg_table *table;
46}; 48};
47 49
48int vgem_fence_open(struct vgem_file *file); 50int vgem_fence_open(struct vgem_file *file);
diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile
index 01352b56c418..9df7766a7f9d 100644
--- a/drivers/gpu/drm/zte/Makefile
+++ b/drivers/gpu/drm/zte/Makefile
@@ -3,6 +3,7 @@ zxdrm-y := \
3 zx_hdmi.o \ 3 zx_hdmi.o \
4 zx_plane.o \ 4 zx_plane.o \
5 zx_tvenc.o \ 5 zx_tvenc.o \
6 zx_vga.o \
6 zx_vou.o 7 zx_vou.o
7 8
8obj-$(CONFIG_DRM_ZTE) += zxdrm.o 9obj-$(CONFIG_DRM_ZTE) += zxdrm.o
diff --git a/drivers/gpu/drm/zte/zx_common_regs.h b/drivers/gpu/drm/zte/zx_common_regs.h
new file mode 100644
index 000000000000..2afd80664c51
--- /dev/null
+++ b/drivers/gpu/drm/zte/zx_common_regs.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
3 * Copyright 2017 Linaro Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef __ZX_COMMON_REGS_H__
11#define __ZX_COMMON_REGS_H__
12
13/* CSC registers */
14#define CSC_CTRL0 0x30
15#define CSC_COV_MODE_SHIFT 16
16#define CSC_COV_MODE_MASK (0xffff << CSC_COV_MODE_SHIFT)
17#define CSC_BT601_IMAGE_RGB2YCBCR 0
18#define CSC_BT601_IMAGE_YCBCR2RGB 1
19#define CSC_BT601_VIDEO_RGB2YCBCR 2
20#define CSC_BT601_VIDEO_YCBCR2RGB 3
21#define CSC_BT709_IMAGE_RGB2YCBCR 4
22#define CSC_BT709_IMAGE_YCBCR2RGB 5
23#define CSC_BT709_VIDEO_RGB2YCBCR 6
24#define CSC_BT709_VIDEO_YCBCR2RGB 7
25#define CSC_BT2020_IMAGE_RGB2YCBCR 8
26#define CSC_BT2020_IMAGE_YCBCR2RGB 9
27#define CSC_BT2020_VIDEO_RGB2YCBCR 10
28#define CSC_BT2020_VIDEO_YCBCR2RGB 11
29#define CSC_WORK_ENABLE BIT(0)
30
31#endif /* __ZX_COMMON_REGS_H__ */
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c
index 614e854f6be5..490aafc99610 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.c
+++ b/drivers/gpu/drm/zte/zx_drm_drv.c
@@ -233,6 +233,7 @@ static struct platform_driver *drivers[] = {
233 &zx_crtc_driver, 233 &zx_crtc_driver,
234 &zx_hdmi_driver, 234 &zx_hdmi_driver,
235 &zx_tvenc_driver, 235 &zx_tvenc_driver,
236 &zx_vga_driver,
236 &zx_drm_platform_driver, 237 &zx_drm_platform_driver,
237}; 238};
238 239
diff --git a/drivers/gpu/drm/zte/zx_drm_drv.h b/drivers/gpu/drm/zte/zx_drm_drv.h
index 5ca035b079c7..2a8cdc5f8be4 100644
--- a/drivers/gpu/drm/zte/zx_drm_drv.h
+++ b/drivers/gpu/drm/zte/zx_drm_drv.h
@@ -14,6 +14,7 @@
14extern struct platform_driver zx_crtc_driver; 14extern struct platform_driver zx_crtc_driver;
15extern struct platform_driver zx_hdmi_driver; 15extern struct platform_driver zx_hdmi_driver;
16extern struct platform_driver zx_tvenc_driver; 16extern struct platform_driver zx_tvenc_driver;
17extern struct platform_driver zx_vga_driver;
17 18
18static inline u32 zx_readl(void __iomem *reg) 19static inline u32 zx_readl(void __iomem *reg)
19{ 20{
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index d646ac931663..4a6252720c10 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -16,6 +16,7 @@
16#include <drm/drm_plane_helper.h> 16#include <drm/drm_plane_helper.h>
17#include <drm/drmP.h> 17#include <drm/drmP.h>
18 18
19#include "zx_common_regs.h"
19#include "zx_drm_drv.h" 20#include "zx_drm_drv.h"
20#include "zx_plane.h" 21#include "zx_plane.h"
21#include "zx_plane_regs.h" 22#include "zx_plane_regs.h"
diff --git a/drivers/gpu/drm/zte/zx_plane_regs.h b/drivers/gpu/drm/zte/zx_plane_regs.h
index 65f271aeabed..9c655f59f9f7 100644
--- a/drivers/gpu/drm/zte/zx_plane_regs.h
+++ b/drivers/gpu/drm/zte/zx_plane_regs.h
@@ -77,24 +77,6 @@
77#define LUMA_STRIDE(x) (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK) 77#define LUMA_STRIDE(x) (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK)
78#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK) 78#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK)
79 79
80/* CSC registers */
81#define CSC_CTRL0 0x30
82#define CSC_COV_MODE_SHIFT 16
83#define CSC_COV_MODE_MASK (0xffff << CSC_COV_MODE_SHIFT)
84#define CSC_BT601_IMAGE_RGB2YCBCR 0
85#define CSC_BT601_IMAGE_YCBCR2RGB 1
86#define CSC_BT601_VIDEO_RGB2YCBCR 2
87#define CSC_BT601_VIDEO_YCBCR2RGB 3
88#define CSC_BT709_IMAGE_RGB2YCBCR 4
89#define CSC_BT709_IMAGE_YCBCR2RGB 5
90#define CSC_BT709_VIDEO_RGB2YCBCR 6
91#define CSC_BT709_VIDEO_YCBCR2RGB 7
92#define CSC_BT2020_IMAGE_RGB2YCBCR 8
93#define CSC_BT2020_IMAGE_YCBCR2RGB 9
94#define CSC_BT2020_VIDEO_RGB2YCBCR 10
95#define CSC_BT2020_VIDEO_YCBCR2RGB 11
96#define CSC_WORK_ENABLE BIT(0)
97
98/* RSZ registers */ 80/* RSZ registers */
99#define RSZ_SRC_CFG 0x00 81#define RSZ_SRC_CFG 0x00
100#define RSZ_DEST_CFG 0x04 82#define RSZ_DEST_CFG 0x04
diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c
new file mode 100644
index 000000000000..1e0811f775cb
--- /dev/null
+++ b/drivers/gpu/drm/zte/zx_vga.c
@@ -0,0 +1,531 @@
1/*
2 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
3 * Copyright 2017 Linaro Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/clk.h>
11#include <linux/component.h>
12#include <linux/mfd/syscon.h>
13#include <linux/regmap.h>
14
15#include <drm/drm_atomic_helper.h>
16#include <drm/drm_crtc_helper.h>
17#include <drm/drmP.h>
18
19#include "zx_drm_drv.h"
20#include "zx_vga_regs.h"
21#include "zx_vou.h"
22
23struct zx_vga_pwrctrl {
24 struct regmap *regmap;
25 u32 reg;
26 u32 mask;
27};
28
29struct zx_vga_i2c {
30 struct i2c_adapter adap;
31 struct mutex lock;
32};
33
34struct zx_vga {
35 struct drm_connector connector;
36 struct drm_encoder encoder;
37 struct zx_vga_i2c *ddc;
38 struct device *dev;
39 void __iomem *mmio;
40 struct clk *i2c_wclk;
41 struct zx_vga_pwrctrl pwrctrl;
42 struct completion complete;
43 bool connected;
44};
45
46#define to_zx_vga(x) container_of(x, struct zx_vga, x)
47
48static void zx_vga_encoder_enable(struct drm_encoder *encoder)
49{
50 struct zx_vga *vga = to_zx_vga(encoder);
51 struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;
52
53 /* Set bit to power up VGA DACs */
54 regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask,
55 pwrctrl->mask);
56
57 vou_inf_enable(VOU_VGA, encoder->crtc);
58}
59
60static void zx_vga_encoder_disable(struct drm_encoder *encoder)
61{
62 struct zx_vga *vga = to_zx_vga(encoder);
63 struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;
64
65 vou_inf_disable(VOU_VGA, encoder->crtc);
66
67 /* Clear bit to power down VGA DACs */
68 regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, 0);
69}
70
71static const struct drm_encoder_helper_funcs zx_vga_encoder_helper_funcs = {
72 .enable = zx_vga_encoder_enable,
73 .disable = zx_vga_encoder_disable,
74};
75
76static const struct drm_encoder_funcs zx_vga_encoder_funcs = {
77 .destroy = drm_encoder_cleanup,
78};
79
80static int zx_vga_connector_get_modes(struct drm_connector *connector)
81{
82 struct zx_vga *vga = to_zx_vga(connector);
83 struct edid *edid;
84 int ret;
85
86 /*
87 * Clear both detection bits to switch I2C bus from device
88 * detecting to EDID reading.
89 */
90 zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, 0);
91
92 edid = drm_get_edid(connector, &vga->ddc->adap);
93 if (!edid) {
94 /*
95 * If EDID reading fails, we set the device state into
96 * disconnected. Locking is not required here, since the
97 * VGA_AUTO_DETECT_SEL register write in irq handler cannot
98 * be triggered when both detection bits are cleared as above.
99 */
100 zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL,
101 VGA_DETECT_SEL_NO_DEVICE);
102 vga->connected = false;
103 return 0;
104 }
105
106 /*
107 * As edid reading succeeds, device must be connected, so we set
108 * up detection bit for unplug interrupt here.
109 */
110 zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_HAS_DEVICE);
111
112 drm_mode_connector_update_edid_property(connector, edid);
113 ret = drm_add_edid_modes(connector, edid);
114 kfree(edid);
115
116 return ret;
117}
118
119static enum drm_mode_status
120zx_vga_connector_mode_valid(struct drm_connector *connector,
121 struct drm_display_mode *mode)
122{
123 return MODE_OK;
124}
125
126static struct drm_connector_helper_funcs zx_vga_connector_helper_funcs = {
127 .get_modes = zx_vga_connector_get_modes,
128 .mode_valid = zx_vga_connector_mode_valid,
129};
130
131static enum drm_connector_status
132zx_vga_connector_detect(struct drm_connector *connector, bool force)
133{
134 struct zx_vga *vga = to_zx_vga(connector);
135
136 return vga->connected ? connector_status_connected :
137 connector_status_disconnected;
138}
139
140static const struct drm_connector_funcs zx_vga_connector_funcs = {
141 .dpms = drm_atomic_helper_connector_dpms,
142 .fill_modes = drm_helper_probe_single_connector_modes,
143 .detect = zx_vga_connector_detect,
144 .destroy = drm_connector_cleanup,
145 .reset = drm_atomic_helper_connector_reset,
146 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
147 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
148};
149
150static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga)
151{
152 struct drm_encoder *encoder = &vga->encoder;
153 struct drm_connector *connector = &vga->connector;
154 struct device *dev = vga->dev;
155 int ret;
156
157 encoder->possible_crtcs = VOU_CRTC_MASK;
158
159 ret = drm_encoder_init(drm, encoder, &zx_vga_encoder_funcs,
160 DRM_MODE_ENCODER_DAC, NULL);
161 if (ret) {
162 DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret);
163 return ret;
164 };
165
166 drm_encoder_helper_add(encoder, &zx_vga_encoder_helper_funcs);
167
168 vga->connector.polled = DRM_CONNECTOR_POLL_HPD;
169
170 ret = drm_connector_init(drm, connector, &zx_vga_connector_funcs,
171 DRM_MODE_CONNECTOR_VGA);
172 if (ret) {
173 DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret);
174 goto clean_encoder;
175 };
176
177 drm_connector_helper_add(connector, &zx_vga_connector_helper_funcs);
178
179 ret = drm_mode_connector_attach_encoder(connector, encoder);
180 if (ret) {
181 DRM_DEV_ERROR(dev, "failed to attach encoder: %d\n", ret);
182 goto clean_connector;
183 };
184
185 return 0;
186
187clean_connector:
188 drm_connector_cleanup(connector);
189clean_encoder:
190 drm_encoder_cleanup(encoder);
191 return ret;
192}
193
194static int zx_vga_pwrctrl_init(struct zx_vga *vga)
195{
196 struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl;
197 struct device *dev = vga->dev;
198 struct of_phandle_args out_args;
199 struct regmap *regmap;
200 int ret;
201
202 ret = of_parse_phandle_with_fixed_args(dev->of_node,
203 "zte,vga-power-control", 2, 0, &out_args);
204 if (ret)
205 return ret;
206
207 regmap = syscon_node_to_regmap(out_args.np);
208 if (IS_ERR(regmap)) {
209 ret = PTR_ERR(regmap);
210 goto out;
211 }
212
213 pwrctrl->regmap = regmap;
214 pwrctrl->reg = out_args.args[0];
215 pwrctrl->mask = out_args.args[1];
216
217out:
218 of_node_put(out_args.np);
219 return ret;
220}
221
222static int zx_vga_i2c_read(struct zx_vga *vga, struct i2c_msg *msg)
223{
224 int len = msg->len;
225 u8 *buf = msg->buf;
226 u32 offset = 0;
227 int i;
228
229 reinit_completion(&vga->complete);
230
231 /* Select combo write */
232 zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_COMBO, VGA_CMD_COMBO);
233 zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_RW, 0);
234
235 while (len > 0) {
236 u32 cnt;
237
238 /* Clear RX FIFO */
239 zx_writel_mask(vga->mmio + VGA_RXF_CTRL, VGA_RX_FIFO_CLEAR,
240 VGA_RX_FIFO_CLEAR);
241
242 /* Data offset to read from */
243 zx_writel(vga->mmio + VGA_SUB_ADDR, offset);
244
245 /* Kick off the transfer */
246 zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS,
247 VGA_CMD_TRANS);
248
249 if (!wait_for_completion_timeout(&vga->complete,
250 msecs_to_jiffies(1000))) {
251 DRM_DEV_ERROR(vga->dev, "transfer timeout\n");
252 return -ETIMEDOUT;
253 }
254
255 cnt = zx_readl(vga->mmio + VGA_RXF_STATUS);
256 cnt = (cnt & VGA_RXF_COUNT_MASK) >> VGA_RXF_COUNT_SHIFT;
257 /* FIFO status may report more data than we need to read */
258 cnt = min_t(u32, len, cnt);
259
260 for (i = 0; i < cnt; i++)
261 *buf++ = zx_readl(vga->mmio + VGA_DATA);
262
263 len -= cnt;
264 offset += cnt;
265 }
266
267 return 0;
268}
269
270static int zx_vga_i2c_write(struct zx_vga *vga, struct i2c_msg *msg)
271{
272 /*
273 * The DDC I2C adapter is only for reading EDID data, so we assume
274 * that the write to this adapter must be the EDID data offset.
275 */
276 if ((msg->len != 1) || ((msg->addr != DDC_ADDR)))
277 return -EINVAL;
278
279 /* Hardware will take care of the slave address shifting */
280 zx_writel(vga->mmio + VGA_DEVICE_ADDR, msg->addr);
281
282 return 0;
283}
284
285static int zx_vga_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
286 int num)
287{
288 struct zx_vga *vga = i2c_get_adapdata(adap);
289 struct zx_vga_i2c *ddc = vga->ddc;
290 int ret = 0;
291 int i;
292
293 mutex_lock(&ddc->lock);
294
295 for (i = 0; i < num; i++) {
296 if (msgs[i].flags & I2C_M_RD)
297 ret = zx_vga_i2c_read(vga, &msgs[i]);
298 else
299 ret = zx_vga_i2c_write(vga, &msgs[i]);
300
301 if (ret < 0)
302 break;
303 }
304
305 if (!ret)
306 ret = num;
307
308 mutex_unlock(&ddc->lock);
309
310 return ret;
311}
312
313static u32 zx_vga_i2c_func(struct i2c_adapter *adapter)
314{
315 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
316}
317
318static const struct i2c_algorithm zx_vga_algorithm = {
319 .master_xfer = zx_vga_i2c_xfer,
320 .functionality = zx_vga_i2c_func,
321};
322
323static int zx_vga_ddc_register(struct zx_vga *vga)
324{
325 struct device *dev = vga->dev;
326 struct i2c_adapter *adap;
327 struct zx_vga_i2c *ddc;
328 int ret;
329
330 ddc = devm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
331 if (!ddc)
332 return -ENOMEM;
333
334 vga->ddc = ddc;
335 mutex_init(&ddc->lock);
336
337 adap = &ddc->adap;
338 adap->owner = THIS_MODULE;
339 adap->class = I2C_CLASS_DDC;
340 adap->dev.parent = dev;
341 adap->algo = &zx_vga_algorithm;
342 snprintf(adap->name, sizeof(adap->name), "zx vga i2c");
343
344 ret = i2c_add_adapter(adap);
345 if (ret) {
346 DRM_DEV_ERROR(dev, "failed to add I2C adapter: %d\n", ret);
347 return ret;
348 }
349
350 i2c_set_adapdata(adap, vga);
351
352 return 0;
353}
354
355static irqreturn_t zx_vga_irq_thread(int irq, void *dev_id)
356{
357 struct zx_vga *vga = dev_id;
358
359 drm_helper_hpd_irq_event(vga->connector.dev);
360
361 return IRQ_HANDLED;
362}
363
364static irqreturn_t zx_vga_irq_handler(int irq, void *dev_id)
365{
366 struct zx_vga *vga = dev_id;
367 u32 status;
368
369 status = zx_readl(vga->mmio + VGA_I2C_STATUS);
370
371 /* Clear interrupt status */
372 zx_writel_mask(vga->mmio + VGA_I2C_STATUS, VGA_CLEAR_IRQ,
373 VGA_CLEAR_IRQ);
374
375 if (status & VGA_DEVICE_CONNECTED) {
376 /*
377 * Since VGA_DETECT_SEL bits need to be reset for switching DDC
378 * bus from device detection to EDID read, rather than setting
379 * up HAS_DEVICE bit here, we need to do that in .get_modes
380 * hook for unplug detecting after EDID read succeeds.
381 */
382 vga->connected = true;
383 return IRQ_WAKE_THREAD;
384 }
385
386 if (status & VGA_DEVICE_DISCONNECTED) {
387 zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL,
388 VGA_DETECT_SEL_NO_DEVICE);
389 vga->connected = false;
390 return IRQ_WAKE_THREAD;
391 }
392
393 if (status & VGA_TRANS_DONE) {
394 complete(&vga->complete);
395 return IRQ_HANDLED;
396 }
397
398 return IRQ_NONE;
399}
400
401static void zx_vga_hw_init(struct zx_vga *vga)
402{
403 unsigned long ref = clk_get_rate(vga->i2c_wclk);
404 int div;
405
406 /*
407 * Set up I2C fast speed divider per formula below to get 400kHz.
408 * scl = ref / ((div + 1) * 4)
409 */
410 div = DIV_ROUND_UP(ref / 1000, 400 * 4) - 1;
411 zx_writel(vga->mmio + VGA_CLK_DIV_FS, div);
412
413 /* Set up device detection */
414 zx_writel(vga->mmio + VGA_AUTO_DETECT_PARA, 0x80);
415 zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_NO_DEVICE);
416
417 /*
418 * We need to poke monitor via DDC bus to get connection irq
419 * start working.
420 */
421 zx_writel(vga->mmio + VGA_DEVICE_ADDR, DDC_ADDR);
422 zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS, VGA_CMD_TRANS);
423}
424
425static int zx_vga_bind(struct device *dev, struct device *master, void *data)
426{
427 struct platform_device *pdev = to_platform_device(dev);
428 struct drm_device *drm = data;
429 struct resource *res;
430 struct zx_vga *vga;
431 int irq;
432 int ret;
433
434 vga = devm_kzalloc(dev, sizeof(*vga), GFP_KERNEL);
435 if (!vga)
436 return -ENOMEM;
437
438 vga->dev = dev;
439 dev_set_drvdata(dev, vga);
440
441 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
442 vga->mmio = devm_ioremap_resource(dev, res);
443 if (IS_ERR(vga->mmio))
444 return PTR_ERR(vga->mmio);
445
446 irq = platform_get_irq(pdev, 0);
447 if (irq < 0)
448 return irq;
449
450 vga->i2c_wclk = devm_clk_get(dev, "i2c_wclk");
451 if (IS_ERR(vga->i2c_wclk)) {
452 ret = PTR_ERR(vga->i2c_wclk);
453 DRM_DEV_ERROR(dev, "failed to get i2c_wclk: %d\n", ret);
454 return ret;
455 }
456
457 ret = zx_vga_pwrctrl_init(vga);
458 if (ret) {
459 DRM_DEV_ERROR(dev, "failed to init power control: %d\n", ret);
460 return ret;
461 }
462
463 ret = zx_vga_ddc_register(vga);
464 if (ret) {
465 DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret);
466 return ret;
467 }
468
469 ret = zx_vga_register(drm, vga);
470 if (ret) {
471 DRM_DEV_ERROR(dev, "failed to register vga: %d\n", ret);
472 return ret;
473 }
474
475 init_completion(&vga->complete);
476
477 ret = devm_request_threaded_irq(dev, irq, zx_vga_irq_handler,
478 zx_vga_irq_thread, IRQF_SHARED,
479 dev_name(dev), vga);
480 if (ret) {
481 DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret);
482 return ret;
483 }
484
485 ret = clk_prepare_enable(vga->i2c_wclk);
486 if (ret)
487 return ret;
488
489 zx_vga_hw_init(vga);
490
491 return 0;
492}
493
494static void zx_vga_unbind(struct device *dev, struct device *master,
495 void *data)
496{
497 struct zx_vga *vga = dev_get_drvdata(dev);
498
499 clk_disable_unprepare(vga->i2c_wclk);
500}
501
502static const struct component_ops zx_vga_component_ops = {
503 .bind = zx_vga_bind,
504 .unbind = zx_vga_unbind,
505};
506
507static int zx_vga_probe(struct platform_device *pdev)
508{
509 return component_add(&pdev->dev, &zx_vga_component_ops);
510}
511
512static int zx_vga_remove(struct platform_device *pdev)
513{
514 component_del(&pdev->dev, &zx_vga_component_ops);
515 return 0;
516}
517
518static const struct of_device_id zx_vga_of_match[] = {
519 { .compatible = "zte,zx296718-vga", },
520 { /* end */ },
521};
522MODULE_DEVICE_TABLE(of, zx_vga_of_match);
523
524struct platform_driver zx_vga_driver = {
525 .probe = zx_vga_probe,
526 .remove = zx_vga_remove,
527 .driver = {
528 .name = "zx-vga",
529 .of_match_table = zx_vga_of_match,
530 },
531};
diff --git a/drivers/gpu/drm/zte/zx_vga_regs.h b/drivers/gpu/drm/zte/zx_vga_regs.h
new file mode 100644
index 000000000000..feaa345fe6a6
--- /dev/null
+++ b/drivers/gpu/drm/zte/zx_vga_regs.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
3 * Copyright 2017 Linaro Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef __ZX_VGA_REGS_H__
11#define __ZX_VGA_REGS_H__
12
13#define VGA_CMD_CFG 0x04
14#define VGA_CMD_TRANS BIT(6)
15#define VGA_CMD_COMBO BIT(5)
16#define VGA_CMD_RW BIT(4)
17#define VGA_SUB_ADDR 0x0c
18#define VGA_DEVICE_ADDR 0x10
19#define VGA_CLK_DIV_FS 0x14
20#define VGA_RXF_CTRL 0x20
21#define VGA_RX_FIFO_CLEAR BIT(7)
22#define VGA_DATA 0x24
23#define VGA_I2C_STATUS 0x28
24#define VGA_DEVICE_DISCONNECTED BIT(7)
25#define VGA_DEVICE_CONNECTED BIT(6)
26#define VGA_CLEAR_IRQ BIT(4)
27#define VGA_TRANS_DONE BIT(0)
28#define VGA_RXF_STATUS 0x30
29#define VGA_RXF_COUNT_SHIFT 2
30#define VGA_RXF_COUNT_MASK GENMASK(7, 2)
31#define VGA_AUTO_DETECT_PARA 0x34
32#define VGA_AUTO_DETECT_SEL 0x38
33#define VGA_DETECT_SEL_HAS_DEVICE BIT(1)
34#define VGA_DETECT_SEL_NO_DEVICE BIT(0)
35
36#endif /* __ZX_VGA_REGS_H__ */
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index b500c8dd0d9d..5fbd10b60ee5 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -23,6 +23,7 @@
23#include <drm/drm_plane_helper.h> 23#include <drm/drm_plane_helper.h>
24#include <drm/drmP.h> 24#include <drm/drmP.h>
25 25
26#include "zx_common_regs.h"
26#include "zx_drm_drv.h" 27#include "zx_drm_drv.h"
27#include "zx_plane.h" 28#include "zx_plane.h"
28#include "zx_vou.h" 29#include "zx_vou.h"
@@ -122,6 +123,8 @@ struct zx_crtc {
122 struct drm_plane *primary; 123 struct drm_plane *primary;
123 struct zx_vou_hw *vou; 124 struct zx_vou_hw *vou;
124 void __iomem *chnreg; 125 void __iomem *chnreg;
126 void __iomem *chncsc;
127 void __iomem *dither;
125 const struct zx_crtc_regs *regs; 128 const struct zx_crtc_regs *regs;
126 const struct zx_crtc_bits *bits; 129 const struct zx_crtc_bits *bits;
127 enum vou_chn_type chn_type; 130 enum vou_chn_type chn_type;
@@ -204,6 +207,11 @@ static struct vou_inf vou_infs[] = {
204 .clocks_en_bits = BIT(15), 207 .clocks_en_bits = BIT(15),
205 .clocks_sel_bits = BIT(11) | BIT(0), 208 .clocks_sel_bits = BIT(11) | BIT(0),
206 }, 209 },
210 [VOU_VGA] = {
211 .data_sel = VOU_RGB_888,
212 .clocks_en_bits = BIT(1),
213 .clocks_sel_bits = BIT(10),
214 },
207}; 215};
208 216
209static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc) 217static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
@@ -227,9 +235,26 @@ void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
227 struct zx_crtc *zcrtc = to_zx_crtc(crtc); 235 struct zx_crtc *zcrtc = to_zx_crtc(crtc);
228 struct zx_vou_hw *vou = zcrtc->vou; 236 struct zx_vou_hw *vou = zcrtc->vou;
229 struct vou_inf *inf = &vou_infs[id]; 237 struct vou_inf *inf = &vou_infs[id];
238 void __iomem *dither = zcrtc->dither;
239 void __iomem *csc = zcrtc->chncsc;
230 bool is_main = zcrtc->chn_type == VOU_CHN_MAIN; 240 bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
231 u32 data_sel_shift = id << 1; 241 u32 data_sel_shift = id << 1;
232 242
243 if (inf->data_sel != VOU_YUV444) {
244 /* Enable channel CSC for RGB output */
245 zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
246 CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT);
247 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE,
248 CSC_WORK_ENABLE);
249
250 /* Bypass Dither block for RGB output */
251 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
252 DITHER_BYSPASS);
253 } else {
254 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
255 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
256 }
257
233 /* Select data format */ 258 /* Select data format */
234 zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift, 259 zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
235 inf->data_sel << data_sel_shift); 260 inf->data_sel << data_sel_shift);
@@ -525,20 +550,24 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
525 550
526 if (chn_type == VOU_CHN_MAIN) { 551 if (chn_type == VOU_CHN_MAIN) {
527 zplane->layer = vou->osd + MAIN_GL_OFFSET; 552 zplane->layer = vou->osd + MAIN_GL_OFFSET;
528 zplane->csc = vou->osd + MAIN_CSC_OFFSET; 553 zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET;
529 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET; 554 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
530 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET; 555 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
531 zplane->bits = &zx_gl_bits[0]; 556 zplane->bits = &zx_gl_bits[0];
532 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN; 557 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
558 zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET;
559 zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET;
533 zcrtc->regs = &main_crtc_regs; 560 zcrtc->regs = &main_crtc_regs;
534 zcrtc->bits = &main_crtc_bits; 561 zcrtc->bits = &main_crtc_bits;
535 } else { 562 } else {
536 zplane->layer = vou->osd + AUX_GL_OFFSET; 563 zplane->layer = vou->osd + AUX_GL_OFFSET;
537 zplane->csc = vou->osd + AUX_CSC_OFFSET; 564 zplane->csc = vou->osd + AUX_GL_CSC_OFFSET;
538 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET; 565 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
539 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET; 566 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
540 zplane->bits = &zx_gl_bits[1]; 567 zplane->bits = &zx_gl_bits[1];
541 zcrtc->chnreg = vou->osd + OSD_AUX_CHN; 568 zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
569 zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET;
570 zcrtc->dither = vou->osd + AUX_DITHER_OFFSET;
542 zcrtc->regs = &aux_crtc_regs; 571 zcrtc->regs = &aux_crtc_regs;
543 zcrtc->bits = &aux_crtc_bits; 572 zcrtc->bits = &aux_crtc_bits;
544 } 573 }
@@ -705,9 +734,6 @@ static void vou_hw_init(struct zx_vou_hw *vou)
705 /* Release reset for all VOU modules */ 734 /* Release reset for all VOU modules */
706 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0); 735 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
707 736
708 /* Enable clock auto-gating for all VOU modules */
709 zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
710
711 /* Enable all VOU module clocks */ 737 /* Enable all VOU module clocks */
712 zx_writel(vou->vouctl + VOU_CLK_EN, ~0); 738 zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
713 739
diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h
index c066ef123434..5a218351b497 100644
--- a/drivers/gpu/drm/zte/zx_vou_regs.h
+++ b/drivers/gpu/drm/zte/zx_vou_regs.h
@@ -13,13 +13,17 @@
13 13
14/* Sub-module offset */ 14/* Sub-module offset */
15#define MAIN_GL_OFFSET 0x130 15#define MAIN_GL_OFFSET 0x130
16#define MAIN_CSC_OFFSET 0x580 16#define MAIN_GL_CSC_OFFSET 0x580
17#define MAIN_CHN_CSC_OFFSET 0x6c0
17#define MAIN_HBSC_OFFSET 0x820 18#define MAIN_HBSC_OFFSET 0x820
19#define MAIN_DITHER_OFFSET 0x960
18#define MAIN_RSZ_OFFSET 0x600 /* OTFPPU sub-module */ 20#define MAIN_RSZ_OFFSET 0x600 /* OTFPPU sub-module */
19 21
20#define AUX_GL_OFFSET 0x200 22#define AUX_GL_OFFSET 0x200
21#define AUX_CSC_OFFSET 0x5d0 23#define AUX_GL_CSC_OFFSET 0x5d0
24#define AUX_CHN_CSC_OFFSET 0x710
22#define AUX_HBSC_OFFSET 0x860 25#define AUX_HBSC_OFFSET 0x860
26#define AUX_DITHER_OFFSET 0x970
23#define AUX_RSZ_OFFSET 0x800 27#define AUX_RSZ_OFFSET 0x800
24 28
25#define OSD_VL0_OFFSET 0x040 29#define OSD_VL0_OFFSET 0x040
@@ -78,6 +82,10 @@
78#define CHN_INTERLACE_BUF_CTRL 0x24 82#define CHN_INTERLACE_BUF_CTRL 0x24
79#define CHN_INTERLACE_EN BIT(2) 83#define CHN_INTERLACE_EN BIT(2)
80 84
85/* Dither registers */
86#define OSD_DITHER_CTRL0 0x00
87#define DITHER_BYSPASS BIT(31)
88
81/* TIMING_CTRL registers */ 89/* TIMING_CTRL registers */
82#define TIMING_TC_ENABLE 0x04 90#define TIMING_TC_ENABLE 0x04
83#define AUX_TC_EN BIT(1) 91#define AUX_TC_EN BIT(1)