video: rockchip: mpp: rkvenc: set clk_mode according to load

Change-Id: Idf7eebf96708d8c5c95c6169a80083952d324540
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2020-07-09 17:07:32 +08:00
committed by Tao Huang
parent 943b52284b
commit 1f32179cba

View File

@@ -79,8 +79,8 @@
(RKVENC_BIT_AXI_WRITE_CHANNEL) |\
(RKVENC_BIT_AXI_READ_CHANNEL) |\
(RKVENC_BIT_TIMEOUT))
#define RKVENC_ENC_PIC_INDEX 10
#define RKVENC_ENC_RSL_INDEX 12
#define RKVENC_ENC_PIC_INDEX 13
#define RKVENC_ENC_PIC_BASE 0x034
#define RKVENC_GET_FORMAT(x) ((x) & 0x1)
#define RKVENC_ENC_PIC_NODE_INT_EN BIT(31)
@@ -106,6 +106,10 @@
#define RKVENC_L2_READ_BASE (0x3f8)
#define RKVENC_L2_BURST_TYPE BIT(0)
#define RKVENC_GET_WIDTH(x) (((x & 0x1ff) + 1) << 3)
#define RKVENC_GET_HEIGHT(x) ((((x >> 16) & 0x1ff) + 1) << 3)
#define RKVENC_DEFAULT_MAX_LOAD (1920 * 1088)
#define to_rkvenc_task(ctx) \
container_of(ctx, struct rkvenc_task, mpp_task)
#define to_rkvenc_dev(dev) \
@@ -136,6 +140,9 @@ struct rkvenc_task {
u32 reg_offset;
u32 reg_num;
u32 reg[RKVENC_REG_L1_NUM];
u32 width;
u32 height;
u32 pixels;
/* level 2 register setting */
u32 reg_l2_offset;
u32 reg_l2_num;
@@ -158,6 +165,7 @@ struct rkvenc_dev {
struct mpp_clk_info aclk_info;
struct mpp_clk_info hclk_info;
struct mpp_clk_info core_clk_info;
u32 default_max_load;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs;
#endif
@@ -338,6 +346,11 @@ static void *rkvenc_alloc_task(struct mpp_session *session,
}
task->link_mode = RKVENC_MODE_ONEFRAME;
task->clk_mode = CLK_MODE_NORMAL;
/* get resolution info */
task->width = RKVENC_GET_WIDTH(task->reg[RKVENC_ENC_RSL_INDEX]);
task->height = RKVENC_GET_HEIGHT(task->reg[RKVENC_ENC_RSL_INDEX]);
task->pixels = task->width * task->height;
mpp_debug(DEBUG_TASK_INFO, "width=%d, height=%d\n", task->width, task->height);
mpp_debug_leave();
@@ -865,6 +878,12 @@ static int rkvenc_init(struct mpp_dev *mpp)
ret = mpp_get_clk_info(mpp, &enc->core_clk_info, "clk_core");
if (ret)
mpp_err("failed on clk_get clk_core\n");
/* Get normal max workload from dtsi */
of_property_read_u32(mpp->dev->of_node,
"rockchip,default-max-load",
&enc->default_max_load);
if (!enc->default_max_load)
enc->default_max_load = RKVENC_DEFAULT_MAX_LOAD;
/* 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);
@@ -954,6 +973,38 @@ static int rkvenc_clk_off(struct mpp_dev *mpp)
return 0;
}
static int rkvenc_get_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
u32 task_cnt;
u32 workload;
struct mpp_task *loop = NULL, *n;
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
struct rkvenc_task *task = to_rkvenc_task(mpp_task);
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 rkvenc_task *loop_task = to_rkvenc_task(loop);
task_cnt++;
workload += loop_task->pixels;
}
mutex_unlock(&mpp->queue->pending_lock);
if (workload > enc->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 rkvenc_set_freq(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
@@ -993,6 +1044,7 @@ 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,
};