summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-31 13:04:01 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-31 13:04:00 -0700
commit3b18362c95a04971bd704a51ca99a9a8044a6698 (patch)
tree37386f0b5977a5d08f32339000b6c43f319b1347 /drivers
parent5ea83a180afd0bc27dbf996aca2f2c36631068cc (diff)
parent3dd9c422660d688da70a3ac20af5177b1f66ca97 (diff)
Merge "msm: kgsl: Clear the interrupt immediately"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/msm/adreno.c21
-rw-r--r--drivers/gpu/msm/adreno.h28
-rw-r--r--drivers/gpu/msm/adreno_a3xx.c5
-rw-r--r--drivers/gpu/msm/adreno_a4xx.c5
-rw-r--r--drivers/gpu/msm/adreno_a5xx.c5
5 files changed, 61 insertions, 3 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 9940f7a7c2b7..6160aa567fbf 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -589,11 +589,21 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct adreno_irq *irq_params = gpudev->irq;
irqreturn_t ret = IRQ_NONE;
- unsigned int status = 0, tmp;
+ unsigned int status = 0, tmp, int_bit;
int i;
adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status);
+ /*
+ * Clear all the interrupt bits but ADRENO_INT_RBBM_AHB_ERROR. Because
+ * even if we clear it here, it will stay high until it is cleared
+ * in its respective handler. Otherwise, the interrupt handler will
+ * fire again.
+ */
+ int_bit = ADRENO_INT_BIT(adreno_dev, ADRENO_INT_RBBM_AHB_ERROR);
+ adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD,
+ status & ~int_bit);
+
/* Loop through all set interrupts and call respective handlers */
for (tmp = status; tmp != 0;) {
i = fls(tmp) - 1;
@@ -612,9 +622,14 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device)
gpudev->irq_trace(adreno_dev, status);
- if (status)
+ /*
+ * Clear ADRENO_INT_RBBM_AHB_ERROR bit after this interrupt has been
+ * cleared in its respective handler
+ */
+ if (status & int_bit)
adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD,
- status);
+ int_bit);
+
return ret;
}
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 0f3403cb0095..a2af26c81f50 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -198,6 +198,10 @@ struct adreno_gpudev;
/* Time to allow preemption to complete (in ms) */
#define ADRENO_PREEMPT_TIMEOUT 10000
+#define ADRENO_INT_BIT(a, _bit) (((a)->gpucore->gpudev->int_bits) ? \
+ (adreno_get_int(a, _bit) < 0 ? 0 : \
+ BIT(adreno_get_int(a, _bit))) : 0)
+
/**
* enum adreno_preempt_states
* ADRENO_PREEMPT_NONE: No preemption is scheduled
@@ -574,6 +578,11 @@ enum adreno_regs {
ADRENO_REG_REGISTER_MAX,
};
+enum adreno_int_bits {
+ ADRENO_INT_RBBM_AHB_ERROR,
+ ADRENO_INT_BITS_MAX,
+};
+
/**
* adreno_reg_offsets: Holds array of register offsets
* @offsets: Offset array of size defined by enum adreno_regs
@@ -589,6 +598,7 @@ struct adreno_reg_offsets {
#define ADRENO_REG_UNUSED 0xFFFFFFFF
#define ADRENO_REG_SKIP 0xFFFFFFFE
#define ADRENO_REG_DEFINE(_offset, _reg) [_offset] = _reg
+#define ADRENO_INT_DEFINE(_offset, _val) ADRENO_REG_DEFINE(_offset, _val)
/*
* struct adreno_vbif_data - Describes vbif register value pair
@@ -726,6 +736,7 @@ struct adreno_gpudev {
* so define them in the structure and use them as variables.
*/
const struct adreno_reg_offsets *reg_offsets;
+ unsigned int *const int_bits;
const struct adreno_ft_perf_counters *ft_perf_counters;
unsigned int ft_perf_counters_count;
@@ -1101,6 +1112,23 @@ static inline unsigned int adreno_getreg(struct adreno_device *adreno_dev,
return gpudev->reg_offsets->offsets[offset_name];
}
+/*
+ * adreno_get_int() - Returns the offset value of an interrupt bit from
+ * the interrupt bit array in the gpudev node
+ * @adreno_dev: Pointer to the the adreno device
+ * @bit_name: The interrupt bit enum whose bit is returned
+ */
+static inline unsigned int adreno_get_int(struct adreno_device *adreno_dev,
+ enum adreno_int_bits bit_name)
+{
+ struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+
+ if (bit_name >= ADRENO_INT_BITS_MAX)
+ return -ERANGE;
+
+ return gpudev->int_bits[bit_name];
+}
+
/**
* adreno_gpu_fault() - Return the current state of the GPU
* @adreno_dev: A pointer to the adreno_device to query
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 97e71464c2df..3f5a9c6318f6 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -1425,6 +1425,10 @@ static struct adreno_coresight a3xx_coresight = {
.groups = a3xx_coresight_groups,
};
+static unsigned int a3xx_int_bits[ADRENO_INT_BITS_MAX] = {
+ ADRENO_INT_DEFINE(ADRENO_INT_RBBM_AHB_ERROR, A3XX_INT_RBBM_AHB_ERROR),
+};
+
/* Register offset defines for A3XX */
static unsigned int a3xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_RAM_WADDR, A3XX_CP_ME_RAM_WADDR),
@@ -1853,6 +1857,7 @@ int a3xx_microcode_load(struct adreno_device *adreno_dev,
struct adreno_gpudev adreno_a3xx_gpudev = {
.reg_offsets = &a3xx_reg_offsets,
+ .int_bits = a3xx_int_bits,
.ft_perf_counters = a3xx_ft_perf_counters,
.ft_perf_counters_count = ARRAY_SIZE(a3xx_ft_perf_counters),
.perfcounters = &a3xx_perfcounters,
diff --git a/drivers/gpu/msm/adreno_a4xx.c b/drivers/gpu/msm/adreno_a4xx.c
index bfbdb0e7ac1f..5ca04e522270 100644
--- a/drivers/gpu/msm/adreno_a4xx.c
+++ b/drivers/gpu/msm/adreno_a4xx.c
@@ -739,6 +739,10 @@ static void a4xx_err_callback(struct adreno_device *adreno_dev, int bit)
}
}
+static unsigned int a4xx_int_bits[ADRENO_INT_BITS_MAX] = {
+ ADRENO_INT_DEFINE(ADRENO_INT_RBBM_AHB_ERROR, A4XX_INT_RBBM_AHB_ERROR),
+};
+
/* Register offset defines for A4XX, in order of enum adreno_regs */
static unsigned int a4xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_RAM_WADDR, A4XX_CP_ME_RAM_WADDR),
@@ -1765,6 +1769,7 @@ static struct adreno_snapshot_data a4xx_snapshot_data = {
struct adreno_gpudev adreno_a4xx_gpudev = {
.reg_offsets = &a4xx_reg_offsets,
+ .int_bits = a4xx_int_bits,
.ft_perf_counters = a4xx_ft_perf_counters,
.ft_perf_counters_count = ARRAY_SIZE(a4xx_ft_perf_counters),
.perfcounters = &a4xx_perfcounters,
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 2891940b8f5b..860f6d2925f1 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -2872,6 +2872,10 @@ static struct adreno_ft_perf_counters a5xx_ft_perf_counters[] = {
{KGSL_PERFCOUNTER_GROUP_TSE, A5XX_TSE_INPUT_PRIM_NUM},
};
+static unsigned int a5xx_int_bits[ADRENO_INT_BITS_MAX] = {
+ ADRENO_INT_DEFINE(ADRENO_INT_RBBM_AHB_ERROR, A5XX_INT_RBBM_AHB_ERROR),
+};
+
/* Register offset defines for A5XX, in order of enum adreno_regs */
static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
ADRENO_REG_DEFINE(ADRENO_REG_CP_WFI_PEND_CTR, A5XX_CP_WFI_PEND_CTR),
@@ -3504,6 +3508,7 @@ static struct adreno_coresight a5xx_coresight = {
struct adreno_gpudev adreno_a5xx_gpudev = {
.reg_offsets = &a5xx_reg_offsets,
+ .int_bits = a5xx_int_bits,
.ft_perf_counters = a5xx_ft_perf_counters,
.ft_perf_counters_count = ARRAY_SIZE(a5xx_ft_perf_counters),
.coresight = &a5xx_coresight,