xf86-video-ati: Branch 'master' - 2 commits

Alex Deucher agd5f at kemper.freedesktop.org
Tue Mar 3 17:25:01 PST 2009


 src/atombios_crtc.c   |    2 -
 src/atombios_output.c |   60 +++++++++++++++++++++++++++++++++-
 src/radeon_modes.c    |   87 ++++++++++++++++++++++++++++++++++++++++++++++++--
 src/radeon_output.c   |   37 +++++++++++++++++++++
 src/radeon_probe.h    |    3 +
 5 files changed, 184 insertions(+), 5 deletions(-)

New commits:
commit 1a2b16561d19ec9c027c562902f5fc086c856994
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Mar 3 20:21:17 2009 -0500

    radeon: adjust LVDS so that default modes get added
    
    we can scale, so add the default modes.  for panels
    with an EDID, set the continous freq bit.  for panels without
    and EDID, add a FAKE edid with the continous freq bit set.
    
    Based on similar code in the Intel driver.

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 0a8fa00..662071b 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -415,6 +415,83 @@ RADEONUpdatePanelSize(xf86OutputPtr output)
     }
 }
 
+static void fill_detailed_block(struct detailed_monitor_section *det_mon,
+				DisplayModePtr mode)
+{
+    struct detailed_timings *timing = &det_mon->section.d_timings;
+    det_mon->type = DT;
+    timing->clock = mode->Clock * 1000;
+    timing->h_active = mode->HDisplay;
+    timing->h_blanking = mode->HTotal - mode->HDisplay;
+    timing->v_active = mode->VDisplay;
+    timing->v_blanking = mode->VTotal - mode->VDisplay;
+    timing->h_sync_off = mode->HSyncStart - mode->HDisplay;
+    timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart;
+    timing->v_sync_off = mode->VSyncStart - mode->VDisplay;
+    timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart;
+
+    if (mode->Flags & V_PVSYNC)
+	timing->misc |= 0x02;
+
+    if (mode->Flags & V_PHSYNC)
+	timing->misc |= 0x01;
+}
+
+static void
+radeon_lvds_add_fake_edid(xf86OutputPtr output, DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    xf86MonPtr edid_mon = NULL;
+
+    if (!output->MonInfo) {
+	edid_mon = xcalloc (1, sizeof (xf86Monitor));
+	if (edid_mon) {
+	    struct detailed_monitor_section *det_mon = edid_mon->det_mon;
+
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Adding fake EDID for LVDS\n");
+
+	    /*support DPM, instead of DPMS*/
+	    edid_mon->features.dpms |= 0x1;
+	    /*default support RGB color display*/
+	    edid_mon->features.display_type |= 0x1;
+	    /*default display support continuous-freqencey*/
+	    edid_mon->features.msc |= 0x1;
+	    /*default the EDID version is 1.4 */
+	    edid_mon->ver.version = 1;
+	    edid_mon->ver.revision = 4;
+
+	    if (mode) {
+		/* now we construct new EDID monitor,
+		 * so filled one detailed timing block
+		 */
+		fill_detailed_block(det_mon, mode);
+		/* the filed timing block should be set preferred*/
+		edid_mon->features.msc |= 0x2;
+		det_mon = det_mon + 1;
+	    }
+
+	    /* Set wide sync ranges so we get all modes
+	     * handed to valid_mode for checking
+	     */
+	    det_mon->type = DS_RANGES;
+	    det_mon->section.ranges.min_v = 0;
+	    det_mon->section.ranges.max_v = 200;
+	    det_mon->section.ranges.min_h = 0;
+	    det_mon->section.ranges.max_h = 200;
+
+	    /* empty edid */
+	    edid_mon->rawData = xcalloc (1, 128);
+
+	    edid_mon->vendor.name[0] = 70;
+	    edid_mon->vendor.name[1] = 65;
+	    edid_mon->vendor.name[2] = 75;
+	    edid_mon->vendor.name[3] = 69;
+
+	    output->MonInfo = edid_mon;
+	}
+    }
+}
+
 DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
@@ -460,10 +537,16 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		    }
 		}
 		if (modes == NULL) {
-		    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+		    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 			modes = RADEONFPNativeMode(output);
+			radeon_lvds_add_fake_edid(output, modes);
+			xfree(modes);
+			modes = xf86OutputGetEDIDModes (output);
+		    }
+
 		    /* add the screen modes */
-		    RADEONAddScreenModes(output, &modes);
+		    if (modes == NULL)
+			RADEONAddScreenModes(output, &modes);
 		}
 	    }
 	}
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 6bbe9ab..cded74b 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -208,6 +208,37 @@ radeon_set_active_device(xf86OutputPtr output)
     }
 }
 
+/* X Server pre-1.5 compatibility */
+#ifndef DS_VENDOR
+#define DS_VENDOR 0x101
+#endif
+
+static void radeon_fixup_edid_for_panel(xf86MonPtr edid_mon)
+{
+    int i, j = -1;
+
+    if (edid_mon) {
+	/* mark it to support continous timing so we can add default modes */
+	edid_mon->features.msc |= 0x1;
+	for (i = 0; i < sizeof (edid_mon->det_mon) / sizeof (edid_mon->det_mon[0]); i++) {
+	    if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1)
+		j = i;
+	    if (edid_mon->det_mon[i].type == DS_RANGES) {
+		j = i;
+		break;
+	    }
+	}
+	if (j != -1) {
+	    struct monitor_ranges   *ranges = &edid_mon->det_mon[j].section.ranges;
+	    edid_mon->det_mon[j].type = DS_RANGES;
+	    ranges->min_v = 0;
+	    ranges->max_v = 200;
+	    ranges->min_h = 0;
+	    ranges->max_h = 200;
+	}
+    }
+}
+
 static RADEONMonitorType
 radeon_ddc_connected(xf86OutputPtr output)
 {
@@ -242,6 +273,7 @@ radeon_ddc_connected(xf86OutputPtr output)
 	switch (radeon_output->ConnectorType) {
 	case CONNECTOR_LVDS:
 	    MonType = MT_LCD;
+	    radeon_fixup_edid_for_panel(MonInfo);
 	    break;
 	case CONNECTOR_DVI_D:
 	case CONNECTOR_HDMI_TYPE_A:
commit 71117970df36cbe689ef15e9a6cca24439b4cd62
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Mar 3 19:40:30 2009 -0500

    AVIVO: add aspect scaling mode
    
    No luck yet for aspect on pre-avivo chips

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 5c26ef8..af79145 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 c4baa13..6d87c8e 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 897c6a2..6bbe9ab 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 f072b9c..afc8e21 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 {


More information about the xorg-commit mailing list