forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/msm/dsi/dsi_manager.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 and
6
- * only version 2 as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
146 #include "msm_kms.h"
....@@ -233,63 +225,79 @@
233225 return dsi_bridge->id;
234226 }
235227
228
+static bool dsi_mgr_is_cmd_mode(struct msm_dsi *msm_dsi)
229
+{
230
+ unsigned long host_flags = msm_dsi_host_get_mode_flags(msm_dsi->host);
231
+ return !(host_flags & MIPI_DSI_MODE_VIDEO);
232
+}
233
+
234
+void msm_dsi_manager_setup_encoder(int id)
235
+{
236
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
237
+ struct msm_drm_private *priv = msm_dsi->dev->dev_private;
238
+ struct msm_kms *kms = priv->kms;
239
+ struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi);
240
+
241
+ if (encoder && kms->funcs->set_encoder_mode)
242
+ kms->funcs->set_encoder_mode(kms, encoder,
243
+ dsi_mgr_is_cmd_mode(msm_dsi));
244
+}
245
+
246
+static int msm_dsi_manager_panel_init(struct drm_connector *conn, u8 id)
247
+{
248
+ struct msm_drm_private *priv = conn->dev->dev_private;
249
+ struct msm_kms *kms = priv->kms;
250
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
251
+ struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
252
+ struct msm_dsi *master_dsi, *slave_dsi;
253
+ struct drm_panel *panel;
254
+
255
+ if (IS_DUAL_DSI() && !IS_MASTER_DSI_LINK(id)) {
256
+ master_dsi = other_dsi;
257
+ slave_dsi = msm_dsi;
258
+ } else {
259
+ master_dsi = msm_dsi;
260
+ slave_dsi = other_dsi;
261
+ }
262
+
263
+ /*
264
+ * There is only 1 panel in the global panel list for dual DSI mode.
265
+ * Therefore slave dsi should get the drm_panel instance from master
266
+ * dsi.
267
+ */
268
+ panel = msm_dsi_host_get_panel(master_dsi->host);
269
+ if (IS_ERR(panel)) {
270
+ DRM_ERROR("Could not find panel for %u (%ld)\n", msm_dsi->id,
271
+ PTR_ERR(panel));
272
+ return PTR_ERR(panel);
273
+ }
274
+
275
+ if (!panel || !IS_DUAL_DSI())
276
+ goto out;
277
+
278
+ drm_object_attach_property(&conn->base,
279
+ conn->dev->mode_config.tile_property, 0);
280
+
281
+ /*
282
+ * Set split display info to kms once dual DSI panel is connected to
283
+ * both hosts.
284
+ */
285
+ if (other_dsi && other_dsi->panel && kms->funcs->set_split_display) {
286
+ kms->funcs->set_split_display(kms, master_dsi->encoder,
287
+ slave_dsi->encoder,
288
+ dsi_mgr_is_cmd_mode(msm_dsi));
289
+ }
290
+
291
+out:
292
+ msm_dsi->panel = panel;
293
+ return 0;
294
+}
295
+
236296 static enum drm_connector_status dsi_mgr_connector_detect(
237297 struct drm_connector *connector, bool force)
238298 {
239299 int id = dsi_mgr_connector_get_id(connector);
240300 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
241
- struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
242
- struct msm_drm_private *priv = connector->dev->dev_private;
243
- struct msm_kms *kms = priv->kms;
244
-
245
- DBG("id=%d", id);
246
- if (!msm_dsi->panel) {
247
- msm_dsi->panel = msm_dsi_host_get_panel(msm_dsi->host,
248
- &msm_dsi->device_flags);
249
-
250
- /* There is only 1 panel in the global panel list
251
- * for dual DSI mode. Therefore slave dsi should get
252
- * the drm_panel instance from master dsi, and
253
- * keep using the panel flags got from the current DSI link.
254
- */
255
- if (!msm_dsi->panel && IS_DUAL_DSI() &&
256
- !IS_MASTER_DSI_LINK(id) && other_dsi)
257
- msm_dsi->panel = msm_dsi_host_get_panel(
258
- other_dsi->host, NULL);
259
-
260
-
261
- if (msm_dsi->panel && kms->funcs->set_encoder_mode) {
262
- bool cmd_mode = !(msm_dsi->device_flags &
263
- MIPI_DSI_MODE_VIDEO);
264
- struct drm_encoder *encoder =
265
- msm_dsi_get_encoder(msm_dsi);
266
-
267
- kms->funcs->set_encoder_mode(kms, encoder, cmd_mode);
268
- }
269
-
270
- if (msm_dsi->panel && IS_DUAL_DSI())
271
- drm_object_attach_property(&connector->base,
272
- connector->dev->mode_config.tile_property, 0);
273
-
274
- /* Set split display info to kms once dual DSI panel is
275
- * connected to both hosts.
276
- */
277
- if (msm_dsi->panel && IS_DUAL_DSI() &&
278
- other_dsi && other_dsi->panel) {
279
- bool cmd_mode = !(msm_dsi->device_flags &
280
- MIPI_DSI_MODE_VIDEO);
281
- struct drm_encoder *encoder = msm_dsi_get_encoder(
282
- dsi_mgr_get_dsi(DSI_ENCODER_MASTER));
283
- struct drm_encoder *slave_enc = msm_dsi_get_encoder(
284
- dsi_mgr_get_dsi(DSI_ENCODER_SLAVE));
285
-
286
- if (kms->funcs->set_split_display)
287
- kms->funcs->set_split_display(kms, encoder,
288
- slave_enc, cmd_mode);
289
- else
290
- pr_err("mdp does not support dual DSI\n");
291
- }
292
- }
293301
294302 return msm_dsi->panel ? connector_status_connected :
295303 connector_status_disconnected;
....@@ -320,8 +328,7 @@
320328 * In dual DSI mode, we have one connector that can be
321329 * attached to the drm_panel.
322330 */
323
- drm_panel_attach(panel, connector);
324
- num = drm_panel_get_modes(panel);
331
+ num = drm_panel_get_modes(panel, connector);
325332 if (!num)
326333 return 0;
327334
....@@ -424,20 +431,8 @@
424431 }
425432 }
426433
427
- if (panel) {
428
- ret = drm_panel_enable(panel);
429
- if (ret) {
430
- pr_err("%s: enable panel %d failed, %d\n", __func__, id,
431
- ret);
432
- goto panel_en_fail;
433
- }
434
- }
435
-
436434 return;
437435
438
-panel_en_fail:
439
- if (is_dual_dsi && msm_dsi1)
440
- msm_dsi_host_disable(msm_dsi1->host);
441436 host1_en_fail:
442437 msm_dsi_host_disable(host);
443438 host_en_fail:
....@@ -456,12 +451,51 @@
456451
457452 static void dsi_mgr_bridge_enable(struct drm_bridge *bridge)
458453 {
459
- DBG("");
454
+ int id = dsi_mgr_bridge_get_id(bridge);
455
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
456
+ struct drm_panel *panel = msm_dsi->panel;
457
+ bool is_dual_dsi = IS_DUAL_DSI();
458
+ int ret;
459
+
460
+ DBG("id=%d", id);
461
+ if (!msm_dsi_device_connected(msm_dsi))
462
+ return;
463
+
464
+ /* Do nothing with the host if it is slave-DSI in case of dual DSI */
465
+ if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
466
+ return;
467
+
468
+ if (panel) {
469
+ ret = drm_panel_enable(panel);
470
+ if (ret) {
471
+ pr_err("%s: enable panel %d failed, %d\n", __func__, id,
472
+ ret);
473
+ }
474
+ }
460475 }
461476
462477 static void dsi_mgr_bridge_disable(struct drm_bridge *bridge)
463478 {
464
- DBG("");
479
+ int id = dsi_mgr_bridge_get_id(bridge);
480
+ struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
481
+ struct drm_panel *panel = msm_dsi->panel;
482
+ bool is_dual_dsi = IS_DUAL_DSI();
483
+ int ret;
484
+
485
+ DBG("id=%d", id);
486
+ if (!msm_dsi_device_connected(msm_dsi))
487
+ return;
488
+
489
+ /* Do nothing with the host if it is slave-DSI in case of dual DSI */
490
+ if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
491
+ return;
492
+
493
+ if (panel) {
494
+ ret = drm_panel_disable(panel);
495
+ if (ret)
496
+ pr_err("%s: Panel %d OFF failed, %d\n", __func__, id,
497
+ ret);
498
+ }
465499 }
466500
467501 static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
....@@ -487,13 +521,6 @@
487521 */
488522 if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
489523 goto disable_phy;
490
-
491
- if (panel) {
492
- ret = drm_panel_disable(panel);
493
- if (ret)
494
- pr_err("%s: Panel %d OFF failed, %d\n", __func__, id,
495
- ret);
496
- }
497524
498525 ret = msm_dsi_host_disable(host);
499526 if (ret)
....@@ -532,8 +559,8 @@
532559 }
533560
534561 static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
535
- struct drm_display_mode *mode,
536
- struct drm_display_mode *adjusted_mode)
562
+ const struct drm_display_mode *mode,
563
+ const struct drm_display_mode *adjusted_mode)
537564 {
538565 int id = dsi_mgr_bridge_get_id(bridge);
539566 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
....@@ -541,14 +568,7 @@
541568 struct mipi_dsi_host *host = msm_dsi->host;
542569 bool is_dual_dsi = IS_DUAL_DSI();
543570
544
- DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
545
- mode->base.id, mode->name,
546
- mode->vrefresh, mode->clock,
547
- mode->hdisplay, mode->hsync_start,
548
- mode->hsync_end, mode->htotal,
549
- mode->vdisplay, mode->vsync_start,
550
- mode->vsync_end, mode->vtotal,
551
- mode->type, mode->flags);
571
+ DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
552572
553573 if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
554574 return;
....@@ -615,7 +635,17 @@
615635
616636 drm_connector_attach_encoder(connector, msm_dsi->encoder);
617637
638
+ ret = msm_dsi_manager_panel_init(connector, id);
639
+ if (ret) {
640
+ DRM_DEV_ERROR(msm_dsi->dev->dev, "init panel failed %d\n", ret);
641
+ goto fail;
642
+ }
643
+
618644 return connector;
645
+
646
+fail:
647
+ connector->funcs->destroy(connector);
648
+ return ERR_PTR(ret);
619649 }
620650
621651 bool msm_dsi_manager_validate_current_config(u8 id)
....@@ -658,7 +688,7 @@
658688 bridge = &dsi_bridge->base;
659689 bridge->funcs = &dsi_mgr_bridge_funcs;
660690
661
- ret = drm_bridge_attach(encoder, bridge, NULL);
691
+ ret = drm_bridge_attach(encoder, bridge, NULL, 0);
662692 if (ret)
663693 goto fail;
664694
....@@ -687,7 +717,7 @@
687717 encoder = msm_dsi->encoder;
688718
689719 /* link the internal dsi bridge to the external bridge */
690
- drm_bridge_attach(encoder, ext_bridge, int_bridge);
720
+ drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
691721
692722 /*
693723 * we need the drm_connector created by the external bridge
....@@ -771,35 +801,6 @@
771801 return true;
772802 }
773803
774
-void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags)
775
-{
776
- struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
777
- struct drm_device *dev = msm_dsi->dev;
778
- struct msm_drm_private *priv;
779
- struct msm_kms *kms;
780
- struct drm_encoder *encoder;
781
- bool cmd_mode;
782
-
783
- /*
784
- * drm_device pointer is assigned to msm_dsi only in the modeset_init
785
- * path. If mipi_dsi_attach() happens in DSI driver's probe path
786
- * (generally the case when we're connected to a drm_panel of the type
787
- * mipi_dsi_device), this would be NULL. In such cases, try to set the
788
- * encoder mode in the DSI connector's detect() op.
789
- */
790
- if (!dev)
791
- return;
792
-
793
- priv = dev->dev_private;
794
- kms = priv->kms;
795
- encoder = msm_dsi_get_encoder(msm_dsi);
796
- cmd_mode = !(device_flags &
797
- MIPI_DSI_MODE_VIDEO);
798
-
799
- if (encoder && kms->funcs->set_encoder_mode)
800
- kms->funcs->set_encoder_mode(kms, encoder, cmd_mode);
801
-}
802
-
803804 int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
804805 {
805806 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
....@@ -844,6 +845,8 @@
844845
845846 if (msm_dsi->host)
846847 msm_dsi_host_unregister(msm_dsi->host);
847
- msm_dsim->dsi[msm_dsi->id] = NULL;
848
+
849
+ if (msm_dsi->id >= 0)
850
+ msm_dsim->dsi[msm_dsi->id] = NULL;
848851 }
849852