mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
video/rockchip: rga: adapt to kernel 5.10
1. Use dma_sync_single_for_device to flush cache. 2. Refer to RGA2 adaptation kernel 5.10. Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: Iebd7f092b8dd070661cde12fd8669d2bdf4001c3
This commit is contained in:
@@ -1,13 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RGA_API_H__
|
||||
#define __RGA_API_H__
|
||||
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
#include "rga_reg_info.h"
|
||||
#include "rga.h"
|
||||
|
||||
#define ENABLE 1
|
||||
#define DISABLE 0
|
||||
|
||||
#define DISABLE 0
|
||||
|
||||
struct rga_drvdata {
|
||||
struct miscdevice miscdev;
|
||||
struct device *dev;
|
||||
void *rga_base;
|
||||
int irq;
|
||||
|
||||
struct delayed_work power_off_work;
|
||||
void (*rga_irq_callback)(int rga_retval); //callback function used by aync call
|
||||
struct wake_lock wake_lock;
|
||||
|
||||
struct clk *pd_rga;
|
||||
struct clk *aclk_rga;
|
||||
struct clk *hclk_rga;
|
||||
|
||||
//#if defined(CONFIG_ION_ROCKCHIP)
|
||||
struct ion_client *ion_client;
|
||||
//#endif
|
||||
char *version;
|
||||
};
|
||||
|
||||
int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1);
|
||||
|
||||
|
||||
|
||||
@@ -97,27 +97,7 @@ unsigned char RGA_NONUSE;
|
||||
unsigned char RGA_INT_FLAG;
|
||||
#endif
|
||||
|
||||
struct rga_drvdata {
|
||||
struct miscdevice miscdev;
|
||||
struct device *dev;
|
||||
void *rga_base;
|
||||
int irq;
|
||||
|
||||
struct delayed_work power_off_work;
|
||||
void (*rga_irq_callback)(int rga_retval); //callback function used by aync call
|
||||
struct wake_lock wake_lock;
|
||||
|
||||
struct clk *pd_rga;
|
||||
struct clk *aclk_rga;
|
||||
struct clk *hclk_rga;
|
||||
|
||||
//#if defined(CONFIG_ION_ROCKCHIP)
|
||||
struct ion_client *ion_client;
|
||||
//#endif
|
||||
char *version;
|
||||
};
|
||||
|
||||
static struct rga_drvdata *drvdata;
|
||||
struct rga_drvdata *drvdata;
|
||||
rga_service_info rga_service;
|
||||
struct rga_mmu_buf_t rga_mmu_buf;
|
||||
|
||||
@@ -842,12 +822,7 @@ static void rga_try_set_reg(void)
|
||||
|
||||
rga_copy_reg(reg, 0);
|
||||
rga_reg_from_wait_to_run(reg);
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]);
|
||||
outer_flush_range(virt_to_phys(&rga_service.cmd_buff[0]),virt_to_phys(&rga_service.cmd_buff[32]));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]);
|
||||
#endif
|
||||
rga_dma_flush_range(&rga_service.cmd_buff[0], &rga_service.cmd_buff[32]);
|
||||
|
||||
rga_soft_reset();
|
||||
|
||||
@@ -2235,15 +2210,7 @@ void rga_slt(void)
|
||||
memset(src1_buf, 0x50, 400 * 200 * 4);
|
||||
memset(dst1_buf, 0x00, 400 * 200 * 4);
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(&src1_buf[0], &src1_buf[400 * 200]);
|
||||
outer_flush_range(virt_to_phys(&src1_buf[0]), virt_to_phys(&src1_buf[400 * 200]));
|
||||
dmac_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]);
|
||||
outer_flush_range(virt_to_phys(&dst1_buf[0]), virt_to_phys(&dst1_buf[400 * 200]));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]);
|
||||
__dma_flush_range(&dst1_buf[0], &dst1_buf[400 * 200]);
|
||||
#endif
|
||||
rga_dma_flush_range(&src1_buf[0], &src1_buf[400 * 200]);
|
||||
|
||||
DBG("\n********************************\n");
|
||||
DBG("************ RGA_TEST ************\n");
|
||||
|
||||
@@ -28,7 +28,12 @@ extern struct rga_mmu_buf_t rga_mmu_buf;
|
||||
extern int RGA_CHECK_MODE;
|
||||
#endif
|
||||
|
||||
#define KERNEL_SPACE_VALID 0xc0000000
|
||||
#define KERNEL_SPACE_VALID 0xc0000000
|
||||
|
||||
void rga_dma_flush_range(void *pstart, void *pend)
|
||||
{
|
||||
dma_sync_single_for_device(drvdata->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size)
|
||||
{
|
||||
@@ -328,16 +333,29 @@ static int rga_MapUserMemory(struct page **pages,
|
||||
Address = 0;
|
||||
|
||||
do {
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_lock(current->mm);
|
||||
#else
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
|
||||
result = get_user_pages(current, current->mm,
|
||||
Memory << PAGE_SHIFT, pageCount, 1, 0,
|
||||
pages, NULL);
|
||||
#else
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)
|
||||
result = get_user_pages_remote(current, current->mm,
|
||||
Memory << PAGE_SHIFT, pageCount, 1, pages, NULL, NULL);
|
||||
#else
|
||||
result = get_user_pages_remote(current->mm, Memory << PAGE_SHIFT,
|
||||
pageCount, 1, pages, NULL, NULL);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_unlock(current->mm);
|
||||
#else
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
#if 0
|
||||
if(result <= 0 || result < pageCount)
|
||||
@@ -365,10 +383,18 @@ static int rga_MapUserMemory(struct page **pages,
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
if (result>0) {
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_lock(current->mm);
|
||||
#else
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
for (i = 0; i < result; i++)
|
||||
put_page(pages[i]);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_unlock(current->mm);
|
||||
#else
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(i=0; i<pageCount; i++)
|
||||
@@ -382,7 +408,10 @@ static int rga_MapUserMemory(struct page **pages,
|
||||
pte_t * pte;
|
||||
spinlock_t * ptl;
|
||||
unsigned long pfn;
|
||||
pgd_t * pgd;
|
||||
pgd_t * pgd;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
p4d_t * p4d;
|
||||
#endif
|
||||
pud_t * pud;
|
||||
|
||||
pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT);
|
||||
@@ -393,7 +422,20 @@ static int rga_MapUserMemory(struct page **pages,
|
||||
break;
|
||||
}
|
||||
|
||||
pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
/* In the four-level page table, it will do nothing and return pgd. */
|
||||
p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT);
|
||||
if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d))) {
|
||||
pr_err("RGA2 failed to get p4d, result = %d, pageCount = %d\n",
|
||||
result, pageCount);
|
||||
status = RGA_OUT_OF_RESOURCES;
|
||||
break;
|
||||
}
|
||||
|
||||
pud = pud_offset(p4d, (Memory + i) << PAGE_SHIFT);
|
||||
#else
|
||||
pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT);
|
||||
#endif
|
||||
if (pud)
|
||||
{
|
||||
pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT);
|
||||
@@ -442,10 +484,18 @@ static int rga_MapUserMemory(struct page **pages,
|
||||
pageTable[i] = page_to_phys(pages[i]);
|
||||
}
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_lock(current->mm);
|
||||
#else
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
for (i = 0; i < result; i++)
|
||||
put_page(pages[i]);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
mmap_read_unlock(current->mm);
|
||||
#else
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -665,12 +715,7 @@ static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req)
|
||||
req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT);
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
outer_flush_range(virt_to_phys(MMU_Base), virt_to_phys(MMU_Base + AllSize + 1));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
|
||||
rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
|
||||
reg->MMU_len = AllSize + 16;
|
||||
@@ -792,12 +837,7 @@ static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *
|
||||
reg->MMU_base = MMU_Base;
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
|
||||
rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
|
||||
reg->MMU_len = AllSize + 16;
|
||||
@@ -878,12 +918,7 @@ static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req
|
||||
reg->MMU_base = MMU_Base;
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
|
||||
rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
|
||||
reg->MMU_len = AllSize + 16;
|
||||
@@ -1033,12 +1068,7 @@ static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req)
|
||||
reg->MMU_base = MMU_Base;
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize + 1));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1));
|
||||
|
||||
rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16);
|
||||
reg->MMU_len = AllSize + 16;
|
||||
@@ -1126,12 +1156,7 @@ static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rg
|
||||
reg->MMU_base = MMU_Base;
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
|
||||
|
||||
if (pages != NULL) {
|
||||
@@ -1230,12 +1255,7 @@ static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_
|
||||
reg->MMU_base = MMU_Base;
|
||||
|
||||
/* flush data to DDR */
|
||||
#ifdef CONFIG_ARM
|
||||
dmac_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
outer_flush_range(virt_to_phys(MMU_Base),virt_to_phys(MMU_Base + AllSize));
|
||||
#elif defined(CONFIG_ARM64)
|
||||
__dma_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
#endif
|
||||
rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize));
|
||||
|
||||
if (pages != NULL) {
|
||||
/* Free the page table */
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#ifndef __RGA_MMU_INFO_H__
|
||||
#define __RGA_MMU_INFO_H__
|
||||
|
||||
#include "rga.h"
|
||||
#include "rga.h"
|
||||
#include "RGA_API.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X)<(Y)?(X):(Y))
|
||||
@@ -11,8 +12,10 @@
|
||||
#ifndef MAX
|
||||
#define MAX(X, Y) ((X)>(Y)?(X):(Y))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
extern struct rga_drvdata *drvdata;
|
||||
|
||||
void rga_dma_flush_range(void *pstart, void *pend);
|
||||
int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user