Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
  4 */
  5
  6#include "msm_kms.h"
  7#include "dsi.h"
  8
  9#define DSI_CLOCK_MASTER	DSI_0
 10#define DSI_CLOCK_SLAVE		DSI_1
 11
 12#define DSI_LEFT		DSI_0
 13#define DSI_RIGHT		DSI_1
 14
 15/* According to the current drm framework sequence, take the encoder of
 16 * DSI_1 as master encoder
 17 */
 18#define DSI_ENCODER_MASTER	DSI_1
 19#define DSI_ENCODER_SLAVE	DSI_0
 20
 21struct msm_dsi_manager {
 22	struct msm_dsi *dsi[DSI_MAX];
 23
 24	bool is_dual_dsi;
 25	bool is_sync_needed;
 26	int master_dsi_link_id;
 27};
 28
 29static struct msm_dsi_manager msm_dsim_glb;
 30
 31#define IS_DUAL_DSI()		(msm_dsim_glb.is_dual_dsi)
 32#define IS_SYNC_NEEDED()	(msm_dsim_glb.is_sync_needed)
 33#define IS_MASTER_DSI_LINK(id)	(msm_dsim_glb.master_dsi_link_id == id)
 34
 35static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
 36{
 37	return msm_dsim_glb.dsi[id];
 38}
 39
 40static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
 41{
 42	return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
 43}
 44
 45static int dsi_mgr_parse_dual_dsi(struct device_node *np, int id)
 46{
 47	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
 48
 49	/* We assume 2 dsi nodes have the same information of dual-dsi and
 50	 * sync-mode, and only one node specifies master in case of dual mode.
 51	 */
 52	if (!msm_dsim->is_dual_dsi)
 53		msm_dsim->is_dual_dsi = of_property_read_bool(
 54						np, "qcom,dual-dsi-mode");
 55
 56	if (msm_dsim->is_dual_dsi) {
 57		if (of_property_read_bool(np, "qcom,master-dsi"))
 58			msm_dsim->master_dsi_link_id = id;
 59		if (!msm_dsim->is_sync_needed)
 60			msm_dsim->is_sync_needed = of_property_read_bool(
 61					np, "qcom,sync-dual-dsi");
 62	}
 63
 64	return 0;
 65}
 66
 67static int dsi_mgr_setup_components(int id)
 68{
 69	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 70	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
 71	struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
 72	struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
 73	int ret;
 74
 75	if (!IS_DUAL_DSI()) {
 76		ret = msm_dsi_host_register(msm_dsi->host, true);
 77		if (ret)
 78			return ret;
 79
 80		msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
 81		ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
 82	} else if (!other_dsi) {
 83		ret = 0;
 84	} else {
 85		struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
 86							msm_dsi : other_dsi;
 87		struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
 88							other_dsi : msm_dsi;
 89		/* Register slave host first, so that slave DSI device
 90		 * has a chance to probe, and do not block the master
 91		 * DSI device's probe.
 92		 * Also, do not check defer for the slave host,
 93		 * because only master DSI device adds the panel to global
 94		 * panel list. The panel's device is the master DSI device.
 95		 */
 96		ret = msm_dsi_host_register(slave_link_dsi->host, false);
 97		if (ret)
 98			return ret;
 99		ret = msm_dsi_host_register(master_link_dsi->host, true);
100		if (ret)
101			return ret;
102
103		/* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */
104		msm_dsi_phy_set_usecase(clk_master_dsi->phy,
105					MSM_DSI_PHY_MASTER);
106		msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
107					MSM_DSI_PHY_SLAVE);
108		ret = msm_dsi_host_set_src_pll(msm_dsi->host, clk_master_dsi->phy);
109		if (ret)
110			return ret;
111		ret = msm_dsi_host_set_src_pll(other_dsi->host, clk_master_dsi->phy);
112	}
113
114	return ret;
115}
116
117static int enable_phy(struct msm_dsi *msm_dsi,
118		      struct msm_dsi_phy_shared_timings *shared_timings)
119{
120	struct msm_dsi_phy_clk_request clk_req;
121	int ret;
122	bool is_dual_dsi = IS_DUAL_DSI();
123
124	msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_dual_dsi);
125
126	ret = msm_dsi_phy_enable(msm_dsi->phy, &clk_req);
127	msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings);
128
129	return ret;
130}
131
132static int
133dsi_mgr_phy_enable(int id,
134		   struct msm_dsi_phy_shared_timings shared_timings[DSI_MAX])
135{
136	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
137	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
138	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
139	int ret;
140
141	/* In case of dual DSI, some registers in PHY1 have been programmed
142	 * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
143	 * will silently reset those PHY1 registers. Therefore we need to reset
144	 * and enable both PHYs before any PLL clock operation.
145	 */
146	if (IS_DUAL_DSI() && mdsi && sdsi) {
147		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
148			msm_dsi_host_reset_phy(mdsi->host);
149			msm_dsi_host_reset_phy(sdsi->host);
150
151			ret = enable_phy(mdsi,
152					 &shared_timings[DSI_CLOCK_MASTER]);
153			if (ret)
154				return ret;
155			ret = enable_phy(sdsi,
156					 &shared_timings[DSI_CLOCK_SLAVE]);
157			if (ret) {
158				msm_dsi_phy_disable(mdsi->phy);
159				return ret;
160			}
161		}
162	} else {
163		msm_dsi_host_reset_phy(msm_dsi->host);
164		ret = enable_phy(msm_dsi, &shared_timings[id]);
165		if (ret)
166			return ret;
167	}
168
169	msm_dsi->phy_enabled = true;
170
171	return 0;
172}
173
174static void dsi_mgr_phy_disable(int id)
175{
176	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
177	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
178	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
179
180	/* disable DSI phy
181	 * In dual-dsi configuration, the phy should be disabled for the
182	 * first controller only when the second controller is disabled.
183	 */
184	msm_dsi->phy_enabled = false;
185	if (IS_DUAL_DSI() && mdsi && sdsi) {
186		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
187			msm_dsi_phy_disable(sdsi->phy);
188			msm_dsi_phy_disable(mdsi->phy);
189		}
190	} else {
191		msm_dsi_phy_disable(msm_dsi->phy);
192	}
193}
194
195struct dsi_connector {
196	struct drm_connector base;
197	int id;
198};
199
200struct dsi_bridge {
201	struct drm_bridge base;
202	int id;
203};
204
205#define to_dsi_connector(x) container_of(x, struct dsi_connector, base)
206#define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base)
207
208static inline int dsi_mgr_connector_get_id(struct drm_connector *connector)
209{
210	struct dsi_connector *dsi_connector = to_dsi_connector(connector);
211	return dsi_connector->id;
212}
213
214static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge)
215{
216	struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge);
217	return dsi_bridge->id;
218}
219
220static bool dsi_mgr_is_cmd_mode(struct msm_dsi *msm_dsi)
221{
222	unsigned long host_flags = msm_dsi_host_get_mode_flags(msm_dsi->host);
223	return !(host_flags & MIPI_DSI_MODE_VIDEO);
224}
225
226void msm_dsi_manager_setup_encoder(int id)
227{
228	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
229	struct msm_drm_private *priv = msm_dsi->dev->dev_private;
230	struct msm_kms *kms = priv->kms;
231	struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi);
232
233	if (encoder && kms->funcs->set_encoder_mode)
234		kms->funcs->set_encoder_mode(kms, encoder,
235					     dsi_mgr_is_cmd_mode(msm_dsi));
236}
237
238static int msm_dsi_manager_panel_init(struct drm_connector *conn, u8 id)
239{
240	struct msm_drm_private *priv = conn->dev->dev_private;
241	struct msm_kms *kms = priv->kms;
242	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
243	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
244	struct msm_dsi *master_dsi, *slave_dsi;
245	struct drm_panel *panel;
246
247	if (IS_DUAL_DSI() && !IS_MASTER_DSI_LINK(id)) {
248		master_dsi = other_dsi;
249		slave_dsi = msm_dsi;
250	} else {
251		master_dsi = msm_dsi;
252		slave_dsi = other_dsi;
253	}
254
255	/*
256	 * There is only 1 panel in the global panel list for dual DSI mode.
257	 * Therefore slave dsi should get the drm_panel instance from master
258	 * dsi.
259	 */
260	panel = msm_dsi_host_get_panel(master_dsi->host);
261	if (IS_ERR(panel)) {
262		DRM_ERROR("Could not find panel for %u (%ld)\n", msm_dsi->id,
263			  PTR_ERR(panel));
264		return PTR_ERR(panel);
265	}
266
267	if (!panel || !IS_DUAL_DSI())
268		goto out;
269
270	drm_object_attach_property(&conn->base,
271				   conn->dev->mode_config.tile_property, 0);
272
273	/*
274	 * Set split display info to kms once dual DSI panel is connected to
275	 * both hosts.
276	 */
277	if (other_dsi && other_dsi->panel && kms->funcs->set_split_display) {
278		kms->funcs->set_split_display(kms, master_dsi->encoder,
279					      slave_dsi->encoder,
280					      dsi_mgr_is_cmd_mode(msm_dsi));
281	}
282
283out:
284	msm_dsi->panel = panel;
285	return 0;
286}
287
288static enum drm_connector_status dsi_mgr_connector_detect(
289		struct drm_connector *connector, bool force)
290{
291	int id = dsi_mgr_connector_get_id(connector);
292	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
293
294	return msm_dsi->panel ? connector_status_connected :
295		connector_status_disconnected;
296}
297
298static void dsi_mgr_connector_destroy(struct drm_connector *connector)
299{
300	struct dsi_connector *dsi_connector = to_dsi_connector(connector);
301
302	DBG("");
303
304	drm_connector_cleanup(connector);
305
306	kfree(dsi_connector);
307}
308
309static int dsi_mgr_connector_get_modes(struct drm_connector *connector)
310{
311	int id = dsi_mgr_connector_get_id(connector);
312	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
313	struct drm_panel *panel = msm_dsi->panel;
314	int num;
315
316	if (!panel)
317		return 0;
318
319	/*
320	 * In dual DSI mode, we have one connector that can be
321	 * attached to the drm_panel.
322	 */
323	num = drm_panel_get_modes(panel, connector);
324	if (!num)
325		return 0;
326
327	return num;
328}
329
330static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector,
331				struct drm_display_mode *mode)
332{
333	int id = dsi_mgr_connector_get_id(connector);
334	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
335	struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi);
336	struct msm_drm_private *priv = connector->dev->dev_private;
337	struct msm_kms *kms = priv->kms;
338	long actual, requested;
339
340	DBG("");
341	requested = 1000 * mode->clock;
342	actual = kms->funcs->round_pixclk(kms, requested, encoder);
343
344	DBG("requested=%ld, actual=%ld", requested, actual);
345	if (actual != requested)
346		return MODE_CLOCK_RANGE;
347
348	return MODE_OK;
349}
350
351static struct drm_encoder *
352dsi_mgr_connector_best_encoder(struct drm_connector *connector)
353{
354	int id = dsi_mgr_connector_get_id(connector);
355	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
356
357	DBG("");
358	return msm_dsi_get_encoder(msm_dsi);
359}
360
361static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
362{
363	int id = dsi_mgr_bridge_get_id(bridge);
364	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
365	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
366	struct mipi_dsi_host *host = msm_dsi->host;
367	struct drm_panel *panel = msm_dsi->panel;
368	struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
369	bool is_dual_dsi = IS_DUAL_DSI();
370	int ret;
371
372	DBG("id=%d", id);
373	if (!msm_dsi_device_connected(msm_dsi))
374		return;
375
376	/* Do nothing with the host if it is slave-DSI in case of dual DSI */
377	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
378		return;
379
380	ret = dsi_mgr_phy_enable(id, phy_shared_timings);
381	if (ret)
382		goto phy_en_fail;
383
384	ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi);
385	if (ret) {
386		pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
387		goto host_on_fail;
388	}
389
390	if (is_dual_dsi && msm_dsi1) {
391		ret = msm_dsi_host_power_on(msm_dsi1->host,
392				&phy_shared_timings[DSI_1], is_dual_dsi);
393		if (ret) {
394			pr_err("%s: power on host1 failed, %d\n",
395							__func__, ret);
396			goto host1_on_fail;
397		}
398	}
399
400	/* Always call panel functions once, because even for dual panels,
401	 * there is only one drm_panel instance.
402	 */
403	if (panel) {
404		ret = drm_panel_prepare(panel);
405		if (ret) {
406			pr_err("%s: prepare panel %d failed, %d\n", __func__,
407								id, ret);
408			goto panel_prep_fail;
409		}
410	}
411
412	ret = msm_dsi_host_enable(host);
413	if (ret) {
414		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
415		goto host_en_fail;
416	}
417
418	if (is_dual_dsi && msm_dsi1) {
419		ret = msm_dsi_host_enable(msm_dsi1->host);
420		if (ret) {
421			pr_err("%s: enable host1 failed, %d\n", __func__, ret);
422			goto host1_en_fail;
423		}
424	}
425
426	return;
427
428host1_en_fail:
429	msm_dsi_host_disable(host);
430host_en_fail:
431	if (panel)
432		drm_panel_unprepare(panel);
433panel_prep_fail:
434	if (is_dual_dsi && msm_dsi1)
435		msm_dsi_host_power_off(msm_dsi1->host);
436host1_on_fail:
437	msm_dsi_host_power_off(host);
438host_on_fail:
439	dsi_mgr_phy_disable(id);
440phy_en_fail:
441	return;
442}
443
444static void dsi_mgr_bridge_enable(struct drm_bridge *bridge)
445{
446	int id = dsi_mgr_bridge_get_id(bridge);
447	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
448	struct drm_panel *panel = msm_dsi->panel;
449	bool is_dual_dsi = IS_DUAL_DSI();
450	int ret;
451
452	DBG("id=%d", id);
453	if (!msm_dsi_device_connected(msm_dsi))
454		return;
455
456	/* Do nothing with the host if it is slave-DSI in case of dual DSI */
457	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
458		return;
459
460	if (panel) {
461		ret = drm_panel_enable(panel);
462		if (ret) {
463			pr_err("%s: enable panel %d failed, %d\n", __func__, id,
464									ret);
465		}
466	}
467}
468
469static void dsi_mgr_bridge_disable(struct drm_bridge *bridge)
470{
471	int id = dsi_mgr_bridge_get_id(bridge);
472	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
473	struct drm_panel *panel = msm_dsi->panel;
474	bool is_dual_dsi = IS_DUAL_DSI();
475	int ret;
476
477	DBG("id=%d", id);
478	if (!msm_dsi_device_connected(msm_dsi))
479		return;
480
481	/* Do nothing with the host if it is slave-DSI in case of dual DSI */
482	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
483		return;
484
485	if (panel) {
486		ret = drm_panel_disable(panel);
487		if (ret)
488			pr_err("%s: Panel %d OFF failed, %d\n", __func__, id,
489									ret);
490	}
491}
492
493static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
494{
495	int id = dsi_mgr_bridge_get_id(bridge);
496	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
497	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
498	struct mipi_dsi_host *host = msm_dsi->host;
499	struct drm_panel *panel = msm_dsi->panel;
500	bool is_dual_dsi = IS_DUAL_DSI();
501	int ret;
502
503	DBG("id=%d", id);
504
505	if (!msm_dsi_device_connected(msm_dsi))
506		return;
507
508	/*
509	 * Do nothing with the host if it is slave-DSI in case of dual DSI.
510	 * It is safe to call dsi_mgr_phy_disable() here because a single PHY
511	 * won't be diabled until both PHYs request disable.
512	 */
513	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
514		goto disable_phy;
515
516	ret = msm_dsi_host_disable(host);
517	if (ret)
518		pr_err("%s: host %d disable failed, %d\n", __func__, id, ret);
519
520	if (is_dual_dsi && msm_dsi1) {
521		ret = msm_dsi_host_disable(msm_dsi1->host);
522		if (ret)
523			pr_err("%s: host1 disable failed, %d\n", __func__, ret);
524	}
525
526	if (panel) {
527		ret = drm_panel_unprepare(panel);
528		if (ret)
529			pr_err("%s: Panel %d unprepare failed,%d\n", __func__,
530								id, ret);
531	}
532
533	/* Save PHY status if it is a clock source */
534	msm_dsi_phy_pll_save_state(msm_dsi->phy);
535
536	ret = msm_dsi_host_power_off(host);
537	if (ret)
538		pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
539
540	if (is_dual_dsi && msm_dsi1) {
541		ret = msm_dsi_host_power_off(msm_dsi1->host);
542		if (ret)
543			pr_err("%s: host1 power off failed, %d\n",
544								__func__, ret);
545	}
546
547disable_phy:
548	dsi_mgr_phy_disable(id);
549}
550
551static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
552		const struct drm_display_mode *mode,
553		const struct drm_display_mode *adjusted_mode)
554{
555	int id = dsi_mgr_bridge_get_id(bridge);
556	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
557	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
558	struct mipi_dsi_host *host = msm_dsi->host;
559	bool is_dual_dsi = IS_DUAL_DSI();
560
561	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
562
563	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
564		return;
565
566	msm_dsi_host_set_display_mode(host, adjusted_mode);
567	if (is_dual_dsi && other_dsi)
568		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
569}
570
571static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
572	.detect = dsi_mgr_connector_detect,
573	.fill_modes = drm_helper_probe_single_connector_modes,
574	.destroy = dsi_mgr_connector_destroy,
575	.reset = drm_atomic_helper_connector_reset,
576	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
577	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
578};
579
580static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = {
581	.get_modes = dsi_mgr_connector_get_modes,
582	.mode_valid = dsi_mgr_connector_mode_valid,
583	.best_encoder = dsi_mgr_connector_best_encoder,
584};
585
586static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
587	.pre_enable = dsi_mgr_bridge_pre_enable,
588	.enable = dsi_mgr_bridge_enable,
589	.disable = dsi_mgr_bridge_disable,
590	.post_disable = dsi_mgr_bridge_post_disable,
591	.mode_set = dsi_mgr_bridge_mode_set,
592};
593
594/* initialize connector when we're connected to a drm_panel */
595struct drm_connector *msm_dsi_manager_connector_init(u8 id)
596{
597	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
598	struct drm_connector *connector = NULL;
599	struct dsi_connector *dsi_connector;
600	int ret;
601
602	dsi_connector = kzalloc(sizeof(*dsi_connector), GFP_KERNEL);
603	if (!dsi_connector)
604		return ERR_PTR(-ENOMEM);
605
606	dsi_connector->id = id;
607
608	connector = &dsi_connector->base;
609
610	ret = drm_connector_init(msm_dsi->dev, connector,
611			&dsi_mgr_connector_funcs, DRM_MODE_CONNECTOR_DSI);
612	if (ret)
613		return ERR_PTR(ret);
614
615	drm_connector_helper_add(connector, &dsi_mgr_conn_helper_funcs);
616
617	/* Enable HPD to let hpd event is handled
618	 * when panel is attached to the host.
619	 */
620	connector->polled = DRM_CONNECTOR_POLL_HPD;
621
622	/* Display driver doesn't support interlace now. */
623	connector->interlace_allowed = 0;
624	connector->doublescan_allowed = 0;
625
626	drm_connector_attach_encoder(connector, msm_dsi->encoder);
627
628	ret = msm_dsi_manager_panel_init(connector, id);
629	if (ret) {
630		DRM_DEV_ERROR(msm_dsi->dev->dev, "init panel failed %d\n", ret);
631		goto fail;
632	}
633
634	return connector;
635
636fail:
637	connector->funcs->destroy(msm_dsi->connector);
638	return ERR_PTR(ret);
639}
640
641bool msm_dsi_manager_validate_current_config(u8 id)
642{
643	bool is_dual_dsi = IS_DUAL_DSI();
644
645	/*
646	 * For dual DSI, we only have one drm panel. For this
647	 * use case, we register only one bridge/connector.
648	 * Skip bridge/connector initialisation if it is
649	 * slave-DSI for dual DSI configuration.
650	 */
651	if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) {
652		DBG("Skip bridge registration for slave DSI->id: %d\n", id);
653		return false;
654	}
655	return true;
656}
657
658/* initialize bridge */
659struct drm_bridge *msm_dsi_manager_bridge_init(u8 id)
660{
661	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
662	struct drm_bridge *bridge = NULL;
663	struct dsi_bridge *dsi_bridge;
664	struct drm_encoder *encoder;
665	int ret;
666
667	dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
668				sizeof(*dsi_bridge), GFP_KERNEL);
669	if (!dsi_bridge) {
670		ret = -ENOMEM;
671		goto fail;
672	}
673
674	dsi_bridge->id = id;
675
676	encoder = msm_dsi->encoder;
677
678	bridge = &dsi_bridge->base;
679	bridge->funcs = &dsi_mgr_bridge_funcs;
680
681	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
682	if (ret)
683		goto fail;
684
685	return bridge;
686
687fail:
688	if (bridge)
689		msm_dsi_manager_bridge_destroy(bridge);
690
691	return ERR_PTR(ret);
692}
693
694struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
695{
696	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
697	struct drm_device *dev = msm_dsi->dev;
698	struct drm_encoder *encoder;
699	struct drm_bridge *int_bridge, *ext_bridge;
700	struct drm_connector *connector;
701	struct list_head *connector_list;
702
703	int_bridge = msm_dsi->bridge;
704	ext_bridge = msm_dsi->external_bridge =
705			msm_dsi_host_get_bridge(msm_dsi->host);
706
707	encoder = msm_dsi->encoder;
708
709	/* link the internal dsi bridge to the external bridge */
710	drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
711
712	/*
713	 * we need the drm_connector created by the external bridge
714	 * driver (or someone else) to feed it to our driver's
715	 * priv->connector[] list, mainly for msm_fbdev_init()
716	 */
717	connector_list = &dev->mode_config.connector_list;
718
719	list_for_each_entry(connector, connector_list, head) {
720		if (drm_connector_has_possible_encoder(connector, encoder))
721			return connector;
722	}
723
724	return ERR_PTR(-ENODEV);
725}
726
727void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
728{
729}
730
731int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
732{
733	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
734	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
735	struct mipi_dsi_host *host = msm_dsi->host;
736	bool is_read = (msg->rx_buf && msg->rx_len);
737	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
738	int ret;
739
740	if (!msg->tx_buf || !msg->tx_len)
741		return 0;
742
743	/* In dual master case, panel requires the same commands sent to
744	 * both DSI links. Host issues the command trigger to both links
745	 * when DSI_1 calls the cmd transfer function, no matter it happens
746	 * before or after DSI_0 cmd transfer.
747	 */
748	if (need_sync && (id == DSI_0))
749		return is_read ? msg->rx_len : msg->tx_len;
750
751	if (need_sync && msm_dsi0) {
752		ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg);
753		if (ret) {
754			pr_err("%s: failed to prepare non-trigger host, %d\n",
755				__func__, ret);
756			return ret;
757		}
758	}
759	ret = msm_dsi_host_xfer_prepare(host, msg);
760	if (ret) {
761		pr_err("%s: failed to prepare host, %d\n", __func__, ret);
762		goto restore_host0;
763	}
764
765	ret = is_read ? msm_dsi_host_cmd_rx(host, msg) :
766			msm_dsi_host_cmd_tx(host, msg);
767
768	msm_dsi_host_xfer_restore(host, msg);
769
770restore_host0:
771	if (need_sync && msm_dsi0)
772		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
773
774	return ret;
775}
776
777bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
778{
779	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
780	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
781	struct mipi_dsi_host *host = msm_dsi->host;
782
783	if (IS_SYNC_NEEDED() && (id == DSI_0))
784		return false;
785
786	if (IS_SYNC_NEEDED() && msm_dsi0)
787		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
788
789	msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
790
791	return true;
792}
793
794int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
795{
796	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
797	int id = msm_dsi->id;
798	int ret;
799
800	if (id >= DSI_MAX) {
801		pr_err("%s: invalid id %d\n", __func__, id);
802		return -EINVAL;
803	}
804
805	if (msm_dsim->dsi[id]) {
806		pr_err("%s: dsi%d already registered\n", __func__, id);
807		return -EBUSY;
808	}
809
810	msm_dsim->dsi[id] = msm_dsi;
811
812	ret = dsi_mgr_parse_dual_dsi(msm_dsi->pdev->dev.of_node, id);
813	if (ret) {
814		pr_err("%s: failed to parse dual DSI info\n", __func__);
815		goto fail;
816	}
817
818	ret = dsi_mgr_setup_components(id);
819	if (ret) {
820		pr_err("%s: failed to register mipi dsi host for DSI %d: %d\n",
821			__func__, id, ret);
822		goto fail;
823	}
824
825	return 0;
826
827fail:
828	msm_dsim->dsi[id] = NULL;
829	return ret;
830}
831
832void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi)
833{
834	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
835
836	if (msm_dsi->host)
837		msm_dsi_host_unregister(msm_dsi->host);
838
839	if (msm_dsi->id >= 0)
840		msm_dsim->dsi[msm_dsi->id] = NULL;
841}
842