From: Baurzhan Ismagulov <ibr@radix50.net>
To: airlied@linux.ie
Cc: dri-devel@lists.freedesktop.org
Subject: quirk for Samsung 2443BW
Date: Sat, 14 Jul 2012 23:42:36 +0200 [thread overview]
Message-ID: <20120714214231.GC3451@radix50.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 514 bytes --]
Hello David,
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.
The patch is against the latest linux-2.6. An attempt to clone
git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git (as
listed in MAINTAINERS) resulted in "fatal: The remote end hung up
unexpectedly".
This implementation matches the wrong mode by size. Other approaches are
possible.
I'd appreciate feedback.
With kind regards,
Baurzhan.
[-- Attachment #2: 0001-drm-Make-edid_quirk_list-const.patch --]
[-- Type: text/x-diff, Size: 1294 bytes --]
>From b6c7a43e8b8fa0b6b39ed4a99c463071269d1a50 Mon Sep 17 00:00:00 2001
From: Baurzhan Ismagulov <ibr@radix50.net>
Date: Sat, 14 Jul 2012 22:27:18 +0200
Subject: [PATCH 1/2] drm: Make edid_quirk_list const
Signed-off-by: Baurzhan Ismagulov <ibr@radix50.net>
---
drivers/gpu/drm/drm_edid.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a8743c3..09ff2bb 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -86,7 +86,7 @@ static struct edid_quirk {
char vendor[4];
int product_id;
u32 quirks;
-} edid_quirk_list[] = {
+} const edid_quirk_list[] = {
/* Acer AL1706 */
{ "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 },
/* Acer F51 */
@@ -415,7 +415,7 @@ EXPORT_SYMBOL(drm_get_edid);
*
* Returns true if @vendor is in @edid, false otherwise
*/
-static bool edid_vendor(struct edid *edid, char *vendor)
+static bool edid_vendor(struct edid *edid, const char *vendor)
{
char edid_vendor[3];
@@ -435,7 +435,7 @@ static bool edid_vendor(struct edid *edid, char *vendor)
*/
static u32 edid_get_quirks(struct edid *edid)
{
- struct edid_quirk *quirk;
+ const struct edid_quirk *quirk;
int i;
for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) {
--
1.7.2.5
[-- Attachment #3: 0002-drm-Add-quirk-for-Samsung-SyncMaster-2443BW.patch --]
[-- Type: text/x-diff, Size: 6886 bytes --]
>From ea4ca18f607c3829239ad602b0cb8d319fbcd75e Mon Sep 17 00:00:00 2001
From: Baurzhan Ismagulov <ibr@radix50.net>
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 <ibr@radix50.net>
---
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
[-- Attachment #4: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next reply other threads:[~2012-07-14 21:57 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-14 21:42 Baurzhan Ismagulov [this message]
2012-07-16 9:13 ` quirk for Samsung 2443BW Maarten Lankhorst
2012-07-16 9:49 ` Baurzhan Ismagulov
2012-07-20 2:34 ` Dave Airlie
2012-08-11 20:04 ` ping: " Baurzhan Ismagulov
-- strict thread matches above, loose matches on Subject: below --
2012-07-16 10:13 Maarten Lankhorst
2012-07-16 11:00 ` Baurzhan Ismagulov
2012-07-16 11:07 ` Maarten Lankhorst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120714214231.GC3451@radix50.net \
--to=ibr@radix50.net \
--cc=airlied@linux.ie \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox