disp: msm: sde: add offline WB QoS support
Add support to parse and configure QoS values for offline writeback. Expose a writeback connector property to allow user-mode to set the usage type of the writeback block - WFD, CWB, offline-WB. Change-Id: I864f79c4896ec757ac2d8b0f57a6a5775d164f21 Signed-off-by: Veera Sundaram Sankaran <quic_veeras@quicinc.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (C) 2013 Red Hat
|
* Copyright (C) 2013 Red Hat
|
||||||
* Author: Rob Clark <robdclark@gmail.com>
|
* Author: Rob Clark <robdclark@gmail.com>
|
||||||
@@ -233,6 +234,7 @@ enum msm_mdp_conn_property {
|
|||||||
CONNECTOR_PROP_AVR_STEP,
|
CONNECTOR_PROP_AVR_STEP,
|
||||||
CONNECTOR_PROP_CACHE_STATE,
|
CONNECTOR_PROP_CACHE_STATE,
|
||||||
CONNECTOR_PROP_DSC_MODE,
|
CONNECTOR_PROP_DSC_MODE,
|
||||||
|
CONNECTOR_PROP_WB_USAGE_TYPE,
|
||||||
|
|
||||||
/* total # of properties */
|
/* total # of properties */
|
||||||
CONNECTOR_PROP_COUNT
|
CONNECTOR_PROP_COUNT
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -682,6 +683,7 @@ struct sde_connector {
|
|||||||
* @dnsc_blur_count: Number of downscale blur blocks used
|
* @dnsc_blur_count: Number of downscale blur blocks used
|
||||||
* @dnsc_blur_cfg: Configs for the downscale blur block
|
* @dnsc_blur_cfg: Configs for the downscale blur block
|
||||||
* @dnsc_blur_lut: LUT idx used for the Gaussian filter LUTs in downscale blur block
|
* @dnsc_blur_lut: LUT idx used for the Gaussian filter LUTs in downscale blur block
|
||||||
|
* @usage_type: WB connector usage type
|
||||||
*/
|
*/
|
||||||
struct sde_connector_state {
|
struct sde_connector_state {
|
||||||
struct drm_connector_state base;
|
struct drm_connector_state base;
|
||||||
@@ -702,6 +704,7 @@ struct sde_connector_state {
|
|||||||
u32 dnsc_blur_count;
|
u32 dnsc_blur_count;
|
||||||
struct sde_drm_dnsc_blur_cfg dnsc_blur_cfg[DNSC_BLUR_MAX_COUNT];
|
struct sde_drm_dnsc_blur_cfg dnsc_blur_cfg[DNSC_BLUR_MAX_COUNT];
|
||||||
u32 dnsc_blur_lut;
|
u32 dnsc_blur_lut;
|
||||||
|
enum sde_wb_usage_type usage_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
|
||||||
* Copyright (C) 2013 Red Hat
|
* Copyright (C) 2013 Red Hat
|
||||||
* Author: Rob Clark <robdclark@gmail.com>
|
* Author: Rob Clark <robdclark@gmail.com>
|
||||||
@@ -140,6 +140,26 @@ static inline struct sde_kms *_sde_crtc_get_kms(struct drm_crtc *crtc)
|
|||||||
return to_sde_kms(priv->kms);
|
return to_sde_kms(priv->kms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum sde_wb_usage_type sde_crtc_get_wb_usage_type(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
struct drm_connector *conn;
|
||||||
|
struct drm_connector_list_iter conn_iter;
|
||||||
|
enum sde_wb_usage_type usage_type = 0;
|
||||||
|
|
||||||
|
drm_connector_list_iter_begin(crtc->dev, &conn_iter);
|
||||||
|
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||||
|
if (conn->state && (conn->state->crtc == crtc)
|
||||||
|
&& (conn->connector_type == DRM_MODE_CONNECTOR_VIRTUAL)) {
|
||||||
|
usage_type = sde_connector_get_property(conn->state,
|
||||||
|
CONNECTOR_PROP_WB_USAGE_TYPE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drm_connector_list_iter_end(&conn_iter);
|
||||||
|
|
||||||
|
return usage_type;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct drm_connector_state *_sde_crtc_get_virt_conn_state(
|
static inline struct drm_connector_state *_sde_crtc_get_virt_conn_state(
|
||||||
struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
|
struct drm_crtc *crtc, struct drm_crtc_state *crtc_state)
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
|
||||||
* Copyright (C) 2013 Red Hat
|
* Copyright (C) 2013 Red Hat
|
||||||
* Author: Rob Clark <robdclark@gmail.com>
|
* Author: Rob Clark <robdclark@gmail.com>
|
||||||
@@ -720,6 +720,12 @@ u32 sde_crtc_get_fps_mode(struct drm_crtc *crtc);
|
|||||||
*/
|
*/
|
||||||
u32 sde_crtc_get_dfps_maxfps(struct drm_crtc *crtc);
|
u32 sde_crtc_get_dfps_maxfps(struct drm_crtc *crtc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sde_crtc_get_wb_usage_type - get writeback usage type
|
||||||
|
* @crtc: Pointert to crtc
|
||||||
|
*/
|
||||||
|
enum sde_wb_usage_type sde_crtc_get_wb_usage_type(struct drm_crtc *crtc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sde_crtc_get_client_type - check the crtc type- rt, rsc_rt, etc.
|
* sde_crtc_get_client_type - check the crtc type- rt, rsc_rt, etc.
|
||||||
* @crtc: Pointer to crtc
|
* @crtc: Pointer to crtc
|
||||||
|
@@ -78,19 +78,24 @@ static enum sde_intr_type sde_encoder_phys_wb_get_intr_type(
|
|||||||
* sde_encoder_phys_wb_set_ot_limit - set OT limit for writeback interface
|
* sde_encoder_phys_wb_set_ot_limit - set OT limit for writeback interface
|
||||||
* @phys_enc: Pointer to physical encoder
|
* @phys_enc: Pointer to physical encoder
|
||||||
*/
|
*/
|
||||||
static void sde_encoder_phys_wb_set_ot_limit(
|
static void sde_encoder_phys_wb_set_ot_limit(struct sde_encoder_phys *phys_enc)
|
||||||
struct sde_encoder_phys *phys_enc)
|
|
||||||
{
|
{
|
||||||
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
|
struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
|
||||||
struct sde_hw_wb *hw_wb = wb_enc->hw_wb;
|
struct sde_hw_wb *hw_wb = wb_enc->hw_wb;
|
||||||
|
struct drm_connector_state *conn_state;
|
||||||
struct sde_vbif_set_ot_params ot_params;
|
struct sde_vbif_set_ot_params ot_params;
|
||||||
|
enum sde_wb_usage_type usage_type;
|
||||||
|
|
||||||
|
conn_state = phys_enc->connector->state;
|
||||||
|
usage_type = sde_connector_get_property(conn_state, CONNECTOR_PROP_WB_USAGE_TYPE);
|
||||||
|
|
||||||
memset(&ot_params, 0, sizeof(ot_params));
|
memset(&ot_params, 0, sizeof(ot_params));
|
||||||
ot_params.xin_id = hw_wb->caps->xin_id;
|
ot_params.xin_id = hw_wb->caps->xin_id;
|
||||||
ot_params.num = hw_wb->idx - WB_0;
|
ot_params.num = hw_wb->idx - WB_0;
|
||||||
ot_params.width = wb_enc->wb_roi.w;
|
ot_params.width = wb_enc->wb_roi.w;
|
||||||
ot_params.height = wb_enc->wb_roi.h;
|
ot_params.height = wb_enc->wb_roi.h;
|
||||||
ot_params.is_wfd = !(phys_enc->in_clone_mode);
|
ot_params.is_wfd = ((phys_enc->in_clone_mode) || (usage_type == WB_USAGE_OFFLINE_WB)) ?
|
||||||
|
false : true;
|
||||||
ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
|
ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
|
||||||
ot_params.vbif_idx = hw_wb->caps->vbif_idx;
|
ot_params.vbif_idx = hw_wb->caps->vbif_idx;
|
||||||
ot_params.clk_ctrl = hw_wb->caps->clk_ctrl;
|
ot_params.clk_ctrl = hw_wb->caps->clk_ctrl;
|
||||||
@@ -108,7 +113,9 @@ static void sde_encoder_phys_wb_set_qos_remap(struct sde_encoder_phys *phys_enc)
|
|||||||
struct sde_encoder_phys_wb *wb_enc;
|
struct sde_encoder_phys_wb *wb_enc;
|
||||||
struct sde_hw_wb *hw_wb;
|
struct sde_hw_wb *hw_wb;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
struct drm_connector_state *conn_state;
|
||||||
struct sde_vbif_set_qos_params qos_params;
|
struct sde_vbif_set_qos_params qos_params;
|
||||||
|
enum sde_wb_usage_type usage_type;
|
||||||
|
|
||||||
if (!phys_enc || !phys_enc->parent || !phys_enc->parent->crtc) {
|
if (!phys_enc || !phys_enc->parent || !phys_enc->parent->crtc) {
|
||||||
SDE_ERROR("invalid arguments\n");
|
SDE_ERROR("invalid arguments\n");
|
||||||
@@ -122,6 +129,8 @@ static void sde_encoder_phys_wb_set_qos_remap(struct sde_encoder_phys *phys_enc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
crtc = wb_enc->crtc;
|
crtc = wb_enc->crtc;
|
||||||
|
conn_state = phys_enc->connector->state;
|
||||||
|
usage_type = sde_connector_get_property(conn_state, CONNECTOR_PROP_WB_USAGE_TYPE);
|
||||||
|
|
||||||
if (!wb_enc->hw_wb || !wb_enc->hw_wb->caps) {
|
if (!wb_enc->hw_wb || !wb_enc->hw_wb->caps) {
|
||||||
SDE_ERROR("[enc:%d wb:%d] invalid WB HW\n", DRMID(phys_enc->parent), WBID(wb_enc));
|
SDE_ERROR("[enc:%d wb:%d] invalid WB HW\n", DRMID(phys_enc->parent), WBID(wb_enc));
|
||||||
@@ -135,8 +144,12 @@ static void sde_encoder_phys_wb_set_qos_remap(struct sde_encoder_phys *phys_enc)
|
|||||||
qos_params.xin_id = hw_wb->caps->xin_id;
|
qos_params.xin_id = hw_wb->caps->xin_id;
|
||||||
qos_params.clk_ctrl = hw_wb->caps->clk_ctrl;
|
qos_params.clk_ctrl = hw_wb->caps->clk_ctrl;
|
||||||
qos_params.num = hw_wb->idx - WB_0;
|
qos_params.num = hw_wb->idx - WB_0;
|
||||||
qos_params.client_type = phys_enc->in_clone_mode ?
|
if (phys_enc->in_clone_mode)
|
||||||
VBIF_CWB_CLIENT : VBIF_NRT_CLIENT;
|
qos_params.client_type = VBIF_CWB_CLIENT;
|
||||||
|
else if (usage_type == WB_USAGE_OFFLINE_WB)
|
||||||
|
qos_params.client_type = VBIF_OFFLINE_WB_CLIENT;
|
||||||
|
else
|
||||||
|
qos_params.client_type = VBIF_NRT_CLIENT;
|
||||||
|
|
||||||
SDE_DEBUG("[enc:%d wb:%d] qos_remap - wb:%d vbif:%d xin:%d clone:%d\n",
|
SDE_DEBUG("[enc:%d wb:%d] qos_remap - wb:%d vbif:%d xin:%d clone:%d\n",
|
||||||
DRMID(phys_enc->parent), WBID(wb_enc), qos_params.num,
|
DRMID(phys_enc->parent), WBID(wb_enc), qos_params.num,
|
||||||
@@ -153,9 +166,11 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
|
|||||||
{
|
{
|
||||||
struct sde_encoder_phys_wb *wb_enc;
|
struct sde_encoder_phys_wb *wb_enc;
|
||||||
struct sde_hw_wb *hw_wb;
|
struct sde_hw_wb *hw_wb;
|
||||||
|
struct drm_connector_state *conn_state;
|
||||||
struct sde_hw_wb_qos_cfg qos_cfg = {0};
|
struct sde_hw_wb_qos_cfg qos_cfg = {0};
|
||||||
struct sde_perf_cfg *perf;
|
struct sde_perf_cfg *perf;
|
||||||
u32 fps_index = 0, lut_index, creq_index, ds_index, frame_rate, qos_count;
|
u32 fps_index = 0, lut_index, creq_index, ds_index, frame_rate, qos_count;
|
||||||
|
enum sde_wb_usage_type usage_type;
|
||||||
|
|
||||||
if (!phys_enc || !phys_enc->sde_kms || !phys_enc->sde_kms->catalog) {
|
if (!phys_enc || !phys_enc->sde_kms || !phys_enc->sde_kms->catalog) {
|
||||||
SDE_ERROR("invalid parameter(s)\n");
|
SDE_ERROR("invalid parameter(s)\n");
|
||||||
@@ -168,6 +183,9 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conn_state = phys_enc->connector->state;
|
||||||
|
usage_type = sde_connector_get_property(conn_state, CONNECTOR_PROP_WB_USAGE_TYPE);
|
||||||
|
|
||||||
perf = &phys_enc->sde_kms->catalog->perf;
|
perf = &phys_enc->sde_kms->catalog->perf;
|
||||||
frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
|
frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
|
||||||
|
|
||||||
@@ -182,13 +200,13 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
|
|||||||
|
|
||||||
qos_cfg.danger_safe_en = true;
|
qos_cfg.danger_safe_en = true;
|
||||||
|
|
||||||
if (phys_enc->in_clone_mode && (SDE_FORMAT_IS_TILE(wb_enc->wb_fmt) ||
|
if (phys_enc->in_clone_mode)
|
||||||
SDE_FORMAT_IS_UBWC(wb_enc->wb_fmt)))
|
lut_index = (SDE_FORMAT_IS_TILE(wb_enc->wb_fmt)
|
||||||
lut_index = SDE_QOS_LUT_USAGE_CWB_TILE;
|
|| SDE_FORMAT_IS_UBWC(wb_enc->wb_fmt)) ?
|
||||||
else if (phys_enc->in_clone_mode)
|
SDE_QOS_LUT_USAGE_CWB_TILE : SDE_QOS_LUT_USAGE_CWB;
|
||||||
lut_index = SDE_QOS_LUT_USAGE_CWB;
|
|
||||||
else
|
else
|
||||||
lut_index = SDE_QOS_LUT_USAGE_NRT;
|
lut_index = (usage_type == WB_USAGE_OFFLINE_WB) ?
|
||||||
|
SDE_QOS_LUT_USAGE_OFFLINE_WB : SDE_QOS_LUT_USAGE_NRT;
|
||||||
|
|
||||||
creq_index = lut_index * SDE_CREQ_LUT_TYPE_MAX;
|
creq_index = lut_index * SDE_CREQ_LUT_TYPE_MAX;
|
||||||
creq_index += (fps_index * SDE_QOS_LUT_USAGE_MAX * SDE_CREQ_LUT_TYPE_MAX);
|
creq_index += (fps_index * SDE_QOS_LUT_USAGE_MAX * SDE_CREQ_LUT_TYPE_MAX);
|
||||||
@@ -199,9 +217,9 @@ static void sde_encoder_phys_wb_set_qos(struct sde_encoder_phys *phys_enc)
|
|||||||
qos_cfg.danger_lut = perf->danger_lut[ds_index];
|
qos_cfg.danger_lut = perf->danger_lut[ds_index];
|
||||||
qos_cfg.safe_lut = (u32) perf->safe_lut[ds_index];
|
qos_cfg.safe_lut = (u32) perf->safe_lut[ds_index];
|
||||||
|
|
||||||
SDE_DEBUG("[enc:%d wb:%d] fps:%d mode:%d luts[0x%x,0x%x 0x%llx]\n",
|
SDE_DEBUG("[enc:%d wb:%d] fps:%d mode:%d type:%d luts[0x%x,0x%x 0x%llx]\n",
|
||||||
DRMID(phys_enc->parent), WBID(wb_enc), frame_rate, phys_enc->in_clone_mode,
|
DRMID(phys_enc->parent), WBID(wb_enc), frame_rate, phys_enc->in_clone_mode,
|
||||||
qos_cfg.danger_lut, qos_cfg.safe_lut, qos_cfg.creq_lut);
|
usage_type, qos_cfg.danger_lut, qos_cfg.safe_lut, qos_cfg.creq_lut);
|
||||||
|
|
||||||
if (hw_wb->ops.setup_qos_lut)
|
if (hw_wb->ops.setup_qos_lut)
|
||||||
hw_wb->ops.setup_qos_lut(hw_wb, &qos_cfg);
|
hw_wb->ops.setup_qos_lut(hw_wb, &qos_cfg);
|
||||||
|
@@ -502,6 +502,7 @@ enum {
|
|||||||
VBIF_QOS_CWB_REMAP,
|
VBIF_QOS_CWB_REMAP,
|
||||||
VBIF_QOS_LUTDMA_REMAP,
|
VBIF_QOS_LUTDMA_REMAP,
|
||||||
VBIF_QOS_CNOC_REMAP,
|
VBIF_QOS_CNOC_REMAP,
|
||||||
|
VBIF_QOS_OFFLINE_WB_REMAP,
|
||||||
VBIF_PROP_MAX,
|
VBIF_PROP_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -943,6 +944,8 @@ static struct sde_prop_type vbif_prop[] = {
|
|||||||
{VBIF_QOS_CWB_REMAP, "qcom,sde-vbif-qos-cwb-remap", false, PROP_TYPE_U32_ARRAY},
|
{VBIF_QOS_CWB_REMAP, "qcom,sde-vbif-qos-cwb-remap", false, PROP_TYPE_U32_ARRAY},
|
||||||
{VBIF_QOS_LUTDMA_REMAP, "qcom,sde-vbif-qos-lutdma-remap", false, PROP_TYPE_U32_ARRAY},
|
{VBIF_QOS_LUTDMA_REMAP, "qcom,sde-vbif-qos-lutdma-remap", false, PROP_TYPE_U32_ARRAY},
|
||||||
{VBIF_QOS_CNOC_REMAP, "qcom,sde-vbif-qos-cnoc-remap", false, PROP_TYPE_U32_ARRAY},
|
{VBIF_QOS_CNOC_REMAP, "qcom,sde-vbif-qos-cnoc-remap", false, PROP_TYPE_U32_ARRAY},
|
||||||
|
{VBIF_QOS_OFFLINE_WB_REMAP, "qcom,sde-vbif-qos-offline-wb-remap", false,
|
||||||
|
PROP_TYPE_U32_ARRAY},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sde_prop_type uidle_prop[] = {
|
static struct sde_prop_type uidle_prop[] = {
|
||||||
@@ -3863,6 +3866,11 @@ static int sde_vbif_parse_dt(struct device_node *np,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
rc = _validate_dt_entry(np, &vbif_prop[VBIF_QOS_OFFLINE_WB_REMAP], 1,
|
||||||
|
&prop_count[VBIF_QOS_OFFLINE_WB_REMAP], NULL);
|
||||||
|
if (rc)
|
||||||
|
goto end;
|
||||||
|
|
||||||
sde_cfg->vbif_count = off_count;
|
sde_cfg->vbif_count = off_count;
|
||||||
|
|
||||||
rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count,
|
rc = _read_dt_entry(np, vbif_prop, ARRAY_SIZE(vbif_prop), prop_count,
|
||||||
|
@@ -850,6 +850,7 @@ enum sde_qos_lut_usage {
|
|||||||
SDE_QOS_LUT_USAGE_CWB_TILE,
|
SDE_QOS_LUT_USAGE_CWB_TILE,
|
||||||
SDE_QOS_LUT_USAGE_INLINE,
|
SDE_QOS_LUT_USAGE_INLINE,
|
||||||
SDE_QOS_LUT_USAGE_INLINE_RESTRICTED_FMTS,
|
SDE_QOS_LUT_USAGE_INLINE_RESTRICTED_FMTS,
|
||||||
|
SDE_QOS_LUT_USAGE_OFFLINE_WB,
|
||||||
SDE_QOS_LUT_USAGE_MAX,
|
SDE_QOS_LUT_USAGE_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1509,6 +1510,7 @@ struct sde_vbif_qos_tbl {
|
|||||||
* @VBIF_CWB_CLIENT: concurrent writeback client
|
* @VBIF_CWB_CLIENT: concurrent writeback client
|
||||||
* @VBIF_LUTDMA_CLIENT: LUTDMA client
|
* @VBIF_LUTDMA_CLIENT: LUTDMA client
|
||||||
* @VBIF_CNOC_CLIENT: HW fence client
|
* @VBIF_CNOC_CLIENT: HW fence client
|
||||||
|
* @VBIF_OFFLINE_WB_CLIENT: Offline WB client used in 2-pass composition
|
||||||
* @VBIF_MAX_CLIENT: max number of clients
|
* @VBIF_MAX_CLIENT: max number of clients
|
||||||
*/
|
*/
|
||||||
enum sde_vbif_client_type {
|
enum sde_vbif_client_type {
|
||||||
@@ -1517,6 +1519,7 @@ enum sde_vbif_client_type {
|
|||||||
VBIF_CWB_CLIENT,
|
VBIF_CWB_CLIENT,
|
||||||
VBIF_LUTDMA_CLIENT,
|
VBIF_LUTDMA_CLIENT,
|
||||||
VBIF_CNOC_CLIENT,
|
VBIF_CNOC_CLIENT,
|
||||||
|
VBIF_OFFLINE_WB_CLIENT,
|
||||||
VBIF_MAX_CLIENT
|
VBIF_MAX_CLIENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -500,6 +500,18 @@ enum sde_sys_cache_state {
|
|||||||
CACHE_STATE_FRAME_READ
|
CACHE_STATE_FRAME_READ
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum sde_wb_usage_type: Type of usage of the WB connector
|
||||||
|
* WB_USAGE_WFD: WB connector used for WFD
|
||||||
|
* WB_USAGE_CWB: WB connector used for concurrent writeback
|
||||||
|
* WB_USAGE_OFFLINE_WB: WB connector used for 2-pass composition
|
||||||
|
*/
|
||||||
|
enum sde_wb_usage_type {
|
||||||
|
WB_USAGE_WFD,
|
||||||
|
WB_USAGE_CWB,
|
||||||
|
WB_USAGE_OFFLINE_WB,
|
||||||
|
};
|
||||||
|
|
||||||
/** struct sde_format - defines the format configuration which
|
/** struct sde_format - defines the format configuration which
|
||||||
* allows SDE HW to correctly fetch and decode the format
|
* allows SDE HW to correctly fetch and decode the format
|
||||||
* @base: base msm_format struture containing fourcc code
|
* @base: base msm_format struture containing fourcc code
|
||||||
|
@@ -78,18 +78,6 @@ enum sde_plane_qos {
|
|||||||
SDE_PLANE_QOS_PANIC_CTRL = BIT(2),
|
SDE_PLANE_QOS_PANIC_CTRL = BIT(2),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* struct sde_plane - local sde plane structure
|
|
||||||
* @aspace: address space pointer
|
|
||||||
* @csc_cfg: Decoded user configuration for csc
|
|
||||||
* @csc_usr_ptr: Points to csc_cfg if valid user config available
|
|
||||||
* @csc_ptr: Points to sde_csc_cfg structure to use for current
|
|
||||||
* @mplane_list: List of multirect planes of the same pipe
|
|
||||||
* @catalog: Points to sde catalog structure
|
|
||||||
* @revalidate: force revalidation of all the plane properties
|
|
||||||
* @xin_halt_forced_clk: whether or not clocks were forced on for xin halt
|
|
||||||
* @blob_rot_caps: Pointer to rotator capability blob
|
|
||||||
*/
|
|
||||||
struct sde_plane {
|
struct sde_plane {
|
||||||
struct drm_plane base;
|
struct drm_plane base;
|
||||||
|
|
||||||
@@ -108,6 +96,7 @@ struct sde_plane {
|
|||||||
uint32_t color_fill;
|
uint32_t color_fill;
|
||||||
bool is_error;
|
bool is_error;
|
||||||
bool is_rt_pipe;
|
bool is_rt_pipe;
|
||||||
|
enum sde_wb_usage_type wb_usage_type;
|
||||||
bool is_virtual;
|
bool is_virtual;
|
||||||
struct list_head mplane_list;
|
struct list_head mplane_list;
|
||||||
struct sde_mdss_cfg *catalog;
|
struct sde_mdss_cfg *catalog;
|
||||||
@@ -305,7 +294,8 @@ static void _sde_plane_set_qos_lut(struct drm_plane *plane,
|
|||||||
else
|
else
|
||||||
lut_index = SDE_QOS_LUT_USAGE_MACROTILE;
|
lut_index = SDE_QOS_LUT_USAGE_MACROTILE;
|
||||||
} else {
|
} else {
|
||||||
lut_index = SDE_QOS_LUT_USAGE_NRT;
|
lut_index = (psde->wb_usage_type == WB_USAGE_OFFLINE_WB) ?
|
||||||
|
SDE_QOS_LUT_USAGE_OFFLINE_WB : SDE_QOS_LUT_USAGE_NRT;
|
||||||
}
|
}
|
||||||
|
|
||||||
creq_lut_index = lut_index * SDE_CREQ_LUT_TYPE_MAX;
|
creq_lut_index = lut_index * SDE_CREQ_LUT_TYPE_MAX;
|
||||||
@@ -325,11 +315,12 @@ static void _sde_plane_set_qos_lut(struct drm_plane *plane,
|
|||||||
(fmt) ? fmt->fetch_mode : 0, psde->pipe_qos_cfg.danger_lut,
|
(fmt) ? fmt->fetch_mode : 0, psde->pipe_qos_cfg.danger_lut,
|
||||||
psde->pipe_qos_cfg.safe_lut, psde->pipe_qos_cfg.creq_lut);
|
psde->pipe_qos_cfg.safe_lut, psde->pipe_qos_cfg.creq_lut);
|
||||||
|
|
||||||
SDE_DEBUG("plane%u: pnum:%d fmt:%4.4s fps:%d mode:%d luts[0x%x,0x%x 0x%llx]\n",
|
SDE_DEBUG("plane%u: pnum:%d fmt:%4.4s fps:%d mode:%d lut[0x%x,0x%x 0x%llx] rt:%d type:%d\n",
|
||||||
plane->base.id, psde->pipe - SSPP_VIG0,
|
plane->base.id, psde->pipe - SSPP_VIG0,
|
||||||
fmt ? (char *)&fmt->base.pixel_format : NULL, frame_rate,
|
fmt ? (char *)&fmt->base.pixel_format : NULL, frame_rate,
|
||||||
fmt ? fmt->fetch_mode : -1, psde->pipe_qos_cfg.danger_lut,
|
fmt ? fmt->fetch_mode : -1, psde->pipe_qos_cfg.danger_lut,
|
||||||
psde->pipe_qos_cfg.safe_lut, psde->pipe_qos_cfg.creq_lut);
|
psde->pipe_qos_cfg.safe_lut, psde->pipe_qos_cfg.creq_lut,
|
||||||
|
psde->is_rt_pipe, psde->wb_usage_type);
|
||||||
|
|
||||||
psde->pipe_hw->ops.setup_qos_lut(psde->pipe_hw, &psde->pipe_qos_cfg);
|
psde->pipe_hw->ops.setup_qos_lut(psde->pipe_hw, &psde->pipe_qos_cfg);
|
||||||
}
|
}
|
||||||
@@ -472,7 +463,8 @@ static void _sde_plane_set_ot_limit(struct drm_plane *plane,
|
|||||||
ot_params.num = psde->pipe_hw->idx - SSPP_NONE;
|
ot_params.num = psde->pipe_hw->idx - SSPP_NONE;
|
||||||
ot_params.width = psde->pipe_cfg.src_rect.w;
|
ot_params.width = psde->pipe_cfg.src_rect.w;
|
||||||
ot_params.height = psde->pipe_cfg.src_rect.h;
|
ot_params.height = psde->pipe_cfg.src_rect.h;
|
||||||
ot_params.is_wfd = !psde->is_rt_pipe;
|
ot_params.is_wfd = ((psde->is_rt_pipe)
|
||||||
|
|| (psde->wb_usage_type == WB_USAGE_OFFLINE_WB)) ? false : true;
|
||||||
ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
|
ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
|
||||||
ot_params.vbif_idx = VBIF_RT;
|
ot_params.vbif_idx = VBIF_RT;
|
||||||
ot_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
|
ot_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
|
||||||
@@ -515,8 +507,11 @@ static void _sde_plane_set_qos_remap(struct drm_plane *plane)
|
|||||||
qos_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
|
qos_params.clk_ctrl = psde->pipe_hw->cap->clk_ctrl;
|
||||||
qos_params.xin_id = psde->pipe_hw->cap->xin_id;
|
qos_params.xin_id = psde->pipe_hw->cap->xin_id;
|
||||||
qos_params.num = psde->pipe_hw->idx - SSPP_VIG0;
|
qos_params.num = psde->pipe_hw->idx - SSPP_VIG0;
|
||||||
qos_params.client_type = psde->is_rt_pipe ?
|
if (psde->is_rt_pipe)
|
||||||
VBIF_RT_CLIENT : VBIF_NRT_CLIENT;
|
qos_params.client_type = VBIF_RT_CLIENT;
|
||||||
|
else
|
||||||
|
qos_params.client_type = (psde->wb_usage_type == WB_USAGE_OFFLINE_WB) ?
|
||||||
|
VBIF_OFFLINE_WB_CLIENT : VBIF_NRT_CLIENT;
|
||||||
|
|
||||||
SDE_DEBUG("plane%d pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
|
SDE_DEBUG("plane%d pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
|
||||||
plane->base.id, qos_params.num,
|
plane->base.id, qos_params.num,
|
||||||
@@ -3331,6 +3326,7 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane,
|
|||||||
is_rt = sde_crtc_is_rt_client(crtc, crtc->state);
|
is_rt = sde_crtc_is_rt_client(crtc, crtc->state);
|
||||||
if (is_rt != psde->is_rt_pipe || crtc->state->mode_changed) {
|
if (is_rt != psde->is_rt_pipe || crtc->state->mode_changed) {
|
||||||
psde->is_rt_pipe = is_rt;
|
psde->is_rt_pipe = is_rt;
|
||||||
|
psde->wb_usage_type = psde->is_rt_pipe ? 0 : sde_crtc_get_wb_usage_type(crtc);
|
||||||
pstate->dirty |= SDE_PLANE_DIRTY_QOS;
|
pstate->dirty |= SDE_PLANE_DIRTY_QOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -602,6 +603,12 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
|
|||||||
{CACHE_STATE_ENABLED, "cache_state_enabled"},
|
{CACHE_STATE_ENABLED, "cache_state_enabled"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct drm_prop_enum_list e_wb_usage_type[] = {
|
||||||
|
{WB_USAGE_WFD, "wb_usage_wfd"},
|
||||||
|
{WB_USAGE_CWB, "wb_usage_cwb"},
|
||||||
|
{WB_USAGE_OFFLINE_WB, "wb_usage_offline_wb"},
|
||||||
|
};
|
||||||
|
|
||||||
if (!connector || !display || !wb_dev->wb_cfg || !wb_dev->drm_dev->dev_private) {
|
if (!connector || !display || !wb_dev->wb_cfg || !wb_dev->drm_dev->dev_private) {
|
||||||
SDE_ERROR("invalid params\n");
|
SDE_ERROR("invalid params\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -654,8 +661,11 @@ int sde_wb_connector_post_init(struct drm_connector *connector, void *display)
|
|||||||
msm_property_install_range(&c_conn->property_info, "dnsc_blur",
|
msm_property_install_range(&c_conn->property_info, "dnsc_blur",
|
||||||
0x0, 0, ~0, 0, CONNECTOR_PROP_DNSC_BLUR);
|
0x0, 0, ~0, 0, CONNECTOR_PROP_DNSC_BLUR);
|
||||||
|
|
||||||
_sde_wb_connector_install_dither_property(wb_dev);
|
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);
|
||||||
|
|
||||||
|
_sde_wb_connector_install_dither_property(wb_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user