📄 i830_driver.c
字号:
/* 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 + -