aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2016-03-08 10:46:25 -0500
committerAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2016-03-09 04:55:31 -0500
commit34177c249af743ceccaf583bf750e8bc17c4f18a (patch)
treee0ac87cc55e6e3988fd4efd50696d30fe591783c
parent304b65cbdc8d6d73b12ea798099b7ca64f491795 (diff)
drm/i915: Move BXT pll configuration logic to intel_dpll_mgr.c
Move the code for configurating BXT plls into the shared dpll code, so that the platform specific details are hidden behind that interface. Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1457451987-17466-12-git-send-email-ander.conselvan.de.oliveira@intel.com
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c141
-rw-r--r--drivers/gpu/drm/i915/intel_dpll_mgr.c139
2 files changed, 134 insertions, 146 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 2890675b5f9e..50cc26435595 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1025,151 +1025,12 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
1025 return true; 1025 return true;
1026} 1026}
1027 1027
1028/* bxt clock parameters */
1029struct bxt_clk_div {
1030 int clock;
1031 uint32_t p1;
1032 uint32_t p2;
1033 uint32_t m2_int;
1034 uint32_t m2_frac;
1035 bool m2_frac_en;
1036 uint32_t n;
1037};
1038
1039/* pre-calculated values for DP linkrates */
1040static const struct bxt_clk_div bxt_dp_clk_val[] = {
1041 {162000, 4, 2, 32, 1677722, 1, 1},
1042 {270000, 4, 1, 27, 0, 0, 1},
1043 {540000, 2, 1, 27, 0, 0, 1},
1044 {216000, 3, 2, 32, 1677722, 1, 1},
1045 {243000, 4, 1, 24, 1258291, 1, 1},
1046 {324000, 4, 1, 32, 1677722, 1, 1},
1047 {432000, 3, 1, 32, 1677722, 1, 1}
1048};
1049
1050static bool 1028static bool
1051bxt_ddi_pll_select(struct intel_crtc *intel_crtc, 1029bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1052 struct intel_crtc_state *crtc_state, 1030 struct intel_crtc_state *crtc_state,
1053 struct intel_encoder *intel_encoder) 1031 struct intel_encoder *intel_encoder)
1054{ 1032{
1055 struct intel_shared_dpll *pll; 1033 return !!intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
1056 struct bxt_clk_div clk_div = {0};
1057 int vco = 0;
1058 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
1059 uint32_t lanestagger;
1060 int clock = crtc_state->port_clock;
1061
1062 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1063 intel_clock_t best_clock;
1064
1065 /* Calculate HDMI div */
1066 /*
1067 * FIXME: tie the following calculation into
1068 * i9xx_crtc_compute_clock
1069 */
1070 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1071 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1072 clock, pipe_name(intel_crtc->pipe));
1073 return false;
1074 }
1075
1076 clk_div.p1 = best_clock.p1;
1077 clk_div.p2 = best_clock.p2;
1078 WARN_ON(best_clock.m1 != 2);
1079 clk_div.n = best_clock.n;
1080 clk_div.m2_int = best_clock.m2 >> 22;
1081 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1082 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1083
1084 vco = best_clock.vco;
1085 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1086 intel_encoder->type == INTEL_OUTPUT_EDP) {
1087 int i;
1088
1089 clk_div = bxt_dp_clk_val[0];
1090 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1091 if (bxt_dp_clk_val[i].clock == clock) {
1092 clk_div = bxt_dp_clk_val[i];
1093 break;
1094 }
1095 }
1096 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1097 }
1098
1099 if (vco >= 6200000 && vco <= 6700000) {
1100 prop_coef = 4;
1101 int_coef = 9;
1102 gain_ctl = 3;
1103 targ_cnt = 8;
1104 } else if ((vco > 5400000 && vco < 6200000) ||
1105 (vco >= 4800000 && vco < 5400000)) {
1106 prop_coef = 5;
1107 int_coef = 11;
1108 gain_ctl = 3;
1109 targ_cnt = 9;
1110 } else if (vco == 5400000) {
1111 prop_coef = 3;
1112 int_coef = 8;
1113 gain_ctl = 1;
1114 targ_cnt = 9;
1115 } else {
1116 DRM_ERROR("Invalid VCO\n");
1117 return false;
1118 }
1119
1120 memset(&crtc_state->dpll_hw_state, 0,
1121 sizeof(crtc_state->dpll_hw_state));
1122
1123 if (clock > 270000)
1124 lanestagger = 0x18;
1125 else if (clock > 135000)
1126 lanestagger = 0x0d;
1127 else if (clock > 67000)
1128 lanestagger = 0x07;
1129 else if (clock > 33000)
1130 lanestagger = 0x04;
1131 else
1132 lanestagger = 0x02;
1133
1134 crtc_state->dpll_hw_state.ebb0 =
1135 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1136 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1137 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1138 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1139
1140 if (clk_div.m2_frac_en)
1141 crtc_state->dpll_hw_state.pll3 =
1142 PORT_PLL_M2_FRAC_ENABLE;
1143
1144 crtc_state->dpll_hw_state.pll6 =
1145 prop_coef | PORT_PLL_INT_COEFF(int_coef);
1146 crtc_state->dpll_hw_state.pll6 |=
1147 PORT_PLL_GAIN_CTL(gain_ctl);
1148
1149 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1150
1151 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1152
1153 crtc_state->dpll_hw_state.pll10 =
1154 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1155 | PORT_PLL_DCO_AMP_OVR_EN_H;
1156
1157 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1158
1159 crtc_state->dpll_hw_state.pcsdw12 =
1160 LANESTAGGER_STRAP_OVRD | lanestagger;
1161
1162 pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
1163 if (pll == NULL) {
1164 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1165 pipe_name(intel_crtc->pipe));
1166 return false;
1167 }
1168
1169 /* shared DPLL id 0 is DPLL A */
1170 crtc_state->ddi_pll_sel = pll->id;
1171
1172 return true;
1173} 1034}
1174 1035
1175/* 1036/*
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 61887ae82b31..a90ef34a7785 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1342,29 +1342,156 @@ out:
1342 return ret; 1342 return ret;
1343} 1343}
1344 1344
1345/* bxt clock parameters */
1346struct bxt_clk_div {
1347 int clock;
1348 uint32_t p1;
1349 uint32_t p2;
1350 uint32_t m2_int;
1351 uint32_t m2_frac;
1352 bool m2_frac_en;
1353 uint32_t n;
1354};
1355
1356/* pre-calculated values for DP linkrates */
1357static const struct bxt_clk_div bxt_dp_clk_val[] = {
1358 {162000, 4, 2, 32, 1677722, 1, 1},
1359 {270000, 4, 1, 27, 0, 0, 1},
1360 {540000, 2, 1, 27, 0, 0, 1},
1361 {216000, 3, 2, 32, 1677722, 1, 1},
1362 {243000, 4, 1, 24, 1258291, 1, 1},
1363 {324000, 4, 1, 32, 1677722, 1, 1},
1364 {432000, 3, 1, 32, 1677722, 1, 1}
1365};
1366
1345static struct intel_shared_dpll * 1367static struct intel_shared_dpll *
1346bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, 1368bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
1347 struct intel_encoder *encoder) 1369 struct intel_encoder *encoder)
1348{ 1370{
1349 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 1371 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1350 struct intel_digital_port *intel_dig_port;
1351 struct intel_shared_dpll *pll; 1372 struct intel_shared_dpll *pll;
1352 enum intel_dpll_id i; 1373 enum intel_dpll_id i;
1374 struct intel_digital_port *intel_dig_port;
1375 struct bxt_clk_div clk_div = {0};
1376 int vco = 0;
1377 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
1378 uint32_t lanestagger;
1379 int clock = crtc_state->port_clock;
1353 1380
1354 /* PLL is attached to port in bxt */ 1381 if (encoder->type == INTEL_OUTPUT_HDMI) {
1355 encoder = intel_ddi_get_crtc_new_encoder(crtc_state); 1382 intel_clock_t best_clock;
1356 if (WARN_ON(!encoder)) 1383
1384 /* Calculate HDMI div */
1385 /*
1386 * FIXME: tie the following calculation into
1387 * i9xx_crtc_compute_clock
1388 */
1389 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1390 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1391 clock, pipe_name(crtc->pipe));
1392 return NULL;
1393 }
1394
1395 clk_div.p1 = best_clock.p1;
1396 clk_div.p2 = best_clock.p2;
1397 WARN_ON(best_clock.m1 != 2);
1398 clk_div.n = best_clock.n;
1399 clk_div.m2_int = best_clock.m2 >> 22;
1400 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1401 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1402
1403 vco = best_clock.vco;
1404 } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1405 encoder->type == INTEL_OUTPUT_EDP) {
1406 int i;
1407
1408 clk_div = bxt_dp_clk_val[0];
1409 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1410 if (bxt_dp_clk_val[i].clock == clock) {
1411 clk_div = bxt_dp_clk_val[i];
1412 break;
1413 }
1414 }
1415 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1416 }
1417
1418 if (vco >= 6200000 && vco <= 6700000) {
1419 prop_coef = 4;
1420 int_coef = 9;
1421 gain_ctl = 3;
1422 targ_cnt = 8;
1423 } else if ((vco > 5400000 && vco < 6200000) ||
1424 (vco >= 4800000 && vco < 5400000)) {
1425 prop_coef = 5;
1426 int_coef = 11;
1427 gain_ctl = 3;
1428 targ_cnt = 9;
1429 } else if (vco == 5400000) {
1430 prop_coef = 3;
1431 int_coef = 8;
1432 gain_ctl = 1;
1433 targ_cnt = 9;
1434 } else {
1435 DRM_ERROR("Invalid VCO\n");
1357 return NULL; 1436 return NULL;
1437 }
1438
1439 memset(&crtc_state->dpll_hw_state, 0,
1440 sizeof(crtc_state->dpll_hw_state));
1441
1442 if (clock > 270000)
1443 lanestagger = 0x18;
1444 else if (clock > 135000)
1445 lanestagger = 0x0d;
1446 else if (clock > 67000)
1447 lanestagger = 0x07;
1448 else if (clock > 33000)
1449 lanestagger = 0x04;
1450 else
1451 lanestagger = 0x02;
1452
1453 crtc_state->dpll_hw_state.ebb0 =
1454 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1455 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1456 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1457 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1458
1459 if (clk_div.m2_frac_en)
1460 crtc_state->dpll_hw_state.pll3 =
1461 PORT_PLL_M2_FRAC_ENABLE;
1462
1463 crtc_state->dpll_hw_state.pll6 =
1464 prop_coef | PORT_PLL_INT_COEFF(int_coef);
1465 crtc_state->dpll_hw_state.pll6 |=
1466 PORT_PLL_GAIN_CTL(gain_ctl);
1467
1468 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1469
1470 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1471
1472 crtc_state->dpll_hw_state.pll10 =
1473 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1474 | PORT_PLL_DCO_AMP_OVR_EN_H;
1475
1476 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1477
1478 crtc_state->dpll_hw_state.pcsdw12 =
1479 LANESTAGGER_STRAP_OVRD | lanestagger;
1358 1480
1359 intel_dig_port = enc_to_dig_port(&encoder->base); 1481 intel_dig_port = enc_to_dig_port(&encoder->base);
1482
1360 /* 1:1 mapping between ports and PLLs */ 1483 /* 1:1 mapping between ports and PLLs */
1361 i = (enum intel_dpll_id)intel_dig_port->port; 1484 i = (enum intel_dpll_id) intel_dig_port->port;
1362 pll = &dev_priv->shared_dplls[i]; 1485 pll = intel_get_shared_dpll_by_id(dev_priv, i);
1486
1363 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n", 1487 DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
1364 crtc->base.base.id, pll->name); 1488 crtc->base.base.id, pll->name);
1365 1489
1366 intel_reference_shared_dpll(pll, crtc_state); 1490 intel_reference_shared_dpll(pll, crtc_state);
1367 1491
1492 /* shared DPLL id 0 is DPLL A */
1493 crtc_state->ddi_pll_sel = pll->id;
1494
1368 return pll; 1495 return pll;
1369} 1496}
1370 1497