aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/qxl
diff options
context:
space:
mode:
authorAndreas Pokorny <andreas.pokorny@canonical.com>2014-08-08 04:40:55 -0400
committerDave Airlie <airlied@redhat.com>2014-09-03 01:35:27 -0400
commit058e9f5c8236ad740ab984588b507758e5feee6d (patch)
tree21a2b80796bbc325069625cdb121dc92122165a1 /drivers/gpu/drm/qxl
parent6ba59f3b5c977af2df3f9446f030f71e29d77dc1 (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.c49
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c18
-rw-r--r--drivers/gpu/drm/qxl/qxl_kms.c16
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
190static 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
190static int 238static int
191qxl_hide_cursor(struct qxl_device *qdev) 239qxl_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
379static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) 428static 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
199static u32 qxl_noop_get_vblank_counter(struct drm_device *dev, int crtc)
200{
201 return dev->vblank[crtc].count.counter;
202}
203
204static int qxl_noop_enable_vblank(struct drm_device *dev, int crtc)
205{
206 return 0;
207}
208
209static void qxl_noop_disable_vblank(struct drm_device *dev, int crtc)
210{
211}
212
198static const struct dev_pm_ops qxl_pm_ops = { 213static 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;
342unload:
343 qxl_driver_unload(dev);
344
337out: 345out:
338 kfree(qdev); 346 kfree(qdev);
339 return r; 347 return r;