diff options
Diffstat (limited to 'drivers/gpu/drm/hyperv/hyperv_drm_drv.c')
| -rw-r--r-- | drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 98 |
1 files changed, 25 insertions, 73 deletions
diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c index eb06c92c4bfd..06b5d96e6eaf 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -3,29 +3,27 @@ * Copyright 2021 Microsoft */ +#include <linux/aperture.h> #include <linux/efi.h> #include <linux/hyperv.h> #include <linux/module.h> #include <linux/pci.h> -#include <drm/drm_aperture.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_gem_shmem_helper.h> +#include <drm/drm_print.h> #include <drm/drm_simple_kms_helper.h> #include "hyperv_drm.h" #define DRIVER_NAME "hyperv_drm" #define DRIVER_DESC "DRM driver for Hyper-V synthetic video device" -#define DRIVER_DATE "2020" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 -#define PCI_VENDOR_ID_MICROSOFT 0x1414 -#define PCI_DEVICE_ID_HYPERV_VIDEO 0x5353 - DEFINE_DRM_GEM_FOPS(hv_fops); static struct drm_driver hyperv_driver = { @@ -33,12 +31,12 @@ static struct drm_driver hyperv_driver = { .name = DRIVER_NAME, .desc = DRIVER_DESC, - .date = DRIVER_DATE, .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .fops = &hv_fops, DRM_GEM_SHMEM_DRIVER_OPS, + DRM_FBDEV_SHMEM_DRIVER_OPS, }; static int hyperv_pci_probe(struct pci_dev *pdev, @@ -69,66 +67,12 @@ static struct pci_driver hyperv_pci_driver = { .remove = hyperv_pci_remove, }; -static int hyperv_setup_gen1(struct hyperv_drm_device *hv) -{ - struct drm_device *dev = &hv->dev; - struct pci_dev *pdev; - int ret; - - pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, - PCI_DEVICE_ID_HYPERV_VIDEO, NULL); - if (!pdev) { - drm_err(dev, "Unable to find PCI Hyper-V video\n"); - return -ENODEV; - } - - ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "hypervdrmfb"); - if (ret) { - drm_err(dev, "Not able to remove boot fb\n"); - return ret; - } - - if (pci_request_region(pdev, 0, DRIVER_NAME) != 0) - drm_warn(dev, "Cannot request framebuffer, boot fb still active?\n"); - - if ((pdev->resource[0].flags & IORESOURCE_MEM) == 0) { - drm_err(dev, "Resource at bar 0 is not IORESOURCE_MEM\n"); - ret = -ENODEV; - goto error; - } - - hv->fb_base = pci_resource_start(pdev, 0); - hv->fb_size = pci_resource_len(pdev, 0); - if (!hv->fb_base) { - drm_err(dev, "Resource not available\n"); - ret = -ENODEV; - goto error; - } - - hv->fb_size = min(hv->fb_size, - (unsigned long)(hv->mmio_megabytes * 1024 * 1024)); - hv->vram = devm_ioremap(&pdev->dev, hv->fb_base, hv->fb_size); - if (!hv->vram) { - drm_err(dev, "Failed to map vram\n"); - ret = -ENOMEM; - } - -error: - pci_dev_put(pdev); - return ret; -} - -static int hyperv_setup_gen2(struct hyperv_drm_device *hv, +static int hyperv_setup_vram(struct hyperv_drm_device *hv, struct hv_device *hdev) { struct drm_device *dev = &hv->dev; int ret; - drm_aperture_remove_conflicting_framebuffers(screen_info.lfb_base, - screen_info.lfb_size, - false, - "hypervdrmfb"); - hv->fb_size = (unsigned long)hv->mmio_megabytes * 1024 * 1024; ret = vmbus_allocate_mmio(&hv->mem, hdev, 0, -1, hv->fb_size, 0x100000, @@ -181,11 +125,9 @@ static int hyperv_vmbus_probe(struct hv_device *hdev, goto err_hv_set_drv_data; } - if (efi_enabled(EFI_BOOT)) - ret = hyperv_setup_gen2(hv, hdev); - else - ret = hyperv_setup_gen1(hv); + aperture_remove_all_conflicting_devices(hyperv_driver.name); + ret = hyperv_setup_vram(hv, hdev); if (ret) goto err_vmbus_close; @@ -198,22 +140,23 @@ static int hyperv_vmbus_probe(struct hv_device *hdev, if (ret) drm_warn(dev, "Failed to update vram location.\n"); - hv->dirt_needed = true; - ret = hyperv_mode_config_init(hv); if (ret) - goto err_vmbus_close; + goto err_free_mmio; ret = drm_dev_register(dev, 0); if (ret) { drm_err(dev, "Failed to register drm driver.\n"); - goto err_vmbus_close; + goto err_free_mmio; } - drm_fbdev_generic_setup(dev, 0); + drm_client_setup(dev, NULL); return 0; +err_free_mmio: + iounmap(hv->vram); + vmbus_free_mmio(hv->mem->start, hv->fb_size); err_vmbus_close: vmbus_close(hdev->channel); err_hv_set_drv_data: @@ -221,7 +164,7 @@ err_hv_set_drv_data: return ret; } -static int hyperv_vmbus_remove(struct hv_device *hdev) +static void hyperv_vmbus_remove(struct hv_device *hdev) { struct drm_device *dev = hv_get_drvdata(hdev); struct hyperv_drm_device *hv = to_hv(dev); @@ -230,9 +173,14 @@ static int hyperv_vmbus_remove(struct hv_device *hdev) drm_atomic_helper_shutdown(dev); vmbus_close(hdev->channel); hv_set_drvdata(hdev, NULL); + + iounmap(hv->vram); vmbus_free_mmio(hv->mem->start, hv->fb_size); +} - return 0; +static void hyperv_vmbus_shutdown(struct hv_device *hdev) +{ + drm_atomic_helper_shutdown(hv_get_drvdata(hdev)); } static int hyperv_vmbus_suspend(struct hv_device *hdev) @@ -277,6 +225,7 @@ static struct hv_driver hyperv_hv_driver = { .id_table = hyperv_vmbus_tbl, .probe = hyperv_vmbus_probe, .remove = hyperv_vmbus_remove, + .shutdown = hyperv_vmbus_shutdown, .suspend = hyperv_vmbus_suspend, .resume = hyperv_vmbus_resume, .driver = { @@ -288,6 +237,9 @@ static int __init hyperv_init(void) { int ret; + if (drm_firmware_drivers_only()) + return -ENODEV; + ret = pci_register_driver(&hyperv_pci_driver); if (ret != 0) return ret; |
