提交 49cd97a3 编写于 作者: V Ville Syrjälä

drm/i915: Start moving the cdclk stuff into a distinct state structure

Introduce intel_cdclk state which for now will track the cdclk
frequency, the vco frequency and the reference frequency (not sure we
want the last one, but I put it there anyway). We'll also make the
.get_cdclk() function fill out this state structure rather than
just returning the current cdclk frequency.

One immediate benefit is that calling .get_cdclk() will no longer
clobber state stored under dev_priv unless ex[plicitly told to do
so. Previously it clobbered the vco and reference clocks stored
there on some platforms.

We'll expand the use of this structure to actually precomputing the
state and whatnot later.

v2: Constify intel_cdclk_state_compare()
v3: Document intel_cdclk_state_compare()
v4: Deal with i945gm_get_cdclk()
Signed-off-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: NAnder Conselvan de Oliveira <conselvan2@gmail.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170207183345.19763-1-ville.syrjala@linux.intel.com
上级 8f0cfa4d
......@@ -1281,7 +1281,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
seq_puts(m, "no P-state info available\n");
}
seq_printf(m, "Current CD clock frequency: %d kHz\n", dev_priv->cdclk_freq);
seq_printf(m, "Current CD clock frequency: %d kHz\n", dev_priv->cdclk.hw.cdclk);
seq_printf(m, "Max CD clock frequency: %d kHz\n", dev_priv->max_cdclk_freq);
seq_printf(m, "Max pixel clock frequency: %d kHz\n", dev_priv->max_dotclk_freq);
......
......@@ -600,9 +600,11 @@ struct intel_initial_plane_config;
struct intel_crtc;
struct intel_limit;
struct dpll;
struct intel_cdclk_state;
struct drm_i915_display_funcs {
int (*get_cdclk)(struct drm_i915_private *dev_priv);
void (*get_cdclk)(struct drm_i915_private *dev_priv,
struct intel_cdclk_state *cdclk_state);
int (*get_fifo_size)(struct drm_i915_private *dev_priv, int plane);
int (*compute_pipe_wm)(struct intel_crtc_state *cstate);
int (*compute_intermediate_wm)(struct drm_device *dev,
......@@ -2060,6 +2062,10 @@ struct i915_oa_ops {
bool (*oa_buffer_is_empty)(struct drm_i915_private *dev_priv);
};
struct intel_cdclk_state {
unsigned int cdclk, vco, ref;
};
struct drm_i915_private {
struct drm_device drm;
......@@ -2164,7 +2170,7 @@ struct drm_i915_private {
unsigned int fsb_freq, mem_freq, is_ddr3;
unsigned int skl_preferred_vco_freq;
unsigned int cdclk_freq, max_cdclk_freq;
unsigned int max_cdclk_freq;
/*
* For reading holding any crtc lock is sufficient,
......@@ -2178,8 +2184,8 @@ struct drm_i915_private {
unsigned int czclk_freq;
struct {
unsigned int vco, ref;
} cdclk_pll;
struct intel_cdclk_state hw;
} cdclk;
/**
* wq - Driver workqueue for GEM.
......
......@@ -734,7 +734,7 @@ static int i915_audio_component_get_cdclk_freq(struct device *kdev)
if (WARN_ON_ONCE(!HAS_DDI(dev_priv)))
return -ENODEV;
return dev_priv->cdclk_freq;
return dev_priv->cdclk.hw.cdclk;
}
/*
......
此差异已折叠。
......@@ -135,7 +135,7 @@ struct intel_limit {
};
/* returns HPLL frequency in kHz */
static int valleyview_get_vco(struct drm_i915_private *dev_priv)
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
{
int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
......@@ -171,7 +171,7 @@ int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
const char *name, u32 reg)
{
if (dev_priv->hpll_freq == 0)
dev_priv->hpll_freq = valleyview_get_vco(dev_priv);
dev_priv->hpll_freq = vlv_get_hpll_vco(dev_priv);
return vlv_get_cck_clock(dev_priv, name, reg,
dev_priv->hpll_freq);
......@@ -12413,7 +12413,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
*/
if (dev_priv->display.modeset_calc_cdclk) {
if (!intel_state->cdclk_pll_vco)
intel_state->cdclk_pll_vco = dev_priv->cdclk_pll.vco;
intel_state->cdclk_pll_vco = dev_priv->cdclk.hw.vco;
if (!intel_state->cdclk_pll_vco)
intel_state->cdclk_pll_vco = dev_priv->skl_preferred_vco_freq;
......@@ -12433,8 +12433,8 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
}
/* All pipes must be switched off while we change the cdclk. */
if (intel_state->dev_cdclk != dev_priv->cdclk_freq ||
intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco) {
if (intel_state->dev_cdclk != dev_priv->cdclk.hw.cdclk ||
intel_state->cdclk_pll_vco != dev_priv->cdclk.hw.vco) {
ret = intel_modeset_all_pipes(state);
if (ret < 0)
return ret;
......@@ -12869,8 +12869,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
drm_atomic_helper_update_legacy_modeset_state(state->dev, state);
if (dev_priv->display.modeset_commit_cdclk &&
(intel_state->dev_cdclk != dev_priv->cdclk_freq ||
intel_state->cdclk_pll_vco != dev_priv->cdclk_pll.vco))
(intel_state->dev_cdclk != dev_priv->cdclk.hw.cdclk ||
intel_state->cdclk_pll_vco != dev_priv->cdclk.hw.vco))
dev_priv->display.modeset_commit_cdclk(state);
/*
......@@ -14855,7 +14855,7 @@ void intel_modeset_init_hw(struct drm_device *dev)
intel_update_cdclk(dev_priv);
dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
dev_priv->atomic_cdclk_freq = dev_priv->cdclk.hw.cdclk;
intel_init_clock_gating(dev_priv);
}
......@@ -15031,7 +15031,7 @@ int intel_modeset_init(struct drm_device *dev)
intel_update_czclk(dev_priv);
intel_update_cdclk(dev_priv);
dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
dev_priv->atomic_cdclk_freq = dev_priv->cdclk.hw.cdclk;
intel_shared_dpll_init(dev);
......
......@@ -918,7 +918,7 @@ static uint32_t ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
* divide by 2000 and use that
*/
if (intel_dig_port->port == PORT_A)
return DIV_ROUND_CLOSEST(dev_priv->cdclk_freq, 2000);
return DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.cdclk, 2000);
else
return DIV_ROUND_CLOSEST(dev_priv->rawclk_freq, 2000);
}
......
......@@ -1251,10 +1251,13 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
void intel_update_cdclk(struct drm_i915_private *dev_priv);
void intel_update_rawclk(struct drm_i915_private *dev_priv);
bool intel_cdclk_state_compare(const struct intel_cdclk_state *a,
const struct intel_cdclk_state *b);
/* intel_display.c */
enum transcoder intel_crtc_pch_transcoder(struct intel_crtc *crtc);
void intel_update_rawclk(struct drm_i915_private *dev_priv);
int vlv_get_hpll_vco(struct drm_i915_private *dev_priv);
int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
const char *name, u32 reg, int ref_freq);
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
......
......@@ -817,7 +817,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
/* WaFbcExceedCdClockThreshold:hsw,bdw */
if ((IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) &&
cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk_freq * 95 / 100) {
cache->crtc.hsw_bdw_pixel_rate >= dev_priv->cdclk.hw.cdclk * 95 / 100) {
fbc->no_fbc_reason = "pixel rate is too big";
return false;
}
......
......@@ -1315,7 +1315,7 @@ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
if (IS_PINEVIEW(dev_priv))
clock = KHz(dev_priv->rawclk_freq);
else
clock = KHz(dev_priv->cdclk_freq);
clock = KHz(dev_priv->cdclk.hw.cdclk);
return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 32);
}
......@@ -1333,7 +1333,7 @@ static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
if (IS_G4X(dev_priv))
clock = KHz(dev_priv->rawclk_freq);
else
clock = KHz(dev_priv->cdclk_freq);
clock = KHz(dev_priv->cdclk.hw.cdclk);
return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * 128);
}
......
......@@ -964,9 +964,12 @@ static void gen9_assert_dbuf_enabled(struct drm_i915_private *dev_priv)
static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
{
struct intel_cdclk_state cdclk_state = {};
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
WARN_ON(dev_priv->cdclk_freq != dev_priv->display.get_cdclk(dev_priv));
dev_priv->display.get_cdclk(dev_priv, &cdclk_state);
WARN_ON(!intel_cdclk_state_compare(&dev_priv->cdclk.hw, &cdclk_state));
gen9_assert_dbuf_enabled(dev_priv);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册