diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b25e99a432fb..a6752a61d99f 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1286,6 +1286,18 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, | |||
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); | 1288 | crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id); |
1289 | } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) { | ||
1290 | struct drm_atomic_state *state = crtc_state->base.state; | ||
1291 | struct intel_shared_dpll_config *spll = | ||
1292 | &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL]; | ||
1293 | |||
1294 | if (spll->crtc_mask && | ||
1295 | WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll)) | ||
1296 | return false; | ||
1297 | |||
1298 | crtc_state->shared_dpll = DPLL_ID_SPLL; | ||
1299 | spll->hw_state.spll = crtc_state->dpll_hw_state.spll; | ||
1300 | spll->crtc_mask |= 1 << intel_crtc->pipe; | ||
1289 | } | 1301 | } |
1290 | 1302 | ||
1291 | return true; | 1303 | return true; |
@@ -2437,7 +2449,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) | |||
2437 | } | 2449 | } |
2438 | } | 2450 | } |
2439 | 2451 | ||
2440 | static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, | 2452 | static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv, |
2441 | struct intel_shared_dpll *pll) | 2453 | struct intel_shared_dpll *pll) |
2442 | { | 2454 | { |
2443 | I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll); | 2455 | I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll); |
@@ -2445,9 +2457,17 @@ static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, | |||
2445 | udelay(20); | 2457 | udelay(20); |
2446 | } | 2458 | } |
2447 | 2459 | ||
2448 | static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv, | 2460 | static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv, |
2449 | struct intel_shared_dpll *pll) | 2461 | struct intel_shared_dpll *pll) |
2450 | { | 2462 | { |
2463 | I915_WRITE(SPLL_CTL, pll->config.hw_state.spll); | ||
2464 | POSTING_READ(SPLL_CTL); | ||
2465 | udelay(20); | ||
2466 | } | ||
2467 | |||
2468 | static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv, | ||
2469 | struct intel_shared_dpll *pll) | ||
2470 | { | ||
2451 | uint32_t val; | 2471 | uint32_t val; |
2452 | 2472 | ||
2453 | val = I915_READ(WRPLL_CTL(pll->id)); | 2473 | val = I915_READ(WRPLL_CTL(pll->id)); |
@@ -2455,9 +2475,19 @@ static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv, | |||
2455 | POSTING_READ(WRPLL_CTL(pll->id)); | 2475 | POSTING_READ(WRPLL_CTL(pll->id)); |
2456 | } | 2476 | } |
2457 | 2477 | ||
2458 | static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | 2478 | static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv, |
2459 | struct intel_shared_dpll *pll, | 2479 | struct intel_shared_dpll *pll) |
2460 | struct intel_dpll_hw_state *hw_state) | 2480 | { |
2481 | uint32_t val; | ||
2482 | |||
2483 | val = I915_READ(SPLL_CTL); | ||
2484 | I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); | ||
2485 | POSTING_READ(SPLL_CTL); | ||
2486 | } | ||
2487 | |||
2488 | static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, | ||
2489 | struct intel_shared_dpll *pll, | ||
2490 | struct intel_dpll_hw_state *hw_state) | ||
2461 | { | 2491 | { |
2462 | uint32_t val; | 2492 | uint32_t val; |
2463 | 2493 | ||
@@ -2470,25 +2500,50 @@ static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2470 | return val & WRPLL_PLL_ENABLE; | 2500 | return val & WRPLL_PLL_ENABLE; |
2471 | } | 2501 | } |
2472 | 2502 | ||
2503 | static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, | ||
2504 | struct intel_shared_dpll *pll, | ||
2505 | struct intel_dpll_hw_state *hw_state) | ||
2506 | { | ||
2507 | uint32_t val; | ||
2508 | |||
2509 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) | ||
2510 | return false; | ||
2511 | |||
2512 | val = I915_READ(SPLL_CTL); | ||
2513 | hw_state->spll = val; | ||
2514 | |||
2515 | return val & SPLL_PLL_ENABLE; | ||
2516 | } | ||
2517 | |||
2518 | |||
2473 | static const char * const hsw_ddi_pll_names[] = { | 2519 | static const char * const hsw_ddi_pll_names[] = { |
2474 | "WRPLL 1", | 2520 | "WRPLL 1", |
2475 | "WRPLL 2", | 2521 | "WRPLL 2", |
2522 | "SPLL" | ||
2476 | }; | 2523 | }; |
2477 | 2524 | ||
2478 | static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) | 2525 | static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) |
2479 | { | 2526 | { |
2480 | int i; | 2527 | int i; |
2481 | 2528 | ||
2482 | dev_priv->num_shared_dpll = 2; | 2529 | dev_priv->num_shared_dpll = 3; |
2483 | 2530 | ||
2484 | for (i = 0; i < dev_priv->num_shared_dpll; i++) { | 2531 | for (i = 0; i < 2; i++) { |
2485 | dev_priv->shared_dplls[i].id = i; | 2532 | dev_priv->shared_dplls[i].id = i; |
2486 | dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; | 2533 | dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; |
2487 | dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable; | 2534 | dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable; |
2488 | dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable; | 2535 | dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable; |
2489 | dev_priv->shared_dplls[i].get_hw_state = | 2536 | dev_priv->shared_dplls[i].get_hw_state = |
2490 | hsw_ddi_pll_get_hw_state; | 2537 | hsw_ddi_wrpll_get_hw_state; |
2491 | } | 2538 | } |
2539 | |||
2540 | /* SPLL is special, but needs to be initialized anyway.. */ | ||
2541 | dev_priv->shared_dplls[i].id = i; | ||
2542 | dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; | ||
2543 | dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable; | ||
2544 | dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable; | ||
2545 | dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state; | ||
2546 | |||
2492 | } | 2547 | } |
2493 | 2548 | ||
2494 | static const char * const skl_ddi_pll_names[] = { | 2549 | static const char * const skl_ddi_pll_names[] = { |