From 8a7ca4ded7e9cc04f3b91dda10521fbba39573dc Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Fri, 27 May 2016 12:40:43 -0600 Subject: [PATCH] msm: kgsl: Ignore EAGAIN when programming perfcounter When programming perfcounter via gpu commands, we may encounter -EAGAIN because of cancelling rb events either due to soft reset or when powering down the device. Ignore this error because we have already set up the perfcounter in software and it will be programmed in hardware by adreno_perfcounter_restore when gpu comes back up. CRs-Fixed: 1024199 Change-Id: I5dc3561d15fa50ac58646f96559cfd262020dda9 Signed-off-by: Harshdeep Dhatt --- drivers/gpu/msm/adreno.c | 5 ++-- drivers/gpu/msm/adreno_perfcounter.c | 34 +++++++++++++++++++++------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 6160aa567fbf..6bd4e119014e 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2109,8 +2109,6 @@ static int adreno_soft_reset(struct kgsl_device *device) adreno_support_64bit(adreno_dev)) gpudev->enable_64bit(adreno_dev); - /* Restore physical performance counter values after soft reset */ - adreno_perfcounter_restore(adreno_dev); /* Reinitialize the GPU */ gpudev->start(adreno_dev); @@ -2137,6 +2135,9 @@ static int adreno_soft_reset(struct kgsl_device *device) set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv); } + /* Restore physical performance counter values after soft reset */ + adreno_perfcounter_restore(adreno_dev); + return ret; } diff --git a/drivers/gpu/msm/adreno_perfcounter.c b/drivers/gpu/msm/adreno_perfcounter.c index 42f8119ad8b4..f5f99c3ebb4a 100644 --- a/drivers/gpu/msm/adreno_perfcounter.c +++ b/drivers/gpu/msm/adreno_perfcounter.c @@ -522,13 +522,19 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev, if (empty == -1) return -EBUSY; - /* enable the new counter */ - ret = adreno_perfcounter_enable(adreno_dev, groupid, empty, countable); - if (ret) - return ret; /* initialize the new counter */ group->regs[empty].countable = countable; + /* enable the new counter */ + ret = adreno_perfcounter_enable(adreno_dev, groupid, empty, countable); + if (ret) { + /* Put back the perfcounter */ + if (!(group->flags & ADRENO_PERFCOUNTER_GROUP_FIXED)) + group->regs[empty].countable = + KGSL_PERFCOUNTER_NOT_USED; + return ret; + } + /* set initial kernel and user count */ if (flags & PERFCOUNTER_FLAG_KERNEL) { group->regs[empty].kernelcount = 1; @@ -720,10 +726,22 @@ static int _perfcounter_enable_default(struct adreno_device *adreno_dev, /* wait for the above commands submitted to complete */ ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp, ADRENO_IDLE_TIMEOUT); - if (ret) - KGSL_DRV_ERR(device, - "Perfcounter %u/%u/%u start via commands failed %d\n", - group, counter, countable, ret); + if (ret) { + /* + * If we were woken up because of cancelling rb events + * either due to soft reset or adreno_stop, ignore the + * error and return 0 here. The perfcounter is already + * set up in software and it will be programmed in + * hardware when we wake up or come up after soft reset, + * by adreno_perfcounter_restore. + */ + if (ret == -EAGAIN) + ret = 0; + else + KGSL_DRV_ERR(device, + "Perfcounter %u/%u/%u start via commands failed %d\n", + group, counter, countable, ret); + } } else { /* Select the desired perfcounter */ kgsl_regwrite(device, reg->select, countable);