提交 6c77d1ab 编写于 作者: R Rob Clark

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: NRob Clark <robdclark@gmail.com>
上级 4313c744
...@@ -200,6 +200,11 @@ static int a4xx_hw_init(struct msm_gpu *gpu) ...@@ -200,6 +200,11 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
/* Turn on performance counters: */ /* Turn on performance counters: */
gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01); 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)) if (adreno_is_a430(adreno_gpu))
gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07); gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07);
...@@ -294,6 +299,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu) ...@@ -294,6 +299,7 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0); gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0);
a4xx_me_init(gpu); a4xx_me_init(gpu);
return 0; return 0;
} }
...@@ -585,6 +591,22 @@ static int a4xx_pm_suspend(struct msm_gpu *gpu) { ...@@ -585,6 +591,22 @@ static int a4xx_pm_suspend(struct msm_gpu *gpu) {
return 0; 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 = { static const struct adreno_gpu_funcs funcs = {
.base = { .base = {
.get_param = adreno_get_param, .get_param = adreno_get_param,
...@@ -602,6 +624,7 @@ static const struct adreno_gpu_funcs funcs = { ...@@ -602,6 +624,7 @@ static const struct adreno_gpu_funcs funcs = {
.show = a4xx_show, .show = a4xx_show,
#endif #endif
}, },
.get_timestamp = a4xx_get_timestamp,
}; };
struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
......
...@@ -44,6 +44,10 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) ...@@ -44,6 +44,10 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
case MSM_PARAM_MAX_FREQ: case MSM_PARAM_MAX_FREQ:
*value = adreno_gpu->base.fast_rate; *value = adreno_gpu->base.fast_rate;
return 0; return 0;
case MSM_PARAM_TIMESTAMP:
if (adreno_gpu->funcs->get_timestamp)
return adreno_gpu->funcs->get_timestamp(gpu, value);
return -EINVAL;
default: default:
DBG("%s: invalid param: %u", gpu->name, param); DBG("%s: invalid param: %u", gpu->name, param);
return -EINVAL; return -EINVAL;
......
...@@ -114,6 +114,7 @@ struct adreno_rev { ...@@ -114,6 +114,7 @@ struct adreno_rev {
struct adreno_gpu_funcs { struct adreno_gpu_funcs {
struct msm_gpu_funcs base; struct msm_gpu_funcs base;
int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value);
}; };
struct adreno_info { struct adreno_info {
......
...@@ -51,6 +51,7 @@ struct drm_msm_timespec { ...@@ -51,6 +51,7 @@ struct drm_msm_timespec {
#define MSM_PARAM_GMEM_SIZE 0x02 #define MSM_PARAM_GMEM_SIZE 0x02
#define MSM_PARAM_CHIP_ID 0x03 #define MSM_PARAM_CHIP_ID 0x03
#define MSM_PARAM_MAX_FREQ 0x04 #define MSM_PARAM_MAX_FREQ 0x04
#define MSM_PARAM_TIMESTAMP 0x05
struct drm_msm_param { struct drm_msm_param {
__u32 pipe; /* in, MSM_PIPE_x */ __u32 pipe; /* in, MSM_PIPE_x */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册