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>
这个提交包含在:

提交者
Gerrit - the friendly Code Review server

父节点
3128214eac
当前提交
c3991049c1
@@ -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
|
||||
|
@@ -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",
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
在新工单中引用
屏蔽一个用户