From patchwork Tue Oct 13 19:18:31 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adam Jackson X-Patchwork-Id: 53513 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9DJo7g9017801 for ; Tue, 13 Oct 2009 19:50:07 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 033BB9E852; Tue, 13 Oct 2009 12:50:07 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTP id 2BC9E9E7EF for ; Tue, 13 Oct 2009 12:50:04 -0700 (PDT) Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n9DJIaZx007033 for ; Tue, 13 Oct 2009 15:18:36 -0400 Received: from localhost.localdomain (atropine.boston.devel.redhat.com [10.16.60.54]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n9DJIZDB004856; Tue, 13 Oct 2009 15:18:35 -0400 From: Adam Jackson To: intel-gfx@lists.freedesktop.org Date: Tue, 13 Oct 2009 15:18:31 -0400 Message-Id: <1255461511-29107-1-git-send-email-ajax@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Subject: [Intel-gfx] [PATCH] LVDS: Fix output mode list construction. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 472bc74..d045903 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -681,107 +681,46 @@ static void fill_detailed_lvds_block(struct detailed_monitor_section *det_mon, timing->misc |= 0x01; } -static int drmmode_output_lvds_edid(xf86OutputPtr output, - struct fixed_panel_lvds *p_lvds) +static DisplayModePtr +drmmode_output_lvds_edid(xf86OutputPtr output, DisplayModePtr modes) { - drmmode_output_private_ptr drmmode_output = output->driver_private; - drmModeConnectorPtr koutput = drmmode_output->mode_output; - int i, j; - DisplayModePtr pmode; - xf86MonPtr edid_mon; - drmModeModeInfo *mode_ptr; - struct detailed_monitor_section *det_mon; - - if (output->MonInfo) { - /* - * If there exists the EDID, we will either find a DS_RANGES - * or replace a DS_VENDOR block, smashing it into a DS_RANGES - * block with opern refresh to match all the default modes. - */ - int edid_det_block_num; - edid_mon = output->MonInfo; - edid_mon->features.msc |= 0x01; - j = -1; - edid_det_block_num = sizeof(edid_mon->det_mon) / - sizeof(edid_mon->det_mon[0]); - for (i = 0; i < edid_det_block_num; 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; - } - return 0; - } - /* - * If there is no EDID, we will construct a bogus EDID for LVDS output - * device. This is similar to what we have done in i830_lvds.c - */ - edid_mon = NULL; - edid_mon = xcalloc(1, sizeof(xf86Monitor)); - if (!edid_mon) { - xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, - "Can't allocate memory for edid_mon.\n"); - return 0; - } - /* Find the fixed panel mode. - * In theory when there is no EDID, KMS kernel will return only one - * mode. And this can be regarded as fixed lvds panel mode. - * But it will be better to traverse the mode list to get the fixed - * lvds panel mode again as we don't know whether some new modes - * are added for the LVDS output device - */ - j = 0; - for (i = 0; i < koutput->count_modes; i++) { - mode_ptr = &koutput->modes[i]; - if ((mode_ptr->hdisplay == p_lvds->hdisplay) && - (mode_ptr->vdisplay == p_lvds->vdisplay)) { - /* find the fixed panel mode */ - j = i; - break; - } + xf86MonPtr mon = output->MonInfo; + + if (!mon || !GTF_SUPPORTED(mon->features.msc)) { + DisplayModePtr i, m, p = NULL; + int max_x = 0, max_y = 0; + float max_vrefresh = 0.0; + + for (m = modes; m; m = m->next) { + if (m->type & M_T_PREFERRED) + p = m; + max_x = max(max_x, m->HDisplay); + max_y = max(max_y, m->VDisplay); + max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); } - pmode = xnfalloc(sizeof(DisplayModeRec)); - drmmode_ConvertFromKMode(output->scrn, &koutput->modes[j], pmode); - /*support DPM, instead of DPMS*/ - edid_mon->features.dpms |= 0x1; - /*defaultly support RGB color display*/ - edid_mon->features.display_type |= 0x1; - /*defaultly display support continuous-freqencey*/ - edid_mon->features.msc |= 0x1; - /*defaultly the EDID version is 1.4 */ - edid_mon->ver.version = 1; - edid_mon->ver.revision = 4; - det_mon = edid_mon->det_mon; - if (pmode) { - /* now we construct new EDID monitor, - * so filled one detailed timing block - */ - fill_detailed_lvds_block(det_mon, pmode); - /* the filed timing block should be set preferred*/ - edid_mon->features.msc |= 0x2; - det_mon = det_mon + 1; + + max_vrefresh = max(max_vrefresh, 60.0); + max_vrefresh *= (1 + SYNC_TOLERANCE); + + m = xf86GetDefaultModes(); + + xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); + + for (i = m; i; i = i->next) { + if (xf86ModeVRefresh(i) > max_vrefresh) + i->status = MODE_VSYNC; + if (p && i->HDisplay >= p->HDisplay && + i->VDisplay >= p->VDisplay && + xf86ModeVRefresh(i) >= xf86ModeVRefresh(p)) + i->status = MODE_VSYNC; } - /* 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; - output->MonInfo = edid_mon; - return 0; + + xf86PruneInvalidModes(output->scrn, &m, FALSE); + + modes = xf86ModesAdd(modes, m); + } + + return modes; } static DisplayModePtr @@ -853,8 +792,11 @@ drmmode_output_get_modes(xf86OutputPtr output) if (!p_lvds->hdisplay || !p_lvds->vdisplay) xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Incorrect KMS mode.\n"); - drmmode_output_lvds_edid(output, p_lvds); } + + if (koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) + Modes = drmmode_output_lvds_edid(output, Modes); + return Modes; }