Commit 6c77d1ab authored by Rob Clark's avatar Rob Clark
Browse files

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: default avatarRob Clark <robdclark@gmail.com>
parent 4313c744
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ struct drm_msm_timespec {
#define MSM_PARAM_GMEM_SIZE  0x02
#define MSM_PARAM_CHIP_ID    0x03
#define MSM_PARAM_MAX_FREQ   0x04
#define MSM_PARAM_TIMESTAMP  0x05

struct drm_msm_param {
	__u32 pipe;           /* in, MSM_PIPE_x */