diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-03-03 19:40:30 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-03-03 19:40:30 -0500 |
commit | 71117970df36cbe689ef15e9a6cca24439b4cd62 (patch) | |
tree | 974d9bda586ad1a3a2c2fcb67dec37136e1a8687 | |
parent | d586a2c6f821c821a4a7708a3382acb63187534f (diff) |
AVIVO: add aspect scaling mode
No luck yet for aspect on pre-avivo chips
-rw-r--r-- | src/atombios_crtc.c | 2 | ||||
-rw-r--r-- | src/atombios_output.c | 60 | ||||
-rw-r--r-- | src/radeon_output.c | 5 | ||||
-rw-r--r-- | src/radeon_probe.h | 3 |
4 files changed, 67 insertions, 3 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 5c26ef82..af791458 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -186,7 +186,7 @@ atombios_set_crtc_timing(atomBiosHandlePtr atomBIOS, SET_CRTC_TIMING_PARAMETERS_ conv_param.ucOverscanRight = crtc_param->ucOverscanRight; conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; - conv_param.ucOverscanTop = crtc_param->ucOverscanTop; + conv_param.ucOverscanTop = crtc_param->ucOverscanTop; conv_param.ucReserved = crtc_param->ucReserved; data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); diff --git a/src/atombios_output.c b/src/atombios_output.c index c4baa130..6d87c8ea 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -995,6 +995,61 @@ atombios_output_yuv_setup(xf86OutputPtr output, Bool enable) } static int +atombios_output_overscan_setup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(output->scrn); + SET_CRTC_OVERSCAN_PS_ALLOCATION overscan_param; + AtomBiosArgRec data; + unsigned char *space; + memset(&overscan_param, 0, sizeof(overscan_param)); + + overscan_param.usOverscanRight = 0; + overscan_param.usOverscanLeft = 0; + overscan_param.usOverscanBottom = 0; + overscan_param.usOverscanTop = 0; + overscan_param.ucCRTC = radeon_crtc->crtc_id; + + if (radeon_output->Flags & RADEON_USE_RMX) { + if (radeon_output->rmx_type == RMX_FULL) { + overscan_param.usOverscanRight = 0; + overscan_param.usOverscanLeft = 0; + overscan_param.usOverscanBottom = 0; + overscan_param.usOverscanTop = 0; + } else if (radeon_output->rmx_type == RMX_CENTER) { + overscan_param.usOverscanTop = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2; + overscan_param.usOverscanBottom = (adjusted_mode->CrtcVDisplay - mode->CrtcVDisplay) / 2; + overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2; + overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - mode->CrtcHDisplay) / 2; + } else if (radeon_output->rmx_type == RMX_ASPECT) { + int a1 = mode->CrtcVDisplay * adjusted_mode->CrtcHDisplay; + int a2 = adjusted_mode->CrtcVDisplay * mode->CrtcHDisplay; + + if (a1 > a2) { + overscan_param.usOverscanLeft = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2; + overscan_param.usOverscanRight = (adjusted_mode->CrtcHDisplay - (a2 / mode->CrtcVDisplay)) / 2; + } else if (a2 > a1) { + overscan_param.usOverscanLeft = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2; + overscan_param.usOverscanRight = (adjusted_mode->CrtcVDisplay - (a1 / mode->CrtcHDisplay)) / 2; + } + } + } + + data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &overscan_param; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { + ErrorF("Set CRTC %d Overscan success\n", radeon_crtc->crtc_id); + return ATOM_SUCCESS ; + } + + ErrorF("Set CRTC %d Overscan failed\n", radeon_crtc->crtc_id); + return ATOM_NOT_IMPLEMENTED; +} + +static int atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) { RADEONInfoPtr info = RADEONPTR(output->scrn); @@ -1051,6 +1106,8 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) disp_data.ucEnable = ATOM_SCALER_EXPANSION; else if (radeon_output->rmx_type == RMX_CENTER) disp_data.ucEnable = ATOM_SCALER_CENTER; + else if (radeon_output->rmx_type == RMX_ASPECT) + disp_data.ucEnable = ATOM_SCALER_EXPANSION; } else { ErrorF("Not using RMX\n"); disp_data.ucEnable = ATOM_SCALER_DISABLE; @@ -1423,7 +1480,8 @@ atombios_output_mode_set(xf86OutputPtr output, if (radeon_encoder == NULL) return; - atombios_output_scaler_setup(output, mode); + atombios_output_overscan_setup(output, mode, adjusted_mode); + atombios_output_scaler_setup(output, adjusted_mode); atombios_set_output_crtc_source(output); if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) atombios_output_yuv_setup(output, TRUE); diff --git a/src/radeon_output.c b/src/radeon_output.c index 897c6a21..6bbe9abc 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -1465,6 +1465,11 @@ radeon_set_property(xf86OutputPtr output, Atom property, radeon_output->rmx_type = RMX_FULL; } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) { radeon_output->rmx_type = RMX_CENTER; + } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) { + if (IS_AVIVO_VARIANT) + radeon_output->rmx_type = RMX_ASPECT; + else + return FALSE; } else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) { radeon_output->rmx_type = RMX_OFF; } else diff --git a/src/radeon_probe.h b/src/radeon_probe.h index f072b9c7..afc8e21c 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -101,7 +101,8 @@ typedef enum { RMX_OFF, RMX_FULL, - RMX_CENTER + RMX_CENTER, + RMX_ASPECT } RADEONRMXType; typedef struct { |