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

Commit d08c1a0f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Map global pagetable entries after IOMMU attach"

parents 28b5b1c2 76247c57
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -979,6 +979,8 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
	if (status)
		goto done;

	kgsl_map_global_pt_entries(mmu->defaultpagetable);

	kgsl_iommu_enable_clk(mmu);

	/* Get the lsb value of pagetables set in the IOMMU ttbr0 register as
+31 −14
Original line number Diff line number Diff line
@@ -104,6 +104,16 @@ EXPORT_SYMBOL(kgsl_search_global_pt_entries);
static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable)
{
	int i;
	unsigned long flags;

	BUG_ON(pagetable->name == KGSL_MMU_GLOBAL_PT);

	spin_lock_irqsave(&kgsl_driver.ptlock, flags);
	if (pagetable->globals_mapped == false) {
		spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
		return;
	}
	spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);

	for (i = 0; i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) {
		struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i];
@@ -123,6 +133,10 @@ static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable)
		kgsl_mmu_unmap(pagetable,
				kgsl_global_pt_entries.entries[i]);
	}

	spin_lock_irqsave(&kgsl_driver.ptlock, flags);
	pagetable->globals_mapped = false;
	spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
}

/**
@@ -131,11 +145,18 @@ static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable)
 * @pagetable: Pointer to a kgsl_pagetable structure
 *
 * Map all the current global PT entries into the specified pagetable.
 * Returns error if an entry fails to map or 0 on success.
 */
static int kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable)
void kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable)
{
	int i, ret = 0;
	unsigned long flags;

	spin_lock_irqsave(&kgsl_driver.ptlock, flags);
	if (pagetable->globals_mapped == true) {
		spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
		return;
	}
	spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);

	for (i = 0; !ret && i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) {
		struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i];
@@ -153,16 +174,15 @@ static int kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable)
			continue;

		ret = kgsl_mmu_map(pagetable, entry);
		if (ret)
			break;

		/* If we cannot map the global entries, nothing will work. */
		BUG_ON(ret);
	}

	if (ret)
		kgsl_unmap_global_pt_entries(pagetable);

	return ret;
	spin_lock_irqsave(&kgsl_driver.ptlock, flags);
	pagetable->globals_mapped = true;
	spin_unlock_irqrestore(&kgsl_driver.ptlock, flags);
}
EXPORT_SYMBOL(kgsl_map_global_pt_entries);

/**
 * kgsl_remove_global_pt_entry() - Remove a memory descriptor from the global PT
@@ -614,11 +634,8 @@ kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu,
			goto err;
	}

	if (KGSL_MMU_SECURE_PT != name) {
		status = kgsl_map_global_pt_entries(pagetable);
		if (status)
			goto err;
	}
	if ((KGSL_MMU_SECURE_PT != name) && (KGSL_MMU_GLOBAL_PT != name))
		kgsl_map_global_pt_entries(pagetable);

	spin_lock_irqsave(&kgsl_driver.ptlock, flags);
	list_add(&pagetable->list, &kgsl_driver.pagetable_list);
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct kgsl_pagetable {
	struct kgsl_mmu *mmu;
	unsigned long *mem_bitmap;
	unsigned int bitmap_size;
	bool globals_mapped;
};

struct kgsl_mmu;
@@ -173,6 +174,7 @@ int kgsl_mmu_gpuaddr_in_range(struct kgsl_pagetable *pt, uint64_t gpuaddr);
int kgsl_add_global_pt_entry(struct kgsl_device *device,
	struct kgsl_memdesc *memdesc);
void kgsl_remove_global_pt_entry(struct kgsl_memdesc *memdesc);
void kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable);

struct kgsl_memdesc *kgsl_search_global_pt_entries(unsigned int gpuaddr,
		unsigned int size);