rk3288: solve vcodec pd control cause decoding failure when iommu enable
authorljf <ljf@rock-chips.com>
Tue, 13 May 2014 09:36:28 +0000 (17:36 +0800)
committerljf <ljf@rock-chips.com>
Tue, 13 May 2014 09:36:28 +0000 (17:36 +0800)
arch/arm/mach-rockchip/vcodec_service.c

index a3207fbc4906f2b4bd38638225043bf0ecec7824..4b7ee70ccdc62c9c9a4c9334191d014d299422b7 100755 (executable)
@@ -346,10 +346,8 @@ typedef struct vpu_service_info {
     u32 irq_status;\r
 #if defined(CONFIG_VCODEC_MMU) \r
        struct ion_client * ion_client;\r
-#endif \r
-\r
-#if defined(CONFIG_VCODEC_MMU)\r
     struct list_head mem_region_list;\r
+    struct device *mmu_dev;\r
 #endif\r
 \r
        enum vcodec_device_id dev_id;\r
@@ -567,6 +565,12 @@ static void vpu_service_power_off(struct vpu_service_info *pservice)
 #endif\r
     wake_unlock(&pservice->wake_lock);\r
     printk("done\n");\r
+    \r
+#if defined(CONFIG_VCODEC_MMU)\r
+    if (pservice->mmu_dev) {\r
+        iovmm_deactivate(pservice->dev);\r
+    }\r
+#endif    \r
 }\r
 \r
 static inline void vpu_queue_power_off_work(struct vpu_service_info *pservice)\r
@@ -623,6 +627,12 @@ static void vpu_service_power_on(struct vpu_service_info *pservice)
     \r
     udelay(10);\r
     wake_lock(&pservice->wake_lock);\r
+    \r
+#if defined(CONFIG_VCODEC_MMU)    \r
+    if (pservice->mmu_dev) {\r
+        iovmm_activate(pservice->dev);\r
+    }\r
+#endif    \r
 }\r
 \r
 static inline bool reg_check_rmvb_wmv(vpu_reg *reg)\r
@@ -796,8 +806,10 @@ static vpu_reg *reg_init(struct vpu_service_info *pservice, vpu_session *session
        INIT_LIST_HEAD(&reg->session_link);\r
        INIT_LIST_HEAD(&reg->status_link);\r
 \r
-#if defined(CONFIG_VCODEC_MMU)    \r
-       INIT_LIST_HEAD(&reg->mem_region_list);\r
+#if defined(CONFIG_VCODEC_MMU)  \r
+        if (pservice->mmu_dev) {\r
+            INIT_LIST_HEAD(&reg->mem_region_list);\r
+        }\r
 #endif\r
 \r
        if (copy_from_user(&reg->reg[0], (void __user *)src, size)) {\r
@@ -807,7 +819,7 @@ static vpu_reg *reg_init(struct vpu_service_info *pservice, vpu_session *session
        }\r
 \r
 #if defined(CONFIG_VCODEC_MMU)\r
-       if (0 > vcodec_reg_address_translate(pservice, reg)) {\r
+       if (pservice->mmu_dev && 0 > vcodec_reg_address_translate(pservice, reg)) {\r
                pr_err("error: translate reg address failed\n");\r
                kfree(reg);\r
                return NULL;\r
@@ -1280,11 +1292,12 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, unsigned long
                break;\r
        }\r
        case VPU_IOC_PROBE_IOMMU_STATUS: {\r
-#if defined(CONFIG_VCODEC_MMU)\r
-               int iommu_enable = 1;\r
-#else\r
                int iommu_enable = 0;\r
-#endif\r
+\r
+#if defined(CONFIG_VCODEC_MMU)                \r
+                iommu_enable = pservice->mmu_dev ? 1 : 0; \r
+#endif                \r
+\r
                if (copy_to_user((void __user *)arg, &iommu_enable, sizeof(int))) {\r
                        pr_err("error: VPU_IOC_PROBE_IOMMU_STATUS copy_to_user failed\n");\r
                        return -EFAULT;\r
@@ -1438,7 +1451,6 @@ static int vcodec_probe(struct platform_device *pdev)
     struct vpu_service_info *pservice = devm_kzalloc(dev, sizeof(struct vpu_service_info), GFP_KERNEL);\r
     char *prop = (char*)dev_name(dev);\r
 #if defined(CONFIG_VCODEC_MMU)\r
-    struct device *mmu_dev = NULL;\r
     char mmu_dev_dts_name[40];\r
 #endif\r
 \r
@@ -1466,7 +1478,9 @@ static int vcodec_probe(struct platform_device *pdev)
     pservice->reg_pproc        = NULL;\r
     atomic_set(&pservice->total_running, 0);\r
     pservice->enabled = false;\r
-\r
+#if defined(CONFIG_VCODEC_MMU)    \r
+    pservice->mmu_dev = NULL;\r
+#endif    \r
     pservice->dev = dev;\r
 \r
     if (0 > vpu_get_clk(pservice)) {\r
@@ -1603,10 +1617,10 @@ static int vcodec_probe(struct platform_device *pdev)
         sprintf(mmu_dev_dts_name, "iommu,vpu_mmu");\r
     }\r
     \r
-    mmu_dev = rockchip_get_sysmmu_device_by_compatible(mmu_dev_dts_name);\r
+    pservice->mmu_dev = rockchip_get_sysmmu_device_by_compatible(mmu_dev_dts_name);\r
     \r
-    if (mmu_dev) {\r
-        platform_set_sysmmu(mmu_dev, pservice->dev);\r
+    if (pservice->mmu_dev) {\r
+        platform_set_sysmmu(pservice->mmu_dev, pservice->dev);\r
         iovmm_activate(pservice->dev);\r
     }\r
 #endif\r