diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi.c')
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.c | 53 | 
1 files changed, 47 insertions, 6 deletions
| diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 28d1f95a90cc..1f2561e2ff71 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -23,12 +23,47 @@ struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi)  		msm_dsi->encoders[MSM_DSI_CMD_ENCODER_ID];  } +static int dsi_get_phy(struct msm_dsi *msm_dsi) +{ +	struct platform_device *pdev = msm_dsi->pdev; +	struct platform_device *phy_pdev; +	struct device_node *phy_node; + +	phy_node = of_parse_phandle(pdev->dev.of_node, "qcom,dsi-phy", 0); +	if (!phy_node) { +		dev_err(&pdev->dev, "cannot find phy device\n"); +		return -ENXIO; +	} + +	phy_pdev = of_find_device_by_node(phy_node); +	if (phy_pdev) +		msm_dsi->phy = platform_get_drvdata(phy_pdev); + +	of_node_put(phy_node); + +	if (!phy_pdev || !msm_dsi->phy) { +		dev_err(&pdev->dev, "%s: phy driver is not ready\n", __func__); +		return -EPROBE_DEFER; +	} + +	msm_dsi->phy_dev = get_device(&phy_pdev->dev); + +	return 0; +} +  static void dsi_destroy(struct msm_dsi *msm_dsi)  {  	if (!msm_dsi)  		return;  	msm_dsi_manager_unregister(msm_dsi); + +	if (msm_dsi->phy_dev) { +		put_device(msm_dsi->phy_dev); +		msm_dsi->phy = NULL; +		msm_dsi->phy_dev = NULL; +	} +  	if (msm_dsi->host) {  		msm_dsi_host_destroy(msm_dsi->host);  		msm_dsi->host = NULL; @@ -43,7 +78,6 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)  	int ret;  	if (!pdev) { -		dev_err(&pdev->dev, "no dsi device\n");  		ret = -ENXIO;  		goto fail;  	} @@ -63,6 +97,11 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)  	if (ret)  		goto fail; +	/* GET dsi PHY */ +	ret = dsi_get_phy(msm_dsi); +	if (ret) +		goto fail; +  	/* Register to dsi manager */  	ret = msm_dsi_manager_register(msm_dsi);  	if (ret) @@ -142,12 +181,14 @@ static struct platform_driver dsi_driver = {  void __init msm_dsi_register(void)  {  	DBG(""); +	msm_dsi_phy_driver_register();  	platform_driver_register(&dsi_driver);  }  void __exit msm_dsi_unregister(void)  {  	DBG(""); +	msm_dsi_phy_driver_unregister();  	platform_driver_unregister(&dsi_driver);  } @@ -177,6 +218,11 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,  		goto fail;  	} +	for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { +		encoders[i]->bridge = msm_dsi->bridge; +		msm_dsi->encoders[i] = encoders[i]; +	} +  	msm_dsi->connector = msm_dsi_manager_connector_init(msm_dsi->id);  	if (IS_ERR(msm_dsi->connector)) {  		ret = PTR_ERR(msm_dsi->connector); @@ -185,11 +231,6 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,  		goto fail;  	} -	for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) { -		encoders[i]->bridge = msm_dsi->bridge; -		msm_dsi->encoders[i] = encoders[i]; -	} -  	priv->bridges[priv->num_bridges++]       = msm_dsi->bridge;  	priv->connectors[priv->num_connectors++] = msm_dsi->connector; | 
