aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c71
1 files changed, 42 insertions, 29 deletions
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 3219bb7d161..50656d271c7 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -875,6 +875,35 @@ static inline int venus_hfi_reset_core(struct venus_hfi_device *device)
return rc;
}
+static struct venus_clock *venus_hfi_get_clock(struct venus_hfi_device *device,
+ char *name)
+{
+ struct venus_clock *vc;
+
+ venus_hfi_for_each_clock(device, vc, {
+ if (!strcmp(vc->name, name))
+ return vc;
+ });
+
+ return NULL;
+}
+
+static unsigned long venus_hfi_get_clock_rate(struct venus_clock *clock,
+ int num_mbs_per_sec)
+{
+ int num_rows = clock->count;
+ struct load_freq_table *table = clock->load_freq_tbl;
+ unsigned long ret = table[0].freq;
+ int i;
+ for (i = 0; i < num_rows; i++) {
+ if (num_mbs_per_sec > table[i].load)
+ break;
+ ret = table[i].freq;
+ }
+ dprintk(VIDC_PROF, "Required clock rate = %lu\n", ret);
+ return ret;
+}
+
/*Calling function is responsible to acquire device->clk_pwr_lock*/
static inline int venus_hfi_clk_enable(struct venus_hfi_device *device)
{
@@ -937,6 +966,19 @@ static inline void venus_hfi_clk_disable(struct venus_hfi_device *device)
return;
}
+ /* We get better power savings if we lower the venus core clock to the
+ * lowest level before disabling it. */
+ cl = venus_hfi_get_clock(device, "core_clk");
+ if (cl && cl->has_sw_power_collapse) {
+ int rc = clk_set_rate(cl->clk,
+ venus_hfi_get_clock_rate(cl, 0));
+ if (rc) {
+ dprintk(VIDC_WARN,
+ "Failed to lower core_clk before disabling: %d\n",
+ rc);
+ }
+ }
+
venus_hfi_for_each_clock(device, cl, {
if (cl->has_sw_power_collapse) {
usleep(100);
@@ -1165,22 +1207,6 @@ fail_clk_power_on:
return rc;
}
-static unsigned long venus_hfi_get_clock_rate(struct venus_clock *clock,
- int num_mbs_per_sec)
-{
- int num_rows = clock->count;
- struct load_freq_table *table = clock->load_freq_tbl;
- unsigned long ret = table[0].freq;
- int i;
- for (i = 0; i < num_rows; i++) {
- if (num_mbs_per_sec > table[i].load)
- break;
- ret = table[i].freq;
- }
- dprintk(VIDC_PROF, "Required clock rate = %lu\n", ret);
- return ret;
-}
-
static int venus_hfi_scale_clocks(void *dev, int load)
{
int rc = 0;
@@ -2734,19 +2760,6 @@ err_core_init:
}
-/*static*/ struct clk *venus_hfi_get_clock(struct venus_hfi_device *device,
- char *name)
-{
- struct venus_clock *vc;
-
- venus_hfi_for_each_clock(device, vc, {
- if (!strcmp(vc->name, name))
- return vc->clk;
- });
-
- return NULL;
-}
-
static inline int venus_hfi_init_clocks(struct msm_vidc_platform_resources *res,
struct venus_hfi_device *device)
{