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 4000be8644Schristos#include "xorg-server.h" 4100be8644Schristos 42f29dbc25Smrg#include "xf86.h" 43f29dbc25Smrg#include "xf86_OSproc.h" 44f29dbc25Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 45f29dbc25Smrg#include "xf86Resources.h" 46f29dbc25Smrg#endif 47f29dbc25Smrg#include "xf86i2c.h" 48f29dbc25Smrg#include "xf86Crtc.h" 49f29dbc25Smrg#include "xf86cmap.h" 50f29dbc25Smrg#include "compiler.h" 51f29dbc25Smrg#include "mipointer.h" 52f29dbc25Smrg#include "fb.h" 53f29dbc25Smrg#include "miscstruct.h" 54f29dbc25Smrg#include "micmap.h" 55f29dbc25Smrg#include "vbe.h" 56f29dbc25Smrg#include "fb.h" 57f29dbc25Smrg#include "cim_defs.h" 58f29dbc25Smrg#include "cim_regs.h" 59f29dbc25Smrg#include "geode.h" 60f29dbc25Smrg 61f29dbc25Smrg/* Bring in VGA functions */ 62f29dbc25Smrg#include "lx_vga.c" 63f29dbc25Smrg 64f29dbc25Smrg#define LX_MAX_WIDTH 1940 65f29dbc25Smrg#define LX_MAX_HEIGHT 1600 66f29dbc25Smrg 67f29dbc25Smrg/* Size of the register blocks */ 68f29dbc25Smrg 69f29dbc25Smrg#define LX_GP_REG_SIZE 0x4000 70f29dbc25Smrg#define LX_VG_REG_SIZE 0x4000 71f29dbc25Smrg#define LX_VID_REG_SIZE 0x4000 72f29dbc25Smrg#define LX_VIP_REG_SIZE 0x4000 73f29dbc25Smrg 74f29dbc25Smrg/* Size of the Cimarron command buffer */ 75f29dbc25Smrg#define CIM_CMD_BFR_SZ 0x200000 76f29dbc25Smrg 77f29dbc25Smrgextern OptionInfoRec LX_GeodeOptions[]; 78f29dbc25Smrg 79ad01e365Sjoergextern unsigned char *XpressROMPtr; 80f29dbc25Smrg 81f29dbc25Smrgstatic Bool 82f29dbc25SmrgLXSaveScreen(ScreenPtr pScrn, int mode) 83f29dbc25Smrg{ 8404007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 85f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 86f29dbc25Smrg 87f29dbc25Smrg if (pGeode->useVGA && !pScrni->vtSema) 8804007ebaSmrg return vgaHWSaveScreen(pScrn, mode); 89f29dbc25Smrg 90f29dbc25Smrg return TRUE; 91f29dbc25Smrg} 92f29dbc25Smrg 93f29dbc25Smrg/* This is an overly complex MSR read mechanism */ 94f29dbc25Smrg 95f29dbc25Smrg/* From Cimarron - the VSAII read/write methods - we use these as fallback */ 96f29dbc25Smrg 97f29dbc25Smrg#define LX_MSR_READ(adr,lo,hi) \ 98f29dbc25Smrg __asm__ __volatile__( \ 99f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 100f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 101f29dbc25Smrg " out %%eax,%%dx\n" \ 102f29dbc25Smrg " add $2,%%dl\n" \ 103f29dbc25Smrg " in %%dx, %%ax" \ 104f29dbc25Smrg : "=a" (lo), "=d" (hi) \ 105f29dbc25Smrg : "c" (adr)) 106f29dbc25Smrg 107f29dbc25Smrg#define LX_MSR_WRITE(adr,low,high) \ 108f29dbc25Smrg { int d0, d1, d2, d3, d4; \ 109f29dbc25Smrg __asm__ __volatile__( \ 110f29dbc25Smrg " push %%ebx\n" \ 111f29dbc25Smrg " mov $0x0AC1C, %%edx\n" \ 112f29dbc25Smrg " mov $0xFC530007, %%eax\n" \ 113f29dbc25Smrg " out %%eax,%%dx\n" \ 114f29dbc25Smrg " add $2,%%dl\n" \ 115f29dbc25Smrg " mov %6, %%ebx\n" \ 116f29dbc25Smrg " mov %7, %0\n" \ 117f29dbc25Smrg " mov %5, %3\n" \ 118f29dbc25Smrg " xor %2, %2\n" \ 119f29dbc25Smrg " xor %1, %1\n" \ 120f29dbc25Smrg " out %%ax, %%dx\n" \ 121f29dbc25Smrg " pop %%ebx\n" \ 122f29dbc25Smrg : "=a"(d0),"=&D"(d1),"=&S"(d2), \ 123f29dbc25Smrg "=c"(d3),"=d"(d4) \ 124f29dbc25Smrg : "1"(adr),"2"(high),"3"(low)); \ 125f29dbc25Smrg } 126f29dbc25Smrg 127f29dbc25Smrgstatic void 128f29dbc25SmrgLXReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) 129f29dbc25Smrg{ 130f29dbc25Smrg if (GeodeReadMSR(addr, lo, hi) == -1) { 13104007ebaSmrg unsigned int l, h; 132f29dbc25Smrg 13304007ebaSmrg LX_MSR_READ(addr, l, h); 13404007ebaSmrg *lo = l; 13504007ebaSmrg *hi = h; 136f29dbc25Smrg } 137f29dbc25Smrg} 138f29dbc25Smrg 139f29dbc25Smrgstatic void 140f29dbc25SmrgLXWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) 141f29dbc25Smrg{ 142f29dbc25Smrg if (GeodeWriteMSR(addr, lo, hi) == -1) 14304007ebaSmrg LX_MSR_WRITE(addr, lo, hi); 144f29dbc25Smrg} 145f29dbc25Smrg 146f29dbc25Smrgstatic unsigned int 147f29dbc25SmrgLXCalcPitch(ScrnInfoPtr pScrni) 148f29dbc25Smrg{ 149f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 150f29dbc25Smrg 151f29dbc25Smrg if (pGeode->tryCompression) 15204007ebaSmrg return GeodeCalculatePitchBytes(pScrni->virtualX, pScrni->bitsPerPixel); 153f29dbc25Smrg else 15404007ebaSmrg return ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3); 155f29dbc25Smrg} 156f29dbc25Smrg 157f29dbc25Smrg#ifdef XSERVER_LIBPCIACCESS 158f29dbc25Smrgstatic inline void * 159f29dbc25Smrgmap_pci_mem(ScrnInfoPtr pScrni, int vram, 16004007ebaSmrg struct pci_device *dev, int bar, int size) 161f29dbc25Smrg{ 162f29dbc25Smrg void *ptr; 163f29dbc25Smrg int map_size = size ? size : dev->regions[bar].size; 164f29dbc25Smrg 165f29dbc25Smrg int err = pci_device_map_range(dev, 16604007ebaSmrg dev->regions[bar].base_addr, 16704007ebaSmrg map_size, 16804007ebaSmrg PCI_DEV_MAP_FLAG_WRITABLE | 16904007ebaSmrg (vram ? PCI_DEV_MAP_FLAG_WRITE_COMBINE : 0), 1707f419768Smrg &ptr); 171f29dbc25Smrg 172f29dbc25Smrg if (err) 17304007ebaSmrg return NULL; 174f29dbc25Smrg return ptr; 175f29dbc25Smrg} 176f29dbc25Smrg 177f29dbc25Smrgstatic inline int 178f29dbc25Smrgunmap_pci_mem(ScrnInfoPtr pScrni, struct pci_device *dev, void *ptr, int size) 179f29dbc25Smrg{ 180f29dbc25Smrg return pci_device_unmap_range(dev, ptr, size); 181f29dbc25Smrg} 182f29dbc25Smrg 183f29dbc25Smrg#endif 184f29dbc25Smrg 185f29dbc25Smrgstatic Bool 186f29dbc25SmrgLXMapMem(ScrnInfoPtr pScrni) 187f29dbc25Smrg{ 188f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 189f29dbc25Smrg int index = pScrni->scrnIndex; 190f29dbc25Smrg unsigned long cmd_bfr_phys; 191f29dbc25Smrg 192f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 193f29dbc25Smrg 194f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 195f29dbc25Smrg PCITAG tag; 196f29dbc25Smrg 197f29dbc25Smrg tag = pciTag(pci->bus, pci->device, pci->func); 198f29dbc25Smrg 19904007ebaSmrg cim_gp_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 20004007ebaSmrg tag, pci->memBase[1], 20104007ebaSmrg LX_GP_REG_SIZE); 202f29dbc25Smrg 20304007ebaSmrg cim_vg_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 20404007ebaSmrg tag, pci->memBase[2], 20504007ebaSmrg LX_VG_REG_SIZE); 206f29dbc25Smrg 20704007ebaSmrg cim_vid_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 20804007ebaSmrg tag, pci->memBase[3], 20904007ebaSmrg LX_VID_REG_SIZE); 210f29dbc25Smrg 21104007ebaSmrg cim_vip_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_MMIO, 21204007ebaSmrg tag, pci->memBase[4], 21304007ebaSmrg LX_VIP_REG_SIZE); 214f29dbc25Smrg 21504007ebaSmrg cim_fb_ptr = (unsigned char *) xf86MapPciMem(index, VIDMEM_FRAMEBUFFER, 21604007ebaSmrg tag, pci->memBase[0], 21704007ebaSmrg pGeode->FBAvail + 21804007ebaSmrg CIM_CMD_BFR_SZ); 219f29dbc25Smrg#else 220f29dbc25Smrg cim_gp_ptr = map_pci_mem(pScrni, 0, pci, 1, LX_GP_REG_SIZE); 221f29dbc25Smrg cim_vg_ptr = map_pci_mem(pScrni, 0, pci, 2, LX_VG_REG_SIZE); 222f29dbc25Smrg cim_vid_ptr = map_pci_mem(pScrni, 0, pci, 3, LX_VID_REG_SIZE); 223f29dbc25Smrg cim_vip_ptr = map_pci_mem(pScrni, 0, pci, 4, LX_VIP_REG_SIZE); 224f29dbc25Smrg cim_fb_ptr = 22504007ebaSmrg map_pci_mem(pScrni, 1, pci, 0, pGeode->FBAvail + CIM_CMD_BFR_SZ); 226f29dbc25Smrg#endif 227f29dbc25Smrg 228f29dbc25Smrg if (pScrni->memPhysBase == 0) 22904007ebaSmrg pScrni->memPhysBase = PCI_REGION_BASE(pci, 0, REGION_MEM); 230f29dbc25Smrg 231f29dbc25Smrg cmd_bfr_phys = PCI_REGION_BASE(pci, 0, REGION_MEM) + pGeode->CmdBfrOffset; 232f29dbc25Smrg cim_cmd_base_ptr = cim_fb_ptr + pGeode->CmdBfrOffset; 233f29dbc25Smrg 234f29dbc25Smrg if (!cim_gp_ptr || !cim_vg_ptr || !cim_vid_ptr || !cim_fb_ptr || 23504007ebaSmrg !cim_vip_ptr) 23604007ebaSmrg return FALSE; 237f29dbc25Smrg 238f29dbc25Smrg gp_set_frame_buffer_base(PCI_REGION_BASE(pci, 0, REGION_MEM), 23904007ebaSmrg pGeode->FBAvail); 240f29dbc25Smrg gp_set_command_buffer_base(cmd_bfr_phys, 0, pGeode->CmdBfrSize); 241f29dbc25Smrg 2427f419768Smrg#ifndef XSERVER_LIBPCIACCESS 243f29dbc25Smrg XpressROMPtr = xf86MapVidMem(index, VIDMEM_FRAMEBUFFER, 0xF0000, 0x10000); 2447f419768Smrg#else 2457f419768Smrg { 2467f419768Smrg int fd = open("/dev/mem", O_RDWR); 2477f419768Smrg if (fd < 0) { 2487f419768Smrg xf86DrvMsg(index, X_ERROR, "Failed to open /dev/mem: %m\n"); 2497f419768Smrg return FALSE; 2507f419768Smrg } 2517f419768Smrg XpressROMPtr = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xF0000); 2527f419768Smrg close(fd); 2537f419768Smrg } 2547f419768Smrg#endif 255f29dbc25Smrg 256f29dbc25Smrg pGeode->FBBase = cim_fb_ptr; 257f29dbc25Smrg 258f29dbc25Smrg if (!pGeode->NoAccel) 25904007ebaSmrg pGeode->pExa->memoryBase = pGeode->FBBase; 260f29dbc25Smrg 261f29dbc25Smrg xf86DrvMsg(index, X_INFO, "Geode LX video memory %x bytes at %p\n", 26204007ebaSmrg pGeode->FBAvail, pGeode->FBBase); 263f29dbc25Smrg 264f29dbc25Smrg return TRUE; 265f29dbc25Smrg} 266f29dbc25Smrg 267f29dbc25Smrg/* Check to see if VGA exists - we map the space and look for a 268f29dbc25Smrg signature - if it doesn't match exactly, then we assume no VGA. 269f29dbc25Smrg*/ 270f29dbc25Smrg 271f29dbc25Smrgstatic Bool 2727f419768SmrgLXCheckVGA(ScrnInfoPtr pScrni, EntityInfoPtr pEnt) 273f29dbc25Smrg{ 2747f419768Smrg#ifndef XSERVER_LIBPCIACCESS 275f29dbc25Smrg unsigned char *ptr; 276f29dbc25Smrg const char *vgasig = "IBM VGA Compatible"; 277f29dbc25Smrg int ret; 278f29dbc25Smrg 279f29dbc25Smrg ptr = 28004007ebaSmrg xf86MapVidMem(pScrni->scrnIndex, VIDMEM_FRAMEBUFFER, 0xC001E, 28104007ebaSmrg strlen(vgasig)); 282f29dbc25Smrg 283f29dbc25Smrg if (ptr == NULL) 28404007ebaSmrg return FALSE; 285f29dbc25Smrg 286f29dbc25Smrg ret = memcmp(ptr, vgasig, strlen(vgasig)); 287f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) ptr, strlen(vgasig)); 288f29dbc25Smrg 289f29dbc25Smrg return ret ? FALSE : TRUE; 2907f419768Smrg#else 2917f419768Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pEnt->index); 2927f419768Smrg 2937f419768Smrg return pci_device_is_boot_vga(pci); 2947f419768Smrg#endif 295f29dbc25Smrg} 296f29dbc25Smrg 297f29dbc25Smrgstatic Bool 298f29dbc25SmrgLXCrtcResize(ScrnInfoPtr pScrni, int width, int height) 299f29dbc25Smrg{ 300f29dbc25Smrg return TRUE; 301f29dbc25Smrg} 302f29dbc25Smrg 303f29dbc25Smrgstatic const xf86CrtcConfigFuncsRec lx_xf86crtc_config_funcs = { 304f29dbc25Smrg LXCrtcResize, 305f29dbc25Smrg}; 306f29dbc25Smrg 307f29dbc25Smrgstatic Bool 308f29dbc25SmrgLXPreInit(ScrnInfoPtr pScrni, int flags) 309f29dbc25Smrg{ 310f29dbc25Smrg GeodePtr pGeode; 311f29dbc25Smrg EntityInfoPtr pEnt; 312f29dbc25Smrg OptionInfoRec *GeodeOptions = &LX_GeodeOptions[0]; 313f29dbc25Smrg rgb defaultWeight = { 0, 0, 0 }; 3143406bd8eSmrg const char *s; 315f29dbc25Smrg 316f29dbc25Smrg if (pScrni->numEntities != 1) 31704007ebaSmrg return FALSE; 318f29dbc25Smrg 319f29dbc25Smrg pEnt = xf86GetEntityInfo(pScrni->entityList[0]); 320f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 321f29dbc25Smrg if (pEnt->resources) 32204007ebaSmrg return FALSE; 323f29dbc25Smrg#endif 324f29dbc25Smrg if (flags & PROBE_DETECT) { 32504007ebaSmrg GeodeProbeDDC(pScrni, pEnt->index); 32604007ebaSmrg return TRUE; 327f29dbc25Smrg } 328f29dbc25Smrg 32904007ebaSmrg pGeode = pScrni->driverPrivate = xnfcalloc(1, sizeof(GeodeRec)); 330f29dbc25Smrg 331f29dbc25Smrg if (pGeode == NULL) 33204007ebaSmrg return FALSE; 333f29dbc25Smrg 3347f419768Smrg pGeode->useVGA = LXCheckVGA(pScrni, pEnt); 335f29dbc25Smrg pGeode->VGAActive = FALSE; 336f29dbc25Smrg pGeode->pEnt = pEnt; 337f29dbc25Smrg 338f29dbc25Smrg if (pGeode->useVGA) { 33904007ebaSmrg if (!xf86LoadSubModule(pScrni, "vgahw") || !vgaHWGetHWRec(pScrni)) 34004007ebaSmrg pGeode->useVGA = FALSE; 34104007ebaSmrg else 34204007ebaSmrg vgaHWSetStdFuncs(VGAHWPTR(pScrni)); 343f29dbc25Smrg 34404007ebaSmrg pGeode->vesa = calloc(1, sizeof(VESARec)); 345f29dbc25Smrg } 346f29dbc25Smrg 347f29dbc25Smrg cim_rdmsr = LXReadMSR; 348f29dbc25Smrg cim_wrmsr = LXWriteMSR; 349f29dbc25Smrg 350f29dbc25Smrg /* Set up the Cimarron MSR tables */ 351f29dbc25Smrg msr_init_table(); 352f29dbc25Smrg 353f29dbc25Smrg /* By default, we support panel and CRT - the config file should 354f29dbc25Smrg * disable the ones we don't want 355f29dbc25Smrg */ 356f29dbc25Smrg 357f29dbc25Smrg pGeode->Output = OUTPUT_PANEL | OUTPUT_CRT; 358f29dbc25Smrg 359f29dbc25Smrg /* Fill in the monitor information */ 360f29dbc25Smrg pScrni->monitor = pScrni->confScreen->monitor; 361f29dbc25Smrg 362f29dbc25Smrg if (!xf86SetDepthBpp(pScrni, 16, 16, 16, Support24bppFb | Support32bppFb)) 36304007ebaSmrg return FALSE; 364f29dbc25Smrg 365f29dbc25Smrg switch (pScrni->depth) { 366f29dbc25Smrg case 8: 36704007ebaSmrg pScrni->rgbBits = 8; 368f29dbc25Smrg case 16: 369f29dbc25Smrg case 24: 370f29dbc25Smrg case 32: 37104007ebaSmrg break; 372f29dbc25Smrg default: 37304007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 37404007ebaSmrg "The driver does not support %d as a depth.\n", 37504007ebaSmrg pScrni->depth); 37604007ebaSmrg return FALSE; 377f29dbc25Smrg } 378f29dbc25Smrg 379f29dbc25Smrg xf86PrintDepthBpp(pScrni); 380f29dbc25Smrg 381f29dbc25Smrg if (!xf86SetWeight(pScrni, defaultWeight, defaultWeight)) 38204007ebaSmrg return FALSE; 383f29dbc25Smrg 384f29dbc25Smrg if (!xf86SetDefaultVisual(pScrni, -1)) 38504007ebaSmrg return FALSE; 386f29dbc25Smrg 387f29dbc25Smrg /* 388f29dbc25Smrg * If the driver can do gamma correction, it should call xf86SetGamma() 389f29dbc25Smrg * here. 390f29dbc25Smrg */ 391f29dbc25Smrg { 39204007ebaSmrg Gamma zeros = { 0.0, 0.0, 0.0 }; 393f29dbc25Smrg 39404007ebaSmrg if (!xf86SetGamma(pScrni, zeros)) { 39504007ebaSmrg return FALSE; 39604007ebaSmrg } 397f29dbc25Smrg } 398f29dbc25Smrg 399f29dbc25Smrg pScrni->progClock = TRUE; 400f29dbc25Smrg xf86CollectOptions(pScrni, NULL); 401f29dbc25Smrg xf86ProcessOptions(pScrni->scrnIndex, pScrni->options, GeodeOptions); 402f29dbc25Smrg 403f29dbc25Smrg /* Set up our various options that may get reversed as we go on */ 404f29dbc25Smrg 405f29dbc25Smrg pGeode->tryHWCursor = TRUE; 406f29dbc25Smrg pGeode->tryCompression = TRUE; 407f29dbc25Smrg 408f29dbc25Smrg /* Protect against old versions of EXA */ 409f29dbc25Smrg 410f29dbc25Smrg#if (EXA_VERSION_MAJOR < 2) 411f29dbc25Smrg pGeode->NoAccel = TRUE; 412f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41304007ebaSmrg "*** This driver was compiled with EXA version %d\n"); 414f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41504007ebaSmrg "*** we need version 2 or greater\n"); 416f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 41704007ebaSmrg "*** All accelerations are being turned off.\n"); 418f29dbc25Smrg#else 419f29dbc25Smrg pGeode->NoAccel = FALSE; 420f29dbc25Smrg#endif 421f29dbc25Smrg 422f29dbc25Smrg pGeode->exaBfrSz = DEFAULT_EXA_SCRATCH_BFRSZ; 423f29dbc25Smrg 42404007ebaSmrg xf86GetOptValBool(GeodeOptions, LX_OPTION_HW_CURSOR, &pGeode->tryHWCursor); 425f29dbc25Smrg 426f29dbc25Smrg if (!xf86GetOptValInteger(GeodeOptions, LX_OPTION_FBSIZE, 42704007ebaSmrg (int *) &(pGeode->FBAvail))) 42804007ebaSmrg pGeode->FBAvail = 0; 429f29dbc25Smrg 430c744f008Smrg /* For compatibility - allow SWCursor too */ 431f29dbc25Smrg 432f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_SW_CURSOR, FALSE)) 43304007ebaSmrg pGeode->tryHWCursor = FALSE; 434f29dbc25Smrg 435f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOCOMPRESSION, FALSE)) 43604007ebaSmrg pGeode->tryCompression = FALSE; 437f29dbc25Smrg 438f29dbc25Smrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOACCEL, FALSE)) 43904007ebaSmrg pGeode->NoAccel = TRUE; 440f29dbc25Smrg 441f29dbc25Smrg pGeode->rotation = RR_Rotate_0; 442f29dbc25Smrg 443f29dbc25Smrg if ((s = xf86GetOptValString(GeodeOptions, LX_OPTION_ROTATE))) { 444f29dbc25Smrg 44504007ebaSmrg if (!xf86NameCmp(s, "LEFT")) 44604007ebaSmrg pGeode->rotation = RR_Rotate_90; 44704007ebaSmrg else if (!xf86NameCmp(s, "INVERT")) 44804007ebaSmrg pGeode->rotation = RR_Rotate_180; 44904007ebaSmrg else if (!xf86NameCmp(s, "CCW")) 45004007ebaSmrg pGeode->rotation = RR_Rotate_270; 45104007ebaSmrg else 45204007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Invalid rotation %s.\n", s); 453f29dbc25Smrg } 454f29dbc25Smrg 455f29dbc25Smrg xf86GetOptValInteger(GeodeOptions, LX_OPTION_EXA_SCRATCH_BFRSZ, 45604007ebaSmrg (int *) &(pGeode->exaBfrSz)); 457f29dbc25Smrg 458f29dbc25Smrg if (pGeode->exaBfrSz <= 0) 45904007ebaSmrg pGeode->exaBfrSz = 0; 460f29dbc25Smrg 461f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) { 46204007ebaSmrg if (xf86ReturnOptValBool(GeodeOptions, LX_OPTION_NOPANEL, FALSE)) 46304007ebaSmrg pGeode->Output &= ~OUTPUT_PANEL; 464f29dbc25Smrg } 465f29dbc25Smrg 466f29dbc25Smrg /* Panel detection code - 467f29dbc25Smrg * 1. See if an OLPC DCON is attached - we can make some assumptions 468f29dbc25Smrg * about the panel if so. 469f29dbc25Smrg * 2. Use panel mode specified in the config 470f29dbc25Smrg * 3. "Autodetect" the panel through VSA 471f29dbc25Smrg */ 472f29dbc25Smrg 473f29dbc25Smrg if (dcon_init(pScrni)) { 47404007ebaSmrg pGeode->Output = OUTPUT_PANEL | OUTPUT_DCON; 47504007ebaSmrg } 47604007ebaSmrg else if (pGeode->Output & OUTPUT_PANEL) { 477861b9feeSmrg const char *pmode = xf86GetOptValString(GeodeOptions, LX_OPTION_PANEL_MODE); 478f29dbc25Smrg 47904007ebaSmrg if (pmode != NULL) 48004007ebaSmrg pGeode->panelMode = LXGetManualPanelMode(pmode); 481f29dbc25Smrg 48204007ebaSmrg if (pGeode->panelMode == NULL) 48304007ebaSmrg pGeode->panelMode = LXGetLegacyPanelMode(pScrni); 484f29dbc25Smrg 48504007ebaSmrg if (pGeode->panelMode == NULL) 48604007ebaSmrg pGeode->Output &= ~OUTPUT_PANEL; 487f29dbc25Smrg } 488f29dbc25Smrg 489f29dbc25Smrg /* Default to turn scaling on for panels */ 490f29dbc25Smrg 491f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 49204007ebaSmrg pGeode->Scale = TRUE; 493f29dbc25Smrg 494f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, "LX output options:\n"); 495f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " CRT: %s\n", 49604007ebaSmrg pGeode->Output & OUTPUT_CRT ? "YES" : "NO"); 497f29dbc25Smrg 498f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " PANEL: %s\n", 49904007ebaSmrg pGeode->Output & OUTPUT_PANEL ? "YES" : "NO"); 500f29dbc25Smrg 501f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " DCON: %s\n", 50204007ebaSmrg pGeode->Output & OUTPUT_DCON ? "YES" : "NO"); 503f29dbc25Smrg 504f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, " VGA: %s\n", 50504007ebaSmrg pGeode->useVGA ? "YES" : "NO"); 506f29dbc25Smrg 507f29dbc25Smrg /* Set up VGA */ 508f29dbc25Smrg 509f29dbc25Smrg if (pGeode->useVGA) { 51004007ebaSmrg VESARec *pVesa; 511f29dbc25Smrg 51204007ebaSmrg if (!xf86LoadSubModule(pScrni, "int10")) 51304007ebaSmrg return FALSE; 514f29dbc25Smrg 51504007ebaSmrg pVesa = pGeode->vesa; 516f29dbc25Smrg 51704007ebaSmrg if ((pVesa->pInt = xf86InitInt10(pGeode->pEnt->index)) == NULL) { 51804007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 51904007ebaSmrg "Unable to initialize 1NT10 support\n"); 52004007ebaSmrg pGeode->useVGA = FALSE; 52104007ebaSmrg } 522f29dbc25Smrg } 523f29dbc25Smrg 524f29dbc25Smrg /* Read the amount of framebuffer memory */ 525f29dbc25Smrg /* First try to read it from the framebuffer, and if that fails, 526f29dbc25Smrg * do it the legacy way 527f29dbc25Smrg */ 528f29dbc25Smrg 529f29dbc25Smrg if (pGeode->FBAvail == 0) { 53004007ebaSmrg if (GeodeGetSizeFromFB(&pGeode->FBAvail)) { 53104007ebaSmrg unsigned long value; 532f29dbc25Smrg 53304007ebaSmrg cim_outw(0xAC1C, 0xFC53); 53404007ebaSmrg cim_outw(0xAC1C, 0x0200); 535f29dbc25Smrg 53604007ebaSmrg value = (unsigned long) (cim_inw(0xAC1E)) & 0xFE; 53704007ebaSmrg pGeode->FBAvail = value << 20; 53804007ebaSmrg } 539f29dbc25Smrg } 540f29dbc25Smrg 541f29dbc25Smrg pScrni->fbOffset = 0; 542f29dbc25Smrg 543f29dbc25Smrg if (pGeode->pEnt->device->videoRam == 0) 54404007ebaSmrg pScrni->videoRam = pGeode->FBAvail / 1024; 545f29dbc25Smrg else { 54604007ebaSmrg pScrni->videoRam = pGeode->pEnt->device->videoRam; 54704007ebaSmrg pGeode->FBAvail = pScrni->videoRam << 10; 548f29dbc25Smrg } 549f29dbc25Smrg 550f29dbc25Smrg /* If we have <= 16Mb of memory then compression is going 551f29dbc25Smrg to hurt - so warn and disable */ 552f29dbc25Smrg 55304007ebaSmrg if (pGeode->tryCompression && pGeode->FBAvail <= 0x1000000) { 55404007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 55504007ebaSmrg "%x bytes of video memory is less then optimal\n", 55604007ebaSmrg pGeode->FBAvail); 55704007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 55804007ebaSmrg "when compression is on. Disabling compression.\n"); 55904007ebaSmrg pGeode->tryCompression = FALSE; 560f29dbc25Smrg } 561f29dbc25Smrg 562f29dbc25Smrg /* Carve out some memory for the command buffer */ 563f29dbc25Smrg 564f29dbc25Smrg pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; 565f29dbc25Smrg pGeode->FBAvail -= CIM_CMD_BFR_SZ; 566f29dbc25Smrg 567f29dbc25Smrg pGeode->CmdBfrOffset = pGeode->FBAvail; 568f29dbc25Smrg 569f29dbc25Smrg /* Allocate a a CRTC config structure */ 570f29dbc25Smrg xf86CrtcConfigInit(pScrni, &lx_xf86crtc_config_funcs); 571f29dbc25Smrg 572f29dbc25Smrg /* Set up the GPU CRTC */ 573f29dbc25Smrg LXSetupCrtc(pScrni); 574f29dbc25Smrg 575f29dbc25Smrg xf86CrtcSetSizeRange(pScrni, 320, 200, LX_MAX_WIDTH, LX_MAX_HEIGHT); 576f29dbc25Smrg 577f29dbc25Smrg /* Setup the output */ 578f29dbc25Smrg LXSetupOutput(pScrni); 579f29dbc25Smrg 580f29dbc25Smrg if (!xf86InitialConfiguration(pScrni, FALSE)) { 58104007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "No valid modes.\n"); 58204007ebaSmrg return FALSE; 583f29dbc25Smrg } 584f29dbc25Smrg 585f29dbc25Smrg xf86PrintModes(pScrni); 586f29dbc25Smrg 587f29dbc25Smrg pScrni->currentMode = pScrni->modes; 588f29dbc25Smrg 589f29dbc25Smrg pGeode->Pitch = LXCalcPitch(pScrni); 590f29dbc25Smrg 591f29dbc25Smrg xf86SetDpi(pScrni, 0, 0); 592f29dbc25Smrg 593f29dbc25Smrg /* Load the modules we'll need */ 594f29dbc25Smrg 595f29dbc25Smrg if (xf86LoadSubModule(pScrni, "fb") == NULL) { 59604007ebaSmrg return FALSE; 597f29dbc25Smrg } 598f29dbc25Smrg 599f29dbc25Smrg if (!pGeode->NoAccel) { 60004007ebaSmrg if (!xf86LoadSubModule(pScrni, "exa")) 60104007ebaSmrg return FALSE; 602f29dbc25Smrg } 603f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 604f29dbc25Smrg if (xf86RegisterResources(pGeode->pEnt->index, NULL, ResExclusive)) { 60504007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 60604007ebaSmrg "Couldn't register the resources.\n"); 60704007ebaSmrg return FALSE; 608f29dbc25Smrg } 609f29dbc25Smrg#endif 610f29dbc25Smrg return TRUE; 611f29dbc25Smrg} 612f29dbc25Smrg 613f29dbc25Smrgstatic void 614f29dbc25SmrgLXRestore(ScrnInfoPtr pScrni) 615f29dbc25Smrg{ 616f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 617f29dbc25Smrg 618f29dbc25Smrg if (pGeode->useVGA) { 61904007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 620f29dbc25Smrg 62104007ebaSmrg vgaHWProtect(pScrni, TRUE); 62204007ebaSmrg vgaHWRestore(pScrni, &pvgaHW->SavedReg, VGA_SR_ALL); 62304007ebaSmrg vgaHWProtect(pScrni, FALSE); 624f29dbc25Smrg } 625f29dbc25Smrg} 626f29dbc25Smrg 627f29dbc25Smrgstatic Bool 628f29dbc25SmrgLXUnmapMem(ScrnInfoPtr pScrni) 629f29dbc25Smrg{ 630f29dbc25Smrg#ifndef XSERVER_LIBPCIACCESS 631f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); 632f29dbc25Smrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); 63304007ebaSmrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vid_ptr, LX_VID_REG_SIZE); 63404007ebaSmrg xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vip_ptr, LX_VIP_REG_SIZE); 6357f419768Smrg 6367f419768Smrg xf86UnMapVidMem(pScrni->scrnIndex, XpressROMPtr, 0x10000); 637f29dbc25Smrg#else 638f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 639f29dbc25Smrg pciVideoPtr pci = xf86GetPciInfoForEntity(pGeode->pEnt->index); 640f29dbc25Smrg 641f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_gp_ptr, LX_GP_REG_SIZE); 642f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vg_ptr, LX_VG_REG_SIZE); 643f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vid_ptr, LX_VID_REG_SIZE); 644f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_vip_ptr, LX_VIP_REG_SIZE); 645f29dbc25Smrg unmap_pci_mem(pScrni, pci, cim_fb_ptr, pGeode->FBAvail + CIM_CMD_BFR_SZ); 646f29dbc25Smrg 6477f419768Smrg munmap(XpressROMPtr, 0x10000); 6487f419768Smrg#endif 649f29dbc25Smrg 650f29dbc25Smrg return TRUE; 651f29dbc25Smrg} 652f29dbc25Smrg 653f29dbc25Smrg/* These should be correctly accounted for rotation */ 654f29dbc25Smrg 655f29dbc25Smrgvoid 65604007ebaSmrgLXAdjustFrame(ADJUST_FRAME_ARGS_DECL) 657f29dbc25Smrg{ 65804007ebaSmrg SCRN_INFO_PTR(arg); 659f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 660f29dbc25Smrg 661f29dbc25Smrg unsigned long offset; 662f29dbc25Smrg 663f29dbc25Smrg offset = (y * pGeode->Pitch); 664f29dbc25Smrg offset += x * (pScrni->bitsPerPixel >> 3); 665f29dbc25Smrg 666f29dbc25Smrg vg_set_display_offset(offset); 667f29dbc25Smrg} 668f29dbc25Smrg 669f29dbc25Smrgstatic Bool 67004007ebaSmrgLXSwitchMode(SWITCH_MODE_ARGS_DECL) 671f29dbc25Smrg{ 67204007ebaSmrg SCRN_INFO_PTR(arg); 673f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 674f29dbc25Smrg 675f29dbc25Smrg /* Set the new mode */ 676f29dbc25Smrg return xf86SetSingleMode(pScrni, pMode, pGeode->rotation); 677f29dbc25Smrg} 678f29dbc25Smrg 679f29dbc25Smrgstatic void 680f29dbc25SmrgLXLeaveGraphics(ScrnInfoPtr pScrni) 681f29dbc25Smrg{ 682f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 683f29dbc25Smrg VG_PANNING_COORDINATES panning; 684f29dbc25Smrg 685f29dbc25Smrg gp_wait_until_idle(); 686f29dbc25Smrg 68744802259Smrg lx_disable_dac_power(pScrni, DF_CRT_DISABLE); 68844802259Smrg 689f29dbc25Smrg vg_set_custom_mode(&(pGeode->FBcimdisplaytiming.vgDisplayMode), 69004007ebaSmrg pGeode->FBcimdisplaytiming.wBpp); 691f29dbc25Smrg 692f29dbc25Smrg vg_set_compression_enable(0); 693f29dbc25Smrg 694f29dbc25Smrg /* Restore the previous Compression state */ 695f29dbc25Smrg if (pGeode->FBCompressionEnable) { 69604007ebaSmrg vg_configure_compression(&(pGeode->FBCBData)); 69704007ebaSmrg vg_set_compression_enable(1); 698f29dbc25Smrg } 699f29dbc25Smrg 700f29dbc25Smrg vg_set_display_pitch(pGeode->FBcimdisplaytiming.wPitch); 701f29dbc25Smrg vg_set_display_offset(pGeode->FBDisplayOffset); 702f29dbc25Smrg 703f29dbc25Smrg /* Restore Cursor */ 704f29dbc25Smrg vg_set_cursor_position(pGeode->FBCursor.cursor_x, 70504007ebaSmrg pGeode->FBCursor.cursor_y, &panning); 706f29dbc25Smrg 707f29dbc25Smrg LXRestore(pScrni); 708f29dbc25Smrg 709f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 71004007ebaSmrg pGeode->vesa->pInt->num = 0x10; 71104007ebaSmrg pGeode->vesa->pInt->ax = 0x0 | pGeode->FBBIOSMode; 71204007ebaSmrg pGeode->vesa->pInt->bx = 0; 71304007ebaSmrg xf86ExecX86int10(pGeode->vesa->pInt); 71404007ebaSmrg vg_delay_milliseconds(3); 715f29dbc25Smrg } 716f29dbc25Smrg 71744802259Smrg lx_enable_dac_power(pScrni, 1); 718f29dbc25Smrg pScrni->vtSema = FALSE; 719f29dbc25Smrg} 720f29dbc25Smrg 721f29dbc25Smrgstatic Bool 72204007ebaSmrgLXCloseScreen(CLOSE_SCREEN_ARGS_DECL) 723f29dbc25Smrg{ 72404007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 725f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 726f29dbc25Smrg 727f29dbc25Smrg if (pScrni->vtSema) 72804007ebaSmrg LXLeaveGraphics(pScrni); 729f29dbc25Smrg 730f29dbc25Smrg if (pGeode->pExa) { 73104007ebaSmrg exaDriverFini(pScrn); 73204007ebaSmrg free(pGeode->pExa); 73304007ebaSmrg pGeode->pExa = NULL; 734f29dbc25Smrg } 735f29dbc25Smrg 736f29dbc25Smrg /* Unmap the offscreen allocations */ 737f29dbc25Smrg GeodeCloseOffscreen(pScrni); 738f29dbc25Smrg 739f29dbc25Smrg LXUnmapMem(pScrni); 740f29dbc25Smrg 741f29dbc25Smrg if (pGeode->useVGA) 74204007ebaSmrg vgaHWUnmapMem(pScrni); 743f29dbc25Smrg 744f29dbc25Smrg pScrni->PointerMoved = pGeode->PointerMoved; 745f29dbc25Smrg pScrn->CloseScreen = pGeode->CloseScreen; 746f29dbc25Smrg 747f29dbc25Smrg if (pScrn->CloseScreen) 74804007ebaSmrg return (*pScrn->CloseScreen) (CLOSE_SCREEN_ARGS); 749f29dbc25Smrg 750f29dbc25Smrg return TRUE; 751f29dbc25Smrg} 752f29dbc25Smrg 753f29dbc25Smrgstatic Bool 754f29dbc25SmrgLXEnterGraphics(ScreenPtr pScrn, ScrnInfoPtr pScrni) 755f29dbc25Smrg{ 756f29dbc25Smrg int bpp; 757f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 758f29dbc25Smrg 759f29dbc25Smrg pGeode->VGAActive = gu3_get_vga_active(); 760f29dbc25Smrg 761f29dbc25Smrg gp_wait_until_idle(); 762f29dbc25Smrg 763f29dbc25Smrg vg_get_current_display_mode(&pGeode->FBcimdisplaytiming.vgDisplayMode, 76404007ebaSmrg &bpp); 765f29dbc25Smrg 766f29dbc25Smrg pGeode->FBcimdisplaytiming.wBpp = bpp; 767f29dbc25Smrg pGeode->FBcimdisplaytiming.wPitch = vg_get_display_pitch(); 768f29dbc25Smrg 769f29dbc25Smrg pGeode->FBDisplayOffset = vg_get_display_offset(); 770f29dbc25Smrg 771f29dbc25Smrg if (pGeode->useVGA && pGeode->VGAActive) { 77204007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 773f29dbc25Smrg 77404007ebaSmrg pGeode->FBBIOSMode = pvgaHW->readCrtc(pvgaHW, 0x040); 775f29dbc25Smrg } 776f29dbc25Smrg 777f29dbc25Smrg pGeode->FBCompressionEnable = vg_get_compression_enable(); 778f29dbc25Smrg vg_get_compression_info(&(pGeode->FBCBData)); 779f29dbc25Smrg 780f29dbc25Smrg /* Save Cursor offset */ 781f29dbc25Smrg vg_get_cursor_info(&pGeode->FBCursor); 782f29dbc25Smrg 783f29dbc25Smrg /* Turn off the VGA */ 784f29dbc25Smrg 785f29dbc25Smrg if (pGeode->useVGA) { 78604007ebaSmrg unsigned short sequencer; 78704007ebaSmrg vgaHWPtr pvgaHW = VGAHWPTR(pScrni); 788f29dbc25Smrg 78904007ebaSmrg /* Unlock VGA registers */ 79004007ebaSmrg vgaHWUnlock(pvgaHW); 791f29dbc25Smrg 79204007ebaSmrg /* Save the current state and setup the current mode */ 79304007ebaSmrg vgaHWSave(pScrni, &VGAHWPTR(pScrni)->SavedReg, VGA_SR_ALL); 794f29dbc25Smrg 79504007ebaSmrg /* DISABLE VGA SEQUENCER */ 79604007ebaSmrg /* This allows the VGA state machine to terminate. We must delay */ 79704007ebaSmrg /* such that there are no pending MBUS requests. */ 798f29dbc25Smrg 79904007ebaSmrg cim_outb(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_CLK_MODE); 80004007ebaSmrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 80104007ebaSmrg sequencer |= DC3_CLK_MODE_SCREEN_OFF; 80204007ebaSmrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 803f29dbc25Smrg 80404007ebaSmrg vg_delay_milliseconds(1); 805f29dbc25Smrg 80604007ebaSmrg /* BLANK THE VGA DISPLAY */ 80704007ebaSmrg cim_outw(DC3_SEQUENCER_INDEX, DC3_SEQUENCER_RESET); 80804007ebaSmrg sequencer = cim_inb(DC3_SEQUENCER_DATA); 80904007ebaSmrg sequencer &= ~DC3_RESET_VGA_DISP_ENABLE; 81004007ebaSmrg cim_outb(DC3_SEQUENCER_DATA, sequencer); 811f29dbc25Smrg 81204007ebaSmrg vg_delay_milliseconds(1); 813f29dbc25Smrg } 814f29dbc25Smrg 815f29dbc25Smrg /* Clear the framebuffer */ 816f29dbc25Smrg memset(pGeode->FBBase, 0, pGeode->displaySize); 817f29dbc25Smrg 818f29dbc25Smrg /* Set the modes */ 819f29dbc25Smrg if (!xf86SetDesiredModes(pScrni)) 82004007ebaSmrg return FALSE; 821f29dbc25Smrg 822f29dbc25Smrg pScrni->vtSema = TRUE; 823f29dbc25Smrg 824f29dbc25Smrg return TRUE; 825f29dbc25Smrg} 826f29dbc25Smrg 827f29dbc25Smrgstatic void 828f29dbc25SmrgLXLoadPalette(ScrnInfoPtr pScrni, 82904007ebaSmrg int numColors, int *indizes, LOCO * colors, VisualPtr pVisual) 830f29dbc25Smrg{ 831f29dbc25Smrg int i, index, color; 832f29dbc25Smrg 833f29dbc25Smrg for (i = 0; i < numColors; i++) { 83404007ebaSmrg index = indizes[i] & 0xFF; 83504007ebaSmrg color = (((unsigned long) (colors[index].red & 0xFF)) << 16) | 83604007ebaSmrg (((unsigned long) (colors[index].green & 0xFF)) << 8) | 83704007ebaSmrg ((unsigned long) (colors[index].blue & 0xFF)); 838f29dbc25Smrg 83904007ebaSmrg vg_set_display_palette_entry(index, color); 840f29dbc25Smrg } 841f29dbc25Smrg} 842f29dbc25Smrg 843f29dbc25Smrgstatic Bool 84404007ebaSmrgLXScreenInit(SCREEN_INIT_ARGS_DECL) 845f29dbc25Smrg{ 84604007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 847f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 848f29dbc25Smrg int ret; 849f29dbc25Smrg unsigned int dwidth; 850f29dbc25Smrg 851f29dbc25Smrg pGeode->starting = TRUE; 852f29dbc25Smrg 853f29dbc25Smrg /* If we are using VGA then go ahead and map the memory */ 854f29dbc25Smrg 855f29dbc25Smrg if (pGeode->useVGA) { 856f29dbc25Smrg 85704007ebaSmrg if (!vgaHWMapMem(pScrni)) 85804007ebaSmrg return FALSE; 859f29dbc25Smrg 86004007ebaSmrg vgaHWGetIOBase(VGAHWPTR(pScrni)); 861f29dbc25Smrg } 862f29dbc25Smrg 863f29dbc25Smrg if (!pGeode->NoAccel) { 864f29dbc25Smrg 86504007ebaSmrg pGeode->pExa = exaDriverAlloc(); 866f29dbc25Smrg 86704007ebaSmrg if (pGeode->pExa) { 868f29dbc25Smrg 86904007ebaSmrg pGeode->pExa->memoryBase = 0; 87004007ebaSmrg pGeode->pExa->memorySize = 0; 871f29dbc25Smrg 87204007ebaSmrg pGeode->pExa->pixmapOffsetAlign = 32; 87304007ebaSmrg pGeode->pExa->pixmapPitchAlign = 32; 87404007ebaSmrg pGeode->pExa->flags = EXA_OFFSCREEN_PIXMAPS; 87504007ebaSmrg pGeode->pExa->maxX = LX_MAX_WIDTH - 1; 87604007ebaSmrg pGeode->pExa->maxY = LX_MAX_HEIGHT - 1; 87704007ebaSmrg } 87804007ebaSmrg else { 87904007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 88004007ebaSmrg "Couldn't allocate the EXA structure.\n"); 88104007ebaSmrg pGeode->NoAccel = TRUE; 88204007ebaSmrg } 883f29dbc25Smrg } 884f29dbc25Smrg 885f29dbc25Smrg /* Map the memory here before doing anything else */ 886f29dbc25Smrg 887f29dbc25Smrg if (!LXMapMem(pScrni)) 88804007ebaSmrg return FALSE; 889f29dbc25Smrg 890f29dbc25Smrg LXInitOffscreen(pScrni); 891f29dbc25Smrg 892f29dbc25Smrg /* XXX FIXME - Take down any of the structures on failure? */ 893f29dbc25Smrg if (!LXEnterGraphics(pScrn, pScrni)) 89404007ebaSmrg return FALSE; 895f29dbc25Smrg 896f29dbc25Smrg miClearVisualTypes(); 897f29dbc25Smrg 898f29dbc25Smrg /* XXX Again - take down anything? */ 899f29dbc25Smrg 900f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 90104007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 90204007ebaSmrg TrueColorMask, pScrni->rgbBits, 90304007ebaSmrg pScrni->defaultVisual)) { 90404007ebaSmrg return FALSE; 90504007ebaSmrg } 90604007ebaSmrg } 90704007ebaSmrg else { 90804007ebaSmrg if (!miSetVisualTypes(pScrni->depth, 90904007ebaSmrg miGetDefaultVisualMask(pScrni->depth), 91004007ebaSmrg pScrni->rgbBits, pScrni->defaultVisual)) { 91104007ebaSmrg return FALSE; 91204007ebaSmrg } 913f29dbc25Smrg } 914f29dbc25Smrg 915f29dbc25Smrg miSetPixmapDepths(); 916f29dbc25Smrg 917f29dbc25Smrg if (pScrni->virtualX > pScrni->displayWidth) 91804007ebaSmrg pScrni->displayWidth = pScrni->virtualX; 919f29dbc25Smrg 920f29dbc25Smrg /* Point at the visible area to start */ 921f29dbc25Smrg 922f29dbc25Smrg /* fbScreenInit assumes that the stride is display width * 923f29dbc25Smrg * bytes per pixel. If compression is on, then our stride might 924f29dbc25Smrg * be completely different, so we divide the pitch by the 925f29dbc25Smrg * bytes per pixel to fake fbScreenInit into doing the right thing */ 926f29dbc25Smrg 927f29dbc25Smrg dwidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 928f29dbc25Smrg 929f29dbc25Smrg ret = fbScreenInit(pScrn, pGeode->FBBase, 93004007ebaSmrg pScrni->virtualX, pScrni->virtualY, 93104007ebaSmrg pScrni->xDpi, pScrni->yDpi, dwidth, 93204007ebaSmrg pScrni->bitsPerPixel); 933f29dbc25Smrg 934f29dbc25Smrg if (!ret) 93504007ebaSmrg return FALSE; 936f29dbc25Smrg 937f29dbc25Smrg xf86SetBlackWhitePixels(pScrn); 938f29dbc25Smrg 939f29dbc25Smrg /* Set up the color ordering */ 940f29dbc25Smrg if (pScrni->bitsPerPixel > 8) { 94104007ebaSmrg VisualPtr visual = pScrn->visuals + pScrn->numVisuals; 94204007ebaSmrg 94304007ebaSmrg while (--visual >= pScrn->visuals) { 94404007ebaSmrg if ((visual->class | DynamicClass) == DirectColor) { 94504007ebaSmrg visual->offsetRed = pScrni->offset.red; 94604007ebaSmrg visual->offsetGreen = pScrni->offset.green; 94704007ebaSmrg visual->offsetBlue = pScrni->offset.blue; 94804007ebaSmrg visual->redMask = pScrni->mask.red; 94904007ebaSmrg visual->greenMask = pScrni->mask.green; 95004007ebaSmrg visual->blueMask = pScrni->mask.blue; 95104007ebaSmrg } 95204007ebaSmrg } 953f29dbc25Smrg } 954f29dbc25Smrg 955f29dbc25Smrg /* Must follow the color ordering */ 956f29dbc25Smrg fbPictureInit(pScrn, 0, 0); 957f29dbc25Smrg 958f29dbc25Smrg if (!pGeode->NoAccel) 95904007ebaSmrg pGeode->NoAccel = LXExaInit(pScrn) ? FALSE : TRUE; 960f29dbc25Smrg 961f29dbc25Smrg xf86SetBackingStore(pScrn); 962f29dbc25Smrg 963f29dbc25Smrg /* Set up the soft cursor */ 964f29dbc25Smrg miDCInitialize(pScrn, xf86GetPointerScreenFuncs()); 965f29dbc25Smrg 966f29dbc25Smrg /* Set up the HW cursor - must follow the soft cursor init */ 967f29dbc25Smrg 968f29dbc25Smrg if (pGeode->tryHWCursor) { 96904007ebaSmrg if (!LXCursorInit(pScrn)) 97004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 97104007ebaSmrg "Hardware cursor initialization failed.\n"); 972f29dbc25Smrg } 973f29dbc25Smrg 974f29dbc25Smrg /* Set up the color map */ 975f29dbc25Smrg 976f29dbc25Smrg if (!miCreateDefColormap(pScrn)) 97704007ebaSmrg return FALSE; 978f29dbc25Smrg 979f29dbc25Smrg if (pScrni->bitsPerPixel == 8) { 98004007ebaSmrg /* Must follow initialization of the default colormap */ 98104007ebaSmrg 98204007ebaSmrg if (!xf86HandleColormaps(pScrn, 256, 8, 98304007ebaSmrg LXLoadPalette, NULL, 98404007ebaSmrg CMAP_PALETTED_TRUECOLOR | 98504007ebaSmrg CMAP_RELOAD_ON_MODE_SWITCH)) { 98604007ebaSmrg return FALSE; 98704007ebaSmrg } 988f29dbc25Smrg } 989f29dbc25Smrg xf86DPMSInit(pScrn, xf86DPMSSet, 0); 990f29dbc25Smrg 991f29dbc25Smrg LXInitVideo(pScrn); 992f29dbc25Smrg 993f29dbc25Smrg pGeode->PointerMoved = pScrni->PointerMoved; 994f29dbc25Smrg pScrni->PointerMoved = GeodePointerMoved; 995f29dbc25Smrg 996f29dbc25Smrg pGeode->CloseScreen = pScrn->CloseScreen; 997f29dbc25Smrg pScrn->CloseScreen = LXCloseScreen; 998f29dbc25Smrg pScrn->SaveScreen = LXSaveScreen; 999f29dbc25Smrg 1000f29dbc25Smrg if (!xf86CrtcScreenInit(pScrn)) { 100104007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "CRTCScreenInit failed.\n"); 100204007ebaSmrg return FALSE; 1003f29dbc25Smrg } 1004f29dbc25Smrg 1005f29dbc25Smrg if (serverGeneration == 1) 100604007ebaSmrg xf86ShowUnusedOptions(pScrni->scrnIndex, pScrni->options); 1007f29dbc25Smrg 1008f29dbc25Smrg pGeode->starting = FALSE; 1009f29dbc25Smrg 1010f29dbc25Smrg return TRUE; 1011f29dbc25Smrg} 1012f29dbc25Smrg 1013f29dbc25Smrgstatic int 101404007ebaSmrgLXValidMode(VALID_MODE_ARGS_DECL) 1015f29dbc25Smrg{ 1016f29dbc25Smrg return MODE_OK; 1017f29dbc25Smrg} 1018f29dbc25Smrg 1019f29dbc25Smrgstatic Bool 102004007ebaSmrgLXEnterVT(VT_FUNC_ARGS_DECL) 1021f29dbc25Smrg{ 102204007ebaSmrg SCRN_INFO_PTR(arg); 102304007ebaSmrg return LXEnterGraphics(NULL, pScrni); 1024f29dbc25Smrg} 1025f29dbc25Smrg 1026f29dbc25Smrgstatic void 102704007ebaSmrgLXLeaveVT(VT_FUNC_ARGS_DECL) 1028f29dbc25Smrg{ 102904007ebaSmrg SCRN_INFO_PTR(arg); 1030f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1031f29dbc25Smrg 1032f29dbc25Smrg pGeode->PrevDisplayOffset = vg_get_display_offset(); 1033f29dbc25Smrg LXLeaveGraphics(pScrni); 1034f29dbc25Smrg} 1035f29dbc25Smrg 1036f29dbc25Smrgvoid 1037f29dbc25SmrgLXSetupChipsetFPtr(ScrnInfoPtr pScrn) 1038f29dbc25Smrg{ 1039f29dbc25Smrg pScrn->PreInit = LXPreInit; 1040f29dbc25Smrg pScrn->ScreenInit = LXScreenInit; 1041f29dbc25Smrg pScrn->SwitchMode = LXSwitchMode; 1042f29dbc25Smrg pScrn->AdjustFrame = LXAdjustFrame; 1043f29dbc25Smrg pScrn->EnterVT = LXEnterVT; 1044f29dbc25Smrg pScrn->LeaveVT = LXLeaveVT; 1045f29dbc25Smrg pScrn->FreeScreen = GeodeFreeScreen; 1046f29dbc25Smrg pScrn->ValidMode = LXValidMode; 1047f29dbc25Smrg} 1048