Linux Audio

Check our new training course

Loading...
v5.14.15
  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
v6.9.4
  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
 23struct 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
 31static 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
 37static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
 38{
 39	return msm_dsim_glb.dsi[id];
 40}
 41
 42static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
 43{
 44	return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
 45}
 46
 47static 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
 68static 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
114static 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
125static int
126dsi_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
167static 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
 
 
 
 
 
188struct 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
 
 
 
 
 
 
195static 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
201static int dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
 
 
 
 
 
 
202{
203	int id = dsi_mgr_bridge_get_id(bridge);
204	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
205	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
206	struct mipi_dsi_host *host = msm_dsi->host;
207	struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
208	bool is_bonded_dsi = IS_BONDED_DSI();
209	int ret;
210
211	DBG("id=%d", id);
 
 
 
212
213	ret = dsi_mgr_phy_enable(id, phy_shared_timings);
214	if (ret)
215		goto phy_en_fail;
 
 
 
 
 
216
217	ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_bonded_dsi, msm_dsi->phy);
218	if (ret) {
219		pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
220		goto host_on_fail;
 
 
221	}
222
223	if (is_bonded_dsi && msm_dsi1) {
224		ret = msm_dsi_host_power_on(msm_dsi1->host,
225				&phy_shared_timings[DSI_1], is_bonded_dsi, msm_dsi1->phy);
226		if (ret) {
227			pr_err("%s: power on host1 failed, %d\n",
228							__func__, ret);
229			goto host1_on_fail;
230		}
 
 
231	}
232
 
 
 
 
 
 
233	/*
234	 * Enable before preparing the panel, disable after unpreparing, so
235	 * that the panel can communicate over the DSI link.
236	 */
237	msm_dsi_host_enable_irq(host);
238	if (is_bonded_dsi && msm_dsi1)
239		msm_dsi_host_enable_irq(msm_dsi1->host);
 
 
240
 
 
241	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
243host1_on_fail:
244	msm_dsi_host_power_off(host);
245host_on_fail:
246	dsi_mgr_phy_disable(id);
247phy_en_fail:
248	return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249}
250
251static void dsi_mgr_bridge_power_off(struct drm_bridge *bridge)
 
252{
253	int id = dsi_mgr_bridge_get_id(bridge);
254	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
255	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
256	struct mipi_dsi_host *host = msm_dsi->host;
257	bool is_bonded_dsi = IS_BONDED_DSI();
258
259	msm_dsi_host_disable_irq(host);
260	if (is_bonded_dsi && msm_dsi1) {
261		msm_dsi_host_disable_irq(msm_dsi1->host);
262		msm_dsi_host_power_off(msm_dsi1->host);
263	}
264	msm_dsi_host_power_off(host);
265	dsi_mgr_phy_disable(id);
266}
267
268static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
269{
270	int id = dsi_mgr_bridge_get_id(bridge);
271	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
272	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
273	struct mipi_dsi_host *host = msm_dsi->host;
274	bool is_bonded_dsi = IS_BONDED_DSI();
 
 
275	int ret;
276
277	DBG("id=%d", id);
 
 
278
279	/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
280	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
281		return;
282
283	ret = dsi_mgr_bridge_power_on(bridge);
 
 
 
 
284	if (ret) {
285		dev_err(&msm_dsi->pdev->dev, "Power on failed: %d\n", ret);
286		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287	}
288
289	ret = msm_dsi_host_enable(host);
290	if (ret) {
291		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
292		goto host_en_fail;
293	}
294
295	if (is_bonded_dsi && msm_dsi1) {
296		ret = msm_dsi_host_enable(msm_dsi1->host);
297		if (ret) {
298			pr_err("%s: enable host1 failed, %d\n", __func__, ret);
299			goto host1_en_fail;
300		}
301	}
302
303	return;
304
305host1_en_fail:
306	msm_dsi_host_disable(host);
307host_en_fail:
308	dsi_mgr_bridge_power_off(bridge);
 
 
 
 
 
 
 
 
 
 
309}
310
311void msm_dsi_manager_tpg_enable(void)
312{
313	struct msm_dsi *m_dsi = dsi_mgr_get_dsi(DSI_0);
314	struct msm_dsi *s_dsi = dsi_mgr_get_dsi(DSI_1);
 
 
 
 
 
 
 
 
 
 
 
315
316	/* if dual dsi, trigger tpg on master first then slave */
317	if (m_dsi) {
318		msm_dsi_host_test_pattern_en(m_dsi->host);
319		if (IS_BONDED_DSI() && s_dsi)
320			msm_dsi_host_test_pattern_en(s_dsi->host);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321	}
322}
323
324static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
325{
326	int id = dsi_mgr_bridge_get_id(bridge);
327	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
328	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
329	struct mipi_dsi_host *host = msm_dsi->host;
330	bool is_bonded_dsi = IS_BONDED_DSI();
 
331	int ret;
332
333	DBG("id=%d", id);
334
 
 
 
335	/*
336	 * Do nothing with the host if it is slave-DSI in case of bonded DSI.
337	 * It is safe to call dsi_mgr_phy_disable() here because a single PHY
338	 * won't be diabled until both PHYs request disable.
339	 */
340	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
341		goto disable_phy;
342
343	ret = msm_dsi_host_disable(host);
344	if (ret)
345		pr_err("%s: host %d disable failed, %d\n", __func__, id, ret);
346
347	if (is_bonded_dsi && msm_dsi1) {
348		ret = msm_dsi_host_disable(msm_dsi1->host);
349		if (ret)
350			pr_err("%s: host1 disable failed, %d\n", __func__, ret);
351	}
352
353	msm_dsi_host_disable_irq(host);
354	if (is_bonded_dsi && msm_dsi1)
355		msm_dsi_host_disable_irq(msm_dsi1->host);
 
 
 
356
357	/* Save PHY status if it is a clock source */
358	msm_dsi_phy_pll_save_state(msm_dsi->phy);
359
360	ret = msm_dsi_host_power_off(host);
361	if (ret)
362		pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
363
364	if (is_bonded_dsi && msm_dsi1) {
365		ret = msm_dsi_host_power_off(msm_dsi1->host);
366		if (ret)
367			pr_err("%s: host1 power off failed, %d\n",
368								__func__, ret);
369	}
370
371disable_phy:
372	dsi_mgr_phy_disable(id);
373}
374
375static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
376		const struct drm_display_mode *mode,
377		const struct drm_display_mode *adjusted_mode)
378{
379	int id = dsi_mgr_bridge_get_id(bridge);
380	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
381	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
382	struct mipi_dsi_host *host = msm_dsi->host;
383	bool is_bonded_dsi = IS_BONDED_DSI();
384
385	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
386
387	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
388		return;
389
390	msm_dsi_host_set_display_mode(host, adjusted_mode);
391	if (is_bonded_dsi && other_dsi)
392		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
393}
394
395static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
396						      const struct drm_display_info *info,
397						      const struct drm_display_mode *mode)
398{
399	int id = dsi_mgr_bridge_get_id(bridge);
400	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
401	struct mipi_dsi_host *host = msm_dsi->host;
402	struct platform_device *pdev = msm_dsi->pdev;
403	struct dev_pm_opp *opp;
404	unsigned long byte_clk_rate;
405
406	byte_clk_rate = dsi_byte_clk_get_rate(host, IS_BONDED_DSI(), mode);
407
408	opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
409	if (!IS_ERR(opp)) {
410		dev_pm_opp_put(opp);
411	} else if (PTR_ERR(opp) == -ERANGE) {
412		/*
413		 * An empty table is created by devm_pm_opp_set_clkname() even
414		 * if there is none. Thus find_freq_ceil will still return
415		 * -ERANGE in such case.
416		 */
417		if (dev_pm_opp_get_opp_count(&pdev->dev) != 0)
418			return MODE_CLOCK_RANGE;
419	} else {
420			return MODE_ERROR;
421	}
422
423	return msm_dsi_host_check_dsc(host, mode);
424}
 
 
 
425
426static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
427	.pre_enable = dsi_mgr_bridge_pre_enable,
 
 
428	.post_disable = dsi_mgr_bridge_post_disable,
429	.mode_set = dsi_mgr_bridge_mode_set,
430	.mode_valid = dsi_mgr_bridge_mode_valid,
431};
432
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
433/* initialize bridge */
434struct drm_bridge *msm_dsi_manager_bridge_init(struct msm_dsi *msm_dsi,
435					       struct drm_encoder *encoder)
436{
437	struct drm_bridge *bridge;
 
438	struct dsi_bridge *dsi_bridge;
 
439	int ret;
440
441	dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
442				sizeof(*dsi_bridge), GFP_KERNEL);
443	if (!dsi_bridge)
444		return ERR_PTR(-ENOMEM);
 
 
 
 
445
446	dsi_bridge->id = msm_dsi->id;
447
448	bridge = &dsi_bridge->base;
449	bridge->funcs = &dsi_mgr_bridge_funcs;
450
451	ret = devm_drm_bridge_add(msm_dsi->dev->dev, bridge);
452	if (ret)
453		return ERR_PTR(ret);
454
455	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
456	if (ret)
457		return ERR_PTR(ret);
458
459	return bridge;
 
 
 
 
 
 
460}
461
462int msm_dsi_manager_ext_bridge_init(u8 id, struct drm_bridge *int_bridge)
463{
464	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
465	struct drm_device *dev = msm_dsi->dev;
466	struct drm_encoder *encoder;
467	struct drm_bridge *ext_bridge;
468	int ret;
 
 
 
 
 
469
470	ext_bridge = devm_drm_of_get_bridge(&msm_dsi->pdev->dev,
471					    msm_dsi->pdev->dev.of_node, 1, 0);
472	if (IS_ERR(ext_bridge))
473		return PTR_ERR(ext_bridge);
474
475	encoder = int_bridge->encoder;
 
476
477	/*
478	 * Try first to create the bridge without it creating its own
479	 * connector.. currently some bridges support this, and others
480	 * do not (and some support both modes)
481	 */
482	ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
483			DRM_BRIDGE_ATTACH_NO_CONNECTOR);
484	if (ret == -EINVAL) {
485		/*
486		 * link the internal dsi bridge to the external bridge,
487		 * connector is created by the next bridge.
488		 */
489		ret = drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
490		if (ret < 0)
491			return ret;
492	} else {
493		struct drm_connector *connector;
494
495		/* We are in charge of the connector, create one now. */
496		connector = drm_bridge_connector_init(dev, encoder);
497		if (IS_ERR(connector)) {
498			DRM_ERROR("Unable to create bridge connector\n");
499			return PTR_ERR(connector);
500		}
501
502		ret = drm_connector_attach_encoder(connector, encoder);
503		if (ret < 0)
504			return ret;
505	}
506
507	return 0;
 
508}
509
510int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
511{
512	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
513	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
514	struct mipi_dsi_host *host = msm_dsi->host;
515	bool is_read = (msg->rx_buf && msg->rx_len);
516	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
517	int ret;
518
519	if (!msg->tx_buf || !msg->tx_len)
520		return 0;
521
522	/* In bonded master case, panel requires the same commands sent to
523	 * both DSI links. Host issues the command trigger to both links
524	 * when DSI_1 calls the cmd transfer function, no matter it happens
525	 * before or after DSI_0 cmd transfer.
526	 */
527	if (need_sync && (id == DSI_0))
528		return is_read ? msg->rx_len : msg->tx_len;
529
530	if (need_sync && msm_dsi0) {
531		ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg);
532		if (ret) {
533			pr_err("%s: failed to prepare non-trigger host, %d\n",
534				__func__, ret);
535			return ret;
536		}
537	}
538	ret = msm_dsi_host_xfer_prepare(host, msg);
539	if (ret) {
540		pr_err("%s: failed to prepare host, %d\n", __func__, ret);
541		goto restore_host0;
542	}
543
544	ret = is_read ? msm_dsi_host_cmd_rx(host, msg) :
545			msm_dsi_host_cmd_tx(host, msg);
546
547	msm_dsi_host_xfer_restore(host, msg);
548
549restore_host0:
550	if (need_sync && msm_dsi0)
551		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
552
553	return ret;
554}
555
556bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
557{
558	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
559	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
560	struct mipi_dsi_host *host = msm_dsi->host;
561
562	if (IS_SYNC_NEEDED() && (id == DSI_0))
563		return false;
564
565	if (IS_SYNC_NEEDED() && msm_dsi0)
566		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
567
568	msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
569
570	return true;
571}
572
573int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
574{
575	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
576	int id = msm_dsi->id;
577	int ret;
578
579	if (id >= DSI_MAX) {
580		pr_err("%s: invalid id %d\n", __func__, id);
581		return -EINVAL;
582	}
583
584	if (msm_dsim->dsi[id]) {
585		pr_err("%s: dsi%d already registered\n", __func__, id);
586		return -EBUSY;
587	}
588
589	msm_dsim->dsi[id] = msm_dsi;
590
591	ret = dsi_mgr_parse_of(msm_dsi->pdev->dev.of_node, id);
592	if (ret) {
593		pr_err("%s: failed to parse OF DSI info\n", __func__);
594		goto fail;
595	}
596
597	ret = dsi_mgr_setup_components(id);
598	if (ret) {
599		pr_err("%s: failed to register mipi dsi host for DSI %d: %d\n",
600			__func__, id, ret);
601		goto fail;
602	}
603
604	return 0;
605
606fail:
607	msm_dsim->dsi[id] = NULL;
608	return ret;
609}
610
611void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi)
612{
613	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
614
615	if (msm_dsi->host)
616		msm_dsi_host_unregister(msm_dsi->host);
617
618	if (msm_dsi->id >= 0)
619		msm_dsim->dsi[msm_dsi->id] = NULL;
620}
621
622bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
623{
624	return IS_BONDED_DSI();
625}
626
627bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
628{
629	return IS_MASTER_DSI_LINK(msm_dsi->id);
630}