Merge "msm: kgsl: Clear the interrupt immediately"
This commit is contained in:
commit
3b18362c95
5 changed files with 61 additions and 3 deletions
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue