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