mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
msm: kgsl: Add return value for perfcounter enable function
Add return value for adreno_perfcounter_enable function because it can fail. Also, some perfcounter enable functions were receiving incorrect parameter, fixed this by passing the right parameter to these enable functions. Change-Id: Ia47e9eab7833c44fcc0dc389ac8afce425f0a28e Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
This commit is contained in:
parent
d66d7c0426
commit
8a7e71b9b5
3 changed files with 137 additions and 58 deletions
|
@ -228,14 +228,28 @@ static const struct {
|
|||
* performance counters will remain active as long as the device is alive.
|
||||
*/
|
||||
|
||||
static void adreno_perfcounter_init(struct kgsl_device *device)
|
||||
static int adreno_perfcounter_init(struct kgsl_device *device)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
|
||||
if (adreno_dev->gpudev->perfcounter_init)
|
||||
adreno_dev->gpudev->perfcounter_init(adreno_dev);
|
||||
return adreno_dev->gpudev->perfcounter_init(adreno_dev);
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* adreno_perfcounter_close: Release counters initialized by
|
||||
* adreno_perfcounter_init
|
||||
* @device: device to realease counters for
|
||||
*
|
||||
*/
|
||||
static void adreno_perfcounter_close(struct kgsl_device *device)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
if (adreno_dev->gpudev->perfcounter_close)
|
||||
return adreno_dev->gpudev->perfcounter_close(adreno_dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* adreno_perfcounter_start: Enable performance counters
|
||||
* @adreno_dev: Adreno device to configure
|
||||
|
@ -243,16 +257,18 @@ static void adreno_perfcounter_init(struct kgsl_device *device)
|
|||
* Ensure all performance counters are enabled that are allocated. Since
|
||||
* the device was most likely stopped, we can't trust that the counters
|
||||
* are still valid so make it so.
|
||||
* Returns 0 on success else error code
|
||||
*/
|
||||
|
||||
static void adreno_perfcounter_start(struct adreno_device *adreno_dev)
|
||||
static int adreno_perfcounter_start(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
|
||||
struct adreno_perfcount_group *group;
|
||||
unsigned int i, j;
|
||||
int ret = 0;
|
||||
|
||||
if (NULL == counters)
|
||||
return;
|
||||
return 0;
|
||||
/* group id iter */
|
||||
for (i = 0; i < counters->group_count; i++) {
|
||||
group = &(counters->groups[i]);
|
||||
|
@ -266,11 +282,15 @@ static void adreno_perfcounter_start(struct adreno_device *adreno_dev)
|
|||
continue;
|
||||
|
||||
if (adreno_dev->gpudev->perfcounter_enable)
|
||||
adreno_dev->gpudev->perfcounter_enable(
|
||||
ret = adreno_dev->gpudev->perfcounter_enable(
|
||||
adreno_dev, i, j,
|
||||
group->regs[j].countable);
|
||||
if (ret)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,8 +312,7 @@ int adreno_perfcounter_read_group(struct adreno_device *adreno_dev,
|
|||
unsigned int i, j;
|
||||
int ret = 0;
|
||||
|
||||
/* perfcounter get/put/query/read not allowed on a2xx */
|
||||
if (adreno_is_a2xx(adreno_dev))
|
||||
if (NULL == counters)
|
||||
return -EINVAL;
|
||||
|
||||
/* sanity check for later */
|
||||
|
@ -371,8 +390,7 @@ int adreno_perfcounter_query_group(struct adreno_device *adreno_dev,
|
|||
|
||||
*max_counters = 0;
|
||||
|
||||
/* perfcounter get/put/query not allowed on a2xx */
|
||||
if (adreno_is_a2xx(adreno_dev))
|
||||
if (NULL == counters)
|
||||
return -EINVAL;
|
||||
|
||||
if (groupid >= counters->group_count)
|
||||
|
@ -421,13 +439,13 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
|
|||
struct adreno_perfcounters *counters = adreno_dev->gpudev->perfcounters;
|
||||
struct adreno_perfcount_group *group;
|
||||
unsigned int i, empty = -1;
|
||||
int ret = 0;
|
||||
|
||||
/* always clear return variables */
|
||||
if (offset)
|
||||
*offset = 0;
|
||||
|
||||
/* perfcounter get/put/query not allowed on a2xx */
|
||||
if (adreno_is_a2xx(adreno_dev))
|
||||
if (NULL == counters)
|
||||
return -EINVAL;
|
||||
|
||||
if (groupid >= counters->group_count)
|
||||
|
@ -462,6 +480,11 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
|
|||
if (empty == -1)
|
||||
return -EBUSY;
|
||||
|
||||
/* enable the new counter */
|
||||
ret = adreno_dev->gpudev->perfcounter_enable(adreno_dev, groupid, empty,
|
||||
countable);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* initialize the new counter */
|
||||
group->regs[empty].countable = countable;
|
||||
|
||||
|
@ -474,14 +497,10 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev,
|
|||
group->regs[empty].usercount = 1;
|
||||
}
|
||||
|
||||
/* enable the new counter */
|
||||
adreno_dev->gpudev->perfcounter_enable(adreno_dev, groupid, empty,
|
||||
countable);
|
||||
|
||||
if (offset)
|
||||
*offset = group->regs[empty].offset;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -503,8 +522,7 @@ int adreno_perfcounter_put(struct adreno_device *adreno_dev,
|
|||
|
||||
unsigned int i;
|
||||
|
||||
/* perfcounter get/put/query not allowed on a2xx */
|
||||
if (adreno_is_a2xx(adreno_dev))
|
||||
if (NULL == counters)
|
||||
return -EINVAL;
|
||||
|
||||
if (groupid >= counters->group_count)
|
||||
|
@ -1556,6 +1574,7 @@ static int __devexit adreno_remove(struct platform_device *pdev)
|
|||
|
||||
adreno_dispatcher_close(adreno_dev);
|
||||
adreno_ringbuffer_close(&adreno_dev->ringbuffer);
|
||||
adreno_perfcounter_close(device);
|
||||
kgsl_device_platform_remove(device);
|
||||
|
||||
clear_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv);
|
||||
|
@ -1568,6 +1587,7 @@ static int adreno_init(struct kgsl_device *device)
|
|||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
|
||||
/*
|
||||
|
@ -1631,18 +1651,21 @@ static int adreno_init(struct kgsl_device *device)
|
|||
for (i = 6; i < FT_DETECT_REGS_COUNT; i++)
|
||||
ft_detect_regs[i] = 0;
|
||||
|
||||
adreno_perfcounter_init(device);
|
||||
ret = adreno_perfcounter_init(device);
|
||||
|
||||
/* Power down the device */
|
||||
kgsl_pwrctrl_disable(device);
|
||||
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* Certain targets need the fixup. You know who you are */
|
||||
if (adreno_is_a330v2(adreno_dev))
|
||||
adreno_a3xx_pwron_fixup_init(adreno_dev);
|
||||
|
||||
set_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv);
|
||||
|
||||
return 0;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adreno_start(struct kgsl_device *device)
|
||||
|
@ -1711,15 +1734,19 @@ static int adreno_start(struct kgsl_device *device)
|
|||
if (status)
|
||||
goto error_irq_off;
|
||||
|
||||
status = adreno_perfcounter_start(adreno_dev);
|
||||
if (status)
|
||||
goto error_rb_stop;
|
||||
|
||||
/* Start the dispatcher */
|
||||
adreno_dispatcher_start(adreno_dev);
|
||||
|
||||
adreno_perfcounter_start(adreno_dev);
|
||||
|
||||
device->reset_counter++;
|
||||
|
||||
return 0;
|
||||
|
||||
error_rb_stop:
|
||||
adreno_ringbuffer_stop(&adreno_dev->ringbuffer);
|
||||
error_irq_off:
|
||||
kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
|
||||
|
||||
|
|
|
@ -364,10 +364,11 @@ struct adreno_gpudev {
|
|||
unsigned int (*irq_pending)(struct adreno_device *);
|
||||
void * (*snapshot)(struct adreno_device *, void *, int *, int);
|
||||
int (*rb_init)(struct adreno_device *, struct adreno_ringbuffer *);
|
||||
void (*perfcounter_init)(struct adreno_device *);
|
||||
int (*perfcounter_init)(struct adreno_device *);
|
||||
void (*perfcounter_close)(struct adreno_device *);
|
||||
void (*start)(struct adreno_device *);
|
||||
unsigned int (*busy_cycles)(struct adreno_device *);
|
||||
void (*perfcounter_enable)(struct adreno_device *, unsigned int group,
|
||||
int (*perfcounter_enable)(struct adreno_device *, unsigned int group,
|
||||
unsigned int counter, unsigned int countable);
|
||||
uint64_t (*perfcounter_read)(struct adreno_device *adreno_dev,
|
||||
unsigned int group, unsigned int counter);
|
||||
|
|
|
@ -3148,41 +3148,41 @@ static void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq)
|
|||
}
|
||||
|
||||
|
||||
static void a3xx_perfcounter_enable_pwr(struct kgsl_device *device,
|
||||
unsigned int countable)
|
||||
static int a3xx_perfcounter_enable_pwr(struct kgsl_device *device,
|
||||
unsigned int counter)
|
||||
{
|
||||
unsigned int in, out;
|
||||
|
||||
if (countable > 1)
|
||||
return;
|
||||
if (counter > 1)
|
||||
return -EINVAL;
|
||||
|
||||
kgsl_regread(device, A3XX_RBBM_RBBM_CTL, &in);
|
||||
|
||||
if (countable == 0)
|
||||
if (counter == 0)
|
||||
out = in | RBBM_RBBM_CTL_RESET_PWR_CTR0;
|
||||
else
|
||||
out = in | RBBM_RBBM_CTL_RESET_PWR_CTR1;
|
||||
|
||||
kgsl_regwrite(device, A3XX_RBBM_RBBM_CTL, out);
|
||||
|
||||
if (countable == 0)
|
||||
if (counter == 0)
|
||||
out = in | RBBM_RBBM_CTL_ENABLE_PWR_CTR0;
|
||||
else
|
||||
out = in | RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
|
||||
|
||||
kgsl_regwrite(device, A3XX_RBBM_RBBM_CTL, out);
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void a3xx_perfcounter_enable_vbif(struct kgsl_device *device,
|
||||
static int a3xx_perfcounter_enable_vbif(struct kgsl_device *device,
|
||||
unsigned int counter,
|
||||
unsigned int countable)
|
||||
{
|
||||
unsigned int in, out, bit, sel;
|
||||
|
||||
if (counter > 1 || countable > 0x7f)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
kgsl_regread(device, A3XX_VBIF_PERF_CNT_EN, &in);
|
||||
kgsl_regread(device, A3XX_VBIF_PERF_CNT_SEL, &sel);
|
||||
|
@ -3204,20 +3204,21 @@ static void a3xx_perfcounter_enable_vbif(struct kgsl_device *device,
|
|||
kgsl_regwrite(device, A3XX_VBIF_PERF_CNT_CLR, 0);
|
||||
|
||||
kgsl_regwrite(device, A3XX_VBIF_PERF_CNT_EN, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void a3xx_perfcounter_enable_vbif_pwr(struct kgsl_device *device,
|
||||
unsigned int countable)
|
||||
static int a3xx_perfcounter_enable_vbif_pwr(struct kgsl_device *device,
|
||||
unsigned int counter)
|
||||
{
|
||||
unsigned int in, out, bit;
|
||||
|
||||
if (countable > 2)
|
||||
return;
|
||||
if (counter > 2)
|
||||
return -EINVAL;
|
||||
|
||||
kgsl_regread(device, A3XX_VBIF_PERF_CNT_EN, &in);
|
||||
if (countable == 0)
|
||||
if (counter == 0)
|
||||
bit = VBIF_PERF_PWR_CNT_0;
|
||||
else if (countable == 1)
|
||||
else if (counter == 1)
|
||||
bit = VBIF_PERF_PWR_CNT_1;
|
||||
else
|
||||
bit = VBIF_PERF_PWR_CNT_2;
|
||||
|
@ -3228,6 +3229,7 @@ static void a3xx_perfcounter_enable_vbif_pwr(struct kgsl_device *device,
|
|||
kgsl_regwrite(device, A3XX_VBIF_PERF_CNT_CLR, 0);
|
||||
|
||||
kgsl_regwrite(device, A3XX_VBIF_PERF_CNT_EN, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3238,9 +3240,10 @@ static void a3xx_perfcounter_enable_vbif_pwr(struct kgsl_device *device,
|
|||
* @countable - Desired countable
|
||||
*
|
||||
* Physically set up a counter within a group with the desired countable
|
||||
* Return 0 on success else error code
|
||||
*/
|
||||
|
||||
static void a3xx_perfcounter_enable(struct adreno_device *adreno_dev,
|
||||
static int a3xx_perfcounter_enable(struct adreno_device *adreno_dev,
|
||||
unsigned int group, unsigned int counter, unsigned int countable)
|
||||
{
|
||||
struct kgsl_device *device = &adreno_dev->dev;
|
||||
|
@ -3249,18 +3252,20 @@ static void a3xx_perfcounter_enable(struct adreno_device *adreno_dev,
|
|||
|
||||
/* Special cases */
|
||||
if (group == KGSL_PERFCOUNTER_GROUP_PWR)
|
||||
return a3xx_perfcounter_enable_pwr(device, countable);
|
||||
return a3xx_perfcounter_enable_pwr(device, counter);
|
||||
else if (group == KGSL_PERFCOUNTER_GROUP_VBIF)
|
||||
return a3xx_perfcounter_enable_vbif(device, counter, countable);
|
||||
return a3xx_perfcounter_enable_vbif(device, counter,
|
||||
countable);
|
||||
else if (group == KGSL_PERFCOUNTER_GROUP_VBIF_PWR)
|
||||
return a3xx_perfcounter_enable_vbif_pwr(device, countable);
|
||||
return a3xx_perfcounter_enable_vbif_pwr(device, counter);
|
||||
|
||||
if (group >= adreno_dev->gpudev->perfcounters->group_count)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
if (counter >=
|
||||
adreno_dev->gpudev->perfcounters->groups[group].reg_count)
|
||||
return;
|
||||
if ((0 == adreno_dev->gpudev->perfcounters->groups[group].reg_count) ||
|
||||
(counter >=
|
||||
adreno_dev->gpudev->perfcounters->groups[group].reg_count))
|
||||
return -EINVAL;
|
||||
|
||||
reg = &(adreno_dev->gpudev->perfcounters->groups[group].regs[counter]);
|
||||
|
||||
|
@ -3268,12 +3273,15 @@ static void a3xx_perfcounter_enable(struct adreno_device *adreno_dev,
|
|||
kgsl_regwrite(device, reg->select, countable);
|
||||
|
||||
if (reg->load_bit < 32) {
|
||||
val = 1 << reg->load_bit;
|
||||
kgsl_regread(device, A3XX_RBBM_PERFCTR_LOAD_CMD0, &val);
|
||||
val |= (1 << reg->load_bit);
|
||||
kgsl_regwrite(device, A3XX_RBBM_PERFCTR_LOAD_CMD0, val);
|
||||
} else {
|
||||
val = 1 << (reg->load_bit - 32);
|
||||
kgsl_regread(device, A3XX_RBBM_PERFCTR_LOAD_CMD1, &val);
|
||||
val |= (1 << (reg->load_bit - 32));
|
||||
kgsl_regwrite(device, A3XX_RBBM_PERFCTR_LOAD_CMD1, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t a3xx_perfcounter_read_pwr(struct adreno_device *adreno_dev,
|
||||
|
@ -3384,8 +3392,9 @@ static uint64_t a3xx_perfcounter_read(struct adreno_device *adreno_dev,
|
|||
if (group >= adreno_dev->gpudev->perfcounters->group_count)
|
||||
return 0;
|
||||
|
||||
if (counter >=
|
||||
adreno_dev->gpudev->perfcounters->groups[group].reg_count)
|
||||
if ((0 == adreno_dev->gpudev->perfcounters->groups[group].reg_count) ||
|
||||
(counter >=
|
||||
adreno_dev->gpudev->perfcounters->groups[group].reg_count))
|
||||
return 0;
|
||||
|
||||
reg = &(adreno_dev->gpudev->perfcounters->groups[group].regs[counter]);
|
||||
|
@ -3838,8 +3847,30 @@ static struct adreno_perfcounters a3xx_perfcounters = {
|
|||
ARRAY_SIZE(a3xx_perfcounter_groups),
|
||||
};
|
||||
|
||||
static void a3xx_perfcounter_init(struct adreno_device *adreno_dev)
|
||||
/*
|
||||
* a3xx_perfcounter_close() - Return counters that were initialized in
|
||||
* a3xx_perfcounter_init
|
||||
* @adreno_dev: The device for which counters were initialized
|
||||
*/
|
||||
static void a3xx_perfcounter_close(struct adreno_device *adreno_dev)
|
||||
{
|
||||
adreno_perfcounter_put(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_FS_FULL_ALU_INSTRUCTIONS,
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
adreno_perfcounter_put(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_FS_CFLOW_INSTRUCTIONS,
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
adreno_perfcounter_put(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP0_ICL1_MISSES,
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
adreno_perfcounter_put(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_ALU_ACTIVE_CYCLES,
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
}
|
||||
|
||||
static int a3xx_perfcounter_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
int ret;
|
||||
/* SP[3] counter is broken on a330 so disable it if a330 device */
|
||||
if (adreno_is_a330(adreno_dev))
|
||||
a3xx_perfcounters_sp[3].countable = KGSL_PERFCOUNTER_BROKEN;
|
||||
|
@ -3854,26 +3885,45 @@ static void a3xx_perfcounter_init(struct adreno_device *adreno_dev)
|
|||
* we will use this to augment our hang detection
|
||||
*/
|
||||
if (adreno_dev->fast_hang_detect) {
|
||||
adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
ret = adreno_perfcounter_get(adreno_dev,
|
||||
KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_ALU_ACTIVE_CYCLES, &ft_detect_regs[6],
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
ft_detect_regs[7] = ft_detect_regs[6] + 1;
|
||||
adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
ret = adreno_perfcounter_get(adreno_dev,
|
||||
KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP0_ICL1_MISSES, &ft_detect_regs[8],
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
ft_detect_regs[9] = ft_detect_regs[8] + 1;
|
||||
adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
ret = adreno_perfcounter_get(adreno_dev,
|
||||
KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_FS_CFLOW_INSTRUCTIONS, &ft_detect_regs[10],
|
||||
PERFCOUNTER_FLAG_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
ft_detect_regs[11] = ft_detect_regs[10] + 1;
|
||||
}
|
||||
|
||||
adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_SP,
|
||||
SP_FS_FULL_ALU_INSTRUCTIONS, NULL, PERFCOUNTER_FLAG_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* Reserve and start countable 1 in the PWR perfcounter group */
|
||||
adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1,
|
||||
ret = adreno_perfcounter_get(adreno_dev, KGSL_PERFCOUNTER_GROUP_PWR, 1,
|
||||
NULL, PERFCOUNTER_FLAG_KERNEL);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
a3xx_perfcounter_close(adreno_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4341,6 +4391,7 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
|
|||
.ctxt_draw_workaround = NULL,
|
||||
.rb_init = a3xx_rb_init,
|
||||
.perfcounter_init = a3xx_perfcounter_init,
|
||||
.perfcounter_close = a3xx_perfcounter_close,
|
||||
.irq_control = a3xx_irq_control,
|
||||
.irq_handler = a3xx_irq_handler,
|
||||
.irq_pending = a3xx_irq_pending,
|
||||
|
|
Loading…
Reference in a new issue