diff options
| author | Benet Clark <benetc@codeaurora.org> | 2014-03-11 18:34:37 -0700 |
|---|---|---|
| committer | Benet Clark <benetc@codeaurora.org> | 2014-04-03 20:40:25 -0700 |
| commit | d43a8123df49ae452316aa4f75d0022a0ed7fa3c (patch) | |
| tree | c323a4325e79c9b1ad8aa9e25b52efcd8a4c19c5 | |
| parent | ec4b001eb1e99e83d213e99dc55453d7dc410c99 (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.h | 17 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_mdp_pp.c | 133 |
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"); } }; } |
