Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca279601 authored by Benjamin Gaignard's avatar Benjamin Gaignard
Browse files

drm: sti: prepare sti_tvout to support auxiliary crtc



Change some functions prototype to prepare the introduction of
auxiliary crtc. It will also help to have a DVO encoder.

Signed-off-by: default avatarBenjamin Gaignard <benjamin.gaignard@linaro.org>
parent ca614aad
Loading
Loading
Loading
Loading
+52 −40
Original line number Diff line number Diff line
@@ -149,14 +149,15 @@ static void tvout_write(struct sti_tvout *tvout, u32 val, int offset)
 * Set the clipping mode of a VIP
 *
 * @tvout: tvout structure
 * @reg: register to set
 * @cr_r:
 * @y_g:
 * @cb_b:
 */
static void tvout_vip_set_color_order(struct sti_tvout *tvout,
static void tvout_vip_set_color_order(struct sti_tvout *tvout, int reg,
				      u32 cr_r, u32 y_g, u32 cb_b)
{
	u32 val = tvout_read(tvout, TVO_VIP_HDMI);
	u32 val = tvout_read(tvout, reg);

	val &= ~(TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_R_SHIFT);
	val &= ~(TVO_VIP_REORDER_MASK << TVO_VIP_REORDER_G_SHIFT);
@@ -165,52 +166,58 @@ static void tvout_vip_set_color_order(struct sti_tvout *tvout,
	val |= y_g << TVO_VIP_REORDER_G_SHIFT;
	val |= cb_b << TVO_VIP_REORDER_B_SHIFT;

	tvout_write(tvout, val, TVO_VIP_HDMI);
	tvout_write(tvout, val, reg);
}

/**
 * Set the clipping mode of a VIP
 *
 * @tvout: tvout structure
 * @reg: register to set
 * @range: clipping range
 */
static void tvout_vip_set_clip_mode(struct sti_tvout *tvout, u32 range)
static void tvout_vip_set_clip_mode(struct sti_tvout *tvout, int reg, u32 range)
{
	u32 val = tvout_read(tvout, TVO_VIP_HDMI);
	u32 val = tvout_read(tvout, reg);

	val &= ~(TVO_VIP_CLIP_MASK << TVO_VIP_CLIP_SHIFT);
	val |= range << TVO_VIP_CLIP_SHIFT;
	tvout_write(tvout, val, TVO_VIP_HDMI);
	tvout_write(tvout, val, reg);
}

/**
 * Set the rounded value of a VIP
 *
 * @tvout: tvout structure
 * @reg: register to set
 * @rnd: rounded val per component
 */
static void tvout_vip_set_rnd(struct sti_tvout *tvout, u32 rnd)
static void tvout_vip_set_rnd(struct sti_tvout *tvout, int reg, u32 rnd)
{
	u32 val = tvout_read(tvout, TVO_VIP_HDMI);
	u32 val = tvout_read(tvout, reg);

	val &= ~(TVO_VIP_RND_MASK << TVO_VIP_RND_SHIFT);
	val |= rnd << TVO_VIP_RND_SHIFT;
	tvout_write(tvout, val, TVO_VIP_HDMI);
	tvout_write(tvout, val, reg);
}

/**
 * Select the VIP input
 *
 * @tvout: tvout structure
 * @reg: register to set
 * @main_path: main or auxiliary path
 * @sel_input_logic_inverted: need to invert the logic
 * @sel_input: selected_input (main/aux + conv)
 */
static void tvout_vip_set_sel_input(struct sti_tvout *tvout,
				    int reg,
				    bool main_path,
				    bool sel_input_logic_inverted,
				    enum sti_tvout_video_out_type video_out)
{
	u32 sel_input;
	u32 val = tvout_read(tvout, TVO_VIP_HDMI);
	u32 val = tvout_read(tvout, reg);

	if (main_path)
		sel_input = TVO_VIP_SEL_INPUT_MAIN;
@@ -232,22 +239,24 @@ static void tvout_vip_set_sel_input(struct sti_tvout *tvout,

	val &= ~TVO_VIP_SEL_INPUT_MASK;
	val |= sel_input;
	tvout_write(tvout, val, TVO_VIP_HDMI);
	tvout_write(tvout, val, reg);
}

/**
 * Select the input video signed or unsigned
 *
 * @tvout: tvout structure
 * @reg: register to set
 * @in_vid_signed: used video input format
 */
static void tvout_vip_set_in_vid_fmt(struct sti_tvout *tvout, u32 in_vid_fmt)
static void tvout_vip_set_in_vid_fmt(struct sti_tvout *tvout,
		int reg, u32 in_vid_fmt)
{
	u32 val = tvout_read(tvout, TVO_VIP_HDMI);
	u32 val = tvout_read(tvout, reg);

	val &= ~TVO_IN_FMT_SIGNED;
	val |= in_vid_fmt;
	tvout_write(tvout, val, TVO_MAIN_IN_VID_FORMAT);
	tvout_write(tvout, val, reg);
}

/**
@@ -261,6 +270,7 @@ static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
{
	struct device_node *node = tvout->dev->of_node;
	bool sel_input_logic_inverted = false;
	u32 tvo_in_vid_format;

	dev_dbg(tvout->dev, "%s\n", __func__);

@@ -268,33 +278,36 @@ static void tvout_hdmi_start(struct sti_tvout *tvout, bool main_path)
		DRM_DEBUG_DRIVER("main vip for hdmi\n");
		/* select the input sync for hdmi = VTG set 1 */
		tvout_write(tvout, TVO_SYNC_MAIN_VTG_SET_1, TVO_HDMI_SYNC_SEL);
		tvo_in_vid_format = TVO_MAIN_IN_VID_FORMAT;
	} else {
		DRM_DEBUG_DRIVER("aux vip for hdmi\n");
		/* select the input sync for hdmi = VTG set 1 */
		tvout_write(tvout, TVO_SYNC_AUX_VTG_SET_1, TVO_HDMI_SYNC_SEL);
		tvo_in_vid_format = TVO_AUX_IN_VID_FORMAT;
	}

	/* set color channel order */
	tvout_vip_set_color_order(tvout,
	tvout_vip_set_color_order(tvout, TVO_VIP_HDMI,
				  TVO_VIP_REORDER_CR_R_SEL,
				  TVO_VIP_REORDER_Y_G_SEL,
				  TVO_VIP_REORDER_CB_B_SEL);

	/* set clipping mode (Limited range RGB/Y) */
	tvout_vip_set_clip_mode(tvout, TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y);
	tvout_vip_set_clip_mode(tvout, TVO_VIP_HDMI,
			TVO_VIP_CLIP_LIMITED_RANGE_RGB_Y);

	/* set round mode (rounded to 8-bit per component) */
	tvout_vip_set_rnd(tvout, TVO_VIP_RND_8BIT_ROUNDED);
	tvout_vip_set_rnd(tvout, TVO_VIP_HDMI, TVO_VIP_RND_8BIT_ROUNDED);

	if (of_device_is_compatible(node, "st,stih407-tvout")) {
		/* set input video format */
		tvout_vip_set_in_vid_fmt(tvout->regs + TVO_MAIN_IN_VID_FORMAT,
		tvout_vip_set_in_vid_fmt(tvout, tvo_in_vid_format,
					TVO_IN_FMT_SIGNED);
		sel_input_logic_inverted = true;
	}

	/* input selection */
	tvout_vip_set_sel_input(tvout, main_path,
	tvout_vip_set_sel_input(tvout, TVO_VIP_HDMI, main_path,
			sel_input_logic_inverted, STI_TVOUT_VIDEO_OUT_RGB);
}

@@ -309,48 +322,47 @@ static void tvout_hda_start(struct sti_tvout *tvout, bool main_path)
{
	struct device_node *node = tvout->dev->of_node;
	bool sel_input_logic_inverted = false;
	u32 tvo_in_vid_format;
	int val;

	dev_dbg(tvout->dev, "%s\n", __func__);

	if (!main_path) {
		DRM_ERROR("HD Analog on aux not implemented\n");
		return;
	if (main_path) {
		val = TVO_SYNC_MAIN_VTG_SET_2 << TVO_SYNC_HD_DCS_SHIFT;
		val |= TVO_SYNC_MAIN_VTG_SET_3;
		tvout_write(tvout, val, TVO_HD_SYNC_SEL);
		tvo_in_vid_format = TVO_MAIN_IN_VID_FORMAT;
	} else {
		val = TVO_SYNC_AUX_VTG_SET_2 << TVO_SYNC_HD_DCS_SHIFT;
		val |= TVO_SYNC_AUX_VTG_SET_3;
		tvout_write(tvout, val, TVO_HD_SYNC_SEL);
		tvo_in_vid_format = TVO_AUX_IN_VID_FORMAT;
	}

	DRM_DEBUG_DRIVER("main vip for HDF\n");

	/* set color channel order */
	tvout_vip_set_color_order(tvout->regs + TVO_VIP_HDF,
	tvout_vip_set_color_order(tvout, TVO_VIP_HDF,
				  TVO_VIP_REORDER_CR_R_SEL,
				  TVO_VIP_REORDER_Y_G_SEL,
				  TVO_VIP_REORDER_CB_B_SEL);

	/* set clipping mode (Limited range RGB/Y) */
	tvout_vip_set_clip_mode(tvout->regs + TVO_VIP_HDF,
				TVO_VIP_CLIP_LIMITED_RANGE_CB_CR);
	/* set clipping mode (EAV/SAV clipping) */
	tvout_vip_set_clip_mode(tvout, TVO_VIP_HDF, TVO_VIP_CLIP_EAV_SAV);

	/* set round mode (rounded to 10-bit per component) */
	tvout_vip_set_rnd(tvout->regs + TVO_VIP_HDF, TVO_VIP_RND_10BIT_ROUNDED);
	tvout_vip_set_rnd(tvout, TVO_VIP_HDF, TVO_VIP_RND_10BIT_ROUNDED);

	if (of_device_is_compatible(node, "st,stih407-tvout")) {
		/* set input video format */
		tvout_vip_set_in_vid_fmt(tvout, TVO_IN_FMT_SIGNED);
		tvout_vip_set_in_vid_fmt(tvout,
			tvo_in_vid_format, TVO_IN_FMT_SIGNED);
		sel_input_logic_inverted = true;
	}

	/* Input selection */
	tvout_vip_set_sel_input(tvout->regs + TVO_VIP_HDF,
				main_path,
	tvout_vip_set_sel_input(tvout, TVO_VIP_HDF, main_path,
				sel_input_logic_inverted,
				STI_TVOUT_VIDEO_OUT_YUV);

	/* select the input sync for HD analog = VTG set 3
	 * and HD DCS = VTG set 2 */
	tvout_write(tvout,
		(TVO_SYNC_MAIN_VTG_SET_2 << TVO_SYNC_HD_DCS_SHIFT)
		| TVO_SYNC_MAIN_VTG_SET_3,
		TVO_HD_SYNC_SEL);

	/* power up HD DAC */
	tvout_write(tvout, 0, TVO_HD_DAC_CFG_OFF);
}