From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 13 May 2024 10:30:14 +0000
Subject: [PATCH] modify sin led gpio
---
kernel/drivers/video/rockchip/rga3/rga_mm.c | 192 ++++++++++++++++++++++++++++++++++++++---------
1 files changed, 153 insertions(+), 39 deletions(-)
diff --git a/kernel/drivers/video/rockchip/rga3/rga_mm.c b/kernel/drivers/video/rockchip/rga3/rga_mm.c
index cd461b5..de7e9a6 100644
--- a/kernel/drivers/video/rockchip/rga3/rga_mm.c
+++ b/kernel/drivers/video/rockchip/rga3/rga_mm.c
@@ -455,6 +455,7 @@
phys_addr = sg_phys(buffer->sgt->sgl);
if (phys_addr == 0) {
pr_err("%s get physical address error!", __func__);
+ ret = -EFAULT;
goto unmap_buffer;
}
@@ -571,11 +572,19 @@
phys_addr = sg_phys(sgt->sgl);
if (phys_addr == 0) {
pr_err("%s get physical address error!", __func__);
+ ret = -EFAULT;
goto free_sgt;
}
mm_flag |= RGA_MEM_PHYSICAL_CONTIGUOUS;
}
+
+ /*
+ * Some userspace virtual addresses do not have an
+ * interface for flushing the cache, so it is mandatory
+ * to flush the cache when the virtual address is used.
+ */
+ mm_flag |= RGA_MEM_FORCE_FLUSH_CACHE;
if (!rga_mm_check_memory_limit(scheduler, mm_flag)) {
pr_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n",
@@ -614,8 +623,9 @@
if (mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS)
break;
- pr_err("Current %s[%d] cannot support virtual address!\n",
+ pr_err("Current %s[%d] cannot support physically discontinuous virtual address!\n",
rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu);
+ ret = -EOPNOTSUPP;
goto free_dma_buffer;
}
@@ -833,9 +843,15 @@
return 0;
}
+static void rga_mm_buffer_destroy(struct rga_internal_buffer *buffer)
+{
+ rga_mm_kref_release_buffer(&buffer->refcount);
+}
+
static struct rga_internal_buffer *
rga_mm_lookup_external(struct rga_mm *mm_session,
- struct rga_external_buffer *external_buffer)
+ struct rga_external_buffer *external_buffer,
+ struct mm_struct *current_mm)
{
int id;
struct dma_buf *dma_buf = NULL;
@@ -868,8 +884,12 @@
continue;
if (temp_buffer->virt_addr->addr == external_buffer->memory) {
- output_buffer = temp_buffer;
- break;
+ if (temp_buffer->current_mm == current_mm) {
+ output_buffer = temp_buffer;
+ break;
+ }
+
+ continue;
}
}
@@ -1295,13 +1315,6 @@
struct sg_table *sgt;
struct rga_scheduler_t *scheduler;
- sgt = rga_mm_lookup_sgt(buffer);
- if (sgt == NULL) {
- pr_err("%s(%d), failed to get sgt, core = 0x%x\n",
- __func__, __LINE__, job->core);
- return -EINVAL;
- }
-
scheduler = buffer->dma_buffer->scheduler;
if (scheduler == NULL) {
pr_err("%s(%d), failed to get scheduler, core = 0x%x\n",
@@ -1309,7 +1322,19 @@
return -EFAULT;
}
- dma_sync_sg_for_device(scheduler->dev, sgt->sgl, sgt->orig_nents, dir);
+ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS &&
+ scheduler->data->mmu != RGA_IOMMU) {
+ dma_sync_single_for_device(scheduler->dev, buffer->phys_addr, buffer->size, dir);
+ } else {
+ sgt = rga_mm_lookup_sgt(buffer);
+ if (sgt == NULL) {
+ pr_err("%s(%d), failed to get sgt, core = 0x%x\n",
+ __func__, __LINE__, job->core);
+ return -EINVAL;
+ }
+
+ dma_sync_sg_for_device(scheduler->dev, sgt->sgl, sgt->orig_nents, dir);
+ }
return 0;
}
@@ -1321,13 +1346,6 @@
struct sg_table *sgt;
struct rga_scheduler_t *scheduler;
- sgt = rga_mm_lookup_sgt(buffer);
- if (sgt == NULL) {
- pr_err("%s(%d), failed to get sgt, core = 0x%x\n",
- __func__, __LINE__, job->core);
- return -EINVAL;
- }
-
scheduler = buffer->dma_buffer->scheduler;
if (scheduler == NULL) {
pr_err("%s(%d), failed to get scheduler, core = 0x%x\n",
@@ -1335,7 +1353,19 @@
return -EFAULT;
}
- dma_sync_sg_for_cpu(scheduler->dev, sgt->sgl, sgt->orig_nents, dir);
+ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS &&
+ scheduler->data->mmu != RGA_IOMMU) {
+ dma_sync_single_for_cpu(scheduler->dev, buffer->phys_addr, buffer->size, dir);
+ } else {
+ sgt = rga_mm_lookup_sgt(buffer);
+ if (sgt == NULL) {
+ pr_err("%s(%d), failed to get sgt, core = 0x%x\n",
+ __func__, __LINE__, job->core);
+ return -EINVAL;
+ }
+
+ dma_sync_sg_for_cpu(scheduler->dev, sgt->sgl, sgt->orig_nents, dir);
+ }
return 0;
}
@@ -1434,7 +1464,7 @@
goto put_internal_buffer;
}
- if (internal_buffer->type == RGA_VIRTUAL_ADDRESS) {
+ if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE) {
/*
* Some userspace virtual addresses do not have an
* interface for flushing the cache, so it is mandatory
@@ -1463,9 +1493,14 @@
struct rga_internal_buffer *internal_buffer,
enum dma_data_direction dir)
{
- if (internal_buffer->type == RGA_VIRTUAL_ADDRESS && dir != DMA_NONE)
+ if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE)
if (rga_mm_sync_dma_sg_for_cpu(internal_buffer, job, dir))
pr_err("sync sgt for cpu error!\n");
+
+ if (DEBUGGER_EN(MM)) {
+ pr_info("handle[%d] put info:\n", (int)internal_buffer->handle);
+ rga_mm_dump_buffer(internal_buffer);
+ }
mutex_lock(&mm->lock);
kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer);
@@ -1574,6 +1609,53 @@
req = &job->rga_command_base;
mm = rga_drvdata->mm;
+
+ switch (req->render_mode) {
+ case BITBLT_MODE:
+ case COLOR_PALETTE_MODE:
+ if (unlikely(req->src.yrgb_addr <= 0)) {
+ pr_err("render_mode[0x%x] src0 channel handle[%ld] must is valid!",
+ req->render_mode, (unsigned long)req->src.yrgb_addr);
+ return -EINVAL;
+ }
+
+ if (unlikely(req->dst.yrgb_addr <= 0)) {
+ pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!",
+ req->render_mode, (unsigned long)req->dst.yrgb_addr);
+ return -EINVAL;
+ }
+
+ if (req->bsfilter_flag) {
+ if (unlikely(req->pat.yrgb_addr <= 0)) {
+ pr_err("render_mode[0x%x] src1/pat channel handle[%ld] must is valid!",
+ req->render_mode, (unsigned long)req->pat.yrgb_addr);
+ return -EINVAL;
+ }
+ }
+
+ break;
+ case COLOR_FILL_MODE:
+ if (unlikely(req->dst.yrgb_addr <= 0)) {
+ pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!",
+ req->render_mode, (unsigned long)req->dst.yrgb_addr);
+ return -EINVAL;
+ }
+
+ break;
+
+ case UPDATE_PALETTE_TABLE_MODE:
+ case UPDATE_PATTEN_BUF_MODE:
+ if (unlikely(req->pat.yrgb_addr <= 0)) {
+ pr_err("render_mode[0x%x] lut/pat channel handle[%ld] must is valid!, req->render_mode",
+ req->render_mode, (unsigned long)req->pat.yrgb_addr);
+ return -EINVAL;
+ }
+
+ break;
+ default:
+ pr_err("%s, unknown render mode!\n", __func__);
+ break;
+ }
if (likely(req->src.yrgb_addr > 0)) {
ret = rga_mm_get_channel_handle_info(mm, job, &req->src,
@@ -1765,7 +1847,7 @@
struct rga_job_buffer *job_buffer,
enum dma_data_direction dir)
{
- if (job_buffer->addr->type == RGA_VIRTUAL_ADDRESS && dir != DMA_NONE)
+ if (job_buffer->addr->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE)
if (rga_mm_sync_dma_sg_for_cpu(job_buffer->addr, job, dir))
pr_err("sync sgt for cpu error!\n");
@@ -1802,12 +1884,7 @@
goto error_unmap_buffer;
}
- if (buffer->type == RGA_VIRTUAL_ADDRESS) {
- /*
- * Some userspace virtual addresses do not have an
- * interface for flushing the cache, so it is mandatory
- * to flush the cache when the virtual address is used.
- */
+ if (buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE) {
ret = rga_mm_sync_dma_sg_for_device(buffer, job, dir);
if (ret < 0) {
pr_err("sync sgt for device error!\n");
@@ -1924,6 +2001,7 @@
int rga_mm_map_job_info(struct rga_job *job)
{
int ret;
+ ktime_t timestamp = ktime_get();
if (job->flags & RGA_JOB_USE_HANDLE) {
ret = rga_mm_get_handle_info(job);
@@ -1931,12 +2009,20 @@
pr_err("failed to get buffer from handle\n");
return ret;
}
+
+ if (DEBUGGER_EN(TIME))
+ pr_info("request[%d], get buffer_handle info cost %lld us\n",
+ job->request_id, ktime_us_delta(ktime_get(), timestamp));
} else {
ret = rga_mm_map_buffer_info(job);
if (ret < 0) {
pr_err("failed to map buffer\n");
return ret;
}
+
+ if (DEBUGGER_EN(TIME))
+ pr_info("request[%d], map buffer cost %lld us\n",
+ job->request_id, ktime_us_delta(ktime_get(), timestamp));
}
return 0;
@@ -1944,14 +2030,35 @@
void rga_mm_unmap_job_info(struct rga_job *job)
{
- if (job->flags & RGA_JOB_USE_HANDLE)
+ ktime_t timestamp = ktime_get();
+
+ if (job->flags & RGA_JOB_USE_HANDLE) {
rga_mm_put_handle_info(job);
- else
+
+ if (DEBUGGER_EN(TIME))
+ pr_info("request[%d], put buffer_handle info cost %lld us\n",
+ job->request_id, ktime_us_delta(ktime_get(), timestamp));
+ } else {
rga_mm_unmap_buffer_info(job);
+
+ if (DEBUGGER_EN(TIME))
+ pr_info("request[%d], unmap buffer cost %lld us\n",
+ job->request_id, ktime_us_delta(ktime_get(), timestamp));
+ }
}
-uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
- struct rga_session *session)
+/*
+ * rga_mm_import_buffer - Importing external buffer into the RGA driver
+ *
+ * @external_buffer: [in] Parameters of external buffer
+ * @session: [in] Session of the current process
+ *
+ * returns:
+ * if return value > 0, the buffer import is successful and is the generated
+ * buffer-handle, negative error code on failure.
+ */
+int rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
+ struct rga_session *session)
{
int ret = 0, new_id;
struct rga_mm *mm;
@@ -1960,17 +2067,23 @@
mm = rga_drvdata->mm;
if (mm == NULL) {
pr_err("rga mm is null!\n");
- return 0;
+ return -EFAULT;
}
mutex_lock(&mm->lock);
/* first, Check whether to rga_mm */
- internal_buffer = rga_mm_lookup_external(mm, external_buffer);
+ internal_buffer = rga_mm_lookup_external(mm, external_buffer, current->mm);
if (!IS_ERR_OR_NULL(internal_buffer)) {
kref_get(&internal_buffer->refcount);
mutex_unlock(&mm->lock);
+
+ if (DEBUGGER_EN(MM)) {
+ pr_info("import existing buffer:\n");
+ rga_mm_dump_buffer(internal_buffer);
+ }
+
return internal_buffer->handle;
}
@@ -1980,7 +2093,7 @@
pr_err("%s alloc internal_buffer error!\n", __func__);
mutex_unlock(&mm->lock);
- return 0;
+ return -ENOMEM;
}
ret = rga_mm_map_buffer(external_buffer, internal_buffer, NULL, true);
@@ -1999,6 +2112,7 @@
idr_preload_end();
if (new_id < 0) {
pr_err("internal_buffer alloc id failed!\n");
+ ret = new_id;
goto FREE_INTERNAL_BUFFER;
}
@@ -2017,7 +2131,7 @@
mutex_unlock(&mm->lock);
kfree(internal_buffer);
- return 0;
+ return ret;
}
int rga_mm_release_buffer(uint32_t handle)
@@ -2069,9 +2183,9 @@
idr_for_each_entry(&mm->memory_idr, buffer, i) {
if (session == buffer->session) {
- pr_err("[tgid:%d] Decrement the reference of handle[%d] when the user exits\n",
+ pr_err("[tgid:%d] Destroy handle[%d] when the user exits\n",
session->tgid, buffer->handle);
- kref_put(&buffer->refcount, rga_mm_kref_release_buffer);
+ rga_mm_buffer_destroy(buffer);
}
}
--
Gitblit v1.6.2