Hello Andrzej,

Andrzej Hajda wrote:
> MIXER in SoCs prior to Exynos5420 supports only 4 video modes:
> 720x480, 720x576, 1280x720, 1920x1080. Support for other modes can be
> enabled by manipulating timings of HDMI. To allow it MIXER must pass
> actual video mode to HDMI, the proper way to do it is to modify
> adjusted_mode property in crtc::mode_fixup callback. Adding such callback
> allows also to simplify mixer_cfg_scan code - choosing mode is performed
> already in crtc::mode_fixup. mode_fixup is also better place to check
> interlace flag.

Reviewed-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de>


> Signed-off-by: Andrzej Hajda <a.ha...@samsung.com>
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 70 
> +++++++++++++++++++++++++----------
>  1 file changed, 50 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
> b/drivers/gpu/drm/exynos/exynos_mixer.c
> index f6ea9d9..5aae82b 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -115,6 +115,7 @@ struct mixer_context {
>       struct clk              *sclk_hdmi;
>       struct clk              *mout_mixer;
>       enum mixer_version_id   mxr_ver;
> +     int                     scan_value;
>  };
>  
>  struct mixer_drv_data {
> @@ -367,23 +368,11 @@ static void mixer_cfg_scan(struct mixer_context *ctx, 
> int width, int height)
>       val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ?
>               MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE;
>  
> -     /* setup display size */
> -     if (ctx->mxr_ver == MXR_VER_128_0_0_184) {
> +     if (ctx->mxr_ver == MXR_VER_128_0_0_184)
>               mixer_reg_write(ctx, MXR_RESOLUTION,
>                       MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
> -     } else {
> -             /* choosing between proper HD and SD mode */
> -             if (height <= 480)
> -                     val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
> -             else if (height <= 576)
> -                     val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
> -             else if (height <= 720)
> -                     val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
> -             else if (height <= 1080)
> -                     val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
> -             else
> -                     val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
> -     }
> +     else
> +             val |= ctx->scan_value;
>  
>       mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK);
>  }
> @@ -467,11 +456,6 @@ static void mixer_commit(struct mixer_context *ctx)
>  {
>       struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode;
>  
> -     if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> -             __set_bit(MXR_BIT_INTERLACE, &ctx->flags);
> -     else
> -             __clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
> -
>       mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay);
>       mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
>       mixer_run(ctx);
> @@ -1033,6 +1017,51 @@ static int mixer_mode_valid(struct exynos_drm_crtc 
> *crtc,
>       return MODE_BAD;
>  }
>  
> +static bool mixer_mode_fixup(struct exynos_drm_crtc *crtc,
> +                const struct drm_display_mode *mode,
> +                struct drm_display_mode *adjusted_mode)
> +{
> +     struct mixer_context *ctx = crtc->ctx;
> +     int width = mode->hdisplay, height = mode->vdisplay, i;
> +
> +     struct {
> +             int hdisplay, vdisplay, htotal, vtotal, scan_val;
> +     } static const modes[] = {
> +             { 720, 480, 858, 525, MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD },
> +             { 720, 576, 864, 625, MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD },
> +             { 1280, 720, 1650, 750, MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD },
> +             { 1920, 1080, 2200, 1125, MXR_CFG_SCAN_HD_1080 | 
> MXR_CFG_SCAN_HD }
> +     };
> +
> +     if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> +             __set_bit(MXR_BIT_INTERLACE, &ctx->flags);
> +     else
> +             __clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
> +
> +     if (ctx->mxr_ver == MXR_VER_128_0_0_184)
> +             return true;
> +
> +     for (i = 0; i < ARRAY_SIZE(modes); ++i)
> +             if (width <= modes[i].hdisplay && height <= modes[i].vdisplay) {
> +                     ctx->scan_value = modes[i].scan_val;
> +                     if (width < modes[i].hdisplay ||
> +                         height < modes[i].vdisplay) {
> +                             adjusted_mode->hdisplay = modes[i].hdisplay;
> +                             adjusted_mode->hsync_start = modes[i].hdisplay;
> +                             adjusted_mode->hsync_end = modes[i].htotal;
> +                             adjusted_mode->htotal = modes[i].htotal;
> +                             adjusted_mode->vdisplay = modes[i].vdisplay;
> +                             adjusted_mode->vsync_start = modes[i].vdisplay;
> +                             adjusted_mode->vsync_end = modes[i].vtotal;
> +                             adjusted_mode->vtotal = modes[i].vtotal;
> +                     }
> +
> +                     return true;
> +             }
> +
> +     return false;
> +}
> +
>  static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
>       .enable                 = mixer_enable,
>       .disable                = mixer_disable,
> @@ -1043,6 +1072,7 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops 
> = {
>       .disable_plane          = mixer_disable_plane,
>       .atomic_flush           = mixer_atomic_flush,
>       .mode_valid             = mixer_mode_valid,
> +     .mode_fixup             = mixer_mode_fixup,
>  };
>  
>  static const struct mixer_drv_data exynos5420_mxr_drv_data = {
> 

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to