1 /*
2  * Copyright 2011-2016 The OpenChrome Project
3  *                     [https://www.freedesktop.org/wiki/Openchrome]
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sub license,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include "globals.h"
30 #include "via_driver.h"
31 
32 static void
viaMMIOEnable(ScrnInfoPtr pScrn)33 viaMMIOEnable(ScrnInfoPtr pScrn)
34 {
35     VIAPtr pVia = VIAPTR(pScrn);
36     vgaHWPtr hwp = VGAHWPTR(pScrn);
37 
38     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
39                         "Entered viaMMIOEnable.\n"));
40 
41     switch (pVia->Chipset) {
42         case VIA_CX700:
43         case VIA_K8M890:
44         case VIA_P4M900:
45         case VIA_VX800:
46         case VIA_VX855:
47         case VIA_VX900:
48             ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
49             break;
50         default:
51             if (pVia->IsSecondary)
52                 ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
53             else
54                 ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
55             break;
56     }
57 
58     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
59                         "Exiting viaMMIOEnable.\n"));
60 }
61 
62 static void
viaMMIODisable(ScrnInfoPtr pScrn)63 viaMMIODisable(ScrnInfoPtr pScrn)
64 {
65     VIAPtr pVia = VIAPTR(pScrn);
66     vgaHWPtr hwp = VGAHWPTR(pScrn);
67 
68     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
69                         "Entered viaMMIODisable.\n"));
70 
71     switch (pVia->Chipset) {
72         case VIA_CX700:
73         case VIA_K8M890:
74         case VIA_P4M900:
75         case VIA_VX800:
76         case VIA_VX855:
77         case VIA_VX900:
78             ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
79             break;
80         default:
81             ViaSeqMask(hwp, 0x1A, 0x00, 0x60);
82             break;
83     }
84 
85     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
86                         "Exiting viaMMIODisable.\n"));
87 }
88 
89 static Bool
viaMapMMIO(ScrnInfoPtr pScrn)90 viaMapMMIO(ScrnInfoPtr pScrn)
91 {
92     VIAPtr pVia = VIAPTR(pScrn);
93     vgaHWPtr hwp = VGAHWPTR(pScrn);
94     CARD8 val;
95 #ifdef HAVE_PCIACCESS
96     int err;
97 #else
98     unsigned char *tmp;
99 #endif
100 
101     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
102                         "Entered viaMapMMIO.\n"));
103 
104 #ifdef HAVE_PCIACCESS
105     pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
106 #else
107     pVia->MmioBase = pVia->PciInfo->memBase[1];
108 #endif
109 
110     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
111                 "Mapping MMIO at address 0x%lX with "
112                 "size %u KB.\n",
113                 pVia->MmioBase, VIA_MMIO_REGSIZE / 1024);
114 
115 #ifdef HAVE_PCIACCESS
116     err = pci_device_map_range(pVia->PciInfo,
117                                pVia->MmioBase,
118                                VIA_MMIO_REGSIZE, PCI_DEV_MAP_FLAG_WRITABLE,
119                                (void **)&pVia->MapBase);
120 
121     if (err) {
122         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
123                     "Unable to map MMIO.\n"
124                     "Error: %s (%u)\n",
125                     strerror(err), err);
126         goto fail;
127     }
128 #else
129     pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex,
130                                     VIDMEM_MMIO, pVia->PciTag,
131                                     pVia->MmioBase, VIA_MMIO_REGSIZE);
132     if (!pVia->MapBase) {
133         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
134                    "Unable to map MMIO.\n");
135         goto fail;
136     }
137 #endif
138 
139     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
140                "Mapping 2D Host BitBLT space at address 0x%lX with "
141                "size %u KB.\n",
142                pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE / 1024);
143 
144 #ifdef HAVE_PCIACCESS
145     err = pci_device_map_range(pVia->PciInfo,
146                                pVia->MmioBase + VIA_MMIO_BLTBASE,
147                                VIA_MMIO_BLTSIZE, PCI_DEV_MAP_FLAG_WRITABLE,
148                                (void **)&pVia->BltBase);
149 
150     if (err) {
151         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
152                     "Unable to map 2D Host BitBLT space.\n"
153                     "Error: %s (%u)\n",
154                     strerror(err), err);
155         goto fail;
156     }
157 #else
158     pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex,
159                                     VIDMEM_MMIO, pVia->PciTag,
160                                     pVia->MmioBase + VIA_MMIO_BLTBASE,
161                                     VIA_MMIO_BLTSIZE);
162     if (!pVia->BltBase) {
163         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
164                    "Unable to map 2D Host BitBLT space.\n");
165         goto fail;
166     }
167 #endif
168 
169     if (!(pVia->videoRambytes)) {
170         goto fail;
171     }
172 
173 #ifdef HAVE_PCIACCESS
174     if (pVia->Chipset == VIA_VX900) {
175         pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr;
176     } else {
177         pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
178     }
179 #else
180     if (pVia->Chipset == VIA_VX900) {
181         pVia->FrameBufferBase = pVia->PciInfo->memBase[2];
182     } else {
183         pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
184     }
185 #endif
186 
187     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
188                "Mapping the frame buffer at address 0x%lX with "
189                "size %lu KB.\n",
190                pVia->FrameBufferBase, pVia->videoRambytes / 1024);
191 
192 #ifdef HAVE_PCIACCESS
193     err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
194                                pVia->videoRambytes,
195                                (PCI_DEV_MAP_FLAG_WRITABLE |
196                                 PCI_DEV_MAP_FLAG_WRITE_COMBINE),
197                                (void **)&pVia->FBBase);
198     if (err) {
199         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
200                     "Unable to map the frame buffer.\n"
201                     "Error: %s (%u)\n",
202                     strerror(err), err);
203         goto fail;
204     }
205 #else
206     /*
207      * FIXME: This is a hack to get rid of offending wrongly sized
208      * MTRR regions set up by the VIA BIOS. Should be taken care of
209      * in the OS support layer.
210      */
211     tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
212                         pVia->FrameBufferBase, pVia->videoRambytes);
213     xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
214 
215     /*
216      * And, as if this wasn't enough, 2.6 series kernels don't
217      * remove MTRR regions on the first attempt. So try again.
218      */
219     tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
220                         pVia->FrameBufferBase, pVia->videoRambytes);
221     xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
222     /*
223      * End of hack.
224      */
225 
226     pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
227                                  pVia->PciTag, pVia->FrameBufferBase,
228                                  pVia->videoRambytes);
229 
230     if (!pVia->FBBase) {
231         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
232                    "Unable to map the frame buffer.\n");
233         goto fail;
234     }
235 #endif
236 
237     pVia->FBFreeStart = 0;
238     pVia->FBFreeEnd = pVia->videoRambytes;
239 
240     xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
241                "Frame buffer start address: %p, free start: 0x%X end: 0x%X\n",
242                pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd);
243 
244 #ifdef HAVE_PCIACCESS
245     if (pVia->Chipset == VIA_VX900) {
246         pScrn->memPhysBase = pVia->PciInfo->regions[2].base_addr;
247     } else {
248         pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr;
249     }
250 #else
251     if (pVia->Chipset == VIA_VX900) {
252         pScrn->memPhysBase = pVia->PciInfo->memBase[2];
253     } else {
254         pScrn->memPhysBase = pVia->PciInfo->memBase[0];
255     }
256 #endif
257 
258     pScrn->fbOffset = 0;
259     if (pVia->IsSecondary) {
260         pScrn->fbOffset = pScrn->videoRam << 10;
261     }
262 
263     /* MMIO for MPEG engine. */
264     pVia->MpegMapBase = pVia->MapBase + 0xc00;
265 
266     /* Set up MMIO vgaHW. */
267     vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
268 
269     val = hwp->readEnable(hwp);
270     hwp->writeEnable(hwp, val | 0x01);
271 
272     val = hwp->readMiscOut(hwp);
273     hwp->writeMiscOut(hwp, val | 0x01);
274 
275     /* Unlock extended I/O space. */
276     ViaSeqMask(hwp, 0x10, 0x01, 0x01);
277 
278     viaMMIOEnable(pScrn);
279 
280     vgaHWGetIOBase(hwp);
281 
282     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
283                         "Exiting viaMapMMIO.\n"));
284     return TRUE;
285 
286 fail:
287 
288 #ifdef HAVE_PCIACCESS
289     if (pVia->FBBase) {
290         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
291                                 pVia->videoRambytes);
292     }
293 
294     if (pVia->BltBase) {
295         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
296                                VIA_MMIO_BLTSIZE);
297     }
298 
299     if (pVia->MapBase) {
300         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
301                                VIA_MMIO_REGSIZE);
302     }
303 #else
304     if (pVia->FBBase) {
305         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
306                         pVia->videoRambytes);
307     }
308 
309     if (pVia->BltBase) {
310         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
311                         VIA_MMIO_BLTSIZE);
312     }
313 
314     if (pVia->MapBase) {
315         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
316                         VIA_MMIO_REGSIZE);
317     }
318 #endif
319 
320     pVia->FBBase = NULL;
321     pVia->BltBase = NULL;
322     pVia->MapBase = NULL;
323 
324     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
325                         "Exiting viaMapMMIO.\n"));
326     return FALSE;
327 }
328 
329 void
viaUnmapMMIO(ScrnInfoPtr pScrn)330 viaUnmapMMIO(ScrnInfoPtr pScrn)
331 {
332     VIAPtr pVia = VIAPTR(pScrn);
333 
334     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
335                         "Entered viaUnmapMMIO.\n"));
336 
337     viaMMIODisable(pScrn);
338 
339 #ifdef HAVE_PCIACCESS
340     if (pVia->FBBase) {
341         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
342                                pVia->videoRambytes);
343     }
344 
345     if (pVia->BltBase) {
346         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
347                                VIA_MMIO_BLTSIZE);
348     }
349 
350     if (pVia->MapBase) {
351         pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
352                                VIA_MMIO_REGSIZE);
353     }
354 #else
355     if (pVia->FBBase) {
356         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
357                         pVia->videoRambytes);
358     }
359 
360     if (pVia->BltBase) {
361         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
362                         VIA_MMIO_BLTSIZE);
363     }
364 
365     if (pVia->MapBase) {
366         xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
367                         VIA_MMIO_REGSIZE);
368     }
369 #endif
370 
371     pVia->FBBase = NULL;
372     pVia->BltBase = NULL;
373     pVia->MapBase = NULL;
374 
375     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
376                         "Exiting viaUnmapMMIO.\n"));
377 }
378 
379 /*
380  * Leftover from VIA's code.
381  */
382 static void
viaInitPCIe(VIAPtr pVia)383 viaInitPCIe(VIAPtr pVia)
384 {
385     VIASETREG(0x41c, 0x00100000);
386     VIASETREG(0x420, 0x680A0000);
387     VIASETREG(0x420, 0x02000000);
388 }
389 
390 static void
viaInitAGP(VIAPtr pVia)391 viaInitAGP(VIAPtr pVia)
392 {
393     VIASETREG(VIA_REG_TRANSET, 0x00100000);
394     VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
395     VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
396     VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
397     VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
398     VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
399     VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
400     VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
401     VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
402 
403     VIASETREG(VIA_REG_TRANSET, 0xfe020000);
404     VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
405 }
406 
407 /*
408  * Initialize the virtual command queue. Header-2 commands can be put
409  * in this queue for buffering. AFAIK it doesn't handle Header-1
410  * commands, which is really a pity, since it has to be idled before
411  * issuing a Header-1 command.
412  */
413 static void
viaEnableAGPVQ(VIAPtr pVia)414 viaEnableAGPVQ(VIAPtr pVia)
415 {
416    CARD32
417        vqStartAddr = pVia->VQStart,
418        vqEndAddr = pVia->VQEnd,
419        vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
420        vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
421        vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
422        ((vqEndAddr & 0xFF000000) >> 16),
423        vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
424 
425     VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
426     VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
427     VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
428     VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
429     VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
430     VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
431     VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
432     VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
433     VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
434     VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
435     VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
436     VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
437     VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
438     VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
439     VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
440     VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
441 
442     VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
443     VIASETREG(VIA_REG_TRANSPACE, vqStartL);
444     VIASETREG(VIA_REG_TRANSPACE, vqEndL);
445     VIASETREG(VIA_REG_TRANSPACE, vqLen);
446 }
447 
448 static void
viaEnablePCIeVQ(VIAPtr pVia)449 viaEnablePCIeVQ(VIAPtr pVia)
450 {
451    CARD32
452        vqStartAddr = pVia->VQStart,
453        vqEndAddr = pVia->VQEnd,
454        vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF),
455        vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF),
456        vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) |
457        ((vqEndAddr & 0xFF000000) >> 16),
458        vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3);
459 
460     VIASETREG(0x41c, 0x00100000);
461     VIASETREG(0x420, vqStartEndH);
462     VIASETREG(0x420, vqStartL);
463     VIASETREG(0x420, vqEndL);
464     VIASETREG(0x420, vqLen);
465     VIASETREG(0x420, 0x74301001);
466     VIASETREG(0x420, 0x00000000);
467 }
468 
469 /*
470  * Disable the virtual command queue.
471  */
472 void
viaDisableVQ(ScrnInfoPtr pScrn)473 viaDisableVQ(ScrnInfoPtr pScrn)
474 {
475     VIAPtr pVia = VIAPTR(pScrn);
476 
477     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
478                         "Entered viaDisableVQ.\n"));
479 
480     switch (pVia->Chipset) {
481     case VIA_K8M890:
482     case VIA_P4M900:
483     case VIA_VX800:
484     case VIA_VX855:
485     case VIA_VX900:
486         VIASETREG(0x41c, 0x00100000);
487         VIASETREG(0x420, 0x74301000);
488         break;
489     default:
490         VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
491         VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
492         VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
493         VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
494         VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
495         VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
496         break;
497     }
498 
499     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
500                         "Exiting viaDisableVQ.\n"));
501 }
502 
503 /*
504  * Initialize the 2D engine and set the 2D context mode to the
505  * current screen depth. Also enable the virtual queue.
506  */
507 static void
viaInitialize2DEngine(ScrnInfoPtr pScrn)508 viaInitialize2DEngine(ScrnInfoPtr pScrn)
509 {
510     VIAPtr pVia = VIAPTR(pScrn);
511     ViaTwodContext *tdc = &pVia->td;
512     int i;
513 
514     /* Initialize the 2D engine registers to reset the 2D engine. */
515     for (i = 0x04; i <= 0x40; i += 4) {
516         VIASETREG(i, 0x0);
517     }
518 
519     if (pVia->Chipset == VIA_VX800 ||
520         pVia->Chipset == VIA_VX855 ||
521         pVia->Chipset == VIA_VX900) {
522         for (i = 0x44; i <= 0x5c; i += 4) {
523             VIASETREG(i, 0x0);
524         }
525     }
526 
527     if (pVia->Chipset == VIA_VX900)
528     {
529         /*410 redefine 0x30 34 38*/
530         VIASETREG(0x60, 0x0); /*already useable here*/
531     }
532 
533     switch (pVia->Chipset) {
534         case VIA_K8M890:
535         case VIA_P4M900:
536         case VIA_VX800:
537         case VIA_VX855:
538         case VIA_VX900:
539             viaInitPCIe(pVia);
540             break;
541         default:
542             viaInitAGP(pVia);
543             break;
544     }
545 
546     if (pVia->VQStart != 0) {
547         switch (pVia->Chipset) {
548             case VIA_K8M890:
549             case VIA_P4M900:
550             case VIA_VX800:
551             case VIA_VX855:
552             case VIA_VX900:
553                 viaEnablePCIeVQ(pVia);
554                 break;
555             default:
556                 viaEnableAGPVQ(pVia);
557                 break;
558         }
559     } else {
560         viaDisableVQ(pScrn);
561     }
562 
563     viaAccelSetMode(pScrn->bitsPerPixel, tdc);
564 }
565 
566 static void
viaInitialize3DEngine(ScrnInfoPtr pScrn)567 viaInitialize3DEngine(ScrnInfoPtr pScrn)
568 {
569     VIAPtr pVia = VIAPTR(pScrn);
570     int i;
571 
572     VIASETREG(VIA_REG_TRANSET, 0x00010000);
573     for (i = 0; i <= 0x7D; i++)
574         VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
575 
576     VIASETREG(VIA_REG_TRANSET, 0x00020000);
577     for (i = 0; i <= 0x94; i++)
578         VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
579     VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
580 
581     VIASETREG(VIA_REG_TRANSET, 0x01020000);
582     for (i = 0; i <= 0x94; i++)
583         VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
584     VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
585 
586     VIASETREG(VIA_REG_TRANSET, 0xfe020000);
587     for (i = 0; i <= 0x03; i++)
588         VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
589 
590     VIASETREG(VIA_REG_TRANSET, 0x00030000);
591     for (i = 0; i <= 0xff; i++)
592         VIASETREG(VIA_REG_TRANSPACE, 0);
593 
594     VIASETREG(VIA_REG_TRANSET, 0x00100000);
595     VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
596     VIASETREG(VIA_REG_TRANSPACE, 0x10000002);
597     VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
598     VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
599     VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
600     VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
601     VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
602 
603     VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
604     if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3)
605         VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
606     else
607         VIASETREG(VIA_REG_TRANSPACE, 0x4000800f);
608     VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
609     VIASETREG(VIA_REG_TRANSPACE, 0x45080C04);
610     VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
611     VIASETREG(VIA_REG_TRANSPACE, 0x50000000);
612     VIASETREG(VIA_REG_TRANSPACE, 0x51000000);
613     VIASETREG(VIA_REG_TRANSPACE, 0x52000000);
614     VIASETREG(VIA_REG_TRANSPACE, 0x53000000);
615 
616     VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
617     VIASETREG(VIA_REG_TRANSPACE, 0x08000001);
618     VIASETREG(VIA_REG_TRANSPACE, 0x0A000183);
619     VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F);
620     VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B);
621     VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B);
622     VIASETREG(VIA_REG_TRANSPACE, 0x0E000000);
623     VIASETREG(VIA_REG_TRANSPACE, 0x0F000000);
624     VIASETREG(VIA_REG_TRANSPACE, 0x10000000);
625     VIASETREG(VIA_REG_TRANSPACE, 0x11000000);
626     VIASETREG(VIA_REG_TRANSPACE, 0x20000000);
627 }
628 
629 /*
630  * Acceleration initialization function. Sets up offscreen memory disposition,
631  * and initializes engines and acceleration method.
632  */
633 Bool
umsAccelInit(ScreenPtr pScreen)634 umsAccelInit(ScreenPtr pScreen)
635 {
636     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
637     VIAPtr pVia = VIAPTR(pScrn);
638     Bool ret = FALSE;
639 
640     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
641                         "Entered umsAccelInit.\n"));
642 
643     pVia->VQStart = 0;
644     pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM);
645     if (!pVia->vq_bo)
646         goto err;
647 
648     pVia->VQStart = pVia->vq_bo->offset;
649     pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size;
650 
651     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
652                         "Initializing the 2D engine.\n"));
653     viaInitialize2DEngine(pScrn);
654 
655     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
656                         "Initializing the 3D engine.\n"));
657     viaInitialize3DEngine(pScrn);
658 
659     pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
660     if (!pVia->exa_sync_bo)
661         goto err;
662 
663     /* Sync marker space. */
664     pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
665     if (!pVia->exa_sync_bo)
666         goto err;
667 
668     pVia->markerOffset = pVia->exa_sync_bo->offset;
669     pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo);
670     if (!pVia->markerBuf)
671         goto err;
672     pVia->curMarker = 0;
673     pVia->lastMarkerRead = 0;
674 
675 #ifdef HAVE_DRI
676     pVia->dBounce = NULL;
677     pVia->scratchAddr = NULL;
678 #endif /* HAVE_DRI */
679     ret = TRUE;
680 err:
681     if (!ret) {
682         if (pVia->markerBuf) {
683             drm_bo_unmap(pScrn, pVia->exa_sync_bo);
684             pVia->markerBuf = NULL;
685         }
686         if (pVia->exa_sync_bo)
687             drm_bo_free(pScrn, pVia->exa_sync_bo);
688         if (pVia->vq_bo)
689             drm_bo_free(pScrn, pVia->vq_bo);
690     }
691 
692     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
693                         "Exiting umsAccelInit.\n"));
694     return ret;
695 }
696 
697 Bool
umsCreate(ScrnInfoPtr pScrn)698 umsCreate(ScrnInfoPtr pScrn)
699 {
700     ScreenPtr pScreen = pScrn->pScreen;
701     VIAPtr pVia = VIAPTR(pScrn);
702     unsigned long offset;
703     BoxRec AvailFBArea;
704     Bool ret = TRUE;
705     long size;
706     int maxY;
707 
708 #ifdef HAVE_DRI
709     if (pVia->directRenderingType == DRI_1) {
710         pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2;
711         if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0)
712             pVia->driSize = pVia->maxDriSize * 1024;
713 
714         /* In the case of DRI we handle all VRAM by the DRI ioctls */
715         if (pVia->useEXA)
716             return TRUE;
717 
718         /* XAA has to use FBManager so we have to split the space with DRI */
719         maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
720     } else
721 #endif
722         maxY = pVia->FBFreeEnd / pVia->Bpl;
723 
724     /* FBManager can't handle more than 32767 scan lines */
725     if (maxY > 32767)
726         maxY = 32767;
727 
728     AvailFBArea.x1 = 0;
729     AvailFBArea.y1 = 0;
730     AvailFBArea.x2 = pScrn->displayWidth;
731     AvailFBArea.y2 = maxY;
732     pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl;
733 
734     /*
735      *   Initialization of the XFree86 framebuffer manager is done via
736      *   Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)
737      *   FullBox represents the area of the framebuffer that the manager
738      *   is allowed to manage. This is typically a box with a width
739      *   of pScrn->displayWidth and a height of as many lines as can be fit
740      *   within the total video memory
741      */
742     ret = xf86InitFBManager(pScreen, &AvailFBArea);
743     if (ret != TRUE)
744         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n");
745 
746     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
747             "Frame Buffer From (%d,%d) To (%d,%d)\n",
748             AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2));
749 
750     offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp;
751     size = pVia->FBFreeEnd / pVia->Bpp - offset;
752     if (size > 0)
753         xf86InitFBManagerLinear(pScreen, offset, size);
754 
755     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
756             "Using %d lines for offscreen memory.\n",
757             AvailFBArea.y2 - pScrn->virtualY));
758     return TRUE;
759 }
760 
761 Bool
umsPreInit(ScrnInfoPtr pScrn)762 umsPreInit(ScrnInfoPtr pScrn)
763 {
764     MessageType from = X_PROBED;
765     VIAPtr pVia = VIAPTR(pScrn);
766     CARD8 videoRam;
767     vgaHWPtr hwp;
768 #ifdef HAVE_PCIACCESS
769     struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3);
770     struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0);
771 #endif
772     int bMemSize = 0;
773 
774     if (!xf86LoadSubModule(pScrn, "vgahw"))
775         return FALSE;
776 
777     if (!vgaHWGetHWRec(pScrn))
778         return FALSE;
779 
780 #if 0
781     /* Here we can alter the number of registers saved and restored by the
782      * standard vgaHWSave and Restore routines.
783      */
784     vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX,
785                       VGA_NUM_ATTR);
786 #endif
787     hwp = VGAHWPTR(pScrn);
788 
789     switch (pVia->Chipset) {
790         case VIA_CLE266:
791 #ifdef HAVE_PCIACCESS
792             pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
793 #else
794             videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
795 #endif
796             pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
797             break;
798         case VIA_KM400:
799 #ifdef HAVE_PCIACCESS
800             /* P4M800 Host Bridge PCI Device ID */
801             if (DEVICE_ID(bridge) == 0x0296) {
802                 pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
803             } else {
804                 pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
805             }
806 #else
807             /* P4M800 Host Bridge PCI Device ID */
808             if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) {
809                 videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
810             } else {
811                 videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
812             }
813 #endif
814             pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
815             break;
816         case VIA_PM800:
817         case VIA_P4M800PRO:
818         case VIA_K8M800:
819 #ifdef HAVE_PCIACCESS
820             pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
821 #else
822             videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
823 #endif
824             pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
825             break;
826         case VIA_P4M890:
827         case VIA_K8M890:
828         case VIA_P4M900:
829         case VIA_CX700:
830         case VIA_VX800:
831         case VIA_VX855:
832         case VIA_VX900:
833 #ifdef HAVE_PCIACCESS
834             pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
835 #else
836             videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
837 #endif
838             pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12;
839             break;
840         default:
841             if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) {
842                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
843                            "Using old memory-detection method.\n");
844                 bMemSize = hwp->readSeq(hwp, 0x39);
845                 if (bMemSize > 16 && bMemSize <= 128)
846                     pScrn->videoRam = (bMemSize + 1) << 9;
847                 else if (bMemSize > 0 && bMemSize < 31)
848                     pScrn->videoRam = bMemSize << 12;
849                 else {
850                     from = X_DEFAULT;
851                     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
852                                "Memory size detection failed: using 16 MB.\n");
853                     pScrn->videoRam = 16 << 10;
854                 }
855             } else {
856                 from = X_DEFAULT;
857                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
858                            "No memory-detection done. Use VideoRAM option.\n");
859             }
860     }
861 
862     /*
863      * PCI BAR are limited to 256 MB.
864      */
865     if (pScrn->videoRam > (256 << 10)) {
866         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
867                     "Cannot use more than 256 MB of VRAM.\n");
868                     pScrn->videoRam = (256 << 10);
869     }
870 
871     if (from == X_PROBED) {
872         xf86DrvMsg(pScrn->scrnIndex, from,
873                    "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam);
874     }
875 
876     /* Split the FB for SAMM. */
877     /* FIXME: For now, split the FB into two equal sections.
878      * This should be user-adjustable via a config option. */
879     if (pVia->IsSecondary) {
880         DevUnion *pPriv;
881         VIAEntPtr pVIAEnt;
882         VIAPtr pVia1;
883 
884         pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex);
885         pVIAEnt = pPriv->ptr;
886         pScrn->videoRam = pScrn->videoRam >> 1;
887         pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam;
888         pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
889         pVia1->videoRambytes = pScrn->videoRam << 10;
890         pVia->FrameBufferBase += (pScrn->videoRam << 10);
891     }
892 
893     pVia->videoRambytes = pScrn->videoRam << 10;
894 
895     /* maybe throw in some more sanity checks here */
896 #ifndef HAVE_PCIACCESS
897     pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device,
898                           pVia->PciInfo->func);
899 #endif
900 
901     /* Map PCI hardware resources to the memory map. */
902     if (!viaMapMMIO(pScrn)) {
903         return FALSE;
904     }
905 
906     return TRUE;
907 }
908 
909 Bool
umsCrtcInit(ScrnInfoPtr pScrn)910 umsCrtcInit(ScrnInfoPtr pScrn)
911 {
912     drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL;
913     vgaHWPtr hwp = VGAHWPTR(pScrn);
914     VIAPtr pVia = VIAPTR(pScrn);
915 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
916     ClockRangePtr clockRanges;
917 #else
918     ClockRangesPtr clockRanges;
919 #endif
920     int max_pitch, max_height;
921     VIABIOSInfoPtr pBIOSInfo;
922     xf86CrtcPtr iga1, iga2;
923 
924     /* 3X5.3B through 3X5.3F are scratch pad registers. */
925     pVia->originalCR3B = hwp->readCrtc(hwp, 0x3B);
926     pVia->originalCR3C = hwp->readCrtc(hwp, 0x3C);
927     pVia->originalCR3D = hwp->readCrtc(hwp, 0x3D);
928     pVia->originalCR3E = hwp->readCrtc(hwp, 0x3E);
929     pVia->originalCR3F = hwp->readCrtc(hwp, 0x3F);
930 
931     /* Read memory bandwidth from registers. */
932     pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4;
933     DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
934                      "Detected MemClk %d\n", pVia->MemClk));
935     if (pVia->MemClk >= VIA_MEM_END) {
936         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
937                    "Unknown Memory clock: %d\n", pVia->MemClk);
938         pVia->MemClk = VIA_MEM_END - 1;
939     }
940     pBIOSInfo = pVia->pBIOSInfo;
941     pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn);
942 
943     if (pBIOSInfo->TVType == TVTYPE_NONE) {
944         /* Use jumper to determine TV type. */
945         if (hwp->readCrtc(hwp, 0x3B) & 0x02) {
946             pBIOSInfo->TVType = TVTYPE_PAL;
947             DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
948                              "Detected TV standard: PAL.\n"));
949         } else {
950             pBIOSInfo->TVType = TVTYPE_NTSC;
951             DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
952                              "Detected TV standard: NTSC.\n"));
953         }
954     }
955 
956     if (pVia->drmmode.hwcursor) {
957         if (!xf86LoadSubModule(pScrn, "ramdac"))
958             return FALSE;
959     }
960 
961     if (!xf86LoadSubModule(pScrn, "i2c"))
962         return FALSE;
963     else
964         ViaI2CInit(pScrn);
965 
966     if (!xf86LoadSubModule(pScrn, "ddc"))
967         return FALSE;
968 
969     /*
970      * Set up ClockRanges, which describe what clock ranges are
971      * available, and what sort of modes they can be used for.
972      */
973 
974 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
975     clockRanges = xnfalloc(sizeof(ClockRange));
976 #else
977     clockRanges = xnfalloc(sizeof(ClockRanges));
978 #endif
979     clockRanges->next = NULL;
980     clockRanges->minClock = 20000;
981     clockRanges->maxClock = 230000;
982 
983     clockRanges->clockIndex = -1;
984     clockRanges->interlaceAllowed = TRUE;
985     clockRanges->doubleScanAllowed = FALSE;
986     pScrn->clockRanges = clockRanges;
987 
988     /*
989      * Now handle the outputs
990      */
991     iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
992     if (!iga1_rec) {
993         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
994         return FALSE;
995     }
996 
997     iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs);
998     if (!iga1) {
999         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1000         free(iga1_rec);
1001         return FALSE;
1002     }
1003     iga1_rec->drmmode = &pVia->drmmode;
1004     iga1_rec->index = 0;
1005     iga1->driver_private = iga1_rec;
1006 
1007     iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
1008     if (!iga2_rec) {
1009         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
1010         xf86CrtcDestroy(iga1);
1011         return FALSE;
1012     }
1013 
1014     iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs);
1015     if (!iga2) {
1016         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1017         xf86CrtcDestroy(iga1);
1018         free(iga2_rec);
1019         return FALSE;
1020     }
1021     iga2_rec->drmmode = &pVia->drmmode;
1022     iga2_rec->index = 1;
1023     iga2->driver_private = iga2_rec;
1024 
1025     if (!pScrn->bitsPerPixel) {
1026         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1027                     "Detected bitsPerPixel to be 0 bit.\n");
1028         xf86CrtcDestroy(iga2);
1029         xf86CrtcDestroy(iga1);
1030         return FALSE;
1031     }
1032 
1033     /*
1034      * CLE266A:
1035      *   Max Line Pitch: 4080, (FB corruption when higher, driver problem?)
1036      *   Max Height: 4096 (and beyond)
1037      *
1038      * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited
1039      * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1).
1040      * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please.
1041      *
1042      * We should be able to limit the memory available for a mode to 32 MB,
1043      * but miScanLineWidth fails to catch this properly (apertureSize).
1044      */
1045     max_pitch = (8192 / ((pScrn->bitsPerPixel + 7) >> 3)) - (16 / ((pScrn->bitsPerPixel + 7) >> 3));
1046     max_height = 8192 / ((pScrn->bitsPerPixel + 7) >> 3);
1047 
1048     xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height);
1049 
1050     viaOutputDetect(pScrn);
1051 
1052     return TRUE;
1053 }
1054