summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-03-03 19:40:30 -0500
committerAlex Deucher <alexdeucher@gmail.com>2009-03-03 19:40:30 -0500
commit71117970df36cbe689ef15e9a6cca24439b4cd62 (patch)
tree974d9bda586ad1a3a2c2fcb67dec37136e1a8687
parentd586a2c6f821c821a4a7708a3382acb63187534f (diff)
AVIVO: add aspect scaling mode
No luck yet for aspect on pre-avivo chips
-rw-r--r--src/atombios_crtc.c2
-rw-r--r--src/atombios_output.c60
-rw-r--r--src/radeon_output.c5
-rw-r--r--src/radeon_probe.h3
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 {