aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c18
-rw-r--r--drivers/gpu/drm/i915/intel_display.c25
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c23
-rw-r--r--drivers/gpu/drm/i915/intel_dp_mst.c4
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c90
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.h12
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
7 files changed, 108 insertions, 65 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 50cc26435595..31f9aa0c2b51 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -992,17 +992,13 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
992{ 992{
993 struct intel_shared_dpll *pll; 993 struct intel_shared_dpll *pll;
994 994
995 if (intel_encoder->type == INTEL_OUTPUT_HDMI || 995 pll = intel_get_shared_dpll(intel_crtc, crtc_state,
996 intel_encoder->type == INTEL_OUTPUT_ANALOG) { 996 intel_encoder);
997 pll = intel_get_shared_dpll(intel_crtc, crtc_state, 997 if (!pll)
998 intel_encoder); 998 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
999 if (!pll) 999 pipe_name(intel_crtc->pipe));
1000 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", 1000
1001 pipe_name(intel_crtc->pipe)); 1001 return pll;
1002 return pll;
1003 } else {
1004 return true;
1005 }
1006} 1002}
1007 1003
1008static bool 1004static bool
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9d2f494c0e65..7e00ee51b2c9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9821,13 +9821,19 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv,
9821 case PORT_CLK_SEL_SPLL: 9821 case PORT_CLK_SEL_SPLL:
9822 id = DPLL_ID_SPLL; 9822 id = DPLL_ID_SPLL;
9823 break; 9823 break;
9824 case PORT_CLK_SEL_LCPLL_810:
9825 id = DPLL_ID_LCPLL_810;
9826 break;
9827 case PORT_CLK_SEL_LCPLL_1350:
9828 id = DPLL_ID_LCPLL_1350;
9829 break;
9830 case PORT_CLK_SEL_LCPLL_2700:
9831 id = DPLL_ID_LCPLL_2700;
9832 break;
9824 default: 9833 default:
9825 MISSING_CASE(pipe_config->ddi_pll_sel); 9834 MISSING_CASE(pipe_config->ddi_pll_sel);
9826 /* fall through */ 9835 /* fall through */
9827 case PORT_CLK_SEL_NONE: 9836 case PORT_CLK_SEL_NONE:
9828 case PORT_CLK_SEL_LCPLL_810:
9829 case PORT_CLK_SEL_LCPLL_1350:
9830 case PORT_CLK_SEL_LCPLL_2700:
9831 return; 9837 return;
9832 } 9838 }
9833 9839
@@ -12942,11 +12948,14 @@ check_shared_dpll_state(struct drm_device *dev)
12942 pll->active, hweight32(pll->config.crtc_mask)); 12948 pll->active, hweight32(pll->config.crtc_mask));
12943 I915_STATE_WARN(pll->active && !pll->on, 12949 I915_STATE_WARN(pll->active && !pll->on,
12944 "pll in active use but not on in sw tracking\n"); 12950 "pll in active use but not on in sw tracking\n");
12945 I915_STATE_WARN(pll->on && !pll->active, 12951
12946 "pll in on but not on in use in sw tracking\n"); 12952 if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) {
12947 I915_STATE_WARN(pll->on != active, 12953 I915_STATE_WARN(pll->on && !pll->active,
12948 "pll on state mismatch (expected %i, found %i)\n", 12954 "pll in on but not on in use in sw tracking\n");
12949 pll->on, active); 12955 I915_STATE_WARN(pll->on != active,
12956 "pll on state mismatch (expected %i, found %i)\n",
12957 pll->on, active);
12958 }
12950 12959
12951 for_each_intel_crtc(dev, crtc) { 12960 for_each_intel_crtc(dev, crtc) {
12952 if (crtc->base.state->enable && crtc->config->shared_dpll == pll) 12961 if (crtc->base.state->enable && crtc->config->shared_dpll == pll)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 109ae6166db1..4f0fad3cf138 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1283,25 +1283,6 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
1283 pipe_config->dpll_hw_state.ctrl1 = ctrl1; 1283 pipe_config->dpll_hw_state.ctrl1 = ctrl1;
1284} 1284}
1285 1285
1286void
1287hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config)
1288{
1289 memset(&pipe_config->dpll_hw_state, 0,
1290 sizeof(pipe_config->dpll_hw_state));
1291
1292 switch (pipe_config->port_clock / 2) {
1293 case 81000:
1294 pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810;
1295 break;
1296 case 135000:
1297 pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350;
1298 break;
1299 case 270000:
1300 pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700;
1301 break;
1302 }
1303}
1304
1305static int 1286static int
1306intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) 1287intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
1307{ 1288{
@@ -1661,10 +1642,8 @@ found:
1661 1642
1662 if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && is_edp(intel_dp)) 1643 if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && is_edp(intel_dp))
1663 skl_edp_set_pll_config(pipe_config); 1644 skl_edp_set_pll_config(pipe_config);
1664 else if (IS_BROXTON(dev)) 1645 else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
1665 /* handled in ddi */; 1646 /* handled in ddi */;
1666 else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
1667 hsw_dp_set_ddi_pll_sel(pipe_config);
1668 else 1647 else
1669 intel_dp_set_clock(encoder, pipe_config); 1648 intel_dp_set_clock(encoder, pipe_config);
1670 1649
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index a2bd698fe2f7..8d1b7033aaba 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -33,7 +33,6 @@
33static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, 33static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
34 struct intel_crtc_state *pipe_config) 34 struct intel_crtc_state *pipe_config)
35{ 35{
36 struct drm_device *dev = encoder->base.dev;
37 struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); 36 struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
38 struct intel_digital_port *intel_dig_port = intel_mst->primary; 37 struct intel_digital_port *intel_dig_port = intel_mst->primary;
39 struct intel_dp *intel_dp = &intel_dig_port->dp; 38 struct intel_dp *intel_dp = &intel_dig_port->dp;
@@ -92,9 +91,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
92 91
93 pipe_config->dp_m_n.tu = slots; 92 pipe_config->dp_m_n.tu = slots;
94 93
95 if (IS_HASWELL(dev) || IS_BROADWELL(dev))
96 hsw_dp_set_ddi_pll_sel(pipe_config);
97
98 return true; 94 return true;
99 95
100} 96}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index a90ef34a7785..a83af07e3570 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -447,6 +447,12 @@ static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
447 return PORT_CLK_SEL_WRPLL2; 447 return PORT_CLK_SEL_WRPLL2;
448 case DPLL_ID_SPLL: 448 case DPLL_ID_SPLL:
449 return PORT_CLK_SEL_SPLL; 449 return PORT_CLK_SEL_SPLL;
450 case DPLL_ID_LCPLL_810:
451 return PORT_CLK_SEL_LCPLL_810;
452 case DPLL_ID_LCPLL_1350:
453 return PORT_CLK_SEL_LCPLL_1350;
454 case DPLL_ID_LCPLL_2700:
455 return PORT_CLK_SEL_LCPLL_2700;
450 default: 456 default:
451 return PORT_CLK_SEL_NONE; 457 return PORT_CLK_SEL_NONE;
452 } 458 }
@@ -671,9 +677,13 @@ static struct intel_shared_dpll *
671hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, 677hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
672 struct intel_encoder *encoder) 678 struct intel_encoder *encoder)
673{ 679{
680 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
674 struct intel_shared_dpll *pll; 681 struct intel_shared_dpll *pll;
675 int clock = crtc_state->port_clock; 682 int clock = crtc_state->port_clock;
676 683
684 memset(&crtc_state->dpll_hw_state, 0,
685 sizeof(crtc_state->dpll_hw_state));
686
677 if (encoder->type == INTEL_OUTPUT_HDMI) { 687 if (encoder->type == INTEL_OUTPUT_HDMI) {
678 uint32_t val; 688 uint32_t val;
679 unsigned p, n2, r2; 689 unsigned p, n2, r2;
@@ -684,21 +694,37 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
684 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | 694 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
685 WRPLL_DIVIDER_POST(p); 695 WRPLL_DIVIDER_POST(p);
686 696
687 memset(&crtc_state->dpll_hw_state, 0,
688 sizeof(crtc_state->dpll_hw_state));
689
690 crtc_state->dpll_hw_state.wrpll = val; 697 crtc_state->dpll_hw_state.wrpll = val;
691 698
692 pll = intel_find_shared_dpll(crtc, crtc_state, 699 pll = intel_find_shared_dpll(crtc, crtc_state,
693 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); 700 DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
694 701
702 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
703 encoder->type == INTEL_OUTPUT_DP_MST ||
704 encoder->type == INTEL_OUTPUT_EDP) {
705 enum intel_dpll_id pll_id;
706
707 switch (clock / 2) {
708 case 81000:
709 pll_id = DPLL_ID_LCPLL_810;
710 break;
711 case 135000:
712 pll_id = DPLL_ID_LCPLL_1350;
713 break;
714 case 270000:
715 pll_id = DPLL_ID_LCPLL_2700;
716 break;
717 default:
718 DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock);
719 return NULL;
720 }
721
722 pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
723
695 } else if (encoder->type == INTEL_OUTPUT_ANALOG) { 724 } else if (encoder->type == INTEL_OUTPUT_ANALOG) {
696 if (WARN_ON(crtc_state->port_clock / 2 != 135000)) 725 if (WARN_ON(crtc_state->port_clock / 2 != 135000))
697 return NULL; 726 return NULL;
698 727
699 memset(&crtc_state->dpll_hw_state, 0,
700 sizeof(crtc_state->dpll_hw_state));
701
702 crtc_state->dpll_hw_state.spll = 728 crtc_state->dpll_hw_state.spll =
703 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; 729 SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
704 730
@@ -731,6 +757,29 @@ static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
731 .get_hw_state = hsw_ddi_spll_get_hw_state, 757 .get_hw_state = hsw_ddi_spll_get_hw_state,
732}; 758};
733 759
760static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
761 struct intel_shared_dpll *pll)
762{
763}
764
765static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
766 struct intel_shared_dpll *pll)
767{
768}
769
770static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
771 struct intel_shared_dpll *pll,
772 struct intel_dpll_hw_state *hw_state)
773{
774 return true;
775}
776
777static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
778 .enable = hsw_ddi_lcpll_enable,
779 .disable = hsw_ddi_lcpll_disable,
780 .get_hw_state = hsw_ddi_lcpll_get_hw_state,
781};
782
734struct skl_dpll_regs { 783struct skl_dpll_regs {
735 i915_reg_t ctl, cfgcr1, cfgcr2; 784 i915_reg_t ctl, cfgcr1, cfgcr2;
736}; 785};
@@ -1537,6 +1586,7 @@ struct dpll_info {
1537 const char *name; 1586 const char *name;
1538 const int id; 1587 const int id;
1539 const struct intel_shared_dpll_funcs *funcs; 1588 const struct intel_shared_dpll_funcs *funcs;
1589 uint32_t flags;
1540}; 1590};
1541 1591
1542struct intel_dpll_mgr { 1592struct intel_dpll_mgr {
@@ -1548,9 +1598,9 @@ struct intel_dpll_mgr {
1548}; 1598};
1549 1599
1550static const struct dpll_info pch_plls[] = { 1600static const struct dpll_info pch_plls[] = {
1551 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs }, 1601 { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 },
1552 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs }, 1602 { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 },
1553 { NULL, -1, NULL }, 1603 { NULL, -1, NULL, 0 },
1554}; 1604};
1555 1605
1556static const struct intel_dpll_mgr pch_pll_mgr = { 1606static const struct intel_dpll_mgr pch_pll_mgr = {
@@ -1559,9 +1609,12 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
1559}; 1609};
1560 1610
1561static const struct dpll_info hsw_plls[] = { 1611static const struct dpll_info hsw_plls[] = {
1562 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs }, 1612 { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 },
1563 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs }, 1613 { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 },
1564 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs }, 1614 { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 },
1615 { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1616 { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1617 { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON },
1565 { NULL, -1, NULL, }, 1618 { NULL, -1, NULL, },
1566}; 1619};
1567 1620
@@ -1571,9 +1624,9 @@ static const struct intel_dpll_mgr hsw_pll_mgr = {
1571}; 1624};
1572 1625
1573static const struct dpll_info skl_plls[] = { 1626static const struct dpll_info skl_plls[] = {
1574 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs }, 1627 { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 },
1575 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs }, 1628 { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 },
1576 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs }, 1629 { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 },
1577 { NULL, -1, NULL, }, 1630 { NULL, -1, NULL, },
1578}; 1631};
1579 1632
@@ -1583,9 +1636,9 @@ static const struct intel_dpll_mgr skl_pll_mgr = {
1583}; 1636};
1584 1637
1585static const struct dpll_info bxt_plls[] = { 1638static const struct dpll_info bxt_plls[] = {
1586 { "PORT PLL A", 0, &bxt_ddi_pll_funcs }, 1639 { "PORT PLL A", 0, &bxt_ddi_pll_funcs, 0 },
1587 { "PORT PLL B", 1, &bxt_ddi_pll_funcs }, 1640 { "PORT PLL B", 1, &bxt_ddi_pll_funcs, 0 },
1588 { "PORT PLL C", 2, &bxt_ddi_pll_funcs }, 1641 { "PORT PLL C", 2, &bxt_ddi_pll_funcs, 0 },
1589 { NULL, -1, NULL, }, 1642 { NULL, -1, NULL, },
1590}; 1643};
1591 1644
@@ -1623,6 +1676,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
1623 dev_priv->shared_dplls[i].id = dpll_info[i].id; 1676 dev_priv->shared_dplls[i].id = dpll_info[i].id;
1624 dev_priv->shared_dplls[i].name = dpll_info[i].name; 1677 dev_priv->shared_dplls[i].name = dpll_info[i].name;
1625 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs; 1678 dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
1679 dev_priv->shared_dplls[i].flags = dpll_info[i].flags;
1626 } 1680 }
1627 1681
1628 dev_priv->dpll_mgr = dpll_mgr; 1682 dev_priv->dpll_mgr = dpll_mgr;
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 82e53f5b5c63..adf4706b8e58 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -49,13 +49,21 @@ enum intel_dpll_id {
49 DPLL_ID_WRPLL1 = 0, 49 DPLL_ID_WRPLL1 = 0,
50 DPLL_ID_WRPLL2 = 1, 50 DPLL_ID_WRPLL2 = 1,
51 DPLL_ID_SPLL = 2, 51 DPLL_ID_SPLL = 2,
52 DPLL_ID_LCPLL_810 = 3,
53 DPLL_ID_LCPLL_1350 = 4,
54 DPLL_ID_LCPLL_2700 = 5,
52 55
53 /* skl */ 56 /* skl */
54 DPLL_ID_SKL_DPLL1 = 0, 57 DPLL_ID_SKL_DPLL1 = 0,
55 DPLL_ID_SKL_DPLL2 = 1, 58 DPLL_ID_SKL_DPLL2 = 1,
56 DPLL_ID_SKL_DPLL3 = 2, 59 DPLL_ID_SKL_DPLL3 = 2,
57}; 60};
58#define I915_NUM_PLLS 3 61#define I915_NUM_PLLS 6
62
63/** Inform the state checker that the DPLL is kept enabled even if not
64 * in use by any crtc.
65 */
66#define INTEL_DPLL_ALWAYS_ON (1 << 0)
59 67
60struct intel_dpll_hw_state { 68struct intel_dpll_hw_state {
61 /* i9xx, pch plls */ 69 /* i9xx, pch plls */
@@ -113,6 +121,8 @@ struct intel_shared_dpll {
113 enum intel_dpll_id id; 121 enum intel_dpll_id id;
114 122
115 struct intel_shared_dpll_funcs funcs; 123 struct intel_shared_dpll_funcs funcs;
124
125 uint32_t flags;
116}; 126};
117 127
118#define SKL_DPLL0 0 128#define SKL_DPLL0 0
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1f62fba3ae3a..1e3992889647 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1312,7 +1312,6 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
1312void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); 1312void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
1313bool intel_digital_port_connected(struct drm_i915_private *dev_priv, 1313bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
1314 struct intel_digital_port *port); 1314 struct intel_digital_port *port);
1315void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config);
1316 1315
1317void 1316void
1318intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, 1317intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,