rk3288: vcodec support pd clk operation
authorljf <ljf@rock-chips.com>
Wed, 16 Apr 2014 07:26:49 +0000 (15:26 +0800)
committerljf <ljf@rock-chips.com>
Wed, 16 Apr 2014 07:27:20 +0000 (15:27 +0800)
arch/arm/mach-rockchip/vcodec_service.c

index 4e6de90854a85d8fe443fc37f5fe6f993a8ed0b9..aba5e2358fd886aabef641bdfe88f65aa62c798d 100755 (executable)
@@ -283,6 +283,7 @@ typedef struct vpu_service_info {
     struct clk *hclk_vcodec;\r
     struct clk *clk_core;\r
     struct clk *clk_cabac;\r
+    struct clk *pd_video;\r
 \r
     int irq_dec;\r
     int irq_enc;\r
@@ -331,10 +332,10 @@ static struct dentry* vcodec_debugfs_create_device_dir(char *dirname, struct den
 static int debug_vcodec_open(struct inode *inode, struct file *file);\r
 \r
 static const struct file_operations debug_vcodec_fops = {\r
-       .open = debug_vcodec_open,\r
-       .read = seq_read,\r
-       .llseek = seq_lseek,\r
-       .release = single_release,\r
+    .open = debug_vcodec_open,\r
+    .read = seq_read,\r
+    .llseek = seq_lseek,\r
+    .release = single_release,\r
 };\r
 #endif\r
 \r
@@ -343,42 +344,61 @@ static const struct file_operations debug_vcodec_fops = {
 \r
 #define VPU_SIMULATE_DELAY      msecs_to_jiffies(15)\r
 \r
-static void vpu_get_clk(struct vpu_service_info *pservice)\r
+static int vpu_get_clk(struct vpu_service_info *pservice)\r
 {\r
 #if VCODEC_CLOCK_ENABLE\r
-       /*pd_video      = clk_get(NULL, "pd_video");\r
-       if (IS_ERR(pd_video)) {\r
-               pr_err("failed on clk_get pd_video\n");\r
-       }*/\r
-\r
-       pservice->aclk_vcodec   = devm_clk_get(pservice->dev, "aclk_vcodec");\r
-       if (IS_ERR(pservice->aclk_vcodec)) {\r
-               dev_err(pservice->dev, "failed on clk_get aclk_vcodec\n");\r
-       }\r
-\r
-       pservice->hclk_vcodec   = devm_clk_get(pservice->dev, "hclk_vcodec");\r
-       if (IS_ERR(pservice->hclk_vcodec)) {\r
-               dev_err(pservice->dev, "failed on clk_get hclk_vcodec\n");\r
-       }\r
-\r
-       if (pservice->dev_id == VCODEC_DEVICE_ID_HEVC) {\r
-               pservice->clk_core = devm_clk_get(pservice->dev, "clk_core");\r
-               if (IS_ERR(pservice->clk_core)) {\r
-                       dev_err(pservice->dev, "failed on clk_get clk_core\n");\r
-               }\r
-\r
-               pservice->clk_cabac = devm_clk_get(pservice->dev, "clk_cabac");\r
-               if (IS_ERR(pservice->clk_cabac)) {\r
-                       dev_err(pservice->dev, "failed on clk_get clk_cabac\n");\r
-               }\r
-       }\r
+    do {\r
+        pservice->aclk_vcodec   = devm_clk_get(pservice->dev, "aclk_vcodec");\r
+        if (IS_ERR(pservice->aclk_vcodec)) {\r
+            dev_err(pservice->dev, "failed on clk_get aclk_vcodec\n");\r
+            break;\r
+        }\r
+    \r
+        pservice->hclk_vcodec   = devm_clk_get(pservice->dev, "hclk_vcodec");\r
+        if (IS_ERR(pservice->hclk_vcodec)) {\r
+            dev_err(pservice->dev, "failed on clk_get hclk_vcodec\n");\r
+            break;\r
+        }\r
+    \r
+        if (pservice->dev_id == VCODEC_DEVICE_ID_HEVC) {\r
+            pservice->clk_core = devm_clk_get(pservice->dev, "clk_core");\r
+            if (IS_ERR(pservice->clk_core)) {\r
+                dev_err(pservice->dev, "failed on clk_get clk_core\n");\r
+                break;\r
+            }\r
+    \r
+            pservice->clk_cabac = devm_clk_get(pservice->dev, "clk_cabac");\r
+            if (IS_ERR(pservice->clk_cabac)) {\r
+                dev_err(pservice->dev, "failed on clk_get clk_cabac\n");\r
+                break;\r
+            }\r
+            \r
+            pservice->pd_video = devm_clk_get(pservice->dev, "pd_hevc");\r
+            if (IS_ERR(pservice->pd_video)) {\r
+                dev_err(pservice->dev, "failed on clk_get pd_hevc\n");\r
+                break;\r
+            }\r
+        } else {\r
+            pservice->pd_video = devm_clk_get(pservice->dev, "pd_video");\r
+            if (IS_ERR(pservice->pd_video)) {\r
+                dev_err(pservice->dev, "failed on clk_get pd_video\n");\r
+                break;\r
+            }\r
+        }\r
+        \r
+        return 0;\r
+    } while (0);\r
+    \r
+    return -1;\r
 #endif\r
 }\r
 \r
 static void vpu_put_clk(struct vpu_service_info *pservice)\r
 {\r
 #if VCODEC_CLOCK_ENABLE\r
-    //clk_put(pd_video);\r
+    if (pservice->pd_video) {\r
+        devm_clk_put(pservice->dev, pservice->pd_video);\r
+    }\r
 \r
     if (pservice->aclk_vcodec) {\r
         devm_clk_put(pservice->dev, pservice->aclk_vcodec);\r
@@ -492,23 +512,19 @@ static void vpu_service_power_off(struct vpu_service_info *pservice)
                vpu_service_dump(pservice);\r
        }\r
 \r
-       printk("%s: power off...", dev_name(pservice->dev));\r
-#ifdef CONFIG_ARCH_RK29\r
-       pmu_set_power_domain(PD_VCODEC, false);\r
-#else\r
-       //clk_disable(pd_video);\r
-#endif\r
-       udelay(10);\r
+    printk("%s: power off...", dev_name(pservice->dev));\r
+    udelay(10);\r
 #if VCODEC_CLOCK_ENABLE\r
-       clk_disable_unprepare(pservice->hclk_vcodec);\r
-       clk_disable_unprepare(pservice->aclk_vcodec);\r
+    clk_disable_unprepare(pservice->pd_video);\r
+    clk_disable_unprepare(pservice->hclk_vcodec);\r
+    clk_disable_unprepare(pservice->aclk_vcodec);\r
     if (pservice->dev_id == VCODEC_DEVICE_ID_HEVC) {\r
         clk_disable_unprepare(pservice->clk_core);\r
         clk_disable_unprepare(pservice->clk_cabac);\r
     }\r
 #endif\r
-       wake_unlock(&pservice->wake_lock);\r
-       printk("done\n");\r
+    wake_unlock(&pservice->wake_lock);\r
+    printk("done\n");\r
 }\r
 \r
 static inline void vpu_queue_power_off_work(struct vpu_service_info *pservice)\r
@@ -532,27 +548,29 @@ static void vpu_power_off_work(struct work_struct *work_s)
 \r
 static void vpu_service_power_on(struct vpu_service_info *pservice)\r
 {\r
-       static ktime_t last;\r
-       ktime_t now = ktime_get();\r
-       if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) {\r
-               cancel_delayed_work_sync(&pservice->power_off_work);\r
-               vpu_queue_power_off_work(pservice);\r
-               last = now;\r
-       }\r
-       if (pservice->enabled)\r
-               return ;\r
+    static ktime_t last;\r
+    ktime_t now = ktime_get();\r
+    if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) {\r
+        cancel_delayed_work_sync(&pservice->power_off_work);\r
+        vpu_queue_power_off_work(pservice);\r
+        last = now;\r
+    }\r
+    if (pservice->enabled)\r
+        return ;\r
 \r
-       pservice->enabled = true;\r
-       printk("%s: power on\n", dev_name(pservice->dev));\r
+    pservice->enabled = true;\r
+    printk("%s: power on\n", dev_name(pservice->dev));\r
 \r
 #if VCODEC_CLOCK_ENABLE\r
     clk_prepare_enable(pservice->aclk_vcodec);\r
-       clk_prepare_enable(pservice->hclk_vcodec);\r
+    clk_prepare_enable(pservice->hclk_vcodec);\r
 \r
     if (pservice->dev_id == VCODEC_DEVICE_ID_HEVC) {\r
         clk_prepare_enable(pservice->clk_core);\r
         clk_prepare_enable(pservice->clk_cabac);\r
     }\r
+    \r
+    clk_prepare_enable(pservice->pd_video);\r
 #endif\r
 \r
 #if defined(CONFIG_ARCH_RK319X)\r
@@ -560,14 +578,9 @@ static void vpu_service_power_on(struct vpu_service_info *pservice)
     #define BIT_VCODEC_SEL  (1<<7)\r
     writel_relaxed(readl_relaxed(RK319X_GRF_BASE + GRF_SOC_CON1) | (BIT_VCODEC_SEL) | (BIT_VCODEC_SEL << 16), RK319X_GRF_BASE + GRF_SOC_CON1);\r
 #endif\r
-       udelay(10);\r
-#ifdef CONFIG_ARCH_RK29\r
-       pmu_set_power_domain(PD_VCODEC, true);\r
-#else\r
-       //clk_enable(pd_video);\r
-#endif\r
-       udelay(10);\r
-       wake_lock(&pservice->wake_lock);\r
+    \r
+    udelay(10);\r
+    wake_lock(&pservice->wake_lock);\r
 }\r
 \r
 static inline bool reg_check_rmvb_wmv(vpu_reg *reg)\r
@@ -1402,7 +1415,9 @@ static int vcodec_probe(struct platform_device *pdev)
 \r
     pservice->dev = dev;\r
 \r
-    vpu_get_clk(pservice);\r
+    if (0 > vpu_get_clk(pservice)) {\r
+        goto err;\r
+    }\r
 \r
     INIT_DELAYED_WORK(&pservice->power_off_work, vpu_power_off_work);\r
 \r