190b17f1bSmrg/* 203bd066fSmrg * Copyright 2011-2016 The OpenChrome Project 31090d90aSmrg * [https://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 " 190f4dbeecdSjakllsch "size %lu 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 vgaHWGetIOBase(hwp); 28203bd066fSmrg 28303bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 28403bd066fSmrg "Exiting viaMapMMIO.\n")); 28503bd066fSmrg return TRUE; 28603bd066fSmrg 28703bd066fSmrgfail: 28890b17f1bSmrg 28990b17f1bSmrg#ifdef HAVE_PCIACCESS 29003bd066fSmrg if (pVia->FBBase) { 29103bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 29203bd066fSmrg pVia->videoRambytes); 29303bd066fSmrg } 29403bd066fSmrg 29503bd066fSmrg if (pVia->BltBase) { 29603bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 29703bd066fSmrg VIA_MMIO_BLTSIZE); 29803bd066fSmrg } 29903bd066fSmrg 30003bd066fSmrg if (pVia->MapBase) { 30103bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 30203bd066fSmrg VIA_MMIO_REGSIZE); 30303bd066fSmrg } 30490b17f1bSmrg#else 30503bd066fSmrg if (pVia->FBBase) { 30603bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 30703bd066fSmrg pVia->videoRambytes); 30803bd066fSmrg } 30990b17f1bSmrg 31003bd066fSmrg if (pVia->BltBase) { 31103bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 31203bd066fSmrg VIA_MMIO_BLTSIZE); 31303bd066fSmrg } 31403bd066fSmrg 31503bd066fSmrg if (pVia->MapBase) { 31603bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 31703bd066fSmrg VIA_MMIO_REGSIZE); 31803bd066fSmrg } 31990b17f1bSmrg#endif 32090b17f1bSmrg 32103bd066fSmrg pVia->FBBase = NULL; 32203bd066fSmrg pVia->BltBase = NULL; 32303bd066fSmrg pVia->MapBase = NULL; 32490b17f1bSmrg 32503bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 32603bd066fSmrg "Exiting viaMapMMIO.\n")); 32703bd066fSmrg return FALSE; 32803bd066fSmrg} 32903bd066fSmrg 33003bd066fSmrgvoid 33103bd066fSmrgviaUnmapMMIO(ScrnInfoPtr pScrn) 33203bd066fSmrg{ 33303bd066fSmrg VIAPtr pVia = VIAPTR(pScrn); 33403bd066fSmrg 33503bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 33603bd066fSmrg "Entered viaUnmapMMIO.\n")); 33703bd066fSmrg 33803bd066fSmrg viaMMIODisable(pScrn); 33990b17f1bSmrg 34090b17f1bSmrg#ifdef HAVE_PCIACCESS 34103bd066fSmrg if (pVia->FBBase) { 34203bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->FBBase, 34303bd066fSmrg pVia->videoRambytes); 34403bd066fSmrg } 34503bd066fSmrg 34603bd066fSmrg if (pVia->BltBase) { 34703bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->BltBase, 34803bd066fSmrg VIA_MMIO_BLTSIZE); 34903bd066fSmrg } 35003bd066fSmrg 35103bd066fSmrg if (pVia->MapBase) { 35203bd066fSmrg pci_device_unmap_range(pVia->PciInfo, (pointer) pVia->MapBase, 35303bd066fSmrg VIA_MMIO_REGSIZE); 35403bd066fSmrg } 35590b17f1bSmrg#else 35603bd066fSmrg if (pVia->FBBase) { 35703bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->FBBase, 35803bd066fSmrg pVia->videoRambytes); 35903bd066fSmrg } 36003bd066fSmrg 36103bd066fSmrg if (pVia->BltBase) { 36203bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->BltBase, 36303bd066fSmrg VIA_MMIO_BLTSIZE); 36403bd066fSmrg } 36503bd066fSmrg 36603bd066fSmrg if (pVia->MapBase) { 36703bd066fSmrg xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pVia->MapBase, 36803bd066fSmrg VIA_MMIO_REGSIZE); 36903bd066fSmrg } 37090b17f1bSmrg#endif 37190b17f1bSmrg 37203bd066fSmrg pVia->FBBase = NULL; 37303bd066fSmrg pVia->BltBase = NULL; 37403bd066fSmrg pVia->MapBase = NULL; 37503bd066fSmrg 37603bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 37703bd066fSmrg "Exiting viaUnmapMMIO.\n")); 37890b17f1bSmrg} 37990b17f1bSmrg 38090b17f1bSmrg/* 38190b17f1bSmrg * Leftover from VIA's code. 38290b17f1bSmrg */ 38390b17f1bSmrgstatic void 38490b17f1bSmrgviaInitPCIe(VIAPtr pVia) 38590b17f1bSmrg{ 38690b17f1bSmrg VIASETREG(0x41c, 0x00100000); 38790b17f1bSmrg VIASETREG(0x420, 0x680A0000); 38890b17f1bSmrg VIASETREG(0x420, 0x02000000); 38990b17f1bSmrg} 39090b17f1bSmrg 39190b17f1bSmrgstatic void 39203bd066fSmrgviaInitAGP(VIAPtr pVia) 39390b17f1bSmrg{ 39490b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00100000); 39590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 39690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 39790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 39890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 39990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 40090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 40190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 40290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); 40390b17f1bSmrg 40490b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0xfe020000); 40590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000000); 40690b17f1bSmrg} 40790b17f1bSmrg 40890b17f1bSmrg/* 40990b17f1bSmrg * Initialize the virtual command queue. Header-2 commands can be put 41090b17f1bSmrg * in this queue for buffering. AFAIK it doesn't handle Header-1 41190b17f1bSmrg * commands, which is really a pity, since it has to be idled before 41290b17f1bSmrg * issuing a Header-1 command. 41390b17f1bSmrg */ 41490b17f1bSmrgstatic void 41503bd066fSmrgviaEnableAGPVQ(VIAPtr pVia) 41690b17f1bSmrg{ 41790b17f1bSmrg CARD32 41890b17f1bSmrg vqStartAddr = pVia->VQStart, 41990b17f1bSmrg vqEndAddr = pVia->VQEnd, 42090b17f1bSmrg vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), 42190b17f1bSmrg vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), 42290b17f1bSmrg vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | 42390b17f1bSmrg ((vqEndAddr & 0xFF000000) >> 16), 42490b17f1bSmrg vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); 42590b17f1bSmrg 42690b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 42790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); 42890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); 42990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); 43090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); 43190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); 43290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); 43390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); 43490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); 43590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); 43690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); 43790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000006); 43890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 43990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 44090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 44190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 44290b17f1bSmrg 44390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); 44490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqStartL); 44590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqEndL); 44690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, vqLen); 44790b17f1bSmrg} 44890b17f1bSmrg 44990b17f1bSmrgstatic void 45090b17f1bSmrgviaEnablePCIeVQ(VIAPtr pVia) 45190b17f1bSmrg{ 45290b17f1bSmrg CARD32 45390b17f1bSmrg vqStartAddr = pVia->VQStart, 45490b17f1bSmrg vqEndAddr = pVia->VQEnd, 45590b17f1bSmrg vqStartL = 0x70000000 | (vqStartAddr & 0xFFFFFF), 45690b17f1bSmrg vqEndL = 0x71000000 | (vqEndAddr & 0xFFFFFF), 45790b17f1bSmrg vqStartEndH = 0x72000000 | ((vqStartAddr & 0xFF000000) >> 24) | 45890b17f1bSmrg ((vqEndAddr & 0xFF000000) >> 16), 45990b17f1bSmrg vqLen = 0x73000000 | (VIA_VQ_SIZE >> 3); 46090b17f1bSmrg 46190b17f1bSmrg VIASETREG(0x41c, 0x00100000); 46290b17f1bSmrg VIASETREG(0x420, vqStartEndH); 46390b17f1bSmrg VIASETREG(0x420, vqStartL); 46490b17f1bSmrg VIASETREG(0x420, vqEndL); 46590b17f1bSmrg VIASETREG(0x420, vqLen); 46690b17f1bSmrg VIASETREG(0x420, 0x74301001); 46790b17f1bSmrg VIASETREG(0x420, 0x00000000); 46890b17f1bSmrg} 46990b17f1bSmrg 47090b17f1bSmrg/* 47190b17f1bSmrg * Disable the virtual command queue. 47290b17f1bSmrg */ 47390b17f1bSmrgvoid 47490b17f1bSmrgviaDisableVQ(ScrnInfoPtr pScrn) 47590b17f1bSmrg{ 47690b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 47790b17f1bSmrg 47803bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 47903bd066fSmrg "Entered viaDisableVQ.\n")); 48003bd066fSmrg 48190b17f1bSmrg switch (pVia->Chipset) { 48203bd066fSmrg case VIA_K8M890: 48303bd066fSmrg case VIA_P4M900: 48403bd066fSmrg case VIA_VX800: 48503bd066fSmrg case VIA_VX855: 48603bd066fSmrg case VIA_VX900: 48703bd066fSmrg VIASETREG(0x41c, 0x00100000); 48803bd066fSmrg VIASETREG(0x420, 0x74301000); 48903bd066fSmrg break; 49003bd066fSmrg default: 49103bd066fSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 49203bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00000004); 49303bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 49403bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 49503bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); 49603bd066fSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 49703bd066fSmrg break; 49890b17f1bSmrg } 49903bd066fSmrg 50003bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 50103bd066fSmrg "Exiting viaDisableVQ.\n")); 50290b17f1bSmrg} 50390b17f1bSmrg 50490b17f1bSmrg/* 50590b17f1bSmrg * Initialize the 2D engine and set the 2D context mode to the 50690b17f1bSmrg * current screen depth. Also enable the virtual queue. 50790b17f1bSmrg */ 50890b17f1bSmrgstatic void 50903bd066fSmrgviaInitialize2DEngine(ScrnInfoPtr pScrn) 51090b17f1bSmrg{ 51190b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 51290b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 51390b17f1bSmrg int i; 51490b17f1bSmrg 51590b17f1bSmrg /* Initialize the 2D engine registers to reset the 2D engine. */ 51690b17f1bSmrg for (i = 0x04; i <= 0x40; i += 4) { 51790b17f1bSmrg VIASETREG(i, 0x0); 51890b17f1bSmrg } 51990b17f1bSmrg 52090b17f1bSmrg if (pVia->Chipset == VIA_VX800 || 52190b17f1bSmrg pVia->Chipset == VIA_VX855 || 52290b17f1bSmrg pVia->Chipset == VIA_VX900) { 52390b17f1bSmrg for (i = 0x44; i <= 0x5c; i += 4) { 52490b17f1bSmrg VIASETREG(i, 0x0); 52590b17f1bSmrg } 52690b17f1bSmrg } 52790b17f1bSmrg 52890b17f1bSmrg if (pVia->Chipset == VIA_VX900) 52990b17f1bSmrg { 53090b17f1bSmrg /*410 redefine 0x30 34 38*/ 53190b17f1bSmrg VIASETREG(0x60, 0x0); /*already useable here*/ 53290b17f1bSmrg } 53390b17f1bSmrg 53490b17f1bSmrg switch (pVia->Chipset) { 53590b17f1bSmrg case VIA_K8M890: 53690b17f1bSmrg case VIA_P4M900: 53790b17f1bSmrg case VIA_VX800: 53890b17f1bSmrg case VIA_VX855: 53990b17f1bSmrg case VIA_VX900: 54090b17f1bSmrg viaInitPCIe(pVia); 54190b17f1bSmrg break; 54290b17f1bSmrg default: 54303bd066fSmrg viaInitAGP(pVia); 54490b17f1bSmrg break; 54590b17f1bSmrg } 54690b17f1bSmrg 54790b17f1bSmrg if (pVia->VQStart != 0) { 54890b17f1bSmrg switch (pVia->Chipset) { 54990b17f1bSmrg case VIA_K8M890: 55090b17f1bSmrg case VIA_P4M900: 55190b17f1bSmrg case VIA_VX800: 55290b17f1bSmrg case VIA_VX855: 55390b17f1bSmrg case VIA_VX900: 55490b17f1bSmrg viaEnablePCIeVQ(pVia); 55590b17f1bSmrg break; 55690b17f1bSmrg default: 55703bd066fSmrg viaEnableAGPVQ(pVia); 55890b17f1bSmrg break; 55990b17f1bSmrg } 56090b17f1bSmrg } else { 56190b17f1bSmrg viaDisableVQ(pScrn); 56290b17f1bSmrg } 56390b17f1bSmrg 56490b17f1bSmrg viaAccelSetMode(pScrn->bitsPerPixel, tdc); 56590b17f1bSmrg} 56690b17f1bSmrg 56790b17f1bSmrgstatic void 56803bd066fSmrgviaInitialize3DEngine(ScrnInfoPtr pScrn) 56990b17f1bSmrg{ 57090b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 57190b17f1bSmrg int i; 57290b17f1bSmrg 57390b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00010000); 57490b17f1bSmrg for (i = 0; i <= 0x7D; i++) 57590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 57690b17f1bSmrg 57790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00020000); 57890b17f1bSmrg for (i = 0; i <= 0x94; i++) 57990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 58090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 58190b17f1bSmrg 58290b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x01020000); 58390b17f1bSmrg for (i = 0; i <= 0x94; i++) 58490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 58590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x82400000); 58690b17f1bSmrg 58790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0xfe020000); 58890b17f1bSmrg for (i = 0; i <= 0x03; i++) 58990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, (CARD32) i << 24); 59090b17f1bSmrg 59190b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00030000); 59290b17f1bSmrg for (i = 0; i <= 0xff; i++) 59390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0); 59490b17f1bSmrg 59590b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00100000); 59690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x00333004); 59790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x10000002); 59890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x60000000); 59990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x61000000); 60090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x62000000); 60190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x63000000); 60290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x64000000); 60390b17f1bSmrg 60490b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 60590b17f1bSmrg if (pVia->Chipset == VIA_CLE266 && pVia->ChipRev >= 3) 60690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); 60790b17f1bSmrg else 60890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x4000800f); 60990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x44000000); 61090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x45080C04); 61190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x46800408); 61290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x50000000); 61390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x51000000); 61490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x52000000); 61590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x53000000); 61690b17f1bSmrg 61790b17f1bSmrg VIASETREG(VIA_REG_TRANSET, 0x00fe0000); 61890b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x08000001); 61990b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0A000183); 62090b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0B00019F); 62190b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0C00018B); 62290b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0D00019B); 62390b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0E000000); 62490b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x0F000000); 62590b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x10000000); 62690b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x11000000); 62790b17f1bSmrg VIASETREG(VIA_REG_TRANSPACE, 0x20000000); 62890b17f1bSmrg} 62990b17f1bSmrg 63090b17f1bSmrg/* 63190b17f1bSmrg * Acceleration initialization function. Sets up offscreen memory disposition, 63290b17f1bSmrg * and initializes engines and acceleration method. 63390b17f1bSmrg */ 63490b17f1bSmrgBool 63503bd066fSmrgumsAccelInit(ScreenPtr pScreen) 63690b17f1bSmrg{ 63790b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 63890b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 63990b17f1bSmrg Bool ret = FALSE; 64090b17f1bSmrg 64103bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 64203bd066fSmrg "Entered umsAccelInit.\n")); 64303bd066fSmrg 64490b17f1bSmrg pVia->VQStart = 0; 64590b17f1bSmrg pVia->vq_bo = drm_bo_alloc(pScrn, VIA_VQ_SIZE, 16, TTM_PL_FLAG_VRAM); 64690b17f1bSmrg if (!pVia->vq_bo) 64790b17f1bSmrg goto err; 64890b17f1bSmrg 64990b17f1bSmrg pVia->VQStart = pVia->vq_bo->offset; 65090b17f1bSmrg pVia->VQEnd = pVia->vq_bo->offset + pVia->vq_bo->size; 65190b17f1bSmrg 65203bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65303bd066fSmrg "Initializing the 2D engine.\n")); 65403bd066fSmrg viaInitialize2DEngine(pScrn); 65503bd066fSmrg 65603bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 65703bd066fSmrg "Initializing the 3D engine.\n")); 65803bd066fSmrg viaInitialize3DEngine(pScrn); 65990b17f1bSmrg 66090b17f1bSmrg pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 66190b17f1bSmrg if (!pVia->exa_sync_bo) 66290b17f1bSmrg goto err; 66390b17f1bSmrg 66490b17f1bSmrg /* Sync marker space. */ 66590b17f1bSmrg pVia->exa_sync_bo = drm_bo_alloc(pScrn, 32, 32, TTM_PL_FLAG_VRAM); 66690b17f1bSmrg if (!pVia->exa_sync_bo) 66790b17f1bSmrg goto err; 66890b17f1bSmrg 66990b17f1bSmrg pVia->markerOffset = pVia->exa_sync_bo->offset; 67090b17f1bSmrg pVia->markerBuf = drm_bo_map(pScrn, pVia->exa_sync_bo); 67190b17f1bSmrg if (!pVia->markerBuf) 67290b17f1bSmrg goto err; 67390b17f1bSmrg pVia->curMarker = 0; 67490b17f1bSmrg pVia->lastMarkerRead = 0; 67590b17f1bSmrg 67690b17f1bSmrg#ifdef HAVE_DRI 67790b17f1bSmrg pVia->dBounce = NULL; 67890b17f1bSmrg pVia->scratchAddr = NULL; 67990b17f1bSmrg#endif /* HAVE_DRI */ 68090b17f1bSmrg ret = TRUE; 68190b17f1bSmrgerr: 68290b17f1bSmrg if (!ret) { 68390b17f1bSmrg if (pVia->markerBuf) { 68490b17f1bSmrg drm_bo_unmap(pScrn, pVia->exa_sync_bo); 68590b17f1bSmrg pVia->markerBuf = NULL; 68690b17f1bSmrg } 68790b17f1bSmrg if (pVia->exa_sync_bo) 68890b17f1bSmrg drm_bo_free(pScrn, pVia->exa_sync_bo); 68990b17f1bSmrg if (pVia->vq_bo) 69090b17f1bSmrg drm_bo_free(pScrn, pVia->vq_bo); 69190b17f1bSmrg } 69203bd066fSmrg 69303bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 69403bd066fSmrg "Exiting umsAccelInit.\n")); 69590b17f1bSmrg return ret; 69690b17f1bSmrg} 69790b17f1bSmrg 69890b17f1bSmrgBool 69903bd066fSmrgumsCreate(ScrnInfoPtr pScrn) 70090b17f1bSmrg{ 70190b17f1bSmrg ScreenPtr pScreen = pScrn->pScreen; 70290b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 70390b17f1bSmrg unsigned long offset; 70490b17f1bSmrg BoxRec AvailFBArea; 70590b17f1bSmrg Bool ret = TRUE; 70690b17f1bSmrg long size; 70790b17f1bSmrg int maxY; 70890b17f1bSmrg 70990b17f1bSmrg#ifdef HAVE_DRI 71090b17f1bSmrg if (pVia->directRenderingType == DRI_1) { 71190b17f1bSmrg pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) >> 2; 71290b17f1bSmrg if ((pVia->driSize > (pVia->maxDriSize * 1024)) && pVia->maxDriSize > 0) 71390b17f1bSmrg pVia->driSize = pVia->maxDriSize * 1024; 71490b17f1bSmrg 71590b17f1bSmrg /* In the case of DRI we handle all VRAM by the DRI ioctls */ 71690b17f1bSmrg if (pVia->useEXA) 71790b17f1bSmrg return TRUE; 71890b17f1bSmrg 71990b17f1bSmrg /* XAA has to use FBManager so we have to split the space with DRI */ 72090b17f1bSmrg maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); 72190b17f1bSmrg } else 72290b17f1bSmrg#endif 72390b17f1bSmrg maxY = pVia->FBFreeEnd / pVia->Bpl; 72490b17f1bSmrg 72590b17f1bSmrg /* FBManager can't handle more than 32767 scan lines */ 72690b17f1bSmrg if (maxY > 32767) 72790b17f1bSmrg maxY = 32767; 72890b17f1bSmrg 72990b17f1bSmrg AvailFBArea.x1 = 0; 73090b17f1bSmrg AvailFBArea.y1 = 0; 73190b17f1bSmrg AvailFBArea.x2 = pScrn->displayWidth; 73290b17f1bSmrg AvailFBArea.y2 = maxY; 73390b17f1bSmrg pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; 73490b17f1bSmrg 73590b17f1bSmrg /* 73690b17f1bSmrg * Initialization of the XFree86 framebuffer manager is done via 73790b17f1bSmrg * Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox) 73890b17f1bSmrg * FullBox represents the area of the framebuffer that the manager 73990b17f1bSmrg * is allowed to manage. This is typically a box with a width 74090b17f1bSmrg * of pScrn->displayWidth and a height of as many lines as can be fit 74190b17f1bSmrg * within the total video memory 74290b17f1bSmrg */ 74390b17f1bSmrg ret = xf86InitFBManager(pScreen, &AvailFBArea); 74490b17f1bSmrg if (ret != TRUE) 74590b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86InitFBManager init failed\n"); 74690b17f1bSmrg 74790b17f1bSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 74890b17f1bSmrg "Frame Buffer From (%d,%d) To (%d,%d)\n", 74990b17f1bSmrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2)); 75090b17f1bSmrg 75190b17f1bSmrg offset = (pVia->FBFreeStart + pVia->Bpp - 1) / pVia->Bpp; 75290b17f1bSmrg size = pVia->FBFreeEnd / pVia->Bpp - offset; 75390b17f1bSmrg if (size > 0) 75490b17f1bSmrg xf86InitFBManagerLinear(pScreen, offset, size); 75590b17f1bSmrg 75690b17f1bSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 75790b17f1bSmrg "Using %d lines for offscreen memory.\n", 75890b17f1bSmrg AvailFBArea.y2 - pScrn->virtualY)); 75990b17f1bSmrg return TRUE; 76090b17f1bSmrg} 76190b17f1bSmrg 76290b17f1bSmrgBool 76303bd066fSmrgumsPreInit(ScrnInfoPtr pScrn) 76490b17f1bSmrg{ 76590b17f1bSmrg MessageType from = X_PROBED; 76690b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 76790b17f1bSmrg CARD8 videoRam; 76890b17f1bSmrg vgaHWPtr hwp; 76990b17f1bSmrg#ifdef HAVE_PCIACCESS 77090b17f1bSmrg struct pci_device *vgaDevice = pci_device_find_by_slot(0, 0, 0, 3); 77190b17f1bSmrg struct pci_device *bridge = pci_device_find_by_slot(0, 0, 0, 0); 77290b17f1bSmrg#endif 77390b17f1bSmrg int bMemSize = 0; 77490b17f1bSmrg 77590b17f1bSmrg if (!xf86LoadSubModule(pScrn, "vgahw")) 77690b17f1bSmrg return FALSE; 77790b17f1bSmrg 77890b17f1bSmrg if (!vgaHWGetHWRec(pScrn)) 77990b17f1bSmrg return FALSE; 78090b17f1bSmrg 78190b17f1bSmrg#if 0 78290b17f1bSmrg /* Here we can alter the number of registers saved and restored by the 78390b17f1bSmrg * standard vgaHWSave and Restore routines. 78490b17f1bSmrg */ 78590b17f1bSmrg vgaHWSetRegCounts(pScrn, VGA_NUM_CRTC, VGA_NUM_SEQ, VGA_NUM_GFX, 78690b17f1bSmrg VGA_NUM_ATTR); 78790b17f1bSmrg#endif 78890b17f1bSmrg hwp = VGAHWPTR(pScrn); 78990b17f1bSmrg 79090b17f1bSmrg switch (pVia->Chipset) { 79190b17f1bSmrg case VIA_CLE266: 79290b17f1bSmrg#ifdef HAVE_PCIACCESS 79390b17f1bSmrg pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 79490b17f1bSmrg#else 79590b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 79690b17f1bSmrg#endif 79790b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 79890b17f1bSmrg break; 79990b17f1bSmrg case VIA_KM400: 80090b17f1bSmrg#ifdef HAVE_PCIACCESS 801963d66acSmrg /* P4M800 Host Bridge PCI Device ID */ 802963d66acSmrg if (DEVICE_ID(bridge) == 0x0296) { 80390b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 80490b17f1bSmrg } else { 80590b17f1bSmrg pci_device_cfg_read_u8(bridge, &videoRam, 0xE1); 806963d66acSmrg } 80790b17f1bSmrg#else 808963d66acSmrg /* P4M800 Host Bridge PCI Device ID */ 809963d66acSmrg if (pciReadWord(pciTag(0, 0, 0), 0x02) == 0x0296) { 810963d66acSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 811963d66acSmrg } else { 81290b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 0), 0xE1) & 0x70; 81390b17f1bSmrg } 814963d66acSmrg#endif 81590b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 81690b17f1bSmrg break; 81790b17f1bSmrg case VIA_PM800: 818963d66acSmrg case VIA_P4M800PRO: 81990b17f1bSmrg case VIA_K8M800: 82090b17f1bSmrg#ifdef HAVE_PCIACCESS 82190b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 82290b17f1bSmrg#else 82390b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 82490b17f1bSmrg#endif 82590b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 10; 82690b17f1bSmrg break; 82790b17f1bSmrg case VIA_P4M890: 828963d66acSmrg case VIA_K8M890: 82990b17f1bSmrg case VIA_P4M900: 83090b17f1bSmrg case VIA_CX700: 83190b17f1bSmrg case VIA_VX800: 83290b17f1bSmrg case VIA_VX855: 83390b17f1bSmrg case VIA_VX900: 83490b17f1bSmrg#ifdef HAVE_PCIACCESS 83590b17f1bSmrg pci_device_cfg_read_u8(vgaDevice, &videoRam, 0xA1); 83690b17f1bSmrg#else 83790b17f1bSmrg videoRam = pciReadByte(pciTag(0, 0, 3), 0xA1) & 0x70; 83890b17f1bSmrg#endif 83990b17f1bSmrg pScrn->videoRam = (1 << ((videoRam & 0x70) >> 4)) << 12; 84090b17f1bSmrg break; 84190b17f1bSmrg default: 84290b17f1bSmrg if (pScrn->videoRam < 16384 || pScrn->videoRam > 65536) { 84390b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 84490b17f1bSmrg "Using old memory-detection method.\n"); 84590b17f1bSmrg bMemSize = hwp->readSeq(hwp, 0x39); 84690b17f1bSmrg if (bMemSize > 16 && bMemSize <= 128) 84790b17f1bSmrg pScrn->videoRam = (bMemSize + 1) << 9; 84890b17f1bSmrg else if (bMemSize > 0 && bMemSize < 31) 84990b17f1bSmrg pScrn->videoRam = bMemSize << 12; 85090b17f1bSmrg else { 85190b17f1bSmrg from = X_DEFAULT; 85290b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 85390b17f1bSmrg "Memory size detection failed: using 16 MB.\n"); 85490b17f1bSmrg pScrn->videoRam = 16 << 10; 85590b17f1bSmrg } 85690b17f1bSmrg } else { 85790b17f1bSmrg from = X_DEFAULT; 85890b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 85990b17f1bSmrg "No memory-detection done. Use VideoRAM option.\n"); 86090b17f1bSmrg } 86190b17f1bSmrg } 86290b17f1bSmrg 86390b17f1bSmrg /* 86490b17f1bSmrg * PCI BAR are limited to 256 MB. 86590b17f1bSmrg */ 86690b17f1bSmrg if (pScrn->videoRam > (256 << 10)) { 86790b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 86890b17f1bSmrg "Cannot use more than 256 MB of VRAM.\n"); 86990b17f1bSmrg pScrn->videoRam = (256 << 10); 87090b17f1bSmrg } 87190b17f1bSmrg 87290b17f1bSmrg if (from == X_PROBED) { 87390b17f1bSmrg xf86DrvMsg(pScrn->scrnIndex, from, 87490b17f1bSmrg "Probed amount of VideoRAM = %d kB\n", pScrn->videoRam); 87590b17f1bSmrg } 87690b17f1bSmrg 87790b17f1bSmrg /* Split the FB for SAMM. */ 87890b17f1bSmrg /* FIXME: For now, split the FB into two equal sections. 87990b17f1bSmrg * This should be user-adjustable via a config option. */ 88090b17f1bSmrg if (pVia->IsSecondary) { 88190b17f1bSmrg DevUnion *pPriv; 88290b17f1bSmrg VIAEntPtr pVIAEnt; 88390b17f1bSmrg VIAPtr pVia1; 88490b17f1bSmrg 88590b17f1bSmrg pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gVIAEntityIndex); 88690b17f1bSmrg pVIAEnt = pPriv->ptr; 88790b17f1bSmrg pScrn->videoRam = pScrn->videoRam >> 1; 88890b17f1bSmrg pVIAEnt->pPrimaryScrn->videoRam = pScrn->videoRam; 88990b17f1bSmrg pVia1 = VIAPTR(pVIAEnt->pPrimaryScrn); 89090b17f1bSmrg pVia1->videoRambytes = pScrn->videoRam << 10; 89190b17f1bSmrg pVia->FrameBufferBase += (pScrn->videoRam << 10); 89290b17f1bSmrg } 89390b17f1bSmrg 89490b17f1bSmrg pVia->videoRambytes = pScrn->videoRam << 10; 89590b17f1bSmrg 89690b17f1bSmrg /* maybe throw in some more sanity checks here */ 89790b17f1bSmrg#ifndef HAVE_PCIACCESS 89890b17f1bSmrg pVia->PciTag = pciTag(pVia->PciInfo->bus, pVia->PciInfo->device, 89990b17f1bSmrg pVia->PciInfo->func); 90090b17f1bSmrg#endif 90190b17f1bSmrg 90203bd066fSmrg /* Map PCI hardware resources to the memory map. */ 90303bd066fSmrg if (!viaMapMMIO(pScrn)) { 90403bd066fSmrg return FALSE; 90503bd066fSmrg } 90603bd066fSmrg 90703bd066fSmrg return TRUE; 90803bd066fSmrg} 90903bd066fSmrg 91003bd066fSmrgBool 91103bd066fSmrgumsCrtcInit(ScrnInfoPtr pScrn) 91203bd066fSmrg{ 91303bd066fSmrg drmmode_crtc_private_ptr iga1_rec = NULL, iga2_rec = NULL; 91403bd066fSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 91503bd066fSmrg VIAPtr pVia = VIAPTR(pScrn); 91603bd066fSmrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 91703bd066fSmrg ClockRangePtr clockRanges; 91803bd066fSmrg#else 91903bd066fSmrg ClockRangesPtr clockRanges; 92003bd066fSmrg#endif 92103bd066fSmrg int max_pitch, max_height; 92203bd066fSmrg VIABIOSInfoPtr pBIOSInfo; 92303bd066fSmrg xf86CrtcPtr iga1, iga2; 92403bd066fSmrg 9251090d90aSmrg /* 3X5.3B through 3X5.3F are scratch pad registers. */ 9261090d90aSmrg pVia->originalCR3B = hwp->readCrtc(hwp, 0x3B); 9271090d90aSmrg pVia->originalCR3C = hwp->readCrtc(hwp, 0x3C); 9281090d90aSmrg pVia->originalCR3D = hwp->readCrtc(hwp, 0x3D); 9291090d90aSmrg pVia->originalCR3E = hwp->readCrtc(hwp, 0x3E); 9301090d90aSmrg pVia->originalCR3F = hwp->readCrtc(hwp, 0x3F); 9311090d90aSmrg 93203bd066fSmrg /* Read memory bandwidth from registers. */ 93303bd066fSmrg pVia->MemClk = hwp->readCrtc(hwp, 0x3D) >> 4; 93403bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 93503bd066fSmrg "Detected MemClk %d\n", pVia->MemClk)); 93603bd066fSmrg if (pVia->MemClk >= VIA_MEM_END) { 93703bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 93803bd066fSmrg "Unknown Memory clock: %d\n", pVia->MemClk); 93903bd066fSmrg pVia->MemClk = VIA_MEM_END - 1; 94003bd066fSmrg } 94103bd066fSmrg pBIOSInfo = pVia->pBIOSInfo; 94203bd066fSmrg pBIOSInfo->Bandwidth = ViaGetMemoryBandwidth(pScrn); 94303bd066fSmrg 94403bd066fSmrg if (pBIOSInfo->TVType == TVTYPE_NONE) { 94503bd066fSmrg /* Use jumper to determine TV type. */ 94603bd066fSmrg if (hwp->readCrtc(hwp, 0x3B) & 0x02) { 94703bd066fSmrg pBIOSInfo->TVType = TVTYPE_PAL; 94803bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 94903bd066fSmrg "Detected TV standard: PAL.\n")); 95003bd066fSmrg } else { 95103bd066fSmrg pBIOSInfo->TVType = TVTYPE_NTSC; 95203bd066fSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 95303bd066fSmrg "Detected TV standard: NTSC.\n")); 95403bd066fSmrg } 95503bd066fSmrg } 95603bd066fSmrg 95703bd066fSmrg if (pVia->drmmode.hwcursor) { 95803bd066fSmrg if (!xf86LoadSubModule(pScrn, "ramdac")) 95903bd066fSmrg return FALSE; 96003bd066fSmrg } 96103bd066fSmrg 96203bd066fSmrg if (!xf86LoadSubModule(pScrn, "i2c")) 96303bd066fSmrg return FALSE; 96403bd066fSmrg else 96503bd066fSmrg ViaI2CInit(pScrn); 96603bd066fSmrg 96703bd066fSmrg if (!xf86LoadSubModule(pScrn, "ddc")) 96803bd066fSmrg return FALSE; 96903bd066fSmrg 97003bd066fSmrg /* 97103bd066fSmrg * Set up ClockRanges, which describe what clock ranges are 97203bd066fSmrg * available, and what sort of modes they can be used for. 97303bd066fSmrg */ 97403bd066fSmrg 97503bd066fSmrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,8,0,0,0) 97603bd066fSmrg clockRanges = xnfalloc(sizeof(ClockRange)); 97703bd066fSmrg#else 97803bd066fSmrg clockRanges = xnfalloc(sizeof(ClockRanges)); 97903bd066fSmrg#endif 98003bd066fSmrg clockRanges->next = NULL; 98103bd066fSmrg clockRanges->minClock = 20000; 98203bd066fSmrg clockRanges->maxClock = 230000; 98303bd066fSmrg 98403bd066fSmrg clockRanges->clockIndex = -1; 98503bd066fSmrg clockRanges->interlaceAllowed = TRUE; 98603bd066fSmrg clockRanges->doubleScanAllowed = FALSE; 98703bd066fSmrg pScrn->clockRanges = clockRanges; 98803bd066fSmrg 98903bd066fSmrg /* 99003bd066fSmrg * Now handle the outputs 99103bd066fSmrg */ 99203bd066fSmrg iga1_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 99303bd066fSmrg if (!iga1_rec) { 99403bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 99590b17f1bSmrg return FALSE; 99603bd066fSmrg } 99703bd066fSmrg 99803bd066fSmrg iga1 = xf86CrtcCreate(pScrn, &iga1_crtc_funcs); 99903bd066fSmrg if (!iga1) { 100003bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 100103bd066fSmrg free(iga1_rec); 100203bd066fSmrg return FALSE; 100303bd066fSmrg } 100403bd066fSmrg iga1_rec->drmmode = &pVia->drmmode; 100503bd066fSmrg iga1_rec->index = 0; 100603bd066fSmrg iga1->driver_private = iga1_rec; 100703bd066fSmrg 100803bd066fSmrg iga2_rec = (drmmode_crtc_private_ptr) xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 100903bd066fSmrg if (!iga2_rec) { 101003bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "IGA1 Rec allocation failed.\n"); 101103bd066fSmrg xf86CrtcDestroy(iga1); 101203bd066fSmrg return FALSE; 101303bd066fSmrg } 101490b17f1bSmrg 101503bd066fSmrg iga2 = xf86CrtcCreate(pScrn, &iga2_crtc_funcs); 101603bd066fSmrg if (!iga2) { 101703bd066fSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "xf86CrtcCreate failed.\n"); 101803bd066fSmrg xf86CrtcDestroy(iga1); 101903bd066fSmrg free(iga2_rec); 102090b17f1bSmrg return FALSE; 102103bd066fSmrg } 102203bd066fSmrg iga2_rec->drmmode = &pVia->drmmode; 102303bd066fSmrg iga2_rec->index = 1; 102403bd066fSmrg iga2->driver_private = iga2_rec; 102503bd066fSmrg 10261090d90aSmrg if (!pScrn->bitsPerPixel) { 10271090d90aSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 10281090d90aSmrg "Detected bitsPerPixel to be 0 bit.\n"); 10291090d90aSmrg xf86CrtcDestroy(iga2); 10301090d90aSmrg xf86CrtcDestroy(iga1); 10311090d90aSmrg return FALSE; 103203bd066fSmrg } 103303bd066fSmrg 103403bd066fSmrg /* 103503bd066fSmrg * CLE266A: 103603bd066fSmrg * Max Line Pitch: 4080, (FB corruption when higher, driver problem?) 103703bd066fSmrg * Max Height: 4096 (and beyond) 103803bd066fSmrg * 103903bd066fSmrg * CLE266A: primary AdjustFrame can use only 24 bits, so we are limited 104003bd066fSmrg * to 12x11 bits; 4080x2048 (~2:1), 3344x2508 (4:3), or 2896x2896 (1:1). 104103bd066fSmrg * TODO Test CLE266Cx, KM400, KM400A, K8M800, CN400 please. 104203bd066fSmrg * 104303bd066fSmrg * We should be able to limit the memory available for a mode to 32 MB, 104403bd066fSmrg * but miScanLineWidth fails to catch this properly (apertureSize). 104503bd066fSmrg */ 10461090d90aSmrg max_pitch = (8192 / ((pScrn->bitsPerPixel + 7) >> 3)) - (16 / ((pScrn->bitsPerPixel + 7) >> 3)); 10471090d90aSmrg max_height = 8192 / ((pScrn->bitsPerPixel + 7) >> 3); 104803bd066fSmrg 104903bd066fSmrg xf86CrtcSetSizeRange(pScrn, 320, 200, max_pitch, max_height); 105003bd066fSmrg 105103bd066fSmrg viaOutputDetect(pScrn); 105203bd066fSmrg 105390b17f1bSmrg return TRUE; 105490b17f1bSmrg} 1055