gx_driver.c revision f29dbc25
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> 35f29dbc25Smrg 36f29dbc25Smrg#include "xf86.h" 37f29dbc25Smrg#include "xf86_OSproc.h" 38f29dbc25Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 39f29dbc25Smrg#include "xf86Resources.h" 40f29dbc25Smrg#endif 41f29dbc25Smrg#include "xf86cmap.h" 42f29dbc25Smrg#include "compiler.h" 43f29dbc25Smrg#include "mipointer.h" 44f29dbc25Smrg#include "shadow.h" 45f29dbc25Smrg#include <X11/extensions/randr.h> 46f29dbc25Smrg#include "fb.h" 47f29dbc25Smrg#include "miscstruct.h" 48f29dbc25Smrg#include "micmap.h" 49f29dbc25Smrg#include "vbe.h" 50f29dbc25Smrg#include "fb.h" 51f29dbc25Smrg#include "randrstr.h" 52f29dbc25Smrg 53f29dbc25Smrg#include "geode.h" 54f29dbc25Smrg#include "gfx_defs.h" 55f29dbc25Smrg#include "gfx_regs.h" 56f29dbc25Smrg#include "panel.h" 57f29dbc25Smrg 58f29dbc25Smrg/* Bring in VGA functions */ 59f29dbc25Smrg#include "gx_vga.c" 60f29dbc25Smrg 61f29dbc25Smrg#define GX_MIN_PITCH 1024 62f29dbc25Smrg#define GX_MAX_PITCH 8192 63f29dbc25Smrg#define GX_MAX_WIDTH 1600 64f29dbc25Smrg#define GX_MIN_HEIGHT 400 65f29dbc25Smrg#define GX_MAX_HEIGHT 1200 66f29dbc25Smrg#define GX_CB_PITCH 544 67f29dbc25Smrg#define GX_CB_SIZE 544 68f29dbc25Smrg 69f29dbc25Smrg#define GX_CPU_REG_SIZE 0x4000 70f29dbc25Smrg#define GX_GP_REG_SIZE 0x4000 71f29dbc25Smrg#define GX_VID_REG_SIZE 0x4000 72f29dbc25Smrg 73f29dbc25Smrg#define DEFAULT_IMG_LINE_BUFS 20 74f29dbc25Smrg#define DEFAULT_CLR_LINE_BUFS 20 75f29dbc25Smrg 76f29dbc25Smrgextern OptionInfoRec GX_GeodeOptions[]; 77f29dbc25Smrg 78f29dbc25Smrgunsigned char *XpressROMPtr; 79f29dbc25Smrg 80f29dbc25Smrgstatic inline void 81f29dbc25Smrggx_enable_dac_power(void) 82f29dbc25Smrg{ 83f29dbc25Smrg gfx_write_vid32(RCDF_VID_MISC, 84f29dbc25Smrg gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH); 85f29dbc25Smrg} 86f29dbc25Smrg 87f29dbc25Smrgstatic inline void 88f29dbc25Smrggx_disable_dac_power(void) 89f29dbc25Smrg{ 90f29dbc25Smrg gfx_write_vid32(RCDF_VID_MISC, 91f29dbc25Smrg RCDF_DAC_POWER_DOWN | RCDF_ANALOG_POWER_DOWN | 92f29dbc25Smrg (gfx_read_vid32(RCDF_VID_MISC) & RCDF_GAMMA_BYPASS_BOTH)); 93f29dbc25Smrg} 94f29dbc25Smrg 95f29dbc25Smrgstatic void 96f29dbc25SmrgGXInitEXAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) 97f29dbc25Smrg{ 98f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 99f29dbc25Smrg 100f29dbc25Smrg if (pGeode->exaBfrSz > 0 && pGeode->exaBfrSz <= *avail) { 101f29dbc25Smrg pGeode->exaBfrOffset = *offset; 102f29dbc25Smrg *offset += pGeode->exaBfrOffset; 103f29dbc25Smrg *avail -= pGeode->exaBfrOffset; 104f29dbc25Smrg } 105f29dbc25Smrg} 106f29dbc25Smrg 107f29dbc25Smrgstatic void 108f29dbc25SmrgGXInitXAAMemory(ScrnInfoPtr pScrni, unsigned int *offset, unsigned int *avail) 109f29dbc25Smrg{ 110f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 111f29dbc25Smrg unsigned int size, i, pitch; 112f29dbc25Smrg 113f29dbc25Smrg /* XXX - FIXME - What if we are out of room? Then what? */ 114f29dbc25Smrg /* For now, we NULL them all out. */ 115f29dbc25Smrg 116f29dbc25Smrg if (pGeode->NoOfImgBuffers > 0) { 117f29dbc25Smrg size = pGeode->displayPitch * pGeode->NoOfImgBuffers; 118f29dbc25Smrg if (size <= *avail) { 119f29dbc25Smrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) { 120f29dbc25Smrg pGeode->AccelImageWriteBuffers[i] = pGeode->FBBase + *offset; 121f29dbc25Smrg *offset += pGeode->displayPitch; 122f29dbc25Smrg *avail -= pGeode->displayPitch; 123f29dbc25Smrg } 124f29dbc25Smrg } else { 125f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 126f29dbc25Smrg "Not enough memory for image write buffers.\n"); 127f29dbc25Smrg 128f29dbc25Smrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) 129f29dbc25Smrg pGeode->AccelImageWriteBuffers[i] = NULL; 130f29dbc25Smrg } 131f29dbc25Smrg } 132f29dbc25Smrg 133f29dbc25Smrg if (pGeode->NoOfColorExpandLines > 0) { 134f29dbc25Smrg pitch = ((pGeode->displayPitch + 31) >> 5) << 2; 135f29dbc25Smrg size = pitch * pGeode->NoOfColorExpandLines; 136f29dbc25Smrg 137f29dbc25Smrg if (size <= *avail) { 138f29dbc25Smrg for (i = 0; i < pGeode->NoOfColorExpandLines; i++) { 139f29dbc25Smrg pGeode->AccelColorExpandBuffers[i] = pGeode->FBBase + *offset; 140f29dbc25Smrg *offset += pitch; 141f29dbc25Smrg *avail -= pitch; 142f29dbc25Smrg } 143f29dbc25Smrg } else { 144f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 145f29dbc25Smrg "Not enough memory for color expansion buffers.\n"); 146f29dbc25Smrg 147f29dbc25Smrg for (i = 0; i < pGeode->NoOfImgBuffers; i++) 148f29dbc25Smrg pGeode->AccelColorExpandBuffers[i] = NULL; 149f29dbc25Smrg } 150f29dbc25Smrg } 151f29dbc25Smrg} 152f29dbc25Smrg 153f29dbc25Smrgstatic Bool 154f29dbc25SmrgGXAllocateMemory(ScreenPtr pScrn, ScrnInfoPtr pScrni, int rotate) 155f29dbc25Smrg{ 156f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 157f29dbc25Smrg 158f29dbc25Smrg unsigned int fboffset, fbavail; 159f29dbc25Smrg unsigned int size; 160f29dbc25Smrg unsigned int bytpp = (pScrni->bitsPerPixel + 7) / 8; 161f29dbc25Smrg BOOL ret = TRUE; 162f29dbc25Smrg 163f29dbc25Smrg if (pGeode->tryCompression) 164f29dbc25Smrg pGeode->displayPitch = 165f29dbc25Smrg GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); 166f29dbc25Smrg else 167f29dbc25Smrg pGeode->displayPitch = 168f29dbc25Smrg ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 169f29dbc25Smrg 170f29dbc25Smrg pGeode->Pitch = pGeode->displayPitch; 171f29dbc25Smrg pGeode->displayWidth = pGeode->displayPitch / bytpp; 172f29dbc25Smrg pScrni->displayWidth = pGeode->displayWidth; 173f29dbc25Smrg 174f29dbc25Smrg fbavail = pGeode->FBAvail - 0x4000; 175f29dbc25Smrg 176f29dbc25Smrg pGeode->displayOffset = fboffset = 0; 177f29dbc25Smrg pGeode->displaySize = pScrni->virtualY * pGeode->displayPitch; 178f29dbc25Smrg 179f29dbc25Smrg fbavail -= pGeode->displaySize; 180f29dbc25Smrg fboffset += pGeode->displaySize; 181f29dbc25Smrg 182f29dbc25Smrg if (pGeode->tryCompression) { 183f29dbc25Smrg size = pScrni->virtualY * GX_CB_PITCH; 184f29dbc25Smrg 185f29dbc25Smrg if (size <= fbavail) { 186f29dbc25Smrg pGeode->CBData.compression_offset = fboffset; 187f29dbc25Smrg 188f29dbc25Smrg fboffset += size; 189f29dbc25Smrg fbavail -= size; 190f29dbc25Smrg 191f29dbc25Smrg pGeode->Compression = TRUE; 192f29dbc25Smrg } else { 193f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 194f29dbc25Smrg "Not enough memory for compression\n"); 195f29dbc25Smrg pGeode->Compression = FALSE; 196f29dbc25Smrg } 197f29dbc25Smrg } 198f29dbc25Smrg 199f29dbc25Smrg if (pGeode->tryHWCursor) { 200f29dbc25Smrg 201f29dbc25Smrg if (fbavail >= 1024) { 202f29dbc25Smrg pGeode->CursorStartOffset = fboffset; 203f29dbc25Smrg fboffset += 1024; 204f29dbc25Smrg fbavail -= 1024; 205f29dbc25Smrg pGeode->HWCursor = TRUE; 206f29dbc25Smrg } else { 207f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 208f29dbc25Smrg "Not enough memory for the hardware cursor\n"); 209f29dbc25Smrg pGeode->HWCursor = FALSE; 210f29dbc25Smrg } 211f29dbc25Smrg } 212f29dbc25Smrg 213f29dbc25Smrg if (!pGeode->NoAccel) { 214f29dbc25Smrg if (pGeode->useEXA) 215f29dbc25Smrg GXInitEXAMemory(pScrni, &fboffset, &fbavail); 216f29dbc25Smrg else 217f29dbc25Smrg GXInitXAAMemory(pScrni, &fboffset, &fbavail); 218f29dbc25Smrg } 219f29dbc25Smrg 220f29dbc25Smrg pGeode->shadowSize = 0; 221f29dbc25Smrg 222f29dbc25Smrg if (rotate != RR_Rotate_0) { 223f29dbc25Smrg if (rotate & (RR_Rotate_90 | RR_Rotate_270)) 224f29dbc25Smrg size = pGeode->displayPitch * pScrni->virtualX; 225f29dbc25Smrg else 226f29dbc25Smrg size = pGeode->displayPitch * pScrni->virtualY; 227f29dbc25Smrg 228f29dbc25Smrg if (size <= fbavail) { 229f29dbc25Smrg pGeode->shadowOffset = fboffset; 230f29dbc25Smrg pGeode->shadowSize = size; 231f29dbc25Smrg 232f29dbc25Smrg fboffset += size; 233f29dbc25Smrg fbavail -= size; 234f29dbc25Smrg } else { 235f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 236f29dbc25Smrg "Not enough memory for the shadow framebuffer\n"); 237f29dbc25Smrg ret = FALSE; 238f29dbc25Smrg } 239f29dbc25Smrg } 240f29dbc25Smrg 241f29dbc25Smrg /* XAA always exists - we can't remove it on demand like we can with EXA. 242f29dbc25Smrg * So we assume the worse, and only give XAA enough offspace room to 243f29dbc25Smrg * account for any eventuality that RandR might throw at us. */ 244f29dbc25Smrg 245f29dbc25Smrg if (!pGeode->NoAccel) { 246f29dbc25Smrg 247f29dbc25Smrg if (pGeode->useEXA && pGeode->pExa) { 248f29dbc25Smrg ExaDriverPtr pExa = pGeode->pExa; 249f29dbc25Smrg 250f29dbc25Smrg pExa->offScreenBase = fboffset; 251f29dbc25Smrg pExa->memorySize = fboffset + fbavail; 252f29dbc25Smrg } 253f29dbc25Smrg 254f29dbc25Smrg if (!pGeode->useEXA) { 255f29dbc25Smrg 256f29dbc25Smrg if (!xf86FBManagerRunning(pScrn)) { 257f29dbc25Smrg 258f29dbc25Smrg unsigned int offset = fboffset; 259f29dbc25Smrg unsigned int avail = fbavail; 260f29dbc25Smrg RegionRec OffscreenRegion; 261f29dbc25Smrg BoxRec AvailBox; 262f29dbc25Smrg 263f29dbc25Smrg /* Assume the shadow FB exists even if it doesnt */ 264f29dbc25Smrg 265f29dbc25Smrg if (pGeode->shadowSize == 0) { 266f29dbc25Smrg size = (pScrn->width * bytpp) * pScrni->virtualX; 267f29dbc25Smrg offset += size; 268f29dbc25Smrg avail -= size; 269f29dbc25Smrg } 270f29dbc25Smrg 271f29dbc25Smrg AvailBox.x1 = 0; 272f29dbc25Smrg AvailBox.y1 = 273f29dbc25Smrg (offset + pGeode->displayPitch - 274f29dbc25Smrg 1) / pGeode->displayPitch; 275f29dbc25Smrg 276f29dbc25Smrg AvailBox.x2 = pGeode->displayWidth; 277f29dbc25Smrg AvailBox.y2 = (offset + avail) / pGeode->displayPitch; 278f29dbc25Smrg 279f29dbc25Smrg if (AvailBox.y1 < AvailBox.y2) { 280f29dbc25Smrg REGION_INIT(pScrn, &OffscreenRegion, &AvailBox, 2); 281f29dbc25Smrg 282f29dbc25Smrg if (!xf86InitFBManagerRegion(pScrn, &OffscreenRegion)) 283f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 284f29dbc25Smrg "Memory manager initialization failed.\n"); 285f29dbc25Smrg 286f29dbc25Smrg REGION_UNINIT(pScrn, &OffscreenRegion); 287f29dbc25Smrg } else 288f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 289f29dbc25Smrg "Cache disabled - no offscreen memory available.\n"); 290f29dbc25Smrg } else 291f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 292f29dbc25Smrg "XAA offscreen memory has already been allocated.\n"); 293f29dbc25Smrg } 294f29dbc25Smrg } 295f29dbc25Smrg return ret; 296f29dbc25Smrg} 297f29dbc25Smrg 298f29dbc25Smrgstatic Bool 299f29dbc25SmrgGXSaveScreen(ScreenPtr pScrn, int mode) 300f29dbc25Smrg{ 301f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; 302f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 303f29dbc25Smrg 304f29dbc25Smrg if (pGeode->useVGA && !pScrni->vtSema) 305f29dbc25Smrg return vgaHWSaveScreen(pScrn, mode); 306f29dbc25Smrg 307f29dbc25Smrg return TRUE; 308f29dbc25Smrg} 309f29dbc25Smrg 310f29dbc25Smrg/* Common function - used by the LX too */ 311f29dbc25Smrg#ifdef XSERVER_LIBPCIACCESS 312f29dbc25Smrgstatic inline void * 313f29dbc25Smrgmap_pci_mem(ScrnInfoPtr pScrni, int vram, 314f29dbc25Smrg struct pci_device *dev, int bar, int size) 315f29dbc25Smrg{ 316f29dbc25Smrg void *ptr; 317f29dbc25Smrg void **result = (void **)&ptr; 318f29dbc25Smrg int map_size = size ? size : dev->regions[bar].size; 319f29dbc25Smrg 320f29dbc25Smrg int err = pci_device_map_range(dev, 321f29dbc25Smrg dev->regions[bar].base_addr, 322f29dbc25Smrg map_size, 323f29dbc25Smrg PCI_DEV_MAP_FLAG_WRITABLE | 324f29dbc25Smrg (vram ? PCI_DEV_MAP_FLAG_WRITE_COMBINE : 0), 325f29dbc25Smrg result); 326f29dbc25Smrg 327f29dbc25Smrg if (err) 328f29dbc25Smrg return NULL; 329f29dbc25Smrg return ptr; 330f29dbc25Smrg} 331f29dbc25Smrg#endif 332f29dbc25Smrg 333f29dbc25Smrgextern unsigned long gfx_gx2_scratch_base; 334f29dbc25Smrg 335f29dbc25Smrgstatic Bool 336f29dbc25SmrgGXMapMem(ScrnInfoPtr pScrni) 337f29dbc25Smrg{ 338f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 339f29dbc25Smrg int index = pScrni->scrnIndex; 340f29dbc25Smrg 341f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 342f29dbc25Smrg 343f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 344f29dbc25Smrg gfx_virt_regptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, 345f29dbc25Smrg pci->memBase[2], pci->size[2]); 346f29dbc25Smrg 347f29dbc25Smrg gfx_virt_gpptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, 348f29dbc25Smrg pci->memBase[1], pci->size[1]); 349f29dbc25Smrg 350f29dbc25Smrg gfx_virt_vidptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_MMIO, 351f29dbc25Smrg pci->memBase[3], pci->size[3]); 352f29dbc25Smrg 353f29dbc25Smrg gfx_virt_fbptr = (unsigned char *)xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 354f29dbc25Smrg pci->memBase[0], pGeode->FBAvail); 355f29dbc25Smrg#else 356f29dbc25Smrg gfx_virt_regptr = map_pci_mem(pScrni, 0, pci, 2, 0); 357f29dbc25Smrg gfx_virt_gpptr = map_pci_mem(pScrni, 0, pci, 1, 0); 358f29dbc25Smrg gfx_virt_vidptr = map_pci_mem(pScrni, 0, pci, 3, 0); 359f29dbc25Smrg gfx_virt_fbptr = map_pci_mem(pScrni, 1, pci, 0, pGeode->FBAvail); 360f29dbc25Smrg#endif 361f29dbc25Smrg 362f29dbc25Smrg gfx_gx2_scratch_base = pGeode->FBAvail - 0x4000; 363f29dbc25Smrg 364f29dbc25Smrg XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); 365f29dbc25Smrg 366f29dbc25Smrg pGeode->FBBase = gfx_virt_fbptr; 367f29dbc25Smrg 368f29dbc25Smrg if ((!gfx_virt_regptr) || (!gfx_virt_gpptr) || 369f29dbc25Smrg (!gfx_virt_vidptr) || (!gfx_virt_fbptr)) 370f29dbc25Smrg return FALSE; 371f29dbc25Smrg 372f29dbc25Smrg if (!pGeode->NoAccel && pGeode->useEXA) 373f29dbc25Smrg pGeode->pExa->memoryBase = pGeode->FBBase; 374f29dbc25Smrg 375f29dbc25Smrg xf86DrvMsg(index, X_INFO, "Found Geode %x %p\n", 376f29dbc25Smrg pGeode->FBAvail, pGeode->FBBase); 377f29dbc25Smrg 378f29dbc25Smrg return TRUE; 379f29dbc25Smrg} 380f29dbc25Smrg 381f29dbc25Smrg/* Check to see if VGA exists - we map the space and look for a 382f29dbc25Smrg signature - if it doesn't match exactly, then we assume no VGA. 383f29dbc25Smrg*/ 384f29dbc25Smrg 385f29dbc25Smrgstatic Bool 386f29dbc25SmrgGXCheckVGA(ScrnInfoPtr pScrni) 387f29dbc25Smrg{ 388f29dbc25Smrg 389f29dbc25Smrg unsigned char *ptr; 390f29dbc25Smrg const char *vgasig = "IBM VGA Compatible"; 391f29dbc25Smrg int ret; 392f29dbc25Smrg 393f29dbc25Smrg ptr = 394f29dbc25Smrg xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, 0xC001E, 395f29dbc25Smrg strlen(vgasig)); 396f29dbc25Smrg 397f29dbc25Smrg if (ptr == NULL) 398f29dbc25Smrg return FALSE; 399f29dbc25Smrg 400f29dbc25Smrg ret = memcmp(ptr, vgasig, strlen(vgasig)); 401f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) ptr, strlen(vgasig)); 402f29dbc25Smrg 403f29dbc25Smrg return ret ? FALSE : TRUE; 404f29dbc25Smrg} 405f29dbc25Smrg 406f29dbc25Smrgstatic Bool 407f29dbc25SmrgGXPreInit(ScrnInfoPtr pScrni, int flags) 408f29dbc25Smrg{ 409f29dbc25Smrg GeodePtr pGeode; 410f29dbc25Smrg ClockRangePtr GeodeClockRange; 411f29dbc25Smrg OptionInfoRec *GeodeOptions = &GX_GeodeOptions[0]; 412f29dbc25Smrg int ret; 413f29dbc25Smrg QQ_WORD msrValue; 414f29dbc25Smrg EntityInfoPtr pEnt; 415f29dbc25Smrg rgb defaultWeight = { 0, 0, 0 }; 416f29dbc25Smrg int modecnt; 417f29dbc25Smrg char *s, *panelgeo; 418f29dbc25Smrg Bool useVGA; 419f29dbc25Smrg 420f29dbc25Smrg if (pScrni->numEntities != 1) 421f29dbc25Smrg return FALSE; 422f29dbc25Smrg 423f29dbc25Smrg pEnt = xf86GetEntityInfo(pScrni->entityList[0]); 424f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 425f29dbc25Smrg if (pEnt->resources) 426f29dbc25Smrg return FALSE; 427f29dbc25Smrg#endif 428f29dbc25Smrg 429f29dbc25Smrg pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); 430f29dbc25Smrg 431f29dbc25Smrg if (pGeode == NULL) 432f29dbc25Smrg return FALSE; 433f29dbc25Smrg 434f29dbc25Smrg useVGA = GXCheckVGA(pScrni); 435f29dbc25Smrg 436f29dbc25Smrg if (flags & PROBE_DETECT) { 437f29dbc25Smrg GeodeProbeDDC(pScrni, pEnt->index); 438f29dbc25Smrg return TRUE; 439f29dbc25Smrg } 440f29dbc25Smrg 441f29dbc25Smrg /* Probe for VGA */ 442f29dbc25Smrg pGeode->useVGA = useVGA; 443f29dbc25Smrg pGeode->pEnt = pEnt; 444f29dbc25Smrg 445f29dbc25Smrg if (pGeode->useVGA) { 446f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "vgahw") || !vgaHWGetHWRec(pScrni)) 447f29dbc25Smrg pGeode->useVGA = FALSE; 448f29dbc25Smrg 449f29dbc25Smrg#if INT10_SUPPORT 450f29dbc25Smrg pGeode->vesa = xcalloc(sizeof(VESARec), 1); 451f29dbc25Smrg#endif 452f29dbc25Smrg } 453f29dbc25Smrg 454f29dbc25Smrg gfx_msr_init(); 455f29dbc25Smrg 456f29dbc25Smrg ret = gfx_msr_read(RC_ID_DF, MBD_MSR_CONFIG, &msrValue); 457f29dbc25Smrg 458f29dbc25Smrg if (!ret) { 459f29dbc25Smrg pGeode->Output = 460f29dbc25Smrg ((msrValue.low & RCDF_CONFIG_FMT_MASK) == 461f29dbc25Smrg RCDF_CONFIG_FMT_FP) ? OUTPUT_PANEL : OUTPUT_CRT; 462f29dbc25Smrg } 463f29dbc25Smrg 464f29dbc25Smrg /* Fill in the monitor information */ 465f29dbc25Smrg pScrni->monitor = pScrni->confScreen->monitor; 466f29dbc25Smrg 467f29dbc25Smrg if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) 468f29dbc25Smrg return FALSE; 469f29dbc25Smrg 470f29dbc25Smrg switch (pScrni->depth) { 471f29dbc25Smrg case 8: 472f29dbc25Smrg pScrni->rgbBits = 8; 473f29dbc25Smrg case 16: 474f29dbc25Smrg case 24: 475f29dbc25Smrg case 32: 476f29dbc25Smrg break; 477f29dbc25Smrg default: 478f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 479f29dbc25Smrg "The driver does not support %d as a depth.\n", pScrni->depth); 480f29dbc25Smrg return FALSE; 481f29dbc25Smrg } 482f29dbc25Smrg 483f29dbc25Smrg xf86PrintDepthBpp(pScrni); 484f29dbc25Smrg 485f29dbc25Smrg if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) 486f29dbc25Smrg return FALSE; 487f29dbc25Smrg 488f29dbc25Smrg if (!xf86SetDefaultVisual(pScrni, -1)) 489f29dbc25Smrg return FALSE; 490f29dbc25Smrg 491f29dbc25Smrg /* 492f29dbc25Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 493f29dbc25Smrg * here. 494f29dbc25Smrg */ 495f29dbc25Smrg { 496f29dbc25Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 497f29dbc25Smrg 498f29dbc25Smrg if (!xf86SetGamma(pScrni, zeros)) { 499f29dbc25Smrg return FALSE; 500f29dbc25Smrg } 501f29dbc25Smrg } 502f29dbc25Smrg 503f29dbc25Smrg pScrni->progClock = TRUE; 504f29dbc25Smrg xf86CollectOptions(pScrni, NULL); 505f29dbc25Smrg xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); 506f29dbc25Smrg 507f29dbc25Smrg /* Set up our various options that may get reversed as we go on */ 508f29dbc25Smrg 509f29dbc25Smrg pGeode->FBVGAActive = FALSE; 510f29dbc25Smrg pGeode->tryHWCursor = TRUE; 511f29dbc25Smrg pGeode->tryCompression = TRUE; 512f29dbc25Smrg 513f29dbc25Smrg pGeode->NoAccel = FALSE; 514f29dbc25Smrg pGeode->useEXA = FALSE; 515f29dbc25Smrg 516f29dbc25Smrg pGeode->Panel = (pGeode->Output & OUTPUT_PANEL) ? TRUE : FALSE; 517f29dbc25Smrg 518f29dbc25Smrg pGeode->NoOfImgBuffers = DEFAULT_IMG_LINE_BUFS; 519f29dbc25Smrg pGeode->NoOfColorExpandLines = DEFAULT_CLR_LINE_BUFS; 520f29dbc25Smrg pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; 521f29dbc25Smrg 522f29dbc25Smrg xf86GetOptValBool(GeodeOptions, GX_OPTION_HW_CURSOR, 523f29dbc25Smrg &pGeode->tryHWCursor); 524f29dbc25Smrg 525f29dbc25Smrg if (!xf86GetOptValInteger(GeodeOptions, GX_OPTION_FBSIZE, 526f29dbc25Smrg (int *)&(pGeode->FBAvail))) 527f29dbc25Smrg pGeode->FBAvail = 0; 528f29dbc25Smrg 529f29dbc25Smrg /* For compatability - allow SWCursor too */ 530f29dbc25Smrg 531f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_SW_CURSOR, FALSE)) 532f29dbc25Smrg pGeode->tryHWCursor = FALSE; 533f29dbc25Smrg 534f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOCOMPRESSION, FALSE)) 535f29dbc25Smrg pGeode->tryCompression = FALSE; 536f29dbc25Smrg 537f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOACCEL, FALSE)) 538f29dbc25Smrg pGeode->NoAccel = TRUE; 539f29dbc25Smrg 540f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 541f29dbc25Smrg 542f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ROTATE))) { 543f29dbc25Smrg 544f29dbc25Smrg if (!xf86NameCmp(s, "LEFT")) 545f29dbc25Smrg pGeode->rotation = RR_Rotate_90; 546f29dbc25Smrg else if (!xf86NameCmp(s, "INVERT")) 547f29dbc25Smrg pGeode->rotation = RR_Rotate_180; 548f29dbc25Smrg else if (!xf86NameCmp(s, "CCW")) 549f29dbc25Smrg pGeode->rotation = RR_Rotate_270; 550f29dbc25Smrg else 551f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 552f29dbc25Smrg "Invalid rotation %s.\n", s); 553f29dbc25Smrg } 554f29dbc25Smrg 555f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_IMG_BUFS, 556f29dbc25Smrg &(pGeode->NoOfImgBuffers)); 557f29dbc25Smrg 558f29dbc25Smrg if (pGeode->NoOfImgBuffers <= 0) 559f29dbc25Smrg pGeode->NoOfImgBuffers = 0; 560f29dbc25Smrg 561f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, 562f29dbc25Smrg &(pGeode->NoOfColorExpandLines)); 563f29dbc25Smrg 564f29dbc25Smrg if (pGeode->NoOfColorExpandLines <= 0) 565f29dbc25Smrg pGeode->NoOfColorExpandLines = 0; 566f29dbc25Smrg 567f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, GX_OPTION_OSM_CLR_BUFS, 568f29dbc25Smrg (int *)&(pGeode->exaBfrSz)); 569f29dbc25Smrg 570f29dbc25Smrg if (pGeode->exaBfrSz <= 0) 571f29dbc25Smrg pGeode->exaBfrSz = 0; 572f29dbc25Smrg 573f29dbc25Smrg if (pGeode->Panel == TRUE) { 574f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, GX_OPTION_NOPANEL, FALSE)) 575f29dbc25Smrg pGeode->Panel = FALSE; 576f29dbc25Smrg } 577f29dbc25Smrg 578f29dbc25Smrg panelgeo = xf86GetOptValString(GeodeOptions, GX_OPTION_PANEL_GEOMETRY); 579f29dbc25Smrg 580f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, GX_OPTION_ACCEL_METHOD))) { 581f29dbc25Smrg if (!xf86NameCmp(s, "XAA")) 582f29dbc25Smrg pGeode->useEXA = FALSE; 583f29dbc25Smrg else if (xf86NameCmp(s, "EXA")) 584f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 585f29dbc25Smrg "Unknown accleration method %s. Defaulting to XAA.\n", s); 586f29dbc25Smrg } 587f29dbc25Smrg 588f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 589f29dbc25Smrg "Using %s acceleration architecture\n", 590f29dbc25Smrg pGeode->useEXA ? "EXA" : "XAA"); 591f29dbc25Smrg 592f29dbc25Smrg /* Set up the panel */ 593f29dbc25Smrg 594f29dbc25Smrg if (pGeode->Panel) { 595f29dbc25Smrg if (panelgeo != NULL) { 596f29dbc25Smrg if (GeodeGetFPGeometry(panelgeo, &pGeode->PanelX, 597f29dbc25Smrg &pGeode->PanelY)) 598f29dbc25Smrg pGeode->Panel = FALSE; 599f29dbc25Smrg } 600f29dbc25Smrg#ifdef PNL_SUP 601f29dbc25Smrg else { 602f29dbc25Smrg int b, f; 603f29dbc25Smrg 604f29dbc25Smrg /* The bitdepth and refresh isn't used anywhere else in the driver */ 605f29dbc25Smrg 606f29dbc25Smrg if ((pGeode->Panel = Pnl_IsPanelEnabledInBIOS())) 607f29dbc25Smrg Pnl_GetPanelInfoFromBIOS(&pGeode->PanelX, &pGeode->PanelY, &b, 608f29dbc25Smrg &f); 609f29dbc25Smrg } 610f29dbc25Smrg#endif 611f29dbc25Smrg } 612f29dbc25Smrg 613f29dbc25Smrg /* Set up the VGA */ 614f29dbc25Smrg 615f29dbc25Smrg if (pGeode->useVGA) { 616f29dbc25Smrg#if INT10_SUPPORT 617f29dbc25Smrg VESARec *pVesa; 618f29dbc25Smrg 619f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "int10")) 620f29dbc25Smrg return FALSE; 621f29dbc25Smrg 622f29dbc25Smrg pVesa = pGeode->vesa; 623f29dbc25Smrg 624f29dbc25Smrg if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { 625f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 626f29dbc25Smrg "Unable to initialize 1NT10 support\n"); 627f29dbc25Smrg pGeode->useVGA = FALSE; 628f29dbc25Smrg } 629f29dbc25Smrg#endif 630f29dbc25Smrg } 631f29dbc25Smrg 632f29dbc25Smrg /* First try to get the framebuffer size from the framebuffer, 633f29dbc25Smrg * and if that fails, revert all the way back to the legacy 634f29dbc25Smrg * method 635f29dbc25Smrg */ 636f29dbc25Smrg 637f29dbc25Smrg if (pGeode->FBAvail == 0) { 638f29dbc25Smrg if (GeodeGetSizeFromFB(&pGeode->FBAvail)) 639f29dbc25Smrg pGeode->FBAvail = gfx_get_frame_buffer_size(); 640f29dbc25Smrg } 641f29dbc25Smrg 642f29dbc25Smrg if (pScrni->memPhysBase == 0) 643f29dbc25Smrg pScrni->memPhysBase = gfx_get_frame_buffer_base(); 644f29dbc25Smrg 645f29dbc25Smrg pScrni->fbOffset = 0; 646f29dbc25Smrg 647f29dbc25Smrg if (pGeode->pEnt->device->videoRam == 0) 648f29dbc25Smrg pScrni->videoRam = pGeode->FBAvail / 1024; 649f29dbc25Smrg else 650f29dbc25Smrg pScrni->videoRam = pGeode->pEnt->device->videoRam; 651f29dbc25Smrg 652f29dbc25Smrg GeodeClockRange = (ClockRangePtr) xnfcalloc(sizeof(ClockRange), 1); 653f29dbc25Smrg GeodeClockRange->next = NULL; 654f29dbc25Smrg GeodeClockRange->minClock = 25175; 655f29dbc25Smrg GeodeClockRange->maxClock = 229500; 656f29dbc25Smrg GeodeClockRange->clockIndex = -1; 657f29dbc25Smrg GeodeClockRange->interlaceAllowed = TRUE; 658f29dbc25Smrg GeodeClockRange->doubleScanAllowed = FALSE; 659f29dbc25Smrg 660f29dbc25Smrg pScrni->monitor->DDC = GeodeDoDDC(pScrni, pGeode->pEnt->index); 661f29dbc25Smrg 662f29dbc25Smrg /* I'm still not 100% sure this uses the right values */ 663f29dbc25Smrg 664f29dbc25Smrg modecnt = xf86ValidateModes(pScrni, 665f29dbc25Smrg pScrni->monitor->Modes, 666f29dbc25Smrg pScrni->display->modes, 667f29dbc25Smrg GeodeClockRange, 668f29dbc25Smrg NULL, GX_MIN_PITCH, GX_MAX_PITCH, 669f29dbc25Smrg 32, GX_MIN_HEIGHT, GX_MAX_HEIGHT, 670f29dbc25Smrg pScrni->display->virtualX, 671f29dbc25Smrg pScrni->display->virtualY, pGeode->FBAvail, LOOKUP_BEST_REFRESH); 672f29dbc25Smrg 673f29dbc25Smrg if (modecnt <= 0) { 674f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); 675f29dbc25Smrg return FALSE; 676f29dbc25Smrg } 677f29dbc25Smrg 678f29dbc25Smrg xf86PruneDriverModes(pScrni); 679f29dbc25Smrg 680f29dbc25Smrg if (pScrni->modes == NULL) { 681f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes were found\n"); 682f29dbc25Smrg return FALSE; 683f29dbc25Smrg } 684f29dbc25Smrg 685f29dbc25Smrg xf86SetCrtcForModes(pScrni, 0); 686f29dbc25Smrg pScrni->currentMode = pScrni->modes; 687f29dbc25Smrg 688f29dbc25Smrg xf86PrintModes(pScrni); 689f29dbc25Smrg xf86SetDpi(pScrni, 0, 0); 690f29dbc25Smrg 691f29dbc25Smrg /* Load the modules we'll need */ 692f29dbc25Smrg 693f29dbc25Smrg if (xf86LoadSubModule(pScrni, "fb") == NULL) { 694f29dbc25Smrg return FALSE; 695f29dbc25Smrg } 696f29dbc25Smrg 697f29dbc25Smrg if (pGeode->NoAccel == FALSE) { 698f29dbc25Smrg const char *module = (pGeode->useEXA) ? "exa" : "xaa"; 699f29dbc25Smrg 700f29dbc25Smrg if (!xf86LoadSubModule(pScrni, module)) { 701f29dbc25Smrg return FALSE; 702f29dbc25Smrg } 703f29dbc25Smrg } 704f29dbc25Smrg 705f29dbc25Smrg if (pGeode->tryHWCursor == TRUE) { 706f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "ramdac")) { 707f29dbc25Smrg return FALSE; 708f29dbc25Smrg } 709f29dbc25Smrg } 710f29dbc25Smrg 711f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 712f29dbc25Smrg if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { 713f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 714f29dbc25Smrg "Couldn't register the resources.\n"); 715f29dbc25Smrg return FALSE; 716f29dbc25Smrg } 717f29dbc25Smrg#endif 718f29dbc25Smrg return TRUE; 719f29dbc25Smrg} 720f29dbc25Smrg 721f29dbc25Smrgstatic void 722f29dbc25SmrgGXRestore(ScrnInfoPtr pScrni) 723f29dbc25Smrg{ 724f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 725f29dbc25Smrg 726f29dbc25Smrg if (pGeode->useVGA && pGeode->FBVGAActive) { 727f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 728f29dbc25Smrg 729f29dbc25Smrg vgaHWProtect(pScrni, TRUE); 730f29dbc25Smrg vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); 731f29dbc25Smrg vgaHWProtect(pScrni, FALSE); 732f29dbc25Smrg } 733f29dbc25Smrg} 734f29dbc25Smrg 735f29dbc25Smrgstatic Bool 736f29dbc25SmrgGXUnmapMem(ScrnInfoPtr pScrni) 737f29dbc25Smrg{ 738f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 739f29dbc25Smrg 740f29dbc25Smrg /* unmap all the memory map's */ 741f29dbc25Smrg 742f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_regptr, GX_CPU_REG_SIZE); 743f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_gpptr, GX_GP_REG_SIZE); 744f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_vidptr, GX_VID_REG_SIZE); 745f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, gfx_virt_fbptr, pGeode->FBAvail); 746f29dbc25Smrg return TRUE; 747f29dbc25Smrg} 748f29dbc25Smrg 749f29dbc25Smrgstatic void 750f29dbc25SmrgGXSetDvLineSize(unsigned int pitch) 751f29dbc25Smrg{ 752f29dbc25Smrg unsigned long temp, dv_size = MDC_DV_LINE_SIZE_1024; 753f29dbc25Smrg 754f29dbc25Smrg if (pitch > 1024) { 755f29dbc25Smrg dv_size = MDC_DV_LINE_SIZE_2048; 756f29dbc25Smrg } 757f29dbc25Smrg if (pitch > 2048) { 758f29dbc25Smrg dv_size = MDC_DV_LINE_SIZE_4096; 759f29dbc25Smrg } 760f29dbc25Smrg if (pitch > 4096) { 761f29dbc25Smrg dv_size = MDC_DV_LINE_SIZE_8192; 762f29dbc25Smrg } 763f29dbc25Smrg 764f29dbc25Smrg /* WRITE DIRTY/VALID CONTROL WITH LINE LENGTH */ 765f29dbc25Smrg 766f29dbc25Smrg temp = READ_REG32(MDC_DV_CTL); 767f29dbc25Smrg WRITE_REG32(MDC_DV_CTL, (temp & ~MDC_DV_LINE_SIZE_MASK) | dv_size); 768f29dbc25Smrg} 769f29dbc25Smrg 770f29dbc25Smrg/* XXX - this is nothing like the original function - not sure exactly what the purpose is for this quite yet */ 771f29dbc25Smrg 772f29dbc25Smrgstatic void 773f29dbc25SmrgGXAdjustFrame(int scrnIndex, int x, int y, int flags) 774f29dbc25Smrg{ 775f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 776f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 777f29dbc25Smrg unsigned long offset; 778f29dbc25Smrg 779f29dbc25Smrg offset = y * pGeode->Pitch + x * (pScrni->bitsPerPixel >> 3); 780f29dbc25Smrg 781f29dbc25Smrg gfx_set_display_offset(offset); 782f29dbc25Smrg} 783f29dbc25Smrg 784f29dbc25Smrgstatic Bool 785f29dbc25SmrgGXSetVideoMode(ScrnInfoPtr pScrni, DisplayModePtr pMode) 786f29dbc25Smrg{ 787f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 788f29dbc25Smrg int flags = 0; 789f29dbc25Smrg int custom = 0; 790f29dbc25Smrg 791f29dbc25Smrg pScrni->vtSema = TRUE; 792f29dbc25Smrg 793f29dbc25Smrg gx_disable_dac_power(); 794f29dbc25Smrg 795f29dbc25Smrg if (pMode->Flags & V_NHSYNC) 796f29dbc25Smrg flags |= 1; 797f29dbc25Smrg if (pMode->Flags & V_NVSYNC) 798f29dbc25Smrg flags |= 2; 799f29dbc25Smrg 800f29dbc25Smrg /* Check to see if we should use custom or built-in timings */ 801f29dbc25Smrg 802f29dbc25Smrg if (pGeode->Panel) 803f29dbc25Smrg custom = (pMode->type & M_T_USERDEF); 804f29dbc25Smrg else 805f29dbc25Smrg custom = !(pMode->type & (M_T_BUILTIN | M_T_DEFAULT)); 806f29dbc25Smrg 807f29dbc25Smrg /* If we're not doing a custom mode, then just set the fixed timings, 808f29dbc25Smrg * otherwise, do the whole shooting match */ 809f29dbc25Smrg 810f29dbc25Smrg if (!custom) { 811f29dbc25Smrg GFX(set_fixed_timings(pGeode->PanelX, pGeode->PanelY, 812f29dbc25Smrg pMode->CrtcHDisplay, pMode->CrtcVDisplay, 813f29dbc25Smrg pScrni->bitsPerPixel)); 814f29dbc25Smrg } else { 815f29dbc25Smrg if (pGeode->Panel) 816f29dbc25Smrg GFX(set_panel_present(pGeode->PanelX, pGeode->PanelY, 817f29dbc25Smrg pMode->CrtcHDisplay, pMode->CrtcVDisplay, 818f29dbc25Smrg pScrni->bitsPerPixel)); 819f29dbc25Smrg 820f29dbc25Smrg GFX(set_display_timings(pScrni->bitsPerPixel, flags, 821f29dbc25Smrg pMode->CrtcHDisplay, pMode->CrtcHBlankStart, 822f29dbc25Smrg pMode->CrtcHSyncStart, pMode->CrtcHSyncEnd, 823f29dbc25Smrg pMode->CrtcHBlankEnd, pMode->CrtcHTotal, 824f29dbc25Smrg pMode->CrtcVDisplay, pMode->CrtcVBlankStart, 825f29dbc25Smrg pMode->CrtcVSyncStart, pMode->CrtcVSyncEnd, 826f29dbc25Smrg pMode->CrtcVBlankEnd, pMode->CrtcVTotal, 827f29dbc25Smrg (int)((pMode->SynthClock / 1000.0) * 0x10000))); 828f29dbc25Smrg } 829f29dbc25Smrg 830f29dbc25Smrg GFX(set_crt_enable(CRT_ENABLE)); 831f29dbc25Smrg GFX(set_display_pitch(pGeode->displayPitch)); 832f29dbc25Smrg GFX(set_display_offset(0L)); 833f29dbc25Smrg GFX(wait_vertical_blank()); 834f29dbc25Smrg 835f29dbc25Smrg if (pGeode->Compression) { 836f29dbc25Smrg GXSetDvLineSize(pGeode->Pitch); 837f29dbc25Smrg 838f29dbc25Smrg gfx_set_compression_offset(pGeode->CBData.compression_offset); 839f29dbc25Smrg gfx_set_compression_pitch(GX_CB_PITCH); 840f29dbc25Smrg gfx_set_compression_size(GX_CB_SIZE); 841f29dbc25Smrg 842f29dbc25Smrg gfx_set_compression_enable(1); 843f29dbc25Smrg } 844f29dbc25Smrg 845f29dbc25Smrg if (pGeode->HWCursor && !(pMode->Flags & V_DBLSCAN)) { 846f29dbc25Smrg GXLoadCursorImage(pScrni, NULL); 847f29dbc25Smrg GFX(set_cursor_position(pGeode->CursorStartOffset, 0, 0, 0, 0)); 848f29dbc25Smrg GXShowCursor(pScrni); 849f29dbc25Smrg } else { 850f29dbc25Smrg GFX(set_cursor_enable(0)); 851f29dbc25Smrg pGeode->HWCursor = FALSE; 852f29dbc25Smrg } 853f29dbc25Smrg 854f29dbc25Smrg GXAdjustFrame(pScrni->scrnIndex, pScrni->frameX0, pScrni->frameY0, 0); 855f29dbc25Smrg gx_enable_dac_power(); 856f29dbc25Smrg 857f29dbc25Smrg return TRUE; 858f29dbc25Smrg} 859f29dbc25Smrg 860f29dbc25Smrgstatic Bool 861f29dbc25SmrgGXSwitchMode(int index, DisplayModePtr pMode, int flags) 862f29dbc25Smrg{ 863f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[index]; 864f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 865f29dbc25Smrg int ret = TRUE; 866f29dbc25Smrg int rotate; 867f29dbc25Smrg 868f29dbc25Smrg /* Syn the engine and shutdown the DAC momentarily */ 869f29dbc25Smrg 870f29dbc25Smrg gfx_wait_until_idle(); 871f29dbc25Smrg 872f29dbc25Smrg /* Set up the memory for the new mode */ 873f29dbc25Smrg rotate = GXGetRotation(pScrni->pScreen); 874f29dbc25Smrg ret = GXAllocateMemory(pScrni->pScreen, pScrni, rotate); 875f29dbc25Smrg 876f29dbc25Smrg if (ret) { 877f29dbc25Smrg if (pGeode->curMode != pMode) 878f29dbc25Smrg ret = GXSetVideoMode(pScrni, pMode); 879f29dbc25Smrg } 880f29dbc25Smrg 881f29dbc25Smrg if (ret) 882f29dbc25Smrg ret = GXRotate(pScrni, pMode); 883f29dbc25Smrg 884f29dbc25Smrg /* Go back the way it was */ 885f29dbc25Smrg 886f29dbc25Smrg if (ret == FALSE) { 887f29dbc25Smrg if (!GXSetVideoMode(pScrni, pGeode->curMode)) 888f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 889f29dbc25Smrg "Could not restore the previous mode\n"); 890f29dbc25Smrg } else 891f29dbc25Smrg pGeode->curMode = pMode; 892f29dbc25Smrg 893f29dbc25Smrg return ret; 894f29dbc25Smrg} 895f29dbc25Smrg 896f29dbc25Smrgstatic void 897f29dbc25SmrgGXLeaveGraphics(ScrnInfoPtr pScrni) 898f29dbc25Smrg{ 899f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 900f29dbc25Smrg 901f29dbc25Smrg gfx_wait_until_idle(); 902f29dbc25Smrg 903f29dbc25Smrg /* Restore VG registers */ 904f29dbc25Smrg gfx_set_display_timings(pGeode->FBgfxdisplaytiming.wBpp, 905f29dbc25Smrg pGeode->FBgfxdisplaytiming.wPolarity, 906f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHActive, 907f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankStart, 908f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncStart, 909f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncEnd, 910f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankEnd, 911f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHTotal, 912f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVActive, 913f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankStart, 914f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncStart, 915f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncEnd, 916f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankEnd, 917f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVTotal, 918f29dbc25Smrg pGeode->FBgfxdisplaytiming.dwDotClock); 919f29dbc25Smrg 920f29dbc25Smrg gfx_set_compression_enable(0); 921f29dbc25Smrg 922f29dbc25Smrg /* Restore the previous Compression state */ 923f29dbc25Smrg if (pGeode->FBCompressionEnable) { 924f29dbc25Smrg gfx_set_compression_offset(pGeode->FBCompressionOffset); 925f29dbc25Smrg gfx_set_compression_pitch(pGeode->FBCompressionPitch); 926f29dbc25Smrg gfx_set_compression_size(pGeode->FBCompressionSize); 927f29dbc25Smrg gfx_set_compression_enable(1); 928f29dbc25Smrg } 929f29dbc25Smrg 930f29dbc25Smrg gfx_set_display_pitch(pGeode->FBgfxdisplaytiming.wPitch); 931f29dbc25Smrg 932f29dbc25Smrg gfx_set_display_offset(pGeode->FBDisplayOffset); 933f29dbc25Smrg 934f29dbc25Smrg /* Restore Cursor */ 935f29dbc25Smrg gfx_set_cursor_position(pGeode->FBCursorOffset, 0, 0, 0, 0); 936f29dbc25Smrg 937f29dbc25Smrg if (pGeode->useVGA) { 938f29dbc25Smrg pGeode->vesa->pInt->num = 0x10; 939f29dbc25Smrg pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; 940f29dbc25Smrg pGeode->vesa->pInt->bx = 0; 941f29dbc25Smrg xf86ExecX86int10(pGeode->vesa->pInt); 942f29dbc25Smrg gfx_delay_milliseconds(3); 943f29dbc25Smrg } 944f29dbc25Smrg 945f29dbc25Smrg GXRestore(pScrni); 946f29dbc25Smrg 947f29dbc25Smrg gx_enable_dac_power(); 948f29dbc25Smrg} 949f29dbc25Smrg 950f29dbc25Smrgstatic Bool 951f29dbc25SmrgGXCloseScreen(int scrnIndex, ScreenPtr pScrn) 952f29dbc25Smrg{ 953f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 954f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 955f29dbc25Smrg 956f29dbc25Smrg if (pScrni->vtSema) 957f29dbc25Smrg GXLeaveGraphics(pScrni); 958f29dbc25Smrg 959f29dbc25Smrg if (pGeode->AccelInfoRec) 960f29dbc25Smrg XAADestroyInfoRec(pGeode->AccelInfoRec); 961f29dbc25Smrg 962f29dbc25Smrg if (pGeode->AccelImageWriteBuffers) { 963f29dbc25Smrg xfree(pGeode->AccelImageWriteBuffers[0]); 964f29dbc25Smrg xfree(pGeode->AccelImageWriteBuffers); 965f29dbc25Smrg pGeode->AccelImageWriteBuffers = NULL; 966f29dbc25Smrg } 967f29dbc25Smrg 968f29dbc25Smrg if (pGeode->AccelColorExpandBuffers) { 969f29dbc25Smrg xfree(pGeode->AccelColorExpandBuffers); 970f29dbc25Smrg pGeode->AccelColorExpandBuffers = NULL; 971f29dbc25Smrg } 972f29dbc25Smrg 973f29dbc25Smrg if (pGeode->pExa) { 974f29dbc25Smrg exaDriverFini(pScrn); 975f29dbc25Smrg xfree(pGeode->pExa); 976f29dbc25Smrg pGeode->pExa = NULL; 977f29dbc25Smrg } 978f29dbc25Smrg 979f29dbc25Smrg pScrni->vtSema = FALSE; 980f29dbc25Smrg 981f29dbc25Smrg GXUnmapMem(pScrni); 982f29dbc25Smrg 983f29dbc25Smrg pScrni->PointerMoved = pGeode->PointerMoved; 984f29dbc25Smrg pScrn->CloseScreen = pGeode->CloseScreen; 985f29dbc25Smrg 986f29dbc25Smrg if (pScrn->CloseScreen) 987f29dbc25Smrg return (*pScrn->CloseScreen) (scrnIndex, pScrn); 988f29dbc25Smrg 989f29dbc25Smrg return TRUE; 990f29dbc25Smrg} 991f29dbc25Smrg 992f29dbc25Smrgstatic Bool 993f29dbc25SmrgGXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 994f29dbc25Smrg{ 995f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 996f29dbc25Smrg 997f29dbc25Smrg if (!GXMapMem(pScrni)) 998f29dbc25Smrg return FALSE; 999f29dbc25Smrg 1000f29dbc25Smrg if (pGeode->useVGA) 1001f29dbc25Smrg pGeode->FBVGAActive = gu2_get_vga_active(); 1002f29dbc25Smrg 1003f29dbc25Smrg gfx_wait_until_idle(); 1004f29dbc25Smrg 1005f29dbc25Smrg /* Save off the current state (should this be somewhere else)? */ 1006f29dbc25Smrg 1007f29dbc25Smrg pGeode->FBgfxdisplaytiming.dwDotClock = gfx_get_clock_frequency(); 1008f29dbc25Smrg pGeode->FBgfxdisplaytiming.wPitch = gfx_get_display_pitch(); 1009f29dbc25Smrg pGeode->FBgfxdisplaytiming.wBpp = gfx_get_display_bpp(); 1010f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHTotal = gfx_get_htotal(); 1011f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHActive = gfx_get_hactive(); 1012f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncStart = gfx_get_hsync_start(); 1013f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHSyncEnd = gfx_get_hsync_end(); 1014f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankStart = gfx_get_hblank_start(); 1015f29dbc25Smrg pGeode->FBgfxdisplaytiming.wHBlankEnd = gfx_get_hblank_end(); 1016f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVTotal = gfx_get_vtotal(); 1017f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVActive = gfx_get_vactive(); 1018f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncStart = gfx_get_vsync_start(); 1019f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVSyncEnd = gfx_get_vsync_end(); 1020f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankStart = gfx_get_vblank_start(); 1021f29dbc25Smrg pGeode->FBgfxdisplaytiming.wVBlankEnd = gfx_get_vblank_end(); 1022f29dbc25Smrg pGeode->FBgfxdisplaytiming.wPolarity = gfx_get_sync_polarities(); 1023f29dbc25Smrg 1024f29dbc25Smrg pGeode->FBDisplayOffset = gfx_get_display_offset(); 1025f29dbc25Smrg 1026f29dbc25Smrg if (pGeode->useVGA) { 1027f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 1028f29dbc25Smrg 1029f29dbc25Smrg pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); 1030f29dbc25Smrg } 1031f29dbc25Smrg 1032f29dbc25Smrg pGeode->FBCompressionEnable = gfx_get_compression_enable(); 1033f29dbc25Smrg pGeode->FBCompressionOffset = gfx_get_compression_offset(); 1034f29dbc25Smrg pGeode->FBCompressionPitch = gfx_get_compression_pitch(); 1035f29dbc25Smrg pGeode->FBCompressionSize = gfx_get_compression_size(); 1036f29dbc25Smrg 1037f29dbc25Smrg#ifdef PNL_SUP 1038f29dbc25Smrg Pnl_SavePanelState(); 1039f29dbc25Smrg#endif 1040f29dbc25Smrg 1041f29dbc25Smrg /* Turn off the VGA */ 1042f29dbc25Smrg 1043f29dbc25Smrg if (pGeode->useVGA && pGeode->FBVGAActive) { 1044f29dbc25Smrg unsigned short sequencer; 1045f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 1046f29dbc25Smrg 1047f29dbc25Smrg /* Map VGA aperture */ 1048f29dbc25Smrg if (!vgaHWMapMem(pScrni)) 1049f29dbc25Smrg return FALSE; 1050f29dbc25Smrg 1051f29dbc25Smrg /* Unlock VGA registers */ 1052f29dbc25Smrg vgaHWUnlock(pvgaHW); 1053f29dbc25Smrg 1054f29dbc25Smrg /* Save the current state and setup the current mode */ 1055f29dbc25Smrg vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); 1056f29dbc25Smrg 1057f29dbc25Smrg /* DISABLE VGA SEQUENCER */ 1058f29dbc25Smrg /* This allows the VGA state machine to terminate. We must delay */ 1059f29dbc25Smrg /* such that there are no pending MBUS requests. */ 1060f29dbc25Smrg 1061f29dbc25Smrg gfx_outb(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_CLK_MODE); 1062f29dbc25Smrg sequencer = gfx_inb(MDC_SEQUENCER_DATA); 1063f29dbc25Smrg sequencer |= MDC_CLK_MODE_SCREEN_OFF; 1064f29dbc25Smrg gfx_outb(MDC_SEQUENCER_DATA, sequencer); 1065f29dbc25Smrg 1066f29dbc25Smrg gfx_delay_milliseconds(1); 1067f29dbc25Smrg 1068f29dbc25Smrg /* BLANK THE VGA DISPLAY */ 1069f29dbc25Smrg gfx_outw(MDC_SEQUENCER_INDEX, MDC_SEQUENCER_RESET); 1070f29dbc25Smrg sequencer = gfx_inb(MDC_SEQUENCER_DATA); 1071f29dbc25Smrg sequencer &= ~MDC_RESET_VGA_DISP_ENABLE; 1072f29dbc25Smrg gfx_outb(MDC_SEQUENCER_DATA, sequencer); 1073f29dbc25Smrg 1074f29dbc25Smrg gfx_delay_milliseconds(1); 1075f29dbc25Smrg } 1076f29dbc25Smrg 1077f29dbc25Smrg /* Set up the memory */ 1078f29dbc25Smrg /* XXX - FIXME - when we alow inital rotation, it should be here */ 1079f29dbc25Smrg GXAllocateMemory(pScrn, pScrni, pGeode->rotation); 1080f29dbc25Smrg 1081f29dbc25Smrg /* Clear the framebuffer */ 1082f29dbc25Smrg memset(pGeode->FBBase + pGeode->displayOffset, 0, pGeode->displaySize); 1083f29dbc25Smrg 1084f29dbc25Smrg /* Set up the video mode */ 1085f29dbc25Smrg GXSetVideoMode(pScrni, pScrni->currentMode); 1086f29dbc25Smrg pGeode->curMode = pScrni->currentMode; 1087f29dbc25Smrg 1088f29dbc25Smrg return TRUE; 1089f29dbc25Smrg} 1090f29dbc25Smrg 1091f29dbc25Smrgstatic void 1092f29dbc25SmrgGXLoadPalette(ScrnInfoPtr pScrni, 1093f29dbc25Smrg int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) 1094f29dbc25Smrg{ 1095f29dbc25Smrg int i, index, color; 1096f29dbc25Smrg 1097f29dbc25Smrg for (i = 0; i < numColors; i++) { 1098f29dbc25Smrg index = indizes[i] & 0xFF; 1099f29dbc25Smrg color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | 1100f29dbc25Smrg (((unsigned long)(colors[index].green & 0xFF)) << 8) | 1101f29dbc25Smrg ((unsigned long)(colors[index].blue & 0xFF)); 1102f29dbc25Smrg 1103f29dbc25Smrg GFX(set_display_palette_entry(index, color)); 1104f29dbc25Smrg } 1105f29dbc25Smrg} 1106f29dbc25Smrg 1107f29dbc25Smrg#ifdef DPMSExtension 1108f29dbc25Smrgstatic void 1109f29dbc25SmrgGXPanelPower(int enable) 1110f29dbc25Smrg{ 1111f29dbc25Smrg unsigned long power = READ_VID32(RCDF_POWER_MANAGEMENT); 1112f29dbc25Smrg 1113f29dbc25Smrg if (enable != 0) 1114f29dbc25Smrg power |= RCDF_PM_PANEL_POWER_ON; 1115f29dbc25Smrg else 1116f29dbc25Smrg power &= ~RCDF_PM_PANEL_POWER_ON; 1117f29dbc25Smrg 1118f29dbc25Smrg WRITE_VID32(RCDF_POWER_MANAGEMENT, power); 1119f29dbc25Smrg} 1120f29dbc25Smrg 1121f29dbc25Smrgstatic void 1122f29dbc25SmrgGXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags) 1123f29dbc25Smrg{ 1124f29dbc25Smrg GeodeRec *pGeode; 1125f29dbc25Smrg 1126f29dbc25Smrg pGeode = GEODEPTR(pScrni); 1127f29dbc25Smrg 1128f29dbc25Smrg if (!pScrni->vtSema) 1129f29dbc25Smrg return; 1130f29dbc25Smrg 1131f29dbc25Smrg switch (mode) { 1132f29dbc25Smrg case DPMSModeOn: 1133f29dbc25Smrg /* Screen: On; HSync: On; VSync: On */ 1134f29dbc25Smrg GFX(set_crt_enable(CRT_ENABLE)); 1135f29dbc25Smrg#if defined(PNL_SUP) 1136f29dbc25Smrg if (pGeode->Panel) { 1137f29dbc25Smrg Pnl_PowerUp(); 1138f29dbc25Smrg GXPanelPower(1); 1139f29dbc25Smrg } 1140f29dbc25Smrg#endif 1141f29dbc25Smrg break; 1142f29dbc25Smrg 1143f29dbc25Smrg case DPMSModeStandby: 1144f29dbc25Smrg /* Screen: Off; HSync: Off; VSync: On */ 1145f29dbc25Smrg GFX(set_crt_enable(CRT_STANDBY)); 1146f29dbc25Smrg#if defined(PNL_SUP) 1147f29dbc25Smrg if (pGeode->Panel) { 1148f29dbc25Smrg Pnl_PowerDown(); 1149f29dbc25Smrg GXPanelPower(0); 1150f29dbc25Smrg } 1151f29dbc25Smrg#endif 1152f29dbc25Smrg break; 1153f29dbc25Smrg 1154f29dbc25Smrg case DPMSModeSuspend: 1155f29dbc25Smrg /* Screen: Off; HSync: On; VSync: Off */ 1156f29dbc25Smrg GFX(set_crt_enable(CRT_SUSPEND)); 1157f29dbc25Smrg#if defined(PNL_SUP) 1158f29dbc25Smrg if (pGeode->Panel) { 1159f29dbc25Smrg Pnl_PowerDown(); 1160f29dbc25Smrg GXPanelPower(0); 1161f29dbc25Smrg } 1162f29dbc25Smrg#endif 1163f29dbc25Smrg break; 1164f29dbc25Smrg 1165f29dbc25Smrg case DPMSModeOff: 1166f29dbc25Smrg /* Screen: Off; HSync: Off; VSync: Off */ 1167f29dbc25Smrg GFX(set_crt_enable(CRT_DISABLE)); 1168f29dbc25Smrg#if defined(PNL_SUP) 1169f29dbc25Smrg if (pGeode->Panel) { 1170f29dbc25Smrg Pnl_PowerDown(); 1171f29dbc25Smrg GXPanelPower(0); 1172f29dbc25Smrg } 1173f29dbc25Smrg#endif 1174f29dbc25Smrg break; 1175f29dbc25Smrg } 1176f29dbc25Smrg} 1177f29dbc25Smrg#endif 1178f29dbc25Smrg 1179f29dbc25Smrgstatic Bool 1180f29dbc25SmrgGXCreateScreenResources(ScreenPtr pScreen) 1181f29dbc25Smrg{ 1182f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; 1183f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1184f29dbc25Smrg 1185f29dbc25Smrg pScreen->CreateScreenResources = pGeode->CreateScreenResources; 1186f29dbc25Smrg if (!(*pScreen->CreateScreenResources) (pScreen)) 1187f29dbc25Smrg return FALSE; 1188f29dbc25Smrg 1189f29dbc25Smrg if (xf86LoaderCheckSymbol("GXRandRSetConfig") 1190f29dbc25Smrg && pGeode->rotation != RR_Rotate_0) { 1191f29dbc25Smrg Rotation(*GXRandRSetConfig) (ScreenPtr pScreen, Rotation rr, int rate, 1192f29dbc25Smrg RRScreenSizePtr pSize) = NULL; 1193f29dbc25Smrg 1194f29dbc25Smrg RRScreenSize p; 1195f29dbc25Smrg Rotation requestedRotation = pGeode->rotation; 1196f29dbc25Smrg 1197f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 1198f29dbc25Smrg 1199f29dbc25Smrg /* Just setup enough for an initial rotate */ 1200f29dbc25Smrg 1201f29dbc25Smrg p.width = pScreen->width; 1202f29dbc25Smrg p.height = pScreen->height; 1203f29dbc25Smrg p.mmWidth = pScreen->mmWidth; 1204f29dbc25Smrg p.mmHeight = pScreen->mmHeight; 1205f29dbc25Smrg 1206f29dbc25Smrg GXRandRSetConfig = LoaderSymbol("GXRandRSetConfig"); 1207f29dbc25Smrg if (GXRandRSetConfig) { 1208f29dbc25Smrg pGeode->starting = TRUE; 1209f29dbc25Smrg (*GXRandRSetConfig) (pScreen, requestedRotation, 0, &p); 1210f29dbc25Smrg pGeode->starting = FALSE; 1211f29dbc25Smrg } 1212f29dbc25Smrg } 1213f29dbc25Smrg 1214f29dbc25Smrg return TRUE; 1215f29dbc25Smrg} 1216f29dbc25Smrg 1217f29dbc25Smrgstatic Bool 1218f29dbc25SmrgGXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) 1219f29dbc25Smrg{ 1220f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 1221f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1222f29dbc25Smrg XF86ModReqInfo shadowReq; 1223f29dbc25Smrg int maj, min, ret, rotate; 1224f29dbc25Smrg 1225f29dbc25Smrg pGeode->starting = TRUE; 1226f29dbc25Smrg 1227f29dbc25Smrg /* If we are using VGA then go ahead and map the memory */ 1228f29dbc25Smrg 1229f29dbc25Smrg if (pGeode->useVGA) { 1230f29dbc25Smrg 1231f29dbc25Smrg if (!vgaHWMapMem(pScrni)) 1232f29dbc25Smrg return FALSE; 1233f29dbc25Smrg 1234f29dbc25Smrg vgaHWGetIOBase(VGAHWPTR(pScrni)); 1235f29dbc25Smrg } 1236f29dbc25Smrg 1237f29dbc25Smrg if (!pGeode->NoAccel) { 1238f29dbc25Smrg 1239f29dbc25Smrg if (pGeode->useEXA) { 1240f29dbc25Smrg 1241f29dbc25Smrg if (!(pGeode->pExa = exaDriverAlloc())) { 1242f29dbc25Smrg xf86DrvMsg(scrnIndex, X_ERROR, 1243f29dbc25Smrg "Couldn't allocate the EXA structure.\n"); 1244f29dbc25Smrg pGeode->NoAccel = TRUE; 1245f29dbc25Smrg } else { 1246f29dbc25Smrg ExaDriverPtr pExa = pGeode->pExa; 1247f29dbc25Smrg 1248f29dbc25Smrg /* THis is set in GXAllocMem */ 1249f29dbc25Smrg pExa->memoryBase = 0; 1250f29dbc25Smrg 1251f29dbc25Smrg /* This is set in GXAllocateMemory */ 1252f29dbc25Smrg pExa->memorySize = 0; 1253f29dbc25Smrg 1254f29dbc25Smrg pExa->pixmapOffsetAlign = 32; 1255f29dbc25Smrg pExa->pixmapPitchAlign = 32; 1256f29dbc25Smrg pExa->flags = EXA_OFFSCREEN_PIXMAPS; 1257f29dbc25Smrg pExa->maxX = GX_MAX_WIDTH - 1; 1258f29dbc25Smrg pExa->maxY = GX_MAX_HEIGHT - 1; 1259f29dbc25Smrg } 1260f29dbc25Smrg } else { 1261f29dbc25Smrg pGeode->AccelImageWriteBuffers = 1262f29dbc25Smrg xcalloc(sizeof(pGeode->AccelImageWriteBuffers[0]), 1263f29dbc25Smrg pGeode->NoOfImgBuffers); 1264f29dbc25Smrg pGeode->AccelColorExpandBuffers = 1265f29dbc25Smrg xcalloc(sizeof(pGeode->AccelColorExpandBuffers[0]), 1266f29dbc25Smrg pGeode->NoOfColorExpandLines); 1267f29dbc25Smrg } 1268f29dbc25Smrg } 1269f29dbc25Smrg 1270f29dbc25Smrg /* XXX FIXME - Take down any of the structures on failure? */ 1271f29dbc25Smrg 1272f29dbc25Smrg if (!GXEnterGraphics(pScrn, pScrni)) 1273f29dbc25Smrg return FALSE; 1274f29dbc25Smrg 1275f29dbc25Smrg miClearVisualTypes(); 1276f29dbc25Smrg 1277f29dbc25Smrg /* XXX Again - take down anything? */ 1278f29dbc25Smrg 1279f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 1280f29dbc25Smrg if (!miSetVisualTypes(pScrni->depth, 1281f29dbc25Smrg TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { 1282f29dbc25Smrg return FALSE; 1283f29dbc25Smrg } 1284f29dbc25Smrg } else { 1285f29dbc25Smrg if (!miSetVisualTypes(pScrni->depth, 1286f29dbc25Smrg miGetDefaultVisualMask(pScrni->depth), 1287f29dbc25Smrg pScrni->rgbBits, pScrni->defaultVisual)) { 1288f29dbc25Smrg return FALSE; 1289f29dbc25Smrg } 1290f29dbc25Smrg } 1291f29dbc25Smrg 1292f29dbc25Smrg miSetPixmapDepths(); 1293f29dbc25Smrg 1294f29dbc25Smrg /* Point at the visible area to start */ 1295f29dbc25Smrg 1296f29dbc25Smrg ret = fbScreenInit(pScrn, pGeode->FBBase + pGeode->displayOffset, 1297f29dbc25Smrg pScrni->virtualX, pScrni->virtualY, 1298f29dbc25Smrg pScrni->xDpi, pScrni->yDpi, pGeode->displayWidth, 1299f29dbc25Smrg pScrni->bitsPerPixel); 1300f29dbc25Smrg 1301f29dbc25Smrg if (!ret) 1302f29dbc25Smrg return FALSE; 1303f29dbc25Smrg 1304f29dbc25Smrg xf86SetBlackWhitePixels(pScrn); 1305f29dbc25Smrg 1306f29dbc25Smrg /* Set up the color ordering */ 1307f29dbc25Smrg 1308f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 1309f29dbc25Smrg VisualPtr visual = pScrn->visuals + pScrn->numVisuals; 1310f29dbc25Smrg 1311f29dbc25Smrg while (--visual >= pScrn->visuals) { 1312f29dbc25Smrg if ((visual->class | DynamicClass) == DirectColor) { 1313f29dbc25Smrg visual->offsetRed = pScrni->offset.red; 1314f29dbc25Smrg visual->offsetGreen = pScrni->offset.green; 1315f29dbc25Smrg visual->offsetBlue = pScrni->offset.blue; 1316f29dbc25Smrg visual->redMask = pScrni->mask.red; 1317f29dbc25Smrg visual->greenMask = pScrni->mask.green; 1318f29dbc25Smrg visual->blueMask = pScrni->mask.blue; 1319f29dbc25Smrg } 1320f29dbc25Smrg } 1321f29dbc25Smrg } 1322f29dbc25Smrg 1323f29dbc25Smrg /* Must follow the color ordering */ 1324f29dbc25Smrg fbPictureInit(pScrn, 0, 0); 1325f29dbc25Smrg 1326f29dbc25Smrg if (!pGeode->NoAccel) 1327f29dbc25Smrg GXAccelInit(pScrn); 1328f29dbc25Smrg 1329f29dbc25Smrg miInitializeBackingStore(pScrn); 1330f29dbc25Smrg xf86SetBackingStore(pScrn); 1331f29dbc25Smrg 1332f29dbc25Smrg /* Set up the soft cursor */ 1333f29dbc25Smrg miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); 1334f29dbc25Smrg 1335f29dbc25Smrg /* Set up the HW cursor - must follow the soft cursor init */ 1336f29dbc25Smrg 1337f29dbc25Smrg if (pGeode->tryHWCursor) { 1338f29dbc25Smrg if (!GXHWCursorInit(pScrn)) 1339f29dbc25Smrg xf86DrvMsg(scrnIndex, X_ERROR, 1340f29dbc25Smrg "Hardware cursor initialization failed.\n"); 1341f29dbc25Smrg } 1342f29dbc25Smrg 1343f29dbc25Smrg /* Set up the color map */ 1344f29dbc25Smrg 1345f29dbc25Smrg if (!miCreateDefColormap(pScrn)) 1346f29dbc25Smrg return FALSE; 1347f29dbc25Smrg 1348f29dbc25Smrg if (pScrni->bitsPerPixel == 8) { 1349f29dbc25Smrg /* Must follow initialization of the default colormap */ 1350f29dbc25Smrg 1351f29dbc25Smrg if (!xf86HandleColormaps(pScrn, 256, 8, 1352f29dbc25Smrg GXLoadPalette, NULL, 1353f29dbc25Smrg CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 1354f29dbc25Smrg return FALSE; 1355f29dbc25Smrg } 1356f29dbc25Smrg } 1357f29dbc25Smrg#ifdef DPMSExtension 1358f29dbc25Smrg xf86DPMSInit(pScrn, GXDPMSSet, 0); 1359f29dbc25Smrg#endif 1360f29dbc25Smrg 1361f29dbc25Smrg GXInitVideo(pScrn); 1362f29dbc25Smrg 1363f29dbc25Smrg /* Set up RandR */ 1364f29dbc25Smrg 1365f29dbc25Smrg xf86DisableRandR(); /* We provide our own RandR goodness */ 1366f29dbc25Smrg 1367f29dbc25Smrg /* Try to set up the shadow FB for rotation */ 1368f29dbc25Smrg 1369f29dbc25Smrg memset(&shadowReq, 0, sizeof(shadowReq)); 1370f29dbc25Smrg shadowReq.majorversion = 1; 1371f29dbc25Smrg shadowReq.minorversion = 1; 1372f29dbc25Smrg 1373f29dbc25Smrg if (LoadSubModule(pScrni->module, "shadow", 1374f29dbc25Smrg NULL, NULL, NULL, &shadowReq, &maj, &min)) { 1375f29dbc25Smrg 1376f29dbc25Smrg rotate = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270; 1377f29dbc25Smrg shadowSetup(pScrn); 1378f29dbc25Smrg } else { 1379f29dbc25Smrg LoaderErrorMsg(NULL, "shadow", maj, min); 1380f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 1381f29dbc25Smrg "Error loading shadow - rotation not available.\n"); 1382f29dbc25Smrg 1383f29dbc25Smrg if (pGeode->rotation != RR_Rotate_0) 1384f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 1385f29dbc25Smrg "Reverting back to normal rotation.\n"); 1386f29dbc25Smrg 1387f29dbc25Smrg rotate = pGeode->rotation = RR_Rotate_0; 1388f29dbc25Smrg } 1389f29dbc25Smrg 1390f29dbc25Smrg GXRandRInit(pScrn, rotate); 1391f29dbc25Smrg 1392f29dbc25Smrg pGeode->PointerMoved = pScrni->PointerMoved; 1393f29dbc25Smrg pScrni->PointerMoved = GeodePointerMoved; 1394f29dbc25Smrg 1395f29dbc25Smrg pGeode->CreateScreenResources = pScrn->CreateScreenResources; 1396f29dbc25Smrg pScrn->CreateScreenResources = GXCreateScreenResources; 1397f29dbc25Smrg 1398f29dbc25Smrg pGeode->CloseScreen = pScrn->CloseScreen; 1399f29dbc25Smrg pScrn->CloseScreen = GXCloseScreen; 1400f29dbc25Smrg pScrn->SaveScreen = GXSaveScreen; 1401f29dbc25Smrg 1402f29dbc25Smrg if (serverGeneration == 1) 1403f29dbc25Smrg xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); 1404f29dbc25Smrg 1405f29dbc25Smrg pGeode->starting = FALSE; 1406f29dbc25Smrg 1407f29dbc25Smrg return TRUE; 1408f29dbc25Smrg} 1409f29dbc25Smrg 1410f29dbc25Smrgstatic int 1411f29dbc25SmrgGXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) 1412f29dbc25Smrg{ 1413f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 1414f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1415f29dbc25Smrg int p; 1416f29dbc25Smrg int custom = 0; 1417f29dbc25Smrg 1418f29dbc25Smrg if (pGeode->Panel) 1419f29dbc25Smrg custom = (pMode->type & M_T_USERDEF); 1420f29dbc25Smrg else 1421f29dbc25Smrg custom = (pMode->type & (M_T_BUILTIN | M_T_DEFAULT)); 1422f29dbc25Smrg 1423f29dbc25Smrg /* Use the durango lookup for !custom modes */ 1424f29dbc25Smrg 1425f29dbc25Smrg if (!custom && pGeode->Panel) { 1426f29dbc25Smrg if (pMode->CrtcHDisplay > pGeode->PanelX || 1427f29dbc25Smrg pMode->CrtcVDisplay > pGeode->PanelY || 1428f29dbc25Smrg gfx_is_panel_mode_supported(pGeode->PanelX, 1429f29dbc25Smrg pGeode->PanelY, 1430f29dbc25Smrg pMode->CrtcHDisplay, 1431f29dbc25Smrg pMode->CrtcVDisplay, 1432f29dbc25Smrg pScrni->bitsPerPixel) < 0) { 1433f29dbc25Smrg 1434f29dbc25Smrg return MODE_BAD; 1435f29dbc25Smrg } 1436f29dbc25Smrg } 1437f29dbc25Smrg 1438f29dbc25Smrg if (gfx_is_display_mode_supported(pMode->CrtcHDisplay, 1439f29dbc25Smrg pMode->CrtcVDisplay, 1440f29dbc25Smrg pScrni->bitsPerPixel, 1441f29dbc25Smrg GeodeGetRefreshRate(pMode)) < 0) { 1442f29dbc25Smrg return MODE_BAD; 1443f29dbc25Smrg } 1444f29dbc25Smrg 1445f29dbc25Smrg if (pMode->Flags & V_INTERLACE) 1446f29dbc25Smrg return MODE_NO_INTERLACE; 1447f29dbc25Smrg 1448f29dbc25Smrg if (pGeode->tryCompression) 1449f29dbc25Smrg p = GeodeCalculatePitchBytes(pMode->CrtcHDisplay, 1450f29dbc25Smrg pScrni->bitsPerPixel); 1451f29dbc25Smrg else 1452f29dbc25Smrg p = ((pMode->CrtcHDisplay + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 1453f29dbc25Smrg 1454f29dbc25Smrg if (p * pMode->CrtcVDisplay > pGeode->FBAvail) 1455f29dbc25Smrg return MODE_MEM; 1456f29dbc25Smrg 1457f29dbc25Smrg return MODE_OK; 1458f29dbc25Smrg} 1459f29dbc25Smrg 1460f29dbc25Smrg/* XXX - Way more to do here */ 1461f29dbc25Smrg 1462f29dbc25Smrgstatic Bool 1463f29dbc25SmrgGXEnterVT(int scrnIndex, int flags) 1464f29dbc25Smrg{ 1465f29dbc25Smrg return GXEnterGraphics(NULL, xf86Screens[scrnIndex]); 1466f29dbc25Smrg} 1467f29dbc25Smrg 1468f29dbc25Smrgstatic void 1469f29dbc25SmrgGXLeaveVT(int scrnIndex, int flags) 1470f29dbc25Smrg{ 1471f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 1472f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1473f29dbc25Smrg 1474f29dbc25Smrg pGeode->PrevDisplayOffset = gfx_get_display_offset(); 1475f29dbc25Smrg GXLeaveGraphics(xf86Screens[scrnIndex]); 1476f29dbc25Smrg} 1477f29dbc25Smrg 1478f29dbc25Smrgvoid 1479f29dbc25SmrgGXSetupChipsetFPtr(ScrnInfoPtr pScrn) 1480f29dbc25Smrg{ 1481f29dbc25Smrg pScrn->PreInit = GXPreInit; 1482f29dbc25Smrg pScrn->ScreenInit = GXScreenInit; 1483f29dbc25Smrg pScrn->SwitchMode = GXSwitchMode; 1484f29dbc25Smrg pScrn->AdjustFrame = GXAdjustFrame; 1485f29dbc25Smrg pScrn->EnterVT = GXEnterVT; 1486f29dbc25Smrg pScrn->LeaveVT = GXLeaveVT; 1487f29dbc25Smrg pScrn->FreeScreen = GeodeFreeScreen; 1488f29dbc25Smrg pScrn->ValidMode = GXValidMode; 1489f29dbc25Smrg} 1490f29dbc25Smrg 1491f29dbc25Smrg/* ====== Common functions ====== 1492f29dbc25Smrg * These are all the common functions that we use for both GX and LX - They live here 1493f29dbc25Smrg * because most of them came along for the GX first, and then were adapted to the LX. 1494f29dbc25Smrg * We could move these to a common function, but there is no hurry 1495f29dbc25Smrg * ============================== */ 1496f29dbc25Smrg 1497f29dbc25Smrgvoid 1498f29dbc25SmrgGeodePointerMoved(int index, int x, int y) 1499f29dbc25Smrg{ 1500f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[index]; 1501f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1502f29dbc25Smrg 1503f29dbc25Smrg int newX = x, newY = y; 1504f29dbc25Smrg 1505f29dbc25Smrg switch (pGeode->rotation) { 1506f29dbc25Smrg case RR_Rotate_0: 1507f29dbc25Smrg break; 1508f29dbc25Smrg case RR_Rotate_90: 1509f29dbc25Smrg newX = y; 1510f29dbc25Smrg newY = pScrni->pScreen->width - x - 1; 1511f29dbc25Smrg break; 1512f29dbc25Smrg case RR_Rotate_180: 1513f29dbc25Smrg newX = pScrni->pScreen->width - x - 1; 1514f29dbc25Smrg newY = pScrni->pScreen->height - y - 1; 1515f29dbc25Smrg break; 1516f29dbc25Smrg case RR_Rotate_270: 1517f29dbc25Smrg newX = pScrni->pScreen->height - y - 1; 1518f29dbc25Smrg newY = x; 1519f29dbc25Smrg break; 1520f29dbc25Smrg } 1521f29dbc25Smrg 1522f29dbc25Smrg (*pGeode->PointerMoved) (index, newX, newY); 1523f29dbc25Smrg} 1524f29dbc25Smrg 1525f29dbc25Smrgint 1526f29dbc25SmrgGeodeGetFPGeometry(const char *str, int *width, int *height) 1527f29dbc25Smrg{ 1528f29dbc25Smrg 1529f29dbc25Smrg int ret = sscanf(str, "%dx%d", width, height); 1530f29dbc25Smrg 1531f29dbc25Smrg return (ret == 2) ? 0 : 1; 1532f29dbc25Smrg} 1533f29dbc25Smrg 1534f29dbc25Smrgstatic void 1535f29dbc25SmrgGeodeFreeRec(ScrnInfoPtr pScrni) 1536f29dbc25Smrg{ 1537f29dbc25Smrg if (pScrni->driverPrivate != NULL) { 1538f29dbc25Smrg xfree(pScrni->driverPrivate); 1539f29dbc25Smrg pScrni->driverPrivate = NULL; 1540f29dbc25Smrg } 1541f29dbc25Smrg} 1542f29dbc25Smrg 1543f29dbc25Smrgvoid 1544f29dbc25SmrgGeodeFreeScreen(int scrnIndex, int flags) 1545f29dbc25Smrg{ 1546f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(xf86Screens[scrnIndex]); 1547f29dbc25Smrg 1548f29dbc25Smrg if (pGeode == NULL) 1549f29dbc25Smrg return; 1550f29dbc25Smrg 1551f29dbc25Smrg if (pGeode->useVGA) { 1552f29dbc25Smrg if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 1553f29dbc25Smrg vgaHWFreeHWRec(xf86Screens[scrnIndex]); 1554f29dbc25Smrg } 1555f29dbc25Smrg 1556f29dbc25Smrg GeodeFreeRec(xf86Screens[scrnIndex]); 1557f29dbc25Smrg} 1558f29dbc25Smrg 1559f29dbc25Smrgint 1560f29dbc25SmrgGeodeCalculatePitchBytes(unsigned int width, unsigned int bpp) 1561f29dbc25Smrg{ 1562f29dbc25Smrg 1563f29dbc25Smrg int delta = width * (bpp >> 3); 1564f29dbc25Smrg 1565f29dbc25Smrg /* Less then 640 has doubling enabled */ 1566f29dbc25Smrg 1567f29dbc25Smrg if (width < 640) 1568f29dbc25Smrg delta <<= 1; 1569f29dbc25Smrg 1570f29dbc25Smrg /* Calculate the pitch (compression rquires a power of 2) */ 1571f29dbc25Smrg 1572f29dbc25Smrg if (delta > 4096) 1573f29dbc25Smrg delta = 8192; 1574f29dbc25Smrg else if (delta > 2048) 1575f29dbc25Smrg delta = 4096; 1576f29dbc25Smrg else if (delta > 1024) 1577f29dbc25Smrg delta = 2048; 1578f29dbc25Smrg else 1579f29dbc25Smrg delta = 1024; 1580f29dbc25Smrg 1581f29dbc25Smrg return delta; 1582f29dbc25Smrg} 1583