diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 1482a3bbff..6fcd7973b1 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -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, diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 47bb0b2038..db6c578c30 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -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 }; /** diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 4542852acd..c0f1b54c1f 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -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 diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 51f666e1dd..2ccb72fcc4 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -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); diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 14c9bcfbac..21e97ed6e0 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -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; diff --git a/msm/sde/sde_hw_ctl.c b/msm/sde/sde_hw_ctl.c index 74a1029dff..25b541ebe3 100644 --- a/msm/sde/sde_hw_ctl.c +++ b/msm/sde/sde_hw_ctl.c @@ -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 */ diff --git a/msm/sde/sde_hw_mdss.h b/msm/sde/sde_hw_mdss.h index 6d38d29396..0a1260c051 100644 --- a/msm/sde/sde_hw_mdss.h +++ b/msm/sde/sde_hw_mdss.h @@ -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 }; diff --git a/msm/sde/sde_hw_wb.c b/msm/sde/sde_hw_wb.c index 441fa80c35..8a8b65a5e2 100644 --- a/msm/sde/sde_hw_wb.c +++ b/msm/sde/sde_hw_wb.c @@ -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: diff --git a/msm/sde/sde_hw_wb.h b/msm/sde/sde_hw_wb.h index a6c95cc5eb..34485fb3f3 100644 --- a/msm/sde/sde_hw_wb.h +++ b/msm/sde/sde_hw_wb.h @@ -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; }; /**