From c653aafaf9c2ea062b09b25fc3f286313e6278fd Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Mon, 18 Nov 2019 14:20:37 +0800 Subject: [PATCH] video: rockchip: remove unused vcodec driver Change-Id: Ibc186e02c2e3d390056fd79066e27af61233798e Signed-off-by: Tao Huang --- drivers/video/rockchip/vcodec/Kconfig | 10 - drivers/video/rockchip/vcodec/Makefile | 12 - .../video/rockchip/vcodec/vcodec_hw_info.h | 250 -- drivers/video/rockchip/vcodec/vcodec_hw_rkv.h | 239 - drivers/video/rockchip/vcodec/vcodec_hw_vpu.h | 336 -- .../video/rockchip/vcodec/vcodec_hw_vpu2.h | 293 -- .../video/rockchip/vcodec/vcodec_iommu_drm.c | 982 ---- .../video/rockchip/vcodec/vcodec_iommu_ion.c | 332 -- .../video/rockchip/vcodec/vcodec_iommu_ops.c | 331 -- .../video/rockchip/vcodec/vcodec_iommu_ops.h | 149 - .../video/rockchip/vcodec/vcodec_service.c | 3941 ----------------- .../video/rockchip/vcodec/vcodec_service.h | 68 - include/uapi/video/rk_vpu_service.h | 101 - 13 files changed, 7044 deletions(-) delete mode 100644 drivers/video/rockchip/vcodec/Kconfig delete mode 100644 drivers/video/rockchip/vcodec/Makefile delete mode 100644 drivers/video/rockchip/vcodec/vcodec_hw_info.h delete mode 100644 drivers/video/rockchip/vcodec/vcodec_hw_rkv.h delete mode 100644 drivers/video/rockchip/vcodec/vcodec_hw_vpu.h delete mode 100644 drivers/video/rockchip/vcodec/vcodec_hw_vpu2.h delete mode 100644 drivers/video/rockchip/vcodec/vcodec_iommu_drm.c delete mode 100644 drivers/video/rockchip/vcodec/vcodec_iommu_ion.c delete mode 100644 drivers/video/rockchip/vcodec/vcodec_iommu_ops.c delete mode 100644 drivers/video/rockchip/vcodec/vcodec_iommu_ops.h delete mode 100644 drivers/video/rockchip/vcodec/vcodec_service.c delete mode 100644 drivers/video/rockchip/vcodec/vcodec_service.h delete mode 100644 include/uapi/video/rk_vpu_service.h diff --git a/drivers/video/rockchip/vcodec/Kconfig b/drivers/video/rockchip/vcodec/Kconfig deleted file mode 100644 index ea898cc994e9..000000000000 --- a/drivers/video/rockchip/vcodec/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -menu "VCODEC" - depends on ARCH_ROCKCHIP - -config RK_VCODEC - tristate "VCODEC (VPU HEVC) service driver in kernel" - depends on ARCH_ROCKCHIP - default n - -endmenu diff --git a/drivers/video/rockchip/vcodec/Makefile b/drivers/video/rockchip/vcodec/Makefile deleted file mode 100644 index a327742a271b..000000000000 --- a/drivers/video/rockchip/vcodec/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -rk-vcodec-objs := vcodec_service.o vcodec_iommu_ops.o - -ifdef CONFIG_DRM -rk-vcodec-objs += vcodec_iommu_drm.o -endif - -ifdef CONFIG_ION -rk-vcodec-objs += vcodec_iommu_ion.o -endif - -obj-$(CONFIG_RK_VCODEC) += rk-vcodec.o diff --git a/drivers/video/rockchip/vcodec/vcodec_hw_info.h b/drivers/video/rockchip/vcodec/vcodec_hw_info.h deleted file mode 100644 index 003ac331050e..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_hw_info.h +++ /dev/null @@ -1,250 +0,0 @@ -/** - * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd - * author: Herman Chen herman.chen@rock-chips.com - * Alpha Lin, alpha.lin@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. - * - */ - -#ifndef __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_INFO_H -#define __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_INFO_H - -/* - * Hardware id is for hardware detection - * Driver will read the hardware ID register first, then try to find a mactch - * hardware from the enum ID below. - */ -enum VPU_HW_ID { - VPU_DEC_ID_9190 = 0x6731, - VPU_ID_8270 = 0x8270, - VPU_ID_4831 = 0x4831, - HEVC_ID = 0x6867, - RKV_DEC_ID = 0x6876, - RKV_DEC_ID2 = 0x3410, - VPU2_ID = 0x0000, -}; - -/* - * Different hardware has different feature. So we catalogue these features - * into three class: - * - * 1. register io feature determined by hardware type - * including register offset, register file size, etc - * - * 2. runtime register config feature determined by task type - * including irq / enable / length register, bit mask, etc - * - * 3. file handle translate feature determined by vcodec format type - * register translation map table - * - * These three type features composite a complete codec information structure - */ - -/* VPU1 and VPU2 */ -#define VCODEC_DEVICE_TYPE_VPUX 0x56505558 -/* VPU Combo */ -#define VCODEC_DEVICE_TYPE_VPUC 0x56505543 -#define VCODEC_DEVICE_TYPE_HEVC 0x56505532 -#define VCODEC_DEVICE_TYPE_RKVD 0x524B5644 - -enum TASK_TYPE { - TASK_ENC, - TASK_DEC, - TASK_PP, - TASK_DEC_PP, - TASK_TYPE_BUTT, -}; - -enum FORMAT_TYPE { - FMT_DEC_BASE = 0, - FMT_JPEGD = FMT_DEC_BASE, - - FMT_H263D, - FMT_H264D, - FMT_H265D, - - FMT_MPEG1D, - FMT_MPEG2D, - FMT_MPEG4D, - - FMT_VP6D, - FMT_VP7D, - FMT_VP8D, - FMT_VP9D, - - FMT_VC1D, - FMT_AVSD, - - FMT_DEC_BUTT, - - FMT_PP_BASE = FMT_DEC_BUTT, - FMT_PP = FMT_PP_BASE, - FMT_PP_BUTT, - - FMT_ENC_BASE = FMT_PP_BUTT, - FMT_JPEGE = FMT_ENC_BASE, - - FMT_H264E, - - FMT_VP8E, - - FMT_ENC_BUTT, - FMT_TYPE_BUTT = FMT_ENC_BUTT, -}; - -/** - * struct for hardware task operation - */ -struct vpu_hw_info { - enum VPU_HW_ID hw_id; - u32 enc_offset; - u32 enc_reg_num; - u32 enc_io_size; - - u32 dec_offset; - u32 dec_reg_num; - u32 dec_io_size; - - /* - * register range for enc/dec/pp/dec_pp - * base/end of dec/pp/dec_pp specify the register range to config - */ - u32 base_dec; - u32 base_pp; - u32 base_dec_pp; - u32 end_dec; - u32 end_pp; - u32 end_dec_pp; -}; - -struct vpu_task_info { - char *name; - struct timeval start; - struct timeval end; - - /* - * input stream register - * use for map/unmap drm buffer for avoiding - * cache sync issue - */ - int reg_rlc; - /* - * task enable register - * use for enable hardware task process - * -1 for invalid - */ - int reg_en; - - /* register of task auto gating, alway valid */ - int reg_gating; - - /* register of task irq, alway valid */ - int reg_irq; - - /* - * stream length register - * only valid for decoder task - * -1 for invalid (encoder) - */ - int reg_len; - - /* - * direct mv register - * special offset scale, offset multiply by 16 - * - * valid on vpu & vpu2 - * -1 for invalid - */ - int reg_dir_mv; - - /* - * pps register - * special register for scaling list address process - * - * valid on rkv - * -1 for invalid - */ - int reg_pps; - - /* - * soft reset register - * special register for soft reset - * valid on vpu & vpu2 & rkv - */ - int reg_reset; - - /* - * decoder pipeline mode register - * - * valid on vpu & vpu2 - * -1 for invalid - */ - int reg_pipe; - - /* task enable bit mask for enable register */ - u32 enable_mask; - - /* task auto gating mask for enable register */ - u32 gating_mask; - - /* task pipeline mode mask for pipe register */ - u32 pipe_mask; - - /* task inturrpt bit mask for irq register */ - u32 irq_mask; - - /* task ready bit mask for irq register */ - u32 ready_mask; - - /* task error bit mask for irq register */ - u32 error_mask; - - /* task reset bit mask for reset register */ - u32 reset_mask; - - enum FORMAT_TYPE (*get_fmt)(u32 *regs); -}; - -struct vpu_trans_info { - const size_t count; - const char * const table; -}; - -struct vcodec_info { - enum VPU_HW_ID hw_id; - struct vpu_hw_info *hw_info; - struct vpu_task_info *task_info; - const struct vpu_trans_info *trans_info; -}; - -struct vcodec_device_info { - s32 device_type; - s8 *name; -}; - -#define DEF_FMT_TRANS_TBL(fmt, args...) \ - static const char trans_tbl_##fmt[] = { \ - args \ - } - -#define SETUP_FMT_TBL(id, fmt) \ - [id] = { \ - .count = sizeof(trans_tbl_##fmt), \ - .table = trans_tbl_##fmt, \ - } - -#define EMPTY_FMT_TBL(id) \ - [id] = { \ - .count = 0, \ - .table = NULL, \ - } - -#endif diff --git a/drivers/video/rockchip/vcodec/vcodec_hw_rkv.h b/drivers/video/rockchip/vcodec/vcodec_hw_rkv.h deleted file mode 100644 index 30e9aea2d866..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_hw_rkv.h +++ /dev/null @@ -1,239 +0,0 @@ -/** - * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd - * author: chenhengming chm@rock-chips.com - * Alpha Lin, alpha.lin@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. - * - */ - -#ifndef __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_RKV_H -#define __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_RKV_H - -#include "vcodec_hw_info.h" - -/* hardware information */ -#define REG_NUM_HEVC_DEC (68) -#define REG_NUM_RKV_DEC (78) - -/* enable and gating register */ -#define RKV_REG_EN_DEC 1 -#define RKV_REG_DEC_GATING_BIT BIT(1) - -/* interrupt and error status register */ -#define HEVC_INTERRUPT_REGISTER 1 -#define HEVC_INTERRUPT_BIT BIT(8) -#define HEVC_DEC_INT_RAW_BIT BIT(9) -#define HEVC_READY_BIT BIT(12) -#define HEVC_DEC_BUS_ERROR_BIT BIT(13) -#define HEVC_DEC_STR_ERROR_BIT BIT(14) -#define HEVC_DEC_TIMEOUT_BIT BIT(15) -#define HEVC_DEC_BUFFER_EMPTY_BIT BIT(16) -#define HEVC_DEC_COLMV_ERROR_BIT BIT(17) -#define HEVC_DEC_ERR_MASK (HEVC_DEC_BUS_ERROR_BIT \ - | HEVC_DEC_STR_ERROR_BIT \ - | HEVC_DEC_TIMEOUT_BIT \ - | HEVC_DEC_BUFFER_EMPTY_BIT \ - | HEVC_DEC_COLMV_ERROR_BIT) - -#define RKV_DEC_INTERRUPT_REGISTER 1 -#define RKV_DEC_INTERRUPT_BIT BIT(8) -#define RKV_DEC_INT_RAW_BIT BIT(9) -#define RKV_DEC_READY_BIT BIT(12) -#define RKV_DEC_BUS_ERROR_BIT BIT(13) -#define RKV_DEC_STR_ERROR_BIT BIT(14) -#define RKV_DEC_TIMEOUT_BIT BIT(15) -#define RKV_DEC_BUFFER_EMPTY_BIT BIT(16) -#define RKV_DEC_COLMV_ERROR_BIT BIT(17) -#define RKV_DEC_ERR_MASK (RKV_DEC_BUS_ERROR_BIT \ - | RKV_DEC_STR_ERROR_BIT \ - | RKV_DEC_TIMEOUT_BIT \ - | RKV_DEC_BUFFER_EMPTY_BIT \ - | RKV_DEC_COLMV_ERROR_BIT) - -/* enable and soft reset register */ -#define RKV_REG_DEC_RESET 1 -#define RKV_REG_DEC_RESET_BIT BIT(20) - -static const enum FORMAT_TYPE rkv_dec_fmt_tbl[] = { - [0] = FMT_H265D, - [1] = FMT_H264D, - [2] = FMT_VP9D, - [3] = FMT_TYPE_BUTT, -}; - -static enum FORMAT_TYPE rkv_dec_get_fmt(u32 *regs) -{ - u32 fmt_id = (regs[2] >> 20) & 0x3; - enum FORMAT_TYPE type = rkv_dec_fmt_tbl[fmt_id]; - return type; -} - -static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = { - { - .name = "invalid", - .reg_en = 0, - .reg_irq = 0, - .reg_len = 0, - .reg_dir_mv = 0, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = 0, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = 0, - .irq_mask = 0, - .ready_mask = 0, - .error_mask = 0, - .reset_mask = 0, - .get_fmt = NULL, - }, - { - .name = "rkvdec", - .reg_rlc = 4, - .reg_en = RKV_REG_EN_DEC, - .reg_irq = RKV_DEC_INTERRUPT_REGISTER, - .reg_len = 4, - .reg_dir_mv = 52, - .reg_pps = 42, - .reg_reset = RKV_REG_DEC_RESET, - .reg_pipe = 0, - .enable_mask = 0, - .gating_mask = RKV_REG_DEC_GATING_BIT, - .irq_mask = HEVC_INTERRUPT_BIT, - .pipe_mask = 0, - .ready_mask = HEVC_READY_BIT, - .error_mask = HEVC_DEC_ERR_MASK, - .reset_mask = RKV_REG_DEC_RESET_BIT, - .get_fmt = rkv_dec_get_fmt, - }, - { - .name = "invalid", - .reg_en = 0, - .reg_irq = 0, - .reg_len = 0, - .reg_dir_mv = 0, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = 0, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = 0, - .irq_mask = 0, - .ready_mask = 0, - .error_mask = 0, - .reset_mask = 0, - .get_fmt = NULL, - }, - { - .name = "invalid", - .reg_en = 0, - .reg_irq = 0, - .reg_len = 0, - .reg_dir_mv = 0, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = 0, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = 0, - .irq_mask = 0, - .ready_mask = 0, - .error_mask = 0, - .reset_mask = 0, - .get_fmt = NULL, - },}; - -static struct vpu_hw_info hw_rkhevc = { - .hw_id = HEVC_ID, - - .enc_offset = 0, - .enc_reg_num = 0, - .enc_io_size = 0, - - .dec_offset = 0, - .dec_reg_num = REG_NUM_HEVC_DEC, - .dec_io_size = REG_NUM_HEVC_DEC * 4, - - /* NOTE: can not write to register 0 */ - .base_dec = 1, - .base_pp = 0, - .base_dec_pp = 0, - .end_dec = REG_NUM_HEVC_DEC, - .end_pp = 0, - .end_dec_pp = 0, -}; - -static struct vpu_hw_info hw_rkvdec = { - .hw_id = RKV_DEC_ID, - - .enc_offset = 0, - .enc_reg_num = 0, - .enc_io_size = 0, - - .dec_offset = 0x0, - .dec_reg_num = REG_NUM_RKV_DEC, - .dec_io_size = REG_NUM_RKV_DEC * 4, - - /* NOTE: can not write to register 0 */ - .base_dec = 1, - .base_pp = 0, - .base_dec_pp = 0, - .end_dec = REG_NUM_RKV_DEC, - .end_pp = 0, - .end_dec_pp = 0, -}; - -/* - * file handle translate information - */ -DEF_FMT_TRANS_TBL(rkv_h264d, - 4, 6, 7, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 41, 42, 43, 48, 75 -); - -DEF_FMT_TRANS_TBL(rkv_h265d, - 4, 6, 7, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 42, 43 -); - -DEF_FMT_TRANS_TBL(rkv_vp9d, - 4, 6, 7, 11, 12, 13, 14, 15, - 16, 52 -); - -const struct vpu_trans_info trans_rkv[FMT_TYPE_BUTT] = { - EMPTY_FMT_TBL(FMT_JPEGD), - EMPTY_FMT_TBL(FMT_H263D), - SETUP_FMT_TBL(FMT_H264D, rkv_h264d), - SETUP_FMT_TBL(FMT_H265D, rkv_h265d), - - EMPTY_FMT_TBL(FMT_MPEG1D), - EMPTY_FMT_TBL(FMT_MPEG2D), - EMPTY_FMT_TBL(FMT_MPEG4D), - - EMPTY_FMT_TBL(FMT_VP6D), - EMPTY_FMT_TBL(FMT_VP7D), - EMPTY_FMT_TBL(FMT_VP8D), - SETUP_FMT_TBL(FMT_VP9D, rkv_vp9d), - - EMPTY_FMT_TBL(FMT_PP), - - EMPTY_FMT_TBL(FMT_VC1D), - EMPTY_FMT_TBL(FMT_AVSD), - - EMPTY_FMT_TBL(FMT_JPEGE), - EMPTY_FMT_TBL(FMT_H264E), - EMPTY_FMT_TBL(FMT_VP8E), -}; - -#endif diff --git a/drivers/video/rockchip/vcodec/vcodec_hw_vpu.h b/drivers/video/rockchip/vcodec/vcodec_hw_vpu.h deleted file mode 100644 index 3b5eeb35c919..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_hw_vpu.h +++ /dev/null @@ -1,336 +0,0 @@ -/** - * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd - * author: chenhengming chm@rock-chips.com - * Alpha Lin, alpha.lin@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. - * - */ - -#ifndef __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_VPU_H -#define __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_VPU_H - -#include "vcodec_hw_info.h" - -/* hardware information */ -#define REG_NUM_9190_DEC (60) -#define REG_NUM_9190_PP (41) -#define REG_NUM_9190_DEC_PP (REG_NUM_9190_DEC + REG_NUM_9190_PP) - -#define REG_NUM_DEC_PP (REG_NUM_9190_DEC + REG_NUM_9190_PP) - -#define REG_NUM_ENC_8270 (96) -#define REG_SIZE_ENC_8270 (0x200) -#define REG_NUM_ENC_4831 (164) -#define REG_SIZE_ENC_4831 (0x400) - -/* enable and gating register */ -#define VPU_REG_EN_ENC 14 -#define VPU_REG_ENC_GATE 2 -#define VPU_REG_ENC_GATE_BIT BIT(4) - -#define VPU_REG_EN_DEC 1 -#define VPU_REG_DEC_GATE 2 -#define VPU_REG_DEC_GATE_BIT BIT(10) -#define VPU_REG_EN_PP 0 -#define VPU_REG_PP_GATE 1 -#define VPU_REG_PP_GATE_BIT BIT(8) -#define VPU_REG_EN_DEC_PP 1 -#define VPU_REG_DEC_PP_GATE 61 -#define VPU_REG_DEC_PP_GATE_BIT BIT(8) - -/* interrupt and error status register */ -#define VPU_DEC_INTERRUPT_REGISTER 1 -#define VPU_DEC_INTERRUPT_BIT BIT(8) -#define VPU_DEC_READY_BIT BIT(12) -#define VPU_DEC_BUS_ERROR_BIT BIT(13) -#define VPU_DEC_BUFFER_EMPTY_BIT BIT(14) -#define VPU_DEC_ASO_ERROR_BIT BIT(15) -#define VPU_DEC_STREAM_ERROR_BIT BIT(16) -#define VPU_DEC_SLICE_DONE_BIT BIT(17) -#define VPU_DEC_TIMEOUT_BIT BIT(18) -#define VPU_DEC_ERR_MASK (VPU_DEC_BUS_ERROR_BIT \ - | VPU_DEC_BUFFER_EMPTY_BIT \ - | VPU_DEC_STREAM_ERROR_BIT \ - | VPU_DEC_TIMEOUT_BIT) - -/* enable and soft reset register*/ -#define VPU_REG_DEC_RESET 101 -#define VPU_REG_DEC_RESET_BIT BIT(0) - -#define VPU_PP_INTERRUPT_REGISTER 60 -#define VPU_PP_PIPELINE_MODE_BIT BIT(1) -#define VPU_PP_INTERRUPT_BIT BIT(8) -#define VPU_PP_READY_BIT BIT(12) -#define VPU_PP_BUS_ERROR_BIT BIT(13) -#define VPU_PP_ERR_MASK VPU_PP_BUS_ERROR_BIT - -#define VPU_ENC_INTERRUPT_REGISTER 1 -#define VPU_ENC_INTERRUPT_BIT BIT(0) -#define VPU_ENC_READY_BIT BIT(2) -#define VPU_ENC_BUS_ERROR_BIT BIT(3) -#define VPU_ENC_BUFFER_FULL_BIT BIT(5) -#define VPU_ENC_TIMEOUT_BIT BIT(6) -#define VPU_ENC_ERR_MASK (VPU_ENC_BUS_ERROR_BIT \ - | VPU_ENC_BUFFER_FULL_BIT \ - | VPU_ENC_TIMEOUT_BIT) - -static const enum FORMAT_TYPE vpu_dec_fmt_tbl[] = { - [0] = FMT_H264D, - [1] = FMT_MPEG4D, - [2] = FMT_H263D, - [3] = FMT_JPEGD, - [4] = FMT_VC1D, - [5] = FMT_MPEG2D, - [6] = FMT_MPEG1D, - [7] = FMT_VP6D, - [8] = FMT_TYPE_BUTT, - [9] = FMT_VP7D, - [10] = FMT_VP8D, - [11] = FMT_AVSD, - [12] = FMT_TYPE_BUTT, - [13] = FMT_TYPE_BUTT, - [14] = FMT_TYPE_BUTT, - [15] = FMT_TYPE_BUTT, -}; - -static enum FORMAT_TYPE vpu_dec_get_fmt(u32 *regs) -{ - u32 fmt_id = (regs[3] >> 28) & 0xf; - enum FORMAT_TYPE type = vpu_dec_fmt_tbl[fmt_id]; - return type; -} - -static enum FORMAT_TYPE vpu_pp_get_fmt(u32 *regs) -{ - return FMT_PP; -} - -static const enum FORMAT_TYPE vpu_enc_fmt_tbl[] = { - [0] = FMT_TYPE_BUTT, - [1] = FMT_VP8E, - [2] = FMT_JPEGE, - [3] = FMT_H264E, -}; - -static enum FORMAT_TYPE vpu_enc_get_fmt(u32 *regs) -{ - u32 fmt_id = (regs[VPU_REG_EN_ENC] >> 1) & 0x3; - enum FORMAT_TYPE type = vpu_enc_fmt_tbl[fmt_id]; - return type; -} - -static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = { - { - .name = "vpu_enc", - .reg_rlc = 11, - .reg_en = VPU_REG_EN_ENC, - .reg_irq = VPU_ENC_INTERRUPT_REGISTER, - .reg_len = -1, - .reg_dir_mv = -1, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = -1, - .enable_mask = 0x6, - .gating_mask = 0, - .pipe_mask = 0, - .irq_mask = VPU_ENC_INTERRUPT_BIT, - .ready_mask = VPU_ENC_READY_BIT, - .error_mask = VPU_ENC_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu_enc_get_fmt, - }, - { - .name = "vpu_dec", - .reg_rlc = 12, - .reg_en = VPU_REG_EN_DEC, - .reg_irq = VPU_DEC_INTERRUPT_REGISTER, - .reg_len = 12, - .reg_dir_mv = 41, - .reg_pps = -1, - .reg_reset = VPU_REG_DEC_RESET, - .reg_pipe = VPU_PP_INTERRUPT_REGISTER, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = VPU_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU_DEC_INTERRUPT_BIT, - .ready_mask = VPU_DEC_READY_BIT, - .error_mask = VPU_DEC_ERR_MASK, - .reset_mask = VPU_REG_DEC_RESET_BIT, - .get_fmt = vpu_dec_get_fmt, - }, - { - .name = "vpu_pp", - .reg_en = VPU_REG_EN_PP, - .reg_irq = VPU_PP_INTERRUPT_REGISTER, - .reg_len = -1, - .reg_dir_mv = -1, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = VPU_PP_INTERRUPT_REGISTER, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = VPU_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU_PP_INTERRUPT_BIT, - .ready_mask = VPU_PP_READY_BIT, - .error_mask = VPU_PP_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu_pp_get_fmt, - }, - { - .name = "vpu_dec_pp", - .reg_rlc = 12, - .reg_en = VPU_REG_EN_DEC, - .reg_irq = VPU_DEC_INTERRUPT_REGISTER, - .reg_len = 12, - .reg_dir_mv = 41, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = VPU_PP_INTERRUPT_REGISTER, - .enable_mask = 0, - .gating_mask = 0, - .pipe_mask = VPU_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU_DEC_INTERRUPT_BIT, - .ready_mask = VPU_DEC_READY_BIT, - .error_mask = VPU_DEC_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu_dec_get_fmt, - }, -}; - -static struct vpu_hw_info hw_vpu_8270 = { - .hw_id = VPU_ID_8270, - - .enc_offset = 0x0, - .enc_reg_num = REG_NUM_ENC_8270, - .enc_io_size = REG_NUM_ENC_8270 * 4, - - .dec_offset = REG_SIZE_ENC_8270, - .dec_reg_num = REG_NUM_9190_DEC_PP, - .dec_io_size = REG_NUM_9190_DEC_PP * 4, - - .base_dec = 0, - .base_pp = VPU_PP_INTERRUPT_REGISTER, - .base_dec_pp = 0, - .end_dec = REG_NUM_9190_DEC, - .end_pp = REG_NUM_9190_DEC_PP, - .end_dec_pp = REG_NUM_9190_DEC_PP, -}; - -static struct vpu_hw_info hw_vpu_4831 = { - .hw_id = VPU_ID_4831, - - .enc_offset = 0x0, - .enc_reg_num = REG_NUM_ENC_4831, - .enc_io_size = REG_NUM_ENC_4831 * 4, - - .dec_offset = REG_SIZE_ENC_4831, - .dec_reg_num = REG_NUM_9190_DEC_PP, - .dec_io_size = REG_NUM_9190_DEC_PP * 4, - - .base_dec = 0, - .base_pp = VPU_PP_INTERRUPT_REGISTER, - .base_dec_pp = 0, - .end_dec = REG_NUM_9190_DEC, - .end_pp = REG_NUM_9190_DEC_PP, - .end_dec_pp = REG_NUM_9190_DEC_PP, -}; - -static struct vpu_hw_info hw_vpu_9190 = { - .hw_id = VPU_DEC_ID_9190, - - .enc_offset = 0x0, - .enc_reg_num = 0, - .enc_io_size = 0, - - .dec_offset = 0, - .dec_reg_num = REG_NUM_9190_DEC_PP, - .dec_io_size = REG_NUM_9190_DEC_PP * 4, - - .base_dec = 0, - .base_pp = VPU_PP_INTERRUPT_REGISTER, - .base_dec_pp = 0, - .end_dec = REG_NUM_9190_DEC, - .end_pp = REG_NUM_9190_DEC_PP, - .end_dec_pp = REG_NUM_9190_DEC_PP, -}; - -/* - * file handle translate information - */ -DEF_FMT_TRANS_TBL(vpu_jpegd, - 12, 13, 14, 40, 66, 67 -); - -DEF_FMT_TRANS_TBL(vpu_h264d, - 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 40, 41 -); - -DEF_FMT_TRANS_TBL(vpu_vp6d, - 12, 13, 14, 18, 27, 40 -); - -DEF_FMT_TRANS_TBL(vpu_vp8d, - 10, 12, 13, 14, 18, 19, 22, 23, - 24, 25, 26, 27, 28, 29, 40 -); - -DEF_FMT_TRANS_TBL(vpu_vc1d, - 12, 13, 14, 15, 16, 17, 27, 41 -); - -DEF_FMT_TRANS_TBL(vpu_avsd, - 12, 13, 14, 15, 16, 17, 40, 41, 45 -); - -DEF_FMT_TRANS_TBL(vpu_defaultd, - 12, 13, 14, 15, 16, 17, 40, 41 -); - -DEF_FMT_TRANS_TBL(vpu_default_pp, - 63, 64, 65, 66, 67, 73, 74 -); - -DEF_FMT_TRANS_TBL(vpu_vp8e, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 26, 51, 52, 58, 59 -); - -DEF_FMT_TRANS_TBL(vpu_defaulte, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 51 -); - -static const struct vpu_trans_info trans_vpu[FMT_TYPE_BUTT] = { - SETUP_FMT_TBL(FMT_JPEGD, vpu_jpegd), - SETUP_FMT_TBL(FMT_H263D, vpu_defaultd), - SETUP_FMT_TBL(FMT_H264D, vpu_h264d), - EMPTY_FMT_TBL(FMT_H265D), - - SETUP_FMT_TBL(FMT_MPEG1D, vpu_defaultd), - SETUP_FMT_TBL(FMT_MPEG2D, vpu_defaultd), - SETUP_FMT_TBL(FMT_MPEG4D, vpu_defaultd), - - SETUP_FMT_TBL(FMT_VP6D, vpu_vp6d), - SETUP_FMT_TBL(FMT_VP7D, vpu_defaultd), - SETUP_FMT_TBL(FMT_VP8D, vpu_vp8d), - EMPTY_FMT_TBL(FMT_VP9D), - - SETUP_FMT_TBL(FMT_VC1D, vpu_vc1d), - SETUP_FMT_TBL(FMT_AVSD, vpu_avsd), - - SETUP_FMT_TBL(FMT_PP, vpu_default_pp), - - SETUP_FMT_TBL(FMT_JPEGE, vpu_defaulte), - SETUP_FMT_TBL(FMT_H264E, vpu_defaulte), - SETUP_FMT_TBL(FMT_VP8E, vpu_vp8e), -}; - -#endif diff --git a/drivers/video/rockchip/vcodec/vcodec_hw_vpu2.h b/drivers/video/rockchip/vcodec/vcodec_hw_vpu2.h deleted file mode 100644 index 6c0c4dd8be74..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_hw_vpu2.h +++ /dev/null @@ -1,293 +0,0 @@ -/** - * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd - * author: chenhengming chm@rock-chips.com - * Alpha Lin, alpha.lin@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. - * - */ - -#ifndef __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_VPU2_H -#define __ARCH_ARM_MACH_ROCKCHIP_VCODEC_HW_VPU2_H - -#include "vcodec_hw_info.h" - -/* hardware information */ -#define REG_NUM_VPU2_DEC (159) -#define REG_NUM_VPU2_DEC_START (50) -#define REG_NUM_VPU2_DEC_END (159) -#define REG_NUM_VPU2_PP (41) -#define REG_NUM_VPU2_DEC_PP (159) -#define REG_NUM_VPU2_ENC (184) -#define REG_NUM_VPU2_DEC_OFFSET (0x400) - -/* enable and gating register */ -#define VPU2_REG_EN_ENC 103 -#define VPU2_REG_ENC_GATE 109 -#define VPU2_REG_ENC_GATE_BIT BIT(4) - -#define VPU2_REG_EN_DEC 57 -#define VPU2_REG_DEC_GATE 57 -#define VPU2_REG_DEC_GATE_BIT BIT(4) -#define VPU2_REG_EN_PP 41 -#define VPU2_REG_PP_GATE 1 -#define VPU2_REG_PP_GATE_BIT BIT(8) -#define VPU2_REG_EN_DEC_PP 57 -#define VPU2_REG_DEC_PP_GATE 57 -#define VPU2_REG_DEC_PP_GATE_BIT BIT(4) - -/* interrupt and error status register */ -#define VPU2_DEC_INTERRUPT_REGISTER 55 -#define VPU2_DEC_INTERRUPT_BIT BIT(0) -#define VPU2_DEC_READY_BIT BIT(4) -#define VPU2_DEC_BUS_ERROR_BIT BIT(5) -#define VPU2_DEC_BUFFER_EMPTY_BIT BIT(6) -#define VPU2_DEC_ASO_ERROR_BIT BIT(8) -#define VPU2_DEC_SLICE_DONE_BIT BIT(9) -#define VPU2_DEC_STREAM_ERROR_BIT BIT(12) -#define VPU2_DEC_TIMEOUT_BIT BIT(13) -#define VPU2_DEC_ERR_MASK (VPU2_DEC_BUS_ERROR_BIT \ - | VPU2_DEC_BUFFER_EMPTY_BIT \ - | VPU2_DEC_STREAM_ERROR_BIT \ - | VPU2_DEC_TIMEOUT_BIT) - -/*enable and soft reset register*/ -#define VPU2_REG_DEC_RESET 58 -#define VPU2_REG_DEC_RESET_BIT BIT(0) - -#define VPU2_PP_INTERRUPT_REGISTER 40 -#define VPU2_PP_INTERRUPT_BIT BIT(0) -#define VPU2_PP_READY_BIT BIT(2) -#define VPU2_PP_BUS_ERROR_BIT BIT(3) -#define VPU2_PP_ERR_MASK VPU2_PP_BUS_ERROR_BIT -#define VPU2_PP_PIPELINE_REGISTER 41 -#define VPU2_PP_PIPELINE_MODE_BIT BIT(4) - -#define VPU2_ENC_INTERRUPT_REGISTER 109 -#define VPU2_ENC_INTERRUPT_BIT BIT(0) -#define VPU2_ENC_READY_BIT BIT(1) -#define VPU2_ENC_BUS_ERROR_BIT BIT(4) -#define VPU2_ENC_BUFFER_FULL_BIT BIT(5) -#define VPU2_ENC_TIMEOUT_BIT BIT(6) -#define VPU2_ENC_ERR_MASK (VPU2_ENC_BUS_ERROR_BIT \ - | VPU2_ENC_BUFFER_FULL_BIT \ - | VPU2_ENC_TIMEOUT_BIT) - -static const enum FORMAT_TYPE vpu2_dec_fmt_tbl[] = { - [0] = FMT_H264D, - [1] = FMT_MPEG4D, - [2] = FMT_H263D, - [3] = FMT_JPEGD, - [4] = FMT_VC1D, - [5] = FMT_MPEG2D, - [6] = FMT_MPEG1D, - [7] = FMT_VP6D, - [8] = FMT_TYPE_BUTT, - [9] = FMT_VP7D, - [10] = FMT_VP8D, - [11] = FMT_AVSD, - [12] = FMT_TYPE_BUTT, - [13] = FMT_TYPE_BUTT, - [14] = FMT_TYPE_BUTT, - [15] = FMT_TYPE_BUTT, -}; - -static enum FORMAT_TYPE vpu2_dec_get_fmt(u32 *regs) -{ - u32 fmt_id = regs[53] & 0xf; - enum FORMAT_TYPE type = vpu2_dec_fmt_tbl[fmt_id]; - return type; -} - -static enum FORMAT_TYPE vpu2_pp_get_fmt(u32 *regs) -{ - return FMT_PP; -} - -static const enum FORMAT_TYPE vpu2_enc_fmt_tbl[] = { - [0] = FMT_TYPE_BUTT, - [1] = FMT_VP8E, - [2] = FMT_JPEGE, - [3] = FMT_H264E, -}; - -static enum FORMAT_TYPE vpu2_enc_get_fmt(u32 *regs) -{ - u32 fmt_id = (regs[VPU2_REG_EN_ENC] >> 4) & 0x3; - enum FORMAT_TYPE type = vpu2_enc_fmt_tbl[fmt_id]; - return type; -} - -static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = { - { - .name = "vpu2_enc", - .reg_rlc = 48, - .reg_en = VPU2_REG_EN_ENC, - .reg_gating = VPU2_REG_ENC_GATE, - .reg_irq = VPU2_ENC_INTERRUPT_REGISTER, - .reg_len = -1, - .reg_dir_mv = -1, - .reg_pps = -1, - .reg_reset = -1, - .reg_pipe = -1, - .enable_mask = 0x30, - .gating_mask = VPU2_REG_ENC_GATE_BIT, - .pipe_mask = 0, - .irq_mask = VPU2_ENC_INTERRUPT_BIT, - .ready_mask = VPU2_ENC_READY_BIT, - .error_mask = VPU2_ENC_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu2_enc_get_fmt, - }, - { - .name = "vpu2_dec", - .reg_rlc = 64, - .reg_en = VPU2_REG_EN_DEC, - .reg_irq = VPU2_DEC_INTERRUPT_REGISTER, - .reg_len = 64, - .reg_dir_mv = 62, - .reg_pps = -1, - .reg_reset = VPU2_REG_DEC_RESET, - .reg_pipe = VPU2_PP_PIPELINE_REGISTER, - .enable_mask = 0, - .gating_mask = VPU2_REG_DEC_GATE_BIT, - .pipe_mask = VPU2_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU2_DEC_INTERRUPT_BIT, - .ready_mask = VPU2_DEC_READY_BIT, - .error_mask = VPU2_DEC_ERR_MASK, - .reset_mask = VPU2_REG_DEC_RESET_BIT, - .get_fmt = vpu2_dec_get_fmt, - }, - { - .name = "vpu2_pp", - .reg_en = VPU2_REG_EN_PP, - .reg_irq = VPU2_PP_INTERRUPT_REGISTER, - .reg_len = -1, - .reg_dir_mv = -1, - .reg_pps = -1, - .reg_pipe = VPU2_PP_PIPELINE_REGISTER, - .enable_mask = 0, - .gating_mask = VPU2_REG_PP_GATE_BIT, - .pipe_mask = VPU2_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU2_PP_INTERRUPT_BIT, - .ready_mask = VPU2_PP_READY_BIT, - .error_mask = VPU2_PP_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu2_pp_get_fmt, - }, - { - .name = "vpu2_dec_pp", - .reg_rlc = 64, - .reg_en = VPU2_REG_EN_DEC_PP, - .reg_irq = VPU2_DEC_INTERRUPT_REGISTER, - .reg_len = 64, - .reg_dir_mv = 62, - .reg_pps = -1, - .reg_pipe = VPU2_PP_PIPELINE_REGISTER, - .enable_mask = 0, - .gating_mask = VPU2_REG_DEC_GATE_BIT, - .pipe_mask = VPU2_PP_PIPELINE_MODE_BIT, - .irq_mask = VPU2_DEC_INTERRUPT_BIT, - .ready_mask = VPU2_DEC_READY_BIT, - .error_mask = VPU2_DEC_ERR_MASK, - .reset_mask = 0, - .get_fmt = vpu2_dec_get_fmt, - }, -}; - -static struct vpu_hw_info hw_vpu2 = { - .hw_id = VPU2_ID, - - .enc_offset = 0x0, - .enc_reg_num = REG_NUM_VPU2_ENC, - .enc_io_size = REG_NUM_VPU2_ENC * 4, - - .dec_offset = REG_NUM_VPU2_DEC_OFFSET, - .dec_reg_num = REG_NUM_VPU2_DEC_PP, - .dec_io_size = REG_NUM_VPU2_DEC_PP * 4, - - .base_dec = REG_NUM_VPU2_DEC_START, - .base_pp = 0, - .base_dec_pp = 0, - .end_dec = REG_NUM_VPU2_DEC_END, - .end_pp = REG_NUM_VPU2_PP, - .end_dec_pp = REG_NUM_VPU2_DEC_END, -}; - -/* - * file handle translate information - */ -DEF_FMT_TRANS_TBL(vpu2_jpegd, - 131, 64, 63, 61, 21, 22 -); - -DEF_FMT_TRANS_TBL(vpu2_h264d, - 61, 62, 63, 64, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, -); - -DEF_FMT_TRANS_TBL(vpu2_vp6d, - 64, 63, 131, 136, 145, 61 -); - -DEF_FMT_TRANS_TBL(vpu2_vp8d, - 149, 64, 63, 131, 136, 137, 140, 141, - 142, 143, 144, 145, 146, 147, 61 -); - -DEF_FMT_TRANS_TBL(vpu2_vc1d, - 64, 63, 131, 148, 134, 135, 145, 62 -); - -DEF_FMT_TRANS_TBL(vpu2_default_dec, - 61, 62, 64, 63, 131, 148, 134, 135, -); - -DEF_FMT_TRANS_TBL(vpu2_default_pp, - 12, 13, 18, 19, 20, 21, 22 -); - -DEF_FMT_TRANS_TBL(vpu2_vp8e, - 77, 78, 56, 57, 63, 64, 48, 49, - 50, 76, 106, 108, 81, 80, 44, 45, 27 -); - -DEF_FMT_TRANS_TBL(vpu2_default_enc, - 77, 78, 56, 57, 63, 64, 48, 49, - 50, 81 -); - -const struct vpu_trans_info trans_vpu2[FMT_TYPE_BUTT] = { - SETUP_FMT_TBL(FMT_JPEGD, vpu2_jpegd), - SETUP_FMT_TBL(FMT_H263D, vpu2_default_dec), - SETUP_FMT_TBL(FMT_H264D, vpu2_h264d), - EMPTY_FMT_TBL(FMT_H265D), - - SETUP_FMT_TBL(FMT_MPEG1D, vpu2_default_dec), - SETUP_FMT_TBL(FMT_MPEG2D, vpu2_default_dec), - SETUP_FMT_TBL(FMT_MPEG4D, vpu2_default_dec), - - SETUP_FMT_TBL(FMT_VP6D, vpu2_vp6d), - SETUP_FMT_TBL(FMT_VP7D, vpu2_default_dec), - SETUP_FMT_TBL(FMT_VP8D, vpu2_vp8d), - EMPTY_FMT_TBL(FMT_VP9D), - - SETUP_FMT_TBL(FMT_PP, vpu2_default_pp), - - SETUP_FMT_TBL(FMT_VC1D, vpu2_vc1d), - SETUP_FMT_TBL(FMT_AVSD, vpu2_default_dec), - - SETUP_FMT_TBL(FMT_JPEGE, vpu2_default_enc), - SETUP_FMT_TBL(FMT_H264E, vpu2_default_enc), - SETUP_FMT_TBL(FMT_VP8E, vpu2_vp8e), -}; - -#endif diff --git a/drivers/video/rockchip/vcodec/vcodec_iommu_drm.c b/drivers/video/rockchip/vcodec/vcodec_iommu_drm.c deleted file mode 100644 index cbc47b92b3e1..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_iommu_drm.c +++ /dev/null @@ -1,982 +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 "vcodec_iommu_ops.h" - -/* - * there two type drm buffer, one is through import interface and - * the other is through alloc. there are some differents between - * import and alloc buffer when free them. this flag is used to - * inform driver which type of this buffer. - */ -#define VCODEC_DRM_BUFFER_ALLOC 0x00000001 - -struct vcodec_drm_buffer { - struct list_head list; - struct dma_buf *dma_buf; - union { - dma_addr_t iova; - unsigned long phys; - }; - /* this is used for page fault */ - unsigned long iova_out; - void *cpu_addr; - unsigned long size; - int index; - struct dma_buf_attachment *attach; - struct sg_table *sgt; - struct sg_table *copy_sgt; - struct page **pages; - struct kref ref; - struct vcodec_iommu_session_info *session_info; - ktime_t last_used; - int flags; -}; - -struct vcodec_iommu_drm_info { - struct iommu_domain *domain; - bool attached; -}; - -static struct vcodec_drm_buffer * -vcodec_drm_get_buffer_no_lock(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct vcodec_drm_buffer *drm_buffer = NULL, *n; - - list_for_each_entry_safe(drm_buffer, n, &session_info->buffer_list, - list) { - if (drm_buffer->index == idx) { - drm_buffer->last_used = ktime_get(); - return drm_buffer; - } - } - - return NULL; -} - -static struct vcodec_drm_buffer * -vcodec_drm_get_buffer_fd_no_lock(struct vcodec_iommu_session_info *session_info, - int fd) -{ - struct vcodec_drm_buffer *drm_buffer = NULL, *n; - struct dma_buf *dma_buf = NULL; - - dma_buf = dma_buf_get(fd); - - list_for_each_entry_safe(drm_buffer, n, &session_info->buffer_list, - list) { - if (drm_buffer->dma_buf == dma_buf) { - drm_buffer->last_used = ktime_get(); - dma_buf_put(dma_buf); - return drm_buffer; - } - } - - dma_buf_put(dma_buf); - - return NULL; -} - -static void *vcodec_drm_sgt_map_kernel(struct vcodec_drm_buffer *drm_buffer) -{ - struct vcodec_iommu_session_info *session_info = - drm_buffer->session_info; - struct device *dev = session_info->dev; - struct scatterlist *sgl, *sg; - int nr_pages = PAGE_ALIGN(drm_buffer->size) >> PAGE_SHIFT; - int i = 0, j = 0, k = 0; - struct page *page; - - drm_buffer->pages = kmalloc_array(nr_pages, sizeof(*drm_buffer->pages), - GFP_KERNEL); - if (!(drm_buffer->pages)) { - dev_err(dev, "drm map alloc %d pages failed!\n", nr_pages); - - return NULL; - } - - sgl = drm_buffer->copy_sgt->sgl; - - for_each_sg(sgl, sg, drm_buffer->copy_sgt->nents, i) { - page = sg_page(sg); - for (j = 0; j < sg->length / PAGE_SIZE; j++) - drm_buffer->pages[k++] = page++; - } - - return vmap(drm_buffer->pages, nr_pages, VM_MAP, - pgprot_noncached(PAGE_KERNEL)); -} - -static void vcodec_drm_sgt_unmap_kernel(struct vcodec_drm_buffer *drm_buffer) -{ - vunmap(drm_buffer->cpu_addr); - kfree(drm_buffer->pages); -} - -static int vcodec_finalise_sg(struct scatterlist *sg, - int nents, - dma_addr_t dma_addr) -{ - struct scatterlist *s, *cur = sg; - unsigned long seg_mask = DMA_BIT_MASK(32); - unsigned int cur_len = 0, max_len = DMA_BIT_MASK(32); - int i, count = 0; - - for_each_sg(sg, s, nents, i) { - /* Restore this segment's original unaligned fields first */ - unsigned int s_iova_off = sg_dma_address(s); - unsigned int s_length = sg_dma_len(s); - unsigned int s_iova_len = s->length; - - s->offset += s_iova_off; - s->length = s_length; - sg_dma_address(s) = DMA_ERROR_CODE; - sg_dma_len(s) = 0; - - /* - * Now fill in the real DMA data. If... - * - there is a valid output segment to append to - * - and this segment starts on an IOVA page boundary - * - but doesn't fall at a segment boundary - * - and wouldn't make the resulting output segment too long - */ - if (cur_len && !s_iova_off && (dma_addr & seg_mask) && - (cur_len + s_length <= max_len)) { - /* ...then concatenate it with the previous one */ - cur_len += s_length; - } else { - /* Otherwise start the next output segment */ - if (i > 0) - cur = sg_next(cur); - cur_len = s_length; - count++; - - sg_dma_address(cur) = dma_addr + s_iova_off; - } - - sg_dma_len(cur) = cur_len; - dma_addr += s_iova_len; - - if (s_length + s_iova_off < s_iova_len) - cur_len = 0; - } - return count; -} - -static void vcodec_invalidate_sg(struct scatterlist *sg, int nents) -{ - struct scatterlist *s; - int i; - - for_each_sg(sg, s, nents, i) { - if (sg_dma_address(s) != DMA_ERROR_CODE) - s->offset += sg_dma_address(s); - if (sg_dma_len(s)) - s->length = sg_dma_len(s); - sg_dma_address(s) = DMA_ERROR_CODE; - sg_dma_len(s) = 0; - } -} - -static void vcodec_dma_unmap_sg(struct iommu_domain *domain, - dma_addr_t dma_addr) -{ - struct iova_domain *iovad = domain->iova_cookie; - unsigned long shift = iova_shift(iovad); - unsigned long pfn = dma_addr >> shift; - struct iova *iova = find_iova(iovad, pfn); - size_t size; - - if (WARN_ON(!iova)) - return; - - size = iova_size(iova) << shift; - size -= iommu_unmap(domain, pfn << shift, size); - /* ...and if we can't, then something is horribly, horribly wrong */ - WARN_ON(size > 0); - __free_iova(iovad, iova); -} - -static void vcodec_drm_clear_map(struct kref *ref) -{ - struct vcodec_drm_buffer *drm_buffer = - container_of(ref, struct vcodec_drm_buffer, ref); - struct vcodec_iommu_session_info *session_info = - drm_buffer->session_info; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - struct sg_table *table; - struct scatterlist *sg; - struct page *page; - int i; - - mutex_lock(&iommu_info->iommu_mutex); - drm_info = session_info->iommu_info->private; - - if (drm_buffer->cpu_addr) { - vcodec_drm_sgt_unmap_kernel(drm_buffer); - drm_buffer->cpu_addr = NULL; - } - - vcodec_dma_unmap_sg(drm_info->domain, drm_buffer->iova); - if (drm_buffer->flags & VCODEC_DRM_BUFFER_ALLOC) { - table = drm_buffer->copy_sgt; - for_each_sg(table->sgl, sg, table->nents, i) { - page = sg_page(sg); - __free_pages(page, compound_order(page)); - } - } - sg_free_table(drm_buffer->copy_sgt); - kfree(drm_buffer->copy_sgt); - - if (drm_buffer->attach) { - dma_buf_unmap_attachment(drm_buffer->attach, drm_buffer->sgt, - DMA_BIDIRECTIONAL); - dma_buf_detach(drm_buffer->dma_buf, drm_buffer->attach); - dma_buf_put(drm_buffer->dma_buf); - drm_buffer->attach = NULL; - } - - mutex_unlock(&iommu_info->iommu_mutex); -} - -static int -vcodec_drm_unmap_iommu_with_iova(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - struct iommu_domain *domain = drm_info->domain; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - return -EINVAL; - } - - iommu_unmap(domain, drm_buffer->iova_out, PAGE_SIZE); - - return 0; -} - -static int -vcodec_drm_map_iommu_with_iova(struct vcodec_iommu_session_info *session_info, - int idx, - unsigned long iova, - unsigned long size) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - return -EINVAL; - } - - drm_buffer->iova_out = iova; - - return iommu_map(drm_info->domain, - iova, - sg_phys(drm_buffer->copy_sgt->sgl), - size, IOMMU_READ | IOMMU_WRITE); -} - -static void* -vcodec_drm_map_kernel(struct vcodec_iommu_session_info *session_info, int idx) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - return NULL; - } - - if (!drm_buffer->cpu_addr) - drm_buffer->cpu_addr = - vcodec_drm_sgt_map_kernel(drm_buffer); - - kref_get(&drm_buffer->ref); - - return drm_buffer->cpu_addr; -} - -static int -vcodec_drm_unmap_kernel(struct vcodec_iommu_session_info *session_info, int idx) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - - return -EINVAL; - } - - if (drm_buffer->cpu_addr) { - vcodec_drm_sgt_unmap_kernel(drm_buffer); - drm_buffer->cpu_addr = NULL; - } - - kref_put(&drm_buffer->ref, vcodec_drm_clear_map); - return 0; -} - -static void -vcodec_drm_remove_extra_buffer_no_lock(struct vcodec_iommu_session_info - *session_info) -{ - struct vcodec_drm_buffer *oldest_buffer = NULL, *loop_buffer = NULL; - struct vcodec_drm_buffer *n; - ktime_t oldest_time = ktime_set(0, 0); - - if (session_info->buffer_nums > BUFFER_LIST_MAX_NUMS) { - list_for_each_entry_safe(loop_buffer, n, - &session_info->buffer_list, list) { - if (loop_buffer->flags & VCODEC_DRM_BUFFER_ALLOC) - continue; - - if (ktime_to_ns(oldest_time) == 0 || - ktime_after(oldest_time, - loop_buffer->last_used)) { - oldest_time = loop_buffer->last_used; - oldest_buffer = loop_buffer; - } - } - kref_put(&oldest_buffer->ref, vcodec_drm_clear_map); - dma_buf_put(oldest_buffer->dma_buf); - list_del_init(&oldest_buffer->list); - kfree(oldest_buffer); - session_info->buffer_nums--; - } -} - -static void vcodec_drm_detach(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - struct device *dev = iommu_info->dev; - struct iommu_domain *domain = drm_info->domain; - - mutex_lock(&iommu_info->iommu_mutex); - - if (!drm_info->attached) { - mutex_unlock(&iommu_info->iommu_mutex); - return; - } - - iommu_detach_device(domain, dev); - drm_info->attached = false; - - mutex_unlock(&iommu_info->iommu_mutex); -} - -static int vcodec_drm_attach_unlock(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - struct device *dev = iommu_info->dev; - struct iommu_domain *domain = drm_info->domain; - int ret = 0; - - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - ret = iommu_attach_device(domain, dev); - if (ret) { - dev_err(dev, "Failed to attach iommu device\n"); - return ret; - } - - return ret; -} - -static int vcodec_drm_attach(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - int ret; - - mutex_lock(&iommu_info->iommu_mutex); - - if (drm_info->attached) { - mutex_unlock(&iommu_info->iommu_mutex); - return 0; - } - - ret = vcodec_drm_attach_unlock(iommu_info); - if (ret) { - mutex_unlock(&iommu_info->iommu_mutex); - return ret; - } - - drm_info->attached = true; - - mutex_unlock(&iommu_info->iommu_mutex); - - return ret; -} - -static dma_addr_t vcodec_dma_map_sg(struct iommu_domain *domain, - struct scatterlist *sg, - int nents, int prot) -{ - struct iova_domain *iovad = domain->iova_cookie; - struct iova *iova; - struct scatterlist *s, *prev = NULL; - dma_addr_t dma_addr; - size_t iova_len = 0; - unsigned long mask = DMA_BIT_MASK(32); - unsigned long shift = iova_shift(iovad); - int i; - - /* - * Work out how much IOVA space we need, and align the segments to - * IOVA granules for the IOMMU driver to handle. With some clever - * trickery we can modify the list in-place, but reversibly, by - * stashing the unaligned parts in the as-yet-unused DMA fields. - */ - for_each_sg(sg, s, nents, i) { - size_t s_iova_off = iova_offset(iovad, s->offset); - size_t s_length = s->length; - size_t pad_len = (mask - iova_len + 1) & mask; - - sg_dma_address(s) = s_iova_off; - sg_dma_len(s) = s_length; - s->offset -= s_iova_off; - s_length = iova_align(iovad, s_length + s_iova_off); - s->length = s_length; - - /* - * Due to the alignment of our single IOVA allocation, we can - * depend on these assumptions about the segment boundary mask: - * - If mask size >= IOVA size, then the IOVA range cannot - * possibly fall across a boundary, so we don't care. - * - If mask size < IOVA size, then the IOVA range must start - * exactly on a boundary, therefore we can lay things out - * based purely on segment lengths without needing to know - * the actual addresses beforehand. - * - The mask must be a power of 2, so pad_len == 0 if - * iova_len == 0, thus we cannot dereference prev the first - * time through here (i.e. before it has a meaningful value). - */ - if (pad_len && pad_len < s_length - 1) { - prev->length += pad_len; - iova_len += pad_len; - } - - iova_len += s_length; - prev = s; - } - - iova = alloc_iova(iovad, iova_align(iovad, iova_len) >> shift, - mask >> shift, true); - if (!iova) - goto out_restore_sg; - - /* - * We'll leave any physical concatenation to the IOMMU driver's - * implementation - it knows better than we do. - */ - dma_addr = iova_dma_addr(iovad, iova); - if (iommu_map_sg(domain, dma_addr, sg, nents, prot) < iova_len) - goto out_free_iova; - - return vcodec_finalise_sg(sg, nents, dma_addr); - -out_free_iova: - __free_iova(iovad, iova); -out_restore_sg: - vcodec_invalidate_sg(sg, nents); - return 0; -} - -static void vcdoec_drm_dump_info(struct vcodec_iommu_session_info *session_info) -{ - struct vcodec_drm_buffer *drm_buffer = NULL, *n; - - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_OPS_DUMP, - "still there are below buffers stored in list\n"); - list_for_each_entry_safe(drm_buffer, n, &session_info->buffer_list, - list) { - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_OPS_DUMP, - "index %d drm_buffer dma_buf %p\n", - drm_buffer->index, - drm_buffer->dma_buf); - } -} - -static int vcodec_drm_free(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct device *dev = session_info->dev; - /* please double-check all maps have been release */ - struct vcodec_drm_buffer *drm_buffer; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - mutex_unlock(&session_info->list_mutex); - - return -EINVAL; - } - - if (atomic_read(&drm_buffer->ref.refcount) == 0) { - dma_buf_put(drm_buffer->dma_buf); - list_del_init(&drm_buffer->list); - kfree(drm_buffer); - session_info->buffer_nums--; - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_NORMAL, - "buffer nums %d\n", session_info->buffer_nums); - } - mutex_unlock(&session_info->list_mutex); - - return 0; -} - -static int -vcodec_drm_unmap_iommu(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - return -EINVAL; - } - - kref_put(&drm_buffer->ref, vcodec_drm_clear_map); - - return 0; -} - -static int vcodec_drm_map_iommu(struct vcodec_iommu_session_info *session_info, - int idx, - dma_addr_t *iova, - unsigned long *size) -{ - struct device *dev = session_info->dev; - struct vcodec_drm_buffer *drm_buffer; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_no_lock(session_info, idx); - mutex_unlock(&session_info->list_mutex); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", idx); - return -EINVAL; - } - - kref_get(&drm_buffer->ref); - if (iova) - *iova = drm_buffer->iova; - if (size) - *size = drm_buffer->size; - return 0; -} - -static int -vcodec_drm_free_fd(struct vcodec_iommu_session_info *session_info, int fd) -{ - struct device *dev = session_info->dev; - /* please double-check all maps have been release */ - struct vcodec_drm_buffer *drm_buffer = NULL; - - mutex_lock(&session_info->list_mutex); - drm_buffer = vcodec_drm_get_buffer_fd_no_lock(session_info, fd); - - if (!drm_buffer) { - dev_err(dev, "can not find %d buffer in list\n", fd); - mutex_unlock(&session_info->list_mutex); - - return -EINVAL; - } - mutex_unlock(&session_info->list_mutex); - - vcodec_drm_unmap_iommu(session_info, drm_buffer->index); - - mutex_lock(&session_info->list_mutex); - if (atomic_read(&drm_buffer->ref.refcount) == 0) { - dma_buf_put(drm_buffer->dma_buf); - list_del_init(&drm_buffer->list); - kfree(drm_buffer); - session_info->buffer_nums--; - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_NORMAL, - "buffer nums %d\n", session_info->buffer_nums); - } - mutex_unlock(&session_info->list_mutex); - - return 0; -} - -static void -vcodec_drm_clear_session(struct vcodec_iommu_session_info *session_info) -{ - struct vcodec_drm_buffer *drm_buffer = NULL, *n; - - list_for_each_entry_safe(drm_buffer, n, &session_info->buffer_list, - list) { - kref_put(&drm_buffer->ref, vcodec_drm_clear_map); - vcodec_drm_free(session_info, drm_buffer->index); - } -} - -static int vcodec_drm_import(struct vcodec_iommu_session_info *session_info, - int fd) -{ - struct vcodec_drm_buffer *drm_buffer = NULL, *n; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - struct device *dev = session_info->dev; - struct dma_buf_attachment *attach; - struct sg_table *sgt; - struct dma_buf *dma_buf; - struct scatterlist *sg, *s; - int i; - int ret = 0; - - dma_buf = dma_buf_get(fd); - if (IS_ERR(dma_buf)) { - ret = PTR_ERR(dma_buf); - return ret; - } - - list_for_each_entry_safe(drm_buffer, n, - &session_info->buffer_list, list) { - if (drm_buffer->dma_buf == dma_buf) { - dma_buf_put(dma_buf); - drm_buffer->last_used = ktime_get(); - return drm_buffer->index; - } - } - - drm_buffer = kzalloc(sizeof(*drm_buffer), GFP_KERNEL); - if (!drm_buffer) { - ret = -ENOMEM; - return ret; - } - - drm_buffer->dma_buf = dma_buf; - drm_buffer->session_info = session_info; - drm_buffer->last_used = ktime_get(); - - kref_init(&drm_buffer->ref); - - mutex_lock(&iommu_info->iommu_mutex); - drm_info = session_info->iommu_info->private; - - attach = dma_buf_attach(drm_buffer->dma_buf, dev); - if (IS_ERR(attach)) { - ret = PTR_ERR(attach); - goto fail_out; - } - - get_dma_buf(drm_buffer->dma_buf); - - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR(sgt)) { - ret = PTR_ERR(sgt); - goto fail_detach; - } - - /* - * Since we call dma_buf_map_attachment outside attach/detach, this - * will cause incorrectly map. we have to re-build map table native - * and for avoiding destroy their origin map table, we need use a - * copy one sg_table. - */ - drm_buffer->copy_sgt = kmalloc(sizeof(*drm_buffer->copy_sgt), - GFP_KERNEL); - if (!drm_buffer->copy_sgt) { - ret = -ENOMEM; - goto fail_detach; - } - - ret = sg_alloc_table(drm_buffer->copy_sgt, sgt->nents, GFP_KERNEL); - s = drm_buffer->copy_sgt->sgl; - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - sg_set_page(s, sg_page(sg), - PAGE_SIZE << compound_order(sg_page(sg)), 0); - sg_dma_address(s) = page_to_phys(sg_page(sg)); - s->offset = sg->offset; - s->length = sg->length; - s = sg_next(s); - } - - ret = vcodec_dma_map_sg(drm_info->domain, drm_buffer->copy_sgt->sgl, - drm_buffer->copy_sgt->nents, - IOMMU_READ | IOMMU_WRITE); - if (!ret) { - ret = -ENOMEM; - goto fail_alloc; - } - drm_buffer->iova = sg_dma_address(drm_buffer->copy_sgt->sgl); - drm_buffer->size = drm_buffer->dma_buf->size; - - drm_buffer->attach = attach; - drm_buffer->sgt = sgt; - - mutex_unlock(&iommu_info->iommu_mutex); - - INIT_LIST_HEAD(&drm_buffer->list); - mutex_lock(&session_info->list_mutex); - session_info->buffer_nums++; - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_NORMAL, - "buffer nums %d\n", session_info->buffer_nums); - vcodec_drm_remove_extra_buffer_no_lock(session_info); - drm_buffer->index = session_info->max_idx; - list_add_tail(&drm_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 drm_buffer->index; - -fail_alloc: - sg_free_table(drm_buffer->copy_sgt); - kfree(drm_buffer->copy_sgt); - dma_buf_unmap_attachment(attach, sgt, - DMA_BIDIRECTIONAL); -fail_detach: - dma_buf_detach(drm_buffer->dma_buf, attach); - dma_buf_put(drm_buffer->dma_buf); -fail_out: - kfree(drm_buffer); - mutex_unlock(&iommu_info->iommu_mutex); - - return ret; -} - -static int vcodec_drm_alloc(struct vcodec_iommu_session_info *session_info, - unsigned long size, - unsigned long align) -{ - struct sg_table *table; - struct scatterlist *sg; - struct list_head pages; - struct page *page, *tmp_page; - long size_remaining = PAGE_ALIGN(size); - struct vcodec_drm_buffer *drm_buffer; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - int i; - - if (align > PAGE_SIZE) - return -EINVAL; - - if (size / PAGE_SIZE > totalram_pages / 2) - return -ENOMEM; - - drm_buffer = kzalloc(sizeof(*drm_buffer), GFP_KERNEL); - if (!drm_buffer) - return -ENOMEM; - - drm_buffer->session_info = session_info; - drm_buffer->last_used = ktime_set(0, 0); - - kref_init(&drm_buffer->ref); - - INIT_LIST_HEAD(&pages); - - i = 0; - while (size_remaining > 0) { - gfp_t gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | - __GFP_NORETRY) & ~__GFP_DIRECT_RECLAIM; - page = alloc_pages(gfp_flags | __GFP_COMP, 1); - if (!page) - goto free_pages; - - size_remaining -= PAGE_SIZE; - list_add_tail(&page->lru, &pages); - i++; - } - - table = kmalloc(sizeof(*table), GFP_KERNEL); - if (!table) - goto free_pages; - - if (sg_alloc_table(table, i, GFP_KERNEL)) - goto free_table; - - sg = table->sgl; - list_for_each_entry_safe(page, tmp_page, &pages, lru) { - sg_set_page(sg, page, PAGE_SIZE, 0); - sg = sg_next(sg); - list_del(&page->lru); - } - - mutex_lock(&iommu_info->iommu_mutex); - drm_info = session_info->iommu_info->private; - drm_buffer->copy_sgt = table; - - vcodec_dma_map_sg(drm_info->domain, drm_buffer->copy_sgt->sgl, - drm_buffer->copy_sgt->nents, - IOMMU_READ | IOMMU_WRITE); - drm_buffer->iova = sg_dma_address(drm_buffer->copy_sgt->sgl); - drm_buffer->size = size; - drm_buffer->flags = VCODEC_DRM_BUFFER_ALLOC; - - mutex_unlock(&iommu_info->iommu_mutex); - - INIT_LIST_HEAD(&drm_buffer->list); - mutex_lock(&session_info->list_mutex); - session_info->buffer_nums++; - vpu_iommu_debug(session_info->debug_level, DEBUG_IOMMU_NORMAL, - "buffer nums %d\n", session_info->buffer_nums); - vcodec_drm_remove_extra_buffer_no_lock(session_info); - drm_buffer->index = session_info->max_idx; - list_add_tail(&drm_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 drm_buffer->index; - -free_table: - kfree(table); -free_pages: - list_for_each_entry_safe(page, tmp_page, &pages, lru) - __free_pages(page, 8); - - kfree(drm_buffer); - - return -ENOMEM; -} - -static int vcodec_drm_create(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_drm_info *drm_info; - struct iommu_group *group; - int ret; - - iommu_info->private = kzalloc(sizeof(*drm_info), - GFP_KERNEL); - drm_info = iommu_info->private; - if (!drm_info) - return -ENOMEM; - - drm_info->domain = iommu_domain_alloc(&platform_bus_type); - drm_info->attached = false; - if (!drm_info->domain) - return -ENOMEM; - - ret = iommu_get_dma_cookie(drm_info->domain); - if (ret) - goto err_free_domain; - - group = iommu_group_get(iommu_info->dev); - if (!group) { - group = iommu_group_alloc(); - if (IS_ERR(group)) { - dev_err(iommu_info->dev, - "Failed to allocate IOMMU group\n"); - goto err_put_cookie; - } - ret = iommu_group_add_device(group, iommu_info->dev); - if (ret) { - dev_err(iommu_info->dev, - "failed to add device to IOMMU group\n"); - goto err_put_cookie; - } - } - iommu_dma_init_domain(drm_info->domain, 0x10000000, SZ_2G); - iommu_group_put(group); - - return 0; - -err_put_cookie: - iommu_put_dma_cookie(drm_info->domain); -err_free_domain: - iommu_domain_free(drm_info->domain); - - return ret; -} - -static int vcodec_drm_destroy(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_drm_info *drm_info = iommu_info->private; - - iommu_put_dma_cookie(drm_info->domain); - iommu_domain_free(drm_info->domain); - - kfree(drm_info); - iommu_info->private = NULL; - - return 0; -} - -static struct vcodec_iommu_ops drm_ops = { - .create = vcodec_drm_create, - .alloc = vcodec_drm_alloc, - .import = vcodec_drm_import, - .free = vcodec_drm_free, - .free_fd = vcodec_drm_free_fd, - .map_kernel = vcodec_drm_map_kernel, - .unmap_kernel = vcodec_drm_unmap_kernel, - .map_iommu = vcodec_drm_map_iommu, - .unmap_iommu = vcodec_drm_unmap_iommu, - .map_iommu_with_iova = vcodec_drm_map_iommu_with_iova, - .unmap_iommu_with_iova = vcodec_drm_unmap_iommu_with_iova, - .destroy = vcodec_drm_destroy, - .dump = vcdoec_drm_dump_info, - .attach = vcodec_drm_attach, - .detach = vcodec_drm_detach, - .clear = vcodec_drm_clear_session, -}; - -void vcodec_iommu_drm_set_ops(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info) - return; - iommu_info->ops = &drm_ops; -} diff --git a/drivers/video/rockchip/vcodec/vcodec_iommu_ion.c b/drivers/video/rockchip/vcodec/vcodec_iommu_ion.c deleted file mode 100644 index 84cec00489ce..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_iommu_ion.c +++ /dev/null @@ -1,332 +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 "vcodec_iommu_ops.h" - -struct vcodec_ion_buffer { - struct list_head list; - struct ion_handle *handle; - int index; -}; - -struct vcodec_iommu_ion_info { - struct ion_client *ion_client; - bool attached; -}; - -static struct vcodec_ion_buffer * -vcodec_ion_get_buffer_no_lock(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct vcodec_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 -vcodec_ion_clear_session(struct vcodec_iommu_session_info *session_info) -{ - /* do nothing */ -} - -static int vcodec_ion_attach(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_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 0; - } - - rockchip_iovmm_activate(iommu_info->dev); - - ion_info->attached = true; - - mutex_unlock(&iommu_info->iommu_mutex); - - return 0; -} - -static void vcodec_ion_detach(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_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 vcodec_ion_destroy(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_iommu_ion_info *ion_info = iommu_info->private; - - vcodec_ion_detach(iommu_info); - kfree(ion_info); - iommu_info->private = NULL; - - return 0; -} - -static int -vcodec_ion_free(struct vcodec_iommu_session_info *session_info, int idx) -{ - struct vcodec_ion_buffer *ion_buffer; - - mutex_lock(&session_info->list_mutex); - ion_buffer = vcodec_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 -vcodec_ion_unmap_iommu(struct vcodec_iommu_session_info *session_info, int idx) -{ - struct vcodec_ion_buffer *ion_buffer; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_ion_info *ion_info = iommu_info->private; - - mutex_lock(&session_info->list_mutex); - ion_buffer = vcodec_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 -vcodec_ion_map_iommu(struct vcodec_iommu_session_info *session_info, int idx, - dma_addr_t *iova, unsigned long *size) -{ - struct vcodec_ion_buffer *ion_buffer; - struct device *dev = session_info->dev; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_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 = vcodec_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, (unsigned long *)iova, - size); - else - ret = ion_phys(ion_info->ion_client, ion_buffer->handle, - (ion_phys_addr_t *)iova, (size_t *)size); - - return ret; -} - -static int -vcodec_ion_import(struct vcodec_iommu_session_info *session_info, int fd) -{ - struct vcodec_ion_buffer *ion_buffer = NULL; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_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 -vcodec_ion_unmap_kernel(struct vcodec_iommu_session_info *session_info, - int idx) -{ - struct vcodec_ion_buffer *ion_buffer; - - mutex_lock(&session_info->list_mutex); - ion_buffer = vcodec_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; - } - - return 0; -} - -static void* -vcodec_ion_map_kernel(struct vcodec_iommu_session_info *session_info, int idx) -{ - struct vcodec_ion_buffer *ion_buffer; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_ion_info *ion_info = iommu_info->private; - - rockchip_iovmm_invalidate_tlb(session_info->dev); - - mutex_lock(&session_info->list_mutex); - ion_buffer = vcodec_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 NULL; - } - - return ion_map_kernel(ion_info->ion_client, ion_buffer->handle); -} - -static int vcodec_ion_alloc(struct vcodec_iommu_session_info *session_info, - unsigned long size, - unsigned long align) -{ - struct vcodec_ion_buffer *ion_buffer = NULL; - struct vcodec_iommu_info *iommu_info = session_info->iommu_info; - struct vcodec_iommu_ion_info *ion_info = iommu_info->private; - unsigned int heap_id_mask; - - if (iommu_info->mmu_dev) - heap_id_mask = ION_HEAP_TYPE_SYSTEM; - else - heap_id_mask = ION_HEAP_TYPE_DMA; - - ion_buffer = kzalloc(sizeof(*ion_buffer), GFP_KERNEL); - if (!ion_buffer) - return -ENOMEM; - - ion_buffer->handle = ion_alloc(ion_info->ion_client, size, - align, heap_id_mask, 0); - - 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 vcodec_ion_create(struct vcodec_iommu_info *iommu_info) -{ - struct vcodec_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; - - vcodec_ion_attach(iommu_info); - - return IS_ERR(ion_info->ion_client) ? -1 : 0; -} - -static struct vcodec_iommu_ops ion_ops = { - .create = vcodec_ion_create, - .destroy = vcodec_ion_destroy, - .alloc = vcodec_ion_alloc, - .import = vcodec_ion_import, - .free = vcodec_ion_free, - .free_fd = NULL, - .map_kernel = vcodec_ion_map_kernel, - .unmap_kernel = vcodec_ion_unmap_kernel, - .map_iommu = vcodec_ion_map_iommu, - .unmap_iommu = vcodec_ion_unmap_iommu, - .map_iommu_with_iova = NULL, - .unmap_iommu_with_iova = NULL, - .dump = NULL, - .attach = vcodec_ion_attach, - .detach = vcodec_ion_detach, - .clear = vcodec_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 vcodec_iommu_ion_set_ops(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info) - return; - iommu_info->ops = &ion_ops; -} diff --git a/drivers/video/rockchip/vcodec/vcodec_iommu_ops.c b/drivers/video/rockchip/vcodec/vcodec_iommu_ops.c deleted file mode 100644 index 1ca2418fe99c..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_iommu_ops.c +++ /dev/null @@ -1,331 +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 "vcodec_iommu_ops.h" - -static -struct vcodec_iommu_session_info *vcodec_iommu_get_session_info - (struct vcodec_iommu_info *iommu_info, struct vpu_session *session) -{ - struct vcodec_iommu_session_info *session_info = NULL, *n; - - list_for_each_entry_safe(session_info, n, &iommu_info->session_list, - head) { - if (session_info->session == session) - return session_info; - } - - return NULL; -} - -int vcodec_iommu_create(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->create) - return -EINVAL; - - return iommu_info->ops->create(iommu_info); -} - -int vcodec_iommu_alloc(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, - unsigned long size, - unsigned long align) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -ENOMEM; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->alloc || !session) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, session); - if (!session_info) { - session_info = kzalloc(sizeof(*session_info), GFP_KERNEL); - if (!session_info) - goto ERROR; - - INIT_LIST_HEAD(&session_info->head); - INIT_LIST_HEAD(&session_info->buffer_list); - mutex_init(&session_info->list_mutex); - session_info->max_idx = 0; - session_info->session = session; - session_info->mmu_dev = iommu_info->mmu_dev; - session_info->dev = iommu_info->dev; - session_info->iommu_info = iommu_info; - session_info->buffer_nums = 0; - list_add_tail(&session_info->head, &iommu_info->session_list); - } - - session_info->debug_level = iommu_info->debug_level; - result = iommu_info->ops->alloc(session_info, size, align); -ERROR: - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_import(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int fd) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -ENOMEM; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->import || !session) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, session); - if (!session_info) { - session_info = kzalloc(sizeof(*session_info), GFP_KERNEL); - if (!session_info) - goto ERROR; - - INIT_LIST_HEAD(&session_info->head); - INIT_LIST_HEAD(&session_info->buffer_list); - mutex_init(&session_info->list_mutex); - session_info->max_idx = 0; - session_info->session = session; - session_info->mmu_dev = iommu_info->mmu_dev; - session_info->dev = iommu_info->dev; - session_info->iommu_info = iommu_info; - session_info->buffer_nums = 0; - list_add_tail(&session_info->head, &iommu_info->session_list); - } - - session_info->debug_level = iommu_info->debug_level; - result = iommu_info->ops->import(session_info, fd); -ERROR: - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_free(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int idx) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->free) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->free(session_info, idx); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_free_fd(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int fd) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->free_fd) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->free_fd(session_info, fd); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_map_iommu_with_iova(struct vcodec_iommu_info *iommu_info, - void *session, - int idx, unsigned long iova, - unsigned long size) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->map_iommu_with_iova) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->map_iommu_with_iova - (session_info, idx, iova, size); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_unmap_iommu_with_iova(struct vcodec_iommu_info *iommu_info, - void *session, int idx) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->unmap_iommu_with_iova) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->unmap_iommu_with_iova - (session_info, idx); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_map_iommu(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, - int idx, dma_addr_t *iova, - unsigned long *size) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->map_iommu) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->map_iommu(session_info, - idx, iova, size); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -int vcodec_iommu_unmap_iommu(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int idx) -{ - struct vcodec_iommu_session_info *session_info = NULL; - int result = -EINVAL; - - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->unmap_iommu) - return -EINVAL; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) - result = iommu_info->ops->unmap_iommu - (session_info, idx); - mutex_unlock(&iommu_info->list_mutex); - return result; -} - -static int vcodec_iommu_destroy(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->destroy) - return -EINVAL; - return iommu_info->ops->destroy(iommu_info); -} - -void vcodec_iommu_dump(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session) -{ - struct vcodec_iommu_session_info *session_info = NULL; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->dump) - return; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info - (iommu_info, session); - if (session_info) - iommu_info->ops->dump(session_info); - mutex_unlock(&iommu_info->list_mutex); -} - -void vcodec_iommu_clear(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session) -{ - struct vcodec_iommu_session_info *session_info = NULL; - - if (!iommu_info || !iommu_info->ops || - !iommu_info->ops->clear) - return; - mutex_lock(&iommu_info->list_mutex); - session_info = vcodec_iommu_get_session_info(iommu_info, - session); - if (session_info) { - iommu_info->ops->clear(session_info); - list_del_init(&session_info->head); - kfree(session_info); - } - mutex_unlock(&iommu_info->list_mutex); -} - -int vcodec_iommu_attach(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->attach) - return 0; - - return iommu_info->ops->attach(iommu_info); -} - -void vcodec_iommu_detach(struct vcodec_iommu_info *iommu_info) -{ - if (!iommu_info || !iommu_info->ops || !iommu_info->ops->detach) - return; - - return iommu_info->ops->detach(iommu_info); -} - -struct vcodec_iommu_info * -vcodec_iommu_info_create(struct device *dev, - struct device *mmu_dev, - int alloc_type) -{ - struct vcodec_iommu_info *iommu_info = NULL; - - iommu_info = kzalloc(sizeof(*iommu_info), GFP_KERNEL); - if (!iommu_info) - return NULL; - - iommu_info->dev = dev; - INIT_LIST_HEAD(&iommu_info->session_list); - mutex_init(&iommu_info->list_mutex); - mutex_init(&iommu_info->iommu_mutex); - switch (alloc_type) { -#ifdef CONFIG_DRM - case ALLOCATOR_USE_DRM: - vcodec_iommu_drm_set_ops(iommu_info); - break; -#endif -#ifdef CONFIG_ION - case ALLOCATOR_USE_ION: - vcodec_iommu_ion_set_ops(iommu_info); - break; -#endif - default: - iommu_info->ops = NULL; - break; - } - - iommu_info->mmu_dev = mmu_dev; - - vcodec_iommu_create(iommu_info); - - return iommu_info; -} - -int vcodec_iommu_info_destroy(struct vcodec_iommu_info *iommu_info) -{ - vcodec_iommu_destroy(iommu_info); - kfree(iommu_info); - - return 0; -} diff --git a/drivers/video/rockchip/vcodec/vcodec_iommu_ops.h b/drivers/video/rockchip/vcodec/vcodec_iommu_ops.h deleted file mode 100644 index ead745fde2b2..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_iommu_ops.h +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd - * author: Jung Zhao jung.zhao@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. - * - */ - -#ifndef __VCODEC_IOMMU_OPS_H__ -#define __VCODEC_IOMMU_OPS_H__ - -#include -#include "vcodec_service.h" - -#define BUFFER_LIST_MAX_NUMS 30 - -#define ALLOCATOR_USE_ION 0x00000000 -#define ALLOCATOR_USE_DRM 0x00000001 - -#define DEBUG_IOMMU_OPS_DUMP 0x00020000 -#define DEBUG_IOMMU_NORMAL 0x00040000 - -#define vpu_iommu_debug_func(debug_level, type, fmt, args...) \ - do { \ - if (unlikely(debug_level & type)) { \ - pr_info("%s:%d: " fmt, \ - __func__, __LINE__, ##args); \ - } \ - } while (0) -#define vpu_iommu_debug(debug_level, type, fmt, args...) \ - do { \ - if (unlikely(debug_level & type)) { \ - pr_info(fmt, ##args); \ - } \ - } while (0) - -struct vcodec_iommu_info; -struct vcodec_iommu_session_info; - -struct vcodec_iommu_ops { - int (*create)(struct vcodec_iommu_info *iommu_info); - int (*alloc)(struct vcodec_iommu_session_info *session_info, - unsigned long size, - unsigned long align); - int (*import)(struct vcodec_iommu_session_info *session_info, int fd); - int (*free)(struct vcodec_iommu_session_info *session_info, int idx); - int (*free_fd)(struct vcodec_iommu_session_info *session_info, int fd); - void* (*map_kernel)(struct vcodec_iommu_session_info *session_info, - int idx); - int (*unmap_kernel)(struct vcodec_iommu_session_info *session_info, - int idx); - int (*map_iommu)(struct vcodec_iommu_session_info *session_info, - int idx, - dma_addr_t *iova, unsigned long *size); - int (*unmap_iommu)(struct vcodec_iommu_session_info *session_info, - int idx); - int (*map_iommu_with_iova)(struct vcodec_iommu_session_info - *session_info, - int idx, - unsigned long iova, unsigned long size); - int (*unmap_iommu_with_iova)(struct vcodec_iommu_session_info - *session_info, - int idx); - int (*destroy)(struct vcodec_iommu_info *iommu_info); - void (*dump)(struct vcodec_iommu_session_info *session_info); - int (*attach)(struct vcodec_iommu_info *iommu_info); - void (*detach)(struct vcodec_iommu_info *iommu_info); - void (*clear)(struct vcodec_iommu_session_info *session_info); -}; - -struct vcodec_iommu_session_info { - struct list_head head; - struct vpu_session *session; - int buffer_nums; - struct list_head buffer_list; - struct mutex list_mutex; - int max_idx; - struct device *dev; - struct device *mmu_dev; - struct vcodec_iommu_info *iommu_info; - int debug_level; -}; - -struct vcodec_iommu_info { - struct list_head session_list; - struct mutex list_mutex; - struct mutex iommu_mutex; - struct device *dev; - struct device *mmu_dev; - struct vcodec_iommu_ops *ops; - int debug_level; - void *private; -}; - -#ifdef CONFIG_DRM -void vcodec_iommu_drm_set_ops(struct vcodec_iommu_info *iommu_info); -#endif -#ifdef CONFIG_ION -void vcodec_iommu_ion_set_ops(struct vcodec_iommu_info *iommu_info); -#endif - -struct vcodec_iommu_info *vcodec_iommu_info_create(struct device *dev, - struct device *mmu_dev, - int alloc_type); -int vcodec_iommu_info_destroy(struct vcodec_iommu_info *iommu_info); - -int vcodec_iommu_create(struct vcodec_iommu_info *iommu_info); -int vcodec_iommu_alloc(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, - unsigned long size, - unsigned long align); -int vcodec_iommu_import(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int fd); -int vcodec_iommu_free(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int idx); -int vcodec_iommu_free_fd(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, int fd); -int vcodec_iommu_map_iommu(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, - int idx, - dma_addr_t *iova, - unsigned long *size); -int vcodec_iommu_unmap_iommu(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session, - int idx); -int vcodec_iommu_map_iommu_with_iova(struct vcodec_iommu_info *iommu_info, - void *session, - int idx, - unsigned long iova, - unsigned long size); -int vcodec_iommu_unmap_iommu_with_iova(struct vcodec_iommu_info *iommu_info, - void *session, - int idx); -void vcodec_iommu_dump(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session); -void vcodec_iommu_clear(struct vcodec_iommu_info *iommu_info, - struct vpu_session *session); - -int vcodec_iommu_attach(struct vcodec_iommu_info *iommu_info); -void vcodec_iommu_detach(struct vcodec_iommu_info *iommu_info); - -#endif diff --git a/drivers/video/rockchip/vcodec/vcodec_service.c b/drivers/video/rockchip/vcodec/vcodec_service.c deleted file mode 100644 index 5b4bd5b23fc3..000000000000 --- a/drivers/video/rockchip/vcodec/vcodec_service.c +++ /dev/null @@ -1,3941 +0,0 @@ -/** - * Copyright (C) 2015 Fuzhou Rockchip Electronics Co., Ltd - * author: chenhengming, chm@rock-chips.com - * Alpha Lin, alpha.lin@rock-chips.com - * Jung Zhao, jung.zhao@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. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include