cir_driver.c revision d8556812
176888252Smrg/* 276888252Smrg * Driver for CL-GD5480. 376888252Smrg * Itai Nahshon. 476888252Smrg * 576888252Smrg * Support for the CL-GD7548: David Monniaux 676888252Smrg * 776888252Smrg * This is mainly a cut & paste from the MGA driver. 876888252Smrg * Original autors and contributors list include: 976888252Smrg * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel, 1076888252Smrg * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff, 1176888252Smrg * Guy DESBIEF 1276888252Smrg */ 1376888252Smrg 1476888252Smrg#ifdef HAVE_CONFIG_H 1576888252Smrg#include "config.h" 1676888252Smrg#endif 1776888252Smrg 1876888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c,v 1.67 2001/05/15 10:19:37 eich Exp $ */ 1976888252Smrg 2076888252Smrg/* All drivers should typically include these */ 2176888252Smrg#include "xf86.h" 2276888252Smrg#include "xf86_OSproc.h" 2376888252Smrg 24d8556812Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 2576888252Smrg#include "xf86Resources.h" 26d8556812Smrg#endif 2776888252Smrg/* All drivers need this */ 2876888252Smrg 2976888252Smrg/* Drivers for PCI hardware need this */ 3076888252Smrg#include "xf86PciInfo.h" 3176888252Smrg 3276888252Smrg/* Drivers that need to access the PCI config space directly need this */ 3376888252Smrg#include "xf86Pci.h" 3476888252Smrg 3576888252Smrg#include "cir.h" 3676888252Smrg#include "alp.h" 3776888252Smrg#include "lg.h" 3876888252Smrg 3976888252Smrg#include "vbe.h" 4076888252Smrg 4176888252Smrg/* 4276888252Smrg * Forward definitions for the functions that make up the driver. 4376888252Smrg */ 4476888252Smrg 4576888252Smrg/* Mandatory functions */ 4676888252Smrg 4776888252Smrgstatic const OptionInfoRec * CIRAvailableOptions(int chipid, int busid); 4876888252Smrgstatic void CIRIdentify(int flags); 4976888252Smrgstatic Bool CIRProbe(DriverPtr drv, int flags); 5076888252Smrg 5176888252Smrgstatic Bool lg_loaded = FALSE; 5276888252Smrgstatic Bool alp_loaded = FALSE; 5376888252Smrg 5476888252Smrg#define CIR_VERSION 4000 5576888252Smrg#define CIR_NAME "CIRRUS" 5676888252Smrg#define CIR_DRIVER_NAME "cirrus" 571ae1b5e8Smrg#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 581ae1b5e8Smrg#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 591ae1b5e8Smrg#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 6076888252Smrg 6176888252Smrg/* 6276888252Smrg * This contains the functions needed by the server after loading the 6376888252Smrg * driver module. It must be supplied, and gets added to the driver list by 6476888252Smrg * the Module Setup function in the dynamic case. In the static case a 6576888252Smrg * reference to this is compiled in, and this requires that the name of 6676888252Smrg * this DriverRec be an upper-case version of the driver name. 6776888252Smrg */ 6876888252Smrg 6976888252Smrg_X_EXPORT DriverRec CIRRUS = { 7076888252Smrg CIR_VERSION, 7176888252Smrg CIR_DRIVER_NAME, 7276888252Smrg CIRIdentify, 7376888252Smrg CIRProbe, 7476888252Smrg CIRAvailableOptions, 7576888252Smrg NULL, 7676888252Smrg 0 7776888252Smrg}; 7876888252Smrg 7976888252Smrg/* Supported chipsets */ 8076888252SmrgSymTabRec CIRChipsets[] = { 8176888252Smrg { PCI_CHIP_GD5430, "CLGD5430" }, 8276888252Smrg { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 8376888252Smrg { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 8476888252Smrg { PCI_CHIP_GD5436, "CLGD5436" }, 8576888252Smrg/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 8676888252Smrg { PCI_CHIP_GD5446, "CLGD5446" }, 8776888252Smrg { PCI_CHIP_GD5480, "CLGD5480" }, 8876888252Smrg { PCI_CHIP_GD5462, "CL-GD5462" }, 8976888252Smrg { PCI_CHIP_GD5464, "CL-GD5464" }, 9076888252Smrg { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 9176888252Smrg { PCI_CHIP_GD5465, "CL-GD5465" }, 9276888252Smrg { PCI_CHIP_GD7548, "CL-GD7548" }, 9376888252Smrg {-1, NULL } 9476888252Smrg}; 9576888252Smrg 9676888252Smrg/* List of PCI chipset names */ 971ae1b5e8Smrg_X_EXPORT PciChipsets CIRPciChipsets[] = { 9876888252Smrg { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 9976888252Smrg { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 10076888252Smrg { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 10176888252Smrg { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 10276888252Smrg/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 10376888252Smrg { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 10476888252Smrg { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 10576888252Smrg { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 10676888252Smrg { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 10776888252Smrg { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 10876888252Smrg { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 10976888252Smrg { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 11076888252Smrg { -1, -1, RES_UNDEFINED} 11176888252Smrg}; 11276888252Smrg 11376888252Smrg#ifdef XFree86LOADER 11476888252Smrg 11576888252Smrgstatic MODULESETUPPROTO(cirSetup); 11676888252Smrg 11776888252Smrgstatic XF86ModuleVersionInfo cirVersRec = 11876888252Smrg{ 11976888252Smrg "cirrus", 12076888252Smrg MODULEVENDORSTRING, 12176888252Smrg MODINFOSTRING1, 12276888252Smrg MODINFOSTRING2, 12376888252Smrg XORG_VERSION_CURRENT, 12476888252Smrg CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 12576888252Smrg ABI_CLASS_VIDEODRV, /* This is a video driver */ 12676888252Smrg ABI_VIDEODRV_VERSION, 12776888252Smrg MOD_CLASS_VIDEODRV, 12876888252Smrg {0,0,0,0} 12976888252Smrg}; 13076888252Smrg 13176888252Smrg/* 13276888252Smrg * This is the module init data. 13376888252Smrg * Its name has to be the driver name followed by ModuleData. 13476888252Smrg */ 13576888252Smrg_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 13676888252Smrg 13776888252Smrgstatic pointer 13876888252SmrgcirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 13976888252Smrg{ 14076888252Smrg static Bool setupDone = FALSE; 14176888252Smrg 14276888252Smrg /* This module should be loaded only once, but check to be sure. */ 14376888252Smrg 14476888252Smrg if (!setupDone) { 14576888252Smrg setupDone = TRUE; 14676888252Smrg xf86AddDriver(&CIRRUS, module, 0); 14776888252Smrg 14876888252Smrg return (pointer)1; 14976888252Smrg } 15076888252Smrg if (errmaj) *errmaj = LDR_ONCEONLY; 15176888252Smrg return NULL; 15276888252Smrg} 15376888252Smrg 15476888252Smrg#endif /* XFree86LOADER */ 15576888252Smrg 15676888252Smrg/* Mandatory */ 15776888252Smrgstatic void 15876888252SmrgCIRIdentify(int flags) 15976888252Smrg{ 16076888252Smrg xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 16176888252Smrg} 16276888252Smrg 16376888252Smrgstatic const OptionInfoRec * 16476888252SmrgCIRAvailableOptions(int chipid, int busid) 16576888252Smrg{ 16676888252Smrg int chip = chipid & 0xffff; 16776888252Smrg 16876888252Smrg switch (chip) 16976888252Smrg { 17076888252Smrg case PCI_CHIP_GD5462: 17176888252Smrg case PCI_CHIP_GD5464: 17276888252Smrg case PCI_CHIP_GD5464BD: 17376888252Smrg case PCI_CHIP_GD5465: 17476888252Smrg if (lg_loaded) 17576888252Smrg return LgAvailableOptions(chipid); 17676888252Smrg else 17776888252Smrg return NULL; 17876888252Smrg 17976888252Smrg default: 18076888252Smrg if (alp_loaded) 18176888252Smrg return AlpAvailableOptions(chipid); 18276888252Smrg else 18376888252Smrg return NULL; 18476888252Smrg } 18576888252Smrg} 18676888252Smrg 18776888252Smrgstatic Bool 18876888252SmrgCIRProbe(DriverPtr drv, int flags) 18976888252Smrg{ 19076888252Smrg int i; 19176888252Smrg GDevPtr *devSections; 19276888252Smrg pciVideoPtr pPci; 19376888252Smrg int *usedChips; 19476888252Smrg int numDevSections; 19576888252Smrg int numUsed; 19676888252Smrg Bool foundScreen = FALSE; 19776888252Smrg ScrnInfoPtr pScrn; 19876888252Smrg 19976888252Smrg#ifdef CIR_DEBUG 20076888252Smrg ErrorF("CirProbe\n"); 20176888252Smrg#endif 20276888252Smrg 20376888252Smrg /* 20476888252Smrg * For PROBE_DETECT, make sure both sub-modules are loaded before 20576888252Smrg * calling xf86MatchPciInstances(), because the AvailableOptions() 20676888252Smrg * functions may be called before xf86MatchPciInstances() returns. 20776888252Smrg */ 20876888252Smrg 20976888252Smrg if (flags & PROBE_DETECT) { 21076888252Smrg if (!lg_loaded) { 21176888252Smrg if (xf86LoadDrvSubModule(drv, "cirrus_laguna")) { 21276888252Smrg lg_loaded = TRUE; 21376888252Smrg } 21476888252Smrg } 21576888252Smrg if (!alp_loaded) { 21676888252Smrg if (xf86LoadDrvSubModule(drv, "cirrus_alpine")) { 21776888252Smrg alp_loaded = TRUE; 21876888252Smrg } 21976888252Smrg } 22076888252Smrg } 22176888252Smrg 22276888252Smrg if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 22376888252Smrg &devSections)) <= 0) { 22476888252Smrg return FALSE; 22576888252Smrg } 2261ae1b5e8Smrg 2271ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 22876888252Smrg if (xf86GetPciVideoInfo() == NULL) { 22976888252Smrg /* 23076888252Smrg * We won't let anything in the config file override finding no 23176888252Smrg * PCI video cards at all. This seems reasonable now, but we'll see. 23276888252Smrg */ 23376888252Smrg return FALSE; 23476888252Smrg } 2351ae1b5e8Smrg#endif 23676888252Smrg 23776888252Smrg numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 23876888252Smrg CIRChipsets, CIRPciChipsets, devSections, 23976888252Smrg numDevSections, drv, &usedChips); 24076888252Smrg /* Free it since we don't need that list after this */ 24176888252Smrg xfree(devSections); 24276888252Smrg if (numUsed <= 0) 24376888252Smrg return FALSE; 24476888252Smrg if (flags & PROBE_DETECT) 24576888252Smrg foundScreen = TRUE; 24676888252Smrg else for (i = 0; i < numUsed; i++) { 24776888252Smrg /* The Laguna family of chips is so different from the Alpine 24876888252Smrg family that we won't share even the highest-level of 24976888252Smrg functions. But, the Laguna chips /are/ Cirrus chips, so 25076888252Smrg they should be handled in this driver (as opposed to their 25176888252Smrg own driver). */ 25276888252Smrg pPci = xf86GetPciInfoForEntity(usedChips[i]); 25376888252Smrg pScrn = NULL; 2541ae1b5e8Smrg if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 2551ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 2561ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 2571ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 25876888252Smrg 25976888252Smrg if (!lg_loaded) { 26076888252Smrg if (!xf86LoadDrvSubModule(drv, "cirrus_laguna")) 26176888252Smrg continue; 26276888252Smrg lg_loaded = TRUE; 26376888252Smrg } 26476888252Smrg pScrn = LgProbe(usedChips[i]); 26576888252Smrg } else { 26676888252Smrg if (!alp_loaded) { 26776888252Smrg if (!xf86LoadDrvSubModule(drv, "cirrus_alpine")) 26876888252Smrg continue; 26976888252Smrg alp_loaded = TRUE; 27076888252Smrg } 27176888252Smrg pScrn = AlpProbe(usedChips[i]); 27276888252Smrg } 27376888252Smrg 27476888252Smrg if (pScrn) { 27576888252Smrg foundScreen = TRUE; 27676888252Smrg /* Fill in what we can of the ScrnInfoRec */ 2771ae1b5e8Smrg pScrn->driverVersion = CIR_VERSION; 27876888252Smrg pScrn->driverName = CIR_DRIVER_NAME; 27976888252Smrg pScrn->name = CIR_NAME; 28076888252Smrg pScrn->Probe = NULL; 28176888252Smrg } 28276888252Smrg } 28376888252Smrg xfree(usedChips); 28476888252Smrg 28576888252Smrg return foundScreen; 28676888252Smrg} 28776888252Smrg 28876888252Smrg/* 28976888252Smrg * Map the framebuffer and MMIO memory. 29076888252Smrg */ 29176888252Smrg 2921ae1b5e8Smrg_X_EXPORT Bool 29376888252SmrgCirMapMem(CirPtr pCir, int scrnIndex) 29476888252Smrg{ 29576888252Smrg int mmioFlags; 29676888252Smrg 29776888252Smrg#ifdef CIR_DEBUG 29876888252Smrg ErrorF("CirMapMem\n"); 29976888252Smrg#endif 30076888252Smrg 30176888252Smrg /* 30276888252Smrg * Map the frame buffer. 30376888252Smrg */ 30476888252Smrg if (pCir->FbMapSize) { 3051ae1b5e8Smrg 3061ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 30776888252Smrg 30876888252Smrg pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 30976888252Smrg pCir->PciTag, pCir->FbAddress, 31076888252Smrg pCir->FbMapSize); 31176888252Smrg if (pCir->FbBase == NULL) 31276888252Smrg return FALSE; 3131ae1b5e8Smrg 3141ae1b5e8Smrg#else 3151ae1b5e8Smrg void** result = (void**)&pCir->FbBase; 3161ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 3171ae1b5e8Smrg pCir->FbAddress, 3181ae1b5e8Smrg pCir->FbMapSize, 3191ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE | 3201ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 3211ae1b5e8Smrg result); 3221ae1b5e8Smrg 3231ae1b5e8Smrg if (err) 3241ae1b5e8Smrg return FALSE; 3251ae1b5e8Smrg#endif 32676888252Smrg } 32776888252Smrg 32876888252Smrg#ifdef CIR_DEBUG 32976888252Smrg ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 33076888252Smrg#endif 33176888252Smrg 33276888252Smrg /* 33376888252Smrg * Map IO registers to virtual address space 33476888252Smrg */ 33576888252Smrg if (pCir->IOAddress == 0) { 33676888252Smrg pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 33776888252Smrg } else { 3381ae1b5e8Smrg 3391ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 34076888252Smrg mmioFlags = VIDMEM_MMIO; 34176888252Smrg /* 34276888252Smrg * For Alpha, we need to map SPARSE memory, since we need 34376888252Smrg * byte/short access. Common-level will automatically use 34476888252Smrg * sparse mapping for MMIO. 34576888252Smrg */ 3461ae1b5e8Smrg 34776888252Smrg pCir->IOBase = 34876888252Smrg xf86MapPciMem(scrnIndex, mmioFlags, pCir->PciTag, 34976888252Smrg pCir->IOAddress, pCir->IoMapSize); 35076888252Smrg if (pCir->IOBase == NULL) 35176888252Smrg return FALSE; 3521ae1b5e8Smrg 3531ae1b5e8Smrg#else 3541ae1b5e8Smrg void** result = (void**)&pCir->IOBase; 3551ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 3561ae1b5e8Smrg pCir->IOAddress, 3571ae1b5e8Smrg pCir->IoMapSize, 3581ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE, 3591ae1b5e8Smrg result); 3601ae1b5e8Smrg 3611ae1b5e8Smrg if (err) 3621ae1b5e8Smrg return FALSE; 3631ae1b5e8Smrg 3641ae1b5e8Smrg#endif 36576888252Smrg } 36676888252Smrg 36776888252Smrg#ifdef CIR_DEBUG 36876888252Smrg ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 36976888252Smrg pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 37076888252Smrg ErrorF("MMIO[GR31] = %2X\n", (int) 37176888252Smrg ((volatile unsigned char*) pCir->IOBase)[0x40]); 37276888252Smrg#endif 37376888252Smrg 37476888252Smrg return TRUE; 37576888252Smrg} 37676888252Smrg 37776888252Smrg 37876888252Smrg/* 37976888252Smrg * Unmap the framebuffer and MMIO memory. 38076888252Smrg */ 38176888252Smrg 3821ae1b5e8Smrg_X_EXPORT Bool 38376888252SmrgCirUnmapMem(CirPtr pCir, int scrnIndex) 38476888252Smrg{ 38576888252Smrg#ifdef CIR_DEBUG 38676888252Smrg ErrorF("CirUnmapMem\n"); 38776888252Smrg#endif 38876888252Smrg 38976888252Smrg if (pCir->IOBase != NULL) { 39076888252Smrg /* 39176888252Smrg * Unmap IO registers to virtual address space 39276888252Smrg */ 3931ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 39476888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 3951ae1b5e8Smrg#else 3961ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 3971ae1b5e8Smrg#endif 39876888252Smrg pCir->IOBase = NULL; 39976888252Smrg } 40076888252Smrg 4011ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 40276888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 4031ae1b5e8Smrg#else 4041ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 4051ae1b5e8Smrg#endif 40676888252Smrg pCir->FbBase = NULL; 40776888252Smrg return TRUE; 40876888252Smrg} 40976888252Smrg 4101ae1b5e8Smrg_X_EXPORT void 41176888252SmrgcirProbeDDC(ScrnInfoPtr pScrn, int index) 41276888252Smrg{ 41376888252Smrg vbeInfoPtr pVbe; 41476888252Smrg 41576888252Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 41676888252Smrg pVbe = VBEInit(NULL,index); 41776888252Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 41876888252Smrg vbeFree(pVbe); 41976888252Smrg } 42076888252Smrg} 421