diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2016-03-08 10:46:25 -0500 |
---|---|---|
committer | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2016-03-09 04:55:31 -0500 |
commit | 34177c249af743ceccaf583bf750e8bc17c4f18a (patch) | |
tree | e0ac87cc55e6e3988fd4efd50696d30fe591783c | |
parent | 304b65cbdc8d6d73b12ea798099b7ca64f491795 (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.c | 141 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dpll_mgr.c | 139 |
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 */ | ||
1029 | struct 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 */ | ||
1040 | static 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 | |||
1050 | static bool | 1028 | static bool |
1051 | bxt_ddi_pll_select(struct intel_crtc *intel_crtc, | 1029 | bxt_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 */ | ||
1346 | struct 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 */ | ||
1357 | static 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 | |||
1345 | static struct intel_shared_dpll * | 1367 | static struct intel_shared_dpll * |
1346 | bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, | 1368 | bxt_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 | ||