From: Jani Nikula <jani.nikula@linux.intel.com>
To: Dylan Semler <dylan.semler@gmail.com>, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v3 1/2] drm: Enhance EDID quirks to explicitly set a mode
Date: Mon, 25 Mar 2013 15:41:25 +0200 [thread overview]
Message-ID: <87vc8fppfe.fsf@intel.com> (raw)
In-Reply-To: <1363993687-6935-2-git-send-email-dylan.semler@gmail.com>
Hi, please find some review comments inline.
BR,
Jani.
On Sat, 23 Mar 2013, Dylan Semler <dylan.semler@gmail.com> wrote:
> There is at least one monitor that doesn't report its native resolution
> in its EDID block. This enhancement extends the EDID quirk logic to
> make monitors like this "just work".
>
> This patch sets up a new quirk list where monitors' correct width,
> height, refresh rate, and reduced blanking parameters are specified.
> When a matching monitor is attached the full mode is calculated with
> drm_cvt_mode() and added to the connector. The DRM_MODE_TYPE_PREFERRED
> bit is set on the new mode and unset from all other modes.
>
> The patch also defines a new quirk bit: EDID_QUIRK_FORCE_MODE. This
> bit needs to be set for the new quirk list discribed above to be
> checked.
>
> Signed-off-by: Dylan Semler <dylan.semler@gmail.com>
> ---
> drivers/gpu/drm/drm_edid.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 78 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index c194f4e..38b8641 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,16 @@ 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;
> + bool reduced;
> +} edid_quirk_force_mode_list[] = {
> +};
> +
> /*
> * Autogenerated from the DMT spec.
> * This table is copied from xfree86/modes/xf86EdidModes.c.
> @@ -2219,6 +2231,70 @@ 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, bool reduced)
Nitpick: This adds one mode, not many _modes_.
> +{
> + struct drm_display_mode *mode, *t, *cur_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;
> +
> + /* loop through the probed modes and clear the preferred bit */
> + list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head)
> + cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
You're not deleting entries, so list_for_each_entry() would suffice,
getting rid of the temp variable.
> +
> + mode = drm_cvt_mode(dev, hdisplay, vdisplay, vrefresh, reduced, 0, 0);
You could
if (!mode)
return 0;
here and get rid of the num_modes variable.
> +
> + 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,
> + quirk_mode->reduced);
I was wondering why you don't bail out here. Maybe you want to be able
to add more than one quirk mode? In that case you should +=, not = the
num_modes.
(Note that then do_force_quirk_modes makes the last one in the array the
preferred mode, clearing the DRM_MODE_TYPE_PREFERRED from the previously
added quirk modes.)
> + }
> + }
> + return num_modes;
> +
> +}
> +
> #define HDMI_IDENTIFIER 0x000C03
> #define AUDIO_BLOCK 0x01
> #define VIDEO_BLOCK 0x02
> @@ -2803,6 +2879,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);
You don't use quirks within add_force_quirk_modes() for anything.
>
> 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
next prev parent reply other threads:[~2013-03-25 13:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-22 23:08 [PATCH v3 0/2] Enhance EDID quirks to allow forcing a mode Dylan Semler
2013-03-22 23:08 ` [PATCH v3 1/2] drm: Enhance EDID quirks to explicitly set " Dylan Semler
2013-03-25 13:41 ` Jani Nikula [this message]
2013-03-25 17:01 ` Dylan Semler
2013-03-25 17:29 ` Jani Nikula
2013-03-22 23:08 ` [PATCH v3 2/2] drm: Add EDID force quirk for MMT Monitor2Go HD+ Dylan Semler
2013-03-23 12:56 ` [PATCH v3 0/2] Enhance EDID quirks to allow forcing a mode Daniel Vetter
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=87vc8fppfe.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=dylan.semler@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.