diff options
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_display.c')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_display.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index b6d52055a11f..443cf4c93074 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -28,6 +28,7 @@ #include "virtgpu_drv.h" #include <drm/drm_crtc_helper.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #define XRES_MIN 32 #define YRES_MIN 32 @@ -48,22 +49,12 @@ static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = { .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; -static void virtio_gpu_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct virtio_gpu_framebuffer *virtio_gpu_fb - = to_virtio_gpu_framebuffer(fb); - - drm_gem_object_unreference_unlocked(virtio_gpu_fb->obj); - drm_framebuffer_cleanup(fb); - kfree(virtio_gpu_fb); -} - static int virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb, struct drm_file *file_priv, - unsigned flags, unsigned color, + unsigned int flags, unsigned int color, struct drm_clip_rect *clips, - unsigned num_clips) + unsigned int num_clips) { struct virtio_gpu_framebuffer *virtio_gpu_fb = to_virtio_gpu_framebuffer(fb); @@ -72,7 +63,8 @@ virtio_gpu_framebuffer_surface_dirty(struct drm_framebuffer *fb, } static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = { - .destroy = virtio_gpu_user_framebuffer_destroy, + .create_handle = drm_gem_fb_create_handle, + .destroy = drm_gem_fb_destroy, .dirty = virtio_gpu_framebuffer_surface_dirty, }; @@ -83,16 +75,14 @@ virtio_gpu_framebuffer_init(struct drm_device *dev, struct drm_gem_object *obj) { int ret; - struct virtio_gpu_object *bo; - vgfb->obj = obj; - bo = gem_to_virtio_gpu_obj(obj); + vgfb->base.obj[0] = obj; drm_helper_mode_fill_fb_struct(dev, &vgfb->base, mode_cmd); ret = drm_framebuffer_init(dev, &vgfb->base, &virtio_gpu_fb_funcs); if (ret) { - vgfb->obj = NULL; + vgfb->base.obj[0] = NULL; return ret; } @@ -116,6 +106,9 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc) static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); + + output->enabled = true; } static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, @@ -126,6 +119,7 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc, struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc); virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0); + output->enabled = false; } static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, @@ -175,6 +169,12 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector) struct drm_display_mode *mode = NULL; int count, width, height; + if (output->edid) { + count = drm_add_edid_modes(connector, output->edid); + if (count) + return count; + } + width = le32_to_cpu(output->info.r.width); height = le32_to_cpu(output->info.r.height); count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX); @@ -195,7 +195,7 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector) return count; } -static int virtio_gpu_conn_mode_valid(struct drm_connector *connector, +static enum drm_mode_status virtio_gpu_conn_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct virtio_gpu_output *output = @@ -243,12 +243,8 @@ static enum drm_connector_status virtio_gpu_conn_detect( static void virtio_gpu_conn_destroy(struct drm_connector *connector) { - struct virtio_gpu_output *virtio_gpu_output = - drm_connector_to_virtio_gpu_output(connector); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(virtio_gpu_output); } static const struct drm_connector_funcs virtio_gpu_connector_funcs = { @@ -295,6 +291,8 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index) drm_connector_init(dev, connector, &virtio_gpu_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); drm_connector_helper_add(connector, &virtio_gpu_conn_helper_funcs); + if (vgdev->has_edid) + drm_connector_attach_edid_property(connector); drm_encoder_init(dev, encoder, &virtio_gpu_enc_funcs, DRM_MODE_ENCODER_VIRTUAL, NULL); @@ -327,7 +325,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj); if (ret) { kfree(virtio_gpu_fb); - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return NULL; } @@ -375,12 +373,17 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) for (i = 0 ; i < vgdev->num_scanouts; ++i) vgdev_output_init(vgdev, i); - drm_mode_config_reset(vgdev->ddev); + drm_mode_config_reset(vgdev->ddev); return 0; } void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) { + int i; + + for (i = 0 ; i < vgdev->num_scanouts; ++i) + kfree(vgdev->outputs[i].edid); virtio_gpu_fbdev_fini(vgdev); + drm_atomic_helper_shutdown(vgdev->ddev); drm_mode_config_cleanup(vgdev->ddev); } |