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
static inline int reg_probe_width(vpu_reg *reg)\r
{\r
- int width_in_mb = reg->reg[4] >> 23;\r
- \r
- return width_in_mb * 16;\r
+ int width_in_mb = reg->reg[4] >> 23;\r
+\r
+ return width_in_mb * 16;\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
INIT_LIST_HEAD(®->status_link);\r
\r
#if defined(CONFIG_VCODEC_MMU) \r
- if (pservice->mmu_dev) {\r
- INIT_LIST_HEAD(®->mem_region_list);\r
- }\r
+ if (pservice->mmu_dev) {\r
+ INIT_LIST_HEAD(®->mem_region_list);\r
+ }\r
#endif\r
\r
if (copy_from_user(®->reg[0], (void __user *)src, size)) {\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