video: rockchip: mpp: add strategy to adjust clocks

method: when meets large resolution, higher clocks will be set.
if pixels less default_max_load, clocks use normal-rates setting.
otherwise, use advanced-rates instead.

Change-Id: I7e3c21903f02e3dbc7f84ea8084610ac76738c27
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2021-02-22 17:39:43 +08:00
parent aedde11d4e
commit c22b38d86a

View File

@@ -143,6 +143,10 @@ struct rkvdec_task {
struct mpp_request w_reqs[MPP_MAX_MSG_NUM];
u32 r_req_cnt;
struct mpp_request r_reqs[MPP_MAX_MSG_NUM];
/* image info */
u32 width;
u32 height;
u32 pixels;
};
struct rkvdec_session_priv {
@@ -165,6 +169,7 @@ struct rkvdec_dev {
struct mpp_clk_info core_clk_info;
struct mpp_clk_info cabac_clk_info;
struct mpp_clk_info hevc_cabac_clk_info;
u32 default_max_load;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *procfs;
#endif
@@ -384,6 +389,18 @@ static void *rkvdec_alloc_task(struct mpp_session *session,
mpp_set_rcbbuf(mpp, task);
task->strm_addr = task->reg[RKVDEC_REG_RLC_BASE_INDEX];
task->clk_mode = CLK_MODE_NORMAL;
/* get resolution info */
if (session->priv) {
struct rkvdec_session_priv *priv = session->priv;
u32 width = priv->codec_info[DEC_INFO_WIDTH].val;
u32 bitdepth = priv->codec_info[DEC_INFO_BITDEPTH].val;
task->width = (bitdepth > 8) ? ((width * bitdepth + 7) >> 3) : width;
task->height = priv->codec_info[DEC_INFO_HEIGHT].val;
task->pixels = task->width * task->height;
mpp_debug(DEBUG_TASK_INFO, "width=%d, bitdepth=%d, height=%d\n",
width, bitdepth, task->height);
}
mpp_debug_leave();
@@ -777,6 +794,9 @@ static int rkvdec_init(struct mpp_dev *mpp)
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);
/* Get normal max workload from dtsi */
of_property_read_u32(mpp->dev->of_node,
"rockchip,default-max-load", &dec->default_max_load);
/* Get reset control from dtsi */
dec->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!dec->rst_a)
@@ -829,6 +849,42 @@ static int rkvdec_clk_off(struct mpp_dev *mpp)
return 0;
}
static int rkvdec_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 task_cnt;
u32 workload;
struct mpp_task *loop = NULL, *n;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
/* if not set max load, consider not have advanced mode */
if (!dec->default_max_load || !task->pixels)
return 0;
task_cnt = 1;
workload = task->pixels;
/* calc workload in pending list */
mutex_lock(&mpp->queue->pending_lock);
list_for_each_entry_safe(loop, n,
&mpp->queue->pending_list,
queue_link) {
struct rkvdec_task *loop_task = to_rkvdec_task(loop);
task_cnt++;
workload += loop_task->pixels;
}
mutex_unlock(&mpp->queue->pending_lock);
if (workload > dec->default_max_load)
task->clk_mode = CLK_MODE_ADVANCED;
mpp_debug(DEBUG_TASK_INFO, "pending task %d, workload %d, clk_mode=%d\n",
task_cnt, workload, task->clk_mode);
return 0;
}
static int rkvdec_set_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
@@ -888,6 +944,7 @@ static struct mpp_hw_ops rkvdec_v2_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,