cir_driver.c revision 1ae1b5e8
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 2476888252Smrg#include "xf86Resources.h" 2576888252Smrg 2676888252Smrg/* All drivers need this */ 2776888252Smrg 2876888252Smrg/* Drivers for PCI hardware need this */ 2976888252Smrg#include "xf86PciInfo.h" 3076888252Smrg 3176888252Smrg/* Drivers that need to access the PCI config space directly need this */ 3276888252Smrg#include "xf86Pci.h" 3376888252Smrg 3476888252Smrg#include "cir.h" 3576888252Smrg#include "alp.h" 3676888252Smrg#include "lg.h" 3776888252Smrg 3876888252Smrg#include "vbe.h" 3976888252Smrg 4076888252Smrg/* 4176888252Smrg * Forward definitions for the functions that make up the driver. 4276888252Smrg */ 4376888252Smrg 4476888252Smrg/* Mandatory functions */ 4576888252Smrg 4676888252Smrgstatic const OptionInfoRec * CIRAvailableOptions(int chipid, int busid); 4776888252Smrgstatic void CIRIdentify(int flags); 4876888252Smrgstatic Bool CIRProbe(DriverPtr drv, int flags); 4976888252Smrg 5076888252Smrgstatic Bool lg_loaded = FALSE; 5176888252Smrgstatic Bool alp_loaded = FALSE; 5276888252Smrg 5376888252Smrg#define CIR_VERSION 4000 5476888252Smrg#define CIR_NAME "CIRRUS" 5576888252Smrg#define CIR_DRIVER_NAME "cirrus" 561ae1b5e8Smrg#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 571ae1b5e8Smrg#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 581ae1b5e8Smrg#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 5976888252Smrg 6076888252Smrg/* 6176888252Smrg * This contains the functions needed by the server after loading the 6276888252Smrg * driver module. It must be supplied, and gets added to the driver list by 6376888252Smrg * the Module Setup function in the dynamic case. In the static case a 6476888252Smrg * reference to this is compiled in, and this requires that the name of 6576888252Smrg * this DriverRec be an upper-case version of the driver name. 6676888252Smrg */ 6776888252Smrg 6876888252Smrg_X_EXPORT DriverRec CIRRUS = { 6976888252Smrg CIR_VERSION, 7076888252Smrg CIR_DRIVER_NAME, 7176888252Smrg CIRIdentify, 7276888252Smrg CIRProbe, 7376888252Smrg CIRAvailableOptions, 7476888252Smrg NULL, 7576888252Smrg 0 7676888252Smrg}; 7776888252Smrg 7876888252Smrg/* Supported chipsets */ 7976888252SmrgSymTabRec CIRChipsets[] = { 8076888252Smrg { PCI_CHIP_GD5430, "CLGD5430" }, 8176888252Smrg { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 8276888252Smrg { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 8376888252Smrg { PCI_CHIP_GD5436, "CLGD5436" }, 8476888252Smrg/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 8576888252Smrg { PCI_CHIP_GD5446, "CLGD5446" }, 8676888252Smrg { PCI_CHIP_GD5480, "CLGD5480" }, 8776888252Smrg { PCI_CHIP_GD5462, "CL-GD5462" }, 8876888252Smrg { PCI_CHIP_GD5464, "CL-GD5464" }, 8976888252Smrg { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 9076888252Smrg { PCI_CHIP_GD5465, "CL-GD5465" }, 9176888252Smrg { PCI_CHIP_GD7548, "CL-GD7548" }, 9276888252Smrg {-1, NULL } 9376888252Smrg}; 9476888252Smrg 9576888252Smrg/* List of PCI chipset names */ 961ae1b5e8Smrg_X_EXPORT PciChipsets CIRPciChipsets[] = { 9776888252Smrg { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 9876888252Smrg { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 9976888252Smrg { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 10076888252Smrg { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 10176888252Smrg/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 10276888252Smrg { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 10376888252Smrg { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 10476888252Smrg { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 10576888252Smrg { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 10676888252Smrg { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 10776888252Smrg { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 10876888252Smrg { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 10976888252Smrg { -1, -1, RES_UNDEFINED} 11076888252Smrg}; 11176888252Smrg 11276888252Smrg/* 11376888252Smrg * List of symbols from other modules that this module references. This 11476888252Smrg * list is used to tell the loader that it is OK for symbols here to be 11576888252Smrg * unresolved providing that it hasn't been told that they haven't been 11676888252Smrg * told that they are essential via a call to xf86LoaderReqSymbols() or 11776888252Smrg * xf86LoaderReqSymLists(). The purpose of this is to avoid warnings about 11876888252Smrg * unresolved symbols that are not required. 11976888252Smrg */ 12076888252Smrg 12176888252Smrgstatic const char *alpSymbols[] = { 12276888252Smrg "AlpAvailableOptions", 12376888252Smrg "AlpProbe", 12476888252Smrg NULL 12576888252Smrg}; 12676888252Smrgstatic const char *lgSymbols[] = { 12776888252Smrg "LgAvailableOptions", 12876888252Smrg "LgProbe", 12976888252Smrg NULL 13076888252Smrg}; 13176888252Smrg 13276888252Smrgstatic const char *vbeSymbols[] = { 13376888252Smrg "VBEInit", 13476888252Smrg "vbeDoEDID", 13576888252Smrg "vbeFree", 13676888252Smrg NULL 13776888252Smrg}; 13876888252Smrg 13976888252Smrg#ifdef XFree86LOADER 14076888252Smrg 14176888252Smrgstatic MODULESETUPPROTO(cirSetup); 14276888252Smrg 14376888252Smrgstatic XF86ModuleVersionInfo cirVersRec = 14476888252Smrg{ 14576888252Smrg "cirrus", 14676888252Smrg MODULEVENDORSTRING, 14776888252Smrg MODINFOSTRING1, 14876888252Smrg MODINFOSTRING2, 14976888252Smrg XORG_VERSION_CURRENT, 15076888252Smrg CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 15176888252Smrg ABI_CLASS_VIDEODRV, /* This is a video driver */ 15276888252Smrg ABI_VIDEODRV_VERSION, 15376888252Smrg MOD_CLASS_VIDEODRV, 15476888252Smrg {0,0,0,0} 15576888252Smrg}; 15676888252Smrg 15776888252Smrg/* 15876888252Smrg * This is the module init data. 15976888252Smrg * Its name has to be the driver name followed by ModuleData. 16076888252Smrg */ 16176888252Smrg_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 16276888252Smrg 16376888252Smrgstatic pointer 16476888252SmrgcirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 16576888252Smrg{ 16676888252Smrg static Bool setupDone = FALSE; 16776888252Smrg 16876888252Smrg /* This module should be loaded only once, but check to be sure. */ 16976888252Smrg 17076888252Smrg if (!setupDone) { 17176888252Smrg setupDone = TRUE; 17276888252Smrg xf86AddDriver(&CIRRUS, module, 0); 17376888252Smrg 17476888252Smrg LoaderRefSymLists(alpSymbols, lgSymbols, vbeSymbols, NULL); 17576888252Smrg return (pointer)1; 17676888252Smrg } 17776888252Smrg if (errmaj) *errmaj = LDR_ONCEONLY; 17876888252Smrg return NULL; 17976888252Smrg} 18076888252Smrg 18176888252Smrg#endif /* XFree86LOADER */ 18276888252Smrg 18376888252Smrg/* Mandatory */ 18476888252Smrgstatic void 18576888252SmrgCIRIdentify(int flags) 18676888252Smrg{ 18776888252Smrg xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 18876888252Smrg} 18976888252Smrg 19076888252Smrgstatic const OptionInfoRec * 19176888252SmrgCIRAvailableOptions(int chipid, int busid) 19276888252Smrg{ 19376888252Smrg int chip = chipid & 0xffff; 19476888252Smrg 19576888252Smrg switch (chip) 19676888252Smrg { 19776888252Smrg case PCI_CHIP_GD5462: 19876888252Smrg case PCI_CHIP_GD5464: 19976888252Smrg case PCI_CHIP_GD5464BD: 20076888252Smrg case PCI_CHIP_GD5465: 20176888252Smrg if (lg_loaded) 20276888252Smrg return LgAvailableOptions(chipid); 20376888252Smrg else 20476888252Smrg return NULL; 20576888252Smrg 20676888252Smrg default: 20776888252Smrg if (alp_loaded) 20876888252Smrg return AlpAvailableOptions(chipid); 20976888252Smrg else 21076888252Smrg return NULL; 21176888252Smrg } 21276888252Smrg} 21376888252Smrg 21476888252Smrgstatic Bool 21576888252SmrgCIRProbe(DriverPtr drv, int flags) 21676888252Smrg{ 21776888252Smrg int i; 21876888252Smrg GDevPtr *devSections; 21976888252Smrg pciVideoPtr pPci; 22076888252Smrg int *usedChips; 22176888252Smrg int numDevSections; 22276888252Smrg int numUsed; 22376888252Smrg Bool foundScreen = FALSE; 22476888252Smrg ScrnInfoPtr pScrn; 22576888252Smrg 22676888252Smrg#ifdef CIR_DEBUG 22776888252Smrg ErrorF("CirProbe\n"); 22876888252Smrg#endif 22976888252Smrg 23076888252Smrg /* 23176888252Smrg * For PROBE_DETECT, make sure both sub-modules are loaded before 23276888252Smrg * calling xf86MatchPciInstances(), because the AvailableOptions() 23376888252Smrg * functions may be called before xf86MatchPciInstances() returns. 23476888252Smrg */ 23576888252Smrg 23676888252Smrg if (flags & PROBE_DETECT) { 23776888252Smrg if (!lg_loaded) { 23876888252Smrg if (xf86LoadDrvSubModule(drv, "cirrus_laguna")) { 23976888252Smrg xf86LoaderReqSymLists(lgSymbols, NULL); 24076888252Smrg lg_loaded = TRUE; 24176888252Smrg } 24276888252Smrg } 24376888252Smrg if (!alp_loaded) { 24476888252Smrg if (xf86LoadDrvSubModule(drv, "cirrus_alpine")) { 24576888252Smrg xf86LoaderReqSymLists(alpSymbols, NULL); 24676888252Smrg alp_loaded = TRUE; 24776888252Smrg } 24876888252Smrg } 24976888252Smrg } 25076888252Smrg 25176888252Smrg if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 25276888252Smrg &devSections)) <= 0) { 25376888252Smrg return FALSE; 25476888252Smrg } 2551ae1b5e8Smrg 2561ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 25776888252Smrg if (xf86GetPciVideoInfo() == NULL) { 25876888252Smrg /* 25976888252Smrg * We won't let anything in the config file override finding no 26076888252Smrg * PCI video cards at all. This seems reasonable now, but we'll see. 26176888252Smrg */ 26276888252Smrg return FALSE; 26376888252Smrg } 2641ae1b5e8Smrg#endif 26576888252Smrg 26676888252Smrg numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 26776888252Smrg CIRChipsets, CIRPciChipsets, devSections, 26876888252Smrg numDevSections, drv, &usedChips); 26976888252Smrg /* Free it since we don't need that list after this */ 27076888252Smrg xfree(devSections); 27176888252Smrg if (numUsed <= 0) 27276888252Smrg return FALSE; 27376888252Smrg if (flags & PROBE_DETECT) 27476888252Smrg foundScreen = TRUE; 27576888252Smrg else for (i = 0; i < numUsed; i++) { 27676888252Smrg /* The Laguna family of chips is so different from the Alpine 27776888252Smrg family that we won't share even the highest-level of 27876888252Smrg functions. But, the Laguna chips /are/ Cirrus chips, so 27976888252Smrg they should be handled in this driver (as opposed to their 28076888252Smrg own driver). */ 28176888252Smrg pPci = xf86GetPciInfoForEntity(usedChips[i]); 28276888252Smrg pScrn = NULL; 2831ae1b5e8Smrg if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 2841ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 2851ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 2861ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 28776888252Smrg 28876888252Smrg if (!lg_loaded) { 28976888252Smrg if (!xf86LoadDrvSubModule(drv, "cirrus_laguna")) 29076888252Smrg continue; 29176888252Smrg xf86LoaderReqSymLists(lgSymbols, NULL); 29276888252Smrg lg_loaded = TRUE; 29376888252Smrg } 29476888252Smrg pScrn = LgProbe(usedChips[i]); 29576888252Smrg } else { 29676888252Smrg if (!alp_loaded) { 29776888252Smrg if (!xf86LoadDrvSubModule(drv, "cirrus_alpine")) 29876888252Smrg continue; 29976888252Smrg xf86LoaderReqSymLists(alpSymbols, NULL); 30076888252Smrg alp_loaded = TRUE; 30176888252Smrg } 30276888252Smrg pScrn = AlpProbe(usedChips[i]); 30376888252Smrg } 30476888252Smrg 30576888252Smrg if (pScrn) { 30676888252Smrg foundScreen = TRUE; 30776888252Smrg /* Fill in what we can of the ScrnInfoRec */ 3081ae1b5e8Smrg pScrn->driverVersion = CIR_VERSION; 30976888252Smrg pScrn->driverName = CIR_DRIVER_NAME; 31076888252Smrg pScrn->name = CIR_NAME; 31176888252Smrg pScrn->Probe = NULL; 31276888252Smrg } 31376888252Smrg } 31476888252Smrg xfree(usedChips); 31576888252Smrg 31676888252Smrg return foundScreen; 31776888252Smrg} 31876888252Smrg 31976888252Smrg/* 32076888252Smrg * Map the framebuffer and MMIO memory. 32176888252Smrg */ 32276888252Smrg 3231ae1b5e8Smrg_X_EXPORT Bool 32476888252SmrgCirMapMem(CirPtr pCir, int scrnIndex) 32576888252Smrg{ 32676888252Smrg int mmioFlags; 32776888252Smrg 32876888252Smrg#ifdef CIR_DEBUG 32976888252Smrg ErrorF("CirMapMem\n"); 33076888252Smrg#endif 33176888252Smrg 33276888252Smrg /* 33376888252Smrg * Map the frame buffer. 33476888252Smrg */ 33576888252Smrg if (pCir->FbMapSize) { 3361ae1b5e8Smrg 3371ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 33876888252Smrg 33976888252Smrg pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 34076888252Smrg pCir->PciTag, pCir->FbAddress, 34176888252Smrg pCir->FbMapSize); 34276888252Smrg if (pCir->FbBase == NULL) 34376888252Smrg return FALSE; 3441ae1b5e8Smrg 3451ae1b5e8Smrg#else 3461ae1b5e8Smrg void** result = (void**)&pCir->FbBase; 3471ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 3481ae1b5e8Smrg pCir->FbAddress, 3491ae1b5e8Smrg pCir->FbMapSize, 3501ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE | 3511ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 3521ae1b5e8Smrg result); 3531ae1b5e8Smrg 3541ae1b5e8Smrg if (err) 3551ae1b5e8Smrg return FALSE; 3561ae1b5e8Smrg#endif 35776888252Smrg } 35876888252Smrg 35976888252Smrg#ifdef CIR_DEBUG 36076888252Smrg ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 36176888252Smrg#endif 36276888252Smrg 36376888252Smrg /* 36476888252Smrg * Map IO registers to virtual address space 36576888252Smrg */ 36676888252Smrg if (pCir->IOAddress == 0) { 36776888252Smrg pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 36876888252Smrg } else { 3691ae1b5e8Smrg 3701ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 37176888252Smrg mmioFlags = VIDMEM_MMIO; 37276888252Smrg /* 37376888252Smrg * For Alpha, we need to map SPARSE memory, since we need 37476888252Smrg * byte/short access. Common-level will automatically use 37576888252Smrg * sparse mapping for MMIO. 37676888252Smrg */ 3771ae1b5e8Smrg 37876888252Smrg pCir->IOBase = 37976888252Smrg xf86MapPciMem(scrnIndex, mmioFlags, pCir->PciTag, 38076888252Smrg pCir->IOAddress, pCir->IoMapSize); 38176888252Smrg if (pCir->IOBase == NULL) 38276888252Smrg return FALSE; 3831ae1b5e8Smrg 3841ae1b5e8Smrg#else 3851ae1b5e8Smrg void** result = (void**)&pCir->IOBase; 3861ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 3871ae1b5e8Smrg pCir->IOAddress, 3881ae1b5e8Smrg pCir->IoMapSize, 3891ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE, 3901ae1b5e8Smrg result); 3911ae1b5e8Smrg 3921ae1b5e8Smrg if (err) 3931ae1b5e8Smrg return FALSE; 3941ae1b5e8Smrg 3951ae1b5e8Smrg#endif 39676888252Smrg } 39776888252Smrg 39876888252Smrg#ifdef CIR_DEBUG 39976888252Smrg ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 40076888252Smrg pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 40176888252Smrg ErrorF("MMIO[GR31] = %2X\n", (int) 40276888252Smrg ((volatile unsigned char*) pCir->IOBase)[0x40]); 40376888252Smrg#endif 40476888252Smrg 40576888252Smrg return TRUE; 40676888252Smrg} 40776888252Smrg 40876888252Smrg 40976888252Smrg/* 41076888252Smrg * Unmap the framebuffer and MMIO memory. 41176888252Smrg */ 41276888252Smrg 4131ae1b5e8Smrg_X_EXPORT Bool 41476888252SmrgCirUnmapMem(CirPtr pCir, int scrnIndex) 41576888252Smrg{ 41676888252Smrg#ifdef CIR_DEBUG 41776888252Smrg ErrorF("CirUnmapMem\n"); 41876888252Smrg#endif 41976888252Smrg 42076888252Smrg if (pCir->IOBase != NULL) { 42176888252Smrg /* 42276888252Smrg * Unmap IO registers to virtual address space 42376888252Smrg */ 4241ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 42576888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 4261ae1b5e8Smrg#else 4271ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 4281ae1b5e8Smrg#endif 42976888252Smrg pCir->IOBase = NULL; 43076888252Smrg } 43176888252Smrg 4321ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 43376888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 4341ae1b5e8Smrg#else 4351ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 4361ae1b5e8Smrg#endif 43776888252Smrg pCir->FbBase = NULL; 43876888252Smrg return TRUE; 43976888252Smrg} 44076888252Smrg 4411ae1b5e8Smrg_X_EXPORT void 44276888252SmrgcirProbeDDC(ScrnInfoPtr pScrn, int index) 44376888252Smrg{ 44476888252Smrg vbeInfoPtr pVbe; 44576888252Smrg 44676888252Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 44776888252Smrg xf86LoaderReqSymLists(vbeSymbols,NULL); 44876888252Smrg pVbe = VBEInit(NULL,index); 44976888252Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 45076888252Smrg vbeFree(pVbe); 45176888252Smrg } 45276888252Smrg} 453