mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
gdc: add gdc cpu cost optimize [1/2]
PD#SWPL-7422 Problem: gdc ioctl have cpu usage issue Solution: 1. dma buffer alloc gdc module,when dma buf exported, fd and phys address can be recorded.driver can get phys address via fd internally. 2. dmabuf alloc by other driver module, need used gdc_dma_buffer_map/ gdc_dma_buffer_unmap to get phys address. Verify: Newman & W400 board Change-Id: Ie270589a19dfae4fa750241fb5721154221f2448 Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
@@ -506,6 +506,7 @@ int gdc_dma_buffer_export(struct aml_dma_buffer *buffer,
|
||||
}
|
||||
gdc_log(LOG_INFO, "buffer %d,exported as %d descriptor\n",
|
||||
index, ret);
|
||||
buffer->gd_buffer[index].fd = ret;
|
||||
gdc_exp_buf->fd = ret;
|
||||
return 0;
|
||||
}
|
||||
@@ -579,25 +580,72 @@ attach_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int gdc_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr)
|
||||
static int gdc_dma_buffer_get_phys_internal(struct aml_dma_buffer *buffer,
|
||||
int fd, unsigned long *addr)
|
||||
{
|
||||
int i = 0, ret = -1;
|
||||
struct aml_dma_buf *dma_buf;
|
||||
|
||||
for (i = 0; i < AML_MAX_DMABUF; i++) {
|
||||
if (buffer->gd_buffer[i].alloc &&
|
||||
(fd == buffer->gd_buffer[i].fd)) {
|
||||
dma_buf = buffer->gd_buffer[i].mem_priv;
|
||||
*addr = dma_buf->dma_addr;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int gdc_dma_buffer_get_phys(struct aml_dma_buffer *buffer,
|
||||
struct aml_dma_cfg *cfg, unsigned long *addr)
|
||||
{
|
||||
struct sg_table *sg_table;
|
||||
struct page *page;
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
ret = gdc_dma_buffer_map(cfg);
|
||||
if (ret < 0) {
|
||||
pr_err("gdc_dma_buffer_map failed\n");
|
||||
return ret;
|
||||
if (cfg == NULL || (cfg->fd < 0)) {
|
||||
pr_err("error input param");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cfg->sg) {
|
||||
sg_table = cfg->sg;
|
||||
page = sg_page(sg_table->sgl);
|
||||
*addr = PFN_PHYS(page_to_pfn(page));
|
||||
ret = 0;
|
||||
ret = gdc_dma_buffer_get_phys_internal(buffer, cfg->fd, addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_INFO, "get_phys(fd=%d) failed.\n", cfg->fd);
|
||||
ret = gdc_dma_buffer_map(cfg);
|
||||
if (ret < 0) {
|
||||
pr_err("gdc_dma_buffer_map failed\n");
|
||||
return ret;
|
||||
}
|
||||
if (cfg->sg) {
|
||||
sg_table = cfg->sg;
|
||||
page = sg_page(sg_table->sgl);
|
||||
*addr = PFN_PHYS(page_to_pfn(page));
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int gdc_dma_buffer_unmap_info(struct aml_dma_buffer *buffer,
|
||||
struct aml_dma_cfg *cfg)
|
||||
{
|
||||
int i, found = 0;
|
||||
|
||||
if (cfg == NULL || (cfg->fd < 0)) {
|
||||
pr_err("error input param");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < AML_MAX_DMABUF; i++) {
|
||||
if (buffer->gd_buffer[i].alloc &&
|
||||
(cfg->fd == buffer->gd_buffer[i].fd)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
gdc_dma_buffer_unmap(cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gdc_dma_buffer_unmap(struct aml_dma_cfg *cfg)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@ struct aml_dma_buf {
|
||||
struct aml_dma_buf_priv {
|
||||
void *mem_priv;
|
||||
int index;
|
||||
int fd;
|
||||
unsigned int alloc;
|
||||
struct dma_buf *dbuf;
|
||||
};
|
||||
@@ -73,7 +74,10 @@ int gdc_dma_buffer_export(struct aml_dma_buffer *buffer,
|
||||
struct gdc_dmabuf_exp_s *gdc_exp_buf);
|
||||
int gdc_dma_buffer_map(struct aml_dma_cfg *cfg);
|
||||
void gdc_dma_buffer_unmap(struct aml_dma_cfg *cfg);
|
||||
int gdc_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr);
|
||||
int gdc_dma_buffer_get_phys(struct aml_dma_buffer *buffer,
|
||||
struct aml_dma_cfg *cfg, unsigned long *addr);
|
||||
int gdc_dma_buffer_unmap_info(struct aml_dma_buffer *buffer,
|
||||
struct aml_dma_cfg *cfg);
|
||||
void gdc_dma_buffer_dma_flush(struct device *dev, int fd);
|
||||
void gdc_dma_buffer_cache_flush(struct device *dev, int fd);
|
||||
#endif
|
||||
|
||||
@@ -530,6 +530,16 @@ static void gdc_buffer_cache_flush(int dma_fd)
|
||||
gdc_dma_buffer_cache_flush(dev, dma_fd);
|
||||
}
|
||||
|
||||
static int gdc_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr)
|
||||
{
|
||||
return gdc_dma_buffer_get_phys(gdc_manager.buffer, cfg, addr);
|
||||
}
|
||||
|
||||
static int gdc_buffer_unmap(struct aml_dma_cfg *cfg)
|
||||
{
|
||||
return gdc_dma_buffer_unmap_info(gdc_manager.buffer, cfg);
|
||||
}
|
||||
|
||||
static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
struct gdc_settings_ex *gs_ex)
|
||||
{
|
||||
@@ -558,7 +568,7 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -572,15 +582,12 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
}
|
||||
gdc_log(LOG_INFO, "1 plane get input addr=%x\n",
|
||||
gdc_cmd->y_base_addr);
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->y_base_addr,
|
||||
gc->input_y_stride * gc->input_height);
|
||||
} else if (gs_ex->input_buffer.plane_number == 2) {
|
||||
cfg = &fh->dma_cfg.input_cfg_plane1;
|
||||
cfg->fd = gs_ex->input_buffer.y_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -588,14 +595,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
gdc_cmd->y_base_addr = addr;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->y_base_addr,
|
||||
gc->input_y_stride * gc->input_height);
|
||||
cfg = &fh->dma_cfg.input_cfg_plane2;
|
||||
cfg->fd = gs_ex->input_buffer.uv_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -603,9 +607,6 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
gdc_cmd->uv_base_addr = addr;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->uv_base_addr,
|
||||
gc->input_y_stride * gc->input_height / 2);
|
||||
gdc_log(LOG_INFO, "2 plane get input y_addr=%x\n",
|
||||
gdc_cmd->y_base_addr);
|
||||
gdc_log(LOG_INFO, "2 plane get input uv_addr=%x\n",
|
||||
@@ -620,7 +621,7 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -634,15 +635,12 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
}
|
||||
gdc_log(LOG_INFO, "1 plane get input addr=%x\n",
|
||||
gdc_cmd->y_base_addr);
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->y_base_addr,
|
||||
gc->input_y_stride * gc->input_height);
|
||||
} else if (gs_ex->input_buffer.plane_number == 3) {
|
||||
cfg = &fh->dma_cfg.input_cfg_plane1;
|
||||
cfg->fd = gs_ex->input_buffer.y_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -650,15 +648,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
gdc_cmd->y_base_addr = addr;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->y_base_addr,
|
||||
gc->input_y_stride * gc->input_height);
|
||||
|
||||
cfg = &fh->dma_cfg.input_cfg_plane2;
|
||||
cfg->fd = gs_ex->input_buffer.u_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -666,15 +660,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
gdc_cmd->u_base_addr = addr;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->u_base_addr,
|
||||
gc->input_y_stride * gc->input_height / 2);
|
||||
|
||||
cfg = &fh->dma_cfg.input_cfg_plane3;
|
||||
cfg->fd = gs_ex->input_buffer.v_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d err\n",
|
||||
@@ -682,10 +672,6 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
return -EINVAL;
|
||||
}
|
||||
gdc_cmd->v_base_addr = addr;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->v_base_addr,
|
||||
gc->input_y_stride * gc->input_height / 2);
|
||||
|
||||
gdc_log(LOG_INFO, "3 plane get input y_addr=%x\n",
|
||||
gdc_cmd->y_base_addr);
|
||||
gdc_log(LOG_INFO, "3 plane get input u_addr=%x\n",
|
||||
@@ -700,7 +686,7 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->input_buffer.y_base_fd;
|
||||
cfg->dev = &(fh->gdev->pdev->dev);
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import input fd %d failed\n",
|
||||
@@ -709,9 +695,6 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh,
|
||||
}
|
||||
gdc_cmd->y_base_addr = addr;
|
||||
gdc_cmd->uv_base_addr = 0;
|
||||
meson_gdc_dma_flush(&fh->gdev->pdev->dev,
|
||||
gdc_cmd->y_base_addr,
|
||||
gc->input_y_stride * gc->input_height);
|
||||
break;
|
||||
default:
|
||||
gdc_log(LOG_ERR, "Error image format");
|
||||
@@ -891,7 +874,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -907,7 +890,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.y_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -921,7 +904,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.uv_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -944,7 +927,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.y_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -960,7 +943,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.y_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -974,7 +957,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.u_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -987,7 +970,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.v_base_fd;
|
||||
cfg->dev = &fh->gdev->pdev->dev;
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -1009,7 +992,7 @@ static long gdc_process_output_dma_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->output_buffer.y_base_fd;
|
||||
cfg->dev = &(fh->gdev->pdev->dev);
|
||||
cfg->dir = DMA_FROM_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR,
|
||||
"dma import output fd %d err\n",
|
||||
@@ -1205,7 +1188,7 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh,
|
||||
cfg->fd = gs_ex->config_buffer.y_base_fd;
|
||||
cfg->dev = &(gdc_manager.gdc_dev->pdev->dev);
|
||||
cfg->dir = DMA_TO_DEVICE;
|
||||
ret = gdc_dma_buffer_get_phys(cfg, &addr);
|
||||
ret = gdc_buffer_get_phys(cfg, &addr);
|
||||
if (ret < 0) {
|
||||
gdc_log(LOG_ERR, "dma import config fd %d failed\n",
|
||||
gs_ex->config_buffer.shared_fd);
|
||||
@@ -1250,28 +1233,24 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh,
|
||||
if (!gdc_reg_store_mode)
|
||||
gdc_pwr_config(false);
|
||||
mutex_unlock(&fh->gdev->d_mutext);
|
||||
#if 0
|
||||
if (gs_ex->output_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF)
|
||||
gdc_buffer_cache_flush(gs_ex->output_buffer.shared_fd);
|
||||
#endif
|
||||
if (gs_ex->input_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) {
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane1);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.input_cfg_plane1);
|
||||
if (gs_ex->input_buffer.plane_number == 2)
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane2);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.input_cfg_plane2);
|
||||
if (gs_ex->input_buffer.plane_number == 3) {
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane2);
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane3);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.input_cfg_plane2);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.input_cfg_plane3);
|
||||
}
|
||||
}
|
||||
if (gs_ex->config_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF)
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.config_cfg);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.config_cfg);
|
||||
if (gs_ex->output_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) {
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.output_cfg_plane1);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.output_cfg_plane1);
|
||||
if (gs_ex->output_buffer.plane_number == 2)
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.output_cfg_plane2);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.output_cfg_plane2);
|
||||
if (gs_ex->output_buffer.plane_number == 3) {
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.output_cfg_plane2);
|
||||
gdc_dma_buffer_unmap(&fh->dma_cfg.output_cfg_plane3);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.output_cfg_plane2);
|
||||
gdc_buffer_unmap(&fh->dma_cfg.output_cfg_plane3);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user