via_ums.c revision 4dc64ea9
1/*
2 * Copyright 2011-2015 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
34ViaMMIODisable(ScrnInfoPtr pScrn)
35{
36    VIAPtr pVia = VIAPTR(pScrn);
37    vgaHWPtr hwp = VGAHWPTR(pScrn);
38
39    switch (pVia->Chipset) {
40        case VIA_CX700:
41        case VIA_K8M890:
42        case VIA_P4M900:
43        case VIA_VX800:
44        case VIA_VX855:
45        case VIA_VX900:
46            ViaSeqMask(hwp, 0x1A, 0x00, 0x08);
47            break;
48        default:
49            ViaSeqMask(hwp, 0x1A, 0x00, 0x60);
50            break;
51    }
52}
53
54void
55VIAUnmapMMIO(ScrnInfoPtr pScrn)
56{
57    VIAPtr pVia = VIAPTR(pScrn);
58
59    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
60                        "Entered VIAUnmapMMIO.\n"));
61
62    ViaMMIODisable(pScrn);
63
64#ifdef HAVE_PCIACCESS
65    if (pVia->MapBase)
66        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase,
67                               VIA_MMIO_REGSIZE);
68
69    if (pVia->BltBase)
70        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase,
71                               VIA_MMIO_BLTSIZE);
72
73    if (pVia->FBBase)
74        pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase,
75                               pVia->videoRambytes);
76#else
77    if (pVia->MapBase)
78        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase,
79                        VIA_MMIO_REGSIZE);
80
81    if (pVia->BltBase)
82        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase,
83                        VIA_MMIO_BLTSIZE);
84
85    if (pVia->FBBase)
86        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase,
87                        pVia->videoRambytes);
88#endif
89
90    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
91                        "Exiting VIAUnmapMMIO.\n"));
92}
93
94static void
95ViaMMIOEnable(ScrnInfoPtr pScrn)
96{
97    VIAPtr pVia = VIAPTR(pScrn);
98    vgaHWPtr hwp = VGAHWPTR(pScrn);
99
100    switch (pVia->Chipset) {
101        case VIA_CX700:
102        case VIA_K8M890:
103        case VIA_P4M900:
104        case VIA_VX800:
105        case VIA_VX855:
106        case VIA_VX900:
107            ViaSeqMask(hwp, 0x1A, 0x08, 0x08);
108            break;
109        default:
110            if (pVia->IsSecondary)
111                ViaSeqMask(hwp, 0x1A, 0x38, 0x38);
112            else
113                ViaSeqMask(hwp, 0x1A, 0x68, 0x68);
114            break;
115    }
116}
117
118static Bool
119VIAMapMMIO(ScrnInfoPtr pScrn)
120{
121    VIAPtr pVia = VIAPTR(pScrn);
122
123#ifdef HAVE_PCIACCESS
124    pVia->MmioBase = pVia->PciInfo->regions[1].base_addr;
125    int err;
126#else
127    pVia->MmioBase = pVia->PciInfo->memBase[1];
128#endif
129
130    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapMMIO\n"));
131
132    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
133               "mapping MMIO @ 0x%lx with size 0x%x\n",
134               pVia->MmioBase, VIA_MMIO_REGSIZE);
135
136#ifdef HAVE_PCIACCESS
137    err = pci_device_map_range(pVia->PciInfo,
138                               pVia->MmioBase,
139                               VIA_MMIO_REGSIZE,
140                               PCI_DEV_MAP_FLAG_WRITABLE,
141                               (void **)&pVia->MapBase);
142
143    if (err) {
144        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
145                   "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
146        return FALSE;
147    }
148#else
149    pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
150                                  pVia->MmioBase, VIA_MMIO_REGSIZE);
151    if (!pVia->MapBase)
152        return FALSE;
153#endif
154
155    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
156               "mapping BitBlt MMIO @ 0x%lx with size 0x%x\n",
157               pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE);
158
159#ifdef HAVE_PCIACCESS
160    err = pci_device_map_range(pVia->PciInfo,
161                               pVia->MmioBase + VIA_MMIO_BLTBASE,
162                               VIA_MMIO_BLTSIZE,
163                               PCI_DEV_MAP_FLAG_WRITABLE,
164                               (void **)&pVia->BltBase);
165
166    if (err) {
167        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
168                   "Unable to map blt BAR. %s (%d)\n", strerror(err), err);
169        return FALSE;
170    }
171#else
172    pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
173                                  pVia->MmioBase + VIA_MMIO_BLTBASE,
174                                  VIA_MMIO_BLTSIZE);
175    if (!pVia->BltBase)
176        return FALSE;
177#endif
178
179    if (!pVia->MapBase || !pVia->BltBase) {
180        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
181                   "BitBlit could not be mapped.\n");
182        return FALSE;
183    }
184
185    /* Memory mapped IO for mpeg engine. */
186    pVia->MpegMapBase = pVia->MapBase + 0xc00;
187
188    /* Set up MMIO vgaHW. */
189    {
190        vgaHWPtr hwp = VGAHWPTR(pScrn);
191        CARD8 val;
192
193        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
194
195        val = hwp->readEnable(hwp);
196        hwp->writeEnable(hwp, val | 0x01);
197
198        val = hwp->readMiscOut(hwp);
199        hwp->writeMiscOut(hwp, val | 0x01);
200
201        /* Unlock extended IO space. */
202        ViaSeqMask(hwp, 0x10, 0x01, 0x01);
203
204        ViaMMIOEnable(pScrn);
205
206        vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
207
208        /* Unlock CRTC. */
209        ViaCrtcMask(hwp, 0x47, 0x00, 0x01);
210
211        vgaHWGetIOBase(hwp);
212    }
213    return TRUE;
214}
215
216static Bool
217VIAMapFB(ScrnInfoPtr pScrn)
218{
219    VIAPtr pVia = VIAPTR(pScrn);
220
221#ifdef HAVE_PCIACCESS
222    if (pVia->Chipset == VIA_VX900) {
223        pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr;
224    } else {
225        pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr;
226    }
227    int err;
228#else
229    if (pVia->Chipset == VIA_VX900) {
230        pVia->FrameBufferBase = pVia->PciInfo->memBase[2];
231    } else {
232        pVia->FrameBufferBase = pVia->PciInfo->memBase[0];
233    }
234#endif
235
236    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAMapFB\n"));
237    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
238               "mapping framebuffer @ 0x%lx with size 0x%lx\n",
239               pVia->FrameBufferBase, pVia->videoRambytes);
240
241    if (pVia->videoRambytes) {
242
243#ifndef HAVE_PCIACCESS
244        /*
245         * FIXME: This is a hack to get rid of offending wrongly sized
246         * MTRR regions set up by the VIA BIOS. Should be taken care of
247         * in the OS support layer.
248         */
249        unsigned char *tmp;
250
251        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
252                            pVia->FrameBufferBase, pVia->videoRambytes);
253        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
254
255        /*
256         * And, as if this wasn't enough, 2.6 series kernels don't
257         * remove MTRR regions on the first attempt. So try again.
258         */
259
260        tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag,
261                            pVia->FrameBufferBase, pVia->videoRambytes);
262        xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes);
263
264        /*
265         * End of hack.
266         */
267#endif
268
269#ifdef HAVE_PCIACCESS
270        err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase,
271                                   pVia->videoRambytes,
272                                   (PCI_DEV_MAP_FLAG_WRITABLE |
273                                    PCI_DEV_MAP_FLAG_WRITE_COMBINE),
274                                   (void **)&pVia->FBBase);
275        if (err) {
276            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
277                       "Unable to map mmio BAR. %s (%d)\n", strerror(err), err);
278            return FALSE;
279        }
280#else
281        pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
282                                     pVia->PciTag, pVia->FrameBufferBase,
283                                     pVia->videoRambytes);
284
285        if (!pVia->FBBase) {
286            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
287                       "Internal error: could not map framebuffer\n");
288            return FALSE;
289        }
290#endif
291
292        pVia->FBFreeStart = 0;
293        pVia->FBFreeEnd = pVia->videoRambytes;
294
295        xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
296                   "Frame buffer start: %p, free start: 0x%x end: 0x%x\n",
297                   pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd);
298    }
299
300#ifdef HAVE_PCIACCESS
301    pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr;
302#else
303    pScrn->memPhysBase = pVia->PciInfo->memBase[0];
304#endif
305    pScrn->fbOffset = 0;
306    if (pVia->IsSecondary)
307        pScrn->fbOffset = pScrn->videoRam << 10;
308
309    return TRUE;
310}
311
312/*
313 * Leftover from VIA's code.
314 */
315static void
316viaInitPCIe(VIAPtr pVia)
317{
318    VIASETREG(0x41c, 0x00100000);
319    VIASETREG(0x420, 0x680A0000);
320    VIASETREG(0x420, 0x02000000);
321}
322
323static void
324viaInitAgp(VIAPtr pVia)
325{
326    VIASETREG(VIA_REG_TRANSET, 0x00100000);
327    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
328    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
329    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
330    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
331    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
332    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
333    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
334    VIASETREG(VIA_REG_TRANSPACE, 0x7D000000);
335
336    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
337    VIASETREG(VIA_REG_TRANSPACE, 0x00000000);
338}
339
340/*
341 * Initialize the virtual command queue. Header-2 commands can be put
342 * in this queue for buffering. AFAIK it doesn't handle Header-1
343 * commands, which is really a pity, since it has to be idled before
344 * issuing a Header-1 command.
345 */
346static void
347viaEnableAgpVQ(VIAPtr pVia)
348{
349   CARD32
350       vqStartAddr = pVia->VQStart,
351       vqEndAddr = pVia->VQEnd,
352       vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF),
353       vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF),
354       vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) |
355       ((vqEndAddr & 0xFF000000) >> 16),
356       vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
357
358    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
359    VIASETREG(VIA_REG_TRANSPACE, 0x080003fe);
360    VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c);
361    VIASETREG(VIA_REG_TRANSPACE, 0x0b000260);
362    VIASETREG(VIA_REG_TRANSPACE, 0x0c000274);
363    VIASETREG(VIA_REG_TRANSPACE, 0x0d000264);
364    VIASETREG(VIA_REG_TRANSPACE, 0x0e000000);
365    VIASETREG(VIA_REG_TRANSPACE, 0x0f000020);
366    VIASETREG(VIA_REG_TRANSPACE, 0x1000027e);
367    VIASETREG(VIA_REG_TRANSPACE, 0x110002fe);
368    VIASETREG(VIA_REG_TRANSPACE, 0x200f0060);
369    VIASETREG(VIA_REG_TRANSPACE, 0x00000006);
370    VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
371    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
372    VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
373    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
374
375    VIASETREG(VIA_REG_TRANSPACE, vqStartEndH);
376    VIASETREG(VIA_REG_TRANSPACE, vqStartL);
377    VIASETREG(VIA_REG_TRANSPACE, vqEndL);
378    VIASETREG(VIA_REG_TRANSPACE, vqLen);
379}
380
381static void
382viaEnablePCIeVQ(VIAPtr pVia)
383{
384   CARD32
385       vqStartAddr = pVia->VQStart,
386       vqEndAddr = pVia->VQEnd,
387       vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF),
388       vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF),
389       vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) |
390       ((vqEndAddr & 0xFF000000) >> 16),
391       vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3);
392
393    VIASETREG(0x41c, 0x00100000);
394    VIASETREG(0x420, vqStartEndH);
395    VIASETREG(0x420, vqStartL);
396    VIASETREG(0x420, vqEndL);
397    VIASETREG(0x420, vqLen);
398    VIASETREG(0x420, 0x74301001);
399    VIASETREG(0x420, 0x00000000);
400}
401
402/*
403 * Disable the virtual command queue.
404 */
405void
406viaDisableVQ(ScrnInfoPtr pScrn)
407{
408    VIAPtr pVia = VIAPTR(pScrn);
409
410    switch (pVia->Chipset) {
411        case VIA_K8M890:
412        case VIA_P4M900:
413        case VIA_VX800:
414        case VIA_VX855:
415        case VIA_VX900:
416            VIASETREG(0x41c, 0x00100000);
417            VIASETREG(0x420, 0x74301000);
418            break;
419        default:
420            VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
421            VIASETREG(VIA_REG_TRANSPACE, 0x00000004);
422            VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
423            VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
424            VIASETREG(VIA_REG_TRANSPACE, 0x45080c04);
425            VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
426            break;
427    }
428}
429
430/*
431 * Initialize the 2D engine and set the 2D context mode to the
432 * current screen depth. Also enable the virtual queue.
433 */
434static void
435VIAInitialize2DEngine(ScrnInfoPtr pScrn)
436{
437    VIAPtr pVia = VIAPTR(pScrn);
438    ViaTwodContext *tdc = &pVia->td;
439    int i;
440
441    /* Initialize the 2D engine registers to reset the 2D engine. */
442    for (i = 0x04; i <= 0x40; i += 4) {
443        VIASETREG(i, 0x0);
444    }
445
446    if (pVia->Chipset == VIA_VX800 ||
447        pVia->Chipset == VIA_VX855 ||
448        pVia->Chipset == VIA_VX900) {
449        for (i = 0x44; i <= 0x5c; i += 4) {
450            VIASETREG(i, 0x0);
451        }
452    }
453
454    if (pVia->Chipset == VIA_VX900)
455    {
456        /*410 redefine 0x30 34 38*/
457        VIASETREG(0x60, 0x0); /*already useable here*/
458    }
459
460    switch (pVia->Chipset) {
461        case VIA_K8M890:
462        case VIA_P4M900:
463        case VIA_VX800:
464        case VIA_VX855:
465        case VIA_VX900:
466            viaInitPCIe(pVia);
467            break;
468        default:
469            viaInitAgp(pVia);
470            break;
471    }
472
473    if (pVia->VQStart != 0) {
474        switch (pVia->Chipset) {
475            case VIA_K8M890:
476            case VIA_P4M900:
477            case VIA_VX800:
478            case VIA_VX855:
479            case VIA_VX900:
480                viaEnablePCIeVQ(pVia);
481                break;
482            default:
483                viaEnableAgpVQ(pVia);
484                break;
485        }
486    } else {
487        viaDisableVQ(pScrn);
488    }
489
490    viaAccelSetMode(pScrn->bitsPerPixel, tdc);
491}
492
493static void
494VIAInitialize3DEngine(ScrnInfoPtr pScrn)
495{
496    VIAPtr pVia = VIAPTR(pScrn);
497    int i;
498
499    VIASETREG(VIA_REG_TRANSET, 0x00010000);
500    for (i = 0; i <= 0x7D; i++)
501        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
502
503    VIASETREG(VIA_REG_TRANSET, 0x00020000);
504    for (i = 0; i <= 0x94; i++)
505        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
506    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
507
508    VIASETREG(VIA_REG_TRANSET, 0x01020000);
509    for (i = 0; i <= 0x94; i++)
510        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
511    VIASETREG(VIA_REG_TRANSPACE, 0x82400000);
512
513    VIASETREG(VIA_REG_TRANSET, 0xfe020000);
514    for (i = 0; i <= 0x03; i++)
515        VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24);
516
517    VIASETREG(VIA_REG_TRANSET, 0x00030000);
518    for (i = 0; i <= 0xff; i++)
519        VIASETREG(VIA_REG_TRANSPACE, 0);
520
521    VIASETREG(VIA_REG_TRANSET, 0x00100000);
522    VIASETREG(VIA_REG_TRANSPACE, 0x00333004);
523    VIASETREG(VIA_REG_TRANSPACE, 0x10000002);
524    VIASETREG(VIA_REG_TRANSPACE, 0x60000000);
525    VIASETREG(VIA_REG_TRANSPACE, 0x61000000);
526    VIASETREG(VIA_REG_TRANSPACE, 0x62000000);
527    VIASETREG(VIA_REG_TRANSPACE, 0x63000000);
528    VIASETREG(VIA_REG_TRANSPACE, 0x64000000);
529
530    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
531    if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3)
532        VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f);
533    else
534        VIASETREG(VIA_REG_TRANSPACE, 0x4000800f);
535    VIASETREG(VIA_REG_TRANSPACE, 0x44000000);
536    VIASETREG(VIA_REG_TRANSPACE, 0x45080C04);
537    VIASETREG(VIA_REG_TRANSPACE, 0x46800408);
538    VIASETREG(VIA_REG_TRANSPACE, 0x50000000);
539    VIASETREG(VIA_REG_TRANSPACE, 0x51000000);
540    VIASETREG(VIA_REG_TRANSPACE, 0x52000000);
541    VIASETREG(VIA_REG_TRANSPACE, 0x53000000);
542
543    VIASETREG(VIA_REG_TRANSET, 0x00fe0000);
544    VIASETREG(VIA_REG_TRANSPACE, 0x08000001);
545    VIASETREG(VIA_REG_TRANSPACE, 0x0A000183);
546    VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F);
547    VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B);
548    VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B);
549    VIASETREG(VIA_REG_TRANSPACE, 0x0E000000);
550    VIASETREG(VIA_REG_TRANSPACE, 0x0F000000);
551    VIASETREG(VIA_REG_TRANSPACE, 0x10000000);
552    VIASETREG(VIA_REG_TRANSPACE, 0x11000000);
553    VIASETREG(VIA_REG_TRANSPACE, 0x20000000);
554}
555
556/*
557 * Acceleration initialization function. Sets up offscreen memory disposition,
558 * and initializes engines and acceleration method.
559 */
560Bool
561UMSAccelInit(ScreenPtr pScreen)
562{
563    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
564    VIAPtr pVia = VIAPTR(pScrn);
565    Bool ret = FALSE;
566
567    pVia->VQStart = 0;
568    pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM);
569    if (!pVia->vq_bo)
570        goto err;
571
572    pVia->VQStart = pVia->vq_bo->offset;
573    pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size;
574
575    VIAInitialize2DEngine(pScrn);
576    VIAInitialize3DEngine(pScrn);
577
578    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
579    if (!pVia->exa_sync_bo)
580        goto err;
581
582    /* Sync marker space. */
583    pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM);
584    if (!pVia->exa_sync_bo)
585        goto err;
586
587    pVia->markerOffset = pVia->exa_sync_bo->offset;
588    pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo);
589    if (!pVia->markerBuf)
590        goto err;
591    pVia->curMarker = 0;
592    pVia->lastMarkerRead = 0;
593
594#ifdef HAVE_DRI
595    pVia->dBounce = NULL;
596    pVia->scratchAddr = NULL;
597#endif /* HAVE_DRI */
598    ret = TRUE;
599err:
600    if (!ret) {
601        if (pVia->markerBuf) {
602            drm_bo_unmap(pScrn, pVia->exa_sync_bo);
603            pVia->markerBuf = NULL;
604        }
605        if (pVia->exa_sync_bo)
606            drm_bo_free(pScrn, pVia->exa_sync_bo);
607        if (pVia->vq_bo)
608            drm_bo_free(pScrn, pVia->vq_bo);
609    }
610    return ret;
611}
612
613Bool
614ums_create(ScrnInfoPtr pScrn)
615{
616    ScreenPtr pScreen = pScrn->pScreen;
617    VIAPtr pVia = VIAPTR(pScrn);
618    unsigned long offset;
619    BoxRec AvailFBArea;
620    Bool ret = TRUE;
621    long size;
622    int maxY;
623
624#ifdef HAVE_DRI
625    if (pVia->directRenderingType == DRI_1) {
626        pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2;
627        if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0)
628            pVia->driSize = pVia->maxDriSize * 1024;
629
630        /* In the case of DRI we handle all VRAM by the DRI ioctls */
631        if (pVia->useEXA)
632            return TRUE;
633
634        /* XAA has to use FBManager so we have to split the space with DRI */
635        maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl);
636    } else
637#endif
638        maxY = pVia->FBFreeEnd / pVia->Bpl;
639
640    /* FBManager can't handle more than 32767 scan lines */
641    if (maxY > 32767)
642        maxY = 32767;
643
644    AvailFBArea.x1 = 0;
645    AvailFBArea.y1 = 0;
646    AvailFBArea.x2 = pScrn->displayWidth;
647    AvailFBArea.y2 = maxY;
648    pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl;
649
650    /*
651     *   Initialization of the XFree86 framebuffer manager is done via
652     *   Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)
653     *   FullBox represents the area of the framebuffer that the manager
654     *   is allowed to manage. This is typically a box with a width
655     *   of pScrn->displayWidth and a height of as many lines as can be fit
656     *   within the total video memory
657     */
658    ret = xf86InitFBManager(pScreen, &AvailFBArea);
659    if (ret != TRUE)
660        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n");
661
662    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
663            "Frame Buffer From (%d,%d) To (%d,%d)\n",
664            AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2));
665
666    offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp;
667    size = pVia->FBFreeEnd / pVia->Bpp - offset;
668    if (size > 0)
669        xf86InitFBManagerLinear(pScreen, offset, size);
670
671    DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO,
672            "Using %d lines for offscreen memory.\n",
673            AvailFBArea.y2 - pScrn->virtualY));
674    return TRUE;
675}
676
677Bool
678UMSPreInit(ScrnInfoPtr pScrn)
679{
680    MessageType from = X_PROBED;
681    VIAPtr pVia = VIAPTR(pScrn);
682    CARD8 videoRam;
683    vgaHWPtr hwp;
684#ifdef HAVE_PCIACCESS
685    struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3);
686    struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0);
687#endif
688    int bMemSize = 0;
689
690    if (!xf86LoadSubModule(pScrn, "vgahw"))
691        return FALSE;
692
693    if (!vgaHWGetHWRec(pScrn))
694        return FALSE;
695
696#if 0
697    /* Here we can alter the number of registers saved and restored by the
698     * standard vgaHWSave and Restore routines.
699     */
700    vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX,
701                      VGA_NUM_ATTR);
702#endif
703    hwp = VGAHWPTR(pScrn);
704
705    switch (pVia->Chipset) {
706        case VIA_CLE266:
707#ifdef HAVE_PCIACCESS
708            pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
709#else
710            videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
711#endif
712            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
713            break;
714        case VIA_KM400:
715#ifdef HAVE_PCIACCESS
716            /* P4M800 Host Bridge PCI Device ID */
717            if (DEVICE_ID(bridge) == 0x0296) {
718                pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
719            } else {
720                pci_device_cfg_read_u8(bridge, &videoRam, 0xE1);
721            }
722#else
723            /* P4M800 Host Bridge PCI Device ID */
724            if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) {
725                videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
726            } else {
727                videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70;
728            }
729#endif
730            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
731            break;
732        case VIA_PM800:
733        case VIA_P4M800PRO:
734        case VIA_K8M800:
735#ifdef HAVE_PCIACCESS
736            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
737#else
738            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
739#endif
740            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10;
741            break;
742        case VIA_P4M890:
743        case VIA_K8M890:
744        case VIA_P4M900:
745        case VIA_CX700:
746        case VIA_VX800:
747        case VIA_VX855:
748        case VIA_VX900:
749#ifdef HAVE_PCIACCESS
750            pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1);
751#else
752            videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70;
753#endif
754            pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12;
755            break;
756        default:
757            if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) {
758                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
759                           "Using old memory-detection method.\n");
760                bMemSize = hwp->readSeq(hwp, 0x39);
761                if (bMemSize > 16 && bMemSize <= 128)
762                    pScrn->videoRam = (bMemSize + 1) << 9;
763                else if (bMemSize > 0 && bMemSize < 31)
764                    pScrn->videoRam = bMemSize << 12;
765                else {
766                    from = X_DEFAULT;
767                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
768                               "Memory size detection failed: using 16 MB.\n");
769                    pScrn->videoRam = 16 << 10;
770                }
771            } else {
772                from = X_DEFAULT;
773                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
774                           "No memory-detection done. Use VideoRAM option.\n");
775            }
776    }
777
778    /*
779     * PCI BAR are limited to 256 MB.
780     */
781    if (pScrn->videoRam > (256 << 10)) {
782        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
783                    "Cannot use more than 256 MB of VRAM.\n");
784                    pScrn->videoRam = (256 << 10);
785    }
786
787    if (from == X_PROBED) {
788        xf86DrvMsg(pScrn->scrnIndex, from,
789                   "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam);
790    }
791
792    /* Split the FB for SAMM. */
793    /* FIXME: For now, split the FB into two equal sections.
794     * This should be user-adjustable via a config option. */
795    if (pVia->IsSecondary) {
796        DevUnion *pPriv;
797        VIAEntPtr pVIAEnt;
798        VIAPtr pVia1;
799
800        pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex);
801        pVIAEnt = pPriv->ptr;
802        pScrn->videoRam = pScrn->videoRam >> 1;
803        pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam;
804        pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn);
805        pVia1->videoRambytes = pScrn->videoRam << 10;
806        pVia->FrameBufferBase += (pScrn->videoRam << 10);
807    }
808
809    pVia->videoRambytes = pScrn->videoRam << 10;
810
811    /* maybe throw in some more sanity checks here */
812#ifndef HAVE_PCIACCESS
813    pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device,
814                          pVia->PciInfo->func);
815#endif
816
817    /* Detect the amount of installed RAM */
818    if (!VIAMapMMIO(pScrn))
819        return FALSE;
820
821    if (!VIAMapFB(pScrn))
822        return FALSE;
823    return TRUE;
824}
825