msm: sde: Enable traffic shaping for 4k@30fps rotation
For 30fps rotation, it is only required to perform a commit every other
vsync for a 60fps refresh rate panel. Rotation time for a 4k resolution
will take approx 12ms including SW overhead, and leave very little room
to perform a frame commit in fb driver. One way is to delay the
rotation time by enabling traffic shaping for 4k@30fps content so that
the it will take approx 15ms to finish, and that will force the frame
commit into next vsync time slot and thus matching the cadence of
30fps commit time.
CRs-Fixed: 1100633
Change-Id: I0aecfe767cd77140f75bb13c4fe6f9267d4d911e
Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
Signed-off-by: Narendra Muppalla <NarendraM@codeaurora.org>
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 9240a32..85235e53 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 @@
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 @@
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);
}
@@ -1580,6 +1630,8 @@
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 +1651,8 @@
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 +1696,9 @@
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 +1716,9 @@
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);
}
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 e666f48..5502cc0 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_mdp_data *data;
u32 img_width;
u32 img_height;
+ u32 fps;
+ u64 bw;
};
@@ -93,6 +95,8 @@
u32 img_height;
u32 v_downscale_factor;
u32 h_downscale_factor;
+ u32 fps;
+ u64 bw;
};
@@ -214,6 +218,7 @@
u32 last_regdma_timestamp;
dma_addr_t ts_addr;
bool is_secure;
+ bool is_traffic_shaping;
};
/**