diff options
Diffstat (limited to 'drivers/gpu/drm/qxl')
-rw-r--r-- | drivers/gpu/drm/qxl/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_cmd.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_debugfs.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_display.c | 104 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_draw.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_drv.h | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_fb.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_gem.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_ioctl.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_irq.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_kms.c | 73 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_object.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_object.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_release.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_ttm.c | 26 |
16 files changed, 221 insertions, 188 deletions
diff --git a/drivers/gpu/drm/qxl/Kconfig b/drivers/gpu/drm/qxl/Kconfig index da45b11b66b8..378da5918e6c 100644 --- a/drivers/gpu/drm/qxl/Kconfig +++ b/drivers/gpu/drm/qxl/Kconfig @@ -1,6 +1,6 @@ config DRM_QXL tristate "QXL virtual GPU" - depends on DRM && PCI + depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_TTM select CRC32 diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 04270f5d110c..74fc9362ecf9 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -578,7 +578,7 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, return 0; } -int qxl_update_surface(struct qxl_device *qdev, struct qxl_bo *surf) +static int qxl_update_surface(struct qxl_device *qdev, struct qxl_bo *surf) { struct qxl_rect rect; int ret; diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index 6911b8c44492..d58751c94618 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -84,8 +84,18 @@ int qxl_debugfs_init(struct drm_minor *minor) { #if defined(CONFIG_DEBUG_FS) + int r; + struct qxl_device *dev = + (struct qxl_device *) minor->dev->dev_private; + drm_debugfs_create_files(qxl_debugfs_list, QXL_DEBUGFS_ENTRIES, minor->debugfs_root, minor); + + r = qxl_ttm_debugfs_init(dev); + if (r) { + DRM_ERROR("Failed to init TTM debugfs\n"); + return r; + } #endif return 0; } @@ -123,11 +133,8 @@ int qxl_debugfs_add_files(struct qxl_device *qdev, qdev->debugfs_count = i; #if defined(CONFIG_DEBUG_FS) drm_debugfs_create_files(files, nfiles, - qdev->ddev->control->debugfs_root, - qdev->ddev->control); - drm_debugfs_create_files(files, nfiles, - qdev->ddev->primary->debugfs_root, - qdev->ddev->primary); + qdev->ddev.primary->debugfs_root, + qdev->ddev.primary); #endif return 0; } @@ -140,10 +147,7 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev) for (i = 0; i < qdev->debugfs_count; i++) { drm_debugfs_remove_files(qdev->debugfs[i].files, qdev->debugfs[i].num_files, - qdev->ddev->control); - drm_debugfs_remove_files(qdev->debugfs[i].files, - qdev->debugfs[i].num_files, - qdev->ddev->primary); + qdev->ddev.primary); } #endif } diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index a61c0d460ec2..1094cd33eb06 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -36,7 +36,7 @@ static bool qxl_head_enabled(struct qxl_head *head) return head->width && head->height; } -void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count) +static void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count) { if (qdev->client_monitors_config && count > qdev->client_monitors_config->count) { @@ -57,11 +57,18 @@ void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count) qdev->client_monitors_config->count = count; } +enum { + MONITORS_CONFIG_MODIFIED, + MONITORS_CONFIG_UNCHANGED, + MONITORS_CONFIG_BAD_CRC, +}; + static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev) { int i; int num_monitors; uint32_t crc; + int status = MONITORS_CONFIG_UNCHANGED; num_monitors = qdev->rom->client_monitors_config.count; crc = crc32(0, (const uint8_t *)&qdev->rom->client_monitors_config, @@ -70,7 +77,7 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev) qxl_io_log(qdev, "crc mismatch: have %X (%zd) != %X\n", crc, sizeof(qdev->rom->client_monitors_config), qdev->rom->client_monitors_config_crc); - return 1; + return MONITORS_CONFIG_BAD_CRC; } if (num_monitors > qdev->monitors_config->max_allowed) { DRM_DEBUG_KMS("client monitors list will be truncated: %d < %d\n", @@ -79,6 +86,10 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev) } else { num_monitors = qdev->rom->client_monitors_config.count; } + if (qdev->client_monitors_config + && (num_monitors != qdev->client_monitors_config->count)) { + status = MONITORS_CONFIG_MODIFIED; + } qxl_alloc_client_monitors_config(qdev, num_monitors); /* we copy max from the client but it isn't used */ qdev->client_monitors_config->max_allowed = @@ -88,22 +99,44 @@ static int qxl_display_copy_rom_client_monitors_config(struct qxl_device *qdev) &qdev->rom->client_monitors_config.heads[i]; struct qxl_head *client_head = &qdev->client_monitors_config->heads[i]; - client_head->x = c_rect->left; - client_head->y = c_rect->top; - client_head->width = c_rect->right - c_rect->left; - client_head->height = c_rect->bottom - c_rect->top; - client_head->surface_id = 0; - client_head->id = i; - client_head->flags = 0; + if (client_head->x != c_rect->left) { + client_head->x = c_rect->left; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->y != c_rect->top) { + client_head->y = c_rect->top; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->width != c_rect->right - c_rect->left) { + client_head->width = c_rect->right - c_rect->left; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->height != c_rect->bottom - c_rect->top) { + client_head->height = c_rect->bottom - c_rect->top; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->surface_id != 0) { + client_head->surface_id = 0; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->id != i) { + client_head->id = i; + status = MONITORS_CONFIG_MODIFIED; + } + if (client_head->flags != 0) { + client_head->flags = 0; + status = MONITORS_CONFIG_MODIFIED; + } DRM_DEBUG_KMS("read %dx%d+%d+%d\n", client_head->width, client_head->height, client_head->x, client_head->y); } - return 0; + + return status; } static void qxl_update_offset_props(struct qxl_device *qdev) { - struct drm_device *dev = qdev->ddev; + struct drm_device *dev = &qdev->ddev; struct drm_connector *connector; struct qxl_output *output; struct qxl_head *head; @@ -123,19 +156,28 @@ static void qxl_update_offset_props(struct qxl_device *qdev) void qxl_display_read_client_monitors_config(struct qxl_device *qdev) { - struct drm_device *dev = qdev->ddev; - while (qxl_display_copy_rom_client_monitors_config(qdev)) { + struct drm_device *dev = &qdev->ddev; + int status; + + status = qxl_display_copy_rom_client_monitors_config(qdev); + while (status == MONITORS_CONFIG_BAD_CRC) { qxl_io_log(qdev, "failed crc check for client_monitors_config," " retrying\n"); + status = qxl_display_copy_rom_client_monitors_config(qdev); + } + if (status == MONITORS_CONFIG_UNCHANGED) { + qxl_io_log(qdev, "config unchanged\n"); + DRM_DEBUG("ignoring unchanged client monitors config"); + return; } drm_modeset_lock_all(dev); qxl_update_offset_props(qdev); drm_modeset_unlock_all(dev); - if (!drm_helper_hpd_irq_event(qdev->ddev)) { + if (!drm_helper_hpd_irq_event(dev)) { /* notify that the monitor configuration changed, to adjust at the arbitrary resolution */ - drm_kms_helper_hotplug_event(qdev->ddev); + drm_kms_helper_hotplug_event(dev); } } @@ -157,6 +199,9 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector, mode = drm_cvt_mode(dev, head->width, head->height, 60, false, false, false); mode->type |= DRM_MODE_TYPE_PREFERRED; + mode->hdisplay = head->width; + mode->vdisplay = head->height; + drm_mode_set_name(mode); *pwidth = head->width; *pheight = head->height; drm_mode_probed_add(connector, mode); @@ -579,12 +624,12 @@ qxl_framebuffer_init(struct drm_device *dev, int ret; qfb->obj = obj; + drm_helper_mode_fill_fb_struct(dev, &qfb->base, mode_cmd); ret = drm_framebuffer_init(dev, &qfb->base, funcs); if (ret) { qfb->obj = NULL; return ret; } - drm_helper_mode_fill_fb_struct(&qfb->base, mode_cmd); return 0; } @@ -607,7 +652,7 @@ static bool qxl_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -void +static void qxl_send_monitors_config(struct qxl_device *qdev) { int i; @@ -991,7 +1036,7 @@ static int qxl_mode_create_hotplug_mode_update_property(struct qxl_device *qdev) return 0; qdev->hotplug_mode_update_property = - drm_property_create_range(qdev->ddev, DRM_MODE_PROP_IMMUTABLE, + drm_property_create_range(&qdev->ddev, DRM_MODE_PROP_IMMUTABLE, "hotplug_mode_update", 0, 1); return 0; @@ -1032,7 +1077,6 @@ static int qdev_output_init(struct drm_device *dev, int num_output) dev->mode_config.suggested_x_property, 0); drm_object_attach_property(&connector->base, dev->mode_config.suggested_y_property, 0); - drm_connector_register(connector); return 0; } @@ -1131,28 +1175,28 @@ int qxl_modeset_init(struct qxl_device *qdev) int i; int ret; - drm_mode_config_init(qdev->ddev); + drm_mode_config_init(&qdev->ddev); ret = qxl_create_monitors_object(qdev); if (ret) return ret; - qdev->ddev->mode_config.funcs = (void *)&qxl_mode_funcs; + qdev->ddev.mode_config.funcs = (void *)&qxl_mode_funcs; /* modes will be validated against the framebuffer size */ - qdev->ddev->mode_config.min_width = 320; - qdev->ddev->mode_config.min_height = 200; - qdev->ddev->mode_config.max_width = 8192; - qdev->ddev->mode_config.max_height = 8192; + qdev->ddev.mode_config.min_width = 320; + qdev->ddev.mode_config.min_height = 200; + qdev->ddev.mode_config.max_width = 8192; + qdev->ddev.mode_config.max_height = 8192; - qdev->ddev->mode_config.fb_base = qdev->vram_base; + qdev->ddev.mode_config.fb_base = qdev->vram_base; - drm_mode_create_suggested_offset_properties(qdev->ddev); + drm_mode_create_suggested_offset_properties(&qdev->ddev); qxl_mode_create_hotplug_mode_update_property(qdev); for (i = 0 ; i < qxl_num_crtc; ++i) { - qdev_crtc_init(qdev->ddev, i); - qdev_output_init(qdev->ddev, i); + qdev_crtc_init(&qdev->ddev, i); + qdev_output_init(&qdev->ddev, i); } qdev->mode_info.mode_config_initialized = true; @@ -1170,7 +1214,7 @@ void qxl_modeset_fini(struct qxl_device *qdev) qxl_destroy_monitors_object(qdev); if (qdev->mode_info.mode_config_initialized) { - drm_mode_config_cleanup(qdev->ddev); + drm_mode_config_cleanup(&qdev->ddev); qdev->mode_info.mode_config_initialized = false; } } diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c index 9b728edf1b49..4d8681e84e68 100644 --- a/drivers/gpu/drm/qxl/qxl_draw.c +++ b/drivers/gpu/drm/qxl/qxl_draw.c @@ -283,7 +283,7 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, struct qxl_rect *rects; int stride = qxl_fb->base.pitches[0]; /* depth is not actually interesting, we don't mask with it */ - int depth = qxl_fb->base.bits_per_pixel; + int depth = qxl_fb->base.format->cpp[0] * 8; uint8_t *surface_base; struct qxl_release *release; struct qxl_bo *clips_bo; diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index 460bbceae297..8e17c241e63c 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -62,20 +62,71 @@ static struct pci_driver qxl_pci_driver; static int qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct qxl_device *qdev; + int ret; + if (pdev->revision < 4) { DRM_ERROR("qxl too old, doesn't support client_monitors_config," " use xf86-video-qxl in user mode"); return -EINVAL; /* TODO: ENODEV ? */ } - return drm_get_pci_dev(pdev, ent, &qxl_driver); + + qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); + if (!qdev) + return -ENOMEM; + + ret = pci_enable_device(pdev); + if (ret) + goto free_dev; + + ret = qxl_device_init(qdev, &qxl_driver, pdev, ent->driver_data); + if (ret) + goto disable_pci; + + ret = drm_vblank_init(&qdev->ddev, 1); + if (ret) + goto unload; + + ret = qxl_modeset_init(qdev); + if (ret) + goto vblank_cleanup; + + drm_kms_helper_poll_init(&qdev->ddev); + + /* Complete initialization. */ + ret = drm_dev_register(&qdev->ddev, ent->driver_data); + if (ret) + goto modeset_cleanup; + + return 0; + +modeset_cleanup: + qxl_modeset_fini(qdev); +vblank_cleanup: + drm_vblank_cleanup(&qdev->ddev); +unload: + qxl_device_fini(qdev); +disable_pci: + pci_disable_device(pdev); +free_dev: + kfree(qdev); + return ret; } static void qxl_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct qxl_device *qdev = dev->dev_private; + + drm_dev_unregister(dev); + + qxl_modeset_fini(qdev); + qxl_device_fini(qdev); - drm_put_dev(dev); + dev->dev_private = NULL; + kfree(qdev); + drm_dev_unref(dev); } static const struct file_operations qxl_fops = { @@ -230,8 +281,6 @@ static struct pci_driver qxl_pci_driver = { static struct drm_driver qxl_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, - .load = qxl_driver_load, - .unload = qxl_driver_unload, .get_vblank_counter = qxl_noop_get_vblank_counter, .enable_vblank = qxl_noop_enable_vblank, .disable_vblank = qxl_noop_disable_vblank, diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 5f3e5ad99de7..785c17b56f73 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -31,7 +31,7 @@ * Definitions taken from spice-protocol, plus kernel driver specific bits. */ -#include <linux/fence.h> +#include <linux/dma-fence.h> #include <linux/workqueue.h> #include <linux/firmware.h> #include <linux/platform_device.h> @@ -43,6 +43,7 @@ #include <ttm/ttm_placement.h> #include <ttm/ttm_module.h> +#include <drm/drm_encoder.h> #include <drm/drm_gem.h> /* just for ttm_validate_buffer */ @@ -190,7 +191,7 @@ enum { * spice-protocol/qxl_dev.h */ #define QXL_MAX_RES 96 struct qxl_release { - struct fence base; + struct dma_fence base; int id; int type; @@ -241,9 +242,7 @@ void qxl_debugfs_remove_files(struct qxl_device *qdev); struct qxl_device; struct qxl_device { - struct device *dev; - struct drm_device *ddev; - struct pci_dev *pdev; + struct drm_device ddev; unsigned long flags; resource_size_t vram_base, vram_size; @@ -335,8 +334,9 @@ __printf(2,3) void qxl_io_log(struct qxl_device *qdev, const char *fmt, ...); extern const struct drm_ioctl_desc qxl_ioctls[]; extern int qxl_max_ioctl; -int qxl_driver_load(struct drm_device *dev, unsigned long flags); -int qxl_driver_unload(struct drm_device *dev); +int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv, + struct pci_dev *pdev, unsigned long flags); +void qxl_device_fini(struct qxl_device *qdev); int qxl_modeset_init(struct qxl_device *qdev); void qxl_modeset_fini(struct qxl_device *qdev); @@ -395,16 +395,11 @@ qxl_framebuffer_init(struct drm_device *dev, struct drm_gem_object *obj, const struct drm_framebuffer_funcs *funcs); void qxl_display_read_client_monitors_config(struct qxl_device *qdev); -void qxl_send_monitors_config(struct qxl_device *qdev); int qxl_create_monitors_object(struct qxl_device *qdev); int qxl_destroy_monitors_object(struct qxl_device *qdev); -/* used by qxl_debugfs only */ -void qxl_crtc_set_from_monitors_config(struct qxl_device *qdev); -void qxl_alloc_client_monitors_config(struct qxl_device *qdev, unsigned count); - /* qxl_gem.c */ -int qxl_gem_init(struct qxl_device *qdev); +void qxl_gem_init(struct qxl_device *qdev); void qxl_gem_fini(struct qxl_device *qdev); int qxl_gem_object_create(struct qxl_device *qdev, int size, int alignment, int initial_domain, @@ -535,6 +530,7 @@ int qxl_garbage_collect(struct qxl_device *qdev); int qxl_debugfs_init(struct drm_minor *minor); void qxl_debugfs_takedown(struct drm_minor *minor); +int qxl_ttm_debugfs_init(struct qxl_device *qdev); /* qxl_prime.c */ int qxl_gem_prime_pin(struct drm_gem_object *obj); @@ -574,6 +570,5 @@ int qxl_bo_check_id(struct qxl_device *qdev, struct qxl_bo *bo); struct qxl_drv_surface * qxl_surface_lookup(struct drm_device *dev, int surface_id); void qxl_surface_evict(struct qxl_device *qdev, struct qxl_bo *surf, bool freeing); -int qxl_update_surface(struct qxl_device *qdev, struct qxl_bo *surf); #endif diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 2cd879a4ae15..d479b7a7abe4 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -81,16 +81,10 @@ static struct fb_deferred_io qxl_defio = { static struct fb_ops qxlfb_ops = { .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, /* TODO: copy vmwgfx */ + DRM_FB_HELPER_DEFAULT_OPS, .fb_fillrect = drm_fb_helper_sys_fillrect, .fb_copyarea = drm_fb_helper_sys_copyarea, .fb_imageblit = drm_fb_helper_sys_imageblit, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, }; static void qxlfb_destroy_pinned_object(struct drm_gem_object *gobj) @@ -197,7 +191,7 @@ static int qxlfb_framebuffer_dirty(struct drm_framebuffer *fb, /* * we are using a shadow draw buffer, at qdev->surface0_shadow */ - qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", clips->x1, clips->x2, + qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]\n", clips->x1, clips->x2, clips->y1, clips->y2); image->dx = clips->x1; image->dy = clips->y1; @@ -274,7 +268,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, info->par = qfbdev; - qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, + qxl_framebuffer_init(&qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, &qxlfb_fb_funcs); fb = &qfbdev->qfb.base; @@ -285,7 +279,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, qfbdev->shadow = shadow; strcpy(info->fix.id, "qxldrmfb"); - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); + drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; info->fbops = &qxlfb_ops; @@ -303,7 +297,7 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, sizes->fb_height); /* setup aperture base/size for vesafb takeover */ - info->apertures->ranges[0].base = qdev->ddev->mode_config.fb_base; + info->apertures->ranges[0].base = qdev->ddev.mode_config.fb_base; info->apertures->ranges[0].size = qdev->vram_size; info->fix.mmio_start = 0; @@ -322,7 +316,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, qdev->fbdev_info = info; qdev->fbdev_qfb = &qfbdev->qfb; DRM_INFO("fb mappable at 0x%lX, size %lu\n", info->fix.smem_start, (unsigned long)info->screen_size); - DRM_INFO("fb: depth %d, pitch %d, width %d, height %d\n", fb->depth, fb->pitches[0], fb->width, fb->height); + DRM_INFO("fb: depth %d, pitch %d, width %d, height %d\n", + fb->format->depth, fb->pitches[0], fb->width, fb->height); return 0; out_destroy_fbi: @@ -400,11 +395,10 @@ int qxl_fbdev_init(struct qxl_device *qdev) spin_lock_init(&qfbdev->delayed_ops_lock); INIT_LIST_HEAD(&qfbdev->delayed_ops); - drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, + drm_fb_helper_prepare(&qdev->ddev, &qfbdev->helper, &qxl_fb_helper_funcs); - ret = drm_fb_helper_init(qdev->ddev, &qfbdev->helper, - qxl_num_crtc /* num_crtc - QXL supports just 1 */, + ret = drm_fb_helper_init(&qdev->ddev, &qfbdev->helper, QXLFB_CONN_LIMIT); if (ret) goto free; @@ -431,7 +425,7 @@ void qxl_fbdev_fini(struct qxl_device *qdev) if (!qdev->mode_info.qfbdev) return; - qxl_fbdev_destroy(qdev->ddev, qdev->mode_info.qfbdev); + qxl_fbdev_destroy(&qdev->ddev, qdev->mode_info.qfbdev); kfree(qdev->mode_info.qfbdev); qdev->mode_info.qfbdev = NULL; } diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c index d9746e904ef1..3f185c4da5b7 100644 --- a/drivers/gpu/drm/qxl/qxl_gem.c +++ b/drivers/gpu/drm/qxl/qxl_gem.c @@ -111,10 +111,9 @@ void qxl_gem_object_close(struct drm_gem_object *obj, { } -int qxl_gem_init(struct qxl_device *qdev) +void qxl_gem_init(struct qxl_device *qdev) { INIT_LIST_HEAD(&qdev->gem.objects); - return 0; } void qxl_gem_fini(struct qxl_device *qdev) diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 5a4c8c492683..0b82a87916ae 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -64,7 +64,7 @@ static int qxl_map_ioctl(struct drm_device *dev, void *data, struct qxl_device *qdev = dev->dev_private; struct drm_qxl_map *qxl_map = data; - return qxl_mode_dumb_mmap(file_priv, qdev->ddev, qxl_map->handle, + return qxl_mode_dumb_mmap(file_priv, &qdev->ddev, qxl_map->handle, &qxl_map->offset); } @@ -375,7 +375,7 @@ static int qxl_clientcap_ioctl(struct drm_device *dev, void *data, byte = param->index / 8; idx = param->index % 8; - if (qdev->pdev->revision < 4) + if (dev->pdev->revision < 4) return -ENOSYS; if (byte >= 58) diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c index 0bf1e20c6e44..23a40106ab53 100644 --- a/drivers/gpu/drm/qxl/qxl_irq.c +++ b/drivers/gpu/drm/qxl/qxl_irq.c @@ -90,7 +90,7 @@ int qxl_irq_init(struct qxl_device *qdev) atomic_set(&qdev->irq_received_cursor, 0); atomic_set(&qdev->irq_received_io_cmd, 0); qdev->irq_received_error = 0; - ret = drm_irq_install(qdev->ddev, qdev->ddev->pdev->irq); + ret = drm_irq_install(&qdev->ddev, qdev->ddev.pdev->irq); qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; if (unlikely(ret != 0)) { DRM_ERROR("Failed installing irq: %d\n", ret); diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index e642242728c0..2dcd5c14cb56 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -115,23 +115,28 @@ static void qxl_gc_work(struct work_struct *work) qxl_garbage_collect(qdev); } -static int qxl_device_init(struct qxl_device *qdev, - struct drm_device *ddev, +int qxl_device_init(struct qxl_device *qdev, + struct drm_driver *drv, struct pci_dev *pdev, unsigned long flags) { int r, sb; - qdev->dev = &pdev->dev; - qdev->ddev = ddev; - qdev->pdev = pdev; + r = drm_dev_init(&qdev->ddev, drv, &pdev->dev); + if (r) + return r; + + qdev->ddev.pdev = pdev; + pci_set_drvdata(pdev, &qdev->ddev); + qdev->ddev.dev_private = qdev; + qdev->flags = flags; mutex_init(&qdev->gem.mutex); mutex_init(&qdev->update_area_mutex); mutex_init(&qdev->release_mutex); mutex_init(&qdev->surf_evict_mutex); - INIT_LIST_HEAD(&qdev->gem.objects); + qxl_gem_init(qdev); qdev->rom_base = pci_resource_start(pdev, 2); qdev->rom_size = pci_resource_len(pdev, 2); @@ -263,7 +268,7 @@ static int qxl_device_init(struct qxl_device *qdev, return 0; } -static void qxl_device_fini(struct qxl_device *qdev) +void qxl_device_fini(struct qxl_device *qdev) { if (qdev->current_release_bo[0]) qxl_bo_unref(&qdev->current_release_bo[0]); @@ -273,6 +278,7 @@ static void qxl_device_fini(struct qxl_device *qdev) qxl_ring_free(qdev->command_ring); qxl_ring_free(qdev->cursor_ring); qxl_ring_free(qdev->release_ring); + qxl_gem_fini(qdev); qxl_bo_fini(qdev); io_mapping_free(qdev->surface_mapping); io_mapping_free(qdev->vram_mapping); @@ -283,56 +289,3 @@ static void qxl_device_fini(struct qxl_device *qdev) qdev->mode_info.num_modes = 0; qxl_debugfs_remove_files(qdev); } - -int qxl_driver_unload(struct drm_device *dev) -{ - struct qxl_device *qdev = dev->dev_private; - - if (qdev == NULL) - return 0; - - drm_vblank_cleanup(dev); - - qxl_modeset_fini(qdev); - qxl_device_fini(qdev); - - kfree(qdev); - dev->dev_private = NULL; - return 0; -} - -int qxl_driver_load(struct drm_device *dev, unsigned long flags) -{ - struct qxl_device *qdev; - int r; - - qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL); - if (qdev == NULL) - return -ENOMEM; - - dev->dev_private = qdev; - - r = qxl_device_init(qdev, dev, dev->pdev, flags); - if (r) - goto out; - - r = drm_vblank_init(dev, 1); - if (r) - goto unload; - - r = qxl_modeset_init(qdev); - if (r) - goto unload; - - drm_kms_helper_poll_init(qdev->ddev); - - return 0; -unload: - qxl_driver_unload(dev); - -out: - kfree(qdev); - return r; -} - - diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index fa5440dc9a19..dbc13510a1f8 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -93,7 +93,7 @@ int qxl_bo_create(struct qxl_device *qdev, if (bo == NULL) return -ENOMEM; size = roundup(size, PAGE_SIZE); - r = drm_gem_object_init(qdev->ddev, &bo->gem_base, size); + r = drm_gem_object_init(&qdev->ddev, &bo->gem_base, size); if (unlikely(r)) { kfree(bo); return r; @@ -113,7 +113,7 @@ int qxl_bo_create(struct qxl_device *qdev, NULL, NULL, &qxl_ttm_bo_destroy); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) - dev_err(qdev->dev, + dev_err(qdev->ddev.dev, "object_init failed for (%lu, 0x%08X)\n", size, domain); return r; @@ -223,7 +223,7 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) { - struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; + struct drm_device *ddev = bo->gem_base.dev; int r; if (bo->pin_count) { @@ -240,17 +240,17 @@ int qxl_bo_pin(struct qxl_bo *bo, u32 domain, u64 *gpu_addr) *gpu_addr = qxl_bo_gpu_offset(bo); } if (unlikely(r != 0)) - dev_err(qdev->dev, "%p pin failed\n", bo); + dev_err(ddev->dev, "%p pin failed\n", bo); return r; } int qxl_bo_unpin(struct qxl_bo *bo) { - struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; + struct drm_device *ddev = bo->gem_base.dev; int r, i; if (!bo->pin_count) { - dev_warn(qdev->dev, "%p unpin not necessary\n", bo); + dev_warn(ddev->dev, "%p unpin not necessary\n", bo); return 0; } bo->pin_count--; @@ -260,7 +260,7 @@ int qxl_bo_unpin(struct qxl_bo *bo) bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT; r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); if (unlikely(r != 0)) - dev_err(qdev->dev, "%p validate failed for unpin\n", bo); + dev_err(ddev->dev, "%p validate failed for unpin\n", bo); return r; } @@ -270,9 +270,9 @@ void qxl_bo_force_delete(struct qxl_device *qdev) if (list_empty(&qdev->gem.objects)) return; - dev_err(qdev->dev, "Userspace still has active objects !\n"); + dev_err(qdev->ddev.dev, "Userspace still has active objects !\n"); list_for_each_entry_safe(bo, n, &qdev->gem.objects, list) { - dev_err(qdev->dev, "%p %p %lu %lu force free\n", + dev_err(qdev->ddev.dev, "%p %p %lu %lu force free\n", &bo->gem_base, bo, (unsigned long)bo->gem_base.size, *((unsigned long *)&bo->gem_base.refcount)); mutex_lock(&qdev->gem.mutex); diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 4d8311373ba3..0374fd93f4d6 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -34,8 +34,8 @@ static inline int qxl_bo_reserve(struct qxl_bo *bo, bool no_wait) r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) { - struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; - dev_err(qdev->dev, "%p reserve failed\n", bo); + struct drm_device *ddev = bo->gem_base.dev; + dev_err(ddev->dev, "%p reserve failed\n", bo); } return r; } @@ -70,8 +70,8 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type, r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) { - struct qxl_device *qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; - dev_err(qdev->dev, "%p reserve failed for wait\n", + struct drm_device *ddev = bo->gem_base.dev; + dev_err(ddev->dev, "%p reserve failed for wait\n", bo); } return r; diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index cd83f050cf3e..e6ec845b5be0 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -21,7 +21,7 @@ */ #include "qxl_drv.h" #include "qxl_object.h" -#include <trace/events/fence.h> +#include <trace/events/dma_fence.h> /* * drawable cmd cache - allocate a bunch of VRAM pages, suballocate @@ -40,23 +40,24 @@ static const int release_size_per_bo[] = { RELEASE_SIZE, SURFACE_RELEASE_SIZE, RELEASE_SIZE }; static const int releases_per_bo[] = { RELEASES_PER_BO, SURFACE_RELEASES_PER_BO, RELEASES_PER_BO }; -static const char *qxl_get_driver_name(struct fence *fence) +static const char *qxl_get_driver_name(struct dma_fence *fence) { return "qxl"; } -static const char *qxl_get_timeline_name(struct fence *fence) +static const char *qxl_get_timeline_name(struct dma_fence *fence) { return "release"; } -static bool qxl_nop_signaling(struct fence *fence) +static bool qxl_nop_signaling(struct dma_fence *fence) { /* fences are always automatically signaled, so just pretend we did this.. */ return true; } -static long qxl_fence_wait(struct fence *fence, bool intr, signed long timeout) +static long qxl_fence_wait(struct dma_fence *fence, bool intr, + signed long timeout) { struct qxl_device *qdev; struct qxl_release *release; @@ -71,7 +72,7 @@ static long qxl_fence_wait(struct fence *fence, bool intr, signed long timeout) retry: sc++; - if (fence_is_signaled(fence)) + if (dma_fence_is_signaled(fence)) goto signaled; qxl_io_notify_oom(qdev); @@ -80,11 +81,11 @@ retry: if (!qxl_queue_garbage_collect(qdev, true)) break; - if (fence_is_signaled(fence)) + if (dma_fence_is_signaled(fence)) goto signaled; } - if (fence_is_signaled(fence)) + if (dma_fence_is_signaled(fence)) goto signaled; if (have_drawable_releases || sc < 4) { @@ -96,9 +97,9 @@ retry: return 0; if (have_drawable_releases && sc > 300) { - FENCE_WARN(fence, "failed to wait on release %llu " - "after spincount %d\n", - fence->context & ~0xf0000000, sc); + DMA_FENCE_WARN(fence, "failed to wait on release %llu " + "after spincount %d\n", + fence->context & ~0xf0000000, sc); goto signaled; } goto retry; @@ -115,7 +116,7 @@ signaled: return end - cur; } -static const struct fence_ops qxl_fence_ops = { +static const struct dma_fence_ops qxl_fence_ops = { .get_driver_name = qxl_get_driver_name, .get_timeline_name = qxl_get_timeline_name, .enable_signaling = qxl_nop_signaling, @@ -133,7 +134,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type, release = kmalloc(size, GFP_KERNEL); if (!release) { DRM_ERROR("Out of memory\n"); - return 0; + return -ENOMEM; } release->base.ops = NULL; release->type = type; @@ -192,8 +193,8 @@ qxl_release_free(struct qxl_device *qdev, WARN_ON(list_empty(&release->bos)); qxl_release_free_list(release); - fence_signal(&release->base); - fence_put(&release->base); + dma_fence_signal(&release->base); + dma_fence_put(&release->base); } else { qxl_release_free_list(release); kfree(release); @@ -453,9 +454,9 @@ void qxl_release_fence_buffer_objects(struct qxl_release *release) * Since we never really allocated a context and we don't want to conflict, * set the highest bits. This will break if we really allow exporting of dma-bufs. */ - fence_init(&release->base, &qxl_fence_ops, &qdev->release_lock, - release->id | 0xf0000000, release->base.seqno); - trace_fence_emit(&release->base); + dma_fence_init(&release->base, &qxl_fence_ops, &qdev->release_lock, + release->id | 0xf0000000, release->base.seqno); + trace_dma_fence_emit(&release->base); driver = bdev->driver; glob = bo->glob; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index e26c82db948b..7d1cab57c89e 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -35,7 +35,6 @@ #include "qxl_object.h" #include <linux/delay.h> -static int qxl_ttm_debugfs_init(struct qxl_device *qdev); static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) { @@ -106,15 +105,15 @@ static void qxl_ttm_global_fini(struct qxl_device *qdev) static struct vm_operations_struct qxl_ttm_vm_ops; static const struct vm_operations_struct *ttm_vm_ops; -static int qxl_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +static int qxl_ttm_fault(struct vm_fault *vmf) { struct ttm_buffer_object *bo; int r; - bo = (struct ttm_buffer_object *)vma->vm_private_data; + bo = (struct ttm_buffer_object *)vmf->vma->vm_private_data; if (bo == NULL) return VM_FAULT_NOPAGE; - r = ttm_vm_ops->fault(vma, vmf); + r = ttm_vm_ops->fault(vmf); return r; } @@ -367,6 +366,7 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, } static void qxl_bo_move_notify(struct ttm_buffer_object *bo, + bool evict, struct ttm_mem_reg *new_mem) { struct qxl_bo *qbo; @@ -387,14 +387,13 @@ static struct ttm_bo_driver qxl_bo_driver = { .ttm_tt_unpopulate = &qxl_ttm_tt_unpopulate, .invalidate_caches = &qxl_invalidate_caches, .init_mem_type = &qxl_init_mem_type, + .eviction_valuable = ttm_bo_eviction_valuable, .evict_flags = &qxl_evict_flags, .move = &qxl_bo_move, .verify_access = &qxl_verify_access, .io_mem_reserve = &qxl_ttm_io_mem_reserve, .io_mem_free = &qxl_ttm_io_mem_free, .move_notify = &qxl_bo_move_notify, - .lru_tail = &ttm_bo_default_lru_tail, - .swap_lru_tail = &ttm_bo_default_swap_lru_tail, }; int qxl_ttm_init(struct qxl_device *qdev) @@ -409,7 +408,7 @@ int qxl_ttm_init(struct qxl_device *qdev) r = ttm_bo_device_init(&qdev->mman.bdev, qdev->mman.bo_global_ref.ref.object, &qxl_bo_driver, - qdev->ddev->anon_inode->i_mapping, + qdev->ddev.anon_inode->i_mapping, DRM_FILE_PAGE_OFFSET, 0); if (r) { DRM_ERROR("failed initializing buffer object driver(%d).\n", r); @@ -435,11 +434,6 @@ int qxl_ttm_init(struct qxl_device *qdev) ((unsigned)num_io_pages * PAGE_SIZE) / (1024 * 1024)); DRM_INFO("qxl: %uM of Surface memory size\n", (unsigned)qdev->surfaceram_size / (1024 * 1024)); - r = qxl_ttm_debugfs_init(qdev); - if (r) { - DRM_ERROR("Failed to init debugfs\n"); - return r; - } return 0; } @@ -462,17 +456,17 @@ static int qxl_mm_dump_table(struct seq_file *m, void *data) struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; struct drm_device *dev = node->minor->dev; struct qxl_device *rdev = dev->dev_private; - int ret; struct ttm_bo_global *glob = rdev->mman.bdev.glob; + struct drm_printer p = drm_seq_file_printer(m); spin_lock(&glob->lru_lock); - ret = drm_mm_dump_table(m, mm); + drm_mm_print(mm, &p); spin_unlock(&glob->lru_lock); - return ret; + return 0; } #endif -static int qxl_ttm_debugfs_init(struct qxl_device *qdev) +int qxl_ttm_debugfs_init(struct qxl_device *qdev) { #if defined(CONFIG_DEBUG_FS) static struct drm_info_list qxl_mem_types_list[QXL_DEBUGFS_MEM_TYPES]; |