Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 156b58aa authored by Harsh Vardhan Dwivedi's avatar Harsh Vardhan Dwivedi
Browse files

msm: kgsl: Modify readtimestamp to return read status



Modify readtimestamp() to return the read status instead of
timestamp value. An additional parameter, a pointer to
timestamp is passed in and the timestamp is instead
returned at that pointer address. This will catch instances
where an invalid type timestamp read request is
issued or otherwise to catch any error that might
occur.

Change-Id: Ib709466877d3ad6adf3bd826979ddb4ef8696bd4
Signed-off-by: default avatarHarsh Vardhan Dwivedi <hdwivedi@codeaurora.org>
parent f80b0e48
Loading
Loading
Loading
Loading
+34 −7
Original line number Diff line number Diff line
@@ -2892,33 +2892,60 @@ static int adreno_waittimestamp(struct kgsl_device *device,
	return ret;
}

static unsigned int adreno_readtimestamp(struct kgsl_device *device,
		struct kgsl_context *context, enum kgsl_timestamp_type type)
/**
 * adreno_readtimestamp(): Return the value of given type of timestamp
 * @device: GPU device whose timestamp values are being queried
 * @context: The context for which timestamp is to be read
 * @type: The type of timestamp (one of 3) to be read
 * @timestamp: Pointer to where the read timestamp is to be written to
 *
 * CONSUMED and RETIRED type timestamps are sorted by id and are constantly
 * updated by the GPU through shared memstore memory. QUEUED type timestamps
 * are read directly from context struct.

 * The function returns 0 on success and timestamp value at the *timestamp
 * address and returns -EINVAL on any read error/invalid type and timestamp = 0.
 */
static int adreno_readtimestamp(struct kgsl_device *device,
					struct kgsl_context *context,
					enum kgsl_timestamp_type type,
					unsigned int *timestamp)
{
	unsigned int timestamp = 0;
	int status = 0;
	unsigned int id = context ? context->id : KGSL_MEMSTORE_GLOBAL;

	/*
	 * If user passed in a NULL pointer for timestamp, return without
	 * doing anything.
	 */
	if (!timestamp)
		return status;

	switch (type) {
	case KGSL_TIMESTAMP_QUEUED: {
		struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

		timestamp = adreno_context_timestamp(context,
		*timestamp = adreno_context_timestamp(context,
				&adreno_dev->ringbuffer);
		break;
	}
	case KGSL_TIMESTAMP_CONSUMED:
		kgsl_sharedmem_readl(&device->memstore, &timestamp,
		kgsl_sharedmem_readl(&device->memstore, timestamp,
			KGSL_MEMSTORE_OFFSET(id, soptimestamp));
		break;
	case KGSL_TIMESTAMP_RETIRED:
		kgsl_sharedmem_readl(&device->memstore, &timestamp,
		kgsl_sharedmem_readl(&device->memstore, timestamp,
			KGSL_MEMSTORE_OFFSET(id, eoptimestamp));
		break;
	default:
		status = -EINVAL;
		*timestamp = 0;
		break;
	}

	rmb();

	return timestamp;
	return status;
}

static long adreno_ioctl(struct kgsl_device_private *dev_priv,
+8 −8
Original line number Diff line number Diff line
@@ -60,8 +60,8 @@ static void fault_detect_read(struct kgsl_device *device)
{
	int i;

	fault_detect_ts = kgsl_readtimestamp(device, NULL,
		KGSL_TIMESTAMP_RETIRED);
	kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED,
		&fault_detect_ts);

	for (i = 0; i < FT_DETECT_REGS_COUNT; i++) {
		if (ft_detect_regs[i] == 0)
@@ -80,7 +80,7 @@ static inline bool _isidle(struct kgsl_device *device)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int ts;

	ts = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
	kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED, &ts);

	if (adreno_isidle(device) == true &&
		(ts >= adreno_dev->ringbuffer.global_ts))
@@ -117,7 +117,7 @@ static int fault_detect_read_compare(struct kgsl_device *device)
		fault_detect_regs[i] = val;
	}

	ts = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
	kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED, &ts);
	if (ts != fault_detect_ts)
		ret = 1;

@@ -1276,8 +1276,8 @@ static void adreno_dispatcher_work(struct work_struct *work)
		 * pointers and continue processing the queue
		 */

		retired = kgsl_readtimestamp(device, cmdbatch->context,
				KGSL_TIMESTAMP_RETIRED);
		kgsl_readtimestamp(device, cmdbatch->context,
			KGSL_TIMESTAMP_RETIRED, &retired);

		if ((timestamp_cmp(cmdbatch->timestamp, retired) <= 0)) {

@@ -1335,8 +1335,8 @@ static void adreno_dispatcher_work(struct work_struct *work)
		fault_handled = 1;

		/* Get the last consumed timestamp */
		consumed = kgsl_readtimestamp(device, cmdbatch->context,
			KGSL_TIMESTAMP_CONSUMED);
		kgsl_readtimestamp(device, cmdbatch->context,
			KGSL_TIMESTAMP_CONSUMED, &consumed);

		/*
		 * Break here if fault detection is disabled for the context or
+1 −1
Original line number Diff line number Diff line
@@ -338,7 +338,7 @@ static bool results_available(struct kgsl_device *device,
	if (shared_buf_empty(profile))
		return false;

	global_eop = kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED);
	kgsl_readtimestamp(device, NULL, KGSL_TIMESTAMP_RETIRED, &global_eop);
	do {
		cnt = *(shared_ptr + off + 1);
		if (cnt == 0)
+23 −19
Original line number Diff line number Diff line
@@ -600,8 +600,8 @@ int kgsl_check_timestamp(struct kgsl_device *device,
{
	unsigned int ts_processed;

	ts_processed = kgsl_readtimestamp(device, context,
					  KGSL_TIMESTAMP_RETIRED);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED,
		&ts_processed);

	return (timestamp_cmp(ts_processed, timestamp) >= 0);
}
@@ -1383,19 +1383,20 @@ static long _device_waittimestamp(struct kgsl_device_private *dev_priv,
	int result = 0;
	struct kgsl_device *device = dev_priv->device;
	unsigned int context_id = context ? context->id : KGSL_MEMSTORE_GLOBAL;
	unsigned int temp_cur_ts = 0;

	trace_kgsl_waittimestamp_entry(device, context_id,
				       kgsl_readtimestamp(device, context,
							KGSL_TIMESTAMP_RETIRED),
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED,
			   &temp_cur_ts);

	trace_kgsl_waittimestamp_entry(device, context_id, temp_cur_ts,
		timestamp, timeout);

	result = device->ftbl->waittimestamp(dev_priv->device,
	context, timestamp, timeout);

	trace_kgsl_waittimestamp_exit(device,
				      kgsl_readtimestamp(device, context,
							KGSL_TIMESTAMP_RETIRED),
				      result);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED,
		&temp_cur_ts);
	trace_kgsl_waittimestamp_exit(device, temp_cur_ts, result);

	return result;
}
@@ -1740,8 +1741,9 @@ static int kgsl_cmdbatch_add_sync_timestamp(struct kgsl_device *device,
	 */

	if (context == cmdbatch->context) {
		unsigned int queued = kgsl_readtimestamp(device, context,
			KGSL_TIMESTAMP_QUEUED);
		unsigned int queued;
		kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_QUEUED,
			&queued);

		if (timestamp_cmp(sync->timestamp, queued) > 0) {
			KGSL_DRV_ERR(device,
@@ -2146,13 +2148,14 @@ static long _cmdstream_readtimestamp(struct kgsl_device_private *dev_priv,
		struct kgsl_context *context, unsigned int type,
		unsigned int *timestamp)
{
	*timestamp = kgsl_readtimestamp(dev_priv->device, context, type);
	int ret;
	ret = kgsl_readtimestamp(dev_priv->device, context, type, timestamp);

	trace_kgsl_readtimestamp(dev_priv->device,
			context ? context->id : KGSL_MEMSTORE_GLOBAL,
			type, *timestamp);

	return 0;
	return ret;
}

long kgsl_ioctl_cmdstream_readtimestamp(struct kgsl_device_private
@@ -2199,8 +2202,9 @@ static long _cmdstream_freememontimestamp(struct kgsl_device_private *dev_priv,
{
	int result = 0;
	struct kgsl_mem_entry *entry = NULL;
	struct kgsl_device *device = dev_priv->device;
	unsigned int context_id = context ? context->id : KGSL_MEMSTORE_GLOBAL;
	unsigned int temp_cur_ts = 0;
	struct kgsl_device *device = dev_priv->device;

	entry = kgsl_sharedmem_find(dev_priv->process_priv, gpuaddr);

@@ -2216,10 +2220,10 @@ static long _cmdstream_freememontimestamp(struct kgsl_device_private *dev_priv,
		return -EBUSY;
	}

	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED,
		&temp_cur_ts);
	trace_kgsl_mem_timestamp_queue(device, entry, context_id,
				       kgsl_readtimestamp(device, context,
						  KGSL_TIMESTAMP_RETIRED),
				       timestamp);
		temp_cur_ts, timestamp);
	result = kgsl_add_event(dev_priv->device, context_id, timestamp,
				kgsl_freemem_event_cb, entry, dev_priv);
	kgsl_mem_entry_put(entry);
+7 −5
Original line number Diff line number Diff line
@@ -108,8 +108,9 @@ struct kgsl_functable {
	int (*waittimestamp) (struct kgsl_device *device,
		struct kgsl_context *context, unsigned int timestamp,
		unsigned int msecs);
	unsigned int (*readtimestamp) (struct kgsl_device *device,
		struct kgsl_context *context, enum kgsl_timestamp_type type);
	int (*readtimestamp) (struct kgsl_device *device,
		struct kgsl_context *context, enum kgsl_timestamp_type type,
		unsigned int *timestamp);
	int (*issueibcmds) (struct kgsl_device_private *dev_priv,
		struct kgsl_context *context, struct kgsl_cmdbatch *cmdbatch,
		uint32_t *timestamps);
@@ -483,11 +484,12 @@ static inline unsigned int kgsl_gpuid(struct kgsl_device *device,
	return device->ftbl->gpuid(device, chipid);
}

static inline unsigned int kgsl_readtimestamp(struct kgsl_device *device,
static inline int kgsl_readtimestamp(struct kgsl_device *device,
					      struct kgsl_context *context,
					      enum kgsl_timestamp_type type)
					      enum kgsl_timestamp_type type,
					      unsigned int *timestamp)
{
	return device->ftbl->readtimestamp(device, context, type);
	return device->ftbl->readtimestamp(device, context, type, timestamp);
}

static inline int kgsl_create_device_sysfs_files(struct device *root,
Loading