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

Commit 2e42f121 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Add the per context preemption buffer



This buffer is used by CP to save/restore the VPC data for
the outgoing/incoming context respectively. So allocate and
map it during context initialization and then specify the
gpu address of this buffer in the preemption packets.

Change-Id: I3bb73322848e2f19f1f8e511fa5c303e57898cc8
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 0cdc8993
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -851,6 +851,8 @@ struct adreno_gpudev {
				unsigned int *cmds);
	int (*preemption_init)(struct adreno_device *);
	void (*preemption_schedule)(struct adreno_device *);
	int (*preemption_context_init)(struct kgsl_context *);
	void (*preemption_context_destroy)(struct kgsl_context *);
	void (*enable_64bit)(struct adreno_device *);
	void (*clk_set_options)(struct adreno_device *,
				const char *, struct clk *, bool on);
+2 −0
Original line number Diff line number Diff line
@@ -2774,4 +2774,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.preemption_init = a6xx_preemption_init,
	.preemption_schedule = a6xx_preemption_schedule,
	.preemption_set_marker = a6xx_preemption_set_marker,
	.preemption_context_init = a6xx_preemption_context_init,
	.preemption_context_destroy = a6xx_preemption_context_destroy,
};
+6 −0
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ struct a6xx_cp_smmu_info {
#define A6XX_CP_CTXRECORD_SIZE_IN_BYTES     (2112 * 1024)
/* Size of the preemption counter block (in bytes) */
#define A6XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE   (16 * 4)
/* Size of the user context record block (in bytes) */
#define A6XX_CP_CTXRECORD_USER_RESTORE_SIZE (192 * 1024)
/* Size of the performance counter save/restore block (in bytes) */
#define A6XX_CP_PERFCOUNTER_SAVE_RESTORE_SIZE   (4 * 1024)

@@ -102,6 +104,10 @@ unsigned int a6xx_preemption_set_marker(unsigned int *cmds, int start);

void a6xx_preemption_callback(struct adreno_device *adreno_dev, int bit);

int a6xx_preemption_context_init(struct kgsl_context *context);

void a6xx_preemption_context_destroy(struct kgsl_context *context);

void a6xx_snapshot(struct adreno_device *adreno_dev,
		struct kgsl_snapshot *snapshot);

+53 −1
Original line number Diff line number Diff line
@@ -277,6 +277,18 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
		A6XX_CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR_HI,
		upper_32_bits(next->preemption_desc.gpuaddr));

	if (next->drawctxt_active) {
		struct kgsl_context *context = &next->drawctxt_active->base;
		uint64_t gpuaddr = context->user_ctxt_record->memdesc.gpuaddr;

		kgsl_regwrite(device,
			A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_LO,
			lower_32_bits(gpuaddr));
		kgsl_regwrite(device,
			A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_HI,
			upper_32_bits(gpuaddr));
	}

	adreno_dev->next_rb = next;

	/* Start the timer to detect a stuck preemption */
@@ -381,6 +393,9 @@ unsigned int a6xx_preemption_pre_ibsubmit(
{
	unsigned int *cmds_orig = cmds;

	if (context)
		*cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 15);
	else
		*cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 12);

	/* NULL SMMU_INFO buffer - we track in KMD */
@@ -393,6 +408,12 @@ unsigned int a6xx_preemption_pre_ibsubmit(
	*cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_PRIV_SECURE_SAVE_ADDR;
	cmds += cp_gpuaddr(adreno_dev, cmds, 0);

	if (context) {
		uint64_t gpuaddr = context->user_ctxt_record->memdesc.gpuaddr;

		*cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_NON_PRIV_SAVE_ADDR;
		cmds += cp_gpuaddr(adreno_dev, cmds, gpuaddr);
	}

	/*
	 * There is no need to specify this address when we are about to
@@ -600,3 +621,34 @@ int a6xx_preemption_init(struct adreno_device *adreno_dev)

	return ret;
}

void a6xx_preemption_context_destroy(struct kgsl_context *context)
{
	struct kgsl_device *device = context->device;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	if (!adreno_is_preemption_enabled(adreno_dev))
		return;

	gpumem_free_entry(context->user_ctxt_record);
}

int a6xx_preemption_context_init(struct kgsl_context *context)
{
	struct kgsl_device *device = context->device;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	if (!adreno_is_preemption_enabled(adreno_dev))
		return 0;

	context->user_ctxt_record = gpumem_alloc_entry(context->dev_priv,
			A6XX_CP_CTXRECORD_USER_RESTORE_SIZE, 0);
	if (IS_ERR(context->user_ctxt_record)) {
		int ret = PTR_ERR(context->user_ctxt_record);

		context->user_ctxt_record = NULL;
		return ret;
	}

	return 0;
}
+19 −0
Original line number Diff line number Diff line
@@ -341,6 +341,7 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv,
	struct adreno_context *drawctxt;
	struct kgsl_device *device = dev_priv->device;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int ret;
	unsigned int local;

@@ -421,6 +422,16 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv,
		return ERR_PTR(ret);
	}

	if (gpudev->preemption_context_init) {
		ret = gpudev->preemption_context_init(&drawctxt->base);
		if (ret != 0) {
			kgsl_context_detach(&drawctxt->base);
			kgsl_context_put(&drawctxt->base);
			kfree(drawctxt);
			return ERR_PTR(ret);
		}
	}

	kgsl_sharedmem_writel(device, &device->memstore,
			KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp),
			0);
@@ -545,10 +556,18 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
void adreno_drawctxt_destroy(struct kgsl_context *context)
{
	struct adreno_context *drawctxt;
	struct adreno_device *adreno_dev;
	struct adreno_gpudev *gpudev;

	if (context == NULL)
		return;

	adreno_dev = ADRENO_DEVICE(context->device);
	gpudev = ADRENO_GPU_DEVICE(adreno_dev);

	if (gpudev->preemption_context_destroy)
		gpudev->preemption_context_destroy(context);

	drawctxt = ADRENO_CONTEXT(context);
	debugfs_remove_recursive(drawctxt->debug_root);
	kfree(drawctxt);
Loading