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
)
164 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
165 pm_runtime_force_resume
)
168 static struct platform_driver dsi_driver
= {
169 .probe
= dsi_dev_probe
,
170 .remove
= dsi_dev_remove
,
173 .of_match_table
= dt_match
,
178 void __init
msm_dsi_register(void)
181 msm_dsi_phy_driver_register();
182 platform_driver_register(&dsi_driver
);
185 void __exit
msm_dsi_unregister(void)
188 msm_dsi_phy_driver_unregister();
189 platform_driver_unregister(&dsi_driver
);
192 int msm_dsi_modeset_init(struct msm_dsi
*msm_dsi
, struct drm_device
*dev
,
193 struct drm_encoder
*encoder
)
195 struct msm_drm_private
*priv
;
196 struct drm_bridge
*ext_bridge
;
199 if (WARN_ON(!encoder
) || WARN_ON(!msm_dsi
) || WARN_ON(!dev
))
202 priv
= dev
->dev_private
;
205 ret
= msm_dsi_host_modeset_init(msm_dsi
->host
, dev
);
207 DRM_DEV_ERROR(dev
->dev
, "failed to modeset init host: %d\n", ret
);
211 if (!msm_dsi_manager_validate_current_config(msm_dsi
->id
))
214 msm_dsi
->encoder
= encoder
;
216 msm_dsi
->bridge
= msm_dsi_manager_bridge_init(msm_dsi
->id
);
217 if (IS_ERR(msm_dsi
->bridge
)) {
218 ret
= PTR_ERR(msm_dsi
->bridge
);
219 DRM_DEV_ERROR(dev
->dev
, "failed to create dsi bridge: %d\n", ret
);
220 msm_dsi
->bridge
= NULL
;
225 * check if the dsi encoder output is connected to a panel or an
226 * external bridge. We create a connector only if we're connected to a
227 * drm_panel device. When we're connected to an external bridge, we
228 * assume that the drm_bridge driver will create the connector itself.
230 ext_bridge
= msm_dsi_host_get_bridge(msm_dsi
->host
);
234 msm_dsi_manager_ext_bridge_init(msm_dsi
->id
);
237 msm_dsi_manager_connector_init(msm_dsi
->id
);
239 if (IS_ERR(msm_dsi
->connector
)) {
240 ret
= PTR_ERR(msm_dsi
->connector
);
241 DRM_DEV_ERROR(dev
->dev
,
242 "failed to create dsi connector: %d\n", ret
);
243 msm_dsi
->connector
= NULL
;
247 msm_dsi_manager_setup_encoder(msm_dsi
->id
);
249 priv
->bridges
[priv
->num_bridges
++] = msm_dsi
->bridge
;
250 priv
->connectors
[priv
->num_connectors
++] = msm_dsi
->connector
;
254 /* bridge/connector are normally destroyed by drm: */
255 if (msm_dsi
->bridge
) {
256 msm_dsi_manager_bridge_destroy(msm_dsi
->bridge
);
257 msm_dsi
->bridge
= NULL
;
260 /* don't destroy connector if we didn't make it */
261 if (msm_dsi
->connector
&& !msm_dsi
->external_bridge
)
262 msm_dsi
->connector
->funcs
->destroy(msm_dsi
->connector
);
264 msm_dsi
->connector
= NULL
;