video: rockchip: mpp: clock relative code refactoring

1. read clock setting using the common code from dtsi.
2. clock enable/disable, all devices using the same function.
3. clock frequency set to two levels: normal and advanced.
4. according to specific requirements, the frequency is set
   level instead of the value.

Change-Id: Idcf8e0f49987df20f3eb2574aff316e507f82cfe
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2020-06-23 17:25:02 +08:00
committed by Tao Huang
parent 08c8b2fbdd
commit bcdfd733fa
9 changed files with 514 additions and 538 deletions

View File

@@ -1707,20 +1707,6 @@ irqreturn_t mpp_dev_isr_sched(int irq, void *param)
return ret;
}
int mpp_safe_reset(struct reset_control *rst)
{
if (rst)
reset_control_assert(rst);
return 0;
}
int mpp_safe_unreset(struct reset_control *rst)
{
if (rst)
reset_control_deassert(rst);
return 0;
}
#define MPP_GRF_VAL_MASK 0xFFFF
u32 mpp_get_grf(struct mpp_grf_info *grf_info)
@@ -1788,6 +1774,118 @@ int mpp_read_req(struct mpp_dev *mpp, u32 *regs,
return 0;
}
int mpp_get_clk_info(struct mpp_dev *mpp,
struct mpp_clk_info *clk_info,
const char *name)
{
int index = of_property_match_string(mpp->dev->of_node,
"clock-names", name);
if (index < 0)
return -EINVAL;
clk_info->clk = devm_clk_get(mpp->dev, name);
of_property_read_u32_index(mpp->dev->of_node,
"rockchip,normal-rates",
index,
&clk_info->normal_rate_hz);
of_property_read_u32_index(mpp->dev->of_node,
"rockchip,advanced-rates",
index,
&clk_info->advanced_rate_hz);
return 0;
}
int mpp_set_clk_info_rate_hz(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode,
unsigned long val)
{
if (!clk_info->clk || !val)
return 0;
switch (mode) {
case CLK_MODE_DEBUG:
clk_info->debug_rate_hz = val;
break;
case CLK_MODE_REDUCE:
clk_info->reduce_rate_hz = val;
break;
case CLK_MODE_NORMAL:
clk_info->normal_rate_hz = val;
break;
case CLK_MODE_ADVANCED:
clk_info->advanced_rate_hz = val;
break;
case CLK_MODE_DEFAULT:
clk_info->default_rate_hz = val;
break;
default:
mpp_err("error mode %d\n", mode);
break;
}
return 0;
}
#define MPP_REDUCE_RATE_HZ (50 * MHZ)
unsigned long mpp_get_clk_info_rate_hz(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode)
{
unsigned long clk_rate_hz = 0;
if (!clk_info->clk)
return 0;
if (clk_info->debug_rate_hz)
return clk_info->debug_rate_hz;
switch (mode) {
case CLK_MODE_REDUCE: {
if (clk_info->reduce_rate_hz)
clk_rate_hz = clk_info->reduce_rate_hz;
else
clk_rate_hz = MPP_REDUCE_RATE_HZ;
} break;
case CLK_MODE_NORMAL: {
if (clk_info->normal_rate_hz)
clk_rate_hz = clk_info->normal_rate_hz;
else
clk_rate_hz = clk_info->default_rate_hz;
} break;
case CLK_MODE_ADVANCED: {
if (clk_info->advanced_rate_hz)
clk_rate_hz = clk_info->advanced_rate_hz;
else
clk_rate_hz = clk_info->default_rate_hz;
} break;
case CLK_MODE_DEFAULT:
default: {
clk_rate_hz = clk_info->default_rate_hz;
} break;
}
return clk_rate_hz;
}
int mpp_clk_set_rate(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode)
{
unsigned long clk_rate_hz;
if (!clk_info->clk)
return -EINVAL;
clk_rate_hz = mpp_get_clk_info_rate_hz(clk_info, mode);
if (clk_rate_hz) {
clk_info->used_rate_hz = clk_rate_hz;
clk_set_rate(clk_info->clk, clk_rate_hz);
}
return 0;
}
int px30_workaround_combo_init(struct mpp_dev *mpp)
{
struct mpp_rk_iommu *iommu = NULL, *loop = NULL, *n;

View File

@@ -101,6 +101,16 @@ enum MPP_DEV_COMMAND_TYPE {
MPP_CMD_BUTT,
};
enum MPP_CLOCK_MODE {
CLK_MODE_BASE = 0,
CLK_MODE_DEFAULT = CLK_MODE_BASE,
CLK_MODE_DEBUG,
CLK_MODE_REDUCE,
CLK_MODE_NORMAL,
CLK_MODE_ADVANCED,
CLK_MODE_BUTT,
};
/* data common struct for parse out */
struct mpp_request {
__u32 cmd;
@@ -157,6 +167,22 @@ struct reg_offset_info {
struct reg_offset_elem elem[MPP_MAX_REG_TRANS_NUM];
};
struct mpp_clk_info {
struct clk *clk;
/* debug rate, from debugfs */
u32 debug_rate_hz;
/* normal rate, from dtsi */
u32 normal_rate_hz;
/* high performance rate, from dtsi */
u32 advanced_rate_hz;
u32 default_rate_hz;
u32 reduce_rate_hz;
/* record last used rate */
u32 used_rate_hz;
};
struct mpp_dev_var {
enum MPP_DEVICE_TYPE device_type;
@@ -429,9 +455,6 @@ irqreturn_t mpp_dev_isr_sched(int irq, void *param);
struct reset_control *
mpp_reset_control_get(struct mpp_dev *mpp, const char *name);
int mpp_safe_reset(struct reset_control *rst);
int mpp_safe_unreset(struct reset_control *rst);
u32 mpp_get_grf(struct mpp_grf_info *grf_info);
int mpp_set_grf(struct mpp_grf_info *grf_info);
@@ -443,6 +466,17 @@ int mpp_write_req(struct mpp_dev *mpp, u32 *regs,
int mpp_read_req(struct mpp_dev *mpp, u32 *regs,
u32 start_idx, u32 end_idx);
int mpp_get_clk_info(struct mpp_dev *mpp,
struct mpp_clk_info *clk_info,
const char *name);
int mpp_set_clk_info_rate_hz(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode,
unsigned long val);
unsigned long mpp_get_clk_info_rate_hz(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode);
int mpp_clk_set_rate(struct mpp_clk_info *clk_info,
enum MPP_CLOCK_MODE mode);
static inline int mpp_write(struct mpp_dev *mpp, u32 reg, u32 val)
{
int idx = reg / sizeof(u32);
@@ -489,6 +523,38 @@ static inline u32 mpp_read_relaxed(struct mpp_dev *mpp, u32 reg)
return val;
}
static inline int mpp_safe_reset(struct reset_control *rst)
{
if (rst)
reset_control_assert(rst);
return 0;
}
static inline int mpp_safe_unreset(struct reset_control *rst)
{
if (rst)
reset_control_deassert(rst);
return 0;
}
static inline int mpp_clk_safe_enable(struct clk *clk)
{
if (clk)
clk_prepare_enable(clk);
return 0;
}
static inline int mpp_clk_safe_disable(struct clk *clk)
{
if (clk)
clk_disable_unprepare(clk);
return 0;
}
/* workaround according hardware */
int px30_workaround_combo_init(struct mpp_dev *mpp);
int px30_workaround_combo_switch_grf(struct mpp_dev *mpp);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*
* author:
* Ding Wei, leo.ding@rock-chips.com
@@ -196,7 +196,8 @@ struct iep2_output {
struct iep_task {
struct mpp_task mpp_task;
struct mpp_hw_info *hw_info;
unsigned long aclk_freq;
enum MPP_CLOCK_MODE clk_mode;
struct iep2_params params;
struct iep2_output output;
@@ -212,13 +213,12 @@ struct iep_task {
struct iep2_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct clk *sclk;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
struct mpp_clk_info sclk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -347,6 +347,7 @@ static void *iep2_alloc_task(struct mpp_session *session,
if (ret)
goto fail;
}
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -772,7 +773,6 @@ static int iep2_debugfs_init(struct mpp_dev *mpp)
{
struct iep2_dev *iep = to_iep2_dev(mpp);
iep->aclk_debug = 0;
iep->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(iep->debugfs)) {
@@ -781,7 +781,7 @@ static int iep2_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
iep->debugfs, &iep->aclk_debug);
iep->debugfs, &iep->aclk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
iep->debugfs, &mpp->session_max_buffers);
@@ -804,25 +804,24 @@ static inline int iep2_debugfs_init(struct mpp_dev *mpp)
static int iep2_init(struct mpp_dev *mpp)
{
int ret;
struct iep2_dev *iep = to_iep2_dev(mpp);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_IEP2];
iep->aclk = devm_clk_get(mpp->dev, "aclk");
if (IS_ERR(iep->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &iep->aclk_info, "aclk");
if (ret)
mpp_err("failed on clk_get aclk\n");
iep->aclk = NULL;
}
iep->hclk = devm_clk_get(mpp->dev, "hclk");
if (IS_ERR(iep->hclk)) {
ret = mpp_get_clk_info(mpp, &iep->hclk_info, "hclk");
if (ret)
mpp_err("failed on clk_get hclk\n");
iep->hclk = NULL;
}
iep->sclk = devm_clk_get(mpp->dev, "sclk");
if (IS_ERR(iep->sclk)) {
ret = mpp_get_clk_info(mpp, &iep->sclk_info, "sclk");
if (ret)
mpp_err("failed on clk_get sclk\n");
iep->sclk = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&iep->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
iep->rst_a = devm_reset_control_get(mpp->dev, "rst_a");
if (IS_ERR_OR_NULL(iep->rst_a)) {
mpp_err("No aclk reset resource define\n");
@@ -855,12 +854,9 @@ static int iep2_clk_on(struct mpp_dev *mpp)
{
struct iep2_dev *iep = to_iep2_dev(mpp);
if (iep->aclk)
clk_prepare_enable(iep->aclk);
if (iep->hclk)
clk_prepare_enable(iep->hclk);
if (iep->sclk)
clk_prepare_enable(iep->sclk);
mpp_clk_safe_enable(iep->aclk_info.clk);
mpp_clk_safe_enable(iep->hclk_info.clk);
mpp_clk_safe_enable(iep->sclk_info.clk);
return 0;
}
@@ -869,22 +865,9 @@ static int iep2_clk_off(struct mpp_dev *mpp)
{
struct iep2_dev *iep = to_iep2_dev(mpp);
if (iep->aclk)
clk_disable_unprepare(iep->aclk);
if (iep->hclk)
clk_disable_unprepare(iep->hclk);
if (iep->sclk)
clk_disable_unprepare(iep->sclk);
return 0;
}
static int iep2_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct iep_task *task = to_iep_task(mpp_task);
task->aclk_freq = 300;
mpp_clk_safe_disable(iep->aclk_info.clk);
mpp_clk_safe_disable(iep->hclk_info.clk);
mpp_clk_safe_disable(iep->sclk_info.clk);
return 0;
}
@@ -895,11 +878,7 @@ static int iep2_set_freq(struct mpp_dev *mpp,
struct iep2_dev *iep = to_iep2_dev(mpp);
struct iep_task *task = to_iep_task(mpp_task);
/* check whether use debug freq */
task->aclk_freq = iep->aclk_debug ?
iep->aclk_debug : task->aclk_freq;
clk_set_rate(iep->aclk, task->aclk_freq * MHZ);
mpp_clk_set_rate(&iep->aclk_info, task->clk_mode);
return 0;
}
@@ -908,8 +887,7 @@ static int iep2_reduce_freq(struct mpp_dev *mpp)
{
struct iep2_dev *iep = to_iep2_dev(mpp);
if (iep->aclk)
clk_set_rate(iep->aclk, 50 * MHZ);
mpp_clk_set_rate(&iep->aclk_info, CLK_MODE_REDUCE);
return 0;
}
@@ -938,7 +916,6 @@ static struct mpp_hw_ops iep_v2_hw_ops = {
.init = iep2_init,
.clk_on = iep2_clk_on,
.clk_off = iep2_clk_off,
.get_freq = iep2_get_freq,
.set_freq = iep2_set_freq,
.reduce_freq = iep2_reduce_freq,
.reset = iep2_reset,

View File

@@ -137,11 +137,7 @@ enum RKVDEC_HW_ID {
struct rkvdec_task {
struct mpp_task mpp_task;
unsigned long aclk_freq;
unsigned long clk_core_freq;
unsigned long clk_cabac_freq;
unsigned long clk_hevc_cabac_freq;
enum MPP_CLOCK_MODE clk_mode;
u32 reg[RKVDEC_V2_REG_NUM];
struct reg_offset_info off_inf;
@@ -159,18 +155,14 @@ struct rkvdec_dev {
/* sip smc reset lock */
struct mutex sip_reset_lock;
struct clk *aclk;
struct clk *hclk;
struct clk *clk_core;
struct clk *clk_cabac;
struct clk *clk_hevc_cabac;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
struct mpp_clk_info core_clk_info;
struct mpp_clk_info cabac_clk_info;
struct mpp_clk_info hevc_cabac_clk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
u32 clk_core_debug;
u32 clk_cabac_debug;
u32 clk_hevc_cabac_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -183,7 +175,7 @@ struct rkvdec_dev {
enum RKVDEC_STATE state;
unsigned long aux_iova;
struct page *aux_page;
/* regulator and devfreq */
#ifdef CONFIG_PM_DEVFREQ
struct regulator *vdd;
struct devfreq *devfreq;
struct devfreq *parent_devfreq;
@@ -192,12 +184,14 @@ struct rkvdec_dev {
struct thermal_zone_device *thermal_zone;
u32 static_power_coeff;
s32 ts[4];
struct mutex set_clk_lock; /* set clk lock */
/* set clk lock */
struct mutex set_clk_lock;
unsigned int thermal_div;
unsigned long volt;
unsigned long aclk_devf;
unsigned long clk_core_devf;
unsigned long clk_cabac_devf;
unsigned long devf_aclk_rate_hz;
unsigned long devf_core_rate_hz;
unsigned long devf_cabac_rate_hz;
#endif
/* record last infos */
u32 last_fmt;
bool had_reset;
@@ -261,55 +255,60 @@ static struct mpp_trans_info rkvdec_v1_trans[] = {
},
};
static int rkvdec_set_clk(struct rkvdec_dev *dec,
unsigned long aclk_freq,
unsigned long core_freq,
unsigned long cabac_freq,
unsigned int event)
#ifdef CONFIG_PM_DEVFREQ
static int rkvdec_devf_set_clk(struct rkvdec_dev *dec,
unsigned long aclk_rate_hz,
unsigned long core_rate_hz,
unsigned long cabac_rate_hz,
unsigned int event)
{
struct clk *aclk = dec->aclk_info.clk;
struct clk *clk_core = dec->core_clk_info.clk;
struct clk *clk_cabac = dec->cabac_clk_info.clk;
mutex_lock(&dec->set_clk_lock);
switch (event) {
case EVENT_POWER_ON:
clk_set_rate(dec->aclk, dec->aclk_devf);
clk_set_rate(dec->clk_core, dec->clk_core_devf);
clk_set_rate(dec->clk_cabac, dec->clk_cabac_devf);
clk_set_rate(aclk, dec->devf_aclk_rate_hz);
clk_set_rate(clk_core, dec->devf_core_rate_hz);
clk_set_rate(clk_cabac, dec->devf_cabac_rate_hz);
dec->thermal_div = 0;
break;
case EVENT_POWER_OFF:
clk_set_rate(dec->aclk, aclk_freq);
clk_set_rate(dec->clk_core, core_freq);
clk_set_rate(dec->clk_cabac, cabac_freq);
clk_set_rate(aclk, aclk_rate_hz);
clk_set_rate(clk_core, core_rate_hz);
clk_set_rate(clk_cabac, cabac_rate_hz);
dec->thermal_div = 0;
break;
case EVENT_ADJUST:
if (!dec->thermal_div) {
clk_set_rate(dec->aclk, aclk_freq);
clk_set_rate(dec->clk_core, core_freq);
clk_set_rate(dec->clk_cabac, cabac_freq);
clk_set_rate(aclk, aclk_rate_hz);
clk_set_rate(clk_core, core_rate_hz);
clk_set_rate(clk_cabac, cabac_rate_hz);
} else {
clk_set_rate(dec->aclk,
aclk_freq / dec->thermal_div);
clk_set_rate(dec->clk_core,
core_freq / dec->thermal_div);
clk_set_rate(dec->clk_cabac,
cabac_freq / dec->thermal_div);
clk_set_rate(aclk,
aclk_rate_hz / dec->thermal_div);
clk_set_rate(clk_core,
core_rate_hz / dec->thermal_div);
clk_set_rate(clk_cabac,
cabac_rate_hz / dec->thermal_div);
}
dec->aclk_devf = aclk_freq;
dec->clk_core_devf = core_freq;
dec->clk_cabac_devf = cabac_freq;
dec->devf_aclk_rate_hz = aclk_rate_hz;
dec->devf_core_rate_hz = core_rate_hz;
dec->devf_cabac_rate_hz = cabac_rate_hz;
break;
case EVENT_THERMAL:
dec->thermal_div = dec->aclk_devf / aclk_freq;
dec->thermal_div = dec->devf_aclk_rate_hz / aclk_rate_hz;
if (dec->thermal_div > 4)
dec->thermal_div = 4;
if (dec->thermal_div) {
clk_set_rate(dec->aclk,
dec->aclk_devf / dec->thermal_div);
clk_set_rate(dec->clk_core,
dec->clk_core_devf / dec->thermal_div);
clk_set_rate(dec->clk_cabac,
dec->clk_cabac_devf / dec->thermal_div);
clk_set_rate(aclk,
dec->devf_aclk_rate_hz / dec->thermal_div);
clk_set_rate(clk_core,
dec->devf_core_rate_hz / dec->thermal_div);
clk_set_rate(clk_cabac,
dec->devf_cabac_rate_hz / dec->thermal_div);
}
break;
}
@@ -326,7 +325,7 @@ static int devfreq_target(struct device *dev,
unsigned int clk_event;
struct dev_pm_opp *opp;
unsigned long target_volt, target_freq;
unsigned long aclk_freq, core_freq, cabac_freq;
unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz;
struct rkvdec_dev *dec = dev_get_drvdata(dev);
struct devfreq *devfreq = dec->devfreq;
@@ -344,14 +343,14 @@ static int devfreq_target(struct device *dev,
if (target_freq < *freq) {
clk_event = EVENT_THERMAL;
aclk_freq = target_freq;
core_freq = target_freq;
cabac_freq = target_freq;
aclk_rate_hz = target_freq;
core_rate_hz = target_freq;
cabac_rate_hz = target_freq;
} else {
clk_event = stat->busy_time ? EVENT_POWER_ON : EVENT_POWER_OFF;
aclk_freq = dec->aclk_devf;
core_freq = dec->clk_core_devf;
cabac_freq = dec->clk_cabac_devf;
aclk_rate_hz = dec->devf_aclk_rate_hz;
core_rate_hz = dec->devf_core_rate_hz;
cabac_rate_hz = dec->devf_cabac_rate_hz;
}
if (old_clk_rate == target_freq) {
@@ -376,7 +375,7 @@ static int devfreq_target(struct device *dev,
}
dev_dbg(dev, "%lu-->%lu\n", old_clk_rate, target_freq);
rkvdec_set_clk(dec, aclk_freq, core_freq, cabac_freq, clk_event);
rkvdec_devf_set_clk(dec, aclk_rate_hz, core_rate_hz, cabac_rate_hz, clk_event);
stat->current_frequency = target_freq;
if (old_clk_rate > target_freq) {
@@ -396,7 +395,7 @@ static int devfreq_get_cur_freq(struct device *dev,
{
struct rkvdec_dev *dec = dev_get_drvdata(dev);
*freq = clk_get_rate(dec->aclk);
*freq = clk_get_rate(dec->aclk_info.clk);
return 0;
}
@@ -534,6 +533,7 @@ static int devfreq_notifier_call(struct notifier_block *nb,
return NOTIFY_OK;
}
#endif
/*
* NOTE: rkvdec/rkhevc put scaling list address in pps buffer hardware will read
@@ -841,6 +841,7 @@ static void *rkvdec_alloc_task(struct mpp_session *session,
goto fail;
}
task->strm_addr = task->reg[RKVDEC_REG_RLC_BASE_INDEX];
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -1119,11 +1120,6 @@ static int rkvdec_debugfs_init(struct mpp_dev *mpp)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
dec->aclk_debug = 0;
dec->clk_core_debug = 0;
dec->clk_cabac_debug = 0;
dec->clk_hevc_cabac_debug = 0;
dec->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(dec->debugfs)) {
@@ -1132,13 +1128,13 @@ static int rkvdec_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
dec->debugfs, &dec->aclk_debug);
dec->debugfs, &dec->aclk_info.debug_rate_hz);
debugfs_create_u32("clk_core", 0644,
dec->debugfs, &dec->clk_core_debug);
dec->debugfs, &dec->core_clk_info.debug_rate_hz);
debugfs_create_u32("clk_cabac", 0644,
dec->debugfs, &dec->clk_cabac_debug);
dec->debugfs, &dec->cabac_clk_info.debug_rate_hz);
debugfs_create_u32("clk_hevc_cabac", 0644,
dec->debugfs, &dec->clk_hevc_cabac_debug);
dec->debugfs, &dec->hevc_cabac_clk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
dec->debugfs, &mpp->session_max_buffers);
@@ -1158,38 +1154,33 @@ static inline int rkvdec_debugfs_init(struct mpp_dev *mpp)
static int rkvdec_init(struct mpp_dev *mpp)
{
int ret;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
mutex_init(&dec->sip_reset_lock);
mutex_init(&dec->set_clk_lock);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVDEC];
dec->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR_OR_NULL(dec->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &dec->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
dec->aclk = NULL;
}
dec->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR_OR_NULL(dec->hclk)) {
ret = mpp_get_clk_info(mpp, &dec->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
dec->hclk = NULL;
}
dec->clk_cabac = devm_clk_get(mpp->dev, "clk_cabac");
if (IS_ERR_OR_NULL(dec->clk_cabac)) {
mpp_err("failed on clk_get clk_cabac\n");
dec->clk_cabac = NULL;
}
dec->clk_core = devm_clk_get(mpp->dev, "clk_core");
if (IS_ERR_OR_NULL(dec->clk_core)) {
ret = mpp_get_clk_info(mpp, &dec->core_clk_info, "clk_core");
if (ret)
mpp_err("failed on clk_get clk_core\n");
dec->clk_core = NULL;
}
dec->clk_hevc_cabac = devm_clk_get(mpp->dev, "clk_hevc_cabac");
if (IS_ERR_OR_NULL(dec->clk_hevc_cabac)) {
ret = mpp_get_clk_info(mpp, &dec->cabac_clk_info, "clk_cabac");
if (ret)
mpp_err("failed on clk_get clk_cabac\n");
ret = mpp_get_clk_info(mpp, &dec->hevc_cabac_clk_info, "clk_hevc_cabac");
if (ret)
mpp_err("failed on clk_get clk_hevc_cabac\n");
dec->clk_hevc_cabac = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
mpp_set_clk_info_rate_hz(&dec->core_clk_info, CLK_MODE_DEFAULT, 200 * MHZ);
mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ);
mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
@@ -1270,6 +1261,7 @@ static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu,
return ret;
}
#ifdef CONFIG_PM_DEVFREQ
static int rkvdec_devfreq_remove(struct mpp_dev *mpp)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
@@ -1286,6 +1278,7 @@ static int rkvdec_devfreq_init(struct mpp_dev *mpp)
struct devfreq_dev_status *stat;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
mutex_init(&dec->set_clk_lock);
dec->parent_devfreq = devfreq_get_devfreq_by_phandle(mpp->dev, 0);
if (IS_ERR_OR_NULL(dec->parent_devfreq)) {
if (PTR_ERR(dec->parent_devfreq) == -EPROBE_DEFER) {
@@ -1327,7 +1320,7 @@ static int rkvdec_devfreq_init(struct mpp_dev *mpp)
}
stat = &dec->devfreq->last_status;
stat->current_frequency = clk_get_rate(dec->aclk);
stat->current_frequency = clk_get_rate(dec->aclk_info.clk);
ret = devfreq_register_opp_notifier(mpp->dev, dec->devfreq);
if (ret)
@@ -1350,6 +1343,17 @@ static int rkvdec_devfreq_init(struct mpp_dev *mpp)
done:
return ret;
}
#else
static inline int rkvdec_devfreq_remove(struct mpp_dev *mpp)
{
return 0;
}
static inline int rkvdec_devfreq_init(struct mpp_dev *mpp)
{
return 0;
}
#endif
static int rkvdec_3328_init(struct mpp_dev *mpp)
{
@@ -1393,14 +1397,11 @@ static int rkvdec_clk_on(struct mpp_dev *mpp)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
if (dec->aclk)
clk_prepare_enable(dec->aclk);
if (dec->hclk)
clk_prepare_enable(dec->hclk);
if (dec->clk_cabac)
clk_prepare_enable(dec->clk_cabac);
if (dec->clk_core)
clk_prepare_enable(dec->clk_core);
mpp_clk_safe_enable(dec->aclk_info.clk);
mpp_clk_safe_enable(dec->hclk_info.clk);
mpp_clk_safe_enable(dec->core_clk_info.clk);
mpp_clk_safe_enable(dec->cabac_clk_info.clk);
mpp_clk_safe_enable(dec->hevc_cabac_clk_info.clk);
return 0;
}
@@ -1409,27 +1410,11 @@ static int rkvdec_clk_off(struct mpp_dev *mpp)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
if (dec->aclk)
clk_disable_unprepare(dec->aclk);
if (dec->hclk)
clk_disable_unprepare(dec->hclk);
if (dec->clk_cabac)
clk_disable_unprepare(dec->clk_cabac);
if (dec->clk_core)
clk_disable_unprepare(dec->clk_core);
return 0;
}
static int rkvdec_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
task->aclk_freq = 300;
task->clk_cabac_freq = 200;
task->clk_core_freq = 200;
task->clk_hevc_cabac_freq = 600;
clk_disable_unprepare(dec->aclk_info.clk);
clk_disable_unprepare(dec->hclk_info.clk);
clk_disable_unprepare(dec->core_clk_info.clk);
clk_disable_unprepare(dec->cabac_clk_info.clk);
clk_disable_unprepare(dec->hevc_cabac_clk_info.clk);
return 0;
}
@@ -1437,71 +1422,27 @@ static int rkvdec_get_freq(struct mpp_dev *mpp,
static int rkvdec_3328_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 fmt;
u32 ddr_align_en;
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
u32 ddr_align_en = task->reg[RKVDEC_REG_INT_EN_INDEX] &
RKVDEC_WR_DDR_ALIGN_EN;
u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_SYS_CTRL_INDEX]);
if (ddr_align_en) {
if (fmt == RKVDEC_FMT_H264D) {
task->aclk_freq = 400;
task->clk_cabac_freq = 400;
task->clk_core_freq = 250;
} else {
task->aclk_freq = 500;
task->clk_cabac_freq = 400;
task->clk_core_freq = 250;
}
} else {
if (fmt == RKVDEC_FMT_H264D) {
task->aclk_freq = 400;
task->clk_cabac_freq = 400;
task->clk_core_freq = 300;
} else {
task->aclk_freq = 500;
task->clk_cabac_freq = 300;
task->clk_core_freq = 400;
}
}
fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_SYS_CTRL_INDEX]);
ddr_align_en = task->reg[RKVDEC_REG_INT_EN_INDEX] & RKVDEC_WR_DDR_ALIGN_EN;
if (fmt == RKVDEC_FMT_H264D || ddr_align_en)
task->clk_mode = CLK_MODE_ADVANCED;
return 0;
}
static int rkvdec_probe_width(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 width = 0;
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
u32 prod_num = REVDEC_GET_PROD_NUM(mpp->var->hw_info->hw_id);
switch (prod_num) {
case HEVC_DEC_ID_6867:
case RKVDEC_ID_6876:
case RKVDEC_ID_3410:
width = RKVDEC_GET_WIDTH(task->reg[RKVDEC_RGE_WIDTH_INDEX]);
break;
default:
break;
}
return width;
}
static int rkvdec_3368_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 width;
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
u32 width = rkvdec_probe_width(mpp, mpp_task);
if (width > 2560) {
task->aclk_freq = 600;
task->clk_cabac_freq = 400;
task->clk_core_freq = 400;
} else {
task->aclk_freq = 300;
task->clk_cabac_freq = 200;
task->clk_core_freq = 200;
}
width = RKVDEC_GET_WIDTH(task->reg[RKVDEC_RGE_WIDTH_INDEX]);
if (width > 2560)
task->clk_mode = CLK_MODE_ADVANCED;
return 0;
}
@@ -1509,58 +1450,89 @@ static int rkvdec_3368_get_freq(struct mpp_dev *mpp,
static int rkvdec_set_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct devfreq_dev_status *stat;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
task->aclk_freq = dec->aclk_debug ?
dec->aclk_debug : task->aclk_freq;
task->clk_cabac_freq = dec->clk_cabac_debug ?
dec->clk_cabac_debug : task->clk_cabac_freq;
task->clk_core_freq = dec->clk_core_debug ?
dec->clk_core_debug : task->clk_core_freq;
task->clk_hevc_cabac_freq = dec->clk_hevc_cabac_debug ?
dec->clk_hevc_cabac_debug : task->clk_hevc_cabac_freq;
mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
mpp_clk_set_rate(&dec->core_clk_info, task->clk_mode);
mpp_clk_set_rate(&dec->cabac_clk_info, task->clk_mode);
mpp_clk_set_rate(&dec->hevc_cabac_clk_info, task->clk_mode);
return 0;
}
static int rkvdec_3328_set_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
#ifdef CONFIG_PM_DEVFREQ
if (dec->devfreq) {
struct devfreq_dev_status *stat;
unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz;
stat = &dec->devfreq->last_status;
stat->busy_time = 1;
stat->total_time = 1;
rkvdec_set_clk(dec, task->aclk_freq * MHZ,
task->clk_core_freq * MHZ,
task->clk_cabac_freq * MHZ,
EVENT_ADJUST);
} else {
clk_set_rate(dec->aclk, task->aclk_freq * MHZ);
clk_set_rate(dec->clk_cabac, task->clk_cabac_freq * MHZ);
clk_set_rate(dec->clk_core, task->clk_core_freq * MHZ);
clk_set_rate(dec->clk_hevc_cabac,
task->clk_hevc_cabac_freq * MHZ);
aclk_rate_hz = mpp_get_clk_info_rate_hz(&dec->aclk_info,
task->clk_mode);
core_rate_hz = mpp_get_clk_info_rate_hz(&dec->core_clk_info,
task->clk_mode);
cabac_rate_hz = mpp_get_clk_info_rate_hz(&dec->cabac_clk_info,
task->clk_mode);
rkvdec_devf_set_clk(dec, aclk_rate_hz,
core_rate_hz, cabac_rate_hz,
EVENT_ADJUST);
}
#else
mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
mpp_clk_set_rate(&dec->core_clk_info, task->clk_mode);
mpp_clk_set_rate(&dec->cabac_clk_info, task->clk_mode);
#endif
return 0;
}
static int rkvdec_reduce_freq(struct mpp_dev *mpp)
{
struct devfreq_dev_status *stat;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
mpp_clk_set_rate(&dec->aclk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&dec->core_clk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&dec->cabac_clk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&dec->hevc_cabac_clk_info, CLK_MODE_REDUCE);
return 0;
}
static int rkvdec_3328_reduce_freq(struct mpp_dev *mpp)
{
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
#ifdef CONFIG_PM_DEVFREQ
if (dec->devfreq) {
struct devfreq_dev_status *stat;
unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz;
stat = &dec->devfreq->last_status;
stat->busy_time = 0;
stat->total_time = 1;
rkvdec_set_clk(dec, 50 * MHZ, 50 * MHZ, 50 * MHZ, EVENT_ADJUST);
} else {
if (dec->aclk)
clk_set_rate(dec->aclk, 50 * MHZ);
if (dec->clk_cabac)
clk_set_rate(dec->clk_cabac, 50 * MHZ);
if (dec->clk_core)
clk_set_rate(dec->clk_core, 50 * MHZ);
if (dec->clk_hevc_cabac)
clk_set_rate(dec->clk_hevc_cabac, 50 * MHZ);
aclk_rate_hz = mpp_get_clk_info_rate_hz(&dec->aclk_info,
CLK_MODE_REDUCE);
core_rate_hz = mpp_get_clk_info_rate_hz(&dec->core_clk_info,
CLK_MODE_REDUCE);
cabac_rate_hz = mpp_get_clk_info_rate_hz(&dec->cabac_clk_info,
CLK_MODE_REDUCE);
rkvdec_devf_set_clk(dec, aclk_rate_hz,
core_rate_hz, cabac_rate_hz,
EVENT_ADJUST);
}
#else
mpp_clk_set_rate(&dec->aclk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&dec->core_clk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&dec->cabac_clk_info, CLK_MODE_REDUCE);
#endif
return 0;
}
@@ -1614,7 +1586,6 @@ static struct mpp_hw_ops rkvdec_v1_hw_ops = {
.init = rkvdec_init,
.clk_on = rkvdec_clk_on,
.clk_off = rkvdec_clk_off,
.get_freq = rkvdec_get_freq,
.set_freq = rkvdec_set_freq,
.reduce_freq = rkvdec_reduce_freq,
.reset = rkvdec_reset,
@@ -1624,7 +1595,6 @@ static struct mpp_hw_ops rkvdec_px30_hw_ops = {
.init = rkvdec_px30_init,
.clk_on = rkvdec_clk_on,
.clk_off = rkvdec_clk_off,
.get_freq = rkvdec_get_freq,
.set_freq = rkvdec_set_freq,
.reduce_freq = rkvdec_reduce_freq,
.reset = rkvdec_reset,
@@ -1635,7 +1605,6 @@ static struct mpp_hw_ops rkvdec_3399_hw_ops = {
.init = rkvdec_init,
.clk_on = rkvdec_clk_on,
.clk_off = rkvdec_clk_off,
.get_freq = rkvdec_get_freq,
.set_freq = rkvdec_set_freq,
.reduce_freq = rkvdec_reduce_freq,
.reset = rkvdec_reset,
@@ -1667,8 +1636,8 @@ static struct mpp_hw_ops rkvdec_3328_hw_ops = {
.clk_on = rkvdec_clk_on,
.clk_off = rkvdec_clk_off,
.get_freq = rkvdec_3328_get_freq,
.set_freq = rkvdec_set_freq,
.reduce_freq = rkvdec_reduce_freq,
.set_freq = rkvdec_3328_set_freq,
.reduce_freq = rkvdec_3328_reduce_freq,
.reset = rkvdec_sip_reset,
};

View File

@@ -143,8 +143,7 @@ struct rkvenc_task {
/* register offset info */
struct reg_offset_info off_inf;
unsigned long aclk_freq_mhz;
unsigned long clk_core_freq_mhz;
enum MPP_CLOCK_MODE clk_mode;
u32 irq_status;
/* req for current task */
u32 w_req_cnt;
@@ -156,14 +155,12 @@ struct rkvenc_task {
struct rkvenc_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct clk *clk_core;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
struct mpp_clk_info core_clk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug_mhz;
u32 clk_core_debug_mhz;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -173,8 +170,8 @@ struct rkvenc_dev {
struct regulator *vdd;
struct devfreq *devfreq;
unsigned long volt;
unsigned long core_freq_mhz;
unsigned long core_last_freq_hz;
unsigned long core_rate_hz;
unsigned long core_last_rate_hz;
struct ipa_power_model_data *model_data;
struct thermal_cooling_device *devfreq_cooling;
#endif
@@ -340,6 +337,7 @@ static void *rkvenc_alloc_task(struct mpp_session *session,
&task->off_inf, task->reg);
}
task->link_mode = RKVENC_MODE_ONEFRAME;
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -602,8 +600,6 @@ static int rkvenc_debugfs_init(struct mpp_dev *mpp)
{
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
enc->aclk_debug_mhz = 0;
enc->clk_core_debug_mhz = 0;
enc->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(enc->debugfs)) {
@@ -612,9 +608,9 @@ static int rkvenc_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
enc->debugfs, &enc->aclk_debug_mhz);
enc->debugfs, &enc->aclk_info.debug_rate_hz);
debugfs_create_u32("clk_core", 0644,
enc->debugfs, &enc->clk_core_debug_mhz);
enc->debugfs, &enc->core_clk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
enc->debugfs, &mpp->session_max_buffers);
@@ -655,7 +651,7 @@ static int rkvenc_devfreq_target(struct device *dev,
dev_pm_opp_put(opp);
if (old_clk_rate == target_freq) {
enc->core_last_freq_hz = target_freq;
enc->core_last_rate_hz = target_freq;
if (enc->volt == target_volt)
return ret;
ret = regulator_set_voltage(enc->vdd, target_volt, INT_MAX);
@@ -677,9 +673,9 @@ static int rkvenc_devfreq_target(struct device *dev,
}
dev_dbg(dev, "%lu-->%lu\n", old_clk_rate, target_freq);
clk_set_rate(enc->clk_core, target_freq);
clk_set_rate(enc->core_clk_info.clk, target_freq);
stat->current_frequency = target_freq;
enc->core_last_freq_hz = target_freq;
enc->core_last_rate_hz = target_freq;
if (old_clk_rate > target_freq) {
ret = regulator_set_voltage(enc->vdd, target_volt, INT_MAX);
@@ -704,7 +700,7 @@ static int rkvenc_devfreq_get_cur_freq(struct device *dev,
{
struct rkvenc_dev *enc = dev_get_drvdata(dev);
*freq = enc->core_last_freq_hz;
*freq = enc->core_last_rate_hz;
return 0;
}
@@ -720,7 +716,7 @@ static int devfreq_venc_ondemand_func(struct devfreq *df, unsigned long *freq)
struct rkvenc_dev *enc = df->data;
if (enc)
*freq = enc->core_freq_mhz * MHZ;
*freq = enc->core_rate_hz;
else
*freq = df->previous_freq;
@@ -758,10 +754,11 @@ static struct devfreq_cooling_power venc_cooling_power_data = {
static int rkvenc_devfreq_init(struct mpp_dev *mpp)
{
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
struct clk *clk_core = enc->core_clk_info.clk;
struct devfreq_cooling_power *venc_dcp = &venc_cooling_power_data;
int ret = 0;
if (!enc->clk_core)
if (!clk_core)
return 0;
enc->vdd = devm_regulator_get_optional(mpp->dev, "venc");
@@ -789,7 +786,7 @@ static int rkvenc_devfreq_init(struct mpp_dev *mpp)
goto governor_err;
}
rkvenc_devfreq_profile.initial_freq = clk_get_rate(enc->clk_core);
rkvenc_devfreq_profile.initial_freq = clk_get_rate(clk_core);
enc->devfreq = devm_devfreq_add_device(mpp->dev,
&rkvenc_devfreq_profile,
@@ -858,21 +855,19 @@ static int rkvenc_init(struct mpp_dev *mpp)
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_RKVENC];
enc->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR(enc->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
enc->aclk = NULL;
}
enc->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR(enc->hclk)) {
ret = mpp_get_clk_info(mpp, &enc->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
enc->hclk = NULL;
}
enc->clk_core = devm_clk_get(mpp->dev, "clk_core");
if (IS_ERR_OR_NULL(enc->clk_core)) {
dev_err(mpp->dev, "failed on clk_get core\n");
enc->clk_core = NULL;
}
ret = mpp_get_clk_info(mpp, &enc->core_clk_info, "clk_core");
if (ret)
mpp_err("failed on clk_get clk_core\n");
/* Set default rates */
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
mpp_set_clk_info_rate_hz(&enc->core_clk_info, CLK_MODE_DEFAULT, 600 * MHZ);
enc->rst_a = devm_reset_control_get_shared(mpp->dev, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
@@ -919,10 +914,8 @@ static int rkvenc_reset(struct mpp_dev *mpp)
if (enc->devfreq)
mutex_lock(&enc->devfreq->lock);
#endif
if (enc->aclk)
clk_set_rate(enc->aclk, 50 * MHZ);
if (enc->clk_core)
clk_set_rate(enc->clk_core, 50 * MHZ);
mpp_clk_set_rate(&enc->aclk_info, CLK_MODE_REDUCE);
mpp_clk_set_rate(&enc->core_clk_info, CLK_MODE_REDUCE);
mpp_write(mpp, RKVENC_INT_EN_BASE, RKVENC_SAFE_CLR_BIT);
mpp_write(mpp, RKVENC_CLR_BASE, RKVENC_SAFE_CLR_BIT);
@@ -951,12 +944,9 @@ static int rkvenc_clk_on(struct mpp_dev *mpp)
{
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
if (enc->aclk)
clk_prepare_enable(enc->aclk);
if (enc->hclk)
clk_prepare_enable(enc->hclk);
if (enc->clk_core)
clk_prepare_enable(enc->clk_core);
mpp_clk_safe_enable(enc->aclk_info.clk);
mpp_clk_safe_enable(enc->hclk_info.clk);
mpp_clk_safe_enable(enc->core_clk_info.clk);
return 0;
}
@@ -965,23 +955,9 @@ static int rkvenc_clk_off(struct mpp_dev *mpp)
{
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
if (enc->aclk)
clk_disable_unprepare(enc->aclk);
if (enc->hclk)
clk_disable_unprepare(enc->hclk);
if (enc->clk_core)
clk_disable_unprepare(enc->clk_core);
return 0;
}
static int rkvenc_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct rkvenc_task *task = to_rkvenc_task(mpp_task);
task->aclk_freq_mhz = 300;
task->clk_core_freq_mhz = 600;
clk_disable_unprepare(enc->aclk_info.clk);
clk_disable_unprepare(enc->hclk_info.clk);
clk_disable_unprepare(enc->core_clk_info.clk);
return 0;
}
@@ -992,35 +968,31 @@ static int rkvenc_set_freq(struct mpp_dev *mpp,
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
struct rkvenc_task *task = to_rkvenc_task(mpp_task);
task->aclk_freq_mhz = enc->aclk_debug_mhz ?
enc->aclk_debug_mhz : task->aclk_freq_mhz;
task->clk_core_freq_mhz = enc->clk_core_debug_mhz ?
enc->clk_core_debug_mhz : task->clk_core_freq_mhz;
if (enc->aclk)
clk_set_rate(enc->aclk, task->aclk_freq_mhz * MHZ);
mpp_clk_set_rate(&enc->aclk_info, task->clk_mode);
#ifdef CONFIG_PM_DEVFREQ
if (enc->devfreq) {
unsigned long core_rate_hz;
mutex_lock(&enc->devfreq->lock);
if (enc->core_freq_mhz != task->clk_core_freq_mhz) {
enc->core_freq_mhz = task->clk_core_freq_mhz;
core_rate_hz = mpp_get_clk_info_rate_hz(&enc->core_clk_info, task->clk_mode);
if (enc->core_rate_hz != core_rate_hz) {
enc->core_rate_hz = core_rate_hz;
update_devfreq(enc->devfreq);
} else {
/*
* Restore frequency when frequency is changed by
* rkvenc_reduce_freq()
*/
clk_set_rate(enc->clk_core, enc->core_last_freq_hz);
clk_set_rate(enc->core_clk_info.clk, enc->core_last_rate_hz);
}
mutex_unlock(&enc->devfreq->lock);
return 0;
}
#else
if (enc->clk_core)
clk_set_rate(enc->clk_core, task->clk_core_freq_mhz * MHZ);
mpp_clk_set_rate(&enc->core_clk_info, task->clk_mode);
#endif
return 0;
}
@@ -1029,7 +1001,6 @@ static struct mpp_hw_ops rkvenc_hw_ops = {
.exit = rkvenc_exit,
.clk_on = rkvenc_clk_on,
.clk_off = rkvenc_clk_off,
.get_freq = rkvenc_get_freq,
.set_freq = rkvenc_set_freq,
.reset = rkvenc_reset,
};

View File

@@ -100,7 +100,7 @@ struct vdpu_task {
/* enable of post process */
bool pp_enable;
unsigned long aclk_freq;
enum MPP_CLOCK_MODE clk_mode;
u32 reg[VDPU1_REG_PP_NUM];
struct reg_offset_info off_inf;
@@ -116,13 +116,11 @@ struct vdpu_task {
struct vdpu_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
};
@@ -377,6 +375,7 @@ static void *vdpu_alloc_task(struct mpp_session *session,
goto fail;
}
task->strm_addr = task->reg[VDPU1_REG_STREAM_RLC_BASE_INDEX];
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -503,7 +502,6 @@ static int vdpu_debugfs_init(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
dec->aclk_debug = 0;
dec->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(dec->debugfs)) {
@@ -512,7 +510,7 @@ static int vdpu_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
dec->debugfs, &dec->aclk_debug);
dec->debugfs, &dec->aclk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
dec->debugfs, &mpp->session_max_buffers);
@@ -532,20 +530,20 @@ static inline int vdpu_debugfs_init(struct mpp_dev *mpp)
static int vdpu_init(struct mpp_dev *mpp)
{
int ret;
struct vdpu_dev *dec = to_vdpu_dev(mpp);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VDPU1];
dec->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR_OR_NULL(dec->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &dec->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
dec->aclk = NULL;
}
dec->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR_OR_NULL(dec->hclk)) {
ret = mpp_get_clk_info(mpp, &dec->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
dec->hclk = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
@@ -565,10 +563,8 @@ static int vdpu_clk_on(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_prepare_enable(dec->aclk);
if (dec->hclk)
clk_prepare_enable(dec->hclk);
mpp_clk_safe_enable(dec->aclk_info.clk);
mpp_clk_safe_enable(dec->hclk_info.clk);
return 0;
}
@@ -577,51 +573,21 @@ static int vdpu_clk_off(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_disable_unprepare(dec->aclk);
if (dec->hclk)
clk_disable_unprepare(dec->hclk);
mpp_clk_safe_disable(dec->aclk_info.clk);
mpp_clk_safe_disable(dec->hclk_info.clk);
return 0;
}
static int vdpu_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct vdpu_task *task = to_vdpu_task(mpp_task);
task->aclk_freq = 300;
return 0;
}
static int vdpu_probe_width(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 width = 0;
struct vdpu_task *task = to_vdpu_task(mpp_task);
u32 prod_num = VDPU1_GET_PROD_NUM(mpp->var->hw_info->hw_id);
switch (prod_num) {
case VDPU1_ID_0102:
case VDPU1_ID_9190:
width = VDPU1_GET_WIDTH(task->reg[VDPU1_RGE_WIDTH_INDEX]);
break;
}
return width;
}
static int vdpu_3288_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 width;
struct vdpu_task *task = to_vdpu_task(mpp_task);
u32 width = vdpu_probe_width(mpp, mpp_task);
width = VDPU1_GET_WIDTH(task->reg[VDPU1_RGE_WIDTH_INDEX]);
if (width > 2560)
task->aclk_freq = 600;
else
task->aclk_freq = 300;
task->clk_mode = CLK_MODE_ADVANCED;
return 0;
}
@@ -629,13 +595,12 @@ static int vdpu_3288_get_freq(struct mpp_dev *mpp,
static int vdpu_3368_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 width;
struct vdpu_task *task = to_vdpu_task(mpp_task);
u32 width = vdpu_probe_width(mpp, mpp_task);
width = VDPU1_GET_WIDTH(task->reg[VDPU1_RGE_WIDTH_INDEX]);
if (width > 2560)
task->aclk_freq = 600;
else
task->aclk_freq = 300;
task->clk_mode = CLK_MODE_ADVANCED;
return 0;
}
@@ -646,11 +611,7 @@ static int vdpu_set_freq(struct mpp_dev *mpp,
struct vdpu_dev *dec = to_vdpu_dev(mpp);
struct vdpu_task *task = to_vdpu_task(mpp_task);
/* check whether use debug freq */
task->aclk_freq = dec->aclk_debug ?
dec->aclk_debug : task->aclk_freq;
clk_set_rate(dec->aclk, task->aclk_freq * MHZ);
mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
return 0;
}
@@ -659,8 +620,7 @@ static int vdpu_reduce_freq(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_set_rate(dec->aclk, 50 * MHZ);
mpp_clk_set_rate(&dec->aclk_info, CLK_MODE_REDUCE);
return 0;
}
@@ -739,7 +699,6 @@ static struct mpp_hw_ops vdpu_v1_hw_ops = {
.init = vdpu_init,
.clk_on = vdpu_clk_on,
.clk_off = vdpu_clk_off,
.get_freq = vdpu_get_freq,
.set_freq = vdpu_set_freq,
.reduce_freq = vdpu_reduce_freq,
.reset = vdpu_reset,

View File

@@ -84,7 +84,7 @@
struct vdpu_task {
struct mpp_task mpp_task;
unsigned long aclk_freq;
enum MPP_CLOCK_MODE clk_mode;
u32 reg[VDPU2_REG_NUM];
struct reg_offset_info off_inf;
@@ -100,12 +100,11 @@ struct vdpu_task {
struct vdpu_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -329,6 +328,7 @@ static void *vdpu_alloc_task(struct mpp_session *session,
goto fail;
}
task->strm_addr = task->reg[VDPU2_REG_STREAM_RLC_BASE_INDEX];
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -455,7 +455,6 @@ static int vdpu_debugfs_init(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
dec->aclk_debug = 0;
dec->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(dec->debugfs)) {
@@ -464,7 +463,7 @@ static int vdpu_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
dec->debugfs, &dec->aclk_debug);
dec->debugfs, &dec->aclk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
dec->debugfs, &mpp->session_max_buffers);
@@ -484,20 +483,20 @@ static inline int vdpu_debugfs_init(struct mpp_dev *mpp)
static int vdpu_init(struct mpp_dev *mpp)
{
int ret;
struct vdpu_dev *dec = to_vdpu_dev(mpp);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VDPU2];
dec->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR(dec->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &dec->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
dec->aclk = NULL;
}
dec->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR(dec->hclk)) {
ret = mpp_get_clk_info(mpp, &dec->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
dec->hclk = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
@@ -523,10 +522,8 @@ static int vdpu_clk_on(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_prepare_enable(dec->aclk);
if (dec->hclk)
clk_prepare_enable(dec->hclk);
mpp_clk_safe_enable(dec->aclk_info.clk);
mpp_clk_safe_enable(dec->hclk_info.clk);
return 0;
}
@@ -535,20 +532,8 @@ static int vdpu_clk_off(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_disable_unprepare(dec->aclk);
if (dec->hclk)
clk_disable_unprepare(dec->hclk);
return 0;
}
static int vdpu_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct vdpu_task *task = to_vdpu_task(mpp_task);
task->aclk_freq = 300;
mpp_clk_safe_disable(dec->aclk_info.clk);
mpp_clk_safe_disable(dec->hclk_info.clk);
return 0;
}
@@ -559,11 +544,7 @@ static int vdpu_set_freq(struct mpp_dev *mpp,
struct vdpu_dev *dec = to_vdpu_dev(mpp);
struct vdpu_task *task = to_vdpu_task(mpp_task);
/* check whether use debug freq */
task->aclk_freq = dec->aclk_debug ?
dec->aclk_debug : task->aclk_freq;
clk_set_rate(dec->aclk, task->aclk_freq * MHZ);
mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
return 0;
}
@@ -572,8 +553,7 @@ static int vdpu_reduce_freq(struct mpp_dev *mpp)
{
struct vdpu_dev *dec = to_vdpu_dev(mpp);
if (dec->aclk)
clk_set_rate(dec->aclk, 50 * MHZ);
mpp_clk_set_rate(&dec->aclk_info, CLK_MODE_REDUCE);
return 0;
}
@@ -649,7 +629,6 @@ static struct mpp_hw_ops vdpu_v2_hw_ops = {
.init = vdpu_init,
.clk_on = vdpu_clk_on,
.clk_off = vdpu_clk_off,
.get_freq = vdpu_get_freq,
.set_freq = vdpu_set_freq,
.reduce_freq = vdpu_reduce_freq,
.reset = vdpu_reset,
@@ -659,7 +638,6 @@ static struct mpp_hw_ops vdpu_px30_hw_ops = {
.init = vdpu_px30_init,
.clk_on = vdpu_clk_on,
.clk_off = vdpu_clk_off,
.get_freq = vdpu_get_freq,
.set_freq = vdpu_set_freq,
.reduce_freq = vdpu_reduce_freq,
.reset = vdpu_reset,

View File

@@ -69,7 +69,7 @@
struct vepu_task {
struct mpp_task mpp_task;
unsigned long aclk_freq;
enum MPP_CLOCK_MODE clk_mode;
u32 reg[VEPU1_REG_NUM];
struct reg_offset_info off_inf;
@@ -84,12 +84,11 @@ struct vepu_task {
struct vepu_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -246,6 +245,7 @@ static void *vepu_alloc_task(struct mpp_session *session,
if (ret)
goto fail;
}
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -409,7 +409,6 @@ static int vepu_debugfs_init(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
enc->aclk_debug = 0;
enc->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(enc->debugfs)) {
@@ -418,7 +417,7 @@ static int vepu_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
enc->debugfs, &enc->aclk_debug);
enc->debugfs, &enc->aclk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
enc->debugfs, &mpp->session_max_buffers);
@@ -438,20 +437,20 @@ static inline int vepu_debugfs_init(struct mpp_dev *mpp)
static int vepu_init(struct mpp_dev *mpp)
{
int ret;
struct vepu_dev *enc = to_vepu_dev(mpp);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VEPU1];
enc->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR(enc->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
enc->aclk = NULL;
}
enc->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR(enc->hclk)) {
ret = mpp_get_clk_info(mpp, &enc->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
enc->hclk = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
enc->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
@@ -471,10 +470,8 @@ static int vepu_clk_on(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_prepare_enable(enc->aclk);
if (enc->hclk)
clk_prepare_enable(enc->hclk);
mpp_clk_safe_enable(enc->aclk_info.clk);
mpp_clk_safe_enable(enc->hclk_info.clk);
return 0;
}
@@ -483,20 +480,8 @@ static int vepu_clk_off(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_disable_unprepare(enc->aclk);
if (enc->hclk)
clk_disable_unprepare(enc->hclk);
return 0;
}
static int vepu_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct vepu_task *task = to_vepu_task(mpp_task);
task->aclk_freq = 300;
mpp_clk_safe_disable(enc->aclk_info.clk);
mpp_clk_safe_disable(enc->hclk_info.clk);
return 0;
}
@@ -507,11 +492,7 @@ static int vepu_set_freq(struct mpp_dev *mpp,
struct vepu_dev *enc = to_vepu_dev(mpp);
struct vepu_task *task = to_vepu_task(mpp_task);
/* check whether use debug freq */
task->aclk_freq = enc->aclk_debug ?
enc->aclk_debug : task->aclk_freq;
clk_set_rate(enc->aclk, task->aclk_freq * MHZ);
mpp_clk_set_rate(&enc->aclk_info, task->clk_mode);
return 0;
}
@@ -520,8 +501,7 @@ static int vepu_reduce_freq(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_set_rate(enc->aclk, 50 * MHZ);
mpp_clk_set_rate(&enc->aclk_info, CLK_MODE_REDUCE);
return 0;
}
@@ -549,7 +529,6 @@ static struct mpp_hw_ops vepu_v1_hw_ops = {
.init = vepu_init,
.clk_on = vepu_clk_on,
.clk_off = vepu_clk_off,
.get_freq = vepu_get_freq,
.set_freq = vepu_set_freq,
.reduce_freq = vepu_reduce_freq,
.reset = vepu_reset,

View File

@@ -77,7 +77,8 @@
struct vepu_task {
struct mpp_task mpp_task;
unsigned long aclk_freq;
enum MPP_CLOCK_MODE clk_mode;
u32 reg[VEPU2_REG_NUM];
struct reg_offset_info off_inf;
@@ -92,12 +93,11 @@ struct vepu_task {
struct vepu_dev {
struct mpp_dev mpp;
struct clk *aclk;
struct clk *hclk;
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
u32 aclk_debug;
struct reset_control *rst_a;
struct reset_control *rst_h;
@@ -255,6 +255,7 @@ static void *vepu_alloc_task(struct mpp_session *session,
if (ret)
goto fail;
}
task->clk_mode = CLK_MODE_NORMAL;
mpp_debug_leave();
@@ -420,7 +421,6 @@ static int vepu_debugfs_init(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
enc->aclk_debug = 0;
enc->debugfs = debugfs_create_dir(mpp->dev->of_node->name,
mpp->srv->debugfs);
if (IS_ERR_OR_NULL(enc->debugfs)) {
@@ -429,7 +429,7 @@ static int vepu_debugfs_init(struct mpp_dev *mpp)
return -EIO;
}
debugfs_create_u32("aclk", 0644,
enc->debugfs, &enc->aclk_debug);
enc->debugfs, &enc->aclk_info.debug_rate_hz);
debugfs_create_u32("session_buffers", 0644,
enc->debugfs, &mpp->session_max_buffers);
@@ -449,20 +449,20 @@ static inline int vepu_debugfs_init(struct mpp_dev *mpp)
static int vepu_init(struct mpp_dev *mpp)
{
int ret;
struct vepu_dev *enc = to_vepu_dev(mpp);
mpp->grf_info = &mpp->srv->grf_infos[MPP_DRIVER_VEPU2];
enc->aclk = devm_clk_get(mpp->dev, "aclk_vcodec");
if (IS_ERR(enc->aclk)) {
/* Get clock info from dtsi */
ret = mpp_get_clk_info(mpp, &enc->aclk_info, "aclk_vcodec");
if (ret)
mpp_err("failed on clk_get aclk_vcodec\n");
enc->aclk = NULL;
}
enc->hclk = devm_clk_get(mpp->dev, "hclk_vcodec");
if (IS_ERR(enc->hclk)) {
ret = mpp_get_clk_info(mpp, &enc->hclk_info, "hclk_vcodec");
if (ret)
mpp_err("failed on clk_get hclk_vcodec\n");
enc->hclk = NULL;
}
/* Set default rates */
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
enc->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
@@ -488,10 +488,8 @@ static int vepu_clk_on(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_prepare_enable(enc->aclk);
if (enc->hclk)
clk_prepare_enable(enc->hclk);
mpp_clk_safe_enable(enc->aclk_info.clk);
mpp_clk_safe_enable(enc->hclk_info.clk);
return 0;
}
@@ -500,20 +498,8 @@ static int vepu_clk_off(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_disable_unprepare(enc->aclk);
if (enc->hclk)
clk_disable_unprepare(enc->hclk);
return 0;
}
static int vepu_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
struct vepu_task *task = to_vepu_task(mpp_task);
task->aclk_freq = 300;
mpp_clk_safe_disable(enc->aclk_info.clk);
mpp_clk_safe_disable(enc->hclk_info.clk);
return 0;
}
@@ -524,11 +510,7 @@ static int vepu_set_freq(struct mpp_dev *mpp,
struct vepu_dev *enc = to_vepu_dev(mpp);
struct vepu_task *task = to_vepu_task(mpp_task);
/* check whether use debug freq */
task->aclk_freq = enc->aclk_debug ?
enc->aclk_debug : task->aclk_freq;
clk_set_rate(enc->aclk, task->aclk_freq * MHZ);
mpp_clk_set_rate(&enc->aclk_info, task->clk_mode);
return 0;
}
@@ -537,8 +519,7 @@ static int vepu_reduce_freq(struct mpp_dev *mpp)
{
struct vepu_dev *enc = to_vepu_dev(mpp);
if (enc->aclk)
clk_set_rate(enc->aclk, 50 * MHZ);
mpp_clk_set_rate(&enc->aclk_info, CLK_MODE_REDUCE);
return 0;
}
@@ -566,7 +547,6 @@ static struct mpp_hw_ops vepu_v2_hw_ops = {
.init = vepu_init,
.clk_on = vepu_clk_on,
.clk_off = vepu_clk_off,
.get_freq = vepu_get_freq,
.set_freq = vepu_set_freq,
.reduce_freq = vepu_reduce_freq,
.reset = vepu_reset,
@@ -576,7 +556,6 @@ static struct mpp_hw_ops vepu_px30_hw_ops = {
.init = vepu_px30_init,
.clk_on = vepu_clk_on,
.clk_off = vepu_clk_off,
.get_freq = vepu_get_freq,
.set_freq = vepu_set_freq,
.reduce_freq = vepu_reduce_freq,
.reset = vepu_reset,