msm: sde: add qos/danger/safe lut config parsing in rotator
Add parsing logic and setting of the qos/danger/safe luts
based on the device tree configuration for both inline and
offline rotator.
Change-Id: Idb0cc388e700e7f661e18ecff41e973dcbdb4dde
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt b/Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt
index 3d790f3..937ccb9 100644
--- a/Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt
+++ b/Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt
@@ -85,6 +85,28 @@
prefetch is available or not. Index 0 represents
if CDP is enabled for read and index 1, if CDP
is enabled for write operation.
+- qcom,mdss-rot-qos-lut A 4 cell property with the format of <rd_lut_0,
+ rd_lut_1, wr_lut_0, wr_lut_1> indicating the qos
+ lut settings for the rotator sspp and writeback
+ client.
+- qcom,mdss-rot-danger-lut A two cell property with the format of <rd_lut,
+ wr_lut> indicating the danger lut settings for
+ the rotator sspp and writeback client.
+- qcom,mdss-rot-safe-lut A two cell property with the format of <rd_lut,
+ wr_lut> indicating the safe lut settings for the
+ rotator sspp and writeback client.
+- qcom,mdss-inline-rot-qos-lut: A 4 cell property with the format of <rd_lut_0,
+ rd_lut_1, wr_lut_0, wr_lut_1> indicating the qos
+ lut settings for the inline rotator sspp and
+ writeback client.
+- qcom,mdss-inline-rot-danger-lut: A two cell property with the format of
+ <rd_lut, wr_lut> indicating the danger lut
+ settings for the inline rotator sspp and
+ writeback client.
+- qcom,mdss-inline-rot-safe-lut: A two cell property with the format of
+ <rd_lut, wr_lut> indicating the safe lut
+ settings for the inline rotator sspp and
+ writeback client.
- qcom,mdss-rot-mode: This is integer value indicates operation mode
of the rotator device
- qcom,mdss-sbuf-headroom: This integer value indicates stream buffer headroom in lines.
@@ -155,6 +177,14 @@
qcom,mdss-default-ot-rd-limit = <8>;
qcom,mdss-default-ot-wr-limit = <16>;
+ qcom,mdss-rot-qos-lut = <0x0 0x0 0x0 0x0>;
+ qcom,mdss-rot-danger-lut = <0x0 0x0>;
+ qcom,mdss-rot-safe-lut = <0x0000ffff 0x0>;
+
+ qcom,mdss-inline-rot-qos-lut = <0x0 0x0 0x00112233 0x44556677>;
+ qcom,mdss-inline-rot-danger-lut = <0x0 0x0000ffff>;
+ qcom,mdss-inline-rot-safe-lut = <0x0 0x0000ff00>;
+
qcom,mdss-sbuf-headroom = <20>;
cache-slice-names = "rotator";
cache-slices = <&llcc 4>;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
index a5428b4..c5b7985 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.c
@@ -445,6 +445,111 @@
clear_bit(SDE_QOS_CDP, mdata->sde_qos_map);
}
+static void sde_mdp_parse_rot_lut_setting(struct platform_device *pdev,
+ struct sde_rot_data_type *mdata)
+{
+ int rc;
+ u32 len, data[4];
+
+ len = sde_mdp_parse_dt_prop_len(pdev, "qcom,mdss-rot-qos-lut");
+ if (len == 4) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-rot-qos-lut", data, len);
+ if (!rc) {
+ mdata->lut_cfg[SDE_ROT_RD].creq_lut_0 = data[0];
+ mdata->lut_cfg[SDE_ROT_RD].creq_lut_1 = data[1];
+ mdata->lut_cfg[SDE_ROT_WR].creq_lut_0 = data[2];
+ mdata->lut_cfg[SDE_ROT_WR].creq_lut_1 = data[3];
+ set_bit(SDE_QOS_LUT, mdata->sde_qos_map);
+ } else {
+ SDEROT_DBG("qos lut setting not found\n");
+ }
+ }
+
+ len = sde_mdp_parse_dt_prop_len(pdev, "qcom,mdss-rot-danger-lut");
+ if (len == SDE_ROT_OP_MAX) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-rot-danger-lut", data, len);
+ if (!rc) {
+ mdata->lut_cfg[SDE_ROT_RD].danger_lut
+ = data[SDE_ROT_RD];
+ mdata->lut_cfg[SDE_ROT_WR].danger_lut
+ = data[SDE_ROT_WR];
+ set_bit(SDE_QOS_DANGER_LUT, mdata->sde_qos_map);
+ } else {
+ SDEROT_DBG("danger lut setting not found\n");
+ }
+ }
+
+ len = sde_mdp_parse_dt_prop_len(pdev, "qcom,mdss-rot-safe-lut");
+ if (len == SDE_ROT_OP_MAX) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-rot-safe-lut", data, len);
+ if (!rc) {
+ mdata->lut_cfg[SDE_ROT_RD].safe_lut = data[SDE_ROT_RD];
+ mdata->lut_cfg[SDE_ROT_WR].safe_lut = data[SDE_ROT_WR];
+ set_bit(SDE_QOS_SAFE_LUT, mdata->sde_qos_map);
+ } else {
+ SDEROT_DBG("safe lut setting not found\n");
+ }
+ }
+}
+
+static void sde_mdp_parse_inline_rot_lut_setting(struct platform_device *pdev,
+ struct sde_rot_data_type *mdata)
+{
+ int rc;
+ u32 len, data[4];
+
+ len = sde_mdp_parse_dt_prop_len(pdev, "qcom,mdss-inline-rot-qos-lut");
+ if (len == 4) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-inline-rot-qos-lut", data, len);
+ if (!rc) {
+ mdata->inline_lut_cfg[SDE_ROT_RD].creq_lut_0 = data[0];
+ mdata->inline_lut_cfg[SDE_ROT_RD].creq_lut_1 = data[1];
+ mdata->inline_lut_cfg[SDE_ROT_WR].creq_lut_0 = data[2];
+ mdata->inline_lut_cfg[SDE_ROT_WR].creq_lut_1 = data[3];
+ set_bit(SDE_INLINE_QOS_LUT, mdata->sde_inline_qos_map);
+ } else {
+ SDEROT_DBG("inline qos lut setting not found\n");
+ }
+ }
+
+ len = sde_mdp_parse_dt_prop_len(pdev,
+ "qcom,mdss-inline-rot-danger-lut");
+ if (len == SDE_ROT_OP_MAX) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-inline-rot-danger-lut", data, len);
+ if (!rc) {
+ mdata->inline_lut_cfg[SDE_ROT_RD].danger_lut
+ = data[SDE_ROT_RD];
+ mdata->inline_lut_cfg[SDE_ROT_WR].danger_lut
+ = data[SDE_ROT_WR];
+ set_bit(SDE_INLINE_QOS_DANGER_LUT,
+ mdata->sde_inline_qos_map);
+ } else {
+ SDEROT_DBG("inline danger lut setting not found\n");
+ }
+ }
+
+ len = sde_mdp_parse_dt_prop_len(pdev, "qcom,mdss-inline-rot-safe-lut");
+ if (len == SDE_ROT_OP_MAX) {
+ rc = sde_mdp_parse_dt_handler(pdev,
+ "qcom,mdss-inline-rot-safe-lut", data, len);
+ if (!rc) {
+ mdata->inline_lut_cfg[SDE_ROT_RD].safe_lut
+ = data[SDE_ROT_RD];
+ mdata->inline_lut_cfg[SDE_ROT_WR].safe_lut
+ = data[SDE_ROT_WR];
+ set_bit(SDE_INLINE_QOS_SAFE_LUT,
+ mdata->sde_inline_qos_map);
+ } else {
+ SDEROT_DBG("inline safe lut setting not found\n");
+ }
+ }
+}
+
static int sde_mdp_parse_dt_misc(struct platform_device *pdev,
struct sde_rot_data_type *mdata)
{
@@ -473,6 +578,10 @@
sde_mdp_parse_vbif_qos(pdev, mdata);
+ sde_mdp_parse_rot_lut_setting(pdev, mdata);
+
+ sde_mdp_parse_inline_rot_lut_setting(pdev, mdata);
+
mdata->mdp_base = mdata->sde_io.base + SDE_MDP_OFFSET;
return 0;
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
index b72151e..ee2561f 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_base.h
@@ -80,9 +80,19 @@
SDE_QOS_PER_PIPE_LUT,
SDE_QOS_SIMPLIFIED_PREFILL,
SDE_QOS_VBLANK_PANIC_CTRL,
+ SDE_QOS_LUT,
+ SDE_QOS_DANGER_LUT,
+ SDE_QOS_SAFE_LUT,
SDE_QOS_MAX,
};
+enum sde_inline_qos_settings {
+ SDE_INLINE_QOS_LUT,
+ SDE_INLINE_QOS_DANGER_LUT,
+ SDE_INLINE_QOS_SAFE_LUT,
+ SDE_INLINE_QOS_MAX,
+};
+
/**
* enum sde_rot_type: SDE rotator HW version
* @SDE_ROT_TYPE_V1_0: V1.0 HW version
@@ -174,6 +184,13 @@
enum sde_rot_regdump_access access;
};
+struct sde_rot_lut_cfg {
+ u32 creq_lut_0;
+ u32 creq_lut_1;
+ u32 danger_lut;
+ u32 safe_lut;
+};
+
struct sde_rot_data_type {
u32 mdss_version;
@@ -186,6 +203,7 @@
/* bitmap to track qos applicable settings */
DECLARE_BITMAP(sde_qos_map, SDE_QOS_MAX);
+ DECLARE_BITMAP(sde_inline_qos_map, SDE_QOS_MAX);
/* bitmap to track capability settings */
DECLARE_BITMAP(sde_caps_map, SDE_CAPS_MAX);
@@ -221,6 +239,9 @@
u32 enable_cdp[SDE_ROT_OP_MAX];
+ struct sde_rot_lut_cfg lut_cfg[SDE_ROT_OP_MAX];
+ struct sde_rot_lut_cfg inline_lut_cfg[SDE_ROT_OP_MAX];
+
struct ion_client *iclient;
bool clk_always_on;
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 f28a469..66d628d 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -906,6 +906,122 @@
}
/*
+ * sde_hw_rotator_setup_qos_lut_wr - Set QoS LUT/Danger LUT/Safe LUT configs
+ * for the WRITEBACK rotator for inline and offline rotation.
+ *
+ * @ctx: Pointer to rotator context
+ */
+static void sde_hw_rotator_setup_qos_lut_wr(struct sde_hw_rotator_context *ctx)
+{
+ struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+ u32 *wrptr = sde_hw_rotator_get_regdma_segment(ctx);
+
+ /* Offline rotation setting */
+ if (!ctx->sbuf_mode) {
+ /* QOS LUT WR setting */
+ if (test_bit(SDE_QOS_LUT, mdata->sde_qos_map)) {
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_CREQ_LUT_0,
+ mdata->lut_cfg[SDE_ROT_WR].creq_lut_0);
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_CREQ_LUT_1,
+ mdata->lut_cfg[SDE_ROT_WR].creq_lut_1);
+ }
+
+ /* Danger LUT WR setting */
+ if (test_bit(SDE_QOS_DANGER_LUT, mdata->sde_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_DANGER_LUT,
+ mdata->lut_cfg[SDE_ROT_WR].danger_lut);
+
+ /* Safe LUT WR setting */
+ if (test_bit(SDE_QOS_SAFE_LUT, mdata->sde_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_SAFE_LUT,
+ mdata->lut_cfg[SDE_ROT_WR].safe_lut);
+
+ /* Inline rotation setting */
+ } else {
+ /* QOS LUT WR setting */
+ if (test_bit(SDE_INLINE_QOS_LUT, mdata->sde_inline_qos_map)) {
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_CREQ_LUT_0,
+ mdata->inline_lut_cfg[SDE_ROT_WR].creq_lut_0);
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_CREQ_LUT_1,
+ mdata->inline_lut_cfg[SDE_ROT_WR].creq_lut_1);
+ }
+
+ /* Danger LUT WR setting */
+ if (test_bit(SDE_INLINE_QOS_DANGER_LUT,
+ mdata->sde_inline_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_DANGER_LUT,
+ mdata->inline_lut_cfg[SDE_ROT_WR].danger_lut);
+
+ /* Safe LUT WR setting */
+ if (test_bit(SDE_INLINE_QOS_SAFE_LUT,
+ mdata->sde_inline_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_WB_SAFE_LUT,
+ mdata->inline_lut_cfg[SDE_ROT_WR].safe_lut);
+ }
+
+ /* Update command queue write ptr */
+ sde_hw_rotator_put_regdma_segment(ctx, wrptr);
+}
+
+/*
+ * sde_hw_rotator_setup_qos_lut_rd - Set QoS LUT/Danger LUT/Safe LUT configs
+ * for the SSPP rotator for inline and offline rotation.
+ *
+ * @ctx: Pointer to rotator context
+ */
+static void sde_hw_rotator_setup_qos_lut_rd(struct sde_hw_rotator_context *ctx)
+{
+ struct sde_rot_data_type *mdata = sde_rot_get_mdata();
+ u32 *wrptr = sde_hw_rotator_get_regdma_segment(ctx);
+
+ /* Offline rotation setting */
+ if (!ctx->sbuf_mode) {
+ /* QOS LUT RD setting */
+ if (test_bit(SDE_QOS_LUT, mdata->sde_qos_map)) {
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_CREQ_LUT_0,
+ mdata->lut_cfg[SDE_ROT_RD].creq_lut_0);
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_CREQ_LUT_1,
+ mdata->lut_cfg[SDE_ROT_RD].creq_lut_1);
+ }
+
+ /* Danger LUT RD setting */
+ if (test_bit(SDE_QOS_DANGER_LUT, mdata->sde_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_DANGER_LUT,
+ mdata->lut_cfg[SDE_ROT_RD].danger_lut);
+
+ /* Safe LUT RD setting */
+ if (test_bit(SDE_QOS_SAFE_LUT, mdata->sde_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_SAFE_LUT,
+ mdata->lut_cfg[SDE_ROT_RD].safe_lut);
+
+ /* inline rotation setting */
+ } else {
+ /* QOS LUT RD setting */
+ if (test_bit(SDE_INLINE_QOS_LUT, mdata->sde_inline_qos_map)) {
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_CREQ_LUT_0,
+ mdata->inline_lut_cfg[SDE_ROT_RD].creq_lut_0);
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_CREQ_LUT_1,
+ mdata->inline_lut_cfg[SDE_ROT_RD].creq_lut_1);
+ }
+
+ /* Danger LUT RD setting */
+ if (test_bit(SDE_INLINE_QOS_DANGER_LUT,
+ mdata->sde_inline_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_DANGER_LUT,
+ mdata->inline_lut_cfg[SDE_ROT_RD].danger_lut);
+
+ /* Safe LUT RD setting */
+ if (test_bit(SDE_INLINE_QOS_SAFE_LUT,
+ mdata->sde_inline_qos_map))
+ SDE_REGDMA_WRITE(wrptr, ROT_SSPP_SAFE_LUT,
+ mdata->inline_lut_cfg[SDE_ROT_RD].safe_lut);
+ }
+
+ /* Update command queue write ptr */
+ sde_hw_rotator_put_regdma_segment(ctx, wrptr);
+}
+
+/*
* sde_hw_rotator_setup_fetchengine - setup fetch engine
* @ctx: Pointer to rotator context
* @queue_id: Priority queue identifier
@@ -1096,6 +1212,7 @@
ctx->is_secure = false;
}
+ /* Update command queue write ptr */
sde_hw_rotator_put_regdma_segment(ctx, wrptr);
/* CDP register RD setting */
@@ -1105,6 +1222,9 @@
cdp_params.offset = ROT_SSPP_CDP_CNTL;
sde_hw_rotator_cdp_configs(ctx, &cdp_params);
+ /* QOS LUT/ Danger LUT/ Safe Lut WR setting */
+ sde_hw_rotator_setup_qos_lut_rd(ctx);
+
wrptr = sde_hw_rotator_get_regdma_segment(ctx);
/*
@@ -1112,8 +1232,9 @@
* 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)) {
+ if (((!ctx->sbuf_mode)
+ && (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 {
@@ -1252,10 +1373,14 @@
cdp_params.offset = ROT_WB_CDP_CNTL;
sde_hw_rotator_cdp_configs(ctx, &cdp_params);
+ /* QOS LUT/ Danger LUT/ Safe LUT WR setting */
+ sde_hw_rotator_setup_qos_lut_wr(ctx);
+
wrptr = sde_hw_rotator_get_regdma_segment(ctx);
/* setup traffic shaper for 4k 30fps content or if prefill_bw is set */
- if (ctx->is_traffic_shaping || cfg->prefill_bw) {
+ if (!ctx->sbuf_mode &&
+ (ctx->is_traffic_shaping || cfg->prefill_bw)) {
u32 bw;
/*
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
index aa762dd..d2b81d5 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3_hwio.h
@@ -81,6 +81,8 @@
#define ROT_SSPP_CREQ_LUT (SDE_ROT_SSPP_OFFSET+0x68)
#define ROT_SSPP_QOS_CTRL (SDE_ROT_SSPP_OFFSET+0x6C)
#define ROT_SSPP_SRC_ADDR_SW_STATUS (SDE_ROT_SSPP_OFFSET+0x70)
+#define ROT_SSPP_CREQ_LUT_0 (SDE_ROT_SSPP_OFFSET+0x74)
+#define ROT_SSPP_CREQ_LUT_1 (SDE_ROT_SSPP_OFFSET+0x78)
#define ROT_SSPP_CURRENT_SRC0_ADDR (SDE_ROT_SSPP_OFFSET+0xA4)
#define ROT_SSPP_CURRENT_SRC1_ADDR (SDE_ROT_SSPP_OFFSET+0xA8)
#define ROT_SSPP_CURRENT_SRC2_ADDR (SDE_ROT_SSPP_OFFSET+0xAC)
@@ -167,6 +169,8 @@
#define ROT_WB_CREQ_LUT (SDE_ROT_WB_OFFSET+0x08C)
#define ROT_WB_QOS_CTRL (SDE_ROT_WB_OFFSET+0x090)
#define ROT_WB_SYS_CACHE_MODE (SDE_ROT_WB_OFFSET+0x094)
+#define ROT_WB_CREQ_LUT_0 (SDE_ROT_WB_OFFSET+0x098)
+#define ROT_WB_CREQ_LUT_1 (SDE_ROT_WB_OFFSET+0x09C)
#define ROT_WB_UBWC_STATIC_CTRL (SDE_ROT_WB_OFFSET+0x144)
#define ROT_WB_SBUF_STATUS_PLANE0 (SDE_ROT_WB_OFFSET+0x148)
#define ROT_WB_SBUF_STATUS_PLANE1 (SDE_ROT_WB_OFFSET+0x14C)