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: Jordan Crouse <jcrouse@codeaurora.org> Signed-off-by: Harshitha Sai Neelati <hsaine@codeaurora.org>
This commit is contained in:
parent
fbc6b845ce
commit
19f118bcf5
1 changed files with 28 additions and 15 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -84,15 +84,8 @@ static struct kmem_cache *addr_entry_cache;
|
||||||
*
|
*
|
||||||
* Here we define an array and a simple allocator to keep track of the currently
|
* 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
|
* active global entries. Each entry is assigned a unique address inside of a
|
||||||
* MMU implementation specific "global" region. The addresses are assigned
|
* MMU implementation specific "global" region. We use a simple bitmap based
|
||||||
* sequentially and never re-used to avoid having to go back and reprogram
|
* allocator for the region to allow for both fixed and dynamic addressing.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLOBAL_PT_ENTRIES 32
|
#define GLOBAL_PT_ENTRIES 32
|
||||||
|
@ -102,10 +95,12 @@ struct global_pt_entry {
|
||||||
char name[32];
|
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 struct global_pt_entry global_pt_entries[GLOBAL_PT_ENTRIES];
|
||||||
static struct kgsl_memdesc *kgsl_global_secure_pt_entry;
|
static struct kgsl_memdesc *kgsl_global_secure_pt_entry;
|
||||||
|
static DECLARE_BITMAP(global_map, GLOBAL_MAP_PAGES);
|
||||||
static int global_pt_count;
|
static int global_pt_count;
|
||||||
uint64_t global_pt_alloc;
|
|
||||||
static struct kgsl_memdesc gpu_qdss_desc;
|
static struct kgsl_memdesc gpu_qdss_desc;
|
||||||
static struct kgsl_memdesc gpu_qtimer_desc;
|
static struct kgsl_memdesc gpu_qtimer_desc;
|
||||||
|
|
||||||
|
@ -186,6 +181,12 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,
|
||||||
|
|
||||||
for (i = 0; i < global_pt_count; i++) {
|
for (i = 0; i < global_pt_count; i++) {
|
||||||
if (global_pt_entries[i].memdesc == memdesc) {
|
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->gpuaddr = 0;
|
||||||
memdesc->priv &= ~KGSL_MEMDESC_GLOBAL;
|
memdesc->priv &= ~KGSL_MEMDESC_GLOBAL;
|
||||||
global_pt_entries[i].memdesc = NULL;
|
global_pt_entries[i].memdesc = NULL;
|
||||||
|
@ -197,15 +198,27 @@ static void kgsl_iommu_remove_global(struct kgsl_mmu *mmu,
|
||||||
static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
|
static void kgsl_iommu_add_global(struct kgsl_mmu *mmu,
|
||||||
struct kgsl_memdesc *memdesc, const char *name)
|
struct kgsl_memdesc *memdesc, const char *name)
|
||||||
{
|
{
|
||||||
|
int bit;
|
||||||
|
u64 size = kgsl_memdesc_footprint(memdesc);
|
||||||
|
|
||||||
if (memdesc->gpuaddr != 0)
|
if (memdesc->gpuaddr != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BUG_ON(global_pt_count >= GLOBAL_PT_ENTRIES);
|
if (WARN_ON(global_pt_count >= GLOBAL_PT_ENTRIES))
|
||||||
BUG_ON((global_pt_alloc + memdesc->size) >= KGSL_IOMMU_GLOBAL_MEM_SIZE);
|
return;
|
||||||
|
|
||||||
|
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->gpuaddr = KGSL_IOMMU_GLOBAL_MEM_BASE(mmu) + global_pt_alloc;
|
|
||||||
memdesc->priv |= KGSL_MEMDESC_GLOBAL;
|
memdesc->priv |= KGSL_MEMDESC_GLOBAL;
|
||||||
global_pt_alloc += memdesc->size;
|
|
||||||
|
|
||||||
global_pt_entries[global_pt_count].memdesc = memdesc;
|
global_pt_entries[global_pt_count].memdesc = memdesc;
|
||||||
strlcpy(global_pt_entries[global_pt_count].name, name,
|
strlcpy(global_pt_entries[global_pt_count].name, name,
|
||||||
|
|
Loading…
Add table
Reference in a new issue