codec_mm: add reserved & cma support for 4.9. [1/1]

PD#172483

Problem:
Add reserved & cma support for 4.9.

Solution:
1. add tvp padding, for test.
2. add no-cma-tvp,to force not used cma for tvp.
3. add nomap for reserved memroy detective.
4. add res & cma two mem region on same board.
5. add clear-map property for codec_mm_cma.

Verify:
Test this function with Android_O-MR1(GTVS) & ExoPlayer.

Change-Id: Ib20e0e9bc4725afb271de97543ce5ebf3bfcfb29
Signed-off-by: Zhi Zhou <zhi.zhou@amlogic.com>
This commit is contained in:
Zhi Zhou
2018-09-14 15:32:06 +08:00
committed by Dongjin Kim
parent af5a75d485
commit df0db9171f
8 changed files with 138 additions and 0 deletions

View File

@@ -121,6 +121,7 @@
size = <0x0 0x13400000>;
alignment = <0x0 0x400000>;
linux,contiguous-region;
clear-map;
};
/* codec shared reserved */
codec_mm_reserved:linux,codec_mm_reserved {

View File

@@ -683,6 +683,7 @@
compatible = "amlogic, codec, mm";
memory-region = <&codec_mm_cma &codec_mm_reserved>;
dev_name = "codec_mm";
/*no-cmatvp;*/
status = "okay";
};

View File

@@ -181,6 +181,10 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end,
static inline bool use_1G_block(unsigned long addr, unsigned long next,
unsigned long phys)
{
#ifdef CONFIG_AMLOGIC_CMA
/* we need create full 2nd page table */
return false;
#else
if (PAGE_SHIFT != 12)
return false;
@@ -188,6 +192,7 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
return false;
return true;
#endif
}
static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,

View File

@@ -943,10 +943,20 @@ int codec_mm_extpool_pool_alloc(
CODEC_MM_FLAGS_FOR_LOCAL_MGR |
CODEC_MM_FLAGS_CMA);
if (mem) {
if (for_tvp) {
cma_mmu_op(mem->mem_handle,
mem->page_count,
0);
}
ret = codec_mm_init_tvp_pool(
tvp_pool,
mem);
if (ret < 0) {
if (for_tvp) {
cma_mmu_op(mem->mem_handle,
mem->page_count,
1);
}
codec_mm_release(mem, TVP_POOL_NAME);
} else {
alloced_size += try_alloced_size;
@@ -994,6 +1004,9 @@ static int codec_mm_extpool_pool_release(struct extpool_mgt_s *tvp_pool)
slot_mem_size = gen_pool_size(gpool);
gen_pool_destroy(tvp_pool->gen_pool[i]);
if (tvp_pool->mm[i]) {
cma_mmu_op(tvp_pool->mm[i]->mem_handle,
tvp_pool->mm[i]->page_count,
1);
codec_mm_release(tvp_pool->mm[i],
TVP_POOL_NAME);
}

View File

@@ -268,6 +268,10 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
}
/* Architecture specific contiguous memory fixup. */
dma_contiguous_early_fixup(rmem->base, rmem->size);
#ifdef CONFIG_AMLOGIC_CMA
if (of_get_flat_dt_prop(node, "clear-map", NULL))
cma_init_clear(cma, 1);
#endif
if (of_get_flat_dt_prop(node, "linux,cma-default", NULL))
dma_contiguous_set_default(cma);

View File

@@ -28,4 +28,10 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
struct cma **res_cma);
extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align);
extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
#ifdef CONFIG_AMLOGIC_CMA
extern void cma_init_clear(struct cma *cma, bool clear);
extern int setup_cma_full_pagemap(struct cma *cma);
extern int cma_mmu_op(struct page *page, int count, bool set);
#endif
#endif

103
mm/cma.c
View File

@@ -37,6 +37,7 @@
#include <linux/io.h>
#include <trace/events/cma.h>
#ifdef CONFIG_AMLOGIC_CMA
#include <asm/pgtable.h>
#include <linux/amlogic/aml_cma.h>
#endif /* CONFIG_AMLOGIC_CMA */
@@ -46,6 +47,103 @@ struct cma cma_areas[MAX_CMA_AREAS];
unsigned cma_area_count;
static DEFINE_MUTEX(cma_mutex);
#ifdef CONFIG_AMLOGIC_CMA
void cma_init_clear(struct cma *cma, bool clear)
{
cma->clear_map = clear;
}
static int clear_cma_pagemap2(struct cma *cma)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
unsigned long addr, end;
struct mm_struct *mm;
addr = (unsigned long)pfn_to_kaddr(cma->base_pfn);
end = addr + cma->count * PAGE_SIZE;
mm = &init_mm;
pgd = pgd_offset(mm, addr);
for (; addr < end; addr += PMD_SIZE) {
if (pgd_none(*pgd) || pgd_bad(*pgd))
break;
pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
break;
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd))
break;
pmd_clear(pmd);
}
return 0;
}
int setup_cma_full_pagemap(struct cma *cma)
{
struct vm_area_struct vma = {};
unsigned long addr, size;
int ret;
clear_cma_pagemap2(cma);
addr = (unsigned long)pfn_to_kaddr(cma->base_pfn);
size = cma->count * PAGE_SIZE;
vma.vm_mm = &init_mm;
vma.vm_start = addr;
vma.vm_end = addr + size;
vma.vm_page_prot = PAGE_KERNEL;
ret = remap_pfn_range(&vma, addr, cma->base_pfn,
size, vma.vm_page_prot);
if (ret < 0)
pr_info("%s, remap pte failed:%d, cma:%lx\n",
__func__, ret, cma->base_pfn);
return 0;
}
int cma_mmu_op(struct page *page, int count, bool set)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long addr, end;
struct mm_struct *mm;
if (!page)
return -EINVAL;
addr = (unsigned long)page_address(page);
end = addr + count * PAGE_SIZE;
mm = &init_mm;
pgd = pgd_offset(mm, addr);
for (; addr < end; addr += PAGE_SIZE) {
if (pgd_none(*pgd) || pgd_bad(*pgd))
break;
pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
break;
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd))
break;
pte = pte_offset_map(pmd, addr);
if (set)
set_pte_at(mm, addr, pte, mk_pte(page, PAGE_KERNEL));
else
pte_clear(mm, addr, pte);
pte_unmap(pte);
page++;
}
return 0;
}
#endif
phys_addr_t cma_get_base(const struct cma *cma)
{
return PFN_PHYS(cma->base_pfn);
@@ -129,6 +227,11 @@ static int __init cma_activate_area(struct cma *cma)
mutex_init(&cma->lock);
#ifdef CONFIG_AMLOGIC_CMA
if (cma->clear_map)
setup_cma_full_pagemap(cma);
#endif
#ifdef CONFIG_CMA_DEBUGFS
INIT_HLIST_HEAD(&cma->mem_head);
spin_lock_init(&cma->mem_head_lock);

View File

@@ -11,6 +11,11 @@ struct cma {
struct hlist_head mem_head;
spinlock_t mem_head_lock;
#endif
#ifdef CONFIG_AMLOGIC_CMA /* clear kernel space mapping after driver it */
bool clear_map;
#endif
};
extern struct cma cma_areas[MAX_CMA_AREAS];