@@ -125,6 +125,84 @@ static int dsi_mgr_setup_components(int id)
125
125
return ret ;
126
126
}
127
127
128
+ static int enable_phy (struct msm_dsi * msm_dsi , int src_pll_id ,
129
+ struct msm_dsi_phy_shared_timings * shared_timings )
130
+ {
131
+ struct msm_dsi_phy_clk_request clk_req ;
132
+ int ret ;
133
+
134
+ msm_dsi_host_get_phy_clk_req (msm_dsi -> host , & clk_req );
135
+
136
+ ret = msm_dsi_phy_enable (msm_dsi -> phy , src_pll_id , & clk_req );
137
+ msm_dsi_phy_get_shared_timings (msm_dsi -> phy , shared_timings );
138
+
139
+ return ret ;
140
+ }
141
+
142
+ static int
143
+ dsi_mgr_phy_enable (int id ,
144
+ struct msm_dsi_phy_shared_timings shared_timings [DSI_MAX ])
145
+ {
146
+ struct msm_dsi * msm_dsi = dsi_mgr_get_dsi (id );
147
+ struct msm_dsi * mdsi = dsi_mgr_get_dsi (DSI_CLOCK_MASTER );
148
+ struct msm_dsi * sdsi = dsi_mgr_get_dsi (DSI_CLOCK_SLAVE );
149
+ int src_pll_id = IS_DUAL_DSI () ? DSI_CLOCK_MASTER : id ;
150
+ int ret ;
151
+
152
+ /* In case of dual DSI, some registers in PHY1 have been programmed
153
+ * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
154
+ * will silently reset those PHY1 registers. Therefore we need to reset
155
+ * and enable both PHYs before any PLL clock operation.
156
+ */
157
+ if (IS_DUAL_DSI () && mdsi && sdsi ) {
158
+ if (!mdsi -> phy_enabled && !sdsi -> phy_enabled ) {
159
+ msm_dsi_host_reset_phy (mdsi -> host );
160
+ msm_dsi_host_reset_phy (sdsi -> host );
161
+
162
+ ret = enable_phy (mdsi , src_pll_id ,
163
+ & shared_timings [DSI_CLOCK_MASTER ]);
164
+ if (ret )
165
+ return ret ;
166
+ ret = enable_phy (sdsi , src_pll_id ,
167
+ & shared_timings [DSI_CLOCK_SLAVE ]);
168
+ if (ret ) {
169
+ msm_dsi_phy_disable (mdsi -> phy );
170
+ return ret ;
171
+ }
172
+ }
173
+ } else {
174
+ msm_dsi_host_reset_phy (mdsi -> host );
175
+ ret = enable_phy (msm_dsi , src_pll_id , & shared_timings [id ]);
176
+ if (ret )
177
+ return ret ;
178
+ }
179
+
180
+ msm_dsi -> phy_enabled = true;
181
+
182
+ return 0 ;
183
+ }
184
+
185
+ static void dsi_mgr_phy_disable (int id )
186
+ {
187
+ struct msm_dsi * msm_dsi = dsi_mgr_get_dsi (id );
188
+ struct msm_dsi * mdsi = dsi_mgr_get_dsi (DSI_CLOCK_MASTER );
189
+ struct msm_dsi * sdsi = dsi_mgr_get_dsi (DSI_CLOCK_SLAVE );
190
+
191
+ /* disable DSI phy
192
+ * In dual-dsi configuration, the phy should be disabled for the
193
+ * first controller only when the second controller is disabled.
194
+ */
195
+ msm_dsi -> phy_enabled = false;
196
+ if (IS_DUAL_DSI () && mdsi && sdsi ) {
197
+ if (!mdsi -> phy_enabled && !sdsi -> phy_enabled ) {
198
+ msm_dsi_phy_disable (sdsi -> phy );
199
+ msm_dsi_phy_disable (mdsi -> phy );
200
+ }
201
+ } else {
202
+ msm_dsi_phy_disable (msm_dsi -> phy );
203
+ }
204
+ }
205
+
128
206
struct dsi_connector {
129
207
struct drm_connector base ;
130
208
int id ;
@@ -360,22 +438,31 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
360
438
struct msm_dsi * msm_dsi1 = dsi_mgr_get_dsi (DSI_1 );
361
439
struct mipi_dsi_host * host = msm_dsi -> host ;
362
440
struct drm_panel * panel = msm_dsi -> panel ;
441
+ struct msm_dsi_phy_shared_timings phy_shared_timings [DSI_MAX ];
363
442
bool is_dual_dsi = IS_DUAL_DSI ();
364
443
int ret ;
365
444
366
445
DBG ("id=%d" , id );
367
- if (!msm_dsi_device_connected (msm_dsi ) ||
368
- (is_dual_dsi && (DSI_1 == id )))
446
+ if (!msm_dsi_device_connected (msm_dsi ))
369
447
return ;
370
448
371
- ret = msm_dsi_host_power_on (host );
449
+ ret = dsi_mgr_phy_enable (id , phy_shared_timings );
450
+ if (ret )
451
+ goto phy_en_fail ;
452
+
453
+ /* Do nothing with the host if it is DSI 1 in case of dual DSI */
454
+ if (is_dual_dsi && (DSI_1 == id ))
455
+ return ;
456
+
457
+ ret = msm_dsi_host_power_on (host , & phy_shared_timings [id ]);
372
458
if (ret ) {
373
459
pr_err ("%s: power on host %d failed, %d\n" , __func__ , id , ret );
374
460
goto host_on_fail ;
375
461
}
376
462
377
463
if (is_dual_dsi && msm_dsi1 ) {
378
- ret = msm_dsi_host_power_on (msm_dsi1 -> host );
464
+ ret = msm_dsi_host_power_on (msm_dsi1 -> host ,
465
+ & phy_shared_timings [DSI_1 ]);
379
466
if (ret ) {
380
467
pr_err ("%s: power on host1 failed, %d\n" ,
381
468
__func__ , ret );
@@ -434,6 +521,8 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
434
521
host1_on_fail :
435
522
msm_dsi_host_power_off (host );
436
523
host_on_fail :
524
+ dsi_mgr_phy_disable (id );
525
+ phy_en_fail :
437
526
return ;
438
527
}
439
528
@@ -459,10 +548,17 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
459
548
460
549
DBG ("id=%d" , id );
461
550
462
- if (!msm_dsi_device_connected (msm_dsi ) ||
463
- (is_dual_dsi && (DSI_1 == id )))
551
+ if (!msm_dsi_device_connected (msm_dsi ))
464
552
return ;
465
553
554
+ /*
555
+ * Do nothing with the host if it is DSI 1 in case of dual DSI.
556
+ * It is safe to call dsi_mgr_phy_disable() here because a single PHY
557
+ * won't be diabled until both PHYs request disable.
558
+ */
559
+ if (is_dual_dsi && (DSI_1 == id ))
560
+ goto disable_phy ;
561
+
466
562
if (panel ) {
467
563
ret = drm_panel_disable (panel );
468
564
if (ret )
@@ -497,6 +593,9 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
497
593
pr_err ("%s: host1 power off failed, %d\n" ,
498
594
__func__ , ret );
499
595
}
596
+
597
+ disable_phy :
598
+ dsi_mgr_phy_disable (id );
500
599
}
501
600
502
601
static void dsi_mgr_bridge_mode_set (struct drm_bridge * bridge ,
@@ -664,73 +763,6 @@ void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
664
763
{
665
764
}
666
765
667
- int msm_dsi_manager_phy_enable (int id ,
668
- const unsigned long bit_rate , const unsigned long esc_rate ,
669
- struct msm_dsi_phy_shared_timings * shared_timings )
670
- {
671
- struct msm_dsi * msm_dsi = dsi_mgr_get_dsi (id );
672
- struct msm_dsi * mdsi = dsi_mgr_get_dsi (DSI_CLOCK_MASTER );
673
- struct msm_dsi * sdsi = dsi_mgr_get_dsi (DSI_CLOCK_SLAVE );
674
- struct msm_dsi_phy * phy = msm_dsi -> phy ;
675
- int src_pll_id = IS_DUAL_DSI () ? DSI_CLOCK_MASTER : id ;
676
- int ret ;
677
-
678
- /* In case of dual DSI, some registers in PHY1 have been programmed
679
- * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
680
- * will silently reset those PHY1 registers. Therefore we need to reset
681
- * and enable both PHYs before any PLL clock operation.
682
- */
683
- if (IS_DUAL_DSI () && mdsi && sdsi ) {
684
- if (!mdsi -> phy_enabled && !sdsi -> phy_enabled ) {
685
- msm_dsi_host_reset_phy (mdsi -> host );
686
- msm_dsi_host_reset_phy (sdsi -> host );
687
- ret = msm_dsi_phy_enable (mdsi -> phy , src_pll_id ,
688
- bit_rate , esc_rate );
689
- if (ret )
690
- return ret ;
691
- ret = msm_dsi_phy_enable (sdsi -> phy , src_pll_id ,
692
- bit_rate , esc_rate );
693
- if (ret ) {
694
- msm_dsi_phy_disable (mdsi -> phy );
695
- return ret ;
696
- }
697
- }
698
- } else {
699
- msm_dsi_host_reset_phy (msm_dsi -> host );
700
- ret = msm_dsi_phy_enable (msm_dsi -> phy , src_pll_id , bit_rate ,
701
- esc_rate );
702
- if (ret )
703
- return ret ;
704
- }
705
-
706
- msm_dsi -> phy_enabled = true;
707
- msm_dsi_phy_get_shared_timings (phy , shared_timings );
708
-
709
- return 0 ;
710
- }
711
-
712
- void msm_dsi_manager_phy_disable (int id )
713
- {
714
- struct msm_dsi * msm_dsi = dsi_mgr_get_dsi (id );
715
- struct msm_dsi * mdsi = dsi_mgr_get_dsi (DSI_CLOCK_MASTER );
716
- struct msm_dsi * sdsi = dsi_mgr_get_dsi (DSI_CLOCK_SLAVE );
717
- struct msm_dsi_phy * phy = msm_dsi -> phy ;
718
-
719
- /* disable DSI phy
720
- * In dual-dsi configuration, the phy should be disabled for the
721
- * first controller only when the second controller is disabled.
722
- */
723
- msm_dsi -> phy_enabled = false;
724
- if (IS_DUAL_DSI () && mdsi && sdsi ) {
725
- if (!mdsi -> phy_enabled && !sdsi -> phy_enabled ) {
726
- msm_dsi_phy_disable (sdsi -> phy );
727
- msm_dsi_phy_disable (mdsi -> phy );
728
- }
729
- } else {
730
- msm_dsi_phy_disable (phy );
731
- }
732
- }
733
-
734
766
int msm_dsi_manager_cmd_xfer (int id , const struct mipi_dsi_msg * msg )
735
767
{
736
768
struct msm_dsi * msm_dsi = dsi_mgr_get_dsi (id );
0 commit comments