via_ums.c revision 03bd066f
190b17f1bSmrg/* 203bd066fSmrg * Copyright 2011-2016 The OpenChrome Project 3963d66acSmrg * [http://www.freedesktop.org/wiki/Openchrome] 490b17f1bSmrg * 590b17f1bSmrg * Permission is hereby granted, free of charge, to any person obtaining a 690b17f1bSmrg * copy of this software and associated documentation files (the "Software"), 790b17f1bSmrg * to deal in the Software without restriction, including without limitation 890b17f1bSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 990b17f1bSmrg * and/or sell copies of the Software, and to permit persons to whom the 1090b17f1bSmrg * Software is furnished to do so, subject to the following conditions: 1190b17f1bSmrg * 1290b17f1bSmrg * The above copyright notice and this permission notice (including the 1390b17f1bSmrg * next paragraph) shall be included in all copies or substantial portions 1490b17f1bSmrg * of the Software. 1590b17f1bSmrg * 1690b17f1bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1790b17f1bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1890b17f1bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 1990b17f1bSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2090b17f1bSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2190b17f1bSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2290b17f1bSmrg * DEALINGS IN THE SOFTWARE. 2390b17f1bSmrg */ 2490b17f1bSmrg 2590b17f1bSmrg#ifdef HAVE_CONFIG_H 2690b17f1bSmrg#include "config.h" 2790b17f1bSmrg#endif 2890b17f1bSmrg 2990b17f1bSmrg#include "globals.h" 3090b17f1bSmrg#include "via_driver.h" 314dc64ea9Smrg#include "xf86fbman.h" 3290b17f1bSmrg 3390b17f1bSmrgstatic void 3403bd066fSmrgviaMMIOEnable(ScrnInfoPtr pScrn) 3590b17f1bSmrg{ 3690b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 3790b17f1bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 3890b17f1bSmrg 3903bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 4003bd066fSmrg "Entered viaMMIOEnable.\n")); 4103bd066fSmrg 4290b17f1bSmrg switch (pVia->Chipset) { 4390b17f1bSmrg case VIA_CX700: 44963d66acSmrg case VIA_K8M890: 4590b17f1bSmrg case VIA_P4M900: 4690b17f1bSmrg case VIA_VX800: 4790b17f1bSmrg case VIA_VX855: 4890b17f1bSmrg case VIA_VX900: 4903bd066fSmrg ViaSeqMask(hwp, 0x1A, 0x08, 0x08); 5090b17f1bSmrg break; 5190b17f1bSmrg default: 5203bd066fSmrg if (pVia->IsSecondary) 5303bd066fSmrg ViaSeqMask(hwp, 0x1A, 0x38, 0x38); 5403bd066fSmrg else 5503bd066fSmrg ViaSeqMask(hwp, 0x1A, 0x68, 0x68); 5690b17f1bSmrg break; 5790b17f1bSmrg } 5890b17f1bSmrg 59963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 6003bd066fSmrg "Exiting viaMMIOEnable.\n")); 6190b17f1bSmrg} 6290b17f1bSmrg 6390b17f1bSmrgstatic void 6403bd066fSmrgviaMMIODisable(ScrnInfoPtr pScrn) 6590b17f1bSmrg{ 6690b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 6790b17f1bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 6890b17f1bSmrg 6903bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 7003bd066fSmrg "Entered viaMMIODisable.\n")); 7103bd066fSmrg 7290b17f1bSmrg switch (pVia->Chipset) { 7390b17f1bSmrg case VIA_CX700: 74963d66acSmrg case VIA_K8M890: 7590b17f1bSmrg case VIA_P4M900: 7690b17f1bSmrg case VIA_VX800: 7790b17f1bSmrg case VIA_VX855: 7890b17f1bSmrg case VIA_VX900: 7903bd066fSmrg ViaSeqMask(hwp, 0x1A, 0x00, 0x08); 8090b17f1bSmrg break; 8190b17f1bSmrg default: 8203bd066fSmrg ViaSeqMask(hwp, 0x1A, 0x00, 0x60); 8390b17f1bSmrg break; 8490b17f1bSmrg } 8503bd066fSmrg 8603bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 8703bd066fSmrg "Exiting viaMMIODisable.\n")); 8890b17f1bSmrg} 8990b17f1bSmrg 9090b17f1bSmrgstatic Bool 9103bd066fSmrgviaMapMMIO(ScrnInfoPtr pScrn) 9290b17f1bSmrg{ 9390b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 9403bd066fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 9503bd066fSmrg CARD8 val; 9603bd066fSmrg#ifdef HAVE_PCIACCESS 9703bd066fSmrg int err; 9803bd066fSmrg#else 9903bd066fSmrg unsigned char *tmp; 10003bd066fSmrg#endif 10103bd066fSmrg 10203bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 10303bd066fSmrg "Entered viaMapMMIO.\n")); 10490b17f1bSmrg 10590b17f1bSmrg#ifdef HAVE_PCIACCESS 10690b17f1bSmrg pVia->MmioBase = pVia->PciInfo->regions[1].base_addr; 10790b17f1bSmrg#else 10890b17f1bSmrg pVia->MmioBase = pVia->PciInfo->memBase[1]; 10990b17f1bSmrg#endif 11090b17f1bSmrg 11190b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 11203bd066fSmrg "Mapping MMIO at address 0x%lX with " 11303bd066fSmrg "size %u KB.\n", 11403bd066fSmrg pVia->MmioBase, VIA_MMIO_REGSIZE / 1024); 11590b17f1bSmrg 11690b17f1bSmrg#ifdef HAVE_PCIACCESS 11790b17f1bSmrg err = pci_device_map_range(pVia->PciInfo, 11890b17f1bSmrg pVia->MmioBase, 11903bd066fSmrg VIA_MMIO_REGSIZE, PCI_DEV_MAP_FLAG_WRITABLE, 12090b17f1bSmrg (void **)&pVia->MapBase); 12190b17f1bSmrg 12290b17f1bSmrg if (err) { 12390b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 12403bd066fSmrg "Unable to map MMIO.\n" 12503bd066fSmrg "Error: %s (%u)\n", 12603bd066fSmrg strerror(err), err); 12703bd066fSmrg goto fail; 12890b17f1bSmrg } 12990b17f1bSmrg#else 13003bd066fSmrg pVia->MapBase = xf86MapPciMem(pScrn->scrnIndex, 13103bd066fSmrg VIDMEM_MMIO, pVia->PciTag, 13203bd066fSmrg pVia->MmioBase, VIA_MMIO_REGSIZE); 13303bd066fSmrg if (!pVia->MapBase) { 13403bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 13503bd066fSmrg "Unable to map MMIO.\n"); 13603bd066fSmrg goto fail; 13703bd066fSmrg } 13890b17f1bSmrg#endif 13990b17f1bSmrg 14090b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 14103bd066fSmrg "Mapping 2D Host BitBLT space at address 0x%lX with " 14203bd066fSmrg "size %u KB.\n", 14303bd066fSmrg pVia->MmioBase + VIA_MMIO_BLTBASE, VIA_MMIO_BLTSIZE / 1024); 14490b17f1bSmrg 14590b17f1bSmrg#ifdef HAVE_PCIACCESS 14690b17f1bSmrg err = pci_device_map_range(pVia->PciInfo, 14790b17f1bSmrg pVia->MmioBase + VIA_MMIO_BLTBASE, 14803bd066fSmrg VIA_MMIO_BLTSIZE, PCI_DEV_MAP_FLAG_WRITABLE, 14990b17f1bSmrg (void **)&pVia->BltBase); 15090b17f1bSmrg 15190b17f1bSmrg if (err) { 15290b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 15303bd066fSmrg "Unable to map 2D Host BitBLT space.\n" 15403bd066fSmrg "Error: %s (%u)\n", 15503bd066fSmrg strerror(err), err); 15603bd066fSmrg goto fail; 15790b17f1bSmrg } 15890b17f1bSmrg#else 15903bd066fSmrg pVia->BltBase = xf86MapPciMem(pScrn->scrnIndex, 16003bd066fSmrg VIDMEM_MMIO, pVia->PciTag, 16103bd066fSmrg pVia->MmioBase + VIA_MMIO_BLTBASE, 16203bd066fSmrg VIA_MMIO_BLTSIZE); 16303bd066fSmrg if (!pVia->BltBase) { 16490b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 16503bd066fSmrg "Unable to map 2D Host BitBLT space.\n"); 16603bd066fSmrg goto fail; 16790b17f1bSmrg } 16803bd066fSmrg#endif 16990b17f1bSmrg 17003bd066fSmrg if (!(pVia->videoRambytes)) { 17103bd066fSmrg goto fail; 17203bd066fSmrg } 17390b17f1bSmrg 17403bd066fSmrg#ifdef HAVE_PCIACCESS 17503bd066fSmrg if (pVia->Chipset == VIA_VX900) { 17603bd066fSmrg pVia->FrameBufferBase = pVia->PciInfo->regions[2].base_addr; 17703bd066fSmrg } else { 17803bd066fSmrg pVia->FrameBufferBase = pVia->PciInfo->regions[0].base_addr; 17903bd066fSmrg } 18003bd066fSmrg#else 18103bd066fSmrg if (pVia->Chipset == VIA_VX900) { 18203bd066fSmrg pVia->FrameBufferBase = pVia->PciInfo->memBase[2]; 18303bd066fSmrg } else { 18403bd066fSmrg pVia->FrameBufferBase = pVia->PciInfo->memBase[0]; 18503bd066fSmrg } 18603bd066fSmrg#endif 18790b17f1bSmrg 18803bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 18903bd066fSmrg "Mapping the frame buffer at address 0x%lX with " 19003bd066fSmrg "size %u KB.\n", 19103bd066fSmrg pVia->FrameBufferBase, pVia->videoRambytes / 1024); 19290b17f1bSmrg 19303bd066fSmrg#ifdef HAVE_PCIACCESS 19403bd066fSmrg err = pci_device_map_range(pVia->PciInfo, pVia->FrameBufferBase, 19503bd066fSmrg pVia->videoRambytes, 19603bd066fSmrg (PCI_DEV_MAP_FLAG_WRITABLE | 19703bd066fSmrg PCI_DEV_MAP_FLAG_WRITE_COMBINE), 19803bd066fSmrg (void **)&pVia->FBBase); 19903bd066fSmrg if (err) { 20003bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 20103bd066fSmrg "Unable to map the frame buffer.\n" 20203bd066fSmrg "Error: %s (%u)\n", 20303bd066fSmrg strerror(err), err); 20403bd066fSmrg goto fail; 20503bd066fSmrg } 20603bd066fSmrg#else 20703bd066fSmrg /* 20803bd066fSmrg * FIXME: This is a hack to get rid of offending wrongly sized 20903bd066fSmrg * MTRR regions set up by the VIA BIOS. Should be taken care of 21003bd066fSmrg * in the OS support layer. 21103bd066fSmrg */ 21203bd066fSmrg tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 21303bd066fSmrg pVia->FrameBufferBase, pVia->videoRambytes); 21403bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 21590b17f1bSmrg 21603bd066fSmrg /* 21703bd066fSmrg * And, as if this wasn't enough, 2.6 series kernels don't 21803bd066fSmrg * remove MTRR regions on the first attempt. So try again. 21903bd066fSmrg */ 22003bd066fSmrg tmp = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, pVia->PciTag, 22103bd066fSmrg pVia->FrameBufferBase, pVia->videoRambytes); 22203bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) tmp, pVia->videoRambytes); 22303bd066fSmrg /* 22403bd066fSmrg * End of hack. 22503bd066fSmrg */ 22690b17f1bSmrg 22703bd066fSmrg pVia->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 22803bd066fSmrg pVia->PciTag, pVia->FrameBufferBase, 22903bd066fSmrg pVia->videoRambytes); 23090b17f1bSmrg 23103bd066fSmrg if (!pVia->FBBase) { 23203bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 23303bd066fSmrg "Unable to map the frame buffer.\n"); 23403bd066fSmrg goto fail; 23590b17f1bSmrg } 23603bd066fSmrg#endif 23790b17f1bSmrg 23803bd066fSmrg pVia->FBFreeStart = 0; 23903bd066fSmrg pVia->FBFreeEnd = pVia->videoRambytes; 24003bd066fSmrg 24103bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 24203bd066fSmrg "Frame buffer start address: %p, free start: 0x%X end: 0x%X\n", 24303bd066fSmrg pVia->FBBase, pVia->FBFreeStart, pVia->FBFreeEnd); 24490b17f1bSmrg 24590b17f1bSmrg#ifdef HAVE_PCIACCESS 24690b17f1bSmrg if (pVia->Chipset == VIA_VX900) { 24703bd066fSmrg pScrn->memPhysBase = pVia->PciInfo->regions[2].base_addr; 24890b17f1bSmrg } else { 24903bd066fSmrg pScrn->memPhysBase = pVia->PciInfo->regions[0].base_addr; 25090b17f1bSmrg } 25190b17f1bSmrg#else 25290b17f1bSmrg if (pVia->Chipset == VIA_VX900) { 25303bd066fSmrg pScrn->memPhysBase = pVia->PciInfo->memBase[2]; 25490b17f1bSmrg } else { 25503bd066fSmrg pScrn->memPhysBase = pVia->PciInfo->memBase[0]; 25690b17f1bSmrg } 25790b17f1bSmrg#endif 25890b17f1bSmrg 25903bd066fSmrg pScrn->fbOffset = 0; 26003bd066fSmrg if (pVia->IsSecondary) { 26103bd066fSmrg pScrn->fbOffset = pScrn->videoRam << 10; 26203bd066fSmrg } 26390b17f1bSmrg 26403bd066fSmrg /* MMIO for MPEG engine. */ 26503bd066fSmrg pVia->MpegMapBase = pVia->MapBase + 0xc00; 26690b17f1bSmrg 26703bd066fSmrg /* Set up MMIO vgaHW. */ 26803bd066fSmrg vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000); 26903bd066fSmrg 27003bd066fSmrg val = hwp->readEnable(hwp); 27103bd066fSmrg hwp->writeEnable(hwp, val | 0x01); 27203bd066fSmrg 27303bd066fSmrg val = hwp->readMiscOut(hwp); 27403bd066fSmrg hwp->writeMiscOut(hwp, val | 0x01); 27503bd066fSmrg 27603bd066fSmrg /* Unlock extended I/O space. */ 27703bd066fSmrg ViaSeqMask(hwp, 0x10, 0x01, 0x01); 27803bd066fSmrg 27903bd066fSmrg viaMMIOEnable(pScrn); 28003bd066fSmrg 28103bd066fSmrg /* Unlock CRTC. */ 28203bd066fSmrg ViaCrtcMask(hwp, 0x47, 0x00, 0x01); 28303bd066fSmrg 28403bd066fSmrg vgaHWGetIOBase(hwp); 28503bd066fSmrg 28603bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 28703bd066fSmrg "Exiting viaMapMMIO.\n")); 28803bd066fSmrg return TRUE; 28903bd066fSmrg 29003bd066fSmrgfail: 29190b17f1bSmrg 29290b17f1bSmrg#ifdef HAVE_PCIACCESS 29303bd066fSmrg if (pVia->FBBase) { 29403bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 29503bd066fSmrg pVia->videoRambytes); 29603bd066fSmrg } 29703bd066fSmrg 29803bd066fSmrg if (pVia->BltBase) { 29903bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 30003bd066fSmrg VIA_MMIO_BLTSIZE); 30103bd066fSmrg } 30203bd066fSmrg 30303bd066fSmrg if (pVia->MapBase) { 30403bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 30503bd066fSmrg VIA_MMIO_REGSIZE); 30603bd066fSmrg } 30790b17f1bSmrg#else 30803bd066fSmrg if (pVia->FBBase) { 30903bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 31003bd066fSmrg pVia->videoRambytes); 31103bd066fSmrg } 31290b17f1bSmrg 31303bd066fSmrg if (pVia->BltBase) { 31403bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 31503bd066fSmrg VIA_MMIO_BLTSIZE); 31603bd066fSmrg } 31703bd066fSmrg 31803bd066fSmrg if (pVia->MapBase) { 31903bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 32003bd066fSmrg VIA_MMIO_REGSIZE); 32103bd066fSmrg } 32290b17f1bSmrg#endif 32390b17f1bSmrg 32403bd066fSmrg pVia->FBBase = NULL; 32503bd066fSmrg pVia->BltBase = NULL; 32603bd066fSmrg pVia->MapBase = NULL; 32790b17f1bSmrg 32803bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 32903bd066fSmrg "Exiting viaMapMMIO.\n")); 33003bd066fSmrg return FALSE; 33103bd066fSmrg} 33203bd066fSmrg 33303bd066fSmrgvoid 33403bd066fSmrgviaUnmapMMIO(ScrnInfoPtr pScrn) 33503bd066fSmrg{ 33603bd066fSmrg VIAPtr pVia = VIAPTR(pScrn); 33703bd066fSmrg 33803bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 33903bd066fSmrg "Entered viaUnmapMMIO.\n")); 34003bd066fSmrg 34103bd066fSmrg viaMMIODisable(pScrn); 34290b17f1bSmrg 34390b17f1bSmrg#ifdef HAVE_PCIACCESS 34403bd066fSmrg if (pVia->FBBase) { 34503bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 34603bd066fSmrg pVia->videoRambytes); 34703bd066fSmrg } 34803bd066fSmrg 34903bd066fSmrg if (pVia->BltBase) { 35003bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 35103bd066fSmrg VIA_MMIO_BLTSIZE); 35203bd066fSmrg } 35303bd066fSmrg 35403bd066fSmrg if (pVia->MapBase) { 35503bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 35603bd066fSmrg VIA_MMIO_REGSIZE); 35703bd066fSmrg } 35890b17f1bSmrg#else 35903bd066fSmrg if (pVia->FBBase) { 36003bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 36103bd066fSmrg pVia->videoRambytes); 36203bd066fSmrg } 36303bd066fSmrg 36403bd066fSmrg if (pVia->BltBase) { 36503bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 36603bd066fSmrg VIA_MMIO_BLTSIZE); 36703bd066fSmrg } 36803bd066fSmrg 36903bd066fSmrg if (pVia->MapBase) { 37003bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 37103bd066fSmrg VIA_MMIO_REGSIZE); 37203bd066fSmrg } 37390b17f1bSmrg#endif 37490b17f1bSmrg 37503bd066fSmrg pVia->FBBase = NULL; 37603bd066fSmrg pVia->BltBase = NULL; 37703bd066fSmrg pVia->MapBase = NULL; 37803bd066fSmrg 37903bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 38003bd066fSmrg "Exiting viaUnmapMMIO.\n")); 38190b17f1bSmrg} 38290b17f1bSmrg 38390b17f1bSmrg/* 38490b17f1bSmrg * Leftover from VIA's code. 38590b17f1bSmrg */ 38690b17f1bSmrgstatic void 38790b17f1bSmrgviaInitPCIe(VIAPtr pVia) 38890b17f1bSmrg{ 38990b17f1bSmrg VIASETREG(0x41c, 0x00100000); 39090b17f1bSmrg VIASETREG(0x420, 0x680A0000); 39190b17f1bSmrg VIASETREG(0x420, 0x02000000); 39290b17f1bSmrg} 39390b17f1bSmrg 39490b17f1bSmrgstatic void 39503bd066fSmrgviaInitAGP(VIAPtr pVia) 39690b17f1bSmrg{ 39790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00100000); 39890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 39990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 40090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 40190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 40290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 40390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 40490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 40590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); 40690b17f1bSmrg 40790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0xfe020000); 40890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 40990b17f1bSmrg} 41090b17f1bSmrg 41190b17f1bSmrg/* 41290b17f1bSmrg * Initialize the virtual command queue. Header-2 commands can be put 41390b17f1bSmrg * in this queue for buffering. AFAIK it doesn't handle Header-1 41490b17f1bSmrg * commands, which is really a pity, since it has to be idled before 41590b17f1bSmrg * issuing a Header-1 command. 41690b17f1bSmrg */ 41790b17f1bSmrgstatic void 41803bd066fSmrgviaEnableAGPVQ(VIAPtr pVia) 41990b17f1bSmrg{ 42090b17f1bSmrg CARD32 42190b17f1bSmrg vqStartAddr = pVia->VQStart, 42290b17f1bSmrg vqEndAddr = pVia->VQEnd, 42390b17f1bSmrg vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), 42490b17f1bSmrg vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), 42590b17f1bSmrg vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | 42690b17f1bSmrg ((vqEndAddr & 0xFF000000) >> 16), 42790b17f1bSmrg vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); 42890b17f1bSmrg 42990b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 43090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); 43190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); 43290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); 43390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); 43490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); 43590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); 43690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); 43790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); 43890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); 43990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); 44090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000006); 44190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 44290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 44390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 44490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 44590b17f1bSmrg 44690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); 44790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqStartL); 44890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqEndL); 44990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqLen); 45090b17f1bSmrg} 45190b17f1bSmrg 45290b17f1bSmrgstatic void 45390b17f1bSmrgviaEnablePCIeVQ(VIAPtr pVia) 45490b17f1bSmrg{ 45590b17f1bSmrg CARD32 45690b17f1bSmrg vqStartAddr = pVia->VQStart, 45790b17f1bSmrg vqEndAddr = pVia->VQEnd, 45890b17f1bSmrg vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), 45990b17f1bSmrg vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), 46090b17f1bSmrg vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | 46190b17f1bSmrg ((vqEndAddr & 0xFF000000) >> 16), 46290b17f1bSmrg vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); 46390b17f1bSmrg 46490b17f1bSmrg VIASETREG(0x41c, 0x00100000); 46590b17f1bSmrg VIASETREG(0x420, vqStartEndH); 46690b17f1bSmrg VIASETREG(0x420, vqStartL); 46790b17f1bSmrg VIASETREG(0x420, vqEndL); 46890b17f1bSmrg VIASETREG(0x420, vqLen); 46990b17f1bSmrg VIASETREG(0x420, 0x74301001); 47090b17f1bSmrg VIASETREG(0x420, 0x00000000); 47190b17f1bSmrg} 47290b17f1bSmrg 47390b17f1bSmrg/* 47490b17f1bSmrg * Disable the virtual command queue. 47590b17f1bSmrg */ 47690b17f1bSmrgvoid 47790b17f1bSmrgviaDisableVQ(ScrnInfoPtr pScrn) 47890b17f1bSmrg{ 47990b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 48090b17f1bSmrg 48103bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 48203bd066fSmrg "Entered viaDisableVQ.\n")); 48303bd066fSmrg 48490b17f1bSmrg switch (pVia->Chipset) { 48503bd066fSmrg case VIA_K8M890: 48603bd066fSmrg case VIA_P4M900: 48703bd066fSmrg case VIA_VX800: 48803bd066fSmrg case VIA_VX855: 48903bd066fSmrg case VIA_VX900: 49003bd066fSmrg VIASETREG(0x41c, 0x00100000); 49103bd066fSmrg VIASETREG(0x420, 0x74301000); 49203bd066fSmrg break; 49303bd066fSmrg default: 49403bd066fSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 49503bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000004); 49603bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 49703bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 49803bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 49903bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 50003bd066fSmrg break; 50190b17f1bSmrg } 50203bd066fSmrg 50303bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 50403bd066fSmrg "Exiting viaDisableVQ.\n")); 50590b17f1bSmrg} 50690b17f1bSmrg 50790b17f1bSmrg/* 50890b17f1bSmrg * Initialize the 2D engine and set the 2D context mode to the 50990b17f1bSmrg * current screen depth. Also enable the virtual queue. 51090b17f1bSmrg */ 51190b17f1bSmrgstatic void 51203bd066fSmrgviaInitialize2DEngine(ScrnInfoPtr pScrn) 51390b17f1bSmrg{ 51490b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 51590b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 51690b17f1bSmrg int i; 51790b17f1bSmrg 51890b17f1bSmrg /* Initialize the 2D engine registers to reset the 2D engine. */ 51990b17f1bSmrg for (i = 0x04; i <= 0x40; i += 4) { 52090b17f1bSmrg VIASETREG(i, 0x0); 52190b17f1bSmrg } 52290b17f1bSmrg 52390b17f1bSmrg if (pVia->Chipset == VIA_VX800 || 52490b17f1bSmrg pVia->Chipset == VIA_VX855 || 52590b17f1bSmrg pVia->Chipset == VIA_VX900) { 52690b17f1bSmrg for (i = 0x44; i <= 0x5c; i += 4) { 52790b17f1bSmrg VIASETREG(i, 0x0); 52890b17f1bSmrg } 52990b17f1bSmrg } 53090b17f1bSmrg 53190b17f1bSmrg if (pVia->Chipset == VIA_VX900) 53290b17f1bSmrg { 53390b17f1bSmrg /*410 redefine 0x30 34 38*/ 53490b17f1bSmrg VIASETREG(0x60, 0x0); /*already useable here*/ 53590b17f1bSmrg } 53690b17f1bSmrg 53790b17f1bSmrg switch (pVia->Chipset) { 53890b17f1bSmrg case VIA_K8M890: 53990b17f1bSmrg case VIA_P4M900: 54090b17f1bSmrg case VIA_VX800: 54190b17f1bSmrg case VIA_VX855: 54290b17f1bSmrg case VIA_VX900: 54390b17f1bSmrg viaInitPCIe(pVia); 54490b17f1bSmrg break; 54590b17f1bSmrg default: 54603bd066fSmrg viaInitAGP(pVia); 54790b17f1bSmrg break; 54890b17f1bSmrg } 54990b17f1bSmrg 55090b17f1bSmrg if (pVia->VQStart != 0) { 55190b17f1bSmrg switch (pVia->Chipset) { 55290b17f1bSmrg case VIA_K8M890: 55390b17f1bSmrg case VIA_P4M900: 55490b17f1bSmrg case VIA_VX800: 55590b17f1bSmrg case VIA_VX855: 55690b17f1bSmrg case VIA_VX900: 55790b17f1bSmrg viaEnablePCIeVQ(pVia); 55890b17f1bSmrg break; 55990b17f1bSmrg default: 56003bd066fSmrg viaEnableAGPVQ(pVia); 56190b17f1bSmrg break; 56290b17f1bSmrg } 56390b17f1bSmrg } else { 56490b17f1bSmrg viaDisableVQ(pScrn); 56590b17f1bSmrg } 56690b17f1bSmrg 56790b17f1bSmrg viaAccelSetMode(pScrn->bitsPerPixel, tdc); 56890b17f1bSmrg} 56990b17f1bSmrg 57090b17f1bSmrgstatic void 57103bd066fSmrgviaInitialize3DEngine(ScrnInfoPtr pScrn) 57290b17f1bSmrg{ 57390b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 57490b17f1bSmrg int i; 57590b17f1bSmrg 57690b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00010000); 57790b17f1bSmrg for (i = 0; i <= 0x7D; i++) 57890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 57990b17f1bSmrg 58090b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00020000); 58190b17f1bSmrg for (i = 0; i <= 0x94; i++) 58290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 58390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 58490b17f1bSmrg 58590b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x01020000); 58690b17f1bSmrg for (i = 0; i <= 0x94; i++) 58790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 58890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 58990b17f1bSmrg 59090b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0xfe020000); 59190b17f1bSmrg for (i = 0; i <= 0x03; i++) 59290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 59390b17f1bSmrg 59490b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00030000); 59590b17f1bSmrg for (i = 0; i <= 0xff; i++) 59690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0); 59790b17f1bSmrg 59890b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00100000); 59990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 60090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x10000002); 60190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 60290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 60390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 60490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 60590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 60690b17f1bSmrg 60790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 60890b17f1bSmrg if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3) 60990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 61090b17f1bSmrg else 61190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x4000800f); 61290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 61390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080C04); 61490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 61590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x50000000); 61690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x51000000); 61790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x52000000); 61890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x53000000); 61990b17f1bSmrg 62090b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 62190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x08000001); 62290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0A000183); 62390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F); 62490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B); 62590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B); 62690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0E000000); 62790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0F000000); 62890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x10000000); 62990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x11000000); 63090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x20000000); 63190b17f1bSmrg} 63290b17f1bSmrg 63390b17f1bSmrg/* 63490b17f1bSmrg * Acceleration initialization function. Sets up offscreen memory disposition, 63590b17f1bSmrg * and initializes engines and acceleration method. 63690b17f1bSmrg */ 63790b17f1bSmrgBool 63803bd066fSmrgumsAccelInit(ScreenPtr pScreen) 63990b17f1bSmrg{ 64090b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 64190b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 64290b17f1bSmrg Bool ret = FALSE; 64390b17f1bSmrg 64403bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 64503bd066fSmrg "Entered umsAccelInit.\n")); 64603bd066fSmrg 64790b17f1bSmrg pVia->VQStart = 0; 64890b17f1bSmrg pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM); 64990b17f1bSmrg if (!pVia->vq_bo) 65090b17f1bSmrg goto err; 65190b17f1bSmrg 65290b17f1bSmrg pVia->VQStart = pVia->vq_bo->offset; 65390b17f1bSmrg pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size; 65490b17f1bSmrg 65503bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65603bd066fSmrg "Initializing the 2D engine.\n")); 65703bd066fSmrg viaInitialize2DEngine(pScrn); 65803bd066fSmrg 65903bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 66003bd066fSmrg "Initializing the 3D engine.\n")); 66103bd066fSmrg viaInitialize3DEngine(pScrn); 66290b17f1bSmrg 66390b17f1bSmrg pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 66490b17f1bSmrg if (!pVia->exa_sync_bo) 66590b17f1bSmrg goto err; 66690b17f1bSmrg 66790b17f1bSmrg /* Sync marker space. */ 66890b17f1bSmrg pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 66990b17f1bSmrg if (!pVia->exa_sync_bo) 67090b17f1bSmrg goto err; 67190b17f1bSmrg 67290b17f1bSmrg pVia->markerOffset = pVia->exa_sync_bo->offset; 67390b17f1bSmrg pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo); 67490b17f1bSmrg if (!pVia->markerBuf) 67590b17f1bSmrg goto err; 67690b17f1bSmrg pVia->curMarker = 0; 67790b17f1bSmrg pVia->lastMarkerRead = 0; 67890b17f1bSmrg 67990b17f1bSmrg#ifdef HAVE_DRI 68090b17f1bSmrg pVia->dBounce = NULL; 68190b17f1bSmrg pVia->scratchAddr = NULL; 68290b17f1bSmrg#endif /* HAVE_DRI */ 68390b17f1bSmrg ret = TRUE; 68490b17f1bSmrgerr: 68590b17f1bSmrg if (!ret) { 68690b17f1bSmrg if (pVia->markerBuf) { 68790b17f1bSmrg drm_bo_unmap(pScrn, pVia->exa_sync_bo); 68890b17f1bSmrg pVia->markerBuf = NULL; 68990b17f1bSmrg } 69090b17f1bSmrg if (pVia->exa_sync_bo) 69190b17f1bSmrg drm_bo_free(pScrn, pVia->exa_sync_bo); 69290b17f1bSmrg if (pVia->vq_bo) 69390b17f1bSmrg drm_bo_free(pScrn, pVia->vq_bo); 69490b17f1bSmrg } 69503bd066fSmrg 69603bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 69703bd066fSmrg "Exiting umsAccelInit.\n")); 69890b17f1bSmrg return ret; 69990b17f1bSmrg} 70090b17f1bSmrg 70190b17f1bSmrgBool 70203bd066fSmrgumsCreate(ScrnInfoPtr pScrn) 70390b17f1bSmrg{ 70490b17f1bSmrg ScreenPtr pScreen = pScrn->pScreen; 70590b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 70690b17f1bSmrg unsigned long offset; 70790b17f1bSmrg BoxRec AvailFBArea; 70890b17f1bSmrg Bool ret = TRUE; 70990b17f1bSmrg long size; 71090b17f1bSmrg int maxY; 71190b17f1bSmrg 71290b17f1bSmrg#ifdef HAVE_DRI 71390b17f1bSmrg if (pVia->directRenderingType == DRI_1) { 71490b17f1bSmrg pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2; 71590b17f1bSmrg if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) 71690b17f1bSmrg pVia->driSize = pVia->maxDriSize * 1024; 71790b17f1bSmrg 71890b17f1bSmrg /* In the case of DRI we handle all VRAM by the DRI ioctls */ 71990b17f1bSmrg if (pVia->useEXA) 72090b17f1bSmrg return TRUE; 72190b17f1bSmrg 72290b17f1bSmrg /* XAA has to use FBManager so we have to split the space with DRI */ 72390b17f1bSmrg maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); 72490b17f1bSmrg } else 72590b17f1bSmrg#endif 72690b17f1bSmrg maxY = pVia->FBFreeEnd / pVia->Bpl; 72790b17f1bSmrg 72890b17f1bSmrg /* FBManager can't handle more than 32767 scan lines */ 72990b17f1bSmrg if (maxY > 32767) 73090b17f1bSmrg maxY = 32767; 73190b17f1bSmrg 73290b17f1bSmrg AvailFBArea.x1 = 0; 73390b17f1bSmrg AvailFBArea.y1 = 0; 73490b17f1bSmrg AvailFBArea.x2 = pScrn->displayWidth; 73590b17f1bSmrg AvailFBArea.y2 = maxY; 73690b17f1bSmrg pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; 73790b17f1bSmrg 73890b17f1bSmrg /* 73990b17f1bSmrg * Initialization of the XFree86 framebuffer manager is done via 74090b17f1bSmrg * Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox) 74190b17f1bSmrg * FullBox represents the area of the framebuffer that the manager 74290b17f1bSmrg * is allowed to manage. This is typically a box with a width 74390b17f1bSmrg * of pScrn->displayWidth and a height of as many lines as can be fit 74490b17f1bSmrg * within the total video memory 74590b17f1bSmrg */ 74690b17f1bSmrg ret = xf86InitFBManager(pScreen, &AvailFBArea); 74790b17f1bSmrg if (ret != TRUE) 74890b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n"); 74990b17f1bSmrg 75090b17f1bSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 75190b17f1bSmrg "Frame Buffer From (%d,%d) To (%d,%d)\n", 75290b17f1bSmrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2)); 75390b17f1bSmrg 75490b17f1bSmrg offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp; 75590b17f1bSmrg size = pVia->FBFreeEnd / pVia->Bpp - offset; 75690b17f1bSmrg if (size > 0) 75790b17f1bSmrg xf86InitFBManagerLinear(pScreen, offset, size); 75890b17f1bSmrg 75990b17f1bSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 76090b17f1bSmrg "Using %d lines for offscreen memory.\n", 76190b17f1bSmrg AvailFBArea.y2 - pScrn->virtualY)); 76290b17f1bSmrg return TRUE; 76390b17f1bSmrg} 76490b17f1bSmrg 76590b17f1bSmrgBool 76603bd066fSmrgumsPreInit(ScrnInfoPtr pScrn) 76790b17f1bSmrg{ 76890b17f1bSmrg MessageType from = X_PROBED; 76990b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 77090b17f1bSmrg CARD8 videoRam; 77190b17f1bSmrg vgaHWPtr hwp; 77290b17f1bSmrg#ifdef HAVE_PCIACCESS 77390b17f1bSmrg struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3); 77490b17f1bSmrg struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0); 77590b17f1bSmrg#endif 77690b17f1bSmrg int bMemSize = 0; 77790b17f1bSmrg 77890b17f1bSmrg if (!xf86LoadSubModule(pScrn, "vgahw")) 77990b17f1bSmrg return FALSE; 78090b17f1bSmrg 78190b17f1bSmrg if (!vgaHWGetHWRec(pScrn)) 78290b17f1bSmrg return FALSE; 78390b17f1bSmrg 78490b17f1bSmrg#if 0 78590b17f1bSmrg /* Here we can alter the number of registers saved and restored by the 78690b17f1bSmrg * standard vgaHWSave and Restore routines. 78790b17f1bSmrg */ 78890b17f1bSmrg vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, 78990b17f1bSmrg VGA_NUM_ATTR); 79090b17f1bSmrg#endif 79190b17f1bSmrg hwp = VGAHWPTR(pScrn); 79290b17f1bSmrg 79390b17f1bSmrg switch (pVia->Chipset) { 79490b17f1bSmrg case VIA_CLE266: 79590b17f1bSmrg#ifdef HAVE_PCIACCESS 79690b17f1bSmrg pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 79790b17f1bSmrg#else 79890b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 79990b17f1bSmrg#endif 80090b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 80190b17f1bSmrg break; 80290b17f1bSmrg case VIA_KM400: 80390b17f1bSmrg#ifdef HAVE_PCIACCESS 804963d66acSmrg /* P4M800 Host Bridge PCI Device ID */ 805963d66acSmrg if (DEVICE_ID(bridge) == 0x0296) { 80690b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 80790b17f1bSmrg } else { 80890b17f1bSmrg pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 809963d66acSmrg } 81090b17f1bSmrg#else 811963d66acSmrg /* P4M800 Host Bridge PCI Device ID */ 812963d66acSmrg if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) { 813963d66acSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 814963d66acSmrg } else { 81590b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 81690b17f1bSmrg } 817963d66acSmrg#endif 81890b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 81990b17f1bSmrg break; 82090b17f1bSmrg case VIA_PM800: 821963d66acSmrg case VIA_P4M800PRO: 82290b17f1bSmrg case VIA_K8M800: 82390b17f1bSmrg#ifdef HAVE_PCIACCESS 82490b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 82590b17f1bSmrg#else 82690b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 82790b17f1bSmrg#endif 82890b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 82990b17f1bSmrg break; 83090b17f1bSmrg case VIA_P4M890: 831963d66acSmrg case VIA_K8M890: 83290b17f1bSmrg case VIA_P4M900: 83390b17f1bSmrg case VIA_CX700: 83490b17f1bSmrg case VIA_VX800: 83590b17f1bSmrg case VIA_VX855: 83690b17f1bSmrg case VIA_VX900: 83790b17f1bSmrg#ifdef HAVE_PCIACCESS 83890b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 83990b17f1bSmrg#else 84090b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 84190b17f1bSmrg#endif 84290b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12; 84390b17f1bSmrg break; 84490b17f1bSmrg default: 84590b17f1bSmrg if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { 84690b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 84790b17f1bSmrg "Using old memory-detection method.\n"); 84890b17f1bSmrg bMemSize = hwp->readSeq(hwp, 0x39); 84990b17f1bSmrg if (bMemSize > 16 && bMemSize <= 128) 85090b17f1bSmrg pScrn->videoRam = (bMemSize + 1) << 9; 85190b17f1bSmrg else if (bMemSize > 0 && bMemSize < 31) 85290b17f1bSmrg pScrn->videoRam = bMemSize << 12; 85390b17f1bSmrg else { 85490b17f1bSmrg from = X_DEFAULT; 85590b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 85690b17f1bSmrg "Memory size detection failed: using 16 MB.\n"); 85790b17f1bSmrg pScrn->videoRam = 16 << 10; 85890b17f1bSmrg } 85990b17f1bSmrg } else { 86090b17f1bSmrg from = X_DEFAULT; 86190b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 86290b17f1bSmrg "No memory-detection done. Use VideoRAM option.\n"); 86390b17f1bSmrg } 86490b17f1bSmrg } 86590b17f1bSmrg 86690b17f1bSmrg /* 86790b17f1bSmrg * PCI BAR are limited to 256 MB. 86890b17f1bSmrg */ 86990b17f1bSmrg if (pScrn->videoRam > (256 << 10)) { 87090b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 87190b17f1bSmrg "Cannot use more than 256 MB of VRAM.\n"); 87290b17f1bSmrg pScrn->videoRam = (256 << 10); 87390b17f1bSmrg } 87490b17f1bSmrg 87590b17f1bSmrg if (from == X_PROBED) { 87690b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, from, 87790b17f1bSmrg "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); 87890b17f1bSmrg } 87990b17f1bSmrg 88090b17f1bSmrg /* Split the FB for SAMM. */ 88190b17f1bSmrg /* FIXME: For now, split the FB into two equal sections. 88290b17f1bSmrg * This should be user-adjustable via a config option. */ 88390b17f1bSmrg if (pVia->IsSecondary) { 88490b17f1bSmrg DevUnion *pPriv; 88590b17f1bSmrg VIAEntPtr pVIAEnt; 88690b17f1bSmrg VIAPtr pVia1; 88790b17f1bSmrg 88890b17f1bSmrg pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); 88990b17f1bSmrg pVIAEnt = pPriv->ptr; 89090b17f1bSmrg pScrn->videoRam = pScrn->videoRam >> 1; 89190b17f1bSmrg pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; 89290b17f1bSmrg pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); 89390b17f1bSmrg pVia1->videoRambytes = pScrn->videoRam << 10; 89490b17f1bSmrg pVia->FrameBufferBase += (pScrn->videoRam << 10); 89590b17f1bSmrg } 89690b17f1bSmrg 89790b17f1bSmrg pVia->videoRambytes = pScrn->videoRam << 10; 89890b17f1bSmrg 89990b17f1bSmrg /* maybe throw in some more sanity checks here */ 90090b17f1bSmrg#ifndef HAVE_PCIACCESS 90190b17f1bSmrg pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, 90290b17f1bSmrg pVia->PciInfo->func); 90390b17f1bSmrg#endif 90490b17f1bSmrg 90503bd066fSmrg /* Map PCI hardware resources to the memory map. */ 90603bd066fSmrg if (!viaMapMMIO(pScrn)) { 90703bd066fSmrg return FALSE; 90803bd066fSmrg } 90903bd066fSmrg 91003bd066fSmrg return TRUE; 91103bd066fSmrg} 91203bd066fSmrg 91303bd066fSmrgBool 91403bd066fSmrgumsCrtcInit(ScrnInfoPtr pScrn) 91503bd066fSmrg{ 91603bd066fSmrg drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 91703bd066fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 91803bd066fSmrg VIAPtr pVia = VIAPTR(pScrn); 91903bd066fSmrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 92003bd066fSmrg ClockRangePtr clockRanges; 92103bd066fSmrg#else 92203bd066fSmrg ClockRangesPtr clockRanges; 92303bd066fSmrg#endif 92403bd066fSmrg int max_pitch, max_height; 92503bd066fSmrg VIABIOSInfoPtr pBIOSInfo; 92603bd066fSmrg xf86CrtcPtr iga1, iga2; 92703bd066fSmrg 92803bd066fSmrg /* Read memory bandwidth from registers. */ 92903bd066fSmrg pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 93003bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 93103bd066fSmrg "Detected MemClk %d\n", pVia->MemClk)); 93203bd066fSmrg if (pVia->MemClk >= VIA_MEM_END) { 93303bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 93403bd066fSmrg "Unknown Memory clock: %d\n", pVia->MemClk); 93503bd066fSmrg pVia->MemClk = VIA_MEM_END - 1; 93603bd066fSmrg } 93703bd066fSmrg pBIOSInfo = pVia->pBIOSInfo; 93803bd066fSmrg pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 93903bd066fSmrg 94003bd066fSmrg if (pBIOSInfo->TVType == TVTYPE_NONE) { 94103bd066fSmrg /* Use jumper to determine TV type. */ 94203bd066fSmrg if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 94303bd066fSmrg pBIOSInfo->TVType = TVTYPE_PAL; 94403bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 94503bd066fSmrg "Detected TV standard: PAL.\n")); 94603bd066fSmrg } else { 94703bd066fSmrg pBIOSInfo->TVType = TVTYPE_NTSC; 94803bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 94903bd066fSmrg "Detected TV standard: NTSC.\n")); 95003bd066fSmrg } 95103bd066fSmrg } 95203bd066fSmrg 95303bd066fSmrg if (pVia->drmmode.hwcursor) { 95403bd066fSmrg if (!xf86LoadSubModule(pScrn, "ramdac")) 95503bd066fSmrg return FALSE; 95603bd066fSmrg } 95703bd066fSmrg 95803bd066fSmrg if (!xf86LoadSubModule(pScrn, "i2c")) 95903bd066fSmrg return FALSE; 96003bd066fSmrg else 96103bd066fSmrg ViaI2CInit(pScrn); 96203bd066fSmrg 96303bd066fSmrg if (!xf86LoadSubModule(pScrn, "ddc")) 96403bd066fSmrg return FALSE; 96503bd066fSmrg 96603bd066fSmrg /* 96703bd066fSmrg * Set up ClockRanges, which describe what clock ranges are 96803bd066fSmrg * available, and what sort of modes they can be used for. 96903bd066fSmrg */ 97003bd066fSmrg 97103bd066fSmrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 97203bd066fSmrg clockRanges = xnfalloc(sizeof(ClockRange)); 97303bd066fSmrg#else 97403bd066fSmrg clockRanges = xnfalloc(sizeof(ClockRanges)); 97503bd066fSmrg#endif 97603bd066fSmrg clockRanges->next = NULL; 97703bd066fSmrg clockRanges->minClock = 20000; 97803bd066fSmrg clockRanges->maxClock = 230000; 97903bd066fSmrg 98003bd066fSmrg clockRanges->clockIndex = -1; 98103bd066fSmrg clockRanges->interlaceAllowed = TRUE; 98203bd066fSmrg clockRanges->doubleScanAllowed = FALSE; 98303bd066fSmrg pScrn->clockRanges = clockRanges; 98403bd066fSmrg 98503bd066fSmrg /* 98603bd066fSmrg * Now handle the outputs 98703bd066fSmrg */ 98803bd066fSmrg iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 98903bd066fSmrg if (!iga1_rec) { 99003bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 99190b17f1bSmrg return FALSE; 99203bd066fSmrg } 99303bd066fSmrg 99403bd066fSmrg iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 99503bd066fSmrg if (!iga1) { 99603bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 99703bd066fSmrg free(iga1_rec); 99803bd066fSmrg return FALSE; 99903bd066fSmrg } 100003bd066fSmrg iga1_rec->drmmode = &pVia->drmmode; 100103bd066fSmrg iga1_rec->index = 0; 100203bd066fSmrg iga1->driver_private = iga1_rec; 100303bd066fSmrg 100403bd066fSmrg iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 100503bd066fSmrg if (!iga2_rec) { 100603bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 100703bd066fSmrg xf86CrtcDestroy(iga1); 100803bd066fSmrg return FALSE; 100903bd066fSmrg } 101090b17f1bSmrg 101103bd066fSmrg iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 101203bd066fSmrg if (!iga2) { 101303bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 101403bd066fSmrg xf86CrtcDestroy(iga1); 101503bd066fSmrg free(iga2_rec); 101690b17f1bSmrg return FALSE; 101703bd066fSmrg } 101803bd066fSmrg iga2_rec->drmmode = &pVia->drmmode; 101903bd066fSmrg iga2_rec->index = 1; 102003bd066fSmrg iga2->driver_private = iga2_rec; 102103bd066fSmrg 102203bd066fSmrg /* Init HI_X0 for cursor */ 102303bd066fSmrg switch (pVia->Chipset) { 102403bd066fSmrg case VIA_CX700: 102503bd066fSmrg /* case VIA_CN750: */ 102603bd066fSmrg case VIA_P4M890: 102703bd066fSmrg case VIA_P4M900: 102803bd066fSmrg case VIA_VX800: 102903bd066fSmrg case VIA_VX855: 103003bd066fSmrg case VIA_VX900: 103103bd066fSmrg /* set 0 as transparent color key for IGA 2 */ 103203bd066fSmrg VIASETREG(HI_TRANSPARENT_COLOR, 0); 103303bd066fSmrg VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 103403bd066fSmrg VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 103503bd066fSmrg VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 103603bd066fSmrg 103703bd066fSmrg /* set 0 as transparent color key for IGA 1 */ 103803bd066fSmrg VIASETREG(PRIM_HI_TRANSCOLOR, 0); 103903bd066fSmrg VIASETREG(PRIM_HI_FIFO, 0x0D000D0F); 104003bd066fSmrg VIASETREG(PRIM_HI_INVTCOLOR, 0x00FFFFFF); 104103bd066fSmrg VIASETREG(V327_HI_INVTCOLOR, 0x00FFFFFF); 104203bd066fSmrg break; 104303bd066fSmrg 104403bd066fSmrg default: 104503bd066fSmrg VIASETREG(HI_TRANSPARENT_COLOR, 0); 104603bd066fSmrg VIASETREG(HI_INVTCOLOR, 0X00FFFFFF); 104703bd066fSmrg VIASETREG(ALPHA_V3_PREFIFO_CONTROL, 0xE0000); 104803bd066fSmrg VIASETREG(ALPHA_V3_FIFO_CONTROL, 0xE0F0000); 104903bd066fSmrg break; 105003bd066fSmrg } 105103bd066fSmrg 105203bd066fSmrg /* 105303bd066fSmrg * CLE266A: 105403bd066fSmrg * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 105503bd066fSmrg * Max Height: 4096 (and beyond) 105603bd066fSmrg * 105703bd066fSmrg * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 105803bd066fSmrg * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 105903bd066fSmrg * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 106003bd066fSmrg * 106103bd066fSmrg * We should be able to limit the memory available for a mode to 32 MB, 106203bd066fSmrg * but miScanLineWidth fails to catch this properly (apertureSize). 106303bd066fSmrg */ 106403bd066fSmrg max_pitch = 8192 / ((pScrn->bitsPerPixel + 7) >> 3); 106503bd066fSmrg max_height = max_pitch; 106603bd066fSmrg 106703bd066fSmrg xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 106803bd066fSmrg 106903bd066fSmrg viaOutputDetect(pScrn); 107003bd066fSmrg 107190b17f1bSmrg return TRUE; 107290b17f1bSmrg} 1073