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

Commit 6d9eff91 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Set correct context restore address during preemption



On A6XX, when triggering preemption, we need to tell CP from where
to restore the incoming context's saved data. Currently, the logic
to figure out the incoming context is incorrect. Fix it by wrapping
the IBs with commands to write the context's restore address to
scratch memory location. The address is then read from the scratch
memory location at the time of triggering preemption.

Change-Id: Ie83bd1adc0f24faa122748b972fad28e0d05b0e6
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 6bf4cf1b
Loading
Loading
Loading
Loading
+38 −14
Original line number Diff line number Diff line
@@ -204,7 +204,7 @@ void a6xx_preemption_trigger(struct adreno_device *adreno_dev)
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);
	struct adreno_ringbuffer *next;
	uint64_t ttbr0;
	uint64_t ttbr0, gpuaddr;
	unsigned int contextidr;
	unsigned long flags;
	uint32_t preempt_level, usesgmem, skipsaverestore;
@@ -282,17 +282,13 @@ 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_sharedmem_readq(&device->scratch, &gpuaddr,
		SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(next->id));

		kgsl_regwrite(device,
			A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_LO,
	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,
	kgsl_regwrite(device, A6XX_CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR_HI,
		upper_32_bits(gpuaddr));
	}

	adreno_dev->next_rb = next;

@@ -397,11 +393,14 @@ unsigned int a6xx_preemption_pre_ibsubmit(
		unsigned int *cmds, struct kgsl_context *context)
{
	unsigned int *cmds_orig = cmds;
	uint64_t gpuaddr = 0;

	if (context)
	if (context) {
		gpuaddr = context->user_ctxt_record->memdesc.gpuaddr;
		*cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 15);
	else
	} else {
		*cmds++ = cp_type7_packet(CP_SET_PSEUDO_REGISTER, 12);
	}

	/* NULL SMMU_INFO buffer - we track in KMD */
	*cmds++ = SET_PSEUDO_REGISTER_SAVE_REGISTER_SMMU_INFO;
@@ -414,7 +413,6 @@ unsigned int a6xx_preemption_pre_ibsubmit(
	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);
@@ -431,6 +429,20 @@ unsigned int a6xx_preemption_pre_ibsubmit(
	cmds += cp_gpuaddr(adreno_dev, cmds,
			rb->perfcounter_save_restore_desc.gpuaddr);

	if (context) {
		struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
		struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
		struct adreno_ringbuffer *rb = drawctxt->rb;
		uint64_t dest =
			SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(device,
			rb->id);

		*cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
		cmds += cp_gpuaddr(adreno_dev, cmds, dest);
		*cmds++ = lower_32_bits(gpuaddr);
		*cmds++ = upper_32_bits(gpuaddr);
	}

	return (unsigned int) (cmds - cmds_orig);
}

@@ -438,6 +450,18 @@ unsigned int a6xx_preemption_post_ibsubmit(struct adreno_device *adreno_dev,
	unsigned int *cmds)
{
	unsigned int *cmds_orig = cmds;
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;

	if (rb) {
		struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
		uint64_t dest = SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(device,
			rb->id);

		*cmds++ = cp_mem_packet(adreno_dev, CP_MEM_WRITE, 2, 2);
		cmds += cp_gpuaddr(adreno_dev, cmds, dest);
		*cmds++ = 0;
		*cmds++ = 0;
	}

	*cmds++ = cp_type7_packet(CP_CONTEXT_SWITCH_YIELD, 4);
	cmds += cp_gpuaddr(adreno_dev, cmds, 0x0);
+2 −2
Original line number Diff line number Diff line
@@ -494,11 +494,11 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,

	if (gpudev->preemption_pre_ibsubmit &&
			adreno_is_preemption_execution_enabled(adreno_dev))
		total_sizedwords += 22;
		total_sizedwords += 27;

	if (gpudev->preemption_post_ibsubmit &&
			adreno_is_preemption_execution_enabled(adreno_dev))
		total_sizedwords += 5;
		total_sizedwords += 10;

	/*
	 * a5xx uses 64 bit memory address. pm4 commands that involve read/write
+8 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@
 * Used Data:
 * Offset: Length(bytes): What
 * 0x0: 4 * KGSL_PRIORITY_MAX_RB_LEVELS: RB0 RPTR
 * 0x10: 8 * KGSL_PRIORITY_MAX_RB_LEVELS: RB0 CTXT RESTORE ADDR
 */

/* Shadow global helpers */
@@ -82,6 +83,13 @@
#define SCRATCH_RPTR_GPU_ADDR(dev, id) \
	((dev)->scratch.gpuaddr + SCRATCH_RPTR_OFFSET(id))

#define SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(id) \
	(SCRATCH_RPTR_OFFSET(KGSL_PRIORITY_MAX_RB_LEVELS) + \
	((id) * sizeof(uint64_t)))
#define SCRATCH_PREEMPTION_CTXT_RESTORE_GPU_ADDR(dev, id) \
	((dev)->scratch.gpuaddr + \
	SCRATCH_PREEMPTION_CTXT_RESTORE_ADDR_OFFSET(id))

/* Timestamp window used to detect rollovers (half of integer range) */
#define KGSL_TIMESTAMP_WINDOW 0x80000000