xref: /linux/drivers/gpu/drm/msm/dsi/dsi_manager.c (revision 5027ec19f1049a07df5b0a37b1f462514cf2724b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4  */
5 
6 #include "drm/drm_bridge_connector.h"
7 
8 #include "msm_kms.h"
9 #include "dsi.h"
10 
11 #define DSI_CLOCK_MASTER	DSI_0
12 #define DSI_CLOCK_SLAVE		DSI_1
13 
14 #define DSI_LEFT		DSI_0
15 #define DSI_RIGHT		DSI_1
16 
17 /* According to the current drm framework sequence, take the encoder of
18  * DSI_1 as master encoder
19  */
20 #define DSI_ENCODER_MASTER	DSI_1
21 #define DSI_ENCODER_SLAVE	DSI_0
22 
23 struct msm_dsi_manager {
24 	struct msm_dsi *dsi[DSI_MAX];
25 
26 	bool is_bonded_dsi;
27 	bool is_sync_needed;
28 	int master_dsi_link_id;
29 };
30 
31 static struct msm_dsi_manager msm_dsim_glb;
32 
33 #define IS_BONDED_DSI()		(msm_dsim_glb.is_bonded_dsi)
34 #define IS_SYNC_NEEDED()	(msm_dsim_glb.is_sync_needed)
35 #define IS_MASTER_DSI_LINK(id)	(msm_dsim_glb.master_dsi_link_id == id)
36 
37 static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
38 {
39 	return msm_dsim_glb.dsi[id];
40 }
41 
42 static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
43 {
44 	return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
45 }
46 
47 static int dsi_mgr_parse_of(struct device_node *np, int id)
48 {
49 	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
50 
51 	/* We assume 2 dsi nodes have the same information of bonded dsi and
52 	 * sync-mode, and only one node specifies master in case of bonded mode.
53 	 */
54 	if (!msm_dsim->is_bonded_dsi)
55 		msm_dsim->is_bonded_dsi = of_property_read_bool(np, "qcom,dual-dsi-mode");
56 
57 	if (msm_dsim->is_bonded_dsi) {
58 		if (of_property_read_bool(np, "qcom,master-dsi"))
59 			msm_dsim->master_dsi_link_id = id;
60 		if (!msm_dsim->is_sync_needed)
61 			msm_dsim->is_sync_needed = of_property_read_bool(
62 					np, "qcom,sync-dual-dsi");
63 	}
64 
65 	return 0;
66 }
67 
68 static int dsi_mgr_setup_components(int id)
69 {
70 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
71 	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
72 	struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
73 	struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
74 	int ret;
75 
76 	if (!IS_BONDED_DSI()) {
77 		ret = msm_dsi_host_register(msm_dsi->host);
78 		if (ret)
79 			return ret;
80 
81 		msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
82 		msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
83 	} else if (other_dsi) {
84 		struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
85 							msm_dsi : other_dsi;
86 		struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
87 							other_dsi : msm_dsi;
88 		/* Register slave host first, so that slave DSI device
89 		 * has a chance to probe, and do not block the master
90 		 * DSI device's probe.
91 		 * Also, do not check defer for the slave host,
92 		 * because only master DSI device adds the panel to global
93 		 * panel list. The panel's device is the master DSI device.
94 		 */
95 		ret = msm_dsi_host_register(slave_link_dsi->host);
96 		if (ret)
97 			return ret;
98 		ret = msm_dsi_host_register(master_link_dsi->host);
99 		if (ret)
100 			return ret;
101 
102 		/* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */
103 		msm_dsi_phy_set_usecase(clk_master_dsi->phy,
104 					MSM_DSI_PHY_MASTER);
105 		msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
106 					MSM_DSI_PHY_SLAVE);
107 		msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
108 		msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
109 	}
110 
111 	return 0;
112 }
113 
114 static int enable_phy(struct msm_dsi *msm_dsi,
115 		      struct msm_dsi_phy_shared_timings *shared_timings)
116 {
117 	struct msm_dsi_phy_clk_request clk_req;
118 	bool is_bonded_dsi = IS_BONDED_DSI();
119 
120 	msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_bonded_dsi);
121 
122 	return msm_dsi_phy_enable(msm_dsi->phy, &clk_req, shared_timings);
123 }
124 
125 static int
126 dsi_mgr_phy_enable(int id,
127 		   struct msm_dsi_phy_shared_timings shared_timings[DSI_MAX])
128 {
129 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
130 	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
131 	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
132 	int ret;
133 
134 	/* In case of bonded DSI, some registers in PHY1 have been programmed
135 	 * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
136 	 * will silently reset those PHY1 registers. Therefore we need to reset
137 	 * and enable both PHYs before any PLL clock operation.
138 	 */
139 	if (IS_BONDED_DSI() && mdsi && sdsi) {
140 		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
141 			msm_dsi_host_reset_phy(mdsi->host);
142 			msm_dsi_host_reset_phy(sdsi->host);
143 
144 			ret = enable_phy(mdsi,
145 					 &shared_timings[DSI_CLOCK_MASTER]);
146 			if (ret)
147 				return ret;
148 			ret = enable_phy(sdsi,
149 					 &shared_timings[DSI_CLOCK_SLAVE]);
150 			if (ret) {
151 				msm_dsi_phy_disable(mdsi->phy);
152 				return ret;
153 			}
154 		}
155 	} else {
156 		msm_dsi_host_reset_phy(msm_dsi->host);
157 		ret = enable_phy(msm_dsi, &shared_timings[id]);
158 		if (ret)
159 			return ret;
160 	}
161 
162 	msm_dsi->phy_enabled = true;
163 
164 	return 0;
165 }
166 
167 static void dsi_mgr_phy_disable(int id)
168 {
169 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
170 	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
171 	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
172 
173 	/* disable DSI phy
174 	 * In bonded dsi configuration, the phy should be disabled for the
175 	 * first controller only when the second controller is disabled.
176 	 */
177 	msm_dsi->phy_enabled = false;
178 	if (IS_BONDED_DSI() && mdsi && sdsi) {
179 		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
180 			msm_dsi_phy_disable(sdsi->phy);
181 			msm_dsi_phy_disable(mdsi->phy);
182 		}
183 	} else {
184 		msm_dsi_phy_disable(msm_dsi->phy);
185 	}
186 }
187 
188 struct dsi_bridge {
189 	struct drm_bridge base;
190 	int id;
191 };
192 
193 #define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base)
194 
195 static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge)
196 {
197 	struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge);
198 	return dsi_bridge->id;
199 }
200 
201 static void msm_dsi_manager_set_split_display(u8 id)
202 {
203 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
204 	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
205 	struct msm_drm_private *priv = msm_dsi->dev->dev_private;
206 	struct msm_kms *kms = priv->kms;
207 	struct msm_dsi *master_dsi, *slave_dsi;
208 
209 	if (IS_BONDED_DSI() && !IS_MASTER_DSI_LINK(id)) {
210 		master_dsi = other_dsi;
211 		slave_dsi = msm_dsi;
212 	} else {
213 		master_dsi = msm_dsi;
214 		slave_dsi = other_dsi;
215 	}
216 
217 	if (!msm_dsi->external_bridge || !IS_BONDED_DSI())
218 		return;
219 
220 	/*
221 	 * Set split display info to kms once bonded DSI panel is connected to
222 	 * both hosts.
223 	 */
224 	if (other_dsi && other_dsi->external_bridge && kms->funcs->set_split_display) {
225 		kms->funcs->set_split_display(kms, master_dsi->encoder,
226 					      slave_dsi->encoder,
227 					      msm_dsi_is_cmd_mode(msm_dsi));
228 	}
229 }
230 
231 static int dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
232 {
233 	int id = dsi_mgr_bridge_get_id(bridge);
234 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
235 	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
236 	struct mipi_dsi_host *host = msm_dsi->host;
237 	struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
238 	bool is_bonded_dsi = IS_BONDED_DSI();
239 	int ret;
240 
241 	DBG("id=%d", id);
242 
243 	ret = dsi_mgr_phy_enable(id, phy_shared_timings);
244 	if (ret)
245 		goto phy_en_fail;
246 
247 	ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_bonded_dsi, msm_dsi->phy);
248 	if (ret) {
249 		pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
250 		goto host_on_fail;
251 	}
252 
253 	if (is_bonded_dsi && msm_dsi1) {
254 		ret = msm_dsi_host_power_on(msm_dsi1->host,
255 				&phy_shared_timings[DSI_1], is_bonded_dsi, msm_dsi1->phy);
256 		if (ret) {
257 			pr_err("%s: power on host1 failed, %d\n",
258 							__func__, ret);
259 			goto host1_on_fail;
260 		}
261 	}
262 
263 	/*
264 	 * Enable before preparing the panel, disable after unpreparing, so
265 	 * that the panel can communicate over the DSI link.
266 	 */
267 	msm_dsi_host_enable_irq(host);
268 	if (is_bonded_dsi && msm_dsi1)
269 		msm_dsi_host_enable_irq(msm_dsi1->host);
270 
271 	return 0;
272 
273 host1_on_fail:
274 	msm_dsi_host_power_off(host);
275 host_on_fail:
276 	dsi_mgr_phy_disable(id);
277 phy_en_fail:
278 	return ret;
279 }
280 
281 static void dsi_mgr_bridge_power_off(struct drm_bridge *bridge)
282 {
283 	int id = dsi_mgr_bridge_get_id(bridge);
284 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
285 	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
286 	struct mipi_dsi_host *host = msm_dsi->host;
287 	bool is_bonded_dsi = IS_BONDED_DSI();
288 
289 	msm_dsi_host_disable_irq(host);
290 	if (is_bonded_dsi && msm_dsi1) {
291 		msm_dsi_host_disable_irq(msm_dsi1->host);
292 		msm_dsi_host_power_off(msm_dsi1->host);
293 	}
294 	msm_dsi_host_power_off(host);
295 	dsi_mgr_phy_disable(id);
296 }
297 
298 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
299 {
300 	int id = dsi_mgr_bridge_get_id(bridge);
301 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
302 	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
303 	struct mipi_dsi_host *host = msm_dsi->host;
304 	bool is_bonded_dsi = IS_BONDED_DSI();
305 	int ret;
306 
307 	DBG("id=%d", id);
308 	if (!msm_dsi_device_connected(msm_dsi))
309 		return;
310 
311 	/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
312 	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
313 		return;
314 
315 	ret = dsi_mgr_bridge_power_on(bridge);
316 	if (ret) {
317 		dev_err(&msm_dsi->pdev->dev, "Power on failed: %d\n", ret);
318 		return;
319 	}
320 
321 	ret = msm_dsi_host_enable(host);
322 	if (ret) {
323 		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
324 		goto host_en_fail;
325 	}
326 
327 	if (is_bonded_dsi && msm_dsi1) {
328 		ret = msm_dsi_host_enable(msm_dsi1->host);
329 		if (ret) {
330 			pr_err("%s: enable host1 failed, %d\n", __func__, ret);
331 			goto host1_en_fail;
332 		}
333 	}
334 
335 	return;
336 
337 host1_en_fail:
338 	msm_dsi_host_disable(host);
339 host_en_fail:
340 	dsi_mgr_bridge_power_off(bridge);
341 }
342 
343 void msm_dsi_manager_tpg_enable(void)
344 {
345 	struct msm_dsi *m_dsi = dsi_mgr_get_dsi(DSI_0);
346 	struct msm_dsi *s_dsi = dsi_mgr_get_dsi(DSI_1);
347 
348 	/* if dual dsi, trigger tpg on master first then slave */
349 	if (m_dsi) {
350 		msm_dsi_host_test_pattern_en(m_dsi->host);
351 		if (IS_BONDED_DSI() && s_dsi)
352 			msm_dsi_host_test_pattern_en(s_dsi->host);
353 	}
354 }
355 
356 static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
357 {
358 	int id = dsi_mgr_bridge_get_id(bridge);
359 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
360 	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
361 	struct mipi_dsi_host *host = msm_dsi->host;
362 	bool is_bonded_dsi = IS_BONDED_DSI();
363 	int ret;
364 
365 	DBG("id=%d", id);
366 
367 	if (!msm_dsi_device_connected(msm_dsi))
368 		return;
369 
370 	/*
371 	 * Do nothing with the host if it is slave-DSI in case of bonded DSI.
372 	 * It is safe to call dsi_mgr_phy_disable() here because a single PHY
373 	 * won't be diabled until both PHYs request disable.
374 	 */
375 	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
376 		goto disable_phy;
377 
378 	ret = msm_dsi_host_disable(host);
379 	if (ret)
380 		pr_err("%s: host %d disable failed, %d\n", __func__, id, ret);
381 
382 	if (is_bonded_dsi && msm_dsi1) {
383 		ret = msm_dsi_host_disable(msm_dsi1->host);
384 		if (ret)
385 			pr_err("%s: host1 disable failed, %d\n", __func__, ret);
386 	}
387 
388 	msm_dsi_host_disable_irq(host);
389 	if (is_bonded_dsi && msm_dsi1)
390 		msm_dsi_host_disable_irq(msm_dsi1->host);
391 
392 	/* Save PHY status if it is a clock source */
393 	msm_dsi_phy_pll_save_state(msm_dsi->phy);
394 
395 	ret = msm_dsi_host_power_off(host);
396 	if (ret)
397 		pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
398 
399 	if (is_bonded_dsi && msm_dsi1) {
400 		ret = msm_dsi_host_power_off(msm_dsi1->host);
401 		if (ret)
402 			pr_err("%s: host1 power off failed, %d\n",
403 								__func__, ret);
404 	}
405 
406 disable_phy:
407 	dsi_mgr_phy_disable(id);
408 }
409 
410 static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
411 		const struct drm_display_mode *mode,
412 		const struct drm_display_mode *adjusted_mode)
413 {
414 	int id = dsi_mgr_bridge_get_id(bridge);
415 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
416 	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
417 	struct mipi_dsi_host *host = msm_dsi->host;
418 	bool is_bonded_dsi = IS_BONDED_DSI();
419 
420 	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
421 
422 	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
423 		return;
424 
425 	msm_dsi_host_set_display_mode(host, adjusted_mode);
426 	if (is_bonded_dsi && other_dsi)
427 		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
428 }
429 
430 static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
431 						      const struct drm_display_info *info,
432 						      const struct drm_display_mode *mode)
433 {
434 	int id = dsi_mgr_bridge_get_id(bridge);
435 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
436 	struct mipi_dsi_host *host = msm_dsi->host;
437 	struct platform_device *pdev = msm_dsi->pdev;
438 	struct dev_pm_opp *opp;
439 	unsigned long byte_clk_rate;
440 
441 	byte_clk_rate = dsi_byte_clk_get_rate(host, IS_BONDED_DSI(), mode);
442 
443 	opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
444 	if (!IS_ERR(opp)) {
445 		dev_pm_opp_put(opp);
446 	} else if (PTR_ERR(opp) == -ERANGE) {
447 		/*
448 		 * An empty table is created by devm_pm_opp_set_clkname() even
449 		 * if there is none. Thus find_freq_ceil will still return
450 		 * -ERANGE in such case.
451 		 */
452 		if (dev_pm_opp_get_opp_count(&pdev->dev) != 0)
453 			return MODE_CLOCK_RANGE;
454 	} else {
455 			return MODE_ERROR;
456 	}
457 
458 	return msm_dsi_host_check_dsc(host, mode);
459 }
460 
461 static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
462 	.pre_enable = dsi_mgr_bridge_pre_enable,
463 	.post_disable = dsi_mgr_bridge_post_disable,
464 	.mode_set = dsi_mgr_bridge_mode_set,
465 	.mode_valid = dsi_mgr_bridge_mode_valid,
466 };
467 
468 /* initialize bridge */
469 int msm_dsi_manager_bridge_init(struct msm_dsi *msm_dsi)
470 {
471 	struct drm_bridge *bridge = NULL;
472 	struct dsi_bridge *dsi_bridge;
473 	struct drm_encoder *encoder;
474 	int ret;
475 
476 	dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
477 				sizeof(*dsi_bridge), GFP_KERNEL);
478 	if (!dsi_bridge)
479 		return -ENOMEM;
480 
481 	dsi_bridge->id = msm_dsi->id;
482 
483 	encoder = msm_dsi->encoder;
484 
485 	bridge = &dsi_bridge->base;
486 	bridge->funcs = &dsi_mgr_bridge_funcs;
487 
488 	ret = devm_drm_bridge_add(msm_dsi->dev->dev, bridge);
489 	if (ret)
490 		return ret;
491 
492 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
493 	if (ret)
494 		return ret;
495 
496 	msm_dsi->bridge = bridge;
497 
498 	return 0;
499 }
500 
501 int msm_dsi_manager_ext_bridge_init(u8 id)
502 {
503 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
504 	struct drm_device *dev = msm_dsi->dev;
505 	struct drm_encoder *encoder;
506 	struct drm_bridge *int_bridge, *ext_bridge;
507 	int ret;
508 
509 	int_bridge = msm_dsi->bridge;
510 	ext_bridge = devm_drm_of_get_bridge(&msm_dsi->pdev->dev,
511 					    msm_dsi->pdev->dev.of_node, 1, 0);
512 	if (IS_ERR(ext_bridge))
513 		return PTR_ERR(ext_bridge);
514 
515 	msm_dsi->external_bridge = ext_bridge;
516 
517 	encoder = msm_dsi->encoder;
518 
519 	/*
520 	 * Try first to create the bridge without it creating its own
521 	 * connector.. currently some bridges support this, and others
522 	 * do not (and some support both modes)
523 	 */
524 	ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
525 			DRM_BRIDGE_ATTACH_NO_CONNECTOR);
526 	if (ret == -EINVAL) {
527 		/*
528 		 * link the internal dsi bridge to the external bridge,
529 		 * connector is created by the next bridge.
530 		 */
531 		ret = drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
532 		if (ret < 0)
533 			return ret;
534 	} else {
535 		struct drm_connector *connector;
536 
537 		/* We are in charge of the connector, create one now. */
538 		connector = drm_bridge_connector_init(dev, encoder);
539 		if (IS_ERR(connector)) {
540 			DRM_ERROR("Unable to create bridge connector\n");
541 			return PTR_ERR(connector);
542 		}
543 
544 		ret = drm_connector_attach_encoder(connector, encoder);
545 		if (ret < 0)
546 			return ret;
547 	}
548 
549 	/* The pipeline is ready, ping encoders if necessary */
550 	msm_dsi_manager_set_split_display(id);
551 
552 	return 0;
553 }
554 
555 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
556 {
557 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
558 	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
559 	struct mipi_dsi_host *host = msm_dsi->host;
560 	bool is_read = (msg->rx_buf && msg->rx_len);
561 	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
562 	int ret;
563 
564 	if (!msg->tx_buf || !msg->tx_len)
565 		return 0;
566 
567 	/* In bonded master case, panel requires the same commands sent to
568 	 * both DSI links. Host issues the command trigger to both links
569 	 * when DSI_1 calls the cmd transfer function, no matter it happens
570 	 * before or after DSI_0 cmd transfer.
571 	 */
572 	if (need_sync && (id == DSI_0))
573 		return is_read ? msg->rx_len : msg->tx_len;
574 
575 	if (need_sync && msm_dsi0) {
576 		ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg);
577 		if (ret) {
578 			pr_err("%s: failed to prepare non-trigger host, %d\n",
579 				__func__, ret);
580 			return ret;
581 		}
582 	}
583 	ret = msm_dsi_host_xfer_prepare(host, msg);
584 	if (ret) {
585 		pr_err("%s: failed to prepare host, %d\n", __func__, ret);
586 		goto restore_host0;
587 	}
588 
589 	ret = is_read ? msm_dsi_host_cmd_rx(host, msg) :
590 			msm_dsi_host_cmd_tx(host, msg);
591 
592 	msm_dsi_host_xfer_restore(host, msg);
593 
594 restore_host0:
595 	if (need_sync && msm_dsi0)
596 		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
597 
598 	return ret;
599 }
600 
601 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
602 {
603 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
604 	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
605 	struct mipi_dsi_host *host = msm_dsi->host;
606 
607 	if (IS_SYNC_NEEDED() && (id == DSI_0))
608 		return false;
609 
610 	if (IS_SYNC_NEEDED() && msm_dsi0)
611 		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
612 
613 	msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
614 
615 	return true;
616 }
617 
618 int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
619 {
620 	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
621 	int id = msm_dsi->id;
622 	int ret;
623 
624 	if (id >= DSI_MAX) {
625 		pr_err("%s: invalid id %d\n", __func__, id);
626 		return -EINVAL;
627 	}
628 
629 	if (msm_dsim->dsi[id]) {
630 		pr_err("%s: dsi%d already registered\n", __func__, id);
631 		return -EBUSY;
632 	}
633 
634 	msm_dsim->dsi[id] = msm_dsi;
635 
636 	ret = dsi_mgr_parse_of(msm_dsi->pdev->dev.of_node, id);
637 	if (ret) {
638 		pr_err("%s: failed to parse OF DSI info\n", __func__);
639 		goto fail;
640 	}
641 
642 	ret = dsi_mgr_setup_components(id);
643 	if (ret) {
644 		pr_err("%s: failed to register mipi dsi host for DSI %d: %d\n",
645 			__func__, id, ret);
646 		goto fail;
647 	}
648 
649 	return 0;
650 
651 fail:
652 	msm_dsim->dsi[id] = NULL;
653 	return ret;
654 }
655 
656 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi)
657 {
658 	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
659 
660 	if (msm_dsi->host)
661 		msm_dsi_host_unregister(msm_dsi->host);
662 
663 	if (msm_dsi->id >= 0)
664 		msm_dsim->dsi[msm_dsi->id] = NULL;
665 }
666 
667 bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
668 {
669 	return IS_BONDED_DSI();
670 }
671 
672 bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
673 {
674 	return IS_MASTER_DSI_LINK(msm_dsi->id);
675 }
676