⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i830_driver.c

📁 是由intel提供的针对intel显卡915以上系列的linux驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_driver.c,v 1.50 2004/02/20 00:06:00 alanh Exp $ *//**************************************************************************Copyright 2001 VA Linux Systems Inc., Fremont, California.Copyright © 2002 by David DawesAll Rights Reserved.Permission is hereby granted, free of charge, to any person obtaining acopy of this software and associated documentation files (the "Software"),to deal in the Software without restriction, including without limitationon the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice (including the nextparagraph) shall be included in all copies or substantial portions of theSoftware.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALLTHE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OROTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THEUSE OR OTHER DEALINGS IN THE SOFTWARE.**************************************************************************//* * Reformatted with GNU indent (2.2.8), using the following options: * *    -bad -bap -c41 -cd0 -ncdb -ci6 -cli0 -cp0 -ncs -d0 -di3 -i3 -ip3 -l78 *    -lp -npcs -psl -sob -ss -br -ce -sc -hnl * * This provides a good match with the original i810 code and preferred * XFree86 formatting conventions. * * When editing this driver, please follow the existing formatting, and edit * with <TAB> characters expanded at 8-column intervals. *//* * Authors: Jeff Hartmann <jhartmann@valinux.com> *          Abraham van der Merwe <abraham@2d3d.co.za> *          David Dawes <dawes@xfree86.org> *          Alan Hourihane <alanh@tungstengraphics.com> *//* * Mode handling is based on the VESA driver written by: * Paulo César Pereira de Andrade <pcpa@conectiva.com.br> *//* * Changes: * *    23/08/2001 Abraham van der Merwe <abraham@2d3d.co.za> *        - Fixed display timing bug (mode information for some *          modes were not initialized correctly) *        - Added workarounds for GTT corruptions (I don't adjust *          the pitches for 1280x and 1600x modes so we don't *          need extra memory) *        - The code will now default to 60Hz if LFP is connected *        - Added different refresh rate setting code to work *          around 0x4f02 BIOS bug *        - BIOS workaround for some mode sets (I use legacy BIOS *          calls for setting those) *        - Removed 0x4f04, 0x01 (save state) BIOS call which causes *          LFP to malfunction (do some house keeping and restore *          modes ourselves instead - not perfect, but at least the *          LFP is working now) *        - Several other smaller bug fixes * *    06/09/2001 Abraham van der Merwe <abraham@2d3d.co.za> *        - Preliminary local memory support (works without agpgart) *        - DGA fixes (the code were still using i810 mode sets, etc.) *        - agpgart fixes * *    18/09/2001 *        - Proper local memory support (should work correctly now *          with/without agpgart module) *        - more agpgart fixes *        - got rid of incorrect GTT adjustments * *    09/10/2001 *        - Changed the DPRINTF() variadic macro to an ANSI C compatible *          version * *    10/10/2001 *        - Fixed DPRINTF_stub(). I forgot the __...__ macros in there *          instead of the function arguments :P *        - Added a workaround for the 1600x1200 bug (Text mode corrupts *          when you exit from any 1600x1200 mode and 1280x1024@85Hz. I *          suspect this is a BIOS bug (hence the 1280x1024@85Hz case)). *          For now I'm switching to 800x600@60Hz then to 80x25 text mode *          and then restoring the registers - very ugly indeed. * *    15/10/2001 *        - Improved 1600x1200 mode set workaround. The previous workaround *          was causing mode set problems later on. * *    18/10/2001 *        - Fixed a bug in I830BIOSLeaveVT() which caused a bug when you *          switched VT's *//* *    07/2002 David Dawes *        - Add Intel(R) 855GM/852GM support. *//* *    07/2002 David Dawes *        - Cleanup code formatting. *        - Improve VESA mode selection, and fix refresh rate selection. *        - Don't duplicate functions provided in 4.2 vbe modules. *        - Don't duplicate functions provided in the vgahw module. *        - Rewrite memory allocation. *        - Rewrite initialisation and save/restore state handling. *        - Decouple the i810 support from i830 and later. *        - Remove various unnecessary hacks and workarounds. *        - Fix an 845G problem with the ring buffer not in pre-allocated *          memory. *        - Fix screen blanking. *        - Clear the screen at startup so you don't see the previous session. *        - Fix some HW cursor glitches, and turn HW cursor off at VT switch *          and exit. * *    08/2002 Keith Whitwell *        - Fix DRI initialisation. * * *    08/2002 Alan Hourihane and David Dawes *        - Add XVideo support. * * *    10/2002 David Dawes *        - Add Intel(R) 865G support. * * *    01/2004 Alan Hourihane *        - Add Intel(R) 915G support. *        - Add Dual Head and Clone capabilities. *        - Add lid status checking *        - Fix Xvideo with high-res LFP's *        - Add ARGB HW cursor support * *    05/2005 Alan Hourihane *        - Add Intel(R) 945G support. * *    09/2005 Alan Hourihane *        - Add Intel(R) 945GM support. */#ifndef PRINT_MODE_INFO#define PRINT_MODE_INFO 0#endif#include "xf86.h"#include "xf86_ansic.h"#include "xf86_OSproc.h"#include "xf86Resources.h"#include "xf86RAC.h"#include "xf86cmap.h"#include "compiler.h"#include "mibstore.h"#include "vgaHW.h"#include "mipointer.h"#include "micmap.h"#include "shadowfb.h"#include <X11/extensions/randr.h>#include "fb.h"#include "miscstruct.h"#include "xf86xv.h"#include <X11/extensions/Xv.h>#include "vbe.h"#include "vbeModes.h"#include "shadow.h"#include "i830.h"#ifdef HAS_MTRR_SUPPORT#include <asm/mtrr.h>#endif#ifdef XF86DRI#include "dri.h"#endif#define BIT(x) (1 << (x))#define MAX(a,b) ((a) > (b) ? (a) : (b))#define NB_OF(x) (sizeof (x) / sizeof (*x))/* *INDENT-OFF* */static SymTabRec I830BIOSChipsets[] = {   {PCI_CHIP_I830_M,		"i830"},   {PCI_CHIP_845_G,		"845G"},   {PCI_CHIP_I855_GM,		"852GM/855GM"},   {PCI_CHIP_I865_G,		"865G"},   {PCI_CHIP_I915_G,		"915G"},   {PCI_CHIP_E7221_G,		"E7221 (i915)"},   {PCI_CHIP_I915_GM,		"915GM"},   {PCI_CHIP_I945_G,		"945G"},   {PCI_CHIP_I945_GM,		"945GM"},   {-1,				NULL}};static PciChipsets I830BIOSPciChipsets[] = {   {PCI_CHIP_I830_M,		PCI_CHIP_I830_M,	RES_SHARED_VGA},   {PCI_CHIP_845_G,		PCI_CHIP_845_G,		RES_SHARED_VGA},   {PCI_CHIP_I855_GM,		PCI_CHIP_I855_GM,	RES_SHARED_VGA},   {PCI_CHIP_I865_G,		PCI_CHIP_I865_G,	RES_SHARED_VGA},   {PCI_CHIP_I915_G,		PCI_CHIP_I915_G,	RES_SHARED_VGA},   {PCI_CHIP_E7221_G,		PCI_CHIP_E7221_G,	RES_SHARED_VGA},   {PCI_CHIP_I915_GM,		PCI_CHIP_I915_GM,	RES_SHARED_VGA},   {PCI_CHIP_I945_G,		PCI_CHIP_I945_G,	RES_SHARED_VGA},   {PCI_CHIP_I945_GM,		PCI_CHIP_I945_GM,	RES_SHARED_VGA},   {-1,				-1,			RES_UNDEFINED}};/* * Note: "ColorKey" is provided for compatibility with the i810 driver. * However, the correct option name is "VideoKey".  "ColorKey" usually * refers to the tranparency key for 8+24 overlays, not for video overlays. */typedef enum {   OPTION_NOACCEL,   OPTION_SW_CURSOR,   OPTION_CACHE_LINES,   OPTION_DRI,   OPTION_PAGEFLIP,   OPTION_XVIDEO,   OPTION_VIDEO_KEY,   OPTION_COLOR_KEY,   OPTION_VBE_RESTORE,   OPTION_DISPLAY_INFO,   OPTION_DEVICE_PRESENCE,   OPTION_MONITOR_LAYOUT,   OPTION_CLONE,   OPTION_CLONE_REFRESH,   OPTION_CHECKDEVICES,   OPTION_FIXEDPIPE,   OPTION_ROTATE} I830Opts;static OptionInfoRec I830BIOSOptions[] = {   {OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_SW_CURSOR,	"SWcursor",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_CACHE_LINES,	"CacheLines",	OPTV_INTEGER,	{0},	FALSE},   {OPTION_DRI,		"DRI",		OPTV_BOOLEAN,	{0},	TRUE},   {OPTION_PAGEFLIP,	"PageFlip",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_XVIDEO,	"XVideo",	OPTV_BOOLEAN,	{0},	TRUE},   {OPTION_COLOR_KEY,	"ColorKey",	OPTV_INTEGER,	{0},	FALSE},   {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},   {OPTION_VBE_RESTORE,	"VBERestore",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_DISPLAY_INFO,"DisplayInfo",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_DEVICE_PRESENCE,"DevicePresence",OPTV_BOOLEAN,{0},	FALSE},   {OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0},	FALSE},   {OPTION_CLONE,	"Clone",	OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER,	{0},	FALSE},   {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},   {OPTION_FIXEDPIPE,   "FixedPipe",    OPTV_ANYSTR, 	{0},	FALSE},   {OPTION_ROTATE,      "Rotate",       OPTV_ANYSTR,    {0},    FALSE},   {-1,			NULL,		OPTV_NONE,	{0},	FALSE}};/* *INDENT-ON* */static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,					  int PowerManagementMode, int flags);static void I830BIOSAdjustFrame(int scrnIndex, int x, int y, int flags);static Bool I830BIOSCloseScreen(int scrnIndex, ScreenPtr pScreen);static Bool I830BIOSSaveScreen(ScreenPtr pScreen, int unblack);static Bool I830BIOSEnterVT(int scrnIndex, int flags);static Bool I830VESASetVBEMode(ScrnInfoPtr pScrn, int mode,			       VbeCRTCInfoBlock *block);static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg);static Bool SetPipeAccess(ScrnInfoPtr pScrn);extern int I830EntityIndex;/* temporary */extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);#ifdef I830DEBUGvoidI830DPRINTF_stub(const char *filename, int line, const char *function,		 const char *fmt, ...){   va_list ap;   ErrorF("\n##############################################\n"	  "*** In function %s, on line %d, in file %s ***\n",	  function, line, filename);   va_start(ap, fmt);   VErrorF(fmt, ap);   va_end(ap);   ErrorF("##############################################\n\n");}#else /* #ifdef I830DEBUG */voidI830DPRINTF_stub(const char *filename, int line, const char *function,		 const char *fmt, ...){   /* do nothing */}#endif /* #ifdef I830DEBUG *//* XXX Check if this is still needed. */const OptionInfoRec *I830BIOSAvailableOptions(int chipid, int busid){   int i;   for (i = 0; I830BIOSPciChipsets[i].PCIid > 0; i++) {      if (chipid == I830BIOSPciChipsets[i].PCIid)	 return I830BIOSOptions;   }   return NULL;}static BoolI830BIOSGetRec(ScrnInfoPtr pScrn){   I830Ptr pI830;   if (pScrn->driverPrivate)      return TRUE;   pI830 = pScrn->driverPrivate = xnfcalloc(sizeof(I830Rec), 1);   pI830->vesa = xnfcalloc(sizeof(VESARec), 1);   return TRUE;}static voidI830BIOSFreeRec(ScrnInfoPtr pScrn){   I830Ptr pI830;   VESAPtr pVesa;   DisplayModePtr mode;   if (!pScrn)      return;   if (!pScrn->driverPrivate)      return;   pI830 = I830PTR(pScrn);   mode = pScrn->modes;   if (mode) {      do {	 if (mode->Private) {	    VbeModeInfoData *data = (VbeModeInfoData *) mode->Private;	    if (data->block)	       xfree(data->block);	    xfree(data);	    mode->Private = NULL;	 }	 mode = mode->next;      } while (mode && mode != pScrn->modes);   }   if (pI830->vbeInfo)      VBEFreeVBEInfo(pI830->vbeInfo);   if (pI830->pVbe)      vbeFree(pI830->pVbe);   pVesa = pI830->vesa;   if (pVesa->monitor)      xfree(pVesa->monitor);   if (pVesa->savedPal)      xfree(pVesa->savedPal);   xfree(pVesa);   xfree(pScrn->driverPrivate);   pScrn->driverPrivate = NULL;}static voidI830BIOSProbeDDC(ScrnInfoPtr pScrn, int index){   vbeInfoPtr pVbe;   /* The vbe module gets loaded in PreInit(), so no need to load it here. */   pVbe = VBEInit(NULL, index);   ConfiguredMonitor = vbeDoEDID(pVbe, NULL);}/* Various extended video BIOS functions.  * 100 and 120Hz aren't really supported, they work but only get close * to the requested refresh, and really not close enough. * I've seen 100Hz come out at 104Hz, and 120Hz come out at 128Hz */const int i830refreshes[] = {   43, 56, 60, 70, 72, 75, 85 /* 100, 120 */};static const int nrefreshes = sizeof(i830refreshes) / sizeof(i830refreshes[0]);static BoolCheck5fStatus(ScrnInfoPtr pScrn, int func, int ax){   if (ax == 0x005f)      return TRUE;   else if (ax == 0x015f) {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		 "Extended BIOS function 0x%04x failed.\n", func);      return FALSE;   } else if ((ax & 0xff) != 0x5f) {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		 "Extended BIOS function 0x%04x not supported.\n", func);      return FALSE;   } else {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		 "Extended BIOS function 0x%04x returns 0x%04x.\n",		 func, ax & 0xffff);      return FALSE;   }}static intGetToggleList(ScrnInfoPtr pScrn, int toggle){   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;   DPRINTF(PFX, "GetToggleList\n");   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f64;   pVbe->pInt10->bx = 0x500;    pVbe->pInt10->bx |= toggle;   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Toggle (%d) 0x%x\n", toggle, pVbe->pInt10->cx);      return pVbe->pInt10->cx & 0xffff;   }   return 0;}static intGetNextDisplayDeviceList(ScrnInfoPtr pScrn, int toggle){   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;   int devices = 0;   int pipe = 0;   int i;   DPRINTF(PFX, "GetNextDisplayDeviceList\n");   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f64;   pVbe->pInt10->bx = 0xA00;   pVbe->pInt10->bx |= toggle;   pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);   pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (!Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax))      return 0;   for (i=0; i<(pVbe->pInt10->cx & 0xff); i++) {      CARD32 VODA = (CARD32)((CARD32*)pVbe->memory)[i];      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Next ACPI _DGS [%d] 0x%lx\n",		i, VODA);      /* Check if it's a custom Video Output Device Attribute */      if (!(VODA & 0x80000000))          continue;      pipe = (VODA & 0x000000F0) >> 4;      if (pipe != 0 && pipe != 1) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -