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