Skip to content

Commit f9476a6

Browse files
author
Ander Conselvan de Oliveira
committed
drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
The function intel_get_shared_dpll() had a more or less generic implementation with some platform specific checks to handle smaller differences between platforms. However, the minimalist approach forces bigger differences between platforms to be implemented outside of the shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c, for instance). This patch changes the implementation of intel_get_share_dpll() so that a completely platform specific version can be used, providing helpers to reduce code duplication. This should allow the code from the ddi pll select functions to be moved, and also make room for making more dplls managed by the shared dpll infrastructure. v2: WARN_ON(!dpll_mgr) in intel_get_shared_dpll(). (Maarten) Signed-off-by: Ander Conselvan de Oliveira <[email protected]> Reviewed-by: Maarten Lankhorst <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-9-git-send-email-ander.conselvan.de.oliveira@intel.com
1 parent 2edd644 commit f9476a6

File tree

3 files changed

+145
-84
lines changed

3 files changed

+145
-84
lines changed

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,7 @@ struct drm_i915_private {
18101810
/* dpll and cdclk state is protected by connection_mutex */
18111811
int num_shared_dpll;
18121812
struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
1813+
const struct intel_dpll_mgr *dpll_mgr;
18131814

18141815
unsigned int active_crtcs;
18151816
unsigned int min_pixclk[I915_MAX_PIPES];

drivers/gpu/drm/i915/intel_dpll_mgr.c

Lines changed: 142 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -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 *
221178
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)
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

306242
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,
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+
401363
static 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

479454
static 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+
597585
static 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+
785799
static 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+
829850
static 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+
835861
static 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+
842873
static 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+
849885
static 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+
856897
void 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+
}

drivers/gpu/drm/i915/intel_dpll_mgr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ struct intel_crtc;
3030
struct intel_crtc_state;
3131
struct intel_shared_dpll;
3232

33+
struct intel_dpll_mgr;
34+
3335
enum intel_dpll_id {
3436
DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
3537
/* real shared dpll ids must be >= 0 */

0 commit comments

Comments
 (0)