summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlan Kwong <akwong@codeaurora.org>2016-07-29 02:10:37 -0400
committerAlan Kwong <akwong@codeaurora.org>2016-08-04 11:39:21 -0400
commit78910c8d3c109a14f2697d389d5422e80bdb3126 (patch)
tree07a9b0e395a09bbf624f7743ca77ee61a8a51300 /drivers/gpu
parent27bb590e99dadfeb59f40cba77b7804b9d9553c5 (diff)
drm/msm/sde: add function to return raw interrupt status
Current hardware interrupt driver does not support reading of raw interrupt status using interrupt index. This patch adds new function to perform atomic read and clear of interrupt status using interrupt index returned from interrupt lookup function. Change-Id: I0cb7f5802df6da270738e98bf4a1748978cdd565 Signed-off-by: Alan Kwong <akwong@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_interrupts.c22
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_interrupts.h12
-rw-r--r--drivers/gpu/drm/msm/sde/sde_irq.c10
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.h12
4 files changed, 56 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
index 921df1f7279f..49930365d989 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.c
@@ -891,6 +891,27 @@ static void sde_hw_intr_clear_interrupt_status(struct sde_hw_intr *intr,
spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
}
+static u32 sde_hw_intr_get_interrupt_status(struct sde_hw_intr *intr,
+ int irq_idx, bool clear)
+{
+ int reg_idx;
+ unsigned long irq_flags;
+ u32 intr_status;
+
+ spin_lock_irqsave(&intr->mask_lock, irq_flags);
+
+ reg_idx = sde_irq_map[irq_idx].reg_idx;
+ intr_status = SDE_REG_READ(&intr->hw,
+ sde_intr_set[reg_idx].status_off) &
+ sde_irq_map[irq_idx].irq_mask;
+ if (intr_status && clear)
+ SDE_REG_WRITE(&intr->hw, sde_intr_set[irq_idx].clr_off,
+ intr_status);
+
+ spin_unlock_irqrestore(&intr->mask_lock, irq_flags);
+
+ return intr_status;
+}
static void __setup_intr_ops(struct sde_hw_intr_ops *ops)
{
@@ -905,6 +926,7 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops)
ops->get_interrupt_sources = sde_hw_intr_get_interrupt_sources;
ops->get_interrupt_statuses = sde_hw_intr_get_interrupt_statuses;
ops->clear_interrupt_status = sde_hw_intr_clear_interrupt_status;
+ ops->get_interrupt_status = sde_hw_intr_get_interrupt_status;
}
static struct sde_mdss_base_cfg *__intr_offset(struct sde_mdss_cfg *m,
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
index 53a693d31616..261ef64c0065 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_interrupts.h
@@ -183,6 +183,18 @@ struct sde_hw_intr_ops {
int irq_idx);
/**
+ * get_interrupt_status - Gets HW interrupt status, and clear if set,
+ * based on given lookup IRQ index.
+ * @intr: HW interrupt handle
+ * @irq_idx: Lookup irq index return from irq_idx_lookup
+ * @clear: True to clear irq after read
+ */
+ u32 (*get_interrupt_status)(
+ struct sde_hw_intr *intr,
+ int irq_idx,
+ bool clear);
+
+ /**
* get_valid_interrupts - Gets a mask of all valid interrupt sources
* within SDE. These are actually status bits
* within interrupt registers that specify the
diff --git a/drivers/gpu/drm/msm/sde/sde_irq.c b/drivers/gpu/drm/msm/sde/sde_irq.c
index 41e5d67141b9..967255697dd1 100644
--- a/drivers/gpu/drm/msm/sde/sde_irq.c
+++ b/drivers/gpu/drm/msm/sde/sde_irq.c
@@ -111,6 +111,16 @@ int sde_disable_irq(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count)
return ret;
}
+u32 sde_read_irq(struct sde_kms *sde_kms, int irq_idx, bool clear)
+{
+ if (!sde_kms || !sde_kms->hw_intr ||
+ !sde_kms->hw_intr->ops.get_interrupt_status)
+ return 0;
+
+ return sde_kms->hw_intr->ops.get_interrupt_status(sde_kms->hw_intr,
+ irq_idx, clear);
+}
+
int sde_register_irq_callback(struct sde_kms *sde_kms, int irq_idx,
struct sde_irq_callback *register_irq_cb)
{
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index cc47cdc2ce22..6530adab85af 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -483,6 +483,18 @@ int sde_disable_irq(
uint32_t irq_count);
/**
+ * sde_read_irq - IRQ helper function for reading IRQ status
+ * @sde_kms: SDE handle
+ * @irq_idx: irq index
+ * @clear: True to clear the irq after read
+ * @return: non-zero if irq detected; otherwise no irq detected
+ */
+u32 sde_read_irq(
+ struct sde_kms *sde_kms,
+ int irq_idx,
+ bool clear);
+
+/**
* sde_register_irq_callback - For registering callback function on IRQ
* interrupt
* @sde_kms: SDE handle