root/drivers/gpu/drm/virtio/virtgpu_drv.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. virtio_gpu_pci_quirk
  2. virtio_gpu_probe
  3. virtio_gpu_remove
  4. virtio_gpu_config_changed

   1 /*
   2  * Copyright (C) 2015 Red Hat, Inc.
   3  * All Rights Reserved.
   4  *
   5  * Authors:
   6  *    Dave Airlie <airlied@redhat.com>
   7  *    Gerd Hoffmann <kraxel@redhat.com>
   8  *
   9  * Permission is hereby granted, free of charge, to any person obtaining a
  10  * copy of this software and associated documentation files (the "Software"),
  11  * to deal in the Software without restriction, including without limitation
  12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13  * and/or sell copies of the Software, and to permit persons to whom the
  14  * Software is furnished to do so, subject to the following conditions:
  15  *
  16  * The above copyright notice and this permission notice (including the next
  17  * paragraph) shall be included in all copies or substantial portions of the
  18  * Software.
  19  *
  20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  23  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  26  * OTHER DEALINGS IN THE SOFTWARE.
  27  */
  28 
  29 #include <linux/module.h>
  30 #include <linux/console.h>
  31 #include <linux/pci.h>
  32 
  33 #include <drm/drm.h>
  34 #include <drm/drm_drv.h>
  35 #include <drm/drm_file.h>
  36 
  37 #include "virtgpu_drv.h"
  38 
  39 static struct drm_driver driver;
  40 
  41 static int virtio_gpu_modeset = -1;
  42 
  43 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
  44 module_param_named(modeset, virtio_gpu_modeset, int, 0400);
  45 
  46 static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev)
  47 {
  48         struct pci_dev *pdev = to_pci_dev(vdev->dev.parent);
  49         const char *pname = dev_name(&pdev->dev);
  50         bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA;
  51         char unique[20];
  52 
  53         DRM_INFO("pci: %s detected at %s\n",
  54                  vga ? "virtio-vga" : "virtio-gpu-pci",
  55                  pname);
  56         dev->pdev = pdev;
  57         if (vga)
  58                 drm_fb_helper_remove_conflicting_pci_framebuffers(pdev,
  59                                                                   0,
  60                                                                   "virtiodrmfb");
  61 
  62         /*
  63          * Normally the drm_dev_set_unique() call is done by core DRM.
  64          * The following comment covers, why virtio cannot rely on it.
  65          *
  66          * Unlike the other virtual GPU drivers, virtio abstracts the
  67          * underlying bus type by using struct virtio_device.
  68          *
  69          * Hence the dev_is_pci() check, used in core DRM, will fail
  70          * and the unique returned will be the virtio_device "virtio0",
  71          * while a "pci:..." one is required.
  72          *
  73          * A few other ideas were considered:
  74          * - Extend the dev_is_pci() check [in drm_set_busid] to
  75          *   consider virtio.
  76          *   Seems like a bigger hack than what we have already.
  77          *
  78          * - Point drm_device::dev to the parent of the virtio_device
  79          *   Semantic changes:
  80          *   * Using the wrong device for i2c, framebuffer_alloc and
  81          *     prime import.
  82          *   Visual changes:
  83          *   * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer,
  84          *     will print the wrong information.
  85          *
  86          * We could address the latter issues, by introducing
  87          * drm_device::bus_dev, ... which would be used solely for this.
  88          *
  89          * So for the moment keep things as-is, with a bulky comment
  90          * for the next person who feels like removing this
  91          * drm_dev_set_unique() quirk.
  92          */
  93         snprintf(unique, sizeof(unique), "pci:%s", pname);
  94         return drm_dev_set_unique(dev, unique);
  95 }
  96 
  97 static int virtio_gpu_probe(struct virtio_device *vdev)
  98 {
  99         struct drm_device *dev;
 100         int ret;
 101 
 102         if (vgacon_text_force() && virtio_gpu_modeset == -1)
 103                 return -EINVAL;
 104 
 105         if (virtio_gpu_modeset == 0)
 106                 return -EINVAL;
 107 
 108         dev = drm_dev_alloc(&driver, &vdev->dev);
 109         if (IS_ERR(dev))
 110                 return PTR_ERR(dev);
 111         vdev->priv = dev;
 112 
 113         if (!strcmp(vdev->dev.parent->bus->name, "pci")) {
 114                 ret = virtio_gpu_pci_quirk(dev, vdev);
 115                 if (ret)
 116                         goto err_free;
 117         }
 118 
 119         ret = virtio_gpu_init(dev);
 120         if (ret)
 121                 goto err_free;
 122 
 123         ret = drm_dev_register(dev, 0);
 124         if (ret)
 125                 goto err_free;
 126 
 127         drm_fbdev_generic_setup(vdev->priv, 32);
 128         return 0;
 129 
 130 err_free:
 131         drm_dev_put(dev);
 132         return ret;
 133 }
 134 
 135 static void virtio_gpu_remove(struct virtio_device *vdev)
 136 {
 137         struct drm_device *dev = vdev->priv;
 138 
 139         drm_dev_unregister(dev);
 140         virtio_gpu_deinit(dev);
 141         drm_put_dev(dev);
 142 }
 143 
 144 static void virtio_gpu_config_changed(struct virtio_device *vdev)
 145 {
 146         struct drm_device *dev = vdev->priv;
 147         struct virtio_gpu_device *vgdev = dev->dev_private;
 148 
 149         schedule_work(&vgdev->config_changed_work);
 150 }
 151 
 152 static struct virtio_device_id id_table[] = {
 153         { VIRTIO_ID_GPU, VIRTIO_DEV_ANY_ID },
 154         { 0 },
 155 };
 156 
 157 static unsigned int features[] = {
 158 #ifdef __LITTLE_ENDIAN
 159         /*
 160          * Gallium command stream send by virgl is native endian.
 161          * Because of that we only support little endian guests on
 162          * little endian hosts.
 163          */
 164         VIRTIO_GPU_F_VIRGL,
 165 #endif
 166         VIRTIO_GPU_F_EDID,
 167 };
 168 static struct virtio_driver virtio_gpu_driver = {
 169         .feature_table = features,
 170         .feature_table_size = ARRAY_SIZE(features),
 171         .driver.name = KBUILD_MODNAME,
 172         .driver.owner = THIS_MODULE,
 173         .id_table = id_table,
 174         .probe = virtio_gpu_probe,
 175         .remove = virtio_gpu_remove,
 176         .config_changed = virtio_gpu_config_changed
 177 };
 178 
 179 module_virtio_driver(virtio_gpu_driver);
 180 
 181 MODULE_DEVICE_TABLE(virtio, id_table);
 182 MODULE_DESCRIPTION("Virtio GPU driver");
 183 MODULE_LICENSE("GPL and additional rights");
 184 MODULE_AUTHOR("Dave Airlie <airlied@redhat.com>");
 185 MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
 186 MODULE_AUTHOR("Alon Levy");
 187 
 188 static const struct file_operations virtio_gpu_driver_fops = {
 189         .owner = THIS_MODULE,
 190         .open = drm_open,
 191         .mmap = virtio_gpu_mmap,
 192         .poll = drm_poll,
 193         .read = drm_read,
 194         .unlocked_ioctl = drm_ioctl,
 195         .release = drm_release,
 196         .compat_ioctl = drm_compat_ioctl,
 197         .llseek = noop_llseek,
 198 };
 199 
 200 static struct drm_driver driver = {
 201         .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC,
 202         .open = virtio_gpu_driver_open,
 203         .postclose = virtio_gpu_driver_postclose,
 204 
 205         .dumb_create = virtio_gpu_mode_dumb_create,
 206         .dumb_map_offset = virtio_gpu_mode_dumb_mmap,
 207 
 208 #if defined(CONFIG_DEBUG_FS)
 209         .debugfs_init = virtio_gpu_debugfs_init,
 210 #endif
 211         .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 212         .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 213         .gem_prime_get_sg_table = virtgpu_gem_prime_get_sg_table,
 214         .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table,
 215         .gem_prime_vmap = virtgpu_gem_prime_vmap,
 216         .gem_prime_vunmap = virtgpu_gem_prime_vunmap,
 217         .gem_prime_mmap = virtgpu_gem_prime_mmap,
 218 
 219         .gem_free_object_unlocked = virtio_gpu_gem_free_object,
 220         .gem_open_object = virtio_gpu_gem_object_open,
 221         .gem_close_object = virtio_gpu_gem_object_close,
 222         .fops = &virtio_gpu_driver_fops,
 223 
 224         .ioctls = virtio_gpu_ioctls,
 225         .num_ioctls = DRM_VIRTIO_NUM_IOCTLS,
 226 
 227         .name = DRIVER_NAME,
 228         .desc = DRIVER_DESC,
 229         .date = DRIVER_DATE,
 230         .major = DRIVER_MAJOR,
 231         .minor = DRIVER_MINOR,
 232         .patchlevel = DRIVER_PATCHLEVEL,
 233 };

/* [<][>][^][v][top][bottom][index][help] */