summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/msm/dsi/dsi.c
diff options
context:
space:
mode:
authorHai Li <hali@codeaurora.org>2015-05-15 17:04:06 (GMT)
committerRob Clark <robdclark@gmail.com>2015-06-11 17:11:05 (GMT)
commitec31abf6684ebe1134eb3320c96fb92e566eff74 (patch)
tree14d254e9bab8f098451bb2b2a92aa8fffa196e5d /drivers/gpu/drm/msm/dsi/dsi.c
parent9d32c4989c858af12b333ae9a3c160a91ff43934 (diff)
downloadlinux-ec31abf6684ebe1134eb3320c96fb92e566eff74.tar.xz
drm/msm/dsi: Separate PHY to another platform device
There are different types of PHY from one chipset to another, while the DSI host controller is relatively consistent across platforms. Also, the PLL inside PHY is providing the source of DSI byte and pixel clocks, which are used by DSI host controller. Separated devices for clock provider and clock consumer make DSI driver better fit into common clock framework. Signed-off-by: Hai Li <hali@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index beb26df..1f2561e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -23,6 +23,34 @@ 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)
@@ -30,9 +58,10 @@ static void dsi_destroy(struct msm_dsi *msm_dsi)
msm_dsi_manager_unregister(msm_dsi);
- if (msm_dsi->phy) {
- msm_dsi_phy_destroy(msm_dsi->phy);
+ if (msm_dsi->phy_dev) {
+ put_device(msm_dsi->phy_dev);
msm_dsi->phy = NULL;
+ msm_dsi->phy_dev = NULL;
}
if (msm_dsi->host) {
@@ -49,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;
}
@@ -69,13 +97,10 @@ static struct msm_dsi *dsi_init(struct platform_device *pdev)
if (ret)
goto fail;
- /* Init dsi PHY */
- msm_dsi->phy = msm_dsi_phy_init(pdev, msm_dsi->phy_type, msm_dsi->id);
- if (!msm_dsi->phy) {
- ret = -ENXIO;
- pr_err("%s: phy init failed\n", __func__);
+ /* GET dsi PHY */
+ ret = dsi_get_phy(msm_dsi);
+ if (ret)
goto fail;
- }
/* Register to dsi manager */
ret = msm_dsi_manager_register(msm_dsi);
@@ -156,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);
}