vbox_drv.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright (C) 2013-2017 Oracle Corporation
  4. * This file is based on ast_drv.c
  5. * Copyright 2012 Red Hat Inc.
  6. * Authors: Dave Airlie <airlied@redhat.com>
  7. * Michael Thayer <michael.thayer@oracle.com,
  8. * Hans de Goede <hdegoede@redhat.com>
  9. */
  10. #include <linux/console.h>
  11. #include <linux/module.h>
  12. #include <linux/pci.h>
  13. #include <linux/vt_kern.h>
  14. #include <drm/drm_crtc_helper.h>
  15. #include <drm/drm_drv.h>
  16. #include <drm/drm_fb_helper.h>
  17. #include <drm/drm_file.h>
  18. #include <drm/drm_ioctl.h>
  19. #include <drm/drm_managed.h>
  20. #include "vbox_drv.h"
  21. static int vbox_modeset = -1;
  22. MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
  23. module_param_named(modeset, vbox_modeset, int, 0400);
  24. static struct drm_driver driver;
  25. static const struct pci_device_id pciidlist[] = {
  26. { PCI_DEVICE(0x80ee, 0xbeef) },
  27. { }
  28. };
  29. MODULE_DEVICE_TABLE(pci, pciidlist);
  30. static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  31. {
  32. struct vbox_private *vbox;
  33. int ret = 0;
  34. if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
  35. return -ENODEV;
  36. ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "vboxvideodrmfb");
  37. if (ret)
  38. return ret;
  39. vbox = devm_drm_dev_alloc(&pdev->dev, &driver,
  40. struct vbox_private, ddev);
  41. if (IS_ERR(vbox))
  42. return PTR_ERR(vbox);
  43. vbox->ddev.pdev = pdev;
  44. pci_set_drvdata(pdev, vbox);
  45. mutex_init(&vbox->hw_mutex);
  46. ret = pcim_enable_device(pdev);
  47. if (ret)
  48. return ret;
  49. ret = vbox_hw_init(vbox);
  50. if (ret)
  51. return ret;
  52. ret = vbox_mm_init(vbox);
  53. if (ret)
  54. goto err_hw_fini;
  55. ret = vbox_mode_init(vbox);
  56. if (ret)
  57. goto err_mm_fini;
  58. ret = vbox_irq_init(vbox);
  59. if (ret)
  60. goto err_mode_fini;
  61. ret = drm_dev_register(&vbox->ddev, 0);
  62. if (ret)
  63. goto err_irq_fini;
  64. drm_fbdev_generic_setup(&vbox->ddev, 32);
  65. return 0;
  66. err_irq_fini:
  67. vbox_irq_fini(vbox);
  68. err_mode_fini:
  69. vbox_mode_fini(vbox);
  70. err_mm_fini:
  71. vbox_mm_fini(vbox);
  72. err_hw_fini:
  73. vbox_hw_fini(vbox);
  74. return ret;
  75. }
  76. static void vbox_pci_remove(struct pci_dev *pdev)
  77. {
  78. struct vbox_private *vbox = pci_get_drvdata(pdev);
  79. drm_dev_unregister(&vbox->ddev);
  80. vbox_irq_fini(vbox);
  81. vbox_mode_fini(vbox);
  82. vbox_mm_fini(vbox);
  83. vbox_hw_fini(vbox);
  84. }
  85. #ifdef CONFIG_PM_SLEEP
  86. static int vbox_pm_suspend(struct device *dev)
  87. {
  88. struct vbox_private *vbox = dev_get_drvdata(dev);
  89. int error;
  90. error = drm_mode_config_helper_suspend(&vbox->ddev);
  91. if (error)
  92. return error;
  93. pci_save_state(vbox->ddev.pdev);
  94. pci_disable_device(vbox->ddev.pdev);
  95. pci_set_power_state(vbox->ddev.pdev, PCI_D3hot);
  96. return 0;
  97. }
  98. static int vbox_pm_resume(struct device *dev)
  99. {
  100. struct vbox_private *vbox = dev_get_drvdata(dev);
  101. if (pci_enable_device(vbox->ddev.pdev))
  102. return -EIO;
  103. return drm_mode_config_helper_resume(&vbox->ddev);
  104. }
  105. static int vbox_pm_freeze(struct device *dev)
  106. {
  107. struct vbox_private *vbox = dev_get_drvdata(dev);
  108. return drm_mode_config_helper_suspend(&vbox->ddev);
  109. }
  110. static int vbox_pm_thaw(struct device *dev)
  111. {
  112. struct vbox_private *vbox = dev_get_drvdata(dev);
  113. return drm_mode_config_helper_resume(&vbox->ddev);
  114. }
  115. static int vbox_pm_poweroff(struct device *dev)
  116. {
  117. struct vbox_private *vbox = dev_get_drvdata(dev);
  118. return drm_mode_config_helper_suspend(&vbox->ddev);
  119. }
  120. static const struct dev_pm_ops vbox_pm_ops = {
  121. .suspend = vbox_pm_suspend,
  122. .resume = vbox_pm_resume,
  123. .freeze = vbox_pm_freeze,
  124. .thaw = vbox_pm_thaw,
  125. .poweroff = vbox_pm_poweroff,
  126. .restore = vbox_pm_resume,
  127. };
  128. #endif
  129. static struct pci_driver vbox_pci_driver = {
  130. .name = DRIVER_NAME,
  131. .id_table = pciidlist,
  132. .probe = vbox_pci_probe,
  133. .remove = vbox_pci_remove,
  134. #ifdef CONFIG_PM_SLEEP
  135. .driver.pm = &vbox_pm_ops,
  136. #endif
  137. };
  138. DEFINE_DRM_GEM_FOPS(vbox_fops);
  139. static struct drm_driver driver = {
  140. .driver_features =
  141. DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
  142. .lastclose = drm_fb_helper_lastclose,
  143. .fops = &vbox_fops,
  144. .irq_handler = vbox_irq_handler,
  145. .name = DRIVER_NAME,
  146. .desc = DRIVER_DESC,
  147. .date = DRIVER_DATE,
  148. .major = DRIVER_MAJOR,
  149. .minor = DRIVER_MINOR,
  150. .patchlevel = DRIVER_PATCHLEVEL,
  151. DRM_GEM_VRAM_DRIVER,
  152. };
  153. static int __init vbox_init(void)
  154. {
  155. #ifdef CONFIG_VGA_CONSOLE
  156. if (vgacon_text_force() && vbox_modeset == -1)
  157. return -EINVAL;
  158. #endif
  159. if (vbox_modeset == 0)
  160. return -EINVAL;
  161. return pci_register_driver(&vbox_pci_driver);
  162. }
  163. static void __exit vbox_exit(void)
  164. {
  165. pci_unregister_driver(&vbox_pci_driver);
  166. }
  167. module_init(vbox_init);
  168. module_exit(vbox_exit);
  169. MODULE_AUTHOR("Oracle Corporation");
  170. MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
  171. MODULE_DESCRIPTION(DRIVER_DESC);
  172. MODULE_LICENSE("GPL and additional rights");