vbox_drv.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 <[email protected]>
  7. * Michael Thayer <[email protected],
  8. * Hans de Goede <[email protected]>
  9. */
  10. #include <linux/module.h>
  11. #include <linux/pci.h>
  12. #include <linux/vt_kern.h>
  13. #include <drm/drm_aperture.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 <drm/drm_module.h>
  21. #include "vbox_drv.h"
  22. static int vbox_modeset = -1;
  23. MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
  24. module_param_named(modeset, vbox_modeset, int, 0400);
  25. static const struct drm_driver driver;
  26. static const struct pci_device_id pciidlist[] = {
  27. { PCI_DEVICE(0x80ee, 0xbeef) },
  28. { }
  29. };
  30. MODULE_DEVICE_TABLE(pci, pciidlist);
  31. static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  32. {
  33. struct vbox_private *vbox;
  34. int ret = 0;
  35. if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
  36. return -ENODEV;
  37. ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
  38. if (ret)
  39. return ret;
  40. vbox = devm_drm_dev_alloc(&pdev->dev, &driver,
  41. struct vbox_private, ddev);
  42. if (IS_ERR(vbox))
  43. return PTR_ERR(vbox);
  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_hw_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_hw_fini:
  71. vbox_hw_fini(vbox);
  72. return ret;
  73. }
  74. static void vbox_pci_remove(struct pci_dev *pdev)
  75. {
  76. struct vbox_private *vbox = pci_get_drvdata(pdev);
  77. drm_dev_unregister(&vbox->ddev);
  78. vbox_irq_fini(vbox);
  79. vbox_mode_fini(vbox);
  80. vbox_hw_fini(vbox);
  81. }
  82. #ifdef CONFIG_PM_SLEEP
  83. static int vbox_pm_suspend(struct device *dev)
  84. {
  85. struct vbox_private *vbox = dev_get_drvdata(dev);
  86. struct pci_dev *pdev = to_pci_dev(dev);
  87. int error;
  88. error = drm_mode_config_helper_suspend(&vbox->ddev);
  89. if (error)
  90. return error;
  91. pci_save_state(pdev);
  92. pci_disable_device(pdev);
  93. pci_set_power_state(pdev, PCI_D3hot);
  94. return 0;
  95. }
  96. static int vbox_pm_resume(struct device *dev)
  97. {
  98. struct vbox_private *vbox = dev_get_drvdata(dev);
  99. struct pci_dev *pdev = to_pci_dev(dev);
  100. if (pci_enable_device(pdev))
  101. return -EIO;
  102. return drm_mode_config_helper_resume(&vbox->ddev);
  103. }
  104. static int vbox_pm_freeze(struct device *dev)
  105. {
  106. struct vbox_private *vbox = dev_get_drvdata(dev);
  107. return drm_mode_config_helper_suspend(&vbox->ddev);
  108. }
  109. static int vbox_pm_thaw(struct device *dev)
  110. {
  111. struct vbox_private *vbox = dev_get_drvdata(dev);
  112. return drm_mode_config_helper_resume(&vbox->ddev);
  113. }
  114. static int vbox_pm_poweroff(struct device *dev)
  115. {
  116. struct vbox_private *vbox = dev_get_drvdata(dev);
  117. return drm_mode_config_helper_suspend(&vbox->ddev);
  118. }
  119. static const struct dev_pm_ops vbox_pm_ops = {
  120. .suspend = vbox_pm_suspend,
  121. .resume = vbox_pm_resume,
  122. .freeze = vbox_pm_freeze,
  123. .thaw = vbox_pm_thaw,
  124. .poweroff = vbox_pm_poweroff,
  125. .restore = vbox_pm_resume,
  126. };
  127. #endif
  128. static struct pci_driver vbox_pci_driver = {
  129. .name = DRIVER_NAME,
  130. .id_table = pciidlist,
  131. .probe = vbox_pci_probe,
  132. .remove = vbox_pci_remove,
  133. #ifdef CONFIG_PM_SLEEP
  134. .driver.pm = &vbox_pm_ops,
  135. #endif
  136. };
  137. DEFINE_DRM_GEM_FOPS(vbox_fops);
  138. static const struct drm_driver driver = {
  139. .driver_features =
  140. DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
  141. .lastclose = drm_fb_helper_lastclose,
  142. .fops = &vbox_fops,
  143. .name = DRIVER_NAME,
  144. .desc = DRIVER_DESC,
  145. .date = DRIVER_DATE,
  146. .major = DRIVER_MAJOR,
  147. .minor = DRIVER_MINOR,
  148. .patchlevel = DRIVER_PATCHLEVEL,
  149. DRM_GEM_VRAM_DRIVER,
  150. };
  151. drm_module_pci_driver_if_modeset(vbox_pci_driver, vbox_modeset);
  152. MODULE_AUTHOR("Oracle Corporation");
  153. MODULE_AUTHOR("Hans de Goede <[email protected]>");
  154. MODULE_DESCRIPTION(DRIVER_DESC);
  155. MODULE_LICENSE("GPL and additional rights");