0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <linux/module.h>
0030 #include <linux/pci.h>
0031
0032 #include <drm/drm_aperture.h>
0033 #include <drm/drm_atomic_helper.h>
0034 #include <drm/drm_crtc_helper.h>
0035 #include <drm/drm_drv.h>
0036 #include <drm/drm_gem_vram_helper.h>
0037 #include <drm/drm_module.h>
0038 #include <drm/drm_probe_helper.h>
0039
0040 #include "ast_drv.h"
0041
0042 int ast_modeset = -1;
0043
0044 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
0045 module_param_named(modeset, ast_modeset, int, 0400);
0046
0047
0048
0049
0050
0051 DEFINE_DRM_GEM_FOPS(ast_fops);
0052
0053 static const struct drm_driver ast_driver = {
0054 .driver_features = DRIVER_ATOMIC |
0055 DRIVER_GEM |
0056 DRIVER_MODESET,
0057
0058 .fops = &ast_fops,
0059 .name = DRIVER_NAME,
0060 .desc = DRIVER_DESC,
0061 .date = DRIVER_DATE,
0062 .major = DRIVER_MAJOR,
0063 .minor = DRIVER_MINOR,
0064 .patchlevel = DRIVER_PATCHLEVEL,
0065
0066 DRM_GEM_VRAM_DRIVER
0067 };
0068
0069
0070
0071
0072
0073 #define PCI_VENDOR_ASPEED 0x1a03
0074
0075 #define AST_VGA_DEVICE(id, info) { \
0076 .class = PCI_BASE_CLASS_DISPLAY << 16, \
0077 .class_mask = 0xff0000, \
0078 .vendor = PCI_VENDOR_ASPEED, \
0079 .device = id, \
0080 .subvendor = PCI_ANY_ID, \
0081 .subdevice = PCI_ANY_ID, \
0082 .driver_data = (unsigned long) info }
0083
0084 static const struct pci_device_id ast_pciidlist[] = {
0085 AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),
0086 AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),
0087 {0, 0, 0},
0088 };
0089
0090 MODULE_DEVICE_TABLE(pci, ast_pciidlist);
0091
0092 static int ast_remove_conflicting_framebuffers(struct pci_dev *pdev)
0093 {
0094 bool primary = false;
0095 resource_size_t base, size;
0096
0097 base = pci_resource_start(pdev, 0);
0098 size = pci_resource_len(pdev, 0);
0099 #ifdef CONFIG_X86
0100 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
0101 #endif
0102
0103 return drm_aperture_remove_conflicting_framebuffers(base, size, primary, &ast_driver);
0104 }
0105
0106 static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0107 {
0108 struct ast_private *ast;
0109 struct drm_device *dev;
0110 int ret;
0111
0112 ret = ast_remove_conflicting_framebuffers(pdev);
0113 if (ret)
0114 return ret;
0115
0116 ret = pcim_enable_device(pdev);
0117 if (ret)
0118 return ret;
0119
0120 ast = ast_device_create(&ast_driver, pdev, ent->driver_data);
0121 if (IS_ERR(ast))
0122 return PTR_ERR(ast);
0123 dev = &ast->base;
0124
0125 ret = drm_dev_register(dev, ent->driver_data);
0126 if (ret)
0127 return ret;
0128
0129 drm_fbdev_generic_setup(dev, 32);
0130
0131 return 0;
0132 }
0133
0134 static void ast_pci_remove(struct pci_dev *pdev)
0135 {
0136 struct drm_device *dev = pci_get_drvdata(pdev);
0137
0138 drm_dev_unregister(dev);
0139 drm_atomic_helper_shutdown(dev);
0140 }
0141
0142 static int ast_drm_freeze(struct drm_device *dev)
0143 {
0144 int error;
0145
0146 error = drm_mode_config_helper_suspend(dev);
0147 if (error)
0148 return error;
0149 pci_save_state(to_pci_dev(dev->dev));
0150 return 0;
0151 }
0152
0153 static int ast_drm_thaw(struct drm_device *dev)
0154 {
0155 ast_post_gpu(dev);
0156
0157 return drm_mode_config_helper_resume(dev);
0158 }
0159
0160 static int ast_drm_resume(struct drm_device *dev)
0161 {
0162 if (pci_enable_device(to_pci_dev(dev->dev)))
0163 return -EIO;
0164
0165 return ast_drm_thaw(dev);
0166 }
0167
0168 static int ast_pm_suspend(struct device *dev)
0169 {
0170 struct pci_dev *pdev = to_pci_dev(dev);
0171 struct drm_device *ddev = pci_get_drvdata(pdev);
0172 int error;
0173
0174 error = ast_drm_freeze(ddev);
0175 if (error)
0176 return error;
0177
0178 pci_disable_device(pdev);
0179 pci_set_power_state(pdev, PCI_D3hot);
0180 return 0;
0181 }
0182
0183 static int ast_pm_resume(struct device *dev)
0184 {
0185 struct pci_dev *pdev = to_pci_dev(dev);
0186 struct drm_device *ddev = pci_get_drvdata(pdev);
0187 return ast_drm_resume(ddev);
0188 }
0189
0190 static int ast_pm_freeze(struct device *dev)
0191 {
0192 struct pci_dev *pdev = to_pci_dev(dev);
0193 struct drm_device *ddev = pci_get_drvdata(pdev);
0194 return ast_drm_freeze(ddev);
0195 }
0196
0197 static int ast_pm_thaw(struct device *dev)
0198 {
0199 struct pci_dev *pdev = to_pci_dev(dev);
0200 struct drm_device *ddev = pci_get_drvdata(pdev);
0201 return ast_drm_thaw(ddev);
0202 }
0203
0204 static int ast_pm_poweroff(struct device *dev)
0205 {
0206 struct pci_dev *pdev = to_pci_dev(dev);
0207 struct drm_device *ddev = pci_get_drvdata(pdev);
0208
0209 return ast_drm_freeze(ddev);
0210 }
0211
0212 static const struct dev_pm_ops ast_pm_ops = {
0213 .suspend = ast_pm_suspend,
0214 .resume = ast_pm_resume,
0215 .freeze = ast_pm_freeze,
0216 .thaw = ast_pm_thaw,
0217 .poweroff = ast_pm_poweroff,
0218 .restore = ast_pm_resume,
0219 };
0220
0221 static struct pci_driver ast_pci_driver = {
0222 .name = DRIVER_NAME,
0223 .id_table = ast_pciidlist,
0224 .probe = ast_pci_probe,
0225 .remove = ast_pci_remove,
0226 .driver.pm = &ast_pm_ops,
0227 };
0228
0229 drm_module_pci_driver_if_modeset(ast_pci_driver, ast_modeset);
0230
0231 MODULE_AUTHOR(DRIVER_AUTHOR);
0232 MODULE_DESCRIPTION(DRIVER_DESC);
0233 MODULE_LICENSE("GPL and additional rights");