summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch307
1 files changed, 307 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch
new file mode 100644
index 0000000000..1b85ecba09
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.31.5/linux-2.6.31-drm-kms-flip.patch
@@ -0,0 +1,307 @@
1From 4e8354884daa2ee3e491bae69a81f85a2d1ca8ba Mon Sep 17 00:00:00 2001
2From: Fei Jiang <fei.jiang@intel.com>
3Date: Mon, 3 Aug 2009 11:31:53 -0400
4Subject: [PATCH] change for general drm code to implement kms-flip feature
5
6
7Signed-off-by: Fei Jiang <fei.jiang@intel.com>
8---
9 drivers/gpu/drm/drm_crtc.c | 128 ++++++++++++++++++++++++++++++++++++++++++++
10 drivers/gpu/drm/drm_drv.c | 1 +
11 drivers/gpu/drm/drm_irq.c | 30 ++++++++++
12 include/drm/drm.h | 1 +
13 include/drm/drmP.h | 9 +++
14 include/drm/drm_crtc.h | 12 ++++
15 include/drm/drm_mode.h | 16 ++++++
16 7 files changed, 197 insertions(+), 0 deletions(-)
17
18diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
19index 8fab789..3ada446
20--- a/drivers/gpu/drm/drm_crtc.c
21+++ b/drivers/gpu/drm/drm_crtc.c
22@@ -2452,3 +2452,131 @@ out:
23 mutex_unlock(&dev->mode_config.mutex);
24 return ret;
25 }
26+
27+/**
28+ * drm_mode_page_flip_ioctl - page flip ioctl
29+ * @dev: DRM device
30+ * @data: ioctl args
31+ * @file_priv: file private data
32+ *
33+ * The page flip ioctl replaces the current front buffer with a new
34+ * one, using the CRTC's set_base function, which should just update
35+ * the front buffer base pointer. It's up to set_base to make
36+ * sure the update doesn't result in tearing (on some hardware the
37+ * base register is double buffered, so this is easy).
38+ *
39+ * Note that this covers just the simple case of flipping the front
40+ * buffer immediately. Interval handling and interlaced modes have to
41+ * be handled by userspace, or with new ioctls.
42+ */
43+int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
44+ struct drm_file *file_priv)
45+{
46+#if 0
47+ struct drm_pending_flip *pending;
48+#endif
49+
50+ struct drm_mode_page_flip *flip_data = data;
51+ struct drm_mode_object *drm_obj, *fb_obj;
52+ struct drm_crtc *crtc;
53+ int ret = 0;
54+
55+ if (!(drm_core_check_feature(dev, DRIVER_MODESET)))
56+ return -ENODEV;
57+
58+ /*
59+ * Reject unknown flags so future userspace knows what we (don't)
60+ * support
61+ */
62+ if (flip_data->flags & (~DRM_MODE_PAGE_FLIP_FLAGS_MASK)) {
63+ DRM_DEBUG("bad page flip flags\n");
64+ return -EINVAL;
65+ }
66+#if 0
67+ pending = kzalloc(sizeof *pending, GFP_KERNEL);
68+ if (pending == NULL)
69+ return -ENOMEM;
70+#endif
71+ mutex_lock(&dev->struct_mutex);
72+
73+ fb_obj = drm_mode_object_find(dev, flip_data->fb_id,
74+ DRM_MODE_OBJECT_FB);
75+ if (!fb_obj) {
76+ DRM_DEBUG("unknown fb %d\n", flip_data->fb_id);
77+ ret = -ENOENT;
78+ goto out_unlock;
79+ }
80+
81+ drm_obj = drm_mode_object_find(dev, flip_data->crtc_id,
82+ DRM_MODE_OBJECT_CRTC);
83+ if (!drm_obj) {
84+ DRM_DEBUG("unknown crtc %d\n", flip_data->crtc_id);
85+ ret = -ENOENT;
86+ goto out_unlock;
87+ }
88+ crtc = obj_to_crtc(drm_obj);
89+ if (!crtc->enabled) {
90+ DRM_DEBUG("crtc %d not enabled\n", flip_data->crtc_id);
91+ ret = -EINVAL;
92+ goto out_unlock;
93+ }
94+
95+#if 0
96+ if (crtc->fb->funcs->unpin == NULL) {
97+ DRM_DEBUG("fb for crtc %d does not support delayed unpin\n",
98+ flip_data->crtc_id);
99+ ret = -ENODEV;
100+ goto out_unlock;
101+ }
102+
103+ pending->crtc = crtc;
104+ pending->old_fb = crtc->fb;
105+ pending->pipe = crtc->pipe;
106+ pending->event.base.type = DRM_EVENT_MODE_PAGE_FLIP;
107+ pending->event.base.length = sizeof pending->event;
108+ pending->event.user_data = flip_data->user_data;
109+ pending->pending_event.event = &pending->event.base;
110+ pending->pending_event.file_priv = file_priv;
111+ pending->pending_event.destroy =
112+ (void (*) (struct drm_pending_event *)) kfree;
113+
114+ /* Get vblank ref for completion handling */
115+ ret = drm_vblank_get(dev, crtc->pipe);
116+ if (ret) {
117+ DRM_DEBUG("failed to take vblank ref\n");
118+ goto out_unlock;
119+ }
120+
121+ pending->frame = drm_vblank_count(dev, crtc->pipe);
122+ list_add_tail(&pending->link, &dev->flip_list);
123+#endif
124+
125+ /*
126+ * The set_base call will change the domain on the new fb,
127+ * which will force the rendering to finish and block the
128+ * ioctl. We need to do this last part from a work queue, to
129+ * avoid blocking userspace here.
130+ */
131+ crtc->fb = obj_to_fb(fb_obj);
132+retry_set:
133+ ret = (*crtc->funcs->set_base)(crtc, 0, 0, NULL);
134+ if (ret == -ERESTARTSYS)
135+ goto retry_set;
136+
137+ if (ret) {
138+ DRM_ERROR("set_base failed: %d\n", ret);
139+ goto out_unlock;
140+ }
141+
142+ mutex_unlock(&dev->struct_mutex);
143+
144+ return 0;
145+
146+out_unlock:
147+ mutex_unlock(&dev->struct_mutex);
148+#if 0
149+ kfree(pending);
150+#endif
151+ return ret;
152+}
153+
154diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
155index 1ce7977..761c2ec
156--- a/drivers/gpu/drm/drm_drv.c
157+++ b/drivers/gpu/drm/drm_drv.c
158@@ -145,6 +145,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
159 DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
160 DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
161 DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
162+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
163 };
164
165 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
166diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
167index b4a3dbc..d5104df
168--- a/drivers/gpu/drm/drm_irq.c
169+++ b/drivers/gpu/drm/drm_irq.c
170@@ -71,6 +71,28 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
171 return 0;
172 }
173
174+#if 0
175+static void drm_flip_work_func(struct work_struct *work)
176+{
177+ struct drm_device *dev =
178+ container_of(work, struct drm_device, flip_work);
179+#if 0
180+ struct drm_pending_flip *f, *t;
181+#endif
182+ u32 frame;
183+
184+ mutex_lock(&dev->struct_mutex);
185+
186+ list_for_each_entry_safe(f, t, &dev->flip_list, link) {
187+ frame = drm_vblank_count(dev, f->pipe);
188+ if (vblank_after(frame, f->frame))
189+ drm_finish_pending_flip(dev, f, frame);
190+ }
191+
192+ mutex_unlock(&dev->struct_mutex);
193+}
194+#endif
195+
196 static void vblank_disable_fn(unsigned long arg)
197 {
198 struct drm_device *dev = (struct drm_device *)arg;
199@@ -161,6 +183,11 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
200 atomic_set(&dev->vblank_refcount[i], 0);
201 }
202
203+#if 0
204+ INIT_LIST_HEAD(&dev->flip_list);
205+ INIT_WORK(&dev->flip_work, drm_flip_work_func);
206+#endif
207+
208 dev->vblank_disable_allowed = 0;
209
210 return 0;
211@@ -626,5 +653,8 @@ void drm_handle_vblank(struct drm_device *dev, int crtc)
212 {
213 atomic_inc(&dev->_vblank_count[crtc]);
214 DRM_WAKEUP(&dev->vbl_queue[crtc]);
215+#if 0
216+ schedule_work(&dev->flip_work);
217+#endif
218 }
219 EXPORT_SYMBOL(drm_handle_vblank);
220diff --git a/include/drm/drm.h b/include/drm/drm.h
221index 7cb50bd..78bd91b
222--- a/include/drm/drm.h
223+++ b/include/drm/drm.h
224@@ -686,6 +686,7 @@ struct drm_gem_open {
225 #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
226 #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
227 #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int)
228+#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOW( 0xB0, struct drm_mode_page_flip)
229
230 /**
231 * Device specific ioctls should only be in their respective headers
232diff --git a/include/drm/drmP.h b/include/drm/drmP.h
233index c5122bf..36f9e6a
234--- a/include/drm/drmP.h
235+++ b/include/drm/drmP.h
236@@ -976,6 +976,15 @@ struct drm_device {
237 cycles_t ctx_start;
238 cycles_t lck_start;
239
240+ struct work_struct flip_work;
241+
242+#if 0
243+ /**
244+ * List of objects waiting on flip completion
245+ */
246+ struct list_head flip_list;
247+#endif
248+
249 struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
250 wait_queue_head_t buf_readers; /**< Processes waiting to read */
251 wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
252diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
253index 7300fb8..742c870
254--- a/include/drm/drm_crtc.h
255+++ b/include/drm/drm_crtc.h
256@@ -331,6 +331,16 @@ struct drm_crtc_funcs {
257 void (*destroy)(struct drm_crtc *crtc);
258
259 int (*set_config)(struct drm_mode_set *set);
260+
261+ /*
262+ * Move the crtc on the current fb to the given position.
263+ * This function is optional. If old_fb is provided, the
264+ * function will wait for vblank and unpin it. If old_fb is
265+ * NULL, nothing is unpinned and the caller must call
266+ * mode_unpin_fb to release the old framebuffer.
267+ */
268+ int (*set_base)(struct drm_crtc *crtc, int x, int y,
269+ struct drm_framebuffer *old_fb);
270 };
271
272 /**
273@@ -736,4 +746,6 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
274 extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
275 void *data, struct drm_file *file_priv);
276 extern bool drm_detect_hdmi_monitor(struct edid *edid);
277+extern int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data,
278+ struct drm_file *file_priv);
279 #endif /* __DRM_CRTC_H__ */
280diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
281index ae304cc..464b779
282--- a/include/drm/drm_mode.h
283+++ b/include/drm/drm_mode.h
284@@ -265,4 +265,20 @@ struct drm_mode_crtc_lut {
285 __u64 blue;
286 };
287
288+#define DRM_MODE_PAGE_FLIP_WAIT (1<<0) /* block on previous page flip */
289+#define DRM_MODE_PAGE_FLIP_FLAGS_MASK (DRM_MODE_PAGE_FLIP_WAIT)
290+
291+struct drm_mode_page_flip {
292+ /** Handle of new front buffer */
293+ __u32 fb_id;
294+ __u32 crtc_id;
295+
296+ /* 64 bit cookie returned to userspace in the page flip event. */
297+ __u64 user_data;
298+ /**
299+ * page flip flags (wait on flip only for now)
300+ */
301+ __u32 flags;
302+};
303+
304 #endif
305--
3061.5.3.4
307