diff for duplicates of <a9e782eacbd88d41eee7bf7475b3c6e48e437923.camel@mediatek.com> diff --git a/N1/2.bin b/N1/2.bin new file mode 100644 index 0000000..5bd9536 --- /dev/null +++ b/N1/2.bin @@ -0,0 +1,1331 @@ +<html><body><p> +<pre> +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(comp->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 + +> + +> +static const unsigned int mt8196_mtk_ddp_disp0_main[] = { +> +DDP_COMPONENT_DLI_ASYNC0, +> +DDP_COMPONENT_DLO_ASYNC1, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_disp1_main[] = { +> +DDP_COMPONENT_DLI_ASYNC21, +> +DDP_COMPONENT_DVO0, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_ovl0_ext[] = { +> +DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1, +> +DDP_COMPONENT_OVL0_DLO_ASYNC6, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_disp0_ext[] = { +> +DDP_COMPONENT_DLI_ASYNC1, +> +DDP_COMPONENT_DLO_ASYNC2, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_disp1_ext[] = { +> +DDP_COMPONENT_DLI_ASYNC22, +> +DDP_COMPONENT_DP_INTF0, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_ovl1_third[] = { +> +DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2, +> +DDP_COMPONENT_OVL1_DLO_ASYNC5, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_disp0_third[] = { +> +DDP_COMPONENT_DLI_ASYNC8, +> +DDP_COMPONENT_DLO_ASYNC3, +> +}; +> + +> +static const unsigned int mt8196_mtk_ddp_disp1_third[] = { +> +DDP_COMPONENT_DLI_ASYNC23, +> +}; +> + +>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = { +>  .main_path = mt2701_mtk_ddp_main, +>  .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main), +> @@ -327,6 +375,67 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = { +>  .min_height = 1, +>  }; +>   +> +static const struct mtk_mmsys_driver_data mt8196_dispsys0_driver_data = { +> +.main_path = mt8196_mtk_ddp_disp0_main, +> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_main), +> +.main_order = 1, +> +.ext_path = mt8196_mtk_ddp_disp0_ext, +> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_ext), +> +.ext_order = 1, +> +.third_path = mt8196_mtk_ddp_disp0_third, +> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_third), +> +.third_order = 1, +> +.mmsys_id = DISPSYS0, +> +.mmsys_dev_num = 4, +> +.max_width = 8191, +> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */ +> +.min_height = 1, +> +}; +> + +> +static const struct mtk_mmsys_driver_data mt8196_dispsys1_driver_data = { +> +.main_path = mt8196_mtk_ddp_disp1_main, +> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_main), +> +.main_order = 2, +> +.ext_path = mt8196_mtk_ddp_disp1_ext, +> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_ext), +> +.ext_order = 2, +> +.third_path = mt8196_mtk_ddp_disp1_third, +> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_third), +> +.conn_routes = mt8196_mtk_ddp_routes, +> +.num_conn_routes = ARRAY_SIZE(mt8196_mtk_ddp_routes), +> +.third_order = 2, +> +.mmsys_id = DISPSYS1, +> +.mmsys_dev_num = 4, +> +.max_width = 8191, +> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */ +> +.min_height = 1, +> +}; +> + +> +static const struct mtk_mmsys_driver_data mt8196_ovlsys0_driver_data = { +> +.main_path = mt8196_mtk_ddp_ovl0_main, +> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl0_main), +> +.main_order = 0, +> +.ext_path = mt8196_mtk_ddp_ovl0_ext, +> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl0_ext), +> +.ext_order = 0, +> +.mmsys_id = OVLSYS0, +> +.mmsys_dev_num = 4, +> +.max_width = 8191, +> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */ +> +.min_height = 1, +> +}; +> + +> +static const struct mtk_mmsys_driver_data mt8196_ovlsys1_driver_data = { +> +.third_path = mt8196_mtk_ddp_ovl1_third, +> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl1_third), +> +.third_order = 0, +> +.mmsys_id = OVLSYS1, +> +.mmsys_dev_num = 4, +> +.max_width = 8191, +> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */ +> +.min_height = 1, +> +}; +> + +>  static const struct of_device_id mtk_drm_of_ids[] = { +>  { .compatible = "mediatek,mt2701-mmsys", +>    .data = &mt2701_mmsys_driver_data}, +> @@ -354,6 +463,14 @@ static const struct of_device_id mtk_drm_of_ids[] = { +>    .data = &mt8195_vdosys0_driver_data}, +>  { .compatible = "mediatek,mt8195-vdosys1", +>    .data = &mt8195_vdosys1_driver_data}, +> +{ .compatible = "mediatek,mt8196-dispsys0", +> +  .data = &mt8196_dispsys0_driver_data}, +> +{ .compatible = "mediatek,mt8196-dispsys1", +> +  .data = &mt8196_dispsys1_driver_data}, +> +{ .compatible = "mediatek,mt8196-ovlsys0", +> +  .data = &mt8196_ovlsys0_driver_data}, +> +{ .compatible = "mediatek,mt8196-ovlsys1", +> +  .data = &mt8196_ovlsys1_driver_data}, +>  { } +>  }; +>  MODULE_DEVICE_TABLE(of, mtk_drm_of_ids); +> @@ -368,7 +485,7 @@ static int mtk_drm_match(struct device *dev, const void *data) +>  static bool mtk_drm_get_all_drm_priv(struct device *dev) +>  { +>  struct mtk_drm_private *drm_priv = dev_get_drvdata(dev); +> -struct mtk_drm_private *all_drm_priv[MAX_CRTC]; +> +struct mtk_drm_private *all_drm_priv[MAX_MMSYS] = {NULL}; +>  struct mtk_drm_private *temp_drm_priv; +>  struct device_node *phandle = dev->parent->of_node; +>  const struct of_device_id *of_id; +> @@ -395,23 +512,18 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) +>  if (!temp_drm_priv) +>  continue; +>   +> -if (temp_drm_priv->data->main_len) +> -all_drm_priv[CRTC_MAIN] = temp_drm_priv; +> -else if (temp_drm_priv->data->ext_len) +> -all_drm_priv[CRTC_EXT] = temp_drm_priv; +> -else if (temp_drm_priv->data->third_len) +> -all_drm_priv[CRTC_THIRD] = temp_drm_priv; +> +all_drm_priv[temp_drm_priv->data->mmsys_id] = temp_drm_priv; +>   +>  if (temp_drm_priv->mtk_drm_bound) +>  cnt++; +>   +> -if (cnt == MAX_CRTC) +> +if (cnt == temp_drm_priv->data->mmsys_dev_num) +>  break; +>  } +>   +>  if (drm_priv->data->mmsys_dev_num == cnt) { +> -for (i = 0; i < cnt; i++) +> -for (j = 0; j < cnt; j++) +> +for (i = 0; i < MAX_MMSYS; i++) +> +for (j = 0; j < MAX_MMSYS; j++) +>  all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i]; +>   +>  return true; +> @@ -498,7 +610,10 @@ static int mtk_drm_kms_init(struct drm_device *drm) +>  drm->mode_config.funcs = &mtk_drm_mode_config_funcs; +>  drm->mode_config.helper_private = &mtk_drm_mode_config_helpers; +>   +> -for (i = 0; i < private->data->mmsys_dev_num; i++) { +> +for (i = 0; i < MAX_MMSYS; i++) { +> +if (!private->all_drm_private[i]) +> +continue; +> + +>  drm->dev_private = private->all_drm_private[i]; +>  ret = component_bind_all(private->all_drm_private[i]->dev, drm); +>  if (ret) +> @@ -521,8 +636,10 @@ static int mtk_drm_kms_init(struct drm_device *drm) +>   *    third path. +>   */ +>  for (i = 0; i < MAX_CRTC; i++) { +> -for (j = 0; j < private->data->mmsys_dev_num; j++) { +> +for (j = 0; j < MAX_MMSYS; j++) { +>  priv_n = private->all_drm_private[j]; +> +if (!priv_n) +> +continue; +>   +>  if (priv_n->data->max_width) +>  drm->mode_config.max_width = priv_n->data->max_width; +> @@ -534,28 +651,23 @@ static int mtk_drm_kms_init(struct drm_device *drm) +>  drm->mode_config.min_height = priv_n->data->min_height; +>   +>  if (i == CRTC_MAIN && priv_n->data->main_len) { +> -ret = mtk_crtc_create(drm, priv_n->data->main_path, +> -      priv_n->data->main_len, j, +> -      priv_n->data->conn_routes, +> -      priv_n->data->num_conn_routes); +> +ret = mtk_crtc_create(drm, CRTC_MAIN); +>  if (ret) +>  goto err_component_unbind; +>   +> -continue; +> +break; +>  } else if (i == CRTC_EXT && priv_n->data->ext_len) { +> -ret = mtk_crtc_create(drm, priv_n->data->ext_path, +> -      priv_n->data->ext_len, j, NULL, 0); +> +ret = mtk_crtc_create(drm, CRTC_EXT); +>  if (ret) +>  goto err_component_unbind; +>   +> -continue; +> +break; +>  } else if (i == CRTC_THIRD && priv_n->data->third_len) { +> -ret = mtk_crtc_create(drm, priv_n->data->third_path, +> -      priv_n->data->third_len, j, NULL, 0); +> +ret = mtk_crtc_create(drm, CRTC_THIRD); +>  if (ret) +>  goto err_component_unbind; +>   +> -continue; +> +break; +>  } +>  } +>  } +> @@ -574,8 +686,9 @@ static int mtk_drm_kms_init(struct drm_device *drm) +>  goto err_component_unbind; +>  } +>   +> -for (i = 0; i < private->data->mmsys_dev_num; i++) +> -private->all_drm_private[i]->dma_dev = dma_dev; +> +for (i = 0; i < MAX_MMSYS; i++) +> +if (private->all_drm_private[i]) +> +private->all_drm_private[i]->dma_dev = dma_dev; +>   +>  /* +>   * Configure the DMA segment size to make sure we get contiguous IOVA +> @@ -593,11 +706,13 @@ static int mtk_drm_kms_init(struct drm_device *drm) +>  return 0; +>   +>  err_component_unbind: +> -for (i = 0; i < private->data->mmsys_dev_num; i++) +> -component_unbind_all(private->all_drm_private[i]->dev, drm); +> +for (i = 0; i < MAX_MMSYS; i++) +> +if (private->all_drm_private[i]) +> +component_unbind_all(private->all_drm_private[i]->dev, drm); +>  put_mutex_dev: +> -for (i = 0; i < private->data->mmsys_dev_num; i++) +> -put_device(private->all_drm_private[i]->mutex_dev); +> +for (i = 0; i < MAX_MMSYS; i++) +> +if (private->all_drm_private[i]) +> +put_device(private->all_drm_private[i]->mutex_dev); +>   +>  return ret; +>  } +> @@ -661,6 +776,19 @@ static int mtk_drm_bind(struct device *dev) +>  } +>   +>  private->mutex_dev = &pdev->dev; +> + +> +if (private->vdisp_ao_node) { +> +pdev = of_find_device_by_node(private->vdisp_ao_node); +> +if (!pdev) { +> +dev_err(dev, "Waiting for vdisp_ao device %pOF\n", +> +private->vdisp_ao_node); +> +of_node_put(private->mutex_node); +> +of_node_put(private->vdisp_ao_node); +> +return -EPROBE_DEFER; +> +} +> +private->vdisp_ao_dev = &pdev->dev; +> +} +> + +>  private->mtk_drm_bound = true; +>  private->dev = dev; +>   +> @@ -673,8 +801,9 @@ static int mtk_drm_bind(struct device *dev) +>   +>  private->drm_master = true; +>  drm->dev_private = private; +> -for (i = 0; i < private->data->mmsys_dev_num; i++) +> -private->all_drm_private[i]->drm = drm; +> +for (i = 0; i < MAX_MMSYS; i++) +> +if (private->all_drm_private[i]) +> +private->all_drm_private[i]->drm = drm; +>   +>  ret = mtk_drm_kms_init(drm); +>  if (ret < 0) +> @@ -771,6 +900,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { +>    .data = (void *)MTK_DISP_MUTEX }, +>  { .compatible = "mediatek,mt8195-disp-mutex", +>    .data = (void *)MTK_DISP_MUTEX }, +> +{ .compatible = "mediatek,mt8196-disp-mutex", +> +  .data = (void *)MTK_DISP_MUTEX }, +>  { .compatible = "mediatek,mt8173-disp-od", +>    .data = (void *)MTK_DISP_OD }, +>  { .compatible = "mediatek,mt2701-disp-ovl", +> @@ -837,6 +968,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { +>    .data = (void *)MTK_DSI }, +>  { .compatible = "mediatek,mt8188-dsi", +>    .data = (void *)MTK_DSI }, +> +{ .compatible = "mediatek,mt8196-vdisp-ao", +> +  .data = (void *)MTK_VDISP_AO }, +>  { } +>  }; +>   +> @@ -1111,7 +1244,7 @@ static int mtk_drm_probe(struct platform_device *pdev) +>  private->data = mtk_drm_data; +>  }; +>   +> -private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num, +> +private->all_drm_private = devm_kmalloc_array(dev, MAX_MMSYS, +>        sizeof(*private->all_drm_private), +>        GFP_KERNEL); +>  if (!private->all_drm_private) +> @@ -1163,6 +1296,22 @@ static int mtk_drm_probe(struct platform_device *pdev) +>  component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev); +>  } +>   +> +if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2)) { +> +struct mtk_drm_ovlsys_private ovlsys_priv; +> + +> +ovlsys_priv.mmsys_dev = private->mmsys_dev; +> +ovlsys_priv.use_path = +> +mtk_drm_mmsys_comp_in_path(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2); +> +ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovlsys-adaptor", +> +    PLATFORM_DEVID_AUTO, +> +    (void *)&ovlsys_priv, +> +    sizeof(struct mtk_drm_ovlsys_private)); +> +private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2].dev = &ovl_adaptor->dev; +> +mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2], +> +  DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2); +> +component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev); +> +} +> + +>  /* Iterate over sibling DISP function blocks */ +>  for_each_child_of_node(phandle->parent, node) { +>  enum mtk_ddp_comp_type comp_type; +> @@ -1189,6 +1338,12 @@ static int mtk_drm_probe(struct platform_device *pdev) +>  continue; +>  } +>   +> +if (comp_type == MTK_VDISP_AO) { +> +private->vdisp_ao_node = of_node_get(node); +> +dev_dbg(dev, "get vdisp_ao node"); +> +continue; +> +} +> + +>  comp_id = mtk_ddp_comp_get_id(node, comp_type); +>  if (comp_id < 0) { +>  dev_warn(dev, "Skipping unknown component %pOF\n", +> @@ -1241,6 +1396,9 @@ static int mtk_drm_probe(struct platform_device *pdev) +>   +>  platform_set_drvdata(pdev, private); +>   +> +if (!match) +> +drm_of_component_match_add(dev, &match, component_compare_of, NULL); +> + +>  ret = component_master_add_with_match(dev, &mtk_drm_ops, match); +>  if (ret) +>  goto err_pm; +> @@ -1264,6 +1422,7 @@ static void mtk_drm_remove(struct platform_device *pdev) +>  component_master_del(&pdev->dev, &mtk_drm_ops); +>  pm_runtime_disable(&pdev->dev); +>  of_node_put(private->mutex_node); +> +of_node_put(private->vdisp_ao_node); +>  for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++) +>  of_node_put(private->comp_node[i]); +>  } +> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +> index aa17e743a1d0..36cfbfa30ff2 100644 +> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h +> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h +> @@ -13,7 +13,8 @@ +>  #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1) +>  #define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1) +>  #define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 + 1) +> -#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1) +> +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1) +> +#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 + 1) +>   +>  enum mtk_crtc_path { +>  CRTC_MAIN, +> @@ -22,6 +23,14 @@ enum mtk_crtc_path { +>  MAX_CRTC, +>  }; +>   +> +enum mtk_drm_mmsys { +> +DISPSYS0, +> +DISPSYS1, +> +OVLSYS0, +> +OVLSYS1, +> +MAX_MMSYS, +> +}; +> + +>  struct device; +>  struct device_node; +>  struct drm_crtc; +> @@ -38,10 +47,13 @@ struct mtk_drm_route { +>  struct mtk_mmsys_driver_data { +>  const unsigned int *main_path; +>  unsigned int main_len; +> +unsigned int main_order; +>  const unsigned int *ext_path; +>  unsigned int ext_len; +> +unsigned int ext_order; +>  const unsigned int *third_path; +>  unsigned int third_len; +> +unsigned int third_order; +>  const struct mtk_drm_route *conn_routes; +>  unsigned int num_conn_routes; +>   +> @@ -63,6 +75,8 @@ struct mtk_drm_private { +>  struct device_node *mutex_node; +>  struct device *mutex_dev; +>  struct device *mmsys_dev; +> +struct device_node *vdisp_ao_node; +> +struct device *vdisp_ao_dev; +>  struct device_node *comp_node[DDP_COMPONENT_DRM_ID_MAX]; +>  struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_DRM_ID_MAX]; +>  struct mtk_mmsys_driver_data *data; + + +</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><!--}--> diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..da1f671 --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,3 @@ +Content-Type: text/html; + charset="utf-8" +Content-Transfer-Encoding: base64 diff --git a/a/content_digest b/N1/content_digest index 49a5d70..8325194 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -24,7 +24,7 @@ p.zabel@pengutronix.de <p.zabel@pengutronix.de> " Sirius Wang (\347\216\213\347\232\223\346\230\261) <Sirius.Wang@mediatek.com>" " linux-arm-kernel@lists.infradead.org <linux-arm-kernel@lists.infradead.org>\0" - "\00:1\0" + "\01:1\0" "b\0" "Hi, Paul:\n" "\n" @@ -1337,5 +1337,1338 @@ "> \tstruct device_node *comp_node[DDP_COMPONENT_DRM_ID_MAX];\n" "> \tstruct mtk_ddp_comp ddp_comp[DDP_COMPONENT_DRM_ID_MAX];\n" "> \tstruct mtk_mmsys_driver_data *data;" + "\01:2\0" + "b\0" + "<html><body><p>\r\n" + "<pre>\r\n" + "Hi, Paul:\r\n" + "\r\n" + "On Fri, 2025-01-10 at 20:34 +0800, paul-pl.chen wrote:\r\n" + "> From: "Nancy.Lin" <nancy.lin@mediatek.com>\r\n" + "> \r\n" + "> To support multiple mmsys instances in the one mediatek-drm instance,\r\n" + "> providing improved flexibility and scalability by the following changes:\r\n" + "> \r\n" + "> 1. Defined new DRM component IDs DDP_COMPONENT_DRM_OVLSYS_ADAPTOR*\r\n" + ">   to support different mmsys composition.\r\n" + "> 2. Added new component types MTK_DISP_VIRTUAL to support the\r\n" + ">   routing to virtual display components.\r\n" + "> 3. Added and adjusted the existed structure or interface to extend\r\n" + ">   the support of multiple mmsys instances.\r\n" + "> 4. Modified the component matching and binding logic to support\r\n" + ">   multiple mmsys instances.\r\n" + "\r\n" + "I think the title would confuse me.\r\n" + "Original mediatek-drm driver already support multiple mmsys.\r\n" + "I try to understand MT8196 display.\r\n" + "Is one display pipeline separated into two mmsys?\r\n" + "The first is ovlsys and the second is dispsys?\r\n" + "If so, I would like mediatek-drm driver see only mmsys (dispsys),\r\n" + "and let ovlsys control is hidden in ovlsys sub driver, so mediatek-drm driver would not change so much.\r\n" + "\r\n" + "> \r\n" + "> Signed-off-by: Nancy.Lin <nancy.lin@mediatek.com>\r\n" + "> Signed-off-by: Paul-pl.Chen <paul-pl.chen@mediatek.com>\r\n" + "> ---\r\n" + ">  drivers/gpu/drm/mediatek/mtk_crtc.c     | 350 +++++++++++++++++++-----\r\n" + ">  drivers/gpu/drm/mediatek/mtk_crtc.h     |   6 +-\r\n" + ">  drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 106 +++++--\r\n" + ">  drivers/gpu/drm/mediatek/mtk_ddp_comp.h |   2 +\r\n" + ">  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 223 ++++++++++++---\r\n" + ">  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  16 +-\r\n" + ">  6 files changed, 578 insertions(+), 125 deletions(-)\r\n" + "> \r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c\r\n" + "> index eb0e1233ad04..eca6941bfaa2 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_crtc.c\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c\r\n" + "> @@ -58,13 +58,17 @@ struct mtk_crtc {\r\n" + ">  wait_queue_head_tcb_blocking_queue;\r\n" + ">  #endif\r\n" + ">  \r\n" + "> -struct device*mmsys_dev;\r\n" + "> +struct device*mmsys_dev[MAX_MMSYS];\r\n" + ">  struct device*dma_dev;\r\n" + "> -struct mtk_mutex*mutex;\r\n" + "> +struct device*vdisp_ao_dev;\r\n" + "> +struct mtk_mutex*mutex[MAX_MMSYS];\r\n" + ">  unsigned intddp_comp_nr;\r\n" + ">  struct mtk_ddp_comp**ddp_comp;\r\n" + "> +enum mtk_drm_mmsys*ddp_comp_sys;\r\n" + "> +boolexist[MAX_MMSYS];\r\n" + ">  unsigned intnum_conn_routes;\r\n" + ">  const struct mtk_drm_route*conn_routes;\r\n" + "> +enum mtk_drm_mmsysconn_routes_sys;\r\n" + ">  \r\n" + ">  /* lock for display hardware access */\r\n" + ">  struct mutexhw_lock;\r\n" + "> @@ -82,6 +86,11 @@ struct mtk_crtc_state {\r\n" + ">  unsigned intpending_vrefresh;\r\n" + ">  };\r\n" + ">  \r\n" + "> +struct mtk_crtc_comp_info {\r\n" + "> +enum mtk_drm_mmsys sys;\r\n" + "> +unsigned int comp_id;\r\n" + "> +};\r\n" + "> +\r\n" + ">  static inline struct mtk_crtc *to_mtk_crtc(struct drm_crtc *c)\r\n" + ">  {\r\n" + ">  return container_of(c, struct mtk_crtc, base);\r\n" + "> @@ -125,7 +134,9 @@ static void mtk_crtc_destroy(struct drm_crtc *crtc)\r\n" + ">  struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);\r\n" + ">  int i;\r\n" + ">  \r\n" + "> -mtk_mutex_put(mtk_crtc->mutex);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_put(mtk_crtc->mutex[i]);\r\n" + ">  #if IS_REACHABLE(CONFIG_MTK_CMDQ)\r\n" + ">  if (mtk_crtc->cmdq_client.chan) {\r\n" + ">  cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle);\r\n" + "> @@ -223,7 +234,14 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_crtc *mtk_crtc)\r\n" + ">  int i;\r\n" + ">  \r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + "> +enum mtk_drm_mmsys mmsys;\r\n" + "> +\r\n" + ">  ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);\r\n" + "> +if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]->id) == MTK_DISP_VIRTUAL) {\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +ret = mtk_mmsys_ddp_clk_enable(mtk_crtc->mmsys_dev[mmsys],\r\n" + "> +       mtk_crtc->ddp_comp[i]->id);\r\n" + "> +}\r\n" + ">  if (ret) {\r\n" + ">  DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);\r\n" + ">  goto err;\r\n" + "> @@ -232,17 +250,28 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_crtc *mtk_crtc)\r\n" + ">  \r\n" + ">  return 0;\r\n" + ">  err:\r\n" + "> -while (--i >= 0)\r\n" + "> +while (--i >= 0) {\r\n" + ">  mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);\r\n" + "> +if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]->id) == MTK_DISP_VIRTUAL)\r\n" + "> +mtk_mmsys_ddp_clk_disable(mtk_crtc->mmsys_dev[mtk_crtc->ddp_comp_sys[i]],\r\n" + "> +  mtk_crtc->ddp_comp[i]->id);\r\n" + "> +}\r\n" + ">  return ret;\r\n" + ">  }\r\n" + ">  \r\n" + ">  static void mtk_crtc_ddp_clk_disable(struct mtk_crtc *mtk_crtc)\r\n" + ">  {\r\n" + ">  int i;\r\n" + "> +enum mtk_drm_mmsys mmsys;\r\n" + ">  \r\n" + "> -for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)\r\n" + "> +for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + ">  mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);\r\n" + "> +if (mtk_ddp_comp_get_type(mtk_crtc->ddp_comp[i]->id) == MTK_DISP_VIRTUAL) {\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +mtk_mmsys_ddp_clk_disable(mtk_crtc->mmsys_dev[mmsys],\r\n" + "> +  mtk_crtc->ddp_comp[i]->id);\r\n" + "> +}\r\n" + "> +}\r\n" + ">  }\r\n" + ">  \r\n" + ">  static\r\n" + "> @@ -332,7 +361,8 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)\r\n" + ">  struct drm_connector_list_iter conn_iter;\r\n" + ">  unsigned int width, height, vrefresh, bpc = MTK_MAX_BPC;\r\n" + ">  int ret;\r\n" + "> -int i;\r\n" + "> +int i, j;\r\n" + "> +enum mtk_drm_mmsys mmsys;\r\n" + ">  \r\n" + ">  if (WARN_ON(!crtc->state))\r\n" + ">  return -EINVAL;\r\n" + "> @@ -362,10 +392,18 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)\r\n" + ">  return ret;\r\n" + ">  }\r\n" + ">  \r\n" + "> -ret = mtk_mutex_prepare(mtk_crtc->mutex);\r\n" + "> -if (ret < 0) {\r\n" + "> -DRM_ERROR("Failed to enable mutex clock: %d\n", ret);\r\n" + "> -goto err_pm_runtime_put;\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +mtk_mmsys_top_clk_enable(mtk_crtc->mmsys_dev[i]);\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++) {\r\n" + "> +if (!mtk_crtc->mutex[i] || !mtk_crtc->exist[i])\r\n" + "> +continue;\r\n" + "> +ret = mtk_mutex_prepare(mtk_crtc->mutex[i]);\r\n" + "> +if (ret < 0) {\r\n" + "> +DRM_ERROR("Failed to enable mmsys%d mutex clock: %d\n", i, ret);\r\n" + "> +goto err_pm_runtime_put;\r\n" + "> +}\r\n" + ">  }\r\n" + ">  \r\n" + ">  ret = mtk_crtc_ddp_clk_enable(mtk_crtc);\r\n" + "> @@ -374,19 +412,36 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)\r\n" + ">  goto err_mutex_unprepare;\r\n" + ">  }\r\n" + ">  \r\n" + "> +if (mtk_crtc->vdisp_ao_dev)\r\n" + "> +mtk_mmsys_default_config(mtk_crtc->vdisp_ao_dev);\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +mtk_mmsys_default_config(mtk_crtc->mmsys_dev[i]);\r\n" + "> +\r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {\r\n" + "> -if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev[mmsys],\r\n" + ">    mtk_crtc->ddp_comp[i + 1]->id))\r\n" + "> -mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,\r\n" + "> +mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev[mmsys],\r\n" + ">        mtk_crtc->ddp_comp[i]->id,\r\n" + ">        mtk_crtc->ddp_comp[i + 1]->id);\r\n" + "> -if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))\r\n" + "> -mtk_mutex_add_comp(mtk_crtc->mutex,\r\n" + "> +if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex[mmsys]))\r\n" + "> +mtk_mutex_add_comp(mtk_crtc->mutex[mmsys],\r\n" + ">     mtk_crtc->ddp_comp[i]->id);\r\n" + ">  }\r\n" + "> -if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))\r\n" + "> -mtk_mutex_add_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);\r\n" + "> -mtk_mutex_enable(mtk_crtc->mutex);\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +if (!mtk_ddp_comp_add(mtk_crtc->ddp_comp[i], mtk_crtc->mutex[mmsys]))\r\n" + "> +mtk_mutex_add_comp(mtk_crtc->mutex[mmsys], mtk_crtc->ddp_comp[i]->id);\r\n" + "> +\r\n" + "> +/* Need to set sof source for all mmsys mutexs in this crtc */\r\n" + "> +for (j = 0; j < MAX_MMSYS; j++)\r\n" + "> +if (mtk_crtc->exist[j] && mtk_crtc->mutex[j])\r\n" + "> +mtk_mutex_write_comp_sof(mtk_crtc->mutex[j], mtk_crtc->ddp_comp[i]->id);\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_enable(mtk_crtc->mutex[i]);\r\n" + ">  \r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + ">  struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[i];\r\n" + "> @@ -394,7 +449,11 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)\r\n" + ">  if (i == 1)\r\n" + ">  mtk_ddp_comp_bgclr_in_on(comp);\r\n" + ">  \r\n" + "> -mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);\r\n" + "> +if (mtk_ddp_comp_get_type(comp->id) == MTK_DISP_VIRTUAL)\r\n" + "> +mtk_mmsys_ddp_config(mtk_crtc->mmsys_dev[mtk_crtc->ddp_comp_sys[i]],\r\n" + "> +     comp->id, width, height, NULL);\r\n" + "> +else\r\n" + "> +mtk_ddp_comp_config(comp, width, height, vrefresh, bpc, NULL);\r\n" + ">  mtk_ddp_comp_start(comp);\r\n" + ">  }\r\n" + ">  \r\n" + "> @@ -418,7 +477,10 @@ static int mtk_crtc_ddp_hw_init(struct mtk_crtc *mtk_crtc)\r\n" + ">  return 0;\r\n" + ">  \r\n" + ">  err_mutex_unprepare:\r\n" + "> -mtk_mutex_unprepare(mtk_crtc->mutex);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_unprepare(mtk_crtc->mutex[i]);\r\n" + "> +\r\n" + ">  err_pm_runtime_put:\r\n" + ">  pm_runtime_put(crtc->dev->dev);\r\n" + ">  return ret;\r\n" + "> @@ -430,6 +492,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_crtc *mtk_crtc)\r\n" + ">  struct drm_crtc *crtc = &mtk_crtc->base;\r\n" + ">  unsigned long flags;\r\n" + ">  int i;\r\n" + "> +enum mtk_drm_mmsys mmsys;\r\n" + ">  \r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + ">  mtk_ddp_comp_stop(mtk_crtc->ddp_comp[i]);\r\n" + "> @@ -437,27 +500,46 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_crtc *mtk_crtc)\r\n" + ">  mtk_ddp_comp_bgclr_in_off(mtk_crtc->ddp_comp[i]);\r\n" + ">  }\r\n" + ">  \r\n" + "> -for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)\r\n" + "> -if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))\r\n" + "> -mtk_mutex_remove_comp(mtk_crtc->mutex,\r\n" + "> +for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex[mmsys]))\r\n" + "> +mtk_mutex_remove_comp(mtk_crtc->mutex[mtk_crtc->ddp_comp_sys[i]],\r\n" + ">        mtk_crtc->ddp_comp[i]->id);\r\n" + "> -mtk_mutex_disable(mtk_crtc->mutex);\r\n" + "> +}\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_disable(mtk_crtc->mutex[i]);\r\n" + "> +\r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {\r\n" + "> -if (!mtk_ddp_comp_disconnect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev,\r\n" + "> -     mtk_crtc->ddp_comp[i + 1]->id))\r\n" + "> -mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,\r\n" + "> - mtk_crtc->ddp_comp[i]->id,\r\n" + "> - mtk_crtc->ddp_comp[i + 1]->id);\r\n" + "> -if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))\r\n" + "> -mtk_mutex_remove_comp(mtk_crtc->mutex,\r\n" + "> +struct mtk_ddp_comp *comp;\r\n" + "> +unsigned int curr, next;\r\n" + "> +\r\n" + "> +comp = mtk_crtc->ddp_comp[i];\r\n" + "> +curr = mtk_crtc->ddp_comp[i]->id;\r\n" + "> +next = mtk_crtc->ddp_comp[i + 1]->id;\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +if (!mtk_ddp_comp_disconnect(comp, mtk_crtc->mmsys_dev[mmsys], next))\r\n" + "> +mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev[mmsys], curr, next);\r\n" + "> +if (!mtk_ddp_comp_remove(comp, mtk_crtc->mutex[mmsys]))\r\n" + "> +mtk_mutex_remove_comp(mtk_crtc->mutex[mtk_crtc->ddp_comp_sys[i]],\r\n" + ">        mtk_crtc->ddp_comp[i]->id);\r\n" + ">  }\r\n" + "> -if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex))\r\n" + "> -mtk_mutex_remove_comp(mtk_crtc->mutex, mtk_crtc->ddp_comp[i]->id);\r\n" + "> +\r\n" + "> +mmsys = mtk_crtc->ddp_comp_sys[i];\r\n" + "> +if (!mtk_ddp_comp_remove(mtk_crtc->ddp_comp[i], mtk_crtc->mutex[mmsys]))\r\n" + "> +mtk_mutex_remove_comp(mtk_crtc->mutex[mmsys], mtk_crtc->ddp_comp[i]->id);\r\n" + "> +\r\n" + ">  mtk_crtc_ddp_clk_disable(mtk_crtc);\r\n" + "> -mtk_mutex_unprepare(mtk_crtc->mutex);\r\n" + ">  \r\n" + "> -pm_runtime_put(drm->dev);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_unprepare(mtk_crtc->mutex[i]);\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +mtk_mmsys_top_clk_disable(mtk_crtc->mmsys_dev[i]);\r\n" + "> +\r\n" + "> +pm_runtime_put_sync(drm->dev);\r\n" + ">  \r\n" + ">  if (crtc->state->event && !crtc->state->active) {\r\n" + ">  spin_lock_irqsave(&crtc->dev->event_lock, flags);\r\n" + "> @@ -581,9 +663,15 @@ static void mtk_crtc_update_config(struct mtk_crtc *mtk_crtc, bool needs_vblank)\r\n" + ">  mtk_crtc->pending_async_planes = true;\r\n" + ">  \r\n" + ">  if (priv->data->shadow_register) {\r\n" + "> -mtk_mutex_acquire(mtk_crtc->mutex);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_acquire(mtk_crtc->mutex[i]);\r\n" + "> +\r\n" + ">  mtk_crtc_ddp_config(crtc, NULL);\r\n" + "> -mtk_mutex_release(mtk_crtc->mutex);\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i] && mtk_crtc->mutex[i])\r\n" + "> +mtk_mutex_release(mtk_crtc->mutex[i]);\r\n" + ">  }\r\n" + ">  #if IS_REACHABLE(CONFIG_MTK_CMDQ)\r\n" + ">  if (mtk_crtc->cmdq_client.chan) {\r\n" + "> @@ -659,6 +747,7 @@ static void mtk_crtc_update_output(struct drm_crtc *crtc,\r\n" + ">  {\r\n" + ">  int crtc_index = drm_crtc_index(crtc);\r\n" + ">  int i;\r\n" + "> +unsigned int mmsys;\r\n" + ">  struct device *dev;\r\n" + ">  struct drm_crtc_state *crtc_state = state->crtcs[crtc_index].new_state;\r\n" + ">  struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);\r\n" + "> @@ -671,7 +760,8 @@ static void mtk_crtc_update_output(struct drm_crtc *crtc,\r\n" + ">  if (!mtk_crtc->num_conn_routes)\r\n" + ">  return;\r\n" + ">  \r\n" + "> -priv = ((struct mtk_drm_private *)crtc->dev->dev_private)->all_drm_private[crtc_index];\r\n" + "> +mmsys = mtk_crtc->conn_routes_sys;\r\n" + "> +priv = ((struct mtk_drm_private *)crtc->dev->dev_private)->all_drm_private[mmsys];\r\n" + ">  dev = priv->dev;\r\n" + ">  \r\n" + ">  dev_dbg(dev, "connector change:%d, encoder mask:0x%x for crtc:%d\n",\r\n" + "> @@ -684,6 +774,8 @@ static void mtk_crtc_update_output(struct drm_crtc *crtc,\r\n" + ">  if (comp->encoder_index >= 0 &&\r\n" + ">      (encoder_mask & BIT(comp->encoder_index))) {\r\n" + ">  mtk_crtc->ddp_comp[mtk_crtc->ddp_comp_nr - 1] = comp;\r\n" + "> +mtk_crtc->ddp_comp_sys[mtk_crtc->ddp_comp_nr - 1] = mmsys;\r\n" + "> +mtk_crtc->exist[mmsys] = true;\r\n" + ">  dev_dbg(dev, "Add comp_id: %d at path index %d\n",\r\n" + ">  comp->id, mtk_crtc->ddp_comp_nr - 1);\r\n" + ">  break;\r\n" + "> @@ -720,13 +812,35 @@ static void mtk_crtc_atomic_enable(struct drm_crtc *crtc,\r\n" + ">  struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);\r\n" + ">  struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];\r\n" + ">  int ret;\r\n" + "> +int i, j;\r\n" + "> +int mmsys_cnt = 0;\r\n" + ">  \r\n" + ">  DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);\r\n" + ">  \r\n" + "> -ret = mtk_ddp_comp_power_on(comp);\r\n" + "> -if (ret < 0) {\r\n" + "> -DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);\r\n" + "> -return;\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +mmsys_cnt++;\r\n" + "> +\r\n" + "> +if (mmsys_cnt == 1) {\r\n" + "> +ret = pm_runtime_resume_and_get(comp->dev);\r\n" + "> +if (ret < 0) {\r\n" + "> +DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);\r\n" + "> +return;\r\n" + "> +}\r\n" + "> +} else {\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++) {\r\n" + "> +if (!mtk_crtc->exist[i])\r\n" + "> +continue;\r\n" + "> +ret = pm_runtime_resume_and_get(mtk_crtc->mmsys_dev[i]);\r\n" + "> +if (ret < 0) {\r\n" + "> +DRM_DEV_ERROR(mtk_crtc->mmsys_dev[i],\r\n" + "> +      "Failed to enable power domain: %d\n", ret);\r\n" + "> +for (j = i - 1; j >= 0; j--)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +pm_runtime_put(comp->dev);\r\n" + "> +return;\r\n" + "> +}\r\n" + "> +}\r\n" + ">  }\r\n" + ">  \r\n" + ">  mtk_crtc_update_output(crtc, state);\r\n" + "> @@ -746,12 +860,17 @@ static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,\r\n" + ">  {\r\n" + ">  struct mtk_crtc *mtk_crtc = to_mtk_crtc(crtc);\r\n" + ">  struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];\r\n" + "> -int i;\r\n" + "> +int i, ret;\r\n" + "> +int mmsys_cnt = 0;\r\n" + ">  \r\n" + ">  DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);\r\n" + ">  if (!mtk_crtc->enabled)\r\n" + ">  return;\r\n" + ">  \r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +mmsys_cnt++;\r\n" + "> +\r\n" + ">  /* Set all pending plane state to disabled */\r\n" + ">  for (i = 0; i < mtk_crtc->layer_nr; i++) {\r\n" + ">  struct drm_plane *plane = &mtk_crtc->planes[i];\r\n" + "> @@ -776,7 +895,21 @@ static void mtk_crtc_atomic_disable(struct drm_crtc *crtc,\r\n" + ">  \r\n" + ">  drm_crtc_vblank_off(crtc);\r\n" + ">  mtk_crtc_ddp_hw_fini(mtk_crtc);\r\n" + "> -mtk_ddp_comp_power_off(comp);\r\n" + "> +\r\n" + "> +if (mmsys_cnt > 1) {\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++) {\r\n" + "> +if (mtk_crtc->exist[i]) {\r\n" + "> +ret = pm_runtime_put(mtk_crtc->mmsys_dev[i]);\r\n" + "> +if (ret < 0)\r\n" + "> +DRM_DEV_ERROR(mtk_crtc->mmsys_dev[i],\r\n" + "> +      "Failed to disable power domain: %d\n", ret);\r\n" + "> +}\r\n" + "> +}\r\n" + "> +} else {\r\n" + "> +ret = pm_runtime_put(comp->dev);\r\n" + "> +if (ret < 0)\r\n" + "> +DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);\r\n" + "> +}\r\n" + ">  \r\n" + ">  mtk_crtc->enabled = false;\r\n" + ">  }\r\n" + "> @@ -937,49 +1070,108 @@ struct device *mtk_crtc_dma_dev_get(struct drm_crtc *crtc)\r\n" + ">  return mtk_crtc->dma_dev;\r\n" + ">  }\r\n" + ">  \r\n" + "> -int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + "> -    unsigned int path_len, int priv_data_index,\r\n" + "> -    const struct mtk_drm_route *conn_routes,\r\n" + "> -    unsigned int num_conn_routes)\r\n" + "> +int mtk_crtc_create(struct drm_device *drm_dev, enum mtk_crtc_path path_sel)\r\n" + ">  {\r\n" + ">  struct mtk_drm_private *priv = drm_dev->dev_private;\r\n" + ">  struct device *dev = drm_dev->dev;\r\n" + ">  struct mtk_crtc *mtk_crtc;\r\n" + ">  unsigned int num_comp_planes = 0;\r\n" + ">  int ret;\r\n" + "> -int i;\r\n" + "> +int i, j, k;\r\n" + ">  bool has_ctm = false;\r\n" + ">  uint gamma_lut_size = 0;\r\n" + ">  struct drm_crtc *tmp;\r\n" + ">  int crtc_i = 0;\r\n" + "> -\r\n" + "> -if (!path)\r\n" + "> -return 0;\r\n" + "> -\r\n" + "> -priv = priv->all_drm_private[priv_data_index];\r\n" + "> +struct mtk_drm_private *subsys_priv;\r\n" + "> +struct mtk_crtc_comp_info path[DDP_COMPONENT_ID_MAX];\r\n" + "> +unsigned int path_len = 0;\r\n" + "> +const struct mtk_drm_route *conn_routes = NULL;\r\n" + "> +unsigned int num_conn_routes = 0;\r\n" + "> +enum mtk_drm_mmsys conn_mmsys;\r\n" + ">  \r\n" + ">  drm_for_each_crtc(tmp, drm_dev)\r\n" + ">  crtc_i++;\r\n" + ">  \r\n" + "> +for (j = 0; j < priv->data->mmsys_dev_num; j++) {\r\n" + "> +for (k = 0; k < MAX_MMSYS; k++) {\r\n" + "> +const unsigned int *subsys_path;\r\n" + "> +unsigned int subsys_path_len;\r\n" + "> +unsigned int order = 0;\r\n" + "> +\r\n" + "> +subsys_priv = priv->all_drm_private[k];\r\n" + "> +if (!subsys_priv)\r\n" + "> +continue;\r\n" + "> +\r\n" + "> +if (path_sel == CRTC_MAIN) {\r\n" + "> +subsys_path = subsys_priv->data->main_path;\r\n" + "> +subsys_path_len = subsys_priv->data->main_len;\r\n" + "> +order = subsys_priv->data->main_order;\r\n" + "> +} else if (path_sel == CRTC_EXT) {\r\n" + "> +subsys_path = subsys_priv->data->ext_path;\r\n" + "> +subsys_path_len = subsys_priv->data->ext_len;\r\n" + "> +order = subsys_priv->data->ext_order;\r\n" + "> +} else if (path_sel == CRTC_THIRD) {\r\n" + "> +subsys_path = subsys_priv->data->third_path;\r\n" + "> +subsys_path_len = subsys_priv->data->third_len;\r\n" + "> +order = subsys_priv->data->third_order;\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (subsys_priv->data->num_conn_routes) {\r\n" + "> +conn_routes = subsys_priv->data->conn_routes;\r\n" + "> +num_conn_routes = subsys_priv->data->num_conn_routes;\r\n" + "> +conn_mmsys = subsys_priv->data->mmsys_id;\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (j != order)\r\n" + "> +continue;\r\n" + "> +if (!subsys_path_len)\r\n" + "> +continue;\r\n" + "> +\r\n" + "> +for (i = 0; i < subsys_path_len; i++) {\r\n" + "> +path[path_len].sys = subsys_priv->data->mmsys_id;\r\n" + "> +path[path_len].comp_id = subsys_path[i];\r\n" + "> +path_len++;\r\n" + "> +}\r\n" + "> +}\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (!path_len)\r\n" + "> +return 0;\r\n" + "> +\r\n" + "> +if (num_conn_routes) {\r\n" + "> +for (i = 0; i < num_conn_routes; i++)\r\n" + "> +if (conn_routes->crtc_id == crtc_i)\r\n" + "> +break;\r\n" + "> +if (i == num_conn_routes) {\r\n" + "> +num_conn_routes = 0;\r\n" + "> +conn_routes = NULL;\r\n" + "> +}\r\n" + "> +}\r\n" + "> +\r\n" + ">  for (i = 0; i < path_len; i++) {\r\n" + "> -enum mtk_ddp_comp_id comp_id = path[i];\r\n" + "> +enum mtk_ddp_comp_id comp_id = path[i].comp_id;\r\n" + ">  struct device_node *node;\r\n" + ">  struct mtk_ddp_comp *comp;\r\n" + ">  \r\n" + "> +priv = priv->all_drm_private[path[i].sys];\r\n" + ">  node = priv->comp_node[comp_id];\r\n" + ">  comp = &priv->ddp_comp[comp_id];\r\n" + ">  \r\n" + ">  /* Not all drm components have a DTS device node, such as ovl_adaptor,\r\n" + ">   * which is the drm bring up sub driver\r\n" + ">   */\r\n" + "> -if (!node && comp_id != DDP_COMPONENT_DRM_OVL_ADAPTOR) {\r\n" + "> +if (!node && comp_id != DDP_COMPONENT_DRM_OVL_ADAPTOR &&\r\n" + "> +    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 &&\r\n" + "> +    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 &&\r\n" + "> +    comp_id != DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 &&\r\n" + "> +    mtk_ddp_comp_get_type(comp_id) != MTK_DISP_VIRTUAL) {\r\n" + ">  dev_info(dev,\r\n" + ">  "Not creating crtc %d because component %d is disabled or missing\n",\r\n" + ">  crtc_i, comp_id);\r\n" + ">  return 0;\r\n" + ">  }\r\n" + ">  \r\n" + "> -if (!comp->dev) {\r\n" + "> +if (!comp->dev && mtk_ddp_comp_get_type(comp_id) != MTK_DISP_VIRTUAL) {\r\n" + ">  dev_err(dev, "Component %pOF not initialized\n", node);\r\n" + ">  return -ENODEV;\r\n" + ">  }\r\n" + "> @@ -989,7 +1181,9 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  if (!mtk_crtc)\r\n" + ">  return -ENOMEM;\r\n" + ">  \r\n" + "> -mtk_crtc->mmsys_dev = priv->mmsys_dev;\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (priv->all_drm_private[i])\r\n" + "> +mtk_crtc->mmsys_dev[i] = priv->all_drm_private[i]->mmsys_dev;\r\n" + ">  mtk_crtc->ddp_comp_nr = path_len;\r\n" + ">  mtk_crtc->ddp_comp = devm_kcalloc(dev,\r\n" + ">    mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0),\r\n" + "> @@ -998,19 +1192,36 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  if (!mtk_crtc->ddp_comp)\r\n" + ">  return -ENOMEM;\r\n" + ">  \r\n" + "> -mtk_crtc->mutex = mtk_mutex_get(priv->mutex_dev);\r\n" + "> -if (IS_ERR(mtk_crtc->mutex)) {\r\n" + "> -ret = PTR_ERR(mtk_crtc->mutex);\r\n" + "> -dev_err(dev, "Failed to get mutex: %d\n", ret);\r\n" + "> -return ret;\r\n" + "> +mtk_crtc->ddp_comp_sys = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr +\r\n" + "> +    (conn_routes ? 1 : 0),\r\n" + "> +    sizeof(mtk_crtc->ddp_comp_sys), GFP_KERNEL);\r\n" + "> +if (!mtk_crtc->ddp_comp_sys)\r\n" + "> +return -ENOMEM;\r\n" + "> +\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++) {\r\n" + "> +if (!priv->all_drm_private[i])\r\n" + "> +continue;\r\n" + "> +\r\n" + "> +priv = priv->all_drm_private[i];\r\n" + "> +mtk_crtc->mutex[i] = mtk_mutex_get(priv->mutex_dev);\r\n" + "> +if (IS_ERR(mtk_crtc->mutex[i])) {\r\n" + "> +ret = PTR_ERR(mtk_crtc->mutex[i]);\r\n" + "> +dev_err(dev, "Failed to get mutex: %d\n", ret);\r\n" + "> +return ret;\r\n" + "> +}\r\n" + ">  }\r\n" + ">  \r\n" + ">  for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {\r\n" + "> -unsigned int comp_id = path[i];\r\n" + "> +unsigned int comp_id = path[i].comp_id;\r\n" + ">  struct mtk_ddp_comp *comp;\r\n" + ">  \r\n" + "> +priv = priv->all_drm_private[path[i].sys];\r\n" + ">  comp = &priv->ddp_comp[comp_id];\r\n" + "> +if (mtk_ddp_comp_get_type(comp_id) == MTK_DISP_VIRTUAL)\r\n" + "> +comp->id = comp_id;\r\n" + ">  mtk_crtc->ddp_comp[i] = comp;\r\n" + "> +mtk_crtc->ddp_comp_sys[i] = path[i].sys;\r\n" + "> +mtk_crtc->exist[path[i].sys] = true;\r\n" + ">  \r\n" + ">  if (comp->funcs) {\r\n" + ">  if (comp->funcs->gamma_set && comp->funcs->gamma_get_lut_size) {\r\n" + "> @@ -1047,8 +1258,10 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">   * In the case of ovl_adaptor sub driver, it needs to use the\r\n" + ">   * dma_dev_get function to get representative dma dev.\r\n" + ">   */\r\n" + "> -mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv->ddp_comp[path[0]]);\r\n" + "> +priv = priv->all_drm_private[path[0].sys];\r\n" + "> +mtk_crtc->dma_dev = mtk_ddp_comp_dma_dev_get(&priv->ddp_comp[path[0].comp_id]);\r\n" + ">  \r\n" + "> +mtk_crtc->vdisp_ao_dev = priv->vdisp_ao_dev;\r\n" + ">  ret = mtk_crtc_init(drm_dev, mtk_crtc, crtc_i);\r\n" + ">  if (ret < 0)\r\n" + ">  return ret;\r\n" + "> @@ -1061,7 +1274,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  \r\n" + ">  #if IS_REACHABLE(CONFIG_MTK_CMDQ)\r\n" + ">  i = priv->mbox_index++;\r\n" + "> -mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;\r\n" + "> +mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev[priv->data->mmsys_id];\r\n" + ">  mtk_crtc->cmdq_client.client.tx_block = false;\r\n" + ">  mtk_crtc->cmdq_client.client.knows_txdone = true;\r\n" + ">  mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;\r\n" + "> @@ -1101,6 +1314,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  #endif\r\n" + ">  \r\n" + ">  if (conn_routes) {\r\n" + "> +priv = priv->all_drm_private[conn_mmsys];\r\n" + ">  for (i = 0; i < num_conn_routes; i++) {\r\n" + ">  unsigned int comp_id = conn_routes[i].route_ddp;\r\n" + ">  struct device_node *node = priv->comp_node[comp_id];\r\n" + "> @@ -1117,6 +1331,7 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  mtk_ddp_comp_encoder_index_set(&priv->ddp_comp[comp_id]);\r\n" + ">  }\r\n" + ">  \r\n" + "> +mtk_crtc->conn_routes_sys = conn_mmsys;\r\n" + ">  mtk_crtc->num_conn_routes = num_conn_routes;\r\n" + ">  mtk_crtc->conn_routes = conn_routes;\r\n" + ">  \r\n" + "> @@ -1124,5 +1339,10 @@ int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + ">  mtk_crtc->ddp_comp_nr++;\r\n" + ">  }\r\n" + ">  \r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (mtk_crtc->exist[i])\r\n" + "> +device_link_add(mtk_crtc->base.dev->dev,\r\n" + "> +priv->all_drm_private[i]->mutex_dev, 0);\r\n" + "> +\r\n" + ">  return 0;\r\n" + ">  }\r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.h b/drivers/gpu/drm/mediatek/mtk_crtc.h\r\n" + "> index 388e900b6f4d..255f2823d17a 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_crtc.h\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_crtc.h\r\n" + "> @@ -15,10 +15,8 @@\r\n" + ">  #define MTK_MIN_BPC3\r\n" + ">  \r\n" + ">  void mtk_crtc_commit(struct drm_crtc *crtc);\r\n" + "> -int mtk_crtc_create(struct drm_device *drm_dev, const unsigned int *path,\r\n" + "> -    unsigned int path_len, int priv_data_index,\r\n" + "> -    const struct mtk_drm_route *conn_routes,\r\n" + "> -    unsigned int num_conn_routes);\r\n" + "> +int mtk_crtc_create(struct drm_device *drm_dev,\r\n" + "> +    enum mtk_crtc_path path_sel);\r\n" + ">  int mtk_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,\r\n" + ">   struct mtk_plane_state *state);\r\n" + ">  void mtk_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,\r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c\r\n" + "> index 492b8d965309..f841184d1e06 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c\r\n" + "> @@ -464,6 +464,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {\r\n" + ">  [MTK_DISP_PWM] = "pwm",\r\n" + ">  [MTK_DISP_RDMA] = "rdma",\r\n" + ">  [MTK_DISP_UFOE] = "ufoe",\r\n" + "> +[MTK_DISP_VIRTUAL] = "virtual",\r\n" + ">  [MTK_DISP_WDMA] = "wdma",\r\n" + ">  [MTK_DP_INTF] = "dp-intf",\r\n" + ">  [MTK_DPI] = "dpi",\r\n" + "> @@ -487,6 +488,15 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]\r\n" + ">  [DDP_COMPONENT_COLOR0]= { MTK_DISP_COLOR,0, &ddp_color },\r\n" + ">  [DDP_COMPONENT_COLOR1]= { MTK_DISP_COLOR,1, &ddp_color },\r\n" + ">  [DDP_COMPONENT_DITHER0]= { MTK_DISP_DITHER,0, &ddp_dither },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC0]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC1]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC8]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC21]     = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC22]     = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLI_ASYNC23]     = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLO_ASYNC1]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLO_ASYNC2]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_DLO_ASYNC3]      = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + ">  [DDP_COMPONENT_DP_INTF0]= { MTK_DP_INTF,0, &ddp_dpi },\r\n" + ">  [DDP_COMPONENT_DP_INTF1]= { MTK_DP_INTF,1, &ddp_dpi },\r\n" + ">  [DDP_COMPONENT_DPI0]= { MTK_DPI,0, &ddp_dpi },\r\n" + "> @@ -494,6 +504,9 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]\r\n" + ">  [DDP_COMPONENT_DRM_OVL_ADAPTOR]= { MTK_DISP_OVL_ADAPTOR,0, &ddp_ovl_adaptor },\r\n" + ">  [DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0] = { MTK_DISP_OVLSYS_ADAPTOR, 0, &ddp_ovlsys_adaptor},\r\n" + ">  [DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1] = { MTK_DISP_OVLSYS_ADAPTOR, 1, &ddp_ovlsys_adaptor},\r\n" + "> +[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0] = { MTK_DISP_OVLSYS_ADAPTOR, 0, &ddp_ovlsys_adaptor},\r\n" + "> +[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1] = { MTK_DISP_OVLSYS_ADAPTOR, 1, &ddp_ovlsys_adaptor},\r\n" + "> +[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2] = { MTK_DISP_OVLSYS_ADAPTOR, 2, &ddp_ovlsys_adaptor},\r\n" + ">  [DDP_COMPONENT_DSC0]= { MTK_DISP_DSC,0, &ddp_dsc },\r\n" + ">  [DDP_COMPONENT_DSC1]= { MTK_DISP_DSC,1, &ddp_dsc },\r\n" + ">  [DDP_COMPONENT_DSI0]= { MTK_DSI,0, &ddp_dsi },\r\n" + "> @@ -510,7 +523,10 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]\r\n" + ">  [DDP_COMPONENT_OD0]= { MTK_DISP_OD,0, &ddp_od },\r\n" + ">  [DDP_COMPONENT_OD1]= { MTK_DISP_OD,1, &ddp_od },\r\n" + ">  [DDP_COMPONENT_OVL0]= { MTK_DISP_OVL,0, &ddp_ovl },\r\n" + "> +[DDP_COMPONENT_OVL0_DLO_ASYNC5] = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + "> +[DDP_COMPONENT_OVL0_DLO_ASYNC6] = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + ">  [DDP_COMPONENT_OVL1]= { MTK_DISP_OVL,1, &ddp_ovl },\r\n" + "> +[DDP_COMPONENT_OVL1_DLO_ASYNC5] = { MTK_DISP_VIRTUAL,           -1, NULL },\r\n" + ">  [DDP_COMPONENT_OVL_2L0]= { MTK_DISP_OVL_2L,0, &ddp_ovl },\r\n" + ">  [DDP_COMPONENT_OVL_2L1]= { MTK_DISP_OVL_2L,1, &ddp_ovl },\r\n" + ">  [DDP_COMPONENT_OVL_2L2]= { MTK_DISP_OVL_2L,2, &ddp_ovl },\r\n" + "> @@ -567,12 +583,19 @@ static bool mtk_ddp_path_available(const unsigned int *path,\r\n" + ">  {\r\n" + ">  unsigned int i;\r\n" + ">  \r\n" + "> +if (!path_len)\r\n" + "> +return true;\r\n" + "> +\r\n" + ">  if (!path || !path_len)\r\n" + ">  return false;\r\n" + ">  \r\n" + ">  for (i = 0U; i < path_len; i++) {\r\n" + ">  /* OVL_ADAPTOR doesn't have a device node */\r\n" + "> -if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR)\r\n" + "> +if (path[i] == DDP_COMPONENT_DRM_OVL_ADAPTOR ||\r\n" + "> +    path[i] == DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 ||\r\n" + "> +path[i] == DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 ||\r\n" + "> +path[i] == DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 ||\r\n" + "> +mtk_ddp_comp_get_type(path[i]) == MTK_DISP_VIRTUAL)\r\n" + ">  continue;\r\n" + ">  \r\n" + ">  if (!comp_node[path[i]])\r\n" + "> @@ -597,44 +620,81 @@ int mtk_ddp_comp_get_id(struct device_node *node,\r\n" + ">  return -EINVAL;\r\n" + ">  }\r\n" + ">  \r\n" + "> +enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id)\r\n" + "> +{\r\n" + "> +return mtk_ddp_matches[comp_id].type;\r\n" + "> +}\r\n" + "> +\r\n" + ">  int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev)\r\n" + ">  {\r\n" + ">  struct mtk_drm_private *private = drm->dev_private;\r\n" + ">  const struct mtk_mmsys_driver_data *data;\r\n" + ">  struct mtk_drm_private *priv_n;\r\n" + "> -int i = 0, j;\r\n" + ">  int ret;\r\n" + "> +int i = 0, j, count = 0;\r\n" + "> +bool found = false;\r\n" + ">  \r\n" + ">  for (j = 0; j < private->data->mmsys_dev_num; j++) {\r\n" + ">  priv_n = private->all_drm_private[j];\r\n" + ">  data = priv_n->data;\r\n" + ">  \r\n" + ">  if (mtk_ddp_path_available(data->main_path, data->main_len,\r\n" + "> -   priv_n->comp_node)) {\r\n" + "> -if (mtk_ddp_comp_find(dev, data->main_path,\r\n" + "> -      data->main_len,\r\n" + "> -      priv_n->ddp_comp))\r\n" + "> -return BIT(i);\r\n" + "> -i++;\r\n" + "> -}\r\n" + "> +   priv_n->comp_node))\r\n" + "> +count++;\r\n" + "> +\r\n" + "> +if (mtk_ddp_comp_find(dev, data->main_path, data->main_len,\r\n" + "> +      priv_n->ddp_comp))\r\n" + "> +found = true;\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (count == private->data->mmsys_dev_num) {\r\n" + "> +if (found)\r\n" + "> +return BIT(i);\r\n" + "> +i++;\r\n" + "> +}\r\n" + "> +\r\n" + "> +count = 0;\r\n" + "> +found = false;\r\n" + "> +\r\n" + "> +for (j = 0; j < private->data->mmsys_dev_num; j++) {\r\n" + "> +priv_n = private->all_drm_private[j];\r\n" + "> +data = priv_n->data;\r\n" + ">  \r\n" + ">  if (mtk_ddp_path_available(data->ext_path, data->ext_len,\r\n" + "> -   priv_n->comp_node)) {\r\n" + "> -if (mtk_ddp_comp_find(dev, data->ext_path,\r\n" + "> -      data->ext_len,\r\n" + "> -      priv_n->ddp_comp))\r\n" + "> -return BIT(i);\r\n" + "> -i++;\r\n" + "> -}\r\n" + "> +   priv_n->comp_node))\r\n" + "> +count++;\r\n" + "> +\r\n" + "> +if (mtk_ddp_comp_find(dev, data->ext_path, data->ext_len,\r\n" + "> +      priv_n->ddp_comp))\r\n" + "> +found = true;\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (count == private->data->mmsys_dev_num) {\r\n" + "> +if (found)\r\n" + "> +return BIT(i);\r\n" + "> +i++;\r\n" + "> +}\r\n" + "> +\r\n" + "> +count = 0;\r\n" + "> +found = false;\r\n" + "> +\r\n" + "> +for (j = 0; j < private->data->mmsys_dev_num; j++) {\r\n" + "> +priv_n = private->all_drm_private[j];\r\n" + "> +data = priv_n->data;\r\n" + ">  \r\n" + ">  if (mtk_ddp_path_available(data->third_path, data->third_len,\r\n" + "> -   priv_n->comp_node)) {\r\n" + "> -if (mtk_ddp_comp_find(dev, data->third_path,\r\n" + "> -      data->third_len,\r\n" + "> -      priv_n->ddp_comp))\r\n" + "> -return BIT(i);\r\n" + "> -i++;\r\n" + "> -}\r\n" + "> +priv_n->comp_node))\r\n" + "> +count++;\r\n" + "> +\r\n" + "> +if (mtk_ddp_comp_find(dev, data->third_path, data->third_len,\r\n" + "> +      priv_n->ddp_comp))\r\n" + "> +found = true;\r\n" + "> +}\r\n" + "> +\r\n" + "> +if (count == private->data->mmsys_dev_num) {\r\n" + "> +if (found)\r\n" + "> +return BIT(i);\r\n" + "> +i++;\r\n" + ">  }\r\n" + ">  \r\n" + ">  ret = mtk_ddp_comp_find_in_route(dev,\r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h\r\n" + "> index ef64ce7a071f..badb42bd4f7c 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h\r\n" + "> @@ -40,6 +40,7 @@ enum mtk_ddp_comp_type {\r\n" + ">  MTK_DISP_PWM,\r\n" + ">  MTK_DISP_RDMA,\r\n" + ">  MTK_DISP_UFOE,\r\n" + "> +MTK_DISP_VIRTUAL,\r\n" + ">  MTK_DISP_WDMA,\r\n" + ">  MTK_DPI,\r\n" + ">  MTK_DP_INTF,\r\n" + "> @@ -47,6 +48,7 @@ enum mtk_ddp_comp_type {\r\n" + ">  MTK_OVL_BLENDER,\r\n" + ">  MTK_OVL_EXDMA,\r\n" + ">  MTK_OVL_OUTPROC,\r\n" + "> +MTK_VDISP_AO,\r\n" + ">  MTK_DDP_COMP_TYPE_MAX,\r\n" + ">  };\r\n" + ">  \r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c\r\n" + "> index 7526bc38bcc7..0665a6feb546 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c\r\n" + "> @@ -193,6 +193,10 @@ static const struct mtk_drm_route mt8188_mtk_ddp_main_routes[] = {\r\n" + ">  {0, DDP_COMPONENT_DSI0},\r\n" + ">  };\r\n" + ">  \r\n" + "> +static const struct mtk_drm_route mt8196_mtk_ddp_routes[] = {\r\n" + "> +{2, DDP_COMPONENT_DSI0},\r\n" + "> +};\r\n" + "> +\r\n" + ">  static const unsigned int mt8192_mtk_ddp_main[] = {\r\n" + ">  DDP_COMPONENT_OVL0,\r\n" + ">  DDP_COMPONENT_OVL_2L0,\r\n" + "> @@ -231,6 +235,50 @@ static const unsigned int mt8195_mtk_ddp_ext[] = {\r\n" + ">  DDP_COMPONENT_DP_INTF1,\r\n" + ">  };\r\n" + ">  \r\n" + "> +static const unsigned int mt8196_mtk_ddp_ovl0_main[] = {\r\n" + "> +DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0,\r\n" + "> +DDP_COMPONENT_OVL0_DLO_ASYNC5,\r\n" + "> +};\r\n" + "\r\n" + "Separate MT8196 part to another patch which add support MT8196.\r\n" + "Let this patch not related to specific SoC.\r\n" + "\r\n" + "Regards,\r\n" + "CK\r\n" + "\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp0_main[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC0,\r\n" + "> +DDP_COMPONENT_DLO_ASYNC1,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp1_main[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC21,\r\n" + "> +DDP_COMPONENT_DVO0,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_ovl0_ext[] = {\r\n" + "> +DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1,\r\n" + "> +DDP_COMPONENT_OVL0_DLO_ASYNC6,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp0_ext[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC1,\r\n" + "> +DDP_COMPONENT_DLO_ASYNC2,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp1_ext[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC22,\r\n" + "> +DDP_COMPONENT_DP_INTF0,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_ovl1_third[] = {\r\n" + "> +DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2,\r\n" + "> +DDP_COMPONENT_OVL1_DLO_ASYNC5,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp0_third[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC8,\r\n" + "> +DDP_COMPONENT_DLO_ASYNC3,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const unsigned int mt8196_mtk_ddp_disp1_third[] = {\r\n" + "> +DDP_COMPONENT_DLI_ASYNC23,\r\n" + "> +};\r\n" + "> +\r\n" + ">  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {\r\n" + ">  .main_path = mt2701_mtk_ddp_main,\r\n" + ">  .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),\r\n" + "> @@ -327,6 +375,67 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {\r\n" + ">  .min_height = 1,\r\n" + ">  };\r\n" + ">  \r\n" + "> +static const struct mtk_mmsys_driver_data mt8196_dispsys0_driver_data = {\r\n" + "> +.main_path = mt8196_mtk_ddp_disp0_main,\r\n" + "> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_main),\r\n" + "> +.main_order = 1,\r\n" + "> +.ext_path = mt8196_mtk_ddp_disp0_ext,\r\n" + "> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_ext),\r\n" + "> +.ext_order = 1,\r\n" + "> +.third_path = mt8196_mtk_ddp_disp0_third,\r\n" + "> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_disp0_third),\r\n" + "> +.third_order = 1,\r\n" + "> +.mmsys_id = DISPSYS0,\r\n" + "> +.mmsys_dev_num = 4,\r\n" + "> +.max_width = 8191,\r\n" + "> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */\r\n" + "> +.min_height = 1,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const struct mtk_mmsys_driver_data mt8196_dispsys1_driver_data = {\r\n" + "> +.main_path = mt8196_mtk_ddp_disp1_main,\r\n" + "> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_main),\r\n" + "> +.main_order = 2,\r\n" + "> +.ext_path = mt8196_mtk_ddp_disp1_ext,\r\n" + "> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_ext),\r\n" + "> +.ext_order = 2,\r\n" + "> +.third_path = mt8196_mtk_ddp_disp1_third,\r\n" + "> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_disp1_third),\r\n" + "> +.conn_routes = mt8196_mtk_ddp_routes,\r\n" + "> +.num_conn_routes = ARRAY_SIZE(mt8196_mtk_ddp_routes),\r\n" + "> +.third_order = 2,\r\n" + "> +.mmsys_id = DISPSYS1,\r\n" + "> +.mmsys_dev_num = 4,\r\n" + "> +.max_width = 8191,\r\n" + "> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */\r\n" + "> +.min_height = 1,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const struct mtk_mmsys_driver_data mt8196_ovlsys0_driver_data = {\r\n" + "> +.main_path = mt8196_mtk_ddp_ovl0_main,\r\n" + "> +.main_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl0_main),\r\n" + "> +.main_order = 0,\r\n" + "> +.ext_path = mt8196_mtk_ddp_ovl0_ext,\r\n" + "> +.ext_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl0_ext),\r\n" + "> +.ext_order = 0,\r\n" + "> +.mmsys_id = OVLSYS0,\r\n" + "> +.mmsys_dev_num = 4,\r\n" + "> +.max_width = 8191,\r\n" + "> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */\r\n" + "> +.min_height = 1,\r\n" + "> +};\r\n" + "> +\r\n" + "> +static const struct mtk_mmsys_driver_data mt8196_ovlsys1_driver_data = {\r\n" + "> +.third_path = mt8196_mtk_ddp_ovl1_third,\r\n" + "> +.third_len = ARRAY_SIZE(mt8196_mtk_ddp_ovl1_third),\r\n" + "> +.third_order = 0,\r\n" + "> +.mmsys_id = OVLSYS1,\r\n" + "> +.mmsys_dev_num = 4,\r\n" + "> +.max_width = 8191,\r\n" + "> +.min_width = 2, /* 2-pixel align when ethdr is bypassed */\r\n" + "> +.min_height = 1,\r\n" + "> +};\r\n" + "> +\r\n" + ">  static const struct of_device_id mtk_drm_of_ids[] = {\r\n" + ">  { .compatible = "mediatek,mt2701-mmsys",\r\n" + ">    .data = &mt2701_mmsys_driver_data},\r\n" + "> @@ -354,6 +463,14 @@ static const struct of_device_id mtk_drm_of_ids[] = {\r\n" + ">    .data = &mt8195_vdosys0_driver_data},\r\n" + ">  { .compatible = "mediatek,mt8195-vdosys1",\r\n" + ">    .data = &mt8195_vdosys1_driver_data},\r\n" + "> +{ .compatible = "mediatek,mt8196-dispsys0",\r\n" + "> +  .data = &mt8196_dispsys0_driver_data},\r\n" + "> +{ .compatible = "mediatek,mt8196-dispsys1",\r\n" + "> +  .data = &mt8196_dispsys1_driver_data},\r\n" + "> +{ .compatible = "mediatek,mt8196-ovlsys0",\r\n" + "> +  .data = &mt8196_ovlsys0_driver_data},\r\n" + "> +{ .compatible = "mediatek,mt8196-ovlsys1",\r\n" + "> +  .data = &mt8196_ovlsys1_driver_data},\r\n" + ">  { }\r\n" + ">  };\r\n" + ">  MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);\r\n" + "> @@ -368,7 +485,7 @@ static int mtk_drm_match(struct device *dev, const void *data)\r\n" + ">  static bool mtk_drm_get_all_drm_priv(struct device *dev)\r\n" + ">  {\r\n" + ">  struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);\r\n" + "> -struct mtk_drm_private *all_drm_priv[MAX_CRTC];\r\n" + "> +struct mtk_drm_private *all_drm_priv[MAX_MMSYS] = {NULL};\r\n" + ">  struct mtk_drm_private *temp_drm_priv;\r\n" + ">  struct device_node *phandle = dev->parent->of_node;\r\n" + ">  const struct of_device_id *of_id;\r\n" + "> @@ -395,23 +512,18 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev)\r\n" + ">  if (!temp_drm_priv)\r\n" + ">  continue;\r\n" + ">  \r\n" + "> -if (temp_drm_priv->data->main_len)\r\n" + "> -all_drm_priv[CRTC_MAIN] = temp_drm_priv;\r\n" + "> -else if (temp_drm_priv->data->ext_len)\r\n" + "> -all_drm_priv[CRTC_EXT] = temp_drm_priv;\r\n" + "> -else if (temp_drm_priv->data->third_len)\r\n" + "> -all_drm_priv[CRTC_THIRD] = temp_drm_priv;\r\n" + "> +all_drm_priv[temp_drm_priv->data->mmsys_id] = temp_drm_priv;\r\n" + ">  \r\n" + ">  if (temp_drm_priv->mtk_drm_bound)\r\n" + ">  cnt++;\r\n" + ">  \r\n" + "> -if (cnt == MAX_CRTC)\r\n" + "> +if (cnt == temp_drm_priv->data->mmsys_dev_num)\r\n" + ">  break;\r\n" + ">  }\r\n" + ">  \r\n" + ">  if (drm_priv->data->mmsys_dev_num == cnt) {\r\n" + "> -for (i = 0; i < cnt; i++)\r\n" + "> -for (j = 0; j < cnt; j++)\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +for (j = 0; j < MAX_MMSYS; j++)\r\n" + ">  all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];\r\n" + ">  \r\n" + ">  return true;\r\n" + "> @@ -498,7 +610,10 @@ static int mtk_drm_kms_init(struct drm_device *drm)\r\n" + ">  drm->mode_config.funcs = &mtk_drm_mode_config_funcs;\r\n" + ">  drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;\r\n" + ">  \r\n" + "> -for (i = 0; i < private->data->mmsys_dev_num; i++) {\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++) {\r\n" + "> +if (!private->all_drm_private[i])\r\n" + "> +continue;\r\n" + "> +\r\n" + ">  drm->dev_private = private->all_drm_private[i];\r\n" + ">  ret = component_bind_all(private->all_drm_private[i]->dev, drm);\r\n" + ">  if (ret)\r\n" + "> @@ -521,8 +636,10 @@ static int mtk_drm_kms_init(struct drm_device *drm)\r\n" + ">   *    third path.\r\n" + ">   */\r\n" + ">  for (i = 0; i < MAX_CRTC; i++) {\r\n" + "> -for (j = 0; j < private->data->mmsys_dev_num; j++) {\r\n" + "> +for (j = 0; j < MAX_MMSYS; j++) {\r\n" + ">  priv_n = private->all_drm_private[j];\r\n" + "> +if (!priv_n)\r\n" + "> +continue;\r\n" + ">  \r\n" + ">  if (priv_n->data->max_width)\r\n" + ">  drm->mode_config.max_width = priv_n->data->max_width;\r\n" + "> @@ -534,28 +651,23 @@ static int mtk_drm_kms_init(struct drm_device *drm)\r\n" + ">  drm->mode_config.min_height = priv_n->data->min_height;\r\n" + ">  \r\n" + ">  if (i == CRTC_MAIN && priv_n->data->main_len) {\r\n" + "> -ret = mtk_crtc_create(drm, priv_n->data->main_path,\r\n" + "> -      priv_n->data->main_len, j,\r\n" + "> -      priv_n->data->conn_routes,\r\n" + "> -      priv_n->data->num_conn_routes);\r\n" + "> +ret = mtk_crtc_create(drm, CRTC_MAIN);\r\n" + ">  if (ret)\r\n" + ">  goto err_component_unbind;\r\n" + ">  \r\n" + "> -continue;\r\n" + "> +break;\r\n" + ">  } else if (i == CRTC_EXT && priv_n->data->ext_len) {\r\n" + "> -ret = mtk_crtc_create(drm, priv_n->data->ext_path,\r\n" + "> -      priv_n->data->ext_len, j, NULL, 0);\r\n" + "> +ret = mtk_crtc_create(drm, CRTC_EXT);\r\n" + ">  if (ret)\r\n" + ">  goto err_component_unbind;\r\n" + ">  \r\n" + "> -continue;\r\n" + "> +break;\r\n" + ">  } else if (i == CRTC_THIRD && priv_n->data->third_len) {\r\n" + "> -ret = mtk_crtc_create(drm, priv_n->data->third_path,\r\n" + "> -      priv_n->data->third_len, j, NULL, 0);\r\n" + "> +ret = mtk_crtc_create(drm, CRTC_THIRD);\r\n" + ">  if (ret)\r\n" + ">  goto err_component_unbind;\r\n" + ">  \r\n" + "> -continue;\r\n" + "> +break;\r\n" + ">  }\r\n" + ">  }\r\n" + ">  }\r\n" + "> @@ -574,8 +686,9 @@ static int mtk_drm_kms_init(struct drm_device *drm)\r\n" + ">  goto err_component_unbind;\r\n" + ">  }\r\n" + ">  \r\n" + "> -for (i = 0; i < private->data->mmsys_dev_num; i++)\r\n" + "> -private->all_drm_private[i]->dma_dev = dma_dev;\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (private->all_drm_private[i])\r\n" + "> +private->all_drm_private[i]->dma_dev = dma_dev;\r\n" + ">  \r\n" + ">  /*\r\n" + ">   * Configure the DMA segment size to make sure we get contiguous IOVA\r\n" + "> @@ -593,11 +706,13 @@ static int mtk_drm_kms_init(struct drm_device *drm)\r\n" + ">  return 0;\r\n" + ">  \r\n" + ">  err_component_unbind:\r\n" + "> -for (i = 0; i < private->data->mmsys_dev_num; i++)\r\n" + "> -component_unbind_all(private->all_drm_private[i]->dev, drm);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (private->all_drm_private[i])\r\n" + "> +component_unbind_all(private->all_drm_private[i]->dev, drm);\r\n" + ">  put_mutex_dev:\r\n" + "> -for (i = 0; i < private->data->mmsys_dev_num; i++)\r\n" + "> -put_device(private->all_drm_private[i]->mutex_dev);\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (private->all_drm_private[i])\r\n" + "> +put_device(private->all_drm_private[i]->mutex_dev);\r\n" + ">  \r\n" + ">  return ret;\r\n" + ">  }\r\n" + "> @@ -661,6 +776,19 @@ static int mtk_drm_bind(struct device *dev)\r\n" + ">  }\r\n" + ">  \r\n" + ">  private->mutex_dev = &pdev->dev;\r\n" + "> +\r\n" + "> +if (private->vdisp_ao_node) {\r\n" + "> +pdev = of_find_device_by_node(private->vdisp_ao_node);\r\n" + "> +if (!pdev) {\r\n" + "> +dev_err(dev, "Waiting for vdisp_ao device %pOF\n",\r\n" + "> +private->vdisp_ao_node);\r\n" + "> +of_node_put(private->mutex_node);\r\n" + "> +of_node_put(private->vdisp_ao_node);\r\n" + "> +return -EPROBE_DEFER;\r\n" + "> +}\r\n" + "> +private->vdisp_ao_dev = &pdev->dev;\r\n" + "> +}\r\n" + "> +\r\n" + ">  private->mtk_drm_bound = true;\r\n" + ">  private->dev = dev;\r\n" + ">  \r\n" + "> @@ -673,8 +801,9 @@ static int mtk_drm_bind(struct device *dev)\r\n" + ">  \r\n" + ">  private->drm_master = true;\r\n" + ">  drm->dev_private = private;\r\n" + "> -for (i = 0; i < private->data->mmsys_dev_num; i++)\r\n" + "> -private->all_drm_private[i]->drm = drm;\r\n" + "> +for (i = 0; i < MAX_MMSYS; i++)\r\n" + "> +if (private->all_drm_private[i])\r\n" + "> +private->all_drm_private[i]->drm = drm;\r\n" + ">  \r\n" + ">  ret = mtk_drm_kms_init(drm);\r\n" + ">  if (ret < 0)\r\n" + "> @@ -771,6 +900,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {\r\n" + ">    .data = (void *)MTK_DISP_MUTEX },\r\n" + ">  { .compatible = "mediatek,mt8195-disp-mutex",\r\n" + ">    .data = (void *)MTK_DISP_MUTEX },\r\n" + "> +{ .compatible = "mediatek,mt8196-disp-mutex",\r\n" + "> +  .data = (void *)MTK_DISP_MUTEX },\r\n" + ">  { .compatible = "mediatek,mt8173-disp-od",\r\n" + ">    .data = (void *)MTK_DISP_OD },\r\n" + ">  { .compatible = "mediatek,mt2701-disp-ovl",\r\n" + "> @@ -837,6 +968,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {\r\n" + ">    .data = (void *)MTK_DSI },\r\n" + ">  { .compatible = "mediatek,mt8188-dsi",\r\n" + ">    .data = (void *)MTK_DSI },\r\n" + "> +{ .compatible = "mediatek,mt8196-vdisp-ao",\r\n" + "> +  .data = (void *)MTK_VDISP_AO },\r\n" + ">  { }\r\n" + ">  };\r\n" + ">  \r\n" + "> @@ -1111,7 +1244,7 @@ static int mtk_drm_probe(struct platform_device *pdev)\r\n" + ">  private->data = mtk_drm_data;\r\n" + ">  };\r\n" + ">  \r\n" + "> -private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,\r\n" + "> +private->all_drm_private = devm_kmalloc_array(dev, MAX_MMSYS,\r\n" + ">        sizeof(*private->all_drm_private),\r\n" + ">        GFP_KERNEL);\r\n" + ">  if (!private->all_drm_private)\r\n" + "> @@ -1163,6 +1296,22 @@ static int mtk_drm_probe(struct platform_device *pdev)\r\n" + ">  component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);\r\n" + ">  }\r\n" + ">  \r\n" + "> +if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2)) {\r\n" + "> +struct mtk_drm_ovlsys_private ovlsys_priv;\r\n" + "> +\r\n" + "> +ovlsys_priv.mmsys_dev = private->mmsys_dev;\r\n" + "> +ovlsys_priv.use_path =\r\n" + "> +mtk_drm_mmsys_comp_in_path(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2);\r\n" + "> +ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovlsys-adaptor",\r\n" + "> +    PLATFORM_DEVID_AUTO,\r\n" + "> +    (void *)&ovlsys_priv,\r\n" + "> +    sizeof(struct mtk_drm_ovlsys_private));\r\n" + "> +private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2].dev = &ovl_adaptor->dev;\r\n" + "> +mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2],\r\n" + "> +  DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2);\r\n" + "> +component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);\r\n" + "> +}\r\n" + "> +\r\n" + ">  /* Iterate over sibling DISP function blocks */\r\n" + ">  for_each_child_of_node(phandle->parent, node) {\r\n" + ">  enum mtk_ddp_comp_type comp_type;\r\n" + "> @@ -1189,6 +1338,12 @@ static int mtk_drm_probe(struct platform_device *pdev)\r\n" + ">  continue;\r\n" + ">  }\r\n" + ">  \r\n" + "> +if (comp_type == MTK_VDISP_AO) {\r\n" + "> +private->vdisp_ao_node = of_node_get(node);\r\n" + "> +dev_dbg(dev, "get vdisp_ao node");\r\n" + "> +continue;\r\n" + "> +}\r\n" + "> +\r\n" + ">  comp_id = mtk_ddp_comp_get_id(node, comp_type);\r\n" + ">  if (comp_id < 0) {\r\n" + ">  dev_warn(dev, "Skipping unknown component %pOF\n",\r\n" + "> @@ -1241,6 +1396,9 @@ static int mtk_drm_probe(struct platform_device *pdev)\r\n" + ">  \r\n" + ">  platform_set_drvdata(pdev, private);\r\n" + ">  \r\n" + "> +if (!match)\r\n" + "> +drm_of_component_match_add(dev, &match, component_compare_of, NULL);\r\n" + "> +\r\n" + ">  ret = component_master_add_with_match(dev, &mtk_drm_ops, match);\r\n" + ">  if (ret)\r\n" + ">  goto err_pm;\r\n" + "> @@ -1264,6 +1422,7 @@ static void mtk_drm_remove(struct platform_device *pdev)\r\n" + ">  component_master_del(&pdev->dev, &mtk_drm_ops);\r\n" + ">  pm_runtime_disable(&pdev->dev);\r\n" + ">  of_node_put(private->mutex_node);\r\n" + "> +of_node_put(private->vdisp_ao_node);\r\n" + ">  for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)\r\n" + ">  of_node_put(private->comp_node[i]);\r\n" + ">  }\r\n" + "> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h\r\n" + "> index aa17e743a1d0..36cfbfa30ff2 100644\r\n" + "> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h\r\n" + "> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h\r\n" + "> @@ -13,7 +13,8 @@\r\n" + ">  #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)\r\n" + ">  #define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)\r\n" + ">  #define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 + 1)\r\n" + "> -#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1)\r\n" + "> +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1)\r\n" + "> +#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2 + 1)\r\n" + ">  \r\n" + ">  enum mtk_crtc_path {\r\n" + ">  CRTC_MAIN,\r\n" + "> @@ -22,6 +23,14 @@ enum mtk_crtc_path {\r\n" + ">  MAX_CRTC,\r\n" + ">  };\r\n" + ">  \r\n" + "> +enum mtk_drm_mmsys {\r\n" + "> +DISPSYS0,\r\n" + "> +DISPSYS1,\r\n" + "> +OVLSYS0,\r\n" + "> +OVLSYS1,\r\n" + "> +MAX_MMSYS,\r\n" + "> +};\r\n" + "> +\r\n" + ">  struct device;\r\n" + ">  struct device_node;\r\n" + ">  struct drm_crtc;\r\n" + "> @@ -38,10 +47,13 @@ struct mtk_drm_route {\r\n" + ">  struct mtk_mmsys_driver_data {\r\n" + ">  const unsigned int *main_path;\r\n" + ">  unsigned int main_len;\r\n" + "> +unsigned int main_order;\r\n" + ">  const unsigned int *ext_path;\r\n" + ">  unsigned int ext_len;\r\n" + "> +unsigned int ext_order;\r\n" + ">  const unsigned int *third_path;\r\n" + ">  unsigned int third_len;\r\n" + "> +unsigned int third_order;\r\n" + ">  const struct mtk_drm_route *conn_routes;\r\n" + ">  unsigned int num_conn_routes;\r\n" + ">  \r\n" + "> @@ -63,6 +75,8 @@ struct mtk_drm_private {\r\n" + ">  struct device_node *mutex_node;\r\n" + ">  struct device *mutex_dev;\r\n" + ">  struct device *mmsys_dev;\r\n" + "> +struct device_node *vdisp_ao_node;\r\n" + "> +struct device *vdisp_ao_dev;\r\n" + ">  struct device_node *comp_node[DDP_COMPONENT_DRM_ID_MAX];\r\n" + ">  struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_DRM_ID_MAX];\r\n" + ">  struct mtk_mmsys_driver_data *data;\r\n" + "\r\n" + "\r\n" + "</pre>\r\n" + "</p></body></html><!--type:text--><!--{--><pre>************* MEDIATEK Confidentiality Notice\r\n" + " ********************\r\n" + "The information contained in this e-mail message (including any \r\n" + "attachments) may be confidential, proprietary, privileged, or otherwise\r\n" + "exempt from disclosure under applicable laws. It is intended to be \r\n" + "conveyed only to the designated recipient(s). Any use, dissemination, \r\n" + "distribution, printing, retaining or copying of this e-mail (including its \r\n" + "attachments) by unintended recipient(s) is strictly prohibited and may \r\n" + "be unlawful. If you are not an intended recipient of this e-mail, or believe\r\n" + " \r\n" + "that you have received this e-mail in error, please notify the sender \r\n" + "immediately (by replying to this e-mail), delete any and all copies of \r\n" + "this e-mail (including any attachments) from your system, and do not\r\n" + "disclose the content of this e-mail to any other person. Thank you!\r\n" + </pre><!--}--> -338a9cd4cf22274489ad53ff8076bcd47a3161b8d8f06beee2f989c95bd8ccb8 +be1e4980eca99f4b620e5735eb987dcd670e0c6a755a185aeddadbb99f16d60b
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.