[PATCH 2/2] drm/edid: Consider alternate cea timings to be the same VIC
Ville Syrjälä
ville.syrjala at linux.intel.com
Mon Nov 28 16:33:01 UTC 2016
On Tue, Nov 08, 2016 at 12:43:55PM +0100, Andrzej Hajda wrote:
> On 03.11.2016 13:53, ville.syrjala at linux.intel.com wrote:
> > From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> >
> > CEA-861 specifies that the vertical front porch may vary by one or two
> > lines for specific VICs. Up to now we've only considered a mode to match
> > the VIC if it matched the shortest possible vertical front porch length
> > (as that is the variant we store in cea_modes[]). Let's allow our VIC
> > matching to work with the other timings variants as well so that that
> > we'll send out the correct VIC if the variant actually used isn't the
> > one with the shortest vertical front porch.
> >
> > Cc: Shashank Sharma <shashank.sharma at intel.com>
> > Cc: Andrzej Hajda <a.hajda at samsung.com>
> > Cc: Adam Jackson <ajax at redhat.com>
> > Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> I have checked against specification and it looks OK.
> I have few nitpicks below regarding implementation, but this could be
> matter of taste, so:
>
> Reviewed-by: Andrzej Hajda <a.hajda at samsung.com>
I decieded to leave the ideas for further improvements to cook
longer.
Patch pushed to drm-misc-next. Thanks for the review.
>
>
> > ---
> > drivers/gpu/drm/drm_edid.c | 66 +++++++++++++++++++++++++++++++++++++---------
> > 1 file changed, 54 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> > index 7eec18925b70..728990fee4ef 100644
> > --- a/drivers/gpu/drm/drm_edid.c
> > +++ b/drivers/gpu/drm/drm_edid.c
> > @@ -2613,6 +2613,41 @@ cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
> > return clock;
> > }
> >
> > +static bool
> > +cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
> > +{
> > + /*
> > + * For certain VICs the spec allows the vertical
> > + * front porch to vary by one or two lines.
> > + *
> > + * cea_modes[] stores the variant with the shortest
> > + * vertical front porch. We can adjust the mode to
> > + * get the other variants by simply increasing the
> > + * vertical front porch length.
> > + */
> > + BUILD_BUG_ON(edid_cea_modes[8].vtotal != 262 ||
> > + edid_cea_modes[9].vtotal != 262 ||
> > + edid_cea_modes[12].vtotal != 262 ||
> > + edid_cea_modes[13].vtotal != 262 ||
> > + edid_cea_modes[23].vtotal != 312 ||
> > + edid_cea_modes[24].vtotal != 312 ||
> > + edid_cea_modes[27].vtotal != 312 ||
> > + edid_cea_modes[28].vtotal != 312);
>
> I am not sure if this compile check is really necessary,
> I would rather put comment before edid_cea_modes array
> which mode should be put into array in multi-mode case.
>
> > +
> > + if (((vic == 8 || vic == 9 ||
> > + vic == 12 || vic == 13) && mode->vtotal < 263) ||
> > + ((vic == 23 || vic == 24 ||
> > + vic == 27 || vic == 28) && mode->vtotal < 314)) {
>
> I wonder if it wouldn't be better to mark somehow these modes
> in the array as alternating ones. This way all info about cea modes
> will be in one place. For example by (ab)using private_flags:
> /* 8 - 720(1440)x240 at 60Hz */
> { DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500, 720, 739,
> 801, 858, 0, 240, 244, 247, 262, 0,
> DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
> DRM_MODE_FLAG_DBLCLK),
> .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> .private_flags = CEA_MODE_FLAG_VFP2},
>
> This is of course just an idea, I am not sure if not overkill :)
>
>
> > + mode->vsync_start++;
> > + mode->vsync_end++;
> > + mode->vtotal++;
> > +
> > + return true;
> > + }
> > +
> > + return false;
> > +}
> > +
> > static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
> > unsigned int clock_tolerance)
> > {
> > @@ -2622,19 +2657,21 @@ static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_m
> > return 0;
> >
> > for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
> > - const struct drm_display_mode *cea_mode = &edid_cea_modes[vic];
> > + struct drm_display_mode cea_mode = edid_cea_modes[vic];
> > unsigned int clock1, clock2;
> >
> > /* Check both 60Hz and 59.94Hz */
> > - clock1 = cea_mode->clock;
> > - clock2 = cea_mode_alternate_clock(cea_mode);
> > + clock1 = cea_mode.clock;
> > + clock2 = cea_mode_alternate_clock(&cea_mode);
> >
> > if (abs(to_match->clock - clock1) > clock_tolerance &&
> > abs(to_match->clock - clock2) > clock_tolerance)
> > continue;
> >
> > - if (drm_mode_equal_no_clocks(to_match, cea_mode))
> > - return vic;
> > + do {
> > + if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
> > + return vic;
> > + } while (cea_mode_alternate_timings(vic, &cea_mode));
> > }
> >
> > return 0;
> > @@ -2655,18 +2692,23 @@ u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
> > return 0;
> >
> > for (vic = 1; vic < ARRAY_SIZE(edid_cea_modes); vic++) {
> > - const struct drm_display_mode *cea_mode = &edid_cea_modes[vic];
> > + struct drm_display_mode cea_mode = edid_cea_modes[vic];
> > unsigned int clock1, clock2;
> >
> > /* Check both 60Hz and 59.94Hz */
> > - clock1 = cea_mode->clock;
> > - clock2 = cea_mode_alternate_clock(cea_mode);
> > + clock1 = cea_mode.clock;
> > + clock2 = cea_mode_alternate_clock(&cea_mode);
> >
> > - if ((KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock1) ||
> > - KHZ2PICOS(to_match->clock) == KHZ2PICOS(clock2)) &&
> > - drm_mode_equal_no_clocks_no_stereo(to_match, cea_mode))
> > - return vic;
> > + if (KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock1) &&
> > + KHZ2PICOS(to_match->clock) != KHZ2PICOS(clock2))
> > + continue;
> > +
> > + do {
> > + if (drm_mode_equal_no_clocks_no_stereo(to_match, &cea_mode))
> > + return vic;
> > + } while (cea_mode_alternate_timings(vic, &cea_mode));
> > }
> > +
> > return 0;
> > }
> > EXPORT_SYMBOL(drm_match_cea_mode);
>
> And finally there is no modification of add_alternate_cea_modes, but I
> guess it can be added later.
>
>
> Regards
>
> Andrzej
>
>
>
--
Ville Syrjälä
Intel OTC
More information about the dri-devel
mailing list