@@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
174174 intel_display_power_put (dev_priv , POWER_DOMAIN_PLLS );
175175}
176176
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 *
221178intel_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 )
223182{
224183 struct drm_i915_private * dev_priv = crtc -> base .dev -> dev_private ;
225184 struct intel_shared_dpll * pll ;
226185 struct intel_shared_dpll_config * shared_dpll ;
227186 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 ;
233187
234188 shared_dpll = intel_atomic_get_shared_dpll_state (crtc_state -> base .state );
235189
236- for (i = 0 ; i < max ; i ++ ) {
190+ for (i = range_min ; i <= range_max ; i ++ ) {
237191 pll = & dev_priv -> shared_dplls [i ];
238192
239193 /* Only want to check enabled timings first */
@@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
247201 crtc -> base .base .id , pll -> name ,
248202 shared_dpll [i ].crtc_mask ,
249203 pll -> active );
250- return i ;
204+ return pll ;
251205 }
252206 }
253207
254208 /* 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 ++ ) {
256210 pll = & dev_priv -> shared_dplls [i ];
257211 if (shared_dpll [i ].crtc_mask == 0 ) {
258212 DRM_DEBUG_KMS ("CRTC:%d allocated %s\n" ,
259213 crtc -> base .base .id , pll -> name );
260- return i ;
214+ return pll ;
261215 }
262216 }
263217
264- return DPLL_ID_PRIVATE ;
218+ return NULL ;
265219}
266220
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 )
270224{
271- struct drm_i915_private * dev_priv = crtc -> base .dev -> dev_private ;
272- struct intel_shared_dpll * pll ;
273225 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 ;
275228
276229 shared_dpll = intel_atomic_get_shared_dpll_state (crtc_state -> base .state );
277230
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-
293231 if (shared_dpll [i ].crtc_mask == 0 )
294232 shared_dpll [i ].hw_state =
295233 crtc_state -> dpll_hw_state ;
@@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
299237 pipe_name (crtc -> pipe ));
300238
301239 intel_shared_dpll_config_get (shared_dpll , pll , crtc );
302-
303- return pll ;
304240}
305241
306242void 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,
398334 udelay (200 );
399335}
400336
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+
401363static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
402364 .mode_set = ibx_pch_dpll_mode_set ,
403365 .enable = ibx_pch_dpll_enable ,
@@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
475437 return val & SPLL_PLL_ENABLE ;
476438}
477439
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+
478453
479454static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
480455 .enable = hsw_ddi_wrpll_enable ,
@@ -594,6 +569,19 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
594569 return ret ;
595570}
596571
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+
597585static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
598586 .enable = skl_ddi_pll_enable ,
599587 .disable = skl_ddi_pll_disable ,
@@ -782,6 +770,32 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
782770 return ret ;
783771}
784772
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+
785799static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
786800 .enable = bxt_ddi_pll_enable ,
787801 .disable = bxt_ddi_pll_disable ,
@@ -826,53 +840,83 @@ struct dpll_info {
826840 const struct intel_shared_dpll_funcs * funcs ;
827841};
828842
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+
829850static const struct dpll_info pch_plls [] = {
830851 { "PCH DPLL A" , DPLL_ID_PCH_PLL_A , & ibx_pch_dpll_funcs },
831852 { "PCH DPLL B" , DPLL_ID_PCH_PLL_B , & ibx_pch_dpll_funcs },
832853 { NULL , -1 , NULL },
833854};
834855
856+ static const struct intel_dpll_mgr pch_pll_mgr = {
857+ .dpll_info = pch_plls ,
858+ .get_dpll = ibx_get_dpll ,
859+ };
860+
835861static const struct dpll_info hsw_plls [] = {
836862 { "WRPLL 1" , DPLL_ID_WRPLL1 , & hsw_ddi_wrpll_funcs },
837863 { "WRPLL 2" , DPLL_ID_WRPLL2 , & hsw_ddi_wrpll_funcs },
838864 { "SPLL" , DPLL_ID_SPLL , & hsw_ddi_spll_funcs },
839865 { NULL , -1 , NULL , },
840866};
841867
868+ static const struct intel_dpll_mgr hsw_pll_mgr = {
869+ .dpll_info = hsw_plls ,
870+ .get_dpll = hsw_get_dpll ,
871+ };
872+
842873static const struct dpll_info skl_plls [] = {
843874 { "DPPL 1" , DPLL_ID_SKL_DPLL1 , & skl_ddi_pll_funcs },
844875 { "DPPL 2" , DPLL_ID_SKL_DPLL2 , & skl_ddi_pll_funcs },
845876 { "DPPL 3" , DPLL_ID_SKL_DPLL3 , & skl_ddi_pll_funcs },
846877 { NULL , -1 , NULL , },
847878};
848879
880+ static const struct intel_dpll_mgr skl_pll_mgr = {
881+ .dpll_info = skl_plls ,
882+ .get_dpll = skl_get_dpll ,
883+ };
884+
849885static const struct dpll_info bxt_plls [] = {
850886 { "PORT PLL A" , 0 , & bxt_ddi_pll_funcs },
851887 { "PORT PLL B" , 1 , & bxt_ddi_pll_funcs },
852888 { "PORT PLL C" , 2 , & bxt_ddi_pll_funcs },
853889 { NULL , -1 , NULL , },
854890};
855891
892+ static const struct intel_dpll_mgr bxt_pll_mgr = {
893+ .dpll_info = bxt_plls ,
894+ .get_dpll = bxt_get_dpll ,
895+ };
896+
856897void intel_shared_dpll_init (struct drm_device * dev )
857898{
858899 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 ;
860902 int i ;
861903
862904 if (IS_SKYLAKE (dev ) || IS_KABYLAKE (dev ))
863- dpll_info = skl_plls ;
905+ dpll_mgr = & skl_pll_mgr ;
864906 else if IS_BROXTON (dev )
865- dpll_info = bxt_plls ;
907+ dpll_mgr = & bxt_pll_mgr ;
866908 else if (HAS_DDI (dev ))
867- dpll_info = hsw_plls ;
909+ dpll_mgr = & hsw_pll_mgr ;
868910 else if (HAS_PCH_IBX (dev ) || HAS_PCH_CPT (dev ))
869- dpll_info = pch_plls ;
911+ dpll_mgr = & pch_pll_mgr ;
870912
871- if (!dpll_info ) {
913+ if (!dpll_mgr ) {
872914 dev_priv -> num_shared_dpll = 0 ;
873915 return ;
874916 }
875917
918+ dpll_info = dpll_mgr -> dpll_info ;
919+
876920 for (i = 0 ; dpll_info [i ].id >= 0 ; i ++ ) {
877921 WARN_ON (i != dpll_info [i ].id );
878922
@@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
881925 dev_priv -> shared_dplls [i ].funcs = * dpll_info [i ].funcs ;
882926 }
883927
928+ dev_priv -> dpll_mgr = dpll_mgr ;
884929 dev_priv -> num_shared_dpll = i ;
885930
886931 BUG_ON (dev_priv -> num_shared_dpll > I915_NUM_PLLS );
@@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
889934 if (HAS_DDI (dev ))
890935 intel_ddi_pll_init (dev );
891936}
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