Re: [Freedreno] [v1] msm: disp: dpu1: add support to access hw irqs regs depending on revision

2019-11-14 Thread Jordan Crouse
On Thu, Nov 14, 2019 at 11:18:56AM +0530, Shubhashree Dhar wrote:
> 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.
> 
> Change-Id: I6052b8237b703a1a9edd53893e04f7bd72223da1
> Signed-off-by: Shubhashree Dhar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   3 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  22 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |   1 +
>  drivers/gpu/drm/panel/panel-visionox-rm69299.c| 478 
> ++
>  5 files changed, 500 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/gpu/drm/panel/panel-visionox-rm69299.c
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index 04c8c44..357e15b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -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[0] = 0x3ff,
>   };
>  }
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index ec76b868..def8a3f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -646,6 +646,7 @@ struct dpu_perf_cfg {
>   * @dma_formatsSupported formats for dma pipe
>   * @cursor_formats Supported formats for cursor pipe
>   * @vig_formatsSupported 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 {
>   struct dpu_format_extended *dma_formats;
>   struct dpu_format_extended *cursor_formats;
>   struct dpu_format_extended *vig_formats;
> +
> + DECLARE_BITMAP(mdss_irqs, BITS_PER_BYTE * sizeof(long));

This is a very round about way of declaring an unsigned long. Do you ever
expect to have more than a long's worth of interrupt bits? If not, then just an
unsigned long mdss_irqs would be the preferred less macro-y way of doing this.

>  };
>  
>  struct dpu_mdss_hw_cfg_handler {
> 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 8bfa7d0..2a3634c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> @@ -800,7 +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) ||
> + if (!test_bit(reg_idx, &intr->irq_mask) ||
> + start_idx >= ARRAY_SIZE(dpu_irq_map) ||
>   end_idx > ARRAY_SIZE(dpu_irq_map)) 

This last one will always be true since end_idx is always 32 bigger than
start_idx. If you add the start_idx check you no longer need the end_idx check.

>   continue;
>  
> @@ -955,8 +956,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, 0x);
> + 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, 0x);
> + }
>  
>   /* ensure register writes go through */
>   wmb();
> @@ -971,8 +975,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, 0x);
> + 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, 0x);
> + }
>  
>   /* ensure register writes go through */
>   wmb();
> @@ -991,6 +998,10 @@ 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++) {
> +

This extra blank line isn't strictly needed if you don't want it.

> + if(!test_bit(i, &intr->irq_mask))
> +

[v1] msm: disp: dpu1: add support to access hw irqs regs depending on revision

2019-11-14 Thread Shubhashree Dhar
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.

Change-Id: I6052b8237b703a1a9edd53893e04f7bd72223da1
Signed-off-by: Shubhashree Dhar 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   3 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  22 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |   1 +
 drivers/gpu/drm/panel/panel-visionox-rm69299.c| 478 ++
 5 files changed, 500 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-visionox-rm69299.c

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 04c8c44..357e15b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -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[0] = 0x3ff,
};
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index ec76b868..def8a3f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -646,6 +646,7 @@ struct dpu_perf_cfg {
  * @dma_formatsSupported formats for dma pipe
  * @cursor_formats Supported formats for cursor pipe
  * @vig_formatsSupported 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 {
struct dpu_format_extended *dma_formats;
struct dpu_format_extended *cursor_formats;
struct dpu_format_extended *vig_formats;
+
+   DECLARE_BITMAP(mdss_irqs, BITS_PER_BYTE * sizeof(long));
 };
 
 struct dpu_mdss_hw_cfg_handler {
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 8bfa7d0..2a3634c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -800,7 +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) ||
+   if (!test_bit(reg_idx, &intr->irq_mask) ||
+   start_idx >= ARRAY_SIZE(dpu_irq_map) ||
end_idx > ARRAY_SIZE(dpu_irq_map))
continue;
 
@@ -955,8 +956,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, 0x);
+   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, 0x);
+   }
 
/* ensure register writes go through */
wmb();
@@ -971,8 +975,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, 0x);
+   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, 0x);
+   }
 
/* ensure register writes go through */
wmb();
@@ -991,6 +998,10 @@ 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 +1126,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
return ERR_PTR(-ENOMEM);
}
 
+   intr->irq_mask = m->mdss_irqs[0];
spin_lock_init(&intr->irq_lock);
 
return intr;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
index 4edcf40..fc9c986 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
+++ b/drivers/gpu/drm/