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"},
|
||||
};
|
||||
|
||||
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[] = {
|
||||
{IDLE_PC_NONE, "idle_pc_none"},
|
||||
{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,
|
||||
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,
|
||||
"capture_mode", 0, 0, e_cwb_data_points,
|
||||
ARRAY_SIZE(e_cwb_data_points), 0,
|
||||
|
@@ -56,10 +56,12 @@ enum sde_crtc_client_type {
|
||||
* enum sde_crtc_output_capture_point
|
||||
* @MIXER_OUT : capture mixer output
|
||||
* @DSPP_OUT : capture output of dspp
|
||||
* @CAPTURE_DEMURA_OUT : capture output of demura
|
||||
*/
|
||||
enum sde_crtc_output_capture_point {
|
||||
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;
|
||||
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, };
|
||||
|
||||
for (i = 0; i < crtc->num_mixers; i++)
|
||||
intf_cfg.cwb[intf_cfg.cwb_count++] =
|
||||
(enum sde_cwb)(hw_pp->idx + i);
|
||||
intf_cfg.cwb[intf_cfg.cwb_count++] = (enum sde_cwb)
|
||||
(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 <
|
||||
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) ?
|
||||
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);
|
||||
|
||||
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) {
|
||||
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_pp->idx - PINGPONG_0,
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -593,13 +600,14 @@ static void _sde_enc_phys_wb_detect_cwb(struct sde_encoder_phys *phys_enc,
|
||||
u32 encoder_mask = 0;
|
||||
|
||||
/* 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 &= ~drm_encoder_mask(phys_enc->parent);
|
||||
}
|
||||
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,
|
||||
@@ -863,6 +871,7 @@ static void _sde_encoder_phys_wb_update_cwb_flush(
|
||||
int i = 0;
|
||||
int cwb_capture_mode = 0;
|
||||
enum sde_cwb cwb_idx = 0;
|
||||
enum sde_dcwb dcwb_idx = 0;
|
||||
enum sde_cwb src_pp_idx = 0;
|
||||
bool dspp_out = 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);
|
||||
need_merge = (crtc->num_mixers > 1) ? true : false;
|
||||
|
||||
if (src_pp_idx > CWB_0 || ((cwb_idx + crtc->num_mixers) > CWB_MAX)) {
|
||||
SDE_ERROR("invalid hw config for CWB\n");
|
||||
return;
|
||||
if (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||
dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
|
||||
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)
|
||||
@@ -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_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++) {
|
||||
cwb_idx = (enum sde_cwb) (hw_pp->idx + i);
|
||||
src_pp_idx = (enum sde_cwb) (src_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 (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
|
||||
dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
|
||||
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)
|
||||
hw_ctl->ops.update_bitmask(hw_ctl,
|
||||
} else if (test_bit(SDE_WB_CWB_CTRL, &hw_wb->caps->features)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_merge && hw_ctl->ops.update_bitmask
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// 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__
|
||||
@@ -306,6 +306,7 @@ enum {
|
||||
enum {
|
||||
PP_OFF,
|
||||
PP_LEN,
|
||||
PP_CWB,
|
||||
TE_OFF,
|
||||
TE_LEN,
|
||||
TE2_OFF,
|
||||
@@ -782,6 +783,7 @@ static struct sde_prop_type ds_prop[] = {
|
||||
static struct sde_prop_type pp_prop[] = {
|
||||
{PP_OFF, "qcom,sde-pp-off", true, PROP_TYPE_U32_ARRAY},
|
||||
{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_LEN, "qcom,sde-te-size", false, PROP_TYPE_U32},
|
||||
{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))
|
||||
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);
|
||||
if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
|
||||
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))
|
||||
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)) {
|
||||
sblk->dsc.base = PROP_VALUE_ACCESS(prop_value,
|
||||
DSC_OFF, i);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
@@ -401,6 +401,7 @@ enum {
|
||||
* @SDE_PINGPONG_DITHER, Dither blocks
|
||||
* @SDE_PINGPONG_DITHER_LUMA, Dither sub-blocks and features
|
||||
* @SDE_PINGPONG_MERGE_3D, Separate MERGE_3D block exists
|
||||
* @SDE_PINGPONG_CWB, PP block supports CWB
|
||||
* @SDE_PINGPONG_MAX
|
||||
*/
|
||||
enum {
|
||||
@@ -412,6 +413,7 @@ enum {
|
||||
SDE_PINGPONG_DITHER,
|
||||
SDE_PINGPONG_DITHER_LUMA,
|
||||
SDE_PINGPONG_MERGE_3D,
|
||||
SDE_PINGPONG_CWB,
|
||||
SDE_PINGPONG_MAX
|
||||
};
|
||||
|
||||
@@ -508,7 +510,9 @@ enum {
|
||||
* @SDE_WB_INPUT_CTRL Writeback supports from which pp block input pixel
|
||||
* data arrives.
|
||||
* @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_DCWB_CTRL Separate DCWB control is available for configuring
|
||||
* @SDE_WB_MAX maximum value
|
||||
*/
|
||||
enum {
|
||||
@@ -529,7 +533,9 @@ enum {
|
||||
SDE_WB_CDP,
|
||||
SDE_WB_INPUT_CTRL,
|
||||
SDE_WB_HAS_CWB,
|
||||
SDE_WB_HAS_DCWB,
|
||||
SDE_WB_CWB_CTRL,
|
||||
SDE_WB_DCWB_CTRL,
|
||||
SDE_WB_MAX
|
||||
};
|
||||
|
||||
@@ -1400,6 +1406,7 @@ struct sde_perf_cfg {
|
||||
* @has_cdp Client driven prefetch feature status
|
||||
* @has_wb_ubwc UBWC feature supported on WB
|
||||
* @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_stride offset between each CWB blk
|
||||
* @ubwc_version UBWC feature version (0x0 for not supported)
|
||||
@@ -1481,6 +1488,7 @@ struct sde_mdss_cfg {
|
||||
bool has_dim_layer;
|
||||
bool has_wb_ubwc;
|
||||
bool has_cwb_support;
|
||||
bool has_dedicated_cwb_support;
|
||||
u32 cwb_blk_off;
|
||||
u32 cwb_blk_stride;
|
||||
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,
|
||||
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
|
||||
*/
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
@@ -223,6 +223,8 @@ enum sde_pingpong {
|
||||
PINGPONG_3,
|
||||
PINGPONG_4,
|
||||
PINGPONG_5,
|
||||
PINGPONG_CWB_0,
|
||||
PINGPONG_CWB_1,
|
||||
PINGPONG_S0,
|
||||
PINGPONG_MAX
|
||||
};
|
||||
@@ -302,6 +304,12 @@ enum sde_cwb {
|
||||
CWB_MAX
|
||||
};
|
||||
|
||||
enum sde_dcwb {
|
||||
DCWB_0 = 0x1,
|
||||
DCWB_1,
|
||||
DCWB_MAX
|
||||
};
|
||||
|
||||
enum sde_wd_timer {
|
||||
WD_TIMER_0 = 0x1,
|
||||
WD_TIMER_1,
|
||||
@@ -335,6 +343,7 @@ enum sde_merge_3d {
|
||||
MERGE_3D_0 = 1,
|
||||
MERGE_3D_1,
|
||||
MERGE_3D_2,
|
||||
MERGE_3D_CWB_0,
|
||||
MERGE_3D_MAX
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// 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"
|
||||
@@ -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,
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
const enum sde_cwb cur_idx, const enum sde_cwb data_src,
|
||||
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))
|
||||
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 = {
|
||||
@@ -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))
|
||||
_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;
|
||||
|
||||
blk_init_error:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
@@ -114,6 +114,16 @@ struct sde_hw_wb_ops {
|
||||
bool enable,
|
||||
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
|
||||
* @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,
|
||||
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
|
||||
* @hw_mdp: MDP top level hardware block
|
||||
* @cwb_hw: CWB control hwio details
|
||||
* @dcwb_hw: DCWB control hwio details
|
||||
*/
|
||||
struct sde_hw_wb {
|
||||
struct sde_hw_blk base;
|
||||
@@ -153,6 +175,7 @@ struct sde_hw_wb {
|
||||
|
||||
struct sde_hw_mdp *hw_mdp;
|
||||
struct sde_hw_blk_reg_map cwb_hw;
|
||||
struct sde_hw_blk_reg_map dcwb_hw;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user