mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
video: rockchip: rga3: use dma_map_sg instead of dma_map_resouce
Change-Id: Ic41f6eb94d2dd749f71bfa02ba718e6bb4dcd263 Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
This commit is contained in:
@@ -44,10 +44,6 @@ int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr,
|
|||||||
int rga_virtual_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd);
|
int rga_virtual_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd);
|
||||||
int rga_dma_memory_check(struct rga_dma_buffer *rga_dma_buffer, struct rga_img_info_t *img);
|
int rga_dma_memory_check(struct rga_dma_buffer *rga_dma_buffer, struct rga_img_info_t *img);
|
||||||
|
|
||||||
int rga_dma_map_phys_addr(phys_addr_t phys_addr, size_t size, struct rga_dma_buffer *buffer,
|
|
||||||
enum dma_data_direction dir, struct device *map_dev);
|
|
||||||
void rga_dma_unmap_phys_addr(struct rga_dma_buffer *buffer);
|
|
||||||
|
|
||||||
int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer,
|
int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer,
|
||||||
enum dma_data_direction dir, struct device *map_dev);
|
enum dma_data_direction dir, struct device *map_dev);
|
||||||
void rga_dma_unmap_sgt(struct rga_dma_buffer *buffer);
|
void rga_dma_unmap_sgt(struct rga_dma_buffer *buffer);
|
||||||
|
|||||||
@@ -251,32 +251,6 @@ int rga_dma_memory_check(struct rga_dma_buffer *rga_dma_buffer, struct rga_img_i
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rga_dma_map_phys_addr(phys_addr_t phys_addr, size_t size, struct rga_dma_buffer *buffer,
|
|
||||||
enum dma_data_direction dir, struct device *map_dev)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
dma_addr_t addr;
|
|
||||||
|
|
||||||
addr = dma_map_resource(map_dev, phys_addr, size, dir, 0);
|
|
||||||
ret = dma_mapping_error(map_dev, addr);
|
|
||||||
if (ret < 0) {
|
|
||||||
rga_err("dma_map_resouce failed!, ret = %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->dma_addr = addr;
|
|
||||||
buffer->dir = dir;
|
|
||||||
buffer->size = size;
|
|
||||||
buffer->map_dev = map_dev;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rga_dma_unmap_phys_addr(struct rga_dma_buffer *buffer)
|
|
||||||
{
|
|
||||||
dma_unmap_resource(buffer->map_dev, buffer->dma_addr, buffer->size, buffer->dir, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer,
|
int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer,
|
||||||
enum dma_data_direction dir, struct device *map_dev)
|
enum dma_data_direction dir, struct device *map_dev)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -160,6 +160,23 @@ static int rga_get_user_pages(struct page **pages, unsigned long Memory,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rga_get_phys_addr_pages(struct page **pages, phys_addr_t phys_addr, uint32_t page_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
phys_addr_t addr;
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(!pfn_valid(PHYS_PFN(phys_addr))))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
addr = phys_addr;
|
||||||
|
for (i = 0; i < page_count; i++) {
|
||||||
|
pages[i] = phys_to_page(addr);
|
||||||
|
addr += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void rga_free_sgt(struct sg_table **sgt_ptr)
|
static void rga_free_sgt(struct sg_table **sgt_ptr)
|
||||||
{
|
{
|
||||||
if (sgt_ptr == NULL || *sgt_ptr == NULL)
|
if (sgt_ptr == NULL || *sgt_ptr == NULL)
|
||||||
@@ -170,24 +187,21 @@ static void rga_free_sgt(struct sg_table **sgt_ptr)
|
|||||||
*sgt_ptr = NULL;
|
*sgt_ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sg_table *rga_alloc_sgt(struct rga_virt_addr *virt_addr)
|
static struct sg_table *rga_alloc_sgt(struct page **pages,
|
||||||
|
int page_count, size_t offset,
|
||||||
|
size_t size, gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sg_table *sgt = NULL;
|
struct sg_table *sgt = NULL;
|
||||||
|
|
||||||
sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
|
sgt = kzalloc(sizeof(*sgt), gfp_mask);
|
||||||
if (sgt == NULL) {
|
if (sgt == NULL) {
|
||||||
rga_err("%s alloc sgt error!\n", __func__);
|
rga_err("%s alloc sgt error!\n", __func__);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get sg form pages. */
|
/* get sg form pages. */
|
||||||
ret = sg_alloc_table_from_pages(sgt,
|
ret = sg_alloc_table_from_pages(sgt, pages, page_count, offset, size, gfp_mask);
|
||||||
virt_addr->pages,
|
|
||||||
virt_addr->page_count,
|
|
||||||
virt_addr->offset,
|
|
||||||
virt_addr->size,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
rga_err("sg_alloc_table_from_pages failed");
|
rga_err("sg_alloc_table_from_pages failed");
|
||||||
goto out_free_sgt;
|
goto out_free_sgt;
|
||||||
@@ -541,7 +555,10 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer,
|
|||||||
goto put_current_mm;
|
goto put_current_mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
sgt = rga_alloc_sgt(virt_addr);
|
sgt = rga_alloc_sgt(virt_addr->pages,
|
||||||
|
virt_addr->page_count,
|
||||||
|
virt_addr->offset,
|
||||||
|
virt_addr->size, GFP_KERNEL);
|
||||||
if (IS_ERR(sgt)) {
|
if (IS_ERR(sgt)) {
|
||||||
rga_err("alloc sgt error!\n");
|
rga_err("alloc sgt error!\n");
|
||||||
ret = PTR_ERR(sgt);
|
ret = PTR_ERR(sgt);
|
||||||
@@ -630,7 +647,8 @@ put_current_mm:
|
|||||||
static void rga_mm_unmap_phys_addr(struct rga_internal_buffer *internal_buffer)
|
static void rga_mm_unmap_phys_addr(struct rga_internal_buffer *internal_buffer)
|
||||||
{
|
{
|
||||||
if (internal_buffer->dma_buffer != NULL) {
|
if (internal_buffer->dma_buffer != NULL) {
|
||||||
rga_dma_unmap_phys_addr(internal_buffer->dma_buffer);
|
rga_dma_unmap_sgt(internal_buffer->dma_buffer);
|
||||||
|
rga_free_sgt(&internal_buffer->dma_buffer->sgt);
|
||||||
kfree(internal_buffer->dma_buffer);
|
kfree(internal_buffer->dma_buffer);
|
||||||
internal_buffer->dma_buffer = NULL;
|
internal_buffer->dma_buffer = NULL;
|
||||||
}
|
}
|
||||||
@@ -644,9 +662,13 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer,
|
|||||||
struct rga_job *job)
|
struct rga_job *job)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
phys_addr_t phys_addr;
|
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
|
size_t offset;
|
||||||
uint32_t mm_flag = 0;
|
uint32_t mm_flag = 0;
|
||||||
|
uint32_t page_count;
|
||||||
|
phys_addr_t phys_addr, phys_addr_aligned;
|
||||||
|
struct page **pages = NULL;
|
||||||
|
struct sg_table *sgt = NULL;
|
||||||
struct rga_dma_buffer *buffer = NULL;
|
struct rga_dma_buffer *buffer = NULL;
|
||||||
struct device *map_dev;
|
struct device *map_dev;
|
||||||
struct rga_scheduler_t *scheduler;
|
struct rga_scheduler_t *scheduler;
|
||||||
@@ -658,16 +680,16 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (internal_buffer->memory_parm.size)
|
if (external_buffer->memory_parm.size)
|
||||||
buffer_size = internal_buffer->memory_parm.size;
|
buffer_size = external_buffer->memory_parm.size;
|
||||||
else
|
else
|
||||||
buffer_size = rga_image_size_cal(internal_buffer->memory_parm.width,
|
buffer_size = rga_image_size_cal(external_buffer->memory_parm.width,
|
||||||
internal_buffer->memory_parm.height,
|
external_buffer->memory_parm.height,
|
||||||
internal_buffer->memory_parm.format,
|
external_buffer->memory_parm.format,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
if (buffer_size <= 0) {
|
if (buffer_size <= 0) {
|
||||||
rga_err("Failed to get phys addr size!\n");
|
rga_err("failed to calculating buffer size!\n");
|
||||||
rga_dump_memory_parm(&internal_buffer->memory_parm);
|
rga_dump_memory_parm(&external_buffer->memory_parm);
|
||||||
return buffer_size == 0 ? -EINVAL : buffer_size;
|
return buffer_size == 0 ? -EINVAL : buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,10 +705,35 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scheduler->data->mmu == RGA_IOMMU) {
|
if (scheduler->data->mmu == RGA_IOMMU) {
|
||||||
|
phys_addr_aligned = phys_addr & PAGE_MASK;
|
||||||
|
offset = phys_addr & (~PAGE_MASK);
|
||||||
|
page_count = RGA_GET_PAGE_COUNT(buffer_size + offset);
|
||||||
|
|
||||||
|
pages = vzalloc(sizeof(struct page *) * page_count);
|
||||||
|
if (pages == NULL) {
|
||||||
|
rga_err("%s can not alloc pages for phys_addr pages\n", __func__);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rga_get_phys_addr_pages(pages, phys_addr_aligned, page_count);
|
||||||
|
if (ret < 0) {
|
||||||
|
rga_err("failed to get pages from physical address: 0x%llx\n",
|
||||||
|
(unsigned long long)phys_addr);
|
||||||
|
goto free_pages;
|
||||||
|
}
|
||||||
|
|
||||||
|
sgt = rga_alloc_sgt(pages, page_count, offset, buffer_size, GFP_KERNEL);
|
||||||
|
if (IS_ERR(sgt)) {
|
||||||
|
rga_err("failed to alloc sgt\n");
|
||||||
|
ret = PTR_ERR(sgt);
|
||||||
|
goto free_pages;
|
||||||
|
}
|
||||||
|
|
||||||
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
|
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
rga_err("%s alloc internal dma buffer error!\n", __func__);
|
rga_err("%s alloc internal dma buffer error!\n", __func__);
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto free_sgt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -695,14 +742,16 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer,
|
|||||||
*/
|
*/
|
||||||
map_dev = scheduler->iommu_info ?
|
map_dev = scheduler->iommu_info ?
|
||||||
scheduler->iommu_info->default_dev : scheduler->dev;
|
scheduler->iommu_info->default_dev : scheduler->dev;
|
||||||
ret = rga_dma_map_phys_addr(phys_addr, buffer_size, buffer,
|
ret = rga_dma_map_sgt(sgt, buffer, DMA_BIDIRECTIONAL, map_dev);
|
||||||
DMA_BIDIRECTIONAL, map_dev);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
rga_err("%s core[%d] map phys_addr error!\n", __func__, scheduler->core);
|
rga_err("%s core[%d] map phys_addr error!, phys_addr = 0x%llx\n",
|
||||||
|
__func__, scheduler->core,
|
||||||
|
(unsigned long long)phys_addr);
|
||||||
goto free_dma_buffer;
|
goto free_dma_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->iova = buffer->dma_addr;
|
buffer->iova = buffer->dma_addr;
|
||||||
|
vfree(pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_buffer->dma_buffer = buffer;
|
internal_buffer->dma_buffer = buffer;
|
||||||
@@ -715,6 +764,10 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer,
|
|||||||
|
|
||||||
free_dma_buffer:
|
free_dma_buffer:
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
|
free_sgt:
|
||||||
|
rga_free_sgt(&sgt);
|
||||||
|
free_pages:
|
||||||
|
vfree(pages);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user