1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
8 struct drm_encoder
*msm_dsi_get_encoder(struct msm_dsi
*msm_dsi
)
10 if (!msm_dsi
|| !msm_dsi_device_connected(msm_dsi
))
13 return msm_dsi
->encoder
;
16 static int dsi_get_phy(struct msm_dsi
*msm_dsi
)
18 struct platform_device
*pdev
= msm_dsi
->pdev
;
19 struct platform_device
*phy_pdev
;
20 struct device_node
*phy_node
;
22 phy_node
= of_parse_phandle(pdev
->dev
.of_node
, "phys", 0);
24 DRM_DEV_ERROR(&pdev
->dev
, "cannot find phy device\n");
28 phy_pdev
= of_find_device_by_node(phy_node
);
30 msm_dsi
->phy
= platform_get_drvdata(phy_pdev
);
32 of_node_put(phy_node
);
34 if (!phy_pdev
|| !msm_dsi
->phy
) {
35 DRM_DEV_ERROR(&pdev
->dev
, "%s: phy driver is not ready\n", __func__
);
39 msm_dsi
->phy_dev
= get_device(&phy_pdev
->dev
);
44 static void dsi_destroy(struct msm_dsi
*msm_dsi
)
49 msm_dsi_manager_unregister(msm_dsi
);
51 if (msm_dsi
->phy_dev
) {
52 put_device(msm_dsi
->phy_dev
);
54 msm_dsi
->phy_dev
= NULL
;
58 msm_dsi_host_destroy(msm_dsi
->host
);
62 platform_set_drvdata(msm_dsi
->pdev
, NULL
);
65 static struct msm_dsi
*dsi_init(struct platform_device
*pdev
)
67 struct msm_dsi
*msm_dsi
;
71 return ERR_PTR(-ENXIO
);
73 msm_dsi
= devm_kzalloc(&pdev
->dev
, sizeof(*msm_dsi
), GFP_KERNEL
);
75 return ERR_PTR(-ENOMEM
);
76 DBG("dsi probed=%p", msm_dsi
);
80 platform_set_drvdata(pdev
, msm_dsi
);
83 ret
= msm_dsi_host_init(msm_dsi
);
88 ret
= dsi_get_phy(msm_dsi
);
92 /* Register to dsi manager */
93 ret
= msm_dsi_manager_register(msm_dsi
);
100 dsi_destroy(msm_dsi
);
104 static int dsi_bind(struct device
*dev
, struct device
*master
, void *data
)
106 struct drm_device
*drm
= dev_get_drvdata(master
);
107 struct msm_drm_private
*priv
= drm
->dev_private
;
108 struct platform_device
*pdev
= to_platform_device(dev
);
109 struct msm_dsi
*msm_dsi
;
112 msm_dsi
= dsi_init(pdev
);
113 if (IS_ERR(msm_dsi
)) {
114 /* Don't fail the bind if the dsi port is not connected */
115 if (PTR_ERR(msm_dsi
) == -ENODEV
)
118 return PTR_ERR(msm_dsi
);
121 priv
->dsi
[msm_dsi
->id
] = msm_dsi
;
126 static void dsi_unbind(struct device
*dev
, struct device
*master
,
129 struct drm_device
*drm
= dev_get_drvdata(master
);
130 struct msm_drm_private
*priv
= drm
->dev_private
;
131 struct msm_dsi
*msm_dsi
= dev_get_drvdata(dev
);
132 int id
= msm_dsi
->id
;
135 dsi_destroy(msm_dsi
);
136 priv
->dsi
[id
] = NULL
;
140 static const struct component_ops dsi_ops
= {
142 .unbind
= dsi_unbind
,
145 static int dsi_dev_probe(struct platform_device
*pdev
)
147 return component_add(&pdev
->dev
, &dsi_ops
);
150 static int dsi_dev_remove(struct platform_device
*pdev
)
153 component_del(&pdev
->dev
, &dsi_ops
);
157 static const struct of_device_id dt_match
[] = {
158 { .compatible
= "qcom,mdss-dsi-ctrl" },
162 static const struct dev_pm_ops dsi_pm_ops
= {
163 SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend
, msm_dsi_runtime_resume
, NULL
)
166 static struct platform_driver dsi_driver
= {
167 .probe
= dsi_dev_probe
,
168 .remove
= dsi_dev_remove
,
171 .of_match_table
= dt_match
,
176 void __init
msm_dsi_register(void)
179 msm_dsi_phy_driver_register();
180 platform_driver_register(&dsi_driver
);
183 void __exit
msm_dsi_unregister(void)
186 msm_dsi_phy_driver_unregister();
187 platform_driver_unregister(&dsi_driver
);
190 int msm_dsi_modeset_init(struct msm_dsi
*msm_dsi
, struct drm_device
*dev
,
191 struct drm_encoder
*encoder
)
193 struct msm_drm_private
*priv
;
194 struct drm_bridge
*ext_bridge
;
197 if (WARN_ON(!encoder
) || WARN_ON(!msm_dsi
) || WARN_ON(!dev
))
200 priv
= dev
->dev_private
;
203 ret
= msm_dsi_host_modeset_init(msm_dsi
->host
, dev
);
205 DRM_DEV_ERROR(dev
->dev
, "failed to modeset init host: %d\n", ret
);
209 if (!msm_dsi_manager_validate_current_config(msm_dsi
->id
))
212 msm_dsi
->encoder
= encoder
;
214 msm_dsi
->bridge
= msm_dsi_manager_bridge_init(msm_dsi
->id
);
215 if (IS_ERR(msm_dsi
->bridge
)) {
216 ret
= PTR_ERR(msm_dsi
->bridge
);
217 DRM_DEV_ERROR(dev
->dev
, "failed to create dsi bridge: %d\n", ret
);
218 msm_dsi
->bridge
= NULL
;
223 * check if the dsi encoder output is connected to a panel or an
224 * external bridge. We create a connector only if we're connected to a
225 * drm_panel device. When we're connected to an external bridge, we
226 * assume that the drm_bridge driver will create the connector itself.
228 ext_bridge
= msm_dsi_host_get_bridge(msm_dsi
->host
);
232 msm_dsi_manager_ext_bridge_init(msm_dsi
->id
);
235 msm_dsi_manager_connector_init(msm_dsi
->id
);
237 if (IS_ERR(msm_dsi
->connector
)) {
238 ret
= PTR_ERR(msm_dsi
->connector
);
239 DRM_DEV_ERROR(dev
->dev
,
240 "failed to create dsi connector: %d\n", ret
);
241 msm_dsi
->connector
= NULL
;
245 msm_dsi_manager_setup_encoder(msm_dsi
->id
);
247 priv
->bridges
[priv
->num_bridges
++] = msm_dsi
->bridge
;
248 priv
->connectors
[priv
->num_connectors
++] = msm_dsi
->connector
;
252 /* bridge/connector are normally destroyed by drm: */
253 if (msm_dsi
->bridge
) {
254 msm_dsi_manager_bridge_destroy(msm_dsi
->bridge
);
255 msm_dsi
->bridge
= NULL
;
258 /* don't destroy connector if we didn't make it */
259 if (msm_dsi
->connector
&& !msm_dsi
->external_bridge
)
260 msm_dsi
->connector
->funcs
->destroy(msm_dsi
->connector
);
262 msm_dsi
->connector
= NULL
;