diff options
author | Dave Airlie <airlied@redhat.com> | 2013-12-22 19:46:07 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-12-22 19:46:07 -0500 |
commit | 859ae233cd0ee76b6143f948ba1cb6b0b4c342f8 (patch) | |
tree | b2071654cf0ef520e047035720a101d3222e47bc /drivers/gpu/drm/i915/intel_ddi.c | |
parent | 785e15ecefbfe8ea311ae320fdacd482a84b3cc3 (diff) | |
parent | ab57fff1302c485d74992d34df24ccb5efda244e (diff) |
Merge tag 'drm-intel-next-2013-12-13' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
- fbc1 improvements from Ville (pre-gm45).
- vlv forcewake improvements from Deepak S.
- Some corner-cases fixes from Mika for the context hang stat code.
- pc8 improvements and prep work for runtime D3 from Paulo, almost ready for
primetime.
- gen2 dpll fixes from Ville.
- DSI improvements from Shobhit Kumar.
- A few smaller fixes and improvements all over.
[airlied: intel_ddi.c conflict fixed up]
* tag 'drm-intel-next-2013-12-13' of git://people.freedesktop.org/~danvet/drm-intel: (61 commits)
drm/i915/bdw: Implement ff workarounds
drm/i915/bdw: Force all Data Cache Data Port access to be Non-Coherent
drm/i915/bdw: Don't use forcewake needlessly
drm/i915: Clear out old GT FIFO errors in intel_uncore_early_sanitize()
drm/i915: dont call irq_put when irq test is on
drm/i915: Rework the FBC interval/stall stuff a bit
drm/i915: Enable FBC for all mobile gen2 and gen3 platforms
drm/i915: FBC_CONTROL2 is gen4 only
drm/i915: Gen2 FBC1 CFB pitch wants 32B units
drm/i915: split intel_ddi_pll_mode_set in 2 pieces
drm/i915: Fix timeout with missed interrupts in __wait_seqno
drm/i915: touch VGA MSR after we enable the power well
drm/i915: extract hsw_power_well_post_{enable, disable}
drm/i915: remove i915_disable_vga_mem declaration
drm/i915: Parametrize the dphy and other spec specific parameters
drm/i915: Remove redundant DSI PLL enabling
drm/i915: Reorganize the DSI enable/disable sequence
drm/i915: Try harder to get best m, n, p values with minimal error
drm/i915: Compute dsi_clk from pixel clock
drm/i915: Use FLISDSI interface for band gap reset
...
Conflicts:
drivers/gpu/drm/i915/intel_ddi.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 113 |
1 files changed, 91 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index c8382f55870c..d7d2683b89df 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -73,7 +73,7 @@ static const u32 hsw_ddi_translations_hdmi[] = { | |||
73 | }; | 73 | }; |
74 | 74 | ||
75 | static const u32 bdw_ddi_translations_edp[] = { | 75 | static const u32 bdw_ddi_translations_edp[] = { |
76 | 0x00FFFFFF, 0x00000012, /* DP parameters */ | 76 | 0x00FFFFFF, 0x00000012, /* eDP parameters */ |
77 | 0x00EBAFFF, 0x00020011, | 77 | 0x00EBAFFF, 0x00020011, |
78 | 0x00C71FFF, 0x0006000F, | 78 | 0x00C71FFF, 0x0006000F, |
79 | 0x00FFFFFF, 0x00020011, | 79 | 0x00FFFFFF, 0x00020011, |
@@ -696,21 +696,23 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */, | |||
696 | *n2_out = best.n2; | 696 | *n2_out = best.n2; |
697 | *p_out = best.p; | 697 | *p_out = best.p; |
698 | *r2_out = best.r2; | 698 | *r2_out = best.r2; |
699 | |||
700 | DRM_DEBUG_KMS("WRPLL: %dHz refresh rate with p=%d, n2=%d r2=%d\n", | ||
701 | clock, *p_out, *n2_out, *r2_out); | ||
702 | } | 699 | } |
703 | 700 | ||
704 | bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) | 701 | /* |
702 | * Tries to find a PLL for the CRTC. If it finds, it increases the refcount and | ||
703 | * stores it in intel_crtc->ddi_pll_sel, so other mode sets won't be able to | ||
704 | * steal the selected PLL. You need to call intel_ddi_pll_enable to actually | ||
705 | * enable the PLL. | ||
706 | */ | ||
707 | bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) | ||
705 | { | 708 | { |
706 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 709 | struct drm_crtc *crtc = &intel_crtc->base; |
707 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); | 710 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
708 | struct drm_encoder *encoder = &intel_encoder->base; | 711 | struct drm_encoder *encoder = &intel_encoder->base; |
709 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 712 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
710 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; | 713 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; |
711 | int type = intel_encoder->type; | 714 | int type = intel_encoder->type; |
712 | enum pipe pipe = intel_crtc->pipe; | 715 | enum pipe pipe = intel_crtc->pipe; |
713 | uint32_t reg, val; | ||
714 | int clock = intel_crtc->config.port_clock; | 716 | int clock = intel_crtc->config.port_clock; |
715 | 717 | ||
716 | intel_ddi_put_crtc_pll(crtc); | 718 | intel_ddi_put_crtc_pll(crtc); |
@@ -734,10 +736,8 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) | |||
734 | return false; | 736 | return false; |
735 | } | 737 | } |
736 | 738 | ||
737 | /* We don't need to turn any PLL on because we'll use LCPLL. */ | ||
738 | return true; | ||
739 | |||
740 | } else if (type == INTEL_OUTPUT_HDMI) { | 739 | } else if (type == INTEL_OUTPUT_HDMI) { |
740 | uint32_t reg, val; | ||
741 | unsigned p, n2, r2; | 741 | unsigned p, n2, r2; |
742 | 742 | ||
743 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); | 743 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); |
@@ -767,6 +767,9 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) | |||
767 | return false; | 767 | return false; |
768 | } | 768 | } |
769 | 769 | ||
770 | DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", | ||
771 | clock, p, n2, r2); | ||
772 | |||
770 | if (reg == WRPLL_CTL1) { | 773 | if (reg == WRPLL_CTL1) { |
771 | plls->wrpll1_refcount++; | 774 | plls->wrpll1_refcount++; |
772 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; | 775 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_WRPLL1; |
@@ -780,29 +783,98 @@ bool intel_ddi_pll_mode_set(struct drm_crtc *crtc) | |||
780 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", | 783 | DRM_DEBUG_KMS("Using SPLL on pipe %c\n", |
781 | pipe_name(pipe)); | 784 | pipe_name(pipe)); |
782 | plls->spll_refcount++; | 785 | plls->spll_refcount++; |
783 | reg = SPLL_CTL; | ||
784 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; | 786 | intel_crtc->ddi_pll_sel = PORT_CLK_SEL_SPLL; |
785 | } else { | 787 | } else { |
786 | DRM_ERROR("SPLL already in use\n"); | 788 | DRM_ERROR("SPLL already in use\n"); |
787 | return false; | 789 | return false; |
788 | } | 790 | } |
789 | 791 | ||
790 | WARN(I915_READ(reg) & SPLL_PLL_ENABLE, | ||
791 | "SPLL already enabled\n"); | ||
792 | |||
793 | val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; | ||
794 | |||
795 | } else { | 792 | } else { |
796 | WARN(1, "Invalid DDI encoder type %d\n", type); | 793 | WARN(1, "Invalid DDI encoder type %d\n", type); |
797 | return false; | 794 | return false; |
798 | } | 795 | } |
799 | 796 | ||
800 | I915_WRITE(reg, val); | ||
801 | udelay(20); | ||
802 | |||
803 | return true; | 797 | return true; |
804 | } | 798 | } |
805 | 799 | ||
800 | /* | ||
801 | * To be called after intel_ddi_pll_select(). That one selects the PLL to be | ||
802 | * used, this one actually enables the PLL. | ||
803 | */ | ||
804 | void intel_ddi_pll_enable(struct intel_crtc *crtc) | ||
805 | { | ||
806 | struct drm_device *dev = crtc->base.dev; | ||
807 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
808 | struct intel_ddi_plls *plls = &dev_priv->ddi_plls; | ||
809 | int clock = crtc->config.port_clock; | ||
810 | uint32_t reg, cur_val, new_val; | ||
811 | int refcount; | ||
812 | const char *pll_name; | ||
813 | uint32_t enable_bit = (1 << 31); | ||
814 | unsigned int p, n2, r2; | ||
815 | |||
816 | BUILD_BUG_ON(enable_bit != SPLL_PLL_ENABLE); | ||
817 | BUILD_BUG_ON(enable_bit != WRPLL_PLL_ENABLE); | ||
818 | |||
819 | switch (crtc->ddi_pll_sel) { | ||
820 | case PORT_CLK_SEL_LCPLL_2700: | ||
821 | case PORT_CLK_SEL_LCPLL_1350: | ||
822 | case PORT_CLK_SEL_LCPLL_810: | ||
823 | /* | ||
824 | * LCPLL should always be enabled at this point of the mode set | ||
825 | * sequence, so nothing to do. | ||
826 | */ | ||
827 | return; | ||
828 | |||
829 | case PORT_CLK_SEL_SPLL: | ||
830 | pll_name = "SPLL"; | ||
831 | reg = SPLL_CTL; | ||
832 | refcount = plls->spll_refcount; | ||
833 | new_val = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | | ||
834 | SPLL_PLL_SSC; | ||
835 | break; | ||
836 | |||
837 | case PORT_CLK_SEL_WRPLL1: | ||
838 | case PORT_CLK_SEL_WRPLL2: | ||
839 | if (crtc->ddi_pll_sel == PORT_CLK_SEL_WRPLL1) { | ||
840 | pll_name = "WRPLL1"; | ||
841 | reg = WRPLL_CTL1; | ||
842 | refcount = plls->wrpll1_refcount; | ||
843 | } else { | ||
844 | pll_name = "WRPLL2"; | ||
845 | reg = WRPLL_CTL2; | ||
846 | refcount = plls->wrpll2_refcount; | ||
847 | } | ||
848 | |||
849 | intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); | ||
850 | |||
851 | new_val = WRPLL_PLL_ENABLE | WRPLL_PLL_SELECT_LCPLL_2700 | | ||
852 | WRPLL_DIVIDER_REFERENCE(r2) | | ||
853 | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p); | ||
854 | |||
855 | break; | ||
856 | |||
857 | case PORT_CLK_SEL_NONE: | ||
858 | WARN(1, "Bad selected pll: PORT_CLK_SEL_NONE\n"); | ||
859 | return; | ||
860 | default: | ||
861 | WARN(1, "Bad selected pll: 0x%08x\n", crtc->ddi_pll_sel); | ||
862 | return; | ||
863 | } | ||
864 | |||
865 | cur_val = I915_READ(reg); | ||
866 | |||
867 | WARN(refcount < 1, "Bad %s refcount: %d\n", pll_name, refcount); | ||
868 | if (refcount == 1) { | ||
869 | WARN(cur_val & enable_bit, "%s already enabled\n", pll_name); | ||
870 | I915_WRITE(reg, new_val); | ||
871 | POSTING_READ(reg); | ||
872 | udelay(20); | ||
873 | } else { | ||
874 | WARN((cur_val & enable_bit) == 0, "%s disabled\n", pll_name); | ||
875 | } | ||
876 | } | ||
877 | |||
806 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) | 878 | void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) |
807 | { | 879 | { |
808 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 880 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; |
@@ -1122,9 +1194,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1122 | 1194 | ||
1123 | if (type == INTEL_OUTPUT_EDP) { | 1195 | if (type == INTEL_OUTPUT_EDP) { |
1124 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1196 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1125 | ironlake_edp_panel_vdd_on(intel_dp); | ||
1126 | ironlake_edp_panel_on(intel_dp); | 1197 | ironlake_edp_panel_on(intel_dp); |
1127 | ironlake_edp_panel_vdd_off(intel_dp, true); | ||
1128 | } | 1198 | } |
1129 | 1199 | ||
1130 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); | 1200 | WARN_ON(intel_crtc->ddi_pll_sel == PORT_CLK_SEL_NONE); |
@@ -1167,7 +1237,6 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) | |||
1167 | 1237 | ||
1168 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { | 1238 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1169 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1239 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1170 | ironlake_edp_panel_vdd_on(intel_dp); | ||
1171 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | 1240 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1172 | ironlake_edp_panel_off(intel_dp); | 1241 | ironlake_edp_panel_off(intel_dp); |
1173 | } | 1242 | } |