aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dpll_mgr.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c410
1 files changed, 185 insertions, 225 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 569903d47aea..22f55574a35c 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -21,6 +21,8 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/string_helpers.h>
+
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dpio_phy.h"
@@ -88,9 +90,9 @@ struct intel_shared_dpll_funcs {
struct intel_dpll_mgr {
const struct dpll_info *dpll_info;
- bool (*get_dplls)(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder);
+ int (*get_dplls)(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder);
void (*put_dplls)(struct intel_atomic_state *state,
struct intel_crtc *crtc);
void (*update_active_dpll)(struct intel_atomic_state *state,
@@ -178,13 +180,14 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
struct intel_dpll_hw_state hw_state;
if (drm_WARN(&dev_priv->drm, !pll,
- "asserting DPLL %s with no DPLL\n", onoff(state)))
+ "asserting DPLL %s with no DPLL\n", str_on_off(state)))
return;
cur_state = intel_dpll_get_hw_state(dev_priv, pll, &hw_state);
I915_STATE_WARN(cur_state != state,
"%s assertion failure (expected %s, current %s)\n",
- pll->info->name, onoff(state), onoff(cur_state));
+ pll->info->name, str_on_off(state),
+ str_on_off(cur_state));
}
static enum tc_port icl_pll_id_to_tc_port(enum intel_dpll_id id)
@@ -511,9 +514,9 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
udelay(200);
}
-static bool ibx_get_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int ibx_get_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@@ -538,7 +541,7 @@ static bool ibx_get_dpll(struct intel_atomic_state *state,
}
if (!pll)
- return false;
+ return -EINVAL;
/* reference the pll */
intel_reference_shared_dpll(state, crtc,
@@ -546,7 +549,7 @@ static bool ibx_get_dpll(struct intel_atomic_state *state,
crtc_state->shared_dpll = pll;
- return true;
+ return 0;
}
static void ibx_dump_hw_state(struct drm_i915_private *dev_priv,
@@ -581,7 +584,7 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
};
static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+ struct intel_shared_dpll *pll)
{
const enum intel_dpll_id id = pll->info->id;
@@ -832,7 +835,7 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
{
u64 freq2k;
unsigned p, n2, r2;
- struct hsw_wrpll_rnp best = { 0, 0, 0 };
+ struct hsw_wrpll_rnp best = {};
unsigned budget;
freq2k = clock / 100;
@@ -1057,16 +1060,13 @@ static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915,
return link_clock * 2;
}
-static bool hsw_get_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int hsw_get_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- struct intel_shared_dpll *pll;
-
- memset(&crtc_state->dpll_hw_state, 0,
- sizeof(crtc_state->dpll_hw_state));
+ struct intel_shared_dpll *pll = NULL;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
pll = hsw_ddi_wrpll_get_dpll(state, crtc);
@@ -1074,18 +1074,16 @@ static bool hsw_get_dpll(struct intel_atomic_state *state,
pll = hsw_ddi_lcpll_get_dpll(crtc_state);
else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
pll = hsw_ddi_spll_get_dpll(state, crtc);
- else
- return false;
if (!pll)
- return false;
+ return -EINVAL;
intel_reference_shared_dpll(state, crtc,
pll, &crtc_state->dpll_hw_state);
crtc_state->shared_dpll = pll;
- return true;
+ return 0;
}
static void hsw_update_dpll_ref_clks(struct drm_i915_private *i915)
@@ -1330,13 +1328,6 @@ struct skl_wrpll_context {
unsigned int p; /* chosen divider */
};
-static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
-{
- memset(ctx, 0, sizeof(*ctx));
-
- ctx->min_deviation = U64_MAX;
-}
-
/* DCO freq must be within +1%/-6% of the DCO central freq */
#define SKL_DCO_MAX_PDEVIATION 100
#define SKL_DCO_MAX_NDEVIATION 600
@@ -1497,33 +1488,33 @@ static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
params->dco_integer * MHz(1)) * 0x8000, MHz(1));
}
-static bool
+static int
skl_ddi_calculate_wrpll(int clock /* in Hz */,
int ref_clock,
struct skl_wrpll_params *wrpll_params)
{
- u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
- u64 dco_central_freq[3] = { 8400000000ULL,
- 9000000000ULL,
- 9600000000ULL };
- static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
- 24, 28, 30, 32, 36, 40, 42, 44,
- 48, 52, 54, 56, 60, 64, 66, 68,
- 70, 72, 76, 78, 80, 84, 88, 90,
- 92, 96, 98 };
- static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
+ static const u64 dco_central_freq[3] = { 8400000000ULL,
+ 9000000000ULL,
+ 9600000000ULL };
+ static const u8 even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
+ 24, 28, 30, 32, 36, 40, 42, 44,
+ 48, 52, 54, 56, 60, 64, 66, 68,
+ 70, 72, 76, 78, 80, 84, 88, 90,
+ 92, 96, 98 };
+ static const u8 odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
static const struct {
- const int *list;
+ const u8 *list;
int n_dividers;
} dividers[] = {
{ even_dividers, ARRAY_SIZE(even_dividers) },
{ odd_dividers, ARRAY_SIZE(odd_dividers) },
};
- struct skl_wrpll_context ctx;
+ struct skl_wrpll_context ctx = {
+ .min_deviation = U64_MAX,
+ };
unsigned int dco, d, i;
unsigned int p0, p1, p2;
-
- skl_wrpll_context_init(&ctx);
+ u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
for (d = 0; d < ARRAY_SIZE(dividers); d++) {
for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
@@ -1556,7 +1547,7 @@ skip_remaining_dividers:
if (!ctx.p) {
DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
- return false;
+ return -EINVAL;
}
/*
@@ -1568,14 +1559,15 @@ skip_remaining_dividers:
skl_wrpll_params_populate(wrpll_params, afe_clock, ref_clock,
ctx.central_freq, p0, p1, p2);
- return true;
+ return 0;
}
-static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
+static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct skl_wrpll_params wrpll_params = {};
u32 ctrl1, cfgcr1, cfgcr2;
- struct skl_wrpll_params wrpll_params = { 0, };
+ int ret;
/*
* See comment in intel_dpll_hw_state to understand why we always use 0
@@ -1585,10 +1577,10 @@ static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
- if (!skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
- i915->dpll.ref_clks.nssc,
- &wrpll_params))
- return false;
+ ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
+ i915->dpll.ref_clks.nssc, &wrpll_params);
+ if (ret)
+ return ret;
cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
@@ -1600,13 +1592,11 @@ static bool skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
wrpll_params.central_freq;
- memset(&crtc_state->dpll_hw_state, 0,
- sizeof(crtc_state->dpll_hw_state));
-
crtc_state->dpll_hw_state.ctrl1 = ctrl1;
crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
- return true;
+
+ return 0;
}
static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
@@ -1680,7 +1670,7 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
return dco_freq / (p0 * p1 * p2 * 5);
}
-static bool
+static int
skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
{
u32 ctrl1;
@@ -1712,12 +1702,9 @@ skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
break;
}
- memset(&crtc_state->dpll_hw_state, 0,
- sizeof(crtc_state->dpll_hw_state));
-
crtc_state->dpll_hw_state.ctrl1 = ctrl1;
- return true;
+ return 0;
}
static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
@@ -1754,33 +1741,23 @@ static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
return link_clock * 2;
}
-static bool skl_get_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int skl_get_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- struct drm_i915_private *i915 = to_i915(crtc->base.dev);
struct intel_shared_dpll *pll;
- bool bret;
-
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
- bret = skl_ddi_hdmi_pll_dividers(crtc_state);
- if (!bret) {
- drm_dbg_kms(&i915->drm,
- "Could not get HDMI pll dividers.\n");
- return false;
- }
- } else if (intel_crtc_has_dp_encoder(crtc_state)) {
- bret = skl_ddi_dp_set_dpll_hw_state(crtc_state);
- if (!bret) {
- drm_dbg_kms(&i915->drm,
- "Could not set DP dpll HW state.\n");
- return false;
- }
- } else {
- return false;
- }
+ int ret;
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ ret = skl_ddi_hdmi_pll_dividers(crtc_state);
+ else if (intel_crtc_has_dp_encoder(crtc_state))
+ ret = skl_ddi_dp_set_dpll_hw_state(crtc_state);
+ else
+ ret = -EINVAL;
+ if (ret)
+ return ret;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
pll = intel_find_shared_dpll(state, crtc,
@@ -1793,14 +1770,14 @@ static bool skl_get_dpll(struct intel_atomic_state *state,
BIT(DPLL_ID_SKL_DPLL2) |
BIT(DPLL_ID_SKL_DPLL1));
if (!pll)
- return false;
+ return -EINVAL;
intel_reference_shared_dpll(state, crtc,
pll, &crtc_state->dpll_hw_state);
crtc_state->shared_dpll = pll;
- return true;
+ return 0;
}
static int skl_ddi_pll_get_freq(struct drm_i915_private *i915,
@@ -1902,7 +1879,7 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
/* Write M2 integer */
temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 0));
- temp &= ~PORT_PLL_M2_MASK;
+ temp &= ~PORT_PLL_M2_INT_MASK;
temp |= pll->state.hw_state.pll0;
intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 0), temp);
@@ -2038,7 +2015,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
hw_state->pll0 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 0));
- hw_state->pll0 &= PORT_PLL_M2_MASK;
+ hw_state->pll0 &= PORT_PLL_M2_INT_MASK;
hw_state->pll1 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 1));
hw_state->pll1 &= PORT_PLL_N_MASK;
@@ -2087,82 +2064,64 @@ out:
return ret;
}
-/* bxt clock parameters */
-struct bxt_clk_div {
- int clock;
- u32 p1;
- u32 p2;
- u32 m2_int;
- u32 m2_frac;
- bool m2_frac_en;
- u32 n;
-
- int vco;
-};
-
/* pre-calculated values for DP linkrates */
-static const struct bxt_clk_div bxt_dp_clk_val[] = {
- {162000, 4, 2, 32, 1677722, 1, 1},
- {270000, 4, 1, 27, 0, 0, 1},
- {540000, 2, 1, 27, 0, 0, 1},
- {216000, 3, 2, 32, 1677722, 1, 1},
- {243000, 4, 1, 24, 1258291, 1, 1},
- {324000, 4, 1, 32, 1677722, 1, 1},
- {432000, 3, 1, 32, 1677722, 1, 1}
+static const struct dpll bxt_dp_clk_val[] = {
+ /* m2 is .22 binary fixed point */
+ { .dot = 162000, .p1 = 4, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
+ { .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
+ { .dot = 540000, .p1 = 2, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
+ { .dot = 216000, .p1 = 3, .p2 = 2, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
+ { .dot = 243000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6133333 /* 24.3 */ },
+ { .dot = 324000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
+ { .dot = 432000, .p1 = 3, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x819999a /* 32.4 */ },
};
-static bool
+static int
bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
- struct bxt_clk_div *clk_div)
+ struct dpll *clk_div)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct dpll best_clock;
/* Calculate HDMI div */
/*
* FIXME: tie the following calculation into
* i9xx_crtc_compute_clock
*/
- if (!bxt_find_best_dpll(crtc_state, &best_clock)) {
+ if (!bxt_find_best_dpll(crtc_state, clk_div)) {
drm_dbg(&i915->drm, "no PLL dividers found for clock %d pipe %c\n",
crtc_state->port_clock,
pipe_name(crtc->pipe));
- return false;
+ return -EINVAL;
}
- clk_div->p1 = best_clock.p1;
- clk_div->p2 = best_clock.p2;
- drm_WARN_ON(&i915->drm, best_clock.m1 != 2);
- clk_div->n = best_clock.n;
- clk_div->m2_int = best_clock.m2 >> 22;
- clk_div->m2_frac = best_clock.m2 & ((1 << 22) - 1);
- clk_div->m2_frac_en = clk_div->m2_frac != 0;
+ drm_WARN_ON(&i915->drm, clk_div->m1 != 2);
- clk_div->vco = best_clock.vco;
-
- return true;
+ return 0;
}
static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state,
- struct bxt_clk_div *clk_div)
+ struct dpll *clk_div)
{
- int clock = crtc_state->port_clock;
+ struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
int i;
*clk_div = bxt_dp_clk_val[0];
for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
- if (bxt_dp_clk_val[i].clock == clock) {
+ if (crtc_state->port_clock == bxt_dp_clk_val[i].dot) {
*clk_div = bxt_dp_clk_val[i];
break;
}
}
- clk_div->vco = clock * 10 / 2 * clk_div->p1 * clk_div->p2;
+ chv_calc_dpll_params(i915->dpll.ref_clks.nssc, clk_div);
+
+ drm_WARN_ON(&i915->drm, clk_div->vco == 0 ||
+ clk_div->dot != crtc_state->port_clock);
}
-static bool bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
- const struct bxt_clk_div *clk_div)
+static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
+ const struct dpll *clk_div)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
struct intel_dpll_hw_state *dpll_hw_state = &crtc_state->dpll_hw_state;
@@ -2171,8 +2130,6 @@ static bool bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
u32 prop_coef, int_coef, gain_ctl, targ_cnt;
u32 lanestagger;
- memset(dpll_hw_state, 0, sizeof(*dpll_hw_state));
-
if (vco >= 6200000 && vco <= 6700000) {
prop_coef = 4;
int_coef = 9;
@@ -2191,7 +2148,7 @@ static bool bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
targ_cnt = 9;
} else {
drm_err(&i915->drm, "Invalid VCO\n");
- return false;
+ return -EINVAL;
}
if (clock > 270000)
@@ -2206,45 +2163,45 @@ static bool bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
lanestagger = 0x02;
dpll_hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
- dpll_hw_state->pll0 = clk_div->m2_int;
+ dpll_hw_state->pll0 = PORT_PLL_M2_INT(clk_div->m2 >> 22);
dpll_hw_state->pll1 = PORT_PLL_N(clk_div->n);
- dpll_hw_state->pll2 = clk_div->m2_frac;
+ dpll_hw_state->pll2 = PORT_PLL_M2_FRAC(clk_div->m2 & 0x3fffff);
- if (clk_div->m2_frac_en)
+ if (clk_div->m2 & 0x3fffff)
dpll_hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
- dpll_hw_state->pll6 = prop_coef | PORT_PLL_INT_COEFF(int_coef);
- dpll_hw_state->pll6 |= PORT_PLL_GAIN_CTL(gain_ctl);
+ dpll_hw_state->pll6 = PORT_PLL_PROP_COEFF(prop_coef) |
+ PORT_PLL_INT_COEFF(int_coef) |
+ PORT_PLL_GAIN_CTL(gain_ctl);
- dpll_hw_state->pll8 = targ_cnt;
+ dpll_hw_state->pll8 = PORT_PLL_TARGET_CNT(targ_cnt);
- dpll_hw_state->pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
+ dpll_hw_state->pll9 = PORT_PLL_LOCK_THRESHOLD(5);
- dpll_hw_state->pll10 =
- PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
- | PORT_PLL_DCO_AMP_OVR_EN_H;
+ dpll_hw_state->pll10 = PORT_PLL_DCO_AMP(15) |
+ PORT_PLL_DCO_AMP_OVR_EN_H;
dpll_hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
dpll_hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
- return true;
+ return 0;
}
-static bool
+static int
bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
{
- struct bxt_clk_div clk_div = {};
+ struct dpll clk_div = {};
bxt_ddi_dp_pll_dividers(crtc_state, &clk_div);
return bxt_ddi_set_dpll_hw_state(crtc_state, &clk_div);
}
-static bool
+static int
bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
{
- struct bxt_clk_div clk_div = {};
+ struct dpll clk_div = {};
bxt_ddi_hdmi_pll_dividers(crtc_state, &clk_div);
@@ -2258,33 +2215,35 @@ static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915,
struct dpll clock;
clock.m1 = 2;
- clock.m2 = (pll_state->pll0 & PORT_PLL_M2_MASK) << 22;
+ clock.m2 = REG_FIELD_GET(PORT_PLL_M2_INT_MASK, pll_state->pll0) << 22;
if (pll_state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
- clock.m2 |= pll_state->pll2 & PORT_PLL_M2_FRAC_MASK;
- clock.n = (pll_state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
- clock.p1 = (pll_state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
- clock.p2 = (pll_state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
+ clock.m2 |= REG_FIELD_GET(PORT_PLL_M2_FRAC_MASK, pll_state->pll2);
+ clock.n = REG_FIELD_GET(PORT_PLL_N_MASK, pll_state->pll1);
+ clock.p1 = REG_FIELD_GET(PORT_PLL_P1_MASK, pll_state->ebb0);
+ clock.p2 = REG_FIELD_GET(PORT_PLL_P2_MASK, pll_state->ebb0);
return chv_calc_dpll_params(i915->dpll.ref_clks.nssc, &clock);
}
-static bool bxt_get_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int bxt_get_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_shared_dpll *pll;
enum intel_dpll_id id;
+ int ret;
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
- !bxt_ddi_hdmi_set_dpll_hw_state(crtc_state))
- return false;
-
- if (intel_crtc_has_dp_encoder(crtc_state) &&
- !bxt_ddi_dp_set_dpll_hw_state(crtc_state))
- return false;
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ ret = bxt_ddi_hdmi_set_dpll_hw_state(crtc_state);
+ else if (intel_crtc_has_dp_encoder(crtc_state))
+ ret = bxt_ddi_dp_set_dpll_hw_state(crtc_state);
+ else
+ ret = -EINVAL;
+ if (ret)
+ return ret;
/* 1:1 mapping between ports and PLLs */
id = (enum intel_dpll_id) encoder->port;
@@ -2298,7 +2257,7 @@ static bool bxt_get_dpll(struct intel_atomic_state *state,
crtc_state->shared_dpll = pll;
- return true;
+ return 0;
}
static void bxt_update_dpll_ref_clks(struct drm_i915_private *i915)
@@ -2535,8 +2494,8 @@ static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = {
/* the following params are unused */
};
-static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
- struct skl_wrpll_params *pll_params)
+static int icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
+ struct skl_wrpll_params *pll_params)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
const struct icl_combo_pll_params *params =
@@ -2549,16 +2508,16 @@ static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
for (i = 0; i < ARRAY_SIZE(icl_dp_combo_pll_24MHz_values); i++) {
if (clock == params[i].clock) {
*pll_params = params[i].wrpll;
- return true;
+ return 0;
}
}
MISSING_CASE(clock);
- return false;
+ return -EINVAL;
}
-static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
- struct skl_wrpll_params *pll_params)
+static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
+ struct skl_wrpll_params *pll_params)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
@@ -2590,7 +2549,7 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
}
}
- return true;
+ return 0;
}
static int icl_ddi_tbt_pll_get_freq(struct drm_i915_private *i915,
@@ -2620,7 +2579,7 @@ static int icl_wrpll_ref_clock(struct drm_i915_private *i915)
return ref_clock;
}
-static bool
+static int
icl_calc_wrpll(struct intel_crtc_state *crtc_state,
struct skl_wrpll_params *wrpll_params)
{
@@ -2655,13 +2614,13 @@ icl_calc_wrpll(struct intel_crtc_state *crtc_state,
}
if (best_div == 0)
- return false;
+ return -EINVAL;
icl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
icl_wrpll_params_populate(wrpll_params, best_dco, ref_clock,
pdiv, qdiv, kdiv);
- return true;
+ return 0;
}
static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915,
@@ -2731,8 +2690,6 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
{
u32 dco_fraction = pll_params->dco_fraction;
- memset(pll_state, 0, sizeof(*pll_state));
-
if (ehl_combo_pll_div_frac_wa_needed(i915))
dco_fraction = DIV_ROUND_CLOSEST(dco_fraction, 2);
@@ -2753,13 +2710,13 @@ static void icl_calc_dpll_state(struct drm_i915_private *i915,
pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->vbt.override_afc_startup_val);
}
-static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
- u32 *target_dco_khz,
- struct intel_dpll_hw_state *state,
- bool is_dkl)
+static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
+ u32 *target_dco_khz,
+ struct intel_dpll_hw_state *state,
+ bool is_dkl)
{
+ static const u8 div1_vals[] = { 7, 5, 3, 2 };
u32 dco_min_freq, dco_max_freq;
- int div1_vals[] = {7, 5, 3, 2};
unsigned int i;
int div2;
@@ -2822,19 +2779,19 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
hsdiv |
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO(div2);
- return true;
+ return 0;
}
}
- return false;
+ return -EINVAL;
}
/*
* The specification for this function uses real numbers, so the math had to be
* adapted to integer-only calculation, that's why it looks so different.
*/
-static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
- struct intel_dpll_hw_state *pll_state)
+static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
+ struct intel_dpll_hw_state *pll_state)
{
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
int refclk_khz = dev_priv->dpll.ref_clks.nssc;
@@ -2848,14 +2805,14 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
bool use_ssc = false;
bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
bool is_dkl = DISPLAY_VER(dev_priv) >= 12;
+ int ret;
- memset(pll_state, 0, sizeof(*pll_state));
-
- if (!icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
- pll_state, is_dkl)) {
+ ret = icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
+ pll_state, is_dkl);
+ if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Failed to find divisors for clock %d\n", clock);
- return false;
+ return ret;
}
m1div = 2;
@@ -2870,7 +2827,7 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
drm_dbg_kms(&dev_priv->drm,
"Failed to find mdiv for clock %d\n",
clock);
- return false;
+ return -EINVAL;
}
}
m2div_rem = dco_khz % (refclk_khz * m1div);
@@ -2897,7 +2854,7 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
break;
default:
MISSING_CASE(refclk_khz);
- return false;
+ return -EINVAL;
}
/*
@@ -3040,7 +2997,7 @@ static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
pll_state->mg_pll_bias &= pll_state->mg_pll_bias_mask;
}
- return true;
+ return 0;
}
static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *dev_priv,
@@ -3162,9 +3119,9 @@ static u32 intel_get_hti_plls(struct drm_i915_private *i915)
return REG_FIELD_GET(HDPORT_DPLL_USED_MASK, i915->hti_state);
}
-static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
@@ -3182,11 +3139,10 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
else
ret = icl_calc_dp_combo_pll(crtc_state, &pll_params);
- if (!ret) {
+ if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Could not calculate combo PHY PLL state.\n");
-
- return false;
+ return ret;
}
icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
@@ -3231,7 +3187,7 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
drm_dbg_kms(&dev_priv->drm,
"No combo PHY PLL found for [ENCODER:%d:%s]\n",
encoder->base.base.id, encoder->base.name);
- return false;
+ return -EINVAL;
}
intel_reference_shared_dpll(state, crtc,
@@ -3239,12 +3195,12 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
icl_update_active_dpll(state, crtc, encoder);
- return true;
+ return 0;
}
-static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int icl_get_tc_phy_dplls(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
@@ -3252,12 +3208,14 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
struct skl_wrpll_params pll_params = { };
struct icl_port_dpll *port_dpll;
enum intel_dpll_id dpll_id;
+ int ret;
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
- if (!icl_calc_tbt_pll(crtc_state, &pll_params)) {
+ ret = icl_calc_tbt_pll(crtc_state, &pll_params);
+ if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Could not calculate TBT PLL state.\n");
- return false;
+ return ret;
}
icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
@@ -3267,14 +3225,15 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
BIT(DPLL_ID_ICL_TBTPLL));
if (!port_dpll->pll) {
drm_dbg_kms(&dev_priv->drm, "No TBT-ALT PLL found\n");
- return false;
+ return -EINVAL;
}
intel_reference_shared_dpll(state, crtc,
port_dpll->pll, &port_dpll->hw_state);
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
- if (!icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state)) {
+ ret = icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state);
+ if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Could not calculate MG PHY PLL state.\n");
goto err_unreference_tbt_pll;
@@ -3286,6 +3245,7 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
&port_dpll->hw_state,
BIT(dpll_id));
if (!port_dpll->pll) {
+ ret = -EINVAL;
drm_dbg_kms(&dev_priv->drm, "No MG PHY PLL found\n");
goto err_unreference_tbt_pll;
}
@@ -3294,18 +3254,18 @@ static bool icl_get_tc_phy_dplls(struct intel_atomic_state *state,
icl_update_active_dpll(state, crtc, encoder);
- return true;
+ return 0;
err_unreference_tbt_pll:
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
intel_unreference_shared_dpll(state, crtc, port_dpll->pll);
- return false;
+ return ret;
}
-static bool icl_get_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+static int icl_get_dplls(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
@@ -3317,7 +3277,7 @@ static bool icl_get_dplls(struct intel_atomic_state *state,
MISSING_CASE(phy);
- return false;
+ return -EINVAL;
}
static void icl_put_dplls(struct intel_atomic_state *state,
@@ -4103,13 +4063,12 @@ static const struct intel_dpll_mgr adlp_pll_mgr = {
/**
* intel_shared_dpll_init - Initialize shared DPLLs
- * @dev: drm device
+ * @dev_priv: i915 device
*
- * Initialize shared DPLLs for @dev.
+ * Initialize shared DPLLs for @dev_priv.
*/
-void intel_shared_dpll_init(struct drm_device *dev)
+void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
const struct intel_dpll_mgr *dpll_mgr = NULL;
const struct dpll_info *dpll_info;
int i;
@@ -4148,7 +4107,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
dpll_info = dpll_mgr->dpll_info;
for (i = 0; dpll_info[i].name; i++) {
- drm_WARN_ON(dev, i != dpll_info[i].id);
+ drm_WARN_ON(&dev_priv->drm, i != dpll_info[i].id);
dev_priv->dpll.shared_dplls[i].info = &dpll_info[i];
}
@@ -4176,17 +4135,18 @@ void intel_shared_dpll_init(struct drm_device *dev)
* intel_release_shared_dplls().
*
* Returns:
- * True if all required DPLLs were successfully reserved.
+ * 0 if all required DPLLs were successfully reserved,
+ * negative error code otherwise.
*/
-bool intel_reserve_shared_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+int intel_reserve_shared_dplls(struct intel_atomic_state *state,
+ struct intel_crtc *crtc,
+ struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll.mgr;
if (drm_WARN_ON(&dev_priv->drm, !dpll_mgr))
- return false;
+ return -EINVAL;
return dpll_mgr->get_dplls(state, crtc, encoder);
}