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

Commit 8996dd90 authored by Benjamin Chan's avatar Benjamin Chan
Browse files

msm: sde: issue vbif xin halt after reset sde rotator



There is a possibility that a pending transaction left in the vbif hw
when the rotator hang. It is necessary to issue a halt to the vbif xin
port after resetting the rotator. Not doing so will cause a smmu fault
once the iommu mapping is released.

Change-Id: Iffd02768336e1e7a22810e687110aa136f347f21
Signed-off-by: default avatarBenjamin Chan <bkchan@codeaurora.org>
parent a88ecb14
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -139,6 +139,43 @@ static bool force_on_xin_clk(u32 bit_off, u32 clk_ctl_reg_off, bool enable)
	return clk_forced_on;
}

void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
	u32 reg_val;
	bool forced_on;

	if (!mdata || !params || !params->reg_off_mdp_clk_ctrl) {
		SDEROT_ERR("null input parameter\n");
		return;
	}

	if (params->xin_id > MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1) {
		SDEROT_ERR("xin_id:%d exceed max limit\n", params->xin_id);
		return;
	}

	forced_on = force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
		params->reg_off_mdp_clk_ctrl, true);

	SDEROT_EVTLOG(forced_on, params->xin_id);

	reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
	SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
		reg_val | BIT(params->xin_id));

	/* this is a polling operation */
	sde_mdp_wait_for_xin_halt(params->xin_id);

	reg_val = SDE_VBIF_READ(mdata, MMSS_VBIF_XIN_HALT_CTRL0);
	SDE_VBIF_WRITE(mdata, MMSS_VBIF_XIN_HALT_CTRL0,
		reg_val & ~BIT(params->xin_id));

	if (forced_on)
		force_on_xin_clk(params->bit_off_mdp_clk_ctrl,
			params->reg_off_mdp_clk_ctrl, false);
}

u32 sde_mdp_get_ot_limit(u32 width, u32 height, u32 pixfmt, u32 fps, u32 is_rd)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+14 −0
Original line number Diff line number Diff line
@@ -63,6 +63,18 @@ struct sde_mdp_set_ot_params {
	u32 rotsts_busy_mask;
};

/*
 * struct sde_mdp_vbif_halt_params: parameters for issue halt request to vbif
 * @xin_id: xin port number of vbif
 * @reg_off_mdp_clk_ctrl: reg offset for vbif clock control
 * @bit_off_mdp_clk_ctrl: bit offset for vbif clock control
 */
struct sde_mdp_vbif_halt_params {
	u32 xin_id;
	u32 reg_off_mdp_clk_ctrl;
	u32 bit_off_mdp_clk_ctrl;
};

enum sde_bus_vote_type {
	VOTE_INDEX_DISABLE,
	VOTE_INDEX_19_MHZ,
@@ -276,6 +288,8 @@ u32 sde_mdp_get_ot_limit(u32 width, u32 height, u32 pixfmt, u32 fps, u32 is_rd);

void sde_mdp_set_ot_limit(struct sde_mdp_set_ot_params *params);

void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params);

int sde_mdp_init_vbif(void);

#define SDE_VBIF_WRITE(mdata, offset, value) \
+22 −0
Original line number Diff line number Diff line
@@ -666,6 +666,25 @@ static void sde_hw_rotator_disable_irq(struct sde_hw_rotator *rot)
	}
}

static void sde_hw_rotator_halt_vbif_xin_client(void)
{
	struct sde_mdp_vbif_halt_params halt_params;

	memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
	halt_params.xin_id = XIN_SSPP;
	halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
	halt_params.bit_off_mdp_clk_ctrl =
		MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0;
	sde_mdp_halt_vbif_xin(&halt_params);

	memset(&halt_params, 0, sizeof(struct sde_mdp_vbif_halt_params));
	halt_params.xin_id = XIN_WRITEBACK;
	halt_params.reg_off_mdp_clk_ctrl = MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
	halt_params.bit_off_mdp_clk_ctrl =
		MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1;
	sde_mdp_halt_vbif_xin(&halt_params);
}

/**
 * sde_hw_rotator_reset - Reset rotator hardware
 * @rot: pointer to hw rotator
@@ -698,6 +717,9 @@ static int sde_hw_rotator_reset(struct sde_hw_rotator *rot,
	usleep_range(MS_TO_US(10), MS_TO_US(20));
	SDE_ROTREG_WRITE(rot->mdss_base, ROTTOP_SW_RESET_OVERRIDE, 0);

	/* halt vbif xin client to ensure no pending transaction */
	sde_hw_rotator_halt_vbif_xin_client();

	spin_lock_irqsave(&rot->rotisr_lock, flags);

	/* update timestamp register with current context */