📄 r128_driver.c
字号:
case PCI_CHIP_RAGE128SM: case PCI_CHIP_RAGE128TF: case PCI_CHIP_RAGE128TL: case PCI_CHIP_RAGE128TR: /* FIXME: Rage 128 S[EFGHKLN], T[STU], P[ABCEGHIJKLMNOQSTUVWX] are * believed to be AGP, but need confirmation. <mharris@redhat.com> */ case PCI_CHIP_RAGE128PA: case PCI_CHIP_RAGE128PB: case PCI_CHIP_RAGE128PC: case PCI_CHIP_RAGE128PE: case PCI_CHIP_RAGE128PG: case PCI_CHIP_RAGE128PH: case PCI_CHIP_RAGE128PI: case PCI_CHIP_RAGE128PJ: case PCI_CHIP_RAGE128PK: case PCI_CHIP_RAGE128PL: case PCI_CHIP_RAGE128PM: case PCI_CHIP_RAGE128PN: case PCI_CHIP_RAGE128PO: case PCI_CHIP_RAGE128PQ: case PCI_CHIP_RAGE128PS: case PCI_CHIP_RAGE128PT: case PCI_CHIP_RAGE128PU: case PCI_CHIP_RAGE128PV: case PCI_CHIP_RAGE128PW: case PCI_CHIP_RAGE128PX: case PCI_CHIP_RAGE128TS: case PCI_CHIP_RAGE128TT: case PCI_CHIP_RAGE128TU: case PCI_CHIP_RAGE128SE: case PCI_CHIP_RAGE128SF: case PCI_CHIP_RAGE128SG: case PCI_CHIP_RAGE128SH: case PCI_CHIP_RAGE128SK: case PCI_CHIP_RAGE128SL: case PCI_CHIP_RAGE128SN: default: info->IsPCI = FALSE; break; } }#endif return TRUE;}static Bool R128PreInitDDC(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10){#if !defined(__powerpc__) && !defined(__alpha__) R128InfoPtr info = R128PTR(pScrn); vbeInfoPtr pVbe;#endif if (!xf86LoadSubModule(pScrn, "ddc")) return FALSE; xf86LoaderReqSymLists(ddcSymbols, NULL);#if defined(__powerpc__) || defined(__alpha__) /* Int10 is broken on PPC and some Alphas */ return TRUE;#else if (xf86LoadSubModule(pScrn, "vbe")) { xf86LoaderReqSymLists(vbeSymbols,NULL); pVbe = VBEInit(pInt10,info->pEnt->index); if (!pVbe) return FALSE; xf86SetDDCproperties(pScrn,xf86PrintEDID(vbeDoEDID(pVbe,NULL))); vbeFree(pVbe); return TRUE; } else return FALSE;#endif}/* This is called by R128PreInit to initialize gamma correction. */static Bool R128PreInitGamma(ScrnInfoPtr pScrn){ Gamma zeros = { 0.0, 0.0, 0.0 }; if (!xf86SetGamma(pScrn, zeros)) return FALSE; return TRUE;}static voidR128I2CGetBits(I2CBusPtr b, int *Clock, int *data){ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; R128InfoPtr info = R128PTR(pScrn); unsigned long val; unsigned char *R128MMIO = info->MMIO; /* Get the result. */ val = INREG(info->DDCReg); *Clock = (val & R128_GPIO_MONID_Y_3) != 0; *data = (val & R128_GPIO_MONID_Y_0) != 0;}static voidR128I2CPutBits(I2CBusPtr b, int Clock, int data){ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; R128InfoPtr info = R128PTR(pScrn); unsigned long val; unsigned char *R128MMIO = info->MMIO; val = INREG(info->DDCReg) & ~(CARD32)(R128_GPIO_MONID_EN_0 | R128_GPIO_MONID_EN_3); val |= (Clock ? 0:R128_GPIO_MONID_EN_3); val |= (data ? 0:R128_GPIO_MONID_EN_0); OUTREG(info->DDCReg, val);}static BoolR128I2cInit(ScrnInfoPtr pScrn){ R128InfoPtr info = R128PTR(pScrn); if ( xf86LoadSubModule(pScrn, "i2c") ) xf86LoaderReqSymLists(i2cSymbols,NULL); else{ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to load i2c module\n"); return FALSE; } info->pI2CBus = xf86CreateI2CBusRec(); if(!info->pI2CBus) return FALSE; info->pI2CBus->BusName = "DDC"; info->pI2CBus->scrnIndex = pScrn->scrnIndex; info->DDCReg = R128_GPIO_MONID; info->pI2CBus->I2CPutBits = R128I2CPutBits; info->pI2CBus->I2CGetBits = R128I2CGetBits; info->pI2CBus->AcknTimeout = 5; if (!xf86I2CBusInit(info->pI2CBus)) { return FALSE; } return TRUE;}/* return TRUE is a DFP is indeed connected to a DVI port */static Bool R128GetDFPInfo(ScrnInfoPtr pScrn){ R128InfoPtr info = R128PTR(pScrn); int i; xf86MonPtr MonInfo = NULL; xf86MonPtr ddc; unsigned char *R128MMIO = info->MMIO; if(!R128I2cInit(pScrn)){ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I2C initialization failed!\n"); } OUTREG(info->DDCReg, (INREG(info->DDCReg) | R128_GPIO_MONID_MASK_0 | R128_GPIO_MONID_MASK_3)); OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(CARD32)(R128_GPIO_MONID_A_0 | R128_GPIO_MONID_A_3)); MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus); if(!MonInfo) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No DFP detected\n"); return FALSE; } xf86SetDDCproperties(pScrn, MonInfo); ddc = pScrn->monitor->DDC; for(i=0; i<4; i++) { if((ddc->det_mon[i].type == 0) && (ddc->det_mon[i].section.d_timings.h_active > 0) && (ddc->det_mon[i].section.d_timings.v_active > 0)) { info->PanelXRes = ddc->det_mon[i].section.d_timings.h_active; info->PanelYRes = ddc->det_mon[i].section.d_timings.v_active; info->HOverPlus = ddc->det_mon[i].section.d_timings.h_sync_off; info->HSyncWidth = ddc->det_mon[i].section.d_timings.h_sync_width; info->HBlank = ddc->det_mon[i].section.d_timings.h_blanking; info->VOverPlus = ddc->det_mon[i].section.d_timings.v_sync_off; info->VSyncWidth = ddc->det_mon[i].section.d_timings.v_sync_width; info->VBlank = ddc->det_mon[i].section.d_timings.v_blanking; } } return TRUE;}static void R128SetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag){ int i; xf86MonPtr ddc = pScrn->monitor->DDC; if(flag) /*HSync*/ { for(i=0; i<4; i++) { if(ddc->det_mon[i].type == DS_RANGES) { pScrn->monitor->nHsync = 1; pScrn->monitor->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h; pScrn->monitor->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h; return; } } /*if no sync ranges detected in detailed timing table, let's try to derive them from supported VESA modes Are we doing too much here!!!? **/ i = 0; if(ddc->timings1.t1 & 0x02) /*800x600@56*/ { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 35.2; i++; } if(ddc->timings1.t1 & 0x04) /*640x480@75*/ { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 37.5; i++; } if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01)) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 37.9; i++; } if(ddc->timings1.t2 & 0x40) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 46.9; i++; } if((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08)) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 48.1; i++; } if(ddc->timings1.t2 & 0x04) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 56.5; i++; } if(ddc->timings1.t2 & 0x02) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 60.0; i++; } if(ddc->timings1.t2 & 0x01) { pScrn->monitor->hsync[i].lo = pScrn->monitor->hsync[i].hi = 64.0; i++; } pScrn->monitor->nHsync = i; } else /*Vrefresh*/ { for(i=0; i<4; i++) { if(ddc->det_mon[i].type == DS_RANGES) { pScrn->monitor->nVrefresh = 1; pScrn->monitor->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v; pScrn->monitor->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v; return; } } i = 0; if(ddc->timings1.t1 & 0x02) /*800x600@56*/ { pScrn->monitor->vrefresh[i].lo = pScrn->monitor->vrefresh[i].hi = 56; i++; } if((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08)) { pScrn->monitor->vrefresh[i].lo = pScrn->monitor->vrefresh[i].hi = 60; i++; } if(ddc->timings1.t2 & 0x04) { pScrn->monitor->vrefresh[i].lo = pScrn->monitor->vrefresh[i].hi = 70; i++; } if((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80)) { pScrn->monitor->vrefresh[i].lo = pScrn->monitor->vrefresh[i].hi = 72; i++; } if((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40) || (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01)) { pScrn->monitor->vrefresh[i].lo = pScrn->monitor->vrefresh[i].hi = 75; i++; } pScrn->monitor->nVrefresh = i; }}/*********** xfree's xf86ValidateModes routine deosn't work well with DFPs here is our own validation routine. All modes between 640<=XRes<=MaxRes and 480<=YRes<=MaxYRes will be permitted. NOTE: RageProII doesn't support rmx, can only work with the standard modes the monitor can support (scale).************/static int R128ValidateFPModes(ScrnInfoPtr pScrn){ int i, j, count=0, width, height; R128InfoPtr info = R128PTR(pScrn); DisplayModePtr last = NULL, new = NULL, first = NULL; xf86MonPtr ddc; /* Free any allocated modes during configuration. We don't need them*/ while (pScrn->modes) { xf86DeleteMode(&pScrn->modes, pScrn->modes); } while (pScrn->modePool) { xf86DeleteMode(&pScrn->modePool, pScrn->modePool); } pScrn->virtualX = pScrn->display->virtualX; pScrn->virtualY = pScrn->display->virtualY; /* If no mode specified in config, we use native resolution*/ if(!pScrn->display->modes[0]) { pScrn->display->modes[0] = xnfalloc(16); sprintf(pScrn->display->modes[0], "%dx%d", info->PanelXRes, info->PanelYRes); } for(i=0; pScrn->display->modes[i] != NULL; i++) { if (sscanf(pScrn->display->modes[i], "%dx%d", &width, &height) == 2) { if(width < 640 || width > info->PanelXRes || height < 480 || height > info->PanelYRes) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode %s is out of range.\n" "Valid mode should be between 640x480-%dx%d\n", pScrn->display->modes[i], info->PanelXRes, info->PanelYRes); continue; } new = xnfcalloc(1, sizeof(DisplayModeRec)); new->prev = last; new->name = xnfalloc(strlen(pScrn->display->modes[i]) + 1); strcpy(new->name, pScrn->display->modes[i]); new->HDisplay = new->CrtcHDisplay = width; new->VDisplay = new->CrtcVDisplay = height; ddc = pScrn->monitor->DDC; for(j=0; j<DET_TIMINGS; j++) { /*We use native mode clock only*/ if(ddc->det_mon[j].type == 0){ new->Clock = ddc->det_mon[j].section.d_timings.clock / 1000; break; } } if(new->prev) new->prev->next = new; last = new; if(!first) first = new; pScrn->display->virtualX = pScrn->virtualX = MAX(pScrn->virtualX, width); pScrn->display->virtualY = pScrn->virtualY = MAX(pScrn->virtualY, height); count++; } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode name %s is invalid\n", pScrn->display->modes[i]); continue; } } if(last) { last->next = first; first->prev = last; pScrn->modes = first; /*FIXME: May need to validate line pitch here*/ { int dummy = 0; switch(pScrn->depth / 8) { case 1: dummy = 128 - pScrn->virtualX % 128; break; case 2: dummy = 32 - pScrn->virtualX % 32; break; case 3: case 4: dummy = 16 - pScrn->virtualX % 16; } pScrn->displayWidth = pScrn->virtualX + dummy; } } return count;}/* This is called by R128PreInit to validate modes and compute parameters for all of the valid modes. */static Bool R128PreInitModes(ScrnInfoPtr pScrn){ R128InfoPtr info = R128PTR(pScrn); ClockRangePtr clockRanges; int modesFound; if(info->isDFP) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -