All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/36] drm/omap: patches for 4.1
@ 2015-03-24 12:15 Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 01/36] drm: omapdrm: Fix indentation of structure and array initializers Tomi Valkeinen
                   ` (35 more replies)
  0 siblings, 36 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

Hi,

This series contains fixes and improvements for omapdrm. The patches from me
have already been sent earlier, and they have been changed according to the
received comments. The patches from Laurent have not been reviewed yet.

I'm resending my patches and the patches from Grygorii in this series, as I
have rebased them on top of Laurent's series as there were some conflicts
between the patches.

These are based on drm-next branch, and can be found from:

git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git 4.1/omapdrm

 Tomi

Grygorii Strashko (2):
  drm/omap: add hibernation callbacks
  drm/omap: tiler: add hibernation callback

Laurent Pinchart (14):
  drm: omapdrm: Fix indentation of structure and array initializers
  drm: omapdrm: Refactor CRTC creation code
  drm: omapdrm: Remove unused variables
  drm: omapdrm: Switch to the universal plane API
  drm: omapdrm: Rename omap_plane_dpms() to omap_plane_set_enable()
  drm: omapdrm: Reset the zorder property when disabling a plane
  drm: omapdrm: Fix race condition between GO and vblank IRQ
  drm: omapdrm: Remove manual update display support
  drm: omapdrm: Remove omap_crtc->full_update field
  drm: omapdrm: Avoid function forward declaration in omap_crtc.c
  drm: omapdrm: Prefix all plane functions with omap_plane_
  drm: omapdrm: Pass integer source coordinates to omap_plane_mode_set()
  drm: omapdrm: Planes are already disabled when destroyed
  drm: omapdrm: Reorder CRTC functions

Tomi Valkeinen (20):
  drm/omap: fix encoder-crtc mapping
  drm/omap: page_flip: return -EBUSY if flip pending
  drm/omap: clear omap_obj->paddr in omap_gem_put_paddr()
  drm/omap: add pin refcounting to omap_framebuffer
  drm/omap: add a comment why locking is missing
  drm/omap: fix operation without fbdev
  drm/omap: fix error handling in omap_framebuffer_create()
  drm/omap: handle incompatible buffer stride and pixel size
  drm/omap: fix TILER on OMAP5
  drm/omap: fix plane's channel selection
  drm/omap: tiler: fix race condition with engine->async
  drm/omap: remove dummy PM functions
  drm/omap: stop connector polling during suspend
  drm/omap: use DRM_ERROR_RATELIMITED() for error irqs
  drm/omap: fix race with error_irq
  drm/omap: only ignore DIGIT SYNC LOST for TV output
  drm/omap: do not use BUG_ON(!spin_is_locked(x))
  drm/omap: fix race condition with dev->obj_list
  drm/omap: fix race conditon in DMM
  drm/omap: keep ref to old_fb

 drivers/gpu/drm/omapdrm/omap_connector.c  |  12 -
 drivers/gpu/drm/omapdrm/omap_crtc.c       | 622 +++++++++++++++---------------
 drivers/gpu/drm/omapdrm/omap_dmm_priv.h   |   8 +-
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c  |  80 ++--
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.h  |   1 +
 drivers/gpu/drm/omapdrm/omap_drv.c        | 241 ++++++------
 drivers/gpu/drm/omapdrm/omap_drv.h        |  23 +-
 drivers/gpu/drm/omapdrm/omap_fb.c         |  66 ++--
 drivers/gpu/drm/omapdrm/omap_fbdev.c      |  57 +--
 drivers/gpu/drm/omapdrm/omap_gem.c        |  10 +-
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c |  20 +-
 drivers/gpu/drm/omapdrm/omap_irq.c        |   2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c      | 146 +++----
 13 files changed, 642 insertions(+), 646 deletions(-)

-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 01/36] drm: omapdrm: Fix indentation of structure and array initializers
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 02/36] drm: omapdrm: Refactor CRTC creation code Tomi Valkeinen
                   ` (34 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Indenting by one tab is enough.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c       |  26 ++++----
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c  |  16 ++---
 drivers/gpu/drm/omapdrm/omap_drv.c        | 106 +++++++++++++++---------------
 drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c |  20 +++---
 drivers/gpu/drm/omapdrm/omap_plane.c      |  24 +++----
 5 files changed, 96 insertions(+), 96 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index b0566a1ca28f..b9c3d8f830e8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -174,15 +174,15 @@ static void omap_crtc_unregister_framedone_handler(
 }
 
 static const struct dss_mgr_ops mgr_ops = {
-		.connect = omap_crtc_connect,
-		.disconnect = omap_crtc_disconnect,
-		.start_update = omap_crtc_start_update,
-		.enable = omap_crtc_enable,
-		.disable = omap_crtc_disable,
-		.set_timings = omap_crtc_set_timings,
-		.set_lcd_config = omap_crtc_set_lcd_config,
-		.register_framedone_handler = omap_crtc_register_framedone_handler,
-		.unregister_framedone_handler = omap_crtc_unregister_framedone_handler,
+	.connect = omap_crtc_connect,
+	.disconnect = omap_crtc_disconnect,
+	.start_update = omap_crtc_start_update,
+	.enable = omap_crtc_enable,
+	.disable = omap_crtc_disable,
+	.set_timings = omap_crtc_set_timings,
+	.set_lcd_config = omap_crtc_set_lcd_config,
+	.register_framedone_handler = omap_crtc_register_framedone_handler,
+	.unregister_framedone_handler = omap_crtc_unregister_framedone_handler,
 };
 
 /*
@@ -658,10 +658,10 @@ void omap_crtc_flush(struct drm_crtc *crtc)
 }
 
 static const char *channel_names[] = {
-		[OMAP_DSS_CHANNEL_LCD] = "lcd",
-		[OMAP_DSS_CHANNEL_DIGIT] = "tv",
-		[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
-		[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
+	[OMAP_DSS_CHANNEL_LCD] = "lcd",
+	[OMAP_DSS_CHANNEL_DIGIT] = "tv",
+	[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
+	[OMAP_DSS_CHANNEL_LCD3] = "lcd3",
 };
 
 void omap_crtc_pre_init(void)
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 56c60552abba..b4476859c1ad 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -58,19 +58,19 @@ static const struct {
 	uint32_t slot_w;	/* width of each slot (in pixels) */
 	uint32_t slot_h;	/* height of each slot (in pixels) */
 } geom[TILFMT_NFORMATS] = {
-		[TILFMT_8BIT]  = GEOM(0, 0, 1),
-		[TILFMT_16BIT] = GEOM(0, 1, 2),
-		[TILFMT_32BIT] = GEOM(1, 1, 4),
-		[TILFMT_PAGE]  = GEOM(SLOT_WIDTH_BITS, SLOT_HEIGHT_BITS, 1),
+	[TILFMT_8BIT]  = GEOM(0, 0, 1),
+	[TILFMT_16BIT] = GEOM(0, 1, 2),
+	[TILFMT_32BIT] = GEOM(1, 1, 4),
+	[TILFMT_PAGE]  = GEOM(SLOT_WIDTH_BITS, SLOT_HEIGHT_BITS, 1),
 };
 
 
 /* lookup table for registers w/ per-engine instances */
 static const uint32_t reg[][4] = {
-		[PAT_STATUS] = {DMM_PAT_STATUS__0, DMM_PAT_STATUS__1,
-				DMM_PAT_STATUS__2, DMM_PAT_STATUS__3},
-		[PAT_DESCR]  = {DMM_PAT_DESCR__0, DMM_PAT_DESCR__1,
-				DMM_PAT_DESCR__2, DMM_PAT_DESCR__3},
+	[PAT_STATUS] = {DMM_PAT_STATUS__0, DMM_PAT_STATUS__1,
+			DMM_PAT_STATUS__2, DMM_PAT_STATUS__3},
+	[PAT_DESCR]  = {DMM_PAT_DESCR__0, DMM_PAT_DESCR__1,
+			DMM_PAT_DESCR__2, DMM_PAT_DESCR__3},
 };
 
 /* simple allocator to grab next 16 byte aligned memory from txn */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 8241ed9b353c..642748cb7a4e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -610,55 +610,55 @@ static const struct vm_operations_struct omap_gem_vm_ops = {
 };
 
 static const struct file_operations omapdriver_fops = {
-		.owner = THIS_MODULE,
-		.open = drm_open,
-		.unlocked_ioctl = drm_ioctl,
-		.release = drm_release,
-		.mmap = omap_gem_mmap,
-		.poll = drm_poll,
-		.read = drm_read,
-		.llseek = noop_llseek,
+	.owner = THIS_MODULE,
+	.open = drm_open,
+	.unlocked_ioctl = drm_ioctl,
+	.release = drm_release,
+	.mmap = omap_gem_mmap,
+	.poll = drm_poll,
+	.read = drm_read,
+	.llseek = noop_llseek,
 };
 
 static struct drm_driver omap_drm_driver = {
-		.driver_features =
-				DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
-		.load = dev_load,
-		.unload = dev_unload,
-		.open = dev_open,
-		.lastclose = dev_lastclose,
-		.preclose = dev_preclose,
-		.postclose = dev_postclose,
-		.set_busid = drm_platform_set_busid,
-		.get_vblank_counter = drm_vblank_count,
-		.enable_vblank = omap_irq_enable_vblank,
-		.disable_vblank = omap_irq_disable_vblank,
-		.irq_preinstall = omap_irq_preinstall,
-		.irq_postinstall = omap_irq_postinstall,
-		.irq_uninstall = omap_irq_uninstall,
-		.irq_handler = omap_irq_handler,
+	.driver_features = DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM
+			 | DRIVER_PRIME,
+	.load = dev_load,
+	.unload = dev_unload,
+	.open = dev_open,
+	.lastclose = dev_lastclose,
+	.preclose = dev_preclose,
+	.postclose = dev_postclose,
+	.set_busid = drm_platform_set_busid,
+	.get_vblank_counter = drm_vblank_count,
+	.enable_vblank = omap_irq_enable_vblank,
+	.disable_vblank = omap_irq_disable_vblank,
+	.irq_preinstall = omap_irq_preinstall,
+	.irq_postinstall = omap_irq_postinstall,
+	.irq_uninstall = omap_irq_uninstall,
+	.irq_handler = omap_irq_handler,
 #ifdef CONFIG_DEBUG_FS
-		.debugfs_init = omap_debugfs_init,
-		.debugfs_cleanup = omap_debugfs_cleanup,
+	.debugfs_init = omap_debugfs_init,
+	.debugfs_cleanup = omap_debugfs_cleanup,
 #endif
-		.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
-		.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
-		.gem_prime_export = omap_gem_prime_export,
-		.gem_prime_import = omap_gem_prime_import,
-		.gem_free_object = omap_gem_free_object,
-		.gem_vm_ops = &omap_gem_vm_ops,
-		.dumb_create = omap_gem_dumb_create,
-		.dumb_map_offset = omap_gem_dumb_map_offset,
-		.dumb_destroy = drm_gem_dumb_destroy,
-		.ioctls = ioctls,
-		.num_ioctls = DRM_OMAP_NUM_IOCTLS,
-		.fops = &omapdriver_fops,
-		.name = DRIVER_NAME,
-		.desc = DRIVER_DESC,
-		.date = DRIVER_DATE,
-		.major = DRIVER_MAJOR,
-		.minor = DRIVER_MINOR,
-		.patchlevel = DRIVER_PATCHLEVEL,
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_export = omap_gem_prime_export,
+	.gem_prime_import = omap_gem_prime_import,
+	.gem_free_object = omap_gem_free_object,
+	.gem_vm_ops = &omap_gem_vm_ops,
+	.dumb_create = omap_gem_dumb_create,
+	.dumb_map_offset = omap_gem_dumb_map_offset,
+	.dumb_destroy = drm_gem_dumb_destroy,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_OMAP_NUM_IOCTLS,
+	.fops = &omapdriver_fops,
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int pdev_suspend(struct platform_device *pDevice, pm_message_t state)
@@ -716,17 +716,17 @@ static const struct dev_pm_ops omapdrm_pm_ops = {
 #endif
 
 static struct platform_driver pdev = {
-		.driver = {
-			.name = DRIVER_NAME,
+	.driver = {
+		.name = DRIVER_NAME,
 #ifdef CONFIG_PM
-			.pm = &omapdrm_pm_ops,
+		.pm = &omapdrm_pm_ops,
 #endif
-		},
-		.probe = pdev_probe,
-		.remove = pdev_remove,
-		.suspend = pdev_suspend,
-		.resume = pdev_resume,
-		.shutdown = pdev_shutdown,
+	},
+	.probe = pdev_probe,
+	.remove = pdev_remove,
+	.suspend = pdev_suspend,
+	.resume = pdev_resume,
+	.shutdown = pdev_shutdown,
 };
 
 static int __init omap_drm_init(void)
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index a2dbfb1737b4..b46dabd9faf7 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -156,16 +156,16 @@ static int omap_gem_dmabuf_mmap(struct dma_buf *buffer,
 }
 
 static struct dma_buf_ops omap_dmabuf_ops = {
-		.map_dma_buf = omap_gem_map_dma_buf,
-		.unmap_dma_buf = omap_gem_unmap_dma_buf,
-		.release = omap_gem_dmabuf_release,
-		.begin_cpu_access = omap_gem_dmabuf_begin_cpu_access,
-		.end_cpu_access = omap_gem_dmabuf_end_cpu_access,
-		.kmap_atomic = omap_gem_dmabuf_kmap_atomic,
-		.kunmap_atomic = omap_gem_dmabuf_kunmap_atomic,
-		.kmap = omap_gem_dmabuf_kmap,
-		.kunmap = omap_gem_dmabuf_kunmap,
-		.mmap = omap_gem_dmabuf_mmap,
+	.map_dma_buf = omap_gem_map_dma_buf,
+	.unmap_dma_buf = omap_gem_unmap_dma_buf,
+	.release = omap_gem_dmabuf_release,
+	.begin_cpu_access = omap_gem_dmabuf_begin_cpu_access,
+	.end_cpu_access = omap_gem_dmabuf_end_cpu_access,
+	.kmap_atomic = omap_gem_dmabuf_kmap_atomic,
+	.kunmap_atomic = omap_gem_dmabuf_kunmap_atomic,
+	.kmap = omap_gem_dmabuf_kmap,
+	.kunmap = omap_gem_dmabuf_kunmap,
+	.mmap = omap_gem_dmabuf_mmap,
 };
 
 struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index ee8e2b3a117e..a418fa7e5d0e 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -353,10 +353,10 @@ int omap_plane_set_property(struct drm_plane *plane,
 }
 
 static const struct drm_plane_funcs omap_plane_funcs = {
-		.update_plane = omap_plane_update,
-		.disable_plane = omap_plane_disable,
-		.destroy = omap_plane_destroy,
-		.set_property = omap_plane_set_property,
+	.update_plane = omap_plane_update,
+	.disable_plane = omap_plane_disable,
+	.destroy = omap_plane_destroy,
+	.set_property = omap_plane_set_property,
 };
 
 static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -367,17 +367,17 @@ static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 }
 
 static const char *plane_names[] = {
-		[OMAP_DSS_GFX] = "gfx",
-		[OMAP_DSS_VIDEO1] = "vid1",
-		[OMAP_DSS_VIDEO2] = "vid2",
-		[OMAP_DSS_VIDEO3] = "vid3",
+	[OMAP_DSS_GFX] = "gfx",
+	[OMAP_DSS_VIDEO1] = "vid1",
+	[OMAP_DSS_VIDEO2] = "vid2",
+	[OMAP_DSS_VIDEO3] = "vid3",
 };
 
 static const uint32_t error_irqs[] = {
-		[OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW,
-		[OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW,
-		[OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW,
-		[OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW,
+	[OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW,
+	[OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW,
+	[OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW,
+	[OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW,
 };
 
 /* initialize plane */
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 02/36] drm: omapdrm: Refactor CRTC creation code
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 01/36] drm: omapdrm: Fix indentation of structure and array initializers Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 03/36] drm: omapdrm: Remove unused variables Tomi Valkeinen
                   ` (33 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Create a omap_modeset_create_crtc() function to avoid duplicating plane
and CRTC creation code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c   | 76 +++++++++++++++++++++---------------
 drivers/gpu/drm/omapdrm/omap_plane.c |  2 +-
 2 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 642748cb7a4e..021855605a1f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -128,6 +128,29 @@ cleanup:
 	return r;
 }
 
+static int omap_modeset_create_crtc(struct drm_device *dev, int id,
+				    enum omap_channel channel)
+{
+	struct omap_drm_private *priv = dev->dev_private;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+
+	plane = omap_plane_init(dev, id, true);
+	if (IS_ERR(plane))
+		return PTR_ERR(plane);
+
+	crtc = omap_crtc_init(dev, plane, channel, id);
+
+	BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
+	priv->crtcs[id] = crtc;
+	priv->num_crtcs++;
+
+	priv->planes[id] = plane;
+	priv->num_planes++;
+
+	return 0;
+}
+
 static int omap_modeset_init(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
@@ -136,6 +159,7 @@ static int omap_modeset_init(struct drm_device *dev)
 	int num_mgrs = dss_feat_get_num_mgrs();
 	int num_crtcs;
 	int i, id = 0;
+	int ret;
 
 	drm_mode_config_init(dev);
 
@@ -209,18 +233,13 @@ static int omap_modeset_init(struct drm_device *dev)
 		 * allocated crtc, we create a new crtc for it
 		 */
 		if (!channel_used(dev, channel)) {
-			struct drm_plane *plane;
-			struct drm_crtc *crtc;
-
-			plane = omap_plane_init(dev, id, true);
-			crtc = omap_crtc_init(dev, plane, channel, id);
-
-			BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
-			priv->crtcs[id] = crtc;
-			priv->num_crtcs++;
-
-			priv->planes[id] = plane;
-			priv->num_planes++;
+			ret = omap_modeset_create_crtc(dev, id, channel);
+			if (ret < 0) {
+				dev_err(dev->dev,
+					"could not create CRTC (channel %u)\n",
+					channel);
+				return ret;
+			}
 
 			id++;
 		}
@@ -234,26 +253,8 @@ static int omap_modeset_init(struct drm_device *dev)
 
 		/* find a free manager for this crtc */
 		for (i = 0; i < num_mgrs; i++) {
-			if (!channel_used(dev, i)) {
-				struct drm_plane *plane;
-				struct drm_crtc *crtc;
-
-				plane = omap_plane_init(dev, id, true);
-				crtc = omap_crtc_init(dev, plane, i, id);
-
-				BUG_ON(priv->num_crtcs >=
-					ARRAY_SIZE(priv->crtcs));
-
-				priv->crtcs[id] = crtc;
-				priv->num_crtcs++;
-
-				priv->planes[id] = plane;
-				priv->num_planes++;
-
+			if (!channel_used(dev, i))
 				break;
-			} else {
-				continue;
-			}
 		}
 
 		if (i == num_mgrs) {
@@ -261,13 +262,24 @@ static int omap_modeset_init(struct drm_device *dev)
 			dev_err(dev->dev, "no managers left for crtc\n");
 			return -ENOMEM;
 		}
+
+		ret = omap_modeset_create_crtc(dev, id, i);
+		if (ret < 0) {
+			dev_err(dev->dev,
+				"could not create CRTC (channel %u)\n", i);
+			return ret;
+		}
 	}
 
 	/*
 	 * Create normal planes for the remaining overlays:
 	 */
 	for (; id < num_ovls; id++) {
-		struct drm_plane *plane = omap_plane_init(dev, id, false);
+		struct drm_plane *plane;
+
+		plane = omap_plane_init(dev, id, false);
+		if (IS_ERR(plane))
+			return PTR_ERR(plane);
 
 		BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
 		priv->planes[priv->num_planes++] = plane;
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index a418fa7e5d0e..056ded8280f8 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -393,7 +393,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 
 	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
 	if (!omap_plane)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	drm_flip_work_init(&omap_plane->unpin_work,
 			"unpin", unpin_worker);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 03/36] drm: omapdrm: Remove unused variables
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 01/36] drm: omapdrm: Fix indentation of structure and array initializers Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 02/36] drm: omapdrm: Refactor CRTC creation code Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 04/36] drm: omapdrm: Switch to the universal plane API Tomi Valkeinen
                   ` (32 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The ilace variable is unused and the replication variable is assigned to
false and just passed to a function. Remove them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 056ded8280f8..c17460336fcc 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -121,7 +121,6 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
 	struct drm_crtc *crtc = plane->crtc;
 	enum omap_channel channel;
 	bool enabled = omap_plane->enabled && crtc;
-	bool ilace, replication;
 	int ret;
 
 	DBG("%s, enabled=%d", omap_plane->name, enabled);
@@ -145,13 +144,9 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
 	DBG("%d,%d %pad %pad", info->pos_x, info->pos_y,
 			&info->paddr, &info->p_uv_addr);
 
-	/* TODO: */
-	ilace = false;
-	replication = false;
-
 	/* and finally, update omapdss: */
-	ret = dispc_ovl_setup(omap_plane->id, info,
-			replication, omap_crtc_timings(crtc), false);
+	ret = dispc_ovl_setup(omap_plane->id, info, false,
+			      omap_crtc_timings(crtc), false);
 	if (ret) {
 		dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret);
 		return;
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 04/36] drm: omapdrm: Switch to the universal plane API
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (2 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 03/36] drm: omapdrm: Remove unused variables Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 05/36] drm: omapdrm: Rename omap_plane_dpms() to omap_plane_set_enable() Tomi Valkeinen
                   ` (31 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Remove the CRTC private planes by switching to the universal plane API.
This results in a merge of the CRTC private plane created by the driver
(omap_crtc->plane) and the CRTC primary plane created by the DRM core
(crtc->primary).

Reference counting of the framebuffers in the update plane operation is
thus simplified as no reference needs to be stored in the private plane
anymore.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 43 ++++++++++++++++++------------------
 drivers/gpu/drm/omapdrm/omap_drv.c   |  4 ++--
 drivers/gpu/drm/omapdrm/omap_drv.h   |  2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c | 36 ++++++++++++++++++------------
 4 files changed, 46 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index b9c3d8f830e8..7570db59a9ea 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -28,7 +28,6 @@
 
 struct omap_crtc {
 	struct drm_crtc base;
-	struct drm_plane *plane;
 
 	const char *name;
 	int pipe;
@@ -217,10 +216,7 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 		omap_crtc->full_update = true;
 		omap_crtc_apply(crtc, &omap_crtc->apply);
 
-		/* also enable our private plane: */
-		WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));
-
-		/* and any attached overlay planes: */
+		/* Enable/disable all planes associated with the CRTC. */
 		for (i = 0; i < priv->num_planes; i++) {
 			struct drm_plane *plane = priv->planes[i];
 			if (plane->crtc == crtc)
@@ -258,7 +254,13 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
 	copy_timings_drm_to_omap(&omap_crtc->timings, mode);
 	omap_crtc->full_update = true;
 
-	return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
+	/*
+	 * The primary plane CRTC can be reset if the plane is disabled directly
+	 * through the universal plane API. Set it again here.
+	 */
+	crtc->primary->crtc = crtc;
+
+	return omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
 			0, 0, mode->hdisplay, mode->vdisplay,
 			x << 16, y << 16,
 			mode->hdisplay << 16, mode->vdisplay << 16,
@@ -282,8 +284,7 @@ static void omap_crtc_commit(struct drm_crtc *crtc)
 static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 		struct drm_framebuffer *old_fb)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	struct drm_plane *plane = omap_crtc->plane;
+	struct drm_plane *plane = crtc->primary;
 	struct drm_display_mode *mode = &crtc->mode;
 
 	return omap_plane_mode_set(plane, crtc, crtc->primary->fb,
@@ -321,7 +322,7 @@ static void page_flip_worker(struct work_struct *work)
 	struct drm_gem_object *bo;
 
 	drm_modeset_lock(&crtc->mutex, NULL);
-	omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
+	omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
 			0, 0, mode->hdisplay, mode->vdisplay,
 			crtc->x << 16, crtc->y << 16,
 			mode->hdisplay << 16, mode->vdisplay << 16,
@@ -385,7 +386,6 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 static int omap_crtc_set_property(struct drm_crtc *crtc,
 		struct drm_property *property, uint64_t val)
 {
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	struct omap_drm_private *priv = crtc->dev->dev_private;
 
 	if (property == priv->rotation_prop) {
@@ -393,7 +393,7 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,
 				!!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270)));
 	}
 
-	return omap_plane_set_property(omap_crtc->plane, property, val);
+	return omap_plane_set_property(crtc->primary, property, val);
 }
 
 static const struct drm_crtc_funcs omap_crtc_funcs = {
@@ -681,12 +681,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	struct drm_crtc *crtc = NULL;
 	struct omap_crtc *omap_crtc;
 	struct omap_overlay_manager_info *info;
+	int ret;
 
 	DBG("%s", channel_names[channel]);
 
 	omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
 	if (!omap_crtc)
-		goto fail;
+		return NULL;
 
 	crtc = &omap_crtc->base;
 
@@ -700,8 +701,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	omap_crtc->apply.post_apply = omap_crtc_post_apply;
 
 	omap_crtc->channel = channel;
-	omap_crtc->plane = plane;
-	omap_crtc->plane->crtc = crtc;
 	omap_crtc->name = channel_names[channel];
 	omap_crtc->pipe = id;
 
@@ -723,18 +722,18 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 	info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
 	info->trans_enabled = false;
 
-	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
+	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
+					&omap_crtc_funcs);
+	if (ret < 0) {
+		kfree(omap_crtc);
+		return NULL;
+	}
+
 	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
 
-	omap_plane_install_properties(omap_crtc->plane, &crtc->base);
+	omap_plane_install_properties(crtc->primary, &crtc->base);
 
 	omap_crtcs[channel] = omap_crtc;
 
 	return crtc;
-
-fail:
-	if (crtc)
-		omap_crtc_destroy(crtc);
-
-	return NULL;
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 021855605a1f..5eab83d7de15 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -135,7 +135,7 @@ static int omap_modeset_create_crtc(struct drm_device *dev, int id,
 	struct drm_plane *plane;
 	struct drm_crtc *crtc;
 
-	plane = omap_plane_init(dev, id, true);
+	plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_PRIMARY);
 	if (IS_ERR(plane))
 		return PTR_ERR(plane);
 
@@ -277,7 +277,7 @@ static int omap_modeset_init(struct drm_device *dev)
 	for (; id < num_ovls; id++) {
 		struct drm_plane *plane;
 
-		plane = omap_plane_init(dev, id, false);
+		plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_OVERLAY);
 		if (IS_ERR(plane))
 			return PTR_ERR(plane);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 60e47b33c801..f38ffd14ff06 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -160,7 +160,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 void omap_crtc_flush(struct drm_crtc *crtc);
 
 struct drm_plane *omap_plane_init(struct drm_device *dev,
-		int plane_id, bool private_plane);
+		int id, enum drm_plane_type type);
 int omap_plane_dpms(struct drm_plane *plane, int mode);
 int omap_plane_mode_set(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct drm_framebuffer *fb,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index c17460336fcc..32df3e783128 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -220,14 +220,6 @@ int omap_plane_mode_set(struct drm_plane *plane,
 		omap_plane->apply_done_cb.arg = arg;
 	}
 
-	if (plane->fb)
-		drm_framebuffer_unreference(plane->fb);
-
-	drm_framebuffer_reference(fb);
-
-	plane->fb = fb;
-	plane->crtc = crtc;
-
 	return apply(plane);
 }
 
@@ -249,6 +241,13 @@ static int omap_plane_update(struct drm_plane *plane,
 		break;
 	}
 
+	/*
+	 * We don't need to take a reference to the framebuffer as the DRM core
+	 * has already done so for the purpose of setting plane->fb.
+	 */
+	plane->fb = fb;
+	plane->crtc = crtc;
+
 	return omap_plane_mode_set(plane, crtc, fb,
 			crtc_x, crtc_y, crtc_w, crtc_h,
 			src_x, src_y, src_w, src_h,
@@ -377,14 +376,15 @@ static const uint32_t error_irqs[] = {
 
 /* initialize plane */
 struct drm_plane *omap_plane_init(struct drm_device *dev,
-		int id, bool private_plane)
+		int id, enum drm_plane_type type)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	struct drm_plane *plane = NULL;
+	struct drm_plane *plane;
 	struct omap_plane *omap_plane;
 	struct omap_overlay_info *info;
+	int ret;
 
-	DBG("%s: priv=%d", plane_names[id], private_plane);
+	DBG("%s: type=%d", plane_names[id], type);
 
 	omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
 	if (!omap_plane)
@@ -408,8 +408,11 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 	omap_plane->error_irq.irq = omap_plane_error_irq;
 	omap_irq_register(dev, &omap_plane->error_irq);
 
-	drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs,
-			omap_plane->formats, omap_plane->nformats, private_plane);
+	ret = drm_universal_plane_init(dev, plane, (1 << priv->num_crtcs) - 1,
+				       &omap_plane_funcs, omap_plane->formats,
+				       omap_plane->nformats, type);
+	if (ret < 0)
+		goto error;
 
 	omap_plane_install_properties(plane, &plane->base);
 
@@ -427,10 +430,15 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 	 * TODO add ioctl to give userspace an API to change this.. this
 	 * will come in a subsequent patch.
 	 */
-	if (private_plane)
+	if (type == DRM_PLANE_TYPE_PRIMARY)
 		omap_plane->info.zorder = 0;
 	else
 		omap_plane->info.zorder = id;
 
 	return plane;
+
+error:
+	omap_irq_unregister(plane->dev, &omap_plane->error_irq);
+	kfree(omap_plane);
+	return NULL;
 }
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 05/36] drm: omapdrm: Rename omap_plane_dpms() to omap_plane_set_enable()
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (3 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 04/36] drm: omapdrm: Switch to the universal plane API Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 06/36] drm: omapdrm: Reset the zorder property when disabling a plane Tomi Valkeinen
                   ` (30 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The planes don't care about DPMS states, don't propagate it
unnecessarily to the plane functions.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  |  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.h   |  2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c | 16 +++++++---------
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 7570db59a9ea..c7d3e1eec6cb 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -220,7 +220,7 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 		for (i = 0; i < priv->num_planes; i++) {
 			struct drm_plane *plane = priv->planes[i];
 			if (plane->crtc == crtc)
-				WARN_ON(omap_plane_dpms(plane, mode));
+				WARN_ON(omap_plane_set_enable(plane, enabled));
 		}
 	}
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index f38ffd14ff06..fa6becc4d1be 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -161,7 +161,7 @@ void omap_crtc_flush(struct drm_crtc *crtc);
 
 struct drm_plane *omap_plane_init(struct drm_device *dev,
 		int id, enum drm_plane_type type);
-int omap_plane_dpms(struct drm_plane *plane, int mode);
+int omap_plane_set_enable(struct drm_plane *plane, bool enable);
 int omap_plane_mode_set(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct drm_framebuffer *fb,
 		int crtc_x, int crtc_y,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 32df3e783128..34f5cca5a6c5 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -257,8 +257,9 @@ static int omap_plane_update(struct drm_plane *plane,
 static int omap_plane_disable(struct drm_plane *plane)
 {
 	struct omap_plane *omap_plane = to_omap_plane(plane);
+
 	omap_plane->win.rotation = BIT(DRM_ROTATE_0);
-	return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
+	return omap_plane_set_enable(plane, false);
 }
 
 static void omap_plane_destroy(struct drm_plane *plane)
@@ -277,18 +278,15 @@ static void omap_plane_destroy(struct drm_plane *plane)
 	kfree(omap_plane);
 }
 
-int omap_plane_dpms(struct drm_plane *plane, int mode)
+int omap_plane_set_enable(struct drm_plane *plane, bool enable)
 {
 	struct omap_plane *omap_plane = to_omap_plane(plane);
-	bool enabled = (mode == DRM_MODE_DPMS_ON);
-	int ret = 0;
 
-	if (enabled != omap_plane->enabled) {
-		omap_plane->enabled = enabled;
-		ret = apply(plane);
-	}
+	if (enable == omap_plane->enabled)
+		return 0;
 
-	return ret;
+	omap_plane->enabled = enable;
+	return apply(plane);
 }
 
 /* helper to install properties which are common to planes and crtcs */
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 06/36] drm: omapdrm: Reset the zorder property when disabling a plane
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (4 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 05/36] drm: omapdrm: Rename omap_plane_dpms() to omap_plane_set_enable() Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 07/36] drm: omapdrm: Fix race condition between GO and vblank IRQ Tomi Valkeinen
                   ` (29 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Whether to reset plane properties at disable time isn't well-defined in
DRM, but resetting only part of them is probably as bad as it can get.
Make the behaviour coherent by resetting the zorder property in addition
to the rotation property.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 34f5cca5a6c5..efec4265c2ae 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -259,6 +259,9 @@ static int omap_plane_disable(struct drm_plane *plane)
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 
 	omap_plane->win.rotation = BIT(DRM_ROTATE_0);
+	omap_plane->info.zorder = plane->type == DRM_PLANE_TYPE_PRIMARY
+				? 0 : omap_plane->id;
+
 	return omap_plane_set_enable(plane, false);
 }
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 07/36] drm: omapdrm: Fix race condition between GO and vblank IRQ
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (5 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 06/36] drm: omapdrm: Reset the zorder property when disabling a plane Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 08/36] drm: omapdrm: Remove manual update display support Tomi Valkeinen
                   ` (28 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The vblank interrupt is used by the driver as a completion signal when
applying new settings.

A race condition exist between enabling the vblank interrupt and
applying new settings to the hardware by setting the GO bit. If a vblank
interrupt occurs in-between, the driver will incorrectly consider the
new settings to be applied. Fix this by enabling the interrupt after
setting the GO bit.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index c7d3e1eec6cb..3f811186c891 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -501,8 +501,8 @@ static void apply_worker(struct work_struct *work)
 		DBG("%s: GO", omap_crtc->name);
 
 		if (dispc_mgr_is_enabled(channel)) {
-			omap_irq_register(dev, &omap_crtc->apply_irq);
 			dispc_mgr_go(channel);
+			omap_irq_register(dev, &omap_crtc->apply_irq);
 		} else {
 			struct omap_drm_private *priv = dev->dev_private;
 			queue_work(priv->wq, &omap_crtc->apply_work);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 08/36] drm: omapdrm: Remove manual update display support
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (6 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 07/36] drm: omapdrm: Fix race condition between GO and vblank IRQ Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 09/36] drm: omapdrm: Remove omap_crtc->full_update field Tomi Valkeinen
                   ` (27 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

All the manual update display code implements eventually ends up to just
calls to omap_connector_flush(), currently implemented as an empty TODO
stub. Remove it, the code can always be revived and implemented later if
interest in manual update displays becomes a reality.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 12 -------
 drivers/gpu/drm/omapdrm/omap_drv.h       |  4 ---
 drivers/gpu/drm/omapdrm/omap_fb.c        | 40 ----------------------
 drivers/gpu/drm/omapdrm/omap_fbdev.c     | 57 +++-----------------------------
 drivers/gpu/drm/omapdrm/omap_plane.c     |  6 ----
 5 files changed, 4 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index a94b11f7859d..b41965c2888d 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -271,18 +271,6 @@ static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
 	.best_encoder = omap_connector_attached_encoder,
 };
 
-/* flush an area of the framebuffer (in case of manual update display that
- * is not automatically flushed)
- */
-void omap_connector_flush(struct drm_connector *connector,
-		int x, int y, int w, int h)
-{
-	struct omap_connector *omap_connector = to_omap_connector(connector);
-
-	/* TODO: enable when supported in dss */
-	VERB("%s: %d,%d, %dx%d", omap_connector->dssdev->name, x, y, w, h);
-}
-
 /* initialize connector */
 struct drm_connector *omap_connector_init(struct drm_device *dev,
 		int connector_type, struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index fa6becc4d1be..1805edc0107d 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -186,8 +186,6 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
 		struct drm_encoder *encoder);
 struct drm_encoder *omap_connector_attached_encoder(
 		struct drm_connector *connector);
-void omap_connector_flush(struct drm_connector *connector,
-		int x, int y, int w, int h);
 bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
 
 void copy_timings_omap_to_drm(struct drm_display_mode *mode,
@@ -208,8 +206,6 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
 		struct omap_drm_window *win, struct omap_overlay_info *info);
 struct drm_connector *omap_framebuffer_get_next_connector(
 		struct drm_framebuffer *fb, struct drm_connector *from);
-void omap_framebuffer_flush(struct drm_framebuffer *fb,
-		int x, int y, int w, int h);
 
 void omap_gem_init(struct drm_device *dev);
 void omap_gem_deinit(struct drm_device *dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 2a5cacdc344b..45dd9eed9c57 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -121,18 +121,6 @@ static int omap_framebuffer_dirty(struct drm_framebuffer *fb,
 		struct drm_file *file_priv, unsigned flags, unsigned color,
 		struct drm_clip_rect *clips, unsigned num_clips)
 {
-	int i;
-
-	drm_modeset_lock_all(fb->dev);
-
-	for (i = 0; i < num_clips; i++) {
-		omap_framebuffer_flush(fb, clips[i].x1, clips[i].y1,
-					clips[i].x2 - clips[i].x1,
-					clips[i].y2 - clips[i].y1);
-	}
-
-	drm_modeset_unlock_all(fb->dev);
-
 	return 0;
 }
 
@@ -336,34 +324,6 @@ struct drm_connector *omap_framebuffer_get_next_connector(
 	return NULL;
 }
 
-/* flush an area of the framebuffer (in case of manual update display that
- * is not automatically flushed)
- */
-void omap_framebuffer_flush(struct drm_framebuffer *fb,
-		int x, int y, int w, int h)
-{
-	struct drm_connector *connector = NULL;
-
-	VERB("flush: %d,%d %dx%d, fb=%p", x, y, w, h, fb);
-
-	/* FIXME: This is racy - no protection against modeset config changes. */
-	while ((connector = omap_framebuffer_get_next_connector(fb, connector))) {
-		/* only consider connectors that are part of a chain */
-		if (connector->encoder && connector->encoder->crtc) {
-			/* TODO: maybe this should propagate thru the crtc who
-			 * could do the coordinate translation..
-			 */
-			struct drm_crtc *crtc = connector->encoder->crtc;
-			int cx = max(0, x - crtc->x);
-			int cy = max(0, y - crtc->y);
-			int cw = w + (x - crtc->x) - cx;
-			int ch = h + (y - crtc->y) - cy;
-
-			omap_connector_flush(connector, cx, cy, cw, ch);
-		}
-	}
-}
-
 #ifdef CONFIG_DEBUG_FS
 void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
 {
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index d292d24b3a6e..950cd3389092 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -42,42 +42,8 @@ struct omap_fbdev {
 	struct work_struct work;
 };
 
-static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h);
 static struct drm_fb_helper *get_fb(struct fb_info *fbi);
 
-static ssize_t omap_fbdev_write(struct fb_info *fbi, const char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	ssize_t res;
-
-	res = fb_sys_write(fbi, buf, count, ppos);
-	omap_fbdev_flush(fbi, 0, 0, fbi->var.xres, fbi->var.yres);
-
-	return res;
-}
-
-static void omap_fbdev_fillrect(struct fb_info *fbi,
-		const struct fb_fillrect *rect)
-{
-	sys_fillrect(fbi, rect);
-	omap_fbdev_flush(fbi, rect->dx, rect->dy, rect->width, rect->height);
-}
-
-static void omap_fbdev_copyarea(struct fb_info *fbi,
-		const struct fb_copyarea *area)
-{
-	sys_copyarea(fbi, area);
-	omap_fbdev_flush(fbi, area->dx, area->dy, area->width, area->height);
-}
-
-static void omap_fbdev_imageblit(struct fb_info *fbi,
-		const struct fb_image *image)
-{
-	sys_imageblit(fbi, image);
-	omap_fbdev_flush(fbi, image->dx, image->dy,
-				image->width, image->height);
-}
-
 static void pan_worker(struct work_struct *work)
 {
 	struct omap_fbdev *fbdev = container_of(work, struct omap_fbdev, work);
@@ -121,10 +87,10 @@ static struct fb_ops omap_fb_ops = {
 	 * basic fbdev ops which write to the framebuffer
 	 */
 	.fb_read = fb_sys_read,
-	.fb_write = omap_fbdev_write,
-	.fb_fillrect = omap_fbdev_fillrect,
-	.fb_copyarea = omap_fbdev_copyarea,
-	.fb_imageblit = omap_fbdev_imageblit,
+	.fb_write = fb_sys_write,
+	.fb_fillrect = sys_fillrect,
+	.fb_copyarea = sys_copyarea,
+	.fb_imageblit = sys_imageblit,
 
 	.fb_check_var = drm_fb_helper_check_var,
 	.fb_set_par = drm_fb_helper_set_par,
@@ -294,21 +260,6 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi)
 	return fbi->par;
 }
 
-/* flush an area of the framebuffer (in case of manual update display that
- * is not automatically flushed)
- */
-static void omap_fbdev_flush(struct fb_info *fbi, int x, int y, int w, int h)
-{
-	struct drm_fb_helper *helper = get_fb(fbi);
-
-	if (!helper)
-		return;
-
-	VERB("flush fbdev: %d,%d %dx%d, fbi=%p", x, y, w, h, fbi);
-
-	omap_framebuffer_flush(helper->fb, x, y, w, h);
-}
-
 /* initialize fbdev helper */
 struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev)
 {
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index efec4265c2ae..2111d415da96 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -162,7 +162,6 @@ static void omap_plane_post_apply(struct omap_drm_apply *apply)
 			container_of(apply, struct omap_plane, apply);
 	struct drm_plane *plane = &omap_plane->base;
 	struct omap_drm_private *priv = plane->dev->dev_private;
-	struct omap_overlay_info *info = &omap_plane->info;
 	struct callback cb;
 
 	cb = omap_plane->apply_done_cb;
@@ -172,11 +171,6 @@ static void omap_plane_post_apply(struct omap_drm_apply *apply)
 
 	if (cb.fxn)
 		cb.fxn(cb.arg);
-
-	if (omap_plane->enabled) {
-		omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y,
-				info->out_width, info->out_height);
-	}
 }
 
 static int apply(struct drm_plane *plane)
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 09/36] drm: omapdrm: Remove omap_crtc->full_update field
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (7 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 08/36] drm: omapdrm: Remove manual update display support Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 10/36] drm: omapdrm: Avoid function forward declaration in omap_crtc.c Tomi Valkeinen
                   ` (26 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The full_update field is always set to true before calling
omap_crtc_appy(), resulting in its value always being true in the single
location where it is tested, in omap_crtc_pre_apply(). Remove it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 3f811186c891..e04782489224 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -45,7 +45,6 @@ struct omap_crtc {
 
 	struct omap_video_timings timings;
 	bool enabled;
-	bool full_update;
 
 	struct omap_drm_apply apply;
 
@@ -148,7 +147,6 @@ static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
 	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
 	DBG("%s", omap_crtc->name);
 	omap_crtc->timings = *timings;
-	omap_crtc->full_update = true;
 }
 
 static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
@@ -213,7 +211,6 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
 
 	if (enabled != omap_crtc->enabled) {
 		omap_crtc->enabled = enabled;
-		omap_crtc->full_update = true;
 		omap_crtc_apply(crtc, &omap_crtc->apply);
 
 		/* Enable/disable all planes associated with the CRTC. */
@@ -252,7 +249,6 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
 			mode->type, mode->flags);
 
 	copy_timings_drm_to_omap(&omap_crtc->timings, mode);
-	omap_crtc->full_update = true;
 
 	/*
 	 * The primary plane CRTC can be reset if the plane is disabled directly
@@ -597,19 +593,16 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
 	struct omap_crtc *omap_crtc =
 			container_of(apply, struct omap_crtc, apply);
 	struct drm_crtc *crtc = &omap_crtc->base;
+	struct omap_drm_private *priv = crtc->dev->dev_private;
 	struct drm_encoder *encoder = NULL;
+	unsigned int i;
 
-	DBG("%s: enabled=%d, full=%d", omap_crtc->name,
-			omap_crtc->enabled, omap_crtc->full_update);
+	DBG("%s: enabled=%d", omap_crtc->name, omap_crtc->enabled);
 
-	if (omap_crtc->full_update) {
-		struct omap_drm_private *priv = crtc->dev->dev_private;
-		int i;
-		for (i = 0; i < priv->num_encoders; i++) {
-			if (priv->encoders[i]->crtc == crtc) {
-				encoder = priv->encoders[i];
-				break;
-			}
+	for (i = 0; i < priv->num_encoders; i++) {
+		if (priv->encoders[i]->crtc == crtc) {
+			encoder = priv->encoders[i];
+			break;
 		}
 	}
 
@@ -629,8 +622,6 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
 			omap_encoder_set_enabled(encoder, true);
 		}
 	}
-
-	omap_crtc->full_update = false;
 }
 
 static void omap_crtc_post_apply(struct omap_drm_apply *apply)
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 10/36] drm: omapdrm: Avoid function forward declaration in omap_crtc.c
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (8 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 09/36] drm: omapdrm: Remove omap_crtc->full_update field Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 11/36] drm: omapdrm: Prefix all plane functions with omap_plane_ Tomi Valkeinen
                   ` (25 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Move the set_enabled function to avoid the forward declaration. While at
it prefix it with omap_crtc_ like most other functions in the file, and
fix the comment stating in which contexts the function is called.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 107 ++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index e04782489224..1ef3e0146c68 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -120,7 +120,57 @@ static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
 {
 }
 
-static void set_enabled(struct drm_crtc *crtc, bool enable);
+/* Called only from CRTC pre_apply and suspend/resume handlers. */
+static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
+{
+	struct drm_device *dev = crtc->dev;
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	enum omap_channel channel = omap_crtc->channel;
+	struct omap_irq_wait *wait;
+	u32 framedone_irq, vsync_irq;
+	int ret;
+
+	if (dispc_mgr_is_enabled(channel) == enable)
+		return;
+
+	/*
+	 * Digit output produces some sync lost interrupts during the first
+	 * frame when enabling, so we need to ignore those.
+	 */
+	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
+
+	framedone_irq = dispc_mgr_get_framedone_irq(channel);
+	vsync_irq = dispc_mgr_get_vsync_irq(channel);
+
+	if (enable) {
+		wait = omap_irq_wait_init(dev, vsync_irq, 1);
+	} else {
+		/*
+		 * When we disable the digit output, we need to wait for
+		 * FRAMEDONE to know that DISPC has finished with the output.
+		 *
+		 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
+		 * that case we need to use vsync interrupt, and wait for both
+		 * even and odd frames.
+		 */
+
+		if (framedone_irq)
+			wait = omap_irq_wait_init(dev, framedone_irq, 1);
+		else
+			wait = omap_irq_wait_init(dev, vsync_irq, 2);
+	}
+
+	dispc_mgr_enable(channel, enable);
+
+	ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
+	if (ret) {
+		dev_err(dev->dev, "%s: timeout waiting for %s\n",
+				omap_crtc->name, enable ? "enable" : "disable");
+	}
+
+	omap_irq_register(crtc->dev, &omap_crtc->error_irq);
+}
+
 
 static int omap_crtc_enable(struct omap_overlay_manager *mgr)
 {
@@ -129,7 +179,7 @@ static int omap_crtc_enable(struct omap_overlay_manager *mgr)
 	dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
 	dispc_mgr_set_timings(omap_crtc->channel,
 			&omap_crtc->timings);
-	set_enabled(&omap_crtc->base, true);
+	omap_crtc_set_enabled(&omap_crtc->base, true);
 
 	return 0;
 }
@@ -138,7 +188,7 @@ static void omap_crtc_disable(struct omap_overlay_manager *mgr)
 {
 	struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
 
-	set_enabled(&omap_crtc->base, false);
+	omap_crtc_set_enabled(&omap_crtc->base, false);
 }
 
 static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
@@ -537,57 +587,6 @@ int omap_crtc_apply(struct drm_crtc *crtc,
 	return 0;
 }
 
-/* called only from apply */
-static void set_enabled(struct drm_crtc *crtc, bool enable)
-{
-	struct drm_device *dev = crtc->dev;
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	enum omap_channel channel = omap_crtc->channel;
-	struct omap_irq_wait *wait;
-	u32 framedone_irq, vsync_irq;
-	int ret;
-
-	if (dispc_mgr_is_enabled(channel) == enable)
-		return;
-
-	/*
-	 * Digit output produces some sync lost interrupts during the first
-	 * frame when enabling, so we need to ignore those.
-	 */
-	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
-
-	framedone_irq = dispc_mgr_get_framedone_irq(channel);
-	vsync_irq = dispc_mgr_get_vsync_irq(channel);
-
-	if (enable) {
-		wait = omap_irq_wait_init(dev, vsync_irq, 1);
-	} else {
-		/*
-		 * When we disable the digit output, we need to wait for
-		 * FRAMEDONE to know that DISPC has finished with the output.
-		 *
-		 * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
-		 * that case we need to use vsync interrupt, and wait for both
-		 * even and odd frames.
-		 */
-
-		if (framedone_irq)
-			wait = omap_irq_wait_init(dev, framedone_irq, 1);
-		else
-			wait = omap_irq_wait_init(dev, vsync_irq, 2);
-	}
-
-	dispc_mgr_enable(channel, enable);
-
-	ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
-	if (ret) {
-		dev_err(dev->dev, "%s: timeout waiting for %s\n",
-				omap_crtc->name, enable ? "enable" : "disable");
-	}
-
-	omap_irq_register(crtc->dev, &omap_crtc->error_irq);
-}
-
 static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
 {
 	struct omap_crtc *omap_crtc =
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 11/36] drm: omapdrm: Prefix all plane functions with omap_plane_
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (9 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 10/36] drm: omapdrm: Avoid function forward declaration in omap_crtc.c Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 12/36] drm: omapdrm: Pass integer source coordinates to omap_plane_mode_set() Tomi Valkeinen
                   ` (24 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

This matches the rest of the file and clarifies the functions' purpose.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2111d415da96..309a2246b6e0 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -65,7 +65,7 @@ struct omap_plane {
 	struct callback apply_done_cb;
 };
 
-static void unpin_worker(struct drm_flip_work *work, void *val)
+static void omap_plane_unpin_worker(struct drm_flip_work *work, void *val)
 {
 	struct omap_plane *omap_plane =
 			container_of(work, struct omap_plane, unpin_work);
@@ -78,7 +78,8 @@ static void unpin_worker(struct drm_flip_work *work, void *val)
 }
 
 /* update which fb (if any) is pinned for scanout */
-static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb)
+static int omap_plane_update_pin(struct drm_plane *plane,
+				 struct drm_framebuffer *fb)
 {
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 	struct drm_framebuffer *pinned_fb = omap_plane->pinned_fb;
@@ -126,7 +127,7 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
 	DBG("%s, enabled=%d", omap_plane->name, enabled);
 
 	/* if fb has changed, pin new fb: */
-	update_pin(plane, enabled ? plane->fb : NULL);
+	omap_plane_update_pin(plane, enabled ? plane->fb : NULL);
 
 	if (!enabled) {
 		dispc_ovl_enable(omap_plane->id, false);
@@ -173,7 +174,7 @@ static void omap_plane_post_apply(struct omap_drm_apply *apply)
 		cb.fxn(cb.arg);
 }
 
-static int apply(struct drm_plane *plane)
+static int omap_plane_apply(struct drm_plane *plane)
 {
 	if (plane->crtc) {
 		struct omap_plane *omap_plane = to_omap_plane(plane);
@@ -214,7 +215,7 @@ int omap_plane_mode_set(struct drm_plane *plane,
 		omap_plane->apply_done_cb.arg = arg;
 	}
 
-	return apply(plane);
+	return omap_plane_apply(plane);
 }
 
 static int omap_plane_update(struct drm_plane *plane,
@@ -283,7 +284,7 @@ int omap_plane_set_enable(struct drm_plane *plane, bool enable)
 		return 0;
 
 	omap_plane->enabled = enable;
-	return apply(plane);
+	return omap_plane_apply(plane);
 }
 
 /* helper to install properties which are common to planes and crtcs */
@@ -331,11 +332,11 @@ int omap_plane_set_property(struct drm_plane *plane,
 	if (property == priv->rotation_prop) {
 		DBG("%s: rotation: %02x", omap_plane->name, (uint32_t)val);
 		omap_plane->win.rotation = val;
-		ret = apply(plane);
+		ret = omap_plane_apply(plane);
 	} else if (property == priv->zorder_prop) {
 		DBG("%s: zorder: %02x", omap_plane->name, (uint32_t)val);
 		omap_plane->info.zorder = val;
-		ret = apply(plane);
+		ret = omap_plane_apply(plane);
 	}
 
 	return ret;
@@ -386,7 +387,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 		return ERR_PTR(-ENOMEM);
 
 	drm_flip_work_init(&omap_plane->unpin_work,
-			"unpin", unpin_worker);
+			"unpin", omap_plane_unpin_worker);
 
 	omap_plane->nformats = omap_framebuffer_get_formats(
 			omap_plane->formats, ARRAY_SIZE(omap_plane->formats),
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 12/36] drm: omapdrm: Pass integer source coordinates to omap_plane_mode_set()
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (10 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 11/36] drm: omapdrm: Prefix all plane functions with omap_plane_ Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 13/36] drm: omapdrm: Planes are already disabled when destroyed Tomi Valkeinen
                   ` (23 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The function will convert the Q16 source coordinates to integers, avoid
converting integers to Q16 first and perform the opposite conversion.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 21 +++++++++------------
 drivers/gpu/drm/omapdrm/omap_drv.h   | 12 ++++++------
 drivers/gpu/drm/omapdrm/omap_plane.c | 24 ++++++++++++------------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 1ef3e0146c68..105eab7cb830 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -307,10 +307,9 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
 	crtc->primary->crtc = crtc;
 
 	return omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
-			0, 0, mode->hdisplay, mode->vdisplay,
-			x << 16, y << 16,
-			mode->hdisplay << 16, mode->vdisplay << 16,
-			NULL, NULL);
+				   0, 0, mode->hdisplay, mode->vdisplay,
+				   x, y, mode->hdisplay, mode->vdisplay,
+				   NULL, NULL);
 }
 
 static void omap_crtc_prepare(struct drm_crtc *crtc)
@@ -334,10 +333,9 @@ static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	struct drm_display_mode *mode = &crtc->mode;
 
 	return omap_plane_mode_set(plane, crtc, crtc->primary->fb,
-			0, 0, mode->hdisplay, mode->vdisplay,
-			x << 16, y << 16,
-			mode->hdisplay << 16, mode->vdisplay << 16,
-			NULL, NULL);
+				   0, 0, mode->hdisplay, mode->vdisplay,
+				   x, y, mode->hdisplay, mode->vdisplay,
+				   NULL, NULL);
 }
 
 static void vblank_cb(void *arg)
@@ -369,10 +367,9 @@ static void page_flip_worker(struct work_struct *work)
 
 	drm_modeset_lock(&crtc->mutex, NULL);
 	omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
-			0, 0, mode->hdisplay, mode->vdisplay,
-			crtc->x << 16, crtc->y << 16,
-			mode->hdisplay << 16, mode->vdisplay << 16,
-			vblank_cb, crtc);
+			    0, 0, mode->hdisplay, mode->vdisplay,
+			    crtc->x, crtc->y, mode->hdisplay, mode->vdisplay,
+			    vblank_cb, crtc);
 	drm_modeset_unlock(&crtc->mutex);
 
 	bo = omap_framebuffer_bo(crtc->primary->fb, 0);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 1805edc0107d..57e11c1f589f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -163,12 +163,12 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
 		int id, enum drm_plane_type type);
 int omap_plane_set_enable(struct drm_plane *plane, bool enable);
 int omap_plane_mode_set(struct drm_plane *plane,
-		struct drm_crtc *crtc, struct drm_framebuffer *fb,
-		int crtc_x, int crtc_y,
-		unsigned int crtc_w, unsigned int crtc_h,
-		uint32_t src_x, uint32_t src_y,
-		uint32_t src_w, uint32_t src_h,
-		void (*fxn)(void *), void *arg);
+			struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			int crtc_x, int crtc_y,
+			unsigned int crtc_w, unsigned int crtc_h,
+			unsigned int src_x, unsigned int src_y,
+			unsigned int src_w, unsigned int src_h,
+			void (*fxn)(void *), void *arg);
 void omap_plane_install_properties(struct drm_plane *plane,
 		struct drm_mode_object *obj);
 int omap_plane_set_property(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 309a2246b6e0..29f4371e9e00 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -184,12 +184,12 @@ static int omap_plane_apply(struct drm_plane *plane)
 }
 
 int omap_plane_mode_set(struct drm_plane *plane,
-		struct drm_crtc *crtc, struct drm_framebuffer *fb,
-		int crtc_x, int crtc_y,
-		unsigned int crtc_w, unsigned int crtc_h,
-		uint32_t src_x, uint32_t src_y,
-		uint32_t src_w, uint32_t src_h,
-		void (*fxn)(void *), void *arg)
+			struct drm_crtc *crtc, struct drm_framebuffer *fb,
+			int crtc_x, int crtc_y,
+			unsigned int crtc_w, unsigned int crtc_h,
+			unsigned int src_x, unsigned int src_y,
+			unsigned int src_w, unsigned int src_h,
+			void (*fxn)(void *), void *arg)
 {
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 	struct omap_drm_window *win = &omap_plane->win;
@@ -199,11 +199,10 @@ int omap_plane_mode_set(struct drm_plane *plane,
 	win->crtc_w = crtc_w;
 	win->crtc_h = crtc_h;
 
-	/* src values are in Q16 fixed point, convert to integer: */
-	win->src_x = src_x >> 16;
-	win->src_y = src_y >> 16;
-	win->src_w = src_w >> 16;
-	win->src_h = src_h >> 16;
+	win->src_x = src_x;
+	win->src_y = src_y;
+	win->src_w = src_w;
+	win->src_h = src_h;
 
 	if (fxn) {
 		/* omap_crtc should ensure that a new page flip
@@ -243,9 +242,10 @@ static int omap_plane_update(struct drm_plane *plane,
 	plane->fb = fb;
 	plane->crtc = crtc;
 
+	/* src values are in Q16 fixed point, convert to integer: */
 	return omap_plane_mode_set(plane, crtc, fb,
 			crtc_x, crtc_y, crtc_w, crtc_h,
-			src_x, src_y, src_w, src_h,
+			src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
 			NULL, NULL);
 }
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 13/36] drm: omapdrm: Planes are already disabled when destroyed
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (11 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 12/36] drm: omapdrm: Pass integer source coordinates to omap_plane_mode_set() Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 14/36] drm: omapdrm: Reorder CRTC functions Tomi Valkeinen
                   ` (22 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Planes are destroyed after framebuffers, which has the side effect of
disabling all planes. There is thus no need to disable planes explicitly
when destroying them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 29f4371e9e00..e03512c86bf8 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -268,7 +268,6 @@ static void omap_plane_destroy(struct drm_plane *plane)
 
 	omap_irq_unregister(plane->dev, &omap_plane->error_irq);
 
-	omap_plane_disable(plane);
 	drm_plane_cleanup(plane);
 
 	drm_flip_work_cleanup(&omap_plane->unpin_work);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 14/36] drm: omapdrm: Reorder CRTC functions
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (12 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 13/36] drm: omapdrm: Planes are already disabled when destroyed Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 15/36] drm/omap: fix encoder-crtc mapping Tomi Valkeinen
                   ` (21 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Laurent Pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

The next commit will need functions to be reordered. Do it separately to
help review.

This only moves functions without any change to the code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 396 +++++++++++++++++++-----------------
 1 file changed, 206 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 105eab7cb830..5cd10cf57985 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -74,6 +74,10 @@ struct omap_crtc {
 	struct work_struct page_flip_work;
 };
 
+/* -----------------------------------------------------------------------------
+ * Helper Functions
+ */
+
 uint32_t pipe2vbl(struct drm_crtc *crtc)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
@@ -81,6 +85,22 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
 	return dispc_mgr_get_vsync_irq(omap_crtc->channel);
 }
 
+const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	return &omap_crtc->timings;
+}
+
+enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	return omap_crtc->channel;
+}
+
+/* -----------------------------------------------------------------------------
+ * DSS Manager Functions
+ */
+
 /*
  * Manager-ops, callbacks from output when they need to configure
  * the upstream part of the video pipe.
@@ -232,8 +252,189 @@ static const struct dss_mgr_ops mgr_ops = {
 	.unregister_framedone_handler = omap_crtc_unregister_framedone_handler,
 };
 
-/*
- * CRTC funcs:
+/* -----------------------------------------------------------------------------
+ * Apply Logic
+ */
+
+static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
+{
+	struct omap_crtc *omap_crtc =
+			container_of(irq, struct omap_crtc, error_irq);
+	struct drm_crtc *crtc = &omap_crtc->base;
+	DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+	/* avoid getting in a flood, unregister the irq until next vblank */
+	__omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
+}
+
+static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
+{
+	struct omap_crtc *omap_crtc =
+			container_of(irq, struct omap_crtc, apply_irq);
+	struct drm_crtc *crtc = &omap_crtc->base;
+
+	if (!omap_crtc->error_irq.registered)
+		__omap_irq_register(crtc->dev, &omap_crtc->error_irq);
+
+	if (!dispc_mgr_go_busy(omap_crtc->channel)) {
+		struct omap_drm_private *priv =
+				crtc->dev->dev_private;
+		DBG("%s: apply done", omap_crtc->name);
+		__omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
+		queue_work(priv->wq, &omap_crtc->apply_work);
+	}
+}
+
+static void apply_worker(struct work_struct *work)
+{
+	struct omap_crtc *omap_crtc =
+			container_of(work, struct omap_crtc, apply_work);
+	struct drm_crtc *crtc = &omap_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	struct omap_drm_apply *apply, *n;
+	bool need_apply;
+
+	/*
+	 * Synchronize everything on mode_config.mutex, to keep
+	 * the callbacks and list modification all serialized
+	 * with respect to modesetting ioctls from userspace.
+	 */
+	drm_modeset_lock(&crtc->mutex, NULL);
+	dispc_runtime_get();
+
+	/*
+	 * If we are still pending a previous update, wait.. when the
+	 * pending update completes, we get kicked again.
+	 */
+	if (omap_crtc->apply_irq.registered)
+		goto out;
+
+	/* finish up previous apply's: */
+	list_for_each_entry_safe(apply, n,
+			&omap_crtc->pending_applies, pending_node) {
+		apply->post_apply(apply);
+		list_del(&apply->pending_node);
+	}
+
+	need_apply = !list_empty(&omap_crtc->queued_applies);
+
+	/* then handle the next round of of queued apply's: */
+	list_for_each_entry_safe(apply, n,
+			&omap_crtc->queued_applies, queued_node) {
+		apply->pre_apply(apply);
+		list_del(&apply->queued_node);
+		apply->queued = false;
+		list_add_tail(&apply->pending_node,
+				&omap_crtc->pending_applies);
+	}
+
+	if (need_apply) {
+		enum omap_channel channel = omap_crtc->channel;
+
+		DBG("%s: GO", omap_crtc->name);
+
+		if (dispc_mgr_is_enabled(channel)) {
+			dispc_mgr_go(channel);
+			omap_irq_register(dev, &omap_crtc->apply_irq);
+		} else {
+			struct omap_drm_private *priv = dev->dev_private;
+			queue_work(priv->wq, &omap_crtc->apply_work);
+		}
+	}
+
+out:
+	dispc_runtime_put();
+	drm_modeset_unlock(&crtc->mutex);
+}
+
+int omap_crtc_apply(struct drm_crtc *crtc,
+		struct omap_drm_apply *apply)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
+
+	/* no need to queue it again if it is already queued: */
+	if (apply->queued)
+		return 0;
+
+	apply->queued = true;
+	list_add_tail(&apply->queued_node, &omap_crtc->queued_applies);
+
+	/*
+	 * If there are no currently pending updates, then go ahead and
+	 * kick the worker immediately, otherwise it will run again when
+	 * the current update finishes.
+	 */
+	if (list_empty(&omap_crtc->pending_applies)) {
+		struct omap_drm_private *priv = crtc->dev->dev_private;
+		queue_work(priv->wq, &omap_crtc->apply_work);
+	}
+
+	return 0;
+}
+
+static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
+{
+	struct omap_crtc *omap_crtc =
+			container_of(apply, struct omap_crtc, apply);
+	struct drm_crtc *crtc = &omap_crtc->base;
+	struct omap_drm_private *priv = crtc->dev->dev_private;
+	struct drm_encoder *encoder = NULL;
+	unsigned int i;
+
+	DBG("%s: enabled=%d", omap_crtc->name, omap_crtc->enabled);
+
+	for (i = 0; i < priv->num_encoders; i++) {
+		if (priv->encoders[i]->crtc == crtc) {
+			encoder = priv->encoders[i];
+			break;
+		}
+	}
+
+	if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
+		omap_encoder_set_enabled(omap_crtc->current_encoder, false);
+
+	omap_crtc->current_encoder = encoder;
+
+	if (!omap_crtc->enabled) {
+		if (encoder)
+			omap_encoder_set_enabled(encoder, false);
+	} else {
+		if (encoder) {
+			omap_encoder_set_enabled(encoder, false);
+			omap_encoder_update(encoder, omap_crtc->mgr,
+					&omap_crtc->timings);
+			omap_encoder_set_enabled(encoder, true);
+		}
+	}
+}
+
+static void omap_crtc_post_apply(struct omap_drm_apply *apply)
+{
+	/* nothing needed for post-apply */
+}
+
+void omap_crtc_flush(struct drm_crtc *crtc)
+{
+	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	int loops = 0;
+
+	while (!list_empty(&omap_crtc->pending_applies) ||
+		!list_empty(&omap_crtc->queued_applies) ||
+		omap_crtc->event || omap_crtc->old_fb) {
+
+		if (++loops > 10) {
+			dev_err(crtc->dev->dev,
+				"omap_crtc_flush() timeout\n");
+			break;
+		}
+
+		schedule_timeout_uninterruptible(msecs_to_jiffies(20));
+	}
+}
+
+/* -----------------------------------------------------------------------------
+ * CRTC Functions
  */
 
 static void omap_crtc_destroy(struct drm_crtc *crtc)
@@ -455,194 +656,9 @@ static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
 	.mode_set_base = omap_crtc_mode_set_base,
 };
 
-const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	return &omap_crtc->timings;
-}
-
-enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	return omap_crtc->channel;
-}
-
-static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
-{
-	struct omap_crtc *omap_crtc =
-			container_of(irq, struct omap_crtc, error_irq);
-	struct drm_crtc *crtc = &omap_crtc->base;
-	DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
-	/* avoid getting in a flood, unregister the irq until next vblank */
-	__omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
-}
-
-static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
-{
-	struct omap_crtc *omap_crtc =
-			container_of(irq, struct omap_crtc, apply_irq);
-	struct drm_crtc *crtc = &omap_crtc->base;
-
-	if (!omap_crtc->error_irq.registered)
-		__omap_irq_register(crtc->dev, &omap_crtc->error_irq);
-
-	if (!dispc_mgr_go_busy(omap_crtc->channel)) {
-		struct omap_drm_private *priv =
-				crtc->dev->dev_private;
-		DBG("%s: apply done", omap_crtc->name);
-		__omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq);
-		queue_work(priv->wq, &omap_crtc->apply_work);
-	}
-}
-
-static void apply_worker(struct work_struct *work)
-{
-	struct omap_crtc *omap_crtc =
-			container_of(work, struct omap_crtc, apply_work);
-	struct drm_crtc *crtc = &omap_crtc->base;
-	struct drm_device *dev = crtc->dev;
-	struct omap_drm_apply *apply, *n;
-	bool need_apply;
-
-	/*
-	 * Synchronize everything on mode_config.mutex, to keep
-	 * the callbacks and list modification all serialized
-	 * with respect to modesetting ioctls from userspace.
-	 */
-	drm_modeset_lock(&crtc->mutex, NULL);
-	dispc_runtime_get();
-
-	/*
-	 * If we are still pending a previous update, wait.. when the
-	 * pending update completes, we get kicked again.
-	 */
-	if (omap_crtc->apply_irq.registered)
-		goto out;
-
-	/* finish up previous apply's: */
-	list_for_each_entry_safe(apply, n,
-			&omap_crtc->pending_applies, pending_node) {
-		apply->post_apply(apply);
-		list_del(&apply->pending_node);
-	}
-
-	need_apply = !list_empty(&omap_crtc->queued_applies);
-
-	/* then handle the next round of of queued apply's: */
-	list_for_each_entry_safe(apply, n,
-			&omap_crtc->queued_applies, queued_node) {
-		apply->pre_apply(apply);
-		list_del(&apply->queued_node);
-		apply->queued = false;
-		list_add_tail(&apply->pending_node,
-				&omap_crtc->pending_applies);
-	}
-
-	if (need_apply) {
-		enum omap_channel channel = omap_crtc->channel;
-
-		DBG("%s: GO", omap_crtc->name);
-
-		if (dispc_mgr_is_enabled(channel)) {
-			dispc_mgr_go(channel);
-			omap_irq_register(dev, &omap_crtc->apply_irq);
-		} else {
-			struct omap_drm_private *priv = dev->dev_private;
-			queue_work(priv->wq, &omap_crtc->apply_work);
-		}
-	}
-
-out:
-	dispc_runtime_put();
-	drm_modeset_unlock(&crtc->mutex);
-}
-
-int omap_crtc_apply(struct drm_crtc *crtc,
-		struct omap_drm_apply *apply)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-
-	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
-
-	/* no need to queue it again if it is already queued: */
-	if (apply->queued)
-		return 0;
-
-	apply->queued = true;
-	list_add_tail(&apply->queued_node, &omap_crtc->queued_applies);
-
-	/*
-	 * If there are no currently pending updates, then go ahead and
-	 * kick the worker immediately, otherwise it will run again when
-	 * the current update finishes.
-	 */
-	if (list_empty(&omap_crtc->pending_applies)) {
-		struct omap_drm_private *priv = crtc->dev->dev_private;
-		queue_work(priv->wq, &omap_crtc->apply_work);
-	}
-
-	return 0;
-}
-
-static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
-{
-	struct omap_crtc *omap_crtc =
-			container_of(apply, struct omap_crtc, apply);
-	struct drm_crtc *crtc = &omap_crtc->base;
-	struct omap_drm_private *priv = crtc->dev->dev_private;
-	struct drm_encoder *encoder = NULL;
-	unsigned int i;
-
-	DBG("%s: enabled=%d", omap_crtc->name, omap_crtc->enabled);
-
-	for (i = 0; i < priv->num_encoders; i++) {
-		if (priv->encoders[i]->crtc == crtc) {
-			encoder = priv->encoders[i];
-			break;
-		}
-	}
-
-	if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
-		omap_encoder_set_enabled(omap_crtc->current_encoder, false);
-
-	omap_crtc->current_encoder = encoder;
-
-	if (!omap_crtc->enabled) {
-		if (encoder)
-			omap_encoder_set_enabled(encoder, false);
-	} else {
-		if (encoder) {
-			omap_encoder_set_enabled(encoder, false);
-			omap_encoder_update(encoder, omap_crtc->mgr,
-					&omap_crtc->timings);
-			omap_encoder_set_enabled(encoder, true);
-		}
-	}
-}
-
-static void omap_crtc_post_apply(struct omap_drm_apply *apply)
-{
-	/* nothing needed for post-apply */
-}
-
-void omap_crtc_flush(struct drm_crtc *crtc)
-{
-	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-	int loops = 0;
-
-	while (!list_empty(&omap_crtc->pending_applies) ||
-		!list_empty(&omap_crtc->queued_applies) ||
-		omap_crtc->event || omap_crtc->old_fb) {
-
-		if (++loops > 10) {
-			dev_err(crtc->dev->dev,
-				"omap_crtc_flush() timeout\n");
-			break;
-		}
-
-		schedule_timeout_uninterruptible(msecs_to_jiffies(20));
-	}
-}
+/* -----------------------------------------------------------------------------
+ * Init and Cleanup
+ */
 
 static const char *channel_names[] = {
 	[OMAP_DSS_CHANNEL_LCD] = "lcd",
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 15/36] drm/omap: fix encoder-crtc mapping
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (13 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 14/36] drm: omapdrm: Reorder CRTC functions Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 16/36] drm/omap: page_flip: return -EBUSY if flip pending Tomi Valkeinen
                   ` (20 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

OMAP DSS hardware supports changing the output port to which an overlay
manager's video stream goes. For example, DPI video stream can come from
any of the four overlay managers on OMAP5.

However, as it's difficult to manage the change in the driver, the
omapdss driver does not support that at the moment, and has a hardcoded
overlay manager per output.

omapdrm, on the other hand, uses the hardware features to find out which
overlay manager to use for an output, which causes problems. For
example, on OMAP5, omapdrm tries to use DIGIT overlay manager for DPI
output, instead of the LCD3 required by the omapdss driver.

This patch changes the omapdrm to use the omapdss driver's hardcoded
overlay managers, which fixes the issue.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 5eab83d7de15..b71a443e671e 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -298,14 +298,13 @@ static int omap_modeset_init(struct drm_device *dev)
 		for (id = 0; id < priv->num_crtcs; id++) {
 			struct drm_crtc *crtc = priv->crtcs[id];
 			enum omap_channel crtc_channel;
-			enum omap_dss_output_id supported_outputs;
 
 			crtc_channel = omap_crtc_channel(crtc);
-			supported_outputs =
-				dss_feat_get_supported_outputs(crtc_channel);
 
-			if (supported_outputs & output->id)
+			if (output->dispc_channel == crtc_channel) {
 				encoder->possible_crtcs |= (1 << id);
+				break;
+			}
 		}
 
 		omap_dss_put_device(output);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 16/36] drm/omap: page_flip: return -EBUSY if flip pending
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (14 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 15/36] drm/omap: fix encoder-crtc mapping Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 17/36] drm/omap: clear omap_obj->paddr in omap_gem_put_paddr() Tomi Valkeinen
                   ` (19 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

The DRM documentation says:

"If a page flip is already pending, the page_flip operation must return
-EBUSY."

Currently omapdrm returns -EINVAL instead. Fix omapdrm by returning
-EBUSY.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 5cd10cf57985..a4d6f5ec627e 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -606,7 +606,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 	if (omap_crtc->old_fb) {
 		spin_unlock_irqrestore(&dev->event_lock, flags);
 		dev_err(dev->dev, "already a pending flip\n");
-		return -EINVAL;
+		return -EBUSY;
 	}
 
 	omap_crtc->event = event;
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 17/36] drm/omap: clear omap_obj->paddr in omap_gem_put_paddr()
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (15 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 16/36] drm/omap: page_flip: return -EBUSY if flip pending Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 18/36] drm/omap: add pin refcounting to omap_framebuffer Tomi Valkeinen
                   ` (18 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

Clear omap_obj's paddr when unmapping the memory, so that it's easier to
catch bad use of the paddr.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_gem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index aeb91ed653c9..9b250c93b046 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -828,6 +828,7 @@ int omap_gem_put_paddr(struct drm_gem_object *obj)
 				dev_err(obj->dev->dev,
 					"could not release unmap: %d\n", ret);
 			}
+			omap_obj->paddr = 0;
 			omap_obj->block = NULL;
 		}
 	}
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 18/36] drm/omap: add pin refcounting to omap_framebuffer
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (16 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 17/36] drm/omap: clear omap_obj->paddr in omap_gem_put_paddr() Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 19/36] drm/omap: add a comment why locking is missing Tomi Valkeinen
                   ` (17 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omap_framebuffer_pin() and omap_framebuffer_unpin() are currently
broken, as they cannot be called multiple times (i.e. pin, pin, unpin,
unpin), which is what happens in certain cases. This issue causes the
driver to possibly use 0 as an address for a displayed buffer, leading
to OCP error from DSS.

This patch fixes the issue by adding a simple pin_count, used to track
the number of pins.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_fb.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 45dd9eed9c57..d1e5f6da30d4 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -86,6 +86,7 @@ struct plane {
 
 struct omap_framebuffer {
 	struct drm_framebuffer base;
+	int pin_count;
 	const struct format *format;
 	struct plane planes[4];
 };
@@ -249,6 +250,11 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
 	int ret, i, n = drm_format_num_planes(fb->pixel_format);
 
+	if (omap_fb->pin_count > 0) {
+		omap_fb->pin_count++;
+		return 0;
+	}
+
 	for (i = 0; i < n; i++) {
 		struct plane *plane = &omap_fb->planes[i];
 		ret = omap_gem_get_paddr(plane->bo, &plane->paddr, true);
@@ -257,6 +263,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
 		omap_gem_dma_sync(plane->bo, DMA_TO_DEVICE);
 	}
 
+	omap_fb->pin_count++;
+
 	return 0;
 
 fail:
@@ -275,6 +283,11 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
 	int ret, i, n = drm_format_num_planes(fb->pixel_format);
 
+	omap_fb->pin_count--;
+
+	if (omap_fb->pin_count > 0)
+		return 0;
+
 	for (i = 0; i < n; i++) {
 		struct plane *plane = &omap_fb->planes[i];
 		ret = omap_gem_put_paddr(plane->bo);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 19/36] drm/omap: add a comment why locking is missing
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (17 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 18/36] drm/omap: add pin refcounting to omap_framebuffer Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 20/36] drm/omap: fix operation without fbdev Tomi Valkeinen
                   ` (16 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

unpin_worker() calls omap_framebuffer_unpin() without any locks, which
looks very suspicious. However, both pin and unpin are always called via
the driver's private workqueue, so the access is synchronized that way.

Add a comment to make this clear.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index e03512c86bf8..6eedca107376 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -71,6 +71,10 @@ static void omap_plane_unpin_worker(struct drm_flip_work *work, void *val)
 			container_of(work, struct omap_plane, unpin_work);
 	struct drm_device *dev = omap_plane->base.dev;
 
+	/*
+	 * omap_framebuffer_pin/unpin are always called from priv->wq,
+	 * so there's no need for locking here.
+	 */
 	omap_framebuffer_unpin(val);
 	mutex_lock(&dev->mode_config.mutex);
 	drm_framebuffer_unreference(val);
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 20/36] drm/omap: fix operation without fbdev
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (18 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 19/36] drm/omap: add a comment why locking is missing Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 21/36] drm/omap: fix error handling in omap_framebuffer_create() Tomi Valkeinen
                   ` (15 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omapdrm should work fine even if fbdev is missing. The current driver
crashes in that case, though, as it is missing checks for the fbdev.

Add the checks so that we don't free fbdev or restore fbdev mode when
there's no fbdev.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index b71a443e671e..63c953971c11 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -530,7 +530,8 @@ static int dev_unload(struct drm_device *dev)
 
 	drm_kms_helper_poll_fini(dev);
 
-	omap_fbdev_free(dev);
+	if (priv->fbdev)
+		omap_fbdev_free(dev);
 
 	/* flush crtcs so the fbs get released */
 	for (i = 0; i < priv->num_crtcs; i++)
@@ -599,9 +600,11 @@ static void dev_lastclose(struct drm_device *dev)
 		}
 	}
 
-	ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
-	if (ret)
-		DBG("failed to restore crtc mode");
+	if (priv->fbdev) {
+		ret = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
+		if (ret)
+			DBG("failed to restore crtc mode");
+	}
 }
 
 static void dev_preclose(struct drm_device *dev, struct drm_file *file)
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 21/36] drm/omap: fix error handling in omap_framebuffer_create()
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (19 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 20/36] drm/omap: fix operation without fbdev Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 22/36] drm/omap: handle incompatible buffer stride and pixel size Tomi Valkeinen
                   ` (14 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

When an error happens in omap_framebuffer_create(),
omap_framebuffer_create() calls omap_framebuffer_destroy() if the fb
struct has been allocated. However, that crashes, as
omap_framebuffer_destroy(), which calls drm_framebuffer_cleanup(),
should only be called after drm_framebuffer_init()

Fix this by just calling kfree() for the allocated fb when an error
happens.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_fb.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index d1e5f6da30d4..3c6488e89788 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -380,7 +380,7 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 		struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
-	struct omap_framebuffer *omap_fb;
+	struct omap_framebuffer *omap_fb = NULL;
 	struct drm_framebuffer *fb = NULL;
 	const struct format *format = NULL;
 	int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
@@ -451,8 +451,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 	return fb;
 
 fail:
-	if (fb)
-		omap_framebuffer_destroy(fb);
+	kfree(omap_fb);
 
 	return ERR_PTR(ret);
 }
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 22/36] drm/omap: handle incompatible buffer stride and pixel size
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (20 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 21/36] drm/omap: fix error handling in omap_framebuffer_create() Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 23/36] drm/omap: fix TILER on OMAP5 Tomi Valkeinen
                   ` (13 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omapdrm doesn't check if the pitch of the framebuffer and the color
format's bits-per-pixel are compatible. omapdss requires that the stride
of a buffer is an integer number of pixels

For example, when using modetest with a display that has x resolution of
1280, and using packed 24 RGB mode (3 bytes per pixel), modetest
allocates a buffer with a byte stride of 4 * 1280 = 5120. But 5120 / 3 =
1706.666... pixels, which causes wrong colors and a tilt on the screen.

Add a check into omapdrm to return an error if the user tries to use
such a combination.

Note: this is not a HW requirement at least for non-rotation use cases,
but a SW driver requirement. In the future we should study if also
rotation use cases are fine with any stride size, and if so, change the
driver to allow these strides.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_fb.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 3c6488e89788..b2c1a29cc12b 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -423,6 +423,14 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 			goto fail;
 		}
 
+		if (pitch % format->planes[i].stride_bpp != 0) {
+			dev_err(dev->dev,
+				"buffer pitch (%d bytes) is not a multiple of pixel size (%d bytes)\n",
+				pitch, format->planes[i].stride_bpp);
+			ret = -EINVAL;
+			goto fail;
+		}
+
 		size = pitch * mode_cmd->height / format->planes[i].sub_y;
 
 		if (size > (omap_gem_mmap_size(bos[i]) - mode_cmd->offsets[i])) {
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 23/36] drm/omap: fix TILER on OMAP5
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (21 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 22/36] drm/omap: handle incompatible buffer stride and pixel size Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 24/36] drm/omap: fix plane's channel selection Tomi Valkeinen
                   ` (12 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

On OMAP5 it is not possible to use TILER buffer with CPU when caching or
write-combining is used. Doing so leads to errors from the memory
manager.

However, on OMAP4, write-combining works fine.

This patch adds platform specific data for the TILER, and a function
tiler_get_cpu_cache_flags() which can be used to get the caching mode to
be used.

Note that without write-combining the use of the TILER buffer with CPU
is unusably slow. It's still good to have it operational for testing
purposes.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_dmm_priv.h  |  6 +++++
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 39 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.h |  1 +
 drivers/gpu/drm/omapdrm/omap_gem.c       |  4 ++--
 4 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
index 58bcd6ae0255..d96660573076 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
@@ -153,6 +153,10 @@ struct refill_engine {
 	struct list_head idle_node;
 };
 
+struct dmm_platform_data {
+	uint32_t cpu_cache_flags;
+};
+
 struct dmm {
 	struct device *dev;
 	void __iomem *base;
@@ -183,6 +187,8 @@ struct dmm {
 
 	/* allocation list and lock */
 	struct list_head alloc_head;
+
+	const struct dmm_platform_data *plat_data;
 };
 
 #endif
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index b4476859c1ad..f06243b3d3c0 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -39,6 +39,10 @@
 static struct tcm *containers[TILFMT_NFORMATS];
 static struct dmm *omap_dmm;
 
+#if defined(CONFIG_OF)
+static const struct of_device_id dmm_of_match[];
+#endif
+
 /* global spinlock for protecting lists */
 static DEFINE_SPINLOCK(list_lock);
 
@@ -529,6 +533,11 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h)
 	return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h;
 }
 
+uint32_t tiler_get_cpu_cache_flags(void)
+{
+	return omap_dmm->plat_data->cpu_cache_flags;
+}
+
 bool dmm_is_available(void)
 {
 	return omap_dmm ? true : false;
@@ -592,6 +601,18 @@ static int omap_dmm_probe(struct platform_device *dev)
 
 	init_waitqueue_head(&omap_dmm->engine_queue);
 
+	if (dev->dev.of_node) {
+		const struct of_device_id *match;
+
+		match = of_match_node(dmm_of_match, dev->dev.of_node);
+		if (!match) {
+			dev_err(&dev->dev, "failed to find matching device node\n");
+			return -ENODEV;
+		}
+
+		omap_dmm->plat_data = match->data;
+	}
+
 	/* lookup hwmod data - base address and irq */
 	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (!mem) {
@@ -972,9 +993,23 @@ static const struct dev_pm_ops omap_dmm_pm_ops = {
 #endif
 
 #if defined(CONFIG_OF)
+static const struct dmm_platform_data dmm_omap4_platform_data = {
+	.cpu_cache_flags = OMAP_BO_WC,
+};
+
+static const struct dmm_platform_data dmm_omap5_platform_data = {
+	.cpu_cache_flags = OMAP_BO_UNCACHED,
+};
+
 static const struct of_device_id dmm_of_match[] = {
-	{ .compatible = "ti,omap4-dmm", },
-	{ .compatible = "ti,omap5-dmm", },
+	{
+		.compatible = "ti,omap4-dmm",
+		.data = &dmm_omap4_platform_data,
+	},
+	{
+		.compatible = "ti,omap5-dmm",
+		.data = &dmm_omap5_platform_data,
+	},
 	{},
 };
 #endif
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h
index 4fdd61e54bd2..e83c78372db8 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.h
@@ -106,6 +106,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient);
 size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h);
 void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h);
+uint32_t tiler_get_cpu_cache_flags(void);
 bool dmm_is_available(void);
 
 extern struct platform_driver omap_dmm_driver;
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 9b250c93b046..d37ee756a0b1 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1359,8 +1359,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
 		/* currently don't allow cached buffers.. there is some caching
 		 * stuff that needs to be handled better
 		 */
-		flags &= ~(OMAP_BO_CACHED|OMAP_BO_UNCACHED);
-		flags |= OMAP_BO_WC;
+		flags &= ~(OMAP_BO_CACHED|OMAP_BO_WC|OMAP_BO_UNCACHED);
+		flags |= tiler_get_cpu_cache_flags();
 
 		/* align dimensions to slot boundaries... */
 		tiler_align(gem2fmt(flags),
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 24/36] drm/omap: fix plane's channel selection
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (22 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 23/36] drm/omap: fix TILER on OMAP5 Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 25/36] drm/omap: tiler: fix race condition with engine->async Tomi Valkeinen
                   ` (11 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omap_plane_pre_apply() sets the plane's output channel too late, only
after the plane has already been otherwise configured and enabled. This
causes problems, as at the configuration stage we need to make decisions
based on the output channel.

This may lead to bad plane settings or failing to setup the plane.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_plane.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 6eedca107376..d52ff0455673 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -149,6 +149,8 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
 	DBG("%d,%d %pad %pad", info->pos_x, info->pos_y,
 			&info->paddr, &info->p_uv_addr);
 
+	dispc_ovl_set_channel_out(omap_plane->id, channel);
+
 	/* and finally, update omapdss: */
 	ret = dispc_ovl_setup(omap_plane->id, info, false,
 			      omap_crtc_timings(crtc), false);
@@ -158,7 +160,6 @@ static void omap_plane_pre_apply(struct omap_drm_apply *apply)
 	}
 
 	dispc_ovl_enable(omap_plane->id, true);
-	dispc_ovl_set_channel_out(omap_plane->id, channel);
 }
 
 static void omap_plane_post_apply(struct omap_drm_apply *apply)
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 25/36] drm/omap: tiler: fix race condition with engine->async
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (23 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 24/36] drm/omap: fix plane's channel selection Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 26/36] drm/omap: remove dummy PM functions Tomi Valkeinen
                   ` (10 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

The tiler irq handler uses engine->async value, but the code that sets
engine->async and enables the interrupt does not have a barrier. This
may cause the irq handler to see the old value of engine->async, causing
memory corruption.

Reported-by: Harinarayan Bhatta <harinarayan@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index f06243b3d3c0..a1a824db1dd6 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -273,6 +273,8 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
 
 	/* mark whether it is async to denote list management in IRQ handler */
 	engine->async = wait ? false : true;
+	/* verify that the irq handler sees the 'async' value */
+	smp_mb();
 
 	/* kick reload */
 	writel(engine->refill_pa,
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 26/36] drm/omap: remove dummy PM functions
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (24 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 25/36] drm/omap: tiler: fix race condition with engine->async Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 27/36] drm/omap: stop connector polling during suspend Tomi Valkeinen
                   ` (9 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omapdrm has dummy functions for platform_device's
suspend/resume/shutdown. The functions don't do anything, and those
platform device functions are deprecated, so remove them from omapdrm.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 63c953971c11..8d8cf82ecdf7 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -675,23 +675,6 @@ static struct drm_driver omap_drm_driver = {
 	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
-static int pdev_suspend(struct platform_device *pDevice, pm_message_t state)
-{
-	DBG("");
-	return 0;
-}
-
-static int pdev_resume(struct platform_device *device)
-{
-	DBG("");
-	return 0;
-}
-
-static void pdev_shutdown(struct platform_device *device)
-{
-	DBG("");
-}
-
 static int pdev_probe(struct platform_device *device)
 {
 	int r;
@@ -738,9 +721,6 @@ static struct platform_driver pdev = {
 	},
 	.probe = pdev_probe,
 	.remove = pdev_remove,
-	.suspend = pdev_suspend,
-	.resume = pdev_resume,
-	.shutdown = pdev_shutdown,
 };
 
 static int __init omap_drm_init(void)
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 27/36] drm/omap: stop connector polling during suspend
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (25 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 26/36] drm/omap: remove dummy PM functions Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 28/36] drm/omap: use DRM_ERROR_RATELIMITED() for error irqs Tomi Valkeinen
                   ` (8 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

When not using proper hotplug detection, DRM polls periodically the
connectors to find out if a cable is connected. This polling can happen
at any time, even very late in the suspend process.

This causes a problem with omapdrm, when the poll happens during the
suspend process after GPIOs have been disabled, leading to a crash in
gpio_get().

This patch fixes the issue by adding suspend and resume hooks to
omapdrm, in which we disable and enable, respectively, the polling.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 8d8cf82ecdf7..c4c237317901 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -706,9 +706,28 @@ static int pdev_remove(struct platform_device *device)
 	return 0;
 }
 
+static int omap_drm_suspend(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+	drm_kms_helper_poll_disable(drm_dev);
+
+	return 0;
+}
+
+static int omap_drm_resume(struct device *dev)
+{
+	struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+	drm_kms_helper_poll_enable(drm_dev);
+
+	return omap_gem_resume(dev);
+}
+
 #ifdef CONFIG_PM
 static const struct dev_pm_ops omapdrm_pm_ops = {
-	.resume = omap_gem_resume,
+	.suspend = omap_drm_suspend,
+	.resume = omap_drm_resume,
 };
 #endif
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 28/36] drm/omap: use DRM_ERROR_RATELIMITED() for error irqs
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (26 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 27/36] drm/omap: stop connector polling during suspend Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 29/36] drm/omap: fix race with error_irq Tomi Valkeinen
                   ` (7 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omapdrm uses normal DRM_ERROR() print when the HW reports an error. As
we sometimes may get a flood of errors, let's rather use
DRM_ERROR_RATELIMITED().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c  | 2 +-
 drivers/gpu/drm/omapdrm/omap_plane.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index a4d6f5ec627e..e91687fe41be 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -261,7 +261,7 @@ static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 	struct omap_crtc *omap_crtc =
 			container_of(irq, struct omap_crtc, error_irq);
 	struct drm_crtc *crtc = &omap_crtc->base;
-	DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
 	/* avoid getting in a flood, unregister the irq until next vblank */
 	__omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index d52ff0455673..1c6b63f39474 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -357,7 +357,8 @@ static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
 	struct omap_plane *omap_plane =
 			container_of(irq, struct omap_plane, error_irq);
-	DRM_ERROR("%s: errors: %08x\n", omap_plane->name, irqstatus);
+	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_plane->name,
+		irqstatus);
 }
 
 static const char *plane_names[] = {
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 29/36] drm/omap: fix race with error_irq
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (27 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 28/36] drm/omap: use DRM_ERROR_RATELIMITED() for error irqs Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 30/36] drm/omap: only ignore DIGIT SYNC LOST for TV output Tomi Valkeinen
                   ` (6 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omapdrm tries to avoid error floods by unregistering the error irq when
an error happens, and then registering the error irq again later.
However, the code is racy, as it sometimes tries to unregister the error
irq when it's already unregistered, leading to WARN().

Also, the code only registers the error irq again when something is done
on that particular output, i.e. if only TV is used to flip the buffers,
and LCD is showing a same buffer, an error on LCD will cause the LCD
error irq to be unregistered and never registered again.

To fix this, let's keep the error irqs always enabled and trust the
DRM_ERROR_RATELIMITED to limit the flood.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index e91687fe41be..c5c21776131a 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -72,6 +72,8 @@ struct omap_crtc {
 	 * XXX maybe fold into apply_work??
 	 */
 	struct work_struct page_flip_work;
+
+	bool ignore_digit_sync_lost;
 };
 
 /* -----------------------------------------------------------------------------
@@ -157,7 +159,7 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 	 * Digit output produces some sync lost interrupts during the first
 	 * frame when enabling, so we need to ignore those.
 	 */
-	omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
+	omap_crtc->ignore_digit_sync_lost = true;
 
 	framedone_irq = dispc_mgr_get_framedone_irq(channel);
 	vsync_irq = dispc_mgr_get_vsync_irq(channel);
@@ -188,7 +190,9 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 				omap_crtc->name, enable ? "enable" : "disable");
 	}
 
-	omap_irq_register(crtc->dev, &omap_crtc->error_irq);
+	omap_crtc->ignore_digit_sync_lost = false;
+	/* make sure the irq handler sees the value above */
+	mb();
 }
 
 
@@ -260,10 +264,14 @@ static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 {
 	struct omap_crtc *omap_crtc =
 			container_of(irq, struct omap_crtc, error_irq);
-	struct drm_crtc *crtc = &omap_crtc->base;
+
+	if (omap_crtc->ignore_digit_sync_lost) {
+		irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+		if (!irqstatus)
+			return;
+	}
+
 	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
-	/* avoid getting in a flood, unregister the irq until next vblank */
-	__omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
 }
 
 static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -272,9 +280,6 @@ static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
 			container_of(irq, struct omap_crtc, apply_irq);
 	struct drm_crtc *crtc = &omap_crtc->base;
 
-	if (!omap_crtc->error_irq.registered)
-		__omap_irq_register(crtc->dev, &omap_crtc->error_irq);
-
 	if (!dispc_mgr_go_busy(omap_crtc->channel)) {
 		struct omap_drm_private *priv =
 				crtc->dev->dev_private;
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 30/36] drm/omap: only ignore DIGIT SYNC LOST for TV output
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (28 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 29/36] drm/omap: fix race with error_irq Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 31/36] drm/omap: do not use BUG_ON(!spin_is_locked(x)) Tomi Valkeinen
                   ` (5 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

We need to ignore DIGIT SYNC LOST error when enabling/disabling TV
output. The code does that, but it ignores the DIGI SYNC LOST when
enabling any output. Normally this does no harm, but it could make us
miss DIGIT SYNC LOST on some rare occasions.

Fix the code to only ignore DIGIT SYNC LOST when enabling/disabling TV.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index c5c21776131a..7b93880a4577 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -155,11 +155,13 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 	if (dispc_mgr_is_enabled(channel) == enable)
 		return;
 
-	/*
-	 * Digit output produces some sync lost interrupts during the first
-	 * frame when enabling, so we need to ignore those.
-	 */
-	omap_crtc->ignore_digit_sync_lost = true;
+	if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
+		/*
+		 * Digit output produces some sync lost interrupts during the
+		 * first frame when enabling, so we need to ignore those.
+		 */
+		omap_crtc->ignore_digit_sync_lost = true;
+	}
 
 	framedone_irq = dispc_mgr_get_framedone_irq(channel);
 	vsync_irq = dispc_mgr_get_vsync_irq(channel);
@@ -190,9 +192,11 @@ static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 				omap_crtc->name, enable ? "enable" : "disable");
 	}
 
-	omap_crtc->ignore_digit_sync_lost = false;
-	/* make sure the irq handler sees the value above */
-	mb();
+	if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
+		omap_crtc->ignore_digit_sync_lost = false;
+		/* make sure the irq handler sees the value above */
+		mb();
+	}
 }
 
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 31/36] drm/omap: do not use BUG_ON(!spin_is_locked(x))
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (29 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 30/36] drm/omap: only ignore DIGIT SYNC LOST for TV output Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 32/36] drm/omap: fix race condition with dev->obj_list Tomi Valkeinen
                   ` (4 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

spin_is_locked(x) returns always 0 on uniprocessor, triggering BUG() in
omapdrm.

Change it to use assert_spin_locked() to fix the issue.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index f035d2bceae7..3eb097efc488 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -34,7 +34,7 @@ static void omap_irq_update(struct drm_device *dev)
 	struct omap_drm_irq *irq;
 	uint32_t irqmask = priv->vblank_mask;
 
-	BUG_ON(!spin_is_locked(&list_lock));
+	assert_spin_locked(&list_lock);
 
 	list_for_each_entry(irq, &priv->irq_list, node)
 		irqmask |= irq->irqmask;
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 32/36] drm/omap: fix race condition with dev->obj_list
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (30 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 31/36] drm/omap: do not use BUG_ON(!spin_is_locked(x)) Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 33/36] drm/omap: fix race conditon in DMM Tomi Valkeinen
                   ` (3 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

omap_gem_objects are added to dev->obj_list in omap_gem_new, and removed
in omap_gem_free_object. Unfortunately there's no locking for
dev->obj_list, which eventually leads to a crash:

WARNING: CPU: 1 PID: 1123 at lib/list_debug.c:59 __list_del_entry+0xa4/0xe0()
list_del corruption. prev->next should be e9281344, but was ea722b84

Add a spinlock to protect dev->obj_list.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 1 +
 drivers/gpu/drm/omapdrm/omap_drv.h | 3 +++
 drivers/gpu/drm/omapdrm/omap_gem.c | 5 +++++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index c4c237317901..c6980985884b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -491,6 +491,7 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
 
 	priv->wq = alloc_ordered_workqueue("omapdrm", 0);
 
+	spin_lock_init(&priv->list_lock);
 	INIT_LIST_HEAD(&priv->obj_list);
 
 	omap_gem_init(dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 57e11c1f589f..b31c79f15aed 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -105,6 +105,9 @@ struct omap_drm_private {
 
 	struct workqueue_struct *wq;
 
+	/* lock for obj_list below */
+	spinlock_t list_lock;
+
 	/* list of GEM objects: */
 	struct list_head obj_list;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index d37ee756a0b1..e9718b99a8a9 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1273,13 +1273,16 @@ unlock:
 void omap_gem_free_object(struct drm_gem_object *obj)
 {
 	struct drm_device *dev = obj->dev;
+	struct omap_drm_private *priv = dev->dev_private;
 	struct omap_gem_object *omap_obj = to_omap_bo(obj);
 
 	evict(obj);
 
 	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
 
+	spin_lock(&priv->list_lock);
 	list_del(&omap_obj->mm_list);
+	spin_unlock(&priv->list_lock);
 
 	drm_gem_free_mmap_offset(obj);
 
@@ -1377,7 +1380,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
 	if (!omap_obj)
 		goto fail;
 
+	spin_lock(&priv->list_lock);
 	list_add(&omap_obj->mm_list, &priv->obj_list);
+	spin_unlock(&priv->list_lock);
 
 	obj = &omap_obj->base;
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 33/36] drm/omap: fix race conditon in DMM
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (31 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 32/36] drm/omap: fix race condition with dev->obj_list Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 34/36] drm/omap: keep ref to old_fb Tomi Valkeinen
                   ` (2 subsequent siblings)
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

The omapdrm DMM code sometimes crashes with:

WARNING: CPU: 0 PID: 1235 at lib/list_debug.c:36 __list_add+0x8c/0xbc()
list_add double add: new=e9265368, prev=e90139c4, next=e9265368.

This is caused by the code calling release_engine() twice for the same
engine.

dmm_txn_commit(wait=true) call is supposed to wait until the DMM
transaction has been finished. And it does that, but it does not wait
for the irq handler to finish.

What happens is that the irq handler is triggered, and it either wakes
up the thread that called dmm_txn_commit(), or that thread never even
slept because the transaction was finished in the HW very quickly. That
thread then continues executing, even if the irq handler is not yet
finished, and a new transaction may be initiated. If that transaction is
async (i.e. wait=false), a 'async' flag is set to true. The original irq
handler, which has yet not finished, then sees the transaction as
'async', even if it was supposed to be 'sync'.

When that happens, the irq handler does an extra release_engine() call
because it thinks it need to release the engine, leading to the crash.

This patch fixes the issue by using completion to ensure that the irq
handler has finished before a dmm_txn_commit(wait=true) may continue.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_dmm_priv.h  |  2 +-
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 15 ++++++++-------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
index d96660573076..9f32a83ca507 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_priv.h
@@ -148,7 +148,7 @@ struct refill_engine {
 
 	bool async;
 
-	wait_queue_head_t wait_for_refill;
+	struct completion compl;
 
 	struct list_head idle_node;
 };
diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index a1a824db1dd6..20db850a1656 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -29,6 +29,7 @@
 #include <linux/mm.h>
 #include <linux/time.h>
 #include <linux/list.h>
+#include <linux/completion.h>
 
 #include "omap_dmm_tiler.h"
 #include "omap_dmm_priv.h"
@@ -146,10 +147,10 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg)
 
 	for (i = 0; i < dmm->num_engines; i++) {
 		if (status & DMM_IRQSTAT_LST) {
-			wake_up_interruptible(&dmm->engines[i].wait_for_refill);
-
 			if (dmm->engines[i].async)
 				release_engine(&dmm->engines[i]);
+
+			complete(&dmm->engines[i].compl);
 		}
 
 		status >>= 8;
@@ -273,7 +274,8 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
 
 	/* mark whether it is async to denote list management in IRQ handler */
 	engine->async = wait ? false : true;
-	/* verify that the irq handler sees the 'async' value */
+	reinit_completion(&engine->compl);
+	/* verify that the irq handler sees the 'async' and completion value */
 	smp_mb();
 
 	/* kick reload */
@@ -281,9 +283,8 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait)
 		dmm->base + reg[PAT_DESCR][engine->id]);
 
 	if (wait) {
-		if (wait_event_interruptible_timeout(engine->wait_for_refill,
-				wait_status(engine, DMM_PATSTATUS_READY) == 0,
-				msecs_to_jiffies(1)) <= 0) {
+		if (!wait_for_completion_timeout(&engine->compl,
+				msecs_to_jiffies(1))) {
 			dev_err(dmm->dev, "timed out waiting for done\n");
 			ret = -ETIMEDOUT;
 		}
@@ -719,7 +720,7 @@ static int omap_dmm_probe(struct platform_device *dev)
 						(REFILL_BUFFER_SIZE * i);
 		omap_dmm->engines[i].refill_pa = omap_dmm->refill_pa +
 						(REFILL_BUFFER_SIZE * i);
-		init_waitqueue_head(&omap_dmm->engines[i].wait_for_refill);
+		init_completion(&omap_dmm->engines[i].compl);
 
 		list_add(&omap_dmm->engines[i].idle_node, &omap_dmm->idle_head);
 	}
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 34/36] drm/omap: keep ref to old_fb
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (32 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 33/36] drm/omap: fix race conditon in DMM Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 35/36] drm/omap: add hibernation callbacks Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 36/36] drm/omap: tiler: add hibernation callback Tomi Valkeinen
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Laurent Pinchart

We store the fb being page-flipped to 'old_fb' field, but we don't
increase the ref count of the fb when doing that. While I am not
sure if it can cause problem in practice, it's still safer to keep a ref
when storing a pointer to a fb.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 7b93880a4577..f456544bf300 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -554,6 +554,7 @@ static void vblank_cb(void *arg)
 	struct drm_device *dev = crtc->dev;
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
 	unsigned long flags;
+	struct drm_framebuffer *fb;
 
 	spin_lock_irqsave(&dev->event_lock, flags);
 
@@ -561,10 +562,15 @@ static void vblank_cb(void *arg)
 	if (omap_crtc->event)
 		drm_send_vblank_event(dev, omap_crtc->pipe, omap_crtc->event);
 
+	fb = omap_crtc->old_fb;
+
 	omap_crtc->event = NULL;
 	omap_crtc->old_fb = NULL;
 
 	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	if (fb)
+		drm_framebuffer_unreference(fb);
 }
 
 static void page_flip_worker(struct work_struct *work)
@@ -620,6 +626,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
 
 	omap_crtc->event = event;
 	omap_crtc->old_fb = primary->fb = fb;
+	drm_framebuffer_reference(omap_crtc->old_fb);
 
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 35/36] drm/omap: add hibernation callbacks
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (33 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 34/36] drm/omap: keep ref to old_fb Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  2015-03-24 12:15 ` [PATCH 36/36] drm/omap: tiler: add hibernation callback Tomi Valkeinen
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Grygorii Strashko, Laurent Pinchart

From: Grygorii Strashko <Grygorii.Strashko@linaro.org>

Setting a dev_pm_ops suspend/resume pair but not a set of hibernation
functions means those pm functions will not be called upon hibernation.

Fix this by using SIMPLE_DEV_PM_OPS, which appropriately assigns the
suspend and hibernation handlers and move
omap_drm_suspend/omap_drm_resume under CONFIG_PM_SLEEP to avoid build
warnings.

Signed-off-by: Grygorii Strashko <Grygorii.Strashko@linaro.org>
[tomi.valkeinen@ti.com: fix conflict, clean up description]
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index c6980985884b..94920d47e3b6 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -707,6 +707,7 @@ static int pdev_remove(struct platform_device *device)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int omap_drm_suspend(struct device *dev)
 {
 	struct drm_device *drm_dev = dev_get_drvdata(dev);
@@ -724,20 +725,14 @@ static int omap_drm_resume(struct device *dev)
 
 	return omap_gem_resume(dev);
 }
-
-#ifdef CONFIG_PM
-static const struct dev_pm_ops omapdrm_pm_ops = {
-	.suspend = omap_drm_suspend,
-	.resume = omap_drm_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(omapdrm_pm_ops, omap_drm_suspend, omap_drm_resume);
+
 static struct platform_driver pdev = {
 	.driver = {
 		.name = DRIVER_NAME,
-#ifdef CONFIG_PM
 		.pm = &omapdrm_pm_ops,
-#endif
 	},
 	.probe = pdev_probe,
 	.remove = pdev_remove,
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 36/36] drm/omap: tiler: add hibernation callback
  2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
                   ` (34 preceding siblings ...)
  2015-03-24 12:15 ` [PATCH 35/36] drm/omap: add hibernation callbacks Tomi Valkeinen
@ 2015-03-24 12:15 ` Tomi Valkeinen
  35 siblings, 0 replies; 37+ messages in thread
From: Tomi Valkeinen @ 2015-03-24 12:15 UTC (permalink / raw)
  To: dri-devel; +Cc: Tomi Valkeinen, Grygorii Strashko, Laurent Pinchart

From: Grygorii Strashko <grygorii.strashko@linaro.org>

Setting a dev_pm_ops resume callback but not a set of hibernation
handler means that pm function will not be called upon hibernation.

Fix this by using SIMPLE_DEV_PM_OPS, which appropriately assigns the
suspend and hibernation handlers and move omap_dmm_resume under
CONFIG_PM_SLEEP to avoid build warnings.

Signed-off-by: Grygorii Strashko <grygorii.strashko@linaro.org>
Reviewed-by: Rob Clark <robdclark@gmail.com>
[tomi valkeinen: add missing 'static']
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
index 20db850a1656..042038e8a662 100644
--- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
+++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c
@@ -965,7 +965,7 @@ error:
 }
 #endif
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int omap_dmm_resume(struct device *dev)
 {
 	struct tcm_area area;
@@ -989,12 +989,10 @@ static int omap_dmm_resume(struct device *dev)
 
 	return 0;
 }
-
-static const struct dev_pm_ops omap_dmm_pm_ops = {
-	.resume = omap_dmm_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(omap_dmm_pm_ops, NULL, omap_dmm_resume);
+
 #if defined(CONFIG_OF)
 static const struct dmm_platform_data dmm_omap4_platform_data = {
 	.cpu_cache_flags = OMAP_BO_WC,
@@ -1024,9 +1022,7 @@ struct platform_driver omap_dmm_driver = {
 		.owner = THIS_MODULE,
 		.name = DMM_DRIVER_NAME,
 		.of_match_table = of_match_ptr(dmm_of_match),
-#ifdef CONFIG_PM
 		.pm = &omap_dmm_pm_ops,
-#endif
 	},
 };
 
-- 
2.3.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2015-03-24 12:17 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-24 12:15 [PATCH 00/36] drm/omap: patches for 4.1 Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 01/36] drm: omapdrm: Fix indentation of structure and array initializers Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 02/36] drm: omapdrm: Refactor CRTC creation code Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 03/36] drm: omapdrm: Remove unused variables Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 04/36] drm: omapdrm: Switch to the universal plane API Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 05/36] drm: omapdrm: Rename omap_plane_dpms() to omap_plane_set_enable() Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 06/36] drm: omapdrm: Reset the zorder property when disabling a plane Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 07/36] drm: omapdrm: Fix race condition between GO and vblank IRQ Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 08/36] drm: omapdrm: Remove manual update display support Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 09/36] drm: omapdrm: Remove omap_crtc->full_update field Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 10/36] drm: omapdrm: Avoid function forward declaration in omap_crtc.c Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 11/36] drm: omapdrm: Prefix all plane functions with omap_plane_ Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 12/36] drm: omapdrm: Pass integer source coordinates to omap_plane_mode_set() Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 13/36] drm: omapdrm: Planes are already disabled when destroyed Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 14/36] drm: omapdrm: Reorder CRTC functions Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 15/36] drm/omap: fix encoder-crtc mapping Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 16/36] drm/omap: page_flip: return -EBUSY if flip pending Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 17/36] drm/omap: clear omap_obj->paddr in omap_gem_put_paddr() Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 18/36] drm/omap: add pin refcounting to omap_framebuffer Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 19/36] drm/omap: add a comment why locking is missing Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 20/36] drm/omap: fix operation without fbdev Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 21/36] drm/omap: fix error handling in omap_framebuffer_create() Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 22/36] drm/omap: handle incompatible buffer stride and pixel size Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 23/36] drm/omap: fix TILER on OMAP5 Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 24/36] drm/omap: fix plane's channel selection Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 25/36] drm/omap: tiler: fix race condition with engine->async Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 26/36] drm/omap: remove dummy PM functions Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 27/36] drm/omap: stop connector polling during suspend Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 28/36] drm/omap: use DRM_ERROR_RATELIMITED() for error irqs Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 29/36] drm/omap: fix race with error_irq Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 30/36] drm/omap: only ignore DIGIT SYNC LOST for TV output Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 31/36] drm/omap: do not use BUG_ON(!spin_is_locked(x)) Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 32/36] drm/omap: fix race condition with dev->obj_list Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 33/36] drm/omap: fix race conditon in DMM Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 34/36] drm/omap: keep ref to old_fb Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 35/36] drm/omap: add hibernation callbacks Tomi Valkeinen
2015-03-24 12:15 ` [PATCH 36/36] drm/omap: tiler: add hibernation callback Tomi Valkeinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.