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

📄 i830_driver.c

📁 是由intel提供的针对intel显卡915以上系列的linux驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* This is needed for SetDisplayDevices to work correctly on I915G. * Enable for all chipsets now as it has no bad side effects, apart * from slightly longer startup time. */#define I915G_WORKAROUNDstatic BoolSetDisplayDevices(ScrnInfoPtr pScrn, int devices){   I830Ptr pI830 = I830PTR(pScrn);   vbeInfoPtr pVbe = pI830->pVbe;   CARD32 temp;   int singlepipe = 0;#ifdef I915G_WORKAROUND   int getmode1;   Bool setmode = FALSE;#endif   DPRINTF(PFX, "SetDisplayDevices: devices 0x%x\n", devices);   if (!pI830->specifiedMonitor)      return TRUE;#ifdef I915G_WORKAROUND   if (pI830->preinit)      setmode = TRUE;   if (pI830->leaving)      setmode = FALSE;   if (pI830->closing)      setmode = FALSE;   if (setmode) {      VBEGetVBEMode(pVbe, &getmode1);      I830Set640x480(pScrn);   }#endif   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f64;   pVbe->pInt10->bx = 0x1;   pVbe->pInt10->cx = devices;   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {#ifdef I915G_WORKAROUND      if (setmode) {  	 VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);      }#endif      pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;      pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;      return TRUE;   }#ifdef I915G_WORKAROUND   if (setmode)      VBESetVBEMode(pI830->pVbe, getmode1 | 1<<15, NULL);#endif   if (devices & 0xff) {      pVbe->pInt10->num = 0x10;      pVbe->pInt10->ax = 0x5f64;      pVbe->pInt10->bx = 0x1;      pVbe->pInt10->cx = devices & 0xff;      xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);      if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Successfully set display devices to 0x%x.\n",devices & 0xff);         singlepipe = devices & 0xff00; /* set alternate */      } else {         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Failed to set display devices to 0x%x.\n",devices & 0xff);         singlepipe = devices;      }   } else      singlepipe = devices;    if (singlepipe == devices && devices & 0xff00) {      pVbe->pInt10->num = 0x10;      pVbe->pInt10->ax = 0x5f64;      pVbe->pInt10->bx = 0x1;      pVbe->pInt10->cx = devices & 0xff00;      xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);      if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Successfully set display devices to 0x%x.\n",devices & 0xff00);         singlepipe = devices & 0xff; /* set alternate */      } else {         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Failed to set display devices to 0x%x.\n",devices & 0xff00);         singlepipe = devices;      }   }    /* LVDS doesn't exist on these */   if (IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))      singlepipe &= ~(PIPE_LFP | (PIPE_LFP<<8));   if (pI830->availablePipes == 1)       singlepipe &= 0xFF;   /* Disable LVDS */   if (singlepipe & PIPE_LFP)  {      /* LFP on PipeA is unlikely! */      OUTREG(0x61200, INREG(0x61200) & ~0x80000000);      OUTREG(0x61204, INREG(0x61204) & ~0x00000001);      while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));      /* Fix up LVDS */      OUTREG(LVDS, (INREG(LVDS) & ~1<<30) | 0x80000300);      /* Enable LVDS */      OUTREG(0x61200, INREG(0x61200) | 0x80000000);      OUTREG(0x61204, INREG(0x61204) | 0x00000001);      while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Enabling LVDS directly. Pipe A.\n");   } else   if (singlepipe & (PIPE_LFP << 8))  {      OUTREG(0x61200, INREG(0x61200) & ~0x80000000);      OUTREG(0x61204, INREG(0x61204) & ~0x00000001);      while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));      /* Fix up LVDS */      OUTREG(LVDS, (INREG(LVDS) | 1<<30) | 0x80000300);      /* Enable LVDS */      OUTREG(0x61200, INREG(0x61200) | 0x80000000);      OUTREG(0x61204, INREG(0x61204) | 0x00000001);      while (!(INREG(0x61200) & 0x80000000) && !(INREG(0x61204) & 1));      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Enabling LVDS directly. Pipe B.\n");   }   else if (!(IS_I830(pI830) || IS_845G(pI830) || IS_I865G(pI830))) {      if (!(devices & (PIPE_LFP | PIPE_LFP<<8))) {         OUTREG(0x61200, INREG(0x61200) & ~0x80000000);         OUTREG(0x61204, INREG(0x61204) & ~0x00000001);         while ((INREG(0x61200) & 0x80000000) || (INREG(0x61204) & 1));         /* Fix up LVDS */         OUTREG(LVDS, (INREG(LVDS) | 1<<30) & ~0x80000300);         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Disabling LVDS directly.\n");      }   }   /* Now try to program the registers directly if the BIOS failed. */   temp = INREG(ADPA);   temp &= ~(ADPA_DAC_ENABLE | ADPA_PIPE_SELECT_MASK);   temp &= ~(ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE);   /* Turn on ADPA */   if (singlepipe & PIPE_CRT)  {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Enabling ADPA directly. Pipe A.\n");      temp |= ADPA_DAC_ENABLE | ADPA_PIPE_A_SELECT;      OUTREG(ADPA, temp);   } else   if (singlepipe & (PIPE_CRT << 8)) {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Enabling ADPA directly. Pipe B.\n");      temp |= ADPA_DAC_ENABLE | ADPA_PIPE_B_SELECT;      OUTREG(ADPA, temp);   }    else {      if (!(devices & (PIPE_CRT | PIPE_CRT<<8))) {         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,	 	"Disabling ADPA directly.\n");         temp |= ADPA_VSYNC_CNTL_DISABLE | ADPA_HSYNC_CNTL_DISABLE;         OUTREG(ADPA, temp);      }   }   xf86DrvMsg(pScrn->scrnIndex, X_WARNING,"Writing config directly to SWF0.\n");   temp = INREG(SWF0);   OUTREG(SWF0, (temp & ~(0xffff)) | (devices & 0xffff));   if (GetDisplayDevices(pScrn) != devices) {      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,		 "SetDisplayDevices failed with devices 0x%x instead of 0x%x\n",	         GetDisplayDevices(pScrn), devices);      return FALSE;   }   pI830->pipeEnabled[0] = (devices & 0xff) ? TRUE : FALSE;   pI830->pipeEnabled[1] = (devices & 0xff00) ? TRUE : FALSE;   return TRUE;}static BoolGetBIOSVersion(ScrnInfoPtr pScrn, unsigned int *version){   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;   DPRINTF(PFX, "GetBIOSVersion\n");   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f01;   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (Check5fStatus(pScrn, 0x5f01, pVbe->pInt10->ax)) {      *version = pVbe->pInt10->bx;      return TRUE;   }   *version = 0;   return FALSE;}static BoolGetDevicePresence(ScrnInfoPtr pScrn, Bool *required, int *attached,		  int *encoderPresent){   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;   DPRINTF(PFX, "GetDevicePresence\n");   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f64;   pVbe->pInt10->bx = 0x200;   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {      if (required)	 *required = ((pVbe->pInt10->bx & 0x1) == 0);      if (attached)	 *attached = (pVbe->pInt10->cx >> 8) & 0xff;      if (encoderPresent)	 *encoderPresent = pVbe->pInt10->cx & 0xff;      return TRUE;   } else      return FALSE;}static BoolGetDisplayInfo(ScrnInfoPtr pScrn, int device, Bool *attached, Bool *present,	       short *x, short *y){   vbeInfoPtr pVbe = I830PTR(pScrn)->pVbe;   DPRINTF(PFX, "GetDisplayInfo: device: 0x%x\n", device);   switch (device & 0xff) {   case 0x01:   case 0x02:   case 0x04:   case 0x08:   case 0x10:   case 0x20:      break;   default:      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		 "GetDisplayInfo: invalid device: 0x%x\n", device & 0xff);      return FALSE;   }   pVbe->pInt10->num = 0x10;   pVbe->pInt10->ax = 0x5f64;   pVbe->pInt10->bx = 0x300;   pVbe->pInt10->cx = device & 0xff;   xf86ExecX86int10_wrapper(pVbe->pInt10, pScrn);   if (Check5fStatus(pScrn, 0x5f64, pVbe->pInt10->ax)) {      if (attached)	 *attached = ((pVbe->pInt10->bx & 0x2) != 0);      if (present)	 *present = ((pVbe->pInt10->bx & 0x1) != 0);      if (pVbe->pInt10->cx != (device & 0xff)) {	 if (y) {	    *y = pVbe->pInt10->cx & 0xffff;	 }	 if (x) {	    *x = (pVbe->pInt10->cx >> 16) & 0xffff;	 }      }      return TRUE;   } else      return FALSE;}/* * Returns a string matching the device corresponding to the first bit set * in "device".  savedDevice is then set to device with that bit cleared. * Subsequent calls with device == -1 will use savedDevice. */static const char *displayDevices[] = {   "CRT",   "TV",   "DFP (digital flat panel)",   "LFP (local flat panel)",   "CRT2 (second CRT)",   "TV2 (second TV)",   "DFP2 (second digital flat panel)",   "LFP2 (second local flat panel)",   NULL};static const char *DeviceToString(int device){   static int savedDevice = -1;   int bit = 0;   const char *name;   if (device == -1) {      device = savedDevice;      bit = 0;   }   if (device == -1)      return NULL;   while (displayDevices[bit]) {      if (device & (1 << bit)) {	 name = displayDevices[bit];	 savedDevice = device & ~(1 << bit);	 bit++;	 return name;      }      bit++;   }   return NULL;}static voidPrintDisplayDeviceInfo(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   int pipe, n;   int displays;   DPRINTF(PFX, "PrintDisplayDeviceInfo\n");   displays = pI830->operatingDevices;   if (displays == -1) {      xf86DrvMsg(pScrn->scrnIndex, X_INFO,		 "No active display devices.\n");      return;   }   /* Check for active devices connected to each display pipe. */   for (n = 0; n < pI830->availablePipes; n++) {      pipe = ((displays >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);      if (pipe) {	 const char *name;	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,		    "Currently active displays on Pipe %c:\n", PIPE_NAME(n));	 name = DeviceToString(pipe);	 do {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t%s\n", name);	    name = DeviceToString(-1);	 } while (name);	 if (pipe & PIPE_UNKNOWN_ACTIVE)	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,		       "\tSome unknown display devices may also be present\n");      } else {	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,		    "No active displays on Pipe %c.\n", PIPE_NAME(n));      }      if (pI830->pipeDisplaySize[n].x2 != 0) {	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,		    "Lowest common panel size for pipe %c is %d x %d\n",		    PIPE_NAME(n), pI830->pipeDisplaySize[n].x2,		    pI830->pipeDisplaySize[n].y2);      } else if (pI830->pipeEnabled[n] && pipe & ~PIPE_CRT_ACTIVE) {	 xf86DrvMsg(pScrn->scrnIndex, X_INFO,		    "No display size information available for pipe %c.\n",		    PIPE_NAME(n));      }   }}static voidGetPipeSizes(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   int pipe, n;   DisplayType i;   DPRINTF(PFX, "GetPipeSizes\n");   for (n = 0; n < pI830->availablePipes; n++) {      pipe = (pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK;      pI830->pipeDisplaySize[n].x1 = pI830->pipeDisplaySize[n].y1 = 0;      pI830->pipeDisplaySize[n].x2 = pI830->pipeDisplaySize[n].y2 = 4096;      for (i = 0; i < NumKnownDisplayTypes; i++) {         if (pipe & (1 << i) & PIPE_SIZED_DISP_MASK) {	    if (pI830->displaySize[i].x2 != 0) {	       xf86DrvMsg(pScrn->scrnIndex, X_INFO,		          "Size of device %s is %d x %d\n",		          displayDevices[i],		          pI830->displaySize[i].x2,		          pI830->displaySize[i].y2);	       if (pI830->displaySize[i].x2 < pI830->pipeDisplaySize[n].x2)	          pI830->pipeDisplaySize[n].x2 = pI830->displaySize[i].x2;	       if (pI830->displaySize[i].y2 < pI830->pipeDisplaySize[n].y2)	          pI830->pipeDisplaySize[n].y2 = pI830->displaySize[i].y2;	    }         }      }      if (pI830->pipeDisplaySize[n].x2 == 4096)         pI830->pipeDisplaySize[n].x2 = 0;      if (pI830->pipeDisplaySize[n].y2 == 4096)         pI830->pipeDisplaySize[n].y2 = 0;   }}static BoolI830DetectDisplayDevice(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   int pipe, n;   DisplayType i;      /* This seems to lockup some Dell BIOS'. So it's on option to turn on */   if (pI830->displayInfo) {       xf86DrvMsg(pScrn->scrnIndex, X_INFO,		  "Broken BIOSes cause the system to hang here.\n"		  "\t      If you encounter this problem please add \n"		  "\t\t Option \"DisplayInfo\" \"FALSE\"\n"		  "\t      to the Device section of your XF86Config file.\n");      for (i = 0; i < NumKnownDisplayTypes; i++) {         if (GetDisplayInfo(pScrn, 1 << i, &pI830->displayAttached[i],			 &pI830->displayPresent[i],			 &pI830->displaySize[i].x2,			 &pI830->displaySize[i].y2)) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,		    "Display Info: %s: attached: %s, present: %s, size: "		    "(%d,%d)\n", displayDevices[i],		    BOOLTOSTRING(pI830->displayAttached[i]),		    BOOLTOSTRING(pI830->displayPresent[i]),		    pI830->displaySize[i].x2, pI830->displaySize[i].y2);         }      }   }   /* Check for active devices connected to each display pipe. */   for (n = 0; n < pI830->availablePipes; n++) {      pipe = ((pI830->operatingDevices >> PIPE_SHIFT(n)) & PIPE_ACTIVE_MASK);      if (pipe)	 pI830->pipeEnabled[n] = TRUE;      else	 pI830->pipeEnabled[n] = FALSE;   }   GetPipeSizes(pScrn);   return TRUE;}static intI830DetectMemory(ScrnInfoPtr pScrn){   I830Ptr pI830 = I830PTR(pScrn);   PCITAG bridge;   CARD16 gmch_ctrl;   int memsize = 0;   int range;   bridge = pciTag(0, 0, 0);		/* This is always the host bridge */   gmch_ctrl = pciReadWord(bridge, I830_GMCH_CTRL);   /* We need to reduce the stolen size, by the GTT and the popup.    * The GTT varying according the the FbMapSize and the popup is 4KB */   range = (pI830->FbMapSize / (1024*1024)) + 4;   if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) {      switch (gmch_ctrl & I830_GMCH_GMS_MASK) {      case I855_GMCH_GMS_STOLEN_1M:

⌨️ 快捷键说明

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