Move the generic fbdev implementation into its own source and header file. Adapt drivers. No functional changes, but some of the internal helpers have been renamed to fit into the drm_fbdev_ naming scheme. v3: * rename drm_fbdev.{c,h} to drm_fbdev_generic.{c,h} * rebase onto vmwgfx changes * rebase onto xlnx changes * fix include statements in amdgpu Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221103151446.2638-22-tzimmermann@suse.de
198 lines
4.2 KiB
C
198 lines
4.2 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright (C) 2013-2017 Oracle Corporation
|
|
* This file is based on ast_drv.c
|
|
* Copyright 2012 Red Hat Inc.
|
|
* Authors: Dave Airlie <airlied@redhat.com>
|
|
* Michael Thayer <michael.thayer@oracle.com,
|
|
* Hans de Goede <hdegoede@redhat.com>
|
|
*/
|
|
#include <linux/module.h>
|
|
#include <linux/pci.h>
|
|
#include <linux/vt_kern.h>
|
|
|
|
#include <drm/drm_aperture.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_drv.h>
|
|
#include <drm/drm_fbdev_generic.h>
|
|
#include <drm/drm_file.h>
|
|
#include <drm/drm_ioctl.h>
|
|
#include <drm/drm_managed.h>
|
|
#include <drm/drm_module.h>
|
|
|
|
#include "vbox_drv.h"
|
|
|
|
static int vbox_modeset = -1;
|
|
|
|
MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
|
|
module_param_named(modeset, vbox_modeset, int, 0400);
|
|
|
|
static const struct drm_driver driver;
|
|
|
|
static const struct pci_device_id pciidlist[] = {
|
|
{ PCI_DEVICE(0x80ee, 0xbeef) },
|
|
{ }
|
|
};
|
|
MODULE_DEVICE_TABLE(pci, pciidlist);
|
|
|
|
static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
{
|
|
struct vbox_private *vbox;
|
|
int ret = 0;
|
|
|
|
if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
|
|
return -ENODEV;
|
|
|
|
ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
|
|
if (ret)
|
|
return ret;
|
|
|
|
vbox = devm_drm_dev_alloc(&pdev->dev, &driver,
|
|
struct vbox_private, ddev);
|
|
if (IS_ERR(vbox))
|
|
return PTR_ERR(vbox);
|
|
|
|
pci_set_drvdata(pdev, vbox);
|
|
mutex_init(&vbox->hw_mutex);
|
|
|
|
ret = pcim_enable_device(pdev);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = vbox_hw_init(vbox);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = vbox_mm_init(vbox);
|
|
if (ret)
|
|
goto err_hw_fini;
|
|
|
|
ret = vbox_mode_init(vbox);
|
|
if (ret)
|
|
goto err_hw_fini;
|
|
|
|
ret = vbox_irq_init(vbox);
|
|
if (ret)
|
|
goto err_mode_fini;
|
|
|
|
ret = drm_dev_register(&vbox->ddev, 0);
|
|
if (ret)
|
|
goto err_irq_fini;
|
|
|
|
drm_fbdev_generic_setup(&vbox->ddev, 32);
|
|
|
|
return 0;
|
|
|
|
err_irq_fini:
|
|
vbox_irq_fini(vbox);
|
|
err_mode_fini:
|
|
vbox_mode_fini(vbox);
|
|
err_hw_fini:
|
|
vbox_hw_fini(vbox);
|
|
return ret;
|
|
}
|
|
|
|
static void vbox_pci_remove(struct pci_dev *pdev)
|
|
{
|
|
struct vbox_private *vbox = pci_get_drvdata(pdev);
|
|
|
|
drm_dev_unregister(&vbox->ddev);
|
|
vbox_irq_fini(vbox);
|
|
vbox_mode_fini(vbox);
|
|
vbox_hw_fini(vbox);
|
|
}
|
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
static int vbox_pm_suspend(struct device *dev)
|
|
{
|
|
struct vbox_private *vbox = dev_get_drvdata(dev);
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
int error;
|
|
|
|
error = drm_mode_config_helper_suspend(&vbox->ddev);
|
|
if (error)
|
|
return error;
|
|
|
|
pci_save_state(pdev);
|
|
pci_disable_device(pdev);
|
|
pci_set_power_state(pdev, PCI_D3hot);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int vbox_pm_resume(struct device *dev)
|
|
{
|
|
struct vbox_private *vbox = dev_get_drvdata(dev);
|
|
struct pci_dev *pdev = to_pci_dev(dev);
|
|
|
|
if (pci_enable_device(pdev))
|
|
return -EIO;
|
|
|
|
return drm_mode_config_helper_resume(&vbox->ddev);
|
|
}
|
|
|
|
static int vbox_pm_freeze(struct device *dev)
|
|
{
|
|
struct vbox_private *vbox = dev_get_drvdata(dev);
|
|
|
|
return drm_mode_config_helper_suspend(&vbox->ddev);
|
|
}
|
|
|
|
static int vbox_pm_thaw(struct device *dev)
|
|
{
|
|
struct vbox_private *vbox = dev_get_drvdata(dev);
|
|
|
|
return drm_mode_config_helper_resume(&vbox->ddev);
|
|
}
|
|
|
|
static int vbox_pm_poweroff(struct device *dev)
|
|
{
|
|
struct vbox_private *vbox = dev_get_drvdata(dev);
|
|
|
|
return drm_mode_config_helper_suspend(&vbox->ddev);
|
|
}
|
|
|
|
static const struct dev_pm_ops vbox_pm_ops = {
|
|
.suspend = vbox_pm_suspend,
|
|
.resume = vbox_pm_resume,
|
|
.freeze = vbox_pm_freeze,
|
|
.thaw = vbox_pm_thaw,
|
|
.poweroff = vbox_pm_poweroff,
|
|
.restore = vbox_pm_resume,
|
|
};
|
|
#endif
|
|
|
|
static struct pci_driver vbox_pci_driver = {
|
|
.name = DRIVER_NAME,
|
|
.id_table = pciidlist,
|
|
.probe = vbox_pci_probe,
|
|
.remove = vbox_pci_remove,
|
|
#ifdef CONFIG_PM_SLEEP
|
|
.driver.pm = &vbox_pm_ops,
|
|
#endif
|
|
};
|
|
|
|
DEFINE_DRM_GEM_FOPS(vbox_fops);
|
|
|
|
static const struct drm_driver driver = {
|
|
.driver_features =
|
|
DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
|
|
|
|
.fops = &vbox_fops,
|
|
.name = DRIVER_NAME,
|
|
.desc = DRIVER_DESC,
|
|
.date = DRIVER_DATE,
|
|
.major = DRIVER_MAJOR,
|
|
.minor = DRIVER_MINOR,
|
|
.patchlevel = DRIVER_PATCHLEVEL,
|
|
|
|
DRM_GEM_VRAM_DRIVER,
|
|
};
|
|
|
|
drm_module_pci_driver_if_modeset(vbox_pci_driver, vbox_modeset);
|
|
|
|
MODULE_AUTHOR("Oracle Corporation");
|
|
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
|
MODULE_DESCRIPTION(DRIVER_DESC);
|
|
MODULE_LICENSE("GPL and additional rights");
|