summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/qxl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/qxl')
-rw-r--r--drivers/gpu/drm/qxl/Kconfig2
-rw-r--r--drivers/gpu/drm/qxl/qxl_cmd.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_debugfs.c22
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c104
-rw-r--r--drivers/gpu/drm/qxl/qxl_draw.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c57
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.h23
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c26
-rw-r--r--drivers/gpu/drm/qxl/qxl_gem.c3
-rw-r--r--drivers/gpu/drm/qxl/qxl_ioctl.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_irq.c2
-rw-r--r--drivers/gpu/drm/qxl/qxl_kms.c73
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.c18
-rw-r--r--drivers/gpu/drm/qxl/qxl_object.h8
-rw-r--r--drivers/gpu/drm/qxl/qxl_release.c37
-rw-r--r--drivers/gpu/drm/qxl/qxl_ttm.c26
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];
OpenPOWER on IntegriCloud