lx_driver.c revision f29dbc25
1f29dbc25Smrg/* Copyright (c) 2003-2008 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#include <string.h> 36f29dbc25Smrg 37f29dbc25Smrg#include "xf86.h" 38f29dbc25Smrg#include "xf86_OSproc.h" 39f29dbc25Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 40f29dbc25Smrg#include "xf86Resources.h" 41f29dbc25Smrg#endif 42f29dbc25Smrg#include "xf86i2c.h" 43f29dbc25Smrg#include "xf86Crtc.h" 44f29dbc25Smrg#include "xf86cmap.h" 45f29dbc25Smrg#include "compiler.h" 46f29dbc25Smrg#include "mipointer.h" 47f29dbc25Smrg#include "fb.h" 48f29dbc25Smrg#include "miscstruct.h" 49f29dbc25Smrg#include "micmap.h" 50f29dbc25Smrg#include "vbe.h" 51f29dbc25Smrg#include "fb.h" 52f29dbc25Smrg#include "cim_defs.h" 53f29dbc25Smrg#include "cim_regs.h" 54f29dbc25Smrg#include "geode.h" 55f29dbc25Smrg 56f29dbc25Smrg/* Bring in VGA functions */ 57f29dbc25Smrg#include "lx_vga.c" 58f29dbc25Smrg 59f29dbc25Smrg#define LX_MAX_WIDTH 1940 60f29dbc25Smrg#define LX_MAX_HEIGHT 1600 61f29dbc25Smrg 62f29dbc25Smrg/* Size of the register blocks */ 63f29dbc25Smrg 64f29dbc25Smrg#define LX_GP_REG_SIZE 0x4000 65f29dbc25Smrg#define LX_VG_REG_SIZE 0x4000 66f29dbc25Smrg#define LX_VID_REG_SIZE 0x4000 67f29dbc25Smrg#define LX_VIP_REG_SIZE 0x4000 68f29dbc25Smrg 69f29dbc25Smrg/* Size of the Cimarron command buffer */ 70f29dbc25Smrg#define CIM_CMD_BFR_SZ 0x200000 71f29dbc25Smrg 72f29dbc25Smrgextern OptionInfoRec LX_GeodeOptions[]; 73f29dbc25Smrg 74f29dbc25Smrgunsigned char *XpressROMPtr; 75f29dbc25Smrg 76f29dbc25Smrgstatic Bool 77f29dbc25SmrgLXSaveScreen(ScreenPtr pScrn, int mode) 78f29dbc25Smrg{ 79f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; 80f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 81f29dbc25Smrg 82f29dbc25Smrg if (pGeode->useVGA && !pScrni->vtSema) 83f29dbc25Smrg return vgaHWSaveScreen(pScrn, mode); 84f29dbc25Smrg 85f29dbc25Smrg return TRUE; 86f29dbc25Smrg} 87f29dbc25Smrg 88f29dbc25Smrg/* This is an overly complex MSR read mechanism */ 89f29dbc25Smrg 90f29dbc25Smrg/* From Cimarron - the VSAII read/write methods - we use these as fallback */ 91f29dbc25Smrg 92f29dbc25Smrg#define LX_MSR_READ(adr,lo,hi) \ 93f29dbc25Smrg __asm__ __volatile__( \ 94f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 95f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 96f29dbc25Smrg " out %%eax,%%dx\n" \ 97f29dbc25Smrg " add $2,%%dl\n" \ 98f29dbc25Smrg " in %%dx, %%ax" \ 99f29dbc25Smrg : "=a" (lo), "=d" (hi) \ 100f29dbc25Smrg : "c" (adr)) 101f29dbc25Smrg 102f29dbc25Smrg#define LX_MSR_WRITE(adr,low,high) \ 103f29dbc25Smrg { int d0, d1, d2, d3, d4; \ 104f29dbc25Smrg __asm__ __volatile__( \ 105f29dbc25Smrg " push %%ebx\n" \ 106f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 107f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 108f29dbc25Smrg " out %%eax,%%dx\n" \ 109f29dbc25Smrg " add $2,%%dl\n" \ 110f29dbc25Smrg " mov %6, %%ebx\n" \ 111f29dbc25Smrg " mov %7, %0\n" \ 112f29dbc25Smrg " mov %5, %3\n" \ 113f29dbc25Smrg " xor %2, %2\n" \ 114f29dbc25Smrg " xor %1, %1\n" \ 115f29dbc25Smrg " out %%ax, %%dx\n" \ 116f29dbc25Smrg " pop %%ebx\n" \ 117f29dbc25Smrg : "=a"(d0),"=&D"(d1),"=&S"(d2), \ 118f29dbc25Smrg "=c"(d3),"=d"(d4) \ 119f29dbc25Smrg : "1"(adr),"2"(high),"3"(low)); \ 120f29dbc25Smrg } 121f29dbc25Smrg 122f29dbc25Smrgstatic void 123f29dbc25SmrgLXReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) 124f29dbc25Smrg{ 125f29dbc25Smrg if (GeodeReadMSR(addr, lo, hi) == -1) { 126f29dbc25Smrg unsigned int l, h; 127f29dbc25Smrg 128f29dbc25Smrg LX_MSR_READ(addr, l, h); 129f29dbc25Smrg *lo = l; 130f29dbc25Smrg *hi = h; 131f29dbc25Smrg } 132f29dbc25Smrg} 133f29dbc25Smrg 134f29dbc25Smrgstatic void 135f29dbc25SmrgLXWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) 136f29dbc25Smrg{ 137f29dbc25Smrg if (GeodeWriteMSR(addr, lo, hi) == -1) 138f29dbc25Smrg LX_MSR_WRITE(addr, lo, hi); 139f29dbc25Smrg} 140f29dbc25Smrg 141f29dbc25Smrgstatic unsigned int 142f29dbc25SmrgLXCalcPitch(ScrnInfoPtr pScrni) 143f29dbc25Smrg{ 144f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 145f29dbc25Smrg 146f29dbc25Smrg if (pGeode->tryCompression) 147f29dbc25Smrg return 148f29dbc25Smrg GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); 149f29dbc25Smrg else 150f29dbc25Smrg return ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 151f29dbc25Smrg} 152f29dbc25Smrg 153f29dbc25Smrg#ifdef XSERVER_LIBPCIACCESS 154f29dbc25Smrgstatic inline void * 155f29dbc25Smrgmap_pci_mem(ScrnInfoPtr pScrni, int vram, 156f29dbc25Smrg struct pci_device *dev, int bar, int size) 157f29dbc25Smrg{ 158f29dbc25Smrg void *ptr; 159f29dbc25Smrg void **result = (void **)&ptr; 160f29dbc25Smrg int map_size = size ? size : dev->regions[bar].size; 161f29dbc25Smrg 162f29dbc25Smrg int err = pci_device_map_range(dev, 163f29dbc25Smrg dev->regions[bar].base_addr, 164f29dbc25Smrg map_size, 165f29dbc25Smrg PCI_DEV_MAP_FLAG_WRITABLE | 166f29dbc25Smrg (vram ? PCI_DEV_MAP_FLAG_WRITE_COMBINE : 0), 167f29dbc25Smrg result); 168f29dbc25Smrg 169f29dbc25Smrg if (err) 170f29dbc25Smrg return NULL; 171f29dbc25Smrg return ptr; 172f29dbc25Smrg} 173f29dbc25Smrg 174f29dbc25Smrgstatic inline int 175f29dbc25Smrgunmap_pci_mem(ScrnInfoPtr pScrni, struct pci_device *dev, void *ptr, int size) 176f29dbc25Smrg{ 177f29dbc25Smrg return pci_device_unmap_range(dev, ptr, size); 178f29dbc25Smrg} 179f29dbc25Smrg 180f29dbc25Smrg#endif 181f29dbc25Smrg 182f29dbc25Smrgstatic Bool 183f29dbc25SmrgLXMapMem(ScrnInfoPtr pScrni) 184f29dbc25Smrg{ 185f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 186f29dbc25Smrg int index = pScrni->scrnIndex; 187f29dbc25Smrg unsigned long cmd_bfr_phys; 188f29dbc25Smrg 189f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 190f29dbc25Smrg 191f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 192f29dbc25Smrg PCITAG tag; 193f29dbc25Smrg 194f29dbc25Smrg tag = pciTag(pci->bus, pci->device, pci->func); 195f29dbc25Smrg 196f29dbc25Smrg cim_gp_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, 197f29dbc25Smrg tag, pci->memBase[1], LX_GP_REG_SIZE); 198f29dbc25Smrg 199f29dbc25Smrg cim_vg_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, 200f29dbc25Smrg tag, pci->memBase[2], LX_VG_REG_SIZE); 201f29dbc25Smrg 202f29dbc25Smrg cim_vid_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, 203f29dbc25Smrg tag, pci->memBase[3], LX_VID_REG_SIZE); 204f29dbc25Smrg 205f29dbc25Smrg cim_vip_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_MMIO, 206f29dbc25Smrg tag, pci->memBase[4], LX_VIP_REG_SIZE); 207f29dbc25Smrg 208f29dbc25Smrg cim_fb_ptr = (unsigned char *)xf86MapPciMem(index, VIDMEM_FRAMEBUFFER, 209f29dbc25Smrg tag, pci->memBase[0], pGeode->FBAvail + CIM_CMD_BFR_SZ); 210f29dbc25Smrg#else 211f29dbc25Smrg cim_gp_ptr = map_pci_mem(pScrni, 0, pci, 1, LX_GP_REG_SIZE); 212f29dbc25Smrg cim_vg_ptr = map_pci_mem(pScrni, 0, pci, 2, LX_VG_REG_SIZE); 213f29dbc25Smrg cim_vid_ptr = map_pci_mem(pScrni, 0, pci, 3, LX_VID_REG_SIZE); 214f29dbc25Smrg cim_vip_ptr = map_pci_mem(pScrni, 0, pci, 4, LX_VIP_REG_SIZE); 215f29dbc25Smrg cim_fb_ptr = 216f29dbc25Smrg map_pci_mem(pScrni, 1, pci, 0, pGeode->FBAvail + CIM_CMD_BFR_SZ); 217f29dbc25Smrg#endif 218f29dbc25Smrg 219f29dbc25Smrg if (pScrni->memPhysBase == 0) 220f29dbc25Smrg pScrni->memPhysBase = PCI_REGION_BASE(pci, 0, REGION_MEM); 221f29dbc25Smrg 222f29dbc25Smrg cmd_bfr_phys = PCI_REGION_BASE(pci, 0, REGION_MEM) + pGeode->CmdBfrOffset; 223f29dbc25Smrg cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; 224f29dbc25Smrg 225f29dbc25Smrg if (!cim_gp_ptr || !cim_vg_ptr || !cim_vid_ptr || !cim_fb_ptr || 226f29dbc25Smrg !cim_vip_ptr) 227f29dbc25Smrg return FALSE; 228f29dbc25Smrg 229f29dbc25Smrg gp_set_frame_buffer_base(PCI_REGION_BASE(pci, 0, REGION_MEM), 230f29dbc25Smrg pGeode->FBAvail); 231f29dbc25Smrg gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); 232f29dbc25Smrg 233f29dbc25Smrg XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); 234f29dbc25Smrg 235f29dbc25Smrg pGeode->FBBase = cim_fb_ptr; 236f29dbc25Smrg 237f29dbc25Smrg if (!pGeode->NoAccel) 238f29dbc25Smrg pGeode->pExa->memoryBase = pGeode->FBBase; 239f29dbc25Smrg 240f29dbc25Smrg xf86DrvMsg(index, X_INFO, "Geode LX video memory %x bytes at %p\n", 241f29dbc25Smrg pGeode->FBAvail, pGeode->FBBase); 242f29dbc25Smrg 243f29dbc25Smrg return TRUE; 244f29dbc25Smrg} 245f29dbc25Smrg 246f29dbc25Smrg/* Check to see if VGA exists - we map the space and look for a 247f29dbc25Smrg signature - if it doesn't match exactly, then we assume no VGA. 248f29dbc25Smrg*/ 249f29dbc25Smrg 250f29dbc25Smrgstatic Bool 251f29dbc25SmrgLXCheckVGA(ScrnInfoPtr pScrni) 252f29dbc25Smrg{ 253f29dbc25Smrg 254f29dbc25Smrg unsigned char *ptr; 255f29dbc25Smrg const char *vgasig = "IBM VGA Compatible"; 256f29dbc25Smrg int ret; 257f29dbc25Smrg 258f29dbc25Smrg ptr = 259f29dbc25Smrg xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, 0xC001E, 260f29dbc25Smrg strlen(vgasig)); 261f29dbc25Smrg 262f29dbc25Smrg if (ptr == NULL) 263f29dbc25Smrg return FALSE; 264f29dbc25Smrg 265f29dbc25Smrg ret = memcmp(ptr, vgasig, strlen(vgasig)); 266f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) ptr, strlen(vgasig)); 267f29dbc25Smrg 268f29dbc25Smrg return ret ? FALSE : TRUE; 269f29dbc25Smrg} 270f29dbc25Smrg 271f29dbc25Smrgstatic Bool 272f29dbc25SmrgLXCrtcResize(ScrnInfoPtr pScrni, int width, int height) 273f29dbc25Smrg{ 274f29dbc25Smrg return TRUE; 275f29dbc25Smrg} 276f29dbc25Smrg 277f29dbc25Smrgstatic const xf86CrtcConfigFuncsRec lx_xf86crtc_config_funcs = { 278f29dbc25Smrg LXCrtcResize, 279f29dbc25Smrg}; 280f29dbc25Smrg 281f29dbc25Smrgstatic Bool 282f29dbc25SmrgLXPreInit(ScrnInfoPtr pScrni, int flags) 283f29dbc25Smrg{ 284f29dbc25Smrg GeodePtr pGeode; 285f29dbc25Smrg EntityInfoPtr pEnt; 286f29dbc25Smrg OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; 287f29dbc25Smrg rgb defaultWeight = { 0, 0, 0 }; 288f29dbc25Smrg char *s; 289f29dbc25Smrg 290f29dbc25Smrg if (pScrni->numEntities != 1) 291f29dbc25Smrg return FALSE; 292f29dbc25Smrg 293f29dbc25Smrg pEnt = xf86GetEntityInfo(pScrni->entityList[0]); 294f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 295f29dbc25Smrg if (pEnt->resources) 296f29dbc25Smrg return FALSE; 297f29dbc25Smrg#endif 298f29dbc25Smrg if (flags & PROBE_DETECT) { 299f29dbc25Smrg GeodeProbeDDC(pScrni, pEnt->index); 300f29dbc25Smrg return TRUE; 301f29dbc25Smrg } 302f29dbc25Smrg 303f29dbc25Smrg pGeode = pScrni->driverPrivate = xnfcalloc(sizeof(GeodeRec), 1); 304f29dbc25Smrg 305f29dbc25Smrg if (pGeode == NULL) 306f29dbc25Smrg return FALSE; 307f29dbc25Smrg 308f29dbc25Smrg pGeode->useVGA = LXCheckVGA(pScrni); 309f29dbc25Smrg pGeode->VGAActive = FALSE; 310f29dbc25Smrg pGeode->pEnt = pEnt; 311f29dbc25Smrg 312f29dbc25Smrg if (pGeode->useVGA) { 313f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "vgahw") || !vgaHWGetHWRec(pScrni)) 314f29dbc25Smrg pGeode->useVGA = FALSE; 315f29dbc25Smrg 316f29dbc25Smrg pGeode->vesa = xcalloc(sizeof(VESARec), 1); 317f29dbc25Smrg } 318f29dbc25Smrg 319f29dbc25Smrg cim_rdmsr = LXReadMSR; 320f29dbc25Smrg cim_wrmsr = LXWriteMSR; 321f29dbc25Smrg 322f29dbc25Smrg /* Set up the Cimarron MSR tables */ 323f29dbc25Smrg msr_init_table(); 324f29dbc25Smrg 325f29dbc25Smrg /* By default, we support panel and CRT - the config file should 326f29dbc25Smrg * disable the ones we don't want 327f29dbc25Smrg */ 328f29dbc25Smrg 329f29dbc25Smrg pGeode->Output = OUTPUT_PANEL | OUTPUT_CRT; 330f29dbc25Smrg 331f29dbc25Smrg /* Fill in the monitor information */ 332f29dbc25Smrg pScrni->monitor = pScrni->confScreen->monitor; 333f29dbc25Smrg 334f29dbc25Smrg if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) 335f29dbc25Smrg return FALSE; 336f29dbc25Smrg 337f29dbc25Smrg switch (pScrni->depth) { 338f29dbc25Smrg case 8: 339f29dbc25Smrg pScrni->rgbBits = 8; 340f29dbc25Smrg case 16: 341f29dbc25Smrg case 24: 342f29dbc25Smrg case 32: 343f29dbc25Smrg break; 344f29dbc25Smrg default: 345f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 346f29dbc25Smrg "The driver does not support %d as a depth.\n", pScrni->depth); 347f29dbc25Smrg return FALSE; 348f29dbc25Smrg } 349f29dbc25Smrg 350f29dbc25Smrg xf86PrintDepthBpp(pScrni); 351f29dbc25Smrg 352f29dbc25Smrg if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) 353f29dbc25Smrg return FALSE; 354f29dbc25Smrg 355f29dbc25Smrg if (!xf86SetDefaultVisual(pScrni, -1)) 356f29dbc25Smrg return FALSE; 357f29dbc25Smrg 358f29dbc25Smrg /* 359f29dbc25Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 360f29dbc25Smrg * here. 361f29dbc25Smrg */ 362f29dbc25Smrg { 363f29dbc25Smrg Gamma zeros = { 0.0, 0.0, 0.0 }; 364f29dbc25Smrg 365f29dbc25Smrg if (!xf86SetGamma(pScrni, zeros)) { 366f29dbc25Smrg return FALSE; 367f29dbc25Smrg } 368f29dbc25Smrg } 369f29dbc25Smrg 370f29dbc25Smrg pScrni->progClock = TRUE; 371f29dbc25Smrg xf86CollectOptions(pScrni, NULL); 372f29dbc25Smrg xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); 373f29dbc25Smrg 374f29dbc25Smrg /* Set up our various options that may get reversed as we go on */ 375f29dbc25Smrg 376f29dbc25Smrg pGeode->tryHWCursor = TRUE; 377f29dbc25Smrg pGeode->tryCompression = TRUE; 378f29dbc25Smrg 379f29dbc25Smrg /* Protect against old versions of EXA */ 380f29dbc25Smrg 381f29dbc25Smrg#if (EXA_VERSION_MAJOR < 2) 382f29dbc25Smrg pGeode->NoAccel = TRUE; 383f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 384f29dbc25Smrg "*** This driver was compiled with EXA version %d\n"); 385f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 386f29dbc25Smrg "*** we need version 2 or greater\n"); 387f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 388f29dbc25Smrg "*** All accelerations are being turned off.\n"); 389f29dbc25Smrg#else 390f29dbc25Smrg pGeode->NoAccel = FALSE; 391f29dbc25Smrg#endif 392f29dbc25Smrg 393f29dbc25Smrg pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; 394f29dbc25Smrg 395f29dbc25Smrg xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, 396f29dbc25Smrg &pGeode->tryHWCursor); 397f29dbc25Smrg 398f29dbc25Smrg if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_FBSIZE, 399f29dbc25Smrg (int *)&(pGeode->FBAvail))) 400f29dbc25Smrg pGeode->FBAvail = 0; 401f29dbc25Smrg 402f29dbc25Smrg /* For compatability - allow SWCursor too */ 403f29dbc25Smrg 404f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) 405f29dbc25Smrg pGeode->tryHWCursor = FALSE; 406f29dbc25Smrg 407f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) 408f29dbc25Smrg pGeode->tryCompression = FALSE; 409f29dbc25Smrg 410f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) 411f29dbc25Smrg pGeode->NoAccel = TRUE; 412f29dbc25Smrg 413f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 414f29dbc25Smrg 415f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { 416f29dbc25Smrg 417f29dbc25Smrg if (!xf86NameCmp(s, "LEFT")) 418f29dbc25Smrg pGeode->rotation = RR_Rotate_90; 419f29dbc25Smrg else if (!xf86NameCmp(s, "INVERT")) 420f29dbc25Smrg pGeode->rotation = RR_Rotate_180; 421f29dbc25Smrg else if (!xf86NameCmp(s, "CCW")) 422f29dbc25Smrg pGeode->rotation = RR_Rotate_270; 423f29dbc25Smrg else 424f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 425f29dbc25Smrg "Invalid rotation %s.\n", s); 426f29dbc25Smrg } 427f29dbc25Smrg 428f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, LX_OPTION_EXA_SCRATCH_BFRSZ, 429f29dbc25Smrg (int *)&(pGeode->exaBfrSz)); 430f29dbc25Smrg 431f29dbc25Smrg if (pGeode->exaBfrSz <= 0) 432f29dbc25Smrg pGeode->exaBfrSz = 0; 433f29dbc25Smrg 434f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) { 435f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOPANEL, FALSE)) 436f29dbc25Smrg pGeode->Output &= ~OUTPUT_PANEL; 437f29dbc25Smrg } 438f29dbc25Smrg 439f29dbc25Smrg /* Panel detection code - 440f29dbc25Smrg * 1. See if an OLPC DCON is attached - we can make some assumptions 441f29dbc25Smrg * about the panel if so. 442f29dbc25Smrg * 2. Use panel mode specified in the config 443f29dbc25Smrg * 3. "Autodetect" the panel through VSA 444f29dbc25Smrg */ 445f29dbc25Smrg 446f29dbc25Smrg if (dcon_init(pScrni)) { 447f29dbc25Smrg pGeode->Output = OUTPUT_PANEL | OUTPUT_DCON; 448f29dbc25Smrg } else if (pGeode->Output & OUTPUT_PANEL) { 449f29dbc25Smrg char *pmode = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_MODE); 450f29dbc25Smrg 451f29dbc25Smrg if (pmode != NULL) 452f29dbc25Smrg pGeode->panelMode = LXGetManualPanelMode(pmode); 453f29dbc25Smrg 454f29dbc25Smrg if (pGeode->panelMode == NULL) 455f29dbc25Smrg pGeode->panelMode = LXGetLegacyPanelMode(); 456f29dbc25Smrg 457f29dbc25Smrg if (pGeode->panelMode == NULL) 458f29dbc25Smrg pGeode->Output &= ~OUTPUT_PANEL; 459f29dbc25Smrg } 460f29dbc25Smrg 461f29dbc25Smrg /* Default to turn scaling on for panels */ 462f29dbc25Smrg 463f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 464f29dbc25Smrg pGeode->Scale = TRUE; 465f29dbc25Smrg 466f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); 467f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", 468f29dbc25Smrg pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); 469f29dbc25Smrg 470f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " PANEL: %s\n", 471f29dbc25Smrg pGeode->Output & OUTPUT_PANEL ? "YES" : "NO"); 472f29dbc25Smrg 473f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " DCON: %s\n", 474f29dbc25Smrg pGeode->Output & OUTPUT_DCON ? "YES" : "NO"); 475f29dbc25Smrg 476f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " VGA: %s\n", 477f29dbc25Smrg pGeode->useVGA ? "YES" : "NO"); 478f29dbc25Smrg 479f29dbc25Smrg /* Set up VGA */ 480f29dbc25Smrg 481f29dbc25Smrg if (pGeode->useVGA) { 482f29dbc25Smrg VESARec *pVesa; 483f29dbc25Smrg 484f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "int10")) 485f29dbc25Smrg return FALSE; 486f29dbc25Smrg 487f29dbc25Smrg pVesa = pGeode->vesa; 488f29dbc25Smrg 489f29dbc25Smrg if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { 490f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 491f29dbc25Smrg "Unable to initialize 1NT10 support\n"); 492f29dbc25Smrg pGeode->useVGA = FALSE; 493f29dbc25Smrg } 494f29dbc25Smrg } 495f29dbc25Smrg 496f29dbc25Smrg /* Read the amount of framebuffer memory */ 497f29dbc25Smrg /* First try to read it from the framebuffer, and if that fails, 498f29dbc25Smrg * do it the legacy way 499f29dbc25Smrg */ 500f29dbc25Smrg 501f29dbc25Smrg if (pGeode->FBAvail == 0) { 502f29dbc25Smrg if (GeodeGetSizeFromFB(&pGeode->FBAvail)) { 503f29dbc25Smrg unsigned long value; 504f29dbc25Smrg 505f29dbc25Smrg cim_outw(0xAC1C, 0xFC53); 506f29dbc25Smrg cim_outw(0xAC1C, 0x0200); 507f29dbc25Smrg 508f29dbc25Smrg value = (unsigned long)(cim_inw(0xAC1E)) & 0xFE; 509f29dbc25Smrg pGeode->FBAvail = value << 20; 510f29dbc25Smrg } 511f29dbc25Smrg } 512f29dbc25Smrg 513f29dbc25Smrg pScrni->fbOffset = 0; 514f29dbc25Smrg 515f29dbc25Smrg if (pGeode->pEnt->device->videoRam == 0) 516f29dbc25Smrg pScrni->videoRam = pGeode->FBAvail / 1024; 517f29dbc25Smrg else { 518f29dbc25Smrg pScrni->videoRam = pGeode->pEnt->device->videoRam; 519f29dbc25Smrg pGeode->FBAvail = pScrni->videoRam << 10; 520f29dbc25Smrg } 521f29dbc25Smrg 522f29dbc25Smrg /* If we have <= 16Mb of memory then compression is going 523f29dbc25Smrg to hurt - so warn and disable */ 524f29dbc25Smrg 525f29dbc25Smrg if (pGeode->tryCompression && 526f29dbc25Smrg pGeode->FBAvail <= 0x1000000) { 527f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 528f29dbc25Smrg "%x bytes of video memory is less then optimal\n", pGeode->FBAvail); 529f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 530f29dbc25Smrg "when compression is on. Disabling compression.\n"); 531f29dbc25Smrg pGeode->tryCompression = FALSE; 532f29dbc25Smrg } 533f29dbc25Smrg 534f29dbc25Smrg /* Carve out some memory for the command buffer */ 535f29dbc25Smrg 536f29dbc25Smrg pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; 537f29dbc25Smrg pGeode->FBAvail -= CIM_CMD_BFR_SZ; 538f29dbc25Smrg 539f29dbc25Smrg pGeode->CmdBfrOffset = pGeode->FBAvail; 540f29dbc25Smrg 541f29dbc25Smrg /* Allocate a a CRTC config structure */ 542f29dbc25Smrg xf86CrtcConfigInit(pScrni, &lx_xf86crtc_config_funcs); 543f29dbc25Smrg 544f29dbc25Smrg /* Set up the GPU CRTC */ 545f29dbc25Smrg LXSetupCrtc(pScrni); 546f29dbc25Smrg 547f29dbc25Smrg xf86CrtcSetSizeRange(pScrni, 320, 200, LX_MAX_WIDTH, LX_MAX_HEIGHT); 548f29dbc25Smrg 549f29dbc25Smrg /* Setup the output */ 550f29dbc25Smrg LXSetupOutput(pScrni); 551f29dbc25Smrg 552f29dbc25Smrg if (!xf86InitialConfiguration(pScrni, FALSE)) { 553f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes.\n"); 554f29dbc25Smrg return FALSE; 555f29dbc25Smrg } 556f29dbc25Smrg 557f29dbc25Smrg xf86PrintModes(pScrni); 558f29dbc25Smrg 559f29dbc25Smrg pScrni->currentMode = pScrni->modes; 560f29dbc25Smrg 561f29dbc25Smrg pGeode->Pitch = LXCalcPitch(pScrni); 562f29dbc25Smrg 563f29dbc25Smrg xf86SetDpi(pScrni, 0, 0); 564f29dbc25Smrg 565f29dbc25Smrg /* Load the modules we'll need */ 566f29dbc25Smrg 567f29dbc25Smrg if (xf86LoadSubModule(pScrni, "fb") == NULL) { 568f29dbc25Smrg return FALSE; 569f29dbc25Smrg } 570f29dbc25Smrg 571f29dbc25Smrg if (!pGeode->NoAccel) { 572f29dbc25Smrg if (!xf86LoadSubModule(pScrni, "exa")) 573f29dbc25Smrg return FALSE; 574f29dbc25Smrg } 575f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 576f29dbc25Smrg if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { 577f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 578f29dbc25Smrg "Couldn't register the resources.\n"); 579f29dbc25Smrg return FALSE; 580f29dbc25Smrg } 581f29dbc25Smrg#endif 582f29dbc25Smrg return TRUE; 583f29dbc25Smrg} 584f29dbc25Smrg 585f29dbc25Smrgstatic void 586f29dbc25SmrgLXRestore(ScrnInfoPtr pScrni) 587f29dbc25Smrg{ 588f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 589f29dbc25Smrg 590f29dbc25Smrg if (pGeode->useVGA) { 591f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 592f29dbc25Smrg 593f29dbc25Smrg vgaHWProtect(pScrni, TRUE); 594f29dbc25Smrg vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); 595f29dbc25Smrg vgaHWProtect(pScrni, FALSE); 596f29dbc25Smrg } 597f29dbc25Smrg} 598f29dbc25Smrg 599f29dbc25Smrgstatic Bool 600f29dbc25SmrgLXUnmapMem(ScrnInfoPtr pScrni) 601f29dbc25Smrg{ 602f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 603f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); 604f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); 605f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vid_ptr, 606f29dbc25Smrg LX_VID_REG_SIZE); 607f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, 608f29dbc25Smrg LX_VIP_REG_SIZE); 609f29dbc25Smrg#else 610f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 611f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 612f29dbc25Smrg 613f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_gp_ptr, LX_GP_REG_SIZE); 614f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vg_ptr, LX_VG_REG_SIZE); 615f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vid_ptr, LX_VID_REG_SIZE); 616f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vip_ptr, LX_VIP_REG_SIZE); 617f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_fb_ptr, pGeode->FBAvail + CIM_CMD_BFR_SZ); 618f29dbc25Smrg#endif 619f29dbc25Smrg 620f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000); 621f29dbc25Smrg 622f29dbc25Smrg return TRUE; 623f29dbc25Smrg} 624f29dbc25Smrg 625f29dbc25Smrg/* These should be correctly accounted for rotation */ 626f29dbc25Smrg 627f29dbc25Smrgvoid 628f29dbc25SmrgLXAdjustFrame(int scrnIndex, int x, int y, int flags) 629f29dbc25Smrg{ 630f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 631f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 632f29dbc25Smrg 633f29dbc25Smrg unsigned long offset; 634f29dbc25Smrg 635f29dbc25Smrg offset = (y * pGeode->Pitch); 636f29dbc25Smrg offset += x * (pScrni->bitsPerPixel >> 3); 637f29dbc25Smrg 638f29dbc25Smrg vg_set_display_offset(offset); 639f29dbc25Smrg} 640f29dbc25Smrg 641f29dbc25Smrgstatic Bool 642f29dbc25SmrgLXSwitchMode(int index, DisplayModePtr pMode, int flags) 643f29dbc25Smrg{ 644f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[index]; 645f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 646f29dbc25Smrg 647f29dbc25Smrg /* Set the new mode */ 648f29dbc25Smrg return xf86SetSingleMode(pScrni, pMode, pGeode->rotation); 649f29dbc25Smrg} 650f29dbc25Smrg 651f29dbc25Smrgstatic void 652f29dbc25SmrgLXLeaveGraphics(ScrnInfoPtr pScrni) 653f29dbc25Smrg{ 654f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 655f29dbc25Smrg VG_PANNING_COORDINATES panning; 656f29dbc25Smrg 657f29dbc25Smrg gp_wait_until_idle(); 658f29dbc25Smrg 659f29dbc25Smrg vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), 660f29dbc25Smrg pGeode->FBcimdisplaytiming.wBpp); 661f29dbc25Smrg 662f29dbc25Smrg vg_set_compression_enable(0); 663f29dbc25Smrg 664f29dbc25Smrg /* Restore the previous Compression state */ 665f29dbc25Smrg if (pGeode->FBCompressionEnable) { 666f29dbc25Smrg vg_configure_compression(&(pGeode->FBCBData)); 667f29dbc25Smrg vg_set_compression_enable(1); 668f29dbc25Smrg } 669f29dbc25Smrg 670f29dbc25Smrg vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); 671f29dbc25Smrg vg_set_display_offset(pGeode->FBDisplayOffset); 672f29dbc25Smrg 673f29dbc25Smrg /* Restore Cursor */ 674f29dbc25Smrg vg_set_cursor_position(pGeode->FBCursor.cursor_x, 675f29dbc25Smrg pGeode->FBCursor.cursor_y, &panning); 676f29dbc25Smrg 677f29dbc25Smrg LXRestore(pScrni); 678f29dbc25Smrg 679f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 680f29dbc25Smrg pGeode->vesa->pInt->num = 0x10; 681f29dbc25Smrg pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; 682f29dbc25Smrg pGeode->vesa->pInt->bx = 0; 683f29dbc25Smrg xf86ExecX86int10(pGeode->vesa->pInt); 684f29dbc25Smrg vg_delay_milliseconds(3); 685f29dbc25Smrg } 686f29dbc25Smrg 687f29dbc25Smrg pScrni->vtSema = FALSE; 688f29dbc25Smrg} 689f29dbc25Smrg 690f29dbc25Smrgstatic Bool 691f29dbc25SmrgLXCloseScreen(int scrnIndex, ScreenPtr pScrn) 692f29dbc25Smrg{ 693f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 694f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 695f29dbc25Smrg 696f29dbc25Smrg if (pScrni->vtSema) 697f29dbc25Smrg LXLeaveGraphics(pScrni); 698f29dbc25Smrg 699f29dbc25Smrg if (pGeode->pExa) { 700f29dbc25Smrg exaDriverFini(pScrn); 701f29dbc25Smrg xfree(pGeode->pExa); 702f29dbc25Smrg pGeode->pExa = NULL; 703f29dbc25Smrg } 704f29dbc25Smrg 705f29dbc25Smrg /* Unmap the offscreen allocations */ 706f29dbc25Smrg GeodeCloseOffscreen(pScrni); 707f29dbc25Smrg 708f29dbc25Smrg LXUnmapMem(pScrni); 709f29dbc25Smrg 710f29dbc25Smrg if (pGeode->useVGA) 711f29dbc25Smrg vgaHWUnmapMem(pScrni); 712f29dbc25Smrg 713f29dbc25Smrg pScrni->PointerMoved = pGeode->PointerMoved; 714f29dbc25Smrg pScrn->CloseScreen = pGeode->CloseScreen; 715f29dbc25Smrg 716f29dbc25Smrg if (pScrn->CloseScreen) 717f29dbc25Smrg return (*pScrn->CloseScreen) (scrnIndex, pScrn); 718f29dbc25Smrg 719f29dbc25Smrg return TRUE; 720f29dbc25Smrg} 721f29dbc25Smrg 722f29dbc25Smrgstatic Bool 723f29dbc25SmrgLXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 724f29dbc25Smrg{ 725f29dbc25Smrg int bpp; 726f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 727f29dbc25Smrg 728f29dbc25Smrg pGeode->VGAActive = gu3_get_vga_active(); 729f29dbc25Smrg 730f29dbc25Smrg gp_wait_until_idle(); 731f29dbc25Smrg 732f29dbc25Smrg vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, 733f29dbc25Smrg &bpp); 734f29dbc25Smrg 735f29dbc25Smrg pGeode->FBcimdisplaytiming.wBpp = bpp; 736f29dbc25Smrg pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); 737f29dbc25Smrg 738f29dbc25Smrg pGeode->FBDisplayOffset = vg_get_display_offset(); 739f29dbc25Smrg 740f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 741f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 742f29dbc25Smrg 743f29dbc25Smrg pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); 744f29dbc25Smrg } 745f29dbc25Smrg 746f29dbc25Smrg pGeode->FBCompressionEnable = vg_get_compression_enable(); 747f29dbc25Smrg vg_get_compression_info(&(pGeode->FBCBData)); 748f29dbc25Smrg 749f29dbc25Smrg /* Save Cursor offset */ 750f29dbc25Smrg vg_get_cursor_info(&pGeode->FBCursor); 751f29dbc25Smrg 752f29dbc25Smrg /* Turn off the VGA */ 753f29dbc25Smrg 754f29dbc25Smrg if (pGeode->useVGA) { 755f29dbc25Smrg unsigned short sequencer; 756f29dbc25Smrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 757f29dbc25Smrg 758f29dbc25Smrg /* Unlock VGA registers */ 759f29dbc25Smrg vgaHWUnlock(pvgaHW); 760f29dbc25Smrg 761f29dbc25Smrg /* Save the current state and setup the current mode */ 762f29dbc25Smrg vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); 763f29dbc25Smrg 764f29dbc25Smrg /* DISABLE VGA SEQUENCER */ 765f29dbc25Smrg /* This allows the VGA state machine to terminate. We must delay */ 766f29dbc25Smrg /* such that there are no pending MBUS requests. */ 767f29dbc25Smrg 768f29dbc25Smrg cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); 769f29dbc25Smrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 770f29dbc25Smrg sequencer |= DC3_CLK_MODE_SCREEN_OFF; 771f29dbc25Smrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 772f29dbc25Smrg 773f29dbc25Smrg vg_delay_milliseconds(1); 774f29dbc25Smrg 775f29dbc25Smrg /* BLANK THE VGA DISPLAY */ 776f29dbc25Smrg cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); 777f29dbc25Smrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 778f29dbc25Smrg sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; 779f29dbc25Smrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 780f29dbc25Smrg 781f29dbc25Smrg vg_delay_milliseconds(1); 782f29dbc25Smrg } 783f29dbc25Smrg 784f29dbc25Smrg /* Clear the framebuffer */ 785f29dbc25Smrg memset(pGeode->FBBase, 0, pGeode->displaySize); 786f29dbc25Smrg 787f29dbc25Smrg /* Set the modes */ 788f29dbc25Smrg if (!xf86SetDesiredModes(pScrni)) 789f29dbc25Smrg return FALSE; 790f29dbc25Smrg 791f29dbc25Smrg pScrni->vtSema = TRUE; 792f29dbc25Smrg 793f29dbc25Smrg return TRUE; 794f29dbc25Smrg} 795f29dbc25Smrg 796f29dbc25Smrgstatic void 797f29dbc25SmrgLXLoadPalette(ScrnInfoPtr pScrni, 798f29dbc25Smrg int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) 799f29dbc25Smrg{ 800f29dbc25Smrg int i, index, color; 801f29dbc25Smrg 802f29dbc25Smrg for (i = 0; i < numColors; i++) { 803f29dbc25Smrg index = indizes[i] & 0xFF; 804f29dbc25Smrg color = (((unsigned long)(colors[index].red & 0xFF)) << 16) | 805f29dbc25Smrg (((unsigned long)(colors[index].green & 0xFF)) << 8) | 806f29dbc25Smrg ((unsigned long)(colors[index].blue & 0xFF)); 807f29dbc25Smrg 808f29dbc25Smrg vg_set_display_palette_entry(index, color); 809f29dbc25Smrg } 810f29dbc25Smrg} 811f29dbc25Smrg 812f29dbc25Smrgstatic Bool 813f29dbc25SmrgLXScreenInit(int scrnIndex, ScreenPtr pScrn, int argc, char **argv) 814f29dbc25Smrg{ 815f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 816f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 817f29dbc25Smrg int ret; 818f29dbc25Smrg unsigned int dwidth; 819f29dbc25Smrg 820f29dbc25Smrg pGeode->starting = TRUE; 821f29dbc25Smrg 822f29dbc25Smrg /* If we are using VGA then go ahead and map the memory */ 823f29dbc25Smrg 824f29dbc25Smrg if (pGeode->useVGA) { 825f29dbc25Smrg 826f29dbc25Smrg if (!vgaHWMapMem(pScrni)) 827f29dbc25Smrg return FALSE; 828f29dbc25Smrg 829f29dbc25Smrg vgaHWGetIOBase(VGAHWPTR(pScrni)); 830f29dbc25Smrg } 831f29dbc25Smrg 832f29dbc25Smrg if (!pGeode->NoAccel) { 833f29dbc25Smrg 834f29dbc25Smrg pGeode->pExa = exaDriverAlloc(); 835f29dbc25Smrg 836f29dbc25Smrg if (pGeode->pExa) { 837f29dbc25Smrg 838f29dbc25Smrg pGeode->pExa->memoryBase = 0; 839f29dbc25Smrg pGeode->pExa->memorySize = 0; 840f29dbc25Smrg 841f29dbc25Smrg pGeode->pExa->pixmapOffsetAlign = 32; 842f29dbc25Smrg pGeode->pExa->pixmapPitchAlign = 32; 843f29dbc25Smrg pGeode->pExa->flags = EXA_OFFSCREEN_PIXMAPS; 844f29dbc25Smrg pGeode->pExa->maxX = LX_MAX_WIDTH - 1; 845f29dbc25Smrg pGeode->pExa->maxY = LX_MAX_HEIGHT - 1; 846f29dbc25Smrg } else { 847f29dbc25Smrg xf86DrvMsg(scrnIndex, X_ERROR, 848f29dbc25Smrg "Couldn't allocate the EXA structure.\n"); 849f29dbc25Smrg pGeode->NoAccel = TRUE; 850f29dbc25Smrg } 851f29dbc25Smrg } 852f29dbc25Smrg 853f29dbc25Smrg /* Map the memory here before doing anything else */ 854f29dbc25Smrg 855f29dbc25Smrg if (!LXMapMem(pScrni)) 856f29dbc25Smrg return FALSE; 857f29dbc25Smrg 858f29dbc25Smrg LXInitOffscreen(pScrni); 859f29dbc25Smrg 860f29dbc25Smrg /* XXX FIXME - Take down any of the structures on failure? */ 861f29dbc25Smrg if (!LXEnterGraphics(pScrn, pScrni)) 862f29dbc25Smrg return FALSE; 863f29dbc25Smrg 864f29dbc25Smrg miClearVisualTypes(); 865f29dbc25Smrg 866f29dbc25Smrg /* XXX Again - take down anything? */ 867f29dbc25Smrg 868f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 869f29dbc25Smrg if (!miSetVisualTypes(pScrni->depth, 870f29dbc25Smrg TrueColorMask, pScrni->rgbBits, pScrni->defaultVisual)) { 871f29dbc25Smrg return FALSE; 872f29dbc25Smrg } 873f29dbc25Smrg } else { 874f29dbc25Smrg if (!miSetVisualTypes(pScrni->depth, 875f29dbc25Smrg miGetDefaultVisualMask(pScrni->depth), 876f29dbc25Smrg pScrni->rgbBits, pScrni->defaultVisual)) { 877f29dbc25Smrg return FALSE; 878f29dbc25Smrg } 879f29dbc25Smrg } 880f29dbc25Smrg 881f29dbc25Smrg miSetPixmapDepths(); 882f29dbc25Smrg 883f29dbc25Smrg if (pScrni->virtualX > pScrni->displayWidth) 884f29dbc25Smrg pScrni->displayWidth = pScrni->virtualX; 885f29dbc25Smrg 886f29dbc25Smrg /* Point at the visible area to start */ 887f29dbc25Smrg 888f29dbc25Smrg /* fbScreenInit assumes that the stride is display width * 889f29dbc25Smrg * bytes per pixel. If compression is on, then our stride might 890f29dbc25Smrg * be completely different, so we divide the pitch by the 891f29dbc25Smrg * bytes per pixel to fake fbScreenInit into doing the right thing */ 892f29dbc25Smrg 893f29dbc25Smrg dwidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 894f29dbc25Smrg 895f29dbc25Smrg ret = fbScreenInit(pScrn, pGeode->FBBase, 896f29dbc25Smrg pScrni->virtualX, pScrni->virtualY, 897f29dbc25Smrg pScrni->xDpi, pScrni->yDpi, dwidth, pScrni->bitsPerPixel); 898f29dbc25Smrg 899f29dbc25Smrg if (!ret) 900f29dbc25Smrg return FALSE; 901f29dbc25Smrg 902f29dbc25Smrg xf86SetBlackWhitePixels(pScrn); 903f29dbc25Smrg 904f29dbc25Smrg /* Set up the color ordering */ 905f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 906f29dbc25Smrg VisualPtr visual = pScrn->visuals + pScrn->numVisuals; 907f29dbc25Smrg 908f29dbc25Smrg while (--visual >= pScrn->visuals) { 909f29dbc25Smrg if ((visual->class | DynamicClass) == DirectColor) { 910f29dbc25Smrg visual->offsetRed = pScrni->offset.red; 911f29dbc25Smrg visual->offsetGreen = pScrni->offset.green; 912f29dbc25Smrg visual->offsetBlue = pScrni->offset.blue; 913f29dbc25Smrg visual->redMask = pScrni->mask.red; 914f29dbc25Smrg visual->greenMask = pScrni->mask.green; 915f29dbc25Smrg visual->blueMask = pScrni->mask.blue; 916f29dbc25Smrg } 917f29dbc25Smrg } 918f29dbc25Smrg } 919f29dbc25Smrg 920f29dbc25Smrg /* Must follow the color ordering */ 921f29dbc25Smrg fbPictureInit(pScrn, 0, 0); 922f29dbc25Smrg 923f29dbc25Smrg if (!pGeode->NoAccel) 924f29dbc25Smrg pGeode->NoAccel = LXExaInit(pScrn) ? FALSE : TRUE; 925f29dbc25Smrg 926f29dbc25Smrg miInitializeBackingStore(pScrn); 927f29dbc25Smrg xf86SetBackingStore(pScrn); 928f29dbc25Smrg 929f29dbc25Smrg /* Set up the soft cursor */ 930f29dbc25Smrg miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); 931f29dbc25Smrg 932f29dbc25Smrg /* Set up the HW cursor - must follow the soft cursor init */ 933f29dbc25Smrg 934f29dbc25Smrg if (pGeode->tryHWCursor) { 935f29dbc25Smrg if (!LXCursorInit(pScrn)) 936f29dbc25Smrg xf86DrvMsg(scrnIndex, X_ERROR, 937f29dbc25Smrg "Hardware cursor initialization failed.\n"); 938f29dbc25Smrg } 939f29dbc25Smrg 940f29dbc25Smrg /* Set up the color map */ 941f29dbc25Smrg 942f29dbc25Smrg if (!miCreateDefColormap(pScrn)) 943f29dbc25Smrg return FALSE; 944f29dbc25Smrg 945f29dbc25Smrg if (pScrni->bitsPerPixel == 8) { 946f29dbc25Smrg /* Must follow initialization of the default colormap */ 947f29dbc25Smrg 948f29dbc25Smrg if (!xf86HandleColormaps(pScrn, 256, 8, 949f29dbc25Smrg LXLoadPalette, NULL, 950f29dbc25Smrg CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) { 951f29dbc25Smrg return FALSE; 952f29dbc25Smrg } 953f29dbc25Smrg } 954f29dbc25Smrg xf86DPMSInit(pScrn, xf86DPMSSet, 0); 955f29dbc25Smrg 956f29dbc25Smrg LXInitVideo(pScrn); 957f29dbc25Smrg 958f29dbc25Smrg pGeode->PointerMoved = pScrni->PointerMoved; 959f29dbc25Smrg pScrni->PointerMoved = GeodePointerMoved; 960f29dbc25Smrg 961f29dbc25Smrg pGeode->CloseScreen = pScrn->CloseScreen; 962f29dbc25Smrg pScrn->CloseScreen = LXCloseScreen; 963f29dbc25Smrg pScrn->SaveScreen = LXSaveScreen; 964f29dbc25Smrg 965f29dbc25Smrg if (!xf86CrtcScreenInit(pScrn)) { 966f29dbc25Smrg xf86DrvMsg(scrnIndex, X_ERROR, "CRTCScreenInit failed.\n"); 967f29dbc25Smrg return FALSE; 968f29dbc25Smrg } 969f29dbc25Smrg 970f29dbc25Smrg if (serverGeneration == 1) 971f29dbc25Smrg xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); 972f29dbc25Smrg 973f29dbc25Smrg pGeode->starting = FALSE; 974f29dbc25Smrg 975f29dbc25Smrg return TRUE; 976f29dbc25Smrg} 977f29dbc25Smrg 978f29dbc25Smrgstatic int 979f29dbc25SmrgLXValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) 980f29dbc25Smrg{ 981f29dbc25Smrg return MODE_OK; 982f29dbc25Smrg} 983f29dbc25Smrg 984f29dbc25Smrgstatic Bool 985f29dbc25SmrgLXEnterVT(int scrnIndex, int flags) 986f29dbc25Smrg{ 987f29dbc25Smrg return LXEnterGraphics(NULL, xf86Screens[scrnIndex]); 988f29dbc25Smrg} 989f29dbc25Smrg 990f29dbc25Smrgstatic void 991f29dbc25SmrgLXLeaveVT(int scrnIndex, int flags) 992f29dbc25Smrg{ 993f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[scrnIndex]; 994f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 995f29dbc25Smrg 996f29dbc25Smrg pGeode->PrevDisplayOffset = vg_get_display_offset(); 997f29dbc25Smrg LXLeaveGraphics(pScrni); 998f29dbc25Smrg} 999f29dbc25Smrg 1000f29dbc25Smrgvoid 1001f29dbc25SmrgLXSetupChipsetFPtr(ScrnInfoPtr pScrn) 1002f29dbc25Smrg{ 1003f29dbc25Smrg pScrn->PreInit = LXPreInit; 1004f29dbc25Smrg pScrn->ScreenInit = LXScreenInit; 1005f29dbc25Smrg pScrn->SwitchMode = LXSwitchMode; 1006f29dbc25Smrg pScrn->AdjustFrame = LXAdjustFrame; 1007f29dbc25Smrg pScrn->EnterVT = LXEnterVT; 1008f29dbc25Smrg pScrn->LeaveVT = LXLeaveVT; 1009f29dbc25Smrg pScrn->FreeScreen = GeodeFreeScreen; 1010f29dbc25Smrg pScrn->ValidMode = LXValidMode; 1011f29dbc25Smrg} 1012