mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user