msm: disp: dpu1: add support to access hw irqs regs depending on revision
authorShubhashree Dhar <dhar@codeaurora.org>
Wed, 20 Nov 2019 11:32:31 +0000 (17:02 +0530)
committerRob Clark <robdclark@chromium.org>
Thu, 2 Jan 2020 23:08:23 +0000 (15:08 -0800)
Current code assumes that all the irqs registers offsets can be
accessed in all the hw revisions; this is not the case for some
targets that should not access some of the irq registers.
This change adds the support to selectively remove the irqs that
are not supported in some of the hw revisions.

Changes in v1:
 - Add support to selectively remove the hw irqs that are not
   not supported.

Changes in v2:
 - Remove unrelated changes.

Changes in v3:
 - Remove change-id (Stephen Boyd).
 - Add colon in variable description to match kernel-doc (Stephen Boyd).
 - Change macro-y way of variable description (Jordon Crouse).
 - Remove unnecessary if checks (Jordon Crouse).
 - Remove extra blank line (Jordon Crouse).

Changes in v4:
 - Remove checkpatch errors.

Signed-off-by: Shubhashree Dhar <dhar@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h

index dd096b6b7bfa13cb28696770c0c3a5bbeb75aeb1..fe0c601ece239ee11e240153b2d4f8a89dca1659 100644 (file)
@@ -421,6 +421,7 @@ static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
                .reg_dma_count = 1,
                .dma_cfg = sdm845_regdma,
                .perf = sdm845_perf_data,
+               .mdss_irqs = 0x3ff,
        };
 }
 
index 79875195cd9ca87796af9056a628109349dce862..9fe20a9e78cb6404174e1cf918a980c12dffa761 100644 (file)
@@ -646,6 +646,7 @@ struct dpu_perf_cfg {
  * @dma_formats        Supported formats for dma pipe
  * @cursor_formats     Supported formats for cursor pipe
  * @vig_formats        Supported formats for vig pipe
+ * @mdss_irqs:         Bitmap with the irqs supported by the target
  */
 struct dpu_mdss_cfg {
        u32 hwversion;
@@ -684,6 +685,8 @@ struct dpu_mdss_cfg {
        const struct dpu_format_extended *dma_formats;
        const struct dpu_format_extended *cursor_formats;
        const struct dpu_format_extended *vig_formats;
+
+       unsigned long mdss_irqs;
 };
 
 struct dpu_mdss_hw_cfg_handler {
index 8bfa7d0eede6c9a4cc8ae3f7a58664cadc8968e3..d84a84f7fe1a9d8ca37cebc44db7833b0d7dc96f 100644 (file)
@@ -800,8 +800,8 @@ static void dpu_hw_intr_dispatch_irq(struct dpu_hw_intr *intr,
                start_idx = reg_idx * 32;
                end_idx = start_idx + 32;
 
-               if (start_idx >= ARRAY_SIZE(dpu_irq_map) ||
-                               end_idx > ARRAY_SIZE(dpu_irq_map))
+               if (!test_bit(reg_idx, &intr->irq_mask) ||
+                       start_idx >= ARRAY_SIZE(dpu_irq_map))
                        continue;
 
                /*
@@ -955,8 +955,11 @@ static int dpu_hw_intr_clear_irqs(struct dpu_hw_intr *intr)
        if (!intr)
                return -EINVAL;
 
-       for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++)
-               DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].clr_off, 0xffffffff);
+       for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
+               if (test_bit(i, &intr->irq_mask))
+                       DPU_REG_WRITE(&intr->hw,
+                                       dpu_intr_set[i].clr_off, 0xffffffff);
+       }
 
        /* ensure register writes go through */
        wmb();
@@ -971,8 +974,11 @@ static int dpu_hw_intr_disable_irqs(struct dpu_hw_intr *intr)
        if (!intr)
                return -EINVAL;
 
-       for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++)
-               DPU_REG_WRITE(&intr->hw, dpu_intr_set[i].en_off, 0x00000000);
+       for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
+               if (test_bit(i, &intr->irq_mask))
+                       DPU_REG_WRITE(&intr->hw,
+                                       dpu_intr_set[i].en_off, 0x00000000);
+       }
 
        /* ensure register writes go through */
        wmb();
@@ -991,6 +997,9 @@ static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
 
        spin_lock_irqsave(&intr->irq_lock, irq_flags);
        for (i = 0; i < ARRAY_SIZE(dpu_intr_set); i++) {
+               if (!test_bit(i, &intr->irq_mask))
+                       continue;
+
                /* Read interrupt status */
                intr->save_irq_status[i] = DPU_REG_READ(&intr->hw,
                                dpu_intr_set[i].status_off);
@@ -1115,6 +1124,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
                return ERR_PTR(-ENOMEM);
        }
 
+       intr->irq_mask = m->mdss_irqs;
        spin_lock_init(&intr->irq_lock);
 
        return intr;
index 4edcf402dc46160f071a8ea28a36f8853102c760..fc9c98617281f17a1a6d8f3d5b20aa2f78b7635e 100644 (file)
@@ -187,6 +187,7 @@ struct dpu_hw_intr {
        u32 *save_irq_status;
        u32 irq_idx_tbl_size;
        spinlock_t irq_lock;
+       unsigned long irq_mask;
 };
 
 /**