rk29: add clk_vpu for notify vpu power on
author黄涛 <huangtao@rock-chips.com>
Thu, 20 Oct 2011 03:15:25 +0000 (11:15 +0800)
committer黄涛 <huangtao@rock-chips.com>
Thu, 20 Oct 2011 03:30:34 +0000 (11:30 +0800)
arch/arm/mach-rk29/clock.c
arch/arm/mach-rk29/cpufreq.c
arch/arm/mach-rk29/vpu_service.c

index 4419dfc48b4867c0008d810e083e13fbf7761c80..327a321bfdcfb0696c9c260ccae71e7d698314a3 100755 (executable)
@@ -1684,6 +1684,11 @@ static struct clk hclk_lcdc = {
        .clksel_maxdiv  = 4,
 };
 
+/* for vpu power on notify */
+static struct clk clk_vpu = {
+       .name           = "vpu",
+};
+
 static struct clk *xpu_parents[4] = { &general_pll_clk, &ddr_pll_clk, &codec_pll_clk, &arm_pll_clk };
 
 static struct clk aclk_vepu = {
@@ -2127,6 +2132,7 @@ static struct clk_lookup clks[] = {
        CLK(NULL, "aclk_lcdc", &aclk_lcdc),
        CLK(NULL, "hclk_lcdc", &hclk_lcdc),
 
+       CLK1(vpu),
        CLK(NULL, "aclk_vepu", &aclk_vepu),
        CLK(NULL, "hclk_vepu", &hclk_vepu),
        CLK(NULL, "aclk_vdpu", &aclk_vdpu),
@@ -2986,7 +2992,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
        int r;
        struct clk *clkp;
 
-       if (!clk || !nb)
+       if (!clk || IS_ERR(clk) || !nb)
                return -EINVAL;
 
        mutex_lock(&clocks_mutex);
@@ -3042,7 +3048,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
        struct clk *clkp;
        int r = -EINVAL;
 
-       if (!clk || !nb)
+       if (!clk || IS_ERR(clk) || !nb)
                return -EINVAL;
 
        mutex_lock(&clocks_mutex);
index bbc7bcc601073214fa081afa90acdaa2481ff5a5..d7199f533d6277650d8c3f5f5de197d2be1b6838 100755 (executable)
@@ -191,7 +191,7 @@ static bool limit_gpu_high;
 module_param(limit_vpu_enabled, bool, 0644);
 module_param(limit_gpu_enabled, bool, 0644);
 module_param(limit_gpu_high, bool, 0644);
-static struct clk* aclk_vepu;
+static struct clk* clk_vpu;
 static struct clk* clk_gpu;
 #define GPU_LOW_RATE   (300 * MHZ)
 static unsigned long limit_gpu_low_rate = GPU_LOW_RATE;
@@ -451,7 +451,7 @@ static void rk29_cpufreq_limit_by_temp_work_func(struct work_struct *work)
        queue_delayed_work(wq, &rk29_cpufreq_limit_by_temp_work, WORK_DELAY);
 }
 
-static int rk29_cpufreq_aclk_vepu_notifier_event(struct notifier_block *this,
+static int rk29_cpufreq_vpu_notifier_event(struct notifier_block *this,
                unsigned long event, void *ptr)
 {
        switch (event) {
@@ -478,11 +478,11 @@ static int rk29_cpufreq_aclk_vepu_notifier_event(struct notifier_block *this,
        return NOTIFY_OK;
 }
 
-static struct notifier_block rk29_cpufreq_aclk_vepu_notifier = {
-       .notifier_call = rk29_cpufreq_aclk_vepu_notifier_event,
+static struct notifier_block rk29_cpufreq_vpu_notifier = {
+       .notifier_call = rk29_cpufreq_vpu_notifier_event,
 };
 
-static int rk29_cpufreq_clk_gpu_notifier_event(struct notifier_block *this,
+static int rk29_cpufreq_gpu_notifier_event(struct notifier_block *this,
                unsigned long event, void *ptr)
 {
        struct clk_notifier_data *cnd = ptr;
@@ -526,8 +526,8 @@ static int rk29_cpufreq_clk_gpu_notifier_event(struct notifier_block *this,
        return NOTIFY_OK;
 }
 
-static struct notifier_block rk29_cpufreq_clk_gpu_notifier = {
-       .notifier_call = rk29_cpufreq_clk_gpu_notifier_event,
+static struct notifier_block rk29_cpufreq_gpu_notifier = {
+       .notifier_call = rk29_cpufreq_gpu_notifier_event,
 };
 #endif
 
@@ -626,9 +626,9 @@ static int rk29_cpufreq_init(struct cpufreq_policy *policy)
        cpufreq_register_notifier(&notifier_policy_block, CPUFREQ_POLICY_NOTIFIER);
        if (limit_max_freq > 1008000) {
                clk_gpu = clk_get(NULL, "gpu");
-               aclk_vepu = clk_get(NULL, "aclk_vepu");
-               clk_notifier_register(clk_gpu, &rk29_cpufreq_clk_gpu_notifier);
-               clk_notifier_register(aclk_vepu, &rk29_cpufreq_aclk_vepu_notifier);
+               clk_vpu = clk_get(NULL, "vpu");
+               clk_notifier_register(clk_gpu, &rk29_cpufreq_gpu_notifier);
+               clk_notifier_register(clk_vpu, &rk29_cpufreq_vpu_notifier);
        }
 #endif
 #ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
@@ -644,10 +644,10 @@ static int rk29_cpufreq_exit(struct cpufreq_policy *policy)
 #endif
 #ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
        if (limit_max_freq > 1008000) {
-               clk_notifier_unregister(clk_gpu, &rk29_cpufreq_clk_gpu_notifier);
-               clk_notifier_unregister(aclk_vepu, &rk29_cpufreq_aclk_vepu_notifier);
+               clk_notifier_unregister(clk_gpu, &rk29_cpufreq_gpu_notifier);
+               clk_notifier_unregister(clk_vpu, &rk29_cpufreq_vpu_notifier);
                clk_put(clk_gpu);
-               clk_put(aclk_vepu);
+               clk_put(clk_vpu);
        }
        cpufreq_unregister_notifier(&notifier_policy_block, CPUFREQ_POLICY_NOTIFIER);
        if (wq)
index 2f70a8331d8d8889e9cf32bf63eef3fc55f5521d..80b28499047281d5c9b1c0807c7d910e1123816c 100644 (file)
@@ -142,6 +142,7 @@ typedef struct vpu_request
        unsigned long   size;
 } vpu_request;
 
+static struct clk *clk_vpu; /* for power on notify */
 static struct clk *aclk_vepu;
 static struct clk *hclk_vepu;
 static struct clk *aclk_ddr_vepu;
@@ -155,6 +156,7 @@ static vpu_device   enc_dev;
 
 static void vpu_get_clk(void)
 {
+       clk_vpu         = clk_get(NULL, "vpu");
        aclk_vepu       = clk_get(NULL, "aclk_vepu");
        hclk_vepu       = clk_get(NULL, "hclk_vepu");
        aclk_ddr_vepu   = clk_get(NULL, "aclk_ddr_vepu");
@@ -163,6 +165,7 @@ static void vpu_get_clk(void)
 
 static void vpu_put_clk(void)
 {
+       clk_put(clk_vpu);
        clk_put(aclk_vepu);
        clk_put(hclk_vepu);
        clk_put(aclk_ddr_vepu);
@@ -254,6 +257,7 @@ static void vpu_service_power_off(void)
        clk_disable(aclk_ddr_vepu);
        clk_disable(hclk_vepu);
        clk_disable(aclk_vepu);
+       clk_disable(clk_vpu);
        printk("done\n");
 }
 
@@ -274,11 +278,14 @@ static void vpu_service_power_maintain(void)
 
 static void vpu_service_power_on(void)
 {
+       clk_enable(clk_vpu); /* notify vpu on without lock. */
+
        spin_lock_bh(&service.lock);
        if (!service.enabled) {
                service.enabled = true;
                printk("vpu: power on\n");
 
+               clk_enable(clk_vpu);
                clk_enable(aclk_vepu);
                clk_enable(hclk_vepu);
                clk_enable(hclk_cpu_vcodec);
@@ -295,6 +302,8 @@ static void vpu_service_power_on(void)
                spin_unlock_bh(&service.lock);
                vpu_service_power_maintain();
        }
+
+       clk_disable(clk_vpu);
 }
 
 static vpu_reg *reg_init(vpu_session *session, void __user *src, unsigned long size)