mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
video: rockchip: rga3: Support using handle
It will be used by finding the memory corresponding to the handle in rga_mm. Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I6bd09a3641671c69aa903010c0aa4e518cf9b5af
This commit is contained in:
@@ -461,7 +461,9 @@ struct rga_req {
|
||||
uint8_t priority;
|
||||
int32_t out_fence_fd;
|
||||
|
||||
uint8_t reservr[128];
|
||||
uint8_t handle_flag;
|
||||
|
||||
uint8_t reservr[127];
|
||||
};
|
||||
|
||||
struct rga2_req {
|
||||
|
||||
@@ -249,6 +249,12 @@ struct rga_job {
|
||||
/* used by rga2 */
|
||||
struct rga_dma_buffer_t *rga_dma_buffer_els;
|
||||
|
||||
struct rga_internal_buffer *src_buffer;
|
||||
struct rga_internal_buffer *src1_buffer;
|
||||
struct rga_internal_buffer *dst_buffer;
|
||||
/* used by rga2 */
|
||||
struct rga_internal_buffer *els_buffer;
|
||||
|
||||
struct dma_buf *dma_buf_src0;
|
||||
struct dma_buf *dma_buf_src1;
|
||||
struct dma_buf *dma_buf_dst;
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
#define RGA_JOB_DONE (1 << 0)
|
||||
#define RGA_JOB_ASYNC (1 << 1)
|
||||
#define RGA_JOB_SYNC (1 << 2)
|
||||
enum job_flags {
|
||||
RGA_JOB_DONE = 1 << 0,
|
||||
RGA_JOB_ASYNC = 1 << 1,
|
||||
RGA_JOB_SYNC = 1 << 2,
|
||||
RGA_JOB_USE_HANDLE = 1 << 3,
|
||||
};
|
||||
|
||||
void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret);
|
||||
int rga_job_commit(struct rga_req *rga_command_base, int flags);
|
||||
|
||||
@@ -34,9 +34,14 @@ struct rga_mm {
|
||||
};
|
||||
|
||||
struct rga_internal_buffer *rga_mm_lookup_handle(struct rga_mm *mm_session, uint32_t handle);
|
||||
dma_addr_t rga_mm_lookup_iova(struct rga_internal_buffer *buffer, int core);
|
||||
struct sg_table *rga_mm_lookup_sgt(struct rga_internal_buffer *buffer, int core);
|
||||
|
||||
void rga_mm_dump_info(struct rga_mm *session);
|
||||
|
||||
int rga_mm_get_handle_info(struct rga_job *job);
|
||||
void rga_mm_put_handle_info(struct rga_job *job);
|
||||
|
||||
uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer);
|
||||
int rga_mm_release_buffer(uint32_t handle);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "rga2_mmu_info.h"
|
||||
#include "rga_dma_buf.h"
|
||||
#include "rga_mm.h"
|
||||
#include "rga_job.h"
|
||||
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
extern int RGA_DEBUG_CHECK_MODE;
|
||||
@@ -511,6 +513,7 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_mmu_other_t *reg,
|
||||
int status;
|
||||
uint32_t uv_size, v_size;
|
||||
struct page **pages = NULL;
|
||||
struct sg_table *sgt;
|
||||
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
@@ -590,24 +593,52 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_mmu_other_t *reg,
|
||||
mutex_unlock(&rga_drvdata->lock);
|
||||
|
||||
if (Src0MemSize) {
|
||||
if (job->rga_dma_buffer_src0) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_src0->sgt,
|
||||
&MMU_Base[0], Src0MemSize);
|
||||
if (job->src_buffer) {
|
||||
switch (job->src_buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
sgt = rga_mm_lookup_sgt(job->src_buffer, scheduler->core);
|
||||
if (sgt == NULL) {
|
||||
pr_err("rga2 cannot get sgt from handle!\n");
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
ret = rga2_MapION(sgt, &MMU_Base[0], Src0MemSize);
|
||||
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
Src0Start, Src0PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler,
|
||||
job->src_buffer->current_mm);
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src0_base = MMU_Base;
|
||||
reg->MMU_src0_count = Src0PageCount;
|
||||
|
||||
break;
|
||||
default:
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
Src0Start, Src0PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler, job->mm);
|
||||
if (job->rga_dma_buffer_src0) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_src0->sgt,
|
||||
&MMU_Base[0], Src0MemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
Src0Start, Src0PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler, job->mm);
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
/* TODO: */
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->src.vir_w,
|
||||
req->src.vir_h,
|
||||
req->src.format, 1);
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
/* TODO: */
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->src.vir_w,
|
||||
req->src.vir_h,
|
||||
req->src.format, 1);
|
||||
#endif
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src0_base = MMU_Base;
|
||||
reg->MMU_src0_count = Src0PageCount;
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src0_base = MMU_Base;
|
||||
reg->MMU_src0_count = Src0PageCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -630,18 +661,48 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_mmu_other_t *reg,
|
||||
}
|
||||
|
||||
if (Src1MemSize) {
|
||||
if (job->rga_dma_buffer_src1) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_src1->sgt,
|
||||
MMU_Base + Src0MemSize, Src1MemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
MMU_Base + Src0MemSize,
|
||||
Src1Start, Src1PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler, job->mm);
|
||||
if (job->src1_buffer) {
|
||||
switch (job->src1_buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
sgt = rga_mm_lookup_sgt(job->src1_buffer, scheduler->core);
|
||||
if (sgt == NULL) {
|
||||
pr_err("rga2 cannot get sgt from handle!\n");
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
ret = rga2_MapION(sgt, MMU_Base + Src0MemSize, Src1MemSize);
|
||||
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src1_base = MMU_Base + Src0MemSize;
|
||||
reg->MMU_src1_count = Src1PageCount;
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
MMU_Base + Src0MemSize,
|
||||
Src1Start, Src1PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler,
|
||||
job->src1_buffer->current_mm);
|
||||
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src1_base = MMU_Base + Src0MemSize;
|
||||
reg->MMU_src1_count = Src1PageCount;
|
||||
|
||||
break;
|
||||
default:
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (job->rga_dma_buffer_src1) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_src1->sgt,
|
||||
MMU_Base + Src0MemSize, Src1MemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
MMU_Base + Src0MemSize,
|
||||
Src1Start, Src1PageCount,
|
||||
0, MMU_MAP_CLEAN, scheduler, job->mm);
|
||||
|
||||
/* Save pagetable to unmap. */
|
||||
reg->MMU_src1_base = MMU_Base + Src0MemSize;
|
||||
reg->MMU_src1_count = Src1PageCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -656,48 +717,88 @@ static int rga2_mmu_info_BitBlt_mode(struct rga2_mmu_other_t *reg,
|
||||
}
|
||||
|
||||
if (DstMemSize) {
|
||||
if (job->rga_dma_buffer_dst) {
|
||||
ret =
|
||||
rga2_MapION(job->rga_dma_buffer_dst->sgt,
|
||||
MMU_Base + Src0MemSize + Src1MemSize,
|
||||
DstMemSize);
|
||||
} else if (req->alpha_mode_0 != 0 && req->bitblt_mode == 0) {
|
||||
/*
|
||||
* The blend mode of src + dst => dst
|
||||
* requires clean and invalidate
|
||||
*/
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount, 1,
|
||||
MMU_MAP_CLEAN |
|
||||
MMU_MAP_INVALID, scheduler, job->mm);
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->dst.vir_w,
|
||||
req->dst.vir_h,
|
||||
req->dst.format, 2);
|
||||
#endif
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base =
|
||||
MMU_Base + Src0MemSize + Src1MemSize;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
if (job->dst_buffer) {
|
||||
switch (job->dst_buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
sgt = rga_mm_lookup_sgt(job->dst_buffer, scheduler->core);
|
||||
if (sgt == NULL) {
|
||||
pr_err("rga2 cannot get sgt from handle!\n");
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
ret = rga2_MapION(sgt, MMU_Base + Src0MemSize + Src1MemSize,
|
||||
DstMemSize);
|
||||
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
if (req->alpha_mode_0 != 0 && req->bitblt_mode == 0)
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount,
|
||||
1,
|
||||
MMU_MAP_CLEAN | MMU_MAP_INVALID,
|
||||
scheduler,
|
||||
job->dst_buffer->current_mm);
|
||||
else
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount,
|
||||
1,
|
||||
MMU_MAP_INVALID,
|
||||
scheduler,
|
||||
job->dst_buffer->current_mm);
|
||||
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base = MMU_Base + Src0MemSize + Src1MemSize;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
|
||||
break;
|
||||
default:
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount,
|
||||
1, MMU_MAP_INVALID, scheduler, job->mm);
|
||||
if (job->rga_dma_buffer_dst) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_dst->sgt,
|
||||
MMU_Base + Src0MemSize + Src1MemSize,
|
||||
DstMemSize);
|
||||
} else if (req->alpha_mode_0 != 0 && req->bitblt_mode == 0) {
|
||||
/*
|
||||
* The blend mode of src + dst => dst
|
||||
* requires clean and invalidate
|
||||
*/
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount, 1,
|
||||
MMU_MAP_CLEAN |
|
||||
MMU_MAP_INVALID, scheduler, job->mm);
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->dst.vir_w,
|
||||
req->dst.vir_h,
|
||||
req->dst.format, 2);
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->dst.vir_w,
|
||||
req->dst.vir_h,
|
||||
req->dst.format, 2);
|
||||
#endif
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base =
|
||||
MMU_Base + Src0MemSize + Src1MemSize;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base = MMU_Base + Src0MemSize + Src1MemSize;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0], MMU_Base
|
||||
+ Src0MemSize + Src1MemSize,
|
||||
DstStart, DstPageCount,
|
||||
1, MMU_MAP_INVALID, scheduler, job->mm);
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE)
|
||||
rga2_user_memory_check(&pages[0],
|
||||
req->dst.vir_w,
|
||||
req->dst.vir_h,
|
||||
req->dst.format, 2);
|
||||
#endif
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base = MMU_Base + Src0MemSize + Src1MemSize;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -756,6 +857,11 @@ static int rga2_mmu_info_color_palette_mode(struct rga2_mmu_other_t *reg,
|
||||
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
if (job->flags & RGA_JOB_USE_HANDLE) {
|
||||
pr_err("color palette mode can not support handle.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scheduler = get_scheduler(job->core);
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
@@ -920,6 +1026,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_mmu_other_t *reg,
|
||||
uint32_t *MMU_Base, *MMU_Base_phys;
|
||||
int ret;
|
||||
int status;
|
||||
struct sg_table *sgt;
|
||||
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
@@ -964,13 +1071,46 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_mmu_other_t *reg,
|
||||
mutex_unlock(&rga_drvdata->lock);
|
||||
|
||||
if (DstMemSize) {
|
||||
if (job->rga_dma_buffer_dst) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_dst->sgt,
|
||||
&MMU_Base[0], DstMemSize);
|
||||
if (job->dst_buffer) {
|
||||
switch (job->src_buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
sgt = rga_mm_lookup_sgt(job->dst_buffer, scheduler->core);
|
||||
if (sgt == NULL) {
|
||||
pr_err("rga2 cannot get sgt from handle!\n");
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
ret = rga2_MapION(sgt, &MMU_Base[0], DstMemSize);
|
||||
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
ret = rga2_MapUserMemory(&pages[0], &MMU_Base[0],
|
||||
DstStart, DstPageCount,
|
||||
1, MMU_MAP_INVALID,
|
||||
scheduler,
|
||||
job->dst_buffer->current_mm);
|
||||
|
||||
/* Save pagetable to invalid cache and unmap. */
|
||||
reg->MMU_dst_base = MMU_Base;
|
||||
reg->MMU_dst_count = DstPageCount;
|
||||
|
||||
break;
|
||||
default:
|
||||
status = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
&MMU_Base[0], DstStart, DstPageCount,
|
||||
1, MMU_MAP_INVALID, scheduler, job->mm);
|
||||
if (job->rga_dma_buffer_dst) {
|
||||
ret = rga2_MapION(job->rga_dma_buffer_dst->sgt,
|
||||
&MMU_Base[0], DstMemSize);
|
||||
} else {
|
||||
ret = rga2_MapUserMemory(&pages[0],
|
||||
&MMU_Base[0], DstStart,
|
||||
DstPageCount, 1,
|
||||
MMU_MAP_INVALID,
|
||||
scheduler, job->mm);
|
||||
}
|
||||
}
|
||||
if (ret < 0) {
|
||||
pr_err("map dst memory failed\n");
|
||||
@@ -1002,6 +1142,7 @@ static int rga2_mmu_info_color_fill_mode(struct rga2_mmu_other_t *reg,
|
||||
return 0;
|
||||
} while (0);
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1020,6 +1161,11 @@ static int rga2_mmu_info_update_palette_table_mode(struct rga2_mmu_other_t *reg,
|
||||
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
if (job->flags & RGA_JOB_USE_HANDLE) {
|
||||
pr_err("update palette table mode can not support handle.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scheduler = get_scheduler(job->core);
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "rga_job.h"
|
||||
#include "rga_fence.h"
|
||||
#include "rga_dma_buf.h"
|
||||
#include "rga_mm.h"
|
||||
#include "rga2_mmu_info.h"
|
||||
|
||||
struct rga_job *
|
||||
@@ -62,53 +63,6 @@ static struct rga_scheduler_t *get_scheduler(struct rga_job *job)
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
static void rga_job_free(struct rga_job *job)
|
||||
{
|
||||
if (job->out_fence)
|
||||
dma_fence_put(job->out_fence);
|
||||
|
||||
free_page((unsigned long)job);
|
||||
}
|
||||
|
||||
static int rga_job_cleanup(struct rga_job *job)
|
||||
{
|
||||
rga_job_free(job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
|
||||
job = (struct rga_job *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
|
||||
if (!job)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&job->fence_lock);
|
||||
INIT_LIST_HEAD(&job->head);
|
||||
|
||||
job->timestamp = ktime_get();
|
||||
job->running_time = ktime_get();
|
||||
|
||||
job->rga_command_base = *rga_command_base;
|
||||
|
||||
if (rga_command_base->priority > 0) {
|
||||
if (rga_command_base->priority > RGA_SCHED_PRIORITY_MAX)
|
||||
job->priority = RGA_SCHED_PRIORITY_MAX;
|
||||
else
|
||||
job->priority = rga_command_base->priority;
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
static void print_job_info(struct rga_job *job)
|
||||
{
|
||||
pr_info("job: priority = %d, core = %d\n",
|
||||
job->priority, job->core);
|
||||
}
|
||||
|
||||
static int rga_job_get_current_mm(struct rga_job *job)
|
||||
{
|
||||
int mmu_flag;
|
||||
@@ -169,6 +123,61 @@ static void rga_job_put_current_mm(struct rga_job *job)
|
||||
job->mm = NULL;
|
||||
}
|
||||
|
||||
static void rga_job_free(struct rga_job *job)
|
||||
{
|
||||
if (job->out_fence)
|
||||
dma_fence_put(job->out_fence);
|
||||
|
||||
if (~job->flags & RGA_JOB_USE_HANDLE)
|
||||
rga_job_put_current_mm(job);
|
||||
|
||||
free_page((unsigned long)job);
|
||||
}
|
||||
|
||||
static int rga_job_cleanup(struct rga_job *job)
|
||||
{
|
||||
rga_job_free(job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
|
||||
job = (struct rga_job *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
|
||||
if (!job)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&job->fence_lock);
|
||||
INIT_LIST_HEAD(&job->head);
|
||||
|
||||
job->timestamp = ktime_get();
|
||||
job->running_time = ktime_get();
|
||||
|
||||
job->rga_command_base = *rga_command_base;
|
||||
|
||||
if (rga_command_base->priority > 0) {
|
||||
if (rga_command_base->priority > RGA_SCHED_PRIORITY_MAX)
|
||||
job->priority = RGA_SCHED_PRIORITY_MAX;
|
||||
else
|
||||
job->priority = rga_command_base->priority;
|
||||
}
|
||||
|
||||
if (job->rga_command_base.handle_flag & 1)
|
||||
job->flags |= RGA_JOB_USE_HANDLE;
|
||||
else
|
||||
rga_job_get_current_mm(job);
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
static void print_job_info(struct rga_job *job)
|
||||
{
|
||||
pr_info("job: priority = %d, core = %d\n",
|
||||
job->priority, job->core);
|
||||
}
|
||||
|
||||
static int rga_job_run(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -180,10 +189,18 @@ static int rga_job_run(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rga_dma_get_info(job);
|
||||
if (ret < 0) {
|
||||
pr_err("dma buf get failed");
|
||||
goto failed;
|
||||
if (job->flags & RGA_JOB_USE_HANDLE) {
|
||||
ret = rga_mm_get_handle_info(job);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to get buffer from handle\n", __func__);
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
ret = rga_dma_get_info(job);
|
||||
if (ret < 0) {
|
||||
pr_err("dma buf get failed");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
ret = scheduler->ops->init_reg(job);
|
||||
@@ -247,6 +264,11 @@ next_job:
|
||||
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
if (job->flags & RGA_JOB_USE_HANDLE)
|
||||
rga_mm_put_handle_info(job);
|
||||
else
|
||||
rga_dma_put_info(job);
|
||||
|
||||
if (job->out_fence)
|
||||
dma_fence_signal(job->out_fence);
|
||||
|
||||
@@ -257,8 +279,6 @@ next_job:
|
||||
wake_up(&rga_scheduler->job_done_wq);
|
||||
}
|
||||
|
||||
rga_dma_put_info(job);
|
||||
|
||||
goto next_job;
|
||||
}
|
||||
}
|
||||
@@ -292,8 +312,10 @@ void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret)
|
||||
rga2_dma_flush_cache_for_virtual_address(&job->vir_page_table,
|
||||
rga_scheduler);
|
||||
|
||||
rga_dma_put_info(job);
|
||||
rga_job_put_current_mm(job);
|
||||
if (job->flags & RGA_JOB_USE_HANDLE)
|
||||
rga_mm_put_handle_info(job);
|
||||
else
|
||||
rga_dma_put_info(job);
|
||||
|
||||
if (job->out_fence)
|
||||
dma_fence_signal(job->out_fence);
|
||||
@@ -325,8 +347,10 @@ static void rga_job_timeout_clean(struct rga_scheduler_t *scheduler)
|
||||
|
||||
scheduler->ops->soft_reset(scheduler);
|
||||
|
||||
rga_dma_put_info(job);
|
||||
rga_job_put_current_mm(job);
|
||||
if (job->flags & RGA_JOB_USE_HANDLE)
|
||||
rga_mm_put_handle_info(job);
|
||||
else
|
||||
rga_dma_put_info(job);
|
||||
|
||||
if (job->out_fence)
|
||||
dma_fence_signal(job->out_fence);
|
||||
@@ -501,8 +525,6 @@ int rga_job_commit(struct rga_req *rga_command_base, int flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rga_job_get_current_mm(job);
|
||||
|
||||
if (flags == RGA_BLIT_ASYNC) {
|
||||
ret = rga_out_fence_alloc(job);
|
||||
if (ret) {
|
||||
|
||||
@@ -12,6 +12,37 @@
|
||||
#include "rga_dma_buf.h"
|
||||
#include "rga_hw_config.h"
|
||||
|
||||
static bool is_yuv422p_format(u32 format)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rga_convert_addr(struct rga_img_info_t *img)
|
||||
{
|
||||
if (img->rd_mode != RGA_FBC_MODE) {
|
||||
img->uv_addr = img->yrgb_addr + (img->vir_w * img->vir_h);
|
||||
|
||||
//warning: rga3 may need /2 for all
|
||||
if (is_yuv422p_format(img->format))
|
||||
img->v_addr =
|
||||
img->uv_addr + (img->vir_w * img->vir_h) / 2;
|
||||
else
|
||||
img->v_addr =
|
||||
img->uv_addr + (img->vir_w * img->vir_h) / 4;
|
||||
} else {
|
||||
img->uv_addr = img->yrgb_addr;
|
||||
img->v_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void rga_current_mm_read_lock(struct mm_struct *mm)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||
@@ -524,8 +555,8 @@ static int rga_mm_handle_remove(int id, void *ptr, void *data)
|
||||
}
|
||||
|
||||
static struct rga_internal_buffer *
|
||||
rga_mm_internal_buffer_lookup_external(struct rga_mm *mm_session,
|
||||
struct rga_external_buffer *external_buffer)
|
||||
rga_mm_lookup_external(struct rga_mm *mm_session,
|
||||
struct rga_external_buffer *external_buffer)
|
||||
{
|
||||
int id;
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
@@ -592,6 +623,38 @@ struct rga_internal_buffer *rga_mm_lookup_handle(struct rga_mm *mm_session, uint
|
||||
return output_buffer;
|
||||
}
|
||||
|
||||
dma_addr_t rga_mm_lookup_iova(struct rga_internal_buffer *buffer, int core)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < buffer->dma_buffer_size; i++)
|
||||
if (buffer->dma_buffer[i].core == core)
|
||||
return buffer->dma_buffer[i].iova;
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
struct sg_table *rga_mm_lookup_sgt(struct rga_internal_buffer *buffer, int core)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
for (i = 0; i < buffer->dma_buffer_size; i++)
|
||||
if (buffer->dma_buffer[i].core == core)
|
||||
return buffer->dma_buffer[i].sgt;
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
return buffer->virt_addr->sgt;
|
||||
case RGA_PHYSICAL_ADDRESS:
|
||||
default:
|
||||
pr_err("Illegal internal buffer, no sgt can be obtained!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rga_mm_dump_info(struct rga_mm *mm_session)
|
||||
{
|
||||
int id, i;
|
||||
@@ -646,6 +709,162 @@ void rga_mm_dump_info(struct rga_mm *mm_session)
|
||||
}
|
||||
}
|
||||
|
||||
static int rga_mm_set_mmu_flag(struct rga_job *job)
|
||||
{
|
||||
struct rga_mmu_t *mmu_info;
|
||||
int src_mmu_en;
|
||||
int src1_mmu_en;
|
||||
int dst_mmu_en;
|
||||
int els_mmu_en;
|
||||
|
||||
src_mmu_en = job->src_buffer ? job->src_buffer->mm_flag & RGA_MM_NEED_USE_IOMMU : 0;
|
||||
src1_mmu_en = job->src1_buffer ? job->src1_buffer->mm_flag & RGA_MM_NEED_USE_IOMMU : 0;
|
||||
dst_mmu_en = job->dst_buffer ? job->dst_buffer->mm_flag & RGA_MM_NEED_USE_IOMMU : 0;
|
||||
els_mmu_en = job->els_buffer ? job->els_buffer->mm_flag & RGA_MM_NEED_USE_IOMMU : 0;
|
||||
|
||||
mmu_info = &job->rga_command_base.mmu_info;
|
||||
if (src_mmu_en)
|
||||
mmu_info->mmu_flag |= (0x1 << 8);
|
||||
if (src1_mmu_en)
|
||||
mmu_info->mmu_flag |= (0x1 << 9);
|
||||
if (dst_mmu_en)
|
||||
mmu_info->mmu_flag |= (0x1 << 10);
|
||||
if (els_mmu_en)
|
||||
mmu_info->mmu_flag |= (0x1 << 11);
|
||||
|
||||
if (mmu_info->mmu_flag & (0xf << 8)) {
|
||||
mmu_info->mmu_flag |= 1;
|
||||
mmu_info->mmu_flag |= 1 << 31;
|
||||
mmu_info->mmu_en = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_mm_get_channel_handle_info(struct rga_mm *mm,
|
||||
struct rga_job *job,
|
||||
struct rga_img_info_t *img,
|
||||
struct rga_internal_buffer **buf)
|
||||
{
|
||||
struct rga_internal_buffer *internal_buffer = NULL;
|
||||
|
||||
if (!(img->yrgb_addr > 0)) {
|
||||
pr_err("No buffer handle can be used!\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
mutex_lock(&mm->lock);
|
||||
*buf = rga_mm_lookup_handle(mm, img->yrgb_addr);
|
||||
if (*buf == NULL) {
|
||||
pr_err("This handle[%ld] is illegal.\n", (unsigned long)img->yrgb_addr);
|
||||
|
||||
mutex_unlock(&mm->lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
internal_buffer = *buf;
|
||||
kref_get(&internal_buffer->refcount);
|
||||
|
||||
switch (internal_buffer->type) {
|
||||
case RGA_DMA_BUFFER:
|
||||
if (job->core == RGA3_SCHEDULER_CORE0 ||
|
||||
job->core == RGA3_SCHEDULER_CORE1)
|
||||
img->yrgb_addr = rga_mm_lookup_iova(internal_buffer, job->core);
|
||||
else
|
||||
img->yrgb_addr = 0;
|
||||
break;
|
||||
case RGA_VIRTUAL_ADDRESS:
|
||||
if (job->core == RGA3_SCHEDULER_CORE0 ||
|
||||
job->core == RGA3_SCHEDULER_CORE1)
|
||||
img->yrgb_addr = rga_mm_lookup_iova(internal_buffer, job->core);
|
||||
else
|
||||
img->yrgb_addr = internal_buffer->virt_addr->addr;
|
||||
break;
|
||||
case RGA_PHYSICAL_ADDRESS:
|
||||
img->yrgb_addr = internal_buffer->phys_addr;
|
||||
break;
|
||||
default:
|
||||
pr_err("Illegal external buffer!\n");
|
||||
|
||||
mutex_unlock(&mm->lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
mutex_unlock(&mm->lock);
|
||||
|
||||
rga_convert_addr(img);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rga_mm_put_channel_handle_info(struct rga_mm *mm,
|
||||
struct rga_internal_buffer *internal_buffer)
|
||||
{
|
||||
mutex_lock(&mm->lock);
|
||||
|
||||
kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer);
|
||||
|
||||
mutex_unlock(&mm->lock);
|
||||
}
|
||||
|
||||
int rga_mm_get_handle_info(struct rga_job *job)
|
||||
{
|
||||
int ret = 0;
|
||||
struct rga_req *req = NULL;
|
||||
struct rga_mm *mm = NULL;
|
||||
|
||||
req = &job->rga_command_base;
|
||||
mm = rga_drvdata->mm;
|
||||
|
||||
if (likely(req->src.yrgb_addr > 0)) {
|
||||
ret = rga_mm_get_channel_handle_info(mm, job, &req->src, &job->src_buffer);
|
||||
if (ret < 0) {
|
||||
pr_err("Can't get src buffer info!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(req->dst.yrgb_addr > 0)) {
|
||||
ret = rga_mm_get_channel_handle_info(mm, job, &req->dst, &job->dst_buffer);
|
||||
if (ret < 0) {
|
||||
pr_err("Can't get dst buffer info!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(req->pat.yrgb_addr > 0)) {
|
||||
if (job->rga_command_base.render_mode != UPDATE_PALETTE_TABLE_MODE)
|
||||
ret = rga_mm_get_channel_handle_info(mm, job, &req->pat,
|
||||
&job->src1_buffer);
|
||||
else
|
||||
ret = rga_mm_get_channel_handle_info(mm, job, &req->pat,
|
||||
&job->els_buffer);
|
||||
if (ret < 0) {
|
||||
pr_err("Can't get pat buffer info!\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
rga_mm_set_mmu_flag(job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rga_mm_put_handle_info(struct rga_job *job)
|
||||
{
|
||||
struct rga_mm *mm = NULL;
|
||||
|
||||
mm = rga_drvdata->mm;
|
||||
|
||||
if (job->src_buffer)
|
||||
rga_mm_put_channel_handle_info(mm, job->src_buffer);
|
||||
if (job->dst_buffer)
|
||||
rga_mm_put_channel_handle_info(mm, job->dst_buffer);
|
||||
if (job->src1_buffer)
|
||||
rga_mm_put_channel_handle_info(mm, job->src1_buffer);
|
||||
if (job->els_buffer)
|
||||
rga_mm_put_channel_handle_info(mm, job->els_buffer);
|
||||
}
|
||||
|
||||
uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -661,7 +880,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer)
|
||||
mutex_lock(&mm->lock);
|
||||
|
||||
/* first, Check whether to rga_mm */
|
||||
internal_buffer = rga_mm_internal_buffer_lookup_external(mm, external_buffer);
|
||||
internal_buffer = rga_mm_lookup_external(mm, external_buffer);
|
||||
if (!IS_ERR_OR_NULL(internal_buffer)) {
|
||||
kref_get(&internal_buffer->refcount);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user