a701d956325717fb2bf99f0fc93cc325388f209e
[linux-2.6-microblaze.git] / drivers / gpu / drm / mgag200 / mgag200_drv.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2012 Red Hat
4  *
5  * Authors: Matthew Garrett
6  *          Dave Airlie
7  */
8
9 #include <linux/console.h>
10 #include <linux/module.h>
11 #include <linux/pci.h>
12 #include <linux/vmalloc.h>
13
14 #include <drm/drm_aperture.h>
15 #include <drm/drm_drv.h>
16 #include <drm/drm_file.h>
17 #include <drm/drm_ioctl.h>
18 #include <drm/drm_pciids.h>
19
20 #include "mgag200_drv.h"
21
22 int mgag200_modeset = -1;
23 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
24 module_param_named(modeset, mgag200_modeset, int, 0400);
25
26 /*
27  * DRM driver
28  */
29
30 DEFINE_DRM_GEM_FOPS(mgag200_driver_fops);
31
32 static const struct drm_driver mgag200_driver = {
33         .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
34         .fops = &mgag200_driver_fops,
35         .name = DRIVER_NAME,
36         .desc = DRIVER_DESC,
37         .date = DRIVER_DATE,
38         .major = DRIVER_MAJOR,
39         .minor = DRIVER_MINOR,
40         .patchlevel = DRIVER_PATCHLEVEL,
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         struct pci_dev *pdev = to_pci_dev(dev->dev);
52         u32 option;
53         int ret;
54
55         ret = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
56         if (drm_WARN(dev, ret, "failed to read PCI config dword: %d\n", ret))
57                 return false;
58
59         return !!(option & PCI_MGA_OPTION_HARDPWMSK);
60 }
61
62 static int mgag200_regs_init(struct mga_device *mdev)
63 {
64         struct drm_device *dev = &mdev->base;
65         struct pci_dev *pdev = to_pci_dev(dev->dev);
66         u32 option, option2;
67         u8 crtcext3;
68
69         switch (mdev->type) {
70         case G200_PCI:
71         case G200_AGP:
72                 if (mgag200_has_sgram(mdev))
73                         option = 0x4049cd21;
74                 else
75                         option = 0x40499121;
76                 option2 = 0x00008000;
77                 break;
78         case G200_SE_A:
79         case G200_SE_B:
80                 option = 0x40049120;
81                 if (mgag200_has_sgram(mdev))
82                         option |= PCI_MGA_OPTION_HARDPWMSK;
83                 option2 = 0x00008000;
84                 break;
85         case G200_WB:
86         case G200_EW3:
87                 option = 0x41049120;
88                 option2 = 0x0000b000;
89                 break;
90         case G200_EV:
91                 option = 0x00000120;
92                 option2 = 0x0000b000;
93                 break;
94         case G200_EH:
95         case G200_EH3:
96                 option = 0x00000120;
97                 option2 = 0x0000b000;
98                 break;
99         default:
100                 option = 0;
101                 option2 = 0;
102         }
103
104         if (option)
105                 pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
106         if (option2)
107                 pci_write_config_dword(pdev, PCI_MGA_OPTION2, option2);
108
109         /* BAR 1 contains registers */
110         mdev->rmmio_base = pci_resource_start(pdev, 1);
111         mdev->rmmio_size = pci_resource_len(pdev, 1);
112
113         if (!devm_request_mem_region(dev->dev, mdev->rmmio_base,
114                                      mdev->rmmio_size, "mgadrmfb_mmio")) {
115                 drm_err(dev, "can't reserve mmio registers\n");
116                 return -ENOMEM;
117         }
118
119         mdev->rmmio = pcim_iomap(pdev, 1, 0);
120         if (mdev->rmmio == NULL)
121                 return -ENOMEM;
122
123         RREG_ECRT(0x03, crtcext3);
124         crtcext3 |= MGAREG_CRTCEXT3_MGAMODE;
125         WREG_ECRT(0x03, crtcext3);
126
127         return 0;
128 }
129
130 static void mgag200_g200_interpret_bios(struct mga_device *mdev,
131                                         const unsigned char *bios,
132                                         size_t size)
133 {
134         static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
135         static const unsigned int expected_length[6] = {
136                 0, 64, 64, 64, 128, 128
137         };
138         struct drm_device *dev = &mdev->base;
139         const unsigned char *pins;
140         unsigned int pins_len, version;
141         int offset;
142         int tmp;
143
144         /* Test for MATROX string. */
145         if (size < 45 + sizeof(matrox))
146                 return;
147         if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
148                 return;
149
150         /* Get the PInS offset. */
151         if (size < MGA_BIOS_OFFSET + 2)
152                 return;
153         offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
154
155         /* Get PInS data structure. */
156
157         if (size < offset + 6)
158                 return;
159         pins = bios + offset;
160         if (pins[0] == 0x2e && pins[1] == 0x41) {
161                 version = pins[5];
162                 pins_len = pins[2];
163         } else {
164                 version = 1;
165                 pins_len = pins[0] + (pins[1] << 8);
166         }
167
168         if (version < 1 || version > 5) {
169                 drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
170                 return;
171         }
172         if (pins_len != expected_length[version]) {
173                 drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
174                          pins_len, expected_length[version]);
175                 return;
176         }
177         if (size < offset + pins_len)
178                 return;
179
180         drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n",
181                     version, pins_len);
182
183         /* Extract the clock values */
184
185         switch (version) {
186         case 1:
187                 tmp = pins[24] + (pins[25] << 8);
188                 if (tmp)
189                         mdev->model.g200.pclk_max = tmp * 10;
190                 break;
191         case 2:
192                 if (pins[41] != 0xff)
193                         mdev->model.g200.pclk_max = (pins[41] + 100) * 1000;
194                 break;
195         case 3:
196                 if (pins[36] != 0xff)
197                         mdev->model.g200.pclk_max = (pins[36] + 100) * 1000;
198                 if (pins[52] & 0x20)
199                         mdev->model.g200.ref_clk = 14318;
200                 break;
201         case 4:
202                 if (pins[39] != 0xff)
203                         mdev->model.g200.pclk_max = pins[39] * 4 * 1000;
204                 if (pins[92] & 0x01)
205                         mdev->model.g200.ref_clk = 14318;
206                 break;
207         case 5:
208                 tmp = pins[4] ? 8000 : 6000;
209                 if (pins[123] != 0xff)
210                         mdev->model.g200.pclk_min = pins[123] * tmp;
211                 if (pins[38] != 0xff)
212                         mdev->model.g200.pclk_max = pins[38] * tmp;
213                 if (pins[110] & 0x01)
214                         mdev->model.g200.ref_clk = 14318;
215                 break;
216         default:
217                 break;
218         }
219 }
220
221 static void mgag200_g200_init_refclk(struct mga_device *mdev)
222 {
223         struct drm_device *dev = &mdev->base;
224         struct pci_dev *pdev = to_pci_dev(dev->dev);
225         unsigned char __iomem *rom;
226         unsigned char *bios;
227         size_t size;
228
229         mdev->model.g200.pclk_min = 50000;
230         mdev->model.g200.pclk_max = 230000;
231         mdev->model.g200.ref_clk = 27050;
232
233         rom = pci_map_rom(pdev, &size);
234         if (!rom)
235                 return;
236
237         bios = vmalloc(size);
238         if (!bios)
239                 goto out;
240         memcpy_fromio(bios, rom, size);
241
242         if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
243                 mgag200_g200_interpret_bios(mdev, bios, size);
244
245         drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
246                     mdev->model.g200.pclk_min, mdev->model.g200.pclk_max,
247                     mdev->model.g200.ref_clk);
248
249         vfree(bios);
250 out:
251         pci_unmap_rom(pdev, rom);
252 }
253
254 static void mgag200_g200se_init_unique_id(struct mga_device *mdev)
255 {
256         struct drm_device *dev = &mdev->base;
257
258         /* stash G200 SE model number for later use */
259         mdev->model.g200se.unique_rev_id = RREG32(0x1e24);
260
261         drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",
262                 mdev->model.g200se.unique_rev_id);
263 }
264
265 static int mgag200_device_init(struct mga_device *mdev, unsigned long flags)
266 {
267         struct drm_device *dev = &mdev->base;
268         int ret;
269
270         mdev->flags = mgag200_flags_from_driver_data(flags);
271         mdev->type = mgag200_type_from_driver_data(flags);
272
273         ret = mgag200_regs_init(mdev);
274         if (ret)
275                 return ret;
276
277         if (mdev->type == G200_PCI || mdev->type == G200_AGP)
278                 mgag200_g200_init_refclk(mdev);
279         else if (IS_G200_SE(mdev))
280                 mgag200_g200se_init_unique_id(mdev);
281
282         ret = mgag200_mm_init(mdev);
283         if (ret)
284                 return ret;
285
286         ret = mgag200_modeset_init(mdev);
287         if (ret) {
288                 drm_err(dev, "Fatal error during modeset init: %d\n", ret);
289                 return ret;
290         }
291
292         return 0;
293 }
294
295 static struct mga_device *
296 mgag200_device_create(struct pci_dev *pdev, unsigned long flags)
297 {
298         struct drm_device *dev;
299         struct mga_device *mdev;
300         int ret;
301
302         mdev = devm_drm_dev_alloc(&pdev->dev, &mgag200_driver,
303                                   struct mga_device, base);
304         if (IS_ERR(mdev))
305                 return mdev;
306         dev = &mdev->base;
307
308         pci_set_drvdata(pdev, dev);
309
310         ret = mgag200_device_init(mdev, flags);
311         if (ret)
312                 return ERR_PTR(ret);
313
314         return mdev;
315 }
316
317 /*
318  * PCI driver
319  */
320
321 static const struct pci_device_id mgag200_pciidlist[] = {
322         { PCI_VENDOR_ID_MATROX, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_PCI },
323         { PCI_VENDOR_ID_MATROX, 0x521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_AGP },
324         { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
325                 G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
326         { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
327         { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
328         { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
329         { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH },
330         { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER },
331         { PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 },
332         { PCI_VENDOR_ID_MATROX, 0x538, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH3 },
333         {0,}
334 };
335
336 MODULE_DEVICE_TABLE(pci, mgag200_pciidlist);
337
338 static int
339 mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
340 {
341         struct mga_device *mdev;
342         struct drm_device *dev;
343         int ret;
344
345         ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, "mgag200drmfb");
346         if (ret)
347                 return ret;
348
349         ret = pcim_enable_device(pdev);
350         if (ret)
351                 return ret;
352
353         mdev = mgag200_device_create(pdev, ent->driver_data);
354         if (IS_ERR(mdev))
355                 return PTR_ERR(mdev);
356         dev = &mdev->base;
357
358         ret = drm_dev_register(dev, ent->driver_data);
359         if (ret)
360                 return ret;
361
362         drm_fbdev_generic_setup(dev, 0);
363
364         return 0;
365 }
366
367 static void mgag200_pci_remove(struct pci_dev *pdev)
368 {
369         struct drm_device *dev = pci_get_drvdata(pdev);
370
371         drm_dev_unregister(dev);
372 }
373
374 static struct pci_driver mgag200_pci_driver = {
375         .name = DRIVER_NAME,
376         .id_table = mgag200_pciidlist,
377         .probe = mgag200_pci_probe,
378         .remove = mgag200_pci_remove,
379 };
380
381 static int __init mgag200_init(void)
382 {
383         if (vgacon_text_force() && mgag200_modeset == -1)
384                 return -EINVAL;
385
386         if (mgag200_modeset == 0)
387                 return -EINVAL;
388
389         return pci_register_driver(&mgag200_pci_driver);
390 }
391
392 static void __exit mgag200_exit(void)
393 {
394         pci_unregister_driver(&mgag200_pci_driver);
395 }
396
397 module_init(mgag200_init);
398 module_exit(mgag200_exit);
399
400 MODULE_AUTHOR(DRIVER_AUTHOR);
401 MODULE_DESCRIPTION(DRIVER_DESC);
402 MODULE_LICENSE("GPL");