summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-09-30 18:23:47 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-09-30 18:23:47 -0700
commit627381d09a60fdd30bb26fe3868afb8568b6b3ae (patch)
tree1e1fc5479324333593633ac86dd58d2bd2688c84
parent789809fbfc27c82a643406d06a87da40aa2fbdbd (diff)
parent6c700903fcf9dddca9a9af57dadbbe24c9ee683f (diff)
Merge "msm: sde: Adjust SDE rotator clock and BW calculation"
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c114
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.h2
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c34
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c33
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h7
5 files changed, 135 insertions, 55 deletions
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
index 041a8219e145..594bac6c5902 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -41,8 +41,12 @@
#define ROT_HW_ACQUIRE_TIMEOUT_IN_MS 100
/* default pixel per clock ratio */
-#define ROT_PIXEL_PER_CLK_NUMERATOR 4
-#define ROT_PIXEL_PER_CLK_DENOMINATOR 1
+#define ROT_PIXEL_PER_CLK_NUMERATOR 36
+#define ROT_PIXEL_PER_CLK_DENOMINATOR 10
+#define ROT_FUDGE_FACTOR_NUMERATOR 105
+#define ROT_FUDGE_FACTOR_DENOMINATOR 100
+#define ROT_OVERHEAD_NUMERATOR 27
+#define ROT_OVERHEAD_DENOMINATOR 10000
/*
* Max rotator hw blocks possible. Used for upper array limits instead of
@@ -998,12 +1002,33 @@ static u32 sde_rotator_calc_buf_bw(struct sde_mdp_format_params *fmt,
return bw;
}
+static int sde_rotator_find_max_fps(struct sde_rot_mgr *mgr)
+{
+ struct sde_rot_file_private *priv;
+ struct sde_rot_perf *perf;
+ int max_fps = 0;
+
+ list_for_each_entry(priv, &mgr->file_list, list) {
+ list_for_each_entry(perf, &priv->perf_list, list) {
+ if (perf->config.frame_rate > max_fps)
+ max_fps = perf->config.frame_rate;
+ }
+ }
+
+ SDEROT_DBG("Max fps:%d\n", max_fps);
+ return max_fps;
+}
+
static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
struct sde_rot_perf *perf)
{
struct sde_rotation_config *config = &perf->config;
u32 read_bw, write_bw;
struct sde_mdp_format_params *in_fmt, *out_fmt;
+ struct sde_rotator_device *rot_dev;
+ int max_fps;
+
+ rot_dev = platform_get_drvdata(mgr->pdev);
in_fmt = sde_get_format_params(config->input.format);
if (!in_fmt) {
@@ -1016,17 +1041,44 @@ static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
return -EINVAL;
}
+ /*
+ * rotator processes 4 pixels per clock, but the actual throughtput
+ * is 3.6. We also need to take into account for overhead time. Final
+ * equation is:
+ * W x H / throughput / (1/fps - overhead) * fudge_factor
+ */
+ max_fps = sde_rotator_find_max_fps(mgr);
perf->clk_rate = config->input.width * config->input.height;
- perf->clk_rate *= config->frame_rate;
- /* rotator processes 4 pixels per clock */
perf->clk_rate = (perf->clk_rate * mgr->pixel_per_clk.denom) /
mgr->pixel_per_clk.numer;
+ perf->clk_rate *= max_fps;
+ perf->clk_rate = (perf->clk_rate * mgr->fudge_factor.numer) /
+ mgr->fudge_factor.denom;
+ perf->clk_rate *= mgr->overhead.denom;
+
+ /*
+ * check for override overhead default value
+ */
+ if (rot_dev->min_overhead_us > (mgr->overhead.numer * 100))
+ perf->clk_rate = DIV_ROUND_UP_ULL(perf->clk_rate,
+ (mgr->overhead.denom - max_fps *
+ (rot_dev->min_overhead_us / 100)));
+ else
+ perf->clk_rate = DIV_ROUND_UP_ULL(perf->clk_rate,
+ (mgr->overhead.denom - max_fps *
+ mgr->overhead.numer));
+
+ /*
+ * check for Override clock calcualtion
+ */
+ if (rot_dev->min_rot_clk > perf->clk_rate)
+ perf->clk_rate = rot_dev->min_rot_clk;
read_bw = sde_rotator_calc_buf_bw(in_fmt, config->input.width,
- config->input.height, config->frame_rate);
+ config->input.height, max_fps);
write_bw = sde_rotator_calc_buf_bw(out_fmt, config->output.width,
- config->output.height, config->frame_rate);
+ config->output.height, max_fps);
read_bw = sde_apply_comp_ratio_factor(read_bw, in_fmt,
&config->input.comp_ratio);
@@ -1035,13 +1087,22 @@ static int sde_rotator_calc_perf(struct sde_rot_mgr *mgr,
perf->bw = read_bw + write_bw;
+ /*
+ * check for override bw calculation
+ */
+ if (rot_dev->min_bw > perf->bw)
+ perf->bw = rot_dev->min_bw;
+
perf->rdot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, config->frame_rate, true);
+ config->input.format, max_fps, true);
perf->wrot_limit = sde_mdp_get_ot_limit(
config->input.width, config->input.height,
- config->input.format, config->frame_rate, false);
+ config->input.format, max_fps, false);
+ SDEROT_DBG("clk:%lu, rdBW:%d, wrBW:%d, rdOT:%d, wrOT:%d\n",
+ perf->clk_rate, read_bw, write_bw, perf->rdot_limit,
+ perf->wrot_limit);
return 0;
}
@@ -1747,16 +1808,9 @@ static int sde_rotator_open_session(struct sde_rot_mgr *mgr,
config.session_id = session_id;
perf->config = config;
- perf->last_wb_idx = -1;
+ perf->last_wb_idx = 0;
INIT_LIST_HEAD(&perf->list);
-
- ret = sde_rotator_calc_perf(mgr, perf);
- if (ret) {
- SDEROT_ERR("error setting the session %d\n", ret);
- goto copy_user_err;
- }
-
list_add(&perf->list, &private->perf_list);
ret = sde_rotator_resource_ctrl(mgr, true);
@@ -1777,25 +1831,17 @@ static int sde_rotator_open_session(struct sde_rot_mgr *mgr,
goto enable_clk_err;
}
- ret = sde_rotator_update_perf(mgr);
- if (ret) {
- SDEROT_ERR("fail to open session, not enough clk/bw\n");
- goto perf_err;
- }
SDEROT_DBG("open session id=%u in{%u,%u}f:%u out{%u,%u}f:%u\n",
config.session_id, config.input.width, config.input.height,
config.input.format, config.output.width, config.output.height,
config.output.format);
goto done;
-perf_err:
- sde_rotator_clk_ctrl(mgr, false);
enable_clk_err:
update_clk_err:
sde_rotator_resource_ctrl(mgr, false);
resource_err:
list_del_init(&perf->list);
-copy_user_err:
devm_kfree(&mgr->pdev->dev, perf->work_distribution);
alloc_err:
devm_kfree(&mgr->pdev->dev, perf);
@@ -1867,11 +1913,23 @@ static int sde_rotator_config_session(struct sde_rot_mgr *mgr,
}
ret = sde_rotator_update_perf(mgr);
+ if (ret) {
+ SDEROT_ERR("error in updating perf: %d\n", ret);
+ goto done;
+ }
+
+ ret = sde_rotator_update_clk(mgr);
+ if (ret) {
+ SDEROT_ERR("error in updating the rotator clk: %d\n", ret);
+ goto done;
+ }
- SDEROT_DBG("reconfig session id=%u in{%u,%u}f:%u out{%u,%u}f:%u\n",
+ SDEROT_DBG(
+ "reconfig session id=%u in{%u,%u}f:%u out{%u,%u}f:%u fps:%d clk:%lu, bw:%llu\n",
config->session_id, config->input.width, config->input.height,
config->input.format, config->output.width,
- config->output.height, config->output.format);
+ config->output.height, config->output.format,
+ config->frame_rate, perf->clk_rate, perf->bw);
done:
return ret;
}
@@ -2386,6 +2444,10 @@ int sde_rotator_core_init(struct sde_rot_mgr **pmgr,
mgr->queue_count = 1;
mgr->pixel_per_clk.numer = ROT_PIXEL_PER_CLK_NUMERATOR;
mgr->pixel_per_clk.denom = ROT_PIXEL_PER_CLK_DENOMINATOR;
+ mgr->fudge_factor.numer = ROT_FUDGE_FACTOR_NUMERATOR;
+ mgr->fudge_factor.denom = ROT_FUDGE_FACTOR_DENOMINATOR;
+ mgr->overhead.numer = ROT_OVERHEAD_NUMERATOR;
+ mgr->overhead.denom = ROT_OVERHEAD_DENOMINATOR;
mutex_init(&mgr->lock);
atomic_set(&mgr->device_suspended, 0);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
index aa17341de7c2..781b03e1b974 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.h
@@ -281,6 +281,8 @@ struct sde_rot_mgr {
u32 hwacquire_timeout;
struct sde_mult_factor pixel_per_clk;
+ struct sde_mult_factor fudge_factor;
+ struct sde_mult_factor overhead;
int (*ops_config_hw)(struct sde_rot_hw_resource *hw,
struct sde_rot_entry *entry);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
index c609dbd2036e..94223b557990 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c
@@ -914,6 +914,34 @@ static int sde_rotator_evtlog_create_debugfs(
return 0;
}
+
+static int sde_rotator_perf_create_debugfs(
+ struct sde_rotator_device *rot_dev,
+ struct dentry *debugfs_root)
+{
+ rot_dev->perf_root = debugfs_create_dir("perf", debugfs_root);
+ if (IS_ERR_OR_NULL(rot_dev->perf_root)) {
+ pr_err("debugfs_create_dir for perf failed, error %ld\n",
+ PTR_ERR(rot_dev->perf_root));
+ rot_dev->perf_root = NULL;
+ return -ENODEV;
+ }
+
+ rot_dev->min_rot_clk = 0;
+ debugfs_create_u32("min_rot_clk", S_IRUGO | S_IWUSR,
+ rot_dev->perf_root, &rot_dev->min_rot_clk);
+
+ rot_dev->min_bw = 0;
+ debugfs_create_u32("min_bw", S_IRUGO | S_IWUSR,
+ rot_dev->perf_root, &rot_dev->min_bw);
+
+ rot_dev->min_overhead_us = 0;
+ debugfs_create_u32("min_overhead_us", S_IRUGO | S_IWUSR,
+ rot_dev->perf_root, &rot_dev->min_overhead_us);
+
+ return 0;
+}
+
/*
* struct sde_rotator_stat_ops - processed statistics file operations
*/
@@ -1006,6 +1034,12 @@ struct dentry *sde_rotator_create_debugfs(
return NULL;
}
+ if (sde_rotator_perf_create_debugfs(rot_dev, debugfs_root)) {
+ SDEROT_ERR("fail create perf debugfs\n");
+ debugfs_remove_recursive(debugfs_root);
+ return NULL;
+ }
+
return debugfs_root;
}
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
index d34623a531ba..930b18abd71b 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c
@@ -546,22 +546,8 @@ static struct vb2_mem_ops sde_rotator_vb2_mem_ops = {
static int sde_rotator_s_ctx_ctrl(struct sde_rotator_ctx *ctx,
s32 *ctx_ctrl, struct v4l2_ctrl *ctrl)
{
- struct sde_rotator_device *rot_dev = ctx->rot_dev;
- struct sde_rotation_config config;
- s32 prev_val;
- int ret;
-
- prev_val = *ctx_ctrl;
*ctx_ctrl = ctrl->val;
- sde_rotator_get_config_from_ctx(ctx, &config);
- ret = sde_rotator_session_config(rot_dev->mgr, ctx->private, &config);
- if (ret) {
- SDEDEV_WARN(rot_dev->dev, "fail %s:%d s:%d\n",
- ctrl->name, ctrl->val, ctx->session_id);
- *ctx_ctrl = prev_val;
- }
-
- return ret;
+ return 0;
}
/*
@@ -1213,7 +1199,6 @@ static int sde_rotator_s_fmt_vid_cap(struct file *file,
{
struct sde_rotator_ctx *ctx = sde_rotator_ctx_from_fh(fh);
struct sde_rotator_device *rot_dev = ctx->rot_dev;
- struct sde_rotation_config config;
int ret;
ret = sde_rotator_try_fmt_vid_cap(file, fh, f);
@@ -1235,12 +1220,6 @@ static int sde_rotator_s_fmt_vid_cap(struct file *file,
f->fmt.pix.field,
f->fmt.pix.width, f->fmt.pix.height);
- /* configure hal to current input/output setting */
- sde_rot_mgr_lock(rot_dev->mgr);
- sde_rotator_get_config_from_ctx(ctx, &config);
- sde_rotator_session_config(rot_dev->mgr, ctx->private, &config);
- sde_rot_mgr_unlock(rot_dev->mgr);
-
return 0;
}
@@ -1524,7 +1503,6 @@ static int sde_rotator_s_crop(struct file *file, void *fh,
{
struct sde_rotator_ctx *ctx = sde_rotator_ctx_from_fh(fh);
struct sde_rotator_device *rot_dev = ctx->rot_dev;
- struct sde_rotation_config config;
struct sde_rotation_item item;
struct v4l2_rect rect;
@@ -1597,12 +1575,6 @@ static int sde_rotator_s_crop(struct file *file, void *fh,
return -EINVAL;
}
- /* configure hal to current input/output setting */
- sde_rot_mgr_lock(rot_dev->mgr);
- sde_rotator_get_config_from_ctx(ctx, &config);
- sde_rotator_session_config(rot_dev->mgr, ctx->private, &config);
- sde_rot_mgr_unlock(rot_dev->mgr);
-
return 0;
}
@@ -2336,6 +2308,9 @@ static int sde_rotator_probe(struct platform_device *pdev)
rot_dev->early_submit = SDE_ROTATOR_EARLY_SUBMIT;
rot_dev->fence_timeout = SDE_ROTATOR_FENCE_TIMEOUT;
rot_dev->streamoff_timeout = SDE_ROTATOR_STREAM_OFF_TIMEOUT;
+ rot_dev->min_rot_clk = 0;
+ rot_dev->min_bw = 0;
+ rot_dev->min_overhead_us = 0;
rot_dev->drvdata = sde_rotator_get_drv_data(&pdev->dev);
rot_dev->pdev = pdev;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h
index fd247d10128c..f3c904817296 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_dev.h
@@ -160,6 +160,9 @@ struct sde_rotator_statistics {
* @session_id: Next context session identifier
* @fence_timeout: Timeout value in msec for fence wait
* @streamoff_timeout: Timeout value in msec for stream off
+ * @min_rot_clk: Override the minimum rotator clock from perf calculation
+ * @min_bw: Override the minimum bandwidth from perf calculation
+ * @min_overhead_us: Override the minimum overhead in us from perf calculation
* @debugfs_root: Pointer to debugfs directory entry.
* @stats: placeholder for rotator statistics
*/
@@ -177,8 +180,12 @@ struct sde_rotator_device {
u32 session_id;
u32 fence_timeout;
u32 streamoff_timeout;
+ u32 min_rot_clk;
+ u32 min_bw;
+ u32 min_overhead_us;
struct sde_rotator_statistics stats;
struct dentry *debugfs_root;
+ struct dentry *perf_root;
};
static inline