diff options
-rw-r--r-- | src/legacy_crtc.c | 26 | ||||
-rw-r--r-- | src/legacy_output.c | 106 | ||||
-rw-r--r-- | src/radeon_probe.h | 1 | ||||
-rw-r--r-- | src/radeon_reg.h | 3 |
4 files changed, 107 insertions, 29 deletions
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c index 4a7071af..53f0374f 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -123,11 +123,6 @@ RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp); OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid); - OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); - OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); - OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); - OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); - if (IS_R300_VARIANT) OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0); OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl); @@ -135,7 +130,6 @@ RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch); OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl); - OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl); if (info->IsDellServer) { OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl); @@ -522,16 +516,10 @@ RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP); save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID); - save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID); - save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID); - save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP); - save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP); - save->crtc_offset = INREG(RADEON_CRTC_OFFSET); save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL); save->crtc_pitch = INREG(RADEON_CRTC_PITCH); save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL); - save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); if (IS_R300_VARIANT) save->crtc_tile_x0_y0 = INREG(R300_CRTC_TILE_X0_Y0); @@ -898,15 +886,6 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, save->disp_merge_cntl = info->SavedReg->disp_merge_cntl; save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN; - save->crtc_more_cntl = 0; - if ((info->ChipFamily == CHIP_FAMILY_RS100) || - (info->ChipFamily == CHIP_FAMILY_RS200)) { - /* This is to workaround the asic bug for RMX, some versions - of BIOS dosen't have this register initialized correctly. - */ - save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN; - } - save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff) | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16)); @@ -938,11 +917,6 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save, ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8)); save->crtc_pitch |= save->crtc_pitch << 16; - - save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; - save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; - save->fp_crtc_h_total_disp = save->crtc_h_total_disp; - save->fp_crtc_v_total_disp = save->crtc_v_total_disp; if (info->IsDellServer) { save->dac2_cntl = info->SavedReg->dac2_cntl; diff --git a/src/legacy_output.c b/src/legacy_output.c index d2d0de67..6e150516 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -132,6 +132,12 @@ RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); + OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl); + OUTREG(RADEON_FP_HORZ_VERT_ACTIVE, restore->fp_horz_vert_active); + OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); + OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); + OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); } @@ -201,11 +207,18 @@ RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) save->fp2_gen_cntl = INREG (RADEON_FP2_GEN_CNTL); save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); + save->fp_horz_vert_active = INREG(RADEON_FP_HORZ_VERT_ACTIVE); + save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL); save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); 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->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID); + save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID); + save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP); + save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP); + if (info->ChipFamily == CHIP_FAMILY_RV280) { /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ save->tmds_pll_cntl ^= (1 << 22); @@ -1022,6 +1035,8 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, int xres = mode->HDisplay; int yres = mode->VDisplay; float Hratio, Vratio; + int hsync_wid; + int vsync_wid; save->fp_vert_stretch = info->SavedReg->fp_vert_stretch & RADEON_VERT_STRETCH_RESERVED; @@ -1029,21 +1044,37 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, (RADEON_HORZ_FP_LOOP_STRETCH | RADEON_HORZ_AUTO_RATIO_INC); + save->crtc_more_cntl = 0; + if ((info->ChipFamily == CHIP_FAMILY_RS100) || + (info->ChipFamily == CHIP_FAMILY_RS200)) { + /* This is to workaround the asic bug for RMX, some versions + of BIOS dosen't have this register initialized correctly. + */ + save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN; + } + if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP) return; + if ((radeon_output->rmx_type == RMX_CENTER) && + (radeon_output->Flags & RADEON_USE_RMX)) { + save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN | + RADEON_CRTC_AUTO_VERT_CENTER_EN); + } + if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) { Hratio = 1.0; Vratio = 1.0; } else { if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes; if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes; - + Hratio = (float)xres/(float)radeon_output->PanelXRes; Vratio = (float)yres/(float)radeon_output->PanelYRes; } - if (Hratio == 1.0 || !(radeon_output->Flags & RADEON_USE_RMX)) { + if ((Hratio == 1.0) || (!(radeon_output->Flags & RADEON_USE_RMX)) || + (radeon_output->rmx_type == RMX_CENTER)) { save->fp_horz_stretch |= ((xres/8-1)<<16); } else { save->fp_horz_stretch |= ((((unsigned long) @@ -1054,7 +1085,8 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, ((radeon_output->PanelXRes/8-1)<<16)); } - if (Vratio == 1.0 || !(radeon_output->Flags & RADEON_USE_RMX)) { + if ((Vratio == 1.0) || (!(radeon_output->Flags & RADEON_USE_RMX)) || + (radeon_output->rmx_type == RMX_CENTER)) { save->fp_vert_stretch |= ((yres-1)<<12); } else { save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) & @@ -1064,6 +1096,74 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save, ((radeon_output->PanelYRes-1)<<12)); } + + + if ((radeon_output->rmx_type == RMX_CENTER) && + (radeon_output->Flags & RADEON_USE_RMX)) { + int blank_width; + + blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8; + if (blank_width > 110) blank_width = 110; + + save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff) + | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) + << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + + save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff) + | ((hsync_wid & 0x3f) << 16) + | ((mode->Flags & V_NHSYNC) + ? RADEON_CRTC_H_SYNC_POL + : 0)); + + save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + + save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff) + | ((vsync_wid & 0x1f) << 16) + | ((mode->Flags & V_NVSYNC) + ? RADEON_CRTC_V_SYNC_POL + : 0))); + + save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) | + (((radeon_output->PanelXRes / 8) & 0x1ff) << 16)); + + } else { + int hsync_start; + + save->fp_crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff) + | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) + << 16)); + + hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8; + if (!hsync_wid) hsync_wid = 1; + hsync_start = mode->CrtcHSyncStart - 8; + + save->fp_h_sync_strt_wid = ((hsync_start & 0x1fff) + | ((hsync_wid & 0x3f) << 16) + | ((mode->Flags & V_NHSYNC) + ? RADEON_CRTC_H_SYNC_POL + : 0)); + + save->fp_crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff) + | ((mode->CrtcVDisplay - 1) << 16)); + + vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; + if (!vsync_wid) vsync_wid = 1; + + save->fp_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff) + | ((vsync_wid & 0x1f) << 16) + | ((mode->Flags & V_NVSYNC) + ? RADEON_CRTC_V_SYNC_POL + : 0)); + + save->fp_horz_vert_active = 0; + } } static void diff --git a/src/radeon_probe.h b/src/radeon_probe.h index d24d8ed2..6bd83431 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -445,6 +445,7 @@ typedef struct { CARD32 fp_h_sync_strt_wid; CARD32 fp_h2_sync_strt_wid; CARD32 fp_horz_stretch; + CARD32 fp_horz_vert_active; CARD32 fp_panel_cntl; CARD32 fp_v_sync_strt_wid; CARD32 fp_v2_sync_strt_wid; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 4d20bf88..eec87842 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -337,6 +337,8 @@ # define RADEON_CRTC2_HSYNC_DIS (1 << 28) # define RADEON_CRTC2_VSYNC_DIS (1 << 29) #define RADEON_CRTC_MORE_CNTL 0x27c +# define RADEON_CRTC_AUTO_HORZ_CENTER_EN (1<<2) +# define RADEON_CRTC_AUTO_VERT_CENTER_EN (1<<3) # define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4) # define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5) #define RADEON_CRTC_GUI_TRIG_VLINE 0x0218 @@ -812,6 +814,7 @@ # define RADEON_HORZ_AUTO_RATIO (1 << 27) # define RADEON_HORZ_FP_LOOP_STRETCH (0x7 << 28) # define RADEON_HORZ_AUTO_RATIO_INC (1 << 31) +#define RADEON_FP_HORZ_VERT_ACTIVE 0x0278 #define RADEON_FP_V_SYNC_STRT_WID 0x02c8 #define RADEON_FP_VERT_STRETCH 0x0290 #define RADEON_FP_V2_SYNC_STRT_WID 0x03c8 |