media: CB1 Fix cts CRC flaky issue [1/1]

PD#SWPL-139469

Problem:
Dirty date in cacheline may pollute data in memory when
flush cacheline

Solution:
Use noncache mapping in afbc decompress lib

Verify:
T7C

Change-Id: I4f6ed2ad6473c0aaab80d175663434b38dfb2af5
Signed-off-by: zhentao.guo <zhentao.guo@amlogic.com>
This commit is contained in:
zhentao.guo
2023-09-23 14:41:59 +08:00
committed by Luan Yuan
parent ee6070a3e6
commit edd367ce14
3 changed files with 48 additions and 10 deletions
+42 -10
View File
@@ -718,17 +718,22 @@ static void *codec_mm_search_vaddr(unsigned long phy_addr)
return vaddr;
}
u8 *codec_mm_vmap(ulong addr, u32 size)
static u8 *__codec_mm_vmap(ulong addr, u32 size, bool is_cache)
{
u8 *vaddr = NULL;
struct page **pages = NULL;
u32 i, npages, offset = 0;
ulong phys, page_start;
pgprot_t pgprot = PAGE_KERNEL;
ulong vm_flags = VM_MAP;
if (!PageHighMem(phys_to_page(addr)))
if (!PageHighMem(phys_to_page(addr)) && is_cache)
return phys_to_virt(addr);
if (!is_cache) { /* remap for noncached. */
pgprot = pgprot_dmacoherent(PAGE_KERNEL);
vm_flags = VM_DMA_COHERENT;
}
offset = offset_in_page(addr);
page_start = addr - offset;
npages = DIV_ROUND_UP(size + offset, PAGE_SIZE);
@@ -742,7 +747,7 @@ u8 *codec_mm_vmap(ulong addr, u32 size)
pages[i] = pfn_to_page(phys >> PAGE_SHIFT);
}
vaddr = vmap(pages, npages, VM_MAP, pgprot);
vaddr = vmap(pages, npages, vm_flags, pgprot);
if (!vaddr) {
pr_err("the phy(%lx) vmaped fail, size: %d\n",
page_start, npages << PAGE_SHIFT);
@@ -753,15 +758,26 @@ u8 *codec_mm_vmap(ulong addr, u32 size)
kfree(pages);
if (debug_mode & 0x20) {
pr_info("[HIGH-MEM-MAP] %s, pa(%lx) to va(%lx), size: %d\n",
pr_info("[VMAP] %s, pa(%lx) to va(%lx), size: %d, cache:%d\n",
__func__, page_start, (ulong)vaddr,
npages << PAGE_SHIFT);
npages << PAGE_SHIFT, is_cache);
}
return vaddr + offset;
}
u8 *codec_mm_vmap(ulong addr, u32 size)
{
return __codec_mm_vmap(addr, size, true);
}
EXPORT_SYMBOL(codec_mm_vmap);
u8 *codec_mm_vmap_noncache(ulong addr, u32 size)
{
return __codec_mm_vmap(addr, size, false);
}
EXPORT_SYMBOL(codec_mm_vmap_noncache);
void codec_mm_memset(ulong phys, u32 val, u32 size)
{
void *ptr = NULL;
@@ -900,6 +916,10 @@ static int codec_mm_alloc_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
if (mem->mem_handle) {
mem->vbuffer = mem->mem_handle;
mem->phy_addr = virt_to_phys(mem->mem_handle);
dma_sync_single_for_device(mgt->dev,
mem->phy_addr,
PAGE_ALIGN(mem->buffer_size),
DMA_FROM_DEVICE);
break;
}
try_alloced_from_sys = 1;
@@ -917,9 +937,14 @@ static int codec_mm_alloc_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
PAGE_SHIFT, false);
mem->from_flags = AMPORTS_MEM_FLAGS_FROM_GET_FROM_CMA;
if (mem->mem_handle) {
mem->vbuffer = mem->mem_handle;
mem->phy_addr =
page_to_phys((struct page *)mem->mem_handle);
page_to_phys((struct page *)mem->mem_handle);
if (!mgt->tvp_enable) {
dma_sync_single_for_device(mgt->dev,
mem->phy_addr,
mem->page_count << PAGE_SHIFT,
DMA_FROM_DEVICE);
}
#ifdef CONFIG_ARM64
if (mem->flags & CODEC_MM_FLAGS_CMA_CLEAR) {
/*dma_clear_buffer((struct page *)*/
@@ -997,9 +1022,12 @@ static int codec_mm_alloc_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
page_to_phys((struct page *)
mem->mem_handle);
if (mem->flags & CODEC_MM_FLAGS_CPU)
mem->vbuffer =
codec_mm_map_phyaddr(mem);
if (!mgt->tvp_enable) {
dma_sync_single_for_device(mgt->dev,
mem->phy_addr,
mem->page_count << PAGE_SHIFT,
DMA_FROM_DEVICE);
}
#ifdef CONFIG_ARM64
if (mem->flags & CODEC_MM_FLAGS_CMA_CLEAR) {
/*dma_clear_buffer((struct page *)*/
@@ -1065,6 +1093,10 @@ static int codec_mm_alloc_in(struct codec_mm_mgt_s *mgt, struct codec_mm_s *mem)
mem->vbuffer = mem->mem_handle;
mem->phy_addr =
virt_to_phys((void *)mem->mem_handle);
dma_sync_single_for_device(mgt->dev,
mem->phy_addr,
PAGE_ALIGN(mem->buffer_size),
DMA_FROM_DEVICE);
break;
}
}
@@ -834,6 +834,11 @@ codec_mm_slot_alloc(struct codec_mm_scatter_mgt *smgt, int size, int flags)
slot->page_num = 1 << page_order;
slot->phy_addr =
virt_to_phys((unsigned long *)slot->page_header);
/* Invalidate range of cache lines. */
dma_sync_single_for_device(smgt->dev,
slot->phy_addr,
(slot->page_num * PAGE_SIZE),
DMA_FROM_DEVICE);
codec_mm_slot_init_bitmap(slot);
if (!slot->pagemap) {
free_pages(slot->page_header, page_order);
@@ -144,6 +144,7 @@ int codec_mm_free_for_dma(const char *owner, unsigned long phy_addr);
void *codec_mm_phys_to_virt(unsigned long phy_addr);
unsigned long codec_mm_virt_to_phys(void *vaddr);
u8 *codec_mm_vmap(ulong addr, u32 size);
u8 *codec_mm_vmap_noncache(ulong addr, u32 size);
void codec_mm_unmap_phyaddr(u8 *vaddr);
void codec_mm_dma_flush(void *vaddr, int size, enum dma_data_direction dir);