@@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
174
174
intel_display_power_put (dev_priv , POWER_DOMAIN_PLLS );
175
175
}
176
176
177
- static enum intel_dpll_id
178
- ibx_get_fixed_dpll (struct intel_crtc * crtc ,
179
- struct intel_crtc_state * crtc_state )
180
- {
181
- struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
182
- struct intel_shared_dpll * pll ;
183
- enum intel_dpll_id i ;
184
-
185
- /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
186
- i = (enum intel_dpll_id ) crtc -> pipe ;
187
- pll = & dev_priv -> shared_dplls [i ];
188
-
189
- DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" ,
190
- crtc -> base .base .id , pll -> name );
191
-
192
- return i ;
193
- }
194
-
195
- static enum intel_dpll_id
196
- bxt_get_fixed_dpll (struct intel_crtc * crtc ,
197
- struct intel_crtc_state * crtc_state )
198
- {
199
- struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
200
- struct intel_encoder * encoder ;
201
- struct intel_digital_port * intel_dig_port ;
202
- struct intel_shared_dpll * pll ;
203
- enum intel_dpll_id i ;
204
-
205
- /* PLL is attached to port in bxt */
206
- encoder = intel_ddi_get_crtc_new_encoder (crtc_state );
207
- if (WARN_ON (!encoder ))
208
- return DPLL_ID_PRIVATE ;
209
-
210
- intel_dig_port = enc_to_dig_port (& encoder -> base );
211
- /* 1:1 mapping between ports and PLLs */
212
- i = (enum intel_dpll_id )intel_dig_port -> port ;
213
- pll = & dev_priv -> shared_dplls [i ];
214
- DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" ,
215
- crtc -> base .base .id , pll -> name );
216
-
217
- return i ;
218
- }
219
-
220
- static enum intel_dpll_id
177
+ static struct intel_shared_dpll *
221
178
intel_find_shared_dpll (struct intel_crtc * crtc ,
222
- struct intel_crtc_state * crtc_state )
179
+ struct intel_crtc_state * crtc_state ,
180
+ enum intel_dpll_id range_min ,
181
+ enum intel_dpll_id range_max )
223
182
{
224
183
struct drm_i915_private * dev_priv = crtc -> base .dev -> dev_private ;
225
184
struct intel_shared_dpll * pll ;
226
185
struct intel_shared_dpll_config * shared_dpll ;
227
186
enum intel_dpll_id i ;
228
- int max = dev_priv -> num_shared_dpll ;
229
-
230
- if (INTEL_INFO (dev_priv )-> gen < 9 && HAS_DDI (dev_priv ))
231
- /* Do not consider SPLL */
232
- max = 2 ;
233
187
234
188
shared_dpll = intel_atomic_get_shared_dpll_state (crtc_state -> base .state );
235
189
236
- for (i = 0 ; i < max ; i ++ ) {
190
+ for (i = range_min ; i <= range_max ; i ++ ) {
237
191
pll = & dev_priv -> shared_dplls [i ];
238
192
239
193
/* Only want to check enabled timings first */
@@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
247
201
crtc -> base .base .id , pll -> name ,
248
202
shared_dpll [i ].crtc_mask ,
249
203
pll -> active );
250
- return i ;
204
+ return pll ;
251
205
}
252
206
}
253
207
254
208
/* Ok no matching timings, maybe there's a free one? */
255
- for (i = 0 ; i < dev_priv -> num_shared_dpll ; i ++ ) {
209
+ for (i = range_min ; i <= range_max ; i ++ ) {
256
210
pll = & dev_priv -> shared_dplls [i ];
257
211
if (shared_dpll [i ].crtc_mask == 0 ) {
258
212
DRM_DEBUG_KMS ("CRTC:%d allocated %s\n" ,
259
213
crtc -> base .base .id , pll -> name );
260
- return i ;
214
+ return pll ;
261
215
}
262
216
}
263
217
264
- return DPLL_ID_PRIVATE ;
218
+ return NULL ;
265
219
}
266
220
267
- struct intel_shared_dpll *
268
- intel_get_shared_dpll (struct intel_crtc * crtc ,
269
- struct intel_crtc_state * crtc_state )
221
+ static void
222
+ intel_reference_shared_dpll (struct intel_shared_dpll * pll ,
223
+ struct intel_crtc_state * crtc_state )
270
224
{
271
- struct drm_i915_private * dev_priv = crtc -> base .dev -> dev_private ;
272
- struct intel_shared_dpll * pll ;
273
225
struct intel_shared_dpll_config * shared_dpll ;
274
- enum intel_dpll_id i ;
226
+ struct intel_crtc * crtc = to_intel_crtc (crtc_state -> base .crtc );
227
+ enum intel_dpll_id i = pll -> id ;
275
228
276
229
shared_dpll = intel_atomic_get_shared_dpll_state (crtc_state -> base .state );
277
230
278
- if (HAS_PCH_IBX (dev_priv -> dev )) {
279
- i = ibx_get_fixed_dpll (crtc , crtc_state );
280
- WARN_ON (shared_dpll [i ].crtc_mask );
281
- } else if (IS_BROXTON (dev_priv -> dev )) {
282
- i = bxt_get_fixed_dpll (crtc , crtc_state );
283
- WARN_ON (shared_dpll [i ].crtc_mask );
284
- } else {
285
- i = intel_find_shared_dpll (crtc , crtc_state );
286
- }
287
-
288
- if (i < 0 )
289
- return NULL ;
290
-
291
- pll = & dev_priv -> shared_dplls [i ];
292
-
293
231
if (shared_dpll [i ].crtc_mask == 0 )
294
232
shared_dpll [i ].hw_state =
295
233
crtc_state -> dpll_hw_state ;
@@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
299
237
pipe_name (crtc -> pipe ));
300
238
301
239
intel_shared_dpll_config_get (shared_dpll , pll , crtc );
302
-
303
- return pll ;
304
240
}
305
241
306
242
void intel_shared_dpll_commit (struct drm_atomic_state * state )
@@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
398
334
udelay (200 );
399
335
}
400
336
337
+ static struct intel_shared_dpll *
338
+ ibx_get_dpll (struct intel_crtc * crtc , struct intel_crtc_state * crtc_state )
339
+ {
340
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
341
+ struct intel_shared_dpll * pll ;
342
+ enum intel_dpll_id i ;
343
+
344
+ if (HAS_PCH_IBX (dev_priv )) {
345
+ /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
346
+ i = (enum intel_dpll_id ) crtc -> pipe ;
347
+ pll = & dev_priv -> shared_dplls [i ];
348
+
349
+ DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" ,
350
+ crtc -> base .base .id , pll -> name );
351
+ } else {
352
+ pll = intel_find_shared_dpll (crtc , crtc_state ,
353
+ DPLL_ID_PCH_PLL_A ,
354
+ DPLL_ID_PCH_PLL_B );
355
+ }
356
+
357
+ /* reference the pll */
358
+ intel_reference_shared_dpll (pll , crtc_state );
359
+
360
+ return pll ;
361
+ }
362
+
401
363
static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
402
364
.mode_set = ibx_pch_dpll_mode_set ,
403
365
.enable = ibx_pch_dpll_enable ,
@@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
475
437
return val & SPLL_PLL_ENABLE ;
476
438
}
477
439
440
+ static struct intel_shared_dpll *
441
+ hsw_get_dpll (struct intel_crtc * crtc , struct intel_crtc_state * crtc_state )
442
+ {
443
+ struct intel_shared_dpll * pll ;
444
+
445
+ pll = intel_find_shared_dpll (crtc , crtc_state ,
446
+ DPLL_ID_WRPLL1 , DPLL_ID_WRPLL2 );
447
+ if (pll )
448
+ intel_reference_shared_dpll (pll , crtc_state );
449
+
450
+ return pll ;
451
+ }
452
+
478
453
479
454
static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
480
455
.enable = hsw_ddi_wrpll_enable ,
@@ -594,6 +569,19 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
594
569
return ret ;
595
570
}
596
571
572
+ static struct intel_shared_dpll *
573
+ skl_get_dpll (struct intel_crtc * crtc , struct intel_crtc_state * crtc_state )
574
+ {
575
+ struct intel_shared_dpll * pll ;
576
+
577
+ pll = intel_find_shared_dpll (crtc , crtc_state ,
578
+ DPLL_ID_SKL_DPLL1 , DPLL_ID_SKL_DPLL3 );
579
+ if (pll )
580
+ intel_reference_shared_dpll (pll , crtc_state );
581
+
582
+ return pll ;
583
+ }
584
+
597
585
static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
598
586
.enable = skl_ddi_pll_enable ,
599
587
.disable = skl_ddi_pll_disable ,
@@ -782,6 +770,32 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
782
770
return ret ;
783
771
}
784
772
773
+ static struct intel_shared_dpll *
774
+ bxt_get_dpll (struct intel_crtc * crtc , struct intel_crtc_state * crtc_state )
775
+ {
776
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
777
+ struct intel_encoder * encoder ;
778
+ struct intel_digital_port * intel_dig_port ;
779
+ struct intel_shared_dpll * pll ;
780
+ enum intel_dpll_id i ;
781
+
782
+ /* PLL is attached to port in bxt */
783
+ encoder = intel_ddi_get_crtc_new_encoder (crtc_state );
784
+ if (WARN_ON (!encoder ))
785
+ return NULL ;
786
+
787
+ intel_dig_port = enc_to_dig_port (& encoder -> base );
788
+ /* 1:1 mapping between ports and PLLs */
789
+ i = (enum intel_dpll_id )intel_dig_port -> port ;
790
+ pll = & dev_priv -> shared_dplls [i ];
791
+ DRM_DEBUG_KMS ("CRTC:%d using pre-allocated %s\n" ,
792
+ crtc -> base .base .id , pll -> name );
793
+
794
+ intel_reference_shared_dpll (pll , crtc_state );
795
+
796
+ return pll ;
797
+ }
798
+
785
799
static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
786
800
.enable = bxt_ddi_pll_enable ,
787
801
.disable = bxt_ddi_pll_disable ,
@@ -826,53 +840,83 @@ struct dpll_info {
826
840
const struct intel_shared_dpll_funcs * funcs ;
827
841
};
828
842
843
+ struct intel_dpll_mgr {
844
+ const struct dpll_info * dpll_info ;
845
+
846
+ struct intel_shared_dpll * (* get_dpll )(struct intel_crtc * crtc ,
847
+ struct intel_crtc_state * crtc_state );
848
+ };
849
+
829
850
static const struct dpll_info pch_plls [] = {
830
851
{ "PCH DPLL A" , DPLL_ID_PCH_PLL_A , & ibx_pch_dpll_funcs },
831
852
{ "PCH DPLL B" , DPLL_ID_PCH_PLL_B , & ibx_pch_dpll_funcs },
832
853
{ NULL , -1 , NULL },
833
854
};
834
855
856
+ static const struct intel_dpll_mgr pch_pll_mgr = {
857
+ .dpll_info = pch_plls ,
858
+ .get_dpll = ibx_get_dpll ,
859
+ };
860
+
835
861
static const struct dpll_info hsw_plls [] = {
836
862
{ "WRPLL 1" , DPLL_ID_WRPLL1 , & hsw_ddi_wrpll_funcs },
837
863
{ "WRPLL 2" , DPLL_ID_WRPLL2 , & hsw_ddi_wrpll_funcs },
838
864
{ "SPLL" , DPLL_ID_SPLL , & hsw_ddi_spll_funcs },
839
865
{ NULL , -1 , NULL , },
840
866
};
841
867
868
+ static const struct intel_dpll_mgr hsw_pll_mgr = {
869
+ .dpll_info = hsw_plls ,
870
+ .get_dpll = hsw_get_dpll ,
871
+ };
872
+
842
873
static const struct dpll_info skl_plls [] = {
843
874
{ "DPPL 1" , DPLL_ID_SKL_DPLL1 , & skl_ddi_pll_funcs },
844
875
{ "DPPL 2" , DPLL_ID_SKL_DPLL2 , & skl_ddi_pll_funcs },
845
876
{ "DPPL 3" , DPLL_ID_SKL_DPLL3 , & skl_ddi_pll_funcs },
846
877
{ NULL , -1 , NULL , },
847
878
};
848
879
880
+ static const struct intel_dpll_mgr skl_pll_mgr = {
881
+ .dpll_info = skl_plls ,
882
+ .get_dpll = skl_get_dpll ,
883
+ };
884
+
849
885
static const struct dpll_info bxt_plls [] = {
850
886
{ "PORT PLL A" , 0 , & bxt_ddi_pll_funcs },
851
887
{ "PORT PLL B" , 1 , & bxt_ddi_pll_funcs },
852
888
{ "PORT PLL C" , 2 , & bxt_ddi_pll_funcs },
853
889
{ NULL , -1 , NULL , },
854
890
};
855
891
892
+ static const struct intel_dpll_mgr bxt_pll_mgr = {
893
+ .dpll_info = bxt_plls ,
894
+ .get_dpll = bxt_get_dpll ,
895
+ };
896
+
856
897
void intel_shared_dpll_init (struct drm_device * dev )
857
898
{
858
899
struct drm_i915_private * dev_priv = dev -> dev_private ;
859
- const struct dpll_info * dpll_info = NULL ;
900
+ const struct intel_dpll_mgr * dpll_mgr = NULL ;
901
+ const struct dpll_info * dpll_info ;
860
902
int i ;
861
903
862
904
if (IS_SKYLAKE (dev ) || IS_KABYLAKE (dev ))
863
- dpll_info = skl_plls ;
905
+ dpll_mgr = & skl_pll_mgr ;
864
906
else if IS_BROXTON (dev )
865
- dpll_info = bxt_plls ;
907
+ dpll_mgr = & bxt_pll_mgr ;
866
908
else if (HAS_DDI (dev ))
867
- dpll_info = hsw_plls ;
909
+ dpll_mgr = & hsw_pll_mgr ;
868
910
else if (HAS_PCH_IBX (dev ) || HAS_PCH_CPT (dev ))
869
- dpll_info = pch_plls ;
911
+ dpll_mgr = & pch_pll_mgr ;
870
912
871
- if (!dpll_info ) {
913
+ if (!dpll_mgr ) {
872
914
dev_priv -> num_shared_dpll = 0 ;
873
915
return ;
874
916
}
875
917
918
+ dpll_info = dpll_mgr -> dpll_info ;
919
+
876
920
for (i = 0 ; dpll_info [i ].id >= 0 ; i ++ ) {
877
921
WARN_ON (i != dpll_info [i ].id );
878
922
@@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
881
925
dev_priv -> shared_dplls [i ].funcs = * dpll_info [i ].funcs ;
882
926
}
883
927
928
+ dev_priv -> dpll_mgr = dpll_mgr ;
884
929
dev_priv -> num_shared_dpll = i ;
885
930
886
931
BUG_ON (dev_priv -> num_shared_dpll > I915_NUM_PLLS );
@@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
889
934
if (HAS_DDI (dev ))
890
935
intel_ddi_pll_init (dev );
891
936
}
937
+
938
+ struct intel_shared_dpll *
939
+ intel_get_shared_dpll (struct intel_crtc * crtc ,
940
+ struct intel_crtc_state * crtc_state )
941
+ {
942
+ struct drm_i915_private * dev_priv = to_i915 (crtc -> base .dev );
943
+ const struct intel_dpll_mgr * dpll_mgr = dev_priv -> dpll_mgr ;
944
+
945
+ if (WARN_ON (!dpll_mgr ))
946
+ return NULL ;
947
+
948
+ return dpll_mgr -> get_dpll (crtc , crtc_state );
949
+ }
0 commit comments