diff options
Diffstat (limited to 'drivers/gpu/drm/tiny/gm12u320.c')
| -rw-r--r-- | drivers/gpu/drm/tiny/gm12u320.c | 103 |
1 files changed, 47 insertions, 56 deletions
diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c index 6bc0c298739c..d73dfebb4353 100644 --- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -4,23 +4,28 @@ */ #include <linux/module.h> +#include <linux/pm.h> #include <linux/usb.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_state_helper.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_edid.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> #include <drm/drm_format_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_gem_shmem_helper.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> @@ -30,7 +35,6 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); #define DRIVER_NAME "gm12u320" #define DRIVER_DESC "Grain Media GM12U320 USB projector display" -#define DRIVER_DATE "2019" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 @@ -67,10 +71,10 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); #define READ_STATUS_SIZE 13 #define MISC_VALUE_SIZE 4 -#define CMD_TIMEOUT msecs_to_jiffies(200) -#define DATA_TIMEOUT msecs_to_jiffies(1000) -#define IDLE_TIMEOUT msecs_to_jiffies(2000) -#define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000) +#define CMD_TIMEOUT 200 +#define DATA_TIMEOUT 1000 +#define IDLE_TIMEOUT 2000 +#define FIRST_FRAME_TIMEOUT 2000 #define MISC_REQ_GET_SET_ECO_A 0xff #define MISC_REQ_GET_SET_ECO_B 0x35 @@ -83,7 +87,6 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); struct gm12u320_device { struct drm_device dev; - struct device *dmadev; struct drm_simple_display_pipe pipe; struct drm_connector conn; unsigned char *cmd_buf; @@ -95,7 +98,7 @@ struct gm12u320_device { struct drm_rect rect; int frame; int draw_status_timeout; - struct dma_buf_map src_map; + struct iosys_map src_map; } fb_update; }; @@ -386,7 +389,7 @@ static void gm12u320_fb_update_work(struct work_struct *work) * switches back to showing its logo. */ queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, - IDLE_TIMEOUT); + msecs_to_jiffies(IDLE_TIMEOUT)); return; err: @@ -395,7 +398,8 @@ err: GM12U320_ERR("Frame update error: %d\n", ret); } -static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb, const struct dma_buf_map *map, +static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb, + const struct iosys_map *map, struct drm_rect *dirty) { struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev); @@ -438,7 +442,7 @@ static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320) mutex_lock(&gm12u320->fb_update.lock); old_fb = gm12u320->fb_update.fb; gm12u320->fb_update.fb = NULL; - dma_buf_map_clear(&gm12u320->fb_update.src_map); + iosys_map_clear(&gm12u320->fb_update.src_map); mutex_unlock(&gm12u320->fb_update.lock); drm_framebuffer_put(old_fb); @@ -460,7 +464,7 @@ static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320) * Note this assumes this driver is only ever used with the Acer C120, if we * add support for other devices the vendor and model should be parameterized. */ -static struct edid gm12u320_edid = { +static const struct edid gm12u320_edid = { .header = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }, .mfg_id = { 0x04, 0x72 }, /* "ACR" */ .prod_code = { 0x20, 0xc1 }, /* C120h */ @@ -519,8 +523,15 @@ static struct edid gm12u320_edid = { static int gm12u320_conn_get_modes(struct drm_connector *connector) { - drm_connector_update_edid_property(connector, &gm12u320_edid); - return drm_add_edid_modes(connector, &gm12u320_edid); + const struct drm_edid *drm_edid; + int count; + + drm_edid = drm_edid_alloc(&gm12u320_edid, sizeof(gm12u320_edid)); + drm_edid_connector_update(connector, drm_edid); + count = drm_edid_connector_add_modes(connector); + drm_edid_free(drm_edid); + + return count; } static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = { @@ -591,22 +602,6 @@ static const uint64_t gm12u320_pipe_modifiers[] = { DRM_FORMAT_MOD_INVALID }; -/* - * 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 *gm12u320_gem_prime_import(struct drm_device *dev, - struct dma_buf *dma_buf) -{ - struct gm12u320_device *gm12u320 = to_gm12u320(dev); - - if (!gm12u320->dmadev) - return ERR_PTR(-ENODEV); - - return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev); -} - DEFINE_DRM_GEM_FOPS(gm12u320_fops); static const struct drm_driver gm12u320_drm_driver = { @@ -614,13 +609,12 @@ static const struct drm_driver gm12u320_drm_driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, - .date = DRIVER_DATE, .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .fops = &gm12u320_fops, DRM_GEM_SHMEM_DRIVER_OPS, - .gem_prime_import = gm12u320_gem_prime_import, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { @@ -634,6 +628,7 @@ static int gm12u320_usb_probe(struct usb_interface *interface, { struct gm12u320_device *gm12u320; struct drm_device *dev; + struct device *dma_dev; int ret; /* @@ -649,16 +644,20 @@ static int gm12u320_usb_probe(struct usb_interface *interface, return PTR_ERR(gm12u320); dev = &gm12u320->dev; - gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); - if (!gm12u320->dmadev) + dma_dev = usb_intf_get_dma_device(interface); + if (dma_dev) { + drm_dev_set_dma_dev(dev, dma_dev); + put_device(dma_dev); + } else { drm_warn(dev, "buffer sharing not supported"); /* not an error */ + } INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); mutex_init(&gm12u320->fb_update.lock); ret = drmm_mode_config_init(dev); if (ret) - goto err_put_device; + return ret; dev->mode_config.min_width = GM12U320_USER_WIDTH; dev->mode_config.max_width = GM12U320_USER_WIDTH; @@ -668,15 +667,15 @@ static int gm12u320_usb_probe(struct usb_interface *interface, ret = gm12u320_usb_alloc(gm12u320); if (ret) - goto err_put_device; + return ret; ret = gm12u320_set_ecomode(gm12u320); if (ret) - goto err_put_device; + return ret; ret = gm12u320_conn_init(gm12u320); if (ret) - goto err_put_device; + return ret; ret = drm_simple_display_pipe_init(&gm12u320->dev, &gm12u320->pipe, @@ -686,44 +685,37 @@ static int gm12u320_usb_probe(struct usb_interface *interface, gm12u320_pipe_modifiers, &gm12u320->conn); if (ret) - goto err_put_device; + return ret; drm_mode_config_reset(dev); usb_set_intfdata(interface, dev); ret = drm_dev_register(dev, 0); if (ret) - goto err_put_device; + return ret; - drm_fbdev_generic_setup(dev, 0); + drm_client_setup(dev, NULL); return 0; - -err_put_device: - put_device(gm12u320->dmadev); - return ret; } static void gm12u320_usb_disconnect(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); - struct gm12u320_device *gm12u320 = to_gm12u320(dev); - put_device(gm12u320->dmadev); - gm12u320->dmadev = NULL; drm_dev_unplug(dev); drm_atomic_helper_shutdown(dev); } -static __maybe_unused int gm12u320_suspend(struct usb_interface *interface, - pm_message_t message) +static int gm12u320_suspend(struct usb_interface *interface, + pm_message_t message) { struct drm_device *dev = usb_get_intfdata(interface); return drm_mode_config_helper_suspend(dev); } -static __maybe_unused int gm12u320_resume(struct usb_interface *interface) +static int gm12u320_resume(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); struct gm12u320_device *gm12u320 = to_gm12u320(dev); @@ -744,13 +736,12 @@ static struct usb_driver gm12u320_usb_driver = { .probe = gm12u320_usb_probe, .disconnect = gm12u320_usb_disconnect, .id_table = id_table, -#ifdef CONFIG_PM - .suspend = gm12u320_suspend, - .resume = gm12u320_resume, - .reset_resume = gm12u320_resume, -#endif + .suspend = pm_ptr(gm12u320_suspend), + .resume = pm_ptr(gm12u320_resume), + .reset_resume = pm_ptr(gm12u320_resume), }; module_usb_driver(gm12u320_usb_driver); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); +MODULE_DESCRIPTION("GM12U320 driver for USB projectors"); MODULE_LICENSE("GPL"); |
