[PATCH 08/10] drm/exynos/mixer: pass actual mode on MIXER to encoder

Tobias Jakobi tjakobi at math.uni-bielefeld.de
Tue Sep 12 12:49:35 UTC 2017


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 <tjakobi at math.uni-bielefeld.de>


> Signed-off-by: Andrzej Hajda <a.hajda at 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 = {
> 



More information about the dri-devel mailing list