diff options
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.c | 106 |
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); |