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. 80814a2baSmrg * Original authors 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/* All drivers should typically include these */ 1976888252Smrg#include "xf86.h" 2076888252Smrg#include "xf86_OSproc.h" 2176888252Smrg 22d8556812Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6 2376888252Smrg#include "xf86Resources.h" 24d8556812Smrg#endif 2576888252Smrg/* All drivers need this */ 2676888252Smrg 2776888252Smrg/* Drivers that need to access the PCI config space directly need this */ 2876888252Smrg#include "xf86Pci.h" 2976888252Smrg 3076888252Smrg#include "cir.h" 3176888252Smrg#include "alp.h" 3276888252Smrg#include "lg.h" 3376888252Smrg 3476888252Smrg#include "vbe.h" 3576888252Smrg 3676888252Smrg/* 3776888252Smrg * Forward definitions for the functions that make up the driver. 3876888252Smrg */ 3976888252Smrg 4076888252Smrg/* Mandatory functions */ 4176888252Smrg 4276888252Smrgstatic const OptionInfoRec * CIRAvailableOptions(int chipid, int busid); 4376888252Smrgstatic void CIRIdentify(int flags); 4476888252Smrgstatic Bool CIRProbe(DriverPtr drv, int flags); 4576888252Smrg 4676888252Smrg#define CIR_VERSION 4000 4776888252Smrg#define CIR_NAME "CIRRUS" 4876888252Smrg#define CIR_DRIVER_NAME "cirrus" 491ae1b5e8Smrg#define CIR_MAJOR_VERSION PACKAGE_VERSION_MAJOR 501ae1b5e8Smrg#define CIR_MINOR_VERSION PACKAGE_VERSION_MINOR 511ae1b5e8Smrg#define CIR_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL 5276888252Smrg 5376888252Smrg/* 5476888252Smrg * This contains the functions needed by the server after loading the 5576888252Smrg * driver module. It must be supplied, and gets added to the driver list by 5676888252Smrg * the Module Setup function in the dynamic case. In the static case a 5776888252Smrg * reference to this is compiled in, and this requires that the name of 5876888252Smrg * this DriverRec be an upper-case version of the driver name. 5976888252Smrg */ 6076888252Smrg 6176888252Smrg_X_EXPORT DriverRec CIRRUS = { 6276888252Smrg CIR_VERSION, 6376888252Smrg CIR_DRIVER_NAME, 6476888252Smrg CIRIdentify, 6576888252Smrg CIRProbe, 6676888252Smrg CIRAvailableOptions, 6776888252Smrg NULL, 6876888252Smrg 0 6976888252Smrg}; 7076888252Smrg 7176888252Smrg/* Supported chipsets */ 7276888252SmrgSymTabRec CIRChipsets[] = { 7376888252Smrg { PCI_CHIP_GD5430, "CLGD5430" }, 7476888252Smrg { PCI_CHIP_GD5434_4, "CLGD5434-4" }, 7576888252Smrg { PCI_CHIP_GD5434_8, "CLGD5434-8" }, 7676888252Smrg { PCI_CHIP_GD5436, "CLGD5436" }, 7776888252Smrg/* { PCI_CHIP_GD5440, "CLGD5440" }, */ 7876888252Smrg { PCI_CHIP_GD5446, "CLGD5446" }, 7976888252Smrg { PCI_CHIP_GD5480, "CLGD5480" }, 8076888252Smrg { PCI_CHIP_GD5462, "CL-GD5462" }, 8176888252Smrg { PCI_CHIP_GD5464, "CL-GD5464" }, 8276888252Smrg { PCI_CHIP_GD5464BD, "CL-GD5464BD" }, 8376888252Smrg { PCI_CHIP_GD5465, "CL-GD5465" }, 8476888252Smrg { PCI_CHIP_GD7548, "CL-GD7548" }, 8563847c39Smrg { PCI_CHIP_GD7555, "CL-GD7555" }, 8663847c39Smrg { PCI_CHIP_GD7556, "CL-GD7556" }, 8776888252Smrg {-1, NULL } 8876888252Smrg}; 8976888252Smrg 9076888252Smrg/* List of PCI chipset names */ 911ae1b5e8Smrg_X_EXPORT PciChipsets CIRPciChipsets[] = { 9276888252Smrg { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA }, 9376888252Smrg { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA }, 9476888252Smrg { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA }, 9576888252Smrg { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA }, 9676888252Smrg/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */ 9776888252Smrg { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA }, 9876888252Smrg { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA }, 9976888252Smrg { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA }, 10076888252Smrg { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA }, 10176888252Smrg { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA }, 10276888252Smrg { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA }, 10376888252Smrg { PCI_CHIP_GD7548, PCI_CHIP_GD7548, RES_SHARED_VGA }, 10463847c39Smrg { PCI_CHIP_GD7555, PCI_CHIP_GD7555, RES_SHARED_VGA }, 10563847c39Smrg { PCI_CHIP_GD7556, PCI_CHIP_GD7556, RES_SHARED_VGA }, 10676888252Smrg { -1, -1, RES_UNDEFINED} 10776888252Smrg}; 10876888252Smrg 10976888252Smrg#ifdef XFree86LOADER 11076888252Smrg 11176888252Smrgstatic MODULESETUPPROTO(cirSetup); 11276888252Smrg 11376888252Smrgstatic XF86ModuleVersionInfo cirVersRec = 11476888252Smrg{ 11576888252Smrg "cirrus", 11676888252Smrg MODULEVENDORSTRING, 11776888252Smrg MODINFOSTRING1, 11876888252Smrg MODINFOSTRING2, 11976888252Smrg XORG_VERSION_CURRENT, 12076888252Smrg CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL, 12176888252Smrg ABI_CLASS_VIDEODRV, /* This is a video driver */ 12276888252Smrg ABI_VIDEODRV_VERSION, 12376888252Smrg MOD_CLASS_VIDEODRV, 12476888252Smrg {0,0,0,0} 12576888252Smrg}; 12676888252Smrg 12776888252Smrg/* 12876888252Smrg * This is the module init data. 12976888252Smrg * Its name has to be the driver name followed by ModuleData. 13076888252Smrg */ 13176888252Smrg_X_EXPORT XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL }; 13276888252Smrg 13376888252Smrgstatic pointer 13476888252SmrgcirSetup(pointer module, pointer opts, int *errmaj, int *errmin) 13576888252Smrg{ 13676888252Smrg static Bool setupDone = FALSE; 13776888252Smrg 13876888252Smrg /* This module should be loaded only once, but check to be sure. */ 13976888252Smrg 14076888252Smrg if (!setupDone) { 14176888252Smrg setupDone = TRUE; 14276888252Smrg xf86AddDriver(&CIRRUS, module, 0); 14376888252Smrg 14476888252Smrg return (pointer)1; 14576888252Smrg } 14676888252Smrg if (errmaj) *errmaj = LDR_ONCEONLY; 14776888252Smrg return NULL; 14876888252Smrg} 14976888252Smrg 15076888252Smrg#endif /* XFree86LOADER */ 15176888252Smrg 15276888252Smrg/* Mandatory */ 15376888252Smrgstatic void 15476888252SmrgCIRIdentify(int flags) 15576888252Smrg{ 15676888252Smrg xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets); 15776888252Smrg} 15876888252Smrg 15976888252Smrgstatic const OptionInfoRec * 16076888252SmrgCIRAvailableOptions(int chipid, int busid) 16176888252Smrg{ 16276888252Smrg int chip = chipid & 0xffff; 16376888252Smrg 16476888252Smrg switch (chip) 16576888252Smrg { 16676888252Smrg case PCI_CHIP_GD5462: 16776888252Smrg case PCI_CHIP_GD5464: 16876888252Smrg case PCI_CHIP_GD5464BD: 16976888252Smrg case PCI_CHIP_GD5465: 1700814a2baSmrg return LgAvailableOptions(chipid); 17176888252Smrg 17276888252Smrg default: 1730814a2baSmrg return AlpAvailableOptions(chipid); 17476888252Smrg } 17576888252Smrg} 17676888252Smrg 17776888252Smrgstatic Bool 17876888252SmrgCIRProbe(DriverPtr drv, int flags) 17976888252Smrg{ 18076888252Smrg int i; 18176888252Smrg GDevPtr *devSections; 18276888252Smrg pciVideoPtr pPci; 18376888252Smrg int *usedChips; 18476888252Smrg int numDevSections; 18576888252Smrg int numUsed; 18676888252Smrg Bool foundScreen = FALSE; 18776888252Smrg ScrnInfoPtr pScrn; 18876888252Smrg 18976888252Smrg#ifdef CIR_DEBUG 19076888252Smrg ErrorF("CirProbe\n"); 19176888252Smrg#endif 19276888252Smrg 19376888252Smrg if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME, 19476888252Smrg &devSections)) <= 0) { 19576888252Smrg return FALSE; 19676888252Smrg } 1971ae1b5e8Smrg 1981ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 19976888252Smrg if (xf86GetPciVideoInfo() == NULL) { 20076888252Smrg /* 20176888252Smrg * We won't let anything in the config file override finding no 20276888252Smrg * PCI video cards at all. This seems reasonable now, but we'll see. 20376888252Smrg */ 20476888252Smrg return FALSE; 20576888252Smrg } 2061ae1b5e8Smrg#endif 20776888252Smrg 20876888252Smrg numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS, 20976888252Smrg CIRChipsets, CIRPciChipsets, devSections, 21076888252Smrg numDevSections, drv, &usedChips); 21176888252Smrg /* Free it since we don't need that list after this */ 21263847c39Smrg if (numUsed <= 0) { 21363847c39Smrg free(devSections); 21476888252Smrg return FALSE; 21563847c39Smrg } 21676888252Smrg if (flags & PROBE_DETECT) 21776888252Smrg foundScreen = TRUE; 21876888252Smrg else for (i = 0; i < numUsed; i++) { 21976888252Smrg /* The Laguna family of chips is so different from the Alpine 22076888252Smrg family that we won't share even the highest-level of 22176888252Smrg functions. But, the Laguna chips /are/ Cirrus chips, so 22276888252Smrg they should be handled in this driver (as opposed to their 22376888252Smrg own driver). */ 22476888252Smrg pPci = xf86GetPciInfoForEntity(usedChips[i]); 22563847c39Smrg 22663847c39Smrg#ifdef XSERVER_LIBPCIACCESS 22763847c39Smrg if (pci_device_has_kernel_driver(pPci)) { 22863847c39Smrg xf86DrvMsg(0, X_ERROR, 22963847c39Smrg "cirrus: The PCI device 0x%x at %2.2d@%2.2d:%2.2d:%1.1d has a kernel module claiming it.\n", 23063847c39Smrg pPci->device_id, pPci->bus, pPci->domain, pPci->dev, pPci->func); 23163847c39Smrg xf86DrvMsg(0, X_ERROR, 23263847c39Smrg "cirrus: This driver cannot operate until it has been unloaded.\n"); 23363847c39Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 13 23463847c39Smrg xf86UnclaimPciSlot(pPci); 23563847c39Smrg#else 23663847c39Smrg xf86UnclaimPciSlot(pPci, devSections[0]); 23763847c39Smrg#endif 23863847c39Smrg free(devSections); 23963847c39Smrg return FALSE; 24063847c39Smrg } 24163847c39Smrg#endif 24276888252Smrg pScrn = NULL; 2431ae1b5e8Smrg if (pPci && (PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5462 || 2441ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464 || 2451ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5464BD || 2461ae1b5e8Smrg PCI_DEV_DEVICE_ID(pPci) == PCI_CHIP_GD5465)) { 24776888252Smrg pScrn = LgProbe(usedChips[i]); 24876888252Smrg } else { 24976888252Smrg pScrn = AlpProbe(usedChips[i]); 25076888252Smrg } 25176888252Smrg 25276888252Smrg if (pScrn) { 25376888252Smrg foundScreen = TRUE; 25476888252Smrg /* Fill in what we can of the ScrnInfoRec */ 2551ae1b5e8Smrg pScrn->driverVersion = CIR_VERSION; 25676888252Smrg pScrn->driverName = CIR_DRIVER_NAME; 25776888252Smrg pScrn->name = CIR_NAME; 25876888252Smrg pScrn->Probe = NULL; 25976888252Smrg } 26076888252Smrg } 26163847c39Smrg free(devSections); 26263847c39Smrg free(usedChips); 26376888252Smrg 26476888252Smrg return foundScreen; 26576888252Smrg} 26676888252Smrg 26776888252Smrg/* 26876888252Smrg * Map the framebuffer and MMIO memory. 26976888252Smrg */ 27076888252Smrg 2711ae1b5e8Smrg_X_EXPORT Bool 27276888252SmrgCirMapMem(CirPtr pCir, int scrnIndex) 27376888252Smrg{ 27476888252Smrg#ifdef CIR_DEBUG 27576888252Smrg ErrorF("CirMapMem\n"); 27676888252Smrg#endif 27776888252Smrg 27876888252Smrg /* 27976888252Smrg * Map the frame buffer. 28076888252Smrg */ 28176888252Smrg if (pCir->FbMapSize) { 2821ae1b5e8Smrg 2831ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 28476888252Smrg 28576888252Smrg pCir->FbBase = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER, 28676888252Smrg pCir->PciTag, pCir->FbAddress, 28776888252Smrg pCir->FbMapSize); 28876888252Smrg if (pCir->FbBase == NULL) 28976888252Smrg return FALSE; 2901ae1b5e8Smrg 2911ae1b5e8Smrg#else 2921ae1b5e8Smrg void** result = (void**)&pCir->FbBase; 2931ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 2941ae1b5e8Smrg pCir->FbAddress, 2951ae1b5e8Smrg pCir->FbMapSize, 2961ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE | 2971ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITE_COMBINE, 2981ae1b5e8Smrg result); 2991ae1b5e8Smrg 3001ae1b5e8Smrg if (err) 3011ae1b5e8Smrg return FALSE; 3021ae1b5e8Smrg#endif 30376888252Smrg } 30476888252Smrg 30576888252Smrg#ifdef CIR_DEBUG 30676888252Smrg ErrorF("CirMapMem pCir->FbBase=0x%08x\n", pCir->FbBase); 30776888252Smrg#endif 30876888252Smrg 30976888252Smrg /* 31076888252Smrg * Map IO registers to virtual address space 31176888252Smrg */ 31276888252Smrg if (pCir->IOAddress == 0) { 31376888252Smrg pCir->IOBase = NULL; /* Until we are ready to use MMIO */ 31476888252Smrg } else { 3151ae1b5e8Smrg 3161ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 31776888252Smrg /* 31876888252Smrg * For Alpha, we need to map SPARSE memory, since we need 31976888252Smrg * byte/short access. Common-level will automatically use 32076888252Smrg * sparse mapping for MMIO. 32176888252Smrg */ 3221ae1b5e8Smrg 32376888252Smrg pCir->IOBase = 3240814a2baSmrg xf86MapPciMem(scrnIndex, VIDMEM_MMIO, pCir->PciTag, 32576888252Smrg pCir->IOAddress, pCir->IoMapSize); 32676888252Smrg if (pCir->IOBase == NULL) 32776888252Smrg return FALSE; 3281ae1b5e8Smrg 3291ae1b5e8Smrg#else 3301ae1b5e8Smrg void** result = (void**)&pCir->IOBase; 3311ae1b5e8Smrg int err = pci_device_map_range(pCir->PciInfo, 3321ae1b5e8Smrg pCir->IOAddress, 3331ae1b5e8Smrg pCir->IoMapSize, 3341ae1b5e8Smrg PCI_DEV_MAP_FLAG_WRITABLE, 3351ae1b5e8Smrg result); 3361ae1b5e8Smrg 3371ae1b5e8Smrg if (err) 3381ae1b5e8Smrg return FALSE; 3391ae1b5e8Smrg 3401ae1b5e8Smrg#endif 34176888252Smrg } 34276888252Smrg 34376888252Smrg#ifdef CIR_DEBUG 34476888252Smrg ErrorF("CirMapMem pCir->IOBase=0x%08x [length=%08x] from PCI=%08x\n", 34576888252Smrg pCir->IOBase, pCir->IoMapSize, pCir->IOAddress); 34676888252Smrg ErrorF("MMIO[GR31] = %2X\n", (int) 34776888252Smrg ((volatile unsigned char*) pCir->IOBase)[0x40]); 34876888252Smrg#endif 34976888252Smrg 35076888252Smrg return TRUE; 35176888252Smrg} 35276888252Smrg 35376888252Smrg 35476888252Smrg/* 35576888252Smrg * Unmap the framebuffer and MMIO memory. 35676888252Smrg */ 35776888252Smrg 3581ae1b5e8Smrg_X_EXPORT Bool 35976888252SmrgCirUnmapMem(CirPtr pCir, int scrnIndex) 36076888252Smrg{ 36176888252Smrg#ifdef CIR_DEBUG 36276888252Smrg ErrorF("CirUnmapMem\n"); 36376888252Smrg#endif 36476888252Smrg 36576888252Smrg if (pCir->IOBase != NULL) { 36676888252Smrg /* 36776888252Smrg * Unmap IO registers to virtual address space 36876888252Smrg */ 3691ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 37076888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->IOBase, pCir->IoMapSize); 3711ae1b5e8Smrg#else 3721ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->IOBase, pCir->IoMapSize); 3731ae1b5e8Smrg#endif 37476888252Smrg pCir->IOBase = NULL; 37576888252Smrg } 37676888252Smrg 3771ae1b5e8Smrg#ifndef XSERVER_LIBPCIACCESS 37876888252Smrg xf86UnMapVidMem(scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize); 3791ae1b5e8Smrg#else 3801ae1b5e8Smrg pci_device_unmap_range(pCir->PciInfo, (pointer)pCir->FbBase, pCir->FbMapSize); 3811ae1b5e8Smrg#endif 38276888252Smrg pCir->FbBase = NULL; 38376888252Smrg return TRUE; 38476888252Smrg} 38576888252Smrg 3861ae1b5e8Smrg_X_EXPORT void 38776888252SmrgcirProbeDDC(ScrnInfoPtr pScrn, int index) 38876888252Smrg{ 38976888252Smrg vbeInfoPtr pVbe; 39076888252Smrg 39176888252Smrg if (xf86LoadSubModule(pScrn, "vbe")) { 39276888252Smrg pVbe = VBEInit(NULL,index); 39376888252Smrg ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 39476888252Smrg vbeFree(pVbe); 39576888252Smrg } 39676888252Smrg} 397