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#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 %lu 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    vgaHWGetIOBase(hwp);
282
283    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
284                        "Exiting viaMapMMIO.\n"));
285    return TRUE;
286
287fail:
288
289#ifdef HAVE_PCIACCESS
290    if (pVia->FBBase) {
291        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
292                                pVia->videoRambytes);
293    }
294
295    if (pVia->BltBase) {
296        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
297                               VIA_MMIO_BLTSIZE);
298    }
299
300    if (pVia->MapBase) {
301        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
302                               VIA_MMIO_REGSIZE);
303    }
304#else
305    if (pVia->FBBase) {
306        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
307                        pVia->videoRambytes);
308    }
309
310    if (pVia->BltBase) {
311        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
312                        VIA_MMIO_BLTSIZE);
313    }
314
315    if (pVia->MapBase) {
316        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
317                        VIA_MMIO_REGSIZE);
318    }
319#endif
320
321    pVia->FBBase = NULL;
322    pVia->BltBase = NULL;
323    pVia->MapBase = NULL;
324
325    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
326                        "Exiting viaMapMMIO.\n"));
327    return FALSE;
328}
329
330void
331viaUnmapMMIO(ScrnInfoPtr pScrn)
332{
333    VIAPtr pVia = VIAPTR(pScrn);
334
335    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
336                        "Entered viaUnmapMMIO.\n"));
337
338    viaMMIODisable(pScrn);
339
340#ifdef HAVE_PCIACCESS
341    if (pVia->FBBase) {
342        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
343                               pVia->videoRambytes);
344    }
345
346    if (pVia->BltBase) {
347        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
348                               VIA_MMIO_BLTSIZE);
349    }
350
351    if (pVia->MapBase) {
352        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
353                               VIA_MMIO_REGSIZE);
354    }
355#else
356    if (pVia->FBBase) {
357        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
358                        pVia->videoRambytes);
359    }
360
361    if (pVia->BltBase) {
362        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
363                        VIA_MMIO_BLTSIZE);
364    }
365
366    if (pVia->MapBase) {
367        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
368                        VIA_MMIO_REGSIZE);
369    }
370#endif
371
372    pVia->FBBase = NULL;
373    pVia->BltBase = NULL;
374    pVia->MapBase = NULL;
375
376    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
377                        "Exiting viaUnmapMMIO.\n"));
378}
379
380/*
381 * Leftover from VIA's code.
382 */
383static void
384viaInitPCIe(VIAPtr pVia)
385{
386    VIASETREG(0x41c, 0x00100000);
387    VIASETREG(0x420, 0x680A0000);
388    VIASETREG(0x420, 0x02000000);
389}
390
391static void
392viaInitAGP(VIAPtr pVia)
393{
394    VIASETREG(VIA_REG_TRANSET, 0x00100000);
395    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
396    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
397    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
398    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
399    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
400    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
401    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
402    VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
403
404    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
405    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
406}
407
408/*
409 * Initialize the virtual command queue. Header-2 commands can be put
410 * in this queue for buffering. AFAIK it doesn't handle Header-1
411 * commands, which is really a pity, since it has to be idled before
412 * issuing a Header-1 command.
413 */
414static void
415viaEnableAGPVQ(VIAPtr pVia)
416{
417   CARD32
418       vqStartAddr = pVia->VQStart,
419       vqEndAddr = pVia->VQEnd,
420       vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
421       vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
422       vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
423       ((vqEndAddr & 0xFF000000) >> 16),
424       vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
425
426    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
427    VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
428    VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
429    VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
430    VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
431    VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
432    VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
433    VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
434    VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
435    VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
436    VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
437    VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
438    VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
439    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
440    VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
441    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
442
443    VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
444    VIASETREG(VIA_REG_TRANSPACE, vqStartL);
445    VIASETREG(VIA_REG_TRANSPACE, vqEndL);
446    VIASETREG(VIA_REG_TRANSPACE, vqLen);
447}
448
449static void
450viaEnablePCIeVQ(VIAPtr pVia)
451{
452   CARD32
453       vqStartAddr = pVia->VQStart,
454       vqEndAddr = pVia->VQEnd,
455       vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF),
456       vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF),
457       vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) |
458       ((vqEndAddr & 0xFF000000) >> 16),
459       vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3);
460
461    VIASETREG(0x41c, 0x00100000);
462    VIASETREG(0x420, vqStartEndH);
463    VIASETREG(0x420, vqStartL);
464    VIASETREG(0x420, vqEndL);
465    VIASETREG(0x420, vqLen);
466    VIASETREG(0x420, 0x74301001);
467    VIASETREG(0x420, 0x00000000);
468}
469
470/*
471 * Disable the virtual command queue.
472 */
473void
474viaDisableVQ(ScrnInfoPtr pScrn)
475{
476    VIAPtr pVia = VIAPTR(pScrn);
477
478    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
479                        "Entered viaDisableVQ.\n"));
480
481    switch (pVia->Chipset) {
482    case VIA_K8M890:
483    case VIA_P4M900:
484    case VIA_VX800:
485    case VIA_VX855:
486    case VIA_VX900:
487        VIASETREG(0x41c, 0x00100000);
488        VIASETREG(0x420, 0x74301000);
489        break;
490    default:
491        VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
492        VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
493        VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
494        VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
495        VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
496        VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
497        break;
498    }
499
500    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
501                        "Exiting viaDisableVQ.\n"));
502}
503
504/*
505 * Initialize the 2D engine and set the 2D context mode to the
506 * current screen depth. Also enable the virtual queue.
507 */
508static void
509viaInitialize2DEngine(ScrnInfoPtr pScrn)
510{
511    VIAPtr pVia = VIAPTR(pScrn);
512    ViaTwodContext *tdc = &pVia->td;
513    int i;
514
515    /* Initialize the 2D engine registers to reset the 2D engine. */
516    for (i = 0x04; i <= 0x40; i += 4) {
517        VIASETREG(i, 0x0);
518    }
519
520    if (pVia->Chipset == VIA_VX800 ||
521        pVia->Chipset == VIA_VX855 ||
522        pVia->Chipset == VIA_VX900) {
523        for (i = 0x44; i <= 0x5c; i += 4) {
524            VIASETREG(i, 0x0);
525        }
526    }
527
528    if (pVia->Chipset == VIA_VX900)
529    {
530        /*410 redefine 0x30 34 38*/
531        VIASETREG(0x60, 0x0); /*already useable here*/
532    }
533
534    switch (pVia->Chipset) {
535        case VIA_K8M890:
536        case VIA_P4M900:
537        case VIA_VX800:
538        case VIA_VX855:
539        case VIA_VX900:
540            viaInitPCIe(pVia);
541            break;
542        default:
543            viaInitAGP(pVia);
544            break;
545    }
546
547    if (pVia->VQStart != 0) {
548        switch (pVia->Chipset) {
549            case VIA_K8M890:
550            case VIA_P4M900:
551            case VIA_VX800:
552            case VIA_VX855:
553            case VIA_VX900:
554                viaEnablePCIeVQ(pVia);
555                break;
556            default:
557                viaEnableAGPVQ(pVia);
558                break;
559        }
560    } else {
561        viaDisableVQ(pScrn);
562    }
563
564    viaAccelSetMode(pScrn->bitsPerPixel, tdc);
565}
566
567static void
568viaInitialize3DEngine(ScrnInfoPtr pScrn)
569{
570    VIAPtr pVia = VIAPTR(pScrn);
571    int i;
572
573    VIASETREG(VIA_REG_TRANSET, 0x00010000);
574    for (i = 0; i <= 0x7D; i++)
575        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
576
577    VIASETREG(VIA_REG_TRANSET, 0x00020000);
578    for (i = 0; i <= 0x94; i++)
579        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
580    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
581
582    VIASETREG(VIA_REG_TRANSET, 0x01020000);
583    for (i = 0; i <= 0x94; i++)
584        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
585    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
586
587    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
588    for (i = 0; i <= 0x03; i++)
589        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
590
591    VIASETREG(VIA_REG_TRANSET, 0x00030000);
592    for (i = 0; i <= 0xff; i++)
593        VIASETREG(VIA_REG_TRANSPACE, 0);
594
595    VIASETREG(VIA_REG_TRANSET, 0x00100000);
596    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
597    VIASETREG(VIA_REG_TRANSPACE, 0x10000002);
598    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
599    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
600    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
601    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
602    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
603
604    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
605    if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3)
606        VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
607    else
608        VIASETREG(VIA_REG_TRANSPACE, 0x4000800f);
609    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
610    VIASETREG(VIA_REG_TRANSPACE, 0x45080C04);
611    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
612    VIASETREG(VIA_REG_TRANSPACE, 0x50000000);
613    VIASETREG(VIA_REG_TRANSPACE, 0x51000000);
614    VIASETREG(VIA_REG_TRANSPACE, 0x52000000);
615    VIASETREG(VIA_REG_TRANSPACE, 0x53000000);
616
617    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
618    VIASETREG(VIA_REG_TRANSPACE, 0x08000001);
619    VIASETREG(VIA_REG_TRANSPACE, 0x0A000183);
620    VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F);
621    VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B);
622    VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B);
623    VIASETREG(VIA_REG_TRANSPACE, 0x0E000000);
624    VIASETREG(VIA_REG_TRANSPACE, 0x0F000000);
625    VIASETREG(VIA_REG_TRANSPACE, 0x10000000);
626    VIASETREG(VIA_REG_TRANSPACE, 0x11000000);
627    VIASETREG(VIA_REG_TRANSPACE, 0x20000000);
628}
629
630/*
631 * Acceleration initialization function. Sets up offscreen memory disposition,
632 * and initializes engines and acceleration method.
633 */
634Bool
635umsAccelInit(ScreenPtr pScreen)
636{
637    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
638    VIAPtr pVia = VIAPTR(pScrn);
639    Bool ret = FALSE;
640
641    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
642                        "Entered umsAccelInit.\n"));
643
644    pVia->VQStart = 0;
645    pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM);
646    if (!pVia->vq_bo)
647        goto err;
648
649    pVia->VQStart = pVia->vq_bo->offset;
650    pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size;
651
652    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
653                        "Initializing the 2D engine.\n"));
654    viaInitialize2DEngine(pScrn);
655
656    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
657                        "Initializing the 3D engine.\n"));
658    viaInitialize3DEngine(pScrn);
659
660    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
661    if (!pVia->exa_sync_bo)
662        goto err;
663
664    /* Sync marker space. */
665    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
666    if (!pVia->exa_sync_bo)
667        goto err;
668
669    pVia->markerOffset = pVia->exa_sync_bo->offset;
670    pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo);
671    if (!pVia->markerBuf)
672        goto err;
673    pVia->curMarker = 0;
674    pVia->lastMarkerRead = 0;
675
676#ifdef HAVE_DRI
677    pVia->dBounce = NULL;
678    pVia->scratchAddr = NULL;
679#endif /* HAVE_DRI */
680    ret = TRUE;
681err:
682    if (!ret) {
683        if (pVia->markerBuf) {
684            drm_bo_unmap(pScrn, pVia->exa_sync_bo);
685            pVia->markerBuf = NULL;
686        }
687        if (pVia->exa_sync_bo)
688            drm_bo_free(pScrn, pVia->exa_sync_bo);
689        if (pVia->vq_bo)
690            drm_bo_free(pScrn, pVia->vq_bo);
691    }
692
693    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
694                        "Exiting umsAccelInit.\n"));
695    return ret;
696}
697
698Bool
699umsCreate(ScrnInfoPtr pScrn)
700{
701    ScreenPtr pScreen = pScrn->pScreen;
702    VIAPtr pVia = VIAPTR(pScrn);
703    unsigned long offset;
704    BoxRec AvailFBArea;
705    Bool ret = TRUE;
706    long size;
707    int maxY;
708
709#ifdef HAVE_DRI
710    if (pVia->directRenderingType == DRI_1) {
711        pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2;
712        if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0)
713            pVia->driSize = pVia->maxDriSize * 1024;
714
715        /* In the case of DRI we handle all VRAM by the DRI ioctls */
716        if (pVia->useEXA)
717            return TRUE;
718
719        /* XAA has to use FBManager so we have to split the space with DRI */
720        maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
721    } else
722#endif
723        maxY = pVia->FBFreeEnd / pVia->Bpl;
724
725    /* FBManager can't handle more than 32767 scan lines */
726    if (maxY > 32767)
727        maxY = 32767;
728
729    AvailFBArea.x1 = 0;
730    AvailFBArea.y1 = 0;
731    AvailFBArea.x2 = pScrn->displayWidth;
732    AvailFBArea.y2 = maxY;
733    pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl;
734
735    /*
736     *   Initialization of the XFree86 framebuffer manager is done via
737     *   Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)
738     *   FullBox represents the area of the framebuffer that the manager
739     *   is allowed to manage. This is typically a box with a width
740     *   of pScrn->displayWidth and a height of as many lines as can be fit
741     *   within the total video memory
742     */
743    ret = xf86InitFBManager(pScreen, &AvailFBArea);
744    if (ret != TRUE)
745        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n");
746
747    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
748            "Frame Buffer From (%d,%d) To (%d,%d)\n",
749            AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2));
750
751    offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp;
752    size = pVia->FBFreeEnd / pVia->Bpp - offset;
753    if (size > 0)
754        xf86InitFBManagerLinear(pScreen, offset, size);
755
756    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
757            "Using %d lines for offscreen memory.\n",
758            AvailFBArea.y2 - pScrn->virtualY));
759    return TRUE;
760}
761
762Bool
763umsPreInit(ScrnInfoPtr pScrn)
764{
765    MessageType from = X_PROBED;
766    VIAPtr pVia = VIAPTR(pScrn);
767    CARD8 videoRam;
768    vgaHWPtr hwp;
769#ifdef HAVE_PCIACCESS
770    struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3);
771    struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0);
772#endif
773    int bMemSize = 0;
774
775    if (!xf86LoadSubModule(pScrn, "vgahw"))
776        return FALSE;
777
778    if (!vgaHWGetHWRec(pScrn))
779        return FALSE;
780
781#if 0
782    /* Here we can alter the number of registers saved and restored by the
783     * standard vgaHWSave and Restore routines.
784     */
785    vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX,
786                      VGA_NUM_ATTR);
787#endif
788    hwp = VGAHWPTR(pScrn);
789
790    switch (pVia->Chipset) {
791        case VIA_CLE266:
792#ifdef HAVE_PCIACCESS
793            pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
794#else
795            videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
796#endif
797            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
798            break;
799        case VIA_KM400:
800#ifdef HAVE_PCIACCESS
801            /* P4M800 Host Bridge PCI Device ID */
802            if (DEVICE_ID(bridge) == 0x0296) {
803                pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
804            } else {
805                pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
806            }
807#else
808            /* P4M800 Host Bridge PCI Device ID */
809            if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) {
810                videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
811            } else {
812                videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
813            }
814#endif
815            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
816            break;
817        case VIA_PM800:
818        case VIA_P4M800PRO:
819        case VIA_K8M800:
820#ifdef HAVE_PCIACCESS
821            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
822#else
823            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
824#endif
825            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
826            break;
827        case VIA_P4M890:
828        case VIA_K8M890:
829        case VIA_P4M900:
830        case VIA_CX700:
831        case VIA_VX800:
832        case VIA_VX855:
833        case VIA_VX900:
834#ifdef HAVE_PCIACCESS
835            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
836#else
837            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
838#endif
839            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12;
840            break;
841        default:
842            if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) {
843                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
844                           "Using old memory-detection method.\n");
845                bMemSize = hwp->readSeq(hwp, 0x39);
846                if (bMemSize > 16 && bMemSize <= 128)
847                    pScrn->videoRam = (bMemSize + 1) << 9;
848                else if (bMemSize > 0 && bMemSize < 31)
849                    pScrn->videoRam = bMemSize << 12;
850                else {
851                    from = X_DEFAULT;
852                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
853                               "Memory size detection failed: using 16 MB.\n");
854                    pScrn->videoRam = 16 << 10;
855                }
856            } else {
857                from = X_DEFAULT;
858                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
859                           "No memory-detection done. Use VideoRAM option.\n");
860            }
861    }
862
863    /*
864     * PCI BAR are limited to 256 MB.
865     */
866    if (pScrn->videoRam > (256 << 10)) {
867        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
868                    "Cannot use more than 256 MB of VRAM.\n");
869                    pScrn->videoRam = (256 << 10);
870    }
871
872    if (from == X_PROBED) {
873        xf86DrvMsg(pScrn->scrnIndex, from,
874                   "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam);
875    }
876
877    /* Split the FB for SAMM. */
878    /* FIXME: For now, split the FB into two equal sections.
879     * This should be user-adjustable via a config option. */
880    if (pVia->IsSecondary) {
881        DevUnion *pPriv;
882        VIAEntPtr pVIAEnt;
883        VIAPtr pVia1;
884
885        pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex);
886        pVIAEnt = pPriv->ptr;
887        pScrn->videoRam = pScrn->videoRam >> 1;
888        pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam;
889        pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
890        pVia1->videoRambytes = pScrn->videoRam << 10;
891        pVia->FrameBufferBase += (pScrn->videoRam << 10);
892    }
893
894    pVia->videoRambytes = pScrn->videoRam << 10;
895
896    /* maybe throw in some more sanity checks here */
897#ifndef HAVE_PCIACCESS
898    pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device,
899                          pVia->PciInfo->func);
900#endif
901
902    /* Map PCI hardware resources to the memory map. */
903    if (!viaMapMMIO(pScrn)) {
904        return FALSE;
905    }
906
907    return TRUE;
908}
909
910Bool
911umsCrtcInit(ScrnInfoPtr pScrn)
912{
913    drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL;
914    vgaHWPtr hwp = VGAHWPTR(pScrn);
915    VIAPtr pVia = VIAPTR(pScrn);
916#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
917    ClockRangePtr clockRanges;
918#else
919    ClockRangesPtr clockRanges;
920#endif
921    int max_pitch, max_height;
922    VIABIOSInfoPtr pBIOSInfo;
923    xf86CrtcPtr iga1, iga2;
924
925    /* 3X5.3B through 3X5.3F are scratch pad registers. */
926    pVia->originalCR3B = hwp->readCrtc(hwp, 0x3B);
927    pVia->originalCR3C = hwp->readCrtc(hwp, 0x3C);
928    pVia->originalCR3D = hwp->readCrtc(hwp, 0x3D);
929    pVia->originalCR3E = hwp->readCrtc(hwp, 0x3E);
930    pVia->originalCR3F = hwp->readCrtc(hwp, 0x3F);
931
932    /* Read memory bandwidth from registers. */
933    pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4;
934    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
935                     "Detected MemClk %d\n", pVia->MemClk));
936    if (pVia->MemClk >= VIA_MEM_END) {
937        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
938                   "Unknown Memory clock: %d\n", pVia->MemClk);
939        pVia->MemClk = VIA_MEM_END - 1;
940    }
941    pBIOSInfo = pVia->pBIOSInfo;
942    pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn);
943
944    if (pBIOSInfo->TVType == TVTYPE_NONE) {
945        /* Use jumper to determine TV type. */
946        if (hwp->readCrtc(hwp, 0x3B) & 0x02) {
947            pBIOSInfo->TVType = TVTYPE_PAL;
948            DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
949                             "Detected TV standard: PAL.\n"));
950        } else {
951            pBIOSInfo->TVType = TVTYPE_NTSC;
952            DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
953                             "Detected TV standard: NTSC.\n"));
954        }
955    }
956
957    if (pVia->drmmode.hwcursor) {
958        if (!xf86LoadSubModule(pScrn, "ramdac"))
959            return FALSE;
960    }
961
962    if (!xf86LoadSubModule(pScrn, "i2c"))
963        return FALSE;
964    else
965        ViaI2CInit(pScrn);
966
967    if (!xf86LoadSubModule(pScrn, "ddc"))
968        return FALSE;
969
970    /*
971     * Set up ClockRanges, which describe what clock ranges are
972     * available, and what sort of modes they can be used for.
973     */
974
975#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0)
976    clockRanges = xnfalloc(sizeof(ClockRange));
977#else
978    clockRanges = xnfalloc(sizeof(ClockRanges));
979#endif
980    clockRanges->next = NULL;
981    clockRanges->minClock = 20000;
982    clockRanges->maxClock = 230000;
983
984    clockRanges->clockIndex = -1;
985    clockRanges->interlaceAllowed = TRUE;
986    clockRanges->doubleScanAllowed = FALSE;
987    pScrn->clockRanges = clockRanges;
988
989    /*
990     * Now handle the outputs
991     */
992    iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
993    if (!iga1_rec) {
994        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
995        return FALSE;
996    }
997
998    iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs);
999    if (!iga1) {
1000        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1001        free(iga1_rec);
1002        return FALSE;
1003    }
1004    iga1_rec->drmmode = &pVia->drmmode;
1005    iga1_rec->index = 0;
1006    iga1->driver_private = iga1_rec;
1007
1008    iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
1009    if (!iga2_rec) {
1010        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n");
1011        xf86CrtcDestroy(iga1);
1012        return FALSE;
1013    }
1014
1015    iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs);
1016    if (!iga2) {
1017        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n");
1018        xf86CrtcDestroy(iga1);
1019        free(iga2_rec);
1020        return FALSE;
1021    }
1022    iga2_rec->drmmode = &pVia->drmmode;
1023    iga2_rec->index = 1;
1024    iga2->driver_private = iga2_rec;
1025
1026    if (!pScrn->bitsPerPixel) {
1027        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1028                    "Detected bitsPerPixel to be 0 bit.\n");
1029        xf86CrtcDestroy(iga2);
1030        xf86CrtcDestroy(iga1);
1031        return FALSE;
1032    }
1033
1034    /*
1035     * CLE266A:
1036     *   Max Line Pitch: 4080, (FB corruption when higher, driver problem?)
1037     *   Max Height: 4096 (and beyond)
1038     *
1039     * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited
1040     * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1).
1041     * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please.
1042     *
1043     * We should be able to limit the memory available for a mode to 32 MB,
1044     * but miScanLineWidth fails to catch this properly (apertureSize).
1045     */
1046    max_pitch = (8192 / ((pScrn->bitsPerPixel + 7) >> 3)) - (16 / ((pScrn->bitsPerPixel + 7) >> 3));
1047    max_height = 8192 / ((pScrn->bitsPerPixel + 7) >> 3);
1048
1049    xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height);
1050
1051    viaOutputDetect(pScrn);
1052
1053    return TRUE;
1054}
1055