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