#include <linux/wakelock.h>\r
#include <linux/cdev.h>\r
#include <linux/of.h>\r
+#include <linux/of_platform.h>\r
#include <linux/rockchip/cpu.h>\r
#include <linux/rockchip/cru.h>\r
\r
#endif\r
\r
#ifdef CONFIG_VCODEC_MMU\r
-#include <linux/rockchip/iovmm.h>\r
-#include <linux/rockchip/sysmmu.h>\r
+#include <linux/rockchip-iovmm.h>\r
#include <linux/dma-buf.h>\r
#endif\r
\r
unsigned long dec_io_size;\r
} VPU_HW_INFO_E;\r
\r
+struct extra_info_elem {\r
+ u32 index;\r
+ u32 offset;\r
+};\r
+\r
+#define EXTRA_INFO_MAGIC 0x4C4A46\r
+\r
+struct extra_info_for_iommu {\r
+ u32 magic;\r
+ u32 cnt;\r
+ struct extra_info_elem elem[20];\r
+};\r
+\r
#define VPU_SERVICE_SHOW_TIME 0\r
\r
#if VPU_SERVICE_SHOW_TIME\r
\r
#if defined(CONFIG_VCODEC_MMU)\r
if (pservice->mmu_dev)\r
- iovmm_activate(pservice->dev);\r
-#endif\r
+ rockchip_iovmm_activate(pservice->dev);\r
+#endif \r
}\r
\r
static inline bool reg_check_rmvb_wmv(vpu_reg *reg)\r
}\r
\r
#if defined(CONFIG_VCODEC_MMU)\r
-static int vcodec_bufid_to_iova(struct vpu_service_info *pservice, u8 *tbl, int size, vpu_reg *reg)\r
+static int vcodec_bufid_to_iova(struct vpu_service_info *pservice, u8 *tbl,\r
+ int size, vpu_reg *reg,\r
+ struct extra_info_for_iommu *ext_inf)\r
{\r
int i;\r
int usr_fd = 0;\r
list_add_tail(&mem_region->reg_lnk, ®->mem_region_list);\r
}\r
}\r
+\r
+ if (ext_inf != NULL && ext_inf->magic == EXTRA_INFO_MAGIC) {\r
+ for (i=0; i<ext_inf->cnt; i++) {\r
+ pr_info("reg[%d] + offset %d\n", ext_inf->elem[i].index, ext_inf->elem[i].offset);\r
+ reg->reg[ext_inf->elem[i].index] += ext_inf->elem[i].offset;\r
+ }\r
+ }\r
+\r
return 0;\r
}\r
\r
-static int vcodec_reg_address_translate(struct vpu_service_info *pservice, vpu_reg *reg)\r
+static int vcodec_reg_address_translate(struct vpu_service_info *pservice,\r
+ vpu_reg *reg,\r
+ struct extra_info_for_iommu *ext_inf)\r
{\r
VPU_HW_ID hw_id;\r
u8 *tbl;\r
}\r
\r
if (size != 0) {\r
- return vcodec_bufid_to_iova(pservice, tbl, size, reg);\r
+ return vcodec_bufid_to_iova(pservice, tbl, size, reg, ext_inf);\r
} else {\r
return -1;\r
}\r
\r
static vpu_reg *reg_init(struct vpu_service_info *pservice, vpu_session *session, void __user *src, unsigned long size)\r
{\r
+ int extra_size = 0;\r
+ struct extra_info_for_iommu extra_info;\r
vpu_reg *reg = kmalloc(sizeof(vpu_reg)+pservice->reg_size, GFP_KERNEL);\r
if (NULL == reg) {\r
pr_err("error: kmalloc fail in reg_init\n");\r
}\r
\r
if (size > pservice->reg_size) {\r
- printk("warning: vpu reg size %lu is larger than hw reg size %lu\n", size, pservice->reg_size);\r
+ /*printk("warning: vpu reg size %lu is larger than hw reg size %lu\n", size, pservice->reg_size);\r
+ size = pservice->reg_size;*/\r
+ extra_size = size - pservice->reg_size;\r
size = pservice->reg_size;\r
}\r
reg->session = session;\r
return NULL;\r
}\r
\r
+ if (copy_from_user(&extra_info, (u8 *)src + size, extra_size)) {\r
+ pr_err("error: copy_from_user failed in reg_init\n");\r
+ kfree(reg);\r
+ return NULL;\r
+ }\r
+\r
#if defined(CONFIG_VCODEC_MMU)\r
- if (pservice->mmu_dev && 0 > vcodec_reg_address_translate(pservice, reg)) {\r
+ if (pservice->mmu_dev && 0 > vcodec_reg_address_translate(pservice, reg, &extra_info)) {\r
pr_err("error: translate reg address failed\n");\r
kfree(reg);\r
return NULL;\r
list_add_tail(®->session_link, ®->session->running);\r
}\r
\r
-static void reg_copy_from_hw(struct vpu_service_info *pservice, vpu_reg *reg, volatile u32 *src, u32 count)\r
+static void reg_copy_from_hw(vpu_reg *reg, volatile u32 *src, u32 count)\r
{\r
int i;\r
u32 *dst = (u32 *)®->reg[0];\r
switch (reg->type) {\r
case VPU_ENC : {\r
pservice->reg_codec = NULL;\r
- reg_copy_from_hw(pservice, reg, pservice->enc_dev.hwregs, pservice->hw_info->enc_reg_num);\r
+ reg_copy_from_hw(reg, pservice->enc_dev.hwregs, pservice->hw_info->enc_reg_num);\r
irq_reg = ENC_INTERRUPT_REGISTER;\r
break;\r
}\r
case VPU_DEC : {\r
int reg_len = pservice->hw_info->hw_id == HEVC_ID ? REG_NUM_HEVC_DEC : REG_NUM_9190_DEC;\r
pservice->reg_codec = NULL;\r
- reg_copy_from_hw(pservice, reg, pservice->dec_dev.hwregs, reg_len);\r
+ reg_copy_from_hw(reg, pservice->dec_dev.hwregs, reg_len);\r
irq_reg = DEC_INTERRUPT_REGISTER;\r
break;\r
}\r
case VPU_PP : {\r
pservice->reg_pproc = NULL;\r
- reg_copy_from_hw(pservice, reg, pservice->dec_dev.hwregs + PP_INTERRUPT_REGISTER, REG_NUM_9190_PP);\r
+ reg_copy_from_hw(reg, pservice->dec_dev.hwregs + PP_INTERRUPT_REGISTER, REG_NUM_9190_PP);\r
pservice->dec_dev.hwregs[PP_INTERRUPT_REGISTER] = 0;\r
break;\r
}\r
case VPU_DEC_PP : {\r
pservice->reg_codec = NULL;\r
pservice->reg_pproc = NULL;\r
- reg_copy_from_hw(pservice, reg, pservice->dec_dev.hwregs, REG_NUM_9190_DEC_PP);\r
+ reg_copy_from_hw(reg, pservice->dec_dev.hwregs, REG_NUM_9190_DEC_PP);\r
pservice->dec_dev.hwregs[PP_INTERRUPT_REGISTER] = 0;\r
break;\r
}\r
}\r
#endif\r
\r
+#ifdef CONFIG_VCODEC_MMU\r
+static struct device *rockchip_get_sysmmu_device_by_compatible(const char *compt)\r
+{\r
+ struct device_node *dn = NULL;\r
+ struct platform_device *pd = NULL;\r
+ struct device *ret = NULL ;\r
+\r
+ dn = of_find_compatible_node(NULL,NULL,compt);\r
+ if(!dn) {\r
+ printk("can't find device node %s \r\n",compt);\r
+ return NULL;\r
+ }\r
+ \r
+ pd = of_find_device_by_node(dn);\r
+ if(!pd) { \r
+ printk("can't find platform device in device node %s \r\n",compt);\r
+ return NULL;\r
+ }\r
+ ret = &pd->dev;\r
+ \r
+ return ret;\r
+\r
+}\r
+#ifdef CONFIG_IOMMU_API\r
+static inline void platform_set_sysmmu(struct device *iommu, struct device *dev)\r
+{\r
+ dev->archdata.iommu = iommu;\r
+}\r
+#else\r
+static inline void platform_set_sysmmu(struct device *iommu, struct device *dev)\r
+{\r
+}\r
+#endif\r
+#endif\r
+\r
#if HEVC_TEST_ENABLE\r
static int hevc_test_case0(vpu_service_info *pservice);\r
#endif\r
}\r
\r
if (pservice->hw_info->hw_id == HEVC_ID)\r
- sprintf(mmu_dev_dts_name, "iommu,hevc_mmu");\r
+ sprintf(mmu_dev_dts_name, HEVC_IOMMU_COMPATIBLE_NAME);\r
else\r
- sprintf(mmu_dev_dts_name, "iommu,vpu_mmu");\r
+ sprintf(mmu_dev_dts_name, VPU_IOMMU_COMPATIBLE_NAME);\r
\r
pservice->mmu_dev = rockchip_get_sysmmu_device_by_compatible(mmu_dev_dts_name);\r
\r
if (pservice->mmu_dev) {\r
platform_set_sysmmu(pservice->mmu_dev, pservice->dev);\r
- iovmm_activate(pservice->dev);\r
+ rockchip_iovmm_activate(pservice->dev);\r
}\r
}\r
#endif\r