[PATCH v2 14/14] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

CK Hu ck.hu at mediatek.com
Sun Aug 1 20:34:40 PDT 2021


Hi, Nancy:

On Thu, 2021-07-22 at 17:45 +0800, Nancy.Lin wrote:
> Add driver data of mt8195 vdosys1 to mediatek-drm and modify drm for
> multi-mmsys support. The two mmsys (vdosys0 and vdosys1) will bring
> up two drm drivers, only one drm driver register as the drm device.
> Each drm driver binds its own component. The first bind drm driver
> will allocate the drm device, and the last bind drm driver registers
> the drm device to drm core. Each crtc path is created with the
> corresponding drm driver data.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c   |   4 +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  18 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h     |   3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  15 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 378 ++++++++++++++++----
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   8 +-
>  7 files changed, 356 insertions(+), 71 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> index 768c282d2d63..829570308761 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -4,6 +4,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/reset.h>
>  #include <linux/component.h>
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
> @@ -106,6 +107,9 @@ void mtk_merge_stop(struct device *dev)
>  	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
>  
>  	mtk_ddp_write(NULL, 0x0, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CTRL);
> +
> +	if (priv->async_clk)
> +		device_reset_optional(dev);

Move this to the merge patch [1].

[1]
https://patchwork.kernel.org/project/linux-mediatek/patch/20210729170737.21424-7-jason-jh.lin@mediatek.com/

>  }
>  
>  static int mtk_merge_check_params(struct mtk_merge_config_struct *merge_config)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 40df2c823187..3324fa1a9e8c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -737,21 +737,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
>  }
>  
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
> -			const enum mtk_ddp_comp_id *path, unsigned int path_len)
> +			const enum mtk_ddp_comp_id *path, unsigned int path_len,
> +			int priv_data_index)
>  {
>  	struct mtk_drm_private *priv = drm_dev->dev_private;
>  	struct device *dev = drm_dev->dev;
>  	struct mtk_drm_crtc *mtk_crtc;
>  	unsigned int num_comp_planes = 0;
> -	int pipe = priv->num_pipes;
>  	int ret;
>  	int i;
>  	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];
> +
> +	drm_for_each_crtc(tmp, drm_dev)
> +		crtc_i++;
> +
>  	for (i = 0; i < path_len; i++) {
>  		enum mtk_ddp_comp_id comp_id = path[i];
>  		struct device_node *node;
> @@ -760,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  		if (!node) {
>  			dev_info(dev,
>  				 "Not creating crtc %d because component %d is disabled or missing\n",
> -				 pipe, comp_id);
> +				 crtc_i, comp_id);
>  			return 0;
>  		}
>  	}
> @@ -816,19 +823,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  
>  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
>  		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
> -						    pipe);
> +						    crtc_i);
>  		if (ret)
>  			return ret;
>  	}
>  
> -	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
> +	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
>  	if (ret < 0)
>  		return ret;
>  
>  	if (gamma_lut_size)
>  		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
>  	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
> -	priv->num_pipes++;
>  	mutex_init(&mtk_crtc->hw_lock);
>  
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> index 66d1cf03dfe8..0646fafffd8b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> @@ -31,7 +31,8 @@
>  void mtk_drm_crtc_commit(struct drm_crtc *crtc);
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
>  			const enum mtk_ddp_comp_id *path,
> -			unsigned int path_len);
> +			unsigned int path_len,
> +			int priv_data_index);
>  int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
>  			     struct mtk_plane_state *state);
>  void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 9125d0f6352f..25f293542f79 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -355,6 +355,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
>  	.start = mtk_ufoe_start,
>  };
>  
> +static const struct mtk_ddp_comp_funcs ddp_pseudo_ovl = {
> +	.clk_enable = mtk_ethdr_clk_enable,
> +	.clk_disable = mtk_ethdr_clk_disable,
> +	.config = mtk_ethdr_config,
> +	.start = mtk_ethdr_start,
> +	.stop = mtk_ethdr_stop,
> +	.layer_nr = mtk_ethdr_layer_nr,
> +	.layer_config = mtk_ethdr_layer_config,
> +	.enable_vblank = mtk_ethdr_enable_vblank,
> +	.disable_vblank = mtk_ethdr_disable_vblank,
> +};

Move this to the pseudo ovl patch.

> +
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>  	[MTK_DISP_OVL] = "ovl",
>  	[MTK_DISP_OVL_2L] = "ovl-2l",
> @@ -368,6 +380,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>  	[MTK_DISP_UFOE] = "ufoe",
>  	[MTK_DSI] = "dsi",
>  	[MTK_DPI] = "dpi",
> +	[MTK_DISP_PSEUDO_OVL] = "pseudo_ovl",

ditto.

>  	[MTK_DISP_PWM] = "pwm",
>  	[MTK_DISP_MUTEX] = "mutex",
>  	[MTK_DISP_OD] = "od",
> @@ -412,6 +425,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>  	[DDP_COMPONENT_OVL1]	= { MTK_DISP_OVL,	1, &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L0]	= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L1]	= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
> +	[DDP_COMPONENT_PSEUDO_OVL] = { MTK_DISP_PSEUDO_OVL,	0, &ddp_pseudo_ovl },

ditto.

>  	[DDP_COMPONENT_PWM0]	= { MTK_DISP_PWM,	0, NULL },
>  	[DDP_COMPONENT_PWM1]	= { MTK_DISP_PWM,	1, NULL },
>  	[DDP_COMPONENT_PWM2]	= { MTK_DISP_PWM,	2, NULL },
> @@ -540,6 +554,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
>  	    type == MTK_DISP_MERGE ||
>  	    type == MTK_DISP_OVL ||
>  	    type == MTK_DISP_OVL_2L ||
> +	    type == MTK_DISP_PSEUDO_OVL ||

ditto.

>  	    type == MTK_DISP_PWM ||
>  	    type == MTK_DISP_RDMA ||
>  	    type == MTK_DPI ||
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 0afd78c0bc92..f2a184b1eceb 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -36,6 +36,7 @@ enum mtk_ddp_comp_type {
>  	MTK_DISP_BLS,
>  	MTK_DISP_DSC,
>  	MTK_DISP_MERGE,
> +	MTK_DISP_PSEUDO_OVL,

ditto.

>  	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 58f9f9f06e94..94527fb040be 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -11,6 +11,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/reset-controller.h>
>  
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_atomic_helper.h>
> @@ -35,6 +36,16 @@
>  #define DRIVER_MAJOR 1
>  #define DRIVER_MINOR 0
>  
> +/* duplicate with mmsys private data */
> +struct mtk_mmsys_private {
> +	void __iomem *regs_reserved;
> +	struct cmdq_client_reg cmdq_base_reserved;
> +	void *data_reserved;
> +	spinlock_t lock_reserved; /* protects mmsys_sw_rst_b reg */
> +	struct reset_controller_dev rcdev_reserved;
> +	void *drm_private;
> +};
> +
>  static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = {
>  	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
>  };
> @@ -160,12 +171,20 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
>  	DDP_COMPONENT_DP_INTF0,
>  };
>  
> +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
> +	DDP_COMPONENT_PSEUDO_OVL,
> +	DDP_COMPONENT_MERGE5,
> +	DDP_COMPONENT_DP_INTF1,
> +};
> +
>  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),
>  	.ext_path = mt2701_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
>  	.shadow_register = true,
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
> @@ -174,6 +193,8 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
>  	.ext_path = mt7623_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
>  	.shadow_register = true,
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
> @@ -183,6 +204,8 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
>  	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
>  	.third_path = mt2712_mtk_ddp_third,
>  	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
> @@ -190,6 +213,8 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
>  	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
>  	.ext_path = mt8173_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
> @@ -197,32 +222,219 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>  	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
>  	.ext_path = mt8183_mtk_ddp_ext,
>  	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 1,
>  };
>  
>  static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
>  	.main_path = mt8195_mtk_ddp_main,
>  	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
> +	.mmsys_id = 0,
> +	.mmsys_dev_num = 2,
> +};
> +
> +static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
> +	.ext_path = mt8195_mtk_ddp_ext,
> +	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
> +	.mmsys_id = 1,
> +	.mmsys_dev_num = 2,
> +};
> +
> +static const struct of_device_id mtk_drm_of_ids[] = {
> +	{ .compatible = "mediatek,mt2701-mmsys",
> +	  .data = &mt2701_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt7623-mmsys",
> +	  .data = &mt7623_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt2712-mmsys",
> +	  .data = &mt2712_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8173-mmsys",
> +	  .data = &mt8173_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8183-mmsys",
> +	  .data = &mt8183_mmsys_driver_data},
> +	{ .compatible = "mediatek,mt8195-vdosys0",
> +	  .data = &mt8195_vdosys0_driver_data},
> +	{ .compatible = "mediatek,mt8195-vdosys1",
> +	  .data = &mt8195_vdosys1_driver_data},
> +	{ }
>  };
> +MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
> +
> +static int mtk_drm_get_mmsys_priv(struct device *dev,
> +				  struct mtk_drm_private **all_drm_priv,
> +				  int num)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct device_node *phandle = dev->parent->of_node;
> +	const struct of_device_id *of_id;
> +	struct device_node *node;
> +	int cnt = 0;
> +
> +	for_each_child_of_node(phandle->parent, node) {
> +		struct platform_device *pdev;
> +		struct mtk_mmsys_private *mmsys_priv;
> +
> +		of_id = of_match_node(mtk_drm_of_ids, node);
> +		if (!of_id)
> +			continue;
> +
> +		pdev = of_find_device_by_node(node);
> +		if (!pdev)
> +			continue;
> +
> +		mmsys_priv = dev_get_drvdata(&pdev->dev);
> +		if (!mmsys_priv || !mmsys_priv->drm_private)
> +			continue;
> +
> +		all_drm_priv[cnt++] = mmsys_priv->drm_private;
> +		if (cnt == num)
> +			break;
> +	}
> +
> +	return 0;
> +}

Move "support multiple mmsys" related code to another patch, and left
only mt8195 part in this patch.

Regards,
CK

> +
> +static bool mtk_drm_check_last_drm_bind(struct device *dev)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int cnt = 0;
> +	int i;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
> +
> +	for (i = 0; i < MAX_CRTC; i++)
> +		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound)
> +			cnt++;
> +
> +	return (drm_priv->data->mmsys_dev_num == cnt);
> +}
> +
> +static bool mtk_drm_find_drm_dev(struct device *dev, struct drm_device **drm)
> +{
> +	struct device_node *phandle = dev->parent->of_node;
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int i;
> +
> +	if (!drm_priv->data->mmsys_dev_num)
> +		return false;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, drm_priv->data->mmsys_dev_num);
> +
> +	for (i = 0; i < MAX_CRTC; i++) {
> +		if (all_drm_priv[i] && all_drm_priv[i]->mtk_drm_bound) {
> +			*drm = all_drm_priv[i]->drm;
> +			return true;
> +		}
> +	}
> +
> +	return false;
> +}
> +
> +static int mtk_drm_setup_all_drm_private(struct device *dev)
> +{
> +	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
> +	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
> +	int mmsys_dev_num = drm_priv->data->mmsys_dev_num;
> +	int i;
> +	int j;
> +
> +	mtk_drm_get_mmsys_priv(dev, all_drm_priv, mmsys_dev_num);
> +
> +	for (i = 0; i < mmsys_dev_num; i++)
> +		for (j = 0; j < mmsys_dev_num; j++)
> +			all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
> +
> +	return 0;
> +}
> +
> +static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
> +{
> +	const struct mtk_mmsys_driver_data *drv_data = private->data;
> +	int ret = false;
> +	int i;
> +
> +	if (drv_data->mmsys_dev_num == 1)
> +		return true;
> +
> +	if (drv_data->main_path) {
> +		for (i = 0; i < drv_data->main_len; i++)
> +			if (drv_data->main_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->main_len)
> +			ret |= false;
> +	}
> +
> +	if (drv_data->ext_path) {
> +		for (i = 0; i < drv_data->ext_len; i++)
> +			if (drv_data->ext_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->ext_len)
> +			ret |= false;
> +	}
> +
> +	if (drv_data->third_path) {
> +		for (i = 0; i < drv_data->third_len; i++)
> +			if (drv_data->third_path[i] == comp_id)
> +				ret |= true;
> +
> +		if (i == drv_data->third_len)
> +			ret |= false;
> +	}
> +
> +	return ret;
> +}
> +
> +static int mtk_drm_check_mutex_dev(struct mtk_drm_private *private)
> +{
> +	struct platform_device *pdev;
> +	struct mtk_drm_private *priv_i;
> +	int ret;
> +	int i;
> +
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		priv_i = private->all_drm_private[i];
> +
> +		pdev = of_find_device_by_node(priv_i->mutex_node);
> +		if (!pdev) {
> +			dev_err(priv_i->dev, "Waiting for disp-mutex device %pOF\n",
> +				priv_i->mutex_node);
> +			ret = -EPROBE_DEFER;
> +			goto err_put_mutex;
> +		}
> +		priv_i->mutex_dev = &pdev->dev;
> +	}
> +
> +	return 0;
> +
> +err_put_mutex:
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		priv_i = private->all_drm_private[i];
> +		of_node_put(priv_i->mutex_node);
> +	}
> +
> +	return ret;
> +}
>  
>  static int mtk_drm_kms_init(struct drm_device *drm)
>  {
>  	struct mtk_drm_private *private = drm->dev_private;
> +	struct mtk_drm_private *priv_n;
>  	struct platform_device *pdev;
> -	struct device_node *np;
> +	struct device_node *np = NULL;
>  	struct device *dma_dev;
>  	int ret;
> +	int i;
> +	int j;
>  
>  	if (!iommu_present(&platform_bus_type))
>  		return -EPROBE_DEFER;
>  
> -	pdev = of_find_device_by_node(private->mutex_node);
> -	if (!pdev) {
> -		dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
> -			private->mutex_node);
> -		of_node_put(private->mutex_node);
> -		return -EPROBE_DEFER;
> -	}
> -	private->mutex_dev = &pdev->dev;
> +	ret = mtk_drm_check_mutex_dev(private);
> +	if (ret)
> +		return ret;
>  
>  	ret = drmm_mode_config_init(drm);
>  	if (ret)
> @@ -241,33 +453,57 @@ 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;
>  
> -	ret = component_bind_all(drm->dev, drm);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++) {
> +		drm->dev_private = private->all_drm_private[i];
> +		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
>  	if (ret)
>  		goto put_mutex_dev;
> +	}
>  
>  	/*
>  	 * We currently support two fixed data streams, each optional,
>  	 * and each statically assigned to a crtc:
>  	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
>  	 */
> -	ret = mtk_drm_crtc_create(drm, private->data->main_path,
> -				  private->data->main_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> -	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
> -	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
> -				  private->data->ext_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> -
> -	ret = mtk_drm_crtc_create(drm, private->data->third_path,
> -				  private->data->third_len);
> -	if (ret < 0)
> -		goto err_component_unbind;
> +	for (i = 0; i < MAX_CRTC; i++) {
> +		for (j = 0; j < private->data->mmsys_dev_num; j++) {
> +			priv_n = private->all_drm_private[j];
> +
> +			if (i == 0 && priv_n->data->main_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
> +							  priv_n->data->main_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->main_path[0]];
> +
> +				continue;
> +			} else if (i == 1 && priv_n->data->ext_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
> +							  priv_n->data->ext_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->ext_path[0]];
> +
> +				continue;
> +			} else if (i == 2 && priv_n->data->third_len) {
> +				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
> +							  priv_n->data->third_len, j);
> +				if (ret)
> +					goto err_component_unbind;
> +
> +				if (!np)
> +					np = priv_n->comp_node[priv_n->data->third_path[0]];
> +
> +				continue;
> +			}
> +		}
> +	}
>  
>  	/* Use OVL device for all DMA memory allocations */
> -	np = private->comp_node[private->data->main_path[0]] ?:
> -	     private->comp_node[private->data->ext_path[0]];
>  	pdev = of_find_device_by_node(np);
>  	if (!pdev) {
>  		ret = -ENODEV;
> @@ -276,13 +512,15 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	}
>  
>  	dma_dev = &pdev->dev;
> -	private->dma_dev = dma_dev;
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		private->all_drm_private[i]->dma_dev = dma_dev;
>  
>  	/*
>  	 * Configure the DMA segment size to make sure we get contiguous IOVA
>  	 * when importing PRIME buffers.
>  	 */
>  	ret = dma_set_max_seg_size(dma_dev, UINT_MAX);
> +
>  	if (ret) {
>  		dev_err(dma_dev, "Failed to set DMA segment size\n");
>  		goto err_component_unbind;
> @@ -304,9 +542,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
>  	return 0;
>  
>  err_component_unbind:
> -	component_unbind_all(drm->dev, drm);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		component_unbind_all(private->all_drm_private[i]->dev, drm);
>  put_mutex_dev:
> -	put_device(private->mutex_dev);
> +	for (i = 0; i < private->data->mmsys_dev_num; i++)
> +		put_device(private->all_drm_private[i]->mutex_dev);
> +
>  	return ret;
>  }
>  
> @@ -371,12 +612,21 @@ static int mtk_drm_bind(struct device *dev)
>  	struct drm_device *drm;
>  	int ret;
>  
> -	drm = drm_dev_alloc(&mtk_drm_driver, dev);
> -	if (IS_ERR(drm))
> -		return PTR_ERR(drm);
> +	if (!mtk_drm_find_drm_dev(dev, &drm)) {
> +		drm = drm_dev_alloc(&mtk_drm_driver, dev);
> +		if (IS_ERR(drm))
> +			return PTR_ERR(drm);
> +		drm->dev_private = private;
> +	}
>  
> -	drm->dev_private = private;
> +	private->dev = dev;
>  	private->drm = drm;
> +	private->mtk_drm_bound = true;
> +
> +	if (!mtk_drm_check_last_drm_bind(dev))
> +		return 0;
> +
> +	mtk_drm_setup_all_drm_private(dev);
>  
>  	ret = mtk_drm_kms_init(drm);
>  	if (ret < 0)
> @@ -401,10 +651,13 @@ static void mtk_drm_unbind(struct device *dev)
>  {
>  	struct mtk_drm_private *private = dev_get_drvdata(dev);
>  
> -	drm_dev_unregister(private->drm);
> -	mtk_drm_kms_deinit(private->drm);
> -	drm_dev_put(private->drm);
> -	private->num_pipes = 0;
> +	/* for multi mmsys dev, unregister drm dev in mmsys master */
> +	if (private->data->mmsys_id == 0) {
> +		drm_dev_unregister(private->drm);
> +		mtk_drm_kms_deinit(private->drm);
> +		drm_dev_put(private->drm);
> +	}
> +	private->mtk_drm_bound = false;
>  	private->drm = NULL;
>  }
>  
> @@ -485,49 +738,42 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>  	{ }
>  };
>  
> -static const struct of_device_id mtk_drm_of_ids[] = {
> -	{ .compatible = "mediatek,mt2701-mmsys",
> -	  .data = &mt2701_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt7623-mmsys",
> -	  .data = &mt7623_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt2712-mmsys",
> -	  .data = &mt2712_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt8173-mmsys",
> -	  .data = &mt8173_mmsys_driver_data},
> -	{ .compatible = "mediatek,mt8183-mmsys",
> -	  .data = &mt8183_mmsys_driver_data},
> -	{.compatible = "mediatek,mt8195-vdosys0",
> -	  .data = &mt8195_vdosys0_driver_data},
> -	{ }
> -};
> -MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
> -
>  static int mtk_drm_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct device_node *phandle = dev->parent->of_node;
>  	const struct of_device_id *of_id;
> +	const struct mtk_mmsys_driver_data *drv_data;
>  	struct mtk_drm_private *private;
>  	struct device_node *node;
>  	struct component_match *match = NULL;
> +	struct mtk_mmsys_private *mmsys_priv;
>  	int ret;
>  	int i;
>  
> +	of_id = of_match_node(mtk_drm_of_ids, phandle);
> +	if (!of_id)
> +		return -ENODEV;
> +
> +	drv_data = of_id->data;
>  	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
>  	if (!private)
>  		return -ENOMEM;
>  
> +	private->all_drm_private = devm_kmalloc_array(dev, drv_data->mmsys_dev_num,
> +						      sizeof(*private->all_drm_private),
> +						      GFP_KERNEL);
> +	if (!private->all_drm_private)
> +		return -ENOMEM;
> +
> +	private->data = drv_data;
>  	private->mmsys_dev = dev->parent;
>  	if (!private->mmsys_dev) {
>  		dev_err(dev, "Failed to get MMSYS device\n");
>  		return -ENODEV;
>  	}
> -
> -	of_id = of_match_node(mtk_drm_of_ids, phandle);
> -	if (!of_id)
> -		return -ENODEV;
> -
> -	private->data = of_id->data;
> +	mmsys_priv = dev_get_drvdata(private->mmsys_dev);
> +	mmsys_priv->drm_private = private;
>  
>  	/* Iterate over sibling DISP function blocks */
>  	for_each_child_of_node(phandle->parent, node) {
> @@ -548,7 +794,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		comp_type = (enum mtk_ddp_comp_type)of_id->data;
>  
>  		if (comp_type == MTK_DISP_MUTEX) {
> -			private->mutex_node = of_node_get(node);
> +			int id;
> +
> +			id = of_alias_get_id(node, "mutex");
> +			if (id < 0 || id == drv_data->mmsys_id) {
> +				private->mutex_node = of_node_get(node);
> +				dev_dbg(dev, "get mutex for mmsys %d", drv_data->mmsys_id);
> +			}
>  			continue;
>  		}
>  
> @@ -559,6 +811,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  			continue;
>  		}
>  
> +		if (!mtk_drm_find_mmsys_comp(private, comp_id))
> +			continue;
> +
>  		private->comp_node[comp_id] = of_node_get(node);
>  
>  		/*
> @@ -573,6 +828,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
>  		    comp_type == MTK_DISP_MERGE ||
>  		    comp_type == MTK_DISP_OVL ||
>  		    comp_type == MTK_DISP_OVL_2L ||
> +		    comp_type == MTK_DISP_PSEUDO_OVL ||
>  		    comp_type == MTK_DISP_RDMA ||
>  		    comp_type == MTK_DPI ||
>  		    comp_type == MTK_DSI) {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index c87ebb5309d0..212e4f87c35c 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -29,14 +29,15 @@ struct mtk_mmsys_driver_data {
>  	unsigned int third_len;
>  
>  	bool shadow_register;
> +	unsigned int mmsys_id;
> +	unsigned int mmsys_dev_num;
>  };
>  
>  struct mtk_drm_private {
>  	struct drm_device *drm;
>  	struct device *dma_dev;
> -
> -	unsigned int num_pipes;
> -
> +	bool mtk_drm_bound;
> +	struct device *dev;
>  	struct device_node *mutex_node;
>  	struct device *mutex_dev;
>  	struct device *mmsys_dev;
> @@ -44,6 +45,7 @@ struct mtk_drm_private {
>  	struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
>  	const struct mtk_mmsys_driver_data *data;
>  	struct drm_atomic_state *suspend_state;
> +	struct mtk_drm_private **all_drm_private;
>  };
>  
>  extern struct platform_driver mtk_disp_ccorr_driver;



More information about the linux-arm-kernel mailing list