forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/mgag200/mgag200_drv.c
....@@ -1,35 +1,326 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2012 Red Hat
3
- *
4
- * This file is subject to the terms and conditions of the GNU General
5
- * Public License version 2. See the file COPYING in the main
6
- * directory of this archive for more details.
74 *
85 * Authors: Matthew Garrett
96 * Dave Airlie
107 */
11
-#include <linux/module.h>
8
+
129 #include <linux/console.h>
13
-#include <drm/drmP.h>
10
+#include <linux/module.h>
11
+#include <linux/pci.h>
12
+#include <linux/vmalloc.h>
13
+
14
+#include <drm/drm_drv.h>
15
+#include <drm/drm_file.h>
16
+#include <drm/drm_ioctl.h>
17
+#include <drm/drm_pciids.h>
1418
1519 #include "mgag200_drv.h"
1620
17
-#include <drm/drm_pciids.h>
18
-
19
-/*
20
- * This is the generic driver code. This binds the driver to the drm core,
21
- * which then performs further device association and calls our graphics init
22
- * functions
23
- */
2421 int mgag200_modeset = -1;
25
-
2622 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
2723 module_param_named(modeset, mgag200_modeset, int, 0400);
2824
29
-static struct drm_driver driver;
25
+/*
26
+ * DRM driver
27
+ */
3028
31
-static const struct pci_device_id pciidlist[] = {
32
- { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
29
+DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
30
+
31
+static struct drm_driver mgag200_driver = {
32
+ .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
33
+ .fops = &mgag200_driver_fops,
34
+ .name = DRIVER_NAME,
35
+ .desc = DRIVER_DESC,
36
+ .date = DRIVER_DATE,
37
+ .major = DRIVER_MAJOR,
38
+ .minor = DRIVER_MINOR,
39
+ .patchlevel = DRIVER_PATCHLEVEL,
40
+ .gem_create_object = drm_gem_shmem_create_object_cached,
41
+ DRM_GEM_SHMEM_DRIVER_OPS,
42
+};
43
+
44
+/*
45
+ * DRM device
46
+ */
47
+
48
+static bool mgag200_has_sgram(struct mga_device *mdev)
49
+{
50
+ struct drm_device *dev = &mdev->base;
51
+ u32 option;
52
+ int ret;
53
+
54
+ ret = pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option);
55
+ if (drm_WARN(dev, ret, "failed to read PCI config dword: %d\n", ret))
56
+ return false;
57
+
58
+ return !!(option & PCI_MGA_OPTION_HARDPWMSK);
59
+}
60
+
61
+static int mgag200_regs_init(struct mga_device *mdev)
62
+{
63
+ struct drm_device *dev = &mdev->base;
64
+ u32 option, option2;
65
+ u8 crtcext3;
66
+
67
+ switch (mdev->type) {
68
+ case G200_PCI:
69
+ case G200_AGP:
70
+ if (mgag200_has_sgram(mdev))
71
+ option = 0x4049cd21;
72
+ else
73
+ option = 0x40499121;
74
+ option2 = 0x00008000;
75
+ break;
76
+ case G200_SE_A:
77
+ case G200_SE_B:
78
+ option = 0x40049120;
79
+ if (mgag200_has_sgram(mdev))
80
+ option |= PCI_MGA_OPTION_HARDPWMSK;
81
+ option2 = 0x00008000;
82
+ break;
83
+ case G200_WB:
84
+ case G200_EW3:
85
+ option = 0x41049120;
86
+ option2 = 0x0000b000;
87
+ break;
88
+ case G200_EV:
89
+ option = 0x00000120;
90
+ option2 = 0x0000b000;
91
+ break;
92
+ case G200_EH:
93
+ case G200_EH3:
94
+ option = 0x00000120;
95
+ option2 = 0x0000b000;
96
+ break;
97
+ default:
98
+ option = 0;
99
+ option2 = 0;
100
+ }
101
+
102
+ if (option)
103
+ pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
104
+ if (option2)
105
+ pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
106
+
107
+ /* BAR 1 contains registers */
108
+ mdev->rmmio_base = pci_resource_start(dev->pdev, 1);
109
+ mdev->rmmio_size = pci_resource_len(dev->pdev, 1);
110
+
111
+ if (!devm_request_mem_region(dev->dev, mdev->rmmio_base,
112
+ mdev->rmmio_size, "mgadrmfb_mmio")) {
113
+ drm_err(dev, "can't reserve mmio registers\n");
114
+ return -ENOMEM;
115
+ }
116
+
117
+ mdev->rmmio = pcim_iomap(dev->pdev, 1, 0);
118
+ if (mdev->rmmio == NULL)
119
+ return -ENOMEM;
120
+
121
+ RREG_ECRT(0x03, crtcext3);
122
+ crtcext3 |= MGAREG_CRTCEXT3_MGAMODE;
123
+ WREG_ECRT(0x03, crtcext3);
124
+
125
+ return 0;
126
+}
127
+
128
+static void mgag200_g200_interpret_bios(struct mga_device *mdev,
129
+ const unsigned char *bios,
130
+ size_t size)
131
+{
132
+ static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
133
+ static const unsigned int expected_length[6] = {
134
+ 0, 64, 64, 64, 128, 128
135
+ };
136
+ struct drm_device *dev = &mdev->base;
137
+ const unsigned char *pins;
138
+ unsigned int pins_len, version;
139
+ int offset;
140
+ int tmp;
141
+
142
+ /* Test for MATROX string. */
143
+ if (size < 45 + sizeof(matrox))
144
+ return;
145
+ if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
146
+ return;
147
+
148
+ /* Get the PInS offset. */
149
+ if (size < MGA_BIOS_OFFSET + 2)
150
+ return;
151
+ offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
152
+
153
+ /* Get PInS data structure. */
154
+
155
+ if (size < offset + 6)
156
+ return;
157
+ pins = bios + offset;
158
+ if (pins[0] == 0x2e && pins[1] == 0x41) {
159
+ version = pins[5];
160
+ pins_len = pins[2];
161
+ } else {
162
+ version = 1;
163
+ pins_len = pins[0] + (pins[1] << 8);
164
+ }
165
+
166
+ if (version < 1 || version > 5) {
167
+ drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
168
+ return;
169
+ }
170
+ if (pins_len != expected_length[version]) {
171
+ drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
172
+ pins_len, expected_length[version]);
173
+ return;
174
+ }
175
+ if (size < offset + pins_len)
176
+ return;
177
+
178
+ drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n",
179
+ version, pins_len);
180
+
181
+ /* Extract the clock values */
182
+
183
+ switch (version) {
184
+ case 1:
185
+ tmp = pins[24] + (pins[25] << 8);
186
+ if (tmp)
187
+ mdev->model.g200.pclk_max = tmp * 10;
188
+ break;
189
+ case 2:
190
+ if (pins[41] != 0xff)
191
+ mdev->model.g200.pclk_max = (pins[41] + 100) * 1000;
192
+ break;
193
+ case 3:
194
+ if (pins[36] != 0xff)
195
+ mdev->model.g200.pclk_max = (pins[36] + 100) * 1000;
196
+ if (pins[52] & 0x20)
197
+ mdev->model.g200.ref_clk = 14318;
198
+ break;
199
+ case 4:
200
+ if (pins[39] != 0xff)
201
+ mdev->model.g200.pclk_max = pins[39] * 4 * 1000;
202
+ if (pins[92] & 0x01)
203
+ mdev->model.g200.ref_clk = 14318;
204
+ break;
205
+ case 5:
206
+ tmp = pins[4] ? 8000 : 6000;
207
+ if (pins[123] != 0xff)
208
+ mdev->model.g200.pclk_min = pins[123] * tmp;
209
+ if (pins[38] != 0xff)
210
+ mdev->model.g200.pclk_max = pins[38] * tmp;
211
+ if (pins[110] & 0x01)
212
+ mdev->model.g200.ref_clk = 14318;
213
+ break;
214
+ default:
215
+ break;
216
+ }
217
+}
218
+
219
+static void mgag200_g200_init_refclk(struct mga_device *mdev)
220
+{
221
+ struct drm_device *dev = &mdev->base;
222
+ unsigned char __iomem *rom;
223
+ unsigned char *bios;
224
+ size_t size;
225
+
226
+ mdev->model.g200.pclk_min = 50000;
227
+ mdev->model.g200.pclk_max = 230000;
228
+ mdev->model.g200.ref_clk = 27050;
229
+
230
+ rom = pci_map_rom(dev->pdev, &size);
231
+ if (!rom)
232
+ return;
233
+
234
+ bios = vmalloc(size);
235
+ if (!bios)
236
+ goto out;
237
+ memcpy_fromio(bios, rom, size);
238
+
239
+ if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
240
+ mgag200_g200_interpret_bios(mdev, bios, size);
241
+
242
+ drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
243
+ mdev->model.g200.pclk_min, mdev->model.g200.pclk_max,
244
+ mdev->model.g200.ref_clk);
245
+
246
+ vfree(bios);
247
+out:
248
+ pci_unmap_rom(dev->pdev, rom);
249
+}
250
+
251
+static void mgag200_g200se_init_unique_id(struct mga_device *mdev)
252
+{
253
+ struct drm_device *dev = &mdev->base;
254
+
255
+ /* stash G200 SE model number for later use */
256
+ mdev->model.g200se.unique_rev_id = RREG32(0x1e24);
257
+
258
+ drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",
259
+ mdev->model.g200se.unique_rev_id);
260
+}
261
+
262
+static int mgag200_device_init(struct mga_device *mdev, unsigned long flags)
263
+{
264
+ struct drm_device *dev = &mdev->base;
265
+ int ret;
266
+
267
+ mdev->flags = mgag200_flags_from_driver_data(flags);
268
+ mdev->type = mgag200_type_from_driver_data(flags);
269
+
270
+ ret = mgag200_regs_init(mdev);
271
+ if (ret)
272
+ return ret;
273
+
274
+ if (mdev->type == G200_PCI || mdev->type == G200_AGP)
275
+ mgag200_g200_init_refclk(mdev);
276
+ else if (IS_G200_SE(mdev))
277
+ mgag200_g200se_init_unique_id(mdev);
278
+
279
+ ret = mgag200_mm_init(mdev);
280
+ if (ret)
281
+ return ret;
282
+
283
+ ret = mgag200_modeset_init(mdev);
284
+ if (ret) {
285
+ drm_err(dev, "Fatal error during modeset init: %d\n", ret);
286
+ return ret;
287
+ }
288
+
289
+ return 0;
290
+}
291
+
292
+static struct mga_device *
293
+mgag200_device_create(struct pci_dev *pdev, unsigned long flags)
294
+{
295
+ struct drm_device *dev;
296
+ struct mga_device *mdev;
297
+ int ret;
298
+
299
+ mdev = devm_drm_dev_alloc(&pdev->dev, &mgag200_driver,
300
+ struct mga_device, base);
301
+ if (IS_ERR(mdev))
302
+ return mdev;
303
+ dev = &mdev->base;
304
+
305
+ dev->pdev = pdev;
306
+ pci_set_drvdata(pdev, dev);
307
+
308
+ ret = mgag200_device_init(mdev, flags);
309
+ if (ret)
310
+ return ERR_PTR(ret);
311
+
312
+ return mdev;
313
+}
314
+
315
+/*
316
+ * PCI driver
317
+ */
318
+
319
+static const struct pci_device_id mgag200_pciidlist[] = {
320
+ { PCI_VENDOR_ID_MATROX, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_PCI },
321
+ { PCI_VENDOR_ID_MATROX, 0x521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_AGP },
322
+ { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
323
+ G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
33324 { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
34325 { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
35326 { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
....@@ -40,75 +331,47 @@
40331 {0,}
41332 };
42333
43
-MODULE_DEVICE_TABLE(pci, pciidlist);
334
+MODULE_DEVICE_TABLE(pci, mgag200_pciidlist);
44335
45
-static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev)
336
+static int
337
+mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
46338 {
47
- struct apertures_struct *ap;
48
- bool primary = false;
339
+ struct mga_device *mdev;
340
+ struct drm_device *dev;
341
+ int ret;
49342
50
- ap = alloc_apertures(1);
51
- if (!ap)
52
- return;
343
+ drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "mgag200drmfb");
53344
54
- ap->ranges[0].base = pci_resource_start(pdev, 0);
55
- ap->ranges[0].size = pci_resource_len(pdev, 0);
345
+ ret = pcim_enable_device(pdev);
346
+ if (ret)
347
+ return ret;
56348
57
-#ifdef CONFIG_X86
58
- primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
59
-#endif
60
- drm_fb_helper_remove_conflicting_framebuffers(ap, "mgag200drmfb", primary);
61
- kfree(ap);
349
+ mdev = mgag200_device_create(pdev, ent->driver_data);
350
+ if (IS_ERR(mdev))
351
+ return PTR_ERR(mdev);
352
+ dev = &mdev->base;
353
+
354
+ ret = drm_dev_register(dev, ent->driver_data);
355
+ if (ret)
356
+ return ret;
357
+
358
+ drm_fbdev_generic_setup(dev, 0);
359
+
360
+ return 0;
62361 }
63362
64
-
65
-static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
66
-{
67
- mgag200_kick_out_firmware_fb(pdev);
68
-
69
- return drm_get_pci_dev(pdev, ent, &driver);
70
-}
71
-
72
-static void mga_pci_remove(struct pci_dev *pdev)
363
+static void mgag200_pci_remove(struct pci_dev *pdev)
73364 {
74365 struct drm_device *dev = pci_get_drvdata(pdev);
75366
76
- drm_put_dev(dev);
367
+ drm_dev_unregister(dev);
77368 }
78
-
79
-static const struct file_operations mgag200_driver_fops = {
80
- .owner = THIS_MODULE,
81
- .open = drm_open,
82
- .release = drm_release,
83
- .unlocked_ioctl = drm_ioctl,
84
- .mmap = mgag200_mmap,
85
- .poll = drm_poll,
86
- .compat_ioctl = drm_compat_ioctl,
87
- .read = drm_read,
88
-};
89
-
90
-static struct drm_driver driver = {
91
- .driver_features = DRIVER_GEM | DRIVER_MODESET,
92
- .load = mgag200_driver_load,
93
- .unload = mgag200_driver_unload,
94
- .fops = &mgag200_driver_fops,
95
- .name = DRIVER_NAME,
96
- .desc = DRIVER_DESC,
97
- .date = DRIVER_DATE,
98
- .major = DRIVER_MAJOR,
99
- .minor = DRIVER_MINOR,
100
- .patchlevel = DRIVER_PATCHLEVEL,
101
-
102
- .gem_free_object_unlocked = mgag200_gem_free_object,
103
- .dumb_create = mgag200_dumb_create,
104
- .dumb_map_offset = mgag200_dumb_mmap_offset,
105
-};
106369
107370 static struct pci_driver mgag200_pci_driver = {
108371 .name = DRIVER_NAME,
109
- .id_table = pciidlist,
110
- .probe = mga_pci_probe,
111
- .remove = mga_pci_remove,
372
+ .id_table = mgag200_pciidlist,
373
+ .probe = mgag200_pci_probe,
374
+ .remove = mgag200_pci_remove,
112375 };
113376
114377 static int __init mgag200_init(void)