diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 112 |
1 files changed, 79 insertions, 33 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cdf2e14aa45d..21a9b83f3bfc 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1913,13 +1913,16 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) | |||
1913 | enum transcoder cpu_transcoder; | 1913 | enum transcoder cpu_transcoder; |
1914 | enum intel_display_power_domain power_domain; | 1914 | enum intel_display_power_domain power_domain; |
1915 | uint32_t tmp; | 1915 | uint32_t tmp; |
1916 | bool ret; | ||
1916 | 1917 | ||
1917 | power_domain = intel_display_port_power_domain(intel_encoder); | 1918 | power_domain = intel_display_port_power_domain(intel_encoder); |
1918 | if (!intel_display_power_is_enabled(dev_priv, power_domain)) | 1919 | if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) |
1919 | return false; | 1920 | return false; |
1920 | 1921 | ||
1921 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) | 1922 | if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) { |
1922 | return false; | 1923 | ret = false; |
1924 | goto out; | ||
1925 | } | ||
1923 | 1926 | ||
1924 | if (port == PORT_A) | 1927 | if (port == PORT_A) |
1925 | cpu_transcoder = TRANSCODER_EDP; | 1928 | cpu_transcoder = TRANSCODER_EDP; |
@@ -1931,23 +1934,33 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) | |||
1931 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { | 1934 | switch (tmp & TRANS_DDI_MODE_SELECT_MASK) { |
1932 | case TRANS_DDI_MODE_SELECT_HDMI: | 1935 | case TRANS_DDI_MODE_SELECT_HDMI: |
1933 | case TRANS_DDI_MODE_SELECT_DVI: | 1936 | case TRANS_DDI_MODE_SELECT_DVI: |
1934 | return (type == DRM_MODE_CONNECTOR_HDMIA); | 1937 | ret = type == DRM_MODE_CONNECTOR_HDMIA; |
1938 | break; | ||
1935 | 1939 | ||
1936 | case TRANS_DDI_MODE_SELECT_DP_SST: | 1940 | case TRANS_DDI_MODE_SELECT_DP_SST: |
1937 | if (type == DRM_MODE_CONNECTOR_eDP) | 1941 | ret = type == DRM_MODE_CONNECTOR_eDP || |
1938 | return true; | 1942 | type == DRM_MODE_CONNECTOR_DisplayPort; |
1939 | return (type == DRM_MODE_CONNECTOR_DisplayPort); | 1943 | break; |
1944 | |||
1940 | case TRANS_DDI_MODE_SELECT_DP_MST: | 1945 | case TRANS_DDI_MODE_SELECT_DP_MST: |
1941 | /* if the transcoder is in MST state then | 1946 | /* if the transcoder is in MST state then |
1942 | * connector isn't connected */ | 1947 | * connector isn't connected */ |
1943 | return false; | 1948 | ret = false; |
1949 | break; | ||
1944 | 1950 | ||
1945 | case TRANS_DDI_MODE_SELECT_FDI: | 1951 | case TRANS_DDI_MODE_SELECT_FDI: |
1946 | return (type == DRM_MODE_CONNECTOR_VGA); | 1952 | ret = type == DRM_MODE_CONNECTOR_VGA; |
1953 | break; | ||
1947 | 1954 | ||
1948 | default: | 1955 | default: |
1949 | return false; | 1956 | ret = false; |
1957 | break; | ||
1950 | } | 1958 | } |
1959 | |||
1960 | out: | ||
1961 | intel_display_power_put(dev_priv, power_domain); | ||
1962 | |||
1963 | return ret; | ||
1951 | } | 1964 | } |
1952 | 1965 | ||
1953 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | 1966 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
@@ -1959,15 +1972,18 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
1959 | enum intel_display_power_domain power_domain; | 1972 | enum intel_display_power_domain power_domain; |
1960 | u32 tmp; | 1973 | u32 tmp; |
1961 | int i; | 1974 | int i; |
1975 | bool ret; | ||
1962 | 1976 | ||
1963 | power_domain = intel_display_port_power_domain(encoder); | 1977 | power_domain = intel_display_port_power_domain(encoder); |
1964 | if (!intel_display_power_is_enabled(dev_priv, power_domain)) | 1978 | if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) |
1965 | return false; | 1979 | return false; |
1966 | 1980 | ||
1981 | ret = false; | ||
1982 | |||
1967 | tmp = I915_READ(DDI_BUF_CTL(port)); | 1983 | tmp = I915_READ(DDI_BUF_CTL(port)); |
1968 | 1984 | ||
1969 | if (!(tmp & DDI_BUF_CTL_ENABLE)) | 1985 | if (!(tmp & DDI_BUF_CTL_ENABLE)) |
1970 | return false; | 1986 | goto out; |
1971 | 1987 | ||
1972 | if (port == PORT_A) { | 1988 | if (port == PORT_A) { |
1973 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); | 1989 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
@@ -1985,25 +2001,32 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | |||
1985 | break; | 2001 | break; |
1986 | } | 2002 | } |
1987 | 2003 | ||
1988 | return true; | 2004 | ret = true; |
1989 | } else { | ||
1990 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { | ||
1991 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); | ||
1992 | 2005 | ||
1993 | if ((tmp & TRANS_DDI_PORT_MASK) | 2006 | goto out; |
1994 | == TRANS_DDI_SELECT_PORT(port)) { | 2007 | } |
1995 | if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST) | ||
1996 | return false; | ||
1997 | 2008 | ||
1998 | *pipe = i; | 2009 | for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) { |
1999 | return true; | 2010 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(i)); |
2000 | } | 2011 | |
2012 | if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) { | ||
2013 | if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == | ||
2014 | TRANS_DDI_MODE_SELECT_DP_MST) | ||
2015 | goto out; | ||
2016 | |||
2017 | *pipe = i; | ||
2018 | ret = true; | ||
2019 | |||
2020 | goto out; | ||
2001 | } | 2021 | } |
2002 | } | 2022 | } |
2003 | 2023 | ||
2004 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); | 2024 | DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); |
2005 | 2025 | ||
2006 | return false; | 2026 | out: |
2027 | intel_display_power_put(dev_priv, power_domain); | ||
2028 | |||
2029 | return ret; | ||
2007 | } | 2030 | } |
2008 | 2031 | ||
2009 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) | 2032 | void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) |
@@ -2449,12 +2472,14 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2449 | { | 2472 | { |
2450 | uint32_t val; | 2473 | uint32_t val; |
2451 | 2474 | ||
2452 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) | 2475 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) |
2453 | return false; | 2476 | return false; |
2454 | 2477 | ||
2455 | val = I915_READ(WRPLL_CTL(pll->id)); | 2478 | val = I915_READ(WRPLL_CTL(pll->id)); |
2456 | hw_state->wrpll = val; | 2479 | hw_state->wrpll = val; |
2457 | 2480 | ||
2481 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); | ||
2482 | |||
2458 | return val & WRPLL_PLL_ENABLE; | 2483 | return val & WRPLL_PLL_ENABLE; |
2459 | } | 2484 | } |
2460 | 2485 | ||
@@ -2464,12 +2489,14 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2464 | { | 2489 | { |
2465 | uint32_t val; | 2490 | uint32_t val; |
2466 | 2491 | ||
2467 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) | 2492 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) |
2468 | return false; | 2493 | return false; |
2469 | 2494 | ||
2470 | val = I915_READ(SPLL_CTL); | 2495 | val = I915_READ(SPLL_CTL); |
2471 | hw_state->spll = val; | 2496 | hw_state->spll = val; |
2472 | 2497 | ||
2498 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); | ||
2499 | |||
2473 | return val & SPLL_PLL_ENABLE; | 2500 | return val & SPLL_PLL_ENABLE; |
2474 | } | 2501 | } |
2475 | 2502 | ||
@@ -2586,16 +2613,19 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2586 | uint32_t val; | 2613 | uint32_t val; |
2587 | unsigned int dpll; | 2614 | unsigned int dpll; |
2588 | const struct skl_dpll_regs *regs = skl_dpll_regs; | 2615 | const struct skl_dpll_regs *regs = skl_dpll_regs; |
2616 | bool ret; | ||
2589 | 2617 | ||
2590 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) | 2618 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) |
2591 | return false; | 2619 | return false; |
2592 | 2620 | ||
2621 | ret = false; | ||
2622 | |||
2593 | /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ | 2623 | /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */ |
2594 | dpll = pll->id + 1; | 2624 | dpll = pll->id + 1; |
2595 | 2625 | ||
2596 | val = I915_READ(regs[pll->id].ctl); | 2626 | val = I915_READ(regs[pll->id].ctl); |
2597 | if (!(val & LCPLL_PLL_ENABLE)) | 2627 | if (!(val & LCPLL_PLL_ENABLE)) |
2598 | return false; | 2628 | goto out; |
2599 | 2629 | ||
2600 | val = I915_READ(DPLL_CTRL1); | 2630 | val = I915_READ(DPLL_CTRL1); |
2601 | hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; | 2631 | hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f; |
@@ -2605,8 +2635,12 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2605 | hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); | 2635 | hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1); |
2606 | hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); | 2636 | hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2); |
2607 | } | 2637 | } |
2638 | ret = true; | ||
2608 | 2639 | ||
2609 | return true; | 2640 | out: |
2641 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); | ||
2642 | |||
2643 | return ret; | ||
2610 | } | 2644 | } |
2611 | 2645 | ||
2612 | static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) | 2646 | static void skl_shared_dplls_init(struct drm_i915_private *dev_priv) |
@@ -2873,13 +2907,16 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2873 | { | 2907 | { |
2874 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ | 2908 | enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */ |
2875 | uint32_t val; | 2909 | uint32_t val; |
2910 | bool ret; | ||
2876 | 2911 | ||
2877 | if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS)) | 2912 | if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) |
2878 | return false; | 2913 | return false; |
2879 | 2914 | ||
2915 | ret = false; | ||
2916 | |||
2880 | val = I915_READ(BXT_PORT_PLL_ENABLE(port)); | 2917 | val = I915_READ(BXT_PORT_PLL_ENABLE(port)); |
2881 | if (!(val & PORT_PLL_ENABLE)) | 2918 | if (!(val & PORT_PLL_ENABLE)) |
2882 | return false; | 2919 | goto out; |
2883 | 2920 | ||
2884 | hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port)); | 2921 | hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port)); |
2885 | hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; | 2922 | hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK; |
@@ -2926,7 +2963,12 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, | |||
2926 | I915_READ(BXT_PORT_PCS_DW12_LN23(port))); | 2963 | I915_READ(BXT_PORT_PCS_DW12_LN23(port))); |
2927 | hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; | 2964 | hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD; |
2928 | 2965 | ||
2929 | return true; | 2966 | ret = true; |
2967 | |||
2968 | out: | ||
2969 | intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); | ||
2970 | |||
2971 | return ret; | ||
2930 | } | 2972 | } |
2931 | 2973 | ||
2932 | static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv) | 2974 | static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv) |
@@ -3061,11 +3103,15 @@ bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, | |||
3061 | { | 3103 | { |
3062 | u32 temp; | 3104 | u32 temp; |
3063 | 3105 | ||
3064 | if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { | 3106 | if (intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_AUDIO)) { |
3065 | temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); | 3107 | temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD); |
3108 | |||
3109 | intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); | ||
3110 | |||
3066 | if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe)) | 3111 | if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe)) |
3067 | return true; | 3112 | return true; |
3068 | } | 3113 | } |
3114 | |||
3069 | return false; | 3115 | return false; |
3070 | } | 3116 | } |
3071 | 3117 | ||