From patchwork Sat Aug 11 20:04:37 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baurzhan Ismagulov X-Patchwork-Id: 1308991 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork2.kernel.org (Postfix) with ESMTP id 73205DF2D2 for ; Sat, 11 Aug 2012 20:05:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 50458A02B1 for ; Sat, 11 Aug 2012 13:05:01 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from almaty.kz-easy.com (almaty.radix50.net [85.214.25.173]) by gabe.freedesktop.org (Postfix) with ESMTP id B67659E756 for ; Sat, 11 Aug 2012 13:04:50 -0700 (PDT) Received: from alatau.radix50.net (dslb-088-065-252-033.pools.arcor-ip.net [88.65.252.33]) (authenticated bits=0) by almaty.kz-easy.com (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id q7BK4hw9022891 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Sat, 11 Aug 2012 22:04:45 +0200 Received: from medeu.radix50.net (root@medeu [192.168.0.3]) by alatau.radix50.net (8.14.3/8.14.3/Debian-5) with ESMTP id q7BK4cka010419 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Sat, 11 Aug 2012 22:04:38 +0200 Received: from medeu.radix50.net (ibr@localhost [127.0.0.1]) by medeu.radix50.net (8.14.3/8.14.3/Debian-9.4) with ESMTP id q7BK4cQv009206 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Sat, 11 Aug 2012 22:04:38 +0200 Received: (from ibr@localhost) by medeu.radix50.net (8.14.3/8.14.3/Submit) id q7BK4b6I009205; Sat, 11 Aug 2012 22:04:37 +0200 Date: Sat, 11 Aug 2012 22:04:37 +0200 From: Baurzhan Ismagulov To: ajax@redhat.com Subject: ping: Re: quirk for Samsung 2443BW Message-ID: <20120811200437.GA8062@radix50.net> References: <20120714214231.GC3451@radix50.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-Spam-Status: No, score=4.9 required=5.0 tests=BAYES_00, RCVD_IN_BRBL_LASTEXT, RCVD_IN_PBL, RCVD_IN_SORBS_DUL, RDNS_DYNAMIC, TO_NO_BRKTS_DYNIP autolearn=no version=3.3.1 X-Spam-Level: **** X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on almaty.kz-easy.com Cc: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Hello Adam, On Fri, Jul 20, 2012 at 12:34:21PM +1000, Dave Airlie wrote: > > Samsung 2443BW is 1920x1200 but reports 1920x1080 in the EDID. Attached > > is a proof-of-concept implementation of a quirk. It works on my i686 PC. ... > > This implementation matches the wrong mode by size. Other approaches are > > possible. > > > > I'd appreciate feedback. > > ajax, seem sane? Ping? With kind regards, Baurzhan. From ea4ca18f607c3829239ad602b0cb8d319fbcd75e Mon Sep 17 00:00:00 2001 From: Baurzhan Ismagulov Date: Sat, 14 Jul 2012 22:23:33 +0200 Subject: [PATCH 2/2] drm: Add quirk for Samsung SyncMaster 2443BW Signed-off-by: Baurzhan Ismagulov --- drivers/gpu/drm/drm_edid.c | 64 ++++++++++++++++++++++++++++++------------- 1 files changed, 44 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 09ff2bb..73dda54 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -68,12 +68,14 @@ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) +/* Force size */ +#define EDID_QUIRK_FORCE_SIZE (1 << 8) struct detailed_mode_closure { struct drm_connector *connector; struct edid *edid; bool preferred; - u32 quirks; + const struct edid_quirk *quirk; int modes; }; @@ -82,10 +84,23 @@ struct detailed_mode_closure { #define LEVEL_GTF2 2 #define LEVEL_CVT 3 +struct size { + int x; + int y; +}; + +struct force_size { + struct size bad; + struct size good; +}; + static struct edid_quirk { char vendor[4]; int product_id; u32 quirks; + union { + struct force_size size; + } u; } const edid_quirk_list[] = { /* Acer AL1706 */ { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, @@ -122,6 +137,9 @@ static struct edid_quirk { /* Samsung SyncMaster 22[5-6]BW */ { "SAM", 596, EDID_QUIRK_PREFER_LARGE_60 }, { "SAM", 638, EDID_QUIRK_PREFER_LARGE_60 }, + /* Samsung SyncMaster 2443BW */ + { "SAM", 0x06b0, EDID_QUIRK_FORCE_SIZE, + .u.size = { { 1920, 1080 }, { 1920, 1200 } } }, /* ViewSonic VA2026w */ { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, @@ -428,12 +446,12 @@ static bool edid_vendor(struct edid *edid, const char *vendor) } /** - * edid_get_quirks - return quirk flags for a given EDID + * edid_get_quirk - return quirk data for a given EDID * @edid: EDID to process * * This tells subsequent routines what fixes they need to apply. */ -static u32 edid_get_quirks(struct edid *edid) +static const struct edid_quirk *edid_get_quirk(struct edid *edid) { const struct edid_quirk *quirk; int i; @@ -443,10 +461,10 @@ static u32 edid_get_quirks(struct edid *edid) if (edid_vendor(edid, quirk->vendor) && (EDID_PRODUCT_ID(edid) == quirk->product_id)) - return quirk->quirks; + return quirk; } - return 0; + return NULL; } #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay) @@ -866,7 +884,7 @@ drm_mode_do_interlace_quirk(struct drm_display_mode *mode, static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, struct edid *edid, struct detailed_timing *timing, - u32 quirks) + const struct edid_quirk *quirk) { struct drm_display_mode *mode; struct detailed_pixel_timing *pt = &timing->data.pixel_data; @@ -898,7 +916,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, return NULL; } - if (quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) { + if (quirk && quirk->quirks & EDID_QUIRK_FORCE_REDUCED_BLANKING) { mode = drm_cvt_mode(dev, hactive, vactive, 60, true, false, false); if (!mode) return NULL; @@ -906,11 +924,17 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, goto set_size; } + if (quirk && quirk->quirks & EDID_QUIRK_FORCE_SIZE && + hactive == quirk->u.size.bad.x && vactive == quirk->u.size.bad.y) { + hactive = quirk->u.size.good.x; + vactive = quirk->u.size.good.y; + } + mode = drm_mode_create(dev); if (!mode) return NULL; - if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) + if (quirk && quirk->quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) timing->pixel_clock = cpu_to_le16(1088); mode->clock = le16_to_cpu(timing->pixel_clock) * 10; @@ -933,9 +957,8 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, drm_mode_do_interlace_quirk(mode, pt); - if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { + if (quirk && quirk->quirks & EDID_QUIRK_DETAILED_SYNC_PP) pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; - } mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; @@ -946,12 +969,12 @@ set_size: mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; - if (quirks & EDID_QUIRK_DETAILED_IN_CM) { + if (quirk && quirk->quirks & EDID_QUIRK_DETAILED_IN_CM) { mode->width_mm *= 10; mode->height_mm *= 10; } - if (quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) { + if (quirk && quirk->quirks & EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE) { mode->width_mm = edid->width_cm * 10; mode->height_mm = edid->height_cm * 10; } @@ -1421,7 +1444,7 @@ do_detailed_mode(struct detailed_timing *timing, void *c) if (timing->pixel_clock) { newmode = drm_mode_detailed(closure->connector->dev, closure->edid, timing, - closure->quirks); + closure->quirk); if (!newmode) return; @@ -1442,13 +1465,13 @@ do_detailed_mode(struct detailed_timing *timing, void *c) */ static int add_detailed_modes(struct drm_connector *connector, struct edid *edid, - u32 quirks) + const struct edid_quirk *quirk) { struct detailed_mode_closure closure = { connector, edid, 1, - quirks, + quirk, 0 }; @@ -1890,7 +1913,7 @@ static void drm_add_display_info(struct edid *edid, int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) { int num_modes = 0; - u32 quirks; + const struct edid_quirk *quirk; if (edid == NULL) { return 0; @@ -1901,7 +1924,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) return 0; } - quirks = edid_get_quirks(edid); + quirk = edid_get_quirk(edid); /* * EDID spec says modes should be preferred in this order: @@ -1917,15 +1940,16 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) * * XXX order for additional mode types in extension blocks? */ - num_modes += add_detailed_modes(connector, edid, quirks); + num_modes += add_detailed_modes(connector, edid, quirk); num_modes += add_cvt_modes(connector, edid); num_modes += add_standard_modes(connector, edid); num_modes += add_established_modes(connector, edid); num_modes += add_inferred_modes(connector, edid); num_modes += add_cea_modes(connector, edid); - if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) - edid_fixup_preferred(connector, quirks); + if (quirk && quirk->quirks & + (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) + edid_fixup_preferred(connector, quirk->quirks); drm_add_display_info(edid, &connector->display_info); -- 1.7.2.5