📄 atipreinit.c
字号:
}#endif /* AVOID_CPIO */ /* * Set colour weights. */ if (pATI->Chip < ATI_CHIP_264CT) pScreenInfo->rgbBits = 6; else pScreenInfo->rgbBits = 8; pATI->rgbBits = pScreenInfo->rgbBits; if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight)) { ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } if ((pScreenInfo->depth > 8) && ((pScreenInfo->weight.red != pScreenInfo->weight.blue) || (pScreenInfo->weight.red != (CARD32)(pScreenInfo->depth / 3)) || ((CARD32)pScreenInfo->depth != (pScreenInfo->weight.red + pScreenInfo->weight.green + pScreenInfo->weight.blue)))) { xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, "Driver does not support weight %d%d%d for depth %d.\n", (int)pScreenInfo->weight.red, (int)pScreenInfo->weight.green, (int)pScreenInfo->weight.blue, pScreenInfo->depth); ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } /* * Set default visual. */ if (!xf86SetDefaultVisual(pScreenInfo, -1)) { ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } if ((pScreenInfo->depth > 8) && (((pScreenInfo->defaultVisual | DynamicClass) != DirectColor) || ((pScreenInfo->defaultVisual == DirectColor) && (pATI->DAC == ATI_DAC_INTERNAL)))) { xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, "Driver does not support default visual %s for depth %d.\n", xf86GetVisualName(pScreenInfo->defaultVisual), pScreenInfo->depth); ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } /* * Set colour gamma. */#ifndef AVOID_CPIO if (pScreenInfo->depth > 1)#endif /* AVOID_CPIO */ { if (!xf86SetGamma(pScreenInfo, defaultGamma)) { ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } } pATI->depth = pScreenInfo->depth; pATI->bitsPerPixel = pScreenInfo->bitsPerPixel; pATI->weight = pScreenInfo->weight; pATI->XModifier = pATI->bitsPerPixel / UnitOf(pATI->bitsPerPixel); /* * Determine which CRT controller to use for video modes. */#ifndef AVOID_CPIO if ((pATI->Chip >= ATI_CHIP_88800GXC) && (pATI->depth >= 8) && (pATI->Chipset == ATI_CHIPSET_ATI))#endif /* AVOID_CPIO */ { pATI->NewHW.crtc = ATI_CRTC_MACH64; xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Using Mach64 accelerator CRTC.\n");#ifndef AVOID_CPIO if (pATI->VGAAdapter != ATI_ADAPTER_NONE) { /* * No need for VGA I/O resources during operating state (but they * are still decoded). */ pResources = xf86SetOperatingState(resVgaIo, pATI->iEntity, ResUnusedOpr); if (pResources) { xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "Logic error setting operating state for VGA I/O.\n"); xf86FreeResList(pResources); } if (pATI->CPIO_VGAWonder) { pResources = xf86SetOperatingState(pATI->VGAWonderResources, pATI->iEntity, ResUnusedOpr); if (pResources) { xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, "Logic error setting operating state for" " VGAWonder I/O.\n"); xf86FreeResList(pResources); } } }#endif /* AVOID_CPIO */ }#ifndef AVOID_CPIO else { pATI->NewHW.crtc = ATI_CRTC_VGA; xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "Using VGA CRTC.\n"); } /* Complain if VGA is needed but not there */ if ((pATI->NewHW.crtc == ATI_CRTC_VGA) || !pATI->OptionLinear) { /* VGA is required at this point */ if (pATI->VGAAdapter == ATI_ADAPTER_NONE) { xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, "VGA is not available through this adapter.\n"); ATILock(pATI); ATIPrintNoiseIfRequested(pATI, BIOS, BIOSSize); ATIUnmapApertures(pScreenInfo->scrnIndex, pATI); return FALSE; } if (pATI->Coprocessor != ATI_CHIP_NONE) { /* Ignore any 8514/A or Mach8 accelerator from this point on */ pATI->Adapter = pATI->VGAAdapter; /* Accelerator and VGA cannot share memory */ pATI->VideoRAM = 0; } }#endif /* AVOID_CPIO */ /* * Decide between the CRT and the panel. */ if (pATI->LCDPanelID >= 0) { if (!pATI->OptionPanelDisplay) { xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, "Using CRT interface and disabling digital flat panel.\n"); } else { unsigned HDisplay, VDisplay; CARD8 ClockMask, PostMask; /* * Determine porch data. This groks the mode on entry to extract * the width and position of its sync and blanking pulses, and * considers any overscan as part of the displayed area, given that * the overscan is also stretched. * * This also attempts to determine panel dimensions but cannot do * so for one that is "auto-stretched". */ if (pATI->Chip == ATI_CHIP_264LT) { pATIHW->lcd_gen_ctrl = inr(LCD_GEN_CTRL); /* Set up to read non-shadow registers */ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN) outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { pATIHW->lcd_index = inr(LCD_INDEX); pATIHW->config_panel = ATIMach64GetLCDReg(LCD_CONFIG_PANEL); pATIHW->lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); /* Set up to read non-shadow registers */ if (pATIHW->lcd_gen_ctrl & SHADOW_RW_EN) ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl & ~SHADOW_RW_EN); }#ifndef AVOID_CPIO if (!(pATIHW->crtc_gen_cntl & CRTC_EXT_DISP_EN)) { unsigned HBlankStart, HSyncStart, HSyncEnd, HBlankEnd, HTotal; unsigned VBlankStart, VSyncStart, VSyncEnd, VBlankEnd, VTotal; pATIHW->clock = (inb(R_GENMO) & 0x0CU) >> 2; pATIHW->crt[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U); pATIHW->crt[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U); pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); pATIHW->crt[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); pATIHW->crt[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U); pATIHW->crt[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP); pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP); pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); /* Switch to shadow registers */ if (pATI->Chip == ATI_CHIP_264LT) outr(LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ ATIMach64PutLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl | SHADOW_RW_EN); pATIHW->shadow_vga[2] = GetReg(CRTX(pATI->CPIO_VGABase), 0x02U); pATIHW->shadow_vga[3] = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U); pATIHW->shadow_vga[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U); pATIHW->shadow_vga[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U); pATIHW->shadow_vga[9] = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U); pATIHW->shadow_vga[21] = GetReg(CRTX(pATI->CPIO_VGABase), 0x15U); pATIHW->shadow_vga[22] = GetReg(CRTX(pATI->CPIO_VGABase), 0x16U); pATIHW->shadow_h_total_disp = inr(CRTC_H_TOTAL_DISP); pATIHW->shadow_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); pATIHW->shadow_v_total_disp = inr(CRTC_V_TOTAL_DISP); pATIHW->shadow_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); /* * HSyncStart and HSyncEnd should equal their shadow * counterparts. Otherwise, due to a chip bug, the panel might * not sync, regardless of which register set is used to drive * the panel. There are certain combinations of register * values where the panel does in fact sync, but it remains * impossible to accurately determine the horizontal sync pulse * timing actually seen by the panel. * * Note that this hardware bug does not affect the CRT output. */ if (((pATIHW->crtc_h_sync_strt_wid ^ pATIHW->shadow_h_sync_strt_wid) & (CRTC_H_SYNC_STRT | CRTC_H_SYNC_STRT_HI | CRTC_H_SYNC_WID))) { xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_NOTICE, 0, "Invalid horizontal sync pulse timing detected in mode" " on server entry.\n"); /* Don't trust input timing */ pATI->OptionLCDSync = TRUE; ModeType = 0; } /* Merge in shadow registers as appropriate */ if (pATIHW->lcd_gen_ctrl & SHADOW_EN) { pATIHW->crt[2] = pATIHW->shadow_vga[2]; pATIHW->crt[3] = pATIHW->shadow_vga[3]; pATIHW->crt[5] = pATIHW->shadow_vga[5]; /* XXX Does this apply to VGA? If so, what about the LT? */ if ((pATI->Chip < ATI_CHIP_264LTPRO) || !(pATIHW->config_panel & DONT_SHADOW_HEND)) { pATIHW->crtc_h_total_disp &= ~CRTC_H_DISP; pATIHW->crtc_h_total_disp |= pATIHW->shadow_h_total_disp & CRTC_H_DISP; } pATIHW->crtc_h_total_disp &= ~CRTC_H_TOTAL; pATIHW->crtc_h_total_disp |= pATIHW->shadow_h_total_disp & CRTC_H_TOTAL; pATIHW->crtc_h_sync_strt_wid = pATIHW->shadow_h_sync_strt_wid; /* XXX Does this apply to VGA? */ if (pATIHW->lcd_gen_ctrl & USE_SHADOWED_VEND) { pATIHW->crtc_v_total_disp &= ~CRTC_V_DISP; pATIHW->crtc_v_total_disp |= pATIHW->shadow_v_total_disp & CRTC_V_DISP; } if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) { pATIHW->crt[7] = pATIHW->shadow_vga[7]; pATIHW->crt[9] = pATIHW->shadow_vga[9]; pATIHW->crt[21] = pATIHW->shadow_vga[21]; pATIHW->crt[22] = pATIHW->shadow_vga[22]; pATIHW->crtc_v_total_disp &= ~CRTC_V_TOTAL; pATIHW->crtc_v_total_disp |= pATIHW->shadow_v_total_disp & CRTC_V_TOTAL; } } if (!(pATIHW->lcd_gen_ctrl & DONT_SHADOW_VPAR)) pATIHW->crtc_v_sync_strt_wid = pATIHW->shadow_v_sync_strt_wid; /* * Decipher input timing. This is complicated by the fact that * the full width of all timing parameters, except for the * blanking pulses, is only available through the accelerator * registers, not the VGA ones. Blanking pulse boundaries must * then be interpolated. * * Note that, in VGA mode, the accelerator's sync width fields * are actually end positions, not widths. */ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP); HSyncStart = (GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT_HI) * (MaxBits(CRTC_H_SYNC_STRT) + 1)) | GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT); HSyncEnd = (HSyncStart & ~MaxBits(CRTC_H_SYNC_WID)) | GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID); if (HSyncStart >= HSyncEnd) HSyncEnd += MaxBits(CRTC_H_SYNC_WID) + 1; HTotal = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL); HBlankStart = (HDisplay & ~0xFFU) | pATIHW->crt[2]; if (HDisplay > HBlankStart) HBlankStart += 0x0100U; HBlankEnd = (HSyncEnd & ~0x3FU) | ((pATIHW->crt[5] >> 2) & 0x20U) | (pATIHW->crt[3] & 0x1FU); if (HSyncEnd > (HBlankEnd + 1)) HBlankEnd += 0x40U; VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP); VSyncStart = GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT); VSyncEnd = (VSyncStart & ~MaxBits(CRTC_V_SYNC_END_VGA)) | GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_END_VGA);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -