diff options
author | Rob Clark <robdclark@gmail.com> | 2016-02-22 14:26:21 +0300 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2016-03-03 19:55:32 +0300 |
commit | 6c77d1abe61797239533918d7a0336fc84f4aef1 (patch) | |
tree | 0745cdcd1ccf1d9bd85445ba135bf6034d4f63fb /drivers/gpu | |
parent | 4313c744d99314f84a7a98771a17c0c1adfb4de6 (diff) | |
download | linux-6c77d1abe61797239533918d7a0336fc84f4aef1.tar.xz |
drm/msm: add timestamp param
We need this for GL_TIMESTAMP queries.
Note: currently only supported on a4xx.. a3xx doesn't have this
always-on counter. I think we could emulate it with the one CP
counter that is available, but for now it is of limited usefulness
on a3xx (since we can't seem to do time-elapsed queries in any sane
way with the existing firmware on a3xx, and if you are trying to do
profiling on a tiler you want time-elapsed). We can add that later
if it becomes useful.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/adreno/adreno_gpu.h | 1 |
3 files changed, 28 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 3d07a5a1f338..b371f1c04a47 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -200,6 +200,11 @@ static int a4xx_hw_init(struct msm_gpu *gpu) /* Turn on performance counters: */ gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01); + /* use the first CP counter for timestamp queries.. userspace may set + * this as well but it selects the same counter/countable: + */ + gpu_write(gpu, REG_A4XX_CP_PERFCTR_CP_SEL_0, CP_ALWAYS_COUNT); + if (adreno_is_a430(adreno_gpu)) gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07); @@ -294,6 +299,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0); a4xx_me_init(gpu); + return 0; } @@ -585,6 +591,22 @@ static int a4xx_pm_suspend(struct msm_gpu *gpu) { return 0; } +static int a4xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) +{ + uint32_t hi, lo, tmp; + + tmp = gpu_read(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_HI); + do { + hi = tmp; + lo = gpu_read(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_LO); + tmp = gpu_read(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_HI); + } while (tmp != hi); + + *value = (((uint64_t)hi) << 32) | lo; + + return 0; +} + static const struct adreno_gpu_funcs funcs = { .base = { .get_param = adreno_get_param, @@ -602,6 +624,7 @@ static const struct adreno_gpu_funcs funcs = { .show = a4xx_show, #endif }, + .get_timestamp = a4xx_get_timestamp, }; struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 2859b1991259..4951172ede06 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -44,6 +44,10 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) case MSM_PARAM_MAX_FREQ: *value = adreno_gpu->base.fast_rate; return 0; + case MSM_PARAM_TIMESTAMP: + if (adreno_gpu->funcs->get_timestamp) + return adreno_gpu->funcs->get_timestamp(gpu, value); + return -EINVAL; default: DBG("%s: invalid param: %u", gpu->name, param); return -EINVAL; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index c26aea13df6d..1d07511f4d22 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -114,6 +114,7 @@ struct adreno_rev { struct adreno_gpu_funcs { struct msm_gpu_funcs base; + int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value); }; struct adreno_info { |