static void meson_venc_hdmi_mode_set()

in drivers/video/meson/meson_venc.c [753:1365]


static void meson_venc_hdmi_mode_set(struct meson_vpu_priv *priv,
				     const struct display_timing *mode)
{
	union meson_hdmi_venc_mode *vmode = NULL;
	union meson_hdmi_venc_mode vmode_dmt;
	bool use_enci = false;
	bool venc_repeat = false;
	bool hdmi_repeat = false;
	unsigned int venc_hdmi_latency = 2;
	unsigned long total_pixels_venc = 0;
	unsigned long active_pixels_venc = 0;
	unsigned long front_porch_venc = 0;
	unsigned long hsync_pixels_venc = 0;
	unsigned long de_h_begin = 0;
	unsigned long de_h_end = 0;
	unsigned long de_v_begin_even = 0;
	unsigned long de_v_end_even = 0;
	unsigned long de_v_begin_odd = 0;
	unsigned long de_v_end_odd = 0;
	unsigned long hs_begin = 0;
	unsigned long hs_end = 0;
	unsigned long vs_adjust = 0;
	unsigned long vs_bline_evn = 0;
	unsigned long vs_eline_evn = 0;
	unsigned long vs_bline_odd = 0;
	unsigned long vs_eline_odd = 0;
	unsigned long vso_begin_evn = 0;
	unsigned long vso_begin_odd = 0;
	unsigned int eof_lines;
	unsigned int sof_lines;
	unsigned int vsync_lines;
	u32 reg;

	/* Use VENCI for 480i and 576i and double HDMI pixels */
	if (mode->flags & DISPLAY_FLAGS_DOUBLECLK) {
		hdmi_repeat = true;
		use_enci = true;
		venc_hdmi_latency = 1;
	}

	meson_venc_hdmi_get_dmt_vmode(mode, &vmode_dmt);
	vmode = &vmode_dmt;
	use_enci = false;

	debug(" max_pxcnt   %04d, max_lncnt   %04d\n"
	      " havon_begin %04d, havon_end   %04d\n"
	      " vavon_bline %04d, vavon_eline %04d\n"
	      " hso_begin   %04d, hso_end     %04d\n"
	      " vso_begin   %04d, vso_end     %04d\n"
	      " vso_bline   %04d, vso_eline   %04d\n",
		vmode->encp.max_pxcnt,   vmode->encp.max_lncnt,
		vmode->encp.havon_begin, vmode->encp.havon_end,
		vmode->encp.vavon_bline, vmode->encp.vavon_eline,
		vmode->encp.hso_begin,   vmode->encp.hso_end,
		vmode->encp.vso_begin,   vmode->encp.vso_end,
		vmode->encp.vso_bline,   vmode->encp.vso_eline);

	eof_lines = mode->vfront_porch.typ;
	if (mode->flags & DISPLAY_FLAGS_INTERLACED)
		eof_lines /= 2;

	sof_lines = mode->vback_porch.typ;
	if (mode->flags & DISPLAY_FLAGS_INTERLACED)
		sof_lines /= 2;

	vsync_lines = mode->vsync_len.typ;
	if (mode->flags & DISPLAY_FLAGS_INTERLACED)
		vsync_lines /= 2;

	total_pixels_venc = mode->hback_porch.typ + mode->hactive.typ +
			mode->hfront_porch.typ + mode->hsync_len.typ;
	if (hdmi_repeat)
		total_pixels_venc /= 2;
	if (venc_repeat)
		total_pixels_venc *= 2;

	active_pixels_venc = mode->hactive.typ;
	if (hdmi_repeat)
		active_pixels_venc /= 2;
	if (venc_repeat)
		active_pixels_venc *= 2;

	front_porch_venc = mode->hfront_porch.typ;
	if (hdmi_repeat)
		front_porch_venc /= 2;
	if (venc_repeat)
		front_porch_venc *= 2;

	hsync_pixels_venc = mode->hsync_len.typ;
	if (hdmi_repeat)
		hsync_pixels_venc /= 2;
	if (venc_repeat)
		hsync_pixels_venc *= 2;

	/* Disable VDACs */
	writel_bits(0xff, 0xff,
		    priv->io_base + _REG(VENC_VDAC_SETTING));

	writel(0, priv->io_base + _REG(ENCI_VIDEO_EN));
	writel(0, priv->io_base + _REG(ENCP_VIDEO_EN));

	debug("use_enci: %d, hdmi_repeat: %d\n", use_enci, hdmi_repeat);

	if (use_enci) {
		unsigned int lines_f0;
		unsigned int lines_f1;

		/* CVBS Filter settings */
		writel(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
		       priv->io_base + _REG(ENCI_CFILT_CTRL));
		writel(ENCI_CFILT_CMPT_CR_DLY(2) |
		       ENCI_CFILT_CMPT_CB_DLY(1),
		       priv->io_base + _REG(ENCI_CFILT_CTRL2));

		/* Digital Video Select : Interlace, clk27 clk, external */
		writel(0, priv->io_base + _REG(VENC_DVI_SETTING));

		/* Reset Video Mode */
		writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE));
		writel(0, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));

		/* Horizontal sync signal output */
		writel(vmode->enci.hso_begin,
		       priv->io_base + _REG(ENCI_SYNC_HSO_BEGIN));
		writel(vmode->enci.hso_end,
		       priv->io_base + _REG(ENCI_SYNC_HSO_END));

		/* Vertical Sync lines */
		writel(vmode->enci.vso_even,
		       priv->io_base + _REG(ENCI_SYNC_VSO_EVNLN));
		writel(vmode->enci.vso_odd,
		       priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));

		/* Macrovision max amplitude change */
		writel(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
		       ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp),
		       priv->io_base + _REG(ENCI_MACV_MAX_AMP));

		/* Video mode */
		writel(vmode->enci.video_prog_mode,
		       priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
		writel(vmode->enci.video_mode,
		       priv->io_base + _REG(ENCI_VIDEO_MODE));

		/*
		 * Advanced Video Mode :
		 * Demux shifting 0x2
		 * Blank line end at line17/22
		 * High bandwidth Luma Filter
		 * Low bandwidth Chroma Filter
		 * Bypass luma low pass filter
		 * No macrovision on CSYNC
		 */
		writel(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
		       ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
		       ENCI_VIDEO_MODE_ADV_YBW_HIGH,
		       priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));

		writel(vmode->enci.sch_adjust,
		       priv->io_base + _REG(ENCI_VIDEO_SCH));

		/* Sync mode : MASTER Master mode, free run, send HSO/VSO out */
		writel(0x07, priv->io_base + _REG(ENCI_SYNC_MODE));

		if (vmode->enci.yc_delay)
			writel(vmode->enci.yc_delay,
			       priv->io_base + _REG(ENCI_YC_DELAY));

		/* UNreset Interlaced TV Encoder */
		writel(0, priv->io_base + _REG(ENCI_DBG_PX_RST));

		/*
		 * Enable Vfifo2vd and set Y_Cb_Y_Cr:
		 * Corresponding value:
		 * Y  => 00 or 10
		 * Cb => 01
		 * Cr => 11
		 * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
		 */
		writel(ENCI_VFIFO2VD_CTL_ENABLE |
		       ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
		       priv->io_base + _REG(ENCI_VFIFO2VD_CTL));

		/* Timings */
		writel(vmode->enci.pixel_start,
		       priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_START));
		writel(vmode->enci.pixel_end,
		       priv->io_base + _REG(ENCI_VFIFO2VD_PIXEL_END));

		writel(vmode->enci.top_field_line_start,
		       priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_START));
		writel(vmode->enci.top_field_line_end,
		       priv->io_base + _REG(ENCI_VFIFO2VD_LINE_TOP_END));

		writel(vmode->enci.bottom_field_line_start,
		       priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_START));
		writel(vmode->enci.bottom_field_line_end,
		       priv->io_base + _REG(ENCI_VFIFO2VD_LINE_BOT_END));

		/* Select ENCI for VIU */
		meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);

		/* Interlace video enable */
		writel(ENCI_VIDEO_EN_ENABLE,
		       priv->io_base + _REG(ENCI_VIDEO_EN));

		lines_f0 = mode->vback_porch.typ + mode->vactive.typ +
			   mode->vback_porch.typ + mode->vsync_len.typ;
		lines_f0 = lines_f0 >> 1;
		lines_f1 = lines_f0 + 1;

		de_h_begin = modulo(readl(priv->io_base +
					_REG(ENCI_VFIFO2VD_PIXEL_START))
					+ venc_hdmi_latency,
				    total_pixels_venc);
		de_h_end  = modulo(de_h_begin + active_pixels_venc,
				   total_pixels_venc);

		writel(de_h_begin,
		       priv->io_base + _REG(ENCI_DE_H_BEGIN));
		writel(de_h_end,
		       priv->io_base + _REG(ENCI_DE_H_END));

		de_v_begin_even = readl(priv->io_base +
					_REG(ENCI_VFIFO2VD_LINE_TOP_START));
		de_v_end_even  = de_v_begin_even + mode->vactive.typ;
		de_v_begin_odd = readl(priv->io_base +
					_REG(ENCI_VFIFO2VD_LINE_BOT_START));
		de_v_end_odd = de_v_begin_odd + mode->vactive.typ;

		writel(de_v_begin_even,
		       priv->io_base + _REG(ENCI_DE_V_BEGIN_EVEN));
		writel(de_v_end_even,
		       priv->io_base + _REG(ENCI_DE_V_END_EVEN));
		writel(de_v_begin_odd,
		       priv->io_base + _REG(ENCI_DE_V_BEGIN_ODD));
		writel(de_v_end_odd,
		       priv->io_base + _REG(ENCI_DE_V_END_ODD));

		/* Program Hsync timing */
		hs_begin = de_h_end + front_porch_venc;
		if (de_h_end + front_porch_venc >= total_pixels_venc) {
			hs_begin -= total_pixels_venc;
			vs_adjust  = 1;
		} else {
			hs_begin = de_h_end + front_porch_venc;
			vs_adjust  = 0;
		}

		hs_end = modulo(hs_begin + hsync_pixels_venc,
				total_pixels_venc);
		writel(hs_begin,
		       priv->io_base + _REG(ENCI_DVI_HSO_BEGIN));
		writel(hs_end,
		       priv->io_base + _REG(ENCI_DVI_HSO_END));

		/* Program Vsync timing for even field */
		if (((de_v_end_odd - 1) + eof_lines + vs_adjust) >= lines_f1) {
			vs_bline_evn = (de_v_end_odd - 1)
					+ eof_lines
					+ vs_adjust
					- lines_f1;
			vs_eline_evn = vs_bline_evn + vsync_lines;

			writel(vs_bline_evn,
			       priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));

			writel(vs_eline_evn,
			       priv->io_base + _REG(ENCI_DVI_VSO_ELINE_EVN));

			writel(hs_begin,
			       priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_EVN));
			writel(hs_begin,
			       priv->io_base + _REG(ENCI_DVI_VSO_END_EVN));
		} else {
			vs_bline_odd = (de_v_end_odd - 1)
					+ eof_lines
					+ vs_adjust;

			writel(vs_bline_odd,
			       priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));

			writel(hs_begin,
			       priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));

			if ((vs_bline_odd + vsync_lines) >= lines_f1) {
				vs_eline_evn = vs_bline_odd
						+ vsync_lines
						- lines_f1;

				writel(vs_eline_evn, priv->io_base
				       + _REG(ENCI_DVI_VSO_ELINE_EVN));

				writel(hs_begin, priv->io_base
				       + _REG(ENCI_DVI_VSO_END_EVN));
			} else {
				vs_eline_odd = vs_bline_odd
						+ vsync_lines;

				writel(vs_eline_odd, priv->io_base
				       + _REG(ENCI_DVI_VSO_ELINE_ODD));

				writel(hs_begin, priv->io_base
				       + _REG(ENCI_DVI_VSO_END_ODD));
			}
		}

		/* Program Vsync timing for odd field */
		if (((de_v_end_even - 1) + (eof_lines + 1)) >= lines_f0) {
			vs_bline_odd = (de_v_end_even - 1)
					+ (eof_lines + 1)
					- lines_f0;
			vs_eline_odd = vs_bline_odd + vsync_lines;

			writel(vs_bline_odd,
			       priv->io_base + _REG(ENCI_DVI_VSO_BLINE_ODD));

			writel(vs_eline_odd,
			       priv->io_base + _REG(ENCI_DVI_VSO_ELINE_ODD));

			vso_begin_odd  = modulo(hs_begin
						+ (total_pixels_venc >> 1),
						total_pixels_venc);

			writel(vso_begin_odd,
			       priv->io_base + _REG(ENCI_DVI_VSO_BEGIN_ODD));
			writel(vso_begin_odd,
			       priv->io_base + _REG(ENCI_DVI_VSO_END_ODD));
		} else {
			vs_bline_evn = (de_v_end_even - 1)
					+ (eof_lines + 1);

			writel(vs_bline_evn,
			       priv->io_base + _REG(ENCI_DVI_VSO_BLINE_EVN));

			vso_begin_evn  = modulo(hs_begin
						+ (total_pixels_venc >> 1),
						total_pixels_venc);

			writel(vso_begin_evn, priv->io_base
					+ _REG(ENCI_DVI_VSO_BEGIN_EVN));

			if (vs_bline_evn + vsync_lines >= lines_f0) {
				vs_eline_odd = vs_bline_evn
						+ vsync_lines
						- lines_f0;

				writel(vs_eline_odd, priv->io_base
						+ _REG(ENCI_DVI_VSO_ELINE_ODD));

				writel(vso_begin_evn, priv->io_base
						+ _REG(ENCI_DVI_VSO_END_ODD));
			} else {
				vs_eline_evn = vs_bline_evn + vsync_lines;

				writel(vs_eline_evn, priv->io_base
						+ _REG(ENCI_DVI_VSO_ELINE_EVN));

				writel(vso_begin_evn, priv->io_base
						+ _REG(ENCI_DVI_VSO_END_EVN));
			}
		}
	} else {
		writel(vmode->encp.dvi_settings,
		       priv->io_base + _REG(VENC_DVI_SETTING));
		writel(vmode->encp.video_mode,
		       priv->io_base + _REG(ENCP_VIDEO_MODE));
		writel(vmode->encp.video_mode_adv,
		       priv->io_base + _REG(ENCP_VIDEO_MODE_ADV));
		if (vmode->encp.video_prog_mode_present)
			writel(vmode->encp.video_prog_mode,
			       priv->io_base + _REG(VENC_VIDEO_PROG_MODE));
		if (vmode->encp.video_sync_mode_present)
			writel(vmode->encp.video_sync_mode,
			       priv->io_base + _REG(ENCP_VIDEO_SYNC_MODE));
		if (vmode->encp.video_yc_dly_present)
			writel(vmode->encp.video_yc_dly,
			       priv->io_base + _REG(ENCP_VIDEO_YC_DLY));
		if (vmode->encp.video_rgb_ctrl_present)
			writel(vmode->encp.video_rgb_ctrl,
			       priv->io_base + _REG(ENCP_VIDEO_RGB_CTRL));
		if (vmode->encp.video_filt_ctrl_present)
			writel(vmode->encp.video_filt_ctrl,
			       priv->io_base + _REG(ENCP_VIDEO_FILT_CTRL));
		if (vmode->encp.video_ofld_voav_ofst_present)
			writel(vmode->encp.video_ofld_voav_ofst,
			       priv->io_base
			       + _REG(ENCP_VIDEO_OFLD_VOAV_OFST));
		writel(vmode->encp.yfp1_htime,
		       priv->io_base + _REG(ENCP_VIDEO_YFP1_HTIME));
		writel(vmode->encp.yfp2_htime,
		       priv->io_base + _REG(ENCP_VIDEO_YFP2_HTIME));
		writel(vmode->encp.max_pxcnt,
		       priv->io_base + _REG(ENCP_VIDEO_MAX_PXCNT));
		writel(vmode->encp.hspuls_begin,
		       priv->io_base + _REG(ENCP_VIDEO_HSPULS_BEGIN));
		writel(vmode->encp.hspuls_end,
		       priv->io_base + _REG(ENCP_VIDEO_HSPULS_END));
		writel(vmode->encp.hspuls_switch,
		       priv->io_base + _REG(ENCP_VIDEO_HSPULS_SWITCH));
		writel(vmode->encp.vspuls_begin,
		       priv->io_base + _REG(ENCP_VIDEO_VSPULS_BEGIN));
		writel(vmode->encp.vspuls_end,
		       priv->io_base + _REG(ENCP_VIDEO_VSPULS_END));
		writel(vmode->encp.vspuls_bline,
		       priv->io_base + _REG(ENCP_VIDEO_VSPULS_BLINE));
		writel(vmode->encp.vspuls_eline,
		       priv->io_base + _REG(ENCP_VIDEO_VSPULS_ELINE));
		if (vmode->encp.eqpuls_begin_present)
			writel(vmode->encp.eqpuls_begin,
			       priv->io_base + _REG(ENCP_VIDEO_EQPULS_BEGIN));
		if (vmode->encp.eqpuls_end_present)
			writel(vmode->encp.eqpuls_end,
			       priv->io_base + _REG(ENCP_VIDEO_EQPULS_END));
		if (vmode->encp.eqpuls_bline_present)
			writel(vmode->encp.eqpuls_bline,
			       priv->io_base + _REG(ENCP_VIDEO_EQPULS_BLINE));
		if (vmode->encp.eqpuls_eline_present)
			writel(vmode->encp.eqpuls_eline,
			       priv->io_base + _REG(ENCP_VIDEO_EQPULS_ELINE));
		writel(vmode->encp.havon_begin,
		       priv->io_base + _REG(ENCP_VIDEO_HAVON_BEGIN));
		writel(vmode->encp.havon_end,
		       priv->io_base + _REG(ENCP_VIDEO_HAVON_END));
		writel(vmode->encp.vavon_bline,
		       priv->io_base + _REG(ENCP_VIDEO_VAVON_BLINE));
		writel(vmode->encp.vavon_eline,
		       priv->io_base + _REG(ENCP_VIDEO_VAVON_ELINE));
		writel(vmode->encp.hso_begin,
		       priv->io_base + _REG(ENCP_VIDEO_HSO_BEGIN));
		writel(vmode->encp.hso_end,
		       priv->io_base + _REG(ENCP_VIDEO_HSO_END));
		writel(vmode->encp.vso_begin,
		       priv->io_base + _REG(ENCP_VIDEO_VSO_BEGIN));
		writel(vmode->encp.vso_end,
		       priv->io_base + _REG(ENCP_VIDEO_VSO_END));
		writel(vmode->encp.vso_bline,
		       priv->io_base + _REG(ENCP_VIDEO_VSO_BLINE));
		if (vmode->encp.vso_eline_present)
			writel(vmode->encp.vso_eline,
			       priv->io_base + _REG(ENCP_VIDEO_VSO_ELINE));
		if (vmode->encp.sy_val_present)
			writel(vmode->encp.sy_val,
			       priv->io_base + _REG(ENCP_VIDEO_SY_VAL));
		if (vmode->encp.sy2_val_present)
			writel(vmode->encp.sy2_val,
			       priv->io_base + _REG(ENCP_VIDEO_SY2_VAL));
		writel(vmode->encp.max_lncnt,
		       priv->io_base + _REG(ENCP_VIDEO_MAX_LNCNT));

		writel(1, priv->io_base + _REG(ENCP_VIDEO_EN));

		/* Set DE signal's polarity is active high */
		writel_bits(ENCP_VIDEO_MODE_DE_V_HIGH,
			    ENCP_VIDEO_MODE_DE_V_HIGH,
			    priv->io_base + _REG(ENCP_VIDEO_MODE));

		/* Program DE timing */
		de_h_begin = modulo(readl(priv->io_base +
					_REG(ENCP_VIDEO_HAVON_BEGIN))
					+ venc_hdmi_latency,
				    total_pixels_venc);
		de_h_end = modulo(de_h_begin + active_pixels_venc,
				  total_pixels_venc);

		writel(de_h_begin,
		       priv->io_base + _REG(ENCP_DE_H_BEGIN));
		writel(de_h_end,
		       priv->io_base + _REG(ENCP_DE_H_END));

		/* Program DE timing for even field */
		de_v_begin_even = readl(priv->io_base
						+ _REG(ENCP_VIDEO_VAVON_BLINE));
		if (mode->flags & DISPLAY_FLAGS_INTERLACED)
			de_v_end_even = de_v_begin_even +
					(mode->vactive.typ / 2);
		else
			de_v_end_even = de_v_begin_even + mode->vactive.typ;

		writel(de_v_begin_even,
		       priv->io_base + _REG(ENCP_DE_V_BEGIN_EVEN));
		writel(de_v_end_even,
		       priv->io_base + _REG(ENCP_DE_V_END_EVEN));

		/* Program DE timing for odd field if needed */
		if (mode->flags & DISPLAY_FLAGS_INTERLACED) {
			unsigned int ofld_voav_ofst =
				readl(priv->io_base +
					_REG(ENCP_VIDEO_OFLD_VOAV_OFST));
			de_v_begin_odd = to_signed((ofld_voav_ofst & 0xf0) >> 4)
					+ de_v_begin_even
					+ ((mode->vfront_porch.typ +
					    mode->vactive.typ +
					    mode->vsync_len.typ - 1) / 2);
			de_v_end_odd = de_v_begin_odd + (mode->vactive.typ / 2);

			writel(de_v_begin_odd,
			       priv->io_base + _REG(ENCP_DE_V_BEGIN_ODD));
			writel(de_v_end_odd,
			       priv->io_base + _REG(ENCP_DE_V_END_ODD));
		}

		/* Program Hsync timing */
		if ((de_h_end + front_porch_venc) >= total_pixels_venc) {
			hs_begin = de_h_end
				   + front_porch_venc
				   - total_pixels_venc;
			vs_adjust  = 1;
		} else {
			hs_begin = de_h_end
				   + front_porch_venc;
			vs_adjust  = 0;
		}

		hs_end = modulo(hs_begin + hsync_pixels_venc,
				total_pixels_venc);

		writel(hs_begin,
		       priv->io_base + _REG(ENCP_DVI_HSO_BEGIN));
		writel(hs_end,
		       priv->io_base + _REG(ENCP_DVI_HSO_END));

		/* Program Vsync timing for even field */
		if (de_v_begin_even >=
				(sof_lines + vsync_lines + (1 - vs_adjust)))
			vs_bline_evn = de_v_begin_even
					- sof_lines
					- vsync_lines
					- (1 - vs_adjust);
		else
			vs_bline_evn = (mode->vfront_porch.typ +
					mode->vactive.typ +
					mode->vsync_len.typ) +
					+ de_v_begin_even
					- sof_lines
					- vsync_lines
					- (1 - vs_adjust);

		vs_eline_evn = modulo(vs_bline_evn + vsync_lines,
				      mode->hfront_porch.typ +
				      mode->hactive.typ +
				      mode->hsync_len.typ);

		writel(vs_bline_evn,
		       priv->io_base + _REG(ENCP_DVI_VSO_BLINE_EVN));
		writel(vs_eline_evn,
		       priv->io_base + _REG(ENCP_DVI_VSO_ELINE_EVN));

		vso_begin_evn = hs_begin;
		writel(vso_begin_evn,
		       priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_EVN));
		writel(vso_begin_evn,
		       priv->io_base + _REG(ENCP_DVI_VSO_END_EVN));

		/* Program Vsync timing for odd field if needed */
		if (mode->flags & DISPLAY_FLAGS_INTERLACED) {
			vs_bline_odd = (de_v_begin_odd - 1)
					- sof_lines
					- vsync_lines;
			vs_eline_odd = (de_v_begin_odd - 1)
					- vsync_lines;
			vso_begin_odd  = modulo(hs_begin
						+ (total_pixels_venc >> 1),
						total_pixels_venc);

			writel(vs_bline_odd,
			       priv->io_base + _REG(ENCP_DVI_VSO_BLINE_ODD));
			writel(vs_eline_odd,
			       priv->io_base + _REG(ENCP_DVI_VSO_ELINE_ODD));
			writel(vso_begin_odd,
			       priv->io_base + _REG(ENCP_DVI_VSO_BEGIN_ODD));
			writel(vso_begin_odd,
			       priv->io_base + _REG(ENCP_DVI_VSO_END_ODD));
		}

		/* Select ENCP for VIU */
		meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
	}

	/* Set VPU HDMI setting */
	/* Select ENCP or ENCI data to HDMI */
	if (use_enci)
		reg = VPU_HDMI_ENCI_DATA_TO_HDMI;
	else
		reg = VPU_HDMI_ENCP_DATA_TO_HDMI;

	/* Invert polarity of HSYNC from VENC */
	if (mode->flags & DISPLAY_FLAGS_HSYNC_HIGH)
		reg |= VPU_HDMI_INV_HSYNC;

	/* Invert polarity of VSYNC from VENC */
	if (mode->flags & DISPLAY_FLAGS_VSYNC_HIGH)
		reg |= VPU_HDMI_INV_VSYNC;

	/* Output data format: CbYCr */
	reg |= VPU_HDMI_OUTPUT_CBYCR;

	/*
	 * Write rate to the async FIFO between VENC and HDMI.
	 * One write every 2 wr_clk.
	 */
	if (venc_repeat)
		reg |= VPU_HDMI_WR_RATE(2);

	/*
	 * Read rate to the async FIFO between VENC and HDMI.
	 * One read every 2 wr_clk.
	 */
	if (hdmi_repeat)
		reg |= VPU_HDMI_RD_RATE(2);

	writel(reg, priv->io_base + _REG(VPU_HDMI_SETTING));
}