diff options
author | Andreas Pokorny <andreas.pokorny@canonical.com> | 2014-08-08 04:40:55 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-09-03 01:35:27 -0400 |
commit | 058e9f5c8236ad740ab984588b507758e5feee6d (patch) | |
tree | 21a2b80796bbc325069625cdb121dc92122165a1 /drivers/gpu/drm/qxl | |
parent | 6ba59f3b5c977af2df3f9446f030f71e29d77dc1 (diff) |
drm/qxl: simple crtc page flipping emulated using buffer copy
Signed-off-by: Andreas Pokorny <andreas.pokorny@canonical.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/qxl')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_display.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_kms.c | 16 |
3 files changed, 79 insertions, 4 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index b8ced08b6291..af9e78546688 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c | |||
@@ -187,6 +187,54 @@ static void qxl_crtc_destroy(struct drm_crtc *crtc) | |||
187 | kfree(qxl_crtc); | 187 | kfree(qxl_crtc); |
188 | } | 188 | } |
189 | 189 | ||
190 | static int qxl_crtc_page_flip(struct drm_crtc *crtc, | ||
191 | struct drm_framebuffer *fb, | ||
192 | struct drm_pending_vblank_event *event, | ||
193 | uint32_t page_flip_flags) | ||
194 | { | ||
195 | struct drm_device *dev = crtc->dev; | ||
196 | struct qxl_device *qdev = dev->dev_private; | ||
197 | struct qxl_crtc *qcrtc = to_qxl_crtc(crtc); | ||
198 | struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb); | ||
199 | struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb); | ||
200 | struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj); | ||
201 | struct qxl_bo *bo = gem_to_qxl_bo(qfb_src->obj); | ||
202 | unsigned long flags; | ||
203 | struct drm_clip_rect norect = { | ||
204 | .x1 = 0, | ||
205 | .y1 = 0, | ||
206 | .x2 = fb->width, | ||
207 | .y2 = fb->height | ||
208 | }; | ||
209 | int inc = 1; | ||
210 | int one_clip_rect = 1; | ||
211 | int ret = 0; | ||
212 | |||
213 | crtc->primary->fb = fb; | ||
214 | bo_old->is_primary = false; | ||
215 | bo->is_primary = true; | ||
216 | |||
217 | ret = qxl_bo_reserve(bo, false); | ||
218 | if (ret) | ||
219 | return ret; | ||
220 | |||
221 | qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0, | ||
222 | &norect, one_clip_rect, inc); | ||
223 | |||
224 | drm_vblank_get(dev, qcrtc->index); | ||
225 | |||
226 | if (event) { | ||
227 | spin_lock_irqsave(&dev->event_lock, flags); | ||
228 | drm_send_vblank_event(dev, qcrtc->index, event); | ||
229 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
230 | } | ||
231 | drm_vblank_put(dev, qcrtc->index); | ||
232 | |||
233 | qxl_bo_unreserve(bo); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
190 | static int | 238 | static int |
191 | qxl_hide_cursor(struct qxl_device *qdev) | 239 | qxl_hide_cursor(struct qxl_device *qdev) |
192 | { | 240 | { |
@@ -374,6 +422,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { | |||
374 | .cursor_move = qxl_crtc_cursor_move, | 422 | .cursor_move = qxl_crtc_cursor_move, |
375 | .set_config = drm_crtc_helper_set_config, | 423 | .set_config = drm_crtc_helper_set_config, |
376 | .destroy = qxl_crtc_destroy, | 424 | .destroy = qxl_crtc_destroy, |
425 | .page_flip = qxl_crtc_page_flip, | ||
377 | }; | 426 | }; |
378 | 427 | ||
379 | static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) | 428 | static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) |
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index a3fd92029a14..b8a3eae4b1b1 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c | |||
@@ -84,6 +84,7 @@ static const struct file_operations qxl_fops = { | |||
84 | .release = drm_release, | 84 | .release = drm_release, |
85 | .unlocked_ioctl = drm_ioctl, | 85 | .unlocked_ioctl = drm_ioctl, |
86 | .poll = drm_poll, | 86 | .poll = drm_poll, |
87 | .read = drm_read, | ||
87 | .mmap = qxl_mmap, | 88 | .mmap = qxl_mmap, |
88 | }; | 89 | }; |
89 | 90 | ||
@@ -195,6 +196,20 @@ static int qxl_pm_restore(struct device *dev) | |||
195 | return qxl_drm_resume(drm_dev, false); | 196 | return qxl_drm_resume(drm_dev, false); |
196 | } | 197 | } |
197 | 198 | ||
199 | static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, int crtc) | ||
200 | { | ||
201 | return dev->vblank[crtc].count.counter; | ||
202 | } | ||
203 | |||
204 | static int qxl_noop_enable_vblank(struct drm_device *dev, int crtc) | ||
205 | { | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static void qxl_noop_disable_vblank(struct drm_device *dev, int crtc) | ||
210 | { | ||
211 | } | ||
212 | |||
198 | static const struct dev_pm_ops qxl_pm_ops = { | 213 | static const struct dev_pm_ops qxl_pm_ops = { |
199 | .suspend = qxl_pm_suspend, | 214 | .suspend = qxl_pm_suspend, |
200 | .resume = qxl_pm_resume, | 215 | .resume = qxl_pm_resume, |
@@ -216,6 +231,9 @@ static struct drm_driver qxl_driver = { | |||
216 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, | 231 | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, |
217 | .load = qxl_driver_load, | 232 | .load = qxl_driver_load, |
218 | .unload = qxl_driver_unload, | 233 | .unload = qxl_driver_unload, |
234 | .get_vblank_counter = qxl_noop_get_vblank_counter, | ||
235 | .enable_vblank = qxl_noop_enable_vblank, | ||
236 | .disable_vblank = qxl_noop_disable_vblank, | ||
219 | 237 | ||
220 | .dumb_create = qxl_mode_dumb_create, | 238 | .dumb_create = qxl_mode_dumb_create, |
221 | .dumb_map_offset = qxl_mode_dumb_mmap, | 239 | .dumb_map_offset = qxl_mode_dumb_mmap, |
diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 7234561e09d9..b2977a181935 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c | |||
@@ -298,6 +298,9 @@ int qxl_driver_unload(struct drm_device *dev) | |||
298 | 298 | ||
299 | if (qdev == NULL) | 299 | if (qdev == NULL) |
300 | return 0; | 300 | return 0; |
301 | |||
302 | drm_vblank_cleanup(dev); | ||
303 | |||
301 | qxl_modeset_fini(qdev); | 304 | qxl_modeset_fini(qdev); |
302 | qxl_device_fini(qdev); | 305 | qxl_device_fini(qdev); |
303 | 306 | ||
@@ -325,15 +328,20 @@ int qxl_driver_load(struct drm_device *dev, unsigned long flags) | |||
325 | if (r) | 328 | if (r) |
326 | goto out; | 329 | goto out; |
327 | 330 | ||
331 | r = drm_vblank_init(dev, 1); | ||
332 | if (r) | ||
333 | goto unload; | ||
334 | |||
328 | r = qxl_modeset_init(qdev); | 335 | r = qxl_modeset_init(qdev); |
329 | if (r) { | 336 | if (r) |
330 | qxl_driver_unload(dev); | 337 | goto unload; |
331 | goto out; | ||
332 | } | ||
333 | 338 | ||
334 | drm_kms_helper_poll_init(qdev->ddev); | 339 | drm_kms_helper_poll_init(qdev->ddev); |
335 | 340 | ||
336 | return 0; | 341 | return 0; |
342 | unload: | ||
343 | qxl_driver_unload(dev); | ||
344 | |||
337 | out: | 345 | out: |
338 | kfree(qdev); | 346 | kfree(qdev); |
339 | return r; | 347 | return r; |