浏览代码

disp: msm: dsi: Fix DMA window scheduling programming

In DMA start window scheduling, TRIG_CTRL.COMMAND_MODE_DMA_TRIGGER_SEL
is programmed to SW + DMA start window trigger. But if DMS switch
comes after command is scheduled, COMMAND_MODE_DMA_TRIGGER_SEL gets
reprogrammed to SW trigger leading to command transfer failure.

Program the COMMAND_MODE_DMA_TRIGGER_SEL only from the CMD DMA Tx path.

Change-Id: I01062497bb70aa5fdcb25be3715c7cbc4c68b681
Signed-off-by: Ritesh Kumar <[email protected]>
Signed-off-by: Rajeev Nandan <[email protected]>
Signed-off-by: Kirill Shpin <[email protected]>
Rajeev Nandan 3 年之前
父节点
当前提交
2b15aded33
共有 6 个文件被更改,包括 45 次插入7 次删除
  1. 1 0
      msm/dsi/dsi_catalog.c
  2. 2 0
      msm/dsi/dsi_catalog.h
  3. 4 0
      msm/dsi/dsi_ctrl.c
  4. 9 0
      msm/dsi/dsi_ctrl_hw.h
  5. 5 4
      msm/dsi/dsi_ctrl_hw_2_2.c
  6. 24 3
      msm/dsi/dsi_ctrl_hw_cmn.c

+ 1 - 0
msm/dsi/dsi_catalog.c

@@ -66,6 +66,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
 		dsi_ctrl_hw_cmn_wait4dynamic_refresh_done;
 	ctrl->ops.hs_req_sel = dsi_ctrl_hw_cmn_hs_req_sel;
 	ctrl->ops.vid_engine_busy = dsi_ctrl_hw_cmn_vid_engine_busy;
+	ctrl->ops.init_cmddma_trig_ctrl = dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl;
 
 	switch (version) {
 	case DSI_CTRL_VERSION_2_2:

+ 2 - 0
msm/dsi/dsi_catalog.h

@@ -233,6 +233,8 @@ void dsi_ctrl_hw_cmn_error_intr_ctrl(struct dsi_ctrl_hw *ctrl, bool en);
 u32 dsi_ctrl_hw_cmn_get_error_mask(struct dsi_ctrl_hw *ctrl);
 u32 dsi_ctrl_hw_cmn_get_hw_version(struct dsi_ctrl_hw *ctrl);
 int dsi_ctrl_hw_cmn_wait_for_cmd_mode_mdp_idle(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl(struct dsi_ctrl_hw *ctrl,
+					   struct dsi_host_common_cfg *cfg);
 
 /* Definitions specific to 1.4 DSI controller hardware */
 int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);

+ 4 - 0
msm/dsi/dsi_ctrl.c

@@ -1400,6 +1400,10 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
 		dsi_hw_ops.splitlink_cmd_setup(&dsi_ctrl->hw,
 				&dsi_ctrl->host_config.common_config, flags);
 
+	if (dsi_hw_ops.init_cmddma_trig_ctrl)
+		dsi_hw_ops.init_cmddma_trig_ctrl(&dsi_ctrl->hw,
+				&dsi_ctrl->host_config.common_config);
+
 	/*
 	 * Always enable DMA scheduling for video mode panel.
 	 *

+ 9 - 0
msm/dsi/dsi_ctrl_hw.h

@@ -909,6 +909,15 @@ struct dsi_ctrl_hw_ops {
 	void (*reset_trig_ctrl)(struct dsi_ctrl_hw *ctrl,
 			struct dsi_host_common_cfg *cfg);
 
+	/**
+	 * hw.ops.init_cmddma_trig_ctrl() - Initialize the default trigger used
+	 *                             for command mode DMA path.
+	 * @ctrl:	Pointer to the controller host hardware.
+	 * @cfg:	Common configuration parameters.
+	 */
+	void (*init_cmddma_trig_ctrl)(struct dsi_ctrl_hw *ctrl,
+			struct dsi_host_common_cfg *cfg);
+
 	/**
 	 * hw.ops.log_line_count() - reads the MDP interface line count
 	 *			     registers.

+ 5 - 4
msm/dsi/dsi_ctrl_hw_2_2.c

@@ -248,14 +248,15 @@ void dsi_ctrl_hw_22_configure_cmddma_window(struct dsi_ctrl_hw *ctrl,
 void dsi_ctrl_hw_22_reset_trigger_controls(struct dsi_ctrl_hw *ctrl,
 				       struct dsi_host_common_cfg *cfg)
 {
-	u32 reg = 0;
+	u32 reg;
 	const u8 trigger_map[DSI_TRIGGER_MAX] = {
 		0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
 
-	reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
-	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
-	reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
+	reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
+	reg &= ~(0xF);
+	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
 	DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
+
 	DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, 0x0);
 	DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, 0x0);
 	ctrl->reset_trig_ctrl = false;

+ 24 - 3
msm/dsi/dsi_ctrl_hw_cmn.c

@@ -95,13 +95,20 @@ static void dsi_split_link_setup(struct dsi_ctrl_hw *ctrl,
 static void dsi_setup_trigger_controls(struct dsi_ctrl_hw *ctrl,
 				       struct dsi_host_common_cfg *cfg)
 {
-	u32 reg = 0;
+	u32 reg;
 	const u8 trigger_map[DSI_TRIGGER_MAX] = {
 		0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
 
-	reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
-	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
+	reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
+
+	if (cfg->te_mode == DSI_TE_ON_EXT_PIN)
+		reg |= BIT(31);
+	else
+		reg &= ~BIT(31);
+
+	reg &= ~(0x7 << 4);
 	reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
+
 	DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
 }
 
@@ -1908,3 +1915,17 @@ bool dsi_ctrl_hw_cmn_vid_engine_busy(struct dsi_ctrl_hw *ctrl)
 
 	return false;
 }
+
+void dsi_ctrl_hw_cmn_init_cmddma_trig_ctrl(struct dsi_ctrl_hw *ctrl,
+					   struct dsi_host_common_cfg *cfg)
+{
+	u32 reg;
+	const u8 trigger_map[DSI_TRIGGER_MAX] = {
+		0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
+
+	/* Initialize the default trigger used for Command Mode DMA path. */
+	reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
+	reg &= ~(0xF);
+	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
+	DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
+}