<html><body><p>
<pre>
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@mediatek.com>
> >
> > 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@mediatek.com>
> > Signed-off-by: Paul-pl.Chen <paul-pl.chen@mediatek.com>
> > ---
> >  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_tcb_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 intddp_comp_nr;
> >  struct mtk_ddp_comp**ddp_comp;
> > +enum mtk_drm_mmsys*ddp_comp_sys;
> > +boolexist[MAX_MMSYS];
> >  unsigned intnum_conn_routes;
> >  const struct mtk_drm_route*conn_routes;
> > +enum mtk_drm_mmsysconn_routes_sys;
> >  
> >  /* lock for display hardware access */
> >  struct mutexhw_lock;
> > @@ -82,6 +86,11 @@ struct mtk_crtc_state {
> >  unsigned intpending_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_BPC3
> >  
> >  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

</pre>
</p></body></html><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!
</pre><!--}-->