summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon_modes.c87
-rw-r--r--src/radeon_output.c32
2 files changed, 117 insertions, 2 deletions
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 0a8fa001..662071b4 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 6bbe9abc..cded74be 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: