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

Commit a8acbcb0 authored by Jordan Crouse's avatar Jordan Crouse Committed by Deepak Kumar
Browse files

msm: kgsl: Use a bitmap allocator for global addressing



To prepare to allow global buffers to allocate a semi-random GPU address
move from a sequential allocator to a bitmap based one.

Change-Id: Ic0dedbadba36c4c7b7839528103997724eac7d6d
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: default avatarDeepak Kumar <dkumar@codeaurora.org>
parent 472c9db2
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -90,15 +90,8 @@ static struct kmem_cache *addr_entry_cache;
 *
 * Here we define an array and a simple allocator to keep track of the currently
 * active global entries. Each entry is assigned a unique address inside of a
 * MMU implementation specific "global" region. The addresses are assigned
 * sequentially and never re-used to avoid having to go back and reprogram
 * existing pagetables. The entire list of active entries are mapped and
 * unmapped into every new pagetable as it is created and destroyed.
 *
 * Because there are relatively few entries and they are defined at boot time we
 * don't need to go over the top to define a dynamic allocation scheme. It will
 * be less wasteful to pick a static number with a little bit of growth
 * potential.
 * MMU implementation specific "global" region. We use a simple bitmap based
 * allocator for the region to allow for both fixed and dynamic addressing.
 */

#define GLOBAL_PT_ENTRIES 32
@@ -108,13 +101,17 @@ struct global_pt_entry {
	char name[32];
};

#define GLOBAL_MAP_PAGES (KGSL_IOMMU_GLOBAL_MEM_SIZE >> PAGE_SHIFT)

static struct global_pt_entry global_pt_entries[GLOBAL_PT_ENTRIES];
static DECLARE_BITMAP(global_map, GLOBAL_MAP_PAGES);

static int secure_global_size;
static int global_pt_count;
uint64_t global_pt_alloc;
static struct kgsl_memdesc gpu_qdss_desc;
static struct kgsl_memdesc gpu_qtimer_desc;
static unsigned int context_bank_number;

void kgsl_print_global_pt_entries(struct seq_file *s)
{
	int i;
@@ -209,6 +206,12 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,

	for (i = 0; i < global_pt_count; i++) {
		if (global_pt_entries[i].memdesc == memdesc) {
			u64 offset = memdesc->gpuaddr -
				KGSL_IOMMU_GLOBAL_MEM_BASE(mmu);

			bitmap_clear(global_map, offset >> PAGE_SHIFT,
				kgsl_memdesc_footprint(memdesc) >> PAGE_SHIFT);

			memdesc->gpuaddr = 0;
			memdesc->priv &= ~KGSL_MEMDESC_GLOBAL;
			global_pt_entries[i].memdesc = NULL;
@@ -220,19 +223,27 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,
static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
		struct kgsl_memdesc *memdesc, const char *name)
{
	int bit;
	u64 size = kgsl_memdesc_footprint(memdesc);

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

	/*Check that we can fit the global allocations */
	if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES) ||
		WARN_ON((global_pt_alloc + memdesc->size) >=
			KGSL_IOMMU_GLOBAL_MEM_SIZE))
	if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES))
		return;

	memdesc->gpuaddr = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + global_pt_alloc;
	bit = bitmap_find_next_zero_area(global_map, GLOBAL_MAP_PAGES,
		0, size >> PAGE_SHIFT, 0);

	if (WARN_ON(bit >= GLOBAL_MAP_PAGES))
		return;

	memdesc->gpuaddr =
		KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + (bit << PAGE_SHIFT);

	bitmap_set(global_map, bit, size >> PAGE_SHIFT);

	memdesc->priv |= KGSL_MEMDESC_GLOBAL;
	global_pt_alloc += kgsl_memdesc_footprint(memdesc);

	global_pt_entries[global_pt_count].memdesc = memdesc;
	strlcpy(global_pt_entries[global_pt_count].name, name,