diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-06-08 22:14:24 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-06-08 22:14:24 -0400 |
| commit | 76c6dccf34413ca460372fde027bedcdc2f59f86 (patch) | |
| tree | 7900bfd4350d7fd81daad98a5c8a58860b7f8795 /drivers/gpu/drm | |
| parent | 5b735940aa11113abd369e8b3a144c68b0ff5ffa (diff) | |
| parent | 0062795e30697b825387a795b9c1791cc28a0a72 (diff) | |
Merge branch 'virtio-gpu-for-airlied' of git://git.kraxel.org/linux into drm-next
Virtio-gpu updates
* 'virtio-gpu-for-airlied' of git://git.kraxel.org/linux:
virtio-gpu: use src not crtc
virtio-gpu: pick up hotspot from framebuffer
add cursor hotspot to drm_framebuffer
virtio-gpu: switch to atomic cursor interfaces
virtio-gpu: add atomic_commit function
virtio-gpu: fix output lookup
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_display.c | 124 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_plane.c | 142 |
4 files changed, 157 insertions, 113 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index da2f28ea5fad..a4e259524e11 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -2919,6 +2919,8 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, | |||
| 2919 | DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); | 2919 | DRM_DEBUG_KMS("failed to wrap cursor buffer in drm framebuffer\n"); |
| 2920 | return PTR_ERR(fb); | 2920 | return PTR_ERR(fb); |
| 2921 | } | 2921 | } |
| 2922 | fb->hot_x = req->hot_x; | ||
| 2923 | fb->hot_y = req->hot_y; | ||
| 2922 | } else { | 2924 | } else { |
| 2923 | fb = NULL; | 2925 | fb = NULL; |
| 2924 | } | 2926 | } |
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index ba5e11ba9f3a..d82ae1cddfcf 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c | |||
| @@ -29,8 +29,8 @@ | |||
| 29 | #include <drm/drm_crtc_helper.h> | 29 | #include <drm/drm_crtc_helper.h> |
| 30 | #include <drm/drm_atomic_helper.h> | 30 | #include <drm/drm_atomic_helper.h> |
| 31 | 31 | ||
| 32 | #define XRES_MIN 320 | 32 | #define XRES_MIN 32 |
| 33 | #define YRES_MIN 200 | 33 | #define YRES_MIN 32 |
| 34 | 34 | ||
| 35 | #define XRES_DEF 1024 | 35 | #define XRES_DEF 1024 |
| 36 | #define YRES_DEF 768 | 36 | #define YRES_DEF 768 |
| @@ -38,86 +38,6 @@ | |||
| 38 | #define XRES_MAX 8192 | 38 | #define XRES_MAX 8192 |
| 39 | #define YRES_MAX 8192 | 39 | #define YRES_MAX 8192 |
| 40 | 40 | ||
| 41 | static void | ||
| 42 | virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev, | ||
| 43 | struct virtio_gpu_output *output) | ||
| 44 | { | ||
| 45 | output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); | ||
| 46 | output->cursor.resource_id = 0; | ||
| 47 | virtio_gpu_cursor_ping(vgdev, output); | ||
| 48 | } | ||
| 49 | |||
| 50 | static int virtio_gpu_crtc_cursor_set(struct drm_crtc *crtc, | ||
| 51 | struct drm_file *file_priv, | ||
| 52 | uint32_t handle, | ||
| 53 | uint32_t width, | ||
| 54 | uint32_t height, | ||
| 55 | int32_t hot_x, int32_t hot_y) | ||
| 56 | { | ||
| 57 | struct virtio_gpu_device *vgdev = crtc->dev->dev_private; | ||
| 58 | struct virtio_gpu_output *output = | ||
| 59 | container_of(crtc, struct virtio_gpu_output, crtc); | ||
| 60 | struct drm_gem_object *gobj = NULL; | ||
| 61 | struct virtio_gpu_object *qobj = NULL; | ||
| 62 | struct virtio_gpu_fence *fence = NULL; | ||
| 63 | int ret = 0; | ||
| 64 | |||
| 65 | if (handle == 0) { | ||
| 66 | virtio_gpu_hide_cursor(vgdev, output); | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* lookup the cursor */ | ||
| 71 | gobj = drm_gem_object_lookup(file_priv, handle); | ||
| 72 | if (gobj == NULL) | ||
| 73 | return -ENOENT; | ||
| 74 | |||
| 75 | qobj = gem_to_virtio_gpu_obj(gobj); | ||
| 76 | |||
| 77 | if (!qobj->hw_res_handle) { | ||
| 78 | ret = -EINVAL; | ||
| 79 | goto out; | ||
| 80 | } | ||
| 81 | |||
| 82 | virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0, | ||
| 83 | cpu_to_le32(64), | ||
| 84 | cpu_to_le32(64), | ||
| 85 | 0, 0, &fence); | ||
| 86 | ret = virtio_gpu_object_reserve(qobj, false); | ||
| 87 | if (!ret) { | ||
| 88 | reservation_object_add_excl_fence(qobj->tbo.resv, | ||
| 89 | &fence->f); | ||
| 90 | fence_put(&fence->f); | ||
| 91 | virtio_gpu_object_unreserve(qobj); | ||
| 92 | virtio_gpu_object_wait(qobj, false); | ||
| 93 | } | ||
| 94 | |||
| 95 | output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); | ||
| 96 | output->cursor.resource_id = cpu_to_le32(qobj->hw_res_handle); | ||
| 97 | output->cursor.hot_x = cpu_to_le32(hot_x); | ||
| 98 | output->cursor.hot_y = cpu_to_le32(hot_y); | ||
| 99 | virtio_gpu_cursor_ping(vgdev, output); | ||
| 100 | ret = 0; | ||
| 101 | |||
| 102 | out: | ||
| 103 | drm_gem_object_unreference_unlocked(gobj); | ||
| 104 | return ret; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc, | ||
| 108 | int x, int y) | ||
| 109 | { | ||
| 110 | struct virtio_gpu_device *vgdev = crtc->dev->dev_private; | ||
| 111 | struct virtio_gpu_output *output = | ||
| 112 | container_of(crtc, struct virtio_gpu_output, crtc); | ||
| 113 | |||
| 114 | output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR); | ||
| 115 | output->cursor.pos.x = cpu_to_le32(x); | ||
| 116 | output->cursor.pos.y = cpu_to_le32(y); | ||
| 117 | virtio_gpu_cursor_ping(vgdev, output); | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | static int virtio_gpu_page_flip(struct drm_crtc *crtc, | 41 | static int virtio_gpu_page_flip(struct drm_crtc *crtc, |
| 122 | struct drm_framebuffer *fb, | 42 | struct drm_framebuffer *fb, |
| 123 | struct drm_pending_vblank_event *event, | 43 | struct drm_pending_vblank_event *event, |
| @@ -164,8 +84,6 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc, | |||
| 164 | } | 84 | } |
| 165 | 85 | ||
| 166 | static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { | 86 | static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { |
| 167 | .cursor_set2 = virtio_gpu_crtc_cursor_set, | ||
| 168 | .cursor_move = virtio_gpu_crtc_cursor_move, | ||
| 169 | .set_config = drm_atomic_helper_set_config, | 87 | .set_config = drm_atomic_helper_set_config, |
| 170 | .destroy = drm_crtc_cleanup, | 88 | .destroy = drm_crtc_cleanup, |
| 171 | 89 | ||
| @@ -406,7 +324,7 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) | |||
| 406 | struct drm_connector *connector = &output->conn; | 324 | struct drm_connector *connector = &output->conn; |
| 407 | struct drm_encoder *encoder = &output->enc; | 325 | struct drm_encoder *encoder = &output->enc; |
| 408 | struct drm_crtc *crtc = &output->crtc; | 326 | struct drm_crtc *crtc = &output->crtc; |
| 409 | struct drm_plane *plane; | 327 | struct drm_plane *primary, *cursor; |
| 410 | 328 | ||
| 411 | output->index = index; | 329 | output->index = index; |
| 412 | if (index == 0) { | 330 | if (index == 0) { |
| @@ -415,13 +333,17 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) | |||
| 415 | output->info.r.height = cpu_to_le32(YRES_DEF); | 333 | output->info.r.height = cpu_to_le32(YRES_DEF); |
| 416 | } | 334 | } |
| 417 | 335 | ||
| 418 | plane = virtio_gpu_plane_init(vgdev, index); | 336 | primary = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_PRIMARY, index); |
| 419 | if (IS_ERR(plane)) | 337 | if (IS_ERR(primary)) |
| 420 | return PTR_ERR(plane); | 338 | return PTR_ERR(primary); |
| 421 | drm_crtc_init_with_planes(dev, crtc, plane, NULL, | 339 | cursor = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_CURSOR, index); |
| 340 | if (IS_ERR(cursor)) | ||
| 341 | return PTR_ERR(cursor); | ||
| 342 | drm_crtc_init_with_planes(dev, crtc, primary, cursor, | ||
| 422 | &virtio_gpu_crtc_funcs, NULL); | 343 | &virtio_gpu_crtc_funcs, NULL); |
| 423 | drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs); | 344 | drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs); |
| 424 | plane->crtc = crtc; | 345 | primary->crtc = crtc; |
| 346 | cursor->crtc = crtc; | ||
| 425 | 347 | ||
| 426 | drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, | 348 | drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, |
| 427 | DRM_MODE_CONNECTOR_VIRTUAL); | 349 | DRM_MODE_CONNECTOR_VIRTUAL); |
| @@ -466,10 +388,30 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, | |||
| 466 | return &virtio_gpu_fb->base; | 388 | return &virtio_gpu_fb->base; |
| 467 | } | 389 | } |
| 468 | 390 | ||
| 391 | static int vgdev_atomic_commit(struct drm_device *dev, | ||
| 392 | struct drm_atomic_state *state, | ||
| 393 | bool nonblock) | ||
| 394 | { | ||
| 395 | if (nonblock) | ||
| 396 | return -EBUSY; | ||
| 397 | |||
| 398 | drm_atomic_helper_swap_state(dev, state); | ||
| 399 | drm_atomic_helper_wait_for_fences(dev, state); | ||
| 400 | |||
| 401 | drm_atomic_helper_commit_modeset_disables(dev, state); | ||
| 402 | drm_atomic_helper_commit_modeset_enables(dev, state); | ||
| 403 | drm_atomic_helper_commit_planes(dev, state, true); | ||
| 404 | |||
| 405 | drm_atomic_helper_wait_for_vblanks(dev, state); | ||
| 406 | drm_atomic_helper_cleanup_planes(dev, state); | ||
| 407 | drm_atomic_state_free(state); | ||
| 408 | return 0; | ||
| 409 | } | ||
| 410 | |||
| 469 | static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { | 411 | static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { |
| 470 | .fb_create = virtio_gpu_user_framebuffer_create, | 412 | .fb_create = virtio_gpu_user_framebuffer_create, |
| 471 | .atomic_check = drm_atomic_helper_check, | 413 | .atomic_check = drm_atomic_helper_check, |
| 472 | .atomic_commit = drm_atomic_helper_commit, | 414 | .atomic_commit = vgdev_atomic_commit, |
| 473 | }; | 415 | }; |
| 474 | 416 | ||
| 475 | int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) | 417 | int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 0a54f43f846a..acf556a35cb2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | #include <drm/drmP.h> | 34 | #include <drm/drmP.h> |
| 35 | #include <drm/drm_gem.h> | 35 | #include <drm/drm_gem.h> |
| 36 | #include <drm/drm_atomic.h> | ||
| 36 | #include <drm/drm_crtc_helper.h> | 37 | #include <drm/drm_crtc_helper.h> |
| 37 | #include <ttm/ttm_bo_api.h> | 38 | #include <ttm/ttm_bo_api.h> |
| 38 | #include <ttm/ttm_bo_driver.h> | 39 | #include <ttm/ttm_bo_driver.h> |
| @@ -335,6 +336,7 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); | |||
| 335 | 336 | ||
| 336 | /* virtio_gpu_plane.c */ | 337 | /* virtio_gpu_plane.c */ |
| 337 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, | 338 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, |
| 339 | enum drm_plane_type type, | ||
| 338 | int index); | 340 | int index); |
| 339 | 341 | ||
| 340 | /* virtio_gpu_ttm.c */ | 342 | /* virtio_gpu_ttm.c */ |
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index e50674bccb09..925ca25209df 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c | |||
| @@ -38,6 +38,10 @@ static const uint32_t virtio_gpu_formats[] = { | |||
| 38 | DRM_FORMAT_ABGR8888, | 38 | DRM_FORMAT_ABGR8888, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static const uint32_t virtio_gpu_cursor_formats[] = { | ||
| 42 | DRM_FORMAT_ARGB8888, | ||
| 43 | }; | ||
| 44 | |||
| 41 | static void virtio_gpu_plane_destroy(struct drm_plane *plane) | 45 | static void virtio_gpu_plane_destroy(struct drm_plane *plane) |
| 42 | { | 46 | { |
| 43 | kfree(plane); | 47 | kfree(plane); |
| @@ -58,8 +62,8 @@ static int virtio_gpu_plane_atomic_check(struct drm_plane *plane, | |||
| 58 | return 0; | 62 | return 0; |
| 59 | } | 63 | } |
| 60 | 64 | ||
| 61 | static void virtio_gpu_plane_atomic_update(struct drm_plane *plane, | 65 | static void virtio_gpu_primary_plane_update(struct drm_plane *plane, |
| 62 | struct drm_plane_state *old_state) | 66 | struct drm_plane_state *old_state) |
| 63 | { | 67 | { |
| 64 | struct drm_device *dev = plane->dev; | 68 | struct drm_device *dev = plane->dev; |
| 65 | struct virtio_gpu_device *vgdev = dev->dev_private; | 69 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| @@ -81,55 +85,149 @@ static void virtio_gpu_plane_atomic_update(struct drm_plane *plane, | |||
| 81 | if (bo->dumb) { | 85 | if (bo->dumb) { |
| 82 | virtio_gpu_cmd_transfer_to_host_2d | 86 | virtio_gpu_cmd_transfer_to_host_2d |
| 83 | (vgdev, handle, 0, | 87 | (vgdev, handle, 0, |
| 84 | cpu_to_le32(plane->state->crtc_w), | 88 | cpu_to_le32(plane->state->src_w >> 16), |
| 85 | cpu_to_le32(plane->state->crtc_h), | 89 | cpu_to_le32(plane->state->src_h >> 16), |
| 86 | plane->state->crtc_x, plane->state->crtc_y, NULL); | 90 | plane->state->src_x >> 16, |
| 91 | plane->state->src_y >> 16, NULL); | ||
| 87 | } | 92 | } |
| 88 | } else { | 93 | } else { |
| 89 | handle = 0; | 94 | handle = 0; |
| 90 | } | 95 | } |
| 91 | 96 | ||
| 92 | DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d\n", handle, | 97 | DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d, src %dx%d+%d+%d\n", handle, |
| 93 | plane->state->crtc_w, plane->state->crtc_h, | 98 | plane->state->crtc_w, plane->state->crtc_h, |
| 94 | plane->state->crtc_x, plane->state->crtc_y); | 99 | plane->state->crtc_x, plane->state->crtc_y, |
| 100 | plane->state->src_w >> 16, | ||
| 101 | plane->state->src_h >> 16, | ||
| 102 | plane->state->src_x >> 16, | ||
| 103 | plane->state->src_y >> 16); | ||
| 95 | virtio_gpu_cmd_set_scanout(vgdev, output->index, handle, | 104 | virtio_gpu_cmd_set_scanout(vgdev, output->index, handle, |
| 96 | plane->state->crtc_w, | 105 | plane->state->src_w >> 16, |
| 97 | plane->state->crtc_h, | 106 | plane->state->src_h >> 16, |
| 98 | plane->state->crtc_x, | 107 | plane->state->src_x >> 16, |
| 99 | plane->state->crtc_y); | 108 | plane->state->src_y >> 16); |
| 100 | virtio_gpu_cmd_resource_flush(vgdev, handle, | 109 | virtio_gpu_cmd_resource_flush(vgdev, handle, |
| 101 | plane->state->crtc_x, | 110 | plane->state->src_x >> 16, |
| 102 | plane->state->crtc_y, | 111 | plane->state->src_y >> 16, |
| 103 | plane->state->crtc_w, | 112 | plane->state->src_w >> 16, |
| 104 | plane->state->crtc_h); | 113 | plane->state->src_h >> 16); |
| 114 | } | ||
| 115 | |||
| 116 | static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, | ||
| 117 | struct drm_plane_state *old_state) | ||
| 118 | { | ||
| 119 | struct drm_device *dev = plane->dev; | ||
| 120 | struct virtio_gpu_device *vgdev = dev->dev_private; | ||
| 121 | struct virtio_gpu_output *output = NULL; | ||
| 122 | struct virtio_gpu_framebuffer *vgfb; | ||
| 123 | struct virtio_gpu_fence *fence = NULL; | ||
| 124 | struct virtio_gpu_object *bo = NULL; | ||
| 125 | uint32_t handle; | ||
| 126 | int ret = 0; | ||
| 127 | |||
| 128 | if (plane->state->crtc) | ||
| 129 | output = drm_crtc_to_virtio_gpu_output(plane->state->crtc); | ||
| 130 | if (old_state->crtc) | ||
| 131 | output = drm_crtc_to_virtio_gpu_output(old_state->crtc); | ||
| 132 | WARN_ON(!output); | ||
| 133 | |||
| 134 | if (plane->state->fb) { | ||
| 135 | vgfb = to_virtio_gpu_framebuffer(plane->state->fb); | ||
| 136 | bo = gem_to_virtio_gpu_obj(vgfb->obj); | ||
| 137 | handle = bo->hw_res_handle; | ||
| 138 | } else { | ||
| 139 | handle = 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | if (bo && bo->dumb && (plane->state->fb != old_state->fb)) { | ||
| 143 | /* new cursor -- update & wait */ | ||
| 144 | virtio_gpu_cmd_transfer_to_host_2d | ||
| 145 | (vgdev, handle, 0, | ||
| 146 | cpu_to_le32(plane->state->crtc_w), | ||
| 147 | cpu_to_le32(plane->state->crtc_h), | ||
| 148 | 0, 0, &fence); | ||
| 149 | ret = virtio_gpu_object_reserve(bo, false); | ||
| 150 | if (!ret) { | ||
| 151 | reservation_object_add_excl_fence(bo->tbo.resv, | ||
| 152 | &fence->f); | ||
| 153 | fence_put(&fence->f); | ||
| 154 | fence = NULL; | ||
| 155 | virtio_gpu_object_unreserve(bo); | ||
| 156 | virtio_gpu_object_wait(bo, false); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | if (plane->state->fb != old_state->fb) { | ||
| 161 | DRM_DEBUG("update, handle %d, pos +%d+%d, hot %d,%d\n", handle, | ||
| 162 | plane->state->crtc_x, | ||
| 163 | plane->state->crtc_y, | ||
| 164 | plane->state->fb ? plane->state->fb->hot_x : 0, | ||
| 165 | plane->state->fb ? plane->state->fb->hot_y : 0); | ||
| 166 | output->cursor.hdr.type = | ||
| 167 | cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR); | ||
| 168 | output->cursor.resource_id = cpu_to_le32(handle); | ||
| 169 | if (plane->state->fb) { | ||
| 170 | output->cursor.hot_x = | ||
| 171 | cpu_to_le32(plane->state->fb->hot_x); | ||
| 172 | output->cursor.hot_y = | ||
| 173 | cpu_to_le32(plane->state->fb->hot_y); | ||
| 174 | } else { | ||
| 175 | output->cursor.hot_x = cpu_to_le32(0); | ||
| 176 | output->cursor.hot_y = cpu_to_le32(0); | ||
| 177 | } | ||
| 178 | } else { | ||
| 179 | DRM_DEBUG("move +%d+%d\n", | ||
| 180 | plane->state->crtc_x, | ||
| 181 | plane->state->crtc_y); | ||
| 182 | output->cursor.hdr.type = | ||
| 183 | cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR); | ||
| 184 | } | ||
| 185 | output->cursor.pos.x = cpu_to_le32(plane->state->crtc_x); | ||
| 186 | output->cursor.pos.y = cpu_to_le32(plane->state->crtc_y); | ||
| 187 | virtio_gpu_cursor_ping(vgdev, output); | ||
| 105 | } | 188 | } |
| 106 | 189 | ||
| 190 | static const struct drm_plane_helper_funcs virtio_gpu_primary_helper_funcs = { | ||
| 191 | .atomic_check = virtio_gpu_plane_atomic_check, | ||
| 192 | .atomic_update = virtio_gpu_primary_plane_update, | ||
| 193 | }; | ||
| 107 | 194 | ||
| 108 | static const struct drm_plane_helper_funcs virtio_gpu_plane_helper_funcs = { | 195 | static const struct drm_plane_helper_funcs virtio_gpu_cursor_helper_funcs = { |
| 109 | .atomic_check = virtio_gpu_plane_atomic_check, | 196 | .atomic_check = virtio_gpu_plane_atomic_check, |
| 110 | .atomic_update = virtio_gpu_plane_atomic_update, | 197 | .atomic_update = virtio_gpu_cursor_plane_update, |
| 111 | }; | 198 | }; |
| 112 | 199 | ||
| 113 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, | 200 | struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, |
| 201 | enum drm_plane_type type, | ||
| 114 | int index) | 202 | int index) |
| 115 | { | 203 | { |
| 116 | struct drm_device *dev = vgdev->ddev; | 204 | struct drm_device *dev = vgdev->ddev; |
| 205 | const struct drm_plane_helper_funcs *funcs; | ||
| 117 | struct drm_plane *plane; | 206 | struct drm_plane *plane; |
| 118 | int ret; | 207 | const uint32_t *formats; |
| 208 | int ret, nformats; | ||
| 119 | 209 | ||
| 120 | plane = kzalloc(sizeof(*plane), GFP_KERNEL); | 210 | plane = kzalloc(sizeof(*plane), GFP_KERNEL); |
| 121 | if (!plane) | 211 | if (!plane) |
| 122 | return ERR_PTR(-ENOMEM); | 212 | return ERR_PTR(-ENOMEM); |
| 123 | 213 | ||
| 214 | if (type == DRM_PLANE_TYPE_CURSOR) { | ||
| 215 | formats = virtio_gpu_cursor_formats; | ||
| 216 | nformats = ARRAY_SIZE(virtio_gpu_cursor_formats); | ||
| 217 | funcs = &virtio_gpu_cursor_helper_funcs; | ||
| 218 | } else { | ||
| 219 | formats = virtio_gpu_formats; | ||
| 220 | nformats = ARRAY_SIZE(virtio_gpu_formats); | ||
| 221 | funcs = &virtio_gpu_primary_helper_funcs; | ||
| 222 | } | ||
| 124 | ret = drm_universal_plane_init(dev, plane, 1 << index, | 223 | ret = drm_universal_plane_init(dev, plane, 1 << index, |
| 125 | &virtio_gpu_plane_funcs, | 224 | &virtio_gpu_plane_funcs, |
| 126 | virtio_gpu_formats, | 225 | formats, nformats, |
| 127 | ARRAY_SIZE(virtio_gpu_formats), | 226 | type, NULL); |
| 128 | DRM_PLANE_TYPE_PRIMARY, NULL); | ||
| 129 | if (ret) | 227 | if (ret) |
| 130 | goto err_plane_init; | 228 | goto err_plane_init; |
| 131 | 229 | ||
| 132 | drm_plane_helper_add(plane, &virtio_gpu_plane_helper_funcs); | 230 | drm_plane_helper_add(plane, funcs); |
| 133 | return plane; | 231 | return plane; |
| 134 | 232 | ||
| 135 | err_plane_init: | 233 | err_plane_init: |
