msm: vidc: Set no memory retention for video clocks
Currently, certain memories are set to retain their contents even after clocks are off. Here, we set the no memory retention flags for the associated clocks, to save power. CRs-Fixed: 1044381 Change-Id: I87c34fece6cb352ecef3aaeb8a02c1196fa8bcc3 Signed-off-by: Chinmay Sawarkar <chinmays@codeaurora.org>
This commit is contained in:
parent
e94b446eac
commit
050ef43ec7
4 changed files with 58 additions and 1 deletions
|
@ -25,6 +25,7 @@
|
|||
|
||||
enum clock_properties {
|
||||
CLOCK_PROP_HAS_SCALING = 1 << 0,
|
||||
CLOCK_PROP_HAS_MEM_RETENTION = 1 << 1,
|
||||
};
|
||||
static int msm_vidc_populate_legacy_context_bank(
|
||||
struct msm_vidc_platform_resources *res);
|
||||
|
@ -943,6 +944,11 @@ static int msm_vidc_load_clock_table(
|
|||
vc->has_scaling = false;
|
||||
}
|
||||
|
||||
if (clock_props[c] & CLOCK_PROP_HAS_MEM_RETENTION)
|
||||
vc->has_mem_retention = true;
|
||||
else
|
||||
vc->has_mem_retention = false;
|
||||
|
||||
dprintk(VIDC_DBG, "Found clock %s: scale-able = %s\n", vc->name,
|
||||
vc->count ? "yes" : "no");
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ struct clock_info {
|
|||
struct load_freq_table *load_freq_tbl;
|
||||
u32 count;
|
||||
bool has_scaling;
|
||||
bool has_mem_retention;
|
||||
};
|
||||
|
||||
struct clock_set {
|
||||
|
|
|
@ -3796,6 +3796,22 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device)
|
|||
if (cl->has_scaling)
|
||||
clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0));
|
||||
|
||||
if (cl->has_mem_retention) {
|
||||
rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_PERIPH);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN,
|
||||
"Failed set flag NORETAIN_PERIPH %s\n",
|
||||
cl->name);
|
||||
}
|
||||
|
||||
rc = clk_set_flags(cl->clk, CLKFLAG_NORETAIN_MEM);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN,
|
||||
"Failed set flag NORETAIN_MEM %s\n",
|
||||
cl->name);
|
||||
}
|
||||
}
|
||||
|
||||
rc = clk_prepare_enable(cl->clk);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to enable clocks\n");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk/msm-clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -111,6 +112,7 @@ struct vmem {
|
|||
struct {
|
||||
const char *name;
|
||||
struct clk *clk;
|
||||
bool has_mem_retention;
|
||||
} *clocks;
|
||||
int num_clocks;
|
||||
struct {
|
||||
|
@ -186,6 +188,21 @@ static inline int __power_on(struct vmem *v)
|
|||
pr_debug("Enabled regulator vdd\n");
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
if (v->clocks[c].has_mem_retention) {
|
||||
rc = clk_set_flags(v->clocks[c].clk,
|
||||
CLKFLAG_NORETAIN_PERIPH);
|
||||
if (rc) {
|
||||
pr_warn("Failed set flag NORETAIN_PERIPH %s\n",
|
||||
v->clocks[c].name);
|
||||
}
|
||||
rc = clk_set_flags(v->clocks[c].clk,
|
||||
CLKFLAG_NORETAIN_MEM);
|
||||
if (rc) {
|
||||
pr_warn("Failed set flag NORETAIN_MEM %s\n",
|
||||
v->clocks[c].name);
|
||||
}
|
||||
}
|
||||
|
||||
rc = clk_prepare_enable(v->clocks[c].clk);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable %s clock (%d)\n",
|
||||
|
@ -448,6 +465,7 @@ static inline int __init_resources(struct vmem *v,
|
|||
struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0, c = 0;
|
||||
int *clock_props = NULL;
|
||||
|
||||
v->irq = platform_get_irq(pdev, 0);
|
||||
if (v->irq < 0) {
|
||||
|
@ -504,6 +522,21 @@ static inline int __init_resources(struct vmem *v,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
clock_props = devm_kzalloc(&pdev->dev,
|
||||
v->num_clocks * sizeof(*clock_props),
|
||||
GFP_KERNEL);
|
||||
if (!clock_props) {
|
||||
pr_err("Failed to allocate clock config table\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(pdev->dev.of_node, "clock-config",
|
||||
clock_props, v->num_clocks);
|
||||
if (rc) {
|
||||
pr_err("Failed to read clock config\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
const char *name = NULL;
|
||||
struct clk *temp = NULL;
|
||||
|
@ -519,6 +552,7 @@ static inline int __init_resources(struct vmem *v,
|
|||
|
||||
v->clocks[c].clk = temp;
|
||||
v->clocks[c].name = name;
|
||||
v->clocks[c].has_mem_retention = clock_props[c];
|
||||
}
|
||||
|
||||
v->vdd = devm_regulator_get(&pdev->dev, "vdd");
|
||||
|
|
Loading…
Add table
Reference in a new issue