lx_driver.c revision 3406bd8e
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> 367f419768Smrg#include <fcntl.h> 377f419768Smrg#include <unistd.h> 387f419768Smrg#include <sys/mman.h> 39f29dbc25Smrg 403406bd8eSmrg#include "xorg-server.h" 41f29dbc25Smrg#include "xf86.h" 42f29dbc25Smrg#include "xf86_OSproc.h" 43f29dbc25Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 44f29dbc25Smrg#include "xf86Resources.h" 45f29dbc25Smrg#endif 46f29dbc25Smrg#include "xf86i2c.h" 47f29dbc25Smrg#include "xf86Crtc.h" 48f29dbc25Smrg#include "xf86cmap.h" 49f29dbc25Smrg#include "compiler.h" 50f29dbc25Smrg#include "mipointer.h" 51f29dbc25Smrg#include "fb.h" 52f29dbc25Smrg#include "miscstruct.h" 53f29dbc25Smrg#include "micmap.h" 54f29dbc25Smrg#include "vbe.h" 55f29dbc25Smrg#include "fb.h" 56f29dbc25Smrg#include "cim_defs.h" 57f29dbc25Smrg#include "cim_regs.h" 58f29dbc25Smrg#include "geode.h" 59f29dbc25Smrg 60f29dbc25Smrg/* Bring in VGA functions */ 61f29dbc25Smrg#include "lx_vga.c" 62f29dbc25Smrg 63f29dbc25Smrg#define LX_MAX_WIDTH 1940 64f29dbc25Smrg#define LX_MAX_HEIGHT 1600 65f29dbc25Smrg 66f29dbc25Smrg/* Size of the register blocks */ 67f29dbc25Smrg 68f29dbc25Smrg#define LX_GP_REG_SIZE 0x4000 69f29dbc25Smrg#define LX_VG_REG_SIZE 0x4000 70f29dbc25Smrg#define LX_VID_REG_SIZE 0x4000 71f29dbc25Smrg#define LX_VIP_REG_SIZE 0x4000 72f29dbc25Smrg 73f29dbc25Smrg/* Size of the Cimarron command buffer */ 74f29dbc25Smrg#define CIM_CMD_BFR_SZ 0x200000 75f29dbc25Smrg 76f29dbc25Smrgextern OptionInfoRec LX_GeodeOptions[]; 77f29dbc25Smrg 78f29dbc25Smrgunsigned char *XpressROMPtr; 79f29dbc25Smrg 80f29dbc25Smrgstatic Bool 81f29dbc25SmrgLXSaveScreen(ScreenPtr pScrn, int mode) 82f29dbc25Smrg{ 8304007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 84f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 85f29dbc25Smrg 86f29dbc25Smrg if (pGeode->useVGA && !pScrni->vtSema) 8704007ebaSmrg return vgaHWSaveScreen(pScrn, mode); 88f29dbc25Smrg 89f29dbc25Smrg return TRUE; 90f29dbc25Smrg} 91f29dbc25Smrg 92f29dbc25Smrg/* This is an overly complex MSR read mechanism */ 93f29dbc25Smrg 94f29dbc25Smrg/* From Cimarron - the VSAII read/write methods - we use these as fallback */ 95f29dbc25Smrg 96f29dbc25Smrg#define LX_MSR_READ(adr,lo,hi) \ 97f29dbc25Smrg __asm__ __volatile__( \ 98f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 99f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 100f29dbc25Smrg " out %%eax,%%dx\n" \ 101f29dbc25Smrg " add $2,%%dl\n" \ 102f29dbc25Smrg " in %%dx, %%ax" \ 103f29dbc25Smrg : "=a" (lo), "=d" (hi) \ 104f29dbc25Smrg : "c" (adr)) 105f29dbc25Smrg 106f29dbc25Smrg#define LX_MSR_WRITE(adr,low,high) \ 107f29dbc25Smrg { int d0, d1, d2, d3, d4; \ 108f29dbc25Smrg __asm__ __volatile__( \ 109f29dbc25Smrg " push %%ebx\n" \ 110f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 111f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 112f29dbc25Smrg " out %%eax,%%dx\n" \ 113f29dbc25Smrg " add $2,%%dl\n" \ 114f29dbc25Smrg " mov %6, %%ebx\n" \ 115f29dbc25Smrg " mov %7, %0\n" \ 116f29dbc25Smrg " mov %5, %3\n" \ 117f29dbc25Smrg " xor %2, %2\n" \ 118f29dbc25Smrg " xor %1, %1\n" \ 119f29dbc25Smrg " out %%ax, %%dx\n" \ 120f29dbc25Smrg " pop %%ebx\n" \ 121f29dbc25Smrg : "=a"(d0),"=&D"(d1),"=&S"(d2), \ 122f29dbc25Smrg "=c"(d3),"=d"(d4) \ 123f29dbc25Smrg : "1"(adr),"2"(high),"3"(low)); \ 124f29dbc25Smrg } 125f29dbc25Smrg 126f29dbc25Smrgstatic void 127f29dbc25SmrgLXReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) 128f29dbc25Smrg{ 129f29dbc25Smrg if (GeodeReadMSR(addr, lo, hi) == -1) { 13004007ebaSmrg unsigned int l, h; 131f29dbc25Smrg 13204007ebaSmrg LX_MSR_READ(addr, l, h); 13304007ebaSmrg *lo = l; 13404007ebaSmrg *hi = h; 135f29dbc25Smrg } 136f29dbc25Smrg} 137f29dbc25Smrg 138f29dbc25Smrgstatic void 139f29dbc25SmrgLXWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) 140f29dbc25Smrg{ 141f29dbc25Smrg if (GeodeWriteMSR(addr, lo, hi) == -1) 14204007ebaSmrg LX_MSR_WRITE(addr, lo, hi); 143f29dbc25Smrg} 144f29dbc25Smrg 145f29dbc25Smrgstatic unsigned int 146f29dbc25SmrgLXCalcPitch(ScrnInfoPtr pScrni) 147f29dbc25Smrg{ 148f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 149f29dbc25Smrg 150f29dbc25Smrg if (pGeode->tryCompression) 15104007ebaSmrg return GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); 152f29dbc25Smrg else 15304007ebaSmrg return ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 154f29dbc25Smrg} 155f29dbc25Smrg 156f29dbc25Smrg#ifdef XSERVER_LIBPCIACCESS 157f29dbc25Smrgstatic inline void * 158f29dbc25Smrgmap_pci_mem(ScrnInfoPtr pScrni, int vram, 15904007ebaSmrg struct pci_device *dev, int bar, int size) 160f29dbc25Smrg{ 161f29dbc25Smrg void *ptr; 162f29dbc25Smrg int map_size = size ? size : dev->regions[bar].size; 163f29dbc25Smrg 164f29dbc25Smrg int err = pci_device_map_range(dev, 16504007ebaSmrg dev->regions[bar].base_addr, 16604007ebaSmrg map_size, 16704007ebaSmrg PCI_DEV_MAP_FLAG_WRITABLE | 16804007ebaSmrg (vram ? PCI_DEV_MAP_FLAG_WRITE_COMBINE : 0), 1697f419768Smrg &ptr); 170f29dbc25Smrg 171f29dbc25Smrg if (err) 17204007ebaSmrg return NULL; 173f29dbc25Smrg return ptr; 174f29dbc25Smrg} 175f29dbc25Smrg 176f29dbc25Smrgstatic inline int 177f29dbc25Smrgunmap_pci_mem(ScrnInfoPtr pScrni, struct pci_device *dev, void *ptr, int size) 178f29dbc25Smrg{ 179f29dbc25Smrg return pci_device_unmap_range(dev, ptr, size); 180f29dbc25Smrg} 181f29dbc25Smrg 182f29dbc25Smrg#endif 183f29dbc25Smrg 184f29dbc25Smrgstatic Bool 185f29dbc25SmrgLXMapMem(ScrnInfoPtr pScrni) 186f29dbc25Smrg{ 187f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 188f29dbc25Smrg int index = pScrni->scrnIndex; 189f29dbc25Smrg unsigned long cmd_bfr_phys; 190f29dbc25Smrg 191f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 192f29dbc25Smrg 193f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 194f29dbc25Smrg PCITAG tag; 195f29dbc25Smrg 196f29dbc25Smrg tag = pciTag(pci->bus, pci->device, pci->func); 197f29dbc25Smrg 19804007ebaSmrg cim_gp_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 19904007ebaSmrg tag, pci->memBase[1], 20004007ebaSmrg LX_GP_REG_SIZE); 201f29dbc25Smrg 20204007ebaSmrg cim_vg_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 20304007ebaSmrg tag, pci->memBase[2], 20404007ebaSmrg LX_VG_REG_SIZE); 205f29dbc25Smrg 20604007ebaSmrg cim_vid_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 20704007ebaSmrg tag, pci->memBase[3], 20804007ebaSmrg LX_VID_REG_SIZE); 209f29dbc25Smrg 21004007ebaSmrg cim_vip_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 21104007ebaSmrg tag, pci->memBase[4], 21204007ebaSmrg LX_VIP_REG_SIZE); 213f29dbc25Smrg 21404007ebaSmrg cim_fb_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_FRAMEBUFFER, 21504007ebaSmrg tag, pci->memBase[0], 21604007ebaSmrg pGeode->FBAvail + 21704007ebaSmrg CIM_CMD_BFR_SZ); 218f29dbc25Smrg#else 219f29dbc25Smrg cim_gp_ptr = map_pci_mem(pScrni, 0, pci, 1, LX_GP_REG_SIZE); 220f29dbc25Smrg cim_vg_ptr = map_pci_mem(pScrni, 0, pci, 2, LX_VG_REG_SIZE); 221f29dbc25Smrg cim_vid_ptr = map_pci_mem(pScrni, 0, pci, 3, LX_VID_REG_SIZE); 222f29dbc25Smrg cim_vip_ptr = map_pci_mem(pScrni, 0, pci, 4, LX_VIP_REG_SIZE); 223f29dbc25Smrg cim_fb_ptr = 22404007ebaSmrg map_pci_mem(pScrni, 1, pci, 0, pGeode->FBAvail + CIM_CMD_BFR_SZ); 225f29dbc25Smrg#endif 226f29dbc25Smrg 227f29dbc25Smrg if (pScrni->memPhysBase == 0) 22804007ebaSmrg pScrni->memPhysBase = PCI_REGION_BASE(pci, 0, REGION_MEM); 229f29dbc25Smrg 230f29dbc25Smrg cmd_bfr_phys = PCI_REGION_BASE(pci, 0, REGION_MEM) + pGeode->CmdBfrOffset; 231f29dbc25Smrg cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; 232f29dbc25Smrg 233f29dbc25Smrg if (!cim_gp_ptr || !cim_vg_ptr || !cim_vid_ptr || !cim_fb_ptr || 23404007ebaSmrg !cim_vip_ptr) 23504007ebaSmrg return FALSE; 236f29dbc25Smrg 237f29dbc25Smrg gp_set_frame_buffer_base(PCI_REGION_BASE(pci, 0, REGION_MEM), 23804007ebaSmrg pGeode->FBAvail); 239f29dbc25Smrg gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); 240f29dbc25Smrg 2417f419768Smrg#ifndef XSERVER_LIBPCIACCESS 242f29dbc25Smrg XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); 2437f419768Smrg#else 2447f419768Smrg { 2457f419768Smrg int fd = open("/dev/mem", O_RDWR); 2467f419768Smrg if (fd < 0) { 2477f419768Smrg xf86DrvMsg(index, X_ERROR, "Failed to open /dev/mem: %m\n"); 2487f419768Smrg return FALSE; 2497f419768Smrg } 2507f419768Smrg XpressROMPtr = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xF0000); 2517f419768Smrg close(fd); 2527f419768Smrg } 2537f419768Smrg#endif 254f29dbc25Smrg 255f29dbc25Smrg pGeode->FBBase = cim_fb_ptr; 256f29dbc25Smrg 257f29dbc25Smrg if (!pGeode->NoAccel) 25804007ebaSmrg pGeode->pExa->memoryBase = pGeode->FBBase; 259f29dbc25Smrg 260f29dbc25Smrg xf86DrvMsg(index, X_INFO, "Geode LX video memory %x bytes at %p\n", 26104007ebaSmrg pGeode->FBAvail, pGeode->FBBase); 262f29dbc25Smrg 263f29dbc25Smrg return TRUE; 264f29dbc25Smrg} 265f29dbc25Smrg 266f29dbc25Smrg/* Check to see if VGA exists - we map the space and look for a 267f29dbc25Smrg signature - if it doesn't match exactly, then we assume no VGA. 268f29dbc25Smrg*/ 269f29dbc25Smrg 270f29dbc25Smrgstatic Bool 2717f419768SmrgLXCheckVGA(ScrnInfoPtr pScrni, EntityInfoPtr pEnt) 272f29dbc25Smrg{ 2737f419768Smrg#ifndef XSERVER_LIBPCIACCESS 274f29dbc25Smrg unsigned char *ptr; 275f29dbc25Smrg const char *vgasig = "IBM VGA Compatible"; 276f29dbc25Smrg int ret; 277f29dbc25Smrg 278f29dbc25Smrg ptr = 27904007ebaSmrg xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, 0xC001E, 28004007ebaSmrg strlen(vgasig)); 281f29dbc25Smrg 282f29dbc25Smrg if (ptr == NULL) 28304007ebaSmrg return FALSE; 284f29dbc25Smrg 285f29dbc25Smrg ret = memcmp(ptr, vgasig, strlen(vgasig)); 286f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) ptr, strlen(vgasig)); 287f29dbc25Smrg 288f29dbc25Smrg return ret ? FALSE : TRUE; 2897f419768Smrg#else 2907f419768Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pEnt->index); 2917f419768Smrg 2927f419768Smrg return pci_device_is_boot_vga(pci); 2937f419768Smrg#endif 294f29dbc25Smrg} 295f29dbc25Smrg 296f29dbc25Smrgstatic Bool 297f29dbc25SmrgLXCrtcResize(ScrnInfoPtr pScrni, int width, int height) 298f29dbc25Smrg{ 299f29dbc25Smrg return TRUE; 300f29dbc25Smrg} 301f29dbc25Smrg 302f29dbc25Smrgstatic const xf86CrtcConfigFuncsRec lx_xf86crtc_config_funcs = { 303f29dbc25Smrg LXCrtcResize, 304f29dbc25Smrg}; 305f29dbc25Smrg 306f29dbc25Smrgstatic Bool 307f29dbc25SmrgLXPreInit(ScrnInfoPtr pScrni, int flags) 308f29dbc25Smrg{ 309f29dbc25Smrg GeodePtr pGeode; 310f29dbc25Smrg EntityInfoPtr pEnt; 311f29dbc25Smrg OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; 312f29dbc25Smrg rgb defaultWeight = { 0, 0, 0 }; 3133406bd8eSmrg const char *s; 314f29dbc25Smrg 315f29dbc25Smrg if (pScrni->numEntities != 1) 31604007ebaSmrg return FALSE; 317f29dbc25Smrg 318f29dbc25Smrg pEnt = xf86GetEntityInfo(pScrni->entityList[0]); 319f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 320f29dbc25Smrg if (pEnt->resources) 32104007ebaSmrg return FALSE; 322f29dbc25Smrg#endif 323f29dbc25Smrg if (flags & PROBE_DETECT) { 32404007ebaSmrg GeodeProbeDDC(pScrni, pEnt->index); 32504007ebaSmrg return TRUE; 326f29dbc25Smrg } 327f29dbc25Smrg 32804007ebaSmrg pGeode = pScrni->driverPrivate = xnfcalloc(1, sizeof(GeodeRec)); 329f29dbc25Smrg 330f29dbc25Smrg if (pGeode == NULL) 33104007ebaSmrg return FALSE; 332f29dbc25Smrg 3337f419768Smrg pGeode->useVGA = LXCheckVGA(pScrni, pEnt); 334f29dbc25Smrg pGeode->VGAActive = FALSE; 335f29dbc25Smrg pGeode->pEnt = pEnt; 336f29dbc25Smrg 337f29dbc25Smrg if (pGeode->useVGA) { 33804007ebaSmrg if (!xf86LoadSubModule(pScrni, "vgahw") || !vgaHWGetHWRec(pScrni)) 33904007ebaSmrg pGeode->useVGA = FALSE; 34004007ebaSmrg else 34104007ebaSmrg vgaHWSetStdFuncs(VGAHWPTR(pScrni)); 342f29dbc25Smrg 34304007ebaSmrg pGeode->vesa = calloc(1, sizeof(VESARec)); 344f29dbc25Smrg } 345f29dbc25Smrg 346f29dbc25Smrg cim_rdmsr = LXReadMSR; 347f29dbc25Smrg cim_wrmsr = LXWriteMSR; 348f29dbc25Smrg 349f29dbc25Smrg /* Set up the Cimarron MSR tables */ 350f29dbc25Smrg msr_init_table(); 351f29dbc25Smrg 352f29dbc25Smrg /* By default, we support panel and CRT - the config file should 353f29dbc25Smrg * disable the ones we don't want 354f29dbc25Smrg */ 355f29dbc25Smrg 356f29dbc25Smrg pGeode->Output = OUTPUT_PANEL | OUTPUT_CRT; 357f29dbc25Smrg 358f29dbc25Smrg /* Fill in the monitor information */ 359f29dbc25Smrg pScrni->monitor = pScrni->confScreen->monitor; 360f29dbc25Smrg 361f29dbc25Smrg if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) 36204007ebaSmrg return FALSE; 363f29dbc25Smrg 364f29dbc25Smrg switch (pScrni->depth) { 365f29dbc25Smrg case 8: 36604007ebaSmrg pScrni->rgbBits = 8; 367f29dbc25Smrg case 16: 368f29dbc25Smrg case 24: 369f29dbc25Smrg case 32: 37004007ebaSmrg break; 371f29dbc25Smrg default: 37204007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 37304007ebaSmrg "The driver does not support %d as a depth.\n", 37404007ebaSmrg pScrni->depth); 37504007ebaSmrg return FALSE; 376f29dbc25Smrg } 377f29dbc25Smrg 378f29dbc25Smrg xf86PrintDepthBpp(pScrni); 379f29dbc25Smrg 380f29dbc25Smrg if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) 38104007ebaSmrg return FALSE; 382f29dbc25Smrg 383f29dbc25Smrg if (!xf86SetDefaultVisual(pScrni, -1)) 38404007ebaSmrg return FALSE; 385f29dbc25Smrg 386f29dbc25Smrg /* 387f29dbc25Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 388f29dbc25Smrg * here. 389f29dbc25Smrg */ 390f29dbc25Smrg { 39104007ebaSmrg Gamma zeros = { 0.0, 0.0, 0.0 }; 392f29dbc25Smrg 39304007ebaSmrg if (!xf86SetGamma(pScrni, zeros)) { 39404007ebaSmrg return FALSE; 39504007ebaSmrg } 396f29dbc25Smrg } 397f29dbc25Smrg 398f29dbc25Smrg pScrni->progClock = TRUE; 399f29dbc25Smrg xf86CollectOptions(pScrni, NULL); 400f29dbc25Smrg xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); 401f29dbc25Smrg 402f29dbc25Smrg /* Set up our various options that may get reversed as we go on */ 403f29dbc25Smrg 404f29dbc25Smrg pGeode->tryHWCursor = TRUE; 405f29dbc25Smrg pGeode->tryCompression = TRUE; 406f29dbc25Smrg 407f29dbc25Smrg /* Protect against old versions of EXA */ 408f29dbc25Smrg 409f29dbc25Smrg#if (EXA_VERSION_MAJOR < 2) 410f29dbc25Smrg pGeode->NoAccel = TRUE; 411f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41204007ebaSmrg "*** This driver was compiled with EXA version %d\n"); 413f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41404007ebaSmrg "*** we need version 2 or greater\n"); 415f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41604007ebaSmrg "*** All accelerations are being turned off.\n"); 417f29dbc25Smrg#else 418f29dbc25Smrg pGeode->NoAccel = FALSE; 419f29dbc25Smrg#endif 420f29dbc25Smrg 421f29dbc25Smrg pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; 422f29dbc25Smrg 42304007ebaSmrg xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, &pGeode->tryHWCursor); 424f29dbc25Smrg 425f29dbc25Smrg if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_FBSIZE, 42604007ebaSmrg (int *) &(pGeode->FBAvail))) 42704007ebaSmrg pGeode->FBAvail = 0; 428f29dbc25Smrg 429f29dbc25Smrg /* For compatability - allow SWCursor too */ 430f29dbc25Smrg 431f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) 43204007ebaSmrg pGeode->tryHWCursor = FALSE; 433f29dbc25Smrg 434f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) 43504007ebaSmrg pGeode->tryCompression = FALSE; 436f29dbc25Smrg 437f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) 43804007ebaSmrg pGeode->NoAccel = TRUE; 439f29dbc25Smrg 440f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 441f29dbc25Smrg 442f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { 443f29dbc25Smrg 44404007ebaSmrg if (!xf86NameCmp(s, "LEFT")) 44504007ebaSmrg pGeode->rotation = RR_Rotate_90; 44604007ebaSmrg else if (!xf86NameCmp(s, "INVERT")) 44704007ebaSmrg pGeode->rotation = RR_Rotate_180; 44804007ebaSmrg else if (!xf86NameCmp(s, "CCW")) 44904007ebaSmrg pGeode->rotation = RR_Rotate_270; 45004007ebaSmrg else 45104007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Invalid rotation %s.\n", s); 452f29dbc25Smrg } 453f29dbc25Smrg 454f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, LX_OPTION_EXA_SCRATCH_BFRSZ, 45504007ebaSmrg (int *) &(pGeode->exaBfrSz)); 456f29dbc25Smrg 457f29dbc25Smrg if (pGeode->exaBfrSz <= 0) 45804007ebaSmrg pGeode->exaBfrSz = 0; 459f29dbc25Smrg 460f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) { 46104007ebaSmrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOPANEL, FALSE)) 46204007ebaSmrg pGeode->Output &= ~OUTPUT_PANEL; 463f29dbc25Smrg } 464f29dbc25Smrg 465f29dbc25Smrg /* Panel detection code - 466f29dbc25Smrg * 1. See if an OLPC DCON is attached - we can make some assumptions 467f29dbc25Smrg * about the panel if so. 468f29dbc25Smrg * 2. Use panel mode specified in the config 469f29dbc25Smrg * 3. "Autodetect" the panel through VSA 470f29dbc25Smrg */ 471f29dbc25Smrg 472f29dbc25Smrg if (dcon_init(pScrni)) { 47304007ebaSmrg pGeode->Output = OUTPUT_PANEL | OUTPUT_DCON; 47404007ebaSmrg } 47504007ebaSmrg else if (pGeode->Output & OUTPUT_PANEL) { 47604007ebaSmrg char *pmode = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_MODE); 477f29dbc25Smrg 47804007ebaSmrg if (pmode != NULL) 47904007ebaSmrg pGeode->panelMode = LXGetManualPanelMode(pmode); 480f29dbc25Smrg 48104007ebaSmrg if (pGeode->panelMode == NULL) 48204007ebaSmrg pGeode->panelMode = LXGetLegacyPanelMode(pScrni); 483f29dbc25Smrg 48404007ebaSmrg if (pGeode->panelMode == NULL) 48504007ebaSmrg pGeode->Output &= ~OUTPUT_PANEL; 486f29dbc25Smrg } 487f29dbc25Smrg 488f29dbc25Smrg /* Default to turn scaling on for panels */ 489f29dbc25Smrg 490f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 49104007ebaSmrg pGeode->Scale = TRUE; 492f29dbc25Smrg 493f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); 494f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", 49504007ebaSmrg pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); 496f29dbc25Smrg 497f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " PANEL: %s\n", 49804007ebaSmrg pGeode->Output & OUTPUT_PANEL ? "YES" : "NO"); 499f29dbc25Smrg 500f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " DCON: %s\n", 50104007ebaSmrg pGeode->Output & OUTPUT_DCON ? "YES" : "NO"); 502f29dbc25Smrg 503f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " VGA: %s\n", 50404007ebaSmrg pGeode->useVGA ? "YES" : "NO"); 505f29dbc25Smrg 506f29dbc25Smrg /* Set up VGA */ 507f29dbc25Smrg 508f29dbc25Smrg if (pGeode->useVGA) { 50904007ebaSmrg VESARec *pVesa; 510f29dbc25Smrg 51104007ebaSmrg if (!xf86LoadSubModule(pScrni, "int10")) 51204007ebaSmrg return FALSE; 513f29dbc25Smrg 51404007ebaSmrg pVesa = pGeode->vesa; 515f29dbc25Smrg 51604007ebaSmrg if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { 51704007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 51804007ebaSmrg "Unable to initialize 1NT10 support\n"); 51904007ebaSmrg pGeode->useVGA = FALSE; 52004007ebaSmrg } 521f29dbc25Smrg } 522f29dbc25Smrg 523f29dbc25Smrg /* Read the amount of framebuffer memory */ 524f29dbc25Smrg /* First try to read it from the framebuffer, and if that fails, 525f29dbc25Smrg * do it the legacy way 526f29dbc25Smrg */ 527f29dbc25Smrg 528f29dbc25Smrg if (pGeode->FBAvail == 0) { 52904007ebaSmrg if (GeodeGetSizeFromFB(&pGeode->FBAvail)) { 53004007ebaSmrg unsigned long value; 531f29dbc25Smrg 53204007ebaSmrg cim_outw(0xAC1C, 0xFC53); 53304007ebaSmrg cim_outw(0xAC1C, 0x0200); 534f29dbc25Smrg 53504007ebaSmrg value = (unsigned long) (cim_inw(0xAC1E)) & 0xFE; 53604007ebaSmrg pGeode->FBAvail = value << 20; 53704007ebaSmrg } 538f29dbc25Smrg } 539f29dbc25Smrg 540f29dbc25Smrg pScrni->fbOffset = 0; 541f29dbc25Smrg 542f29dbc25Smrg if (pGeode->pEnt->device->videoRam == 0) 54304007ebaSmrg pScrni->videoRam = pGeode->FBAvail / 1024; 544f29dbc25Smrg else { 54504007ebaSmrg pScrni->videoRam = pGeode->pEnt->device->videoRam; 54604007ebaSmrg pGeode->FBAvail = pScrni->videoRam << 10; 547f29dbc25Smrg } 548f29dbc25Smrg 549f29dbc25Smrg /* If we have <= 16Mb of memory then compression is going 550f29dbc25Smrg to hurt - so warn and disable */ 551f29dbc25Smrg 55204007ebaSmrg if (pGeode->tryCompression && pGeode->FBAvail <= 0x1000000) { 55304007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 55404007ebaSmrg "%x bytes of video memory is less then optimal\n", 55504007ebaSmrg pGeode->FBAvail); 55604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 55704007ebaSmrg "when compression is on. Disabling compression.\n"); 55804007ebaSmrg pGeode->tryCompression = FALSE; 559f29dbc25Smrg } 560f29dbc25Smrg 561f29dbc25Smrg /* Carve out some memory for the command buffer */ 562f29dbc25Smrg 563f29dbc25Smrg pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; 564f29dbc25Smrg pGeode->FBAvail -= CIM_CMD_BFR_SZ; 565f29dbc25Smrg 566f29dbc25Smrg pGeode->CmdBfrOffset = pGeode->FBAvail; 567f29dbc25Smrg 568f29dbc25Smrg /* Allocate a a CRTC config structure */ 569f29dbc25Smrg xf86CrtcConfigInit(pScrni, &lx_xf86crtc_config_funcs); 570f29dbc25Smrg 571f29dbc25Smrg /* Set up the GPU CRTC */ 572f29dbc25Smrg LXSetupCrtc(pScrni); 573f29dbc25Smrg 574f29dbc25Smrg xf86CrtcSetSizeRange(pScrni, 320, 200, LX_MAX_WIDTH, LX_MAX_HEIGHT); 575f29dbc25Smrg 576f29dbc25Smrg /* Setup the output */ 577f29dbc25Smrg LXSetupOutput(pScrni); 578f29dbc25Smrg 579f29dbc25Smrg if (!xf86InitialConfiguration(pScrni, FALSE)) { 58004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes.\n"); 58104007ebaSmrg return FALSE; 582f29dbc25Smrg } 583f29dbc25Smrg 584f29dbc25Smrg xf86PrintModes(pScrni); 585f29dbc25Smrg 586f29dbc25Smrg pScrni->currentMode = pScrni->modes; 587f29dbc25Smrg 588f29dbc25Smrg pGeode->Pitch = LXCalcPitch(pScrni); 589f29dbc25Smrg 590f29dbc25Smrg xf86SetDpi(pScrni, 0, 0); 591f29dbc25Smrg 592f29dbc25Smrg /* Load the modules we'll need */ 593f29dbc25Smrg 594f29dbc25Smrg if (xf86LoadSubModule(pScrni, "fb") == NULL) { 59504007ebaSmrg return FALSE; 596f29dbc25Smrg } 597f29dbc25Smrg 598f29dbc25Smrg if (!pGeode->NoAccel) { 59904007ebaSmrg if (!xf86LoadSubModule(pScrni, "exa")) 60004007ebaSmrg return FALSE; 601f29dbc25Smrg } 602f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 603f29dbc25Smrg if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { 60404007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 60504007ebaSmrg "Couldn't register the resources.\n"); 60604007ebaSmrg return FALSE; 607f29dbc25Smrg } 608f29dbc25Smrg#endif 609f29dbc25Smrg return TRUE; 610f29dbc25Smrg} 611f29dbc25Smrg 612f29dbc25Smrgstatic void 613f29dbc25SmrgLXRestore(ScrnInfoPtr pScrni) 614f29dbc25Smrg{ 615f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 616f29dbc25Smrg 617f29dbc25Smrg if (pGeode->useVGA) { 61804007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 619f29dbc25Smrg 62004007ebaSmrg vgaHWProtect(pScrni, TRUE); 62104007ebaSmrg vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); 62204007ebaSmrg vgaHWProtect(pScrni, FALSE); 623f29dbc25Smrg } 624f29dbc25Smrg} 625f29dbc25Smrg 626f29dbc25Smrgstatic Bool 627f29dbc25SmrgLXUnmapMem(ScrnInfoPtr pScrni) 628f29dbc25Smrg{ 629f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 630f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); 631f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); 63204007ebaSmrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vid_ptr, LX_VID_REG_SIZE); 63304007ebaSmrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, LX_VIP_REG_SIZE); 6347f419768Smrg 6357f419768Smrg xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000); 636f29dbc25Smrg#else 637f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 638f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 639f29dbc25Smrg 640f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_gp_ptr, LX_GP_REG_SIZE); 641f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vg_ptr, LX_VG_REG_SIZE); 642f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vid_ptr, LX_VID_REG_SIZE); 643f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vip_ptr, LX_VIP_REG_SIZE); 644f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_fb_ptr, pGeode->FBAvail + CIM_CMD_BFR_SZ); 645f29dbc25Smrg 6467f419768Smrg munmap(XpressROMPtr, 0x10000); 6477f419768Smrg#endif 648f29dbc25Smrg 649f29dbc25Smrg return TRUE; 650f29dbc25Smrg} 651f29dbc25Smrg 652f29dbc25Smrg/* These should be correctly accounted for rotation */ 653f29dbc25Smrg 654f29dbc25Smrgvoid 65504007ebaSmrgLXAdjustFrame(ADJUST_FRAME_ARGS_DECL) 656f29dbc25Smrg{ 65704007ebaSmrg SCRN_INFO_PTR(arg); 658f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 659f29dbc25Smrg 660f29dbc25Smrg unsigned long offset; 661f29dbc25Smrg 662f29dbc25Smrg offset = (y * pGeode->Pitch); 663f29dbc25Smrg offset += x * (pScrni->bitsPerPixel >> 3); 664f29dbc25Smrg 665f29dbc25Smrg vg_set_display_offset(offset); 666f29dbc25Smrg} 667f29dbc25Smrg 668f29dbc25Smrgstatic Bool 66904007ebaSmrgLXSwitchMode(SWITCH_MODE_ARGS_DECL) 670f29dbc25Smrg{ 67104007ebaSmrg SCRN_INFO_PTR(arg); 672f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 673f29dbc25Smrg 674f29dbc25Smrg /* Set the new mode */ 675f29dbc25Smrg return xf86SetSingleMode(pScrni, pMode, pGeode->rotation); 676f29dbc25Smrg} 677f29dbc25Smrg 678f29dbc25Smrgstatic void 679f29dbc25SmrgLXLeaveGraphics(ScrnInfoPtr pScrni) 680f29dbc25Smrg{ 681f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 682f29dbc25Smrg VG_PANNING_COORDINATES panning; 683f29dbc25Smrg 684f29dbc25Smrg gp_wait_until_idle(); 685f29dbc25Smrg 686f29dbc25Smrg vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), 68704007ebaSmrg pGeode->FBcimdisplaytiming.wBpp); 688f29dbc25Smrg 689f29dbc25Smrg vg_set_compression_enable(0); 690f29dbc25Smrg 691f29dbc25Smrg /* Restore the previous Compression state */ 692f29dbc25Smrg if (pGeode->FBCompressionEnable) { 69304007ebaSmrg vg_configure_compression(&(pGeode->FBCBData)); 69404007ebaSmrg vg_set_compression_enable(1); 695f29dbc25Smrg } 696f29dbc25Smrg 697f29dbc25Smrg vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); 698f29dbc25Smrg vg_set_display_offset(pGeode->FBDisplayOffset); 699f29dbc25Smrg 700f29dbc25Smrg /* Restore Cursor */ 701f29dbc25Smrg vg_set_cursor_position(pGeode->FBCursor.cursor_x, 70204007ebaSmrg pGeode->FBCursor.cursor_y, &panning); 703f29dbc25Smrg 704f29dbc25Smrg LXRestore(pScrni); 705f29dbc25Smrg 706f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 70704007ebaSmrg pGeode->vesa->pInt->num = 0x10; 70804007ebaSmrg pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; 70904007ebaSmrg pGeode->vesa->pInt->bx = 0; 71004007ebaSmrg xf86ExecX86int10(pGeode->vesa->pInt); 71104007ebaSmrg vg_delay_milliseconds(3); 712f29dbc25Smrg } 713f29dbc25Smrg 714f29dbc25Smrg pScrni->vtSema = FALSE; 715f29dbc25Smrg} 716f29dbc25Smrg 717f29dbc25Smrgstatic Bool 71804007ebaSmrgLXCloseScreen(CLOSE_SCREEN_ARGS_DECL) 719f29dbc25Smrg{ 72004007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 721f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 722f29dbc25Smrg 723f29dbc25Smrg if (pScrni->vtSema) 72404007ebaSmrg LXLeaveGraphics(pScrni); 725f29dbc25Smrg 726f29dbc25Smrg if (pGeode->pExa) { 72704007ebaSmrg exaDriverFini(pScrn); 72804007ebaSmrg free(pGeode->pExa); 72904007ebaSmrg pGeode->pExa = NULL; 730f29dbc25Smrg } 731f29dbc25Smrg 732f29dbc25Smrg /* Unmap the offscreen allocations */ 733f29dbc25Smrg GeodeCloseOffscreen(pScrni); 734f29dbc25Smrg 735f29dbc25Smrg LXUnmapMem(pScrni); 736f29dbc25Smrg 737f29dbc25Smrg if (pGeode->useVGA) 73804007ebaSmrg vgaHWUnmapMem(pScrni); 739f29dbc25Smrg 740f29dbc25Smrg pScrni->PointerMoved = pGeode->PointerMoved; 741f29dbc25Smrg pScrn->CloseScreen = pGeode->CloseScreen; 742f29dbc25Smrg 743f29dbc25Smrg if (pScrn->CloseScreen) 74404007ebaSmrg return (*pScrn->CloseScreen) (CLOSE_SCREEN_ARGS); 745f29dbc25Smrg 746f29dbc25Smrg return TRUE; 747f29dbc25Smrg} 748f29dbc25Smrg 749f29dbc25Smrgstatic Bool 750f29dbc25SmrgLXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 751f29dbc25Smrg{ 752f29dbc25Smrg int bpp; 753f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 754f29dbc25Smrg 755f29dbc25Smrg pGeode->VGAActive = gu3_get_vga_active(); 756f29dbc25Smrg 757f29dbc25Smrg gp_wait_until_idle(); 758f29dbc25Smrg 759f29dbc25Smrg vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, 76004007ebaSmrg &bpp); 761f29dbc25Smrg 762f29dbc25Smrg pGeode->FBcimdisplaytiming.wBpp = bpp; 763f29dbc25Smrg pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); 764f29dbc25Smrg 765f29dbc25Smrg pGeode->FBDisplayOffset = vg_get_display_offset(); 766f29dbc25Smrg 767f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 76804007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 769f29dbc25Smrg 77004007ebaSmrg pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); 771f29dbc25Smrg } 772f29dbc25Smrg 773f29dbc25Smrg pGeode->FBCompressionEnable = vg_get_compression_enable(); 774f29dbc25Smrg vg_get_compression_info(&(pGeode->FBCBData)); 775f29dbc25Smrg 776f29dbc25Smrg /* Save Cursor offset */ 777f29dbc25Smrg vg_get_cursor_info(&pGeode->FBCursor); 778f29dbc25Smrg 779f29dbc25Smrg /* Turn off the VGA */ 780f29dbc25Smrg 781f29dbc25Smrg if (pGeode->useVGA) { 78204007ebaSmrg unsigned short sequencer; 78304007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 784f29dbc25Smrg 78504007ebaSmrg /* Unlock VGA registers */ 78604007ebaSmrg vgaHWUnlock(pvgaHW); 787f29dbc25Smrg 78804007ebaSmrg /* Save the current state and setup the current mode */ 78904007ebaSmrg vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); 790f29dbc25Smrg 79104007ebaSmrg /* DISABLE VGA SEQUENCER */ 79204007ebaSmrg /* This allows the VGA state machine to terminate. We must delay */ 79304007ebaSmrg /* such that there are no pending MBUS requests. */ 794f29dbc25Smrg 79504007ebaSmrg cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); 79604007ebaSmrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 79704007ebaSmrg sequencer |= DC3_CLK_MODE_SCREEN_OFF; 79804007ebaSmrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 799f29dbc25Smrg 80004007ebaSmrg vg_delay_milliseconds(1); 801f29dbc25Smrg 80204007ebaSmrg /* BLANK THE VGA DISPLAY */ 80304007ebaSmrg cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); 80404007ebaSmrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 80504007ebaSmrg sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; 80604007ebaSmrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 807f29dbc25Smrg 80804007ebaSmrg vg_delay_milliseconds(1); 809f29dbc25Smrg } 810f29dbc25Smrg 811f29dbc25Smrg /* Clear the framebuffer */ 812f29dbc25Smrg memset(pGeode->FBBase, 0, pGeode->displaySize); 813f29dbc25Smrg 814f29dbc25Smrg /* Set the modes */ 815f29dbc25Smrg if (!xf86SetDesiredModes(pScrni)) 81604007ebaSmrg return FALSE; 817f29dbc25Smrg 818f29dbc25Smrg pScrni->vtSema = TRUE; 819f29dbc25Smrg 820f29dbc25Smrg return TRUE; 821f29dbc25Smrg} 822f29dbc25Smrg 823f29dbc25Smrgstatic void 824f29dbc25SmrgLXLoadPalette(ScrnInfoPtr pScrni, 82504007ebaSmrg int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) 826f29dbc25Smrg{ 827f29dbc25Smrg int i, index, color; 828f29dbc25Smrg 829f29dbc25Smrg for (i = 0; i < numColors; i++) { 83004007ebaSmrg index = indizes[i] & 0xFF; 83104007ebaSmrg color = (((unsigned long) (colors[index].red & 0xFF)) << 16) | 83204007ebaSmrg (((unsigned long) (colors[index].green & 0xFF)) << 8) | 83304007ebaSmrg ((unsigned long) (colors[index].blue & 0xFF)); 834f29dbc25Smrg 83504007ebaSmrg vg_set_display_palette_entry(index, color); 836f29dbc25Smrg } 837f29dbc25Smrg} 838f29dbc25Smrg 839f29dbc25Smrgstatic Bool 84004007ebaSmrgLXScreenInit(SCREEN_INIT_ARGS_DECL) 841f29dbc25Smrg{ 84204007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 843f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 844f29dbc25Smrg int ret; 845f29dbc25Smrg unsigned int dwidth; 846f29dbc25Smrg 847f29dbc25Smrg pGeode->starting = TRUE; 848f29dbc25Smrg 849f29dbc25Smrg /* If we are using VGA then go ahead and map the memory */ 850f29dbc25Smrg 851f29dbc25Smrg if (pGeode->useVGA) { 852f29dbc25Smrg 85304007ebaSmrg if (!vgaHWMapMem(pScrni)) 85404007ebaSmrg return FALSE; 855f29dbc25Smrg 85604007ebaSmrg vgaHWGetIOBase(VGAHWPTR(pScrni)); 857f29dbc25Smrg } 858f29dbc25Smrg 859f29dbc25Smrg if (!pGeode->NoAccel) { 860f29dbc25Smrg 86104007ebaSmrg pGeode->pExa = exaDriverAlloc(); 862f29dbc25Smrg 86304007ebaSmrg if (pGeode->pExa) { 864f29dbc25Smrg 86504007ebaSmrg pGeode->pExa->memoryBase = 0; 86604007ebaSmrg pGeode->pExa->memorySize = 0; 867f29dbc25Smrg 86804007ebaSmrg pGeode->pExa->pixmapOffsetAlign = 32; 86904007ebaSmrg pGeode->pExa->pixmapPitchAlign = 32; 87004007ebaSmrg pGeode->pExa->flags = EXA_OFFSCREEN_PIXMAPS; 87104007ebaSmrg pGeode->pExa->maxX = LX_MAX_WIDTH - 1; 87204007ebaSmrg pGeode->pExa->maxY = LX_MAX_HEIGHT - 1; 87304007ebaSmrg } 87404007ebaSmrg else { 87504007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 87604007ebaSmrg "Couldn't allocate the EXA structure.\n"); 87704007ebaSmrg pGeode->NoAccel = TRUE; 87804007ebaSmrg } 879f29dbc25Smrg } 880f29dbc25Smrg 881f29dbc25Smrg /* Map the memory here before doing anything else */ 882f29dbc25Smrg 883f29dbc25Smrg if (!LXMapMem(pScrni)) 88404007ebaSmrg return FALSE; 885f29dbc25Smrg 886f29dbc25Smrg LXInitOffscreen(pScrni); 887f29dbc25Smrg 888f29dbc25Smrg /* XXX FIXME - Take down any of the structures on failure? */ 889f29dbc25Smrg if (!LXEnterGraphics(pScrn, pScrni)) 89004007ebaSmrg return FALSE; 891f29dbc25Smrg 892f29dbc25Smrg miClearVisualTypes(); 893f29dbc25Smrg 894f29dbc25Smrg /* XXX Again - take down anything? */ 895f29dbc25Smrg 896f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 89704007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 89804007ebaSmrg TrueColorMask, pScrni->rgbBits, 89904007ebaSmrg pScrni->defaultVisual)) { 90004007ebaSmrg return FALSE; 90104007ebaSmrg } 90204007ebaSmrg } 90304007ebaSmrg else { 90404007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 90504007ebaSmrg miGetDefaultVisualMask(pScrni->depth), 90604007ebaSmrg pScrni->rgbBits, pScrni->defaultVisual)) { 90704007ebaSmrg return FALSE; 90804007ebaSmrg } 909f29dbc25Smrg } 910f29dbc25Smrg 911f29dbc25Smrg miSetPixmapDepths(); 912f29dbc25Smrg 913f29dbc25Smrg if (pScrni->virtualX > pScrni->displayWidth) 91404007ebaSmrg pScrni->displayWidth = pScrni->virtualX; 915f29dbc25Smrg 916f29dbc25Smrg /* Point at the visible area to start */ 917f29dbc25Smrg 918f29dbc25Smrg /* fbScreenInit assumes that the stride is display width * 919f29dbc25Smrg * bytes per pixel. If compression is on, then our stride might 920f29dbc25Smrg * be completely different, so we divide the pitch by the 921f29dbc25Smrg * bytes per pixel to fake fbScreenInit into doing the right thing */ 922f29dbc25Smrg 923f29dbc25Smrg dwidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 924f29dbc25Smrg 925f29dbc25Smrg ret = fbScreenInit(pScrn, pGeode->FBBase, 92604007ebaSmrg pScrni->virtualX, pScrni->virtualY, 92704007ebaSmrg pScrni->xDpi, pScrni->yDpi, dwidth, 92804007ebaSmrg pScrni->bitsPerPixel); 929f29dbc25Smrg 930f29dbc25Smrg if (!ret) 93104007ebaSmrg return FALSE; 932f29dbc25Smrg 933f29dbc25Smrg xf86SetBlackWhitePixels(pScrn); 934f29dbc25Smrg 935f29dbc25Smrg /* Set up the color ordering */ 936f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 93704007ebaSmrg VisualPtr visual = pScrn->visuals + pScrn->numVisuals; 93804007ebaSmrg 93904007ebaSmrg while (--visual >= pScrn->visuals) { 94004007ebaSmrg if ((visual->class | DynamicClass) == DirectColor) { 94104007ebaSmrg visual->offsetRed = pScrni->offset.red; 94204007ebaSmrg visual->offsetGreen = pScrni->offset.green; 94304007ebaSmrg visual->offsetBlue = pScrni->offset.blue; 94404007ebaSmrg visual->redMask = pScrni->mask.red; 94504007ebaSmrg visual->greenMask = pScrni->mask.green; 94604007ebaSmrg visual->blueMask = pScrni->mask.blue; 94704007ebaSmrg } 94804007ebaSmrg } 949f29dbc25Smrg } 950f29dbc25Smrg 951f29dbc25Smrg /* Must follow the color ordering */ 952f29dbc25Smrg fbPictureInit(pScrn, 0, 0); 953f29dbc25Smrg 954f29dbc25Smrg if (!pGeode->NoAccel) 95504007ebaSmrg pGeode->NoAccel = LXExaInit(pScrn) ? FALSE : TRUE; 956f29dbc25Smrg 957f29dbc25Smrg xf86SetBackingStore(pScrn); 958f29dbc25Smrg 959f29dbc25Smrg /* Set up the soft cursor */ 960f29dbc25Smrg miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); 961f29dbc25Smrg 962f29dbc25Smrg /* Set up the HW cursor - must follow the soft cursor init */ 963f29dbc25Smrg 964f29dbc25Smrg if (pGeode->tryHWCursor) { 96504007ebaSmrg if (!LXCursorInit(pScrn)) 96604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 96704007ebaSmrg "Hardware cursor initialization failed.\n"); 968f29dbc25Smrg } 969f29dbc25Smrg 970f29dbc25Smrg /* Set up the color map */ 971f29dbc25Smrg 972f29dbc25Smrg if (!miCreateDefColormap(pScrn)) 97304007ebaSmrg return FALSE; 974f29dbc25Smrg 975f29dbc25Smrg if (pScrni->bitsPerPixel == 8) { 97604007ebaSmrg /* Must follow initialization of the default colormap */ 97704007ebaSmrg 97804007ebaSmrg if (!xf86HandleColormaps(pScrn, 256, 8, 97904007ebaSmrg LXLoadPalette, NULL, 98004007ebaSmrg CMAP_PALETTED_TRUECOLOR | 98104007ebaSmrg CMAP_RELOAD_ON_MODE_SWITCH)) { 98204007ebaSmrg return FALSE; 98304007ebaSmrg } 984f29dbc25Smrg } 985f29dbc25Smrg xf86DPMSInit(pScrn, xf86DPMSSet, 0); 986f29dbc25Smrg 987f29dbc25Smrg LXInitVideo(pScrn); 988f29dbc25Smrg 989f29dbc25Smrg pGeode->PointerMoved = pScrni->PointerMoved; 990f29dbc25Smrg pScrni->PointerMoved = GeodePointerMoved; 991f29dbc25Smrg 992f29dbc25Smrg pGeode->CloseScreen = pScrn->CloseScreen; 993f29dbc25Smrg pScrn->CloseScreen = LXCloseScreen; 994f29dbc25Smrg pScrn->SaveScreen = LXSaveScreen; 995f29dbc25Smrg 996f29dbc25Smrg if (!xf86CrtcScreenInit(pScrn)) { 99704007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "CRTCScreenInit failed.\n"); 99804007ebaSmrg return FALSE; 999f29dbc25Smrg } 1000f29dbc25Smrg 1001f29dbc25Smrg if (serverGeneration == 1) 100204007ebaSmrg xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); 1003f29dbc25Smrg 1004f29dbc25Smrg pGeode->starting = FALSE; 1005f29dbc25Smrg 1006f29dbc25Smrg return TRUE; 1007f29dbc25Smrg} 1008f29dbc25Smrg 1009f29dbc25Smrgstatic int 101004007ebaSmrgLXValidMode(VALID_MODE_ARGS_DECL) 1011f29dbc25Smrg{ 1012f29dbc25Smrg return MODE_OK; 1013f29dbc25Smrg} 1014f29dbc25Smrg 1015f29dbc25Smrgstatic Bool 101604007ebaSmrgLXEnterVT(VT_FUNC_ARGS_DECL) 1017f29dbc25Smrg{ 101804007ebaSmrg SCRN_INFO_PTR(arg); 101904007ebaSmrg return LXEnterGraphics(NULL, pScrni); 1020f29dbc25Smrg} 1021f29dbc25Smrg 1022f29dbc25Smrgstatic void 102304007ebaSmrgLXLeaveVT(VT_FUNC_ARGS_DECL) 1024f29dbc25Smrg{ 102504007ebaSmrg SCRN_INFO_PTR(arg); 1026f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1027f29dbc25Smrg 1028f29dbc25Smrg pGeode->PrevDisplayOffset = vg_get_display_offset(); 1029f29dbc25Smrg LXLeaveGraphics(pScrni); 1030f29dbc25Smrg} 1031f29dbc25Smrg 1032f29dbc25Smrgvoid 1033f29dbc25SmrgLXSetupChipsetFPtr(ScrnInfoPtr pScrn) 1034f29dbc25Smrg{ 1035f29dbc25Smrg pScrn->PreInit = LXPreInit; 1036f29dbc25Smrg pScrn->ScreenInit = LXScreenInit; 1037f29dbc25Smrg pScrn->SwitchMode = LXSwitchMode; 1038f29dbc25Smrg pScrn->AdjustFrame = LXAdjustFrame; 1039f29dbc25Smrg pScrn->EnterVT = LXEnterVT; 1040f29dbc25Smrg pScrn->LeaveVT = LXLeaveVT; 1041f29dbc25Smrg pScrn->FreeScreen = GeodeFreeScreen; 1042f29dbc25Smrg pScrn->ValidMode = LXValidMode; 1043f29dbc25Smrg} 1044