The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
The first patch enhances the quirk logic as described above. The second one adds my new monitor to the quirk lists.
Signed-off-by: Dylan Semler dylan.semler@gmail.com --- drivers/gpu/drm/drm_edid.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c194f4e..b1036b5 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -68,6 +68,8 @@ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) +/* Force specific mode for monitors that don't report correct EDIDs */ +#define EDID_QUIRK_FORCE_MODE (1 << 8)
struct detailed_mode_closure { struct drm_connector *connector; @@ -127,6 +129,15 @@ static struct edid_quirk { { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, };
+static struct edid_quirk_force_mode { + char vendor[4]; + int product_id; + int hdisplay; + int vdisplay; + int vrefresh; +} edid_quirk_force_mode_list[] = { +}; + /* * Autogenerated from the DMT spec. * This table is copied from xfree86/modes/xf86EdidModes.c. @@ -2219,6 +2230,65 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, return closure.modes; }
+/* Add an explicit mode based on a quirk + */ +static int +do_force_quirk_modes(struct drm_connector *connector, int hdisplay, + int vdisplay, int vrefresh) +{ + struct drm_display_mode *mode; + struct drm_device *dev = connector->dev; + int num_modes = 0; + + /* sanity check display parameters */ + if (hdisplay < 0) + return 0; + if (vdisplay < 0) + return 0; + if (vrefresh < 0) + return 0; + + mode = drm_gtf_mode(dev, hdisplay, vdisplay, vrefresh, 0, 0); + + if (mode) { + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + num_modes++; + } + return num_modes; +} + +/* + * add_force_quirk_modes - Add modes based on monitor's EDID quirks + * @connector: attached connector + * @edid: EDID block to scan + * @quirks: quirks to apply + * + * At least one monitor doesn't report its native resolution in its EDID block. + * Here we add the native mode according to this quirk + */ +static int +add_force_quirk_modes(struct drm_connector *connector, struct edid *edid, + u32 quirks) +{ + struct edid_quirk_force_mode *quirk_mode; + int i, num_modes = 0; + + for (i = 0; i < ARRAY_SIZE(edid_quirk_force_mode_list); i++) { + quirk_mode = &edid_quirk_force_mode_list[i]; + + if (edid_vendor(edid, quirk_mode->vendor) && + (EDID_PRODUCT_ID(edid) == quirk_mode->product_id)) { + num_modes = do_force_quirk_modes(connector, + quirk_mode->hdisplay, + quirk_mode->vdisplay, + quirk_mode->vrefresh); + } + } + return num_modes; + +} + #define HDMI_IDENTIFIER 0x000C03 #define AUDIO_BLOCK 0x01 #define VIDEO_BLOCK 0x02 @@ -2803,6 +2873,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); + if (quirks & EDID_QUIRK_FORCE_MODE) + num_modes += add_force_quirk_modes(connector, edid, quirks);
drm_add_display_info(edid, &connector->display_info);
On Thu, Mar 21, 2013 at 5:36 PM, Dylan Semler dylan.semler@gmail.com wrote:
Signed-off-by: Dylan Semler dylan.semler@gmail.com
drivers/gpu/drm/drm_edid.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c194f4e..b1036b5 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -68,6 +68,8 @@ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) +/* Force specific mode for monitors that don't report correct EDIDs */ +#define EDID_QUIRK_FORCE_MODE (1 << 8)
struct detailed_mode_closure { struct drm_connector *connector; @@ -127,6 +129,15 @@ static struct edid_quirk { { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, };
+static struct edid_quirk_force_mode {
char vendor[4];
int product_id;
int hdisplay;
int vdisplay;
int vrefresh;
+} edid_quirk_force_mode_list[] = { +};
/*
- Autogenerated from the DMT spec.
- This table is copied from xfree86/modes/xf86EdidModes.c.
@@ -2219,6 +2230,65 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, return closure.modes; }
+/* Add an explicit mode based on a quirk
- */
+static int +do_force_quirk_modes(struct drm_connector *connector, int hdisplay,
int vdisplay, int vrefresh)
+{
struct drm_display_mode *mode;
struct drm_device *dev = connector->dev;
int num_modes = 0;
/* sanity check display parameters */
if (hdisplay < 0)
return 0;
if (vdisplay < 0)
return 0;
if (vrefresh < 0)
return 0;
mode = drm_gtf_mode(dev, hdisplay, vdisplay, vrefresh, 0, 0);
I would suggest using drm_cvt_mode() here since most modern monitors prefer cvt timing and usually reduced blanking. A lot of LCD monitors don't like gtf timing. You might also want to add a reduced blanking field to the edid_quirk_force_mode struct so that you can specify on a quirk by quirk basis.
Alex
if (mode) {
mode->type |= DRM_MODE_TYPE_PREFERRED;
drm_mode_probed_add(connector, mode);
num_modes++;
}
return num_modes;
+}
+/*
- add_force_quirk_modes - Add modes based on monitor's EDID quirks
- @connector: attached connector
- @edid: EDID block to scan
- @quirks: quirks to apply
- At least one monitor doesn't report its native resolution in its EDID block.
- Here we add the native mode according to this quirk
- */
+static int +add_force_quirk_modes(struct drm_connector *connector, struct edid *edid,
u32 quirks)
+{
struct edid_quirk_force_mode *quirk_mode;
int i, num_modes = 0;
for (i = 0; i < ARRAY_SIZE(edid_quirk_force_mode_list); i++) {
quirk_mode = &edid_quirk_force_mode_list[i];
if (edid_vendor(edid, quirk_mode->vendor) &&
(EDID_PRODUCT_ID(edid) == quirk_mode->product_id)) {
num_modes = do_force_quirk_modes(connector,
quirk_mode->hdisplay,
quirk_mode->vdisplay,
quirk_mode->vrefresh);
}
}
return num_modes;
+}
#define HDMI_IDENTIFIER 0x000C03 #define AUDIO_BLOCK 0x01 #define VIDEO_BLOCK 0x02 @@ -2803,6 +2873,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks);
if (quirks & EDID_QUIRK_FORCE_MODE)
num_modes += add_force_quirk_modes(connector, edid, quirks); drm_add_display_info(edid, &connector->display_info);
-- 1.7.11.7
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signed-off-by: Dylan Semler dylan.semler@gmail.com --- drivers/gpu/drm/drm_edid.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b1036b5..b400971 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -109,6 +109,9 @@ static struct edid_quirk { { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | EDID_QUIRK_DETAILED_IN_CM },
+ /* Mobile Monitor Technologies LLC, Monitor2Go HD+ */ + { "LLP", 0x4c54, EDID_QUIRK_FORCE_MODE}, + /* LG Philips LCD LP154W01-A5 */ { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, @@ -136,6 +139,8 @@ static struct edid_quirk_force_mode { int vdisplay; int vrefresh; } edid_quirk_force_mode_list[] = { + /* Mobile Monitor Technologies LLC, Monitor2Go HD+ */ + { "LLP", 0x4c54, 1600, 900, 60 }, };
/*
Oops. I neglected to preface this with my motivation: I have a new monitor that doesn't report its native resolution in its EDID block. It seemed to me this calls for an EDID quirk, but the current quirk infrastructure doesn't allow explicitly creating new modes. So I set out to make a simple enhancement to allow specifying a new mode and then setting it as preferred.
On Thu, Mar 21, 2013 at 5:36 PM, Dylan Semler dylan.semler@gmail.comwrote:
The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
The first patch enhances the quirk logic as described above. The second one adds my new monitor to the quirk lists.
On Thu, Mar 21, 2013 at 10:42 PM, Dylan Semler dylan.semler@gmail.com wrote:
Oops. I neglected to preface this with my motivation: I have a new monitor that doesn't report its native resolution in its EDID block. It seemed to me this calls for an EDID quirk, but the current quirk infrastructure doesn't allow explicitly creating new modes. So I set out to make a simple enhancement to allow specifying a new mode and then setting it as preferred.
On Thu, Mar 21, 2013 at 5:36 PM, Dylan Semler dylan.semler@gmail.com wrote:
The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
The first patch enhances the quirk logic as described above. The second one adds my new monitor to the quirk lists.
I think it'd be good to shovel these text blocks into the (currently rather empty) commit messages of the patches. Since when reading old commits with e.g. git blame that's what people will read. -Daniel
On Fri, Mar 22, 2013 at 4:48 AM, Daniel Vetter daniel@ffwll.ch wrote:
I think it'd be good to shovel these text blocks into the (currently
rather
empty) commit messages of the patches. Since when reading old commits with e.g. git blame that's what people will read.
Yeah, I just noticed that. For some reason my git format-patch didn't place the commit messages above the signoff. Here comes v2.
Changes in this version * Fix missing commit messages in patch emails
These patches offer a fix for a monitor that doesn't report its native resolution in its EDID. The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
Dylan Semler (2): Enhances EDID quirks to allow for specifying and preferring a mode not reported in the EDID block. Adds EDID force mode quirk for MMT Monitor2Go HD+.
drivers/gpu/drm/drm_edid.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
Signed-off-by: Dylan Semler dylan.semler@gmail.com --- drivers/gpu/drm/drm_edid.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index c194f4e..b1036b5 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -68,6 +68,8 @@ #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) /* Force reduced-blanking timings for detailed modes */ #define EDID_QUIRK_FORCE_REDUCED_BLANKING (1 << 7) +/* Force specific mode for monitors that don't report correct EDIDs */ +#define EDID_QUIRK_FORCE_MODE (1 << 8)
struct detailed_mode_closure { struct drm_connector *connector; @@ -127,6 +129,15 @@ static struct edid_quirk { { "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING }, };
+static struct edid_quirk_force_mode { + char vendor[4]; + int product_id; + int hdisplay; + int vdisplay; + int vrefresh; +} edid_quirk_force_mode_list[] = { +}; + /* * Autogenerated from the DMT spec. * This table is copied from xfree86/modes/xf86EdidModes.c. @@ -2219,6 +2230,65 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, return closure.modes; }
+/* Add an explicit mode based on a quirk + */ +static int +do_force_quirk_modes(struct drm_connector *connector, int hdisplay, + int vdisplay, int vrefresh) +{ + struct drm_display_mode *mode; + struct drm_device *dev = connector->dev; + int num_modes = 0; + + /* sanity check display parameters */ + if (hdisplay < 0) + return 0; + if (vdisplay < 0) + return 0; + if (vrefresh < 0) + return 0; + + mode = drm_gtf_mode(dev, hdisplay, vdisplay, vrefresh, 0, 0); + + if (mode) { + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + num_modes++; + } + return num_modes; +} + +/* + * add_force_quirk_modes - Add modes based on monitor's EDID quirks + * @connector: attached connector + * @edid: EDID block to scan + * @quirks: quirks to apply + * + * At least one monitor doesn't report its native resolution in its EDID block. + * Here we add the native mode according to this quirk + */ +static int +add_force_quirk_modes(struct drm_connector *connector, struct edid *edid, + u32 quirks) +{ + struct edid_quirk_force_mode *quirk_mode; + int i, num_modes = 0; + + for (i = 0; i < ARRAY_SIZE(edid_quirk_force_mode_list); i++) { + quirk_mode = &edid_quirk_force_mode_list[i]; + + if (edid_vendor(edid, quirk_mode->vendor) && + (EDID_PRODUCT_ID(edid) == quirk_mode->product_id)) { + num_modes = do_force_quirk_modes(connector, + quirk_mode->hdisplay, + quirk_mode->vdisplay, + quirk_mode->vrefresh); + } + } + return num_modes; + +} + #define HDMI_IDENTIFIER 0x000C03 #define AUDIO_BLOCK 0x01 #define VIDEO_BLOCK 0x02 @@ -2803,6 +2873,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); + if (quirks & EDID_QUIRK_FORCE_MODE) + num_modes += add_force_quirk_modes(connector, edid, quirks);
drm_add_display_info(edid, &connector->display_info);
Signed-off-by: Dylan Semler dylan.semler@gmail.com --- drivers/gpu/drm/drm_edid.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index b1036b5..b400971 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -109,6 +109,9 @@ static struct edid_quirk { { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | EDID_QUIRK_DETAILED_IN_CM },
+ /* Mobile Monitor Technologies LLC, Monitor2Go HD+ */ + { "LLP", 0x4c54, EDID_QUIRK_FORCE_MODE}, + /* LG Philips LCD LP154W01-A5 */ { "LPL", 0, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, { "LPL", 0x2a00, EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE }, @@ -136,6 +139,8 @@ static struct edid_quirk_force_mode { int vdisplay; int vrefresh; } edid_quirk_force_mode_list[] = { + /* Mobile Monitor Technologies LLC, Monitor2Go HD+ */ + { "LLP", 0x4c54, 1600, 900, 60 }, };
/*
On Fri, Mar 22, 2013 at 09:48:49AM -0400, Dylan Semler wrote:
Changes in this version
- Fix missing commit messages in patch emails
Seems to be still missing. Also I kinda liked Alex' idea of adding a gtf/gtf2/cdt flag for the detailed timing generation algorithm. -Daniel
These patches offer a fix for a monitor that doesn't report its native resolution in its EDID. The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
Dylan Semler (2): Enhances EDID quirks to allow for specifying and preferring a mode not reported in the EDID block. Adds EDID force mode quirk for MMT Monitor2Go HD+.
drivers/gpu/drm/drm_edid.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+)
-- 1.7.11.7
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Thu, Mar 21, 2013 at 5:42 PM, Dylan Semler dylan.semler@gmail.com wrote:
Oops. I neglected to preface this with my motivation: I have a new monitor that doesn't report its native resolution in its EDID block. It seemed to me this calls for an EDID quirk, but the current quirk infrastructure doesn't allow explicitly creating new modes. So I set out to make a simple enhancement to allow specifying a new mode and then setting it as preferred.
That's odd. Maybe it's actually in an extension block or something like that?
On Thu, Mar 21, 2013 at 5:36 PM, Dylan Semler dylan.semler@gmail.com wrote:
The idea is setup a new quirk list with width, height, and refresh rates for each monitor that needs this quirk. If a monitor is attached that matches one in this list, the full modeline is calculated with drm_gtf_mode, the DRM_MODE_TYPE_PREFERRED bit is set, and the new mode is added to the connector.
The patch also creates a new quirk bit: EDID_QUIRK_FORCE_MODE. This bit needs to be set for the new quirk list discribed above to be checked.
The first patch enhances the quirk logic as described above. The second one adds my new monitor to the quirk lists.
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Fri, Mar 22, 2013 at 9:50 AM, Alex Deucher alexdeucher@gmail.com wrote:
On Thu, Mar 21, 2013 at 5:42 PM, Dylan Semler dylan.semler@gmail.com
wrote:
Oops. I neglected to preface this with my motivation: I have a new monitor that doesn't report its native resolution in its EDID block. It seemed to me this calls for an EDID quirk, but the current quirk infrastructure doesn't allow explicitly creating new modes. So I set
out
to make a simple enhancement to allow specifying a new mode and then setting it as preferred.
That's odd. Maybe it's actually in an extension block or something like that?
Yeah, I agree. According to edid-decode /sys/class/drm/card0-HDMI-A-1/edid there's one extension block, but none of those modes are the native resolution either.
On Fri, Mar 22, 2013 at 3:02 PM, Dylan Semler dylan.semler@gmail.com wrote:
On Fri, Mar 22, 2013 at 9:50 AM, Alex Deucher alexdeucher@gmail.com wrote:
On Thu, Mar 21, 2013 at 5:42 PM, Dylan Semler dylan.semler@gmail.com wrote:
Oops. I neglected to preface this with my motivation: I have a new monitor that doesn't report its native resolution in its EDID block. It seemed to me this calls for an EDID quirk, but the current quirk infrastructure doesn't allow explicitly creating new modes. So I set out to make a simple enhancement to allow specifying a new mode and then setting it as preferred.
That's odd. Maybe it's actually in an extension block or something like that?
Yeah, I agree. According to edid-decode /sys/class/drm/card0-HDMI-A-1/edid there's one extension block, but none of those modes are the native resolution either.
Hm, we only recently added support for E-EDID (i.e. more than 1 extension block). Have you checked whether latest kernels fare better? -Daniel
On Fri, Mar 22, 2013 at 10:41 AM, Daniel Vetter daniel@ffwll.ch wrote:
On Fri, Mar 22, 2013 at 3:02 PM, Dylan Semler dylan.semler@gmail.com
wrote:
On Fri, Mar 22, 2013 at 9:50 AM, Alex Deucher alexdeucher@gmail.com wrote:
That's odd. Maybe it's actually in an extension block or something
like
that?
Yeah, I agree. According to edid-decode
/sys/class/drm/card0-HDMI-A-1/edid
there's one extension block, but none of those modes are the native resolution either.
Hm, we only recently added support for E-EDID (i.e. more than 1 extension block). Have you checked whether latest kernels fare better?
I just tried booting with 3.9rc3 and my distro's latest package of xorg-utils; I get the same results.
dri-devel@lists.freedesktop.org