diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/virtio/Makefile | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_display.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 103 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.c | 79 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_kms.c | 9 |
6 files changed, 83 insertions, 122 deletions
diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index f29deec83d1f..4e90cc8fa651 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # Makefile for the drm device driver. This driver provides support for the | 3 | # Makefile for the drm device driver. This driver provides support for the |
| 4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 4 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
| 5 | 5 | ||
| 6 | virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ | 6 | virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \ |
| 7 | virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ | 7 | virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ |
| 8 | virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ | 8 | virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ |
| 9 | virtgpu_ioctl.o virtgpu_prime.o | 9 | virtgpu_ioctl.o virtgpu_prime.o |
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index d539bc28dc97..87d7c49cf057 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c | |||
| @@ -358,7 +358,7 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { | |||
| 358 | .atomic_commit = drm_atomic_helper_commit, | 358 | .atomic_commit = drm_atomic_helper_commit, |
| 359 | }; | 359 | }; |
| 360 | 360 | ||
| 361 | int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) | 361 | void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) |
| 362 | { | 362 | { |
| 363 | int i; | 363 | int i; |
| 364 | 364 | ||
| @@ -377,7 +377,6 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) | |||
| 377 | vgdev_output_init(vgdev, i); | 377 | vgdev_output_init(vgdev, i); |
| 378 | 378 | ||
| 379 | drm_mode_config_reset(vgdev->ddev); | 379 | drm_mode_config_reset(vgdev->ddev); |
| 380 | return 0; | ||
| 381 | } | 380 | } |
| 382 | 381 | ||
| 383 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) | 382 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) |
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c deleted file mode 100644 index 0887e0b64b9c..000000000000 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ /dev/null | |||
| @@ -1,103 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2015 Red Hat, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * Permission is hereby granted, free of charge, to any person obtaining | ||
| 6 | * a copy of this software and associated documentation files (the | ||
| 7 | * "Software"), to deal in the Software without restriction, including | ||
| 8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
| 9 | * distribute, sublicense, and/or sell copies of the Software, and to | ||
| 10 | * permit persons to whom the Software is furnished to do so, subject to | ||
| 11 | * the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice (including the | ||
| 14 | * next paragraph) shall be included in all copies or substantial | ||
| 15 | * portions of the Software. | ||
| 16 | * | ||
| 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 20 | * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||
| 21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| 23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/pci.h> | ||
| 27 | #include <drm/drm_fb_helper.h> | ||
| 28 | |||
| 29 | #include "virtgpu_drv.h" | ||
| 30 | |||
| 31 | int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev) | ||
| 32 | { | ||
| 33 | struct drm_device *dev; | ||
| 34 | int ret; | ||
| 35 | |||
| 36 | dev = drm_dev_alloc(driver, &vdev->dev); | ||
| 37 | if (IS_ERR(dev)) | ||
| 38 | return PTR_ERR(dev); | ||
| 39 | vdev->priv = dev; | ||
| 40 | |||
| 41 | if (strcmp(vdev->dev.parent->bus->name, "pci") == 0) { | ||
| 42 | struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); | ||
| 43 | const char *pname = dev_name(&pdev->dev); | ||
| 44 | bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; | ||
| 45 | char unique[20]; | ||
| 46 | |||
| 47 | DRM_INFO("pci: %s detected at %s\n", | ||
| 48 | vga ? "virtio-vga" : "virtio-gpu-pci", | ||
| 49 | pname); | ||
| 50 | dev->pdev = pdev; | ||
| 51 | if (vga) | ||
| 52 | drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, | ||
| 53 | 0, | ||
| 54 | "virtiodrmfb"); | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Normally the drm_dev_set_unique() call is done by core DRM. | ||
| 58 | * The following comment covers, why virtio cannot rely on it. | ||
| 59 | * | ||
| 60 | * Unlike the other virtual GPU drivers, virtio abstracts the | ||
| 61 | * underlying bus type by using struct virtio_device. | ||
| 62 | * | ||
| 63 | * Hence the dev_is_pci() check, used in core DRM, will fail | ||
| 64 | * and the unique returned will be the virtio_device "virtio0", | ||
| 65 | * while a "pci:..." one is required. | ||
| 66 | * | ||
| 67 | * A few other ideas were considered: | ||
| 68 | * - Extend the dev_is_pci() check [in drm_set_busid] to | ||
| 69 | * consider virtio. | ||
| 70 | * Seems like a bigger hack than what we have already. | ||
| 71 | * | ||
| 72 | * - Point drm_device::dev to the parent of the virtio_device | ||
| 73 | * Semantic changes: | ||
| 74 | * * Using the wrong device for i2c, framebuffer_alloc and | ||
| 75 | * prime import. | ||
| 76 | * Visual changes: | ||
| 77 | * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer, | ||
| 78 | * will print the wrong information. | ||
| 79 | * | ||
| 80 | * We could address the latter issues, by introducing | ||
| 81 | * drm_device::bus_dev, ... which would be used solely for this. | ||
| 82 | * | ||
| 83 | * So for the moment keep things as-is, with a bulky comment | ||
| 84 | * for the next person who feels like removing this | ||
| 85 | * drm_dev_set_unique() quirk. | ||
| 86 | */ | ||
| 87 | snprintf(unique, sizeof(unique), "pci:%s", pname); | ||
| 88 | ret = drm_dev_set_unique(dev, unique); | ||
| 89 | if (ret) | ||
| 90 | goto err_free; | ||
| 91 | |||
| 92 | } | ||
| 93 | |||
| 94 | ret = drm_dev_register(dev, 0); | ||
| 95 | if (ret) | ||
| 96 | goto err_free; | ||
| 97 | |||
| 98 | return 0; | ||
| 99 | |||
| 100 | err_free: | ||
| 101 | drm_dev_put(dev); | ||
| 102 | return ret; | ||
| 103 | } | ||
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 7df50920c1e0..af92964b6889 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c | |||
| @@ -40,8 +40,60 @@ static int virtio_gpu_modeset = -1; | |||
| 40 | MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); | 40 | MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); |
| 41 | module_param_named(modeset, virtio_gpu_modeset, int, 0400); | 41 | module_param_named(modeset, virtio_gpu_modeset, int, 0400); |
| 42 | 42 | ||
| 43 | static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev) | ||
| 44 | { | ||
| 45 | struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); | ||
| 46 | const char *pname = dev_name(&pdev->dev); | ||
| 47 | bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; | ||
| 48 | char unique[20]; | ||
| 49 | |||
| 50 | DRM_INFO("pci: %s detected at %s\n", | ||
| 51 | vga ? "virtio-vga" : "virtio-gpu-pci", | ||
| 52 | pname); | ||
| 53 | dev->pdev = pdev; | ||
| 54 | if (vga) | ||
| 55 | drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, | ||
| 56 | 0, | ||
| 57 | "virtiodrmfb"); | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Normally the drm_dev_set_unique() call is done by core DRM. | ||
| 61 | * The following comment covers, why virtio cannot rely on it. | ||
| 62 | * | ||
| 63 | * Unlike the other virtual GPU drivers, virtio abstracts the | ||
| 64 | * underlying bus type by using struct virtio_device. | ||
| 65 | * | ||
| 66 | * Hence the dev_is_pci() check, used in core DRM, will fail | ||
| 67 | * and the unique returned will be the virtio_device "virtio0", | ||
| 68 | * while a "pci:..." one is required. | ||
| 69 | * | ||
| 70 | * A few other ideas were considered: | ||
| 71 | * - Extend the dev_is_pci() check [in drm_set_busid] to | ||
| 72 | * consider virtio. | ||
| 73 | * Seems like a bigger hack than what we have already. | ||
| 74 | * | ||
| 75 | * - Point drm_device::dev to the parent of the virtio_device | ||
| 76 | * Semantic changes: | ||
| 77 | * * Using the wrong device for i2c, framebuffer_alloc and | ||
| 78 | * prime import. | ||
| 79 | * Visual changes: | ||
| 80 | * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer, | ||
| 81 | * will print the wrong information. | ||
| 82 | * | ||
| 83 | * We could address the latter issues, by introducing | ||
| 84 | * drm_device::bus_dev, ... which would be used solely for this. | ||
| 85 | * | ||
| 86 | * So for the moment keep things as-is, with a bulky comment | ||
| 87 | * for the next person who feels like removing this | ||
| 88 | * drm_dev_set_unique() quirk. | ||
| 89 | */ | ||
| 90 | snprintf(unique, sizeof(unique), "pci:%s", pname); | ||
| 91 | return drm_dev_set_unique(dev, unique); | ||
| 92 | } | ||
| 93 | |||
| 43 | static int virtio_gpu_probe(struct virtio_device *vdev) | 94 | static int virtio_gpu_probe(struct virtio_device *vdev) |
| 44 | { | 95 | { |
| 96 | struct drm_device *dev; | ||
| 45 | int ret; | 97 | int ret; |
| 46 | 98 | ||
| 47 | if (vgacon_text_force() && virtio_gpu_modeset == -1) | 99 | if (vgacon_text_force() && virtio_gpu_modeset == -1) |
| @@ -50,18 +102,39 @@ static int virtio_gpu_probe(struct virtio_device *vdev) | |||
| 50 | if (virtio_gpu_modeset == 0) | 102 | if (virtio_gpu_modeset == 0) |
| 51 | return -EINVAL; | 103 | return -EINVAL; |
| 52 | 104 | ||
| 53 | ret = drm_virtio_init(&driver, vdev); | 105 | dev = drm_dev_alloc(&driver, &vdev->dev); |
| 106 | if (IS_ERR(dev)) | ||
| 107 | return PTR_ERR(dev); | ||
| 108 | vdev->priv = dev; | ||
| 109 | |||
| 110 | if (!strcmp(vdev->dev.parent->bus->name, "pci")) { | ||
| 111 | ret = virtio_gpu_pci_quirk(dev, vdev); | ||
| 112 | if (ret) | ||
| 113 | goto err_free; | ||
| 114 | } | ||
| 115 | |||
| 116 | ret = virtio_gpu_init(dev); | ||
| 54 | if (ret) | 117 | if (ret) |
| 55 | return ret; | 118 | goto err_free; |
| 119 | |||
| 120 | ret = drm_dev_register(dev, 0); | ||
| 121 | if (ret) | ||
| 122 | goto err_free; | ||
| 56 | 123 | ||
| 57 | drm_fbdev_generic_setup(vdev->priv, 32); | 124 | drm_fbdev_generic_setup(vdev->priv, 32); |
| 58 | return 0; | 125 | return 0; |
| 126 | |||
| 127 | err_free: | ||
| 128 | drm_dev_put(dev); | ||
| 129 | return ret; | ||
| 59 | } | 130 | } |
| 60 | 131 | ||
| 61 | static void virtio_gpu_remove(struct virtio_device *vdev) | 132 | static void virtio_gpu_remove(struct virtio_device *vdev) |
| 62 | { | 133 | { |
| 63 | struct drm_device *dev = vdev->priv; | 134 | struct drm_device *dev = vdev->priv; |
| 64 | 135 | ||
| 136 | drm_dev_unregister(dev); | ||
| 137 | virtio_gpu_deinit(dev); | ||
| 65 | drm_put_dev(dev); | 138 | drm_put_dev(dev); |
| 66 | } | 139 | } |
| 67 | 140 | ||
| @@ -123,8 +196,6 @@ static const struct file_operations virtio_gpu_driver_fops = { | |||
| 123 | 196 | ||
| 124 | static struct drm_driver driver = { | 197 | static struct drm_driver driver = { |
| 125 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, | 198 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, |
| 126 | .load = virtio_gpu_driver_load, | ||
| 127 | .unload = virtio_gpu_driver_unload, | ||
| 128 | .open = virtio_gpu_driver_open, | 199 | .open = virtio_gpu_driver_open, |
| 129 | .postclose = virtio_gpu_driver_postclose, | 200 | .postclose = virtio_gpu_driver_postclose, |
| 130 | 201 | ||
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bfb31fc3d01d..cf896d879382 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h | |||
| @@ -50,9 +50,6 @@ | |||
| 50 | #define DRIVER_MINOR 1 | 50 | #define DRIVER_MINOR 1 |
| 51 | #define DRIVER_PATCHLEVEL 0 | 51 | #define DRIVER_PATCHLEVEL 0 |
| 52 | 52 | ||
| 53 | /* virtgpu_drm_bus.c */ | ||
| 54 | int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); | ||
| 55 | |||
| 56 | struct virtio_gpu_object { | 53 | struct virtio_gpu_object { |
| 57 | struct drm_gem_object gem_base; | 54 | struct drm_gem_object gem_base; |
| 58 | uint32_t hw_res_handle; | 55 | uint32_t hw_res_handle; |
| @@ -209,8 +206,8 @@ struct virtio_gpu_fpriv { | |||
| 209 | extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; | 206 | extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; |
| 210 | 207 | ||
| 211 | /* virtio_kms.c */ | 208 | /* virtio_kms.c */ |
| 212 | int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); | 209 | int virtio_gpu_init(struct drm_device *dev); |
| 213 | void virtio_gpu_driver_unload(struct drm_device *dev); | 210 | void virtio_gpu_deinit(struct drm_device *dev); |
| 214 | int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); | 211 | int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); |
| 215 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); | 212 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); |
| 216 | 213 | ||
| @@ -320,7 +317,7 @@ int virtio_gpu_framebuffer_init(struct drm_device *dev, | |||
| 320 | struct virtio_gpu_framebuffer *vgfb, | 317 | struct virtio_gpu_framebuffer *vgfb, |
| 321 | const struct drm_mode_fb_cmd2 *mode_cmd, | 318 | const struct drm_mode_fb_cmd2 *mode_cmd, |
| 322 | struct drm_gem_object *obj); | 319 | struct drm_gem_object *obj); |
| 323 | int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); | 320 | void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); |
| 324 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); | 321 | void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); |
| 325 | 322 | ||
| 326 | /* virtio_gpu_plane.c */ | 323 | /* virtio_gpu_plane.c */ |
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index c340be252fce..84b6a6bf00c6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c | |||
| @@ -106,7 +106,7 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, | |||
| 106 | vgdev->num_capsets = num_capsets; | 106 | vgdev->num_capsets = num_capsets; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) | 109 | int virtio_gpu_init(struct drm_device *dev) |
| 110 | { | 110 | { |
| 111 | static vq_callback_t *callbacks[] = { | 111 | static vq_callback_t *callbacks[] = { |
| 112 | virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack | 112 | virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack |
| @@ -193,9 +193,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 193 | num_capsets, &num_capsets); | 193 | num_capsets, &num_capsets); |
| 194 | DRM_INFO("number of cap sets: %d\n", num_capsets); | 194 | DRM_INFO("number of cap sets: %d\n", num_capsets); |
| 195 | 195 | ||
| 196 | ret = virtio_gpu_modeset_init(vgdev); | 196 | virtio_gpu_modeset_init(vgdev); |
| 197 | if (ret) | ||
| 198 | goto err_modeset; | ||
| 199 | 197 | ||
| 200 | virtio_device_ready(vgdev->vdev); | 198 | virtio_device_ready(vgdev->vdev); |
| 201 | vgdev->vqs_ready = true; | 199 | vgdev->vqs_ready = true; |
| @@ -209,7 +207,6 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 209 | 5 * HZ); | 207 | 5 * HZ); |
| 210 | return 0; | 208 | return 0; |
| 211 | 209 | ||
| 212 | err_modeset: | ||
| 213 | err_scanouts: | 210 | err_scanouts: |
| 214 | virtio_gpu_ttm_fini(vgdev); | 211 | virtio_gpu_ttm_fini(vgdev); |
| 215 | err_ttm: | 212 | err_ttm: |
| @@ -231,7 +228,7 @@ static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev) | |||
| 231 | } | 228 | } |
| 232 | } | 229 | } |
| 233 | 230 | ||
| 234 | void virtio_gpu_driver_unload(struct drm_device *dev) | 231 | void virtio_gpu_deinit(struct drm_device *dev) |
| 235 | { | 232 | { |
| 236 | struct virtio_gpu_device *vgdev = dev->dev_private; | 233 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| 237 | 234 | ||
