Re: [PATCH 12/12] drm/mediatek: Add support for multiple mmsys in the one mediatek-drm driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2025-02-12 at 09:30 +0000, CK Hu (胡俊光) wrote:
> Hi, Paul:
> 
> On Fri, 2025-01-10 at 20:34 +0800, paul-pl.chen wrote:
> > From: "Nancy.Lin" <nancy.lin@xxxxxxxxxxxx>
> > 
> > To support multiple mmsys instances in the one mediatek-drm
> > instance,
> > providing improved flexibility and scalability by the following
> > changes:
> > 
> > 1. Defined new DRM component IDs DDP_COMPONENT_DRM_OVLSYS_ADAPTOR*
> >   to support different mmsys composition.
> > 2. Added new component types MTK_DISP_VIRTUAL to support the
> >   routing to virtual display components.
> > 3. Added and adjusted the existed structure or interface to extend
> >   the support of multiple mmsys instances.
> > 4. Modified the component matching and binding logic to support
> >   multiple mmsys instances.
> 
> I think the title would confuse me.
> Original mediatek-drm driver already support multiple mmsys.
> I try to understand MT8196 display.
> Is one display pipeline separated into two mmsys?
> The first is ovlsys and the second is dispsys?
> If so, I would like mediatek-drm driver see only mmsys (dispsys),
> and let ovlsys control is hidden in ovlsys sub driver, so mediatek-
> drm driver would not change so much.
> 
> > 
> > Signed-off-by: Nancy.Lin <nancy.lin@xxxxxxxxxxxx>
> > Signed-off-by: Paul-pl.Chen <paul-pl.chen@xxxxxxxxxxxx>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_crtc.c     | 350 +++++++++++++++++++-
> > ----
> >  drivers/gpu/drm/mediatek/mtk_crtc.h     |   6 +-
> >  drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 106 +++++--
> >  drivers/gpu/drm/mediatek/mtk_ddp_comp.h |   2 +
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 223 ++++++++++++---
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  16 +-
> >  6 files changed, 578 insertions(+), 125 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c
> > b/drivers/gpu/drm/mediatek/mtk_crtc.c
> > index eb0e1233ad04..eca6941bfaa2 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_crtc.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c
> > @@ -58,13 +58,17 @@ struct mtk_crtc {
> >  	wait_queue_head_t		cb_blocking_queue;
> >  #endif
> >  
> > -	struct device			*mmsys_dev;
> > +	struct device			*mmsys_dev[MAX_MMSYS];
> >  	struct device			*dma_dev;
> > -	struct mtk_mutex		*mutex;
> > +	struct device			*vdisp_ao_dev;
> > +	struct mtk_mutex		*mutex[MAX_MMSYS];
> >  	unsigned int			ddp_comp_nr;
> >  	struct mtk_ddp_comp		**ddp_comp;
> > +	enum mtk_drm_mmsys		*ddp_comp_sys;
> > +	bool				exist[MAX_MMSYS];
> >  	unsigned int			num_conn_routes;
> >  	const struct mtk_drm_route	*conn_routes;
> > +	enum mtk_drm_mmsys		conn_routes_sys;
> >  
> >  	/* lock for display hardware access */
> >  	struct mutex			hw_lock;
> > @@ -82,6 +86,11 @@ struct mtk_crtc_state {
> >  	unsigned int			pending_vrefresh;
> >  };
> >  
> > +struct mtk_crtc_comp_info {
> > +	enum mtk_drm_mmsys sys;
> > +	unsigned int comp_id;
> > +};
> > +
> >  static inline struct mtk_crtc *to_mtk_crtc(struct drm_crtc *c)
> >  {
> >  	return container_of(c, struct mtk_crtc, base);
> > @@ -125,7 +134,9 @@ static void mtk_crtc_destroy(struct drm_crtc
> > *crtc)
> >  	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >  	int i;
> >  
> > -	mtk_mutex_put(mtk_crtc->mutex);
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->mutex[i])
> > +			mtk_mutex_put(mtk_crtc->mutex[i]);
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (mtk_crtc->cmdq_client.chan) {
> >  		cmdq_pkt_destroy(&mtk_crtc->cmdq_client,
> > &mtk_crtc->cmdq_handle);
> > @@ -223,7 +234,14 @@ static int mtk_crtc_ddp_clk_enable(struct
> > mtk_crtc *mtk_crtc)
> >  	int i;
> >  
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> > +		enum mtk_drm_mmsys mmsys;
> > +
> >  		ret = mtk_ddp_comp_clk_enable(mtk_crtc-
> > >ddp_comp[i]);
> > +		if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]-
> > >id) == MTK_DISP_VIRTUAL) {
> > +			mmsys = mtk_crtc->ddp_comp_sys[i];
> > +			ret = mtk_mmsys_ddp_clk_enable(mtk_crtc-
> > >mmsys_dev[mmsys],
> > +						       mtk_crtc-
> > >ddp_comp[i]->id);
> > +		}
> >  		if (ret) {
> >  			DRM_ERROR("Failed to enable clock %d:
> > %d\n", i, ret);
> >  			goto err;
> > @@ -232,17 +250,28 @@ static int mtk_crtc_ddp_clk_enable(struct
> > mtk_crtc *mtk_crtc)
> >  
> >  	return 0;
> >  err:
> > -	while (--i >= 0)
> > +	while (--i >= 0) {
> >  		mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
> > +		if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]-
> > >id) == MTK_DISP_VIRTUAL)
> > +			mtk_mmsys_ddp_clk_disable(mtk_crtc-
> > >mmsys_dev[mtk_crtc->ddp_comp_sys[i]],
> > +						  mtk_crtc-
> > >ddp_comp[i]->id);
> > +	}
> >  	return ret;
> >  }
> >  
> >  static void mtk_crtc_ddp_clk_disable(struct mtk_crtc *mtk_crtc)
> >  {
> >  	int i;
> > +	enum mtk_drm_mmsys mmsys;
> >  
> > -	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
> > +	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> >  		mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
> > +		if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]-
> > >id) == MTK_DISP_VIRTUAL) {
> > +			mmsys = mtk_crtc->ddp_comp_sys[i];
> > +			mtk_mmsys_ddp_clk_disable(mtk_crtc-
> > >mmsys_dev[mmsys],
> > +						  mtk_crtc-
> > >ddp_comp[i]->id);
> > +		}
> > +	}
> >  }
> >  
> >  static
> > @@ -332,7 +361,8 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc
> > *mtk_crtc)
> >  	struct drm_connector_list_iter conn_iter;
> >  	unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;
> >  	int ret;
> > -	int i;
> > +	int i, j;
> > +	enum mtk_drm_mmsys mmsys;
> >  
> >  	if (WARN_ON(!crtc->state))
> >  		return -EINVAL;
> > @@ -362,10 +392,18 @@ static int mtk_crtc_ddp_hw_init(struct
> > mtk_crtc *mtk_crtc)
> >  		return ret;
> >  	}
> >  
> > -	ret = mtk_mutex_prepare(mtk_crtc->mutex);
> > -	if (ret < 0) {
> > -		DRM_ERROR("Failed to enable mutex clock: %d\n",
> > ret);
> > -		goto err_pm_runtime_put;
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			mtk_mmsys_top_clk_enable(mtk_crtc-
> > >mmsys_dev[i]);
> > +
> > +	for (i = 0; i < MAX_MMSYS; i++) {
> > +		if (!mtk_crtc->mutex[i] || !mtk_crtc->exist[i])
> > +			continue;
> > +		ret = mtk_mutex_prepare(mtk_crtc->mutex[i]);
> > +		if (ret < 0) {
> > +			DRM_ERROR("Failed to enable mmsys%d mutex
> > clock: %d\n", i, ret);
> > +			goto err_pm_runtime_put;
> > +		}
> >  	}
> >  
> >  	ret = mtk_crtc_ddp_clk_enable(mtk_crtc);
> > @@ -374,19 +412,36 @@ static int mtk_crtc_ddp_hw_init(struct
> > mtk_crtc *mtk_crtc)
> >  		goto err_mutex_unprepare;
> >  	}
> >  
> > +	if (mtk_crtc->vdisp_ao_dev)
> > +		mtk_mmsys_default_config(mtk_crtc->vdisp_ao_dev);
> > +
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			mtk_mmsys_default_config(mtk_crtc-
> > >mmsys_dev[i]);
> > +
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
> > -		if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mmsys_dev,
> > +		mmsys = mtk_crtc->ddp_comp_sys[i];
> > +		if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mmsys_dev[mmsys],
> >  					  mtk_crtc->ddp_comp[i +
> > 1]->id))
> > -			mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
> > +			mtk_mmsys_ddp_connect(mtk_crtc-
> > >mmsys_dev[mmsys],
> >  					      mtk_crtc-
> > >ddp_comp[i]->id,
> >  					      mtk_crtc->ddp_comp[i
> > + 1]->id);
> > -		if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mutex))
> > -			mtk_mutex_add_comp(mtk_crtc->mutex,
> > +		if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mutex[mmsys]))
> > +			mtk_mutex_add_comp(mtk_crtc->mutex[mmsys],
> >  					   mtk_crtc->ddp_comp[i]-
> > >id);
> >  	}
> > -	if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc-
> > >mutex))
> > -		mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc-
> > >ddp_comp[i]->id);
> > -	mtk_mutex_enable(mtk_crtc->mutex);
> > +	mmsys = mtk_crtc->ddp_comp_sys[i];
> > +	if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc-
> > >mutex[mmsys]))
> > +		mtk_mutex_add_comp(mtk_crtc->mutex[mmsys],
> > mtk_crtc->ddp_comp[i]->id);
> > +
> > +	/* Need to set sof source for all mmsys mutexs in this
> > crtc */
> > +	for (j = 0; j < MAX_MMSYS; j++)
> > +		if (mtk_crtc->exist[j] && mtk_crtc->mutex[j])
> > +			mtk_mutex_write_comp_sof(mtk_crtc-
> > >mutex[j], mtk_crtc->ddp_comp[i]->id);
> > +
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])
> > +			mtk_mutex_enable(mtk_crtc->mutex[i]);
> >  
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> >  		struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];
> > @@ -394,7 +449,11 @@ static int mtk_crtc_ddp_hw_init(struct
> > mtk_crtc *mtk_crtc)
> >  		if (i == 1)
> >  			mtk_ddp_comp_bgclr_in_on(comp);
> >  
> > -		mtk_ddp_comp_config(comp, width, height, vrefresh,
> > bpc, NULL);
> > +		if (mtk_ddp_comp_get_type(comp->id) ==
> > MTK_DISP_VIRTUAL)
> > +			mtk_mmsys_ddp_config(mtk_crtc-
> > >mmsys_dev[mtk_crtc->ddp_comp_sys[i]],
> > +					     comp->id, width,
> > height, NULL);
> > +		else
> > +			mtk_ddp_comp_config(comp, width, height,
> > vrefresh, bpc, NULL);
> >  		mtk_ddp_comp_start(comp);
> >  	}
> >  
> > @@ -418,7 +477,10 @@ static int mtk_crtc_ddp_hw_init(struct
> > mtk_crtc *mtk_crtc)
> >  	return 0;
> >  
> >  err_mutex_unprepare:
> > -	mtk_mutex_unprepare(mtk_crtc->mutex);
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])
> > +			mtk_mutex_unprepare(mtk_crtc->mutex[i]);
> > +
> >  err_pm_runtime_put:
> >  	pm_runtime_put(crtc->dev->dev);
> >  	return ret;
> > @@ -430,6 +492,7 @@ static void mtk_crtc_ddp_hw_fini(struct
> > mtk_crtc *mtk_crtc)
> >  	struct drm_crtc *crtc = &mtk_crtc->base;
> >  	unsigned long flags;
> >  	int i;
> > +	enum mtk_drm_mmsys mmsys;
> >  
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> >  		mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);
> > @@ -437,27 +500,46 @@ static void mtk_crtc_ddp_hw_fini(struct
> > mtk_crtc *mtk_crtc)
> >  			mtk_ddp_comp_bgclr_in_off(mtk_crtc-
> > >ddp_comp[i]);
> >  	}
> >  
> > -	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
> > -		if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mutex))
> > -			mtk_mutex_remove_comp(mtk_crtc->mutex,
> > +	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> > +		mmsys = mtk_crtc->ddp_comp_sys[i];
> > +		if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mutex[mmsys]))
> > +			mtk_mutex_remove_comp(mtk_crtc-
> > >mutex[mtk_crtc->ddp_comp_sys[i]],
> >  					      mtk_crtc-
> > >ddp_comp[i]->id);
> > -	mtk_mutex_disable(mtk_crtc->mutex);
> > +	}
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])
> > +			mtk_mutex_disable(mtk_crtc->mutex[i]);
> > +
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
> > -		if (!mtk_ddp_comp_disconnect(mtk_crtc-
> > >ddp_comp[i], mtk_crtc->mmsys_dev,
> > -					     mtk_crtc->ddp_comp[i
> > + 1]->id))
> > -			mtk_mmsys_ddp_disconnect(mtk_crtc-
> > >mmsys_dev,
> > -						 mtk_crtc-
> > >ddp_comp[i]->id,
> > -						 mtk_crtc-
> > >ddp_comp[i + 1]->id);
> > -		if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i],
> > mtk_crtc->mutex))
> > -			mtk_mutex_remove_comp(mtk_crtc->mutex,
> > +		struct mtk_ddp_comp *comp;
> > +		unsigned int curr, next;
> > +
> > +		comp = mtk_crtc->ddp_comp[i];
> > +		curr = mtk_crtc->ddp_comp[i]->id;
> > +		next = mtk_crtc->ddp_comp[i + 1]->id;
> > +		mmsys = mtk_crtc->ddp_comp_sys[i];
> > +		if (!mtk_ddp_comp_disconnect(comp, mtk_crtc-
> > >mmsys_dev[mmsys], next))
> > +			mtk_mmsys_ddp_disconnect(mtk_crtc-
> > >mmsys_dev[mmsys], curr, next);
> > +		if (!mtk_ddp_comp_remove(comp, mtk_crtc-
> > >mutex[mmsys]))
> > +			mtk_mutex_remove_comp(mtk_crtc-
> > >mutex[mtk_crtc->ddp_comp_sys[i]],
> >  					      mtk_crtc-
> > >ddp_comp[i]->id);
> >  	}
> > -	if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc-
> > >mutex))
> > -		mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc-
> > >ddp_comp[i]->id);
> > +
> > +	mmsys = mtk_crtc->ddp_comp_sys[i];
> > +	if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc-
> > >mutex[mmsys]))
> > +		mtk_mutex_remove_comp(mtk_crtc->mutex[mmsys],
> > mtk_crtc->ddp_comp[i]->id);
> > +
> >  	mtk_crtc_ddp_clk_disable(mtk_crtc);
> > -	mtk_mutex_unprepare(mtk_crtc->mutex);
> >  
> > -	pm_runtime_put(drm->dev);
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])
> > +			mtk_mutex_unprepare(mtk_crtc->mutex[i]);
> > +
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			mtk_mmsys_top_clk_disable(mtk_crtc-
> > >mmsys_dev[i]);
> > +
> > +	pm_runtime_put_sync(drm->dev);
> >  
> >  	if (crtc->state->event && !crtc->state->active) {
> >  		spin_lock_irqsave(&crtc->dev->event_lock, flags);
> > @@ -581,9 +663,15 @@ static void mtk_crtc_update_config(struct
> > mtk_crtc *mtk_crtc, bool needs_vblank)
> >  		mtk_crtc->pending_async_planes = true;
> >  
> >  	if (priv->data->shadow_register) {
> > -		mtk_mutex_acquire(mtk_crtc->mutex);
> > +		for (i = 0; i < MAX_MMSYS; i++)
> > +			if (mtk_crtc->exist[i] && mtk_crtc-
> > >mutex[i])
> > +				mtk_mutex_acquire(mtk_crtc-
> > >mutex[i]);
> > +
> >  		mtk_crtc_ddp_config(crtc, NULL);
> > -		mtk_mutex_release(mtk_crtc->mutex);
> > +
> > +		for (i = 0; i < MAX_MMSYS; i++)
> > +			if (mtk_crtc->exist[i] && mtk_crtc-
> > >mutex[i])
> > +				mtk_mutex_release(mtk_crtc-
> > >mutex[i]);
> >  	}
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	if (mtk_crtc->cmdq_client.chan) {
> > @@ -659,6 +747,7 @@ static void mtk_crtc_update_output(struct
> > drm_crtc *crtc,
> >  {
> >  	int crtc_index = drm_crtc_index(crtc);
> >  	int i;
> > +	unsigned int mmsys;
> >  	struct device *dev;
> >  	struct drm_crtc_state *crtc_state = state-
> > >crtcs[crtc_index].new_state;
> >  	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> > @@ -671,7 +760,8 @@ static void mtk_crtc_update_output(struct
> > drm_crtc *crtc,
> >  	if (!mtk_crtc->num_conn_routes)
> >  		return;
> >  
> > -	priv = ((struct mtk_drm_private *)crtc->dev->dev_private)-
> > >all_drm_private[crtc_index];
> > +	mmsys = mtk_crtc->conn_routes_sys;
> > +	priv = ((struct mtk_drm_private *)crtc->dev->dev_private)-
> > >all_drm_private[mmsys];
> >  	dev = priv->dev;
> >  
> >  	dev_dbg(dev, "connector change:%d, encoder mask:0x%x for
> > crtc:%d\n",
> > @@ -684,6 +774,8 @@ static void mtk_crtc_update_output(struct
> > drm_crtc *crtc,
> >  		if (comp->encoder_index >= 0 &&
> >  		    (encoder_mask & BIT(comp->encoder_index))) {
> >  			mtk_crtc->ddp_comp[mtk_crtc->ddp_comp_nr -
> > 1] = comp;
> > +			mtk_crtc->ddp_comp_sys[mtk_crtc-
> > >ddp_comp_nr - 1] = mmsys;
> > +			mtk_crtc->exist[mmsys] = true;
> >  			dev_dbg(dev, "Add comp_id: %d at path
> > index %d\n",
> >  				comp->id, mtk_crtc->ddp_comp_nr -
> > 1);
> >  			break;
> > @@ -720,13 +812,35 @@ static void mtk_crtc_atomic_enable(struct
> > drm_crtc *crtc,
> >  	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >  	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
> >  	int ret;
> > +	int i, j;
> > +	int mmsys_cnt = 0;
> >  
> >  	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
> >  
> > -	ret = mtk_ddp_comp_power_on(comp);
> > -	if (ret < 0) {
> > -		DRM_DEV_ERROR(comp->dev, "Failed to enable power
> > domain: %d\n", ret);
> > -		return;
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			mmsys_cnt++;
> > +
> > +	if (mmsys_cnt == 1) {
> > +		ret = pm_runtime_resume_and_get(comp->dev);
> > +		if (ret < 0) {
> > +			DRM_DEV_ERROR(comp->dev, "Failed to enable
> > power domain: %d\n", ret);
> > +			return;
> > +		}
> > +	} else {
> > +		for (i = 0; i < MAX_MMSYS; i++) {
> > +			if (!mtk_crtc->exist[i])
> > +				continue;
> > +			ret = pm_runtime_resume_and_get(mtk_crtc-
> > >mmsys_dev[i]);
> > +			if (ret < 0) {
> > +				DRM_DEV_ERROR(mtk_crtc-
> > >mmsys_dev[i],
> > +					      "Failed to enable
> > power domain: %d\n", ret);
> > +				for (j = i - 1; j >= 0; j--)
> > +					if (mtk_crtc->exist[i])
> > +						pm_runtime_put(com
> > p->dev);
> > +				return;
> > +			}
> > +		}
> >  	}
> >  
> >  	mtk_crtc_update_output(crtc, state);
> > @@ -746,12 +860,17 @@ static void mtk_crtc_atomic_disable(struct
> > drm_crtc *crtc,
> >  {
> >  	struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);
> >  	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
> > -	int i;
> > +	int i, ret;
> > +	int mmsys_cnt = 0;
> >  
> >  	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
> >  	if (!mtk_crtc->enabled)
> >  		return;
> >  
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			mmsys_cnt++;
> > +
> >  	/* Set all pending plane state to disabled */
> >  	for (i = 0; i < mtk_crtc->layer_nr; i++) {
> >  		struct drm_plane *plane = &mtk_crtc->planes[i];
> > @@ -776,7 +895,21 @@ static void mtk_crtc_atomic_disable(struct
> > drm_crtc *crtc,
> >  
> >  	drm_crtc_vblank_off(crtc);
> >  	mtk_crtc_ddp_hw_fini(mtk_crtc);
> > -	mtk_ddp_comp_power_off(comp);
> > +
> > +	if (mmsys_cnt > 1) {
> > +		for (i = 0; i < MAX_MMSYS; i++) {
> > +			if (mtk_crtc->exist[i]) {
> > +				ret = pm_runtime_put(mtk_crtc-
> > >mmsys_dev[i]);
> > +				if (ret < 0)
> > +					DRM_DEV_ERROR(mtk_crtc-
> > >mmsys_dev[i],
> > +						      "Failed to
> > disable power domain: %d\n", ret);
> > +			}
> > +		}
> > +	} else {
> > +		ret = pm_runtime_put(comp->dev);
> > +		if (ret < 0)
> > +			DRM_DEV_ERROR(comp->dev, "Failed to
> > disable power domain: %d\n", ret);
> > +	}
> >  
> >  	mtk_crtc->enabled = false;
> >  }
> > @@ -937,49 +1070,108 @@ struct device *mtk_crtc_dma_dev_get(struct
> > drm_crtc *crtc)
> >  	return mtk_crtc->dma_dev;
> >  }
> >  
> > -int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int
> > *path,
> > -		    unsigned int path_len, int priv_data_index,
> > -		    const struct mtk_drm_route *conn_routes,
> > -		    unsigned int num_conn_routes)
> > +int mtk_crtc_create(struct drm_device *drm_dev, enum mtk_crtc_path
> > path_sel)
> >  {
> >  	struct mtk_drm_private *priv = drm_dev->dev_private;
> >  	struct device *dev = drm_dev->dev;
> >  	struct mtk_crtc *mtk_crtc;
> >  	unsigned int num_comp_planes = 0;
> >  	int ret;
> > -	int i;
> > +	int i, j, k;
> >  	bool has_ctm = false;
> >  	uint gamma_lut_size = 0;
> >  	struct drm_crtc *tmp;
> >  	int crtc_i = 0;
> > -
> > -	if (!path)
> > -		return 0;
> > -
> > -	priv = priv->all_drm_private[priv_data_index];
> > +	struct mtk_drm_private *subsys_priv;
> > +	struct mtk_crtc_comp_info path[DDP_COMPONENT_ID_MAX];
> > +	unsigned int path_len = 0;
> > +	const struct mtk_drm_route *conn_routes = NULL;
> > +	unsigned int num_conn_routes = 0;
> > +	enum mtk_drm_mmsys conn_mmsys;
> >  
> >  	drm_for_each_crtc(tmp, drm_dev)
> >  		crtc_i++;
> >  
> > +	for (j = 0; j < priv->data->mmsys_dev_num; j++) {
> > +		for (k = 0; k < MAX_MMSYS; k++) {
> > +			const unsigned int *subsys_path;
> > +			unsigned int subsys_path_len;
> > +			unsigned int order = 0;
> > +
> > +			subsys_priv = priv->all_drm_private[k];
> > +			if (!subsys_priv)
> > +				continue;
> > +
> > +			if (path_sel == CRTC_MAIN) {
> > +				subsys_path = subsys_priv->data-
> > >main_path;
> > +				subsys_path_len = subsys_priv-
> > >data->main_len;
> > +				order = subsys_priv->data-
> > >main_order;
> > +			} else if (path_sel == CRTC_EXT) {
> > +				subsys_path = subsys_priv->data-
> > >ext_path;
> > +				subsys_path_len = subsys_priv-
> > >data->ext_len;
> > +				order = subsys_priv->data-
> > >ext_order;
> > +			} else if (path_sel == CRTC_THIRD) {
> > +				subsys_path = subsys_priv->data-
> > >third_path;
> > +				subsys_path_len = subsys_priv-
> > >data->third_len;
> > +				order = subsys_priv->data-
> > >third_order;
> > +			}
> > +
> > +			if (subsys_priv->data->num_conn_routes) {
> > +				conn_routes = subsys_priv->data-
> > >conn_routes;
> > +				num_conn_routes = subsys_priv-
> > >data->num_conn_routes;
> > +				conn_mmsys = subsys_priv->data-
> > >mmsys_id;
> > +			}
> > +
> > +			if (j != order)
> > +				continue;
> > +			if (!subsys_path_len)
> > +				continue;
> > +
> > +			for (i = 0; i < subsys_path_len; i++) {
> > +				path[path_len].sys = subsys_priv-
> > >data->mmsys_id;
> > +				path[path_len].comp_id =
> > subsys_path[i];
> > +				path_len++;
> > +			}
> > +		}
> > +	}
> > +
> > +	if (!path_len)
> > +		return 0;
> > +
> > +	if (num_conn_routes) {
> > +		for (i = 0; i < num_conn_routes; i++)
> > +			if (conn_routes->crtc_id == crtc_i)
> > +				break;
> > +		if (i == num_conn_routes) {
> > +			num_conn_routes = 0;
> > +			conn_routes = NULL;
> > +		}
> > +	}
> > +
> >  	for (i = 0; i < path_len; i++) {
> > -		enum mtk_ddp_comp_id comp_id = path[i];
> > +		enum mtk_ddp_comp_id comp_id = path[i].comp_id;
> >  		struct device_node *node;
> >  		struct mtk_ddp_comp *comp;
> >  
> > +		priv = priv->all_drm_private[path[i].sys];
> >  		node = priv->comp_node[comp_id];
> >  		comp = &priv->ddp_comp[comp_id];
> >  
> >  		/* Not all drm components have a DTS device node,
> > such as ovl_adaptor,
> >  		 * which is the drm bring up sub driver
> >  		 */
> > -		if (!node && comp_id !=
> > DDP_COMPONENT_DRM_OVL_ADAPTOR) {
> > +		if (!node && comp_id !=
> > DDP_COMPONENT_DRM_OVL_ADAPTOR &&
> > +		    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0
> > &&
> > +		    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1
> > &&
> > +		    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2
> > &&
> > +		    mtk_ddp_comp_get_type(comp_id) !=
> > MTK_DISP_VIRTUAL) {
> >  			dev_info(dev,
> >  				"Not creating crtc %d because
> > component %d is disabled or missing\n",
> >  				crtc_i, comp_id);
> >  			return 0;
> >  		}
> >  
> > -		if (!comp->dev) {
> > +		if (!comp->dev && mtk_ddp_comp_get_type(comp_id)
> > != MTK_DISP_VIRTUAL) {
> >  			dev_err(dev, "Component %pOF not
> > initialized\n", node);
> >  			return -ENODEV;
> >  		}
> > @@ -989,7 +1181,9 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  	if (!mtk_crtc)
> >  		return -ENOMEM;
> >  
> > -	mtk_crtc->mmsys_dev = priv->mmsys_dev;
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (priv->all_drm_private[i])
> > +			mtk_crtc->mmsys_dev[i] = priv-
> > >all_drm_private[i]->mmsys_dev;
> >  	mtk_crtc->ddp_comp_nr = path_len;
> >  	mtk_crtc->ddp_comp = devm_kcalloc(dev,
> >  					  mtk_crtc->ddp_comp_nr +
> > (conn_routes ? 1 : 0),
> > @@ -998,19 +1192,36 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  	if (!mtk_crtc->ddp_comp)
> >  		return -ENOMEM;
> >  
> > -	mtk_crtc->mutex = mtk_mutex_get(priv->mutex_dev);
> > -	if (IS_ERR(mtk_crtc->mutex)) {
> > -		ret = PTR_ERR(mtk_crtc->mutex);
> > -		dev_err(dev, "Failed to get mutex: %d\n", ret);
> > -		return ret;
> > +	mtk_crtc->ddp_comp_sys = devm_kmalloc_array(dev, mtk_crtc-
> > >ddp_comp_nr +
> > +						    (conn_routes ?
> > 1 : 0),
> > +						   
> > sizeof(mtk_crtc->ddp_comp_sys), GFP_KERNEL);
> > +	if (!mtk_crtc->ddp_comp_sys)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < MAX_MMSYS; i++) {
> > +		if (!priv->all_drm_private[i])
> > +			continue;
> > +
> > +		priv = priv->all_drm_private[i];
> > +		mtk_crtc->mutex[i] = mtk_mutex_get(priv-
> > >mutex_dev);
> > +		if (IS_ERR(mtk_crtc->mutex[i])) {
> > +			ret = PTR_ERR(mtk_crtc->mutex[i]);
> > +			dev_err(dev, "Failed to get mutex: %d\n",
> > ret);
> > +			return ret;
> > +		}
> >  	}
> >  
> >  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
> > -		unsigned int comp_id = path[i];
> > +		unsigned int comp_id = path[i].comp_id;
> >  		struct mtk_ddp_comp *comp;
> >  
> > +		priv = priv->all_drm_private[path[i].sys];
> >  		comp = &priv->ddp_comp[comp_id];
> > +		if (mtk_ddp_comp_get_type(comp_id) ==
> > MTK_DISP_VIRTUAL)
> > +			comp->id = comp_id;
> >  		mtk_crtc->ddp_comp[i] = comp;
> > +		mtk_crtc->ddp_comp_sys[i] = path[i].sys;
> > +		mtk_crtc->exist[path[i].sys] = true;
> >  
> >  		if (comp->funcs) {
> >  			if (comp->funcs->gamma_set && comp->funcs-
> > >gamma_get_lut_size) {
> > @@ -1047,8 +1258,10 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  	 * In the case of ovl_adaptor sub driver, it needs to use
> > the
> >  	 * dma_dev_get function to get representative dma dev.
> >  	 */
> > -	mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv-
> > >ddp_comp[path[0]]);
> > +	priv = priv->all_drm_private[path[0].sys];
> > +	mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv-
> > >ddp_comp[path[0].comp_id]);
> >  
> > +	mtk_crtc->vdisp_ao_dev = priv->vdisp_ao_dev;
> >  	ret = mtk_crtc_init(drm_dev, mtk_crtc, crtc_i);
> >  	if (ret < 0)
> >  		return ret;
> > @@ -1061,7 +1274,7 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  
> >  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> >  	i = priv->mbox_index++;
> > -	mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
> > +	mtk_crtc->cmdq_client.client.dev = mtk_crtc-
> > >mmsys_dev[priv->data->mmsys_id];
> >  	mtk_crtc->cmdq_client.client.tx_block = false;
> >  	mtk_crtc->cmdq_client.client.knows_txdone = true;
> >  	mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
> > @@ -1101,6 +1314,7 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  #endif
> >  
> >  	if (conn_routes) {
> > +		priv = priv->all_drm_private[conn_mmsys];
> >  		for (i = 0; i < num_conn_routes; i++) {
> >  			unsigned int comp_id =
> > conn_routes[i].route_ddp;
> >  			struct device_node *node = priv-
> > >comp_node[comp_id];
> > @@ -1117,6 +1331,7 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  			mtk_ddp_comp_encoder_index_set(&priv-
> > >ddp_comp[comp_id]);
> >  		}
> >  
> > +		mtk_crtc->conn_routes_sys = conn_mmsys;
> >  		mtk_crtc->num_conn_routes = num_conn_routes;
> >  		mtk_crtc->conn_routes = conn_routes;
> >  
> > @@ -1124,5 +1339,10 @@ int mtk_crtc_create(struct drm_device
> > *drm_dev, const unsigned int *path,
> >  		mtk_crtc->ddp_comp_nr++;
> >  	}
> >  
> > +	for (i = 0; i < MAX_MMSYS; i++)
> > +		if (mtk_crtc->exist[i])
> > +			device_link_add(mtk_crtc->base.dev->dev,
> > +					priv->all_drm_private[i]-
> > >mutex_dev, 0);
> > +
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h
> > b/drivers/gpu/drm/mediatek/mtk_crtc.h
> > index 388e900b6f4d..255f2823d17a 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_crtc.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_crtc.h
> > @@ -15,10 +15,8 @@
> >  #define MTK_MIN_BPC	3
> >  
> >  void mtk_crtc_commit(struct drm_crtc *crtc);
> > -int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int
> > *path,
> > -		    unsigned int path_len, int priv_data_index,
> > -		    const struct mtk_drm_route *conn_routes,
> > -		    unsigned int num_conn_routes);
> > +int mtk_crtc_create(struct drm_device *drm_dev,
> > +		    enum mtk_crtc_path path_sel);
> >  int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane
> > *plane,
> >  			 struct mtk_plane_state *state);
> >  void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane
> > *plane,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > index 492b8d965309..f841184d1e06 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> > @@ -464,6 +464,7 @@ static const char * const
> > mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> >  	[MTK_DISP_PWM] = "pwm",
> >  	[MTK_DISP_RDMA] = "rdma",
> >  	[MTK_DISP_UFOE] = "ufoe",
> > +	[MTK_DISP_VIRTUAL] = "virtual",
> >  	[MTK_DISP_WDMA] = "wdma",
> >  	[MTK_DP_INTF] = "dp-intf",
> >  	[MTK_DPI] = "dpi",
> > @@ -487,6 +488,15 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
> >  	[DDP_COMPONENT_COLOR0]		= {
> > MTK_DISP_COLOR,		0, &ddp_color },
> >  	[DDP_COMPONENT_COLOR1]		= {
> > MTK_DISP_COLOR,		1, &ddp_color },
> >  	[DDP_COMPONENT_DITHER0]		= {
> > MTK_DISP_DITHER,		0, &ddp_dither },
> > +	[DDP_COMPONENT_DLI_ASYNC0]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLI_ASYNC1]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLI_ASYNC8]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLI_ASYNC21]     = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLI_ASYNC22]     = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLI_ASYNC23]     = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLO_ASYNC1]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLO_ASYNC2]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_DLO_ASYNC3]      = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> >  	[DDP_COMPONENT_DP_INTF0]	= {
> > MTK_DP_INTF,		0, &ddp_dpi },
> >  	[DDP_COMPONENT_DP_INTF1]	= {
> > MTK_DP_INTF,		1, &ddp_dpi },
> >  	[DDP_COMPONENT_DPI0]		= {
> > MTK_DPI,			0, &ddp_dpi },
> > @@ -494,6 +504,9 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
> >  	[DDP_COMPONENT_DRM_OVL_ADAPTOR]	= {
> > MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
> >  	[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0] = {
> > MTK_DISP_OVLSYS_ADAPTOR, 0, &ddp_ovlsys_adaptor},
> >  	[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1] = {
> > MTK_DISP_OVLSYS_ADAPTOR, 1, &ddp_ovlsys_adaptor},
> > +	[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0] = {
> > MTK_DISP_OVLSYS_ADAPTOR, 0, &ddp_ovlsys_adaptor},
> > +	[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1] = {
> > MTK_DISP_OVLSYS_ADAPTOR, 1, &ddp_ovlsys_adaptor},
> > +	[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2] = {
> > MTK_DISP_OVLSYS_ADAPTOR, 2, &ddp_ovlsys_adaptor},
> >  	[DDP_COMPONENT_DSC0]		= {
> > MTK_DISP_DSC,		0, &ddp_dsc },
> >  	[DDP_COMPONENT_DSC1]		= {
> > MTK_DISP_DSC,		1, &ddp_dsc },
> >  	[DDP_COMPONENT_DSI0]		= {
> > MTK_DSI,			0, &ddp_dsi },
> > @@ -510,7 +523,10 @@ static const struct mtk_ddp_comp_match
> > mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
> >  	[DDP_COMPONENT_OD0]		= {
> > MTK_DISP_OD,		0, &ddp_od },
> >  	[DDP_COMPONENT_OD1]		= {
> > MTK_DISP_OD,		1, &ddp_od },
> >  	[DDP_COMPONENT_OVL0]		= {
> > MTK_DISP_OVL,		0, &ddp_ovl },
> > +	[DDP_COMPONENT_OVL0_DLO_ASYNC5] = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> > +	[DDP_COMPONENT_OVL0_DLO_ASYNC6] = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> >  	[DDP_COMPONENT_OVL1]		= {
> > MTK_DISP_OVL,		1, &ddp_ovl },
> > +	[DDP_COMPONENT_OVL1_DLO_ASYNC5] = {
> > MTK_DISP_VIRTUAL,           -1, NULL },
> >  	[DDP_COMPONENT_OVL_2L0]		= {
> > MTK_DISP_OVL_2L,		0, &ddp_ovl },
> >  	[DDP_COMPONENT_OVL_2L1]		= {
> > MTK_DISP_OVL_2L,		1, &ddp_ovl },
> >  	[DDP_COMPONENT_OVL_2L2]		= {
> > MTK_DISP_OVL_2L,		2, &ddp_ovl },
> > @@ -567,12 +583,19 @@ static bool mtk_ddp_path_available(const
> > unsigned int *path,
> >  {
> >  	unsigned int i;
> >  
> > +	if (!path_len)
> > +		return true;
> > +
> >  	if (!path || !path_len)
> >  		return false;
> >  
> >  	for (i = 0U; i < path_len; i++) {
> >  		/* OVL_ADAPTOR doesn't have a device node */
> > -		if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR)
> > +		if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR ||
> > +		    path[i] == DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0
> > ||
> > +			path[i] ==
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 ||
> > +			path[i] ==
> > DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 ||
> > +			mtk_ddp_comp_get_type(path[i]) ==
> > MTK_DISP_VIRTUAL)
> >  			continue;
> >  
> >  		if (!comp_node[path[i]])
> > @@ -597,44 +620,81 @@ int mtk_ddp_comp_get_id(struct device_node
> > *node,
> >  	return -EINVAL;
> >  }
> >  
> > +enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id)
> > +{
> > +	return mtk_ddp_matches[comp_id].type;
> > +}
> > +
> >  int mtk_find_possible_crtcs(struct drm_device *drm, struct device
> > *dev)
> >  {
> >  	struct mtk_drm_private *private = drm->dev_private;
> >  	const struct mtk_mmsys_driver_data *data;
> >  	struct mtk_drm_private *priv_n;
> > -	int i = 0, j;
> >  	int ret;
> > +	int i = 0, j, count = 0;
> > +	bool found = false;
> >  
> >  	for (j = 0; j < private->data->mmsys_dev_num; j++) {
> >  		priv_n = private->all_drm_private[j];
> >  		data = priv_n->data;
> >  
> >  		if (mtk_ddp_path_available(data->main_path, data-
> > >main_len,
> > -					   priv_n->comp_node)) {
> > -			if (mtk_ddp_comp_find(dev, data-
> > >main_path,
> > -					      data->main_len,
> > -					      priv_n->ddp_comp))
> > -				return BIT(i);
> > -			i++;
> > -		}
> > +					   priv_n->comp_node))
> > +			count++;
> > +
> > +		if (mtk_ddp_comp_find(dev, data->main_path, data-
> > >main_len,
> > +				      priv_n->ddp_comp))
> > +			found = true;
> > +	}
> > +
> > +	if (count == private->data->mmsys_dev_num) {
> > +		if (found)
> > +			return BIT(i);
> > +		i++;
> > +	}
> > +
> > +	count = 0;
> > +	found = false;
> > +
> > +	for (j = 0; j < private->data->mmsys_dev_num; j++) {
> > +		priv_n = private->all_drm_private[j];
> > +		data = priv_n->data;
> >  
> >  		if (mtk_ddp_path_available(data->ext_path, data-
> > >ext_len,
> > -					   priv_n->comp_node)) {
> > -			if (mtk_ddp_comp_find(dev, data->ext_path,
> > -					      data->ext_len,
> > -					      priv_n->ddp_comp))
> > -				return BIT(i);
> > -			i++;
> > -		}
> > +					   priv_n->comp_node))
> > +			count++;
> > +
> > +		if (mtk_ddp_comp_find(dev, data->ext_path, data-
> > >ext_len,
> > +				      priv_n->ddp_comp))
> > +			found = true;
> > +	}
> > +
> > +	if (count == private->data->mmsys_dev_num) {
> > +		if (found)
> > +			return BIT(i);
> > +		i++;
> > +	}
> > +
> > +	count = 0;
> > +	found = false;
> > +
> > +	for (j = 0; j < private->data->mmsys_dev_num; j++) {
> > +		priv_n = private->all_drm_private[j];
> > +		data = priv_n->data;
> >  
> >  		if (mtk_ddp_path_available(data->third_path, data-
> > >third_len,
> > -					   priv_n->comp_node)) {
> > -			if (mtk_ddp_comp_find(dev, data-
> > >third_path,
> > -					      data->third_len,
> > -					      priv_n->ddp_comp))
> > -				return BIT(i);
> > -			i++;
> > -		}
> > +					priv_n->comp_node))
> > +			count++;
> > +
> > +		if (mtk_ddp_comp_find(dev, data->third_path, data-
> > >third_len,
> > +				      priv_n->ddp_comp))
> > +			found = true;
> > +	}
> > +
> > +	if (count == private->data->mmsys_dev_num) {
> > +		if (found)
> > +			return BIT(i);
> > +		i++;
> >  	}
> >  
> >  	ret = mtk_ddp_comp_find_in_route(dev,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> > b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> > index ef64ce7a071f..badb42bd4f7c 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> > @@ -40,6 +40,7 @@ enum mtk_ddp_comp_type {
> >  	MTK_DISP_PWM,
> >  	MTK_DISP_RDMA,
> >  	MTK_DISP_UFOE,
> > +	MTK_DISP_VIRTUAL,
> >  	MTK_DISP_WDMA,
> >  	MTK_DPI,
> >  	MTK_DP_INTF,
> > @@ -47,6 +48,7 @@ enum mtk_ddp_comp_type {
> >  	MTK_OVL_BLENDER,
> >  	MTK_OVL_EXDMA,
> >  	MTK_OVL_OUTPROC,
> > +	MTK_VDISP_AO,
> >  	MTK_DDP_COMP_TYPE_MAX,
> >  };
> >  
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index 7526bc38bcc7..0665a6feb546 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -193,6 +193,10 @@ static const struct mtk_drm_route
> > mt8188_mtk_ddp_main_routes[] = {
> >  	{0, DDP_COMPONENT_DSI0},
> >  };
> >  
> > +static const struct mtk_drm_route mt8196_mtk_ddp_routes[] = {
> > +	{2, DDP_COMPONENT_DSI0},
> > +};
> > +
> >  static const unsigned int mt8192_mtk_ddp_main[] = {
> >  	DDP_COMPONENT_OVL0,
> >  	DDP_COMPONENT_OVL_2L0,
> > @@ -231,6 +235,50 @@ static const unsigned int mt8195_mtk_ddp_ext[]
> > = {
> >  	DDP_COMPONENT_DP_INTF1,
> >  };
> >  
> > +static const unsigned int mt8196_mtk_ddp_ovl0_main[] = {
> > +	DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0,
> > +	DDP_COMPONENT_OVL0_DLO_ASYNC5,
> > +};
> 
> Separate MT8196 part to another patch which add support MT8196.
> Let this patch not related to specific SoC.
> 
> Regards,
> CK

Sure, I will separate this patch to 2 part, first patch is to supprt
the multiple MMSYS for mediatek drm driver. Second patch is to support
MT8196 SOC.

Best, 
Paul  




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux