From patchwork Thu Sep 3 01:33:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao, Yakui" X-Patchwork-Id: 45287 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 n831YCtD010376 for ; Thu, 3 Sep 2009 01:34:12 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6C0AAA01E7; Wed, 2 Sep 2009 18:34:12 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [143.182.124.37]) by gabe.freedesktop.org (Postfix) with ESMTP id 0621A9E76D for ; Wed, 2 Sep 2009 18:34:09 -0700 (PDT) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 02 Sep 2009 18:34:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.44,271,1249282800"; d="scan'208";a="183506409" Received: from yakui_zhao.sh.intel.com (HELO localhost.localdomain) ([10.239.13.106]) by azsmga001.ch.intel.com with ESMTP; 02 Sep 2009 18:34:08 -0700 From: yakui.zhao@intel.com To: airlied@redhat.com Date: Thu, 3 Sep 2009 09:33:47 +0800 Message-Id: <1251941629-6694-2-git-send-email-yakui.zhao@intel.com> X-Mailer: git-send-email 1.5.4.5 In-Reply-To: <1251941629-6694-1-git-send-email-yakui.zhao@intel.com> References: <1251941629-6694-1-git-send-email-yakui.zhao@intel.com> Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.sourceforge.net Subject: [Intel-gfx] [Patch 2/4] DRM: try to find the std mode in DMT table 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 From: Zhao Yakui When we need to add the standard timing mode, we will firstly check whether it can be found in DMT table by comparing the hdisplay/vdisplay/vfresh_rate. If it can't be found, then we will use the cvt/gtf to add the required mode. If it can be found, it will be returned. At the same time the function of drm_mode_vrefresh is also fixed. It will return the result of actual refresh_rate plus 0.5. For example: When the calculated value is 84.9, then the fresh_rate is 85. When the calculated value is 70.02, then the fresh_rate is 70. Signed-off-by: Zhao Yakui --- drivers/gpu/drm/drm_edid.c | 40 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/drm_modes.c | 11 ++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) Index: linux-2.6/drivers/gpu/drm/drm_edid.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/drm_edid.c 2009-09-02 14:59:38.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/drm_edid.c 2009-09-02 17:12:25.000000000 +0800 @@ -480,6 +480,26 @@ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, }; +static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh) +{ + int i, count; + struct drm_display_mode *ptr, *mode; + + count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); + mode = NULL; + for (i = 0; i < count; i++) { + ptr = &drm_dmt_modes[i]; + if (hsize == ptr->hdisplay && + vsize == ptr->vdisplay && + fresh == drm_mode_vrefresh(ptr)) { + /* get the expected default mode */ + mode = drm_mode_duplicate(dev, ptr); + break; + } + } + return mode; +} /** * drm_mode_std - convert standard mode info (width, height, refresh) into mode * @t: standard timing params @@ -516,16 +536,22 @@ vsize = (hsize * 4) / 5; else vsize = (hsize * 9) / 16; - + /* HDTV hack */ + if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { + mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); + mode->hdisplay = 1366; + mode->vsync_start = mode->vsync_start - 1; + mode->vsync_end = mode->vsync_end - 1; + return mode; + } mode = NULL; + /* check whether it can be found in default mode table */ + mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); + if (mode) + return mode; + switch (timing_level) { case LEVEL_DMT: - mode = drm_mode_create(dev); - if (mode) { - mode->hdisplay = hsize; - mode->vdisplay = vsize; - drm_mode_set_name(mode); - } break; case LEVEL_GTF: mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); Index: linux-2.6/drivers/gpu/drm/drm_modes.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/drm_modes.c 2009-09-02 08:41:36.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/drm_modes.c 2009-09-02 15:34:11.000000000 +0800 @@ -566,7 +566,9 @@ * FIXME: why is this needed? shouldn't vrefresh be set already? * * RETURNS: - * Vertical refresh rate of @mode x 1000. For precision reasons. + * Vertical refresh rate. It will be the result of actual value plus 0.5. + * If it is 70.288, it will return 70Hz. + * If it is 59.6, it will return 60Hz. */ int drm_mode_vrefresh(struct drm_display_mode *mode) { @@ -576,14 +578,13 @@ if (mode->vrefresh > 0) refresh = mode->vrefresh; else if (mode->htotal > 0 && mode->vtotal > 0) { + int vtotal; + vtotal = mode->vtotal; /* work out vrefresh the value will be x1000 */ calc_val = (mode->clock * 1000); - calc_val /= mode->htotal; - calc_val *= 1000; - calc_val /= mode->vtotal; + refresh = (calc_val + vtotal / 2) / vtotal; - refresh = calc_val; if (mode->flags & DRM_MODE_FLAG_INTERLACE) refresh *= 2; if (mode->flags & DRM_MODE_FLAG_DBLSCAN)