]>
Commit | Line | Data |
---|---|---|
c51669ea | 1 | // SPDX-License-Identifier: GPL-2.0-only |
414c4531 DA |
2 | /* |
3 | * Copyright 2012 Red Hat | |
4 | * | |
414c4531 DA |
5 | * Authors: Matthew Garrett |
6 | * Dave Airlie | |
7 | */ | |
9f397801 | 8 | |
414c4531 DA |
9 | #include <linux/module.h> |
10 | #include <linux/console.h> | |
414c4531 | 11 | |
9f397801 SR |
12 | #include <drm/drm_drv.h> |
13 | #include <drm/drm_file.h> | |
14 | #include <drm/drm_ioctl.h> | |
15 | #include <drm/drm_pci.h> | |
760285e7 | 16 | #include <drm/drm_pciids.h> |
414c4531 | 17 | |
9f397801 SR |
18 | #include "mgag200_drv.h" |
19 | ||
414c4531 DA |
20 | /* |
21 | * This is the generic driver code. This binds the driver to the drm core, | |
22 | * which then performs further device association and calls our graphics init | |
23 | * functions | |
24 | */ | |
25 | int mgag200_modeset = -1; | |
26 | ||
27 | MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); | |
28 | module_param_named(modeset, mgag200_modeset, int, 0400); | |
29 | ||
30 | static struct drm_driver driver; | |
31 | ||
9baa3c34 | 32 | static const struct pci_device_id pciidlist[] = { |
4adf0b49 | 33 | { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1591fadf | 34 | G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, |
414c4531 DA |
35 | { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, |
36 | { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, | |
37 | { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, | |
38 | { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH }, | |
39 | { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER }, | |
6d857c18 | 40 | { PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 }, |
f0493e65 | 41 | { PCI_VENDOR_ID_MATROX, 0x538, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH3 }, |
414c4531 DA |
42 | {0,} |
43 | }; | |
44 | ||
45 | MODULE_DEVICE_TABLE(pci, pciidlist); | |
46 | ||
08ef8e41 | 47 | |
56550d94 | 48 | static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
414c4531 | 49 | { |
35616a4a | 50 | drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "mgag200drmfb"); |
08ef8e41 | 51 | |
414c4531 DA |
52 | return drm_get_pci_dev(pdev, ent, &driver); |
53 | } | |
54 | ||
55 | static void mga_pci_remove(struct pci_dev *pdev) | |
56 | { | |
57 | struct drm_device *dev = pci_get_drvdata(pdev); | |
58 | ||
59 | drm_put_dev(dev); | |
60 | } | |
61 | ||
02f64b2d | 62 | DEFINE_DRM_GEM_FOPS(mgag200_driver_fops); |
414c4531 | 63 | |
1591fadf TZ |
64 | static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) |
65 | { | |
66 | return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; | |
67 | } | |
68 | ||
69 | int mgag200_driver_dumb_create(struct drm_file *file, | |
70 | struct drm_device *dev, | |
71 | struct drm_mode_create_dumb *args) | |
72 | { | |
73 | struct mga_device *mdev = dev->dev_private; | |
74 | unsigned long pg_align; | |
75 | ||
76 | if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) | |
77 | return -EINVAL; | |
78 | ||
79 | pg_align = 0ul; | |
80 | ||
81 | /* | |
82 | * Aligning scanout buffers to the size of the video ram forces | |
83 | * placement at offset 0. Works around a bug where HW does not | |
84 | * respect 'startadd' field. | |
85 | */ | |
86 | if (mgag200_pin_bo_at_0(mdev)) | |
87 | pg_align = PFN_UP(mdev->mc.vram_size); | |
88 | ||
89 | return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, | |
90 | pg_align, false, args); | |
91 | } | |
92 | ||
414c4531 | 93 | static struct drm_driver driver = { |
28185647 | 94 | .driver_features = DRIVER_GEM | DRIVER_MODESET, |
414c4531 DA |
95 | .load = mgag200_driver_load, |
96 | .unload = mgag200_driver_unload, | |
97 | .fops = &mgag200_driver_fops, | |
98 | .name = DRIVER_NAME, | |
99 | .desc = DRIVER_DESC, | |
100 | .date = DRIVER_DATE, | |
101 | .major = DRIVER_MAJOR, | |
102 | .minor = DRIVER_MINOR, | |
103 | .patchlevel = DRIVER_PATCHLEVEL, | |
1591fadf TZ |
104 | .debugfs_init = drm_vram_mm_debugfs_init, |
105 | .dumb_create = mgag200_driver_dumb_create, | |
106 | .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, | |
107 | .gem_prime_mmap = drm_gem_prime_mmap, | |
414c4531 DA |
108 | }; |
109 | ||
110 | static struct pci_driver mgag200_pci_driver = { | |
111 | .name = DRIVER_NAME, | |
112 | .id_table = pciidlist, | |
113 | .probe = mga_pci_probe, | |
114 | .remove = mga_pci_remove, | |
115 | }; | |
116 | ||
117 | static int __init mgag200_init(void) | |
118 | { | |
119 | if (vgacon_text_force() && mgag200_modeset == -1) | |
120 | return -EINVAL; | |
121 | ||
122 | if (mgag200_modeset == 0) | |
123 | return -EINVAL; | |
10631d72 DV |
124 | |
125 | return pci_register_driver(&mgag200_pci_driver); | |
414c4531 DA |
126 | } |
127 | ||
128 | static void __exit mgag200_exit(void) | |
129 | { | |
10631d72 | 130 | pci_unregister_driver(&mgag200_pci_driver); |
414c4531 DA |
131 | } |
132 | ||
133 | module_init(mgag200_init); | |
134 | module_exit(mgag200_exit); | |
135 | ||
136 | MODULE_AUTHOR(DRIVER_AUTHOR); | |
137 | MODULE_DESCRIPTION(DRIVER_DESC); | |
138 | MODULE_LICENSE("GPL"); |