summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorJeykumar Sankaran <jsanka@codeaurora.org>2016-03-09 15:03:00 -0800
committerKyle Yan <kyan@codeaurora.org>2016-04-28 16:46:12 -0700
commit1e1bf68fa5da6cfa19fd06faaea13b37aa0ace12 (patch)
tree76dc0ef7bbb70c630f0480aedbeeb4f6ece81c38 /drivers/video/fbdev
parent8e11c85eb89f8594aa268cc0a6fbe9191f3d2c19 (diff)
msm: mdss: handle multiple MDP interrupt register sets
This change enhances the existing MDP ISR routine handlers to handle multiple MDP register sets. Maintain IRQ handlers and callbacks in a single file. Change-Id: Iea6e77be1eaab5ccf2fd89f7c98e2dd328af7de0 Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c387
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_hwio.h23
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c81
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_video.c31
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_util.c268
8 files changed, 417 insertions, 388 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index d9397cc5614d..06f7438814aa 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -338,7 +338,7 @@ struct mdss_data_type {
u32 default_ot_wr_limit;
struct irq_domain *irq_domain;
- u32 mdp_irq_mask;
+ u32 *mdp_irq_mask;
u32 mdp_hist_irq_mask;
int suspend_fs_ena;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 4fad99d5617c..e247596ff782 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -89,6 +89,7 @@ struct msm_mdp_interface mdp5 = {
#define MEM_PROTECT_SD_CTRL_FLAT 0x14
static DEFINE_SPINLOCK(mdp_lock);
+static DEFINE_SPINLOCK(mdss_mdp_intr_lock);
static DEFINE_MUTEX(mdp_clk_lock);
static DEFINE_MUTEX(mdp_iommu_ref_cnt_lock);
static DEFINE_MUTEX(mdp_fs_idle_pc_lock);
@@ -149,6 +150,83 @@ u32 invalid_mdp107_wb_output_fmts[] = {
MDP_BGRX_8888,
};
+/*
+ * struct intr_call - array of intr handlers
+ * @func: intr handler
+ * @arg: requested argument to the handler
+ */
+struct intr_callback {
+ void (*func)(void *);
+ void *arg;
+};
+
+/*
+ * struct mdss_mdp_intr_reg - array of MDP intr register sets
+ * @clr_off: offset to CLEAR reg
+ * @en_off: offset to ENABLE reg
+ * @status_off: offset to STATUS reg
+ */
+struct mdss_mdp_intr_reg {
+ u32 clr_off;
+ u32 en_off;
+ u32 status_off;
+};
+
+/*
+ * struct mdss_mdp_irq - maps each irq with i/f
+ * @intr_type: type of interface
+ * @intf_num: i/f the irq is associated with
+ * @irq_mask: corresponding bit in the reg set
+ * @reg_idx: which reg set to program
+ */
+struct mdss_mdp_irq {
+ u32 intr_type;
+ u32 intf_num;
+ u32 irq_mask;
+ u32 reg_idx;
+};
+
+static struct mdss_mdp_intr_reg mdp_intr_reg[] = {
+ { MDSS_MDP_REG_INTR_CLEAR, MDSS_MDP_REG_INTR_EN,
+ MDSS_MDP_REG_INTR_STATUS },
+ { MDSS_MDP_REG_INTR2_CLEAR, MDSS_MDP_REG_INTR2_EN,
+ MDSS_MDP_REG_INTR2_STATUS }
+};
+
+static struct mdss_mdp_irq mdp_irq_map[] = {
+ { MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN, 1, MDSS_MDP_INTR_INTF_0_UNDERRUN, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN, 2, MDSS_MDP_INTR_INTF_1_UNDERRUN, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN, 3, MDSS_MDP_INTR_INTF_2_UNDERRUN, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN, 4, MDSS_MDP_INTR_INTF_3_UNDERRUN, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_VSYNC, 1, MDSS_MDP_INTR_INTF_0_VSYNC, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_VSYNC, 2, MDSS_MDP_INTR_INTF_1_VSYNC, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_VSYNC, 3, MDSS_MDP_INTR_INTF_2_VSYNC, 0},
+ { MDSS_MDP_IRQ_TYPE_INTF_VSYNC, 4, MDSS_MDP_INTR_INTF_3_VSYNC, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, 0, MDSS_MDP_INTR_PING_PONG_0_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, 1, MDSS_MDP_INTR_PING_PONG_1_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, 2, MDSS_MDP_INTR_PING_PONG_2_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_COMP, 3, MDSS_MDP_INTR_PING_PONG_3_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR, 0, MDSS_MDP_INTR_PING_PONG_0_RD_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR, 1, MDSS_MDP_INTR_PING_PONG_1_RD_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR, 2, MDSS_MDP_INTR_PING_PONG_2_RD_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR, 3, MDSS_MDP_INTR_PING_PONG_3_RD_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR, 0, MDSS_MDP_INTR_PING_PONG_0_WR_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR, 1, MDSS_MDP_INTR_PING_PONG_1_WR_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR, 2, MDSS_MDP_INTR_PING_PONG_2_WR_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR, 3, MDSS_MDP_INTR_PING_PONG_3_WR_PTR, 0},
+ { MDSS_MDP_IRQ_TYPE_WB_ROT_COMP, 0, MDSS_MDP_INTR_WB_0_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_WB_ROT_COMP, 1, MDSS_MDP_INTR_WB_1_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_WB_WFD_COMP, 0, MDSS_MDP_INTR_WB_2_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF, 0, MDSS_MDP_INTR_PING_PONG_0_AUTOREFRESH_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF, 1, MDSS_MDP_INTR_PING_PONG_1_AUTOREFRESH_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF, 2, MDSS_MDP_INTR_PING_PONG_2_AUTOREFRESH_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF, 3, MDSS_MDP_INTR_PING_PONG_3_AUTOREFRESH_DONE, 0},
+ { MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, 2, MDSS_MDP_INTR2_PING_PONG_2_CWB_OVERFLOW, 1},
+ { MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW, 3, MDSS_MDP_INTR2_PING_PONG_2_CWB_OVERFLOW, 1}
+};
+
+static struct intr_callback *mdp_intr_cb;
+
static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on);
static int mdss_mdp_parse_dt(struct platform_device *pdev);
static int mdss_mdp_parse_dt_pipe(struct platform_device *pdev);
@@ -157,9 +235,9 @@ static int mdss_mdp_parse_dt_wb(struct platform_device *pdev);
static int mdss_mdp_parse_dt_ctl(struct platform_device *pdev);
static int mdss_mdp_parse_dt_video_intf(struct platform_device *pdev);
static int mdss_mdp_parse_dt_handler(struct platform_device *pdev,
- char *prop_name, u32 *offsets, int len);
+ char *prop_name, u32 *offsets, int len);
static int mdss_mdp_parse_dt_prop_len(struct platform_device *pdev,
- char *prop_name);
+ char *prop_name);
static int mdss_mdp_parse_dt_smp(struct platform_device *pdev);
static int mdss_mdp_parse_dt_prefill(struct platform_device *pdev);
static int mdss_mdp_parse_dt_misc(struct platform_device *pdev);
@@ -168,6 +246,21 @@ static int mdss_mdp_parse_dt_ppb_off(struct platform_device *pdev);
static int mdss_mdp_parse_dt_cdm(struct platform_device *pdev);
static int mdss_mdp_parse_dt_dsc(struct platform_device *pdev);
+static inline u32 is_mdp_irq_enabled(void)
+{
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_intr_reg); i++)
+ if (mdata->mdp_irq_mask[i] != 0)
+ return 1;
+
+ if (mdata->mdp_hist_irq_mask)
+ return 1;
+
+ return 0;
+}
+
u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp)
{
/* The adreno GPU hardware requires that the pitch be aligned to
@@ -612,12 +705,23 @@ int mdss_update_reg_bus_vote(struct reg_bus_client *bus_client, u32 usecase_ndx)
#endif
-static inline u32 mdss_mdp_irq_mask(u32 intr_type, u32 intf_num)
+static int mdss_mdp_intr2index(u32 intr_type, u32 intf_num)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_irq_map); i++) {
+ if (intr_type == mdp_irq_map[i].intr_type &&
+ intf_num == mdp_irq_map[i].intf_num)
+ return i;
+ }
+ return -EINVAL;
+}
+
+u32 mdss_mdp_get_irq_mask(u32 intr_type, u32 intf_num)
{
- if (intr_type == MDSS_MDP_IRQ_INTF_UNDER_RUN ||
- intr_type == MDSS_MDP_IRQ_INTF_VSYNC)
- intf_num = (intf_num - MDSS_MDP_INTF0) * 2;
- return 1 << (intr_type + intf_num);
+ int idx = mdss_mdp_intr2index(intr_type, intf_num);
+
+ return (idx < 0) ? 0 : mdp_irq_map[idx].irq_mask;
}
/* function assumes that mdp is clocked to access hw registers */
@@ -625,38 +729,55 @@ void mdss_mdp_irq_clear(struct mdss_data_type *mdata,
u32 intr_type, u32 intf_num)
{
unsigned long irq_flags;
- u32 irq;
+ int irq_idx;
+ struct mdss_mdp_intr_reg reg;
+ struct mdss_mdp_irq irq;
+
+ irq_idx = mdss_mdp_intr2index(intr_type, intf_num);
+ if (irq_idx < 0) {
+ pr_err("invalid irq request\n");
+ return;
+ }
- irq = mdss_mdp_irq_mask(intr_type, intf_num);
+ irq = mdp_irq_map[irq_idx];
+ reg = mdp_intr_reg[irq.reg_idx];
- pr_debug("clearing mdp irq mask=%x\n", irq);
+ pr_debug("clearing mdp irq mask=%x\n", irq.irq_mask);
spin_lock_irqsave(&mdp_lock, irq_flags);
- writel_relaxed(irq, mdata->mdp_base + MDSS_MDP_REG_INTR_CLEAR);
+ writel_relaxed(irq.irq_mask, mdata->mdp_base + reg.clr_off);
spin_unlock_irqrestore(&mdp_lock, irq_flags);
}
int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num)
{
- u32 irq;
+ int irq_idx, idx;
unsigned long irq_flags;
int ret = 0;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_intr_reg reg;
+ struct mdss_mdp_irq irq;
- irq = mdss_mdp_irq_mask(intr_type, intf_num);
+ irq_idx = mdss_mdp_intr2index(intr_type, intf_num);
+ if (irq_idx < 0) {
+ pr_err("invalid irq request\n");
+ return -EINVAL;
+ }
+
+ irq = mdp_irq_map[irq_idx];
+ reg = mdp_intr_reg[irq.reg_idx];
spin_lock_irqsave(&mdp_lock, irq_flags);
- if (mdata->mdp_irq_mask & irq) {
+ if (mdata->mdp_irq_mask[irq.reg_idx] & irq.irq_mask) {
pr_warn("MDSS MDP IRQ-0x%x is already set, mask=%x\n",
- irq, mdata->mdp_irq_mask);
+ irq.irq_mask, mdata->mdp_irq_mask[idx]);
ret = -EBUSY;
} else {
pr_debug("MDP IRQ mask old=%x new=%x\n",
- mdata->mdp_irq_mask, irq);
- mdata->mdp_irq_mask |= irq;
- writel_relaxed(irq, mdata->mdp_base +
- MDSS_MDP_REG_INTR_CLEAR);
- writel_relaxed(mdata->mdp_irq_mask, mdata->mdp_base +
- MDSS_MDP_REG_INTR_EN);
+ mdata->mdp_irq_mask[irq.reg_idx], irq.irq_mask);
+ mdata->mdp_irq_mask[irq.reg_idx] |= irq.irq_mask;
+ writel_relaxed(irq.irq_mask, mdata->mdp_base + reg.clr_off);
+ writel_relaxed(mdata->mdp_irq_mask[irq.reg_idx],
+ mdata->mdp_base + reg.en_off);
mdata->mdss_util->enable_irq(&mdss_mdp_hw);
}
spin_unlock_irqrestore(&mdp_lock, irq_flags);
@@ -673,7 +794,7 @@ int mdss_mdp_hist_irq_enable(u32 irq)
irq, mdata->mdp_hist_irq_mask);
ret = -EBUSY;
} else {
- pr_debug("MDP IRQ mask old=%x new=%x\n",
+ pr_debug("mask old=%x new=%x\n",
mdata->mdp_hist_irq_mask, irq);
mdata->mdp_hist_irq_mask |= irq;
writel_relaxed(irq, mdata->mdp_base +
@@ -688,47 +809,61 @@ int mdss_mdp_hist_irq_enable(u32 irq)
void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num)
{
- u32 irq;
+ int irq_idx;
unsigned long irq_flags;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_intr_reg reg;
+ struct mdss_mdp_irq irq;
- irq = mdss_mdp_irq_mask(intr_type, intf_num);
+ irq_idx = mdss_mdp_intr2index(intr_type, intf_num);
+ if (irq_idx < 0) {
+ pr_err("invalid irq request\n");
+ return;
+ }
+
+ irq = mdp_irq_map[irq_idx];
+ reg = mdp_intr_reg[irq.reg_idx];
spin_lock_irqsave(&mdp_lock, irq_flags);
- if (!(mdata->mdp_irq_mask & irq)) {
+ if (!(mdata->mdp_irq_mask[irq.reg_idx] & irq.irq_mask)) {
pr_warn("MDSS MDP IRQ-%x is NOT set, mask=%x\n",
- irq, mdata->mdp_irq_mask);
+ irq.irq_mask, mdata->mdp_irq_mask[irq.reg_idx]);
} else {
- mdata->mdp_irq_mask &= ~irq;
-
- writel_relaxed(mdata->mdp_irq_mask, mdata->mdp_base +
- MDSS_MDP_REG_INTR_EN);
- if ((mdata->mdp_irq_mask == 0) &&
- (mdata->mdp_hist_irq_mask == 0))
+ mdata->mdp_irq_mask[irq.reg_idx] &= ~irq.irq_mask;
+ writel_relaxed(mdata->mdp_irq_mask[irq.reg_idx],
+ mdata->mdp_base + reg.en_off);
+ if (!is_mdp_irq_enabled())
mdata->mdss_util->disable_irq(&mdss_mdp_hw);
}
spin_unlock_irqrestore(&mdp_lock, irq_flags);
}
-/*
- * This function is used to check and clear the status of
- * INTR and does not handle INTR2 and HIST_INTR
- */
+/* This function is used to check and clear the status of MDP interrupts */
void mdss_mdp_intr_check_and_clear(u32 intr_type, u32 intf_num)
{
- u32 status, irq;
+ u32 status;
+ int irq_idx;
unsigned long irq_flags;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_intr_reg reg;
+ struct mdss_mdp_irq irq;
- irq = mdss_mdp_irq_mask(intr_type, intf_num);
+ irq_idx = mdss_mdp_intr2index(intr_type, intf_num);
+ if (irq_idx < 0) {
+ pr_err("invalid irq request\n");
+ return;
+ }
+
+ irq = mdp_irq_map[irq_idx];
+ reg = mdp_intr_reg[irq.reg_idx];
spin_lock_irqsave(&mdp_lock, irq_flags);
- status = irq & readl_relaxed(mdata->mdp_base +
- MDSS_MDP_REG_INTR_STATUS);
+ status = irq.irq_mask & readl_relaxed(mdata->mdp_base +
+ reg.status_off);
if (status) {
pr_debug("clearing irq: intr_type:%d, intf_num:%d\n",
intr_type, intf_num);
- writel_relaxed(irq, mdata->mdp_base + MDSS_MDP_REG_INTR_CLEAR);
+ writel_relaxed(irq.irq_mask, mdata->mdp_base + reg.clr_off);
}
spin_unlock_irqrestore(&mdp_lock, irq_flags);
}
@@ -744,8 +879,7 @@ void mdss_mdp_hist_irq_disable(u32 irq)
mdata->mdp_hist_irq_mask &= ~irq;
writel_relaxed(mdata->mdp_hist_irq_mask, mdata->mdp_base +
MDSS_MDP_REG_HIST_INTR_EN);
- if ((mdata->mdp_irq_mask == 0) &&
- (mdata->mdp_hist_irq_mask == 0))
+ if (!is_mdp_irq_enabled())
mdata->mdss_util->disable_irq(&mdss_mdp_hw);
}
}
@@ -762,24 +896,163 @@ void mdss_mdp_hist_irq_disable(u32 irq)
*/
void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num)
{
- u32 irq;
+ int irq_idx;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ struct mdss_mdp_intr_reg reg;
+ struct mdss_mdp_irq irq;
- irq = mdss_mdp_irq_mask(intr_type, intf_num);
+ irq_idx = mdss_mdp_intr2index(intr_type, intf_num);
+ if (irq_idx < 0) {
+ pr_err("invalid irq request\n");
+ return;
+ }
+
+ irq = mdp_irq_map[irq_idx];
+ reg = mdp_intr_reg[irq.reg_idx];
- if (!(mdata->mdp_irq_mask & irq)) {
+ if (!(mdata->mdp_irq_mask[irq.reg_idx] & irq.irq_mask)) {
pr_warn("MDSS MDP IRQ-%x is NOT set, mask=%x\n",
- irq, mdata->mdp_irq_mask);
+ irq.irq_mask, mdata->mdp_irq_mask[irq.reg_idx]);
} else {
- mdata->mdp_irq_mask &= ~irq;
- writel_relaxed(mdata->mdp_irq_mask, mdata->mdp_base +
- MDSS_MDP_REG_INTR_EN);
- if ((mdata->mdp_irq_mask == 0) &&
- (mdata->mdp_hist_irq_mask == 0))
+ mdata->mdp_irq_mask[irq.reg_idx] &= ~irq.irq_mask;
+ writel_relaxed(mdata->mdp_irq_mask[irq.reg_idx],
+ mdata->mdp_base + reg.en_off);
+ if (!is_mdp_irq_enabled())
mdata->mdss_util->disable_irq_nosync(&mdss_mdp_hw);
}
}
+int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
+ void (*fnc_ptr)(void *), void *arg)
+{
+ unsigned long flags;
+ int index;
+
+ index = mdss_mdp_intr2index(intr_type, intf_num);
+ if (index < 0) {
+ pr_warn("invalid intr type=%u intf_numf_num=%u\n",
+ intr_type, intf_num);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
+ WARN(mdp_intr_cb[index].func && fnc_ptr,
+ "replacing current intr callback for ndx=%d\n", index);
+ mdp_intr_cb[index].func = fnc_ptr;
+ mdp_intr_cb[index].arg = arg;
+ spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
+
+ return 0;
+}
+
+int mdss_mdp_set_intr_callback_nosync(u32 intr_type, u32 intf_num,
+ void (*fnc_ptr)(void *), void *arg)
+{
+ int index;
+
+ index = mdss_mdp_intr2index(intr_type, intf_num);
+ if (index < 0) {
+ pr_warn("invalid intr Typee=%u intf_num=%u\n",
+ intr_type, intf_num);
+ return -EINVAL;
+ }
+
+ WARN(mdp_intr_cb[index].func && fnc_ptr,
+ "replacing current intr callbackack for ndx=%d\n",
+ index);
+ mdp_intr_cb[index].func = fnc_ptr;
+ mdp_intr_cb[index].arg = arg;
+
+ return 0;
+}
+
+static inline void mdss_mdp_intr_done(int index)
+{
+ void (*fnc)(void *);
+ void *arg;
+
+ spin_lock(&mdss_mdp_intr_lock);
+ fnc = mdp_intr_cb[index].func;
+ arg = mdp_intr_cb[index].arg;
+ spin_unlock(&mdss_mdp_intr_lock);
+ if (fnc)
+ fnc(arg);
+}
+
+irqreturn_t mdss_mdp_isr(int irq, void *ptr)
+{
+ struct mdss_data_type *mdata = ptr;
+ u32 isr, mask, hist_isr, hist_mask;
+ int i, j;
+
+ if (!mdata->clk_ena)
+ return IRQ_HANDLED;
+
+ for (i = 0; i < ARRAY_SIZE(mdp_intr_reg); i++) {
+ struct mdss_mdp_intr_reg reg = mdp_intr_reg[i];
+
+ isr = readl_relaxed(mdata->mdp_base + reg.status_off);
+ if (isr == 0)
+ continue;
+
+ mask = readl_relaxed(mdata->mdp_base + reg.en_off);
+ writel_relaxed(isr, mdata->mdp_base + reg.clr_off);
+
+ pr_debug("%s: reg:%d isr=%x mask=%x\n",
+ __func__, i+1, isr, mask);
+
+ isr &= mask;
+ if (isr == 0)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(mdp_irq_map); j++)
+ if (mdp_irq_map[j].reg_idx == i &&
+ (isr & mdp_irq_map[j].irq_mask))
+ mdss_mdp_intr_done(j);
+ if (!i) {
+ if (isr & MDSS_MDP_INTR_PING_PONG_0_DONE)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI0, false);
+
+ if (isr & MDSS_MDP_INTR_PING_PONG_1_DONE)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI1, false);
+
+ if (isr & MDSS_MDP_INTR_INTF_0_VSYNC)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_EDP, true);
+
+ if (isr & MDSS_MDP_INTR_INTF_1_VSYNC)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI0, true);
+
+ if (isr & MDSS_MDP_INTR_INTF_2_VSYNC)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI1, true);
+
+ if (isr & MDSS_MDP_INTR_INTF_3_VSYNC)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_HDMI, true);
+
+ if (isr & MDSS_MDP_INTR_WB_0_DONE)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
+
+ if (isr & MDSS_MDP_INTR_WB_1_DONE)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
+
+ if (isr & MDSS_MDP_INTR_WB_2_DONE)
+ mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
+ }
+ }
+
+ hist_isr = readl_relaxed(mdata->mdp_base +
+ MDSS_MDP_REG_HIST_INTR_STATUS);
+ if (hist_isr != 0) {
+ hist_mask = readl_relaxed(mdata->mdp_base +
+ MDSS_MDP_REG_HIST_INTR_EN);
+ writel_relaxed(hist_isr, mdata->mdp_base +
+ MDSS_MDP_REG_HIST_INTR_CLEAR);
+ hist_isr &= hist_mask;
+ if (hist_isr != 0)
+ mdss_mdp_hist_intr_done(hist_isr);
+ }
+ return IRQ_HANDLED;
+}
+
static int mdss_mdp_clk_update(u32 clk_idx, u32 enable)
{
int ret = -ENODEV;
@@ -2366,6 +2639,16 @@ static int mdss_mdp_probe(struct platform_device *pdev)
if (!display_on)
mdss_mdp_footswitch_ctrl_splash(false);
+ mdp_intr_cb = kcalloc(ARRAY_SIZE(mdp_irq_map),
+ sizeof(struct intr_callback), GFP_KERNEL);
+ if (mdp_intr_cb == NULL)
+ return -ENOMEM;
+
+ mdss_res->mdp_irq_mask = kcalloc(ARRAY_SIZE(mdp_intr_reg),
+ sizeof(u32), GFP_KERNEL);
+ if (mdss_res->mdp_irq_mask == NULL)
+ return -ENOMEM;
+
pr_info("mdss version = 0x%x, bootloader display is %s\n",
mdata->mdp_rev, display_on ? "on" : "off");
diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h
index 30b2e4be940c..a91c8df4fc89 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.h
+++ b/drivers/video/fbdev/msm/mdss_mdp.h
@@ -1388,6 +1388,7 @@ int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
void (*fnc_ptr)(void *), void *arg);
int mdss_mdp_set_intr_callback_nosync(u32 intr_type, u32 intf_num,
void (*fnc_ptr)(void *), void *arg);
+u32 mdss_mdp_get_irq_mask(u32 intr_type, u32 intf_num);
void mdss_mdp_footswitch_ctrl_splash(int on);
void mdss_mdp_batfet_ctrl(struct mdss_data_type *mdata, int enable);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
index d98896435d98..27ed5246649f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
@@ -60,6 +60,9 @@ static inline u32 mdss_mdp_hwio_mask(struct mdss_mdp_hwio_cfg *cfg, u32 val)
#define MDSS_MDP_REG_HW_VERSION 0x0
#define MDSS_MDP_REG_DISP_INTF_SEL 0x00004
+#define MDSS_MDP_REG_INTR2_EN 0x00008
+#define MDSS_MDP_REG_INTR2_STATUS 0x0000C
+#define MDSS_MDP_REG_INTR2_CLEAR 0x0002C
#define MDSS_MDP_REG_INTR_EN 0x00010
#define MDSS_MDP_REG_INTR_STATUS 0x00014
#define MDSS_MDP_REG_INTR_CLEAR 0x00018
@@ -115,6 +118,9 @@ static inline u32 mdss_mdp_hwio_mask(struct mdss_mdp_hwio_cfg *cfg, u32 val)
#define MDSS_MDP_INTR_INTF_3_UNDERRUN BIT(30)
#define MDSS_MDP_INTR_INTF_3_VSYNC BIT(31)
+#define MDSS_MDP_INTR2_PING_PONG_2_CWB_OVERFLOW BIT(14)
+#define MDSS_MDP_INTR2_PING_PONG_3_CWB_OVERFLOW BIT(15)
+
#define MDSS_MDP_HIST_INTR_VIG_0_DONE BIT(0)
#define MDSS_MDP_HIST_INTR_VIG_0_RESET_DONE BIT(1)
#define MDSS_MDP_HIST_INTR_VIG_1_DONE BIT(4)
@@ -133,14 +139,15 @@ static inline u32 mdss_mdp_hwio_mask(struct mdss_mdp_hwio_cfg *cfg, u32 val)
#define MDSS_MDP_HIST_INTR_DSPP_3_RESET_DONE BIT(23)
enum mdss_mdp_intr_type {
- MDSS_MDP_IRQ_WB_ROT_COMP = 0,
- MDSS_MDP_IRQ_WB_WFD = 4,
- MDSS_MDP_IRQ_PING_PONG_COMP = 8,
- MDSS_MDP_IRQ_PING_PONG_RD_PTR = 12,
- MDSS_MDP_IRQ_PING_PONG_WR_PTR = 16,
- MDSS_MDP_IRQ_PING_PONG_AUTO_REF = 20,
- MDSS_MDP_IRQ_INTF_UNDER_RUN = 24,
- MDSS_MDP_IRQ_INTF_VSYNC = 25,
+ MDSS_MDP_IRQ_TYPE_WB_ROT_COMP,
+ MDSS_MDP_IRQ_TYPE_WB_WFD_COMP,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
+ MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
+ MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
+ MDSS_MDP_IRQ_TYPE_CWB_OVERFLOW,
};
#define MDSS_MDP_REG_IGC_VIG_BASE 0x200
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 58e84eb7a141..4874e055b274 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1124,10 +1124,11 @@ static void mdss_mdp_cmd_intf_recovery(void *data, int event)
spin_lock_irqsave(&ctx->koff_lock, flags);
if (reset_done && atomic_add_unless(&ctx->koff_cnt, -1, 0)) {
pr_debug("%s: intf_num=%d\n", __func__, ctx->ctl->intf_num);
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
- ctx->current_pp_num, NULL, NULL);
+ mdss_mdp_set_intr_callback_nosync(
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num, NULL, NULL);
if (mdss_mdp_cmd_do_notifier(ctx))
notify_frame_timeout = true;
}
@@ -1163,9 +1164,9 @@ static void mdss_mdp_cmd_pingpong_done(void *arg)
spin_lock(&ctx->koff_lock);
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num, NULL, NULL);
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->current_pp_num);
@@ -1237,18 +1238,18 @@ static int mdss_mdp_setup_lineptr(struct mdss_mdp_cmd_ctx *ctx,
if (enable) {
/* enable clocks and irq */
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_WR_PTR,
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
ctx->default_pp_num);
} else {
/* disable clocks and irq */
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_WR_PTR,
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
ctx->default_pp_num);
/*
* check the intr status and clear the irq before
* disabling the clocks
*/
mdss_mdp_intr_check_and_clear(
- MDSS_MDP_IRQ_PING_PONG_WR_PTR,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
ctx->default_pp_num);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
@@ -1392,9 +1393,9 @@ static void mdss_mdp_cmd_autorefresh_pp_done(void *arg)
return;
}
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num, NULL, NULL);
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->current_pp_num);
@@ -1688,18 +1689,18 @@ static int mdss_mdp_setup_vsync(struct mdss_mdp_cmd_ctx *ctx,
if (enable) {
/* enable clocks and irq */
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
ctx->default_pp_num);
} else {
/* disable clocks and irq */
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
ctx->default_pp_num);
/*
* check the intr status and clear the irq before
* disabling the clocks
*/
mdss_mdp_intr_check_and_clear(
- MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
ctx->default_pp_num);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
@@ -1864,14 +1865,15 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
if (rc <= 0) {
u32 status, mask;
- mask = BIT(MDSS_MDP_IRQ_PING_PONG_COMP + ctx->current_pp_num);
+ mask = mdss_mdp_get_irq_mask(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num);
status = mask & readl_relaxed(ctl->mdata->mdp_base +
MDSS_MDP_REG_INTR_STATUS);
MDSS_XLOG(status, rc, atomic_read(&ctx->koff_cnt));
if (status) {
pr_warn("pp done but irq not triggered\n");
mdss_mdp_irq_clear(ctl->mdata,
- MDSS_MDP_IRQ_PING_PONG_COMP,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
local_irq_save(flags);
mdss_mdp_cmd_pingpong_done(ctl);
@@ -1902,10 +1904,11 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg)
ctx->pp_timeout_report_cnt++;
rc = -EPERM;
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
- ctx->current_pp_num, NULL, NULL);
+ mdss_mdp_set_intr_callback_nosync(
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num, NULL, NULL);
if (atomic_add_unless(&ctx->koff_cnt, -1, 0)
&& mdss_mdp_cmd_do_notifier(ctx))
mdss_mdp_ctl_notify(ctl, MDP_NOTIFY_FRAME_TIMEOUT);
@@ -2277,7 +2280,7 @@ static void mdss_mdp_cmd_post_programming(struct mdss_mdp_ctl *mctl)
static void mdss_mdp_cmd_wait4_autorefresh_pp(struct mdss_mdp_ctl *ctl)
{
int rc;
- u32 val, line_out, intr_type = MDSS_MDP_IRQ_PING_PONG_COMP;
+ u32 val, line_out, intr_type = MDSS_MDP_IRQ_TYPE_PING_PONG_COMP;
char __iomem *pp_base = ctl->mixer_left->pingpong_base;
struct mdss_mdp_cmd_ctx *ctx = ctl->intf_ctx[MASTER_CTX];
@@ -2301,7 +2304,7 @@ static void mdss_mdp_cmd_wait4_autorefresh_pp(struct mdss_mdp_ctl *ctl)
MDSS_MDP_REG_PP_LINE_COUNT);
if (val == ctl->mixer_left->roi.h) {
mdss_mdp_irq_clear(ctl->mdata,
- MDSS_MDP_IRQ_PING_PONG_COMP,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num);
mdss_mdp_irq_disable_nosync(intr_type,
ctx->current_pp_num);
@@ -2329,9 +2332,9 @@ static void mdss_mdp_cmd_autorefresh_done(void *arg)
return;
}
- mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ mdss_mdp_irq_disable_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num, NULL, NULL);
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctx->current_pp_num);
@@ -2400,9 +2403,9 @@ static void mdss_mdp_cmd_wait4_autorefresh_done(struct mdss_mdp_ctl *ctl)
reinit_completion(&ctx->autorefresh_done);
/* enable autorefresh done */
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num, mdss_mdp_cmd_autorefresh_done, ctl);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num);
/*
@@ -2420,22 +2423,23 @@ static void mdss_mdp_cmd_wait4_autorefresh_done(struct mdss_mdp_ctl *ctl)
if (rc <= 0) {
u32 status, mask;
- mask = BIT(MDSS_MDP_IRQ_PING_PONG_AUTO_REF +
- ctx->current_pp_num);
+ mask = mdss_mdp_get_irq_mask(
+ MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
+ ctx->current_pp_num);
status = mask & readl_relaxed(ctl->mdata->mdp_base +
MDSS_MDP_REG_INTR_STATUS);
if (status) {
pr_warn("autorefresh done but irq not triggered\n");
mdss_mdp_irq_clear(ctl->mdata,
- MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num);
local_irq_save(flags);
mdss_mdp_irq_disable_nosync(
- MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num);
mdss_mdp_set_intr_callback_nosync(
- MDSS_MDP_IRQ_PING_PONG_AUTO_REF,
+ MDSS_MDP_IRQ_TYPE_PING_PONG_AUTO_REF,
ctx->current_pp_num, NULL, NULL);
local_irq_restore(flags);
rc = 1;
@@ -2663,13 +2667,14 @@ static int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
mdss_mdp_disable_autorefresh(ctl, sctl);
}
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->current_pp_num, mdss_mdp_cmd_pingpong_done, ctl);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->current_pp_num);
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
+ ctx->current_pp_num);
if (sctx) {
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
sctx->current_pp_num, mdss_mdp_cmd_pingpong_done, sctl);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
sctx->current_pp_num);
}
@@ -2805,11 +2810,11 @@ int mdss_mdp_cmd_ctx_stop(struct mdss_mdp_ctl *ctl,
return 0;
}
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
ctx->default_pp_num, NULL, NULL);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_WR_PTR,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
ctx->default_pp_num, NULL, NULL);
- mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_PING_PONG_COMP,
+ mdss_mdp_set_intr_callback_nosync(MDSS_MDP_IRQ_TYPE_PING_PONG_COMP,
ctx->default_pp_num, NULL, NULL);
memset(ctx, 0, sizeof(*ctx));
@@ -3140,10 +3145,10 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl,
default_pp_num, aux_pp_num);
MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt));
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_RD_PTR,
ctx->default_pp_num, mdss_mdp_cmd_readptr_done, ctl);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_PING_PONG_WR_PTR,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR,
ctx->default_pp_num, mdss_mdp_cmd_writeptr_done, ctl);
ret = mdss_mdp_cmd_tearcheck_setup(ctx, false);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
index 9eae668526e4..4e4caf98ea9f 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_video.c
@@ -34,9 +34,6 @@
/* Filter out input events for 1 vsync time after receiving an input event*/
#define INPUT_EVENT_HANDLER_DELAY_USECS 16000
-#define MDP_INTR_MASK_INTF_VSYNC(intf_num) \
- (1 << (2 * (intf_num - MDSS_MDP_INTF0) + MDSS_MDP_IRQ_INTF_VSYNC))
-
/* intf timing settings */
struct intf_timing_params {
u32 width;
@@ -354,9 +351,10 @@ static inline void video_vsync_irq_enable(struct mdss_mdp_ctl *ctl, bool clear)
mutex_lock(&ctx->vsync_mtx);
if (atomic_inc_return(&ctx->vsync_ref) == 1)
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
+ ctl->intf_num);
else if (clear)
- mdss_mdp_irq_clear(ctl->mdata, MDSS_MDP_IRQ_INTF_VSYNC,
+ mdss_mdp_irq_clear(ctl->mdata, MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
ctl->intf_num);
mutex_unlock(&ctx->vsync_mtx);
}
@@ -367,7 +365,8 @@ static inline void video_vsync_irq_disable(struct mdss_mdp_ctl *ctl)
mutex_lock(&ctx->vsync_mtx);
if (atomic_dec_return(&ctx->vsync_ref) == 0)
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_VSYNC, ctl->intf_num);
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
+ ctl->intf_num);
mutex_unlock(&ctx->vsync_mtx);
}
@@ -450,11 +449,11 @@ void mdss_mdp_turn_off_time_engine(struct mdss_mdp_ctl *ctl,
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
ctx->timegen_en = false;
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num);
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN, ctl->intf_num);
sctl = mdss_mdp_get_split_ctl(ctl);
if (sctl)
- mdss_mdp_irq_disable(MDSS_MDP_IRQ_INTF_UNDER_RUN,
+ mdss_mdp_irq_disable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
sctl->intf_num);
}
@@ -489,9 +488,9 @@ static int mdss_mdp_video_ctx_stop(struct mdss_mdp_ctl *ctl,
mdss_bus_bandwidth_ctrl(false);
}
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
ctx->intf_num, NULL, NULL);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_UNDER_RUN,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
ctx->intf_num, NULL, NULL);
ctx->ref_cnt--;
@@ -614,7 +613,8 @@ static int mdss_mdp_video_pollwait(struct mdss_mdp_ctl *ctl)
u32 mask, status;
int rc;
- mask = MDP_INTR_MASK_INTF_VSYNC(ctl->intf_num);
+ mask = mdss_mdp_get_irq_mask(MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
+ ctl->intf_num);
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
rc = readl_poll_timeout(ctl->mdata->mdp_base + MDSS_MDP_REG_INTR_STATUS,
@@ -1140,10 +1140,11 @@ static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg)
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_UNDER_RUN, ctl->intf_num);
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
+ ctl->intf_num);
sctl = mdss_mdp_get_split_ctl(ctl);
if (sctl)
- mdss_mdp_irq_enable(MDSS_MDP_IRQ_INTF_UNDER_RUN,
+ mdss_mdp_irq_enable(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
sctl->intf_num);
mdss_bus_bandwidth_ctrl(true);
@@ -1447,10 +1448,10 @@ static int mdss_mdp_video_ctx_setup(struct mdss_mdp_ctl *ctl,
if (pinfo->compression_mode == COMPRESSION_DSC)
dsc = &pinfo->dsc;
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_VSYNC,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_INTF_VSYNC,
ctx->intf_num, mdss_mdp_video_vsync_intr_done,
ctl);
- mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_INTF_UNDER_RUN,
+ mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_INTF_UNDER_RUN,
ctx->intf_num,
mdss_mdp_video_underrun_intr_done, ctl);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
index e019bcf6eeaf..5d9d8f45a965 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
@@ -76,7 +76,7 @@ struct mdss_mdp_writeback_ctx {
static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = {
{
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
- .intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
+ .intr_type = MDSS_MDP_IRQ_TYPE_WB_ROT_COMP,
.intf_num = 0,
.xin_id = 3,
.clk_ctrl.reg_off = 0x2BC,
@@ -84,7 +84,7 @@ static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = {
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
- .intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
+ .intr_type = MDSS_MDP_IRQ_TYPE_WB_ROT_COMP,
.intf_num = 1,
.xin_id = 11,
.clk_ctrl.reg_off = 0x2BC,
@@ -92,7 +92,7 @@ static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = {
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
- .intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
+ .intr_type = MDSS_MDP_IRQ_TYPE_WB_ROT_COMP,
.intf_num = 0,
.xin_id = 3,
.clk_ctrl.reg_off = 0x2BC,
@@ -100,7 +100,7 @@ static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = {
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
- .intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
+ .intr_type = MDSS_MDP_IRQ_TYPE_WB_ROT_COMP,
.intf_num = 1,
.xin_id = 11,
.clk_ctrl.reg_off = 0x2BC,
@@ -108,7 +108,7 @@ static struct mdss_mdp_writeback_ctx wb_ctx_list[MDSS_MDP_MAX_WRITEBACK] = {
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_WFD,
- .intr_type = MDSS_MDP_IRQ_WB_WFD,
+ .intr_type = MDSS_MDP_IRQ_TYPE_WB_WFD_COMP,
.intf_num = 0,
.xin_id = 6,
.clk_ctrl.reg_off = 0x2BC,
@@ -889,7 +889,7 @@ int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl)
/* WB2 Intr Enable is BIT(2) in MDSS 1.8.0 */
if (ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_108) {
- ctx->intr_type = MDSS_MDP_IRQ_WB_ROT_COMP;
+ ctx->intr_type = MDSS_MDP_IRQ_TYPE_WB_ROT_COMP;
ctx->intf_num = 2;
}
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c
index 2d173647422b..20bbfcedaad4 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_util.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_util.c
@@ -32,274 +32,6 @@
#define PHY_ADDR_4G (1ULL<<32)
-enum {
- MDP_INTR_VSYNC_INTF_0,
- MDP_INTR_VSYNC_INTF_1,
- MDP_INTR_VSYNC_INTF_2,
- MDP_INTR_VSYNC_INTF_3,
- MDP_INTR_UNDERRUN_INTF_0,
- MDP_INTR_UNDERRUN_INTF_1,
- MDP_INTR_UNDERRUN_INTF_2,
- MDP_INTR_UNDERRUN_INTF_3,
- MDP_INTR_PING_PONG_0,
- MDP_INTR_PING_PONG_1,
- MDP_INTR_PING_PONG_2,
- MDP_INTR_PING_PONG_3,
- MDP_INTR_PING_PONG_0_RD_PTR,
- MDP_INTR_PING_PONG_1_RD_PTR,
- MDP_INTR_PING_PONG_2_RD_PTR,
- MDP_INTR_PING_PONG_3_RD_PTR,
- MDP_INTR_PING_PONG_0_WR_PTR,
- MDP_INTR_PING_PONG_1_WR_PTR,
- MDP_INTR_PING_PONG_2_WR_PTR,
- MDP_INTR_PING_PONG_3_WR_PTR,
- MDP_INTR_WB_0,
- MDP_INTR_WB_1,
- MDP_INTR_WB_2,
- MDP_INTR_PING_PONG_0_AUTO_REF,
- MDP_INTR_PING_PONG_1_AUTO_REF,
- MDP_INTR_PING_PONG_2_AUTO_REF,
- MDP_INTR_PING_PONG_3_AUTO_REF,
- MDP_INTR_MAX,
-};
-
-struct intr_callback {
- void (*func)(void *);
- void *arg;
-};
-
-struct intr_callback mdp_intr_cb[MDP_INTR_MAX];
-static DEFINE_SPINLOCK(mdss_mdp_intr_lock);
-
-static int mdss_mdp_intr2index(u32 intr_type, u32 intf_num)
-{
- int index = -1;
- switch (intr_type) {
- case MDSS_MDP_IRQ_INTF_UNDER_RUN:
- index = MDP_INTR_UNDERRUN_INTF_0 + (intf_num - MDSS_MDP_INTF0);
- break;
- case MDSS_MDP_IRQ_INTF_VSYNC:
- index = MDP_INTR_VSYNC_INTF_0 + (intf_num - MDSS_MDP_INTF0);
- break;
- case MDSS_MDP_IRQ_PING_PONG_COMP:
- index = MDP_INTR_PING_PONG_0 + intf_num;
- break;
- case MDSS_MDP_IRQ_PING_PONG_RD_PTR:
- index = MDP_INTR_PING_PONG_0_RD_PTR + intf_num;
- break;
- case MDSS_MDP_IRQ_PING_PONG_WR_PTR:
- index = MDP_INTR_PING_PONG_0_WR_PTR + intf_num;
- break;
- case MDSS_MDP_IRQ_WB_ROT_COMP:
- index = MDP_INTR_WB_0 + intf_num;
- break;
- case MDSS_MDP_IRQ_WB_WFD:
- index = MDP_INTR_WB_2 + intf_num;
- break;
- case MDSS_MDP_IRQ_PING_PONG_AUTO_REF:
- index = MDP_INTR_PING_PONG_0_AUTO_REF + intf_num;
- break;
- }
-
- return index;
-}
-
-int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
- void (*fnc_ptr)(void *), void *arg)
-{
- unsigned long flags;
- int index;
-
- index = mdss_mdp_intr2index(intr_type, intf_num);
- if (index < 0) {
- pr_warn("invalid intr type=%u intf_num=%u\n",
- intr_type, intf_num);
- return -EINVAL;
- }
-
- spin_lock_irqsave(&mdss_mdp_intr_lock, flags);
- WARN(mdp_intr_cb[index].func && fnc_ptr,
- "replacing current intr callback for ndx=%d\n", index);
- mdp_intr_cb[index].func = fnc_ptr;
- mdp_intr_cb[index].arg = arg;
- spin_unlock_irqrestore(&mdss_mdp_intr_lock, flags);
-
- return 0;
-}
-
-int mdss_mdp_set_intr_callback_nosync(u32 intr_type, u32 intf_num,
- void (*fnc_ptr)(void *), void *arg)
-{
- int index;
-
- index = mdss_mdp_intr2index(intr_type, intf_num);
- if (index < 0) {
- pr_warn("invalid intr type=%u intf_num=%u\n",
- intr_type, intf_num);
- return -EINVAL;
- }
-
- WARN(mdp_intr_cb[index].func && fnc_ptr,
- "replacing current intr callback for ndx=%d\n", index);
- mdp_intr_cb[index].func = fnc_ptr;
- mdp_intr_cb[index].arg = arg;
-
- return 0;
-}
-
-static inline void mdss_mdp_intr_done(int index)
-{
- void (*fnc)(void *);
- void *arg;
-
- spin_lock(&mdss_mdp_intr_lock);
- fnc = mdp_intr_cb[index].func;
- arg = mdp_intr_cb[index].arg;
- spin_unlock(&mdss_mdp_intr_lock);
- if (fnc)
- fnc(arg);
-}
-
-irqreturn_t mdss_mdp_isr(int irq, void *ptr)
-{
- struct mdss_data_type *mdata = ptr;
- u32 isr, mask, hist_isr, hist_mask;
-
- if (!mdata->clk_ena)
- return IRQ_HANDLED;
-
- isr = readl_relaxed(mdata->mdp_base + MDSS_MDP_REG_INTR_STATUS);
-
- if (isr == 0)
- goto mdp_isr_done;
-
-
- mask = readl_relaxed(mdata->mdp_base + MDSS_MDP_REG_INTR_EN);
- writel_relaxed(isr, mdata->mdp_base + MDSS_MDP_REG_INTR_CLEAR);
-
- pr_debug("%s: isr=%x mask=%x\n", __func__, isr, mask);
-
- isr &= mask;
- if (isr == 0)
- goto mdp_isr_done;
-
- if (isr & MDSS_MDP_INTR_INTF_0_UNDERRUN)
- mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_0);
-
- if (isr & MDSS_MDP_INTR_INTF_1_UNDERRUN)
- mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_1);
-
- if (isr & MDSS_MDP_INTR_INTF_2_UNDERRUN)
- mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_2);
-
- if (isr & MDSS_MDP_INTR_INTF_3_UNDERRUN)
- mdss_mdp_intr_done(MDP_INTR_UNDERRUN_INTF_3);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_0_DONE) {
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_0);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI0, false);
- }
-
- if (isr & MDSS_MDP_INTR_PING_PONG_1_DONE) {
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_1);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI1, false);
- }
-
- if (isr & MDSS_MDP_INTR_PING_PONG_2_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_2);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_3_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_3);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_0_RD_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_0_RD_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_1_RD_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_1_RD_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_2_RD_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_2_RD_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_3_RD_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_3_RD_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_0_WR_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_0_WR_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_1_WR_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_1_WR_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_2_WR_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_2_WR_PTR);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_3_WR_PTR)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_3_WR_PTR);
-
- if (isr & MDSS_MDP_INTR_INTF_0_VSYNC) {
- mdss_mdp_intr_done(MDP_INTR_VSYNC_INTF_0);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_EDP, true);
- }
-
- if (isr & MDSS_MDP_INTR_INTF_1_VSYNC) {
- mdss_mdp_intr_done(MDP_INTR_VSYNC_INTF_1);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI0, true);
- }
-
- if (isr & MDSS_MDP_INTR_INTF_2_VSYNC) {
- mdss_mdp_intr_done(MDP_INTR_VSYNC_INTF_2);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_DSI1, true);
- }
-
- if (isr & MDSS_MDP_INTR_INTF_3_VSYNC) {
- mdss_mdp_intr_done(MDP_INTR_VSYNC_INTF_3);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_HDMI, true);
- }
-
- if (isr & MDSS_MDP_INTR_WB_0_DONE) {
- mdss_mdp_intr_done(MDP_INTR_WB_0);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
- }
-
- if (isr & MDSS_MDP_INTR_WB_1_DONE) {
- mdss_mdp_intr_done(MDP_INTR_WB_1);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
- }
-
- if (isr & ((mdata->mdp_rev == MDSS_MDP_HW_REV_108) ?
- MDSS_MDP_INTR_WB_2_DONE >> 2 : MDSS_MDP_INTR_WB_2_DONE)) {
- mdss_mdp_intr_done(MDP_INTR_WB_2);
- mdss_misr_crc_collect(mdata, DISPLAY_MISR_MDP, true);
- }
-
- if (isr & MDSS_MDP_INTR_PING_PONG_0_AUTOREFRESH_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_0_AUTO_REF);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_1_AUTOREFRESH_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_1_AUTO_REF);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_2_AUTOREFRESH_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_2_AUTO_REF);
-
- if (isr & MDSS_MDP_INTR_PING_PONG_3_AUTOREFRESH_DONE)
- mdss_mdp_intr_done(MDP_INTR_PING_PONG_3_AUTO_REF);
-
-mdp_isr_done:
- hist_isr = readl_relaxed(mdata->mdp_base +
- MDSS_MDP_REG_HIST_INTR_STATUS);
- if (hist_isr == 0)
- goto hist_isr_done;
- hist_mask = readl_relaxed(mdata->mdp_base +
- MDSS_MDP_REG_HIST_INTR_EN);
- writel_relaxed(hist_isr, mdata->mdp_base +
- MDSS_MDP_REG_HIST_INTR_CLEAR);
- hist_isr &= hist_mask;
- if (hist_isr == 0)
- goto hist_isr_done;
- mdss_mdp_hist_intr_done(hist_isr);
-hist_isr_done:
- return IRQ_HANDLED;
-}
-
void mdss_mdp_format_flag_removal(u32 *table, u32 num, u32 remove_bits)
{
struct mdss_mdp_format_params *fmt = NULL;