summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_core.c17
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c74
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h7
3 files changed, 84 insertions, 14 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 2fc130137c25..920f5a809777 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -1390,6 +1390,14 @@ static void sde_rotator_commit_handler(struct work_struct *work)
entry->item.dst_rect.x, entry->item.dst_rect.y,
entry->item.dst_rect.w, entry->item.dst_rect.h);
+ ATRACE_INT("sde_smmu_ctrl", 0);
+ ret = sde_smmu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ SDEROT_ERR("IOMMU attach failed\n");
+ goto smmu_error;
+ }
+ ATRACE_INT("sde_smmu_ctrl", 1);
+
ret = sde_rotator_map_and_check_data(entry);
if (ret) {
SDEROT_ERR("fail to prepare input/output data %d\n", ret);
@@ -1415,6 +1423,8 @@ static void sde_rotator_commit_handler(struct work_struct *work)
sde_rot_mgr_unlock(mgr);
return;
error:
+ sde_smmu_ctrl(0);
+smmu_error:
sde_rotator_put_hw_resource(entry->commitq, entry, hw);
get_hw_res_err:
sde_rotator_signal_output(entry);
@@ -1491,6 +1501,7 @@ static void sde_rotator_done_handler(struct work_struct *work)
sde_rot_mgr_lock(mgr);
sde_rotator_put_hw_resource(entry->commitq, entry, entry->commitq->hw);
sde_rotator_signal_output(entry);
+ ATRACE_INT("sde_rot_done", 1);
sde_rotator_release_entry(mgr, entry);
atomic_dec(&request->pending_count);
if (request->retireq && request->retire_work)
@@ -1498,6 +1509,10 @@ static void sde_rotator_done_handler(struct work_struct *work)
if (entry->item.ts)
entry->item.ts[SDE_ROTATOR_TS_RETIRE] = ktime_get();
sde_rot_mgr_unlock(mgr);
+
+ ATRACE_INT("sde_smmu_ctrl", 3);
+ sde_smmu_ctrl(0);
+ ATRACE_INT("sde_smmu_ctrl", 4);
}
static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index f2a9da737453..ddf11b35a1d6 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -36,6 +36,12 @@
#include "sde_rotator_trace.h"
#include "sde_rotator_debug.h"
+#define RES_UHD (3840*2160)
+
+/* traffic shaping clock ticks = finish_time x 19.2MHz */
+#define TRAFFIC_SHAPE_CLKTICK_14MS 268800
+#define TRAFFIC_SHAPE_CLKTICK_12MS 230400
+
/* XIN mapping */
#define XIN_SSPP 0
#define XIN_WRITEBACK 1
@@ -650,6 +656,20 @@ static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx,
ctx->is_secure = false;
}
+ /*
+ * Determine if traffic shaping is required. Only enable traffic
+ * shaping when content is 4k@30fps. The actual traffic shaping
+ * bandwidth calculation is done in output setup.
+ */
+ if (((cfg->src_rect->w * cfg->src_rect->h) >= RES_UHD) &&
+ (cfg->fps <= 30)) {
+ SDEROT_DBG("Enable Traffic Shaper\n");
+ ctx->is_traffic_shaping = true;
+ } else {
+ SDEROT_DBG("Disable Traffic Shaper\n");
+ ctx->is_traffic_shaping = false;
+ }
+
/* Update command queue write ptr */
sde_hw_rotator_put_regdma_segment(ctx, wrptr);
}
@@ -762,6 +782,36 @@ static void sde_hw_rotator_setup_wbengine(struct sde_hw_rotator_context *ctx,
else
SDE_REGDMA_WRITE(wrptr, ROTTOP_OP_MODE, 0x1);
+ /* setup traffic shaper for 4k 30fps content */
+ if (ctx->is_traffic_shaping) {
+ u32 bw;
+
+ /*
+ * Target to finish in 12ms, and we need to set number of bytes
+ * per clock tick for traffic shaping.
+ * Each clock tick run @ 19.2MHz, so we need we know total of
+ * clock ticks in 14ms, i.e. 12ms/(1/19.2MHz) ==> 23040
+ * Finally, calcualte the byte count per clock tick based on
+ * resolution, bpp and compression ratio.
+ */
+ bw = cfg->dst_rect->w * cfg->dst_rect->h;
+
+ if (fmt->chroma_sample == SDE_MDP_CHROMA_420)
+ bw = (bw * 3) / 2;
+ else
+ bw *= fmt->bpp;
+
+ bw /= TRAFFIC_SHAPE_CLKTICK_12MS;
+ if (bw > 0xFF)
+ bw = 0xFF;
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT,
+ BIT(31) | bw);
+ SDEROT_DBG("Enable ROT_WB Traffic Shaper:%d\n", bw);
+ } else {
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_TRAFFIC_SHAPER_WR_CLIENT, 0);
+ SDEROT_DBG("Disable ROT_WB Traffic Shaper\n");
+ }
+
/* Update command queue write ptr */
sde_hw_rotator_put_regdma_segment(ctx, wrptr);
}
@@ -1039,6 +1089,7 @@ static u32 sde_hw_rotator_wait_done_regdma(
!sde_hw_rotator_pending_swts(rot, ctx, &swts),
KOFF_TIMEOUT);
+ ATRACE_INT("sde_rot_done", 0);
spin_lock_irqsave(&rot->rotisr_lock, flags);
last_isr = ctx->last_regdma_isr_status;
@@ -1580,6 +1631,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
sspp_cfg.img_width = item->input.width;
sspp_cfg.img_height = item->input.height;
+ sspp_cfg.fps = entry->perf->config.frame_rate;
+ sspp_cfg.bw = entry->perf->bw;
sspp_cfg.fmt = sde_get_format_params(item->input.format);
if (!sspp_cfg.fmt) {
SDEROT_ERR("null format\n");
@@ -1599,6 +1652,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
wb_cfg.img_width = item->output.width;
wb_cfg.img_height = item->output.height;
+ wb_cfg.fps = entry->perf->config.frame_rate;
+ wb_cfg.bw = entry->perf->bw;
wb_cfg.fmt = sde_get_format_params(item->output.format);
wb_cfg.dst_rect = &item->dst_rect;
wb_cfg.data = &entry->dst_buf;
@@ -1642,7 +1697,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
ot_params.bit_off_mdp_clk_ctrl =
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN0;
- ot_params.fmt = entry->perf->config.input.format;
+ ot_params.fmt = ctx->is_traffic_shaping ?
+ SDE_PIX_FMT_ABGR_8888 :
+ entry->perf->config.input.format;
sde_mdp_set_ot_limit(&ot_params);
}
@@ -1660,7 +1717,9 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0;
ot_params.bit_off_mdp_clk_ctrl =
MMSS_VBIF_NRT_VBIF_CLK_FORCE_CTRL0_XIN1;
- ot_params.fmt = entry->perf->config.input.format;
+ ot_params.fmt = ctx->is_traffic_shaping ?
+ SDE_PIX_FMT_ABGR_8888 :
+ entry->perf->config.input.format;
sde_mdp_set_ot_limit(&ot_params);
}
@@ -1711,7 +1770,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw,
struct sde_hw_rotator *rot;
struct sde_hw_rotator_resource_info *resinfo;
struct sde_hw_rotator_context *ctx;
- int ret = 0;
if (!hw || !entry) {
SDEROT_ERR("null hw resource/entry\n");
@@ -1729,12 +1787,6 @@ static int sde_hw_rotator_kickoff(struct sde_rot_hw_resource *hw,
return -EINVAL;
}
- ret = sde_smmu_ctrl(1);
- if (IS_ERR_VALUE(ret)) {
- SDEROT_ERR("IOMMU attach failed\n");
- return ret;
- }
-
rot->ops.start_rotator(ctx, ctx->q_id);
return 0;
@@ -1774,8 +1826,6 @@ static int sde_hw_rotator_wait4done(struct sde_rot_hw_resource *hw,
ret = rot->ops.wait_rotator_done(ctx, ctx->q_id, 0);
- sde_smmu_ctrl(0);
-
if (rot->dbgmem) {
sde_hw_rotator_unmap_vaddr(&ctx->src_dbgbuf);
sde_hw_rotator_unmap_vaddr(&ctx->dst_dbgbuf);
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
index e666f4811c77..5502cc09ae19 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -73,6 +73,8 @@ struct sde_hw_rot_sspp_cfg {
struct sde_mdp_data *data;
u32 img_width;
u32 img_height;
+ u32 fps;
+ u64 bw;
};
@@ -93,6 +95,8 @@ struct sde_hw_rot_wb_cfg {
u32 img_height;
u32 v_downscale_factor;
u32 h_downscale_factor;
+ u32 fps;
+ u64 bw;
};
@@ -214,6 +218,7 @@ struct sde_hw_rotator_context {
u32 last_regdma_timestamp;
dma_addr_t ts_addr;
bool is_secure;
+ bool is_traffic_shaping;
};
/**