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

Commit bc9e7635 authored by Shubhraprakash Das's avatar Shubhraprakash Das
Browse files

msm: kgsl: Fix TTBR0 in stream programming from GPU



The TTBR0 register can be 64 bit when phys_addr_t is 32 bit. Only
32 bits of TTBR0 register were programmed when phys_addr_t was set
to 32 bit. Use CONFIG_IOMMU_LPAE option to decide if TTBR0 is
32 bit or 64 bit.

Change-Id: I48970f6321c4ee2d5fdb955ca71159fddc83b32c
Signed-off-by: default avatarShubhraprakash Das <sadas@codeaurora.org>
parent 34d3db4c
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -874,7 +874,7 @@ static unsigned int _adreno_iommu_setstate_v1(struct kgsl_device *device,
					int num_iommu_units, uint32_t flags)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	phys_addr_t ttbr0_val;
	uint64_t ttbr0_val;
	unsigned int reg_pt_val;
	unsigned int *cmds = cmds_orig;
	int i;
@@ -938,9 +938,14 @@ static unsigned int _adreno_iommu_setstate_v1(struct kgsl_device *device,
					KGSL_IOMMU_IMPLDEF_MICRO_MMU_CTRL_IDLE,
					0xF);
			}
			/* set ttbr0 */
			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
				reg_pt_val = ttbr0_val & 0xFFFFFFFF;
			/*
			 * set ttbr0, only need to set the higer bits if the
			 * address bits lie in the higher bits
			 */
			if (KGSL_IOMMU_CTX_TTBR0_ADDR_MASK &
				0xFFFFFFFF00000000ULL) {
				reg_pt_val = (unsigned int)ttbr0_val &
						0xFFFFFFFF;
				*cmds++ = cp_type0_packet(ttbr0, 1);
				*cmds++ = reg_pt_val;
				reg_pt_val = (unsigned int)
@@ -1005,7 +1010,7 @@ static unsigned int _adreno_iommu_setstate_v2(struct kgsl_device *device,
					int num_iommu_units, uint32_t flags)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	phys_addr_t ttbr0_val;
	uint64_t ttbr0_val;
	unsigned int reg_pt_val;
	unsigned int *cmds = cmds_orig;
	int i;
@@ -1047,8 +1052,10 @@ static unsigned int _adreno_iommu_setstate_v2(struct kgsl_device *device,
					1, 0xFFFFFFFF, 0xF);

			/* set ttbr0 */
			if (sizeof(phys_addr_t) > sizeof(unsigned int)) {
				reg_pt_val = ttbr0_val & 0xFFFFFFFF;
			if (KGSL_IOMMU_CTX_TTBR0_ADDR_MASK &
				0xFFFFFFFF00000000ULL) {
				reg_pt_val = (unsigned int)ttbr0_val &
						0xFFFFFFFF;
				*cmds++ = cp_type3_packet(CP_REG_WR_NO_CTXT, 2);
				*cmds++ = ttbr0;
				*cmds++ = reg_pt_val;
+2 −2
Original line number Diff line number Diff line
@@ -1214,7 +1214,7 @@ static phys_addr_t kgsl_iommu_get_pt_base_addr(struct kgsl_mmu *mmu,
 * @ctx_id - The context bank whose lsb valus is to be returned
 * Return - returns the ttbr0 value programmed by iommu driver
 */
static phys_addr_t kgsl_iommu_get_default_ttbr0(struct kgsl_mmu *mmu,
static uint64_t kgsl_iommu_get_default_ttbr0(struct kgsl_mmu *mmu,
				unsigned int unit_id,
				enum kgsl_iommu_context_id ctx_id)
{
@@ -1904,7 +1904,7 @@ static int kgsl_iommu_default_setstate(struct kgsl_mmu *mmu,
	int ret = 0;
	phys_addr_t pt_base = kgsl_iommu_get_pt_base_addr(mmu,
						mmu->hwpagetable);
	phys_addr_t pt_val;
	uint64_t pt_val;

	ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
	if (ret) {
+1 −1
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ struct kgsl_iommu_register_list {
struct kgsl_iommu_device {
	struct device *dev;
	bool attached;
	phys_addr_t default_ttbr0;
	uint64_t default_ttbr0;
	enum kgsl_iommu_context_id ctx_id;
	bool clk_enabled;
	struct kgsl_device *kgsldev;
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ struct kgsl_mmu_ops {
		(struct kgsl_mmu *mmu, int ctx_id);
	void (*mmu_disable_clk)
		(struct kgsl_mmu *mmu, int ctx_id);
	phys_addr_t (*mmu_get_default_ttbr0)(struct kgsl_mmu *mmu,
	uint64_t (*mmu_get_default_ttbr0)(struct kgsl_mmu *mmu,
				unsigned int unit_id,
				enum kgsl_iommu_context_id ctx_id);
	unsigned int (*mmu_get_reg_gpuaddr)(struct kgsl_mmu *mmu,