diff mbox series

[10/21] drm/msm/dpu: add CWB support to dpu_hw_wb

Message ID 20240829-concurrent-wb-v1-10-502b16ae2ebb@quicinc.com
State New
Headers show
Series drm/msm/dpu: Add Concurrent Writeback Support for DPU 10.x+ | expand

Commit Message

Jessica Zhang Aug. 29, 2024, 8:48 p.m. UTC
From: Esha Bharadwaj <quic_ebharadw@quicinc.com>

Add function ops to allow hw_wb to configure CWB registers and adjust
the WB_MUX configuration to account for using dedicated CWB pingpong
blocks.

Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 69 ++++++++++++++++++++++++++++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 34 +++++++++++++++
 2 files changed, 102 insertions(+), 1 deletion(-)

Comments

Dmitry Baryshkov Aug. 30, 2024, 5:41 p.m. UTC | #1
On Thu, Aug 29, 2024 at 01:48:31PM GMT, Jessica Zhang wrote:
> From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
> 
> Add function ops to allow hw_wb to configure CWB registers and adjust
> the WB_MUX configuration to account for using dedicated CWB pingpong
> blocks.
> 
> Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 69 ++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 34 +++++++++++++++
>  2 files changed, 102 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> index 93ff01c889b5..998c9fbd22a6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
> @@ -51,6 +51,12 @@
>  #define WB_CDP_CNTL                           0x2B4
>  #define WB_OUT_IMAGE_SIZE                     0x2C0
>  #define WB_OUT_XY                             0x2C4

Empty line

> +#define CWB_MUX                               0x000
> +#define CWB_MODE                              0x004
> +
> +/* CWB mux block bit definitions */
> +#define CWB_MUX_MASK                          GENMASK(3, 0)
> +#define CWB_MODE_MASK                         GENMASK(2, 0)
>  
>  static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx,
>  		struct dpu_hw_wb_cfg *data)
> @@ -173,7 +179,9 @@ static void dpu_hw_wb_bind_pingpong_blk(
>  	mux_cfg = DPU_REG_READ(c, WB_MUX);
>  	mux_cfg &= ~0xf;
>  
> -	if (pp)
> +	if (pp >= PINGPONG_CWB_0)
> +		mux_cfg |= (pp < PINGPONG_CWB_2) ? 0xd : 0xb;
> +	else if (pp)
>  		mux_cfg |= (pp - PINGPONG_0) & 0x7;
>  	else
>  		mux_cfg |= 0xf;
> @@ -237,3 +245,62 @@ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
>  
>  	return c;
>  }
> +
> +static void dpu_hw_cwb_setup_input_ctrl(struct dpu_hw_wb *ctx,
> +				enum dpu_cwb cwb_idx,
> +				const enum dpu_pingpong pp)

Align to opening bracket, please.

> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	int cwb_mux_cfg = 0xF;
> +
> +	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX)
> +		return;
> +
> +	c = &ctx->cwb_hw[cwb_idx - CWB_0];
> +
> +	/*
> +	 * The CWB_MUX register takes the pingpong index relative to
> +	 * PINGPONG_CWB_0 and not PINGPONG_0
> +	 */
> +	if ((pp != PINGPONG_NONE) && (pp < PINGPONG_MAX))
> +		cwb_mux_cfg = FIELD_PREP(CWB_MUX_MASK, pp - PINGPONG_CWB_0);
> +
> +	DPU_REG_WRITE(c, CWB_MUX, cwb_mux_cfg);
> +}
> +
> +static void dpu_hw_cwb_setup_input_mode(struct dpu_hw_wb *ctx,
> +				enum dpu_cwb cwb_idx,
> +				const enum cwb_mode_input input)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	int cwb_mux_cfg;
> +
> +	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX || input >= INPUT_MODE_MAX)
> +		return;
> +
> +	c = &ctx->cwb_hw[cwb_idx - CWB_0];
> +	cwb_mux_cfg = FIELD_PREP(CWB_MODE_MASK, input);
> +
> +	DPU_REG_WRITE(c, CWB_MODE, cwb_mux_cfg);
> +}
> +
> +static void _setup_cwb_ops(struct dpu_hw_wb_ops *ops)
> +{
> +	ops->setup_input_ctrl = dpu_hw_cwb_setup_input_ctrl;
> +	ops->setup_input_mode = dpu_hw_cwb_setup_input_mode;
> +}
> +
> +struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
> +				 const struct dpu_wb_cfg *cfg,
> +				 void __iomem *addr,
> +				 const struct dpu_mdss_version *mdss_rev,
> +				 struct dpu_hw_blk_reg_map *cwb_hw)
> +{
> +	struct dpu_hw_wb *c = dpu_hw_wb_init(dev, cfg, addr, mdss_rev);
> +
> +	c->cwb_hw = cwb_hw;
> +
> +	_setup_cwb_ops(&c->ops);
> +
> +	return c;
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
> index 37497473e16c..1ff40f8325e5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
> @@ -21,6 +21,12 @@ struct dpu_hw_wb_cfg {
>  	struct drm_rect crop;
>  };
>  
> +enum cwb_mode_input {
> +	INPUT_MODE_LM_OUT,
> +	INPUT_MODE_DSPP_OUT,
> +	INPUT_MODE_MAX
> +};
> +
>  /**
>   *
>   * struct dpu_hw_wb_ops : Interface to the wb hw driver functions
> @@ -31,6 +37,8 @@ struct dpu_hw_wb_cfg {
>   *  @setup_cdp:       setup chroma down prefetch block for writeback block
>   *  @setup_clk_force_ctrl: setup clock force control
>   *  @bind_pingpong_blk: enable/disable the connection with ping-pong block
> + *  @setup_ctrl: setup ctrl register for cwb
> + *  @setup_mode: setup mode register for cwb
>   */
>  struct dpu_hw_wb_ops {
>  	void (*setup_outaddress)(struct dpu_hw_wb *ctx,
> @@ -54,11 +62,20 @@ struct dpu_hw_wb_ops {
>  
>  	void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx,
>  				  const enum dpu_pingpong pp);
> +
> +	void (*setup_input_ctrl)(struct dpu_hw_wb *ctx,
> +				 enum dpu_cwb cwb_idx,
> +				 const enum dpu_pingpong pp);
> +
> +	void (*setup_input_mode)(struct dpu_hw_wb *ctx,
> +				 enum dpu_cwb cwb_idx,
> +				 const enum cwb_mode_input input);

Judging by the usage, could you please add single setup_cwb() callback
and let WB code call corresponding functions internally.

>  };
>  
>  /**
>   * struct dpu_hw_wb : WB driver object
>   * @hw: block hardware details
> + * @cwb_hw: block hardware details of cwb_muxes
>   * @idx: hardware index number within type
>   * @wb_hw_caps: hardware capabilities
>   * @ops: function pointers
> @@ -66,6 +83,9 @@ struct dpu_hw_wb_ops {
>  struct dpu_hw_wb {
>  	struct dpu_hw_blk_reg_map hw;
>  
> +	/* cwb data */
> +	struct dpu_hw_blk_reg_map *cwb_hw;
> +
>  	/* wb path */
>  	int idx;
>  	const struct dpu_wb_cfg *caps;
> @@ -87,4 +107,18 @@ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
>  				 void __iomem *addr,
>  				 const struct dpu_mdss_version *mdss_rev);
>  
> +/**
> + * dpu_hw_wb_init_with_cwb() - Initializes the writeback hw driver object with cwb.
> + * @dev:  Corresponding device for devres management
> + * @cfg:  wb_path catalog entry for which driver object is required
> + * @addr: mapped register io address of MDP
> + * @hw: array of cwb muxes
> + * Return: Error code or allocated dpu_hw_wb context
> + */

Please move the comment to the function body. This way make W=1 will
check that it is valid.

> +struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
> +					const struct dpu_wb_cfg *cfg,
> +					void __iomem *addr,
> +					const struct dpu_mdss_version *mdss_rev,
> +					struct dpu_hw_blk_reg_map *hw);
> +
>  #endif /*_DPU_HW_WB_H */
> 
> -- 
> 2.34.1
>
Jessica Zhang Sept. 3, 2024, 10:22 p.m. UTC | #2
On 8/30/2024 10:41 AM, Dmitry Baryshkov wrote:
> On Thu, Aug 29, 2024 at 01:48:31PM GMT, Jessica Zhang wrote:
>> From: Esha Bharadwaj <quic_ebharadw@quicinc.com>
>>
>> Add function ops to allow hw_wb to configure CWB registers and adjust
>> the WB_MUX configuration to account for using dedicated CWB pingpong
>> blocks.
>>
>> Signed-off-by: Esha Bharadwaj <quic_ebharadw@quicinc.com>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 69 ++++++++++++++++++++++++++++++-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 34 +++++++++++++++
>>   2 files changed, 102 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>> index 93ff01c889b5..998c9fbd22a6 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
>> @@ -51,6 +51,12 @@
>>   #define WB_CDP_CNTL                           0x2B4
>>   #define WB_OUT_IMAGE_SIZE                     0x2C0
>>   #define WB_OUT_XY                             0x2C4
> 
> Empty line
> 
>> +#define CWB_MUX                               0x000
>> +#define CWB_MODE                              0x004
>> +
>> +/* CWB mux block bit definitions */
>> +#define CWB_MUX_MASK                          GENMASK(3, 0)
>> +#define CWB_MODE_MASK                         GENMASK(2, 0)
>>   
>>   static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx,
>>   		struct dpu_hw_wb_cfg *data)
>> @@ -173,7 +179,9 @@ static void dpu_hw_wb_bind_pingpong_blk(
>>   	mux_cfg = DPU_REG_READ(c, WB_MUX);
>>   	mux_cfg &= ~0xf;
>>   
>> -	if (pp)
>> +	if (pp >= PINGPONG_CWB_0)
>> +		mux_cfg |= (pp < PINGPONG_CWB_2) ? 0xd : 0xb;
>> +	else if (pp)
>>   		mux_cfg |= (pp - PINGPONG_0) & 0x7;
>>   	else
>>   		mux_cfg |= 0xf;
>> @@ -237,3 +245,62 @@ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
>>   
>>   	return c;
>>   }
>> +
>> +static void dpu_hw_cwb_setup_input_ctrl(struct dpu_hw_wb *ctx,
>> +				enum dpu_cwb cwb_idx,
>> +				const enum dpu_pingpong pp)
> 
> Align to opening bracket, please.

Hi Dmitry,

Acked for all comments here -- I'll squash the 2 cwb ops together.

Thanks,

Jessica Zhang

> 
>> +{
>> +	struct dpu_hw_blk_reg_map *c;
>> +	int cwb_mux_cfg = 0xF;
>> +
>> +	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX)
>> +		return;
>> +
>> +	c = &ctx->cwb_hw[cwb_idx - CWB_0];
>> +
>> +	/*
>> +	 * The CWB_MUX register takes the pingpong index relative to
>> +	 * PINGPONG_CWB_0 and not PINGPONG_0
>> +	 */
>> +	if ((pp != PINGPONG_NONE) && (pp < PINGPONG_MAX))
>> +		cwb_mux_cfg = FIELD_PREP(CWB_MUX_MASK, pp - PINGPONG_CWB_0);
>> +
>> +	DPU_REG_WRITE(c, CWB_MUX, cwb_mux_cfg);
>> +}
>> +
>> +static void dpu_hw_cwb_setup_input_mode(struct dpu_hw_wb *ctx,
>> +				enum dpu_cwb cwb_idx,
>> +				const enum cwb_mode_input input)
>> +{
>> +	struct dpu_hw_blk_reg_map *c;
>> +	int cwb_mux_cfg;
>> +
>> +	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX || input >= INPUT_MODE_MAX)
>> +		return;
>> +
>> +	c = &ctx->cwb_hw[cwb_idx - CWB_0];
>> +	cwb_mux_cfg = FIELD_PREP(CWB_MODE_MASK, input);
>> +
>> +	DPU_REG_WRITE(c, CWB_MODE, cwb_mux_cfg);
>> +}
>> +
>> +static void _setup_cwb_ops(struct dpu_hw_wb_ops *ops)
>> +{
>> +	ops->setup_input_ctrl = dpu_hw_cwb_setup_input_ctrl;
>> +	ops->setup_input_mode = dpu_hw_cwb_setup_input_mode;
>> +}
>> +
>> +struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
>> +				 const struct dpu_wb_cfg *cfg,
>> +				 void __iomem *addr,
>> +				 const struct dpu_mdss_version *mdss_rev,
>> +				 struct dpu_hw_blk_reg_map *cwb_hw)
>> +{
>> +	struct dpu_hw_wb *c = dpu_hw_wb_init(dev, cfg, addr, mdss_rev);
>> +
>> +	c->cwb_hw = cwb_hw;
>> +
>> +	_setup_cwb_ops(&c->ops);
>> +
>> +	return c;
>> +}
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
>> index 37497473e16c..1ff40f8325e5 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
>> @@ -21,6 +21,12 @@ struct dpu_hw_wb_cfg {
>>   	struct drm_rect crop;
>>   };
>>   
>> +enum cwb_mode_input {
>> +	INPUT_MODE_LM_OUT,
>> +	INPUT_MODE_DSPP_OUT,
>> +	INPUT_MODE_MAX
>> +};
>> +
>>   /**
>>    *
>>    * struct dpu_hw_wb_ops : Interface to the wb hw driver functions
>> @@ -31,6 +37,8 @@ struct dpu_hw_wb_cfg {
>>    *  @setup_cdp:       setup chroma down prefetch block for writeback block
>>    *  @setup_clk_force_ctrl: setup clock force control
>>    *  @bind_pingpong_blk: enable/disable the connection with ping-pong block
>> + *  @setup_ctrl: setup ctrl register for cwb
>> + *  @setup_mode: setup mode register for cwb
>>    */
>>   struct dpu_hw_wb_ops {
>>   	void (*setup_outaddress)(struct dpu_hw_wb *ctx,
>> @@ -54,11 +62,20 @@ struct dpu_hw_wb_ops {
>>   
>>   	void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx,
>>   				  const enum dpu_pingpong pp);
>> +
>> +	void (*setup_input_ctrl)(struct dpu_hw_wb *ctx,
>> +				 enum dpu_cwb cwb_idx,
>> +				 const enum dpu_pingpong pp);
>> +
>> +	void (*setup_input_mode)(struct dpu_hw_wb *ctx,
>> +				 enum dpu_cwb cwb_idx,
>> +				 const enum cwb_mode_input input);
> 
> Judging by the usage, could you please add single setup_cwb() callback
> and let WB code call corresponding functions internally.
> 
>>   };
>>   
>>   /**
>>    * struct dpu_hw_wb : WB driver object
>>    * @hw: block hardware details
>> + * @cwb_hw: block hardware details of cwb_muxes
>>    * @idx: hardware index number within type
>>    * @wb_hw_caps: hardware capabilities
>>    * @ops: function pointers
>> @@ -66,6 +83,9 @@ struct dpu_hw_wb_ops {
>>   struct dpu_hw_wb {
>>   	struct dpu_hw_blk_reg_map hw;
>>   
>> +	/* cwb data */
>> +	struct dpu_hw_blk_reg_map *cwb_hw;
>> +
>>   	/* wb path */
>>   	int idx;
>>   	const struct dpu_wb_cfg *caps;
>> @@ -87,4 +107,18 @@ struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
>>   				 void __iomem *addr,
>>   				 const struct dpu_mdss_version *mdss_rev);
>>   
>> +/**
>> + * dpu_hw_wb_init_with_cwb() - Initializes the writeback hw driver object with cwb.
>> + * @dev:  Corresponding device for devres management
>> + * @cfg:  wb_path catalog entry for which driver object is required
>> + * @addr: mapped register io address of MDP
>> + * @hw: array of cwb muxes
>> + * Return: Error code or allocated dpu_hw_wb context
>> + */
> 
> Please move the comment to the function body. This way make W=1 will
> check that it is valid.
> 
>> +struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
>> +					const struct dpu_wb_cfg *cfg,
>> +					void __iomem *addr,
>> +					const struct dpu_mdss_version *mdss_rev,
>> +					struct dpu_hw_blk_reg_map *hw);
>> +
>>   #endif /*_DPU_HW_WB_H */
>>
>> -- 
>> 2.34.1
>>
> 
> -- 
> With best wishes
> Dmitry
diff mbox series

Patch

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
index 93ff01c889b5..998c9fbd22a6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c
@@ -51,6 +51,12 @@ 
 #define WB_CDP_CNTL                           0x2B4
 #define WB_OUT_IMAGE_SIZE                     0x2C0
 #define WB_OUT_XY                             0x2C4
+#define CWB_MUX                               0x000
+#define CWB_MODE                              0x004
+
+/* CWB mux block bit definitions */
+#define CWB_MUX_MASK                          GENMASK(3, 0)
+#define CWB_MODE_MASK                         GENMASK(2, 0)
 
 static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx,
 		struct dpu_hw_wb_cfg *data)
@@ -173,7 +179,9 @@  static void dpu_hw_wb_bind_pingpong_blk(
 	mux_cfg = DPU_REG_READ(c, WB_MUX);
 	mux_cfg &= ~0xf;
 
-	if (pp)
+	if (pp >= PINGPONG_CWB_0)
+		mux_cfg |= (pp < PINGPONG_CWB_2) ? 0xd : 0xb;
+	else if (pp)
 		mux_cfg |= (pp - PINGPONG_0) & 0x7;
 	else
 		mux_cfg |= 0xf;
@@ -237,3 +245,62 @@  struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
 
 	return c;
 }
+
+static void dpu_hw_cwb_setup_input_ctrl(struct dpu_hw_wb *ctx,
+				enum dpu_cwb cwb_idx,
+				const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int cwb_mux_cfg = 0xF;
+
+	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX)
+		return;
+
+	c = &ctx->cwb_hw[cwb_idx - CWB_0];
+
+	/*
+	 * The CWB_MUX register takes the pingpong index relative to
+	 * PINGPONG_CWB_0 and not PINGPONG_0
+	 */
+	if ((pp != PINGPONG_NONE) && (pp < PINGPONG_MAX))
+		cwb_mux_cfg = FIELD_PREP(CWB_MUX_MASK, pp - PINGPONG_CWB_0);
+
+	DPU_REG_WRITE(c, CWB_MUX, cwb_mux_cfg);
+}
+
+static void dpu_hw_cwb_setup_input_mode(struct dpu_hw_wb *ctx,
+				enum dpu_cwb cwb_idx,
+				const enum cwb_mode_input input)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int cwb_mux_cfg;
+
+	if (cwb_idx < CWB_0 || cwb_idx >= CWB_MAX || input >= INPUT_MODE_MAX)
+		return;
+
+	c = &ctx->cwb_hw[cwb_idx - CWB_0];
+	cwb_mux_cfg = FIELD_PREP(CWB_MODE_MASK, input);
+
+	DPU_REG_WRITE(c, CWB_MODE, cwb_mux_cfg);
+}
+
+static void _setup_cwb_ops(struct dpu_hw_wb_ops *ops)
+{
+	ops->setup_input_ctrl = dpu_hw_cwb_setup_input_ctrl;
+	ops->setup_input_mode = dpu_hw_cwb_setup_input_mode;
+}
+
+struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
+				 const struct dpu_wb_cfg *cfg,
+				 void __iomem *addr,
+				 const struct dpu_mdss_version *mdss_rev,
+				 struct dpu_hw_blk_reg_map *cwb_hw)
+{
+	struct dpu_hw_wb *c = dpu_hw_wb_init(dev, cfg, addr, mdss_rev);
+
+	c->cwb_hw = cwb_hw;
+
+	_setup_cwb_ops(&c->ops);
+
+	return c;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
index 37497473e16c..1ff40f8325e5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h
@@ -21,6 +21,12 @@  struct dpu_hw_wb_cfg {
 	struct drm_rect crop;
 };
 
+enum cwb_mode_input {
+	INPUT_MODE_LM_OUT,
+	INPUT_MODE_DSPP_OUT,
+	INPUT_MODE_MAX
+};
+
 /**
  *
  * struct dpu_hw_wb_ops : Interface to the wb hw driver functions
@@ -31,6 +37,8 @@  struct dpu_hw_wb_cfg {
  *  @setup_cdp:       setup chroma down prefetch block for writeback block
  *  @setup_clk_force_ctrl: setup clock force control
  *  @bind_pingpong_blk: enable/disable the connection with ping-pong block
+ *  @setup_ctrl: setup ctrl register for cwb
+ *  @setup_mode: setup mode register for cwb
  */
 struct dpu_hw_wb_ops {
 	void (*setup_outaddress)(struct dpu_hw_wb *ctx,
@@ -54,11 +62,20 @@  struct dpu_hw_wb_ops {
 
 	void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx,
 				  const enum dpu_pingpong pp);
+
+	void (*setup_input_ctrl)(struct dpu_hw_wb *ctx,
+				 enum dpu_cwb cwb_idx,
+				 const enum dpu_pingpong pp);
+
+	void (*setup_input_mode)(struct dpu_hw_wb *ctx,
+				 enum dpu_cwb cwb_idx,
+				 const enum cwb_mode_input input);
 };
 
 /**
  * struct dpu_hw_wb : WB driver object
  * @hw: block hardware details
+ * @cwb_hw: block hardware details of cwb_muxes
  * @idx: hardware index number within type
  * @wb_hw_caps: hardware capabilities
  * @ops: function pointers
@@ -66,6 +83,9 @@  struct dpu_hw_wb_ops {
 struct dpu_hw_wb {
 	struct dpu_hw_blk_reg_map hw;
 
+	/* cwb data */
+	struct dpu_hw_blk_reg_map *cwb_hw;
+
 	/* wb path */
 	int idx;
 	const struct dpu_wb_cfg *caps;
@@ -87,4 +107,18 @@  struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
 				 void __iomem *addr,
 				 const struct dpu_mdss_version *mdss_rev);
 
+/**
+ * dpu_hw_wb_init_with_cwb() - Initializes the writeback hw driver object with cwb.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  wb_path catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ * @hw: array of cwb muxes
+ * Return: Error code or allocated dpu_hw_wb context
+ */
+struct dpu_hw_wb *dpu_hw_wb_init_with_cwb(struct drm_device *dev,
+					const struct dpu_wb_cfg *cfg,
+					void __iomem *addr,
+					const struct dpu_mdss_version *mdss_rev,
+					struct dpu_hw_blk_reg_map *hw);
+
 #endif /*_DPU_HW_WB_H */