aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-25 15:02:02 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-10 16:13:24 -0400
commit716c2e55100ff5588bd2bbca14951ef11624cba2 (patch)
treebf84cf57752a42f3a1e09651ba8ffc22b125ea16
parente0b01be41dcdfd28c6855f605983a61b29f65692 (diff)
drm/i915: Switch to common shared dpll framework for WRPLLs
Mostly this patch is one big excersize in deleting code and asserts which are no longer needed. Note that we still abuse the shared dpll framework a bit since we call the enable/disable functions from the crtc mode_set and off hooks. But changing the actual hardware sequence will be done in the next step. Note that besides the massive amount of changes in this patch the places and order in which the low-level WRPLL code is called is absolutely unchanged. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> [imre: rebased on patchset version w/o pch/crt/fdi refactoring] Signed-off-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-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)