aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenet Clark <benetc@codeaurora.org>2014-03-11 18:34:37 -0700
committerBenet Clark <benetc@codeaurora.org>2014-04-03 20:40:25 -0700
commitd43a8123df49ae452316aa4f75d0022a0ed7fa3c (patch)
treec323a4325e79c9b1ad8aa9e25b52efcd8a4c19c5
parentec4b001eb1e99e83d213e99dc55453d7dc410c99 (diff)
msm: mdss: Add support for DSPP3 in histogram interrupt handler
Previously, we weren't handling histogram done interrupts for DSPP3 in the interrupt handler. The handler now looks to handle those interrupts. A helper function to parse the interrupt mask has been added to return the correct histogram info block. Change-Id: Ie469a4030b4f4f7ee8e4b8a766539c43f87504ac Signed-off-by: Benet Clark <benetc@codeaurora.org>
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_hwio.h17
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_pp.c133
2 files changed, 104 insertions, 46 deletions
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index b0ac75a4857..b65354d4a06 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -80,6 +80,23 @@
#define MDSS_MDP_INTR_INTF_3_UNDERRUN BIT(30)
#define MDSS_MDP_INTR_INTF_3_VSYNC BIT(31)
+#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)
+#define MDSS_MDP_HIST_INTR_VIG_1_RESET_DONE BIT(5)
+#define MDSS_MDP_HIST_INTR_VIG_2_DONE BIT(8)
+#define MDSS_MDP_HIST_INTR_VIG_2_RESET_DONE BIT(9)
+#define MDSS_MDP_HIST_INTR_VIG_3_DONE BIT(10)
+#define MDSS_MDP_HIST_INTR_VIG_3_RESET_DONE BIT(11)
+#define MDSS_MDP_HIST_INTR_DSPP_0_DONE BIT(12)
+#define MDSS_MDP_HIST_INTR_DSPP_0_RESET_DONE BIT(13)
+#define MDSS_MDP_HIST_INTR_DSPP_1_DONE BIT(16)
+#define MDSS_MDP_HIST_INTR_DSPP_1_RESET_DONE BIT(17)
+#define MDSS_MDP_HIST_INTR_DSPP_2_DONE BIT(20)
+#define MDSS_MDP_HIST_INTR_DSPP_2_RESET_DONE BIT(21)
+#define MDSS_MDP_HIST_INTR_DSPP_3_DONE BIT(22)
+#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,
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index c8102ad3418..6324aa35444 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -81,6 +81,9 @@ struct mdp_csc_cfg mdp_csc_convert[MDSS_MDP_MAX_CSC] = {
#define MDSS_BLOCK_DISP_NUM (MDP_BLOCK_MAX - MDP_LOGICAL_BLOCK_DISP_0)
+#define HIST_INTR_DSPP_MASK 0xFFF000
+#define HIST_V2_INTR_BIT_MASK 0xF33000
+#define HIST_V1_INTR_BIT_MASK 0X333333
#define HIST_WAIT_TIMEOUT(frame) ((75 * HZ * (frame)) / 1000)
/* hist collect state */
enum {
@@ -3832,54 +3835,94 @@ hist_collect_exit:
return ret;
}
-void mdss_mdp_hist_intr_done(u32 isr)
+
+static inline struct pp_hist_col_info *get_hist_info_from_isr(u32 *isr)
{
- u32 isr_blk, blk_idx;
+ u32 blk_idx;
struct pp_hist_col_info *hist_info = NULL;
struct mdss_mdp_pipe *pipe;
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+ if (*isr & HIST_INTR_DSPP_MASK) {
+ if (*isr & (MDSS_MDP_HIST_INTR_DSPP_0_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_0_RESET_DONE)) {
+ blk_idx = 0;
+ *isr &= ~(MDSS_MDP_HIST_INTR_DSPP_0_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_0_RESET_DONE);
+ } else if (*isr & (MDSS_MDP_HIST_INTR_DSPP_1_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_1_RESET_DONE)) {
+ blk_idx = 1;
+ *isr &= ~(MDSS_MDP_HIST_INTR_DSPP_1_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_1_RESET_DONE);
+ } else if (*isr & (MDSS_MDP_HIST_INTR_DSPP_2_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_2_RESET_DONE)) {
+ blk_idx = 2;
+ *isr &= ~(MDSS_MDP_HIST_INTR_DSPP_2_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_2_RESET_DONE);
+ } else {
+ blk_idx = 3;
+ *isr &= ~(MDSS_MDP_HIST_INTR_DSPP_3_DONE |
+ MDSS_MDP_HIST_INTR_DSPP_3_RESET_DONE);
+ }
+ hist_info = &mdss_pp_res->dspp_hist[blk_idx];
+ } else {
+ if (*isr & (MDSS_MDP_HIST_INTR_VIG_0_DONE |
+ MDSS_MDP_HIST_INTR_VIG_0_RESET_DONE)) {
+ blk_idx = MDSS_MDP_SSPP_VIG0;
+ *isr &= ~(MDSS_MDP_HIST_INTR_VIG_0_DONE |
+ MDSS_MDP_HIST_INTR_VIG_0_RESET_DONE);
+ } else if (*isr & (MDSS_MDP_HIST_INTR_VIG_1_DONE |
+ MDSS_MDP_HIST_INTR_VIG_1_RESET_DONE)) {
+ blk_idx = MDSS_MDP_SSPP_VIG1;
+ *isr &= ~(MDSS_MDP_HIST_INTR_VIG_1_DONE |
+ MDSS_MDP_HIST_INTR_VIG_1_RESET_DONE);
+ } else {
+ blk_idx = MDSS_MDP_SSPP_VIG2;
+ *isr &= ~(MDSS_MDP_HIST_INTR_VIG_2_DONE |
+ MDSS_MDP_HIST_INTR_VIG_2_RESET_DONE);
+ }
+ pipe = mdss_mdp_pipe_search(mdata, BIT(blk_idx));
+ if (IS_ERR_OR_NULL(pipe)) {
+ pr_debug("pipe DNE, %d", blk_idx);
+ return NULL;
+ }
+ hist_info = &pipe->pp_res.hist;
+ }
+
+ return hist_info;
+}
+
+/**
+ * mdss_mdp_hist_intr_done - Handle histogram interrupts.
+ * @isr: incoming histogram interrupts as bit mask
+ *
+ * This function takes the histogram interrupts received by the
+ * MDP interrupt handler, and handles each of the interrupts by
+ * progressing the histogram state if necessary and then clearing
+ * the interrupt.
+ */
+void mdss_mdp_hist_intr_done(u32 isr)
+{
+ u32 isr_blk, is_hist_done, is_hist_reset_done, isr_tmp;
+ struct pp_hist_col_info *hist_info = NULL;
+ struct mdss_data_type *mdata = mdss_mdp_get_mdata();
bool is_hist_v2 = mdata->mdp_rev >= MDSS_MDP_HW_REV_103;
bool need_complete = false;
- isr &= 0x333333;
+ u32 isr_mask = (is_hist_v2) ? HIST_V2_INTR_BIT_MASK :
+ HIST_V1_INTR_BIT_MASK;
+
+ isr &= isr_mask;
while (isr != 0) {
- if (isr & 0xFFF000) {
- if (isr & 0x3000) {
- blk_idx = 0;
- isr_blk = (isr >> 12) & 0x3;
- isr &= ~0x3000;
- } else if (isr & 0x30000) {
- blk_idx = 1;
- isr_blk = (isr >> 16) & 0x3;
- isr &= ~0x30000;
- } else {
- blk_idx = 2;
- isr_blk = (isr >> 20) & 0x3;
- isr &= ~0x300000;
- }
- hist_info = &mdss_pp_res->dspp_hist[blk_idx];
- } else {
- if (isr & 0x3) {
- blk_idx = MDSS_MDP_SSPP_VIG0;
- isr_blk = isr & 0x3;
- isr &= ~0x3;
- } else if (isr & 0x30) {
- blk_idx = MDSS_MDP_SSPP_VIG1;
- isr_blk = (isr >> 4) & 0x3;
- isr &= ~0x30;
- } else {
- blk_idx = MDSS_MDP_SSPP_VIG2;
- isr_blk = (isr >> 8) & 0x3;
- isr &= ~0x300;
- }
- pipe = mdss_mdp_pipe_search(mdata, BIT(blk_idx));
- if (IS_ERR_OR_NULL(pipe)) {
- pr_debug("pipe DNE, %d", blk_idx);
- continue;
- }
- hist_info = &pipe->pp_res.hist;
+ isr_tmp = isr;
+ hist_info = get_hist_info_from_isr(&isr);
+ if (NULL == hist_info) {
+ pr_err("hist interrupt gave incorrect blk_idx\n");
+ continue;
}
+ isr_blk = (isr_tmp >> hist_info->intr_shift) & 0x3;
+ is_hist_done = isr_blk & 0x1;
+ is_hist_reset_done = isr_blk & 0x2;
/* Histogram Done Interrupt */
- if (hist_info && (isr_blk & 0x1) && (hist_info->col_en)) {
+ if (hist_info && is_hist_done && (hist_info->col_en)) {
spin_lock(&hist_info->hist_lock);
if (!is_hist_v2)
hist_info->col_state = HIST_READY;
@@ -3894,24 +3937,22 @@ void mdss_mdp_hist_intr_done(u32 isr)
spin_unlock(&hist_info->hist_lock);
if (need_complete)
complete(&hist_info->comp);
- } else if (hist_info && (isr_blk & 0x1) &&
+ } else if (hist_info && is_hist_done &&
!(hist_info->col_en)) {
/*
* Histogram collection is disabled yet we got an
* interrupt somehow.
*/
- pr_err("Hist[%d] Done interrupt, col_en=false!\n",
- blk_idx);
+ pr_err("hist Done interrupt, col_en=false!\n");
}
/* Histogram Reset Done Interrupt */
- if (hist_info && (isr_blk & 0x2) && (hist_info->col_en)) {
+ if (hist_info && is_hist_reset_done && (hist_info->col_en)) {
spin_lock(&hist_info->hist_lock);
hist_info->col_state = HIST_IDLE;
spin_unlock(&hist_info->hist_lock);
- } else if (hist_info && (isr_blk & 0x2) &&
+ } else if (hist_info && is_hist_reset_done &&
!(hist_info->col_en)) {
- pr_err("Hist[%d] Reset Done interrupt, col_en=false!\n",
- blk_idx);
+ pr_err("hist Reset Done interrupt, col_en=false!\n");
}
};
}