diff --git a/drivers/video/rockchip/iep/Makefile b/drivers/video/rockchip/iep/Makefile index 37760fbf42b7..f4dba6e9379a 100644 --- a/drivers/video/rockchip/iep/Makefile +++ b/drivers/video/rockchip/iep/Makefile @@ -1,2 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_IEP) += hw_iep_reg.o iep_drv.o iep_iommu_drm.o iep_iommu_ion.o iep_iommu_ops.o +iep-y += hw_iep_reg.o iep_drv.o iep_iommu_ops.o +iep-$(CONFIG_DRM) += iep_iommu_drm.o +obj-$(CONFIG_IEP) += iep.o diff --git a/drivers/video/rockchip/iep/iep.h b/drivers/video/rockchip/iep/iep.h index 784b77c8bed8..94e372e6a471 100644 --- a/drivers/video/rockchip/iep/iep.h +++ b/drivers/video/rockchip/iep/iep.h @@ -80,7 +80,8 @@ struct IEP_CAP { #define IEP_INFORMATION 1 #if IEP_INFORMATION -#define IEP_INFO(format, args...) printk(format, ## args) +#define IEP_INFO(format, args...) \ + printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) #else #define IEP_INFO(format, args...) #endif diff --git a/drivers/video/rockchip/iep/iep_drv.c b/drivers/video/rockchip/iep/iep_drv.c index 94dd24a76962..dc7b145d457f 100644 --- a/drivers/video/rockchip/iep/iep_drv.c +++ b/drivers/video/rockchip/iep/iep_drv.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -579,8 +578,7 @@ static void iep_service_session_clear(iep_session *session) static int iep_open(struct inode *inode, struct file *filp) { //DECLARE_WAITQUEUE(wait, current); - iep_session *session = (iep_session *)kzalloc(sizeof(iep_session), - GFP_KERNEL); + iep_session *session = kzalloc(sizeof(*session), GFP_KERNEL); if (NULL == session) { IEP_ERR("unable to allocate memory for iep_session.\n"); return -ENOMEM; @@ -660,7 +658,6 @@ static int iep_get_result_sync(iep_session *session) if (unlikely(ret < 0)) { IEP_ERR("sync pid %d wait task ret %d\n", session->pid, ret); iep_del_running_list(); - ret = ret; } else if (0 == ret) { IEP_ERR("sync pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running)); @@ -696,8 +693,7 @@ static long iep_ioctl(struct file *filp, uint32_t cmd, unsigned long arg) case IEP_SET_PARAMETER: { struct IEP_MSG *msg; - msg = (struct IEP_MSG *)kzalloc(sizeof(struct IEP_MSG), - GFP_KERNEL); + msg = kzalloc(sizeof(*msg), GFP_KERNEL); if (msg) { if (copy_from_user(msg, (struct IEP_MSG *)arg, sizeof(struct IEP_MSG))) { @@ -951,8 +947,8 @@ static int iep_drv_probe(struct platform_device *pdev) struct device *mmu_dev = NULL; of_property_read_u32(np, "iommu_enabled", &iommu_en); - data = (struct iep_drvdata *)devm_kzalloc(&pdev->dev, - sizeof(struct iep_drvdata), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(*data), + GFP_KERNEL); if (NULL == data) { IEP_ERR("failed to allocate driver data.\n"); return -ENOMEM; @@ -1171,7 +1167,6 @@ static struct platform_driver iep_driver = { .probe = iep_drv_probe, .remove = iep_drv_remove, .driver = { - .owner = THIS_MODULE, .name = "iep", #if defined(CONFIG_OF) .of_match_table = of_match_ptr(iep_dt_ids), @@ -1284,6 +1279,10 @@ MODULE_LICENSE("GPL"); #ifdef IEP_TEST_CASE +/*this test just test for iep , not test iep's iommu + *so dts need cancel iommus handle + */ + #include "yuv420sp_480x480_interlaced.h" #include "yuv420sp_480x480_deinterlaced_i2o1.h" @@ -1293,7 +1292,7 @@ void iep_test_case0(void) { struct IEP_MSG msg; iep_session session; - unsigned int phy_src, phy_dst, phy_tmp; + unsigned int phy_src, phy_tmp; int i; int ret = 0; unsigned char *tmp_buf; @@ -1313,15 +1312,21 @@ void iep_test_case0(void) memset(&msg, 0, sizeof(struct IEP_MSG)); memset(tmp_buf, 0xCC, 480 * 480 * 3 / 2); +#ifdef CONFIG_ARM + dmac_flush_range(&yuv420sp_480x480_interlaced[0], + &yuv420sp_480x480_interlaced[480 * 480 * 3 / 2]); + outer_flush_range(virt_to_phys(&yuv420sp_480x480_interlaced[0]), + virt_to_phys(&yuv420sp_480x480_interlaced[480 * 480 * 3 / 2])); + dmac_flush_range(&tmp_buf[0], &tmp_buf[480 * 480 * 3 / 2]); outer_flush_range(virt_to_phys(&tmp_buf[0]), virt_to_phys(&tmp_buf[480 * 480 * 3 / 2])); +#elif defined(CONFIG_ARM64) + __dma_flush_area(&yuv420sp_480x480_interlaced[0], 480 * 480 * 3 / 2); + __dma_flush_area(&tmp_buf[0], 480 * 480 * 3 / 2); +#endif phy_src = virt_to_phys(&yuv420sp_480x480_interlaced[0]); phy_tmp = virt_to_phys(&tmp_buf[0]); - phy_dst = virt_to_phys(&yuv420sp_480x480_deinterlaced_i2o1[0]); - - dmac_flush_range(&yuv420sp_480x480_interlaced[0], &yuv420sp_480x480_interlaced[480 * 480 * 3 / 2]); - outer_flush_range(virt_to_phys(&yuv420sp_480x480_interlaced[0]), virt_to_phys(&yuv420sp_480x480_interlaced[480 * 480 * 3 / 2])); IEP_INFO("*********** IEP MSG GENARATE ************\n"); @@ -1332,8 +1337,8 @@ void iep_test_case0(void) msg.src.vir_w = 480; msg.src.vir_h = 480; msg.src.format = IEP_FORMAT_YCbCr_420_SP; - msg.src.mem_addr = (uint32_t *)phy_src; - msg.src.uv_addr = (uint32_t *)(phy_src + 480 * 480); + msg.src.mem_addr = phy_src; + msg.src.uv_addr = (phy_src + 480 * 480); msg.src.v_addr = 0; msg.dst.act_w = 480; @@ -1343,8 +1348,8 @@ void iep_test_case0(void) msg.dst.vir_w = 480; msg.dst.vir_h = 480; msg.dst.format = IEP_FORMAT_YCbCr_420_SP; - msg.dst.mem_addr = (uint32_t *)phy_tmp; - msg.dst.uv_addr = (uint32_t *)(phy_tmp + 480 * 480); + msg.dst.mem_addr = phy_tmp; + msg.dst.uv_addr = (phy_tmp + 480 * 480); msg.dst.v_addr = 0; msg.dein_mode = IEP_DEINTERLACE_MODE_I2O1; @@ -1361,9 +1366,6 @@ void iep_test_case0(void) mdelay(10); - dmac_flush_range(&tmp_buf[0], &tmp_buf[480 * 480 * 3 / 2]); - outer_flush_range(virt_to_phys(&tmp_buf[0]), virt_to_phys(&tmp_buf[480 * 480 * 3 / 2])); - IEP_INFO("*********** RESULT CHECKING ************\n"); for (i = 0; i < 480 * 480 * 3 / 2; i++) { diff --git a/drivers/video/rockchip/iep/iep_iommu_drm.c b/drivers/video/rockchip/iep/iep_iommu_drm.c index e3c30f8a3423..8d451a60a306 100644 --- a/drivers/video/rockchip/iep/iep_iommu_drm.c +++ b/drivers/video/rockchip/iep/iep_iommu_drm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "iep_iommu_ops.h" @@ -116,12 +117,6 @@ static int iep_drm_attach_unlock(struct iep_iommu_info *iommu_info) return ret; } - if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) { - dev_err(dev, "Failed to set dma_ops\n"); - iommu_detach_device(domain, dev); - ret = -ENODEV; - } - return ret; } @@ -214,7 +209,7 @@ static int iep_drm_free(struct iep_iommu_session_info *session_info, return -EINVAL; } - if (atomic_read(&drm_buffer->ref.refcount) == 0) { + if (kref_read(&drm_buffer->ref) == 0) { dma_buf_put(drm_buffer->dma_buf); list_del_init(&drm_buffer->list); kfree(drm_buffer); @@ -302,7 +297,7 @@ iep_drm_free_fd(struct iep_iommu_session_info *session_info, int fd) iep_drm_unmap_iommu(session_info, drm_buffer->index); mutex_lock(&session_info->list_mutex); - if (atomic_read(&drm_buffer->ref.refcount) == 0) { + if (kref_read(&drm_buffer->ref) == 0) { dma_buf_put(drm_buffer->dma_buf); list_del_init(&drm_buffer->list); kfree(drm_buffer); @@ -426,7 +421,6 @@ fail_out: static int iep_drm_create(struct iep_iommu_info *iommu_info) { struct iep_iommu_drm_info *drm_info; - int ret; iommu_info->private = kzalloc(sizeof(*drm_info), GFP_KERNEL); @@ -434,25 +428,14 @@ static int iep_drm_create(struct iep_iommu_info *iommu_info) if (!drm_info) return -ENOMEM; - drm_info->domain = iommu_domain_alloc(&platform_bus_type); + drm_info->domain = iommu_get_domain_for_dev(iommu_info->dev); drm_info->attached = false; if (!drm_info->domain) { kfree(iommu_info->private); return -ENOMEM; } - ret = iommu_get_dma_cookie(drm_info->domain); - if (ret) - goto err_free_domain; - - iep_drm_attach(iommu_info); - return 0; - -err_free_domain: - iommu_domain_free(drm_info->domain); - - return ret; } static int iep_drm_destroy(struct iep_iommu_info *iommu_info) @@ -460,8 +443,6 @@ static int iep_drm_destroy(struct iep_iommu_info *iommu_info) struct iep_iommu_drm_info *drm_info = iommu_info->private; iep_drm_detach(iommu_info); - iommu_put_dma_cookie(drm_info->domain); - iommu_domain_free(drm_info->domain); kfree(drm_info); iommu_info->private = NULL; diff --git a/drivers/video/rockchip/iep/iep_iommu_ion.c b/drivers/video/rockchip/iep/iep_iommu_ion.c deleted file mode 100644 index b6a91d685d0f..000000000000 --- a/drivers/video/rockchip/iep/iep_iommu_ion.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd - * author: Jung Zhao jung.zhao@rock-chips.com - * Randy Li, randy.li@rock-chips.com - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "iep_iommu_ops.h" - -struct iep_ion_buffer { - struct list_head list; - struct ion_handle *handle; - int index; -}; - -struct iep_iommu_ion_info { - struct ion_client *ion_client; - bool attached; -}; - -static struct iep_ion_buffer * -iep_ion_get_buffer_no_lock(struct iep_iommu_session_info *session_info, - int idx) -{ - struct iep_ion_buffer *ion_buffer = NULL, *n; - - list_for_each_entry_safe(ion_buffer, n, - &session_info->buffer_list, list) { - if (ion_buffer->index == idx) - return ion_buffer; - } - - return NULL; -} - -static void -iep_ion_clear_session(struct iep_iommu_session_info *session_info) -{ - /* do nothing */ -} - -static int iep_ion_attach(struct iep_iommu_info *iommu_info) -{ - struct iep_iommu_ion_info *ion_info = iommu_info->private; - int ret; - - mutex_lock(&iommu_info->iommu_mutex); - - if (ion_info->attached) { - mutex_unlock(&iommu_info->iommu_mutex); - return 0; - } - - rockchip_iovmm_activate(iommu_info->dev); - - ion_info->attached = true; - - mutex_unlock(&iommu_info->iommu_mutex); - - return ret; -} - -static void iep_ion_detach(struct iep_iommu_info *iommu_info) -{ - struct iep_iommu_ion_info *ion_info = iommu_info->private; - - mutex_lock(&iommu_info->iommu_mutex); - - if (!ion_info->attached) { - mutex_unlock(&iommu_info->iommu_mutex); - return; - } - - rockchip_iovmm_deactivate(iommu_info->dev); - ion_info->attached = false; - - mutex_unlock(&iommu_info->iommu_mutex); -} - -static int iep_ion_destroy(struct iep_iommu_info *iommu_info) -{ - struct iep_iommu_ion_info *ion_info = iommu_info->private; - - iep_ion_detach(iommu_info); - kfree(ion_info); - iommu_info->private = NULL; - - return 0; -} - -static int -iep_ion_free(struct iep_iommu_session_info *session_info, int idx) -{ - struct iep_ion_buffer *ion_buffer; - - mutex_lock(&session_info->list_mutex); - ion_buffer = iep_ion_get_buffer_no_lock(session_info, idx); - - if (!ion_buffer) { - mutex_unlock(&session_info->list_mutex); - pr_err("%s can not find %d buffer in list\n", __func__, idx); - - return -EINVAL; - } - - list_del_init(&ion_buffer->list); - mutex_unlock(&session_info->list_mutex); - kfree(ion_buffer); - - return 0; -} - -static int -iep_ion_unmap_iommu(struct iep_iommu_session_info *session_info, int idx) -{ - struct iep_ion_buffer *ion_buffer; - struct iep_iommu_info *iommu_info = session_info->iommu_info; - struct iep_iommu_ion_info *ion_info = iommu_info->private; - - mutex_lock(&session_info->list_mutex); - ion_buffer = iep_ion_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!ion_buffer) { - pr_err("%s can not find %d buffer in list\n", __func__, idx); - - return -EINVAL; - } - - ion_free(ion_info->ion_client, ion_buffer->handle); - - return 0; -} - -static int -iep_ion_map_iommu(struct iep_iommu_session_info *session_info, int idx, - unsigned long *iova, unsigned long *size) -{ - struct iep_ion_buffer *ion_buffer; - struct device *dev = session_info->dev; - struct iep_iommu_info *iommu_info = session_info->iommu_info; - struct iep_iommu_ion_info *ion_info = iommu_info->private; - int ret = 0; - - /* Force to flush iommu table */ - rockchip_iovmm_invalidate_tlb(session_info->dev); - - mutex_lock(&session_info->list_mutex); - ion_buffer = iep_ion_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!ion_buffer) { - pr_err("%s can not find %d buffer in list\n", __func__, idx); - - return -EINVAL; - } - - if (session_info->mmu_dev) - ret = ion_map_iommu(dev, ion_info->ion_client, - ion_buffer->handle, iova, size); - else - ret = ion_phys(ion_info->ion_client, ion_buffer->handle, - iova, (size_t *)size); - - return ret; -} - -static int -iep_ion_import(struct iep_iommu_session_info *session_info, int fd) -{ - struct iep_ion_buffer *ion_buffer = NULL; - struct iep_iommu_info *iommu_info = session_info->iommu_info; - struct iep_iommu_ion_info *ion_info = iommu_info->private; - - ion_buffer = kzalloc(sizeof(*ion_buffer), GFP_KERNEL); - if (!ion_buffer) - return -ENOMEM; - - ion_buffer->handle = ion_import_dma_buf(ion_info->ion_client, fd); - - INIT_LIST_HEAD(&ion_buffer->list); - mutex_lock(&session_info->list_mutex); - ion_buffer->index = session_info->max_idx; - list_add_tail(&ion_buffer->list, &session_info->buffer_list); - session_info->max_idx++; - if ((session_info->max_idx & 0xfffffff) == 0) - session_info->max_idx = 0; - mutex_unlock(&session_info->list_mutex); - - return ion_buffer->index; -} - -static int iep_ion_create(struct iep_iommu_info *iommu_info) -{ - struct iep_iommu_ion_info *ion_info; - - iommu_info->private = kmalloc(sizeof(*ion_info), GFP_KERNEL); - - ion_info = iommu_info->private; - if (!ion_info) - return -ENOMEM; - - ion_info->ion_client = rockchip_ion_client_create("vpu"); - ion_info->attached = false; - - iep_ion_attach(iommu_info); - - return IS_ERR(ion_info->ion_client) ? -1 : 0; -} - -static struct iep_iommu_ops ion_ops = { - .create = iep_ion_create, - .destroy = iep_ion_destroy, - .import = iep_ion_import, - .free = iep_ion_free, - .free_fd = NULL, - .map_iommu = iep_ion_map_iommu, - .unmap_iommu = iep_ion_unmap_iommu, - .dump = NULL, - .attach = iep_ion_attach, - .detach = iep_ion_detach, - .clear = iep_ion_clear_session, -}; - -/* - * we do not manage the ref number ourselves, - * since ion will help us to do that. what we - * need to do is just map/unmap and import/free - * every time - */ -void iep_iommu_ion_set_ops(struct iep_iommu_info *iommu_info) -{ - if (!iommu_info) - return; - iommu_info->ops = &ion_ops; -} diff --git a/drivers/video/rockchip/iep/iep_iommu_ops.c b/drivers/video/rockchip/iep/iep_iommu_ops.c index 36c4815f1660..e84772237b89 100644 --- a/drivers/video/rockchip/iep/iep_iommu_ops.c +++ b/drivers/video/rockchip/iep/iep_iommu_ops.c @@ -35,7 +35,7 @@ struct iep_iommu_session_info *iep_iommu_get_session_info int iep_iommu_create(struct iep_iommu_info *iommu_info) { - if (!iommu_info || !iommu_info->ops->create) + if (!iommu_info || !iommu_info->ops || !iommu_info->ops->create) return -EINVAL; return iommu_info->ops->create(iommu_info); @@ -46,7 +46,8 @@ int iep_iommu_import(struct iep_iommu_info *iommu_info, { struct iep_iommu_session_info *session_info = NULL; - if (!iommu_info || !iommu_info->ops->import || !session) + if (!iommu_info || !iommu_info->ops || + !iommu_info->ops->import || !session) return -EINVAL; session_info = iep_iommu_get_session_info(iommu_info, session); @@ -84,7 +85,7 @@ int iep_iommu_free(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->free || !session_info) + if (!iommu_info->ops || !iommu_info->ops->free || !session_info) return -EINVAL; return iommu_info->ops->free(session_info, idx); @@ -100,7 +101,7 @@ int iep_iommu_free_fd(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->free_fd || !session_info) + if (!iommu_info->ops || !iommu_info->ops->free_fd || !session_info) return -EINVAL; return iommu_info->ops->free_fd(session_info, fd); @@ -118,7 +119,7 @@ int iep_iommu_map_iommu(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->map_iommu || !session_info) + if (!iommu_info->ops || !iommu_info->ops->map_iommu || !session_info) return -EINVAL; return iommu_info->ops->map_iommu(session_info, idx, iova, size); @@ -134,7 +135,7 @@ int iep_iommu_unmap_iommu(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->unmap_iommu || !session_info) + if (!iommu_info->ops || !iommu_info->ops->unmap_iommu || !session_info) return -EINVAL; return iommu_info->ops->unmap_iommu(session_info, idx); @@ -142,7 +143,7 @@ int iep_iommu_unmap_iommu(struct iep_iommu_info *iommu_info, int iep_iommu_destroy(struct iep_iommu_info *iommu_info) { - if (!iommu_info || !iommu_info->ops->destroy) + if (!iommu_info || !iommu_info->ops || !iommu_info->ops->destroy) return -EINVAL; return iommu_info->ops->destroy(iommu_info); @@ -158,7 +159,7 @@ void iep_iommu_dump(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->dump || !session_info) + if (!iommu_info->ops || !iommu_info->ops->dump || !session_info) return; iommu_info->ops->dump(session_info); @@ -174,7 +175,7 @@ void iep_iommu_clear(struct iep_iommu_info *iommu_info, session_info = iep_iommu_get_session_info(iommu_info, session); - if (!iommu_info->ops->clear || !session_info) + if (!iommu_info->ops || !iommu_info->ops->clear || !session_info) return; iommu_info->ops->clear(session_info); @@ -187,7 +188,7 @@ void iep_iommu_clear(struct iep_iommu_info *iommu_info, int iep_iommu_attach(struct iep_iommu_info *iommu_info) { - if (!iommu_info || !iommu_info->ops->attach) + if (!iommu_info || !iommu_info->ops || !iommu_info->ops->attach) return 0; return iommu_info->ops->attach(iommu_info); @@ -195,7 +196,7 @@ int iep_iommu_attach(struct iep_iommu_info *iommu_info) void iep_iommu_detach(struct iep_iommu_info *iommu_info) { - if (!iommu_info || !iommu_info->ops->detach) + if (!iommu_info || !iommu_info->ops || !iommu_info->ops->detach) return; return iommu_info->ops->detach(iommu_info); @@ -221,11 +222,6 @@ iep_iommu_info_create(struct device *dev, case ALLOCATOR_USE_DRM: iep_iommu_drm_set_ops(iommu_info); break; -#endif -#ifdef CONFIG_ION - case ALLOCATOR_USE_ION: - iep_iommu_ion_set_ops(iommu_info); - break; #endif default: iommu_info->ops = NULL; diff --git a/drivers/video/rockchip/iep/iep_iommu_ops.h b/drivers/video/rockchip/iep/iep_iommu_ops.h index 09f33fd5139c..de92f5c67428 100644 --- a/drivers/video/rockchip/iep/iep_iommu_ops.h +++ b/drivers/video/rockchip/iep/iep_iommu_ops.h @@ -89,9 +89,6 @@ struct iep_iommu_info { #ifdef CONFIG_DRM void iep_iommu_drm_set_ops(struct iep_iommu_info *iommu_info); #endif -#ifdef CONFIG_ION -void iep_iommu_ion_set_ops(struct iep_iommu_info *iommu_info); -#endif struct iep_iommu_info *iep_iommu_info_create(struct device *dev, struct device *mmu_dev,