summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaoming Zhou <zhoux@codeaurora.org>2013-12-03 14:54:44 -0500
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:24:01 -0700
commite8a07e087d64989f340a2152e70f708e671bb66d (patch)
tree44d3309a18b6ac34bd841bac91aa66741ca48e1f
parentb9ba1cf0d2d372a16d7bb728459eb553aa7b3594 (diff)
msm: mdss: update the dsi interrupt handling on 8x10
The previous dsi interrupt handling logic was scattered in a few places. This is to centralize the interrupt handling logic. Change-Id: If89a45d80a2e3523368a37d96f1d226c443e1f61 Signed-off-by: Xiaoming Zhou <zhoux@codeaurora.org> [cip@codeaurora.org: Removed IRQF_DISABLED] Signed-off-by: Clarence Ip <cip@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/dsi_host_v2.c148
1 files changed, 87 insertions, 61 deletions
diff --git a/drivers/video/fbdev/msm/dsi_host_v2.c b/drivers/video/fbdev/msm/dsi_host_v2.c
index 191b87c15136..b6b71c375a18 100644
--- a/drivers/video/fbdev/msm/dsi_host_v2.c
+++ b/drivers/video/fbdev/msm/dsi_host_v2.c
@@ -33,10 +33,6 @@
#define DSI_DMA_CMD_TIMEOUT_MS 200
struct dsi_host_v2_private {
- struct completion dma_comp;
- int irq_enabled;
- spinlock_t irq_lock;
-
int irq_no;
unsigned char *dsi_base;
size_t dsi_reg_size;
@@ -58,8 +54,6 @@ int msm_dsi_init(void)
}
}
- init_completion(&dsi_host_private->dma_comp);
- spin_lock_init(&dsi_host_private->irq_lock);
return 0;
}
@@ -137,61 +131,98 @@ void msm_dsi_error(unsigned char *ctrl_base)
msm_dsi_dln0_phy_err(ctrl_base);
}
-void msm_dsi_enable_irq(void)
+void msm_dsi_set_irq_mask(struct mdss_dsi_ctrl_pdata *ctrl, u32 mask)
{
- unsigned long flags;
-
- spin_lock_irqsave(&dsi_host_private->irq_lock, flags);
- dsi_host_private->irq_enabled++;
- if (dsi_host_private->irq_enabled == 1)
- enable_irq(dsi_host_private->irq_no);
+ u32 intr_ctrl;
+ intr_ctrl = MIPI_INP(dsi_host_private->dsi_base + DSI_INT_CTRL);
+ intr_ctrl |= mask;
+ MIPI_OUTP(dsi_host_private->dsi_base + DSI_INT_CTRL, intr_ctrl);
+}
- spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
+void msm_dsi_clear_irq_mask(struct mdss_dsi_ctrl_pdata *ctrl, u32 mask)
+{
+ u32 intr_ctrl;
+ intr_ctrl = MIPI_INP(dsi_host_private->dsi_base + DSI_INT_CTRL);
+ intr_ctrl &= ~mask;
+ MIPI_OUTP(dsi_host_private->dsi_base + DSI_INT_CTRL, intr_ctrl);
}
-void msm_dsi_disable_irq(void)
+void msm_dsi_set_irq(struct mdss_dsi_ctrl_pdata *ctrl, u32 mask)
{
unsigned long flags;
- spin_lock_irqsave(&dsi_host_private->irq_lock, flags);
- dsi_host_private->irq_enabled--;
- if (dsi_host_private->irq_enabled == 0)
- disable_irq(dsi_host_private->irq_no);
+ spin_lock_irqsave(&ctrl->irq_lock, flags);
+ if (ctrl->dsi_irq_mask & mask) {
+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
+ return;
+ }
+ if (ctrl->dsi_irq_mask == 0) {
+ enable_irq(dsi_host_private->irq_no);
+ pr_debug("%s: IRQ Enable, mask=%x term=%x\n", __func__,
+ (int)ctrl->dsi_irq_mask, (int)mask);
+ }
- spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
+ msm_dsi_set_irq_mask(ctrl, mask);
+ ctrl->dsi_irq_mask |= mask;
+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
}
-void msm_dsi_disable_irq_nosync(void)
+void msm_dsi_clear_irq(struct mdss_dsi_ctrl_pdata *ctrl, u32 mask)
{
- spin_lock(&dsi_host_private->irq_lock);
- dsi_host_private->irq_enabled--;
- if (dsi_host_private->irq_enabled == 0)
- disable_irq_nosync(dsi_host_private->irq_no);
- spin_unlock(&dsi_host_private->irq_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctrl->irq_lock, flags);
+ if (!(ctrl->dsi_irq_mask & mask)) {
+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
+ return;
+ }
+ ctrl->dsi_irq_mask &= ~mask;
+ if (ctrl->dsi_irq_mask == 0) {
+ disable_irq(dsi_host_private->irq_no);
+ pr_debug("%s: IRQ Disable, mask=%x term=%x\n", __func__,
+ (int)ctrl->dsi_irq_mask, (int)mask);
+ }
+ msm_dsi_clear_irq_mask(ctrl, mask);
+ spin_unlock_irqrestore(&ctrl->irq_lock, flags);
}
-irqreturn_t msm_dsi_isr(int irq, void *ptr)
+irqreturn_t msm_dsi_isr_handler(int irq, void *ptr)
{
u32 isr;
+ struct mdss_dsi_ctrl_pdata *ctrl =
+ (struct mdss_dsi_ctrl_pdata *)ptr;
+
isr = MIPI_INP(dsi_host_private->dsi_base + DSI_INT_CTRL);
MIPI_OUTP(dsi_host_private->dsi_base + DSI_INT_CTRL, isr);
- if (isr & DSI_INTR_ERROR)
+ pr_debug("%s: isr=%x", __func__, isr);
+
+ if (isr & DSI_INTR_ERROR) {
+ pr_err("%s: isr=%x %x", __func__, isr, (int)DSI_INTR_ERROR);
msm_dsi_error(dsi_host_private->dsi_base);
+ }
+
+ spin_lock(&ctrl->mdp_lock);
+
+ if (isr & DSI_INTR_VIDEO_DONE)
+ complete(&ctrl->video_comp);
if (isr & DSI_INTR_CMD_DMA_DONE)
- complete(&dsi_host_private->dma_comp);
+ complete(&ctrl->dma_comp);
+
+ spin_unlock(&ctrl->mdp_lock);
return IRQ_HANDLED;
}
-int msm_dsi_irq_init(struct device *dev, int irq_no)
+int msm_dsi_irq_init(struct device *dev, int irq_no,
+ struct mdss_dsi_ctrl_pdata *ctrl)
{
int ret;
- ret = devm_request_irq(dev, irq_no, msm_dsi_isr,
- IRQF_DISABLED, "DSI", NULL);
+ ret = devm_request_irq(dev, irq_no, msm_dsi_isr_handler,
+ 0x0, "DSI", ctrl);
if (ret) {
pr_err("msm_dsi_irq_init request_irq() failed!\n");
return ret;
@@ -203,7 +234,7 @@ int msm_dsi_irq_init(struct device *dev, int irq_no)
void msm_dsi_host_init(struct mipi_panel_info *pinfo)
{
- u32 dsi_ctrl, intr_ctrl, data;
+ u32 dsi_ctrl, data;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
pr_debug("msm_dsi_host_init\n");
@@ -262,8 +293,6 @@ void msm_dsi_host_init(struct mipi_panel_info *pinfo)
pr_err("%s: Unknown DSI mode=%d\n", __func__, pinfo->mode);
dsi_ctrl = BIT(8) | BIT(2); /* clock enable & cmd mode */
- intr_ctrl = 0;
- intr_ctrl = (DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_CMD_MDP_DONE_MASK);
if (pinfo->crc_check)
dsi_ctrl |= BIT(24);
@@ -312,9 +341,6 @@ void msm_dsi_host_init(struct mipi_panel_info *pinfo)
/* DSI_ERR_INT_MASK0 */
MIPI_OUTP(ctrl_base + DSI_ERR_INT_MASK0, 0x13ff3fe0);
- intr_ctrl |= DSI_INTR_ERROR_MASK;
- MIPI_OUTP(ctrl_base + DSI_INT_CTRL, intr_ctrl);
-
/* turn esc, byte, dsi, pclk, sclk, hclk on */
MIPI_OUTP(ctrl_base + DSI_CLK_CTRL, 0x23f);
@@ -404,7 +430,7 @@ void msm_dsi_controller_cfg(int enable)
void msm_dsi_op_mode_config(int mode, struct mdss_panel_data *pdata)
{
- u32 dsi_ctrl, intr_ctrl;
+ u32 dsi_ctrl;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
pr_debug("msm_dsi_op_mode_config\n");
@@ -415,24 +441,19 @@ void msm_dsi_op_mode_config(int mode, struct mdss_panel_data *pdata)
dsi_ctrl &= ~0x06;
- if (mode == DSI_VIDEO_MODE) {
+ if (mode == DSI_VIDEO_MODE)
dsi_ctrl |= 0x02;
- intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
- } else { /* command mode */
+ else
dsi_ctrl |= 0x04;
- intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
- DSI_INTR_CMD_MDP_DONE_MASK;
- }
-
- pr_debug("%s: dsi_ctrl=%x intr=%x\n", __func__, dsi_ctrl, intr_ctrl);
+ pr_debug("%s: dsi_ctrl=%x\n", __func__, dsi_ctrl);
- MIPI_OUTP(ctrl_base + DSI_INT_CTRL, intr_ctrl);
MIPI_OUTP(ctrl_base + DSI_CTRL, dsi_ctrl);
wmb();
}
-int msm_dsi_cmd_dma_tx(struct dsi_buf *tp)
+int msm_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
+ struct dsi_buf *tp)
{
int len, rc;
unsigned long size, addr;
@@ -450,7 +471,7 @@ int msm_dsi_cmd_dma_tx(struct dsi_buf *tp)
addr = tp->dmap;
- INIT_COMPLETION(dsi_host_private->dma_comp);
+ INIT_COMPLETION(ctrl->dma_comp);
MIPI_OUTP(ctrl_base + DSI_DMA_CMD_OFFSET, addr);
MIPI_OUTP(ctrl_base + DSI_DMA_CMD_LENGTH, len);
@@ -459,7 +480,7 @@ int msm_dsi_cmd_dma_tx(struct dsi_buf *tp)
MIPI_OUTP(ctrl_base + DSI_CMD_MODE_DMA_SW_TRIGGER, 0x01);
wmb();
- rc = wait_for_completion_timeout(&dsi_host_private->dma_comp,
+ rc = wait_for_completion_timeout(&ctrl->dma_comp,
msecs_to_jiffies(DSI_DMA_CMD_TIMEOUT_MS));
if (rc == 0) {
pr_err("DSI command transaction time out\n");
@@ -524,7 +545,7 @@ int msm_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
MIPI_OUTP(ctrl_base + DSI_CTRL, data);
}
- msm_dsi_enable_irq();
+ msm_dsi_set_irq(ctrl, DSI_INTR_CMD_DMA_DONE_MASK);
tp = &ctrl->tx_buf;
cm = cmds;
@@ -536,7 +557,7 @@ int msm_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
rc = -EINVAL;
break;
}
- rc = msm_dsi_cmd_dma_tx(tp);
+ rc = msm_dsi_cmd_dma_tx(ctrl, tp);
if (IS_ERR_VALUE(rc)) {
pr_err("%s: failed to call cmd_dma_tx\n", __func__);
break;
@@ -546,7 +567,7 @@ int msm_dsi_cmds_tx(struct mdss_dsi_ctrl_pdata *ctrl,
cm++;
}
- msm_dsi_disable_irq();
+ msm_dsi_clear_irq(ctrl, DSI_INTR_CMD_DMA_DONE_MASK);
if (video_mode)
MIPI_OUTP(ctrl_base + DSI_CTRL, dsi_ctrl);
@@ -617,7 +638,7 @@ int msm_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
cnt = len + 6; /* 4 bytes header + 2 bytes crc */
}
- msm_dsi_enable_irq();
+ msm_dsi_set_irq(ctrl, DSI_INTR_CMD_DMA_DONE_MASK);
tp = &ctrl->tx_buf;
rp = &ctrl->rx_buf;
@@ -633,7 +654,7 @@ int msm_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
rp->len = 0;
goto msm_dsi_cmds_rx_err;
}
- rc = msm_dsi_cmd_dma_tx(tp);
+ rc = msm_dsi_cmd_dma_tx(ctrl, tp);
if (IS_ERR_VALUE(rc)) {
pr_err("%s: msm_dsi_cmd_dma_tx failed\n", __func__);
rp->len = 0;
@@ -651,7 +672,7 @@ int msm_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
}
/* transmit read comamnd to client */
- rc = msm_dsi_cmd_dma_tx(tp);
+ rc = msm_dsi_cmd_dma_tx(ctrl, tp);
if (IS_ERR_VALUE(rc)) {
pr_err("%s: msm_dsi_cmd_dma_tx failed\n", __func__);
rp->len = 0;
@@ -715,7 +736,7 @@ int msm_dsi_cmds_rx(struct mdss_dsi_ctrl_pdata *ctrl,
dsi_ctrl); /* restore */
msm_dsi_cmds_rx_err:
- msm_dsi_disable_irq();
+ msm_dsi_clear_irq(ctrl, DSI_INTR_CMD_DMA_DONE_MASK);
return rp->len;
}
@@ -927,6 +948,8 @@ static int msm_dsi_on(struct mdss_panel_data *pdata)
msm_dsi_op_mode_config(mipi->mode, pdata);
+ msm_dsi_set_irq(ctrl_pdata, DSI_INTR_ERROR_MASK);
+
return ret;
}
@@ -945,6 +968,7 @@ static int msm_dsi_off(struct mdss_panel_data *pdata)
panel_data);
pr_debug("msm_dsi_off\n");
+ msm_dsi_clear_irq(ctrl_pdata, ctrl_pdata->dsi_irq_mask);
msm_dsi_controller_cfg(0);
msm_dsi_clk_set_rate(DSI_ESC_CLK_RATE, 0, 0, 0);
msm_dsi_clk_disable();
@@ -993,6 +1017,7 @@ static int msm_dsi_cont_on(struct mdss_panel_data *pdata)
msm_dsi_ahb_ctrl(1);
msm_dsi_prepare_clocks();
msm_dsi_clk_enable();
+ msm_dsi_set_irq(ctrl_pdata, DSI_INTR_ERROR_MASK);
return 0;
}
@@ -1218,7 +1243,8 @@ static int msm_dsi_probe(struct platform_device *pdev)
rc = -ENODEV;
goto error_irq_resource;
} else {
- rc = msm_dsi_irq_init(&pdev->dev, mdss_dsi_mres->start);
+ rc = msm_dsi_irq_init(&pdev->dev, mdss_dsi_mres->start,
+ ctrl_pdata);
if (rc) {
dev_err(&pdev->dev, "%s: failed to init irq, rc=%d\n",
__func__, rc);
@@ -1300,7 +1326,7 @@ error_io_init:
error_pan_node:
of_node_put(dsi_pan_node);
error_platform_pop:
- msm_dsi_disable_irq();
+ msm_dsi_clear_irq(ctrl_pdata, ctrl_pdata->dsi_irq_mask);
error_irq_resource:
if (dsi_host_private->dsi_base) {
iounmap(dsi_host_private->dsi_base);
@@ -1322,7 +1348,7 @@ static int msm_dsi_remove(struct platform_device *pdev)
return -ENODEV;
}
- msm_dsi_disable_irq();
+ msm_dsi_clear_irq(ctrl_pdata, ctrl_pdata->dsi_irq_mask);
msm_dsi_io_deinit(pdev, &(ctrl_pdata->power_data));
dsi_ctrl_config_deinit(pdev, ctrl_pdata);
iounmap(dsi_host_private->dsi_base);