aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h6
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c141
-rw-r--r--drivers/gpu/drm/i915/intel_display.c14
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h9
5 files changed, 27 insertions, 144 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5d13c990b1fd..647ea67d0b1d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -234,11 +234,6 @@ void intel_link_compute_m_n(int bpp, int nlanes,
234 int pixel_clock, int link_clock, 234 int pixel_clock, int link_clock,
235 struct intel_link_m_n *m_n); 235 struct intel_link_m_n *m_n);
236 236
237struct intel_ddi_plls {
238 int wrpll1_refcount;
239 int wrpll2_refcount;
240};
241
242/* Interface history: 237/* Interface history:
243 * 238 *
244 * 1.1: Original. 239 * 1.1: Original.
@@ -1517,7 +1512,6 @@ struct drm_i915_private {
1517 1512
1518 int num_shared_dpll; 1513 int num_shared_dpll;
1519 struct intel_shared_dpll shared_dplls[I915_NUM_PLLS]; 1514 struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
1520 struct intel_ddi_plls ddi_plls;
1521 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV]; 1515 int dpio_phy_iosf_port[I915_NUM_PHYS_VLV];
1522 1516
1523 /* Reclocking support */ 1517 /* Reclocking support */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d20fadd9acf3..2d2c4deb3e87 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5946,6 +5946,7 @@ enum punit_power_well {
5946#define PORT_CLK_SEL_LCPLL_1350 (1<<29) 5946#define PORT_CLK_SEL_LCPLL_1350 (1<<29)
5947#define PORT_CLK_SEL_LCPLL_810 (2<<29) 5947#define PORT_CLK_SEL_LCPLL_810 (2<<29)
5948#define PORT_CLK_SEL_SPLL (3<<29) 5948#define PORT_CLK_SEL_SPLL (3<<29)
5949#define PORT_CLK_SEL_WRPLL(pll) (((pll)+4)<<29)
5949#define PORT_CLK_SEL_WRPLL1 (4<<29) 5950#define PORT_CLK_SEL_WRPLL1 (4<<29)
5950#define PORT_CLK_SEL_WRPLL2 (5<<29) 5951#define PORT_CLK_SEL_WRPLL2 (5<<29)
5951#define PORT_CLK_SEL_NONE (7<<29) 5952#define PORT_CLK_SEL_NONE (7<<29)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 150b64b45cb6..60e67a11791b 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -388,30 +388,12 @@ intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
388 388
389void intel_ddi_put_crtc_pll(struct drm_crtc *crtc) 389void intel_ddi_put_crtc_pll(struct drm_crtc *crtc)
390{ 390{
391 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
392 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
393 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 391 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
394 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(intel_crtc);
395 392
396 switch (intel_crtc->config.ddi_pll_sel) { 393 if (intel_crtc_to_shared_dpll(intel_crtc))
397 case PORT_CLK_SEL_WRPLL1: 394 intel_disable_shared_dpll(intel_crtc);
398 plls->wrpll1_refcount--;
399 if (plls->wrpll1_refcount == 0) {
400 pll->disable(dev_priv, pll);
401 }
402 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
403 break;
404 case PORT_CLK_SEL_WRPLL2:
405 plls->wrpll2_refcount--;
406 if (plls->wrpll2_refcount == 0) {
407 pll->disable(dev_priv, pll);
408 }
409 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
410 break;
411 }
412 395
413 WARN(plls->wrpll1_refcount < 0, "Invalid WRPLL1 refcount\n"); 396 intel_put_shared_dpll(intel_crtc);
414 WARN(plls->wrpll2_refcount < 0, "Invalid WRPLL2 refcount\n");
415} 397}
416 398
417#define LC_FREQ 2700 399#define LC_FREQ 2700
@@ -731,17 +713,14 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
731{ 713{
732 struct drm_crtc *crtc = &intel_crtc->base; 714 struct drm_crtc *crtc = &intel_crtc->base;
733 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); 715 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
734 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
735 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
736 int type = intel_encoder->type; 716 int type = intel_encoder->type;
737 enum pipe pipe = intel_crtc->pipe;
738 int clock = intel_crtc->config.port_clock; 717 int clock = intel_crtc->config.port_clock;
739 718
740 intel_ddi_put_crtc_pll(crtc); 719 intel_ddi_put_crtc_pll(crtc);
741 720
742 if (type == INTEL_OUTPUT_HDMI) { 721 if (type == INTEL_OUTPUT_HDMI) {
743 struct intel_shared_dpll *pll; 722 struct intel_shared_dpll *pll;
744 uint32_t reg, val; 723 uint32_t val;
745 unsigned p, n2, r2; 724 unsigned p, n2, r2;
746 725
747 intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); 726 intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
@@ -750,79 +729,21 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc)
750 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | 729 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
751 WRPLL_DIVIDER_POST(p); 730 WRPLL_DIVIDER_POST(p);
752 731
753 if (val == I915_READ(WRPLL_CTL1)) { 732 intel_crtc->config.dpll_hw_state.wrpll = val;
754 DRM_DEBUG_KMS("Reusing WRPLL 1 on pipe %c\n",
755 pipe_name(pipe));
756 reg = WRPLL_CTL1;
757 } else if (val == I915_READ(WRPLL_CTL2)) {
758 DRM_DEBUG_KMS("Reusing WRPLL 2 on pipe %c\n",
759 pipe_name(pipe));
760 reg = WRPLL_CTL2;
761 } else if (plls->wrpll1_refcount == 0) {
762 DRM_DEBUG_KMS("Using WRPLL 1 on pipe %c\n",
763 pipe_name(pipe));
764 reg = WRPLL_CTL1;
765 } else if (plls->wrpll2_refcount == 0) {
766 DRM_DEBUG_KMS("Using WRPLL 2 on pipe %c\n",
767 pipe_name(pipe));
768 reg = WRPLL_CTL2;
769 } else {
770 DRM_ERROR("No WRPLLs available!\n");
771 return false;
772 }
773 733
774 DRM_DEBUG_KMS("WRPLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n", 734 pll = intel_get_shared_dpll(intel_crtc);
775 clock, p, n2, r2); 735 if (pll == NULL) {
776 736 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
777 if (reg == WRPLL_CTL1) { 737 pipe_name(intel_crtc->pipe));
778 plls->wrpll1_refcount++; 738 return false;
779 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL1;
780 intel_crtc->config.shared_dpll = DPLL_ID_WRPLL1;
781 } else {
782 plls->wrpll2_refcount++;
783 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL2;
784 intel_crtc->config.shared_dpll = DPLL_ID_WRPLL2;
785 } 739 }
786 740
787 intel_crtc->config.dpll_hw_state.wrpll = val; 741 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
788
789 pll = &dev_priv->shared_dplls[intel_crtc->config.shared_dpll];
790 pll->hw_state.wrpll = val;
791 } 742 }
792 743
793 return true; 744 return true;
794} 745}
795 746
796/*
797 * To be called after intel_ddi_pll_select(). That one selects the PLL to be
798 * used, this one actually enables the PLL.
799 */
800void intel_ddi_pll_enable(struct intel_crtc *crtc)
801{
802 struct drm_device *dev = crtc->base.dev;
803 struct drm_i915_private *dev_priv = dev->dev_private;
804 struct intel_ddi_plls *plls = &dev_priv->ddi_plls;
805 int refcount;
806 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
807
808 switch (crtc->config.ddi_pll_sel) {
809 case PORT_CLK_SEL_WRPLL1:
810 case PORT_CLK_SEL_WRPLL2:
811 if (crtc->config.ddi_pll_sel == PORT_CLK_SEL_WRPLL1) {
812 refcount = plls->wrpll1_refcount;
813 } else {
814 refcount = plls->wrpll2_refcount;
815 }
816 break;
817 default:
818 return;
819 }
820
821 if (refcount == 1) {
822 pll->enable(dev_priv, pll);
823 }
824}
825
826void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) 747void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
827{ 748{
828 struct drm_i915_private *dev_priv = crtc->dev->dev_private; 749 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
@@ -1054,35 +975,6 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1054 return false; 975 return false;
1055} 976}
1056 977
1057void intel_ddi_setup_hw_pll_state(struct drm_device *dev)
1058{
1059 struct drm_i915_private *dev_priv = dev->dev_private;
1060 enum pipe pipe;
1061 struct intel_crtc *intel_crtc;
1062
1063 dev_priv->ddi_plls.wrpll1_refcount = 0;
1064 dev_priv->ddi_plls.wrpll2_refcount = 0;
1065
1066 for_each_pipe(pipe) {
1067 intel_crtc =
1068 to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
1069
1070 if (!intel_crtc->active) {
1071 intel_crtc->config.ddi_pll_sel = PORT_CLK_SEL_NONE;
1072 continue;
1073 }
1074
1075 switch (intel_crtc->config.ddi_pll_sel) {
1076 case PORT_CLK_SEL_WRPLL1:
1077 dev_priv->ddi_plls.wrpll1_refcount++;
1078 break;
1079 case PORT_CLK_SEL_WRPLL2:
1080 dev_priv->ddi_plls.wrpll2_refcount++;
1081 break;
1082 }
1083 }
1084}
1085
1086void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) 978void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
1087{ 979{
1088 struct drm_crtc *crtc = &intel_crtc->base; 980 struct drm_crtc *crtc = &intel_crtc->base;
@@ -1288,10 +1180,6 @@ int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1288static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, 1180static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
1289 struct intel_shared_dpll *pll) 1181 struct intel_shared_dpll *pll)
1290{ 1182{
1291 uint32_t cur_val;
1292
1293 cur_val = I915_READ(WRPLL_CTL(pll->id));
1294 WARN(cur_val & WRPLL_PLL_ENABLE, "%s already enabled\n", pll->name);
1295 I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll); 1183 I915_WRITE(WRPLL_CTL(pll->id), pll->hw_state.wrpll);
1296 POSTING_READ(WRPLL_CTL(pll->id)); 1184 POSTING_READ(WRPLL_CTL(pll->id));
1297 udelay(20); 1185 udelay(20);
@@ -1303,7 +1191,6 @@ static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
1303 uint32_t val; 1191 uint32_t val;
1304 1192
1305 val = I915_READ(WRPLL_CTL(pll->id)); 1193 val = I915_READ(WRPLL_CTL(pll->id));
1306 WARN_ON(!(val & WRPLL_PLL_ENABLE));
1307 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE); 1194 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
1308 POSTING_READ(WRPLL_CTL(pll->id)); 1195 POSTING_READ(WRPLL_CTL(pll->id));
1309} 1196}
@@ -1334,11 +1221,9 @@ void intel_ddi_pll_init(struct drm_device *dev)
1334 uint32_t val = I915_READ(LCPLL_CTL); 1221 uint32_t val = I915_READ(LCPLL_CTL);
1335 int i; 1222 int i;
1336 1223
1337 /* Dummy setup until everything is moved over to avoid upsetting the hw 1224 dev_priv->num_shared_dpll = 2;
1338 * state cross checker. */
1339 dev_priv->num_shared_dpll = 0;
1340 1225
1341 for (i = 0; i < 2; i++) { 1226 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
1342 dev_priv->shared_dplls[i].id = i; 1227 dev_priv->shared_dplls[i].id = i;
1343 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i]; 1228 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
1344 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable; 1229 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 851221d6e7af..a3305a074650 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1821,7 +1821,7 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc)
1821 pll->on = true; 1821 pll->on = true;
1822} 1822}
1823 1823
1824static void intel_disable_shared_dpll(struct intel_crtc *crtc) 1824void intel_disable_shared_dpll(struct intel_crtc *crtc)
1825{ 1825{
1826 struct drm_device *dev = crtc->base.dev; 1826 struct drm_device *dev = crtc->base.dev;
1827 struct drm_i915_private *dev_priv = dev->dev_private; 1827 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3621,7 +3621,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
3621 lpt_enable_pch_transcoder(dev_priv, cpu_transcoder); 3621 lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
3622} 3622}
3623 3623
3624static void intel_put_shared_dpll(struct intel_crtc *crtc) 3624void intel_put_shared_dpll(struct intel_crtc *crtc)
3625{ 3625{
3626 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); 3626 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
3627 3627
@@ -3641,7 +3641,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc)
3641 crtc->config.shared_dpll = DPLL_ID_PRIVATE; 3641 crtc->config.shared_dpll = DPLL_ID_PRIVATE;
3642} 3642}
3643 3643
3644static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc) 3644struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
3645{ 3645{
3646 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; 3646 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
3647 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc); 3647 struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
@@ -7569,7 +7569,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
7569 7569
7570 if (!intel_ddi_pll_select(intel_crtc)) 7570 if (!intel_ddi_pll_select(intel_crtc))
7571 return -EINVAL; 7571 return -EINVAL;
7572 intel_ddi_pll_enable(intel_crtc); 7572
7573 if (intel_crtc_to_shared_dpll(intel_crtc))
7574 intel_enable_shared_dpll(intel_crtc);
7573 7575
7574 intel_crtc->lowfreq_avail = false; 7576 intel_crtc->lowfreq_avail = false;
7575 7577
@@ -12868,10 +12870,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
12868 crtc->active ? "enabled" : "disabled"); 12870 crtc->active ? "enabled" : "disabled");
12869 } 12871 }
12870 12872
12871 /* FIXME: Smash this into the new shared dpll infrastructure. */
12872 if (HAS_DDI(dev))
12873 intel_ddi_setup_hw_pll_state(dev);
12874
12875 for (i = 0; i < dev_priv->num_shared_dpll; i++) { 12873 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
12876 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; 12874 struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
12877 12875
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0c12558050ea..a7d12f363af7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -710,9 +710,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
710 enum transcoder cpu_transcoder); 710 enum transcoder cpu_transcoder);
711void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc); 711void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc);
712void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc); 712void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc);
713void intel_ddi_setup_hw_pll_state(struct drm_device *dev);
714bool intel_ddi_pll_select(struct intel_crtc *crtc); 713bool intel_ddi_pll_select(struct intel_crtc *crtc);
715void intel_ddi_pll_enable(struct intel_crtc *crtc);
716void intel_ddi_put_crtc_pll(struct drm_crtc *crtc); 714void intel_ddi_put_crtc_pll(struct drm_crtc *crtc);
717void intel_ddi_set_pipe_settings(struct drm_crtc *crtc); 715void intel_ddi_set_pipe_settings(struct drm_crtc *crtc);
718void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder); 716void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder);
@@ -796,12 +794,19 @@ __intel_framebuffer_create(struct drm_device *dev,
796void intel_prepare_page_flip(struct drm_device *dev, int plane); 794void intel_prepare_page_flip(struct drm_device *dev, int plane);
797void intel_finish_page_flip(struct drm_device *dev, int pipe); 795void intel_finish_page_flip(struct drm_device *dev, int pipe);
798void intel_finish_page_flip_plane(struct drm_device *dev, int plane); 796void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
797
798/* shared dpll functions */
799struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc); 799struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
800void assert_shared_dpll(struct drm_i915_private *dev_priv, 800void assert_shared_dpll(struct drm_i915_private *dev_priv,
801 struct intel_shared_dpll *pll, 801 struct intel_shared_dpll *pll,
802 bool state); 802 bool state);
803#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true) 803#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
804#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false) 804#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
805void intel_disable_shared_dpll(struct intel_crtc *crtc);
806struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc);
807void intel_put_shared_dpll(struct intel_crtc *crtc);
808
809/* modesetting asserts */
805void assert_pll(struct drm_i915_private *dev_priv, 810void assert_pll(struct drm_i915_private *dev_priv,
806 enum pipe pipe, bool state); 811 enum pipe pipe, bool state);
807#define assert_pll_enabled(d, p) assert_pll(d, p, true) 812#define assert_pll_enabled(d, p) assert_pll(d, p, true)