sde: wb: add changes to support Dedicated-CWB
Add new capture/tap point as CRTC property for D-CWB feature. Update the hardware blocks and corresponding APIs to configure D-CWB data path. Add new hardware pingpong blocks that are dedicated for CWB. Change-Id: I22576df1768b50f9f47d8527f62913b01ff4d9a7 Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org>
This commit is contained in:
@@ -5454,6 +5454,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
|
|||||||
{CAPTURE_DSPP_OUT, "capture_pp_out"},
|
{CAPTURE_DSPP_OUT, "capture_pp_out"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct drm_prop_enum_list e_dcwb_data_points[] = {
|
||||||
|
{CAPTURE_MIXER_OUT, "capture_mixer_out"},
|
||||||
|
{CAPTURE_DSPP_OUT, "capture_pp_out"},
|
||||||
|
{CAPTURE_DEMURA_OUT, "capture_demura_out"},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct drm_prop_enum_list e_idle_pc_state[] = {
|
static const struct drm_prop_enum_list e_idle_pc_state[] = {
|
||||||
{IDLE_PC_NONE, "idle_pc_none"},
|
{IDLE_PC_NONE, "idle_pc_none"},
|
||||||
{IDLE_PC_ENABLE, "idle_pc_enable"},
|
{IDLE_PC_ENABLE, "idle_pc_enable"},
|
||||||
@@ -5524,7 +5530,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
|
|||||||
ARRAY_SIZE(e_idle_pc_state), 0,
|
ARRAY_SIZE(e_idle_pc_state), 0,
|
||||||
CRTC_PROP_IDLE_PC_STATE);
|
CRTC_PROP_IDLE_PC_STATE);
|
||||||
|
|
||||||
if (catalog->has_cwb_support)
|
if (catalog->has_dedicated_cwb_support)
|
||||||
|
msm_property_install_enum(&sde_crtc->property_info,
|
||||||
|
"capture_mode", 0, 0, e_dcwb_data_points,
|
||||||
|
ARRAY_SIZE(e_dcwb_data_points), 0,
|
||||||
|
CRTC_PROP_CAPTURE_OUTPUT);
|
||||||
|
else if (catalog->has_cwb_support)
|
||||||
msm_property_install_enum(&sde_crtc->property_info,
|
msm_property_install_enum(&sde_crtc->property_info,
|
||||||
"capture_mode", 0, 0, e_cwb_data_points,
|
"capture_mode", 0, 0, e_cwb_data_points,
|
||||||
ARRAY_SIZE(e_cwb_data_points), 0,
|
ARRAY_SIZE(e_cwb_data_points), 0,
|
||||||
|
@@ -56,10 +56,12 @@ enum sde_crtc_client_type {
|
|||||||
* enum sde_crtc_output_capture_point
|
* enum sde_crtc_output_capture_point
|
||||||
* @MIXER_OUT : capture mixer output
|
* @MIXER_OUT : capture mixer output
|
||||||
* @DSPP_OUT : capture output of dspp
|
* @DSPP_OUT : capture output of dspp
|
||||||
|
* @CAPTURE_DEMURA_OUT : capture output of demura
|
||||||
*/
|
*/
|
||||||
enum sde_crtc_output_capture_point {
|
enum sde_crtc_output_capture_point {
|
||||||
CAPTURE_MIXER_OUT,
|
CAPTURE_MIXER_OUT,
|
||||||
CAPTURE_DSPP_OUT
|
CAPTURE_DSPP_OUT,
|
||||||
|
CAPTURE_DEMURA_OUT
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -467,12 +467,14 @@ static void _sde_encoder_phys_wb_setup_cwb(struct sde_encoder_phys *phys_enc,
|
|||||||
|
|
||||||
hw_ctl = crtc->mixers[0].hw_ctl;
|
hw_ctl = crtc->mixers[0].hw_ctl;
|
||||||
if (hw_ctl && hw_ctl->ops.setup_intf_cfg_v1 &&
|
if (hw_ctl && hw_ctl->ops.setup_intf_cfg_v1 &&
|
||||||
test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features)) {
|
test_bit(SDE_WB_CWB_CTRL | SDE_WB_DCWB_CTRL,
|
||||||
|
&hw_wb->caps->features)) {
|
||||||
struct sde_hw_intf_cfg_v1 intf_cfg = { 0, };
|
struct sde_hw_intf_cfg_v1 intf_cfg = { 0, };
|
||||||
|
|
||||||
for (i = 0; i < crtc->num_mixers; i++)
|
for (i = 0; i < crtc->num_mixers; i++)
|
||||||
intf_cfg.cwb[intf_cfg.cwb_count++] =
|
intf_cfg.cwb[intf_cfg.cwb_count++] = (enum sde_cwb)
|
||||||
(enum sde_cwb)(hw_pp->idx + i);
|
(test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features) ?
|
||||||
|
((hw_pp->idx % 2) + i) : (hw_pp->idx + i));
|
||||||
|
|
||||||
if (hw_pp->merge_3d && (intf_cfg.merge_3d_count <
|
if (hw_pp->merge_3d && (intf_cfg.merge_3d_count <
|
||||||
MAX_MERGE_3D_PER_CTL_V1) && need_merge)
|
MAX_MERGE_3D_PER_CTL_V1) && need_merge)
|
||||||
@@ -483,12 +485,17 @@ static void _sde_encoder_phys_wb_setup_cwb(struct sde_encoder_phys *phys_enc,
|
|||||||
hw_pp->ops.setup_3d_mode(hw_pp, (enable && need_merge) ?
|
hw_pp->ops.setup_3d_mode(hw_pp, (enable && need_merge) ?
|
||||||
BLEND_3D_H_ROW_INT : 0);
|
BLEND_3D_H_ROW_INT : 0);
|
||||||
|
|
||||||
if (hw_wb->ops.bind_pingpong_blk)
|
if ((hw_wb->ops.bind_pingpong_blk) &&
|
||||||
|
test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features))
|
||||||
hw_wb->ops.bind_pingpong_blk(hw_wb, enable, hw_pp->idx);
|
hw_wb->ops.bind_pingpong_blk(hw_wb, enable, hw_pp->idx);
|
||||||
|
|
||||||
|
if ((hw_wb->ops.bind_dcwb_pp_blk) &&
|
||||||
|
test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features))
|
||||||
|
hw_wb->ops.bind_dcwb_pp_blk(hw_wb, enable, hw_pp->idx);
|
||||||
|
|
||||||
if (hw_ctl->ops.update_intf_cfg) {
|
if (hw_ctl->ops.update_intf_cfg) {
|
||||||
hw_ctl->ops.update_intf_cfg(hw_ctl, &intf_cfg, enable);
|
hw_ctl->ops.update_intf_cfg(hw_ctl, &intf_cfg, enable);
|
||||||
SDE_DEBUG("in CWB mode on CTL_%d PP-%d merge3d:%d\n",
|
SDE_DEBUG("in CWB/DCWB mode on CTL_%d PP-%d merge3d:%d\n",
|
||||||
hw_ctl->idx - CTL_0,
|
hw_ctl->idx - CTL_0,
|
||||||
hw_pp->idx - PINGPONG_0,
|
hw_pp->idx - PINGPONG_0,
|
||||||
hw_pp->merge_3d ?
|
hw_pp->merge_3d ?
|
||||||
@@ -503,7 +510,7 @@ static void _sde_encoder_phys_wb_setup_cwb(struct sde_encoder_phys *phys_enc,
|
|||||||
|
|
||||||
if (hw_ctl && hw_ctl->ops.update_wb_cfg) {
|
if (hw_ctl && hw_ctl->ops.update_wb_cfg) {
|
||||||
hw_ctl->ops.update_wb_cfg(hw_ctl, intf_cfg, enable);
|
hw_ctl->ops.update_wb_cfg(hw_ctl, intf_cfg, enable);
|
||||||
SDE_DEBUG("in CWB mode adding WB for CTL_%d\n",
|
SDE_DEBUG("in CWB/DCWB mode adding WB for CTL_%d\n",
|
||||||
hw_ctl->idx - CTL_0);
|
hw_ctl->idx - CTL_0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -593,13 +600,14 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc,
|
|||||||
u32 encoder_mask = 0;
|
u32 encoder_mask = 0;
|
||||||
|
|
||||||
/* Check if WB has CWB support */
|
/* Check if WB has CWB support */
|
||||||
if (wb_cfg->features & BIT(SDE_WB_HAS_CWB)) {
|
if ((wb_cfg->features & BIT(SDE_WB_HAS_CWB))
|
||||||
|
|| (wb_cfg->features & BIT(SDE_WB_HAS_DCWB))) {
|
||||||
encoder_mask = crtc_state->encoder_mask;
|
encoder_mask = crtc_state->encoder_mask;
|
||||||
encoder_mask &= ~drm_encoder_mask(phys_enc->parent);
|
encoder_mask &= ~drm_encoder_mask(phys_enc->parent);
|
||||||
}
|
}
|
||||||
phys_enc->in_clone_mode = encoder_mask ? true : false;
|
phys_enc->in_clone_mode = encoder_mask ? true : false;
|
||||||
|
|
||||||
SDE_DEBUG("detect CWB - status:%d\n", phys_enc->in_clone_mode);
|
SDE_DEBUG("detect CWB(OR)DCWB - status:%d\n", phys_enc->in_clone_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc,
|
static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc,
|
||||||
@@ -863,6 +871,7 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
int cwb_capture_mode = 0;
|
int cwb_capture_mode = 0;
|
||||||
enum sde_cwb cwb_idx = 0;
|
enum sde_cwb cwb_idx = 0;
|
||||||
|
enum sde_dcwb dcwb_idx = 0;
|
||||||
enum sde_cwb src_pp_idx = 0;
|
enum sde_cwb src_pp_idx = 0;
|
||||||
bool dspp_out = false;
|
bool dspp_out = false;
|
||||||
bool need_merge = false;
|
bool need_merge = false;
|
||||||
@@ -895,9 +904,19 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
|||||||
dspp_out = (cwb_capture_mode == CAPTURE_DSPP_OUT);
|
dspp_out = (cwb_capture_mode == CAPTURE_DSPP_OUT);
|
||||||
need_merge = (crtc->num_mixers > 1) ? true : false;
|
need_merge = (crtc->num_mixers > 1) ? true : false;
|
||||||
|
|
||||||
if (src_pp_idx > CWB_0 || ((cwb_idx + crtc->num_mixers) > CWB_MAX)) {
|
if (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||||
SDE_ERROR("invalid hw config for CWB\n");
|
dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
|
||||||
return;
|
if ((dcwb_idx + crtc->num_mixers) > DCWB_MAX) {
|
||||||
|
SDE_ERROR("invalid hw config for DCWB. dcwb_idx=%d, num_mixers=%d\n",
|
||||||
|
dcwb_idx, crtc->num_mixers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src_pp_idx > CWB_0 || ((cwb_idx + crtc->num_mixers) > CWB_MAX)) {
|
||||||
|
SDE_ERROR("invalid hw config for CWB. pp_idx-%d, cwb_idx=%d, num_mixers=%d\n",
|
||||||
|
src_pp_idx, dcwb_idx, crtc->num_mixers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hw_ctl->ops.update_bitmask)
|
if (hw_ctl->ops.update_bitmask)
|
||||||
@@ -908,18 +927,30 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
|||||||
hw_ctl->ops.update_bitmask(hw_ctl, SDE_HW_FLUSH_CDM,
|
hw_ctl->ops.update_bitmask(hw_ctl, SDE_HW_FLUSH_CDM,
|
||||||
hw_cdm->idx, 1);
|
hw_cdm->idx, 1);
|
||||||
|
|
||||||
if (test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features)) {
|
if (test_bit(SDE_WB_CWB_CTRL | SDE_WB_DCWB_CTRL,
|
||||||
|
&hw_wb->caps->features)) {
|
||||||
for (i = 0; i < crtc->num_mixers; i++) {
|
for (i = 0; i < crtc->num_mixers; i++) {
|
||||||
cwb_idx = (enum sde_cwb) (hw_pp->idx + i);
|
|
||||||
src_pp_idx = (enum sde_cwb) (src_pp_idx + i);
|
src_pp_idx = (enum sde_cwb) (src_pp_idx + i);
|
||||||
|
|
||||||
if (hw_wb->ops.program_cwb_ctrl)
|
if (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||||
hw_wb->ops.program_cwb_ctrl(hw_wb, cwb_idx,
|
dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
|
||||||
src_pp_idx, dspp_out, enable);
|
if (hw_wb->ops.program_dcwb_ctrl)
|
||||||
|
hw_wb->ops.program_dcwb_ctrl(hw_wb, dcwb_idx,
|
||||||
|
src_pp_idx, cwb_capture_mode,
|
||||||
|
enable);
|
||||||
|
if (hw_ctl->ops.update_bitmask)
|
||||||
|
hw_ctl->ops.update_bitmask(hw_ctl,
|
||||||
|
SDE_HW_FLUSH_CWB, dcwb_idx, 1);
|
||||||
|
|
||||||
if (hw_ctl->ops.update_bitmask)
|
} else if (test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features)) {
|
||||||
hw_ctl->ops.update_bitmask(hw_ctl,
|
cwb_idx = (enum sde_cwb) (hw_pp->idx + i);
|
||||||
|
if (hw_wb->ops.program_cwb_ctrl)
|
||||||
|
hw_wb->ops.program_cwb_ctrl(hw_wb, cwb_idx,
|
||||||
|
src_pp_idx, dspp_out, enable);
|
||||||
|
if (hw_ctl->ops.update_bitmask)
|
||||||
|
hw_ctl->ops.update_bitmask(hw_ctl,
|
||||||
SDE_HW_FLUSH_CWB, cwb_idx, 1);
|
SDE_HW_FLUSH_CWB, cwb_idx, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_merge && hw_ctl->ops.update_bitmask
|
if (need_merge && hw_ctl->ops.update_bitmask
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
|
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
|
||||||
@@ -306,6 +306,7 @@ enum {
|
|||||||
enum {
|
enum {
|
||||||
PP_OFF,
|
PP_OFF,
|
||||||
PP_LEN,
|
PP_LEN,
|
||||||
|
PP_CWB,
|
||||||
TE_OFF,
|
TE_OFF,
|
||||||
TE_LEN,
|
TE_LEN,
|
||||||
TE2_OFF,
|
TE2_OFF,
|
||||||
@@ -782,6 +783,7 @@ static struct sde_prop_type ds_prop[] = {
|
|||||||
static struct sde_prop_type pp_prop[] = {
|
static struct sde_prop_type pp_prop[] = {
|
||||||
{PP_OFF, "qcom,sde-pp-off", true, PROP_TYPE_U32_ARRAY},
|
{PP_OFF, "qcom,sde-pp-off", true, PROP_TYPE_U32_ARRAY},
|
||||||
{PP_LEN, "qcom,sde-pp-size", false, PROP_TYPE_U32},
|
{PP_LEN, "qcom,sde-pp-size", false, PROP_TYPE_U32},
|
||||||
|
{PP_CWB, "qcom,sde-pp-cwb", false, PROP_TYPE_U32_ARRAY},
|
||||||
{TE_OFF, "qcom,sde-te-off", false, PROP_TYPE_U32_ARRAY},
|
{TE_OFF, "qcom,sde-te-off", false, PROP_TYPE_U32_ARRAY},
|
||||||
{TE_LEN, "qcom,sde-te-size", false, PROP_TYPE_U32},
|
{TE_LEN, "qcom,sde-te-size", false, PROP_TYPE_U32},
|
||||||
{TE2_OFF, "qcom,sde-te2-off", false, PROP_TYPE_U32_ARRAY},
|
{TE2_OFF, "qcom,sde-te2-off", false, PROP_TYPE_U32_ARRAY},
|
||||||
@@ -2349,7 +2351,18 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
|
|||||||
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
||||||
set_bit(SDE_WB_INPUT_CTRL, &wb->features);
|
set_bit(SDE_WB_INPUT_CTRL, &wb->features);
|
||||||
|
|
||||||
if (sde_cfg->has_cwb_support) {
|
if (sde_cfg->has_dedicated_cwb_support) {
|
||||||
|
set_bit(SDE_WB_HAS_DCWB, &wb->features);
|
||||||
|
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
||||||
|
set_bit(SDE_WB_DCWB_CTRL, &wb->features);
|
||||||
|
if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_810)) {
|
||||||
|
sde_cfg->cwb_blk_off = 0x66A00;
|
||||||
|
sde_cfg->cwb_blk_stride = 0x400;
|
||||||
|
} else {
|
||||||
|
sde_cfg->cwb_blk_off = 0x83000;
|
||||||
|
sde_cfg->cwb_blk_stride = 0x100;
|
||||||
|
}
|
||||||
|
} else if (sde_cfg->has_cwb_support) {
|
||||||
set_bit(SDE_WB_HAS_CWB, &wb->features);
|
set_bit(SDE_WB_HAS_CWB, &wb->features);
|
||||||
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
||||||
set_bit(SDE_WB_CWB_CTRL, &wb->features);
|
set_bit(SDE_WB_CWB_CTRL, &wb->features);
|
||||||
@@ -3629,6 +3642,9 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
|
|||||||
if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i))
|
if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i))
|
||||||
set_bit(SDE_PINGPONG_SLAVE, &pp->features);
|
set_bit(SDE_PINGPONG_SLAVE, &pp->features);
|
||||||
|
|
||||||
|
if (PROP_VALUE_ACCESS(prop_value, PP_CWB, i))
|
||||||
|
set_bit(SDE_PINGPONG_CWB, &pp->features);
|
||||||
|
|
||||||
if (major_version < SDE_HW_MAJOR(SDE_HW_VER_700)) {
|
if (major_version < SDE_HW_MAJOR(SDE_HW_VER_700)) {
|
||||||
sblk->dsc.base = PROP_VALUE_ACCESS(prop_value,
|
sblk->dsc.base = PROP_VALUE_ACCESS(prop_value,
|
||||||
DSC_OFF, i);
|
DSC_OFF, i);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SDE_HW_CATALOG_H
|
#ifndef _SDE_HW_CATALOG_H
|
||||||
@@ -401,6 +401,7 @@ enum {
|
|||||||
* @SDE_PINGPONG_DITHER, Dither blocks
|
* @SDE_PINGPONG_DITHER, Dither blocks
|
||||||
* @SDE_PINGPONG_DITHER_LUMA, Dither sub-blocks and features
|
* @SDE_PINGPONG_DITHER_LUMA, Dither sub-blocks and features
|
||||||
* @SDE_PINGPONG_MERGE_3D, Separate MERGE_3D block exists
|
* @SDE_PINGPONG_MERGE_3D, Separate MERGE_3D block exists
|
||||||
|
* @SDE_PINGPONG_CWB, PP block supports CWB
|
||||||
* @SDE_PINGPONG_MAX
|
* @SDE_PINGPONG_MAX
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
@@ -412,6 +413,7 @@ enum {
|
|||||||
SDE_PINGPONG_DITHER,
|
SDE_PINGPONG_DITHER,
|
||||||
SDE_PINGPONG_DITHER_LUMA,
|
SDE_PINGPONG_DITHER_LUMA,
|
||||||
SDE_PINGPONG_MERGE_3D,
|
SDE_PINGPONG_MERGE_3D,
|
||||||
|
SDE_PINGPONG_CWB,
|
||||||
SDE_PINGPONG_MAX
|
SDE_PINGPONG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -508,7 +510,9 @@ enum {
|
|||||||
* @SDE_WB_INPUT_CTRL Writeback supports from which pp block input pixel
|
* @SDE_WB_INPUT_CTRL Writeback supports from which pp block input pixel
|
||||||
* data arrives.
|
* data arrives.
|
||||||
* @SDE_WB_HAS_CWB Writeback block supports concurrent writeback
|
* @SDE_WB_HAS_CWB Writeback block supports concurrent writeback
|
||||||
|
* @SDE_WB_HAS_DCWB Writeback block supports dedicated CWB
|
||||||
* @SDE_WB_CWB_CTRL Separate CWB control is available for configuring
|
* @SDE_WB_CWB_CTRL Separate CWB control is available for configuring
|
||||||
|
* @SDE_WB_DCWB_CTRL Separate DCWB control is available for configuring
|
||||||
* @SDE_WB_MAX maximum value
|
* @SDE_WB_MAX maximum value
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
@@ -529,7 +533,9 @@ enum {
|
|||||||
SDE_WB_CDP,
|
SDE_WB_CDP,
|
||||||
SDE_WB_INPUT_CTRL,
|
SDE_WB_INPUT_CTRL,
|
||||||
SDE_WB_HAS_CWB,
|
SDE_WB_HAS_CWB,
|
||||||
|
SDE_WB_HAS_DCWB,
|
||||||
SDE_WB_CWB_CTRL,
|
SDE_WB_CWB_CTRL,
|
||||||
|
SDE_WB_DCWB_CTRL,
|
||||||
SDE_WB_MAX
|
SDE_WB_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1400,6 +1406,7 @@ struct sde_perf_cfg {
|
|||||||
* @has_cdp Client driven prefetch feature status
|
* @has_cdp Client driven prefetch feature status
|
||||||
* @has_wb_ubwc UBWC feature supported on WB
|
* @has_wb_ubwc UBWC feature supported on WB
|
||||||
* @has_cwb_support indicates if device supports primary capture through CWB
|
* @has_cwb_support indicates if device supports primary capture through CWB
|
||||||
|
* @has_dedicated_cwb_support indicates if device supports dedicated path for CWB capture
|
||||||
* @cwb_blk_off CWB offset address
|
* @cwb_blk_off CWB offset address
|
||||||
* @cwb_blk_stride offset between each CWB blk
|
* @cwb_blk_stride offset between each CWB blk
|
||||||
* @ubwc_version UBWC feature version (0x0 for not supported)
|
* @ubwc_version UBWC feature version (0x0 for not supported)
|
||||||
@@ -1481,6 +1488,7 @@ struct sde_mdss_cfg {
|
|||||||
bool has_dim_layer;
|
bool has_dim_layer;
|
||||||
bool has_wb_ubwc;
|
bool has_wb_ubwc;
|
||||||
bool has_cwb_support;
|
bool has_cwb_support;
|
||||||
|
bool has_dedicated_cwb_support;
|
||||||
u32 cwb_blk_off;
|
u32 cwb_blk_off;
|
||||||
u32 cwb_blk_stride;
|
u32 cwb_blk_stride;
|
||||||
u32 ubwc_version;
|
u32 ubwc_version;
|
||||||
|
@@ -161,6 +161,11 @@ static const u32 cdm_flush_tbl[CDM_MAX] = {SDE_NONE, 0};
|
|||||||
static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 1, 2, 3,
|
static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 1, 2, 3,
|
||||||
4, 5};
|
4, 5};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list of CWB bits in CTL_CWB_FLUSH for dedicated cwb
|
||||||
|
*/
|
||||||
|
static const u32 dcwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 0, 1};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list of DSPP sub-blk flush bits in CTL_DSPP_x_FLUSH
|
* list of DSPP sub-blk flush bits in CTL_DSPP_x_FLUSH
|
||||||
*/
|
*/
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SDE_HW_MDSS_H
|
#ifndef _SDE_HW_MDSS_H
|
||||||
@@ -223,6 +223,8 @@ enum sde_pingpong {
|
|||||||
PINGPONG_3,
|
PINGPONG_3,
|
||||||
PINGPONG_4,
|
PINGPONG_4,
|
||||||
PINGPONG_5,
|
PINGPONG_5,
|
||||||
|
PINGPONG_CWB_0,
|
||||||
|
PINGPONG_CWB_1,
|
||||||
PINGPONG_S0,
|
PINGPONG_S0,
|
||||||
PINGPONG_MAX
|
PINGPONG_MAX
|
||||||
};
|
};
|
||||||
@@ -302,6 +304,12 @@ enum sde_cwb {
|
|||||||
CWB_MAX
|
CWB_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum sde_dcwb {
|
||||||
|
DCWB_0 = 0x1,
|
||||||
|
DCWB_1,
|
||||||
|
DCWB_MAX
|
||||||
|
};
|
||||||
|
|
||||||
enum sde_wd_timer {
|
enum sde_wd_timer {
|
||||||
WD_TIMER_0 = 0x1,
|
WD_TIMER_0 = 0x1,
|
||||||
WD_TIMER_1,
|
WD_TIMER_1,
|
||||||
@@ -335,6 +343,7 @@ enum sde_merge_3d {
|
|||||||
MERGE_3D_0 = 1,
|
MERGE_3D_0 = 1,
|
||||||
MERGE_3D_1,
|
MERGE_3D_1,
|
||||||
MERGE_3D_2,
|
MERGE_3D_2,
|
||||||
|
MERGE_3D_CWB_0,
|
||||||
MERGE_3D_MAX
|
MERGE_3D_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sde_hw_mdss.h"
|
#include "sde_hw_mdss.h"
|
||||||
@@ -99,6 +99,31 @@ static void _sde_hw_cwb_ctrl_init(struct sde_mdss_cfg *m,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _sde_hw_dcwb_ctrl_init(struct sde_mdss_cfg *m,
|
||||||
|
void __iomem *addr, struct sde_hw_blk_reg_map *b)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 blk_off;
|
||||||
|
char name[64] = {0};
|
||||||
|
|
||||||
|
if (!b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
b->base_off = addr;
|
||||||
|
b->blk_off = m->cwb_blk_off;
|
||||||
|
b->length = 0x20;
|
||||||
|
b->hwversion = m->hwversion;
|
||||||
|
b->log_mask = SDE_DBG_MASK_WB;
|
||||||
|
|
||||||
|
for (i = 0; i < m->pingpong_count; i++) {
|
||||||
|
snprintf(name, sizeof(name), "dcwb%d", i);
|
||||||
|
blk_off = b->blk_off + (m->cwb_blk_stride * i);
|
||||||
|
|
||||||
|
sde_dbg_reg_register_dump_range(SDE_DBG_NAME, name,
|
||||||
|
blk_off, blk_off + b->length, 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void sde_hw_wb_setup_outaddress(struct sde_hw_wb *ctx,
|
static void sde_hw_wb_setup_outaddress(struct sde_hw_wb *ctx,
|
||||||
struct sde_hw_wb_cfg *data)
|
struct sde_hw_wb_cfg *data)
|
||||||
{
|
{
|
||||||
@@ -270,6 +295,46 @@ static void sde_hw_wb_bind_pingpong_blk(
|
|||||||
SDE_REG_WRITE(c, WB_MUX, mux_cfg);
|
SDE_REG_WRITE(c, WB_MUX, mux_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sde_hw_wb_bind_dcwb_pp_blk(
|
||||||
|
struct sde_hw_wb *ctx,
|
||||||
|
bool enable,
|
||||||
|
const enum sde_pingpong pp)
|
||||||
|
{
|
||||||
|
struct sde_hw_blk_reg_map *c;
|
||||||
|
int mux_cfg = 0xF;
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c = &ctx->hw;
|
||||||
|
if (enable)
|
||||||
|
mux_cfg = 0xd;
|
||||||
|
|
||||||
|
SDE_REG_WRITE(c, WB_MUX, mux_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sde_hw_wb_program_dcwb_ctrl(struct sde_hw_wb *ctx,
|
||||||
|
const enum sde_dcwb cur_idx, const enum sde_cwb data_src,
|
||||||
|
int tap_location, bool enable)
|
||||||
|
{
|
||||||
|
struct sde_hw_blk_reg_map *c;
|
||||||
|
u32 blk_base;
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c = &ctx->dcwb_hw;
|
||||||
|
blk_base = ctx->catalog->cwb_blk_stride * (cur_idx - DCWB_0);
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
SDE_REG_WRITE(c, blk_base + CWB_CTRL_SRC_SEL, data_src - CWB_0);
|
||||||
|
SDE_REG_WRITE(c, blk_base + CWB_CTRL_MODE, tap_location);
|
||||||
|
} else {
|
||||||
|
SDE_REG_WRITE(c, blk_base + CWB_CTRL_SRC_SEL, 0xf);
|
||||||
|
SDE_REG_WRITE(c, blk_base + CWB_CTRL_MODE, 0x0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void sde_hw_wb_program_cwb_ctrl(struct sde_hw_wb *ctx,
|
static void sde_hw_wb_program_cwb_ctrl(struct sde_hw_wb *ctx,
|
||||||
const enum sde_cwb cur_idx, const enum sde_cwb data_src,
|
const enum sde_cwb cur_idx, const enum sde_cwb data_src,
|
||||||
bool dspp_out, bool enable)
|
bool dspp_out, bool enable)
|
||||||
@@ -312,6 +377,11 @@ static void _setup_wb_ops(struct sde_hw_wb_ops *ops,
|
|||||||
|
|
||||||
if (test_bit(SDE_WB_CWB_CTRL, &features))
|
if (test_bit(SDE_WB_CWB_CTRL, &features))
|
||||||
ops->program_cwb_ctrl = sde_hw_wb_program_cwb_ctrl;
|
ops->program_cwb_ctrl = sde_hw_wb_program_cwb_ctrl;
|
||||||
|
|
||||||
|
if (test_bit(SDE_WB_DCWB_CTRL, &features)) {
|
||||||
|
ops->program_dcwb_ctrl = sde_hw_wb_program_dcwb_ctrl;
|
||||||
|
ops->bind_dcwb_pp_blk = sde_hw_wb_bind_dcwb_pp_blk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sde_hw_blk_ops sde_hw_ops = {
|
static struct sde_hw_blk_ops sde_hw_ops = {
|
||||||
@@ -362,6 +432,9 @@ struct sde_hw_wb *sde_hw_wb_init(enum sde_wb idx,
|
|||||||
if (test_bit(SDE_WB_CWB_CTRL, &cfg->features))
|
if (test_bit(SDE_WB_CWB_CTRL, &cfg->features))
|
||||||
_sde_hw_cwb_ctrl_init(m, addr, &c->cwb_hw);
|
_sde_hw_cwb_ctrl_init(m, addr, &c->cwb_hw);
|
||||||
|
|
||||||
|
if (test_bit(SDE_WB_DCWB_CTRL, &cfg->features))
|
||||||
|
_sde_hw_dcwb_ctrl_init(m, addr, &c->dcwb_hw);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
blk_init_error:
|
blk_init_error:
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SDE_HW_WB_H
|
#ifndef _SDE_HW_WB_H
|
||||||
@@ -114,6 +114,16 @@ struct sde_hw_wb_ops {
|
|||||||
bool enable,
|
bool enable,
|
||||||
const enum sde_pingpong pp);
|
const enum sde_pingpong pp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bind_dcwb_pp_blk - enable/disable the connection with cwb pp
|
||||||
|
* @ctx: Pointer to wb context
|
||||||
|
* @enable: enable/disable connection
|
||||||
|
* @pp: pingpong blk id
|
||||||
|
*/
|
||||||
|
void (*bind_dcwb_pp_blk)(struct sde_hw_wb *ctx,
|
||||||
|
bool enable,
|
||||||
|
const enum sde_pingpong pp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* program_cwb_ctrl - program cwb block configp
|
* program_cwb_ctrl - program cwb block configp
|
||||||
* @ctx: Pointer to wb context
|
* @ctx: Pointer to wb context
|
||||||
@@ -124,6 +134,17 @@ struct sde_hw_wb_ops {
|
|||||||
*/
|
*/
|
||||||
void (*program_cwb_ctrl)(struct sde_hw_wb *ctx, const enum sde_cwb cwb,
|
void (*program_cwb_ctrl)(struct sde_hw_wb *ctx, const enum sde_cwb cwb,
|
||||||
const enum sde_cwb data_src, bool dspp_out, bool enable);
|
const enum sde_cwb data_src, bool dspp_out, bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* program_dcwb_ctrl - program cwb block configp
|
||||||
|
* @ctx: Pointer to wb context
|
||||||
|
* @pp_idx: Current CWB block index to poram
|
||||||
|
* @data_src: Source CWB/PingPong block index
|
||||||
|
* @tap_location: Tap LM output, dspp output or Demura output
|
||||||
|
* @enable: enable or disable the CWB path to tap the output
|
||||||
|
*/
|
||||||
|
void (*program_dcwb_ctrl)(struct sde_hw_wb *ctx, const enum sde_dcwb cwb,
|
||||||
|
const enum sde_cwb data_src, int tap_location, bool enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,6 +158,7 @@ struct sde_hw_wb_ops {
|
|||||||
* @ops: function pointers
|
* @ops: function pointers
|
||||||
* @hw_mdp: MDP top level hardware block
|
* @hw_mdp: MDP top level hardware block
|
||||||
* @cwb_hw: CWB control hwio details
|
* @cwb_hw: CWB control hwio details
|
||||||
|
* @dcwb_hw: DCWB control hwio details
|
||||||
*/
|
*/
|
||||||
struct sde_hw_wb {
|
struct sde_hw_wb {
|
||||||
struct sde_hw_blk base;
|
struct sde_hw_blk base;
|
||||||
@@ -153,6 +175,7 @@ struct sde_hw_wb {
|
|||||||
|
|
||||||
struct sde_hw_mdp *hw_mdp;
|
struct sde_hw_mdp *hw_mdp;
|
||||||
struct sde_hw_blk_reg_map cwb_hw;
|
struct sde_hw_blk_reg_map cwb_hw;
|
||||||
|
struct sde_hw_blk_reg_map dcwb_hw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user