[Intel-gfx] [PATCH] drm/edid: Adding common CVT inferred modes when monitor allows range limited ones trough EDID.
Adam Jackson
ajax at redhat.com
Thu Apr 12 18:03:21 CEST 2012
On Wed, 2012-04-11 at 21:59 -0300, Rodrigo Vivi wrote:
> There are many bugs open on fd.o regarding missing modes that are supported on Windows and other closed source drivers.
> From EDID spec we can (might?) infer modes using GTF and CVT when monitor allows it trough range limited flag... obviously limiting by the range.
> From our code:
> * EDID spec says modes should be preferred in this order:
> * - preferred detailed mode
> * - other detailed modes from base block
> * - detailed modes from extension blocks
> * - CVT 3-byte code modes
> * - standard timing codes
> * - established timing codes
> * - modes inferred from GTF or CVT range information
> *
> * We get this pretty much right.
>
> Not actually so right... We were inferring just using GTF... not CVT or even GTF2.
> This patch not just add some common cvt modes but also allows some modes been inferred when using gtf2 as well.
The intent here is great, but I don't like the way this is phrased, or
the implementation.
CVT monitors _must_ accept GTF as well, EDID says so. So functionally
there's nothing wrong with the existing code. The thing you're trying
to sneak in here is a 1600x900 timing that doesn't correspond to
anything in DMT (at least, not in the copy of DMT that I have handy).
It's fine to want to add more modes - although I'm still unclear exactly
which machine you're trying to compensate for here - but not if it comes
by sacrificing the DMT list, which is there for a reason.
So...
> +static int
> +drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
> + struct detailed_timing *timing)
> +{
> + int i, modes = 0;
> + struct drm_display_mode *newmode;
> + struct drm_device *dev = connector->dev;
> +
> + for (i = 0; i < drm_num_cvt_inferred_modes; i++) {
> + if (mode_in_range(drm_cvt_inferred_modes + i, edid, timing)) {
> + newmode = drm_mode_duplicate(dev, &drm_cvt_inferred_modes[i]);
> + if (newmode) {
> + drm_mode_probed_add(connector, newmode);
> + modes++;
> + }
> + }
> + }
> +
> + return modes;
> +}
The mode list you're iterating over here should just be a w/h/r/rb tuple
like est3_modes. This list should _not_ duplicate any size or rate
already present in the DMT list. There should be a function like this
for each of CVT and GTF (and I guess dual-curve GTF too, although
honestly I have no monitors left that support it with which to test),
all iterating over the same list, and they should generate the timing
from drm_{cvt,gtf}_mode(). The CVT version should generate RB modes if
the monitor is RB-capable.
> static void
> do_inferred_modes(struct detailed_timing *timing, void *c)
> {
> struct detailed_mode_closure *closure = c;
> struct detailed_non_pixel *data = &timing->data.other_data;
> - int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF);
> + int timing_level = standard_timing_level(closure->edid);
>
> - if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE)
> + if (data->type == EDID_DETAIL_MONITOR_RANGE)
> + switch (timing_level) {
> + case LEVEL_DMT:
> + break;
> + case LEVEL_GTF:
> + case LEVEL_GTF2:
> closure->modes += drm_gtf_modes_for_range(closure->connector,
> closure->edid,
> timing);
> + break;
> + case LEVEL_CVT:
> + closure->modes += drm_cvt_modes_for_range(closure->connector,
> + closure->edid,
> + timing);
> + break;
> + }
> }
drm_gtf_modes_for_range should be renamed drm_dmt_modes_for_range, and
run unconditionally for the range descriptor. drm_*_modes_for_range
will then handle generating the timings by formula.
> + /* 900x600 at 60Hz */
> + { DRM_MODE("900x600", DRM_MODE_TYPE_DRIVER, 45250, 960, 992,
> + 1088, 1216, 0, 600, 603, 609, 624, 0,
> + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
> + /* 1024x576 at 60Hz */
> + { DRM_MODE("1024x576", DRM_MODE_TYPE_DRIVER, 46500, 1024, 1064,
> + 1160, 1296, 0, 576, 579, 584, 599, 0,
> + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
Citation needed. Can you point to real hardware with these panel sizes,
or are you just copying from Windows?
> + /* 2560x1600 at 60Hz */
> + { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2760,
> + 3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
> + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
lol no. Nobody does a size this large without also doing reduced
blanking.
I have a patch somewhere to fix the DMT list to re-include the reduced
blanking modes (as should have been done in the first place). I'll send
that along.
- ajax
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20120412/81cc067d/attachment.sig>
More information about the Intel-gfx
mailing list