disp: msm: sde: add support for new QoS mode of WB rotation

This change adds support for new dynamic QoS mode for WB rotation
which is required to achieve rotation output available at required
rate to meet real time use case. Though traffic shaper can be
disabled in dynamic QoS mode, part of traffic shaper algo to track
WB operating speed is enabled and WB generates creq priority
based on current ouput rate compared to targetted ouput to help
meeting real time use case requirement.

Change-Id: I98c2dcae53f1b175dc49b40238b9da33e95717a6
Signed-off-by: Prabhanjan Kandula <quic_pkandula@quicinc.com>
This commit is contained in:
Prabhanjan Kandula
2022-06-23 00:31:38 -07:00
committed by Gerrit - the friendly Code Review server
parent 3128214eac
commit c3991049c1
5 changed files with 44 additions and 6 deletions

View File

@@ -244,6 +244,7 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_DSC_MODE,
CONNECTOR_PROP_WB_USAGE_TYPE,
CONNECTOR_PROP_WB_ROT_TYPE,
CONNECTOR_PROP_WB_ROT_BYTES_PER_CLK,
/* total # of properties */
CONNECTOR_PROP_COUNT

View File

@@ -101,8 +101,7 @@ static void sde_encoder_phys_wb_set_ot_limit(struct sde_encoder_phys *phys_enc)
ot_params.num = hw_wb->idx - WB_0;
ot_params.width = wb_enc->wb_roi.w;
ot_params.height = wb_enc->wb_roi.h;
ot_params.is_wfd = ((phys_enc->in_clone_mode) || (usage_type == WB_USAGE_OFFLINE_WB)) ?
false : true;
ot_params.is_wfd = (usage_type == WB_USAGE_WFD);
ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
ot_params.vbif_idx = hw_wb->caps->vbif_idx;
ot_params.clk_ctrl = hw_wb->caps->clk_ctrl;
@@ -153,7 +152,7 @@ static void sde_encoder_phys_wb_set_qos_remap(struct sde_encoder_phys *phys_enc)
qos_params.num = hw_wb->idx - WB_0;
if (phys_enc->in_clone_mode)
qos_params.client_type = VBIF_CWB_CLIENT;
else if (usage_type == WB_USAGE_OFFLINE_WB)
else if (usage_type == WB_USAGE_OFFLINE_WB || usage_type == WB_USAGE_ROT)
qos_params.client_type = VBIF_OFFLINE_WB_CLIENT;
else
qos_params.client_type = VBIF_NRT_CLIENT;
@@ -206,13 +205,19 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
}
qos_cfg.danger_safe_en = true;
if (usage_type == WB_USAGE_ROT) {
qos_cfg.danger_safe_en = false;
qos_cfg.qos_mode = SDE_WB_QOS_MODE_DYNAMIC;
qos_cfg.bytes_per_clk = sde_connector_get_property(conn_state,
CONNECTOR_PROP_WB_ROT_BYTES_PER_CLK);
}
if (phys_enc->in_clone_mode)
lut_index = (SDE_FORMAT_IS_TILE(wb_enc->wb_fmt)
|| SDE_FORMAT_IS_UBWC(wb_enc->wb_fmt)) ?
SDE_QOS_LUT_USAGE_CWB_TILE : SDE_QOS_LUT_USAGE_CWB;
else
lut_index = (usage_type == WB_USAGE_OFFLINE_WB) ?
lut_index = (usage_type == WB_USAGE_OFFLINE_WB || usage_type == WB_USAGE_ROT) ?
SDE_QOS_LUT_USAGE_OFFLINE_WB : SDE_QOS_LUT_USAGE_NRT;
creq_index = lut_index * SDE_CREQ_LUT_TYPE_MAX;
@@ -996,14 +1001,15 @@ static int _sde_encoder_phys_wb_validate_rotation(struct sde_encoder_phys *phys_
enum sde_wb_rot_type rotation_type;
int ret = 0;
u32 src_w, src_h;
u32 bytes_per_clk;
struct sde_rect wb_src, wb_roi = {0,};
struct sde_io_res dnsc_res = {0,};
const struct sde_rect *crtc_roi = NULL;
struct drm_display_mode *mode;
enum sde_wb_usage_type usage_type;
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
rotation_type = sde_connector_get_property(conn_state, CONNECTOR_PROP_WB_ROT_TYPE);
if (rotation_type == WB_ROT_NONE)
return ret;
@@ -1014,6 +1020,13 @@ static int _sde_encoder_phys_wb_validate_rotation(struct sde_encoder_phys *phys_
return -EINVAL;
}
bytes_per_clk = sde_connector_get_property(conn_state, CONNECTOR_PROP_WB_ROT_BYTES_PER_CLK);
if (!bytes_per_clk) {
SDE_ERROR("[enc:%d wb:%d] WB output bytes per XO clock is must for rotation\n",
DRMID(phys_enc->parent), WBID(wb_enc));
return -EINVAL;
}
ret = sde_wb_connector_state_get_output_roi(conn_state, &wb_roi);
if (ret) {
SDE_ERROR("[enc:%d wb:%d] failed to get WB output roi, ret:%d\n",

View File

@@ -23,6 +23,7 @@
#define WB_DST3_ADDR 0x018
#define WB_DST_YSTRIDE0 0x01C
#define WB_DST_YSTRIDE1 0x020
#define WB_TS_WR_CLIENT 0x040
#define WB_DST_WRITE_CONFIG 0x048
#define WB_OUT_SIZE 0x074
#define WB_ALPHA_X_VALUE 0x078
@@ -307,6 +308,11 @@ static void sde_hw_wb_setup_qos_lut(struct sde_hw_wb *ctx,
if (cfg->danger_safe_en)
qos_ctrl |= WB_QOS_CTRL_DANGER_SAFE_EN;
if (test_bit(SDE_WB_LINEAR_ROTATION, &ctx->caps->features)) {
SDE_REG_WRITE(c, WB_TS_WR_CLIENT, cfg->bytes_per_clk & 0xFF);
qos_ctrl |= (cfg->qos_mode << 1);
}
SDE_REG_WRITE(c, WB_QOS_CTRL, qos_ctrl);
}

View File

@@ -49,17 +49,31 @@ struct sde_hw_wb_cdp_cfg {
u32 preload_ahead;
};
/**
* enum sde_hw_wb_qos_mode: enumeration of available QOS modes for WB
* @SDE_WB_QOS_MODE_STATIC: static qos mode same as existing NRT qos mode
* @SDE_WB_QOS_MODE_DYNAMIC: new qos mode to support rotation for real time
*/
enum sde_hw_wb_qos_mode {
SDE_WB_QOS_MODE_STATIC,
SDE_WB_QOS_MODE_DYNAMIC,
};
/**
* struct sde_hw_wb_qos_cfg : Writeback pipe QoS configuration
* @danger_lut: LUT for generate danger level based on fill level
* @safe_lut: LUT for generate safe level based on fill level
* @creq_lut: LUT for generate creq level based on fill level
* @bytes_per_clk: WB output bytes per XO clock value used in rotation
* @qos_mode: enum value mapped for selecting WB QOS mode
* @danger_safe_en: enable danger safe generation
*/
struct sde_hw_wb_qos_cfg {
u32 danger_lut;
u32 safe_lut;
u64 creq_lut;
u32 bytes_per_clk;
enum sde_hw_wb_qos_mode qos_mode;
bool danger_safe_en;
};

View File

@@ -682,11 +682,15 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
msm_property_install_range(&c_conn->property_info, "dnsc_blur",
0x0, 0, ~0, 0, CONNECTOR_PROP_DNSC_BLUR);
if (wb_dev->wb_cfg->features & BIT(SDE_WB_LINEAR_ROTATION))
if (wb_dev->wb_cfg->features & BIT(SDE_WB_LINEAR_ROTATION)) {
msm_property_install_enum(&c_conn->property_info, "wb_rotate_type",
0x0, 0, e_wb_rotate_type, ARRAY_SIZE(e_wb_rotate_type),
0, CONNECTOR_PROP_WB_ROT_TYPE);
msm_property_install_range(&c_conn->property_info, "wb_rot_bytes_per_clk",
0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_WB_ROT_BYTES_PER_CLK);
}
msm_property_install_enum(&c_conn->property_info, "wb_usage_type",
0x0, 0, e_wb_usage_type, ARRAY_SIZE(e_wb_usage_type),
0, CONNECTOR_PROP_WB_USAGE_TYPE);