diff options
Diffstat (limited to 'drivers/gpu/drm/gud/gud_drv.c')
| -rw-r--r-- | drivers/gpu/drm/gud/gud_drv.c | 132 |
1 files changed, 71 insertions, 61 deletions
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 8d1630b8edac..42135a48d92e 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -13,12 +13,14 @@ #include <linux/vmalloc.h> #include <linux/workqueue.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> +#include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_debugfs.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> @@ -26,7 +28,6 @@ #include <drm/drm_managed.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> #include <drm/gud.h> #include "gud_internal.h" @@ -248,7 +249,7 @@ int gud_usb_set_u8(struct gud_device *gdrm, u8 request, u8 val) return gud_usb_set(gdrm, request, 0, &val, sizeof(val)); } -static int gud_get_properties(struct gud_device *gdrm) +static int gud_plane_add_properties(struct gud_device *gdrm) { struct gud_property_req *properties; unsigned int i, num_properties; @@ -288,7 +289,7 @@ static int gud_get_properties(struct gud_device *gdrm) * but mask out any additions on future devices. */ val &= GUD_ROTATION_MASK; - ret = drm_plane_create_rotation_property(&gdrm->pipe.plane, + ret = drm_plane_create_rotation_property(&gdrm->plane, DRM_MODE_ROTATE_0, val); break; default: @@ -308,25 +309,10 @@ out: return ret; } -/* - * FIXME: Dma-buf sharing requires DMA support by the importing device. - * This function is a workaround to make USB devices work as well. - * See todo.rst for how to fix the issue in the dma-buf framework. - */ -static struct drm_gem_object *gud_gem_prime_import(struct drm_device *drm, struct dma_buf *dma_buf) -{ - struct gud_device *gdrm = to_gud_device(drm); - - if (!gdrm->dmadev) - return ERR_PTR(-ENODEV); - - return drm_gem_prime_import_dev(drm, dma_buf, gdrm->dmadev); -} - static int gud_stats_debugfs(struct seq_file *m, void *data) { - struct drm_info_node *node = m->private; - struct gud_device *gdrm = to_gud_device(node->minor->dev); + struct drm_debugfs_entry *entry = m->private; + struct gud_device *gdrm = to_gud_device(entry->dev); char buf[10]; string_get_size(gdrm->bulk_len, 1, STRING_UNITS_2, buf, sizeof(buf)); @@ -352,19 +338,30 @@ static int gud_stats_debugfs(struct seq_file *m, void *data) return 0; } -static const struct drm_info_list gud_debugfs_list[] = { - { "stats", gud_stats_debugfs, 0, NULL }, +static const struct drm_crtc_helper_funcs gud_crtc_helper_funcs = { + .atomic_check = drm_crtc_helper_atomic_check }; -static void gud_debugfs_init(struct drm_minor *minor) -{ - drm_debugfs_create_files(gud_debugfs_list, ARRAY_SIZE(gud_debugfs_list), - minor->debugfs_root, minor); -} +static const struct drm_crtc_funcs gud_crtc_funcs = { + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; -static const struct drm_simple_display_pipe_funcs gud_pipe_funcs = { - .check = gud_pipe_check, - .update = gud_pipe_update, +static const struct drm_plane_helper_funcs gud_plane_helper_funcs = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = gud_plane_atomic_check, + .atomic_update = gud_plane_atomic_update, +}; + +static const struct drm_plane_funcs gud_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + DRM_GEM_SHADOW_PLANE_FUNCS, }; static const struct drm_mode_config_funcs gud_mode_config_funcs = { @@ -373,7 +370,7 @@ static const struct drm_mode_config_funcs gud_mode_config_funcs = { .atomic_commit = drm_atomic_helper_commit, }; -static const u64 gud_pipe_modifiers[] = { +static const u64 gud_plane_modifiers[] = { DRM_FORMAT_MOD_LINEAR, DRM_FORMAT_MOD_INVALID }; @@ -384,12 +381,10 @@ static const struct drm_driver gud_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .fops = &gud_fops, DRM_GEM_SHMEM_DRIVER_OPS, - .gem_prime_import = gud_gem_prime_import, - .debugfs_init = gud_debugfs_init, + DRM_FBDEV_SHMEM_DRIVER_OPS, .name = "gud", .desc = "Generic USB Display", - .date = "20200422", .major = 1, .minor = 0, }; @@ -443,6 +438,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) size_t max_buffer_size = 0; struct gud_device *gdrm; struct drm_device *drm; + struct device *dma_dev; u8 *formats_dev; u32 *formats; int ret, i; @@ -467,10 +463,6 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) return PTR_ERR(gdrm); drm = &gdrm->drm; - drm->mode_config.funcs = &gud_mode_config_funcs; - ret = drmm_mode_config_init(drm); - if (ret) - return ret; gdrm->flags = le32_to_cpu(desc.flags); gdrm->compression = desc.compression & GUD_COMPRESSION_LZ4; @@ -487,11 +479,28 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) if (ret) return ret; + usb_set_intfdata(intf, gdrm); + + dma_dev = usb_intf_get_dma_device(intf); + if (dma_dev) { + drm_dev_set_dma_dev(drm, dma_dev); + put_device(dma_dev); + } else { + dev_warn(dev, "buffer sharing not supported"); /* not an error */ + } + + /* Mode config init */ + ret = drmm_mode_config_init(drm); + if (ret) + return ret; + drm->mode_config.min_width = le32_to_cpu(desc.min_width); drm->mode_config.max_width = le32_to_cpu(desc.max_width); drm->mode_config.min_height = le32_to_cpu(desc.min_height); drm->mode_config.max_height = le32_to_cpu(desc.max_height); + drm->mode_config.funcs = &gud_mode_config_funcs; + /* Format init */ formats_dev = devm_kmalloc(dev, GUD_FORMATS_MAX_NUM, GFP_KERNEL); /* Add room for emulated XRGB8888 */ formats = devm_kmalloc_array(dev, GUD_FORMATS_MAX_NUM + 1, sizeof(*formats), GFP_KERNEL); @@ -591,22 +600,30 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) return -ENOMEM; } - ret = drm_simple_display_pipe_init(drm, &gdrm->pipe, &gud_pipe_funcs, - formats, num_formats, - gud_pipe_modifiers, NULL); + /* Pipeline init */ + ret = drm_universal_plane_init(drm, &gdrm->plane, 0, + &gud_plane_funcs, + formats, num_formats, + gud_plane_modifiers, + DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ret; - devm_kfree(dev, formats); - devm_kfree(dev, formats_dev); + drm_plane_helper_add(&gdrm->plane, &gud_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(&gdrm->plane); - ret = gud_get_properties(gdrm); + ret = gud_plane_add_properties(gdrm); if (ret) { - dev_err(dev, "Failed to get properties (error=%d)\n", ret); + dev_err(dev, "Failed to add properties (error=%d)\n", ret); return ret; } - drm_plane_enable_fb_damage_clips(&gdrm->pipe.plane); + ret = drm_crtc_init_with_planes(drm, &gdrm->crtc, &gdrm->plane, NULL, + &gud_crtc_funcs, NULL); + if (ret) + return ret; + + drm_crtc_helper_add(&gdrm->crtc, &gud_crtc_helper_funcs); ret = gud_get_connectors(gdrm); if (ret) { @@ -615,22 +632,18 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) } drm_mode_config_reset(drm); + drm_kms_helper_poll_init(drm); - usb_set_intfdata(intf, gdrm); - - gdrm->dmadev = usb_intf_get_dma_device(intf); - if (!gdrm->dmadev) - dev_warn(dev, "buffer sharing not supported"); + drm_debugfs_add_file(drm, "stats", gud_stats_debugfs, NULL); ret = drm_dev_register(drm, 0); - if (ret) { - put_device(gdrm->dmadev); + if (ret) return ret; - } - drm_kms_helper_poll_init(drm); + devm_kfree(dev, formats); + devm_kfree(dev, formats_dev); - drm_fbdev_generic_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } @@ -640,13 +653,9 @@ static void gud_disconnect(struct usb_interface *interface) struct gud_device *gdrm = usb_get_intfdata(interface); struct drm_device *drm = &gdrm->drm; - drm_dbg(drm, "%s:\n", __func__); - drm_kms_helper_poll_fini(drm); drm_dev_unplug(drm); drm_atomic_helper_shutdown(drm); - put_device(gdrm->dmadev); - gdrm->dmadev = NULL; } static int gud_suspend(struct usb_interface *intf, pm_message_t message) @@ -686,4 +695,5 @@ static struct usb_driver gud_usb_driver = { module_usb_driver(gud_usb_driver); MODULE_AUTHOR("Noralf Trønnes"); +MODULE_DESCRIPTION("GUD USB Display driver"); MODULE_LICENSE("Dual MIT/GPL"); |
