diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_accel.c | 5 | ||||
-rw-r--r-- | src/radeon_driver.c | 448 | ||||
-rw-r--r-- | src/radeon_probe.c | 10 | ||||
-rw-r--r-- | src/radeon_reg.h | 62 | ||||
-rw-r--r-- | src/radeon_video.c | 33 |
6 files changed, 503 insertions, 57 deletions
diff --git a/src/radeon.h b/src/radeon.h index 3e8f554..6c2c628 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -130,7 +130,9 @@ typedef struct { CARD32 cap1_trig_cntl; CARD32 bus_cntl; CARD32 surface_cntl; + CARD32 bios_4_scratch; CARD32 bios_5_scratch; + CARD32 bios_6_scratch; /* Other registers to save for VT switches */ CARD32 dp_datatype; CARD32 rbbm_soft_reset; diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 6bebd6c..c91c5cc 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -175,6 +175,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); if (info->R300CGWorkaround) R300CGWorkaround(pScrn); +#if 0 /* taken care of by new PM code */ /* Some ASICs have bugs with dynamic-on feature, which are * ASIC-version dependent, so we force all blocks on for now */ @@ -191,8 +192,11 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) OUTPLL(RADEON_SCLK_MORE_CNTL, tmp | RADEON_SCLK_MORE_FORCEON); } } +#endif /* new PM code */ mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL); + +#if 0 /* handled by new PM code */ OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | RADEON_FORCEON_MCLKA | RADEON_FORCEON_MCLKB | @@ -200,6 +204,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC | RADEON_FORCEON_AIC)); +#endif /* new PM code */ /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some * unexpected behaviour on some machines. Here we use diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 6c4d184..5bcbb82 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -115,6 +115,7 @@ static void RADEONInitDispBandwidth(ScrnInfoPtr pScrn); static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); static int RADEONValidateMergeModes(ScrnInfoPtr pScrn); +static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); /* psuedo xinerama support */ @@ -160,7 +161,8 @@ typedef enum { OPTION_RENDER_ACCEL, OPTION_SUBPIXEL_ORDER, #endif - OPTION_SHOWCACHE + OPTION_SHOWCACHE, + OPTION_DYNAMIC_CLOCKS } RADEONOpts; const OptionInfoRec RADEONOptions[] = { @@ -204,6 +206,7 @@ const OptionInfoRec RADEONOptions[] = { { OPTION_SUBPIXEL_ORDER, "SubPixelOrder", OPTV_ANYSTR, {0}, FALSE }, #endif { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_DYNAMIC_CLOCKS, "DynamicClocks", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -929,8 +932,17 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT if (*MonInfo) { if ((*MonInfo)->rawData[0x14] & 0x80) { - if (INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON) MonType = MT_LCD; - else MonType = MT_DFP; + /* Note some laptops have a DVI output that uses internal TMDS, + * when its DVI is enabled by hotkey, LVDS panel is not used. + * In this case, the laptop is configured as DVI+VGA as a normal + * desktop card. + * Also for laptop, when X starts with lid closed (no DVI connection) + * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel. + */ + if ((INREG(RADEON_FP_GEN_CNTL) & (1<<7)) || !info->IsMobility) + MonType = MT_DFP; + else + MonType = MT_LCD; } else MonType = MT_CRT; } else MonType = MT_NONE; @@ -1572,7 +1584,7 @@ static Bool RADEONGetBIOSParameters(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10) info->PanelXRes = RADEON_BIOS16(tmp+25); info->PanelYRes = RADEON_BIOS16(tmp+27); - xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n", + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Size from BIOS: %dx%d\n", info->PanelXRes, info->PanelYRes); info->PanelPwrDly = RADEON_BIOS16(tmp+44); @@ -4255,7 +4267,7 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, if (info->CPStarted) DRILock(pScrn->pScreen, 0); #endif - if (info->accelOn) info->accel->Sync(pScrn); + if (info->accelOn && pScrn->pScreen) info->accel->Sync(pScrn); if (info->FBDev) { fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual); @@ -4430,6 +4442,13 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->PaletteSavedOnVT = FALSE; RADEONSave(pScrn); + + if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) { + RADEONSetDynamicClock(pScrn, 1); + } else { + RADEONSetDynamicClock(pScrn, 0); + } + if (info->FBDev) { unsigned char *RADEONMMIO = info->MMIO; @@ -4819,10 +4838,6 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (RADEONAccelInit(pScreen)) { xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n"); info->accelOn = TRUE; - - /* FIXME: Figure out why this was added because it shouldn't be! */ - /* This is needed by the DRI and XAA code for shared entities */ - pScrn->pScreen = pScreen; } else { xf86DrvMsg(scrnIndex, X_ERROR, "Acceleration initialization failed\n"); @@ -5103,6 +5118,12 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_GRPH_BUFFER_CNTL, INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000); + if (info->IsMobility) { + OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); + OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); + OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch); + } + if (info->DisplayType != MT_DFP) { unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); @@ -5271,11 +5292,6 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn, | RADEON_PPLL_ATOMIC_UPDATE_EN | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN)); - xf86DrvMsg(0, X_INFO, "Wrote: rd=%ld, fd=%ld, pd=%ld\n", - restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, - restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK, - (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16); - RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n", restore->ppll_ref_div, restore->ppll_div_3, @@ -5534,7 +5550,9 @@ static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL); save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL); save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL); + save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH); save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); + save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); if (info->ChipFamily == CHIP_FAMILY_RV280) { /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ @@ -6110,10 +6128,7 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, int format; int hsync_start; int hsync_wid; - int hsync_fudge; int vsync_wid; - int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; - int hsync_fudge_fp[] = { 0x02, 0x02, 0x00, 0x00, 0x05, 0x05 }; switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; @@ -6131,7 +6146,6 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, if ((info->DisplayType == MT_DFP) || (info->DisplayType == MT_LCD)) { - hsync_fudge = hsync_fudge_fp[format-1]; if (mode->Flags & RADEON_USE_RMX) { #if 0 mode->CrtcHDisplay = info->PanelXRes; @@ -6146,8 +6160,6 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, mode->Clock = info->DotClock; mode->Flags = info->Flags | RADEON_USE_RMX; } - } else { - hsync_fudge = hsync_fudge_default[format-1]; } save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN @@ -6185,7 +6197,7 @@ static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; if (!hsync_wid) hsync_wid = 1; - hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + hsync_start = mode->CrtcHSyncStart - 8; save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | ((hsync_wid & 0x3f) << 16) @@ -6279,9 +6291,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, int format; int hsync_start; int hsync_wid; - int hsync_fudge; int vsync_wid; - int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 }; switch (info->CurrentLayout.pixel_code) { case 4: format = 1; break; @@ -6297,8 +6307,6 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, return FALSE; } - hsync_fudge = hsync_fudge_default[format-1]; - save->crtc2_gen_cntl = (RADEON_CRTC2_EN | RADEON_CRTC2_CRT2_ON | (format << 8) @@ -6362,7 +6370,7 @@ static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save, hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; if (!hsync_wid) hsync_wid = 1; - hsync_start = mode->CrtcHSyncStart - 8 + hsync_fudge; + hsync_start = mode->CrtcHSyncStart - 8; save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff) | ((hsync_wid & 0x3f) << 16) @@ -6590,15 +6598,6 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else { if (info->DisplayType == MT_LCD) { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - - /* BIOS will use this setting to reset displays upon lid close/open. - * Here we let BIOS controls LCD, but the driver will control the external CRT. - */ - if (info->MergedFB || pRADEONEnt->HasSecondary) - save->bios_5_scratch = 0x01020201; - else - save->bios_5_scratch = orig->bios_5_scratch; save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); @@ -6640,6 +6639,36 @@ static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, } } + if (info->IsMobility) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + + /* To work correctly with laptop hotkeys. + * Since there is no machnism for accessing ACPI evnets + * and the driver currently doesn't know how to validate + * a mode dynamically, we have to tell BIOS don't do + * display switching after X has started. + * If LCD is on, lid close/open should still work + * with below settings + */ + if (info->DisplayType == MT_LCD) { + if (pRADEONEnt->MonType2 == MT_CRT) + save->bios_5_scratch = 0x0201; + else if (pRADEONEnt->MonType2 == MT_DFP) + save->bios_5_scratch = 0x0801; + else + save->bios_5_scratch = orig->bios_5_scratch; + } else { + if (pRADEONEnt->MonType2 == MT_CRT) + save->bios_5_scratch = 0x0200; + else if (pRADEONEnt->MonType2 == MT_DFP) + save->bios_5_scratch = 0x0800; + else + save->bios_5_scratch = 0x0; + } + save->bios_4_scratch = 0x4; + save->bios_6_scratch = orig->bios_6_scratch | 0x40000000; + } + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; save->fp_crtc_v_total_disp = save->crtc_v_total_disp; save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; @@ -7682,3 +7711,352 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn) } } } + +static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + switch(mode) { + case 0: /* Turn everything OFF (ForceON to everything)*/ + if ( !info->HasCRTC2 ) { + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_RB); + OUTPLL(RADEON_SCLK_CNTL, tmp); + } else if (info->ChipFamily == CHIP_FAMILY_RV350) { + /* for RV350/M10, no delays are required. */ + tmp = INPLL(pScrn, R300_SCLK_CNTL2); + tmp |= (R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + OUTPLL(R300_SCLK_CNTL2, tmp); + + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + OUTPLL(RADEON_SCLK_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); + tmp |= RADEON_SCLK_MORE_FORCEON; + OUTPLL(RADEON_SCLK_MORE_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_MCLK_CNTL); + tmp |= (RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB | + RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC); + OUTPLL(RADEON_MCLK_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); + tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb | + R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); + OUTPLL(RADEON_VCLK_ECP_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); + OUTPLL(RADEON_PIXCLKS_CNTL, tmp); + } else { + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); + tmp |= RADEON_SCLK_FORCE_SE; + + if ( !info->HasCRTC2 ) { + tmp |= ( RADEON_SCLK_FORCE_RB | + RADEON_SCLK_FORCE_TDM | + RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_PB | + RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_VIP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_HDP ); + } else if ((info->ChipFamily == CHIP_FAMILY_R300) || + (info->ChipFamily == CHIP_FAMILY_R350)) { + tmp |= ( RADEON_SCLK_FORCE_HDP | + RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_DISP2 | + RADEON_SCLK_FORCE_TOP | + RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP); + } + OUTREG(RADEON_SCLK_CNTL, tmp); + + usleep(16000); + + if ((info->ChipFamily == CHIP_FAMILY_R300) || + (info->ChipFamily == CHIP_FAMILY_R350)) { + tmp = INPLL(pScrn, R300_SCLK_CNTL2); + tmp |= ( R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + OUTPLL(R300_SCLK_CNTL2, tmp); + usleep(16000); + } + + if (info->IsIGP) { + tmp = INPLL(pScrn, RADEON_MCLK_CNTL); + tmp &= ~(RADEON_FORCEON_MCLKA | + RADEON_FORCEON_YCLKA); + OUTREG(RADEON_MCLK_CNTL, tmp); + usleep(16000); + } + + if ((info->ChipFamily == CHIP_FAMILY_RV200) || + (info->ChipFamily == CHIP_FAMILY_RV250) || + (info->ChipFamily == CHIP_FAMILY_RV280)) { + tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); + tmp |= RADEON_SCLK_MORE_FORCEON; + OUTPLL(RADEON_SCLK_MORE_CNTL, tmp); + usleep(16000); + } + + tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + OUTREG(RADEON_PIXCLKS_CNTL, tmp); + usleep(16000); + + tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); + tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + OUTPLL(RADEON_VCLK_ECP_CNTL, tmp); + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Disabled\n"); + break; + case 1: + if (!info->HasCRTC2) { + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + if ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) > + RADEON_CFG_ATI_REV_A13) { + tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB); + } + tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | + RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | + RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | + RADEON_SCLK_FORCE_TDM); + OUTPLL (RADEON_SCLK_CNTL, tmp); + } else if ((info->ChipFamily == CHIP_FAMILY_R300) || + (info->ChipFamily == CHIP_FAMILY_R350) || + (info->ChipFamily == CHIP_FAMILY_RV350)) { + if (info->ChipFamily == CHIP_FAMILY_RV350) { + tmp = INPLL(pScrn, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | + R300_SCLK_GA_MAX_DYN_STOP_LAT | + R300_SCLK_CBA_MAX_DYN_STOP_LAT); + OUTPLL(R300_SCLK_CNTL2, tmp); + + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | + RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | + RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | + R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | + RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | + R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | + R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | + R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); + tmp |= RADEON_DYN_STOP_LAT_MASK; + OUTPLL(RADEON_SCLK_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; + OUTPLL(RADEON_SCLK_MORE_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + OUTPLL(RADEON_VCLK_ECP_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | + R300_DVOCLK_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + R300_PIXCLK_DVO_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb | + R300_PIXCLK_TRANS_ALWAYS_ONb | + R300_PIXCLK_TVO_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb | + R300_P2G2CLK_ALWAYS_ONb); + OUTPLL(RADEON_PIXCLKS_CNTL, tmp); + + tmp = INPLL(pScrn, RADEON_MCLK_MISC); + tmp |= (RADEON_MC_MCLK_DYN_ENABLE | + RADEON_IO_MCLK_DYN_ENABLE); + OUTPLL(RADEON_MCLK_MISC, tmp); + + tmp = INPLL(pScrn, RADEON_MCLK_CNTL); + tmp |= (RADEON_FORCEON_MCLKA | + RADEON_FORCEON_MCLKB); + + tmp &= ~(RADEON_FORCEON_YCLKA | + RADEON_FORCEON_YCLKB | + RADEON_FORCEON_MC); + + /* Some releases of vbios have set DISABLE_MC_MCLKA + and DISABLE_MC_MCLKB bits in the vbios table. Setting these + bits will cause H/W hang when reading video memory with dynamic clocking + enabled. */ + if ((tmp & R300_DISABLE_MC_MCLKA) && + (tmp & R300_DISABLE_MC_MCLKB)) { + /* If both bits are set, then check the active channels */ + tmp = INPLL(pScrn, RADEON_MCLK_CNTL); + if (info->RamWidth == 64) { + if (INREG(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY) + tmp &= ~R300_DISABLE_MC_MCLKB; + else + tmp &= ~R300_DISABLE_MC_MCLKA; + } else { + tmp &= ~(R300_DISABLE_MC_MCLKA | + R300_DISABLE_MC_MCLKB); + } + } + + OUTPLL(RADEON_MCLK_CNTL, tmp); + } else { + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + tmp &= ~(R300_SCLK_FORCE_VAP); + tmp |= RADEON_SCLK_FORCE_CP; + OUTPLL(RADEON_SCLK_CNTL, tmp); + usleep(15000); + + tmp = INPLL(pScrn, R300_SCLK_CNTL2); + tmp &= ~(R300_SCLK_FORCE_TCL | + R300_SCLK_FORCE_GA | + R300_SCLK_FORCE_CBA); + OUTPLL(R300_SCLK_CNTL2, tmp); + } + } else { + tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL); + + tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | + RADEON_DISP_DYN_STOP_LAT_MASK | + RADEON_DYN_STOP_MODE_MASK); + + tmp |= (RADEON_ENGIN_DYNCLK_MODE | + (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); + OUTPLL(RADEON_CLK_PWRMGT_CNTL, tmp); + usleep(15000); + + tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL); + tmp |= RADEON_SCLK_DYN_START_CNTL; + OUTPLL(RADEON_CLK_PIN_CNTL, tmp); + usleep(15000); + + /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 + to lockup randomly, leave them as set by BIOS. + */ + tmp = INPLL(pScrn, RADEON_SCLK_CNTL); + /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/ + tmp &= ~RADEON_SCLK_FORCEON_MASK; + + /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ + if (((info->ChipFamily == CHIP_FAMILY_RV250) && + ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) || + ((info->ChipFamily == CHIP_FAMILY_RV100) && + ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <= + RADEON_CFG_ATI_REV_A13))){ + tmp |= RADEON_SCLK_FORCE_CP; + tmp |= RADEON_SCLK_FORCE_VIP; + } + + OUTPLL(RADEON_SCLK_CNTL, tmp); + + if ((info->ChipFamily == CHIP_FAMILY_RV200) || + (info->ChipFamily == CHIP_FAMILY_RV250) || + (info->ChipFamily == CHIP_FAMILY_RV280)) { + tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); + tmp &= ~RADEON_SCLK_MORE_FORCEON; + + /* RV200::A11 A12 RV250::A11 A12 */ + if (((info->ChipFamily == CHIP_FAMILY_RV200) || + (info->ChipFamily == CHIP_FAMILY_RV250)) && + ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp |= RADEON_SCLK_MORE_FORCEON; + } + OUTPLL(RADEON_SCLK_MORE_CNTL, tmp); + usleep(15000); + } + + /* RV200::A11 A12, RV250::A11 A12 */ + if (((info->ChipFamily == CHIP_FAMILY_RV200) || + (info->ChipFamily == CHIP_FAMILY_RV250)) && + ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < + RADEON_CFG_ATI_REV_A13)) { + tmp = INPLL(pScrn, RADEON_PLL_PWRMGT_CNTL); + tmp |= RADEON_TCL_BYPASS_DISABLE; + OUTREG(RADEON_PLL_PWRMGT_CNTL, tmp); + } + usleep(15000); + + /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/ + tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | + RADEON_PIX2CLK_DAC_ALWAYS_ONb | + RADEON_PIXCLK_BLEND_ALWAYS_ONb | + RADEON_PIXCLK_GV_ALWAYS_ONb | + RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | + RADEON_PIXCLK_LVDS_ALWAYS_ONb | + RADEON_PIXCLK_TMDS_ALWAYS_ONb); + + OUTPLL(RADEON_PIXCLKS_CNTL, tmp); + usleep(15000); + + tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); + tmp |= (RADEON_PIXCLK_ALWAYS_ONb | + RADEON_PIXCLK_DAC_ALWAYS_ONb); + + OUTPLL(RADEON_VCLK_ECP_CNTL, tmp); + usleep(15000); + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Enabled\n"); + break; + default: + break; + } +} + diff --git a/src/radeon_probe.c b/src/radeon_probe.c index adb336a..5dade63 100644 --- a/src/radeon_probe.c +++ b/src/radeon_probe.c @@ -133,12 +133,12 @@ SymTabRec RADEONChipsets[] = { { PCI_CHIP_RV350_AS, "ATI Radeon 9600 AS (AGP)" }, { PCI_CHIP_RV350_AT, "ATI FireGL T2 AT (AGP)" }, { PCI_CHIP_RV350_AV, "ATI FireGL RV360 AV (AGP)" }, - { PCI_CHIP_RV350_NP, "ATI Radeon Mobility 9600 (M10) NP (AGP)" }, + { PCI_CHIP_RV350_NP, "ATI Radeon Mobility 9600/9700 (M10/M11) NP (AGP)" }, { PCI_CHIP_RV350_NQ, "ATI Radeon Mobility 9600 (M10) NQ (AGP)" }, { PCI_CHIP_RV350_NR, "ATI Radeon Mobility 9600 (M11) NR (AGP)" }, { PCI_CHIP_RV350_NS, "ATI Radeon Mobility 9600 (M10) NS (AGP)" }, { PCI_CHIP_RV350_NT, "ATI FireGL Mobility T2 (M10) NT (AGP)" }, - { PCI_CHIP_RV350_NV, "ATI FireGL Mobility T2 (M11) NV (AGP)" }, + { PCI_CHIP_RV350_NV, "ATI FireGL Mobility T2e (M11) NV (AGP)" }, { PCI_CHIP_R350_AH, "ATI Radeon 9800SE AH (AGP)" }, { PCI_CHIP_R350_AI, "ATI Radeon 9800 AI (AGP)" }, { PCI_CHIP_R350_AJ, "ATI Radeon 9800 AJ (AGP)" }, @@ -337,10 +337,10 @@ RADEONProbe(DriverPtr drv, int flags) pEnt = xf86GetEntityInfo(usedChips[i]); - /* create a RADEONEntity for all chips, even with - old single head Radeon, need to use pRADEONEnt + /* create a RADEONEntity for all chips, even with + old single head Radeon, need to use pRADEONEnt for new monitor detection routines - */ + */ { DevUnion *pPriv; RADEONEntPtr pRADEONEnt; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 3e3a9f8..92ae561 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -203,11 +203,20 @@ #define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ #define RADEON_CAPABILITIES_PTR 0x0f34 /* PCI */ #define RADEON_CLK_PIN_CNTL 0x0001 /* PLL */ +# define RADEON_SCLK_DYN_START_CNTL (1 << 15) #define RADEON_CLOCK_CNTL_DATA 0x000c #define RADEON_CLOCK_CNTL_INDEX 0x0008 # define RADEON_PLL_WR_EN (1 << 7) # define RADEON_PLL_DIV_SEL (3 << 8) # define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8) +#define RADEON_CLK_PWRMGT_CNTL 0x0014 +# define RADEON_ENGIN_DYNCLK_MODE (1 << 12) +# define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13) +# define RADEON_ACTIVE_HILO_LAT_SHIFT 13 +# define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12) +# define RADEON_DYN_STOP_MODE_MASK (7 << 21) +#define RADEON_PLL_PWRMGT_CNTL 0x0015 +# define RADEON_TCL_BYPASS_DISABLE (1 << 20) #define RADEON_CLR_CMP_CLR_3D 0x1a24 #define RADEON_CLR_CMP_CLR_DST 0x15c8 #define RADEON_CLR_CMP_CLR_SRC 0x15c4 @@ -413,10 +422,10 @@ # define RADEON_DAC_PDWN_B (1 << 18) #define RADEON_TV_DAC_CNTL 0x088c # define RADEON_TV_DAC_STD_MASK 0x0300 +# define RADEON_TV_DAC_BGSLEEP (1 << 6) # define RADEON_TV_DAC_RDACPD (1 << 24) # define RADEON_TV_DAC_GDACPD (1 << 25) # define RADEON_TV_DAC_BDACPD (1 << 26) -# define RADEON_TV_DAC_BGSLEEP (1 << 26) #define RADEON_DISP_HW_DEBUG 0x0d14 # define RADEON_CRT2_DISP1_SEL (1 << 5) #define RADEON_DISP_OUTPUT_CNTL 0x0d64 @@ -779,6 +788,13 @@ # define RADEON_FORCEON_YCLKB (1 << 19) # define RADEON_FORCEON_MC (1 << 20) # define RADEON_FORCEON_AIC (1 << 21) +# define R300_DISABLE_MC_MCLKA (1 << 21) +# define R300_DISABLE_MC_MCLKB (1 << 21) +#define RADEON_MCLK_MISC 0x001f /* PLL */ +# define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1<<12) +# define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13) +# define RADEON_MC_MCLK_DYN_ENABLE (1 << 14) +# define RADEON_IO_MCLK_DYN_ENABLE (1 << 14) #define RADEON_MDGPIO_A_REG 0x01ac #define RADEON_MDGPIO_EN_REG 0x01b0 #define RADEON_MDGPIO_MASK 0x0198 @@ -981,8 +997,19 @@ # define RADEON_PIX2CLK_ALWAYS_ONb (1<<6) # define RADEON_PIX2CLK_DAC_ALWAYS_ONb (1<<7) # define RADEON_PIXCLK_TV_SRC_SEL (1 << 8) +# define RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb (1 << 9) +# define R300_DVOCLK_ALWAYS_ONb (1 << 10) +# define RADEON_PIXCLK_BLEND_ALWAYS_ONb (1 << 11) +# define RADEON_PIXCLK_GV_ALWAYS_ONb (1 << 12) +# define RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb (1 << 13) +# define R300_PIXCLK_DVO_ALWAYS_ONb (1 << 13) # define RADEON_PIXCLK_LVDS_ALWAYS_ONb (1 << 14) # define RADEON_PIXCLK_TMDS_ALWAYS_ONb (1 << 15) +# define R300_PIXCLK_TRANS_ALWAYS_ONb (1 << 16) +# define R300_PIXCLK_TVO_ALWAYS_ONb (1 << 17) +# define R300_P2G2CLK_ALWAYS_ONb (1 << 18) +# define R300_P2G2CLK_DAC_ALWAYS_ONb (1 << 19) +# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23) #define RADEON_PLANE_3D_MASK_C 0x1d44 #define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */ #define RADEON_PMI_CAP_ID 0x0f5c /* PCI */ @@ -1047,10 +1074,42 @@ # define RADEON_SC_SIGN_MASK_LO 0x8000 # define RADEON_SC_SIGN_MASK_HI 0x80000000 #define RADEON_SCLK_CNTL 0x000d /* PLL */ +# define RADEON_SCLK_SRC_SEL_MASK 0x0007 # define RADEON_DYN_STOP_LAT_MASK 0x00007ff8 # define RADEON_CP_MAX_DYN_STOP_LAT 0x0008 # define RADEON_SCLK_FORCEON_MASK 0xffff8000 +# define RADEON_SCLK_FORCE_DISP2 (1<<15) +# define RADEON_SCLK_FORCE_CP (1<<16) +# define RADEON_SCLK_FORCE_HDP (1<<17) +# define RADEON_SCLK_FORCE_DISP1 (1<<18) +# define RADEON_SCLK_FORCE_TOP (1<<19) +# define RADEON_SCLK_FORCE_E2 (1<<20) +# define RADEON_SCLK_FORCE_SE (1<<21) +# define RADEON_SCLK_FORCE_IDCT (1<<22) +# define RADEON_SCLK_FORCE_VIP (1<<23) +# define RADEON_SCLK_FORCE_RE (1<<24) +# define RADEON_SCLK_FORCE_PB (1<<25) +# define RADEON_SCLK_FORCE_TAM (1<<26) +# define RADEON_SCLK_FORCE_TDM (1<<27) +# define RADEON_SCLK_FORCE_RB (1<<28) +# define RADEON_SCLK_FORCE_TV_SCLK (1<<29) +# define RADEON_SCLK_FORCE_SUBPIC (1<<30) +# define RADEON_SCLK_FORCE_OV0 (1<<31) +# define R300_SCLK_FORCE_VAP (1<<21) +# define R300_SCLK_FORCE_SR (1<<25) +# define R300_SCLK_FORCE_PX (1<<26) +# define R300_SCLK_FORCE_TX (1<<27) +# define R300_SCLK_FORCE_US (1<<28) +# define R300_SCLK_FORCE_SU (1<<30) +#define R300_SCLK_CNTL2 0x1e /* PLL */ +# define R300_SCLK_TCL_MAX_DYN_STOP_LAT (1<<10) +# define R300_SCLK_GA_MAX_DYN_STOP_LAT (1<<11) +# define R300_SCLK_CBA_MAX_DYN_STOP_LAT (1<<12) +# define R300_SCLK_FORCE_TCL (1<<13) +# define R300_SCLK_FORCE_CBA (1<<14) +# define R300_SCLK_FORCE_GA (1<<15) #define RADEON_SCLK_MORE_CNTL 0x0035 /* PLL */ +# define RADEON_SCLK_MORE_MAX_DYN_STOP_LAT 0x0007 # define RADEON_SCLK_MORE_FORCEON 0x0700 #define RADEON_SDRAM_MODE_REG 0x0158 #define RADEON_SEQ8_DATA 0x03c5 /* VGA */ @@ -1124,6 +1183,7 @@ # define RADEON_VCLK_SRC_SEL_PPLLCLK 0x03 # define RADEON_PIXCLK_ALWAYS_ONb (1<<6) # define RADEON_PIXCLK_DAC_ALWAYS_ONb (1<<7) +# define R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF (1<<23) #define RADEON_VENDOR_ID 0x0f00 /* PCI */ #define RADEON_VGA_DDA_CONFIG 0x02e8 diff --git a/src/radeon_video.c b/src/radeon_video.c index 7654f10..b977062 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -41,6 +41,7 @@ static void RADEONVideoTimerCallback(ScrnInfoPtr pScrn, Time now); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) +#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer; static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity; @@ -303,15 +304,14 @@ static void RADEONSetTransform (ScrnInfoPtr pScrn, OvBOff = -1104; #endif + OvROff = ClipValue(OvROff, -2048.0, 2047.5); + OvGOff = ClipValue(OvGOff, -2048.0, 2047.5); + OvBOff = ClipValue(OvBOff, -2048.0, 2047.5); dwOvROff = ((INT32)(OvROff * 2.0)) & 0x1fff; dwOvGOff = ((INT32)(OvGOff * 2.0)) & 0x1fff; dwOvBOff = ((INT32)(OvBOff * 2.0)) & 0x1fff; - /* - * Whatever docs say about R200 having 3.8 format instead of 3.11 - * as in Radeon is a lie - * Or more precisely the location of bit fields is a lie - */ - if(1 || info->ChipFamily < CHIP_FAMILY_R200) + + if(info->ChipFamily < CHIP_FAMILY_RADEON) { dwOvLuma =(((INT32)(OvLuma * 2048.0))&0x7fff)<<17; dwOvRCb = (((INT32)(OvRCb * 2048.0))&0x7fff)<<1; @@ -323,13 +323,13 @@ static void RADEONSetTransform (ScrnInfoPtr pScrn, } else { - dwOvLuma = (((INT32)(OvLuma * 256.0))&0x7ff)<<20; - dwOvRCb = (((INT32)(OvRCb * 256.0))&0x7ff)<<4; - dwOvRCr = (((INT32)(OvRCr * 256.0))&0x7ff)<<20; - dwOvGCb = (((INT32)(OvGCb * 256.0))&0x7ff)<<4; - dwOvGCr = (((INT32)(OvGCr * 256.0))&0x7ff)<<20; - dwOvBCb = (((INT32)(OvBCb * 256.0))&0x7ff)<<4; - dwOvBCr = (((INT32)(OvBCr * 256.0))&0x7ff)<<20; + dwOvLuma = (((INT32)(OvLuma * 256.0))&0xfff)<<20; + dwOvRCb = (((INT32)(OvRCb * 256.0))&0xfff)<<4; + dwOvRCr = (((INT32)(OvRCr * 256.0))&0xfff)<<20; + dwOvGCb = (((INT32)(OvGCb * 256.0))&0xfff)<<4; + dwOvGCr = (((INT32)(OvGCr * 256.0))&0xfff)<<20; + dwOvBCb = (((INT32)(OvBCb * 256.0))&0xfff)<<4; + dwOvBCr = (((INT32)(OvBCr * 256.0))&0xfff)<<20; } OUTREG(RADEON_OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); OUTREG(RADEON_OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); @@ -382,9 +382,11 @@ RADEONResetVideo(ScrnInfoPtr pScrn) unsigned char *RADEONMMIO = info->MMIO; RADEONPortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr; - if (info->accelOn) info->accel->Sync(pScrn); + /* this function is called from ScreenInit. pScreen is used + by XAA internally, but not valid until ScreenInit finishs. + */ + if (info->accelOn && pScrn->pScreen) info->accel->Sync(pScrn); - RADEONWaitForIdleMMIO(pScrn); OUTREG(RADEON_OV0_SCALE_CNTL, 0x80000000); OUTREG(RADEON_OV0_AUTO_FLIP_CNTL, 0); /* maybe */ OUTREG(RADEON_OV0_EXCLUSIVE_HORZ, 0); @@ -615,7 +617,6 @@ RADEONSetPortAttribute(ScrnInfoPtr pScrn, #define RTFIntensity(a) (((a)*1.0)/2000.0) #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) -#define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v)) if(attribute == xvAutopaintColorkey) { |