gx_driver.c revision 3406bd8e
1f29dbc25Smrg/* Copyright (c) 2003-2006 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Portioned modeled from xf86-video-intel/src/i830_driver.c 4f29dbc25Smrg * Copyright 2001 VA Linux Systems Inc., Fremont, California. 5f29dbc25Smrg * Copyright \ufffd 2002 by David Dawes 6f29dbc25Smrg 7f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 8f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 9f29dbc25Smrg * deal in the Software without restriction, including without limitation the 10f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 12f29dbc25Smrg * furnished to do so, subject to the following conditions: 13f29dbc25Smrg * 14f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 15f29dbc25Smrg * all copies or substantial portions of the Software. 16f29dbc25Smrg * 17f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23f29dbc25Smrg * IN THE SOFTWARE. 24f29dbc25Smrg * 25f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 26f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 27f29dbc25Smrg * software without specific prior written permission. 28f29dbc25Smrg */ 29f29dbc25Smrg 30f29dbc25Smrg#ifdef HAVE_CONFIG_H 31f29dbc25Smrg#include "config.h" 32f29dbc25Smrg#endif 33f29dbc25Smrg 34f29dbc25Smrg#include <stdio.h> 357f419768Smrg#include <fcntl.h> 367f419768Smrg#include <unistd.h> 377f419768Smrg#include <sys/mman.h> 38f29dbc25Smrg 393406bd8eSmrg#include "xorg-server.h" 40f29dbc25Smrg#include "xf86.h" 41f29dbc25Smrg#include "xf86_OSproc.h" 42f29dbc25Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 43f29dbc25Smrg#include "xf86Resources.h" 44f29dbc25Smrg#endif 45f29dbc25Smrg#include "xf86cmap.h" 46f29dbc25Smrg#include "compiler.h" 47f29dbc25Smrg#include "mipointer.h" 48f29dbc25Smrg#include "shadow.h" 49f29dbc25Smrg#include <X11/extensions/randr.h> 50f29dbc25Smrg#include "fb.h" 51f29dbc25Smrg#include "miscstruct.h" 52f29dbc25Smrg#include "micmap.h" 53f29dbc25Smrg#include "vbe.h" 54f29dbc25Smrg#include "fb.h" 55f29dbc25Smrg#include "randrstr.h" 56f29dbc25Smrg 57f29dbc25Smrg#include "geode.h" 58f29dbc25Smrg#include "gfx_defs.h" 59f29dbc25Smrg#include "gfx_regs.h" 60f29dbc25Smrg#include "panel.h" 61f29dbc25Smrg 62f29dbc25Smrg/* Bring in VGA functions */ 63f29dbc25Smrg#include "gx_vga.c" 64f29dbc25Smrg 65f29dbc25Smrg#define GX_MIN_PITCH 1024 66f29dbc25Smrg#define GX_MAX_PITCH 8192 67f29dbc25Smrg#define GX_MAX_WIDTH 1600 68f29dbc25Smrg#define GX_MIN_HEIGHT 400 69f29dbc25Smrg#define GX_MAX_HEIGHT 1200 70f29dbc25Smrg#define GX_CB_PITCH 544 71f29dbc25Smrg#define GX_CB_SIZE 544 72f29dbc25Smrg 73f29dbc25Smrg#define GX_CPU_REG_SIZE 0x4000 74f29dbc25Smrg#define GX_GP_REG_SIZE 0x4000 75f29dbc25Smrg#define GX_VID_REG_SIZE 0x4000 76f29dbc25Smrg 77f29dbc25Smrg#define DEFAULT_IMG_LINE_BUFS 20 78f29dbc25Smrg#define DEFAULT_CLR_LINE_BUFS 20 79f29dbc25Smrg 80f29dbc25Smrgextern OptionInfoRec GX_GeodeOptions[]; 81f29dbc25Smrg 82f29dbc25Smrgunsigned char *XpressROMPtr; 83f29dbc25Smrg 84f29dbc25Smrgstatic inline void 85f29dbc25Smrggx_enable_dac_power(void) 86f29dbc25Smrg{ 87f29dbc25Smrg gfx_write_vid32(RCDF_VID_MISC, 8804007ebaSmrg gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); 89f29dbc25Smrg} 90f29dbc25Smrg 91f29dbc25Smrgstatic inline void 92f29dbc25Smrggx_disable_dac_power(void) 93f29dbc25Smrg{ 94f29dbc25Smrg gfx_write_vid32(RCDF_VID_MISC, 9504007ebaSmrg RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | 9604007ebaSmrg (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); 97f29dbc25Smrg} 98f29dbc25Smrg 99f29dbc25Smrgstatic void 100f29dbc25SmrgGXInitEXAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) 101f29dbc25Smrg{ 102f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 103f29dbc25Smrg 104f29dbc25Smrg if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= *avail) { 10504007ebaSmrg pGeode->exaBfrOffset = *offset; 10604007ebaSmrg *offset += pGeode->exaBfrOffset; 10704007ebaSmrg *avail -= pGeode->exaBfrOffset; 108f29dbc25Smrg } 109f29dbc25Smrg} 110f29dbc25Smrg 111f29dbc25Smrgstatic void 112f29dbc25SmrgGXInitXAAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) 113f29dbc25Smrg{ 114f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 115f29dbc25Smrg unsigned int size, i, pitch; 116f29dbc25Smrg 117f29dbc25Smrg /* XXX - FIXME - What if we are out of room? Then what? */ 118f29dbc25Smrg /* For now, we NULL them all out. */ 119f29dbc25Smrg 120f29dbc25Smrg if (pGeode->NoOfImgBuffers > 0) { 12104007ebaSmrg size = pGeode->displayPitch * pGeode->NoOfImgBuffers; 12204007ebaSmrg if (size <= *avail) { 12304007ebaSmrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) { 12404007ebaSmrg pGeode->AccelImageWriteBuffers[i] = pGeode->FBBase + *offset; 12504007ebaSmrg *offset += pGeode->displayPitch; 12604007ebaSmrg *avail -= pGeode->displayPitch; 12704007ebaSmrg } 12804007ebaSmrg } 12904007ebaSmrg else { 13004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 13104007ebaSmrg "Not enough memory for image write buffers.\n"); 13204007ebaSmrg 13304007ebaSmrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) 13404007ebaSmrg pGeode->AccelImageWriteBuffers[i] = NULL; 13504007ebaSmrg } 136f29dbc25Smrg } 137f29dbc25Smrg 138f29dbc25Smrg if (pGeode->NoOfColorExpandLines > 0) { 13904007ebaSmrg pitch = ((pGeode->displayPitch + 31) >> 5) << 2; 14004007ebaSmrg size = pitch * pGeode->NoOfColorExpandLines; 14104007ebaSmrg 14204007ebaSmrg if (size <= *avail) { 14304007ebaSmrg for (i = 0; i < pGeode->NoOfColorExpandLines; i++) { 14404007ebaSmrg pGeode->AccelColorExpandBuffers[i] = pGeode->FBBase + *offset; 14504007ebaSmrg *offset += pitch; 14604007ebaSmrg *avail -= pitch; 14704007ebaSmrg } 14804007ebaSmrg } 14904007ebaSmrg else { 15004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 15104007ebaSmrg "Not enough memory for color expansion buffers.\n"); 15204007ebaSmrg 15304007ebaSmrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) 15404007ebaSmrg pGeode->AccelColorExpandBuffers[i] = NULL; 15504007ebaSmrg } 156f29dbc25Smrg } 157f29dbc25Smrg} 158f29dbc25Smrg 159f29dbc25Smrgstatic Bool 160f29dbc25SmrgGXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) 161f29dbc25Smrg{ 162f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 163f29dbc25Smrg 164f29dbc25Smrg unsigned int fboffset, fbavail; 165f29dbc25Smrg unsigned int size; 166f29dbc25Smrg unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; 167f29dbc25Smrg BOOL ret = TRUE; 168f29dbc25Smrg 169f29dbc25Smrg if (pGeode->tryCompression) 17004007ebaSmrg pGeode->displayPitch = 17104007ebaSmrg GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); 172f29dbc25Smrg else 17304007ebaSmrg pGeode->displayPitch = 17404007ebaSmrg ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 175f29dbc25Smrg 176f29dbc25Smrg pGeode->Pitch = pGeode->displayPitch; 177f29dbc25Smrg pGeode->displayWidth = pGeode->displayPitch / bytpp; 178f29dbc25Smrg pScrni->displayWidth = pGeode->displayWidth; 179f29dbc25Smrg 180f29dbc25Smrg fbavail = pGeode->FBAvail - 0x4000; 181f29dbc25Smrg 182f29dbc25Smrg pGeode->displayOffset = fboffset = 0; 183f29dbc25Smrg pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; 184f29dbc25Smrg 185f29dbc25Smrg fbavail -= pGeode->displaySize; 186f29dbc25Smrg fboffset += pGeode->displaySize; 187f29dbc25Smrg 188f29dbc25Smrg if (pGeode->tryCompression) { 18904007ebaSmrg size = pScrni->virtualY * GX_CB_PITCH; 190f29dbc25Smrg 19104007ebaSmrg if (size <= fbavail) { 19204007ebaSmrg pGeode->CBData.compression_offset = fboffset; 193f29dbc25Smrg 19404007ebaSmrg fboffset += size; 19504007ebaSmrg fbavail -= size; 196f29dbc25Smrg 19704007ebaSmrg pGeode->Compression = TRUE; 19804007ebaSmrg } 19904007ebaSmrg else { 20004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 20104007ebaSmrg "Not enough memory for compression\n"); 20204007ebaSmrg pGeode->Compression = FALSE; 20304007ebaSmrg } 204f29dbc25Smrg } 205f29dbc25Smrg 206f29dbc25Smrg if (pGeode->tryHWCursor) { 207f29dbc25Smrg 20804007ebaSmrg if (fbavail >= 1024) { 20904007ebaSmrg pGeode->CursorStartOffset = fboffset; 21004007ebaSmrg fboffset += 1024; 21104007ebaSmrg fbavail -= 1024; 21204007ebaSmrg pGeode->HWCursor = TRUE; 21304007ebaSmrg } 21404007ebaSmrg else { 21504007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 21604007ebaSmrg "Not enough memory for the hardware cursor\n"); 21704007ebaSmrg pGeode->HWCursor = FALSE; 21804007ebaSmrg } 219f29dbc25Smrg } 220f29dbc25Smrg 221f29dbc25Smrg if (!pGeode->NoAccel) { 22204007ebaSmrg if (pGeode->useEXA) 22304007ebaSmrg GXInitEXAMemory(pScrni, &fboffset, &fbavail); 22404007ebaSmrg else 22504007ebaSmrg GXInitXAAMemory(pScrni, &fboffset, &fbavail); 226f29dbc25Smrg } 227f29dbc25Smrg 228f29dbc25Smrg pGeode->shadowSize = 0; 229f29dbc25Smrg 230f29dbc25Smrg if (rotate != RR_Rotate_0) { 23104007ebaSmrg if (rotate & (RR_Rotate_90 | RR_Rotate_270)) 23204007ebaSmrg size = pGeode->displayPitch * pScrni->virtualX; 23304007ebaSmrg else 23404007ebaSmrg size = pGeode->displayPitch * pScrni->virtualY; 23504007ebaSmrg 23604007ebaSmrg if (size <= fbavail) { 23704007ebaSmrg pGeode->shadowOffset = fboffset; 23804007ebaSmrg pGeode->shadowSize = size; 23904007ebaSmrg 24004007ebaSmrg fboffset += size; 24104007ebaSmrg fbavail -= size; 24204007ebaSmrg } 24304007ebaSmrg else { 24404007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 24504007ebaSmrg "Not enough memory for the shadow framebuffer\n"); 24604007ebaSmrg ret = FALSE; 24704007ebaSmrg } 248f29dbc25Smrg } 249f29dbc25Smrg 250f29dbc25Smrg /* XAA always exists - we can't remove it on demand like we can with EXA. 251f29dbc25Smrg * So we assume the worse, and only give XAA enough offspace room to 252f29dbc25Smrg * account for any eventuality that RandR might throw at us. */ 253f29dbc25Smrg 254f29dbc25Smrg if (!pGeode->NoAccel) { 255f29dbc25Smrg 25604007ebaSmrg if (pGeode->useEXA && pGeode->pExa) { 25704007ebaSmrg ExaDriverPtr pExa = pGeode->pExa; 258f29dbc25Smrg 25904007ebaSmrg pExa->offScreenBase = fboffset; 26004007ebaSmrg pExa->memorySize = fboffset + fbavail; 26104007ebaSmrg } 262f29dbc25Smrg 26304007ebaSmrg if (!pGeode->useEXA) { 264f29dbc25Smrg 26504007ebaSmrg#if XF86XAA 26604007ebaSmrg if (!xf86FBManagerRunning(pScrn)) { 267f29dbc25Smrg 26804007ebaSmrg unsigned int offset = fboffset; 26904007ebaSmrg unsigned int avail = fbavail; 27004007ebaSmrg RegionRec OffscreenRegion; 27104007ebaSmrg BoxRec AvailBox; 272f29dbc25Smrg 27304007ebaSmrg /* Assume the shadow FB exists even if it doesnt */ 274f29dbc25Smrg 27504007ebaSmrg if (pGeode->shadowSize == 0) { 27604007ebaSmrg size = (pScrn->width * bytpp) * pScrni->virtualX; 27704007ebaSmrg offset += size; 27804007ebaSmrg avail -= size; 27904007ebaSmrg } 280f29dbc25Smrg 28104007ebaSmrg AvailBox.x1 = 0; 28204007ebaSmrg AvailBox.y1 = 28304007ebaSmrg (offset + pGeode->displayPitch - 1) / pGeode->displayPitch; 284f29dbc25Smrg 28504007ebaSmrg AvailBox.x2 = pGeode->displayWidth; 28604007ebaSmrg AvailBox.y2 = (offset + avail) / pGeode->displayPitch; 287f29dbc25Smrg 28804007ebaSmrg if (AvailBox.y1 < AvailBox.y2) { 28904007ebaSmrg REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); 290f29dbc25Smrg 29104007ebaSmrg if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) 29204007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 29304007ebaSmrg "Memory manager initialization failed.\n"); 294f29dbc25Smrg 29504007ebaSmrg REGION_UNINIT(pScrn, &OffscreenRegion); 29604007ebaSmrg } 29704007ebaSmrg else 29804007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 29904007ebaSmrg "Cache disabled - no offscreen memory available.\n"); 30004007ebaSmrg } 30104007ebaSmrg else 30204007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 30304007ebaSmrg "XAA offscreen memory has already been allocated.\n"); 30404007ebaSmrg#endif 30504007ebaSmrg } 306f29dbc25Smrg } 307f29dbc25Smrg return ret; 308f29dbc25Smrg} 309f29dbc25Smrg 310f29dbc25Smrgstatic Bool 311f29dbc25SmrgGXSaveScreen(ScreenPtr pScrn, int mode) 312f29dbc25Smrg{ 31304007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 314f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 315f29dbc25Smrg 316f29dbc25Smrg if (pGeode->useVGA && !pScrni->vtSema) 31704007ebaSmrg return vgaHWSaveScreen(pScrn, mode); 318f29dbc25Smrg 319f29dbc25Smrg return TRUE; 320f29dbc25Smrg} 321f29dbc25Smrg 322f29dbc25Smrg/* Common function - used by the LX too */ 323f29dbc25Smrg#ifdef XSERVER_LIBPCIACCESS 324f29dbc25Smrgstatic inline void * 325f29dbc25Smrgmap_pci_mem(ScrnInfoPtr pScrni, int vram, 32604007ebaSmrg struct pci_device *dev, int bar, int size) 327f29dbc25Smrg{ 328f29dbc25Smrg void *ptr; 329f29dbc25Smrg int map_size = size ? size : dev->regions[bar].size; 330f29dbc25Smrg 331f29dbc25Smrg int err = pci_device_map_range(dev, 33204007ebaSmrg dev->regions[bar].base_addr, 33304007ebaSmrg map_size, 33404007ebaSmrg PCI_DEV_MAP_FLAG_WRITABLE | 33504007ebaSmrg (vram ? PCI_DEV_MAP_FLAG_WRITE_COMBINE : 0), 3367f419768Smrg &ptr); 337f29dbc25Smrg 338f29dbc25Smrg if (err) 33904007ebaSmrg return NULL; 340f29dbc25Smrg return ptr; 341f29dbc25Smrg} 3427f419768Smrg 3437f419768Smrgstatic inline int 3447f419768Smrgunmap_pci_mem(ScrnInfoPtr pScrni, struct pci_device *dev, void *ptr, int size) 3457f419768Smrg{ 3467f419768Smrg return pci_device_unmap_range(dev, ptr, size); 3477f419768Smrg} 348f29dbc25Smrg#endif 349f29dbc25Smrg 350f29dbc25Smrgextern unsigned long gfx_gx2_scratch_base; 351f29dbc25Smrg 352f29dbc25Smrgstatic Bool 353f29dbc25SmrgGXMapMem(ScrnInfoPtr pScrni) 354f29dbc25Smrg{ 355f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 356f29dbc25Smrg int index = pScrni->scrnIndex; 357f29dbc25Smrg 358f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 359f29dbc25Smrg 360f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 36104007ebaSmrg gfx_virt_regptr = (unsigned char *) xf86MapVidMem(index, VIDMEM_MMIO, 36204007ebaSmrg pci->memBase[2], 36304007ebaSmrg pci->size[2]); 364f29dbc25Smrg 36504007ebaSmrg gfx_virt_gpptr = (unsigned char *) xf86MapVidMem(index, VIDMEM_MMIO, 36604007ebaSmrg pci->memBase[1], 36704007ebaSmrg pci->size[1]); 368f29dbc25Smrg 36904007ebaSmrg gfx_virt_vidptr = (unsigned char *) xf86MapVidMem(index, VIDMEM_MMIO, 37004007ebaSmrg pci->memBase[3], 37104007ebaSmrg pci->size[3]); 372f29dbc25Smrg 37304007ebaSmrg gfx_virt_fbptr = (unsigned char *) xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 37404007ebaSmrg pci->memBase[0], 37504007ebaSmrg pGeode->FBAvail); 376f29dbc25Smrg#else 377f29dbc25Smrg gfx_virt_regptr = map_pci_mem(pScrni, 0, pci, 2, 0); 378f29dbc25Smrg gfx_virt_gpptr = map_pci_mem(pScrni, 0, pci, 1, 0); 379f29dbc25Smrg gfx_virt_vidptr = map_pci_mem(pScrni, 0, pci, 3, 0); 380f29dbc25Smrg gfx_virt_fbptr = map_pci_mem(pScrni, 1, pci, 0, pGeode->FBAvail); 381f29dbc25Smrg#endif 382f29dbc25Smrg 383f29dbc25Smrg gfx_gx2_scratch_base = pGeode->FBAvail - 0x4000; 384f29dbc25Smrg 3857f419768Smrg#ifndef XSERVER_LIBPCIACCESS 386f29dbc25Smrg XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); 3877f419768Smrg#else 3887f419768Smrg { 3897f419768Smrg int fd = open("/dev/mem", O_RDWR); 3907f419768Smrg if (fd < 0) { 3917f419768Smrg xf86DrvMsg(index, X_ERROR, "Failed to open /dev/mem: %m\n"); 3927f419768Smrg return FALSE; 3937f419768Smrg } 3947f419768Smrg XpressROMPtr = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xF0000); 3957f419768Smrg close(fd); 3967f419768Smrg } 3977f419768Smrg#endif 398f29dbc25Smrg pGeode->FBBase = gfx_virt_fbptr; 399f29dbc25Smrg 400f29dbc25Smrg if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || 40104007ebaSmrg (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) 40204007ebaSmrg return FALSE; 403f29dbc25Smrg 404f29dbc25Smrg if (!pGeode->NoAccel && pGeode->useEXA) 40504007ebaSmrg pGeode->pExa->memoryBase = pGeode->FBBase; 406f29dbc25Smrg 407f29dbc25Smrg xf86DrvMsg(index, X_INFO, "Found Geode %x %p\n", 40804007ebaSmrg pGeode->FBAvail, pGeode->FBBase); 409f29dbc25Smrg 410f29dbc25Smrg return TRUE; 411f29dbc25Smrg} 412f29dbc25Smrg 413f29dbc25Smrg/* Check to see if VGA exists - we map the space and look for a 414f29dbc25Smrg signature - if it doesn't match exactly, then we assume no VGA. 415f29dbc25Smrg*/ 416f29dbc25Smrg 417f29dbc25Smrgstatic Bool 4187f419768SmrgGXCheckVGA(ScrnInfoPtr pScrni, EntityInfoPtr pEnt) 419f29dbc25Smrg{ 4207f419768Smrg#ifndef XSERVER_LIBPCIACCESS 421f29dbc25Smrg unsigned char *ptr; 422f29dbc25Smrg const char *vgasig = "IBM VGA Compatible"; 423f29dbc25Smrg int ret; 424f29dbc25Smrg 425f29dbc25Smrg ptr = 42604007ebaSmrg xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, 0xC001E, 42704007ebaSmrg strlen(vgasig)); 428f29dbc25Smrg 429f29dbc25Smrg if (ptr == NULL) 43004007ebaSmrg return FALSE; 431f29dbc25Smrg 432f29dbc25Smrg ret = memcmp(ptr, vgasig, strlen(vgasig)); 433f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) ptr, strlen(vgasig)); 434f29dbc25Smrg 435f29dbc25Smrg return ret ? FALSE : TRUE; 4367f419768Smrg#else 4377f419768Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pEnt->index); 4387f419768Smrg 4397f419768Smrg return pci_device_is_boot_vga(pci); 4407f419768Smrg#endif 441f29dbc25Smrg} 442f29dbc25Smrg 443f29dbc25Smrgstatic Bool 444f29dbc25SmrgGXPreInit(ScrnInfoPtr pScrni, int flags) 445f29dbc25Smrg{ 446f29dbc25Smrg GeodePtr pGeode; 447f29dbc25Smrg ClockRangePtr GeodeClockRange; 448f29dbc25Smrg OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; 449f29dbc25Smrg int ret; 450f29dbc25Smrg QQ_WORD msrValue; 451f29dbc25Smrg EntityInfoPtr pEnt; 452f29dbc25Smrg rgb defaultWeight = { 0, 0, 0 }; 453f29dbc25Smrg int modecnt; 4543406bd8eSmrg const char *s, *panelgeo; 455f29dbc25Smrg Bool useVGA; 456f29dbc25Smrg 457f29dbc25Smrg if (pScrni->numEntities != 1) 45804007ebaSmrg return FALSE; 459f29dbc25Smrg 460f29dbc25Smrg pEnt = xf86GetEntityInfo(pScrni->entityList[0]); 461f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 462f29dbc25Smrg if (pEnt->resources) 46304007ebaSmrg return FALSE; 464f29dbc25Smrg#endif 465f29dbc25Smrg 46604007ebaSmrg pGeode = pScrni->driverPrivate = xnfcalloc(1, sizeof(GeodeRec)); 467f29dbc25Smrg 468f29dbc25Smrg if (pGeode == NULL) 46904007ebaSmrg return FALSE; 470f29dbc25Smrg 4717f419768Smrg useVGA = GXCheckVGA(pScrni, pEnt); 472f29dbc25Smrg 473f29dbc25Smrg if (flags & PROBE_DETECT) { 47404007ebaSmrg GeodeProbeDDC(pScrni, pEnt->index); 47504007ebaSmrg return TRUE; 476f29dbc25Smrg } 477f29dbc25Smrg 478f29dbc25Smrg /* Probe for VGA */ 479f29dbc25Smrg pGeode->useVGA = useVGA; 480f29dbc25Smrg pGeode->pEnt = pEnt; 481f29dbc25Smrg 482f29dbc25Smrg if (pGeode->useVGA) { 48304007ebaSmrg if (!xf86LoadSubModule(pScrni, "vgahw") || !vgaHWGetHWRec(pScrni)) 48404007ebaSmrg pGeode->useVGA = FALSE; 48504007ebaSmrg else 48604007ebaSmrg vgaHWSetStdFuncs(VGAHWPTR(pScrni)); 487f29dbc25Smrg 488f29dbc25Smrg#if INT10_SUPPORT 48904007ebaSmrg pGeode->vesa = calloc(1, sizeof(VESARec)); 490f29dbc25Smrg#endif 491f29dbc25Smrg } 492f29dbc25Smrg 493f29dbc25Smrg gfx_msr_init(); 494f29dbc25Smrg 495f29dbc25Smrg ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); 496f29dbc25Smrg 497f29dbc25Smrg if (!ret) { 49804007ebaSmrg pGeode->Output = 49904007ebaSmrg ((msrValue.low & RCDF_CONFIG_FMT_MASK) == 50004007ebaSmrg RCDF_CONFIG_FMT_FP) ? OUTPUT_PANEL : OUTPUT_CRT; 501f29dbc25Smrg } 502f29dbc25Smrg 503f29dbc25Smrg /* Fill in the monitor information */ 504f29dbc25Smrg pScrni->monitor = pScrni->confScreen->monitor; 505f29dbc25Smrg 506f29dbc25Smrg if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) 50704007ebaSmrg return FALSE; 508f29dbc25Smrg 509f29dbc25Smrg switch (pScrni->depth) { 510f29dbc25Smrg case 8: 51104007ebaSmrg pScrni->rgbBits = 8; 512f29dbc25Smrg case 16: 513f29dbc25Smrg case 24: 514f29dbc25Smrg case 32: 51504007ebaSmrg break; 516f29dbc25Smrg default: 51704007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 51804007ebaSmrg "The driver does not support %d as a depth.\n", 51904007ebaSmrg pScrni->depth); 52004007ebaSmrg return FALSE; 521f29dbc25Smrg } 522f29dbc25Smrg 523f29dbc25Smrg xf86PrintDepthBpp(pScrni); 524f29dbc25Smrg 525f29dbc25Smrg if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) 52604007ebaSmrg return FALSE; 527f29dbc25Smrg 528f29dbc25Smrg if (!xf86SetDefaultVisual(pScrni, -1)) 52904007ebaSmrg return FALSE; 530f29dbc25Smrg 531f29dbc25Smrg /* 532f29dbc25Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 533f29dbc25Smrg * here. 534f29dbc25Smrg */ 535f29dbc25Smrg { 53604007ebaSmrg Gamma zeros = { 0.0, 0.0, 0.0 }; 537f29dbc25Smrg 53804007ebaSmrg if (!xf86SetGamma(pScrni, zeros)) { 53904007ebaSmrg return FALSE; 54004007ebaSmrg } 541f29dbc25Smrg } 542f29dbc25Smrg 543f29dbc25Smrg pScrni->progClock = TRUE; 544f29dbc25Smrg xf86CollectOptions(pScrni, NULL); 545f29dbc25Smrg xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); 546f29dbc25Smrg 547f29dbc25Smrg /* Set up our various options that may get reversed as we go on */ 548f29dbc25Smrg 549f29dbc25Smrg pGeode->FBVGAActive = FALSE; 550f29dbc25Smrg pGeode->tryHWCursor = TRUE; 551f29dbc25Smrg pGeode->tryCompression = TRUE; 552f29dbc25Smrg 553f29dbc25Smrg pGeode->NoAccel = FALSE; 554f29dbc25Smrg pGeode->useEXA = FALSE; 555f29dbc25Smrg 556f29dbc25Smrg pGeode->Panel = (pGeode->Output & OUTPUT_PANEL) ? TRUE : FALSE; 557f29dbc25Smrg 558f29dbc25Smrg pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; 559f29dbc25Smrg pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; 560f29dbc25Smrg pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; 561f29dbc25Smrg 56204007ebaSmrg xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, &pGeode->tryHWCursor); 563f29dbc25Smrg 564f29dbc25Smrg if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, 56504007ebaSmrg (int *) &(pGeode->FBAvail))) 56604007ebaSmrg pGeode->FBAvail = 0; 567f29dbc25Smrg 568f29dbc25Smrg /* For compatability - allow SWCursor too */ 569f29dbc25Smrg 570f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) 57104007ebaSmrg pGeode->tryHWCursor = FALSE; 572f29dbc25Smrg 573f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) 57404007ebaSmrg pGeode->tryCompression = FALSE; 575f29dbc25Smrg 576f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) 57704007ebaSmrg pGeode->NoAccel = TRUE; 578f29dbc25Smrg 579f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 580f29dbc25Smrg 581f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { 582f29dbc25Smrg 58304007ebaSmrg if (!xf86NameCmp(s, "LEFT")) 58404007ebaSmrg pGeode->rotation = RR_Rotate_90; 58504007ebaSmrg else if (!xf86NameCmp(s, "INVERT")) 58604007ebaSmrg pGeode->rotation = RR_Rotate_180; 58704007ebaSmrg else if (!xf86NameCmp(s, "CCW")) 58804007ebaSmrg pGeode->rotation = RR_Rotate_270; 58904007ebaSmrg else 59004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Invalid rotation %s.\n", s); 591f29dbc25Smrg } 592f29dbc25Smrg 593f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, 59404007ebaSmrg &(pGeode->NoOfImgBuffers)); 595f29dbc25Smrg 596f29dbc25Smrg if (pGeode->NoOfImgBuffers <= 0) 59704007ebaSmrg pGeode->NoOfImgBuffers = 0; 598f29dbc25Smrg 599f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, 60004007ebaSmrg &(pGeode->NoOfColorExpandLines)); 601f29dbc25Smrg 602f29dbc25Smrg if (pGeode->NoOfColorExpandLines <= 0) 60304007ebaSmrg pGeode->NoOfColorExpandLines = 0; 604f29dbc25Smrg 605f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, 60604007ebaSmrg (int *) &(pGeode->exaBfrSz)); 607f29dbc25Smrg 608f29dbc25Smrg if (pGeode->exaBfrSz <= 0) 60904007ebaSmrg pGeode->exaBfrSz = 0; 610f29dbc25Smrg 611f29dbc25Smrg if (pGeode->Panel == TRUE) { 61204007ebaSmrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOPANEL, FALSE)) 61304007ebaSmrg pGeode->Panel = FALSE; 614f29dbc25Smrg } 615f29dbc25Smrg 616f29dbc25Smrg panelgeo = xf86GetOptValString(GeodeOptions, GX_OPTION_PANEL_GEOMETRY); 617f29dbc25Smrg 618f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { 6197f419768Smrg#if defined(XF86XAA) && defined(XF86EXA) 62004007ebaSmrg if (!xf86NameCmp(s, "XAA")) 62104007ebaSmrg pGeode->useEXA = FALSE; 62204007ebaSmrg else if (xf86NameCmp(s, "EXA")) 62304007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 62404007ebaSmrg "Unknown accleration method %s. Defaulting to XAA.\n", 62504007ebaSmrg s); 6267f419768Smrg#elif defined(XF86EXA) 6277f419768Smrg pGeode->useEXA = TRUE; 6287f419768Smrg#else 6297f419768Smrg pGeode->useEXA = FALSE; 6307f419768Smrg#endif 631f29dbc25Smrg } 632f29dbc25Smrg 633f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 63404007ebaSmrg "Using %s acceleration architecture\n", 63504007ebaSmrg pGeode->useEXA ? "EXA" : "XAA"); 636f29dbc25Smrg 637f29dbc25Smrg /* Set up the panel */ 638f29dbc25Smrg 639f29dbc25Smrg if (pGeode->Panel) { 64004007ebaSmrg if (panelgeo != NULL) { 64104007ebaSmrg if (GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, &pGeode->PanelY)) 64204007ebaSmrg pGeode->Panel = FALSE; 64304007ebaSmrg } 644f29dbc25Smrg#ifdef PNL_SUP 64504007ebaSmrg else { 64604007ebaSmrg int b, f; 647f29dbc25Smrg 64804007ebaSmrg /* The bitdepth and refresh isn't used anywhere else in the driver */ 649f29dbc25Smrg 65004007ebaSmrg if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) 65104007ebaSmrg Pnl_GetPanelInfoFromBIOS(&pGeode->PanelX, &pGeode->PanelY, &b, 65204007ebaSmrg &f); 65304007ebaSmrg } 654f29dbc25Smrg#endif 655f29dbc25Smrg } 656f29dbc25Smrg 657f29dbc25Smrg /* Set up the VGA */ 658f29dbc25Smrg 659f29dbc25Smrg if (pGeode->useVGA) { 660f29dbc25Smrg#if INT10_SUPPORT 66104007ebaSmrg VESARec *pVesa; 662f29dbc25Smrg 66304007ebaSmrg if (!xf86LoadSubModule(pScrni, "int10")) 66404007ebaSmrg return FALSE; 665f29dbc25Smrg 66604007ebaSmrg pVesa = pGeode->vesa; 667f29dbc25Smrg 66804007ebaSmrg if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { 66904007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 67004007ebaSmrg "Unable to initialize 1NT10 support\n"); 67104007ebaSmrg pGeode->useVGA = FALSE; 67204007ebaSmrg } 673f29dbc25Smrg#endif 674f29dbc25Smrg } 675f29dbc25Smrg 676f29dbc25Smrg /* First try to get the framebuffer size from the framebuffer, 677f29dbc25Smrg * and if that fails, revert all the way back to the legacy 678f29dbc25Smrg * method 679f29dbc25Smrg */ 680f29dbc25Smrg 681f29dbc25Smrg if (pGeode->FBAvail == 0) { 68204007ebaSmrg if (GeodeGetSizeFromFB(&pGeode->FBAvail)) 68304007ebaSmrg pGeode->FBAvail = gfx_get_frame_buffer_size(); 684f29dbc25Smrg } 685f29dbc25Smrg 686f29dbc25Smrg if (pScrni->memPhysBase == 0) 68704007ebaSmrg pScrni->memPhysBase = gfx_get_frame_buffer_base(); 688f29dbc25Smrg 689f29dbc25Smrg pScrni->fbOffset = 0; 690f29dbc25Smrg 691f29dbc25Smrg if (pGeode->pEnt->device->videoRam == 0) 69204007ebaSmrg pScrni->videoRam = pGeode->FBAvail / 1024; 693f29dbc25Smrg else 69404007ebaSmrg pScrni->videoRam = pGeode->pEnt->device->videoRam; 695f29dbc25Smrg 69604007ebaSmrg GeodeClockRange = (ClockRangePtr) xnfcalloc(1, sizeof(ClockRange)); 697f29dbc25Smrg GeodeClockRange->next = NULL; 698f29dbc25Smrg GeodeClockRange->minClock = 25175; 699f29dbc25Smrg GeodeClockRange->maxClock = 229500; 700f29dbc25Smrg GeodeClockRange->clockIndex = -1; 701f29dbc25Smrg GeodeClockRange->interlaceAllowed = TRUE; 702f29dbc25Smrg GeodeClockRange->doubleScanAllowed = FALSE; 703f29dbc25Smrg 704f29dbc25Smrg pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); 705f29dbc25Smrg 706f29dbc25Smrg /* I'm still not 100% sure this uses the right values */ 707f29dbc25Smrg 708f29dbc25Smrg modecnt = xf86ValidateModes(pScrni, 70904007ebaSmrg pScrni->monitor->Modes, 71004007ebaSmrg pScrni->display->modes, 71104007ebaSmrg GeodeClockRange, 71204007ebaSmrg NULL, GX_MIN_PITCH, GX_MAX_PITCH, 71304007ebaSmrg 32, GX_MIN_HEIGHT, GX_MAX_HEIGHT, 71404007ebaSmrg pScrni->display->virtualX, 71504007ebaSmrg pScrni->display->virtualY, pGeode->FBAvail, 71604007ebaSmrg LOOKUP_BEST_REFRESH); 717f29dbc25Smrg 718f29dbc25Smrg if (modecnt <= 0) { 71904007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); 72004007ebaSmrg return FALSE; 721f29dbc25Smrg } 722f29dbc25Smrg 723f29dbc25Smrg xf86PruneDriverModes(pScrni); 724f29dbc25Smrg 725f29dbc25Smrg if (pScrni->modes == NULL) { 72604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); 72704007ebaSmrg return FALSE; 728f29dbc25Smrg } 729f29dbc25Smrg 730f29dbc25Smrg xf86SetCrtcForModes(pScrni, 0); 731f29dbc25Smrg pScrni->currentMode = pScrni->modes; 732f29dbc25Smrg 733f29dbc25Smrg xf86PrintModes(pScrni); 734f29dbc25Smrg xf86SetDpi(pScrni, 0, 0); 735f29dbc25Smrg 736f29dbc25Smrg /* Load the modules we'll need */ 737f29dbc25Smrg 738f29dbc25Smrg if (xf86LoadSubModule(pScrni, "fb") == NULL) { 73904007ebaSmrg return FALSE; 740f29dbc25Smrg } 741f29dbc25Smrg 742f29dbc25Smrg if (pGeode->NoAccel == FALSE) { 74304007ebaSmrg const char *module = (pGeode->useEXA) ? "exa" : "xaa"; 744f29dbc25Smrg 74504007ebaSmrg if (!xf86LoadSubModule(pScrni, module)) { 74604007ebaSmrg return FALSE; 74704007ebaSmrg } 748f29dbc25Smrg } 749f29dbc25Smrg 750f29dbc25Smrg if (pGeode->tryHWCursor == TRUE) { 75104007ebaSmrg if (!xf86LoadSubModule(pScrni, "ramdac")) { 75204007ebaSmrg return FALSE; 75304007ebaSmrg } 754f29dbc25Smrg } 755f29dbc25Smrg 756f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 757f29dbc25Smrg if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { 75804007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 75904007ebaSmrg "Couldn't register the resources.\n"); 76004007ebaSmrg return FALSE; 761f29dbc25Smrg } 762f29dbc25Smrg#endif 763f29dbc25Smrg return TRUE; 764f29dbc25Smrg} 765f29dbc25Smrg 766f29dbc25Smrgstatic void 767f29dbc25SmrgGXRestore(ScrnInfoPtr pScrni) 768f29dbc25Smrg{ 769f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 770f29dbc25Smrg 771f29dbc25Smrg if (pGeode->useVGA && pGeode->FBVGAActive) { 77204007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 773f29dbc25Smrg 77404007ebaSmrg vgaHWProtect(pScrni, TRUE); 77504007ebaSmrg vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); 77604007ebaSmrg vgaHWProtect(pScrni, FALSE); 777f29dbc25Smrg } 778f29dbc25Smrg} 779f29dbc25Smrg 780f29dbc25Smrgstatic Bool 781f29dbc25SmrgGXUnmapMem(ScrnInfoPtr pScrni) 782f29dbc25Smrg{ 783f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 784f29dbc25Smrg 785f29dbc25Smrg /* unmap all the memory map's */ 7867f419768Smrg#ifndef XSERVER_LIBPCIACCESS 787f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, GX_CPU_REG_SIZE); 788f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_gpptr, GX_GP_REG_SIZE); 789f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, GX_VID_REG_SIZE); 790f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); 7917f419768Smrg#else 7927f419768Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 7937f419768Smrg 7947f419768Smrg unmap_pci_mem(pScrni, pci, gfx_virt_regptr, GX_CPU_REG_SIZE); 7957f419768Smrg unmap_pci_mem(pScrni, pci, gfx_virt_gpptr, GX_GP_REG_SIZE); 7967f419768Smrg unmap_pci_mem(pScrni, pci, gfx_virt_vidptr, GX_VID_REG_SIZE); 7977f419768Smrg unmap_pci_mem(pScrni, pci, gfx_virt_fbptr, pGeode->FBAvail); 7987f419768Smrg 7997f419768Smrg munmap(XpressROMPtr, 0x10000); 8007f419768Smrg#endif 801f29dbc25Smrg return TRUE; 802f29dbc25Smrg} 803f29dbc25Smrg 804f29dbc25Smrgstatic void 805f29dbc25SmrgGXSetDvLineSize(unsigned int pitch) 806f29dbc25Smrg{ 807f29dbc25Smrg unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; 808f29dbc25Smrg 809f29dbc25Smrg if (pitch > 1024) { 81004007ebaSmrg dv_size = MDC_DV_LINE_SIZE_2048; 811f29dbc25Smrg } 812f29dbc25Smrg if (pitch > 2048) { 81304007ebaSmrg dv_size = MDC_DV_LINE_SIZE_4096; 814f29dbc25Smrg } 815f29dbc25Smrg if (pitch > 4096) { 81604007ebaSmrg dv_size = MDC_DV_LINE_SIZE_8192; 817f29dbc25Smrg } 818f29dbc25Smrg 819f29dbc25Smrg /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ 820f29dbc25Smrg 821f29dbc25Smrg temp = READ_REG32(MDC_DV_CTL); 822f29dbc25Smrg WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); 823f29dbc25Smrg} 824f29dbc25Smrg 825f29dbc25Smrg/* XXX - this is nothing like the original function - not sure exactly what the purpose is for this quite yet */ 826f29dbc25Smrg 827f29dbc25Smrgstatic void 82804007ebaSmrgGXAdjustFrame(ADJUST_FRAME_ARGS_DECL) 829f29dbc25Smrg{ 83004007ebaSmrg SCRN_INFO_PTR(arg); 831f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 832f29dbc25Smrg unsigned long offset; 833f29dbc25Smrg 834f29dbc25Smrg offset = y * pGeode->Pitch + x * (pScrni->bitsPerPixel >> 3); 835f29dbc25Smrg 836f29dbc25Smrg gfx_set_display_offset(offset); 837f29dbc25Smrg} 838f29dbc25Smrg 839f29dbc25Smrgstatic Bool 840f29dbc25SmrgGXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) 841f29dbc25Smrg{ 842f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 843f29dbc25Smrg int flags = 0; 844f29dbc25Smrg int custom = 0; 845f29dbc25Smrg 846f29dbc25Smrg pScrni->vtSema = TRUE; 847f29dbc25Smrg 848f29dbc25Smrg gx_disable_dac_power(); 849f29dbc25Smrg 850f29dbc25Smrg if (pMode->Flags & V_NHSYNC) 85104007ebaSmrg flags |= 1; 852f29dbc25Smrg if (pMode->Flags & V_NVSYNC) 85304007ebaSmrg flags |= 2; 854f29dbc25Smrg 855f29dbc25Smrg /* Check to see if we should use custom or built-in timings */ 856f29dbc25Smrg 857f29dbc25Smrg if (pGeode->Panel) 85804007ebaSmrg custom = (pMode->type & M_T_USERDEF); 859f29dbc25Smrg else 86004007ebaSmrg custom = !(pMode->type & (M_T_BUILTIN | M_T_DEFAULT)); 861f29dbc25Smrg 862f29dbc25Smrg /* If we're not doing a custom mode, then just set the fixed timings, 863f29dbc25Smrg * otherwise, do the whole shooting match */ 864f29dbc25Smrg 865f29dbc25Smrg if (!custom) { 86604007ebaSmrg GFX(set_fixed_timings(pGeode->PanelX, pGeode->PanelY, 86704007ebaSmrg pMode->CrtcHDisplay, pMode->CrtcVDisplay, 86804007ebaSmrg pScrni->bitsPerPixel)); 86904007ebaSmrg } 87004007ebaSmrg else { 87104007ebaSmrg if (pGeode->Panel) 87204007ebaSmrg GFX(set_panel_present(pGeode->PanelX, pGeode->PanelY, 87304007ebaSmrg pMode->CrtcHDisplay, pMode->CrtcVDisplay, 87404007ebaSmrg pScrni->bitsPerPixel)); 87504007ebaSmrg 87604007ebaSmrg GFX(set_display_timings(pScrni->bitsPerPixel, flags, 87704007ebaSmrg pMode->CrtcHDisplay, pMode->CrtcHBlankStart, 87804007ebaSmrg pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, 87904007ebaSmrg pMode->CrtcHBlankEnd, pMode->CrtcHTotal, 88004007ebaSmrg pMode->CrtcVDisplay, pMode->CrtcVBlankStart, 88104007ebaSmrg pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, 88204007ebaSmrg pMode->CrtcVBlankEnd, pMode->CrtcVTotal, 88304007ebaSmrg (int) ((pMode->SynthClock / 1000.0) * 88404007ebaSmrg 0x10000))); 885f29dbc25Smrg } 886f29dbc25Smrg 887f29dbc25Smrg GFX(set_crt_enable(CRT_ENABLE)); 888f29dbc25Smrg GFX(set_display_pitch(pGeode->displayPitch)); 889f29dbc25Smrg GFX(set_display_offset(0L)); 890f29dbc25Smrg GFX(wait_vertical_blank()); 891f29dbc25Smrg 892f29dbc25Smrg if (pGeode->Compression) { 89304007ebaSmrg GXSetDvLineSize(pGeode->Pitch); 894f29dbc25Smrg 89504007ebaSmrg gfx_set_compression_offset(pGeode->CBData.compression_offset); 89604007ebaSmrg gfx_set_compression_pitch(GX_CB_PITCH); 89704007ebaSmrg gfx_set_compression_size(GX_CB_SIZE); 898f29dbc25Smrg 89904007ebaSmrg gfx_set_compression_enable(1); 900f29dbc25Smrg } 901f29dbc25Smrg 902f29dbc25Smrg if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { 90304007ebaSmrg GXLoadCursorImage(pScrni, NULL); 90404007ebaSmrg GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); 90504007ebaSmrg GXShowCursor(pScrni); 90604007ebaSmrg } 90704007ebaSmrg else { 90804007ebaSmrg GFX(set_cursor_enable(0)); 90904007ebaSmrg pGeode->HWCursor = FALSE; 910f29dbc25Smrg } 911f29dbc25Smrg 91204007ebaSmrg GXAdjustFrame(ADJUST_FRAME_ARGS(pScrni->frameX0, pScrni->frameY0)); 913f29dbc25Smrg gx_enable_dac_power(); 914f29dbc25Smrg 915f29dbc25Smrg return TRUE; 916f29dbc25Smrg} 917f29dbc25Smrg 918f29dbc25Smrgstatic Bool 91904007ebaSmrgGXSwitchMode(SWITCH_MODE_ARGS_DECL) 920f29dbc25Smrg{ 92104007ebaSmrg SCRN_INFO_PTR(arg); 922f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 923f29dbc25Smrg int ret = TRUE; 924f29dbc25Smrg int rotate; 925f29dbc25Smrg 926f29dbc25Smrg /* Syn the engine and shutdown the DAC momentarily */ 927f29dbc25Smrg 928f29dbc25Smrg gfx_wait_until_idle(); 929f29dbc25Smrg 930f29dbc25Smrg /* Set up the memory for the new mode */ 931f29dbc25Smrg rotate = GXGetRotation(pScrni->pScreen); 932f29dbc25Smrg ret = GXAllocateMemory(pScrni->pScreen, pScrni, rotate); 933f29dbc25Smrg 934f29dbc25Smrg if (ret) { 93504007ebaSmrg if (pGeode->curMode != pMode) 93604007ebaSmrg ret = GXSetVideoMode(pScrni, pMode); 937f29dbc25Smrg } 938f29dbc25Smrg 939f29dbc25Smrg if (ret) 94004007ebaSmrg ret = GXRotate(pScrni, pMode); 941f29dbc25Smrg 942f29dbc25Smrg /* Go back the way it was */ 943f29dbc25Smrg 944f29dbc25Smrg if (ret == FALSE) { 94504007ebaSmrg if (!GXSetVideoMode(pScrni, pGeode->curMode)) 94604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 94704007ebaSmrg "Could not restore the previous mode\n"); 94804007ebaSmrg } 94904007ebaSmrg else 95004007ebaSmrg pGeode->curMode = pMode; 951f29dbc25Smrg 952f29dbc25Smrg return ret; 953f29dbc25Smrg} 954f29dbc25Smrg 955f29dbc25Smrgstatic void 956f29dbc25SmrgGXLeaveGraphics(ScrnInfoPtr pScrni) 957f29dbc25Smrg{ 958f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 959f29dbc25Smrg 960f29dbc25Smrg gfx_wait_until_idle(); 961f29dbc25Smrg 962f29dbc25Smrg /* Restore VG registers */ 963f29dbc25Smrg gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, 96404007ebaSmrg pGeode->FBgfxdisplaytiming.wPolarity, 96504007ebaSmrg pGeode->FBgfxdisplaytiming.wHActive, 96604007ebaSmrg pGeode->FBgfxdisplaytiming.wHBlankStart, 96704007ebaSmrg pGeode->FBgfxdisplaytiming.wHSyncStart, 96804007ebaSmrg pGeode->FBgfxdisplaytiming.wHSyncEnd, 96904007ebaSmrg pGeode->FBgfxdisplaytiming.wHBlankEnd, 97004007ebaSmrg pGeode->FBgfxdisplaytiming.wHTotal, 97104007ebaSmrg pGeode->FBgfxdisplaytiming.wVActive, 97204007ebaSmrg pGeode->FBgfxdisplaytiming.wVBlankStart, 97304007ebaSmrg pGeode->FBgfxdisplaytiming.wVSyncStart, 97404007ebaSmrg pGeode->FBgfxdisplaytiming.wVSyncEnd, 97504007ebaSmrg pGeode->FBgfxdisplaytiming.wVBlankEnd, 97604007ebaSmrg pGeode->FBgfxdisplaytiming.wVTotal, 97704007ebaSmrg pGeode->FBgfxdisplaytiming.dwDotClock); 978f29dbc25Smrg 979f29dbc25Smrg gfx_set_compression_enable(0); 980f29dbc25Smrg 981f29dbc25Smrg /* Restore the previous Compression state */ 982f29dbc25Smrg if (pGeode->FBCompressionEnable) { 98304007ebaSmrg gfx_set_compression_offset(pGeode->FBCompressionOffset); 98404007ebaSmrg gfx_set_compression_pitch(pGeode->FBCompressionPitch); 98504007ebaSmrg gfx_set_compression_size(pGeode->FBCompressionSize); 98604007ebaSmrg gfx_set_compression_enable(1); 987f29dbc25Smrg } 988f29dbc25Smrg 989f29dbc25Smrg gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); 990f29dbc25Smrg 991f29dbc25Smrg gfx_set_display_offset(pGeode->FBDisplayOffset); 992f29dbc25Smrg 993f29dbc25Smrg /* Restore Cursor */ 994f29dbc25Smrg gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); 995f29dbc25Smrg 996f29dbc25Smrg if (pGeode->useVGA) { 99704007ebaSmrg pGeode->vesa->pInt->num = 0x10; 99804007ebaSmrg pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; 99904007ebaSmrg pGeode->vesa->pInt->bx = 0; 100004007ebaSmrg xf86ExecX86int10(pGeode->vesa->pInt); 100104007ebaSmrg gfx_delay_milliseconds(3); 1002f29dbc25Smrg } 1003f29dbc25Smrg 1004f29dbc25Smrg GXRestore(pScrni); 1005f29dbc25Smrg 1006f29dbc25Smrg gx_enable_dac_power(); 1007f29dbc25Smrg} 1008f29dbc25Smrg 1009f29dbc25Smrgstatic Bool 101004007ebaSmrgGXCloseScreen(CLOSE_SCREEN_ARGS_DECL) 1011f29dbc25Smrg{ 101204007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 1013f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1014f29dbc25Smrg 1015f29dbc25Smrg if (pScrni->vtSema) 101604007ebaSmrg GXLeaveGraphics(pScrni); 1017f29dbc25Smrg 101804007ebaSmrg#ifdef XF86XAA 1019f29dbc25Smrg if (pGeode->AccelInfoRec) 102004007ebaSmrg XAADestroyInfoRec(pGeode->AccelInfoRec); 102104007ebaSmrg#endif 1022f29dbc25Smrg 1023f29dbc25Smrg if (pGeode->AccelImageWriteBuffers) { 102404007ebaSmrg free(pGeode->AccelImageWriteBuffers[0]); 102504007ebaSmrg free(pGeode->AccelImageWriteBuffers); 102604007ebaSmrg pGeode->AccelImageWriteBuffers = NULL; 1027f29dbc25Smrg } 1028f29dbc25Smrg 1029f29dbc25Smrg if (pGeode->AccelColorExpandBuffers) { 103004007ebaSmrg free(pGeode->AccelColorExpandBuffers); 103104007ebaSmrg pGeode->AccelColorExpandBuffers = NULL; 1032f29dbc25Smrg } 1033f29dbc25Smrg 1034f29dbc25Smrg if (pGeode->pExa) { 103504007ebaSmrg exaDriverFini(pScrn); 103604007ebaSmrg free(pGeode->pExa); 103704007ebaSmrg pGeode->pExa = NULL; 1038f29dbc25Smrg } 1039f29dbc25Smrg 1040f29dbc25Smrg pScrni->vtSema = FALSE; 1041f29dbc25Smrg 1042f29dbc25Smrg GXUnmapMem(pScrni); 1043f29dbc25Smrg 1044f29dbc25Smrg pScrni->PointerMoved = pGeode->PointerMoved; 1045f29dbc25Smrg pScrn->CloseScreen = pGeode->CloseScreen; 1046f29dbc25Smrg 1047f29dbc25Smrg if (pScrn->CloseScreen) 104804007ebaSmrg return (*pScrn->CloseScreen) (CLOSE_SCREEN_ARGS); 1049f29dbc25Smrg 1050f29dbc25Smrg return TRUE; 1051f29dbc25Smrg} 1052f29dbc25Smrg 1053f29dbc25Smrgstatic Bool 1054f29dbc25SmrgGXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 1055f29dbc25Smrg{ 1056f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1057f29dbc25Smrg 1058f29dbc25Smrg if (!GXMapMem(pScrni)) 105904007ebaSmrg return FALSE; 1060f29dbc25Smrg 1061f29dbc25Smrg if (pGeode->useVGA) 106204007ebaSmrg pGeode->FBVGAActive = gu2_get_vga_active(); 1063f29dbc25Smrg 1064f29dbc25Smrg gfx_wait_until_idle(); 1065f29dbc25Smrg 1066f29dbc25Smrg /* Save off the current state (should this be somewhere else)? */ 1067f29dbc25Smrg 1068f29dbc25Smrg pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); 1069f29dbc25Smrg pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); 1070f29dbc25Smrg pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); 1071f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); 1072f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); 1073f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); 1074f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); 1075f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); 1076f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); 1077f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); 1078f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); 1079f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); 1080f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); 1081f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); 1082f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); 1083f29dbc25Smrg pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); 1084f29dbc25Smrg 1085f29dbc25Smrg pGeode->FBDisplayOffset = gfx_get_display_offset(); 1086f29dbc25Smrg 1087f29dbc25Smrg if (pGeode->useVGA) { 108804007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 1089f29dbc25Smrg 109004007ebaSmrg pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); 1091f29dbc25Smrg } 1092f29dbc25Smrg 1093f29dbc25Smrg pGeode->FBCompressionEnable = gfx_get_compression_enable(); 1094f29dbc25Smrg pGeode->FBCompressionOffset = gfx_get_compression_offset(); 1095f29dbc25Smrg pGeode->FBCompressionPitch = gfx_get_compression_pitch(); 1096f29dbc25Smrg pGeode->FBCompressionSize = gfx_get_compression_size(); 1097f29dbc25Smrg 1098f29dbc25Smrg#ifdef PNL_SUP 1099f29dbc25Smrg Pnl_SavePanelState(); 1100f29dbc25Smrg#endif 1101f29dbc25Smrg 1102f29dbc25Smrg /* Turn off the VGA */ 1103f29dbc25Smrg 1104f29dbc25Smrg if (pGeode->useVGA && pGeode->FBVGAActive) { 110504007ebaSmrg unsigned short sequencer; 110604007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 1107f29dbc25Smrg 110804007ebaSmrg /* Map VGA aperture */ 110904007ebaSmrg if (!vgaHWMapMem(pScrni)) 111004007ebaSmrg return FALSE; 1111f29dbc25Smrg 111204007ebaSmrg /* Unlock VGA registers */ 111304007ebaSmrg vgaHWUnlock(pvgaHW); 1114f29dbc25Smrg 111504007ebaSmrg /* Save the current state and setup the current mode */ 111604007ebaSmrg vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); 1117f29dbc25Smrg 111804007ebaSmrg /* DISABLE VGA SEQUENCER */ 111904007ebaSmrg /* This allows the VGA state machine to terminate. We must delay */ 112004007ebaSmrg /* such that there are no pending MBUS requests. */ 1121f29dbc25Smrg 112204007ebaSmrg gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); 112304007ebaSmrg sequencer = gfx_inb(MDC_SEQUENCER_DATA); 112404007ebaSmrg sequencer |= MDC_CLK_MODE_SCREEN_OFF; 112504007ebaSmrg gfx_outb(MDC_SEQUENCER_DATA, sequencer); 1126f29dbc25Smrg 112704007ebaSmrg gfx_delay_milliseconds(1); 1128f29dbc25Smrg 112904007ebaSmrg /* BLANK THE VGA DISPLAY */ 113004007ebaSmrg gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); 113104007ebaSmrg sequencer = gfx_inb(MDC_SEQUENCER_DATA); 113204007ebaSmrg sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; 113304007ebaSmrg gfx_outb(MDC_SEQUENCER_DATA, sequencer); 1134f29dbc25Smrg 113504007ebaSmrg gfx_delay_milliseconds(1); 1136f29dbc25Smrg } 1137f29dbc25Smrg 1138f29dbc25Smrg /* Set up the memory */ 1139f29dbc25Smrg /* XXX - FIXME - when we alow inital rotation, it should be here */ 1140f29dbc25Smrg GXAllocateMemory(pScrn, pScrni, pGeode->rotation); 1141f29dbc25Smrg 1142f29dbc25Smrg /* Clear the framebuffer */ 1143f29dbc25Smrg memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); 1144f29dbc25Smrg 1145f29dbc25Smrg /* Set up the video mode */ 1146f29dbc25Smrg GXSetVideoMode(pScrni, pScrni->currentMode); 1147f29dbc25Smrg pGeode->curMode = pScrni->currentMode; 1148f29dbc25Smrg 1149f29dbc25Smrg return TRUE; 1150f29dbc25Smrg} 1151f29dbc25Smrg 1152f29dbc25Smrgstatic void 1153f29dbc25SmrgGXLoadPalette(ScrnInfoPtr pScrni, 115404007ebaSmrg int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) 1155f29dbc25Smrg{ 1156f29dbc25Smrg int i, index, color; 1157f29dbc25Smrg 1158f29dbc25Smrg for (i = 0; i < numColors; i++) { 115904007ebaSmrg index = indizes[i] & 0xFF; 116004007ebaSmrg color = (((unsigned long) (colors[index].red & 0xFF)) << 16) | 116104007ebaSmrg (((unsigned long) (colors[index].green & 0xFF)) << 8) | 116204007ebaSmrg ((unsigned long) (colors[index].blue & 0xFF)); 1163f29dbc25Smrg 116404007ebaSmrg GFX(set_display_palette_entry(index, color)); 1165f29dbc25Smrg } 1166f29dbc25Smrg} 1167f29dbc25Smrg 1168f29dbc25Smrg#ifdef DPMSExtension 1169f29dbc25Smrgstatic void 1170f29dbc25SmrgGXPanelPower(int enable) 1171f29dbc25Smrg{ 1172f29dbc25Smrg unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); 1173f29dbc25Smrg 1174f29dbc25Smrg if (enable != 0) 117504007ebaSmrg power |= RCDF_PM_PANEL_POWER_ON; 1176f29dbc25Smrg else 117704007ebaSmrg power &= ~RCDF_PM_PANEL_POWER_ON; 1178f29dbc25Smrg 1179f29dbc25Smrg WRITE_VID32(RCDF_POWER_MANAGEMENT, power); 1180f29dbc25Smrg} 1181f29dbc25Smrg 1182f29dbc25Smrgstatic void 1183f29dbc25SmrgGXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) 1184f29dbc25Smrg{ 1185f29dbc25Smrg GeodeRec *pGeode; 1186f29dbc25Smrg 1187f29dbc25Smrg pGeode = GEODEPTR(pScrni); 1188f29dbc25Smrg 1189f29dbc25Smrg if (!pScrni->vtSema) 119004007ebaSmrg return; 1191f29dbc25Smrg 1192f29dbc25Smrg switch (mode) { 1193f29dbc25Smrg case DPMSModeOn: 119404007ebaSmrg /* Screen: On; HSync: On; VSync: On */ 119504007ebaSmrg GFX(set_crt_enable(CRT_ENABLE)); 1196f29dbc25Smrg#if defined(PNL_SUP) 119704007ebaSmrg if (pGeode->Panel) { 119804007ebaSmrg Pnl_PowerUp(); 119904007ebaSmrg GXPanelPower(1); 120004007ebaSmrg } 1201f29dbc25Smrg#endif 120204007ebaSmrg break; 1203f29dbc25Smrg 1204f29dbc25Smrg case DPMSModeStandby: 120504007ebaSmrg /* Screen: Off; HSync: Off; VSync: On */ 120604007ebaSmrg GFX(set_crt_enable(CRT_STANDBY)); 1207f29dbc25Smrg#if defined(PNL_SUP) 120804007ebaSmrg if (pGeode->Panel) { 120904007ebaSmrg Pnl_PowerDown(); 121004007ebaSmrg GXPanelPower(0); 121104007ebaSmrg } 1212f29dbc25Smrg#endif 121304007ebaSmrg break; 1214f29dbc25Smrg 1215f29dbc25Smrg case DPMSModeSuspend: 121604007ebaSmrg /* Screen: Off; HSync: On; VSync: Off */ 121704007ebaSmrg GFX(set_crt_enable(CRT_SUSPEND)); 1218f29dbc25Smrg#if defined(PNL_SUP) 121904007ebaSmrg if (pGeode->Panel) { 122004007ebaSmrg Pnl_PowerDown(); 122104007ebaSmrg GXPanelPower(0); 122204007ebaSmrg } 1223f29dbc25Smrg#endif 122404007ebaSmrg break; 1225f29dbc25Smrg 1226f29dbc25Smrg case DPMSModeOff: 122704007ebaSmrg /* Screen: Off; HSync: Off; VSync: Off */ 122804007ebaSmrg GFX(set_crt_enable(CRT_DISABLE)); 1229f29dbc25Smrg#if defined(PNL_SUP) 123004007ebaSmrg if (pGeode->Panel) { 123104007ebaSmrg Pnl_PowerDown(); 123204007ebaSmrg GXPanelPower(0); 123304007ebaSmrg } 1234f29dbc25Smrg#endif 123504007ebaSmrg break; 1236f29dbc25Smrg } 1237f29dbc25Smrg} 1238f29dbc25Smrg#endif 1239f29dbc25Smrg 1240f29dbc25Smrgstatic Bool 1241f29dbc25SmrgGXCreateScreenResources(ScreenPtr pScreen) 1242f29dbc25Smrg{ 124304007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 1244f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1245f29dbc25Smrg 1246f29dbc25Smrg pScreen->CreateScreenResources = pGeode->CreateScreenResources; 1247f29dbc25Smrg if (!(*pScreen->CreateScreenResources) (pScreen)) 124804007ebaSmrg return FALSE; 1249f29dbc25Smrg 1250f29dbc25Smrg if (xf86LoaderCheckSymbol("GXRandRSetConfig") 125104007ebaSmrg && pGeode->rotation != RR_Rotate_0) { 125204007ebaSmrg Rotation(*GXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, 125304007ebaSmrg RRScreenSizePtr pSize) = NULL; 1254f29dbc25Smrg 125504007ebaSmrg RRScreenSize p; 125604007ebaSmrg Rotation requestedRotation = pGeode->rotation; 1257f29dbc25Smrg 125804007ebaSmrg pGeode->rotation = RR_Rotate_0; 1259f29dbc25Smrg 126004007ebaSmrg /* Just setup enough for an initial rotate */ 1261f29dbc25Smrg 126204007ebaSmrg p.width = pScreen->width; 126304007ebaSmrg p.height = pScreen->height; 126404007ebaSmrg p.mmWidth = pScreen->mmWidth; 126504007ebaSmrg p.mmHeight = pScreen->mmHeight; 1266f29dbc25Smrg 126704007ebaSmrg GXRandRSetConfig = LoaderSymbol("GXRandRSetConfig"); 126804007ebaSmrg if (GXRandRSetConfig) { 126904007ebaSmrg pGeode->starting = TRUE; 127004007ebaSmrg (*GXRandRSetConfig) (pScreen, requestedRotation, 0, &p); 127104007ebaSmrg pGeode->starting = FALSE; 127204007ebaSmrg } 1273f29dbc25Smrg } 1274f29dbc25Smrg 1275f29dbc25Smrg return TRUE; 1276f29dbc25Smrg} 1277f29dbc25Smrg 1278f29dbc25Smrgstatic Bool 127904007ebaSmrgGXScreenInit(SCREEN_INIT_ARGS_DECL) 1280f29dbc25Smrg{ 128104007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 1282f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1283f29dbc25Smrg XF86ModReqInfo shadowReq; 1284f29dbc25Smrg int maj, min, ret, rotate; 1285f29dbc25Smrg 1286f29dbc25Smrg pGeode->starting = TRUE; 1287f29dbc25Smrg 1288f29dbc25Smrg /* If we are using VGA then go ahead and map the memory */ 1289f29dbc25Smrg 1290f29dbc25Smrg if (pGeode->useVGA) { 1291f29dbc25Smrg 129204007ebaSmrg if (!vgaHWMapMem(pScrni)) 129304007ebaSmrg return FALSE; 1294f29dbc25Smrg 129504007ebaSmrg vgaHWGetIOBase(VGAHWPTR(pScrni)); 1296f29dbc25Smrg } 1297f29dbc25Smrg 1298f29dbc25Smrg if (!pGeode->NoAccel) { 1299f29dbc25Smrg 130004007ebaSmrg if (pGeode->useEXA) { 130104007ebaSmrg 130204007ebaSmrg if (!(pGeode->pExa = exaDriverAlloc())) { 130304007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 130404007ebaSmrg "Couldn't allocate the EXA structure.\n"); 130504007ebaSmrg pGeode->NoAccel = TRUE; 130604007ebaSmrg } 130704007ebaSmrg else { 130804007ebaSmrg ExaDriverPtr pExa = pGeode->pExa; 130904007ebaSmrg 131004007ebaSmrg /* THis is set in GXAllocMem */ 131104007ebaSmrg pExa->memoryBase = 0; 131204007ebaSmrg 131304007ebaSmrg /* This is set in GXAllocateMemory */ 131404007ebaSmrg pExa->memorySize = 0; 131504007ebaSmrg 131604007ebaSmrg pExa->pixmapOffsetAlign = 32; 131704007ebaSmrg pExa->pixmapPitchAlign = 32; 131804007ebaSmrg pExa->flags = EXA_OFFSCREEN_PIXMAPS; 131904007ebaSmrg pExa->maxX = GX_MAX_WIDTH - 1; 132004007ebaSmrg pExa->maxY = GX_MAX_HEIGHT - 1; 132104007ebaSmrg } 132204007ebaSmrg } 132304007ebaSmrg else { 132404007ebaSmrg pGeode->AccelImageWriteBuffers = 132504007ebaSmrg calloc(pGeode->NoOfImgBuffers, 132604007ebaSmrg sizeof(pGeode->AccelImageWriteBuffers[0])); 132704007ebaSmrg pGeode->AccelColorExpandBuffers = 132804007ebaSmrg calloc(pGeode->NoOfColorExpandLines, 132904007ebaSmrg sizeof(pGeode->AccelColorExpandBuffers[0])); 133004007ebaSmrg } 1331f29dbc25Smrg } 1332f29dbc25Smrg 1333f29dbc25Smrg /* XXX FIXME - Take down any of the structures on failure? */ 1334f29dbc25Smrg 1335f29dbc25Smrg if (!GXEnterGraphics(pScrn, pScrni)) 133604007ebaSmrg return FALSE; 1337f29dbc25Smrg 1338f29dbc25Smrg miClearVisualTypes(); 1339f29dbc25Smrg 1340f29dbc25Smrg /* XXX Again - take down anything? */ 1341f29dbc25Smrg 1342f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 134304007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 134404007ebaSmrg TrueColorMask, pScrni->rgbBits, 134504007ebaSmrg pScrni->defaultVisual)) { 134604007ebaSmrg return FALSE; 134704007ebaSmrg } 134804007ebaSmrg } 134904007ebaSmrg else { 135004007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 135104007ebaSmrg miGetDefaultVisualMask(pScrni->depth), 135204007ebaSmrg pScrni->rgbBits, pScrni->defaultVisual)) { 135304007ebaSmrg return FALSE; 135404007ebaSmrg } 1355f29dbc25Smrg } 1356f29dbc25Smrg 1357f29dbc25Smrg miSetPixmapDepths(); 1358f29dbc25Smrg 1359f29dbc25Smrg /* Point at the visible area to start */ 1360f29dbc25Smrg 1361f29dbc25Smrg ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, 136204007ebaSmrg pScrni->virtualX, pScrni->virtualY, 136304007ebaSmrg pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, 136404007ebaSmrg pScrni->bitsPerPixel); 1365f29dbc25Smrg 1366f29dbc25Smrg if (!ret) 136704007ebaSmrg return FALSE; 1368f29dbc25Smrg 1369f29dbc25Smrg xf86SetBlackWhitePixels(pScrn); 1370f29dbc25Smrg 1371f29dbc25Smrg /* Set up the color ordering */ 1372f29dbc25Smrg 1373f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 137404007ebaSmrg VisualPtr visual = pScrn->visuals + pScrn->numVisuals; 137504007ebaSmrg 137604007ebaSmrg while (--visual >= pScrn->visuals) { 137704007ebaSmrg if ((visual->class | DynamicClass) == DirectColor) { 137804007ebaSmrg visual->offsetRed = pScrni->offset.red; 137904007ebaSmrg visual->offsetGreen = pScrni->offset.green; 138004007ebaSmrg visual->offsetBlue = pScrni->offset.blue; 138104007ebaSmrg visual->redMask = pScrni->mask.red; 138204007ebaSmrg visual->greenMask = pScrni->mask.green; 138304007ebaSmrg visual->blueMask = pScrni->mask.blue; 138404007ebaSmrg } 138504007ebaSmrg } 1386f29dbc25Smrg } 1387f29dbc25Smrg 1388f29dbc25Smrg /* Must follow the color ordering */ 1389f29dbc25Smrg fbPictureInit(pScrn, 0, 0); 1390f29dbc25Smrg 1391f29dbc25Smrg if (!pGeode->NoAccel) 139204007ebaSmrg GXAccelInit(pScrn); 1393f29dbc25Smrg 1394f29dbc25Smrg xf86SetBackingStore(pScrn); 1395f29dbc25Smrg 1396f29dbc25Smrg /* Set up the soft cursor */ 1397f29dbc25Smrg miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); 1398f29dbc25Smrg 1399f29dbc25Smrg /* Set up the HW cursor - must follow the soft cursor init */ 1400f29dbc25Smrg 1401f29dbc25Smrg if (pGeode->tryHWCursor) { 140204007ebaSmrg if (!GXHWCursorInit(pScrn)) 140304007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 140404007ebaSmrg "Hardware cursor initialization failed.\n"); 1405f29dbc25Smrg } 1406f29dbc25Smrg 1407f29dbc25Smrg /* Set up the color map */ 1408f29dbc25Smrg 1409f29dbc25Smrg if (!miCreateDefColormap(pScrn)) 141004007ebaSmrg return FALSE; 1411f29dbc25Smrg 1412f29dbc25Smrg if (pScrni->bitsPerPixel == 8) { 141304007ebaSmrg /* Must follow initialization of the default colormap */ 1414f29dbc25Smrg 141504007ebaSmrg if (!xf86HandleColormaps(pScrn, 256, 8, 141604007ebaSmrg GXLoadPalette, NULL, 141704007ebaSmrg CMAP_PALETTED_TRUECOLOR | 141804007ebaSmrg CMAP_RELOAD_ON_MODE_SWITCH)) { 141904007ebaSmrg return FALSE; 142004007ebaSmrg } 1421f29dbc25Smrg } 1422f29dbc25Smrg#ifdef DPMSExtension 1423f29dbc25Smrg xf86DPMSInit(pScrn, GXDPMSSet, 0); 1424f29dbc25Smrg#endif 1425f29dbc25Smrg 1426f29dbc25Smrg GXInitVideo(pScrn); 1427f29dbc25Smrg 1428f29dbc25Smrg /* Set up RandR */ 1429f29dbc25Smrg 143004007ebaSmrg xf86DisableRandR(); /* We provide our own RandR goodness */ 1431f29dbc25Smrg 1432f29dbc25Smrg /* Try to set up the shadow FB for rotation */ 1433f29dbc25Smrg 1434f29dbc25Smrg memset(&shadowReq, 0, sizeof(shadowReq)); 1435f29dbc25Smrg shadowReq.majorversion = 1; 1436f29dbc25Smrg shadowReq.minorversion = 1; 1437f29dbc25Smrg 1438f29dbc25Smrg if (LoadSubModule(pScrni->module, "shadow", 143904007ebaSmrg NULL, NULL, NULL, &shadowReq, &maj, &min)) { 1440f29dbc25Smrg 144104007ebaSmrg rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; 144204007ebaSmrg shadowSetup(pScrn); 144304007ebaSmrg } 144404007ebaSmrg else { 144504007ebaSmrg LoaderErrorMsg(NULL, "shadow", maj, min); 144604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 144704007ebaSmrg "Error loading shadow - rotation not available.\n"); 1448f29dbc25Smrg 144904007ebaSmrg if (pGeode->rotation != RR_Rotate_0) 145004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 145104007ebaSmrg "Reverting back to normal rotation.\n"); 1452f29dbc25Smrg 145304007ebaSmrg rotate = pGeode->rotation = RR_Rotate_0; 1454f29dbc25Smrg } 1455f29dbc25Smrg 1456f29dbc25Smrg GXRandRInit(pScrn, rotate); 1457f29dbc25Smrg 1458f29dbc25Smrg pGeode->PointerMoved = pScrni->PointerMoved; 1459f29dbc25Smrg pScrni->PointerMoved = GeodePointerMoved; 1460f29dbc25Smrg 1461f29dbc25Smrg pGeode->CreateScreenResources = pScrn->CreateScreenResources; 1462f29dbc25Smrg pScrn->CreateScreenResources = GXCreateScreenResources; 1463f29dbc25Smrg 1464f29dbc25Smrg pGeode->CloseScreen = pScrn->CloseScreen; 1465f29dbc25Smrg pScrn->CloseScreen = GXCloseScreen; 1466f29dbc25Smrg pScrn->SaveScreen = GXSaveScreen; 1467f29dbc25Smrg 1468f29dbc25Smrg if (serverGeneration == 1) 146904007ebaSmrg xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); 1470f29dbc25Smrg 1471f29dbc25Smrg pGeode->starting = FALSE; 1472f29dbc25Smrg 1473f29dbc25Smrg return TRUE; 1474f29dbc25Smrg} 1475f29dbc25Smrg 1476f29dbc25Smrgstatic int 147704007ebaSmrgGXValidMode(VALID_MODE_ARGS_DECL) 1478f29dbc25Smrg{ 147904007ebaSmrg SCRN_INFO_PTR(arg); 1480f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1481f29dbc25Smrg int p; 1482f29dbc25Smrg int custom = 0; 1483f29dbc25Smrg 1484f29dbc25Smrg if (pGeode->Panel) 148504007ebaSmrg custom = (pMode->type & M_T_USERDEF); 1486f29dbc25Smrg else 148704007ebaSmrg custom = (pMode->type & (M_T_BUILTIN | M_T_DEFAULT)); 1488f29dbc25Smrg 1489f29dbc25Smrg /* Use the durango lookup for !custom modes */ 1490f29dbc25Smrg 1491f29dbc25Smrg if (!custom && pGeode->Panel) { 1492f29dbc25Smrg if (pMode->CrtcHDisplay > pGeode->PanelX || 1493f29dbc25Smrg pMode->CrtcVDisplay > pGeode->PanelY || 1494f29dbc25Smrg gfx_is_panel_mode_supported(pGeode->PanelX, 1495f29dbc25Smrg pGeode->PanelY, 1496f29dbc25Smrg pMode->CrtcHDisplay, 1497f29dbc25Smrg pMode->CrtcVDisplay, 1498f29dbc25Smrg pScrni->bitsPerPixel) < 0) { 1499f29dbc25Smrg 1500f29dbc25Smrg return MODE_BAD; 1501f29dbc25Smrg } 1502f29dbc25Smrg } 1503f29dbc25Smrg 1504f29dbc25Smrg if (gfx_is_display_mode_supported(pMode->CrtcHDisplay, 1505f29dbc25Smrg pMode->CrtcVDisplay, 1506f29dbc25Smrg pScrni->bitsPerPixel, 1507f29dbc25Smrg GeodeGetRefreshRate(pMode)) < 0) { 1508f29dbc25Smrg return MODE_BAD; 1509f29dbc25Smrg } 1510f29dbc25Smrg 1511f29dbc25Smrg if (pMode->Flags & V_INTERLACE) 151204007ebaSmrg return MODE_NO_INTERLACE; 1513f29dbc25Smrg 1514f29dbc25Smrg if (pGeode->tryCompression) 151504007ebaSmrg p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, pScrni->bitsPerPixel); 1516f29dbc25Smrg else 151704007ebaSmrg p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 1518f29dbc25Smrg 1519f29dbc25Smrg if (p * pMode->CrtcVDisplay > pGeode->FBAvail) 152004007ebaSmrg return MODE_MEM; 1521f29dbc25Smrg 1522f29dbc25Smrg return MODE_OK; 1523f29dbc25Smrg} 1524f29dbc25Smrg 1525f29dbc25Smrg/* XXX - Way more to do here */ 1526f29dbc25Smrg 1527f29dbc25Smrgstatic Bool 152804007ebaSmrgGXEnterVT(VT_FUNC_ARGS_DECL) 1529f29dbc25Smrg{ 153004007ebaSmrg SCRN_INFO_PTR(arg); 153104007ebaSmrg return GXEnterGraphics(NULL, pScrni); 1532f29dbc25Smrg} 1533f29dbc25Smrg 1534f29dbc25Smrgstatic void 153504007ebaSmrgGXLeaveVT(VT_FUNC_ARGS_DECL) 1536f29dbc25Smrg{ 153704007ebaSmrg SCRN_INFO_PTR(arg); 1538f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1539f29dbc25Smrg 1540f29dbc25Smrg pGeode->PrevDisplayOffset = gfx_get_display_offset(); 154104007ebaSmrg GXLeaveGraphics(pScrni); 1542f29dbc25Smrg} 1543f29dbc25Smrg 1544f29dbc25Smrgvoid 1545f29dbc25SmrgGXSetupChipsetFPtr(ScrnInfoPtr pScrn) 1546f29dbc25Smrg{ 1547f29dbc25Smrg pScrn->PreInit = GXPreInit; 1548f29dbc25Smrg pScrn->ScreenInit = GXScreenInit; 1549f29dbc25Smrg pScrn->SwitchMode = GXSwitchMode; 1550f29dbc25Smrg pScrn->AdjustFrame = GXAdjustFrame; 1551f29dbc25Smrg pScrn->EnterVT = GXEnterVT; 1552f29dbc25Smrg pScrn->LeaveVT = GXLeaveVT; 1553f29dbc25Smrg pScrn->FreeScreen = GeodeFreeScreen; 1554f29dbc25Smrg pScrn->ValidMode = GXValidMode; 1555f29dbc25Smrg} 1556f29dbc25Smrg 1557f29dbc25Smrg/* ====== Common functions ====== 1558f29dbc25Smrg * These are all the common functions that we use for both GX and LX - They live here 1559f29dbc25Smrg * because most of them came along for the GX first, and then were adapted to the LX. 1560f29dbc25Smrg * We could move these to a common function, but there is no hurry 1561f29dbc25Smrg * ============================== */ 1562f29dbc25Smrg 1563f29dbc25Smrgvoid 156404007ebaSmrgGeodePointerMoved(POINTER_MOVED_ARGS_DECL) 1565f29dbc25Smrg{ 156604007ebaSmrg SCRN_INFO_PTR(arg); 1567f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1568f29dbc25Smrg 1569f29dbc25Smrg int newX = x, newY = y; 1570f29dbc25Smrg 1571f29dbc25Smrg switch (pGeode->rotation) { 1572f29dbc25Smrg case RR_Rotate_0: 157304007ebaSmrg break; 1574f29dbc25Smrg case RR_Rotate_90: 157504007ebaSmrg newX = y; 157604007ebaSmrg newY = pScrni->pScreen->width - x - 1; 157704007ebaSmrg break; 1578f29dbc25Smrg case RR_Rotate_180: 157904007ebaSmrg newX = pScrni->pScreen->width - x - 1; 158004007ebaSmrg newY = pScrni->pScreen->height - y - 1; 158104007ebaSmrg break; 1582f29dbc25Smrg case RR_Rotate_270: 158304007ebaSmrg newX = pScrni->pScreen->height - y - 1; 158404007ebaSmrg newY = x; 158504007ebaSmrg break; 1586f29dbc25Smrg } 1587f29dbc25Smrg 158804007ebaSmrg (*pGeode->PointerMoved) (POINTER_MOVED_ARGS(newX, newY)); 1589f29dbc25Smrg} 1590f29dbc25Smrg 1591f29dbc25Smrgint 1592f29dbc25SmrgGeodeGetFPGeometry(const char *str, int *width, int *height) 1593f29dbc25Smrg{ 1594f29dbc25Smrg 1595f29dbc25Smrg int ret = sscanf(str, "%dx%d", width, height); 1596f29dbc25Smrg 1597f29dbc25Smrg return (ret == 2) ? 0 : 1; 1598f29dbc25Smrg} 1599f29dbc25Smrg 1600f29dbc25Smrgstatic void 1601f29dbc25SmrgGeodeFreeRec(ScrnInfoPtr pScrni) 1602f29dbc25Smrg{ 1603f29dbc25Smrg if (pScrni->driverPrivate != NULL) { 160404007ebaSmrg free(pScrni->driverPrivate); 160504007ebaSmrg pScrni->driverPrivate = NULL; 1606f29dbc25Smrg } 1607f29dbc25Smrg} 1608f29dbc25Smrg 1609f29dbc25Smrgvoid 161004007ebaSmrgGeodeFreeScreen(FREE_SCREEN_ARGS_DECL) 1611f29dbc25Smrg{ 161204007ebaSmrg SCRN_INFO_PTR(arg); 161304007ebaSmrg GeodeRec *pGeode = GEODEPTR(pScrni); 1614f29dbc25Smrg 1615f29dbc25Smrg if (pGeode == NULL) 161604007ebaSmrg return; 1617f29dbc25Smrg 1618f29dbc25Smrg if (pGeode->useVGA) { 161904007ebaSmrg if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 162004007ebaSmrg vgaHWFreeHWRec(pScrni); 1621f29dbc25Smrg } 1622f29dbc25Smrg 162304007ebaSmrg GeodeFreeRec(pScrni); 1624f29dbc25Smrg} 1625f29dbc25Smrg 1626f29dbc25Smrgint 1627f29dbc25SmrgGeodeCalculatePitchBytes(unsigned int width, unsigned int bpp) 1628f29dbc25Smrg{ 1629f29dbc25Smrg 1630f29dbc25Smrg int delta = width * (bpp >> 3); 1631f29dbc25Smrg 1632f29dbc25Smrg /* Less then 640 has doubling enabled */ 1633f29dbc25Smrg 1634f29dbc25Smrg if (width < 640) 163504007ebaSmrg delta <<= 1; 1636f29dbc25Smrg 1637f29dbc25Smrg /* Calculate the pitch (compression rquires a power of 2) */ 1638f29dbc25Smrg 1639f29dbc25Smrg if (delta > 4096) 164004007ebaSmrg delta = 8192; 1641f29dbc25Smrg else if (delta > 2048) 164204007ebaSmrg delta = 4096; 1643f29dbc25Smrg else if (delta > 1024) 164404007ebaSmrg delta = 2048; 1645f29dbc25Smrg else 164604007ebaSmrg delta = 1024; 1647f29dbc25Smrg 1648f29dbc25Smrg return delta; 1649f29dbc25Smrg} 1650