diff options
Diffstat (limited to 'drivers/gpu/drm/mediatek/mtk_drm_crtc.c')
| -rw-r--r-- | drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 89 | 
1 files changed, 62 insertions, 27 deletions
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 5071f1263216..d40142842f85 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -58,6 +58,7 @@ struct mtk_drm_crtc {  #endif  	struct device			*mmsys_dev; +	struct device			*dma_dev;  	struct mtk_mutex		*mutex;  	unsigned int			ddp_comp_nr;  	struct mtk_ddp_comp		**ddp_comp; @@ -378,13 +379,17 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)  	}  	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) { -		mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev, -				      mtk_crtc->ddp_comp[i]->id, -				      mtk_crtc->ddp_comp[i + 1]->id); -		mtk_mutex_add_comp(mtk_crtc->mutex, -					mtk_crtc->ddp_comp[i]->id); +		if (!mtk_ddp_comp_connect(mtk_crtc->ddp_comp[i], mtk_crtc->mmsys_dev, +					  mtk_crtc->ddp_comp[i + 1]->id)) +			mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev, +					      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, +					   mtk_crtc->ddp_comp[i]->id);  	} -	mtk_mutex_add_comp(mtk_crtc->mutex, 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);  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { @@ -433,17 +438,22 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)  	}  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) -		mtk_mutex_remove_comp(mtk_crtc->mutex, -					   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);  	mtk_mutex_disable(mtk_crtc->mutex);  	for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) { -		mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev, -					 mtk_crtc->ddp_comp[i]->id, -					 mtk_crtc->ddp_comp[i + 1]->id); -		mtk_mutex_remove_comp(mtk_crtc->mutex, -					   mtk_crtc->ddp_comp[i]->id); +		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, +					      mtk_crtc->ddp_comp[i]->id);  	} -	mtk_mutex_remove_comp(mtk_crtc->mutex, 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);  	mtk_crtc_ddp_clk_disable(mtk_crtc);  	mtk_mutex_unprepare(mtk_crtc->mutex); @@ -856,7 +866,9 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,  				BIT(pipe),  				mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,  							num_planes), -				mtk_ddp_comp_supported_rotations(comp)); +				mtk_ddp_comp_supported_rotations(comp), +				mtk_ddp_comp_get_formats(comp), +				mtk_ddp_comp_get_num_formats(comp));  		if (ret)  			return ret; @@ -865,22 +877,36 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,  	return 0;  } +struct device *mtk_drm_crtc_dma_dev_get(struct drm_crtc *crtc) +{ +	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + +	return mtk_crtc->dma_dev; +} +  int mtk_drm_crtc_create(struct drm_device *drm_dev, -			const enum mtk_ddp_comp_id *path, unsigned int path_len) +			const unsigned int *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; @@ -889,10 +915,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  		node = priv->comp_node[comp_id];  		comp = &priv->ddp_comp[comp_id]; -		if (!node) { +		/* 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) {  			dev_info(dev, -				 "Not creating crtc %d because component %d is disabled or missing\n", -				 pipe, comp_id); +				"Not creating crtc %d because component %d is disabled or missing\n", +				crtc_i, comp_id);  			return 0;  		} @@ -922,7 +951,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  	}  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { -		enum mtk_ddp_comp_id comp_id = path[i]; +		unsigned int comp_id = path[i];  		struct mtk_ddp_comp *comp;  		comp = &priv->ddp_comp[comp_id]; @@ -950,29 +979,35 @@ 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); +	/* +	 * Default to use the first component as the dma dev. +	 * 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]]); + +	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) +	i = priv->mbox_index++;  	mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;  	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;  	mtk_crtc->cmdq_client.chan = -			mbox_request_channel(&mtk_crtc->cmdq_client.client, -					     drm_crtc_index(&mtk_crtc->base)); +			mbox_request_channel(&mtk_crtc->cmdq_client.client, i);  	if (IS_ERR(mtk_crtc->cmdq_client.chan)) {  		dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",  			drm_crtc_index(&mtk_crtc->base)); @@ -982,7 +1017,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,  	if (mtk_crtc->cmdq_client.chan) {  		ret = of_property_read_u32_index(priv->mutex_node,  						 "mediatek,gce-events", -						 drm_crtc_index(&mtk_crtc->base), +						 i,  						 &mtk_crtc->cmdq_event);  		if (ret) {  			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",  |