summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c')
-rw-r--r--drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c106
1 files changed, 71 insertions, 35 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 5e2d68ebb113..e3c50439f80a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -51,11 +51,9 @@ struct dpu_intr_reg {
};
/*
- * struct dpu_intr_reg - List of DPU interrupt registers
- *
- * When making changes be sure to sync with dpu_hw_intr_reg
+ * dpu_intr_set_legacy - List of DPU interrupt registers for DPU <= 6.x
*/
-static const struct dpu_intr_reg dpu_intr_set[] = {
+static const struct dpu_intr_reg dpu_intr_set_legacy[] = {
[MDP_SSPP_TOP0_INTR] = {
INTR_CLEAR,
INTR_EN,
@@ -121,57 +119,78 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
MDP_AD4_INTR_EN_OFF(1),
MDP_AD4_INTR_STATUS_OFF(1),
},
- [MDP_INTF0_7xxx_INTR] = {
+};
+
+/*
+ * dpu_intr_set_7xxx - List of DPU interrupt registers for DPU >= 7.0
+ */
+static const struct dpu_intr_reg dpu_intr_set_7xxx[] = {
+ [MDP_SSPP_TOP0_INTR] = {
+ INTR_CLEAR,
+ INTR_EN,
+ INTR_STATUS
+ },
+ [MDP_SSPP_TOP0_INTR2] = {
+ INTR2_CLEAR,
+ INTR2_EN,
+ INTR2_STATUS
+ },
+ [MDP_SSPP_TOP0_HIST_INTR] = {
+ HIST_INTR_CLEAR,
+ HIST_INTR_EN,
+ HIST_INTR_STATUS
+ },
+ [MDP_INTF0_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(0),
MDP_INTF_REV_7xxx_INTR_EN(0),
MDP_INTF_REV_7xxx_INTR_STATUS(0)
},
- [MDP_INTF1_7xxx_INTR] = {
+ [MDP_INTF1_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(1),
MDP_INTF_REV_7xxx_INTR_EN(1),
MDP_INTF_REV_7xxx_INTR_STATUS(1)
},
- [MDP_INTF1_7xxx_TEAR_INTR] = {
+ [MDP_INTF1_TEAR_INTR] = {
MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(1),
MDP_INTF_REV_7xxx_INTR_TEAR_EN(1),
MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(1)
},
- [MDP_INTF2_7xxx_INTR] = {
+ [MDP_INTF2_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(2),
MDP_INTF_REV_7xxx_INTR_EN(2),
MDP_INTF_REV_7xxx_INTR_STATUS(2)
},
- [MDP_INTF2_7xxx_TEAR_INTR] = {
+ [MDP_INTF2_TEAR_INTR] = {
MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(2),
MDP_INTF_REV_7xxx_INTR_TEAR_EN(2),
MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(2)
},
- [MDP_INTF3_7xxx_INTR] = {
+ [MDP_INTF3_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(3),
MDP_INTF_REV_7xxx_INTR_EN(3),
MDP_INTF_REV_7xxx_INTR_STATUS(3)
},
- [MDP_INTF4_7xxx_INTR] = {
+ [MDP_INTF4_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(4),
MDP_INTF_REV_7xxx_INTR_EN(4),
MDP_INTF_REV_7xxx_INTR_STATUS(4)
},
- [MDP_INTF5_7xxx_INTR] = {
+ [MDP_INTF5_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(5),
MDP_INTF_REV_7xxx_INTR_EN(5),
MDP_INTF_REV_7xxx_INTR_STATUS(5)
},
- [MDP_INTF6_7xxx_INTR] = {
+ [MDP_INTF6_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(6),
MDP_INTF_REV_7xxx_INTR_EN(6),
MDP_INTF_REV_7xxx_INTR_STATUS(6)
},
- [MDP_INTF7_7xxx_INTR] = {
+ [MDP_INTF7_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(7),
MDP_INTF_REV_7xxx_INTR_EN(7),
MDP_INTF_REV_7xxx_INTR_STATUS(7)
},
- [MDP_INTF8_7xxx_INTR] = {
+ [MDP_INTF8_INTR] = {
MDP_INTF_REV_7xxx_INTR_CLEAR(8),
MDP_INTF_REV_7xxx_INTR_EN(8),
MDP_INTF_REV_7xxx_INTR_STATUS(8)
@@ -216,19 +235,19 @@ irqreturn_t dpu_core_irq(struct msm_kms *kms)
return IRQ_NONE;
spin_lock_irqsave(&intr->irq_lock, irq_flags);
- for (reg_idx = 0; reg_idx < ARRAY_SIZE(dpu_intr_set); reg_idx++) {
+ for (reg_idx = 0; reg_idx < MDP_INTR_MAX; reg_idx++) {
if (!test_bit(reg_idx, &intr->irq_mask))
continue;
/* Read interrupt status */
- irq_status = DPU_REG_READ(&intr->hw, dpu_intr_set[reg_idx].status_off);
+ irq_status = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].status_off);
/* Read enable mask */
- enable_mask = DPU_REG_READ(&intr->hw, dpu_intr_set[reg_idx].en_off);
+ enable_mask = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].en_off);
/* and clear the interrupt */
if (irq_status)
- DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
+ DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off,
irq_status);
/* Finally update IRQ status based on enable mask */
@@ -285,7 +304,11 @@ static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
assert_spin_locked(&intr->irq_lock);
reg_idx = DPU_IRQ_REG(irq_idx);
- reg = &dpu_intr_set[reg_idx];
+ reg = &intr->intr_set[reg_idx];
+
+ /* Is this interrupt register supported on the platform */
+ if (WARN_ON(!reg->en_off))
+ return -EINVAL;
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
@@ -334,7 +357,7 @@ static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr, int irq_idx)
assert_spin_locked(&intr->irq_lock);
reg_idx = DPU_IRQ_REG(irq_idx);
- reg = &dpu_intr_set[reg_idx];
+ reg = &intr->intr_set[reg_idx];
cache_irq_mask = intr->cache_irq_mask[reg_idx];
if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
@@ -368,10 +391,10 @@ static void dpu_clear_irqs(struct dpu_kms *dpu_kms)
if (!intr)
return;
- for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
+ for (i = 0; i < MDP_INTR_MAX; i++) {
if (test_bit(i, &intr->irq_mask))
DPU_REG_WRITE(&intr->hw,
- dpu_intr_set[i].clr_off, 0xffffffff);
+ intr->intr_set[i].clr_off, 0xffffffff);
}
/* ensure register writes go through */
@@ -386,10 +409,10 @@ static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms)
if (!intr)
return;
- for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
+ for (i = 0; i < MDP_INTR_MAX; i++) {
if (test_bit(i, &intr->irq_mask))
DPU_REG_WRITE(&intr->hw,
- dpu_intr_set[i].en_off, 0x00000000);
+ intr->intr_set[i].en_off, 0x00000000);
}
/* ensure register writes go through */
@@ -421,10 +444,10 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx)
reg_idx = DPU_IRQ_REG(irq_idx);
intr_status = DPU_REG_READ(&intr->hw,
- dpu_intr_set[reg_idx].status_off) &
+ intr->intr_set[reg_idx].status_off) &
DPU_IRQ_MASK(irq_idx);
if (intr_status)
- DPU_REG_WRITE(&intr->hw, dpu_intr_set[reg_idx].clr_off,
+ DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off,
intr_status);
/* ensure register writes go through */
@@ -435,17 +458,12 @@ u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx)
return intr_status;
}
-static void __intr_offset(const struct dpu_mdss_cfg *m,
- void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
-{
- hw->blk_addr = addr + m->mdp[0].base;
-}
-
struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
const struct dpu_mdss_cfg *m)
{
struct dpu_hw_intr *intr;
int nirq = MDP_INTR_MAX * 32;
+ unsigned int i;
if (!addr || !m)
return ERR_PTR(-EINVAL);
@@ -454,11 +472,29 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
if (!intr)
return ERR_PTR(-ENOMEM);
- __intr_offset(m, addr, &intr->hw);
+ if (m->mdss_ver->core_major_ver >= 7)
+ intr->intr_set = dpu_intr_set_7xxx;
+ else
+ intr->intr_set = dpu_intr_set_legacy;
+
+ intr->hw.blk_addr = addr + m->mdp[0].base;
intr->total_irqs = nirq;
- intr->irq_mask = m->mdss_irqs;
+ intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) |
+ BIT(MDP_SSPP_TOP0_INTR2) |
+ BIT(MDP_SSPP_TOP0_HIST_INTR);
+ for (i = 0; i < m->intf_count; i++) {
+ const struct dpu_intf_cfg *intf = &m->intf[i];
+
+ if (intf->type == INTF_NONE)
+ continue;
+
+ intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id));
+
+ if (intf->intr_tear_rd_ptr != -1)
+ intr->irq_mask |= BIT(DPU_IRQ_REG(intf->intr_tear_rd_ptr));
+ }
spin_lock_init(&intr->irq_lock);