Commit 0f3801d6 authored by Jessica Zhang's avatar Jessica Zhang Committed by Dmitry Baryshkov
Browse files

drm/msm/dpu: Support CWB in dpu_hw_ctl



The CWB mux has a pending flush bit and *_active register.

Add support for configuring them within the dpu_hw_ctl layer.

Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarAbhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: default avatarJessica Zhang <quic_jesszhan@quicinc.com>
Patchwork: https://patchwork.freedesktop.org/patch/637492/
Link: https://lore.kernel.org/r/20250214-concurrent-wb-v6-9-a44c293cf422@quicinc.com


Signed-off-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
parent dd331404
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -2274,6 +2274,7 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
	intf_cfg.stream_sel = 0; /* Don't care value for video mode */
	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
	intf_cfg.cwb = dpu_enc->cwb_mask;

	if (phys_enc->hw_intf)
		intf_cfg.intf = phys_enc->hw_intf->idx;
@@ -2296,6 +2297,7 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
{
	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
	struct dpu_hw_cwb *hw_cwb;
	struct dpu_hw_ctl *hw_ctl;
	struct dpu_hw_cwb_setup_cfg cwb_cfg;

	struct dpu_kms *dpu_kms;
@@ -2306,6 +2308,14 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
	if (!phys_enc->hw_wb)
		return;

	hw_ctl = phys_enc->hw_ctl;

	if (!phys_enc->hw_ctl) {
		DPU_DEBUG("[wb:%d] no ctl assigned\n",
			  phys_enc->hw_wb->idx - WB_0);
		return;
	}

	dpu_kms = phys_enc->dpu_kms;
	global_state = dpu_kms_get_existing_global_state(dpu_kms);
	num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
@@ -2338,6 +2348,9 @@ void dpu_encoder_helper_phys_setup_cwb(struct dpu_encoder_phys *phys_enc,
		}

		hw_cwb->ops.config_cwb(hw_cwb, &cwb_cfg);

		if (hw_ctl->ops.update_pending_flush_cwb)
			hw_ctl->ops.update_pending_flush_cwb(hw_ctl, hw_cwb->idx);
	}
}

+1 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)

		intf_cfg.intf = DPU_NONE;
		intf_cfg.wb = hw_wb->idx;
		intf_cfg.cwb = dpu_encoder_helper_get_cwb_mask(phys_enc);

		if (mode_3d && hw_pp && hw_pp->merge_3d)
			intf_cfg.merge_3d = hw_pp->merge_3d->idx;
+29 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/delay.h>
@@ -31,12 +31,14 @@
#define   CTL_MERGE_3D_ACTIVE           0x0E4
#define   CTL_DSC_ACTIVE                0x0E8
#define   CTL_WB_ACTIVE                 0x0EC
#define   CTL_CWB_ACTIVE                0x0F0
#define   CTL_INTF_ACTIVE               0x0F4
#define   CTL_CDM_ACTIVE                0x0F8
#define   CTL_FETCH_PIPE_ACTIVE         0x0FC
#define   CTL_MERGE_3D_FLUSH            0x100
#define   CTL_DSC_FLUSH                0x104
#define   CTL_WB_FLUSH                  0x108
#define   CTL_CWB_FLUSH                 0x10C
#define   CTL_INTF_FLUSH                0x110
#define   CTL_CDM_FLUSH                0x114
#define   CTL_PERIPH_FLUSH              0x128
@@ -53,6 +55,7 @@
#define  PERIPH_IDX     30
#define  INTF_IDX       31
#define WB_IDX          16
#define CWB_IDX         28
#define  DSPP_IDX       29  /* From DPU hw rev 7.x.x */
#define CTL_INVALID_BIT                 0xffff
#define CTL_DEFAULT_GROUP_ID		0xf
@@ -110,6 +113,7 @@ static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
	ctx->pending_flush_mask = 0x0;
	ctx->pending_intf_flush_mask = 0;
	ctx->pending_wb_flush_mask = 0;
	ctx->pending_cwb_flush_mask = 0;
	ctx->pending_merge_3d_flush_mask = 0;
	ctx->pending_dsc_flush_mask = 0;
	ctx->pending_cdm_flush_mask = 0;
@@ -144,6 +148,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
	if (ctx->pending_flush_mask & BIT(WB_IDX))
		DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
				ctx->pending_wb_flush_mask);
	if (ctx->pending_flush_mask & BIT(CWB_IDX))
		DPU_REG_WRITE(&ctx->hw, CTL_CWB_FLUSH,
				ctx->pending_cwb_flush_mask);

	if (ctx->pending_flush_mask & BIT(DSPP_IDX))
		for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
@@ -310,6 +317,13 @@ static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
	ctx->pending_flush_mask |= BIT(WB_IDX);
}

static void dpu_hw_ctl_update_pending_flush_cwb_v1(struct dpu_hw_ctl *ctx,
		enum dpu_cwb cwb)
{
	ctx->pending_cwb_flush_mask |= BIT(cwb - CWB_0);
	ctx->pending_flush_mask |= BIT(CWB_IDX);
}

static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
		enum dpu_intf intf)
{
@@ -547,6 +561,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
	u32 intf_active = 0;
	u32 dsc_active = 0;
	u32 wb_active = 0;
	u32 cwb_active = 0;
	u32 mode_sel = 0;

	/* CTL_TOP[31:28] carries group_id to collate CTL paths
@@ -561,6 +576,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,

	intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
	wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
	cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);
	dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);

	if (cfg->intf)
@@ -569,12 +585,16 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
	if (cfg->wb)
		wb_active |= BIT(cfg->wb - WB_0);

	if (cfg->cwb)
		cwb_active |= cfg->cwb;

	if (cfg->dsc)
		dsc_active |= cfg->dsc;

	DPU_REG_WRITE(c, CTL_TOP, mode_sel);
	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
	DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
	DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);
	DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);

	if (cfg->merge_3d)
@@ -624,6 +644,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
	struct dpu_hw_blk_reg_map *c = &ctx->hw;
	u32 intf_active = 0;
	u32 wb_active = 0;
	u32 cwb_active = 0;
	u32 merge3d_active = 0;
	u32 dsc_active;
	u32 cdm_active;
@@ -651,6 +672,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
		DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
	}

	if (cfg->cwb) {
		cwb_active = DPU_REG_READ(c, CTL_CWB_ACTIVE);
		cwb_active &= ~cfg->cwb;
		DPU_REG_WRITE(c, CTL_CWB_ACTIVE, cwb_active);
	}

	if (cfg->wb) {
		wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
		wb_active &= ~BIT(cfg->wb - WB_0);
@@ -703,6 +730,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
		ops->update_pending_flush_merge_3d =
			dpu_hw_ctl_update_pending_flush_merge_3d_v1;
		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
		ops->update_pending_flush_cwb = dpu_hw_ctl_update_pending_flush_cwb_v1;
		ops->update_pending_flush_dsc =
			dpu_hw_ctl_update_pending_flush_dsc_v1;
		ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1;
+14 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#ifndef _DPU_HW_CTL_H
@@ -42,6 +42,7 @@ struct dpu_hw_stage_cfg {
 * @cdm:                   CDM block used
 * @stream_sel:            Stream selection for multi-stream interfaces
 * @dsc:                   DSC BIT masks used
 * @cwb:                   CWB BIT masks used
 */
struct dpu_hw_intf_cfg {
	enum dpu_intf intf;
@@ -51,6 +52,7 @@ struct dpu_hw_intf_cfg {
	enum dpu_ctl_mode_sel intf_mode_sel;
	enum dpu_cdm cdm;
	int stream_sel;
	unsigned int cwb;
	unsigned int dsc;
};

@@ -114,6 +116,15 @@ struct dpu_hw_ctl_ops {
	void (*update_pending_flush_wb)(struct dpu_hw_ctl *ctx,
		enum dpu_wb blk);

	/**
	 * OR in the given flushbits to the cached pending_(cwb_)flush_mask
	 * No effect on hardware
	 * @ctx       : ctl path ctx pointer
	 * @blk       : concurrent writeback block index
	 */
	void (*update_pending_flush_cwb)(struct dpu_hw_ctl *ctx,
		enum dpu_cwb blk);

	/**
	 * OR in the given flushbits to the cached pending_(intf_)flush_mask
	 * No effect on hardware
@@ -258,6 +269,7 @@ struct dpu_hw_ctl_ops {
 * @pending_flush_mask: storage for pending ctl_flush managed via ops
 * @pending_intf_flush_mask: pending INTF flush
 * @pending_wb_flush_mask: pending WB flush
 * @pending_cwb_flush_mask: pending CWB flush
 * @pending_dsc_flush_mask: pending DSC flush
 * @pending_cdm_flush_mask: pending CDM flush
 * @ops: operation list
@@ -274,6 +286,7 @@ struct dpu_hw_ctl {
	u32 pending_flush_mask;
	u32 pending_intf_flush_mask;
	u32 pending_wb_flush_mask;
	u32 pending_cwb_flush_mask;
	u32 pending_periph_flush_mask;
	u32 pending_merge_3d_flush_mask;
	u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];