summaryrefslogtreecommitdiff
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.c2645
1 files changed, 1406 insertions, 1239 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 64dd603dc69a..9c7cf03cf022 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -21,17 +21,27 @@
* DEALINGS IN THE SOFTWARE.
*/
+#include <linux/math.h>
#include <linux/string_helpers.h>
+#include <drm/drm_print.h>
+
+#include "bxt_dpio_phy_regs.h"
+#include "intel_cx0_phy.h"
#include "intel_de.h"
+#include "intel_display_regs.h"
#include "intel_display_types.h"
+#include "intel_display_utils.h"
#include "intel_dkl_phy.h"
+#include "intel_dkl_phy_regs.h"
#include "intel_dpio_phy.h"
#include "intel_dpll.h"
#include "intel_dpll_mgr.h"
+#include "intel_hti.h"
+#include "intel_mg_phy_regs.h"
#include "intel_pch_refclk.h"
+#include "intel_step.h"
#include "intel_tc.h"
-#include "intel_tc_phy_regs.h"
/**
* DOC: Display PLLs
@@ -42,50 +52,51 @@
* share a PLL if their configurations match.
*
* This file provides an abstraction over display PLLs. The function
- * intel_shared_dpll_init() initializes the PLLs for the given platform. The
+ * intel_dpll_init() initializes the PLLs for the given platform. The
* users of a PLL are tracked and that tracking is integrated with the atomic
* modset interface. During an atomic operation, required PLLs can be reserved
* for a given CRTC and encoder configuration by calling
- * intel_reserve_shared_dplls() and previously reserved PLLs can be released
- * with intel_release_shared_dplls().
+ * intel_dpll_reserve() and previously reserved PLLs can be released
+ * with intel_dpll_release().
* Changes to the users are first staged in the atomic state, and then made
- * effective by calling intel_shared_dpll_swap_state() during the atomic
+ * effective by calling intel_dpll_swap_state() during the atomic
* commit phase.
*/
/* platform specific hooks for managing DPLLs */
-struct intel_shared_dpll_funcs {
+struct intel_dpll_funcs {
/*
- * Hook for enabling the pll, called from intel_enable_shared_dpll() if
+ * Hook for enabling the pll, called from intel_enable_dpll() if
* the pll is not already enabled.
*/
- void (*enable)(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll);
+ void (*enable)(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state);
/*
- * Hook for disabling the pll, called from intel_disable_shared_dpll()
+ * Hook for disabling the pll, called from intel_disable_dpll()
* only when it is safe to disable the pll, i.e., there are no more
* tracked users for it.
*/
- void (*disable)(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll);
+ void (*disable)(struct intel_display *display,
+ struct intel_dpll *pll);
/*
* Hook for reading the values currently programmed to the DPLL
* registers. This is used for initial hw state readout and state
* verification after a mode set.
*/
- bool (*get_hw_state)(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state);
+ bool (*get_hw_state)(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state);
/*
* Hook for calculating the pll's output frequency based on its passed
* in state.
*/
- int (*get_freq)(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state);
+ int (*get_freq)(struct intel_display *i915,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state);
};
struct intel_dpll_mgr {
@@ -102,96 +113,84 @@ struct intel_dpll_mgr {
void (*update_active_dpll)(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder);
- void (*update_ref_clks)(struct drm_i915_private *i915);
- void (*dump_hw_state)(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state);
+ void (*update_ref_clks)(struct intel_display *display);
+ void (*dump_hw_state)(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state);
+ bool (*compare_hw_state)(const struct intel_dpll_hw_state *a,
+ const struct intel_dpll_hw_state *b);
};
static void
-intel_atomic_duplicate_dpll_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll_state *shared_dpll)
+intel_atomic_duplicate_dpll_state(struct intel_display *display,
+ struct intel_dpll_state *dpll_state)
{
- enum intel_dpll_id i;
-
- /* Copy shared dpll state */
- for (i = 0; i < dev_priv->display.dpll.num_shared_dpll; i++) {
- struct intel_shared_dpll *pll = &dev_priv->display.dpll.shared_dplls[i];
+ struct intel_dpll *pll;
+ int i;
- shared_dpll[i] = pll->state;
- }
+ /* Copy dpll state */
+ for_each_dpll(display, pll, i)
+ dpll_state[pll->index] = pll->state;
}
-static struct intel_shared_dpll_state *
-intel_atomic_get_shared_dpll_state(struct drm_atomic_state *s)
+static struct intel_dpll_state *
+intel_atomic_get_dpll_state(struct drm_atomic_state *s)
{
struct intel_atomic_state *state = to_intel_atomic_state(s);
+ struct intel_display *display = to_intel_display(state);
drm_WARN_ON(s->dev, !drm_modeset_is_locked(&s->dev->mode_config.connection_mutex));
if (!state->dpll_set) {
state->dpll_set = true;
- intel_atomic_duplicate_dpll_state(to_i915(s->dev),
- state->shared_dpll);
+ intel_atomic_duplicate_dpll_state(display,
+ state->dpll_state);
}
- return state->shared_dpll;
+ return state->dpll_state;
}
/**
- * intel_get_shared_dpll_by_id - get a DPLL given its id
- * @dev_priv: i915 device instance
+ * intel_get_dpll_by_id - get a DPLL given its id
+ * @display: intel_display device instance
* @id: pll id
*
* Returns:
* A pointer to the DPLL with @id
*/
-struct intel_shared_dpll *
-intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
- enum intel_dpll_id id)
+struct intel_dpll *
+intel_get_dpll_by_id(struct intel_display *display,
+ enum intel_dpll_id id)
{
- return &dev_priv->display.dpll.shared_dplls[id];
-}
-
-/**
- * intel_get_shared_dpll_id - get the id of a DPLL
- * @dev_priv: i915 device instance
- * @pll: the DPLL
- *
- * Returns:
- * The id of @pll
- */
-enum intel_dpll_id
-intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
-{
- long pll_idx = pll - dev_priv->display.dpll.shared_dplls;
+ struct intel_dpll *pll;
+ int i;
- if (drm_WARN_ON(&dev_priv->drm,
- pll_idx < 0 ||
- pll_idx >= dev_priv->display.dpll.num_shared_dpll))
- return -1;
+ for_each_dpll(display, pll, i) {
+ if (pll->info->id == id)
+ return pll;
+ }
- return pll_idx;
+ MISSING_CASE(id);
+ return NULL;
}
/* For ILK+ */
-void assert_shared_dpll(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- bool state)
+void assert_dpll(struct intel_display *display,
+ struct intel_dpll *pll,
+ bool state)
{
bool cur_state;
struct intel_dpll_hw_state hw_state;
- if (drm_WARN(&dev_priv->drm, !pll,
+ if (drm_WARN(display->drm, !pll,
"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, str_on_off(state),
- str_on_off(cur_state));
+ cur_state = intel_dpll_get_hw_state(display, pll, &hw_state);
+ INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
+ "%s assertion failure (expected %s, current %s)\n",
+ 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)
@@ -205,155 +204,197 @@ enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port)
}
static i915_reg_t
-intel_combo_pll_enable_reg(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll)
+intel_combo_pll_enable_reg(struct intel_display *display,
+ struct intel_dpll *pll)
{
- if (IS_DG1(i915))
+ if (display->platform.dg1)
return DG1_DPLL_ENABLE(pll->info->id);
- else if (IS_JSL_EHL(i915) && (pll->info->id == DPLL_ID_EHL_DPLL4))
+ else if ((display->platform.jasperlake || display->platform.elkhartlake) &&
+ (pll->info->id == DPLL_ID_EHL_DPLL4))
return MG_PLL_ENABLE(0);
return ICL_DPLL_ENABLE(pll->info->id);
}
static i915_reg_t
-intel_tc_pll_enable_reg(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll)
+intel_tc_pll_enable_reg(struct intel_display *display,
+ struct intel_dpll *pll)
{
const enum intel_dpll_id id = pll->info->id;
enum tc_port tc_port = icl_pll_id_to_tc_port(id);
- if (IS_ALDERLAKE_P(i915))
+ if (display->platform.alderlake_p)
return ADLP_PORTTC_PLL_ENABLE(tc_port);
return MG_PLL_ENABLE(tc_port);
}
+static void _intel_enable_shared_dpll(struct intel_display *display,
+ struct intel_dpll *pll)
+{
+ if (pll->info->power_domain)
+ pll->wakeref = intel_display_power_get(display, pll->info->power_domain);
+
+ pll->info->funcs->enable(display, pll, &pll->state.hw_state);
+ pll->on = true;
+}
+
+static void _intel_disable_shared_dpll(struct intel_display *display,
+ struct intel_dpll *pll)
+{
+ pll->info->funcs->disable(display, pll);
+ pll->on = false;
+
+ if (pll->info->power_domain)
+ intel_display_power_put(display, pll->info->power_domain, pll->wakeref);
+}
+
/**
- * intel_enable_shared_dpll - enable a CRTC's shared DPLL
- * @crtc_state: CRTC, and its state, which has a shared DPLL
+ * intel_dpll_enable - enable a CRTC's DPLL
+ * @crtc_state: CRTC, and its state, which has a DPLL
*
- * Enable the shared DPLL used by @crtc.
+ * Enable DPLL used by @crtc.
*/
-void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
+void intel_dpll_enable(const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_shared_dpll *pll = crtc_state->shared_dpll;
- unsigned int pipe_mask = BIT(crtc->pipe);
+ struct intel_dpll *pll = crtc_state->intel_dpll;
+ unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state);
unsigned int old_mask;
- if (drm_WARN_ON(&dev_priv->drm, pll == NULL))
+ if (drm_WARN_ON(display->drm, !pll))
return;
- mutex_lock(&dev_priv->display.dpll.lock);
+ mutex_lock(&display->dpll.lock);
old_mask = pll->active_mask;
- if (drm_WARN_ON(&dev_priv->drm, !(pll->state.pipe_mask & pipe_mask)) ||
- drm_WARN_ON(&dev_priv->drm, pll->active_mask & pipe_mask))
+ if (drm_WARN_ON(display->drm, !(pll->state.pipe_mask & pipe_mask)) ||
+ drm_WARN_ON(display->drm, pll->active_mask & pipe_mask))
goto out;
pll->active_mask |= pipe_mask;
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"enable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n",
pll->info->name, pll->active_mask, pll->on,
crtc->base.base.id, crtc->base.name);
if (old_mask) {
- drm_WARN_ON(&dev_priv->drm, !pll->on);
- assert_shared_dpll_enabled(dev_priv, pll);
+ drm_WARN_ON(display->drm, !pll->on);
+ assert_dpll_enabled(display, pll);
goto out;
}
- drm_WARN_ON(&dev_priv->drm, pll->on);
+ drm_WARN_ON(display->drm, pll->on);
- drm_dbg_kms(&dev_priv->drm, "enabling %s\n", pll->info->name);
- pll->info->funcs->enable(dev_priv, pll);
- pll->on = true;
+ drm_dbg_kms(display->drm, "enabling %s\n", pll->info->name);
+
+ _intel_enable_shared_dpll(display, pll);
out:
- mutex_unlock(&dev_priv->display.dpll.lock);
+ mutex_unlock(&display->dpll.lock);
}
/**
- * intel_disable_shared_dpll - disable a CRTC's shared DPLL
+ * intel_dpll_disable - disable a CRTC's shared DPLL
* @crtc_state: CRTC, and its state, which has a shared DPLL
*
- * Disable the shared DPLL used by @crtc.
+ * Disable DPLL used by @crtc.
*/
-void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state)
+void intel_dpll_disable(const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_shared_dpll *pll = crtc_state->shared_dpll;
- unsigned int pipe_mask = BIT(crtc->pipe);
+ struct intel_dpll *pll = crtc_state->intel_dpll;
+ unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state);
/* PCH only available on ILK+ */
- if (DISPLAY_VER(dev_priv) < 5)
+ if (DISPLAY_VER(display) < 5)
return;
if (pll == NULL)
return;
- mutex_lock(&dev_priv->display.dpll.lock);
- if (drm_WARN(&dev_priv->drm, !(pll->active_mask & pipe_mask),
+ mutex_lock(&display->dpll.lock);
+ if (drm_WARN(display->drm, !(pll->active_mask & pipe_mask),
"%s not used by [CRTC:%d:%s]\n", pll->info->name,
crtc->base.base.id, crtc->base.name))
goto out;
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"disable %s (active 0x%x, on? %d) for [CRTC:%d:%s]\n",
pll->info->name, pll->active_mask, pll->on,
crtc->base.base.id, crtc->base.name);
- assert_shared_dpll_enabled(dev_priv, pll);
- drm_WARN_ON(&dev_priv->drm, !pll->on);
+ assert_dpll_enabled(display, pll);
+ drm_WARN_ON(display->drm, !pll->on);
pll->active_mask &= ~pipe_mask;
if (pll->active_mask)
goto out;
- drm_dbg_kms(&dev_priv->drm, "disabling %s\n", pll->info->name);
- pll->info->funcs->disable(dev_priv, pll);
- pll->on = false;
+ drm_dbg_kms(display->drm, "disabling %s\n", pll->info->name);
+
+ _intel_disable_shared_dpll(display, pll);
out:
- mutex_unlock(&dev_priv->display.dpll.lock);
+ mutex_unlock(&display->dpll.lock);
}
-static struct intel_shared_dpll *
-intel_find_shared_dpll(struct intel_atomic_state *state,
- const struct intel_crtc *crtc,
- const struct intel_dpll_hw_state *pll_state,
- unsigned long dpll_mask)
+static unsigned long
+intel_dpll_mask_all(struct intel_display *display)
{
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
- struct intel_shared_dpll *pll, *unused_pll = NULL;
- struct intel_shared_dpll_state *shared_dpll;
- enum intel_dpll_id i;
+ struct intel_dpll *pll;
+ unsigned long dpll_mask = 0;
+ int i;
+
+ for_each_dpll(display, pll, i) {
+ drm_WARN_ON(display->drm, dpll_mask & BIT(pll->info->id));
- shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
+ dpll_mask |= BIT(pll->info->id);
+ }
+
+ return dpll_mask;
+}
+
+static struct intel_dpll *
+intel_find_dpll(struct intel_atomic_state *state,
+ const struct intel_crtc *crtc,
+ const struct intel_dpll_hw_state *dpll_hw_state,
+ unsigned long dpll_mask)
+{
+ struct intel_display *display = to_intel_display(crtc);
+ unsigned long dpll_mask_all = intel_dpll_mask_all(display);
+ struct intel_dpll_state *dpll_state;
+ struct intel_dpll *unused_pll = NULL;
+ enum intel_dpll_id id;
- drm_WARN_ON(&dev_priv->drm, dpll_mask & ~(BIT(I915_NUM_PLLS) - 1));
+ dpll_state = intel_atomic_get_dpll_state(&state->base);
- for_each_set_bit(i, &dpll_mask, I915_NUM_PLLS) {
- pll = &dev_priv->display.dpll.shared_dplls[i];
+ drm_WARN_ON(display->drm, dpll_mask & ~dpll_mask_all);
+
+ for_each_set_bit(id, &dpll_mask, fls(dpll_mask_all)) {
+ struct intel_dpll *pll;
+
+ pll = intel_get_dpll_by_id(display, id);
+ if (!pll)
+ continue;
/* Only want to check enabled timings first */
- if (shared_dpll[i].pipe_mask == 0) {
+ if (dpll_state[pll->index].pipe_mask == 0) {
if (!unused_pll)
unused_pll = pll;
continue;
}
- if (memcmp(pll_state,
- &shared_dpll[i].hw_state,
- sizeof(*pll_state)) == 0) {
- drm_dbg_kms(&dev_priv->drm,
+ if (memcmp(dpll_hw_state,
+ &dpll_state[pll->index].hw_state,
+ sizeof(*dpll_hw_state)) == 0) {
+ drm_dbg_kms(display->drm,
"[CRTC:%d:%s] sharing existing %s (pipe mask 0x%x, active 0x%x)\n",
crtc->base.base.id, crtc->base.name,
pll->info->name,
- shared_dpll[i].pipe_mask,
+ dpll_state[pll->index].pipe_mask,
pll->active_mask);
return pll;
}
@@ -361,7 +402,7 @@ intel_find_shared_dpll(struct intel_atomic_state *state,
/* Ok no matching timings, maybe there's a free one? */
if (unused_pll) {
- drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] allocated %s\n",
+ drm_dbg_kms(display->drm, "[CRTC:%d:%s] allocated %s\n",
crtc->base.base.id, crtc->base.name,
unused_pll->info->name);
return unused_pll;
@@ -370,35 +411,77 @@ intel_find_shared_dpll(struct intel_atomic_state *state,
return NULL;
}
+/**
+ * intel_dpll_crtc_get - Get a DPLL reference for a CRTC
+ * @crtc: CRTC on which behalf the reference is taken
+ * @pll: DPLL for which the reference is taken
+ * @dpll_state: the DPLL atomic state in which the reference is tracked
+ *
+ * Take a reference for @pll tracking the use of it by @crtc.
+ */
static void
-intel_reference_shared_dpll(struct intel_atomic_state *state,
- const struct intel_crtc *crtc,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+intel_dpll_crtc_get(const struct intel_crtc *crtc,
+ const struct intel_dpll *pll,
+ struct intel_dpll_state *dpll_state)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
- struct intel_shared_dpll_state *shared_dpll;
- const enum intel_dpll_id id = pll->info->id;
+ struct intel_display *display = to_intel_display(crtc);
+
+ drm_WARN_ON(display->drm, (dpll_state->pipe_mask & BIT(crtc->pipe)) != 0);
+
+ dpll_state->pipe_mask |= BIT(crtc->pipe);
+
+ drm_dbg_kms(display->drm, "[CRTC:%d:%s] reserving %s\n",
+ crtc->base.base.id, crtc->base.name, pll->info->name);
+}
- shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
+static void
+intel_reference_dpll(struct intel_atomic_state *state,
+ const struct intel_crtc *crtc,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ struct intel_dpll_state *dpll_state;
- if (shared_dpll[id].pipe_mask == 0)
- shared_dpll[id].hw_state = *pll_state;
+ dpll_state = intel_atomic_get_dpll_state(&state->base);
- drm_dbg(&i915->drm, "using %s for pipe %c\n", pll->info->name,
- pipe_name(crtc->pipe));
+ if (dpll_state[pll->index].pipe_mask == 0)
+ dpll_state[pll->index].hw_state = *dpll_hw_state;
- shared_dpll[id].pipe_mask |= BIT(crtc->pipe);
+ intel_dpll_crtc_get(crtc, pll, &dpll_state[pll->index]);
}
-static void intel_unreference_shared_dpll(struct intel_atomic_state *state,
- const struct intel_crtc *crtc,
- const struct intel_shared_dpll *pll)
+/**
+ * intel_dpll_crtc_put - Drop a DPLL reference for a CRTC
+ * @crtc: CRTC on which behalf the reference is dropped
+ * @pll: DPLL for which the reference is dropped
+ * @dpll_state: the DPLL atomic state in which the reference is tracked
+ *
+ * Drop a reference for @pll tracking the end of use of it by @crtc.
+ */
+void
+intel_dpll_crtc_put(const struct intel_crtc *crtc,
+ const struct intel_dpll *pll,
+ struct intel_dpll_state *dpll_state)
{
- struct intel_shared_dpll_state *shared_dpll;
+ struct intel_display *display = to_intel_display(crtc);
+
+ drm_WARN_ON(display->drm, (dpll_state->pipe_mask & BIT(crtc->pipe)) == 0);
+
+ dpll_state->pipe_mask &= ~BIT(crtc->pipe);
+
+ drm_dbg_kms(display->drm, "[CRTC:%d:%s] releasing %s\n",
+ crtc->base.base.id, crtc->base.name, pll->info->name);
+}
+
+static void intel_unreference_dpll(struct intel_atomic_state *state,
+ const struct intel_crtc *crtc,
+ const struct intel_dpll *pll)
+{
+ struct intel_dpll_state *dpll_state;
+
+ dpll_state = intel_atomic_get_dpll_state(&state->base);
- shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
- shared_dpll[pll->info->id].pipe_mask &= ~BIT(crtc->pipe);
+ intel_dpll_crtc_put(crtc, pll, &dpll_state[pll->index]);
}
static void intel_put_dpll(struct intel_atomic_state *state,
@@ -409,16 +492,16 @@ static void intel_put_dpll(struct intel_atomic_state *state,
struct intel_crtc_state *new_crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- new_crtc_state->shared_dpll = NULL;
+ new_crtc_state->intel_dpll = NULL;
- if (!old_crtc_state->shared_dpll)
+ if (!old_crtc_state->intel_dpll)
return;
- intel_unreference_shared_dpll(state, crtc, old_crtc_state->shared_dpll);
+ intel_unreference_dpll(state, crtc, old_crtc_state->intel_dpll);
}
/**
- * intel_shared_dpll_swap_state - make atomic DPLL configuration effective
+ * intel_dpll_swap_state - make atomic DPLL configuration effective
* @state: atomic state
*
* This is the dpll version of drm_atomic_helper_swap_state() since the
@@ -428,74 +511,73 @@ static void intel_put_dpll(struct intel_atomic_state *state,
* i.e. it also puts the current state into @state, even though there is no
* need for that at this moment.
*/
-void intel_shared_dpll_swap_state(struct intel_atomic_state *state)
+void intel_dpll_swap_state(struct intel_atomic_state *state)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
- struct intel_shared_dpll_state *shared_dpll = state->shared_dpll;
- enum intel_dpll_id i;
+ struct intel_display *display = to_intel_display(state);
+ struct intel_dpll_state *dpll_state = state->dpll_state;
+ struct intel_dpll *pll;
+ int i;
if (!state->dpll_set)
return;
- for (i = 0; i < dev_priv->display.dpll.num_shared_dpll; i++) {
- struct intel_shared_dpll *pll =
- &dev_priv->display.dpll.shared_dplls[i];
-
- swap(pll->state, shared_dpll[i]);
- }
+ for_each_dpll(display, pll, i)
+ swap(pll->state, dpll_state[pll->index]);
}
-static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool ibx_pch_dpll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
const enum intel_dpll_id id = pll->info->id;
intel_wakeref_t wakeref;
u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, PCH_DPLL(id));
+ val = intel_de_read(display, PCH_DPLL(id));
hw_state->dpll = val;
- hw_state->fp0 = intel_de_read(dev_priv, PCH_FP0(id));
- hw_state->fp1 = intel_de_read(dev_priv, PCH_FP1(id));
+ hw_state->fp0 = intel_de_read(display, PCH_FP0(id));
+ hw_state->fp1 = intel_de_read(display, PCH_FP1(id));
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return val & DPLL_VCO_ENABLE;
}
-static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
+static void ibx_assert_pch_refclk_enabled(struct intel_display *display)
{
u32 val;
bool enabled;
- I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
-
- val = intel_de_read(dev_priv, PCH_DREF_CONTROL);
+ val = intel_de_read(display, PCH_DREF_CONTROL);
enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
DREF_SUPERSPREAD_SOURCE_MASK));
- I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
+ INTEL_DISPLAY_STATE_WARN(display, !enabled,
+ "PCH refclk assertion failure, should be active but is disabled\n");
}
-static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void ibx_pch_dpll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
const enum intel_dpll_id id = pll->info->id;
/* PCH refclock must be enabled first */
- ibx_assert_pch_refclk_enabled(dev_priv);
+ ibx_assert_pch_refclk_enabled(display);
- intel_de_write(dev_priv, PCH_FP0(id), pll->state.hw_state.fp0);
- intel_de_write(dev_priv, PCH_FP1(id), pll->state.hw_state.fp1);
+ intel_de_write(display, PCH_FP0(id), hw_state->fp0);
+ intel_de_write(display, PCH_FP1(id), hw_state->fp1);
- intel_de_write(dev_priv, PCH_DPLL(id), pll->state.hw_state.dpll);
+ intel_de_write(display, PCH_DPLL(id), hw_state->dpll);
/* Wait for the clocks to stabilize. */
- intel_de_posting_read(dev_priv, PCH_DPLL(id));
+ intel_de_posting_read(display, PCH_DPLL(id));
udelay(150);
/* The pixel multiplier can only be updated once the
@@ -503,18 +585,18 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
*
* So write it again.
*/
- intel_de_write(dev_priv, PCH_DPLL(id), pll->state.hw_state.dpll);
- intel_de_posting_read(dev_priv, PCH_DPLL(id));
+ intel_de_write(display, PCH_DPLL(id), hw_state->dpll);
+ intel_de_posting_read(display, PCH_DPLL(id));
udelay(200);
}
-static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void ibx_pch_dpll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
const enum intel_dpll_id id = pll->info->id;
- intel_de_write(dev_priv, PCH_DPLL(id), 0);
- intel_de_posting_read(dev_priv, PCH_DPLL(id));
+ intel_de_write(display, PCH_DPLL(id), 0);
+ intel_de_posting_read(display, PCH_DPLL(id));
udelay(200);
}
@@ -529,62 +611,75 @@ static int ibx_get_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
{
+ struct intel_display *display = to_intel_display(state);
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 i;
+ struct intel_dpll *pll;
+ enum intel_dpll_id id;
- if (HAS_PCH_IBX(dev_priv)) {
+ if (HAS_PCH_IBX(display)) {
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
- i = (enum intel_dpll_id) crtc->pipe;
- pll = &dev_priv->display.dpll.shared_dplls[i];
+ id = (enum intel_dpll_id) crtc->pipe;
+ pll = intel_get_dpll_by_id(display, id);
- drm_dbg_kms(&dev_priv->drm,
+ drm_dbg_kms(display->drm,
"[CRTC:%d:%s] using pre-allocated %s\n",
crtc->base.base.id, crtc->base.name,
pll->info->name);
} else {
- pll = intel_find_shared_dpll(state, crtc,
- &crtc_state->dpll_hw_state,
- BIT(DPLL_ID_PCH_PLL_B) |
- BIT(DPLL_ID_PCH_PLL_A));
+ pll = intel_find_dpll(state, crtc,
+ &crtc_state->dpll_hw_state,
+ BIT(DPLL_ID_PCH_PLL_B) |
+ BIT(DPLL_ID_PCH_PLL_A));
}
if (!pll)
return -EINVAL;
/* reference the pll */
- intel_reference_shared_dpll(state, crtc,
- pll, &crtc_state->dpll_hw_state);
+ intel_reference_dpll(state, crtc,
+ pll, &crtc_state->dpll_hw_state);
- crtc_state->shared_dpll = pll;
+ crtc_state->intel_dpll = pll;
return 0;
}
-static void ibx_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
+static void ibx_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- drm_dbg_kms(&dev_priv->drm,
- "dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
- "fp0: 0x%x, fp1: 0x%x\n",
- hw_state->dpll,
- hw_state->dpll_md,
- hw_state->fp0,
- hw_state->fp1);
+ const struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx;
+
+ drm_printf(p, "dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
+ "fp0: 0x%x, fp1: 0x%x\n",
+ hw_state->dpll,
+ hw_state->dpll_md,
+ hw_state->fp0,
+ hw_state->fp1);
+}
+
+static bool ibx_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct i9xx_dpll_hw_state *a = &_a->i9xx;
+ const struct i9xx_dpll_hw_state *b = &_b->i9xx;
+
+ return a->dpll == b->dpll &&
+ a->dpll_md == b->dpll_md &&
+ a->fp0 == b->fp0 &&
+ a->fp1 == b->fp1;
}
-static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
+static const struct intel_dpll_funcs ibx_pch_dpll_funcs = {
.enable = ibx_pch_dpll_enable,
.disable = ibx_pch_dpll_disable,
.get_hw_state = ibx_pch_dpll_get_hw_state,
};
static const struct dpll_info pch_plls[] = {
- { "PCH DPLL A", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_A, 0 },
- { "PCH DPLL B", &ibx_pch_dpll_funcs, DPLL_ID_PCH_PLL_B, 0 },
- { },
+ { .name = "PCH DPLL A", .funcs = &ibx_pch_dpll_funcs, .id = DPLL_ID_PCH_PLL_A, },
+ { .name = "PCH DPLL B", .funcs = &ibx_pch_dpll_funcs, .id = DPLL_ID_PCH_PLL_B, },
+ {}
};
static const struct intel_dpll_mgr pch_pll_mgr = {
@@ -593,99 +688,103 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
.get_dplls = ibx_get_dpll,
.put_dplls = intel_put_dpll,
.dump_hw_state = ibx_dump_hw_state,
+ .compare_hw_state = ibx_compare_hw_state,
};
-static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_wrpll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
const enum intel_dpll_id id = pll->info->id;
- intel_de_write(dev_priv, WRPLL_CTL(id), pll->state.hw_state.wrpll);
- intel_de_posting_read(dev_priv, WRPLL_CTL(id));
+ intel_de_write(display, WRPLL_CTL(id), hw_state->wrpll);
+ intel_de_posting_read(display, WRPLL_CTL(id));
udelay(20);
}
-static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_spll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- intel_de_write(dev_priv, SPLL_CTL, pll->state.hw_state.spll);
- intel_de_posting_read(dev_priv, SPLL_CTL);
+ const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
+
+ intel_de_write(display, SPLL_CTL, hw_state->spll);
+ intel_de_posting_read(display, SPLL_CTL);
udelay(20);
}
-static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_wrpll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
const enum intel_dpll_id id = pll->info->id;
- u32 val;
- val = intel_de_read(dev_priv, WRPLL_CTL(id));
- intel_de_write(dev_priv, WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE);
- intel_de_posting_read(dev_priv, WRPLL_CTL(id));
+ intel_de_rmw(display, WRPLL_CTL(id), WRPLL_PLL_ENABLE, 0);
+ intel_de_posting_read(display, WRPLL_CTL(id));
/*
* Try to set up the PCH reference clock once all DPLLs
* that depend on it have been shut down.
*/
- if (dev_priv->pch_ssc_use & BIT(id))
- intel_init_pch_refclk(dev_priv);
+ if (display->dpll.pch_ssc_use & BIT(id))
+ intel_init_pch_refclk(display);
}
-static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_spll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
enum intel_dpll_id id = pll->info->id;
- u32 val;
- val = intel_de_read(dev_priv, SPLL_CTL);
- intel_de_write(dev_priv, SPLL_CTL, val & ~SPLL_PLL_ENABLE);
- intel_de_posting_read(dev_priv, SPLL_CTL);
+ intel_de_rmw(display, SPLL_CTL, SPLL_PLL_ENABLE, 0);
+ intel_de_posting_read(display, SPLL_CTL);
/*
* Try to set up the PCH reference clock once all DPLLs
* that depend on it have been shut down.
*/
- if (dev_priv->pch_ssc_use & BIT(id))
- intel_init_pch_refclk(dev_priv);
+ if (display->dpll.pch_ssc_use & BIT(id))
+ intel_init_pch_refclk(display);
}
-static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool hsw_ddi_wrpll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
const enum intel_dpll_id id = pll->info->id;
intel_wakeref_t wakeref;
u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, WRPLL_CTL(id));
+ val = intel_de_read(display, WRPLL_CTL(id));
hw_state->wrpll = val;
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return val & WRPLL_PLL_ENABLE;
}
-static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool hsw_ddi_spll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
intel_wakeref_t wakeref;
u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, SPLL_CTL);
+ val = intel_de_read(display, SPLL_CTL);
hw_state->spll = val;
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return val & SPLL_PLL_ENABLE;
}
@@ -709,8 +808,6 @@ struct hsw_wrpll_rnp {
static unsigned hsw_wrpll_get_budget_for_freq(int clock)
{
- unsigned budget;
-
switch (clock) {
case 25175000:
case 25200000:
@@ -743,21 +840,18 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
case 222750000:
case 296703000:
case 297000000:
- budget = 0;
- break;
+ return 0;
case 233500000:
case 245250000:
case 247750000:
case 253250000:
case 298000000:
- budget = 1500;
- break;
+ return 1500;
case 169128000:
case 169500000:
case 179500000:
case 202000000:
- budget = 2000;
- break;
+ return 2000;
case 256250000:
case 262500000:
case 270000000:
@@ -767,18 +861,13 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
case 281250000:
case 286000000:
case 291750000:
- budget = 4000;
- break;
+ return 4000;
case 267250000:
case 268500000:
- budget = 5000;
- break;
+ return 5000;
default:
- budget = 1000;
- break;
+ return 1000;
}
-
- return budget;
}
static void hsw_wrpll_update_rnp(u64 freq2k, unsigned int budget,
@@ -906,19 +995,20 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
*r2_out = best.r2;
}
-static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int hsw_ddi_wrpll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
int refclk;
int n, p, r;
- u32 wrpll = pll_state->wrpll;
+ u32 wrpll = hw_state->wrpll;
switch (wrpll & WRPLL_REF_MASK) {
case WRPLL_REF_SPECIAL_HSW:
/* Muxed-SSC for BDW, non-SSC for non-ULT HSW. */
- if (IS_HASWELL(dev_priv) && !IS_HSW_ULT(dev_priv)) {
- refclk = dev_priv->display.dpll.ref_clks.nssc;
+ if (display->platform.haswell && !display->platform.haswell_ult) {
+ refclk = display->dpll.ref_clks.nssc;
break;
}
fallthrough;
@@ -928,7 +1018,7 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
* code only cares about 5% accuracy, and spread is a max of
* 0.5% downspread.
*/
- refclk = dev_priv->display.dpll.ref_clks.ssc;
+ refclk = display->dpll.ref_clks.ssc;
break;
case WRPLL_REF_LCPLL:
refclk = 2700000;
@@ -950,32 +1040,33 @@ static int
hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
- struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+ struct hsw_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.hsw;
unsigned int p, n2, r2;
hsw_ddi_calculate_wrpll(crtc_state->port_clock * 1000, &r2, &n2, &p);
- crtc_state->dpll_hw_state.wrpll =
+ hw_state->wrpll =
WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
WRPLL_DIVIDER_POST(p);
- crtc_state->port_clock = hsw_ddi_wrpll_get_freq(i915, NULL,
+ crtc_state->port_clock = hsw_ddi_wrpll_get_freq(display, NULL,
&crtc_state->dpll_hw_state);
return 0;
}
-static struct intel_shared_dpll *
+static struct intel_dpll *
hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- return intel_find_shared_dpll(state, crtc,
+ return intel_find_dpll(state, crtc,
&crtc_state->dpll_hw_state,
BIT(DPLL_ID_WRPLL2) |
BIT(DPLL_ID_WRPLL1));
@@ -984,7 +1075,7 @@ hsw_ddi_wrpll_get_dpll(struct intel_atomic_state *state,
static int
hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
int clock = crtc_state->port_clock;
switch (clock / 2) {
@@ -993,17 +1084,17 @@ hsw_ddi_lcpll_compute_dpll(struct intel_crtc_state *crtc_state)
case 270000:
return 0;
default:
- drm_dbg_kms(&dev_priv->drm, "Invalid clock for DP: %d\n",
+ drm_dbg_kms(display->drm, "Invalid clock for DP: %d\n",
clock);
return -EINVAL;
}
}
-static struct intel_shared_dpll *
+static struct intel_dpll *
hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
- struct intel_shared_dpll *pll;
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct intel_dpll *pll;
enum intel_dpll_id pll_id;
int clock = crtc_state->port_clock;
@@ -1022,7 +1113,7 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state)
return NULL;
}
- pll = intel_get_shared_dpll_by_id(dev_priv, pll_id);
+ pll = intel_get_dpll_by_id(display, pll_id);
if (!pll)
return NULL;
@@ -1030,9 +1121,9 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state *crtc_state)
return pll;
}
-static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int hsw_ddi_lcpll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
int link_clock = 0;
@@ -1047,7 +1138,7 @@ static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915,
link_clock = 270000;
break;
default:
- drm_WARN(&i915->drm, 1, "bad port clock sel\n");
+ drm_WARN(display->drm, 1, "bad port clock sel\n");
break;
}
@@ -1060,34 +1151,36 @@ hsw_ddi_spll_compute_dpll(struct intel_atomic_state *state,
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+ struct hsw_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.hsw;
if (drm_WARN_ON(crtc->base.dev, crtc_state->port_clock / 2 != 135000))
return -EINVAL;
- crtc_state->dpll_hw_state.spll =
+ hw_state->spll =
SPLL_PLL_ENABLE | SPLL_FREQ_1350MHz | SPLL_REF_MUXED_SSC;
return 0;
}
-static struct intel_shared_dpll *
+static struct intel_dpll *
hsw_ddi_spll_get_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- return intel_find_shared_dpll(state, crtc, &crtc_state->dpll_hw_state,
+ return intel_find_dpll(state, crtc, &crtc_state->dpll_hw_state,
BIT(DPLL_ID_SPLL));
}
-static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int hsw_ddi_spll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
int link_clock = 0;
- switch (pll_state->spll & SPLL_FREQ_MASK) {
+ switch (hw_state->spll & SPLL_FREQ_MASK) {
case SPLL_FREQ_810MHz:
link_clock = 81000;
break;
@@ -1098,7 +1191,7 @@ static int hsw_ddi_spll_get_freq(struct drm_i915_private *i915,
link_clock = 270000;
break;
default:
- drm_WARN(&i915->drm, 1, "bad spll freq\n");
+ drm_WARN(display->drm, 1, "bad spll freq\n");
break;
}
@@ -1128,7 +1221,7 @@ static int hsw_get_dpll(struct intel_atomic_state *state,
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- struct intel_shared_dpll *pll = NULL;
+ struct intel_dpll *pll = NULL;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
pll = hsw_ddi_wrpll_get_dpll(state, crtc);
@@ -1140,63 +1233,76 @@ static int hsw_get_dpll(struct intel_atomic_state *state,
if (!pll)
return -EINVAL;
- intel_reference_shared_dpll(state, crtc,
- pll, &crtc_state->dpll_hw_state);
+ intel_reference_dpll(state, crtc,
+ pll, &crtc_state->dpll_hw_state);
- crtc_state->shared_dpll = pll;
+ crtc_state->intel_dpll = pll;
return 0;
}
-static void hsw_update_dpll_ref_clks(struct drm_i915_private *i915)
+static void hsw_update_dpll_ref_clks(struct intel_display *display)
{
- i915->display.dpll.ref_clks.ssc = 135000;
+ display->dpll.ref_clks.ssc = 135000;
/* Non-SSC is only used on non-ULT HSW. */
- if (intel_de_read(i915, FUSE_STRAP3) & HSW_REF_CLK_SELECT)
- i915->display.dpll.ref_clks.nssc = 24000;
+ if (intel_de_read(display, FUSE_STRAP3) & HSW_REF_CLK_SELECT)
+ display->dpll.ref_clks.nssc = 24000;
else
- i915->display.dpll.ref_clks.nssc = 135000;
+ display->dpll.ref_clks.nssc = 135000;
}
-static void hsw_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
+static void hsw_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- drm_dbg_kms(&dev_priv->drm, "dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
- hw_state->wrpll, hw_state->spll);
+ const struct hsw_dpll_hw_state *hw_state = &dpll_hw_state->hsw;
+
+ drm_printf(p, "dpll_hw_state: wrpll: 0x%x spll: 0x%x\n",
+ hw_state->wrpll, hw_state->spll);
}
-static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
+static bool hsw_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct hsw_dpll_hw_state *a = &_a->hsw;
+ const struct hsw_dpll_hw_state *b = &_b->hsw;
+
+ return a->wrpll == b->wrpll &&
+ a->spll == b->spll;
+}
+
+static const struct intel_dpll_funcs hsw_ddi_wrpll_funcs = {
.enable = hsw_ddi_wrpll_enable,
.disable = hsw_ddi_wrpll_disable,
.get_hw_state = hsw_ddi_wrpll_get_hw_state,
.get_freq = hsw_ddi_wrpll_get_freq,
};
-static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
+static const struct intel_dpll_funcs hsw_ddi_spll_funcs = {
.enable = hsw_ddi_spll_enable,
.disable = hsw_ddi_spll_disable,
.get_hw_state = hsw_ddi_spll_get_hw_state,
.get_freq = hsw_ddi_spll_get_freq,
};
-static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_lcpll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *hw_state)
{
}
-static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void hsw_ddi_lcpll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
}
-static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool hsw_ddi_lcpll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
return true;
}
-static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
+static const struct intel_dpll_funcs hsw_ddi_lcpll_funcs = {
.enable = hsw_ddi_lcpll_enable,
.disable = hsw_ddi_lcpll_disable,
.get_hw_state = hsw_ddi_lcpll_get_hw_state,
@@ -1204,13 +1310,16 @@ static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = {
};
static const struct dpll_info hsw_plls[] = {
- { "WRPLL 1", &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL1, 0 },
- { "WRPLL 2", &hsw_ddi_wrpll_funcs, DPLL_ID_WRPLL2, 0 },
- { "SPLL", &hsw_ddi_spll_funcs, DPLL_ID_SPLL, 0 },
- { "LCPLL 810", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_810, INTEL_DPLL_ALWAYS_ON },
- { "LCPLL 1350", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_1350, INTEL_DPLL_ALWAYS_ON },
- { "LCPLL 2700", &hsw_ddi_lcpll_funcs, DPLL_ID_LCPLL_2700, INTEL_DPLL_ALWAYS_ON },
- { },
+ { .name = "WRPLL 1", .funcs = &hsw_ddi_wrpll_funcs, .id = DPLL_ID_WRPLL1, },
+ { .name = "WRPLL 2", .funcs = &hsw_ddi_wrpll_funcs, .id = DPLL_ID_WRPLL2, },
+ { .name = "SPLL", .funcs = &hsw_ddi_spll_funcs, .id = DPLL_ID_SPLL, },
+ { .name = "LCPLL 810", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_810,
+ .always_on = true, },
+ { .name = "LCPLL 1350", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_1350,
+ .always_on = true, },
+ { .name = "LCPLL 2700", .funcs = &hsw_ddi_lcpll_funcs, .id = DPLL_ID_LCPLL_2700,
+ .always_on = true, },
+ {}
};
static const struct intel_dpll_mgr hsw_pll_mgr = {
@@ -1220,6 +1329,7 @@ static const struct intel_dpll_mgr hsw_pll_mgr = {
.put_dplls = intel_put_dpll,
.update_ref_clks = hsw_update_dpll_ref_clks,
.dump_hw_state = hsw_dump_hw_state,
+ .compare_hw_state = hsw_compare_hw_state,
};
struct skl_dpll_regs {
@@ -1253,115 +1363,117 @@ static const struct skl_dpll_regs skl_dpll_regs[4] = {
},
};
-static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void skl_ddi_pll_write_ctrl1(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct skl_dpll_hw_state *hw_state)
{
const enum intel_dpll_id id = pll->info->id;
- u32 val;
-
- val = intel_de_read(dev_priv, DPLL_CTRL1);
- val &= ~(DPLL_CTRL1_HDMI_MODE(id) |
- DPLL_CTRL1_SSC(id) |
- DPLL_CTRL1_LINK_RATE_MASK(id));
- val |= pll->state.hw_state.ctrl1 << (id * 6);
-
- intel_de_write(dev_priv, DPLL_CTRL1, val);
- intel_de_posting_read(dev_priv, DPLL_CTRL1);
+ intel_de_rmw(display, DPLL_CTRL1,
+ DPLL_CTRL1_HDMI_MODE(id) |
+ DPLL_CTRL1_SSC(id) |
+ DPLL_CTRL1_LINK_RATE_MASK(id),
+ hw_state->ctrl1 << (id * 6));
+ intel_de_posting_read(display, DPLL_CTRL1);
}
-static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void skl_ddi_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
const struct skl_dpll_regs *regs = skl_dpll_regs;
const enum intel_dpll_id id = pll->info->id;
- skl_ddi_pll_write_ctrl1(dev_priv, pll);
+ skl_ddi_pll_write_ctrl1(display, pll, hw_state);
- intel_de_write(dev_priv, regs[id].cfgcr1, pll->state.hw_state.cfgcr1);
- intel_de_write(dev_priv, regs[id].cfgcr2, pll->state.hw_state.cfgcr2);
- intel_de_posting_read(dev_priv, regs[id].cfgcr1);
- intel_de_posting_read(dev_priv, regs[id].cfgcr2);
+ intel_de_write(display, regs[id].cfgcr1, hw_state->cfgcr1);
+ intel_de_write(display, regs[id].cfgcr2, hw_state->cfgcr2);
+ intel_de_posting_read(display, regs[id].cfgcr1);
+ intel_de_posting_read(display, regs[id].cfgcr2);
/* the enable bit is always bit 31 */
- intel_de_write(dev_priv, regs[id].ctl,
- intel_de_read(dev_priv, regs[id].ctl) | LCPLL_PLL_ENABLE);
+ intel_de_rmw(display, regs[id].ctl, 0, LCPLL_PLL_ENABLE);
- if (intel_de_wait_for_set(dev_priv, DPLL_STATUS, DPLL_LOCK(id), 5))
- drm_err(&dev_priv->drm, "DPLL %d not locked\n", id);
+ if (intel_de_wait_for_set_ms(display, DPLL_STATUS, DPLL_LOCK(id), 5))
+ drm_err(display->drm, "DPLL %d not locked\n", id);
}
-static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void skl_ddi_dpll0_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- skl_ddi_pll_write_ctrl1(dev_priv, pll);
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
+
+ skl_ddi_pll_write_ctrl1(display, pll, hw_state);
}
-static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void skl_ddi_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
const struct skl_dpll_regs *regs = skl_dpll_regs;
const enum intel_dpll_id id = pll->info->id;
/* the enable bit is always bit 31 */
- intel_de_write(dev_priv, regs[id].ctl,
- intel_de_read(dev_priv, regs[id].ctl) & ~LCPLL_PLL_ENABLE);
- intel_de_posting_read(dev_priv, regs[id].ctl);
+ intel_de_rmw(display, regs[id].ctl, LCPLL_PLL_ENABLE, 0);
+ intel_de_posting_read(display, regs[id].ctl);
}
-static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void skl_ddi_dpll0_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
}
-static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool skl_ddi_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
- u32 val;
+ struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
const struct skl_dpll_regs *regs = skl_dpll_regs;
const enum intel_dpll_id id = pll->info->id;
intel_wakeref_t wakeref;
bool ret;
+ u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
ret = false;
- val = intel_de_read(dev_priv, regs[id].ctl);
+ val = intel_de_read(display, regs[id].ctl);
if (!(val & LCPLL_PLL_ENABLE))
goto out;
- val = intel_de_read(dev_priv, DPLL_CTRL1);
+ val = intel_de_read(display, DPLL_CTRL1);
hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
/* avoid reading back stale values if HDMI mode is not enabled */
if (val & DPLL_CTRL1_HDMI_MODE(id)) {
- hw_state->cfgcr1 = intel_de_read(dev_priv, regs[id].cfgcr1);
- hw_state->cfgcr2 = intel_de_read(dev_priv, regs[id].cfgcr2);
+ hw_state->cfgcr1 = intel_de_read(display, regs[id].cfgcr1);
+ hw_state->cfgcr2 = intel_de_read(display, regs[id].cfgcr2);
}
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
-static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool skl_ddi_dpll0_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
const struct skl_dpll_regs *regs = skl_dpll_regs;
const enum intel_dpll_id id = pll->info->id;
intel_wakeref_t wakeref;
u32 val;
bool ret;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
@@ -1369,17 +1481,17 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
ret = false;
/* DPLL0 is always enabled since it drives CDCLK */
- val = intel_de_read(dev_priv, regs[id].ctl);
- if (drm_WARN_ON(&dev_priv->drm, !(val & LCPLL_PLL_ENABLE)))
+ val = intel_de_read(display, regs[id].ctl);
+ if (drm_WARN_ON(display->drm, !(val & LCPLL_PLL_ENABLE)))
goto out;
- val = intel_de_read(dev_priv, DPLL_CTRL1);
+ val = intel_de_read(display, DPLL_CTRL1);
hw_state->ctrl1 = (val >> (id * 6)) & 0x3f;
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
@@ -1552,7 +1664,7 @@ static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
}
static int
-skl_ddi_calculate_wrpll(int clock /* in Hz */,
+skl_ddi_calculate_wrpll(int clock,
int ref_clock,
struct skl_wrpll_params *wrpll_params)
{
@@ -1577,7 +1689,7 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */,
};
unsigned int dco, d, i;
unsigned int p0, p1, p2;
- u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+ u64 afe_clock = (u64)clock * 1000 * 5; /* AFE Clock is 5x Pixel clock, in Hz */
for (d = 0; d < ARRAY_SIZE(dividers); d++) {
for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
@@ -1623,18 +1735,19 @@ skip_remaining_dividers:
return 0;
}
-static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int skl_ddi_wrpll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- int ref_clock = i915->display.dpll.ref_clks.nssc;
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
+ int ref_clock = display->dpll.ref_clks.nssc;
u32 p0, p1, p2, dco_freq;
- p0 = pll_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK;
- p2 = pll_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK;
+ p0 = hw_state->cfgcr2 & DPLL_CFGCR2_PDIV_MASK;
+ p2 = hw_state->cfgcr2 & DPLL_CFGCR2_KDIV_MASK;
- if (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1))
- p1 = (pll_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
+ if (hw_state->cfgcr2 & DPLL_CFGCR2_QDIV_MODE(1))
+ p1 = (hw_state->cfgcr2 & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
else
p1 = 1;
@@ -1654,7 +1767,7 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
* Incorrect ASUS-Z170M BIOS setting, the HW seems to ignore bit#0,
* handling it the same way as PDIV_7.
*/
- drm_dbg_kms(&i915->drm, "Invalid WRPLL PDIV divider value, fixing it.\n");
+ drm_dbg_kms(display->drm, "Invalid WRPLL PDIV divider value, fixing it.\n");
fallthrough;
case DPLL_CFGCR2_PDIV_7:
p0 = 7;
@@ -1682,13 +1795,13 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
return 0;
}
- dco_freq = (pll_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) *
+ dco_freq = (hw_state->cfgcr1 & DPLL_CFGCR1_DCO_INTEGER_MASK) *
ref_clock;
- dco_freq += ((pll_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) *
+ dco_freq += ((hw_state->cfgcr1 & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) *
ref_clock / 0x8000;
- if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0))
+ if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0))
return 0;
return dco_freq / (p0 * p1 * p2 * 5);
@@ -1696,39 +1809,37 @@ static int skl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
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 intel_display *display = to_intel_display(crtc_state);
+ struct skl_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.skl;
struct skl_wrpll_params wrpll_params = {};
- u32 ctrl1, cfgcr1, cfgcr2;
int ret;
+ ret = skl_ddi_calculate_wrpll(crtc_state->port_clock,
+ display->dpll.ref_clks.nssc, &wrpll_params);
+ if (ret)
+ return ret;
+
/*
* See comment in intel_dpll_hw_state to understand why we always use 0
* as the DPLL id in this function.
*/
- ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+ hw_state->ctrl1 =
+ DPLL_CTRL1_OVERRIDE(0) |
+ DPLL_CTRL1_HDMI_MODE(0);
- ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
-
- ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
- i915->display.dpll.ref_clks.nssc, &wrpll_params);
- if (ret)
- return ret;
-
- cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+ hw_state->cfgcr1 =
+ DPLL_CFGCR1_FREQ_ENABLE |
DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
wrpll_params.dco_integer;
- cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+ hw_state->cfgcr2 =
+ DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
wrpll_params.central_freq;
- crtc_state->dpll_hw_state.ctrl1 = ctrl1;
- crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
- crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
-
- crtc_state->port_clock = skl_ddi_wrpll_get_freq(i915, NULL,
+ crtc_state->port_clock = skl_ddi_wrpll_get_freq(display, NULL,
&crtc_state->dpll_hw_state);
return 0;
@@ -1737,6 +1848,7 @@ static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
static int
skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
{
+ struct skl_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.skl;
u32 ctrl1;
/*
@@ -1766,18 +1878,19 @@ skl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
break;
}
- crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+ hw_state->ctrl1 = ctrl1;
return 0;
}
-static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int skl_ddi_lcpll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
int link_clock = 0;
- switch ((pll_state->ctrl1 & DPLL_CTRL1_LINK_RATE_MASK(0)) >>
+ switch ((hw_state->ctrl1 & DPLL_CTRL1_LINK_RATE_MASK(0)) >>
DPLL_CTRL1_LINK_RATE_SHIFT(0)) {
case DPLL_CTRL1_LINK_RATE_810:
link_clock = 81000;
@@ -1798,7 +1911,7 @@ static int skl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
link_clock = 270000;
break;
default:
- drm_WARN(&i915->drm, 1, "Unsupported link rate\n");
+ drm_WARN(display->drm, 1, "Unsupported link rate\n");
break;
}
@@ -1826,67 +1939,79 @@ static int skl_get_dpll(struct intel_atomic_state *state,
{
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
- struct intel_shared_dpll *pll;
+ struct intel_dpll *pll;
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
- pll = intel_find_shared_dpll(state, crtc,
- &crtc_state->dpll_hw_state,
- BIT(DPLL_ID_SKL_DPLL0));
+ pll = intel_find_dpll(state, crtc,
+ &crtc_state->dpll_hw_state,
+ BIT(DPLL_ID_SKL_DPLL0));
else
- pll = intel_find_shared_dpll(state, crtc,
- &crtc_state->dpll_hw_state,
- BIT(DPLL_ID_SKL_DPLL3) |
- BIT(DPLL_ID_SKL_DPLL2) |
- BIT(DPLL_ID_SKL_DPLL1));
+ pll = intel_find_dpll(state, crtc,
+ &crtc_state->dpll_hw_state,
+ BIT(DPLL_ID_SKL_DPLL3) |
+ BIT(DPLL_ID_SKL_DPLL2) |
+ BIT(DPLL_ID_SKL_DPLL1));
if (!pll)
return -EINVAL;
- intel_reference_shared_dpll(state, crtc,
- pll, &crtc_state->dpll_hw_state);
+ intel_reference_dpll(state, crtc,
+ pll, &crtc_state->dpll_hw_state);
- crtc_state->shared_dpll = pll;
+ crtc_state->intel_dpll = pll;
return 0;
}
-static int skl_ddi_pll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int skl_ddi_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
+
/*
* ctrl1 register is already shifted for each pll, just use 0 to get
* the internal shift for each field
*/
- if (pll_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0))
- return skl_ddi_wrpll_get_freq(i915, pll, pll_state);
+ if (hw_state->ctrl1 & DPLL_CTRL1_HDMI_MODE(0))
+ return skl_ddi_wrpll_get_freq(display, pll, dpll_hw_state);
else
- return skl_ddi_lcpll_get_freq(i915, pll, pll_state);
+ return skl_ddi_lcpll_get_freq(display, pll, dpll_hw_state);
}
-static void skl_update_dpll_ref_clks(struct drm_i915_private *i915)
+static void skl_update_dpll_ref_clks(struct intel_display *display)
{
/* No SSC ref */
- i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref;
+ display->dpll.ref_clks.nssc = display->cdclk.hw.ref;
}
-static void skl_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
+static void skl_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- drm_dbg_kms(&dev_priv->drm, "dpll_hw_state: "
- "ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
- hw_state->ctrl1,
- hw_state->cfgcr1,
- hw_state->cfgcr2);
+ const struct skl_dpll_hw_state *hw_state = &dpll_hw_state->skl;
+
+ drm_printf(p, "dpll_hw_state: ctrl1: 0x%x, cfgcr1: 0x%x, cfgcr2: 0x%x\n",
+ hw_state->ctrl1, hw_state->cfgcr1, hw_state->cfgcr2);
}
-static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
+static bool skl_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct skl_dpll_hw_state *a = &_a->skl;
+ const struct skl_dpll_hw_state *b = &_b->skl;
+
+ return a->ctrl1 == b->ctrl1 &&
+ a->cfgcr1 == b->cfgcr1 &&
+ a->cfgcr2 == b->cfgcr2;
+}
+
+static const struct intel_dpll_funcs skl_ddi_pll_funcs = {
.enable = skl_ddi_pll_enable,
.disable = skl_ddi_pll_disable,
.get_hw_state = skl_ddi_pll_get_hw_state,
.get_freq = skl_ddi_pll_get_freq,
};
-static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
+static const struct intel_dpll_funcs skl_ddi_dpll0_funcs = {
.enable = skl_ddi_dpll0_enable,
.disable = skl_ddi_dpll0_disable,
.get_hw_state = skl_ddi_dpll0_get_hw_state,
@@ -1894,11 +2019,12 @@ static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
};
static const struct dpll_info skl_plls[] = {
- { "DPLL 0", &skl_ddi_dpll0_funcs, DPLL_ID_SKL_DPLL0, INTEL_DPLL_ALWAYS_ON },
- { "DPLL 1", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
- { "DPLL 2", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
- { "DPLL 3", &skl_ddi_pll_funcs, DPLL_ID_SKL_DPLL3, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &skl_ddi_dpll0_funcs, .id = DPLL_ID_SKL_DPLL0,
+ .always_on = true, },
+ { .name = "DPLL 1", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL1, },
+ { .name = "DPLL 2", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL2, },
+ { .name = "DPLL 3", .funcs = &skl_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL3, },
+ {}
};
static const struct intel_dpll_mgr skl_pll_mgr = {
@@ -1908,156 +2034,143 @@ static const struct intel_dpll_mgr skl_pll_mgr = {
.put_dplls = intel_put_dpll,
.update_ref_clks = skl_update_dpll_ref_clks,
.dump_hw_state = skl_dump_hw_state,
+ .compare_hw_state = skl_compare_hw_state,
};
-static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void bxt_ddi_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- u32 temp;
+ const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
- enum dpio_phy phy;
- enum dpio_channel ch;
+ enum dpio_phy phy = DPIO_PHY0;
+ enum dpio_channel ch = DPIO_CH0;
+ u32 temp;
+ int ret;
- bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
+ bxt_port_to_phy_channel(display, port, &phy, &ch);
/* Non-SSC reference */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
- temp |= PORT_PLL_REF_SEL;
- intel_de_write(dev_priv, BXT_PORT_PLL_ENABLE(port), temp);
-
- if (IS_GEMINILAKE(dev_priv)) {
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
- temp |= PORT_PLL_POWER_ENABLE;
- intel_de_write(dev_priv, BXT_PORT_PLL_ENABLE(port), temp);
-
- if (wait_for_us((intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port)) &
- PORT_PLL_POWER_STATE), 200))
- drm_err(&dev_priv->drm,
+ intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_REF_SEL);
+
+ if (display->platform.geminilake) {
+ intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
+ 0, PORT_PLL_POWER_ENABLE);
+
+ ret = intel_de_wait_for_set_us(display,
+ BXT_PORT_PLL_ENABLE(port),
+ PORT_PLL_POWER_STATE, 200);
+ if (ret)
+ drm_err(display->drm,
"Power state not set for PLL:%d\n", port);
}
/* Disable 10 bit clock */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch));
- temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
- intel_de_write(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch), temp);
+ intel_de_rmw(display, BXT_PORT_PLL_EBB_4(phy, ch),
+ PORT_PLL_10BIT_CLK_ENABLE, 0);
/* Write P1 & P2 */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_EBB_0(phy, ch));
- temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
- temp |= pll->state.hw_state.ebb0;
- intel_de_write(dev_priv, BXT_PORT_PLL_EBB_0(phy, ch), temp);
+ intel_de_rmw(display, BXT_PORT_PLL_EBB_0(phy, ch),
+ PORT_PLL_P1_MASK | PORT_PLL_P2_MASK, hw_state->ebb0);
/* Write M2 integer */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 0));
- temp &= ~PORT_PLL_M2_INT_MASK;
- temp |= pll->state.hw_state.pll0;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 0), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 0),
+ PORT_PLL_M2_INT_MASK, hw_state->pll0);
/* Write N */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 1));
- temp &= ~PORT_PLL_N_MASK;
- temp |= pll->state.hw_state.pll1;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 1), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 1),
+ PORT_PLL_N_MASK, hw_state->pll1);
/* Write M2 fraction */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 2));
- temp &= ~PORT_PLL_M2_FRAC_MASK;
- temp |= pll->state.hw_state.pll2;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 2), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 2),
+ PORT_PLL_M2_FRAC_MASK, hw_state->pll2);
/* Write M2 fraction enable */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 3));
- temp &= ~PORT_PLL_M2_FRAC_ENABLE;
- temp |= pll->state.hw_state.pll3;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 3), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 3),
+ PORT_PLL_M2_FRAC_ENABLE, hw_state->pll3);
/* Write coeff */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 6));
+ temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6));
temp &= ~PORT_PLL_PROP_COEFF_MASK;
temp &= ~PORT_PLL_INT_COEFF_MASK;
temp &= ~PORT_PLL_GAIN_CTL_MASK;
- temp |= pll->state.hw_state.pll6;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 6), temp);
+ temp |= hw_state->pll6;
+ intel_de_write(display, BXT_PORT_PLL(phy, ch, 6), temp);
/* Write calibration val */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 8));
- temp &= ~PORT_PLL_TARGET_CNT_MASK;
- temp |= pll->state.hw_state.pll8;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 8), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 8),
+ PORT_PLL_TARGET_CNT_MASK, hw_state->pll8);
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 9));
- temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
- temp |= pll->state.hw_state.pll9;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 9), temp);
+ intel_de_rmw(display, BXT_PORT_PLL(phy, ch, 9),
+ PORT_PLL_LOCK_THRESHOLD_MASK, hw_state->pll9);
- temp = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 10));
+ temp = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10));
temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
temp &= ~PORT_PLL_DCO_AMP_MASK;
- temp |= pll->state.hw_state.pll10;
- intel_de_write(dev_priv, BXT_PORT_PLL(phy, ch, 10), temp);
+ temp |= hw_state->pll10;
+ intel_de_write(display, BXT_PORT_PLL(phy, ch, 10), temp);
/* Recalibrate with new settings */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch));
+ temp = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch));
temp |= PORT_PLL_RECALIBRATE;
- intel_de_write(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch), temp);
+ intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), temp);
temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
- temp |= pll->state.hw_state.ebb4;
- intel_de_write(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch), temp);
+ temp |= hw_state->ebb4;
+ intel_de_write(display, BXT_PORT_PLL_EBB_4(phy, ch), temp);
/* Enable PLL */
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
- temp |= PORT_PLL_ENABLE;
- intel_de_write(dev_priv, BXT_PORT_PLL_ENABLE(port), temp);
- intel_de_posting_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
+ intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), 0, PORT_PLL_ENABLE);
+ intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port));
- if (wait_for_us((intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK),
- 200))
- drm_err(&dev_priv->drm, "PLL %d not locked\n", port);
+ ret = intel_de_wait_for_set_us(display, BXT_PORT_PLL_ENABLE(port),
+ PORT_PLL_LOCK, 200);
+ if (ret)
+ drm_err(display->drm, "PLL %d not locked\n", port);
- if (IS_GEMINILAKE(dev_priv)) {
- temp = intel_de_read(dev_priv, BXT_PORT_TX_DW5_LN0(phy, ch));
+ if (display->platform.geminilake) {
+ temp = intel_de_read(display, BXT_PORT_TX_DW5_LN(phy, ch, 0));
temp |= DCC_DELAY_RANGE_2;
- intel_de_write(dev_priv, BXT_PORT_TX_DW5_GRP(phy, ch), temp);
+ intel_de_write(display, BXT_PORT_TX_DW5_GRP(phy, ch), temp);
}
/*
* While we write to the group register to program all lanes at once we
* can read only lane registers and we pick lanes 0/1 for that.
*/
- temp = intel_de_read(dev_priv, BXT_PORT_PCS_DW12_LN01(phy, ch));
+ temp = intel_de_read(display, BXT_PORT_PCS_DW12_LN01(phy, ch));
temp &= ~LANE_STAGGER_MASK;
temp &= ~LANESTAGGER_STRAP_OVRD;
- temp |= pll->state.hw_state.pcsdw12;
- intel_de_write(dev_priv, BXT_PORT_PCS_DW12_GRP(phy, ch), temp);
+ temp |= hw_state->pcsdw12;
+ intel_de_write(display, BXT_PORT_PCS_DW12_GRP(phy, ch), temp);
}
-static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void bxt_ddi_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
- u32 temp;
+ int ret;
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
- temp &= ~PORT_PLL_ENABLE;
- intel_de_write(dev_priv, BXT_PORT_PLL_ENABLE(port), temp);
- intel_de_posting_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
+ intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port), PORT_PLL_ENABLE, 0);
+ intel_de_posting_read(display, BXT_PORT_PLL_ENABLE(port));
- if (IS_GEMINILAKE(dev_priv)) {
- temp = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
- temp &= ~PORT_PLL_POWER_ENABLE;
- intel_de_write(dev_priv, BXT_PORT_PLL_ENABLE(port), temp);
+ if (display->platform.geminilake) {
+ intel_de_rmw(display, BXT_PORT_PLL_ENABLE(port),
+ PORT_PLL_POWER_ENABLE, 0);
- if (wait_for_us(!(intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port)) &
- PORT_PLL_POWER_STATE), 200))
- drm_err(&dev_priv->drm,
+ ret = intel_de_wait_for_clear_us(display,
+ BXT_PORT_PLL_ENABLE(port),
+ PORT_PLL_POWER_STATE, 200);
+ if (ret)
+ drm_err(display->drm,
"Power state not reset for PLL:%d\n", port);
}
}
-static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool bxt_ddi_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */
intel_wakeref_t wakeref;
enum dpio_phy phy;
@@ -2065,49 +2178,49 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
u32 val;
bool ret;
- bxt_port_to_phy_channel(dev_priv, port, &phy, &ch);
+ bxt_port_to_phy_channel(display, port, &phy, &ch);
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
ret = false;
- val = intel_de_read(dev_priv, BXT_PORT_PLL_ENABLE(port));
+ val = intel_de_read(display, BXT_PORT_PLL_ENABLE(port));
if (!(val & PORT_PLL_ENABLE))
goto out;
- hw_state->ebb0 = intel_de_read(dev_priv, BXT_PORT_PLL_EBB_0(phy, ch));
+ hw_state->ebb0 = intel_de_read(display, BXT_PORT_PLL_EBB_0(phy, ch));
hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
- hw_state->ebb4 = intel_de_read(dev_priv, BXT_PORT_PLL_EBB_4(phy, ch));
+ hw_state->ebb4 = intel_de_read(display, BXT_PORT_PLL_EBB_4(phy, ch));
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 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 0));
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 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 1));
hw_state->pll1 &= PORT_PLL_N_MASK;
- hw_state->pll2 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 2));
+ hw_state->pll2 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 2));
hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
- hw_state->pll3 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 3));
+ hw_state->pll3 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 3));
hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
- hw_state->pll6 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 6));
+ hw_state->pll6 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 6));
hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
PORT_PLL_INT_COEFF_MASK |
PORT_PLL_GAIN_CTL_MASK;
- hw_state->pll8 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 8));
+ hw_state->pll8 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 8));
hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
- hw_state->pll9 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 9));
+ hw_state->pll9 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 9));
hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
- hw_state->pll10 = intel_de_read(dev_priv, BXT_PORT_PLL(phy, ch, 10));
+ hw_state->pll10 = intel_de_read(display, BXT_PORT_PLL(phy, ch, 10));
hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
PORT_PLL_DCO_AMP_MASK;
@@ -2116,20 +2229,20 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
* can read only lane registers. We configure all lanes the same way, so
* here just read out lanes 0/1 and output a note if lanes 2/3 differ.
*/
- hw_state->pcsdw12 = intel_de_read(dev_priv,
+ hw_state->pcsdw12 = intel_de_read(display,
BXT_PORT_PCS_DW12_LN01(phy, ch));
- if (intel_de_read(dev_priv, BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12)
- drm_dbg(&dev_priv->drm,
+ if (intel_de_read(display, BXT_PORT_PCS_DW12_LN23(phy, ch)) != hw_state->pcsdw12)
+ drm_dbg(display->drm,
"lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
hw_state->pcsdw12,
- intel_de_read(dev_priv,
+ intel_de_read(display,
BXT_PORT_PCS_DW12_LN23(phy, ch)));
hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
@@ -2150,7 +2263,7 @@ static int
bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
struct dpll *clk_div)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
/* Calculate HDMI div */
/*
@@ -2160,7 +2273,7 @@ bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
if (!bxt_find_best_dpll(crtc_state, clk_div))
return -EINVAL;
- drm_WARN_ON(&i915->drm, clk_div->m1 != 2);
+ drm_WARN_ON(display->drm, clk_div->m1 != 2);
return 0;
}
@@ -2168,7 +2281,7 @@ bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state,
struct dpll *clk_div)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
int i;
*clk_div = bxt_dp_clk_val[0];
@@ -2179,17 +2292,17 @@ static void bxt_ddi_dp_pll_dividers(struct intel_crtc_state *crtc_state,
}
}
- chv_calc_dpll_params(i915->display.dpll.ref_clks.nssc, clk_div);
+ chv_calc_dpll_params(display->dpll.ref_clks.nssc, clk_div);
- drm_WARN_ON(&i915->drm, clk_div->vco == 0 ||
+ drm_WARN_ON(display->drm, clk_div->vco == 0 ||
clk_div->dot != crtc_state->port_clock);
}
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;
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct bxt_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.bxt;
int clock = crtc_state->port_clock;
int vco = clk_div->vco;
u32 prop_coef, int_coef, gain_ctl, targ_cnt;
@@ -2212,7 +2325,7 @@ static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
gain_ctl = 1;
targ_cnt = 9;
} else {
- drm_err(&i915->drm, "Invalid VCO\n");
+ drm_err(display->drm, "Invalid VCO\n");
return -EINVAL;
}
@@ -2227,47 +2340,49 @@ static int bxt_ddi_set_dpll_hw_state(struct intel_crtc_state *crtc_state,
else
lanestagger = 0x02;
- dpll_hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
- 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 = PORT_PLL_M2_FRAC(clk_div->m2 & 0x3fffff);
+ hw_state->ebb0 = PORT_PLL_P1(clk_div->p1) | PORT_PLL_P2(clk_div->p2);
+ hw_state->pll0 = PORT_PLL_M2_INT(clk_div->m2 >> 22);
+ hw_state->pll1 = PORT_PLL_N(clk_div->n);
+ hw_state->pll2 = PORT_PLL_M2_FRAC(clk_div->m2 & 0x3fffff);
if (clk_div->m2 & 0x3fffff)
- dpll_hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
+ hw_state->pll3 = PORT_PLL_M2_FRAC_ENABLE;
- dpll_hw_state->pll6 = PORT_PLL_PROP_COEFF(prop_coef) |
+ 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 = PORT_PLL_TARGET_CNT(targ_cnt);
+ hw_state->pll8 = PORT_PLL_TARGET_CNT(targ_cnt);
- dpll_hw_state->pll9 = PORT_PLL_LOCK_THRESHOLD(5);
+ hw_state->pll9 = PORT_PLL_LOCK_THRESHOLD(5);
- dpll_hw_state->pll10 = PORT_PLL_DCO_AMP(15) |
+ hw_state->pll10 = PORT_PLL_DCO_AMP(15) |
PORT_PLL_DCO_AMP_OVR_EN_H;
- dpll_hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+ hw_state->ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
- dpll_hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
+ hw_state->pcsdw12 = LANESTAGGER_STRAP_OVRD | lanestagger;
return 0;
}
-static int bxt_ddi_pll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int bxt_ddi_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
struct dpll clock;
clock.m1 = 2;
- 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 |= 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);
+ clock.m2 = REG_FIELD_GET(PORT_PLL_M2_INT_MASK, hw_state->pll0) << 22;
+ if (hw_state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
+ clock.m2 |= REG_FIELD_GET(PORT_PLL_M2_FRAC_MASK,
+ hw_state->pll2);
+ clock.n = REG_FIELD_GET(PORT_PLL_N_MASK, hw_state->pll1);
+ clock.p1 = REG_FIELD_GET(PORT_PLL_P1_MASK, hw_state->ebb0);
+ clock.p2 = REG_FIELD_GET(PORT_PLL_P2_MASK, hw_state->ebb0);
- return chv_calc_dpll_params(i915->display.dpll.ref_clks.nssc, &clock);
+ return chv_calc_dpll_params(display->dpll.ref_clks.nssc, &clock);
}
static int
@@ -2283,7 +2398,7 @@ bxt_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
static int
bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ struct intel_display *display = to_intel_display(crtc_state);
struct dpll clk_div = {};
int ret;
@@ -2293,7 +2408,7 @@ bxt_ddi_hdmi_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
if (ret)
return ret;
- crtc_state->port_clock = bxt_ddi_pll_get_freq(i915, NULL,
+ crtc_state->port_clock = bxt_ddi_pll_get_freq(display, NULL,
&crtc_state->dpll_hw_state);
return 0;
@@ -2318,54 +2433,67 @@ static int bxt_get_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
{
+ struct intel_display *display = to_intel_display(state);
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;
+ struct intel_dpll *pll;
enum intel_dpll_id id;
/* 1:1 mapping between ports and PLLs */
id = (enum intel_dpll_id) encoder->port;
- pll = intel_get_shared_dpll_by_id(dev_priv, id);
+ pll = intel_get_dpll_by_id(display, id);
- drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] using pre-allocated %s\n",
+ drm_dbg_kms(display->drm, "[CRTC:%d:%s] using pre-allocated %s\n",
crtc->base.base.id, crtc->base.name, pll->info->name);
- intel_reference_shared_dpll(state, crtc,
- pll, &crtc_state->dpll_hw_state);
+ intel_reference_dpll(state, crtc,
+ pll, &crtc_state->dpll_hw_state);
- crtc_state->shared_dpll = pll;
+ crtc_state->intel_dpll = pll;
return 0;
}
-static void bxt_update_dpll_ref_clks(struct drm_i915_private *i915)
+static void bxt_update_dpll_ref_clks(struct intel_display *display)
{
- i915->display.dpll.ref_clks.ssc = 100000;
- i915->display.dpll.ref_clks.nssc = 100000;
+ display->dpll.ref_clks.ssc = 100000;
+ display->dpll.ref_clks.nssc = 100000;
/* DSI non-SSC ref 19.2MHz */
}
-static void bxt_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
+static void bxt_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- drm_dbg_kms(&dev_priv->drm, "dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
- "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
- "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
- hw_state->ebb0,
- hw_state->ebb4,
- hw_state->pll0,
- hw_state->pll1,
- hw_state->pll2,
- hw_state->pll3,
- hw_state->pll6,
- hw_state->pll8,
- hw_state->pll9,
- hw_state->pll10,
- hw_state->pcsdw12);
+ const struct bxt_dpll_hw_state *hw_state = &dpll_hw_state->bxt;
+
+ drm_printf(p, "dpll_hw_state: ebb0: 0x%x, ebb4: 0x%x,"
+ "pll0: 0x%x, pll1: 0x%x, pll2: 0x%x, pll3: 0x%x, "
+ "pll6: 0x%x, pll8: 0x%x, pll9: 0x%x, pll10: 0x%x, pcsdw12: 0x%x\n",
+ hw_state->ebb0, hw_state->ebb4,
+ hw_state->pll0, hw_state->pll1, hw_state->pll2, hw_state->pll3,
+ hw_state->pll6, hw_state->pll8, hw_state->pll9, hw_state->pll10,
+ hw_state->pcsdw12);
}
-static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
+static bool bxt_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct bxt_dpll_hw_state *a = &_a->bxt;
+ const struct bxt_dpll_hw_state *b = &_b->bxt;
+
+ return a->ebb0 == b->ebb0 &&
+ a->ebb4 == b->ebb4 &&
+ a->pll0 == b->pll0 &&
+ a->pll1 == b->pll1 &&
+ a->pll2 == b->pll2 &&
+ a->pll3 == b->pll3 &&
+ a->pll6 == b->pll6 &&
+ a->pll8 == b->pll8 &&
+ a->pll10 == b->pll10 &&
+ a->pcsdw12 == b->pcsdw12;
+}
+
+static const struct intel_dpll_funcs bxt_ddi_pll_funcs = {
.enable = bxt_ddi_pll_enable,
.disable = bxt_ddi_pll_disable,
.get_hw_state = bxt_ddi_pll_get_hw_state,
@@ -2373,10 +2501,10 @@ static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
};
static const struct dpll_info bxt_plls[] = {
- { "PORT PLL A", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
- { "PORT PLL B", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
- { "PORT PLL C", &bxt_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
- { },
+ { .name = "PORT PLL A", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL0, },
+ { .name = "PORT PLL B", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL1, },
+ { .name = "PORT PLL C", .funcs = &bxt_ddi_pll_funcs, .id = DPLL_ID_SKL_DPLL2, },
+ {}
};
static const struct intel_dpll_mgr bxt_pll_mgr = {
@@ -2386,6 +2514,7 @@ static const struct intel_dpll_mgr bxt_pll_mgr = {
.put_dplls = intel_put_dpll,
.update_ref_clks = bxt_update_dpll_ref_clks,
.dump_hw_state = bxt_dump_hw_state,
+ .compare_hw_state = bxt_compare_hw_state,
};
static void icl_wrpll_get_multipliers(int bestdiv, int *pdiv,
@@ -2480,12 +2609,12 @@ static void icl_wrpll_params_populate(struct skl_wrpll_params *params,
* Program half of the nominal DCO divider fraction value.
*/
static bool
-ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915)
+ehl_combo_pll_div_frac_wa_needed(struct intel_display *display)
{
- return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) &&
- IS_JSL_EHL_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) ||
- IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) &&
- i915->display.dpll.ref_clks.nssc == 38400;
+ return ((display->platform.elkhartlake &&
+ IS_DISPLAY_STEP(display, STEP_B0, STEP_FOREVER)) ||
+ DISPLAY_VER(display) >= 12) &&
+ display->dpll.ref_clks.nssc == 38400;
}
struct icl_combo_pll_params {
@@ -2577,9 +2706,9 @@ static const struct skl_wrpll_params tgl_tbt_pll_24MHz_values = {
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);
+ struct intel_display *display = to_intel_display(crtc_state);
const struct icl_combo_pll_params *params =
- dev_priv->display.dpll.ref_clks.nssc == 24000 ?
+ display->dpll.ref_clks.nssc == 24000 ?
icl_dp_combo_pll_24MHz_values :
icl_dp_combo_pll_19_2MHz_values;
int clock = crtc_state->port_clock;
@@ -2599,12 +2728,12 @@ static int icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
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);
+ struct intel_display *display = to_intel_display(crtc_state);
- if (DISPLAY_VER(dev_priv) >= 12) {
- switch (dev_priv->display.dpll.ref_clks.nssc) {
+ if (DISPLAY_VER(display) >= 12) {
+ switch (display->dpll.ref_clks.nssc) {
default:
- MISSING_CASE(dev_priv->display.dpll.ref_clks.nssc);
+ MISSING_CASE(display->dpll.ref_clks.nssc);
fallthrough;
case 19200:
case 38400:
@@ -2615,9 +2744,9 @@ static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
break;
}
} else {
- switch (dev_priv->display.dpll.ref_clks.nssc) {
+ switch (display->dpll.ref_clks.nssc) {
default:
- MISSING_CASE(dev_priv->display.dpll.ref_clks.nssc);
+ MISSING_CASE(display->dpll.ref_clks.nssc);
fallthrough;
case 19200:
case 38400:
@@ -2632,22 +2761,22 @@ static int icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
return 0;
}
-static int icl_ddi_tbt_pll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int icl_ddi_tbt_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
/*
* The PLL outputs multiple frequencies at the same time, selection is
* made at DDI clock mux level.
*/
- drm_WARN_ON(&i915->drm, 1);
+ drm_WARN_ON(display->drm, 1);
return 0;
}
-static int icl_wrpll_ref_clock(struct drm_i915_private *i915)
+static int icl_wrpll_ref_clock(struct intel_display *display)
{
- int ref_clock = i915->display.dpll.ref_clks.nssc;
+ int ref_clock = display->dpll.ref_clks.nssc;
/*
* For ICL+, the spec states: if reference frequency is 38.4,
@@ -2663,8 +2792,8 @@ static int
icl_calc_wrpll(struct intel_crtc_state *crtc_state,
struct skl_wrpll_params *wrpll_params)
{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- int ref_clock = icl_wrpll_ref_clock(i915);
+ struct intel_display *display = to_intel_display(crtc_state);
+ int ref_clock = icl_wrpll_ref_clock(display);
u32 afe_clock = crtc_state->port_clock * 5;
u32 dco_min = 7998000;
u32 dco_max = 10000000;
@@ -2703,19 +2832,20 @@ icl_calc_wrpll(struct intel_crtc_state *crtc_state,
return 0;
}
-static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int icl_ddi_combo_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- int ref_clock = icl_wrpll_ref_clock(i915);
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
+ int ref_clock = icl_wrpll_ref_clock(display);
u32 dco_fraction;
u32 p0, p1, p2, dco_freq;
- p0 = pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
- p2 = pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
+ p0 = hw_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
+ p2 = hw_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
- if (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
- p1 = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
+ if (hw_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
+ p1 = (hw_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
DPLL_CFGCR1_QDIV_RATIO_SHIFT;
else
p1 = 1;
@@ -2747,52 +2877,53 @@ static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915,
break;
}
- dco_freq = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
+ dco_freq = (hw_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
ref_clock;
- dco_fraction = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
+ dco_fraction = (hw_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
DPLL_CFGCR0_DCO_FRACTION_SHIFT;
- if (ehl_combo_pll_div_frac_wa_needed(i915))
+ if (ehl_combo_pll_div_frac_wa_needed(display))
dco_fraction *= 2;
dco_freq += (dco_fraction * ref_clock) / 0x8000;
- if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0))
+ if (drm_WARN_ON(display->drm, p0 == 0 || p1 == 0 || p2 == 0))
return 0;
return dco_freq / (p0 * p1 * p2 * 5);
}
-static void icl_calc_dpll_state(struct drm_i915_private *i915,
+static void icl_calc_dpll_state(struct intel_display *display,
const struct skl_wrpll_params *pll_params,
- struct intel_dpll_hw_state *pll_state)
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
u32 dco_fraction = pll_params->dco_fraction;
- if (ehl_combo_pll_div_frac_wa_needed(i915))
+ if (ehl_combo_pll_div_frac_wa_needed(display))
dco_fraction = DIV_ROUND_CLOSEST(dco_fraction, 2);
- pll_state->cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(dco_fraction) |
+ hw_state->cfgcr0 = DPLL_CFGCR0_DCO_FRACTION(dco_fraction) |
pll_params->dco_integer;
- pll_state->cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params->qdiv_ratio) |
+ hw_state->cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(pll_params->qdiv_ratio) |
DPLL_CFGCR1_QDIV_MODE(pll_params->qdiv_mode) |
DPLL_CFGCR1_KDIV(pll_params->kdiv) |
DPLL_CFGCR1_PDIV(pll_params->pdiv);
- if (DISPLAY_VER(i915) >= 12)
- pll_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL;
+ if (DISPLAY_VER(display) >= 12)
+ hw_state->cfgcr1 |= TGL_DPLL_CFGCR1_CFSELOVRD_NORMAL_XTAL;
else
- pll_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
+ hw_state->cfgcr1 |= DPLL_CFGCR1_CENTRAL_FREQ_8400;
- if (i915->display.vbt.override_afc_startup)
- pll_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(i915->display.vbt.override_afc_startup_val);
+ if (display->vbt.override_afc_startup)
+ hw_state->div0 = TGL_DPLL0_DIV0_AFC_STARTUP(display->vbt.override_afc_startup_val);
}
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,
+ struct icl_dpll_hw_state *hw_state,
bool is_dkl)
{
static const u8 div1_vals[] = { 7, 5, 3, 2 };
@@ -2848,12 +2979,12 @@ static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
*target_dco_khz = dco;
- state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
+ hw_state->mg_refclkin_ctl = MG_REFCLKIN_CTL_OD_2_MUX(1);
- state->mg_clktop2_coreclkctl1 =
+ hw_state->mg_clktop2_coreclkctl1 =
MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO(a_divratio);
- state->mg_clktop2_hsclkctl =
+ hw_state->mg_clktop2_hsclkctl =
MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL(tlinedrv) |
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL(inputsel) |
hsdiv |
@@ -2871,10 +3002,11 @@ static int icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
* adapted to integer-only calculation, that's why it looks so different.
*/
static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
- struct intel_dpll_hw_state *pll_state)
+ struct intel_dpll_hw_state *dpll_hw_state)
{
- struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
- int refclk_khz = dev_priv->display.dpll.ref_clks.nssc;
+ struct intel_display *display = to_intel_display(crtc_state);
+ struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
+ int refclk_khz = display->dpll.ref_clks.nssc;
int clock = crtc_state->port_clock;
u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
u32 iref_ndiv, iref_trim, iref_pulse_w;
@@ -2884,11 +3016,11 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
u64 tmp;
bool use_ssc = false;
bool is_dp = !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI);
- bool is_dkl = DISPLAY_VER(dev_priv) >= 12;
+ bool is_dkl = DISPLAY_VER(display) >= 12;
int ret;
ret = icl_mg_pll_find_divisors(clock, is_dp, use_ssc, &dco_khz,
- pll_state, is_dkl);
+ hw_state, is_dkl);
if (ret)
return ret;
@@ -2978,61 +3110,61 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
/* write pll_state calculations */
if (is_dkl) {
- pll_state->mg_pll_div0 = DKL_PLL_DIV0_INTEG_COEFF(int_coeff) |
+ hw_state->mg_pll_div0 = DKL_PLL_DIV0_INTEG_COEFF(int_coeff) |
DKL_PLL_DIV0_PROP_COEFF(prop_coeff) |
DKL_PLL_DIV0_FBPREDIV(m1div) |
DKL_PLL_DIV0_FBDIV_INT(m2div_int);
- if (dev_priv->display.vbt.override_afc_startup) {
- u8 val = dev_priv->display.vbt.override_afc_startup_val;
+ if (display->vbt.override_afc_startup) {
+ u8 val = display->vbt.override_afc_startup_val;
- pll_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val);
+ hw_state->mg_pll_div0 |= DKL_PLL_DIV0_AFC_STARTUP(val);
}
- pll_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
+ hw_state->mg_pll_div1 = DKL_PLL_DIV1_IREF_TRIM(iref_trim) |
DKL_PLL_DIV1_TDC_TARGET_CNT(tdc_targetcnt);
- pll_state->mg_pll_ssc = DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) |
+ hw_state->mg_pll_ssc = DKL_PLL_SSC_IREF_NDIV_RATIO(iref_ndiv) |
DKL_PLL_SSC_STEP_LEN(ssc_steplen) |
DKL_PLL_SSC_STEP_NUM(ssc_steplog) |
(use_ssc ? DKL_PLL_SSC_EN : 0);
- pll_state->mg_pll_bias = (m2div_frac ? DKL_PLL_BIAS_FRAC_EN_H : 0) |
+ hw_state->mg_pll_bias = (m2div_frac ? DKL_PLL_BIAS_FRAC_EN_H : 0) |
DKL_PLL_BIAS_FBDIV_FRAC(m2div_frac);
- pll_state->mg_pll_tdc_coldst_bias =
+ hw_state->mg_pll_tdc_coldst_bias =
DKL_PLL_TDC_SSC_STEP_SIZE(ssc_stepsize) |
DKL_PLL_TDC_FEED_FWD_GAIN(feedfwgain);
} else {
- pll_state->mg_pll_div0 =
+ hw_state->mg_pll_div0 =
(m2div_rem > 0 ? MG_PLL_DIV0_FRACNEN_H : 0) |
MG_PLL_DIV0_FBDIV_FRAC(m2div_frac) |
MG_PLL_DIV0_FBDIV_INT(m2div_int);
- pll_state->mg_pll_div1 =
+ hw_state->mg_pll_div1 =
MG_PLL_DIV1_IREF_NDIVRATIO(iref_ndiv) |
MG_PLL_DIV1_DITHER_DIV_2 |
MG_PLL_DIV1_NDIVRATIO(1) |
MG_PLL_DIV1_FBPREDIV(m1div);
- pll_state->mg_pll_lf =
+ hw_state->mg_pll_lf =
MG_PLL_LF_TDCTARGETCNT(tdc_targetcnt) |
MG_PLL_LF_AFCCNTSEL_512 |
MG_PLL_LF_GAINCTRL(1) |
MG_PLL_LF_INT_COEFF(int_coeff) |
MG_PLL_LF_PROP_COEFF(prop_coeff);
- pll_state->mg_pll_frac_lock =
+ hw_state->mg_pll_frac_lock =
MG_PLL_FRAC_LOCK_TRUELOCK_CRIT_32 |
MG_PLL_FRAC_LOCK_EARLYLOCK_CRIT_32 |
MG_PLL_FRAC_LOCK_LOCKTHRESH(10) |
MG_PLL_FRAC_LOCK_DCODITHEREN |
MG_PLL_FRAC_LOCK_FEEDFWRDGAIN(feedfwgain);
if (use_ssc || m2div_rem > 0)
- pll_state->mg_pll_frac_lock |=
+ hw_state->mg_pll_frac_lock |=
MG_PLL_FRAC_LOCK_FEEDFWRDCAL_EN;
- pll_state->mg_pll_ssc =
+ hw_state->mg_pll_ssc =
(use_ssc ? MG_PLL_SSC_EN : 0) |
MG_PLL_SSC_TYPE(2) |
MG_PLL_SSC_STEPLENGTH(ssc_steplen) |
@@ -3040,14 +3172,14 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
MG_PLL_SSC_FLLEN |
MG_PLL_SSC_STEPSIZE(ssc_stepsize);
- pll_state->mg_pll_tdc_coldst_bias =
+ hw_state->mg_pll_tdc_coldst_bias =
MG_PLL_TDC_COLDST_COLDSTART |
MG_PLL_TDC_COLDST_IREFINT_EN |
MG_PLL_TDC_COLDST_REFBIAS_START_PULSE_W(iref_pulse_w) |
MG_PLL_TDC_TDCOVCCORR_EN |
MG_PLL_TDC_TDCSEL(3);
- pll_state->mg_pll_bias =
+ hw_state->mg_pll_bias =
MG_PLL_BIAS_BIAS_GB_SEL(3) |
MG_PLL_BIAS_INIT_DCOAMP(0x3F) |
MG_PLL_BIAS_BIAS_BONUS(10) |
@@ -3057,49 +3189,50 @@ static int icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
MG_PLL_BIAS_IREFTRIM(iref_trim);
if (refclk_khz == 38400) {
- pll_state->mg_pll_tdc_coldst_bias_mask =
+ hw_state->mg_pll_tdc_coldst_bias_mask =
MG_PLL_TDC_COLDST_COLDSTART;
- pll_state->mg_pll_bias_mask = 0;
+ hw_state->mg_pll_bias_mask = 0;
} else {
- pll_state->mg_pll_tdc_coldst_bias_mask = -1U;
- pll_state->mg_pll_bias_mask = -1U;
+ hw_state->mg_pll_tdc_coldst_bias_mask = -1U;
+ hw_state->mg_pll_bias_mask = -1U;
}
- pll_state->mg_pll_tdc_coldst_bias &=
- pll_state->mg_pll_tdc_coldst_bias_mask;
- pll_state->mg_pll_bias &= pll_state->mg_pll_bias_mask;
+ hw_state->mg_pll_tdc_coldst_bias &=
+ hw_state->mg_pll_tdc_coldst_bias_mask;
+ hw_state->mg_pll_bias &= hw_state->mg_pll_bias_mask;
}
return 0;
}
-static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *dev_priv,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+static int icl_ddi_mg_pll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
u32 m1, m2_int, m2_frac, div1, div2, ref_clock;
u64 tmp;
- ref_clock = dev_priv->display.dpll.ref_clks.nssc;
+ ref_clock = display->dpll.ref_clks.nssc;
- if (DISPLAY_VER(dev_priv) >= 12) {
- m1 = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
+ if (DISPLAY_VER(display) >= 12) {
+ m1 = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBPREDIV_MASK;
m1 = m1 >> DKL_PLL_DIV0_FBPREDIV_SHIFT;
- m2_int = pll_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
+ m2_int = hw_state->mg_pll_div0 & DKL_PLL_DIV0_FBDIV_INT_MASK;
- if (pll_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
- m2_frac = pll_state->mg_pll_bias &
+ if (hw_state->mg_pll_bias & DKL_PLL_BIAS_FRAC_EN_H) {
+ m2_frac = hw_state->mg_pll_bias &
DKL_PLL_BIAS_FBDIV_FRAC_MASK;
m2_frac = m2_frac >> DKL_PLL_BIAS_FBDIV_SHIFT;
} else {
m2_frac = 0;
}
} else {
- m1 = pll_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
- m2_int = pll_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
+ m1 = hw_state->mg_pll_div1 & MG_PLL_DIV1_FBPREDIV_MASK;
+ m2_int = hw_state->mg_pll_div0 & MG_PLL_DIV0_FBDIV_INT_MASK;
- if (pll_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
- m2_frac = pll_state->mg_pll_div0 &
+ if (hw_state->mg_pll_div0 & MG_PLL_DIV0_FRACNEN_H) {
+ m2_frac = hw_state->mg_pll_div0 &
MG_PLL_DIV0_FBDIV_FRAC_MASK;
m2_frac = m2_frac >> MG_PLL_DIV0_FBDIV_FRAC_SHIFT;
} else {
@@ -3107,7 +3240,7 @@ static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *dev_priv,
}
}
- switch (pll_state->mg_clktop2_hsclkctl &
+ switch (hw_state->mg_clktop2_hsclkctl &
MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK) {
case MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2:
div1 = 2;
@@ -3122,11 +3255,11 @@ static int icl_ddi_mg_pll_get_freq(struct drm_i915_private *dev_priv,
div1 = 7;
break;
default:
- MISSING_CASE(pll_state->mg_clktop2_hsclkctl);
+ MISSING_CASE(hw_state->mg_clktop2_hsclkctl);
return 0;
}
- div2 = (pll_state->mg_clktop2_hsclkctl &
+ div2 = (hw_state->mg_clktop2_hsclkctl &
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK) >>
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_SHIFT;
@@ -3159,7 +3292,7 @@ void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
struct icl_port_dpll *port_dpll =
&crtc_state->icl_port_dplls[port_dpll_id];
- crtc_state->shared_dpll = port_dpll->pll;
+ crtc_state->intel_dpll = port_dpll->pll;
crtc_state->dpll_hw_state = port_dpll->hw_state;
}
@@ -3184,18 +3317,10 @@ static void icl_update_active_dpll(struct intel_atomic_state *state,
icl_set_active_port_dpll(crtc_state, port_dpll_id);
}
-static u32 intel_get_hti_plls(struct drm_i915_private *i915)
-{
- if (!(i915->hti_state & HDPORT_ENABLED))
- return 0;
-
- return REG_FIELD_GET(HDPORT_DPLL_USED_MASK, i915->hti_state);
-}
-
static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct icl_port_dpll *port_dpll =
@@ -3212,12 +3337,12 @@ static int icl_compute_combo_phy_dpll(struct intel_atomic_state *state,
if (ret)
return ret;
- icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
+ icl_calc_dpll_state(display, &pll_params, &port_dpll->hw_state);
/* this is mainly for the fastset check */
icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
- crtc_state->port_clock = icl_ddi_combo_pll_get_freq(dev_priv, NULL,
+ crtc_state->port_clock = icl_ddi_combo_pll_get_freq(display, NULL,
&port_dpll->hw_state);
return 0;
@@ -3227,7 +3352,7 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
{
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct intel_display *display = to_intel_display(crtc);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
struct icl_port_dpll *port_dpll =
@@ -3235,13 +3360,13 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
enum port port = encoder->port;
unsigned long dpll_mask;
- if (IS_ALDERLAKE_S(dev_priv)) {
+ if (display->platform.alderlake_s) {
dpll_mask =
BIT(DPLL_ID_DG1_DPLL3) |
BIT(DPLL_ID_DG1_DPLL2) |
BIT(DPLL_ID_ICL_DPLL1) |
BIT(DPLL_ID_ICL_DPLL0);
- } else if (IS_DG1(dev_priv)) {
+ } else if (display->platform.dg1) {
if (port == PORT_D || port == PORT_E) {
dpll_mask =
BIT(DPLL_ID_DG1_DPLL2) |
@@ -3251,12 +3376,14 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
BIT(DPLL_ID_DG1_DPLL0) |
BIT(DPLL_ID_DG1_DPLL1);
}
- } else if (IS_ROCKETLAKE(dev_priv)) {
+ } else if (display->platform.rocketlake) {
dpll_mask =
BIT(DPLL_ID_EHL_DPLL4) |
BIT(DPLL_ID_ICL_DPLL1) |
BIT(DPLL_ID_ICL_DPLL0);
- } else if (IS_JSL_EHL(dev_priv) && port != PORT_A) {
+ } else if ((display->platform.jasperlake ||
+ display->platform.elkhartlake) &&
+ port != PORT_A) {
dpll_mask =
BIT(DPLL_ID_EHL_DPLL4) |
BIT(DPLL_ID_ICL_DPLL1) |
@@ -3266,16 +3393,16 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
}
/* Eliminate DPLLs from consideration if reserved by HTI */
- dpll_mask &= ~intel_get_hti_plls(dev_priv);
+ dpll_mask &= ~intel_hti_dpll_mask(display);
- port_dpll->pll = intel_find_shared_dpll(state, crtc,
- &port_dpll->hw_state,
- dpll_mask);
+ port_dpll->pll = intel_find_dpll(state, crtc,
+ &port_dpll->hw_state,
+ dpll_mask);
if (!port_dpll->pll)
return -EINVAL;
- intel_reference_shared_dpll(state, crtc,
- port_dpll->pll, &port_dpll->hw_state);
+ intel_reference_dpll(state, crtc,
+ port_dpll->pll, &port_dpll->hw_state);
icl_update_active_dpll(state, crtc, encoder);
@@ -3285,9 +3412,11 @@ static int icl_get_combo_phy_dpll(struct intel_atomic_state *state,
static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+ struct intel_display *display = to_intel_display(state);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
struct icl_port_dpll *port_dpll =
&crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
struct skl_wrpll_params pll_params = {};
@@ -3298,7 +3427,7 @@ static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state,
if (ret)
return ret;
- icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
+ icl_calc_dpll_state(display, &pll_params, &port_dpll->hw_state);
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
ret = icl_calc_mg_pll_state(crtc_state, &port_dpll->hw_state);
@@ -3306,9 +3435,13 @@ static int icl_compute_tc_phy_dplls(struct intel_atomic_state *state,
return ret;
/* this is mainly for the fastset check */
- icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
+ if (old_crtc_state->intel_dpll &&
+ old_crtc_state->intel_dpll->info->id == DPLL_ID_ICL_TBTPLL)
+ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
+ else
+ icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
- crtc_state->port_clock = icl_ddi_mg_pll_get_freq(dev_priv, NULL,
+ crtc_state->port_clock = icl_ddi_mg_pll_get_freq(display, NULL,
&port_dpll->hw_state);
return 0;
@@ -3318,7 +3451,6 @@ 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 =
intel_atomic_get_new_crtc_state(state, crtc);
struct icl_port_dpll *port_dpll =
@@ -3327,27 +3459,25 @@ static int icl_get_tc_phy_dplls(struct intel_atomic_state *state,
int ret;
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
- port_dpll->pll = intel_find_shared_dpll(state, crtc,
- &port_dpll->hw_state,
- BIT(DPLL_ID_ICL_TBTPLL));
+ port_dpll->pll = intel_find_dpll(state, crtc,
+ &port_dpll->hw_state,
+ BIT(DPLL_ID_ICL_TBTPLL));
if (!port_dpll->pll)
return -EINVAL;
- intel_reference_shared_dpll(state, crtc,
- port_dpll->pll, &port_dpll->hw_state);
-
+ intel_reference_dpll(state, crtc,
+ port_dpll->pll, &port_dpll->hw_state);
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
- dpll_id = icl_tc_port_to_pll_id(intel_port_to_tc(dev_priv,
- encoder->port));
- port_dpll->pll = intel_find_shared_dpll(state, crtc,
- &port_dpll->hw_state,
- BIT(dpll_id));
+ dpll_id = icl_tc_port_to_pll_id(intel_encoder_to_tc(encoder));
+ port_dpll->pll = intel_find_dpll(state, crtc,
+ &port_dpll->hw_state,
+ BIT(dpll_id));
if (!port_dpll->pll) {
ret = -EINVAL;
goto err_unreference_tbt_pll;
}
- intel_reference_shared_dpll(state, crtc,
- port_dpll->pll, &port_dpll->hw_state);
+ intel_reference_dpll(state, crtc,
+ port_dpll->pll, &port_dpll->hw_state);
icl_update_active_dpll(state, crtc, encoder);
@@ -3355,7 +3485,7 @@ static int icl_get_tc_phy_dplls(struct intel_atomic_state *state,
err_unreference_tbt_pll:
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
- intel_unreference_shared_dpll(state, crtc, port_dpll->pll);
+ intel_unreference_dpll(state, crtc, port_dpll->pll);
return ret;
}
@@ -3364,15 +3494,12 @@ static int icl_compute_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);
-
- if (intel_phy_is_combo(dev_priv, phy))
+ if (intel_encoder_is_combo(encoder))
return icl_compute_combo_phy_dpll(state, crtc);
- else if (intel_phy_is_tc(dev_priv, phy))
+ else if (intel_encoder_is_tc(encoder))
return icl_compute_tc_phy_dplls(state, crtc);
- MISSING_CASE(phy);
+ MISSING_CASE(encoder->port);
return 0;
}
@@ -3381,15 +3508,12 @@ 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);
-
- if (intel_phy_is_combo(dev_priv, phy))
+ if (intel_encoder_is_combo(encoder))
return icl_get_combo_phy_dpll(state, crtc, encoder);
- else if (intel_phy_is_tc(dev_priv, phy))
+ else if (intel_encoder_is_tc(encoder))
return icl_get_tc_phy_dplls(state, crtc, encoder);
- MISSING_CASE(phy);
+ MISSING_CASE(encoder->port);
return -EINVAL;
}
@@ -3403,7 +3527,7 @@ static void icl_put_dplls(struct intel_atomic_state *state,
intel_atomic_get_new_crtc_state(state, crtc);
enum icl_port_dpll_id id;
- new_crtc_state->shared_dpll = NULL;
+ new_crtc_state->intel_dpll = NULL;
for (id = ICL_PORT_DPLL_DEFAULT; id < ICL_PORT_DPLL_COUNT; id++) {
const struct icl_port_dpll *old_port_dpll =
@@ -3416,60 +3540,61 @@ static void icl_put_dplls(struct intel_atomic_state *state,
if (!old_port_dpll->pll)
continue;
- intel_unreference_shared_dpll(state, crtc, old_port_dpll->pll);
+ intel_unreference_dpll(state, crtc, old_port_dpll->pll);
}
}
-static bool mg_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool mg_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
const enum intel_dpll_id id = pll->info->id;
enum tc_port tc_port = icl_pll_id_to_tc_port(id);
intel_wakeref_t wakeref;
bool ret = false;
u32 val;
- i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, enable_reg);
+ val = intel_de_read(display, enable_reg);
if (!(val & PLL_ENABLE))
goto out;
- hw_state->mg_refclkin_ctl = intel_de_read(dev_priv,
+ hw_state->mg_refclkin_ctl = intel_de_read(display,
MG_REFCLKIN_CTL(tc_port));
hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
hw_state->mg_clktop2_coreclkctl1 =
- intel_de_read(dev_priv, MG_CLKTOP2_CORECLKCTL1(tc_port));
+ intel_de_read(display, MG_CLKTOP2_CORECLKCTL1(tc_port));
hw_state->mg_clktop2_coreclkctl1 &=
MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
hw_state->mg_clktop2_hsclkctl =
- intel_de_read(dev_priv, MG_CLKTOP2_HSCLKCTL(tc_port));
+ intel_de_read(display, MG_CLKTOP2_HSCLKCTL(tc_port));
hw_state->mg_clktop2_hsclkctl &=
MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
- hw_state->mg_pll_div0 = intel_de_read(dev_priv, MG_PLL_DIV0(tc_port));
- hw_state->mg_pll_div1 = intel_de_read(dev_priv, MG_PLL_DIV1(tc_port));
- hw_state->mg_pll_lf = intel_de_read(dev_priv, MG_PLL_LF(tc_port));
- hw_state->mg_pll_frac_lock = intel_de_read(dev_priv,
+ hw_state->mg_pll_div0 = intel_de_read(display, MG_PLL_DIV0(tc_port));
+ hw_state->mg_pll_div1 = intel_de_read(display, MG_PLL_DIV1(tc_port));
+ hw_state->mg_pll_lf = intel_de_read(display, MG_PLL_LF(tc_port));
+ hw_state->mg_pll_frac_lock = intel_de_read(display,
MG_PLL_FRAC_LOCK(tc_port));
- hw_state->mg_pll_ssc = intel_de_read(dev_priv, MG_PLL_SSC(tc_port));
+ hw_state->mg_pll_ssc = intel_de_read(display, MG_PLL_SSC(tc_port));
- hw_state->mg_pll_bias = intel_de_read(dev_priv, MG_PLL_BIAS(tc_port));
+ hw_state->mg_pll_bias = intel_de_read(display, MG_PLL_BIAS(tc_port));
hw_state->mg_pll_tdc_coldst_bias =
- intel_de_read(dev_priv, MG_PLL_TDC_COLDST_BIAS(tc_port));
+ intel_de_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port));
- if (dev_priv->display.dpll.ref_clks.nssc == 38400) {
+ if (display->dpll.ref_clks.nssc == 38400) {
hw_state->mg_pll_tdc_coldst_bias_mask = MG_PLL_TDC_COLDST_COLDSTART;
hw_state->mg_pll_bias_mask = 0;
} else {
@@ -3482,26 +3607,27 @@ static bool mg_pll_get_hw_state(struct drm_i915_private *dev_priv,
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
-static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool dkl_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
+ struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
const enum intel_dpll_id id = pll->info->id;
enum tc_port tc_port = icl_pll_id_to_tc_port(id);
intel_wakeref_t wakeref;
bool ret = false;
u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, intel_tc_pll_enable_reg(dev_priv, pll));
+ val = intel_de_read(display, intel_tc_pll_enable_reg(display, pll));
if (!(val & PLL_ENABLE))
goto out;
@@ -3509,12 +3635,12 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
* All registers read here have the same HIP_INDEX_REG even though
* they are on different building blocks
*/
- hw_state->mg_refclkin_ctl = intel_dkl_phy_read(dev_priv,
- DKL_REFCLKIN_CTL(tc_port), 2);
+ hw_state->mg_refclkin_ctl = intel_dkl_phy_read(display,
+ DKL_REFCLKIN_CTL(tc_port));
hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
hw_state->mg_clktop2_hsclkctl =
- intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2);
+ intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port));
hw_state->mg_clktop2_hsclkctl &=
MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
@@ -3522,138 +3648,141 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
hw_state->mg_clktop2_coreclkctl1 =
- intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2);
+ intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port));
hw_state->mg_clktop2_coreclkctl1 &=
MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
- hw_state->mg_pll_div0 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV0(tc_port), 2);
+ hw_state->mg_pll_div0 = intel_dkl_phy_read(display, DKL_PLL_DIV0(tc_port));
val = DKL_PLL_DIV0_MASK;
- if (dev_priv->display.vbt.override_afc_startup)
+ if (display->vbt.override_afc_startup)
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
hw_state->mg_pll_div0 &= val;
- hw_state->mg_pll_div1 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port), 2);
+ hw_state->mg_pll_div1 = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port));
hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
- hw_state->mg_pll_ssc = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port), 2);
+ hw_state->mg_pll_ssc = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port));
hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
DKL_PLL_SSC_STEP_LEN_MASK |
DKL_PLL_SSC_STEP_NUM_MASK |
DKL_PLL_SSC_EN);
- hw_state->mg_pll_bias = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port), 2);
+ hw_state->mg_pll_bias = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port));
hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H |
DKL_PLL_BIAS_FBDIV_FRAC_MASK);
hw_state->mg_pll_tdc_coldst_bias =
- intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2);
+ intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
-static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state,
+static bool icl_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state,
i915_reg_t enable_reg)
{
+ struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
const enum intel_dpll_id id = pll->info->id;
intel_wakeref_t wakeref;
bool ret = false;
u32 val;
- wakeref = intel_display_power_get_if_enabled(dev_priv,
+ wakeref = intel_display_power_get_if_enabled(display,
POWER_DOMAIN_DISPLAY_CORE);
if (!wakeref)
return false;
- val = intel_de_read(dev_priv, enable_reg);
+ val = intel_de_read(display, enable_reg);
if (!(val & PLL_ENABLE))
goto out;
- if (IS_ALDERLAKE_S(dev_priv)) {
- hw_state->cfgcr0 = intel_de_read(dev_priv, ADLS_DPLL_CFGCR0(id));
- hw_state->cfgcr1 = intel_de_read(dev_priv, ADLS_DPLL_CFGCR1(id));
- } else if (IS_DG1(dev_priv)) {
- hw_state->cfgcr0 = intel_de_read(dev_priv, DG1_DPLL_CFGCR0(id));
- hw_state->cfgcr1 = intel_de_read(dev_priv, DG1_DPLL_CFGCR1(id));
- } else if (IS_ROCKETLAKE(dev_priv)) {
- hw_state->cfgcr0 = intel_de_read(dev_priv,
+ if (display->platform.alderlake_s) {
+ hw_state->cfgcr0 = intel_de_read(display, ADLS_DPLL_CFGCR0(id));
+ hw_state->cfgcr1 = intel_de_read(display, ADLS_DPLL_CFGCR1(id));
+ } else if (display->platform.dg1) {
+ hw_state->cfgcr0 = intel_de_read(display, DG1_DPLL_CFGCR0(id));
+ hw_state->cfgcr1 = intel_de_read(display, DG1_DPLL_CFGCR1(id));
+ } else if (display->platform.rocketlake) {
+ hw_state->cfgcr0 = intel_de_read(display,
RKL_DPLL_CFGCR0(id));
- hw_state->cfgcr1 = intel_de_read(dev_priv,
+ hw_state->cfgcr1 = intel_de_read(display,
RKL_DPLL_CFGCR1(id));
- } else if (DISPLAY_VER(dev_priv) >= 12) {
- hw_state->cfgcr0 = intel_de_read(dev_priv,
+ } else if (DISPLAY_VER(display) >= 12) {
+ hw_state->cfgcr0 = intel_de_read(display,
TGL_DPLL_CFGCR0(id));
- hw_state->cfgcr1 = intel_de_read(dev_priv,
+ hw_state->cfgcr1 = intel_de_read(display,
TGL_DPLL_CFGCR1(id));
- if (dev_priv->display.vbt.override_afc_startup) {
- hw_state->div0 = intel_de_read(dev_priv, TGL_DPLL0_DIV0(id));
+ if (display->vbt.override_afc_startup) {
+ hw_state->div0 = intel_de_read(display, TGL_DPLL0_DIV0(id));
hw_state->div0 &= TGL_DPLL0_DIV0_AFC_STARTUP_MASK;
}
} else {
- if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
- hw_state->cfgcr0 = intel_de_read(dev_priv,
+ if ((display->platform.jasperlake || display->platform.elkhartlake) &&
+ id == DPLL_ID_EHL_DPLL4) {
+ hw_state->cfgcr0 = intel_de_read(display,
ICL_DPLL_CFGCR0(4));
- hw_state->cfgcr1 = intel_de_read(dev_priv,
+ hw_state->cfgcr1 = intel_de_read(display,
ICL_DPLL_CFGCR1(4));
} else {
- hw_state->cfgcr0 = intel_de_read(dev_priv,
+ hw_state->cfgcr0 = intel_de_read(display,
ICL_DPLL_CFGCR0(id));
- hw_state->cfgcr1 = intel_de_read(dev_priv,
+ hw_state->cfgcr1 = intel_de_read(display,
ICL_DPLL_CFGCR1(id));
}
}
ret = true;
out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
+ intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
return ret;
}
-static bool combo_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool combo_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
- i915_reg_t enable_reg = intel_combo_pll_enable_reg(dev_priv, pll);
+ i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
- return icl_pll_get_hw_state(dev_priv, pll, hw_state, enable_reg);
+ return icl_pll_get_hw_state(display, pll, dpll_hw_state, enable_reg);
}
-static bool tbt_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+static bool tbt_pll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
- return icl_pll_get_hw_state(dev_priv, pll, hw_state, TBT_PLL_ENABLE);
+ return icl_pll_get_hw_state(display, pll, dpll_hw_state, TBT_PLL_ENABLE);
}
-static void icl_dpll_write(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void icl_dpll_write(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct icl_dpll_hw_state *hw_state)
{
- struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
const enum intel_dpll_id id = pll->info->id;
i915_reg_t cfgcr0_reg, cfgcr1_reg, div0_reg = INVALID_MMIO_REG;
- if (IS_ALDERLAKE_S(dev_priv)) {
+ if (display->platform.alderlake_s) {
cfgcr0_reg = ADLS_DPLL_CFGCR0(id);
cfgcr1_reg = ADLS_DPLL_CFGCR1(id);
- } else if (IS_DG1(dev_priv)) {
+ } else if (display->platform.dg1) {
cfgcr0_reg = DG1_DPLL_CFGCR0(id);
cfgcr1_reg = DG1_DPLL_CFGCR1(id);
- } else if (IS_ROCKETLAKE(dev_priv)) {
+ } else if (display->platform.rocketlake) {
cfgcr0_reg = RKL_DPLL_CFGCR0(id);
cfgcr1_reg = RKL_DPLL_CFGCR1(id);
- } else if (DISPLAY_VER(dev_priv) >= 12) {
+ } else if (DISPLAY_VER(display) >= 12) {
cfgcr0_reg = TGL_DPLL_CFGCR0(id);
cfgcr1_reg = TGL_DPLL_CFGCR1(id);
div0_reg = TGL_DPLL0_DIV0(id);
} else {
- if (IS_JSL_EHL(dev_priv) && id == DPLL_ID_EHL_DPLL4) {
+ if ((display->platform.jasperlake || display->platform.elkhartlake) &&
+ id == DPLL_ID_EHL_DPLL4) {
cfgcr0_reg = ICL_DPLL_CFGCR0(4);
cfgcr1_reg = ICL_DPLL_CFGCR1(4);
} else {
@@ -3662,23 +3791,22 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
}
}
- intel_de_write(dev_priv, cfgcr0_reg, hw_state->cfgcr0);
- intel_de_write(dev_priv, cfgcr1_reg, hw_state->cfgcr1);
- drm_WARN_ON_ONCE(&dev_priv->drm, dev_priv->display.vbt.override_afc_startup &&
+ intel_de_write(display, cfgcr0_reg, hw_state->cfgcr0);
+ intel_de_write(display, cfgcr1_reg, hw_state->cfgcr1);
+ drm_WARN_ON_ONCE(display->drm, display->vbt.override_afc_startup &&
!i915_mmio_reg_valid(div0_reg));
- if (dev_priv->display.vbt.override_afc_startup &&
+ if (display->vbt.override_afc_startup &&
i915_mmio_reg_valid(div0_reg))
- intel_de_rmw(dev_priv, div0_reg, TGL_DPLL0_DIV0_AFC_STARTUP_MASK,
- hw_state->div0);
- intel_de_posting_read(dev_priv, cfgcr1_reg);
+ intel_de_rmw(display, div0_reg,
+ TGL_DPLL0_DIV0_AFC_STARTUP_MASK, hw_state->div0);
+ intel_de_posting_read(display, cfgcr1_reg);
}
-static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void icl_mg_pll_write(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct icl_dpll_hw_state *hw_state)
{
- struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
enum tc_port tc_port = icl_pll_id_to_tc_port(pll->info->id);
- u32 val;
/*
* Some of the following registers have reserved fields, so program
@@ -3686,48 +3814,41 @@ static void icl_mg_pll_write(struct drm_i915_private *dev_priv,
* during the calc/readout phase if the mask depends on some other HW
* state like refclk, see icl_calc_mg_pll_state().
*/
- val = intel_de_read(dev_priv, MG_REFCLKIN_CTL(tc_port));
- val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
- val |= hw_state->mg_refclkin_ctl;
- intel_de_write(dev_priv, MG_REFCLKIN_CTL(tc_port), val);
-
- val = intel_de_read(dev_priv, MG_CLKTOP2_CORECLKCTL1(tc_port));
- val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
- val |= hw_state->mg_clktop2_coreclkctl1;
- intel_de_write(dev_priv, MG_CLKTOP2_CORECLKCTL1(tc_port), val);
-
- val = intel_de_read(dev_priv, MG_CLKTOP2_HSCLKCTL(tc_port));
- val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
- MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
- MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
- MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
- val |= hw_state->mg_clktop2_hsclkctl;
- intel_de_write(dev_priv, MG_CLKTOP2_HSCLKCTL(tc_port), val);
-
- intel_de_write(dev_priv, MG_PLL_DIV0(tc_port), hw_state->mg_pll_div0);
- intel_de_write(dev_priv, MG_PLL_DIV1(tc_port), hw_state->mg_pll_div1);
- intel_de_write(dev_priv, MG_PLL_LF(tc_port), hw_state->mg_pll_lf);
- intel_de_write(dev_priv, MG_PLL_FRAC_LOCK(tc_port),
+ intel_de_rmw(display, MG_REFCLKIN_CTL(tc_port),
+ MG_REFCLKIN_CTL_OD_2_MUX_MASK, hw_state->mg_refclkin_ctl);
+
+ intel_de_rmw(display, MG_CLKTOP2_CORECLKCTL1(tc_port),
+ MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK,
+ hw_state->mg_clktop2_coreclkctl1);
+
+ intel_de_rmw(display, MG_CLKTOP2_HSCLKCTL(tc_port),
+ MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
+ MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
+ MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
+ MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK,
+ hw_state->mg_clktop2_hsclkctl);
+
+ intel_de_write(display, MG_PLL_DIV0(tc_port), hw_state->mg_pll_div0);
+ intel_de_write(display, MG_PLL_DIV1(tc_port), hw_state->mg_pll_div1);
+ intel_de_write(display, MG_PLL_LF(tc_port), hw_state->mg_pll_lf);
+ intel_de_write(display, MG_PLL_FRAC_LOCK(tc_port),
hw_state->mg_pll_frac_lock);
- intel_de_write(dev_priv, MG_PLL_SSC(tc_port), hw_state->mg_pll_ssc);
+ intel_de_write(display, MG_PLL_SSC(tc_port), hw_state->mg_pll_ssc);
- val = intel_de_read(dev_priv, MG_PLL_BIAS(tc_port));
- val &= ~hw_state->mg_pll_bias_mask;
- val |= hw_state->mg_pll_bias;
- intel_de_write(dev_priv, MG_PLL_BIAS(tc_port), val);
+ intel_de_rmw(display, MG_PLL_BIAS(tc_port),
+ hw_state->mg_pll_bias_mask, hw_state->mg_pll_bias);
- val = intel_de_read(dev_priv, MG_PLL_TDC_COLDST_BIAS(tc_port));
- val &= ~hw_state->mg_pll_tdc_coldst_bias_mask;
- val |= hw_state->mg_pll_tdc_coldst_bias;
- intel_de_write(dev_priv, MG_PLL_TDC_COLDST_BIAS(tc_port), val);
+ intel_de_rmw(display, MG_PLL_TDC_COLDST_BIAS(tc_port),
+ hw_state->mg_pll_tdc_coldst_bias_mask,
+ hw_state->mg_pll_tdc_coldst_bias);
- intel_de_posting_read(dev_priv, MG_PLL_TDC_COLDST_BIAS(tc_port));
+ intel_de_posting_read(display, MG_PLL_TDC_COLDST_BIAS(tc_port));
}
-static void dkl_pll_write(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void dkl_pll_write(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct icl_dpll_hw_state *hw_state)
{
- struct intel_dpll_hw_state *hw_state = &pll->state.hw_state;
enum tc_port tc_port = icl_pll_id_to_tc_port(pll->info->id);
u32 val;
@@ -3736,98 +3857,90 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv,
* though on different building block
*/
/* All the registers are RMW */
- val = intel_dkl_phy_read(dev_priv, DKL_REFCLKIN_CTL(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_REFCLKIN_CTL(tc_port));
val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
val |= hw_state->mg_refclkin_ctl;
- intel_dkl_phy_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_REFCLKIN_CTL(tc_port), val);
- val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_CLKTOP2_CORECLKCTL1(tc_port));
val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
val |= hw_state->mg_clktop2_coreclkctl1;
- intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
- val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_CLKTOP2_HSCLKCTL(tc_port));
val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
val |= hw_state->mg_clktop2_hsclkctl;
- intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
val = DKL_PLL_DIV0_MASK;
- if (dev_priv->display.vbt.override_afc_startup)
+ if (display->vbt.override_afc_startup)
val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
- intel_dkl_phy_rmw(dev_priv, DKL_PLL_DIV0(tc_port), 2, val,
+ intel_dkl_phy_rmw(display, DKL_PLL_DIV0(tc_port), val,
hw_state->mg_pll_div0);
- val = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_PLL_DIV1(tc_port));
val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
val |= hw_state->mg_pll_div1;
- intel_dkl_phy_write(dev_priv, DKL_PLL_DIV1(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_PLL_DIV1(tc_port), val);
- val = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_PLL_SSC(tc_port));
val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
DKL_PLL_SSC_STEP_LEN_MASK |
DKL_PLL_SSC_STEP_NUM_MASK |
DKL_PLL_SSC_EN);
val |= hw_state->mg_pll_ssc;
- intel_dkl_phy_write(dev_priv, DKL_PLL_SSC(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_PLL_SSC(tc_port), val);
- val = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_PLL_BIAS(tc_port));
val &= ~(DKL_PLL_BIAS_FRAC_EN_H |
DKL_PLL_BIAS_FBDIV_FRAC_MASK);
val |= hw_state->mg_pll_bias;
- intel_dkl_phy_write(dev_priv, DKL_PLL_BIAS(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_PLL_BIAS(tc_port), val);
- val = intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2);
+ val = intel_dkl_phy_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
val |= hw_state->mg_pll_tdc_coldst_bias;
- intel_dkl_phy_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2, val);
+ intel_dkl_phy_write(display, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
- intel_dkl_phy_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2);
+ intel_dkl_phy_posting_read(display, DKL_PLL_TDC_COLDST_BIAS(tc_port));
}
-static void icl_pll_power_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
+static void icl_pll_power_enable(struct intel_display *display,
+ struct intel_dpll *pll,
i915_reg_t enable_reg)
{
- u32 val;
-
- val = intel_de_read(dev_priv, enable_reg);
- val |= PLL_POWER_ENABLE;
- intel_de_write(dev_priv, enable_reg, val);
+ intel_de_rmw(display, enable_reg, 0, PLL_POWER_ENABLE);
/*
* The spec says we need to "wait" but it also says it should be
* immediate.
*/
- if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_POWER_STATE, 1))
- drm_err(&dev_priv->drm, "PLL %d Power not enabled\n",
+ if (intel_de_wait_for_set_ms(display, enable_reg, PLL_POWER_STATE, 1))
+ drm_err(display->drm, "PLL %d Power not enabled\n",
pll->info->id);
}
-static void icl_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
+static void icl_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
i915_reg_t enable_reg)
{
- u32 val;
-
- val = intel_de_read(dev_priv, enable_reg);
- val |= PLL_ENABLE;
- intel_de_write(dev_priv, enable_reg, val);
+ intel_de_rmw(display, enable_reg, 0, PLL_ENABLE);
/* Timeout is actually 600us. */
- if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "PLL %d not locked\n", pll->info->id);
+ if (intel_de_wait_for_set_ms(display, enable_reg, PLL_LOCK, 1))
+ drm_err(display->drm, "PLL %d not locked\n", pll->info->id);
}
-static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct intel_shared_dpll *pll)
+static void adlp_cmtg_clock_gating_wa(struct intel_display *display, struct intel_dpll *pll)
{
u32 val;
- if (!IS_ADLP_DISPLAY_STEP(i915, STEP_A0, STEP_B0) ||
+ if (!(display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) ||
pll->info->id != DPLL_ID_ICL_DPLL0)
return;
/*
@@ -3841,33 +3954,22 @@ static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct inte
* Instead of the usual place for workarounds we apply this one here,
* since TRANS_CMTG_CHICKEN is only accessible while DPLL0 is enabled.
*/
- val = intel_de_read(i915, TRANS_CMTG_CHICKEN);
- val = intel_de_read(i915, TRANS_CMTG_CHICKEN);
- intel_de_write(i915, TRANS_CMTG_CHICKEN, DISABLE_DPT_CLK_GATING);
- if (drm_WARN_ON(&i915->drm, val & ~DISABLE_DPT_CLK_GATING))
- drm_dbg_kms(&i915->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val);
+ val = intel_de_read(display, TRANS_CMTG_CHICKEN);
+ val = intel_de_rmw(display, TRANS_CMTG_CHICKEN, ~0, DISABLE_DPT_CLK_GATING);
+ if (drm_WARN_ON(display->drm, val & ~DISABLE_DPT_CLK_GATING))
+ drm_dbg_kms(display->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val);
}
-static void combo_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void combo_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- i915_reg_t enable_reg = intel_combo_pll_enable_reg(dev_priv, pll);
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
+ i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
- if (IS_JSL_EHL(dev_priv) &&
- pll->info->id == DPLL_ID_EHL_DPLL4) {
+ icl_pll_power_enable(display, pll, enable_reg);
- /*
- * We need to disable DC states when this DPLL is enabled.
- * This can be done by taking a reference on DPLL4 power
- * domain.
- */
- pll->wakeref = intel_display_power_get(dev_priv,
- POWER_DOMAIN_DC_OFF);
- }
-
- icl_pll_power_enable(dev_priv, pll, enable_reg);
-
- icl_dpll_write(dev_priv, pll);
+ icl_dpll_write(display, pll, hw_state);
/*
* DVFS pre sequence would be here, but in our driver the cdclk code
@@ -3875,19 +3977,22 @@ static void combo_pll_enable(struct drm_i915_private *dev_priv,
* nothing here.
*/
- icl_pll_enable(dev_priv, pll, enable_reg);
+ icl_pll_enable(display, pll, enable_reg);
- adlp_cmtg_clock_gating_wa(dev_priv, pll);
+ adlp_cmtg_clock_gating_wa(display, pll);
/* DVFS post sequence would be here. See the comment above. */
}
-static void tbt_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void tbt_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- icl_pll_power_enable(dev_priv, pll, TBT_PLL_ENABLE);
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
- icl_dpll_write(dev_priv, pll);
+ icl_pll_power_enable(display, pll, TBT_PLL_ENABLE);
+
+ icl_dpll_write(display, pll, hw_state);
/*
* DVFS pre sequence would be here, but in our driver the cdclk code
@@ -3895,22 +4000,24 @@ static void tbt_pll_enable(struct drm_i915_private *dev_priv,
* nothing here.
*/
- icl_pll_enable(dev_priv, pll, TBT_PLL_ENABLE);
+ icl_pll_enable(display, pll, TBT_PLL_ENABLE);
/* DVFS post sequence would be here. See the comment above. */
}
-static void mg_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void mg_pll_enable(struct intel_display *display,
+ struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
- icl_pll_power_enable(dev_priv, pll, enable_reg);
+ icl_pll_power_enable(display, pll, enable_reg);
- if (DISPLAY_VER(dev_priv) >= 12)
- dkl_pll_write(dev_priv, pll);
+ if (DISPLAY_VER(display) >= 12)
+ dkl_pll_write(display, pll, hw_state);
else
- icl_mg_pll_write(dev_priv, pll);
+ icl_mg_pll_write(display, pll, hw_state);
/*
* DVFS pre sequence would be here, but in our driver the cdclk code
@@ -3918,17 +4025,15 @@ static void mg_pll_enable(struct drm_i915_private *dev_priv,
* nothing here.
*/
- icl_pll_enable(dev_priv, pll, enable_reg);
+ icl_pll_enable(display, pll, enable_reg);
/* DVFS post sequence would be here. See the comment above. */
}
-static void icl_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
+static void icl_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll,
i915_reg_t enable_reg)
{
- u32 val;
-
/* The first steps are done by intel_ddi_post_disable(). */
/*
@@ -3937,101 +4042,114 @@ static void icl_pll_disable(struct drm_i915_private *dev_priv,
* nothing here.
*/
- val = intel_de_read(dev_priv, enable_reg);
- val &= ~PLL_ENABLE;
- intel_de_write(dev_priv, enable_reg, val);
+ intel_de_rmw(display, enable_reg, PLL_ENABLE, 0);
/* Timeout is actually 1us. */
- if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 1))
- drm_err(&dev_priv->drm, "PLL %d locked\n", pll->info->id);
+ if (intel_de_wait_for_clear_ms(display, enable_reg, PLL_LOCK, 1))
+ drm_err(display->drm, "PLL %d locked\n", pll->info->id);
/* DVFS post sequence would be here. See the comment above. */
- val = intel_de_read(dev_priv, enable_reg);
- val &= ~PLL_POWER_ENABLE;
- intel_de_write(dev_priv, enable_reg, val);
+ intel_de_rmw(display, enable_reg, PLL_POWER_ENABLE, 0);
/*
* The spec says we need to "wait" but it also says it should be
* immediate.
*/
- if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_POWER_STATE, 1))
- drm_err(&dev_priv->drm, "PLL %d Power not disabled\n",
+ if (intel_de_wait_for_clear_ms(display, enable_reg, PLL_POWER_STATE, 1))
+ drm_err(display->drm, "PLL %d Power not disabled\n",
pll->info->id);
}
-static void combo_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void combo_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
- i915_reg_t enable_reg = intel_combo_pll_enable_reg(dev_priv, pll);
+ i915_reg_t enable_reg = intel_combo_pll_enable_reg(display, pll);
- icl_pll_disable(dev_priv, pll, enable_reg);
-
- if (IS_JSL_EHL(dev_priv) &&
- pll->info->id == DPLL_ID_EHL_DPLL4)
- intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF,
- pll->wakeref);
+ icl_pll_disable(display, pll, enable_reg);
}
-static void tbt_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void tbt_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
- icl_pll_disable(dev_priv, pll, TBT_PLL_ENABLE);
+ icl_pll_disable(display, pll, TBT_PLL_ENABLE);
}
-static void mg_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
+static void mg_pll_disable(struct intel_display *display,
+ struct intel_dpll *pll)
{
- i915_reg_t enable_reg = intel_tc_pll_enable_reg(dev_priv, pll);
+ i915_reg_t enable_reg = intel_tc_pll_enable_reg(display, pll);
- icl_pll_disable(dev_priv, pll, enable_reg);
+ icl_pll_disable(display, pll, enable_reg);
}
-static void icl_update_dpll_ref_clks(struct drm_i915_private *i915)
+static void icl_update_dpll_ref_clks(struct intel_display *display)
{
/* No SSC ref */
- i915->display.dpll.ref_clks.nssc = i915->display.cdclk.hw.ref;
-}
-
-static void icl_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
-{
- drm_dbg_kms(&dev_priv->drm,
- "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, div0: 0x%x, "
- "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
- "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
- "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
- "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
- "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
- hw_state->cfgcr0, hw_state->cfgcr1,
- hw_state->div0,
- hw_state->mg_refclkin_ctl,
- hw_state->mg_clktop2_coreclkctl1,
- hw_state->mg_clktop2_hsclkctl,
- hw_state->mg_pll_div0,
- hw_state->mg_pll_div1,
- hw_state->mg_pll_lf,
- hw_state->mg_pll_frac_lock,
- hw_state->mg_pll_ssc,
- hw_state->mg_pll_bias,
- hw_state->mg_pll_tdc_coldst_bias);
-}
-
-static const struct intel_shared_dpll_funcs combo_pll_funcs = {
+ display->dpll.ref_clks.nssc = display->cdclk.hw.ref;
+}
+
+static void icl_dump_hw_state(struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ const struct icl_dpll_hw_state *hw_state = &dpll_hw_state->icl;
+
+ drm_printf(p, "dpll_hw_state: cfgcr0: 0x%x, cfgcr1: 0x%x, div0: 0x%x, "
+ "mg_refclkin_ctl: 0x%x, hg_clktop2_coreclkctl1: 0x%x, "
+ "mg_clktop2_hsclkctl: 0x%x, mg_pll_div0: 0x%x, "
+ "mg_pll_div2: 0x%x, mg_pll_lf: 0x%x, "
+ "mg_pll_frac_lock: 0x%x, mg_pll_ssc: 0x%x, "
+ "mg_pll_bias: 0x%x, mg_pll_tdc_coldst_bias: 0x%x\n",
+ hw_state->cfgcr0, hw_state->cfgcr1, hw_state->div0,
+ hw_state->mg_refclkin_ctl,
+ hw_state->mg_clktop2_coreclkctl1,
+ hw_state->mg_clktop2_hsclkctl,
+ hw_state->mg_pll_div0,
+ hw_state->mg_pll_div1,
+ hw_state->mg_pll_lf,
+ hw_state->mg_pll_frac_lock,
+ hw_state->mg_pll_ssc,
+ hw_state->mg_pll_bias,
+ hw_state->mg_pll_tdc_coldst_bias);
+}
+
+static bool icl_compare_hw_state(const struct intel_dpll_hw_state *_a,
+ const struct intel_dpll_hw_state *_b)
+{
+ const struct icl_dpll_hw_state *a = &_a->icl;
+ const struct icl_dpll_hw_state *b = &_b->icl;
+
+ /* FIXME split combo vs. mg more thoroughly */
+ return a->cfgcr0 == b->cfgcr0 &&
+ a->cfgcr1 == b->cfgcr1 &&
+ a->div0 == b->div0 &&
+ a->mg_refclkin_ctl == b->mg_refclkin_ctl &&
+ a->mg_clktop2_coreclkctl1 == b->mg_clktop2_coreclkctl1 &&
+ a->mg_clktop2_hsclkctl == b->mg_clktop2_hsclkctl &&
+ a->mg_pll_div0 == b->mg_pll_div0 &&
+ a->mg_pll_div1 == b->mg_pll_div1 &&
+ a->mg_pll_lf == b->mg_pll_lf &&
+ a->mg_pll_frac_lock == b->mg_pll_frac_lock &&
+ a->mg_pll_ssc == b->mg_pll_ssc &&
+ a->mg_pll_bias == b->mg_pll_bias &&
+ a->mg_pll_tdc_coldst_bias == b->mg_pll_tdc_coldst_bias;
+}
+
+static const struct intel_dpll_funcs combo_pll_funcs = {
.enable = combo_pll_enable,
.disable = combo_pll_disable,
.get_hw_state = combo_pll_get_hw_state,
.get_freq = icl_ddi_combo_pll_get_freq,
};
-static const struct intel_shared_dpll_funcs tbt_pll_funcs = {
+static const struct intel_dpll_funcs tbt_pll_funcs = {
.enable = tbt_pll_enable,
.disable = tbt_pll_disable,
.get_hw_state = tbt_pll_get_hw_state,
.get_freq = icl_ddi_tbt_pll_get_freq,
};
-static const struct intel_shared_dpll_funcs mg_pll_funcs = {
+static const struct intel_dpll_funcs mg_pll_funcs = {
.enable = mg_pll_enable,
.disable = mg_pll_disable,
.get_hw_state = mg_pll_get_hw_state,
@@ -4039,14 +4157,15 @@ static const struct intel_shared_dpll_funcs mg_pll_funcs = {
};
static const struct dpll_info icl_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "TBT PLL", &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
- { "MG PLL 1", &mg_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
- { "MG PLL 2", &mg_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
- { "MG PLL 3", &mg_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
- { "MG PLL 4", &mg_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+ .is_alt_port_dpll = true, },
+ { .name = "MG PLL 1", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
+ { .name = "MG PLL 2", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
+ { .name = "MG PLL 3", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
+ { .name = "MG PLL 4", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
+ {}
};
static const struct intel_dpll_mgr icl_pll_mgr = {
@@ -4057,13 +4176,15 @@ static const struct intel_dpll_mgr icl_pll_mgr = {
.update_active_dpll = icl_update_active_dpll,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
static const struct dpll_info ehl_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "DPLL 4", &combo_pll_funcs, DPLL_ID_EHL_DPLL4, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "DPLL 4", .funcs = &combo_pll_funcs, .id = DPLL_ID_EHL_DPLL4,
+ .power_domain = POWER_DOMAIN_DC_OFF, },
+ {}
};
static const struct intel_dpll_mgr ehl_pll_mgr = {
@@ -4073,9 +4194,10 @@ static const struct intel_dpll_mgr ehl_pll_mgr = {
.put_dplls = icl_put_dplls,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
-static const struct intel_shared_dpll_funcs dkl_pll_funcs = {
+static const struct intel_dpll_funcs dkl_pll_funcs = {
.enable = mg_pll_enable,
.disable = mg_pll_disable,
.get_hw_state = dkl_pll_get_hw_state,
@@ -4083,16 +4205,17 @@ static const struct intel_shared_dpll_funcs dkl_pll_funcs = {
};
static const struct dpll_info tgl_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "TBT PLL", &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
- { "TC PLL 1", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
- { "TC PLL 2", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
- { "TC PLL 3", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
- { "TC PLL 4", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
- { "TC PLL 5", &dkl_pll_funcs, DPLL_ID_TGL_MGPLL5, 0 },
- { "TC PLL 6", &dkl_pll_funcs, DPLL_ID_TGL_MGPLL6, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+ .is_alt_port_dpll = true, },
+ { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
+ { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
+ { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
+ { .name = "TC PLL 4", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
+ { .name = "TC PLL 5", .funcs = &dkl_pll_funcs, .id = DPLL_ID_TGL_MGPLL5, },
+ { .name = "TC PLL 6", .funcs = &dkl_pll_funcs, .id = DPLL_ID_TGL_MGPLL6, },
+ {}
};
static const struct intel_dpll_mgr tgl_pll_mgr = {
@@ -4103,13 +4226,14 @@ static const struct intel_dpll_mgr tgl_pll_mgr = {
.update_active_dpll = icl_update_active_dpll,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
static const struct dpll_info rkl_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "DPLL 4", &combo_pll_funcs, DPLL_ID_EHL_DPLL4, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "DPLL 4", .funcs = &combo_pll_funcs, .id = DPLL_ID_EHL_DPLL4, },
+ {}
};
static const struct intel_dpll_mgr rkl_pll_mgr = {
@@ -4119,14 +4243,15 @@ static const struct intel_dpll_mgr rkl_pll_mgr = {
.put_dplls = icl_put_dplls,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
static const struct dpll_info dg1_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_DG1_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_DG1_DPLL1, 0 },
- { "DPLL 2", &combo_pll_funcs, DPLL_ID_DG1_DPLL2, 0 },
- { "DPLL 3", &combo_pll_funcs, DPLL_ID_DG1_DPLL3, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL1, },
+ { .name = "DPLL 2", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL2, },
+ { .name = "DPLL 3", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL3, },
+ {}
};
static const struct intel_dpll_mgr dg1_pll_mgr = {
@@ -4136,14 +4261,15 @@ static const struct intel_dpll_mgr dg1_pll_mgr = {
.put_dplls = icl_put_dplls,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
static const struct dpll_info adls_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "DPLL 2", &combo_pll_funcs, DPLL_ID_DG1_DPLL2, 0 },
- { "DPLL 3", &combo_pll_funcs, DPLL_ID_DG1_DPLL3, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "DPLL 2", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL2, },
+ { .name = "DPLL 3", .funcs = &combo_pll_funcs, .id = DPLL_ID_DG1_DPLL3, },
+ {}
};
static const struct intel_dpll_mgr adls_pll_mgr = {
@@ -4153,17 +4279,19 @@ static const struct intel_dpll_mgr adls_pll_mgr = {
.put_dplls = icl_put_dplls,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
static const struct dpll_info adlp_plls[] = {
- { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
- { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
- { "TBT PLL", &tbt_pll_funcs, DPLL_ID_ICL_TBTPLL, 0 },
- { "TC PLL 1", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL1, 0 },
- { "TC PLL 2", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL2, 0 },
- { "TC PLL 3", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL3, 0 },
- { "TC PLL 4", &dkl_pll_funcs, DPLL_ID_ICL_MGPLL4, 0 },
- { },
+ { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
+ { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
+ { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+ .is_alt_port_dpll = true, },
+ { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
+ { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
+ { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
+ { .name = "TC PLL 4", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL4, },
+ {}
};
static const struct intel_dpll_mgr adlp_pll_mgr = {
@@ -4174,69 +4302,73 @@ static const struct intel_dpll_mgr adlp_pll_mgr = {
.update_active_dpll = icl_update_active_dpll,
.update_ref_clks = icl_update_dpll_ref_clks,
.dump_hw_state = icl_dump_hw_state,
+ .compare_hw_state = icl_compare_hw_state,
};
/**
- * intel_shared_dpll_init - Initialize shared DPLLs
- * @dev_priv: i915 device
+ * intel_dpll_init - Initialize DPLLs
+ * @display: intel_display device
*
- * Initialize shared DPLLs for @dev_priv.
+ * Initialize DPLLs for @display.
*/
-void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
+void intel_dpll_init(struct intel_display *display)
{
const struct intel_dpll_mgr *dpll_mgr = NULL;
const struct dpll_info *dpll_info;
int i;
- if (IS_DG2(dev_priv))
+ mutex_init(&display->dpll.lock);
+
+ if (DISPLAY_VER(display) >= 14 || display->platform.dg2)
/* No shared DPLLs on DG2; port PLLs are part of the PHY */
dpll_mgr = NULL;
- else if (IS_ALDERLAKE_P(dev_priv))
+ else if (display->platform.alderlake_p)
dpll_mgr = &adlp_pll_mgr;
- else if (IS_ALDERLAKE_S(dev_priv))
+ else if (display->platform.alderlake_s)
dpll_mgr = &adls_pll_mgr;
- else if (IS_DG1(dev_priv))
+ else if (display->platform.dg1)
dpll_mgr = &dg1_pll_mgr;
- else if (IS_ROCKETLAKE(dev_priv))
+ else if (display->platform.rocketlake)
dpll_mgr = &rkl_pll_mgr;
- else if (DISPLAY_VER(dev_priv) >= 12)
+ else if (DISPLAY_VER(display) >= 12)
dpll_mgr = &tgl_pll_mgr;
- else if (IS_JSL_EHL(dev_priv))
+ else if (display->platform.jasperlake || display->platform.elkhartlake)
dpll_mgr = &ehl_pll_mgr;
- else if (DISPLAY_VER(dev_priv) >= 11)
+ else if (DISPLAY_VER(display) >= 11)
dpll_mgr = &icl_pll_mgr;
- else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
+ else if (display->platform.geminilake || display->platform.broxton)
dpll_mgr = &bxt_pll_mgr;
- else if (DISPLAY_VER(dev_priv) == 9)
+ else if (DISPLAY_VER(display) == 9)
dpll_mgr = &skl_pll_mgr;
- else if (HAS_DDI(dev_priv))
+ else if (HAS_DDI(display))
dpll_mgr = &hsw_pll_mgr;
- else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
+ else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display))
dpll_mgr = &pch_pll_mgr;
- if (!dpll_mgr) {
- dev_priv->display.dpll.num_shared_dpll = 0;
+ if (!dpll_mgr)
return;
- }
dpll_info = dpll_mgr->dpll_info;
for (i = 0; dpll_info[i].name; i++) {
- if (drm_WARN_ON(&dev_priv->drm,
- i >= ARRAY_SIZE(dev_priv->display.dpll.shared_dplls)))
+ if (drm_WARN_ON(display->drm,
+ i >= ARRAY_SIZE(display->dpll.dplls)))
+ break;
+
+ /* must fit into unsigned long bitmask on 32bit */
+ if (drm_WARN_ON(display->drm, dpll_info[i].id >= 32))
break;
- drm_WARN_ON(&dev_priv->drm, i != dpll_info[i].id);
- dev_priv->display.dpll.shared_dplls[i].info = &dpll_info[i];
+ display->dpll.dplls[i].info = &dpll_info[i];
+ display->dpll.dplls[i].index = i;
}
- dev_priv->display.dpll.mgr = dpll_mgr;
- dev_priv->display.dpll.num_shared_dpll = i;
- mutex_init(&dev_priv->display.dpll.lock);
+ display->dpll.mgr = dpll_mgr;
+ display->dpll.num_dpll = i;
}
/**
- * intel_compute_shared_dplls - compute DPLL state CRTC and encoder combination
+ * intel_dpll_compute - compute DPLL state CRTC and encoder combination
* @state: atomic state
* @crtc: CRTC to compute DPLLs for
* @encoder: encoder
@@ -4244,26 +4376,26 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
* This function computes the DPLL state for the given CRTC and encoder.
*
* The new configuration in the atomic commit @state is made effective by
- * calling intel_shared_dpll_swap_state().
+ * calling intel_dpll_swap_state().
*
* Returns:
- * 0 on success, negative error code on falure.
+ * 0 on success, negative error code on failure.
*/
-int intel_compute_shared_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+int intel_dpll_compute(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->display.dpll.mgr;
+ struct intel_display *display = to_intel_display(state);
+ const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
- if (drm_WARN_ON(&dev_priv->drm, !dpll_mgr))
+ if (drm_WARN_ON(display->drm, !dpll_mgr))
return -EINVAL;
return dpll_mgr->compute_dplls(state, crtc, encoder);
}
/**
- * intel_reserve_shared_dplls - reserve DPLLs for CRTC and encoder combination
+ * intel_dpll_reserve - reserve DPLLs for CRTC and encoder combination
* @state: atomic state
* @crtc: CRTC to reserve DPLLs for
* @encoder: encoder
@@ -4273,49 +4405,49 @@ int intel_compute_shared_dplls(struct intel_atomic_state *state,
* state.
*
* The new configuration in the atomic commit @state is made effective by
- * calling intel_shared_dpll_swap_state().
+ * calling intel_dpll_swap_state().
*
* The reserved DPLLs should be released by calling
- * intel_release_shared_dplls().
+ * intel_dpll_release().
*
* Returns:
* 0 if all required DPLLs were successfully reserved,
* negative error code otherwise.
*/
-int intel_reserve_shared_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
+int intel_dpll_reserve(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->display.dpll.mgr;
+ struct intel_display *display = to_intel_display(state);
+ const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
- if (drm_WARN_ON(&dev_priv->drm, !dpll_mgr))
+ if (drm_WARN_ON(display->drm, !dpll_mgr))
return -EINVAL;
return dpll_mgr->get_dplls(state, crtc, encoder);
}
/**
- * intel_release_shared_dplls - end use of DPLLs by CRTC in atomic state
+ * intel_dpll_release - end use of DPLLs by CRTC in atomic state
* @state: atomic state
* @crtc: crtc from which the DPLLs are to be released
*
- * This function releases all DPLLs reserved by intel_reserve_shared_dplls()
+ * This function releases all DPLLs reserved by intel_dpll_reserve()
* from the current atomic commit @state and the old @crtc atomic state.
*
* The new configuration in the atomic commit @state is made effective by
- * calling intel_shared_dpll_swap_state().
+ * calling intel_dpll_swap_state().
*/
-void intel_release_shared_dplls(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
+void intel_dpll_release(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = to_i915(state->base.dev);
- const struct intel_dpll_mgr *dpll_mgr = dev_priv->display.dpll.mgr;
+ struct intel_display *display = to_intel_display(state);
+ const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
/*
* FIXME: this function is called for every platform having a
* compute_clock hook, even though the platform doesn't yet support
- * the shared DPLL framework and intel_reserve_shared_dplls() is not
+ * the DPLL framework and intel_dpll_reserve() is not
* called on those.
*/
if (!dpll_mgr)
@@ -4325,23 +4457,23 @@ void intel_release_shared_dplls(struct intel_atomic_state *state,
}
/**
- * intel_update_active_dpll - update the active DPLL for a CRTC/encoder
+ * intel_dpll_update_active - update the active DPLL for a CRTC/encoder
* @state: atomic state
* @crtc: the CRTC for which to update the active DPLL
* @encoder: encoder determining the type of port DPLL
*
* Update the active DPLL for the given @crtc/@encoder in @crtc's atomic state,
- * from the port DPLLs reserved previously by intel_reserve_shared_dplls(). The
+ * from the port DPLLs reserved previously by intel_dpll_reserve(). The
* DPLL selected will be based on the current mode of the encoder's port.
*/
-void intel_update_active_dpll(struct intel_atomic_state *state,
+void intel_dpll_update_active(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- const struct intel_dpll_mgr *dpll_mgr = dev_priv->display.dpll.mgr;
+ struct intel_display *display = to_intel_display(encoder);
+ const struct intel_dpll_mgr *dpll_mgr = display->dpll.mgr;
- if (drm_WARN_ON(&dev_priv->drm, !dpll_mgr))
+ if (drm_WARN_ON(display->drm, !dpll_mgr))
return;
dpll_mgr->update_active_dpll(state, crtc, encoder);
@@ -4349,162 +4481,181 @@ void intel_update_active_dpll(struct intel_atomic_state *state,
/**
* intel_dpll_get_freq - calculate the DPLL's output frequency
- * @i915: i915 device
+ * @display: intel_display device
* @pll: DPLL for which to calculate the output frequency
- * @pll_state: DPLL state from which to calculate the output frequency
+ * @dpll_hw_state: DPLL state from which to calculate the output frequency
*
- * Return the output frequency corresponding to @pll's passed in @pll_state.
+ * Return the output frequency corresponding to @pll's passed in @dpll_hw_state.
*/
-int intel_dpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+int intel_dpll_get_freq(struct intel_display *display,
+ const struct intel_dpll *pll,
+ const struct intel_dpll_hw_state *dpll_hw_state)
{
- if (drm_WARN_ON(&i915->drm, !pll->info->funcs->get_freq))
+ if (drm_WARN_ON(display->drm, !pll->info->funcs->get_freq))
return 0;
- return pll->info->funcs->get_freq(i915, pll, pll_state);
+ return pll->info->funcs->get_freq(display, pll, dpll_hw_state);
}
/**
* intel_dpll_get_hw_state - readout the DPLL's hardware state
- * @i915: i915 device
+ * @display: intel_display device instance
* @pll: DPLL for which to calculate the output frequency
- * @hw_state: DPLL's hardware state
+ * @dpll_hw_state: DPLL's hardware state
*
- * Read out @pll's hardware state into @hw_state.
+ * Read out @pll's hardware state into @dpll_hw_state.
*/
-bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
+bool intel_dpll_get_hw_state(struct intel_display *display,
+ struct intel_dpll *pll,
+ struct intel_dpll_hw_state *dpll_hw_state)
{
- return pll->info->funcs->get_hw_state(i915, pll, hw_state);
+ return pll->info->funcs->get_hw_state(display, pll, dpll_hw_state);
}
-static void readout_dpll_hw_state(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll)
+static void readout_dpll_hw_state(struct intel_display *display,
+ struct intel_dpll *pll)
{
struct intel_crtc *crtc;
- pll->on = intel_dpll_get_hw_state(i915, pll, &pll->state.hw_state);
+ pll->on = intel_dpll_get_hw_state(display, pll, &pll->state.hw_state);
- if (IS_JSL_EHL(i915) && pll->on &&
- pll->info->id == DPLL_ID_EHL_DPLL4) {
- pll->wakeref = intel_display_power_get(i915,
- POWER_DOMAIN_DC_OFF);
- }
+ if (pll->on && pll->info->power_domain)
+ pll->wakeref = intel_display_power_get(display, pll->info->power_domain);
pll->state.pipe_mask = 0;
- for_each_intel_crtc(&i915->drm, crtc) {
+ for_each_intel_crtc(display->drm, crtc) {
struct intel_crtc_state *crtc_state =
to_intel_crtc_state(crtc->base.state);
- if (crtc_state->hw.active && crtc_state->shared_dpll == pll)
- pll->state.pipe_mask |= BIT(crtc->pipe);
+ if (crtc_state->hw.active && crtc_state->intel_dpll == pll)
+ intel_dpll_crtc_get(crtc, pll, &pll->state);
}
pll->active_mask = pll->state.pipe_mask;
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"%s hw state readout: pipe_mask 0x%x, on %i\n",
pll->info->name, pll->state.pipe_mask, pll->on);
}
-void intel_dpll_update_ref_clks(struct drm_i915_private *i915)
+void intel_dpll_update_ref_clks(struct intel_display *display)
{
- if (i915->display.dpll.mgr && i915->display.dpll.mgr->update_ref_clks)
- i915->display.dpll.mgr->update_ref_clks(i915);
+ if (display->dpll.mgr && display->dpll.mgr->update_ref_clks)
+ display->dpll.mgr->update_ref_clks(display);
}
-void intel_dpll_readout_hw_state(struct drm_i915_private *i915)
+void intel_dpll_readout_hw_state(struct intel_display *display)
{
+ struct intel_dpll *pll;
int i;
- for (i = 0; i < i915->display.dpll.num_shared_dpll; i++)
- readout_dpll_hw_state(i915, &i915->display.dpll.shared_dplls[i]);
+ for_each_dpll(display, pll, i)
+ readout_dpll_hw_state(display, pll);
}
-static void sanitize_dpll_state(struct drm_i915_private *i915,
- struct intel_shared_dpll *pll)
+static void sanitize_dpll_state(struct intel_display *display,
+ struct intel_dpll *pll)
{
if (!pll->on)
return;
- adlp_cmtg_clock_gating_wa(i915, pll);
+ adlp_cmtg_clock_gating_wa(display, pll);
if (pll->active_mask)
return;
- drm_dbg_kms(&i915->drm,
+ drm_dbg_kms(display->drm,
"%s enabled but not in use, disabling\n",
pll->info->name);
- pll->info->funcs->disable(i915, pll);
- pll->on = false;
+ _intel_disable_shared_dpll(display, pll);
}
-void intel_dpll_sanitize_state(struct drm_i915_private *i915)
+void intel_dpll_sanitize_state(struct intel_display *display)
{
+ struct intel_dpll *pll;
int i;
- for (i = 0; i < i915->display.dpll.num_shared_dpll; i++)
- sanitize_dpll_state(i915, &i915->display.dpll.shared_dplls[i]);
+ intel_cx0_pll_power_save_wa(display);
+
+ for_each_dpll(display, pll, i)
+ sanitize_dpll_state(display, pll);
+}
+
+/**
+ * intel_dpll_dump_hw_state - dump hw_state
+ * @display: intel_display structure
+ * @p: where to print the state to
+ * @dpll_hw_state: hw state to be dumped
+ *
+ * Dumo out the relevant values in @dpll_hw_state.
+ */
+void intel_dpll_dump_hw_state(struct intel_display *display,
+ struct drm_printer *p,
+ const struct intel_dpll_hw_state *dpll_hw_state)
+{
+ if (display->dpll.mgr) {
+ display->dpll.mgr->dump_hw_state(p, dpll_hw_state);
+ } else {
+ /* fallback for platforms that don't use the shared dpll
+ * infrastructure
+ */
+ ibx_dump_hw_state(p, dpll_hw_state);
+ }
}
/**
- * intel_dpll_dump_hw_state - write hw_state to dmesg
- * @dev_priv: i915 drm device
- * @hw_state: hw state to be written to the log
+ * intel_dpll_compare_hw_state - compare the two states
+ * @display: intel_display structure
+ * @a: first DPLL hw state
+ * @b: second DPLL hw state
+ *
+ * Compare DPLL hw states @a and @b.
*
- * Write the relevant values in @hw_state to dmesg using drm_dbg_kms.
+ * Returns: true if the states are equal, false if the differ
*/
-void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
+bool intel_dpll_compare_hw_state(struct intel_display *display,
+ const struct intel_dpll_hw_state *a,
+ const struct intel_dpll_hw_state *b)
{
- if (dev_priv->display.dpll.mgr) {
- dev_priv->display.dpll.mgr->dump_hw_state(dev_priv, hw_state);
+ if (display->dpll.mgr) {
+ return display->dpll.mgr->compare_hw_state(a, b);
} else {
/* fallback for platforms that don't use the shared dpll
* infrastructure
*/
- drm_dbg_kms(&dev_priv->drm,
- "dpll_hw_state: dpll: 0x%x, dpll_md: 0x%x, "
- "fp0: 0x%x, fp1: 0x%x\n",
- hw_state->dpll,
- hw_state->dpll_md,
- hw_state->fp0,
- hw_state->fp1);
+ return ibx_compare_hw_state(a, b);
}
}
static void
-verify_single_dpll_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
+verify_single_dpll_state(struct intel_display *display,
+ struct intel_dpll *pll,
struct intel_crtc *crtc,
- struct intel_crtc_state *new_crtc_state)
+ const struct intel_crtc_state *new_crtc_state)
{
- struct intel_dpll_hw_state dpll_hw_state;
+ struct intel_dpll_hw_state dpll_hw_state = {};
u8 pipe_mask;
bool active;
- memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
-
- drm_dbg_kms(&dev_priv->drm, "%s\n", pll->info->name);
-
- active = intel_dpll_get_hw_state(dev_priv, pll, &dpll_hw_state);
-
- if (!(pll->info->flags & INTEL_DPLL_ALWAYS_ON)) {
- I915_STATE_WARN(!pll->on && pll->active_mask,
- "pll in active use but not on in sw tracking\n");
- I915_STATE_WARN(pll->on && !pll->active_mask,
- "pll is on but not used by any active pipe\n");
- I915_STATE_WARN(pll->on != active,
- "pll on state mismatch (expected %i, found %i)\n",
- pll->on, active);
+ active = intel_dpll_get_hw_state(display, pll, &dpll_hw_state);
+
+ if (!pll->info->always_on) {
+ INTEL_DISPLAY_STATE_WARN(display, !pll->on && pll->active_mask,
+ "%s: pll in active use but not on in sw tracking\n",
+ pll->info->name);
+ INTEL_DISPLAY_STATE_WARN(display, pll->on && !pll->active_mask,
+ "%s: pll is on but not used by any active pipe\n",
+ pll->info->name);
+ INTEL_DISPLAY_STATE_WARN(display, pll->on != active,
+ "%s: pll on state mismatch (expected %i, found %i)\n",
+ pll->info->name, pll->on, active);
}
if (!crtc) {
- I915_STATE_WARN(pll->active_mask & ~pll->state.pipe_mask,
- "more active pll users than references: 0x%x vs 0x%x\n",
- pll->active_mask, pll->state.pipe_mask);
+ INTEL_DISPLAY_STATE_WARN(display,
+ pll->active_mask & ~pll->state.pipe_mask,
+ "%s: more active pll users than references: 0x%x vs 0x%x\n",
+ pll->info->name, pll->active_mask, pll->state.pipe_mask);
return;
}
@@ -4512,53 +4663,69 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
pipe_mask = BIT(crtc->pipe);
if (new_crtc_state->hw.active)
- I915_STATE_WARN(!(pll->active_mask & pipe_mask),
- "pll active mismatch (expected pipe %c in active mask 0x%x)\n",
- pipe_name(crtc->pipe), pll->active_mask);
+ INTEL_DISPLAY_STATE_WARN(display, !(pll->active_mask & pipe_mask),
+ "%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n",
+ pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
else
- I915_STATE_WARN(pll->active_mask & pipe_mask,
- "pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
- pipe_name(crtc->pipe), pll->active_mask);
+ INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
+ "%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
+ pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
- I915_STATE_WARN(!(pll->state.pipe_mask & pipe_mask),
- "pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
- pipe_mask, pll->state.pipe_mask);
+ INTEL_DISPLAY_STATE_WARN(display, !(pll->state.pipe_mask & pipe_mask),
+ "%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
+ pll->info->name, pipe_mask, pll->state.pipe_mask);
- I915_STATE_WARN(pll->on && memcmp(&pll->state.hw_state,
- &dpll_hw_state,
- sizeof(dpll_hw_state)),
- "pll hw state mismatch\n");
+ INTEL_DISPLAY_STATE_WARN(display,
+ pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
+ sizeof(dpll_hw_state)),
+ "%s: pll hw state mismatch\n",
+ pll->info->name);
}
-void intel_shared_dpll_state_verify(struct intel_crtc *crtc,
- struct intel_crtc_state *old_crtc_state,
- struct intel_crtc_state *new_crtc_state)
+static bool has_alt_port_dpll(const struct intel_dpll *old_pll,
+ const struct intel_dpll *new_pll)
{
- struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ return old_pll && new_pll && old_pll != new_pll &&
+ (old_pll->info->is_alt_port_dpll || new_pll->info->is_alt_port_dpll);
+}
+
+void intel_dpll_state_verify(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct intel_display *display = to_intel_display(state);
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ const struct intel_crtc_state *new_crtc_state =
+ intel_atomic_get_new_crtc_state(state, crtc);
- if (new_crtc_state->shared_dpll)
- verify_single_dpll_state(dev_priv, new_crtc_state->shared_dpll,
+ if (new_crtc_state->intel_dpll)
+ verify_single_dpll_state(display, new_crtc_state->intel_dpll,
crtc, new_crtc_state);
- if (old_crtc_state->shared_dpll &&
- old_crtc_state->shared_dpll != new_crtc_state->shared_dpll) {
+ if (old_crtc_state->intel_dpll &&
+ old_crtc_state->intel_dpll != new_crtc_state->intel_dpll) {
u8 pipe_mask = BIT(crtc->pipe);
- struct intel_shared_dpll *pll = old_crtc_state->shared_dpll;
-
- I915_STATE_WARN(pll->active_mask & pipe_mask,
- "pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
- pipe_name(crtc->pipe), pll->active_mask);
- I915_STATE_WARN(pll->state.pipe_mask & pipe_mask,
- "pll enabled crtcs mismatch (found %x in enabled mask (0x%x))\n",
- pipe_name(crtc->pipe), pll->state.pipe_mask);
+ struct intel_dpll *pll = old_crtc_state->intel_dpll;
+
+ INTEL_DISPLAY_STATE_WARN(display, pll->active_mask & pipe_mask,
+ "%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
+ pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
+
+ /* TC ports have both MG/TC and TBT PLL referenced simultaneously */
+ INTEL_DISPLAY_STATE_WARN(display, !has_alt_port_dpll(old_crtc_state->intel_dpll,
+ new_crtc_state->intel_dpll) &&
+ pll->state.pipe_mask & pipe_mask,
+ "%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
+ pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask);
}
}
-void intel_shared_dpll_verify_disabled(struct drm_i915_private *i915)
+void intel_dpll_verify_disabled(struct intel_atomic_state *state)
{
+ struct intel_display *display = to_intel_display(state);
+ struct intel_dpll *pll;
int i;
- for (i = 0; i < i915->display.dpll.num_shared_dpll; i++)
- verify_single_dpll_state(i915, &i915->display.dpll.shared_dplls[i],
- NULL, NULL);
+ for_each_dpll(display, pll, i)
+ verify_single_dpll_state(display, pll, NULL, NULL);
}