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

Commit af9b1413 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: don't map private entries into all pagetables"

parents 23b567df e4b0a74a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ struct kgsl_memdesc_ops {
#define KGSL_MEMDESC_SECURE BIT(5)
/* Indicates gpuaddr is assigned via bimap */
#define KGSL_MEMDESC_BITMAP_ALLOC BIT(6)
/* The memdesc is private for use during pagetable switch only */
#define KGSL_MEMDESC_PRIVATE BIT(7)

/* shared memory allocation */
struct kgsl_memdesc {
+17 −3
Original line number Diff line number Diff line
@@ -999,6 +999,7 @@ static int kgsl_iommu_init_sync_lock(struct kgsl_mmu *mmu)
	}

	/* Add the entry to the global PT list */
	iommu->sync_lock_desc.priv |= KGSL_MEMDESC_PRIVATE;
	status = kgsl_add_global_pt_entry(mmu->device, &iommu->sync_lock_desc);
	if (status) {
		kgsl_sg_free(iommu->sync_lock_desc.sg,
@@ -1189,6 +1190,7 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu)
			ret = -EINVAL;
			goto err;
		}
		/* this mapping is only for use during pagetable switch */
		iommu_unit->reg_map.hostptr = ioremap(data.physstart,
					data.physend - data.physstart + 1);
		if (!iommu_unit->reg_map.hostptr) {
@@ -1206,9 +1208,22 @@ static int kgsl_set_register_map(struct kgsl_mmu *mmu)
		if (ret)
			goto err;

		/* Add the register map to the global PT list */
		kgsl_add_global_pt_entry(mmu->device, &iommu_unit->reg_map);
		if (msm_soc_version_supports_iommu_v0()) {
			/*
			* Add the register map to the global PT list so that it
			* gets a GPU virtual address. This is needed for v0
			* only, on later hardware the registers are in the
			* RBBM adress space.
			*/
			iommu_unit->reg_map.priv |= KGSL_MEMDESC_PRIVATE;
			kgsl_add_global_pt_entry(mmu->device,
					&iommu_unit->reg_map);

		}

		/* For v0, iommu_halt_enable is read from devtree
		 * elsewhere, but force it on for v1 and later hardware.
		 */
		if (!msm_soc_version_supports_iommu_v0())
			iommu_unit->iommu_halt_enable = 1;

@@ -1865,7 +1880,6 @@ static int kgsl_iommu_close(struct kgsl_mmu *mmu)
		if (reg_map->hostptr)
			iounmap(reg_map->hostptr);
		kgsl_free(reg_map->sg);
		reg_map->priv &= ~KGSL_MEMDESC_GLOBAL;
	}
	/* clear IOMMU GPU CPU sync structures */

+40 −12
Original line number Diff line number Diff line
@@ -107,7 +107,20 @@ static void kgsl_unmap_global_pt_entries(struct kgsl_pagetable *pagetable)
	int i;

	for (i = 0; i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) {
		if (kgsl_global_pt_entries.entries[i])
		struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i];
		/* entry was removed */
		if (entry == NULL)
			continue;

		/*
		 * Private entries are only in the private pagetable,
		 * but they are in the global list so that they have a unique
		 * address.
		 */
		if ((entry->priv & KGSL_MEMDESC_PRIVATE) &&
			(pagetable->name != KGSL_MMU_PRIV_PT))
			continue;

		kgsl_mmu_unmap(pagetable,
				kgsl_global_pt_entries.entries[i]);
	}
@@ -126,12 +139,24 @@ static int kgsl_map_global_pt_entries(struct kgsl_pagetable *pagetable)
	int i, ret = 0;

	for (i = 0; !ret && i < KGSL_MAX_GLOBAL_PT_ENTRIES; i++) {
		if (kgsl_global_pt_entries.entries[i]) {
			ret = kgsl_mmu_map(pagetable,
				kgsl_global_pt_entries.entries[i]);
		struct kgsl_memdesc *entry = kgsl_global_pt_entries.entries[i];
		/* entry was removed */
		if (entry == NULL)
			continue;

		/*
		 * Private entries are only in the private pagetable,
		 * but they are in the global list so that they have a unique
		 * address.
		 */
		if ((entry->priv & KGSL_MEMDESC_PRIVATE) &&
			(pagetable->name != KGSL_MMU_PRIV_PT))
			continue;

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

	}

	if (ret)
@@ -152,11 +177,14 @@ void kgsl_remove_global_pt_entry(struct kgsl_memdesc *memdesc)
{
	int i, j;

	if (!(memdesc->priv & KGSL_MEMDESC_GLOBAL))
	if (memdesc->gpuaddr == 0)
		return;

	for (i = 0; i < kgsl_global_pt_entries.count; i++) {
		if (kgsl_global_pt_entries.entries[i] == memdesc) {
			memdesc->gpuaddr = 0;
			memdesc->priv &= ~(KGSL_MEMDESC_GLOBAL |
						KGSL_MEMDESC_PRIVATE);
			for (j = i; j < kgsl_global_pt_entries.count; j++)
				kgsl_global_pt_entries.entries[j] =
				kgsl_global_pt_entries.entries[j + 1];
@@ -183,7 +211,8 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device,
	unsigned int gaddr = KGSL_MMU_GLOBAL_MEM_BASE;
	unsigned int size = ALIGN(memdesc->size, PAGE_SIZE);

	if (memdesc->priv & KGSL_MEMDESC_GLOBAL)
	/* do we already have a mapping? */
	if (memdesc->gpuaddr != 0)
		return 0;

	if (kgsl_global_pt_entries.count == KGSL_MAX_GLOBAL_PT_ENTRIES)
@@ -209,13 +238,12 @@ int kgsl_add_global_pt_entry(struct kgsl_device *device,
				KGSL_GLOBAL_PT_SIZE))
		return -ENOMEM;

	memdesc->priv |= KGSL_MEMDESC_GLOBAL;

	if (kgsl_mmu_type == KGSL_MMU_TYPE_NONE)
		memdesc->gpuaddr = memdesc->physaddr;
	else
		memdesc->gpuaddr = gaddr;

	memdesc->priv |= KGSL_MEMDESC_GLOBAL;
	/*
	 * Move the entries from index till the last entry 1 slot right leaving
	 * the slot at index empty for the newcomer