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

Commit ef5440e7 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Remove nonsense around the a5xx and a6xx SMMU table update



All a5xx and a6xx targets use the CP_SMMU_TABLE_UPDATE opcode to switch the
pagetable which handles all the needed locking but we've seen fit to add a
bunch more around it, including keeping a dummy NOP IB used for
synchronization on a3xx targets.

Stop the madness and remove all the extraneous locking and other baloney
and just do a straight up SMMU_TABLE_UPDATE without fanfare.  And now
that the setstate is only valid for a3xx, only create it for a3xx thereby
removing another global buffer from the mix.

Change-Id: Ic0dedbad7694cad6d40fcee66b7864a454df1653
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 07350074
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -605,7 +605,6 @@ enum adreno_regs {
	ADRENO_REG_CP_RB_RPTR_ADDR_HI,
	ADRENO_REG_CP_RB_RPTR_ADDR_HI,
	ADRENO_REG_CP_RB_RPTR,
	ADRENO_REG_CP_RB_RPTR,
	ADRENO_REG_CP_RB_WPTR,
	ADRENO_REG_CP_RB_WPTR,
	ADRENO_REG_CP_CNTL,
	ADRENO_REG_CP_ME_CNTL,
	ADRENO_REG_CP_ME_CNTL,
	ADRENO_REG_CP_RB_CNTL,
	ADRENO_REG_CP_RB_CNTL,
	ADRENO_REG_CP_IB1_BASE,
	ADRENO_REG_CP_IB1_BASE,
+0 −1
Original line number Original line Diff line number Diff line
@@ -1198,7 +1198,6 @@ static unsigned int a3xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_BASE_HI, ADRENO_REG_SKIP),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_BASE_HI, ADRENO_REG_SKIP),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A3XX_CP_RB_RPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A3XX_CP_RB_RPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A3XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A3XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A3XX_CP_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A3XX_CP_ME_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A3XX_CP_ME_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A3XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A3XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A3XX_CP_IB1_BASE),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A3XX_CP_IB1_BASE),
+0 −1
Original line number Original line Diff line number Diff line
@@ -2393,7 +2393,6 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
			A5XX_CP_RB_RPTR_ADDR_HI),
			A5XX_CP_RB_RPTR_ADDR_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A5XX_CP_RB_RPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_RPTR, A5XX_CP_RB_RPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A5XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A5XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A5XX_CP_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A5XX_CP_ME_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A5XX_CP_ME_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A5XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A5XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A5XX_CP_IB1_BASE),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A5XX_CP_IB1_BASE),
+0 −1
Original line number Original line Diff line number Diff line
@@ -2264,7 +2264,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A6XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_WPTR, A6XX_CP_RB_WPTR),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A6XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_RB_CNTL, A6XX_CP_RB_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A6XX_CP_SQE_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_ME_CNTL, A6XX_CP_SQE_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_CNTL, A6XX_CP_MISC_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_HW_FAULT, A6XX_CP_HW_FAULT),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_HW_FAULT, A6XX_CP_HW_FAULT),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A6XX_CP_IB1_BASE),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE, A6XX_CP_IB1_BASE),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE_HI, A6XX_CP_IB1_BASE_HI),
	ADRENO_REG_DEFINE(ADRENO_REG_CP_IB1_BASE_HI, A6XX_CP_IB1_BASE_HI),
+42 −100
Original line number Original line Diff line number Diff line
@@ -116,66 +116,36 @@ static unsigned int a3xx_tlbiall(struct adreno_device *adreno_dev,
	return cmds - start;
	return cmds - start;
}
}


/* offset at which a nop command is placed in setstate */
#define KGSL_IOMMU_SETSTATE_NOP_OFFSET	1024


/**
static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device,
 * _adreno_iommu_add_idle_cmds - Add pm4 packets for GPU idle
					unsigned int *cmds_orig,
 * @adreno_dev - Pointer to device structure
					u64 ttbr0, u32 contextidr)
 * @cmds - Pointer to memory where idle commands need to be added
 */
static inline int _adreno_iommu_add_idle_cmds(struct adreno_device *adreno_dev,
							unsigned int *cmds)
{
{
	unsigned int *start = cmds;
	struct kgsl_iommu *iommu = KGSL_IOMMU_PRIV(device);

	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	cmds += cp_wait_for_idle(adreno_dev, cmds);
	unsigned int *cmds = cmds_orig;

	if (adreno_is_a3xx(adreno_dev))
		cmds += cp_wait_for_me(adreno_dev, cmds);

	return cmds - start;
}


/**
	/*
 * adreno_iommu_set_apriv() - Generate commands to set/reset the APRIV
	 * Adding an indirect buffer ensures that the prefetch stalls until
 * @adreno_dev: Device on which the commands will execute
	 * the commands in indirect buffer have completed. We need to stall
 * @cmds: The memory pointer where commands are generated
	 * prefetch with a nop indirect buffer when updating pagetables
 * @set: If set then APRIV is set else reset
	 * because it provides stabler synchronization.
 *
 * Returns the number of commands generated
	 */
	 */
static unsigned int adreno_iommu_set_apriv(struct adreno_device *adreno_dev,
				unsigned int *cmds, int set)
{
	unsigned int *cmds_orig = cmds;

	/* adreno 3xx doesn't have the CP_CNTL.APRIV field */
	if (adreno_is_a3xx(adreno_dev))
		return 0;

	/* Targets with apriv control do not need to explicitly set the bit */
	if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV))
		return 0;

	cmds += cp_wait_for_idle(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);
	*cmds++ = cp_register(adreno_dev, adreno_getreg(adreno_dev,
				ADRENO_REG_CP_CNTL), 1);
	if (set)
		*cmds++ = 1;
	else
		*cmds++ = 0;


	return cmds - cmds_orig;
	if (!IS_ERR_OR_NULL(iommu->setstate)) {
		*cmds++ = cp_mem_packet(adreno_dev,
			CP_INDIRECT_BUFFER_PFE, 2, 1);
		cmds += cp_gpuaddr(adreno_dev, cmds, iommu->setstate->gpuaddr +
			KGSL_IOMMU_SETSTATE_NOP_OFFSET);
		*cmds++ = 2;
	}
	}


static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device,
	cmds += cp_wait_for_idle(adreno_dev, cmds);
					unsigned int *cmds_orig,
					u64 ttbr0, u32 contextidr)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int *cmds = cmds_orig;


	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);


	cmds += a3xx_vbif_lock(adreno_dev, cmds);
	cmds += a3xx_vbif_lock(adreno_dev, cmds);


@@ -192,8 +162,11 @@ static unsigned int _adreno_iommu_set_pt_v2_a3xx(struct kgsl_device *device,


	/* wait for me to finish the TLBI */
	/* wait for me to finish the TLBI */
	cmds += cp_wait_for_me(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);
	cmds += cp_wait_for_idle(adreno_dev, cmds);


	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
	/* Invalidate the state */
	*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
	*cmds++ = 0x7ffff;


	return cmds - cmds_orig;
	return cmds - cmds_orig;
}
}
@@ -206,9 +179,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device,
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int *cmds = cmds_orig;
	unsigned int *cmds = cmds_orig;


	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);

	/* CP switches the pagetable and flushes the Caches */
	/* CP switches the pagetable and flushes the Caches */
	*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 3);
	*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 3);
	*cmds++ = lower_32_bits(ttbr0);
	*cmds++ = lower_32_bits(ttbr0);
@@ -222,11 +192,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a5xx(struct kgsl_device *device,
	*cmds++ = upper_32_bits(ttbr0);
	*cmds++ = upper_32_bits(ttbr0);
	*cmds++ = contextidr;
	*cmds++ = contextidr;


	/* release all commands with wait_for_me */
	cmds += cp_wait_for_me(adreno_dev, cmds);

	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);

	return cmds - cmds_orig;
	return cmds - cmds_orig;
}
}


@@ -239,9 +204,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int *cmds = cmds_orig;
	unsigned int *cmds = cmds_orig;


	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);
	cmds += cp_wait_for_me(adreno_dev, cmds);

	/* CP switches the pagetable and flushes the Caches */
	/* CP switches the pagetable and flushes the Caches */
	*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4);
	*cmds++ = cp_packet(adreno_dev, CP_SMMU_TABLE_UPDATE, 4);
	*cmds++ = lower_32_bits(ttbr0);
	*cmds++ = lower_32_bits(ttbr0);
@@ -256,11 +218,6 @@ static unsigned int _adreno_iommu_set_pt_v2_a6xx(struct kgsl_device *device,
	*cmds++ = upper_32_bits(ttbr0);
	*cmds++ = upper_32_bits(ttbr0);
	*cmds++ = contextidr;
	*cmds++ = contextidr;


	/* release all commands with wait_for_me */
	cmds += cp_wait_for_me(adreno_dev, cmds);

	cmds += _adreno_iommu_add_idle_cmds(adreno_dev, cmds);

	return cmds - cmds_orig;
	return cmds - cmds_orig;
}
}


@@ -281,42 +238,22 @@ unsigned int adreno_iommu_set_pt_generate_cmds(
	struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
	struct kgsl_iommu_context *ctx = &iommu->ctx[KGSL_IOMMU_CONTEXT_USER];
	u64 ttbr0;
	u64 ttbr0;
	u32 contextidr;
	u32 contextidr;
	unsigned int *cmds_orig = cmds;


	ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt);
	ttbr0 = kgsl_mmu_pagetable_get_ttbr0(pt);
	contextidr = kgsl_mmu_pagetable_get_contextidr(pt);
	contextidr = kgsl_mmu_pagetable_get_contextidr(pt);


	cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 1);
	/*
	 * Adding an indirect buffer ensures that the prefetch stalls until
	 * the commands in indirect buffer have completed. We need to stall
	 * prefetch with a nop indirect buffer when updating pagetables
	 * because it provides stabler synchronization.
	 */
	cmds += cp_wait_for_me(adreno_dev, cmds);
	*cmds++ = cp_mem_packet(adreno_dev, CP_INDIRECT_BUFFER_PFE, 2, 1);
	cmds += cp_gpuaddr(adreno_dev, cmds,
		iommu->setstate->gpuaddr + KGSL_IOMMU_SETSTATE_NOP_OFFSET);
	*cmds++ = 2;
	cmds += cp_wait_for_idle(adreno_dev, cmds);

	if (adreno_is_a6xx(adreno_dev))
	if (adreno_is_a6xx(adreno_dev))
		cmds += _adreno_iommu_set_pt_v2_a6xx(device, cmds,
		return _adreno_iommu_set_pt_v2_a6xx(device, cmds,
					ttbr0, contextidr, rb,
					ttbr0, contextidr, rb,
					ctx->cb_num);
					ctx->cb_num);
	else if (adreno_is_a5xx(adreno_dev))
	else if (adreno_is_a5xx(adreno_dev))
		cmds += _adreno_iommu_set_pt_v2_a5xx(device, cmds,
		return _adreno_iommu_set_pt_v2_a5xx(device, cmds,
					ttbr0, contextidr, rb);
					ttbr0, contextidr, rb);
	else if (adreno_is_a3xx(adreno_dev))
	else if (adreno_is_a3xx(adreno_dev))
		cmds += _adreno_iommu_set_pt_v2_a3xx(device, cmds,
		return _adreno_iommu_set_pt_v2_a3xx(device, cmds,
					ttbr0, contextidr);
					ttbr0, contextidr);


	/* invalidate all base pointers */
	return 0;
	cmds += cp_invalidate_state(adreno_dev, cmds);

	cmds += adreno_iommu_set_apriv(adreno_dev, cmds, 0);

	return cmds - cmds_orig;
}
}


/**
/**
@@ -440,17 +377,22 @@ void adreno_iommu_init(struct adreno_device *adreno_dev)
	if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE)
	if (kgsl_mmu_get_mmutype(device) == KGSL_MMU_TYPE_NONE)
		return;
		return;


	if (!adreno_is_a3xx(adreno_dev))
		return;

	/*
	/*
	 * A nop is required in an indirect buffer when switching
	 * 3xx requres a nop in an indirect buffer when switching
	 * pagetables in-stream
	 * pagetables in-stream
	 */
	 */
	if (IS_ERR_OR_NULL(iommu->setstate)) {
		iommu->setstate = kgsl_allocate_global(device, PAGE_SIZE,
			KGSL_MEMFLAGS_GPUREADONLY, 0, "setstate");


		kgsl_sharedmem_writel(device, iommu->setstate,
		kgsl_sharedmem_writel(device, iommu->setstate,
			KGSL_IOMMU_SETSTATE_NOP_OFFSET,
			KGSL_IOMMU_SETSTATE_NOP_OFFSET,
				cp_packet(adreno_dev, CP_NOP, 1));
			cp_type3_packet(CP_NOP, 1));
	}


	/* Enable guard page MMU feature for A3xx and A4xx targets only */
	if (adreno_is_a3xx(adreno_dev))
	device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE;
	device->mmu.features |= KGSL_MMU_NEED_GUARD_PAGE;
}
}


Loading