All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: dri-devel@lists.freedesktop.org
Subject: [PATCH 16/51] drm: Add drm_flip helper
Date: Thu, 25 Oct 2012 21:05:19 +0300	[thread overview]
Message-ID: <1351188354-24233-17-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1351188354-24233-1-git-send-email-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The drm_flip mechanism can be used to implement robust page flipping
support, and also to synchronize the flips on multiple hardware
scanout engines (eg. CRTCs and overlays).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/Makefile   |    2 +-
 drivers/gpu/drm/drm_flip.c |  376 ++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_flip.h     |  244 ++++++++++++++++++++++++++++
 3 files changed, 621 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_flip.c
 create mode 100644 include/drm/drm_flip.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 2ff5cef..f98afd8 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -12,7 +12,7 @@ drm-y       :=	drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
 		drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \
 		drm_crtc.o drm_modes.o drm_edid.o \
 		drm_info.o drm_debugfs.o drm_encoder_slave.o \
-		drm_trace_points.o drm_global.o drm_prime.o
+		drm_trace_points.o drm_global.o drm_prime.o drm_flip.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/drm_flip.c b/drivers/gpu/drm/drm_flip.c
new file mode 100644
index 0000000..6ccc3f8
--- /dev/null
+++ b/drivers/gpu/drm/drm_flip.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Ville Syrjälä <ville.syrjala@linux.intel.com>
+ */
+
+#include <drm/drm_flip.h>
+
+static void drm_flip_driver_cleanup(struct work_struct *work)
+{
+	struct drm_flip *flip, *next;
+	struct drm_flip_driver *driver =
+		container_of(work, struct drm_flip_driver, cleanup_work);
+	LIST_HEAD(list);
+
+	spin_lock_irq(&driver->lock);
+
+	list_cut_position(&list,
+			  &driver->cleanup_list,
+			  driver->cleanup_list.prev);
+
+	spin_unlock_irq(&driver->lock);
+
+	if (list_empty(&list))
+		return;
+
+	list_for_each_entry_safe(flip, next, &list, list) {
+		struct drm_flip_helper *helper = flip->helper;
+
+		WARN_ON(!flip->finished);
+
+		helper->funcs->cleanup(flip);
+	}
+}
+
+static void drm_flip_driver_finish(struct work_struct *work)
+{
+	struct drm_flip *flip, *next;
+	struct drm_flip_driver *driver =
+		container_of(work, struct drm_flip_driver, finish_work);
+	LIST_HEAD(list);
+	bool need_cleanup = false;
+
+	spin_lock_irq(&driver->lock);
+
+	list_cut_position(&list,
+			  &driver->finish_list,
+			  driver->finish_list.prev);
+
+	spin_unlock_irq(&driver->lock);
+
+	if (list_empty(&list))
+		return;
+
+	list_for_each_entry_safe(flip, next, &list, list) {
+		struct drm_flip_helper *helper = flip->helper;
+
+		helper->funcs->finish(flip);
+
+		spin_lock_irq(&driver->lock);
+
+		flip->finished = true;
+
+		/*
+		 * It's possible that drm_flip_set_scanout() was called after we
+		 * pulled this flip from finish_list, in which case the flip
+		 * could be in need of cleanup, but not on cleanup_list.
+		 */
+		if (flip == helper->scanout_flip) {
+			list_del_init(&flip->list);
+		} else {
+			need_cleanup = true;
+			list_move_tail(&flip->list, &driver->cleanup_list);
+		}
+
+		spin_unlock_irq(&driver->lock);
+	}
+
+	if (need_cleanup)
+		queue_work(driver->wq, &driver->cleanup_work);
+}
+
+static bool drm_flip_set_scanout(struct drm_flip_helper *helper,
+				 struct drm_flip *flip)
+{
+	struct drm_flip_driver *driver = helper->driver;
+	struct drm_flip *old = helper->scanout_flip;
+
+	helper->scanout_flip = flip;
+
+	if (old && old->finished)
+		list_move_tail(&old->list, &driver->cleanup_list);
+
+	return old != NULL;
+}
+
+static bool drm_flip_complete(struct drm_flip *flip)
+{
+	struct drm_flip_helper *helper = flip->helper;
+	struct drm_flip_driver *driver = helper->driver;
+	bool need_cleanup = false;
+
+	helper->funcs->complete(flip);
+
+	if (flip->flipped) {
+		if (drm_flip_set_scanout(helper, flip))
+			need_cleanup = true;
+	}
+
+	list_add_tail(&flip->list, &driver->finish_list);
+
+	return need_cleanup;
+}
+
+void drm_flip_helper_init(struct drm_flip_helper *helper,
+			  struct drm_flip_driver *driver,
+			  const struct drm_flip_helper_funcs *funcs)
+{
+	helper->pending_flip = NULL;
+	helper->scanout_flip = NULL;
+	helper->driver = driver;
+	helper->funcs = funcs;
+}
+
+void drm_flip_helper_clear(struct drm_flip_helper *helper)
+{
+	unsigned long flags;
+	struct drm_flip_driver *driver = helper->driver;
+	struct drm_flip *pending_flip;
+	bool need_finish = false;
+	bool need_cleanup = false;
+
+	spin_lock_irqsave(&driver->lock, flags);
+
+	pending_flip = helper->pending_flip;
+
+	if (pending_flip) {
+		BUG_ON(pending_flip->helper != helper);
+
+		need_finish = true;
+
+		if (drm_flip_complete(pending_flip))
+			need_cleanup = true;
+
+		helper->pending_flip = NULL;
+	}
+
+	if (drm_flip_set_scanout(helper, NULL))
+		need_cleanup = true;
+
+	spin_unlock_irqrestore(&driver->lock, flags);
+
+	if (need_finish)
+		queue_work(driver->wq, &driver->finish_work);
+
+	if (need_cleanup)
+		queue_work(driver->wq, &driver->cleanup_work);
+}
+
+void drm_flip_helper_fini(struct drm_flip_helper *helper)
+{
+	struct drm_flip_driver *driver = helper->driver;
+
+	drm_flip_helper_clear(helper);
+
+	flush_work_sync(&driver->finish_work);
+	flush_work_sync(&driver->cleanup_work);
+}
+
+void drm_flip_helper_vblank(struct drm_flip_helper *helper)
+{
+	struct drm_flip_driver *driver = helper->driver;
+	struct drm_flip *pending_flip;
+	unsigned long flags;
+	bool need_finish = false;
+	bool need_cleanup = false;
+
+	spin_lock_irqsave(&driver->lock, flags);
+
+	pending_flip = helper->pending_flip;
+
+	if (pending_flip) {
+		BUG_ON(pending_flip->helper != helper);
+
+		if (helper->funcs->vblank(pending_flip))
+			pending_flip->flipped = true;
+
+		if (pending_flip->flipped) {
+			need_finish = true;
+
+			if (drm_flip_complete(pending_flip))
+				need_cleanup = true;
+
+			helper->pending_flip = NULL;
+		}
+	}
+
+	spin_unlock_irqrestore(&driver->lock, flags);
+
+	if (need_finish)
+		queue_work(driver->wq, &driver->finish_work);
+
+	if (need_cleanup)
+		queue_work(driver->wq, &driver->cleanup_work);
+}
+
+void drm_flip_driver_init(struct drm_flip_driver *driver,
+			  const struct drm_flip_driver_funcs *funcs)
+{
+	spin_lock_init(&driver->lock);
+
+	INIT_LIST_HEAD(&driver->finish_list);
+	INIT_LIST_HEAD(&driver->cleanup_list);
+
+	INIT_WORK(&driver->finish_work, drm_flip_driver_finish);
+	INIT_WORK(&driver->cleanup_work, drm_flip_driver_cleanup);
+
+	driver->funcs = funcs;
+
+	driver->wq = create_singlethread_workqueue("drm_flip");
+}
+
+void drm_flip_driver_fini(struct drm_flip_driver *driver)
+{
+	destroy_workqueue(driver->wq);
+
+	/* All the scheduled flips should be cleaned up by now. */
+	WARN_ON(!list_empty(&driver->finish_list));
+	WARN_ON(!list_empty(&driver->cleanup_list));
+}
+
+void drm_flip_driver_schedule_flips(struct drm_flip_driver *driver,
+				    struct list_head *flips)
+{
+	unsigned long flags;
+	struct drm_flip *flip, *next;
+	bool need_finish = false;
+	bool need_cleanup = false;
+
+	spin_lock_irqsave(&driver->lock, flags);
+
+	list_for_each_entry(flip, flips, list) {
+		struct drm_flip_helper *helper = flip->helper;
+		struct drm_flip *pending_flip = helper->pending_flip;
+
+		if (helper->funcs->flip(flip, pending_flip))
+			pending_flip->flipped = true;
+	}
+
+	if (driver->funcs->flush)
+		driver->funcs->flush(driver);
+
+	/* Complete all flips that got overridden */
+	list_for_each_entry_safe(flip, next, flips, list) {
+		struct drm_flip_helper *helper = flip->helper;
+		struct drm_flip *pending_flip = helper->pending_flip;
+
+		BUG_ON(helper->driver != driver);
+
+		if (pending_flip) {
+			BUG_ON(pending_flip->helper != helper);
+
+			need_finish = true;
+
+			if (drm_flip_complete(pending_flip))
+				need_cleanup = true;
+		}
+
+		list_del_init(&flip->list);
+		helper->pending_flip = flip;
+	}
+
+	spin_unlock_irqrestore(&driver->lock, flags);
+
+	if (need_finish)
+		queue_work(driver->wq, &driver->finish_work);
+
+	if (need_cleanup)
+		queue_work(driver->wq, &driver->cleanup_work);
+}
+
+void drm_flip_driver_prepare_flips(struct drm_flip_driver *driver,
+				   struct list_head *flips)
+{
+	struct drm_flip *flip;
+
+	list_for_each_entry(flip, flips, list) {
+		struct drm_flip_helper *helper = flip->helper;
+
+		if (helper->funcs->prepare)
+			helper->funcs->prepare(flip);
+	}
+}
+
+void drm_flip_driver_complete_flips(struct drm_flip_driver *driver,
+				    struct list_head *flips)
+{
+	unsigned long flags;
+	struct drm_flip *flip, *next;
+	bool need_finish = false;
+	bool need_cleanup = false;
+
+	spin_lock_irqsave(&driver->lock, flags);
+
+	/* first complete all pending flips */
+	list_for_each_entry(flip, flips, list) {
+		struct drm_flip_helper *helper = flip->helper;
+		struct drm_flip *pending_flip = helper->pending_flip;
+
+		BUG_ON(helper->driver != driver);
+
+		if (pending_flip) {
+			BUG_ON(pending_flip->helper != helper);
+
+			need_finish = true;
+
+			if (drm_flip_complete(pending_flip))
+				need_cleanup = true;
+
+			helper->pending_flip = NULL;
+		}
+	}
+
+	/* then complete all new flips as well */
+	list_for_each_entry_safe(flip, next, flips, list) {
+		list_del_init(&flip->list);
+
+		/*
+		 * This is the flip that gets scanned out
+		 * next time the hardware is fired up.
+		 */
+		flip->flipped = true;
+
+		need_finish = true;
+
+		if (drm_flip_complete(flip))
+			need_cleanup = true;
+	}
+
+	spin_unlock_irqrestore(&driver->lock, flags);
+
+	if (need_finish)
+		queue_work(driver->wq, &driver->finish_work);
+
+	if (need_cleanup)
+		queue_work(driver->wq, &driver->cleanup_work);
+}
+
+void drm_flip_init(struct drm_flip *flip,
+		   struct drm_flip_helper *helper)
+{
+	flip->helper = helper;
+	flip->flipped = false;
+	flip->finished = false;
+	INIT_LIST_HEAD(&flip->list);
+}
diff --git a/include/drm/drm_flip.h b/include/drm/drm_flip.h
new file mode 100644
index 0000000..4172d6e
--- /dev/null
+++ b/include/drm/drm_flip.h
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and iated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Ville Syrjälä <ville.syrjala@linux.intel.com>
+ */
+
+#ifndef DRM_FLIP_H
+#define DRM_FLIP_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+struct drm_flip;
+struct drm_flip_helper;
+struct drm_flip_driver;
+
+/* Driver callbacks for drm_flip_driver */
+struct drm_flip_driver_funcs {
+	/*
+	 * Optional callback, called after drm_flip_driver_schedule_flips()
+	 * has called drm_flip_helper::flip() for all the provided flips.
+	 * Can be used to:
+	 * - commit the flips atomically to the hardware, if the
+	 *   hardware provides some mechanism to do that.
+	 * - flush posted writes to make sure all the flips have reached
+	 *   the hardware
+	 * Called with drm_flip_driver::lock held.
+	 */
+	void (*flush)(struct drm_flip_driver *driver);
+};
+
+/*
+ * The driver needs one drm_flip_driver to
+ * coordinates the drm_flip mechanism.
+ */
+struct drm_flip_driver {
+	/* protects drm_flip_driver, drm_flip_helper, and drm_flip internals. */
+	spinlock_t lock;
+
+	/* list of drm_flips waiting to be finished, protected by 'lock' */
+	struct list_head finish_list;
+
+	/* list of drm_flips waiting to be cleaned up, protected by 'lock' */
+	struct list_head cleanup_list;
+
+	/* work used to finish the drm_flips */
+	struct work_struct finish_work;
+
+	/* work used to clean up the drm_flips */
+	struct work_struct cleanup_work;
+
+	/* driver provided callback functions */
+	const struct drm_flip_driver_funcs *funcs;
+
+	/* work queue for finish_work and cleanup_work */
+	struct workqueue_struct *wq;
+};
+
+/* Driver callbacks for drm_flip_helper */
+struct drm_flip_helper_funcs {
+	/*
+	 * Optional function to perform heavy but non-timing
+	 * critial preparations for the flip.
+	 * Called from drm_flip_driver_prepare_flips() with
+	 * no extra locks being held.
+	 */
+	void (*prepare)(struct drm_flip *flip);
+	/*
+	 * Instruct the hardware to flip on the next vblank.
+	 * Must return true, iff pending_flip exists, and has
+	 * actually flipped (ie. now being scanned out).
+	 * Otherwise must return false.
+	 * Called with drm_flip_driver::lock held.
+	 */
+	bool (*flip)(struct drm_flip *flip,
+		     struct drm_flip *pending_flip);
+	/*
+	 * Called from drm_flip_helper_vblank() if
+	 * pending_flip exists. Must return true, iff
+	 * pending_flip has actually flipped (ie. now
+	 * being scanned out). Otherwise must return false.
+	 * Called with drm_flip_driver::lock held.
+	 */
+	bool (*vblank)(struct drm_flip *pending_flip);
+
+	/*
+	 * The flip has just occured, or it got overwritten
+	 * by a more recent flip. If the flip occured, it is
+	 * now being scanned out, otherwise it is scheduled
+	 * for cleanup.
+	 * Can be called from drm_flip_driver_schedule_flips(),
+	 * drm_flip_driver_complete_flips(), or from
+	 * drm_flip_helper_vblank().
+	 * Called with drm_flip_driver::lock held.
+	 */
+	void (*complete)(struct drm_flip *flip);
+
+	/*
+	 * Perform finishing steps on the flip. Called from a workqueue
+	 * soon after the flip has completed. The flip's buffer may be
+	 * actively scanned out.
+	 * Called with no locks being held.
+	 */
+	void (*finish)(struct drm_flip *flip);
+
+	/*
+	 * Perform final cleanup on the flip. Called from a workqueue
+	 * after the flip's buffer is no longer being scanned out.
+	 * Called with no locks being held.
+	 */
+	void (*cleanup)(struct drm_flip *flip);
+
+};
+
+/*
+ * The driver needs one drm_flip_helper for each scanout engine it
+ * wants to operate through the drm_flip mechanism.
+ */
+struct drm_flip_helper {
+	/* drm_flip from the previous drm_flip_schedule() call */
+	struct drm_flip *pending_flip;
+	/* drm_flip whose buffer is being scanned out */
+	struct drm_flip *scanout_flip;
+	/* associated drm_flip_driver */
+	struct drm_flip_driver *driver;
+	/* driver provided callback functions */
+	const struct drm_flip_helper_funcs *funcs;
+};
+
+/*
+ * This structure represents a single page flip operation.
+ */
+struct drm_flip {
+	/* associated drm_flip_helper */
+	struct drm_flip_helper *helper;
+	/* has this flip occured? */
+	bool flipped;
+	/* has the finish work been executed for this flip? */
+	bool finished;
+	/* used to keep this flip on various lists */
+	struct list_head list;
+};
+
+/*
+ * Initialize the flip driver.
+ */
+void drm_flip_driver_init(struct drm_flip_driver *driver,
+			  const struct drm_flip_driver_funcs *funcs);
+
+/*
+ * Finalize the flip driver. This will block until all the
+ * pending finish and cleanup work has been completed.
+ */
+void drm_flip_driver_fini(struct drm_flip_driver *driver);
+
+/*
+ * Initialize flip helper.
+ */
+void drm_flip_helper_init(struct drm_flip_helper *helper,
+			  struct drm_flip_driver *driver,
+			  const struct drm_flip_helper_funcs *funcs);
+
+/*
+ * Clear flip helper state. This will forcefully complete the
+ * helper's pending flip (if any).
+ */
+void drm_flip_helper_clear(struct drm_flip_helper *helper);
+
+/*
+ * Finalize the flip helper. This will forcefully complete the
+ * helper's pending flip (if any), and wait for the finish and
+ * cleanup works to finish.
+ */
+void drm_flip_helper_fini(struct drm_flip_helper *helper);
+
+/*
+ * Call this from the driver's vblank handler for the scanout engine
+ * associated with this helper.
+ */
+void drm_flip_helper_vblank(struct drm_flip_helper *helper);
+
+/*
+ * This will call drm_flip_helper::prepare() (if provided) for all the
+ * drm_flips on the list. The purpose is to perform any non-timing critical
+ * preparation steps for the flips before taking locks or disabling interrupts.
+ */
+void drm_flip_driver_prepare_flips(struct drm_flip_driver *driver,
+				   struct list_head *flips);
+
+/*
+ * Schedule the flips on the list to occur on the next vblank.
+ *
+ * This will call drm_flip_helper::flip() for all the drm_flips on the list.
+ * It will then call drm_flip_driver::flush(), after which it will complete
+ * any pending_flip that got overridden by the new flips.
+ *
+ * Unless the hardware provides some mechanism to synchronize the flips, the
+ * time spent until drm_flip_driver::flush() is timing critical and the driver
+ * must somehow make sure it can complete the operation in a seemingly atomic
+ * fashion.
+ */
+void drm_flip_driver_schedule_flips(struct drm_flip_driver *driver,
+				    struct list_head *flips);
+
+/*
+ * This will complete any pending_flip and also all the flips
+ * on the provided list (in that order).
+ *
+ * Call this instead of drm_flip_driver_schedule_flips()
+ * eg. if the hardware powered down, and you just want to keep
+ * the drm_flip mechanim's state consistent w/o waking up the
+ * hardware.
+ */
+void drm_flip_driver_complete_flips(struct drm_flip_driver *driver,
+				    struct list_head *flips);
+
+/*
+ * Initialize the flip structure members.
+ */
+void drm_flip_init(struct drm_flip *flip,
+		   struct drm_flip_helper *helper);
+
+#endif
-- 
1.7.8.6

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

  parent reply	other threads:[~2012-10-25 18:16 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-25 18:05 [PATCH 00/51] Atomic mode setting and page flip ville.syrjala
2012-10-25 18:05 ` [PATCH 01/51] drm: Be more paranoid with integer overflows ville.syrjala
2012-10-25 18:05 ` [PATCH 02/51] drm: Constify some function arguments ville.syrjala
2012-10-25 18:05 ` [PATCH 03/51] drm: Ignore blob propertys in drm_property_change_is_valid() ville.syrjala
2012-10-25 18:05 ` [PATCH 04/51] drm: Add struct drm_region and assorted utility functions ville.syrjala
2012-10-25 18:05 ` [PATCH 05/51] drm: Add drm_calc_{hscale, vscale}() " ville.syrjala
2012-10-25 18:05 ` [PATCH 06/51] drm: Keep a copy of last plane coordinates ville.syrjala
2012-10-25 18:05 ` [PATCH 07/51] drm: Add restore_fbdev_mode() hook to drm_fb_helper ville.syrjala
2012-10-25 18:05 ` [PATCH 08/51] drm: Export drm_property_create_blob() and drm_property_destroy_blob() ville.syrjala
2012-10-25 18:05 ` [PATCH 09/51] drm: Allow signed values for range properties ville.syrjala
2012-10-25 18:05 ` [PATCH 10/51] drm: Allow drm_mode_object_find() to look up an object of any type ville.syrjala
2012-10-25 18:05 ` [PATCH 11/51] drm: Export drm_encoder_crtc_ok ville.syrjala
2012-10-25 18:05 ` [PATCH 12/51] drm: Export drm_crtc_prepare_encoders() ville.syrjala
2012-10-25 18:05 ` [PATCH 13/51] drm: Refactor object property check code ville.syrjala
2012-10-25 18:05 ` [PATCH 14/51] drm: Export mode<->umode conversion functions ville.syrjala
2012-10-25 18:05 ` [PATCH 15/51] drm: Make blobs resizeable ville.syrjala
2012-10-25 18:05 ` ville.syrjala [this message]
2012-10-25 18:05 ` [PATCH 17/51] drm: Add mode_blob and connector_ids_blob to drm_crtc ville.syrjala
2012-10-25 18:05 ` [PATCH 18/51] drm: Add the atomic modeset ioctl ville.syrjala
2012-10-25 18:05 ` [PATCH 19/51] drm/i915: Fix display pixel format handling ville.syrjala
2012-10-25 18:05 ` [PATCH 20/51] drm/i915: Add SURFLIVE register definitions ville.syrjala
2012-10-25 18:05 ` [PATCH 21/51] drm/i915: Implement execbuffer wait for all planes ville.syrjala
2012-10-25 18:05 ` [PATCH 22/51] drm/i915: Check framebuffer stride more thoroughly ville.syrjala
2012-10-25 18:05 ` [PATCH 23/51] drm/i915: Check the framebuffer offset ville.syrjala
2012-10-25 18:05 ` [PATCH 24/51] drm/i915: Handle framebuffer offsets[] ville.syrjala
2012-10-25 18:05 ` [PATCH 25/51] drm/i915: Implement proper clipping for video sprites ville.syrjala
2012-10-25 18:05 ` [PATCH 26/51] drm/i915: pixel_size == cpp ville.syrjala
2012-10-25 18:05 ` [PATCH 27/51] drm/i915: Bad pixel formats can't reach the sprite code ville.syrjala
2012-10-25 18:05 ` [PATCH 28/51] drm/i915: Implement restore_fbdev_mode hook ville.syrjala
2012-10-25 18:05 ` [PATCH 29/51] drm/i915: Split clipping and checking from update_plane hook ville.syrjala
2012-10-25 18:05 ` [PATCH 30/51] drm/i915: Factor out i9xx_compute_clocks() like ironlake_compute_clocks() ville.syrjala
2012-10-25 18:05 ` [PATCH 31/51] drm/i915: Consitify adjusted_mode parameter ville.syrjala
2012-10-25 18:05 ` [PATCH 32/51] drm/i915: Add intel_check_clock() ville.syrjala
2012-10-25 18:05 ` [PATCH 33/51] drm/i915: store cursor_handle in struct intel_crtc ville.syrjala
2012-10-25 18:05 ` [PATCH 34/51] drm/i915: split cursor setting code into prepare/commit/unref parts ville.syrjala
2012-10-25 18:05 ` [PATCH 35/51] drm/i915: unstatic cursor functions for use with atomic modesetting ville.syrjala
2012-10-25 18:05 ` [PATCH 36/51] drm/i915: Unstatic intel_finish_fb() ville.syrjala
2012-10-25 18:05 ` [PATCH 37/51] drm/i915: Pull intel_pipe_set_base() out of the crtc_mode_set() functions ville.syrjala
2012-10-25 18:05 ` [PATCH 38/51] drm/i915: Unstatic intel_crtc_update_sarea() ville.syrjala
2012-10-25 18:05 ` [PATCH 39/51] drm/i915: Introduce intel_crtc_update_sarea_pos() ville.syrjala
2012-10-25 18:05 ` [PATCH 40/51] drm/i915: Constify mode argument to intel_modeset_adjusted_mode() ville.syrjala
2012-10-25 18:05 ` [PATCH 41/51] drm/i915: Unstatic intel_crtc_mode_fixup() ville.syrjala
2012-10-25 18:05 ` [PATCH 42/51] drm/i915: Introduce intel_plane_regs ville.syrjala
2012-10-25 18:05 ` [PATCH 43/51] drm/i915: Split primary plane update_plane() into calc+commit phases ville.syrjala
2012-10-25 18:05 ` [PATCH 44/51] drm/i915: Split sprite " ville.syrjala
2012-10-25 18:05 ` [PATCH 45/51] drm/i915: Implement atomic modesetting ville.syrjala
2012-10-25 18:05 ` [PATCH 46/51] drm/i915: Add support for atomic modesetting completion events ville.syrjala
2012-11-01 11:12   ` Daniel Vetter
2012-11-01 14:39     ` Jesse Barnes
2012-11-01 17:07       ` Ville Syrjälä
2012-11-01 17:12         ` Jesse Barnes
2012-11-01 22:39           ` Daniel Vetter
2012-11-02  9:10             ` Ville Syrjälä
2012-11-07 20:29             ` Rob Clark
2012-11-09 21:20               ` Daniel Vetter
2012-11-09 21:25                 ` Rob Clark
2012-10-25 18:05 ` [PATCH 47/51] drm/i915: Add atomic page flip support ville.syrjala
2012-10-25 18:05 ` [PATCH 48/51] drm/i915: Unstatic intel_enable_primary() and intel_disable_primary() ville.syrjala
2012-10-25 18:05 ` [PATCH 49/51] drm/i915: Respect primary_disabled in crtc_enable() ville.syrjala
2012-10-25 18:05 ` [PATCH 50/51] drm/i915: Enable/disable primary plane in calc_plane() ville.syrjala
2012-10-25 18:05 ` [PATCH 51/51] drm/i915: Add primary plane disable logic to atomic mode setting code ville.syrjala

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1351188354-24233-17-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.