|
@@ -45,6 +45,11 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
|
|
static void intel_increase_pllclock(struct drm_crtc *crtc);
|
|
static void intel_increase_pllclock(struct drm_crtc *crtc);
|
|
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
|
|
static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
|
|
|
|
|
|
|
|
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
|
|
|
|
+ struct intel_crtc_config *pipe_config);
|
|
|
|
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
|
|
|
|
+ struct intel_crtc_config *pipe_config);
|
|
|
|
+
|
|
typedef struct {
|
|
typedef struct {
|
|
int min, max;
|
|
int min, max;
|
|
} intel_range_t;
|
|
} intel_range_t;
|
|
@@ -84,7 +89,7 @@ intel_fdi_link_freq(struct drm_device *dev)
|
|
return 27;
|
|
return 27;
|
|
}
|
|
}
|
|
|
|
|
|
-static const intel_limit_t intel_limits_i8xx_dvo = {
|
|
|
|
|
|
+static const intel_limit_t intel_limits_i8xx_dac = {
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
.n = { .min = 3, .max = 16 },
|
|
.n = { .min = 3, .max = 16 },
|
|
@@ -97,6 +102,19 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
|
|
.p2_slow = 4, .p2_fast = 2 },
|
|
.p2_slow = 4, .p2_fast = 2 },
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static const intel_limit_t intel_limits_i8xx_dvo = {
|
|
|
|
+ .dot = { .min = 25000, .max = 350000 },
|
|
|
|
+ .vco = { .min = 930000, .max = 1400000 },
|
|
|
|
+ .n = { .min = 3, .max = 16 },
|
|
|
|
+ .m = { .min = 96, .max = 140 },
|
|
|
|
+ .m1 = { .min = 18, .max = 26 },
|
|
|
|
+ .m2 = { .min = 6, .max = 16 },
|
|
|
|
+ .p = { .min = 4, .max = 128 },
|
|
|
|
+ .p1 = { .min = 2, .max = 33 },
|
|
|
|
+ .p2 = { .dot_limit = 165000,
|
|
|
|
+ .p2_slow = 4, .p2_fast = 4 },
|
|
|
|
+};
|
|
|
|
+
|
|
static const intel_limit_t intel_limits_i8xx_lvds = {
|
|
static const intel_limit_t intel_limits_i8xx_lvds = {
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
.dot = { .min = 25000, .max = 350000 },
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
.vco = { .min = 930000, .max = 1400000 },
|
|
@@ -405,8 +423,10 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk)
|
|
} else {
|
|
} else {
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
|
|
limit = &intel_limits_i8xx_lvds;
|
|
limit = &intel_limits_i8xx_lvds;
|
|
- else
|
|
|
|
|
|
+ else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO))
|
|
limit = &intel_limits_i8xx_dvo;
|
|
limit = &intel_limits_i8xx_dvo;
|
|
|
|
+ else
|
|
|
|
+ limit = &intel_limits_i8xx_dac;
|
|
}
|
|
}
|
|
return limit;
|
|
return limit;
|
|
}
|
|
}
|
|
@@ -892,8 +912,8 @@ static const char *state_string(bool enabled)
|
|
}
|
|
}
|
|
|
|
|
|
/* Only for pre-ILK configs */
|
|
/* Only for pre-ILK configs */
|
|
-static void assert_pll(struct drm_i915_private *dev_priv,
|
|
|
|
- enum pipe pipe, bool state)
|
|
|
|
|
|
+void assert_pll(struct drm_i915_private *dev_priv,
|
|
|
|
+ enum pipe pipe, bool state)
|
|
{
|
|
{
|
|
int reg;
|
|
int reg;
|
|
u32 val;
|
|
u32 val;
|
|
@@ -906,10 +926,8 @@ static void assert_pll(struct drm_i915_private *dev_priv,
|
|
"PLL state assertion failure (expected %s, current %s)\n",
|
|
"PLL state assertion failure (expected %s, current %s)\n",
|
|
state_string(state), state_string(cur_state));
|
|
state_string(state), state_string(cur_state));
|
|
}
|
|
}
|
|
-#define assert_pll_enabled(d, p) assert_pll(d, p, true)
|
|
|
|
-#define assert_pll_disabled(d, p) assert_pll(d, p, false)
|
|
|
|
|
|
|
|
-static struct intel_shared_dpll *
|
|
|
|
|
|
+struct intel_shared_dpll *
|
|
intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
|
|
intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
@@ -921,9 +939,9 @@ intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
|
|
}
|
|
}
|
|
|
|
|
|
/* For ILK+ */
|
|
/* For ILK+ */
|
|
-static void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
|
|
|
- struct intel_shared_dpll *pll,
|
|
|
|
- bool state)
|
|
|
|
|
|
+void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
|
|
|
+ struct intel_shared_dpll *pll,
|
|
|
|
+ bool state)
|
|
{
|
|
{
|
|
bool cur_state;
|
|
bool cur_state;
|
|
struct intel_dpll_hw_state hw_state;
|
|
struct intel_dpll_hw_state hw_state;
|
|
@@ -942,8 +960,6 @@ static void assert_shared_dpll(struct drm_i915_private *dev_priv,
|
|
"%s assertion failure (expected %s, current %s)\n",
|
|
"%s assertion failure (expected %s, current %s)\n",
|
|
pll->name, state_string(state), state_string(cur_state));
|
|
pll->name, state_string(state), state_string(cur_state));
|
|
}
|
|
}
|
|
-#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
|
|
|
|
-#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
|
|
|
|
|
|
|
|
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
|
|
static void assert_fdi_tx(struct drm_i915_private *dev_priv,
|
|
enum pipe pipe, bool state)
|
|
enum pipe pipe, bool state)
|
|
@@ -1007,15 +1023,19 @@ static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv,
|
|
WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
|
|
WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n");
|
|
}
|
|
}
|
|
|
|
|
|
-static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv,
|
|
|
|
- enum pipe pipe)
|
|
|
|
|
|
+void assert_fdi_rx_pll(struct drm_i915_private *dev_priv,
|
|
|
|
+ enum pipe pipe, bool state)
|
|
{
|
|
{
|
|
int reg;
|
|
int reg;
|
|
u32 val;
|
|
u32 val;
|
|
|
|
+ bool cur_state;
|
|
|
|
|
|
reg = FDI_RX_CTL(pipe);
|
|
reg = FDI_RX_CTL(pipe);
|
|
val = I915_READ(reg);
|
|
val = I915_READ(reg);
|
|
- WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n");
|
|
|
|
|
|
+ cur_state = !!(val & FDI_RX_PLL_ENABLE);
|
|
|
|
+ WARN(cur_state != state,
|
|
|
|
+ "FDI RX PLL assertion failure (expected %s, current %s)\n",
|
|
|
|
+ state_string(state), state_string(cur_state));
|
|
}
|
|
}
|
|
|
|
|
|
static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
|
|
static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
|
|
@@ -1111,7 +1131,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
|
|
}
|
|
}
|
|
|
|
|
|
/* Need to check both planes against the pipe */
|
|
/* Need to check both planes against the pipe */
|
|
- for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
|
|
|
|
|
|
+ for_each_pipe(i) {
|
|
reg = DSPCNTR(i);
|
|
reg = DSPCNTR(i);
|
|
val = I915_READ(reg);
|
|
val = I915_READ(reg);
|
|
cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
|
|
cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
|
|
@@ -1301,51 +1321,92 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
|
|
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
|
|
assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * intel_enable_pll - enable a PLL
|
|
|
|
- * @dev_priv: i915 private structure
|
|
|
|
- * @pipe: pipe PLL to enable
|
|
|
|
- *
|
|
|
|
- * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to
|
|
|
|
- * make sure the PLL reg is writable first though, since the panel write
|
|
|
|
- * protect mechanism may be enabled.
|
|
|
|
- *
|
|
|
|
- * Note! This is for pre-ILK only.
|
|
|
|
- *
|
|
|
|
- * Unfortunately needed by dvo_ns2501 since the dvo depends on it running.
|
|
|
|
- */
|
|
|
|
-static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
|
|
|
|
+static void vlv_enable_pll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
- int reg;
|
|
|
|
- u32 val;
|
|
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
+ int reg = DPLL(crtc->pipe);
|
|
|
|
+ u32 dpll = crtc->config.dpll_hw_state.dpll;
|
|
|
|
|
|
- assert_pipe_disabled(dev_priv, pipe);
|
|
|
|
|
|
+ assert_pipe_disabled(dev_priv, crtc->pipe);
|
|
|
|
|
|
/* No really, not for ILK+ */
|
|
/* No really, not for ILK+ */
|
|
- BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5);
|
|
|
|
|
|
+ BUG_ON(!IS_VALLEYVIEW(dev_priv->dev));
|
|
|
|
|
|
/* PLL is protected by panel, make sure we can write it */
|
|
/* PLL is protected by panel, make sure we can write it */
|
|
if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
|
|
if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
|
|
- assert_panel_unlocked(dev_priv, pipe);
|
|
|
|
|
|
+ assert_panel_unlocked(dev_priv, crtc->pipe);
|
|
|
|
|
|
- reg = DPLL(pipe);
|
|
|
|
- val = I915_READ(reg);
|
|
|
|
- val |= DPLL_VCO_ENABLE;
|
|
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+ udelay(150);
|
|
|
|
+
|
|
|
|
+ if (wait_for(((I915_READ(reg) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
|
|
|
|
+ DRM_ERROR("DPLL %d failed to lock\n", crtc->pipe);
|
|
|
|
+
|
|
|
|
+ I915_WRITE(DPLL_MD(crtc->pipe), crtc->config.dpll_hw_state.dpll_md);
|
|
|
|
+ POSTING_READ(DPLL_MD(crtc->pipe));
|
|
|
|
|
|
/* We do this three times for luck */
|
|
/* We do this three times for luck */
|
|
- I915_WRITE(reg, val);
|
|
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
POSTING_READ(reg);
|
|
POSTING_READ(reg);
|
|
udelay(150); /* wait for warmup */
|
|
udelay(150); /* wait for warmup */
|
|
- I915_WRITE(reg, val);
|
|
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
POSTING_READ(reg);
|
|
POSTING_READ(reg);
|
|
udelay(150); /* wait for warmup */
|
|
udelay(150); /* wait for warmup */
|
|
- I915_WRITE(reg, val);
|
|
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+ udelay(150); /* wait for warmup */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void i9xx_enable_pll(struct intel_crtc *crtc)
|
|
|
|
+{
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
+ int reg = DPLL(crtc->pipe);
|
|
|
|
+ u32 dpll = crtc->config.dpll_hw_state.dpll;
|
|
|
|
+
|
|
|
|
+ assert_pipe_disabled(dev_priv, crtc->pipe);
|
|
|
|
+
|
|
|
|
+ /* No really, not for ILK+ */
|
|
|
|
+ BUG_ON(dev_priv->info->gen >= 5);
|
|
|
|
+
|
|
|
|
+ /* PLL is protected by panel, make sure we can write it */
|
|
|
|
+ if (IS_MOBILE(dev) && !IS_I830(dev))
|
|
|
|
+ assert_panel_unlocked(dev_priv, crtc->pipe);
|
|
|
|
+
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+
|
|
|
|
+ /* Wait for the clocks to stabilize. */
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+ udelay(150);
|
|
|
|
+
|
|
|
|
+ if (INTEL_INFO(dev)->gen >= 4) {
|
|
|
|
+ I915_WRITE(DPLL_MD(crtc->pipe),
|
|
|
|
+ crtc->config.dpll_hw_state.dpll_md);
|
|
|
|
+ } else {
|
|
|
|
+ /* The pixel multiplier can only be updated once the
|
|
|
|
+ * DPLL is enabled and the clocks are stable.
|
|
|
|
+ *
|
|
|
|
+ * So write it again.
|
|
|
|
+ */
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* We do this three times for luck */
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+ udelay(150); /* wait for warmup */
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
|
|
+ POSTING_READ(reg);
|
|
|
|
+ udelay(150); /* wait for warmup */
|
|
|
|
+ I915_WRITE(reg, dpll);
|
|
POSTING_READ(reg);
|
|
POSTING_READ(reg);
|
|
udelay(150); /* wait for warmup */
|
|
udelay(150); /* wait for warmup */
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * intel_disable_pll - disable a PLL
|
|
|
|
|
|
+ * i9xx_disable_pll - disable a PLL
|
|
* @dev_priv: i915 private structure
|
|
* @dev_priv: i915 private structure
|
|
* @pipe: pipe PLL to disable
|
|
* @pipe: pipe PLL to disable
|
|
*
|
|
*
|
|
@@ -1353,11 +1414,8 @@ static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
*
|
|
*
|
|
* Note! This is for pre-ILK only.
|
|
* Note! This is for pre-ILK only.
|
|
*/
|
|
*/
|
|
-static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
|
|
|
|
+static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
{
|
|
{
|
|
- int reg;
|
|
|
|
- u32 val;
|
|
|
|
-
|
|
|
|
/* Don't disable pipe A or pipe A PLLs if needed */
|
|
/* Don't disable pipe A or pipe A PLLs if needed */
|
|
if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
|
if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
|
|
return;
|
|
return;
|
|
@@ -1365,11 +1423,8 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|
/* Make sure the pipe isn't still relying on us */
|
|
/* Make sure the pipe isn't still relying on us */
|
|
assert_pipe_disabled(dev_priv, pipe);
|
|
assert_pipe_disabled(dev_priv, pipe);
|
|
|
|
|
|
- reg = DPLL(pipe);
|
|
|
|
- val = I915_READ(reg);
|
|
|
|
- val &= ~DPLL_VCO_ENABLE;
|
|
|
|
- I915_WRITE(reg, val);
|
|
|
|
- POSTING_READ(reg);
|
|
|
|
|
|
+ I915_WRITE(DPLL(pipe), 0);
|
|
|
|
+ POSTING_READ(DPLL(pipe));
|
|
}
|
|
}
|
|
|
|
|
|
void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
|
|
void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
|
|
@@ -1942,16 +1997,17 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|
intel_crtc->dspaddr_offset = linear_offset;
|
|
intel_crtc->dspaddr_offset = linear_offset;
|
|
}
|
|
}
|
|
|
|
|
|
- DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
|
|
|
|
- obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
|
|
|
|
|
|
+ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
|
|
|
|
+ i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
|
|
|
|
+ fb->pitches[0]);
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
- obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
|
|
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
|
|
I915_WRITE(DSPLINOFF(plane), linear_offset);
|
|
I915_WRITE(DSPLINOFF(plane), linear_offset);
|
|
} else
|
|
} else
|
|
- I915_WRITE(DSPADDR(plane), obj->gtt_offset + linear_offset);
|
|
|
|
|
|
+ I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset);
|
|
POSTING_READ(reg);
|
|
POSTING_READ(reg);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -2031,11 +2087,12 @@ static int ironlake_update_plane(struct drm_crtc *crtc,
|
|
fb->pitches[0]);
|
|
fb->pitches[0]);
|
|
linear_offset -= intel_crtc->dspaddr_offset;
|
|
linear_offset -= intel_crtc->dspaddr_offset;
|
|
|
|
|
|
- DRM_DEBUG_KMS("Writing base %08X %08lX %d %d %d\n",
|
|
|
|
- obj->gtt_offset, linear_offset, x, y, fb->pitches[0]);
|
|
|
|
|
|
+ DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
|
|
|
|
+ i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
|
|
|
|
+ fb->pitches[0]);
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]);
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
I915_MODIFY_DISPBASE(DSPSURF(plane),
|
|
- obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
if (IS_HASWELL(dev)) {
|
|
if (IS_HASWELL(dev)) {
|
|
I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
|
|
I915_WRITE(DSPOFFSET(plane), (y << 16) | x);
|
|
} else {
|
|
} else {
|
|
@@ -2183,6 +2240,20 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Update pipe size and adjust fitter if needed */
|
|
|
|
+ if (i915_fastboot) {
|
|
|
|
+ I915_WRITE(PIPESRC(intel_crtc->pipe),
|
|
|
|
+ ((crtc->mode.hdisplay - 1) << 16) |
|
|
|
|
+ (crtc->mode.vdisplay - 1));
|
|
|
|
+ if (!intel_crtc->config.pch_pfit.size &&
|
|
|
|
+ (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
|
|
|
|
+ intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
|
|
|
|
+ I915_WRITE(PF_CTL(intel_crtc->pipe), 0);
|
|
|
|
+ I915_WRITE(PF_WIN_POS(intel_crtc->pipe), 0);
|
|
|
|
+ I915_WRITE(PF_WIN_SZ(intel_crtc->pipe), 0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
ret = dev_priv->display.update_plane(crtc, fb, x, y);
|
|
ret = dev_priv->display.update_plane(crtc, fb, x, y);
|
|
if (ret) {
|
|
if (ret) {
|
|
intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
|
|
intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj);
|
|
@@ -2927,15 +2998,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
|
|
/* For PCH output, training FDI link */
|
|
/* For PCH output, training FDI link */
|
|
dev_priv->display.fdi_link_train(crtc);
|
|
dev_priv->display.fdi_link_train(crtc);
|
|
|
|
|
|
- /* XXX: pch pll's can be enabled any time before we enable the PCH
|
|
|
|
- * transcoder, and we actually should do this to not upset any PCH
|
|
|
|
- * transcoder that already use the clock when we share it.
|
|
|
|
- *
|
|
|
|
- * Note that enable_shared_dpll tries to do the right thing, but
|
|
|
|
- * get_shared_dpll unconditionally resets the pll - we need that to have
|
|
|
|
- * the right LVDS enable sequence. */
|
|
|
|
- ironlake_enable_shared_dpll(intel_crtc);
|
|
|
|
-
|
|
|
|
|
|
+ /* We need to program the right clock selection before writing the pixel
|
|
|
|
+ * mutliplier into the DPLL. */
|
|
if (HAS_PCH_CPT(dev)) {
|
|
if (HAS_PCH_CPT(dev)) {
|
|
u32 sel;
|
|
u32 sel;
|
|
|
|
|
|
@@ -2949,6 +3013,15 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
|
|
I915_WRITE(PCH_DPLL_SEL, temp);
|
|
I915_WRITE(PCH_DPLL_SEL, temp);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* XXX: pch pll's can be enabled any time before we enable the PCH
|
|
|
|
+ * transcoder, and we actually should do this to not upset any PCH
|
|
|
|
+ * transcoder that already use the clock when we share it.
|
|
|
|
+ *
|
|
|
|
+ * Note that enable_shared_dpll tries to do the right thing, but
|
|
|
|
+ * get_shared_dpll unconditionally resets the pll - we need that to have
|
|
|
|
+ * the right LVDS enable sequence. */
|
|
|
|
+ ironlake_enable_shared_dpll(intel_crtc);
|
|
|
|
+
|
|
/* set transcoder timing, panel must allow it */
|
|
/* set transcoder timing, panel must allow it */
|
|
assert_panel_unlocked(dev_priv, pipe);
|
|
assert_panel_unlocked(dev_priv, pipe);
|
|
ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
|
|
ironlake_pch_transcoder_set_timings(intel_crtc, pipe);
|
|
@@ -3031,7 +3104,7 @@ static void intel_put_shared_dpll(struct intel_crtc *crtc)
|
|
crtc->config.shared_dpll = DPLL_ID_PRIVATE;
|
|
crtc->config.shared_dpll = DPLL_ID_PRIVATE;
|
|
}
|
|
}
|
|
|
|
|
|
-static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc, u32 dpll, u32 fp)
|
|
|
|
|
|
+static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
|
|
@@ -3045,7 +3118,7 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
|
|
|
|
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
|
|
/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
|
|
- i = crtc->pipe;
|
|
|
|
|
|
+ i = (enum intel_dpll_id) crtc->pipe;
|
|
pll = &dev_priv->shared_dplls[i];
|
|
pll = &dev_priv->shared_dplls[i];
|
|
|
|
|
|
DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
|
|
DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
|
|
@@ -3061,8 +3134,8 @@ static struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
|
|
if (pll->refcount == 0)
|
|
if (pll->refcount == 0)
|
|
continue;
|
|
continue;
|
|
|
|
|
|
- if (dpll == (I915_READ(PCH_DPLL(pll->id)) & 0x7fffffff) &&
|
|
|
|
- fp == I915_READ(PCH_FP0(pll->id))) {
|
|
|
|
|
|
+ if (memcmp(&crtc->config.dpll_hw_state, &pll->hw_state,
|
|
|
|
+ sizeof(pll->hw_state)) == 0) {
|
|
DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n",
|
|
DRM_DEBUG_KMS("CRTC:%d sharing existing %s (refcount %d, ative %d)\n",
|
|
crtc->base.base.id,
|
|
crtc->base.base.id,
|
|
pll->name, pll->refcount, pll->active);
|
|
pll->name, pll->refcount, pll->active);
|
|
@@ -3096,13 +3169,7 @@ found:
|
|
WARN_ON(pll->on);
|
|
WARN_ON(pll->on);
|
|
assert_shared_dpll_disabled(dev_priv, pll);
|
|
assert_shared_dpll_disabled(dev_priv, pll);
|
|
|
|
|
|
- /* Wait for the clocks to stabilize before rewriting the regs */
|
|
|
|
- I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
- POSTING_READ(PCH_DPLL(pll->id));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- I915_WRITE(PCH_FP0(pll->id), fp);
|
|
|
|
- I915_WRITE(PCH_DPLL(pll->id), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
|
|
+ pll->mode_set(dev_priv, pll);
|
|
}
|
|
}
|
|
pll->refcount++;
|
|
pll->refcount++;
|
|
|
|
|
|
@@ -3174,7 +3241,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|
struct intel_encoder *encoder;
|
|
struct intel_encoder *encoder;
|
|
int pipe = intel_crtc->pipe;
|
|
int pipe = intel_crtc->pipe;
|
|
int plane = intel_crtc->plane;
|
|
int plane = intel_crtc->plane;
|
|
- u32 temp;
|
|
|
|
|
|
|
|
WARN_ON(!crtc->enabled);
|
|
WARN_ON(!crtc->enabled);
|
|
|
|
|
|
@@ -3188,12 +3254,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|
|
|
|
|
intel_update_watermarks(dev);
|
|
intel_update_watermarks(dev);
|
|
|
|
|
|
- if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
|
|
- temp = I915_READ(PCH_LVDS);
|
|
|
|
- if ((temp & LVDS_PORT_EN) == 0)
|
|
|
|
- I915_WRITE(PCH_LVDS, temp | LVDS_PORT_EN);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
+ if (encoder->pre_enable)
|
|
|
|
+ encoder->pre_enable(encoder);
|
|
|
|
|
|
if (intel_crtc->config.has_pch_encoder) {
|
|
if (intel_crtc->config.has_pch_encoder) {
|
|
/* Note: FDI PLL enabling _must_ be done before we enable the
|
|
/* Note: FDI PLL enabling _must_ be done before we enable the
|
|
@@ -3205,10 +3268,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
|
|
assert_fdi_rx_disabled(dev_priv, pipe);
|
|
assert_fdi_rx_disabled(dev_priv, pipe);
|
|
}
|
|
}
|
|
|
|
|
|
- for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
- if (encoder->pre_enable)
|
|
|
|
- encoder->pre_enable(encoder);
|
|
|
|
-
|
|
|
|
ironlake_pfit_enable(intel_crtc);
|
|
ironlake_pfit_enable(intel_crtc);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3389,7 +3448,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
|
drm_vblank_off(dev, pipe);
|
|
drm_vblank_off(dev, pipe);
|
|
|
|
|
|
- if (dev_priv->cfb_plane == plane)
|
|
|
|
|
|
+ if (dev_priv->fbc.plane == plane)
|
|
intel_disable_fbc(dev);
|
|
intel_disable_fbc(dev);
|
|
|
|
|
|
intel_crtc_update_cursor(crtc, false);
|
|
intel_crtc_update_cursor(crtc, false);
|
|
@@ -3462,7 +3521,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
|
|
drm_vblank_off(dev, pipe);
|
|
drm_vblank_off(dev, pipe);
|
|
|
|
|
|
/* FBC must be disabled before disabling the plane on HSW. */
|
|
/* FBC must be disabled before disabling the plane on HSW. */
|
|
- if (dev_priv->cfb_plane == plane)
|
|
|
|
|
|
+ if (dev_priv->fbc.plane == plane)
|
|
intel_disable_fbc(dev);
|
|
intel_disable_fbc(dev);
|
|
|
|
|
|
hsw_disable_ips(intel_crtc);
|
|
hsw_disable_ips(intel_crtc);
|
|
@@ -3599,7 +3658,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
|
|
if (encoder->pre_pll_enable)
|
|
if (encoder->pre_pll_enable)
|
|
encoder->pre_pll_enable(encoder);
|
|
encoder->pre_pll_enable(encoder);
|
|
|
|
|
|
- intel_enable_pll(dev_priv, pipe);
|
|
|
|
|
|
+ vlv_enable_pll(intel_crtc);
|
|
|
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
if (encoder->pre_enable)
|
|
if (encoder->pre_enable)
|
|
@@ -3640,12 +3699,12 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
|
|
intel_crtc->active = true;
|
|
intel_crtc->active = true;
|
|
intel_update_watermarks(dev);
|
|
intel_update_watermarks(dev);
|
|
|
|
|
|
- intel_enable_pll(dev_priv, pipe);
|
|
|
|
-
|
|
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
if (encoder->pre_enable)
|
|
if (encoder->pre_enable)
|
|
encoder->pre_enable(encoder);
|
|
encoder->pre_enable(encoder);
|
|
|
|
|
|
|
|
+ i9xx_enable_pll(intel_crtc);
|
|
|
|
+
|
|
i9xx_pfit_enable(intel_crtc);
|
|
i9xx_pfit_enable(intel_crtc);
|
|
|
|
|
|
intel_crtc_load_lut(crtc);
|
|
intel_crtc_load_lut(crtc);
|
|
@@ -3701,7 +3760,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
|
intel_crtc_wait_for_pending_flips(crtc);
|
|
drm_vblank_off(dev, pipe);
|
|
drm_vblank_off(dev, pipe);
|
|
|
|
|
|
- if (dev_priv->cfb_plane == plane)
|
|
|
|
|
|
+ if (dev_priv->fbc.plane == plane)
|
|
intel_disable_fbc(dev);
|
|
intel_disable_fbc(dev);
|
|
|
|
|
|
intel_crtc_dpms_overlay(intel_crtc, false);
|
|
intel_crtc_dpms_overlay(intel_crtc, false);
|
|
@@ -3717,7 +3776,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
|
|
if (encoder->post_disable)
|
|
if (encoder->post_disable)
|
|
encoder->post_disable(encoder);
|
|
encoder->post_disable(encoder);
|
|
|
|
|
|
- intel_disable_pll(dev_priv, pipe);
|
|
|
|
|
|
+ i9xx_disable_pll(dev_priv, pipe);
|
|
|
|
|
|
intel_crtc->active = false;
|
|
intel_crtc->active = false;
|
|
intel_update_fbc(dev);
|
|
intel_update_fbc(dev);
|
|
@@ -4266,14 +4325,17 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc,
|
|
}
|
|
}
|
|
|
|
|
|
I915_WRITE(FP0(pipe), fp);
|
|
I915_WRITE(FP0(pipe), fp);
|
|
|
|
+ crtc->config.dpll_hw_state.fp0 = fp;
|
|
|
|
|
|
crtc->lowfreq_avail = false;
|
|
crtc->lowfreq_avail = false;
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
|
|
reduced_clock && i915_powersave) {
|
|
reduced_clock && i915_powersave) {
|
|
I915_WRITE(FP1(pipe), fp2);
|
|
I915_WRITE(FP1(pipe), fp2);
|
|
|
|
+ crtc->config.dpll_hw_state.fp1 = fp2;
|
|
crtc->lowfreq_avail = true;
|
|
crtc->lowfreq_avail = true;
|
|
} else {
|
|
} else {
|
|
I915_WRITE(FP1(pipe), fp);
|
|
I915_WRITE(FP1(pipe), fp);
|
|
|
|
+ crtc->config.dpll_hw_state.fp1 = fp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4351,7 +4413,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
|
|
{
|
|
{
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
- struct intel_encoder *encoder;
|
|
|
|
int pipe = crtc->pipe;
|
|
int pipe = crtc->pipe;
|
|
u32 dpll, mdiv;
|
|
u32 dpll, mdiv;
|
|
u32 bestn, bestm1, bestm2, bestp1, bestp2;
|
|
u32 bestn, bestm1, bestm2, bestp1, bestp2;
|
|
@@ -4407,7 +4468,7 @@ static void vlv_update_pll(struct intel_crtc *crtc)
|
|
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
|
|
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
|
|
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
|
|
intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
|
|
vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
|
|
vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
|
|
- 0x005f0021);
|
|
|
|
|
|
+ 0x009f0003);
|
|
else
|
|
else
|
|
vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
|
|
vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
|
|
0x00d0000f);
|
|
0x00d0000f);
|
|
@@ -4440,10 +4501,6 @@ static void vlv_update_pll(struct intel_crtc *crtc)
|
|
|
|
|
|
vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000);
|
|
vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000);
|
|
|
|
|
|
- for_each_encoder_on_crtc(dev, &crtc->base, encoder)
|
|
|
|
- if (encoder->pre_pll_enable)
|
|
|
|
- encoder->pre_pll_enable(encoder);
|
|
|
|
-
|
|
|
|
/* Enable DPIO clock input */
|
|
/* Enable DPIO clock input */
|
|
dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
|
|
dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
|
|
DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
|
|
DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
|
|
@@ -4451,17 +4508,11 @@ static void vlv_update_pll(struct intel_crtc *crtc)
|
|
dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
|
|
dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
- I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
- POSTING_READ(DPLL(pipe));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1))
|
|
|
|
- DRM_ERROR("DPLL %d failed to lock\n", pipe);
|
|
|
|
|
|
+ crtc->config.dpll_hw_state.dpll = dpll;
|
|
|
|
|
|
dpll_md = (crtc->config.pixel_multiplier - 1)
|
|
dpll_md = (crtc->config.pixel_multiplier - 1)
|
|
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
- I915_WRITE(DPLL_MD(pipe), dpll_md);
|
|
|
|
- POSTING_READ(DPLL_MD(pipe));
|
|
|
|
|
|
+ crtc->config.dpll_hw_state.dpll_md = dpll_md;
|
|
|
|
|
|
if (crtc->config.has_dp_encoder)
|
|
if (crtc->config.has_dp_encoder)
|
|
intel_dp_set_m_n(crtc);
|
|
intel_dp_set_m_n(crtc);
|
|
@@ -4475,8 +4526,6 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
|
|
{
|
|
{
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
- struct intel_encoder *encoder;
|
|
|
|
- int pipe = crtc->pipe;
|
|
|
|
u32 dpll;
|
|
u32 dpll;
|
|
bool is_sdvo;
|
|
bool is_sdvo;
|
|
struct dpll *clock = &crtc->config.dpll;
|
|
struct dpll *clock = &crtc->config.dpll;
|
|
@@ -4499,10 +4548,10 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
|
|
}
|
|
}
|
|
|
|
|
|
if (is_sdvo)
|
|
if (is_sdvo)
|
|
- dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
|
|
+ dpll |= DPLL_SDVO_HIGH_SPEED;
|
|
|
|
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT))
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT))
|
|
- dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
|
|
+ dpll |= DPLL_SDVO_HIGH_SPEED;
|
|
|
|
|
|
/* compute bitmask from p1 value */
|
|
/* compute bitmask from p1 value */
|
|
if (IS_PINEVIEW(dev))
|
|
if (IS_PINEVIEW(dev))
|
|
@@ -4538,35 +4587,16 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
- I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
- POSTING_READ(DPLL(pipe));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- for_each_encoder_on_crtc(dev, &crtc->base, encoder)
|
|
|
|
- if (encoder->pre_pll_enable)
|
|
|
|
- encoder->pre_pll_enable(encoder);
|
|
|
|
-
|
|
|
|
- if (crtc->config.has_dp_encoder)
|
|
|
|
- intel_dp_set_m_n(crtc);
|
|
|
|
-
|
|
|
|
- I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
-
|
|
|
|
- /* Wait for the clocks to stabilize. */
|
|
|
|
- POSTING_READ(DPLL(pipe));
|
|
|
|
- udelay(150);
|
|
|
|
|
|
+ crtc->config.dpll_hw_state.dpll = dpll;
|
|
|
|
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
if (INTEL_INFO(dev)->gen >= 4) {
|
|
u32 dpll_md = (crtc->config.pixel_multiplier - 1)
|
|
u32 dpll_md = (crtc->config.pixel_multiplier - 1)
|
|
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
<< DPLL_MD_UDI_MULTIPLIER_SHIFT;
|
|
- I915_WRITE(DPLL_MD(pipe), dpll_md);
|
|
|
|
- } else {
|
|
|
|
- /* The pixel multiplier can only be updated once the
|
|
|
|
- * DPLL is enabled and the clocks are stable.
|
|
|
|
- *
|
|
|
|
- * So write it again.
|
|
|
|
- */
|
|
|
|
- I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
|
|
+ crtc->config.dpll_hw_state.dpll_md = dpll_md;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (crtc->config.has_dp_encoder)
|
|
|
|
+ intel_dp_set_m_n(crtc);
|
|
}
|
|
}
|
|
|
|
|
|
static void i8xx_update_pll(struct intel_crtc *crtc,
|
|
static void i8xx_update_pll(struct intel_crtc *crtc,
|
|
@@ -4575,8 +4605,6 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
|
|
{
|
|
{
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_device *dev = crtc->base.dev;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
- struct intel_encoder *encoder;
|
|
|
|
- int pipe = crtc->pipe;
|
|
|
|
u32 dpll;
|
|
u32 dpll;
|
|
struct dpll *clock = &crtc->config.dpll;
|
|
struct dpll *clock = &crtc->config.dpll;
|
|
|
|
|
|
@@ -4595,6 +4623,9 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
|
|
dpll |= PLL_P2_DIVIDE_BY_4;
|
|
dpll |= PLL_P2_DIVIDE_BY_4;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO))
|
|
|
|
+ dpll |= DPLL_DVO_2X_MODE;
|
|
|
|
+
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
|
|
if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
|
|
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
|
|
intel_panel_use_ssc(dev_priv) && num_connectors < 2)
|
|
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
|
|
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
|
|
@@ -4602,26 +4633,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
dpll |= PLL_REF_INPUT_DREFCLK;
|
|
|
|
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
dpll |= DPLL_VCO_ENABLE;
|
|
- I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
|
|
|
|
- POSTING_READ(DPLL(pipe));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- for_each_encoder_on_crtc(dev, &crtc->base, encoder)
|
|
|
|
- if (encoder->pre_pll_enable)
|
|
|
|
- encoder->pre_pll_enable(encoder);
|
|
|
|
-
|
|
|
|
- I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
-
|
|
|
|
- /* Wait for the clocks to stabilize. */
|
|
|
|
- POSTING_READ(DPLL(pipe));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- /* The pixel multiplier can only be updated once the
|
|
|
|
- * DPLL is enabled and the clocks are stable.
|
|
|
|
- *
|
|
|
|
- * So write it again.
|
|
|
|
- */
|
|
|
|
- I915_WRITE(DPLL(pipe), dpll);
|
|
|
|
|
|
+ crtc->config.dpll_hw_state.dpll = dpll;
|
|
}
|
|
}
|
|
|
|
|
|
static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
|
|
static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)
|
|
@@ -4727,6 +4739,27 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
|
|
pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
|
|
pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
|
|
|
|
+ struct intel_crtc_config *pipe_config)
|
|
|
|
+{
|
|
|
|
+ struct drm_crtc *crtc = &intel_crtc->base;
|
|
|
|
+
|
|
|
|
+ crtc->mode.hdisplay = pipe_config->adjusted_mode.crtc_hdisplay;
|
|
|
|
+ crtc->mode.htotal = pipe_config->adjusted_mode.crtc_htotal;
|
|
|
|
+ crtc->mode.hsync_start = pipe_config->adjusted_mode.crtc_hsync_start;
|
|
|
|
+ crtc->mode.hsync_end = pipe_config->adjusted_mode.crtc_hsync_end;
|
|
|
|
+
|
|
|
|
+ crtc->mode.vdisplay = pipe_config->adjusted_mode.crtc_vdisplay;
|
|
|
|
+ crtc->mode.vtotal = pipe_config->adjusted_mode.crtc_vtotal;
|
|
|
|
+ crtc->mode.vsync_start = pipe_config->adjusted_mode.crtc_vsync_start;
|
|
|
|
+ crtc->mode.vsync_end = pipe_config->adjusted_mode.crtc_vsync_end;
|
|
|
|
+
|
|
|
|
+ crtc->mode.flags = pipe_config->adjusted_mode.flags;
|
|
|
|
+
|
|
|
|
+ crtc->mode.clock = pipe_config->adjusted_mode.clock;
|
|
|
|
+ crtc->mode.flags |= pipe_config->adjusted_mode.flags;
|
|
|
|
+}
|
|
|
|
+
|
|
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
|
static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
|
|
{
|
|
{
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
|
struct drm_device *dev = intel_crtc->base.dev;
|
|
@@ -4942,7 +4975,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
uint32_t tmp;
|
|
uint32_t tmp;
|
|
|
|
|
|
- pipe_config->cpu_transcoder = crtc->pipe;
|
|
|
|
|
|
+ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
|
|
|
|
tmp = I915_READ(PIPECONF(crtc->pipe));
|
|
tmp = I915_READ(PIPECONF(crtc->pipe));
|
|
@@ -4958,6 +4991,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
|
pipe_config->pixel_multiplier =
|
|
pipe_config->pixel_multiplier =
|
|
((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
|
|
((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
|
|
>> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
|
|
>> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
|
|
|
|
+ pipe_config->dpll_hw_state.dpll_md = tmp;
|
|
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
|
|
} else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) {
|
|
tmp = I915_READ(DPLL(crtc->pipe));
|
|
tmp = I915_READ(DPLL(crtc->pipe));
|
|
pipe_config->pixel_multiplier =
|
|
pipe_config->pixel_multiplier =
|
|
@@ -4969,6 +5003,16 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
|
|
* function. */
|
|
* function. */
|
|
pipe_config->pixel_multiplier = 1;
|
|
pipe_config->pixel_multiplier = 1;
|
|
}
|
|
}
|
|
|
|
+ pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe));
|
|
|
|
+ if (!IS_VALLEYVIEW(dev)) {
|
|
|
|
+ pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe));
|
|
|
|
+ pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe));
|
|
|
|
+ } else {
|
|
|
|
+ /* Mask out read-only status bits. */
|
|
|
|
+ pipe_config->dpll_hw_state.dpll &= ~(DPLL_LOCK_VLV |
|
|
|
|
+ DPLL_PORTC_READY_MASK |
|
|
|
|
+ DPLL_PORTB_READY_MASK);
|
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -5613,9 +5657,9 @@ static uint32_t ironlake_compute_dpll(struct intel_crtc *intel_crtc,
|
|
<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
|
|
<< PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
|
|
|
|
|
|
if (is_sdvo)
|
|
if (is_sdvo)
|
|
- dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
|
|
+ dpll |= DPLL_SDVO_HIGH_SPEED;
|
|
if (intel_crtc->config.has_dp_encoder)
|
|
if (intel_crtc->config.has_dp_encoder)
|
|
- dpll |= DPLL_DVO_HIGH_SPEED;
|
|
|
|
|
|
+ dpll |= DPLL_SDVO_HIGH_SPEED;
|
|
|
|
|
|
/* compute bitmask from p1 value */
|
|
/* compute bitmask from p1 value */
|
|
dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
|
|
dpll |= (1 << (intel_crtc->config.dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
|
|
@@ -5711,7 +5755,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|
else
|
|
else
|
|
intel_crtc->config.dpll_hw_state.fp1 = fp;
|
|
intel_crtc->config.dpll_hw_state.fp1 = fp;
|
|
|
|
|
|
- pll = intel_get_shared_dpll(intel_crtc, dpll, fp);
|
|
|
|
|
|
+ pll = intel_get_shared_dpll(intel_crtc);
|
|
if (pll == NULL) {
|
|
if (pll == NULL) {
|
|
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
|
|
DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
|
|
pipe_name(pipe));
|
|
pipe_name(pipe));
|
|
@@ -5723,10 +5767,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|
if (intel_crtc->config.has_dp_encoder)
|
|
if (intel_crtc->config.has_dp_encoder)
|
|
intel_dp_set_m_n(intel_crtc);
|
|
intel_dp_set_m_n(intel_crtc);
|
|
|
|
|
|
- for_each_encoder_on_crtc(dev, crtc, encoder)
|
|
|
|
- if (encoder->pre_pll_enable)
|
|
|
|
- encoder->pre_pll_enable(encoder);
|
|
|
|
-
|
|
|
|
if (is_lvds && has_reduced_clock && i915_powersave)
|
|
if (is_lvds && has_reduced_clock && i915_powersave)
|
|
intel_crtc->lowfreq_avail = true;
|
|
intel_crtc->lowfreq_avail = true;
|
|
else
|
|
else
|
|
@@ -5735,23 +5775,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
|
|
if (intel_crtc->config.has_pch_encoder) {
|
|
if (intel_crtc->config.has_pch_encoder) {
|
|
pll = intel_crtc_to_shared_dpll(intel_crtc);
|
|
pll = intel_crtc_to_shared_dpll(intel_crtc);
|
|
|
|
|
|
- I915_WRITE(PCH_DPLL(pll->id), dpll);
|
|
|
|
-
|
|
|
|
- /* Wait for the clocks to stabilize. */
|
|
|
|
- POSTING_READ(PCH_DPLL(pll->id));
|
|
|
|
- udelay(150);
|
|
|
|
-
|
|
|
|
- /* The pixel multiplier can only be updated once the
|
|
|
|
- * DPLL is enabled and the clocks are stable.
|
|
|
|
- *
|
|
|
|
- * So write it again.
|
|
|
|
- */
|
|
|
|
- I915_WRITE(PCH_DPLL(pll->id), dpll);
|
|
|
|
-
|
|
|
|
- if (has_reduced_clock)
|
|
|
|
- I915_WRITE(PCH_FP1(pll->id), fp2);
|
|
|
|
- else
|
|
|
|
- I915_WRITE(PCH_FP1(pll->id), fp);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
intel_set_pipe_timings(intel_crtc);
|
|
intel_set_pipe_timings(intel_crtc);
|
|
@@ -5823,7 +5846,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
uint32_t tmp;
|
|
uint32_t tmp;
|
|
|
|
|
|
- pipe_config->cpu_transcoder = crtc->pipe;
|
|
|
|
|
|
+ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
|
|
|
|
tmp = I915_READ(PIPECONF(crtc->pipe));
|
|
tmp = I915_READ(PIPECONF(crtc->pipe));
|
|
@@ -5841,12 +5864,9 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
|
|
|
|
|
ironlake_get_fdi_m_n_config(crtc, pipe_config);
|
|
ironlake_get_fdi_m_n_config(crtc, pipe_config);
|
|
|
|
|
|
- /* XXX: Can't properly read out the pch dpll pixel multiplier
|
|
|
|
- * since we don't have state tracking for pch clocks yet. */
|
|
|
|
- pipe_config->pixel_multiplier = 1;
|
|
|
|
-
|
|
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
if (HAS_PCH_IBX(dev_priv->dev)) {
|
|
- pipe_config->shared_dpll = crtc->pipe;
|
|
|
|
|
|
+ pipe_config->shared_dpll =
|
|
|
|
+ (enum intel_dpll_id) crtc->pipe;
|
|
} else {
|
|
} else {
|
|
tmp = I915_READ(PCH_DPLL_SEL);
|
|
tmp = I915_READ(PCH_DPLL_SEL);
|
|
if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
|
|
if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
|
|
@@ -5859,6 +5879,11 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
|
|
|
|
|
|
WARN_ON(!pll->get_hw_state(dev_priv, pll,
|
|
WARN_ON(!pll->get_hw_state(dev_priv, pll,
|
|
&pipe_config->dpll_hw_state));
|
|
&pipe_config->dpll_hw_state));
|
|
|
|
+
|
|
|
|
+ tmp = pipe_config->dpll_hw_state.dpll;
|
|
|
|
+ pipe_config->pixel_multiplier =
|
|
|
|
+ ((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK)
|
|
|
|
+ >> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1;
|
|
} else {
|
|
} else {
|
|
pipe_config->pixel_multiplier = 1;
|
|
pipe_config->pixel_multiplier = 1;
|
|
}
|
|
}
|
|
@@ -5938,7 +5963,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
|
|
enum intel_display_power_domain pfit_domain;
|
|
enum intel_display_power_domain pfit_domain;
|
|
uint32_t tmp;
|
|
uint32_t tmp;
|
|
|
|
|
|
- pipe_config->cpu_transcoder = crtc->pipe;
|
|
|
|
|
|
+ pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
|
|
|
|
tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
|
|
tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
|
|
@@ -6551,7 +6576,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|
goto fail_unpin;
|
|
goto fail_unpin;
|
|
}
|
|
}
|
|
|
|
|
|
- addr = obj->gtt_offset;
|
|
|
|
|
|
+ addr = i915_gem_obj_ggtt_offset(obj);
|
|
} else {
|
|
} else {
|
|
int align = IS_I830(dev) ? 16 * 1024 : 256;
|
|
int align = IS_I830(dev) ? 16 * 1024 : 256;
|
|
ret = i915_gem_attach_phys_object(dev, obj,
|
|
ret = i915_gem_attach_phys_object(dev, obj,
|
|
@@ -6878,11 +6903,12 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
|
|
}
|
|
}
|
|
|
|
|
|
/* Returns the clock of the currently programmed mode of the given pipe. */
|
|
/* Returns the clock of the currently programmed mode of the given pipe. */
|
|
-static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
|
|
|
|
|
|
+static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
|
|
|
|
+ struct intel_crtc_config *pipe_config)
|
|
{
|
|
{
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
|
- int pipe = intel_crtc->pipe;
|
|
|
|
|
|
+ int pipe = pipe_config->cpu_transcoder;
|
|
u32 dpll = I915_READ(DPLL(pipe));
|
|
u32 dpll = I915_READ(DPLL(pipe));
|
|
u32 fp;
|
|
u32 fp;
|
|
intel_clock_t clock;
|
|
intel_clock_t clock;
|
|
@@ -6921,7 +6947,8 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
|
|
default:
|
|
default:
|
|
DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
|
|
DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
|
|
"mode\n", (int)(dpll & DPLL_MODE_MASK));
|
|
"mode\n", (int)(dpll & DPLL_MODE_MASK));
|
|
- return 0;
|
|
|
|
|
|
+ pipe_config->adjusted_mode.clock = 0;
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
if (IS_PINEVIEW(dev))
|
|
if (IS_PINEVIEW(dev))
|
|
@@ -6958,12 +6985,55 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* XXX: It would be nice to validate the clocks, but we can't reuse
|
|
|
|
- * i830PllIsValid() because it relies on the xf86_config connector
|
|
|
|
- * configuration being accurate, which it isn't necessarily.
|
|
|
|
|
|
+ pipe_config->adjusted_mode.clock = clock.dot *
|
|
|
|
+ pipe_config->pixel_multiplier;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
|
|
|
|
+ struct intel_crtc_config *pipe_config)
|
|
|
|
+{
|
|
|
|
+ struct drm_device *dev = crtc->base.dev;
|
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
+ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
|
|
|
+ int link_freq, repeat;
|
|
|
|
+ u64 clock;
|
|
|
|
+ u32 link_m, link_n;
|
|
|
|
+
|
|
|
|
+ repeat = pipe_config->pixel_multiplier;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The calculation for the data clock is:
|
|
|
|
+ * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp
|
|
|
|
+ * But we want to avoid losing precison if possible, so:
|
|
|
|
+ * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp))
|
|
|
|
+ *
|
|
|
|
+ * and the link clock is simpler:
|
|
|
|
+ * link_clock = (m * link_clock * repeat) / n
|
|
*/
|
|
*/
|
|
|
|
|
|
- return clock.dot;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * We need to get the FDI or DP link clock here to derive
|
|
|
|
+ * the M/N dividers.
|
|
|
|
+ *
|
|
|
|
+ * For FDI, we read it from the BIOS or use a fixed 2.7GHz.
|
|
|
|
+ * For DP, it's either 1.62GHz or 2.7GHz.
|
|
|
|
+ * We do our calculations in 10*MHz since we don't need much precison.
|
|
|
|
+ */
|
|
|
|
+ if (pipe_config->has_pch_encoder)
|
|
|
|
+ link_freq = intel_fdi_link_freq(dev) * 10000;
|
|
|
|
+ else
|
|
|
|
+ link_freq = pipe_config->port_clock;
|
|
|
|
+
|
|
|
|
+ link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder));
|
|
|
|
+ link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder));
|
|
|
|
+
|
|
|
|
+ if (!link_m || !link_n)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
|
|
|
|
+ do_div(clock, link_n);
|
|
|
|
+
|
|
|
|
+ pipe_config->adjusted_mode.clock = clock;
|
|
}
|
|
}
|
|
|
|
|
|
/** Returns the currently programmed mode of the given pipe. */
|
|
/** Returns the currently programmed mode of the given pipe. */
|
|
@@ -6974,6 +7044,7 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
|
|
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
|
|
struct drm_display_mode *mode;
|
|
struct drm_display_mode *mode;
|
|
|
|
+ struct intel_crtc_config pipe_config;
|
|
int htot = I915_READ(HTOTAL(cpu_transcoder));
|
|
int htot = I915_READ(HTOTAL(cpu_transcoder));
|
|
int hsync = I915_READ(HSYNC(cpu_transcoder));
|
|
int hsync = I915_READ(HSYNC(cpu_transcoder));
|
|
int vtot = I915_READ(VTOTAL(cpu_transcoder));
|
|
int vtot = I915_READ(VTOTAL(cpu_transcoder));
|
|
@@ -6983,7 +7054,18 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
|
|
if (!mode)
|
|
if (!mode)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- mode->clock = intel_crtc_clock_get(dev, crtc);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Construct a pipe_config sufficient for getting the clock info
|
|
|
|
+ * back out of crtc_clock_get.
|
|
|
|
+ *
|
|
|
|
+ * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
|
|
|
|
+ * to use a real value here instead.
|
|
|
|
+ */
|
|
|
|
+ pipe_config.cpu_transcoder = (enum transcoder) intel_crtc->pipe;
|
|
|
|
+ pipe_config.pixel_multiplier = 1;
|
|
|
|
+ i9xx_crtc_clock_get(intel_crtc, &pipe_config);
|
|
|
|
+
|
|
|
|
+ mode->clock = pipe_config.adjusted_mode.clock;
|
|
mode->hdisplay = (htot & 0xffff) + 1;
|
|
mode->hdisplay = (htot & 0xffff) + 1;
|
|
mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
|
|
mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
|
|
mode->hsync_start = (hsync & 0xffff) + 1;
|
|
mode->hsync_start = (hsync & 0xffff) + 1;
|
|
@@ -7266,7 +7348,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
intel_ring_emit(ring, 0); /* aux display base address, unused */
|
|
intel_ring_emit(ring, 0); /* aux display base address, unused */
|
|
|
|
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
@@ -7307,7 +7389,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 |
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 |
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
intel_ring_emit(ring, MI_NOOP);
|
|
intel_ring_emit(ring, MI_NOOP);
|
|
|
|
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
@@ -7347,7 +7429,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
intel_ring_emit(ring, fb->pitches[0]);
|
|
intel_ring_emit(ring,
|
|
intel_ring_emit(ring,
|
|
- (obj->gtt_offset + intel_crtc->dspaddr_offset) |
|
|
|
|
|
|
+ (i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset) |
|
|
obj->tiling_mode);
|
|
obj->tiling_mode);
|
|
|
|
|
|
/* XXX Enabling the panel-fitter across page-flip is so far
|
|
/* XXX Enabling the panel-fitter across page-flip is so far
|
|
@@ -7390,7 +7472,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP |
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
|
|
intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
|
|
intel_ring_emit(ring, fb->pitches[0] | obj->tiling_mode);
|
|
- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
/* Contrary to the suggestions in the documentation,
|
|
/* Contrary to the suggestions in the documentation,
|
|
* "Enable Panel Fitter" does not seem to be required when page
|
|
* "Enable Panel Fitter" does not seem to be required when page
|
|
@@ -7455,7 +7537,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
|
|
|
|
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
|
|
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
|
|
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
|
|
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
|
|
- intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
|
|
|
|
|
|
+ intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);
|
|
intel_ring_emit(ring, (MI_NOOP));
|
|
intel_ring_emit(ring, (MI_NOOP));
|
|
|
|
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
intel_mark_page_flip_active(intel_crtc);
|
|
@@ -7809,7 +7891,8 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
|
|
|
|
|
|
drm_mode_copy(&pipe_config->adjusted_mode, mode);
|
|
drm_mode_copy(&pipe_config->adjusted_mode, mode);
|
|
drm_mode_copy(&pipe_config->requested_mode, mode);
|
|
drm_mode_copy(&pipe_config->requested_mode, mode);
|
|
- pipe_config->cpu_transcoder = to_intel_crtc(crtc)->pipe;
|
|
|
|
|
|
+ pipe_config->cpu_transcoder =
|
|
|
|
+ (enum transcoder) to_intel_crtc(crtc)->pipe;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
pipe_config->shared_dpll = DPLL_ID_PRIVATE;
|
|
|
|
|
|
/* Compute a starting value for pipe_config->pipe_bpp taking the source
|
|
/* Compute a starting value for pipe_config->pipe_bpp taking the source
|
|
@@ -8044,6 +8127,28 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool intel_fuzzy_clock_check(struct intel_crtc_config *cur,
|
|
|
|
+ struct intel_crtc_config *new)
|
|
|
|
+{
|
|
|
|
+ int clock1, clock2, diff;
|
|
|
|
+
|
|
|
|
+ clock1 = cur->adjusted_mode.clock;
|
|
|
|
+ clock2 = new->adjusted_mode.clock;
|
|
|
|
+
|
|
|
|
+ if (clock1 == clock2)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ if (!clock1 || !clock2)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ diff = abs(clock1 - clock2);
|
|
|
|
+
|
|
|
|
+ if (((((diff + clock1 + clock2) * 100)) / (clock1 + clock2)) < 105)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
|
|
#define for_each_intel_crtc_masked(dev, mask, intel_crtc) \
|
|
list_for_each_entry((intel_crtc), \
|
|
list_for_each_entry((intel_crtc), \
|
|
&(dev)->mode_config.crtc_list, \
|
|
&(dev)->mode_config.crtc_list, \
|
|
@@ -8075,7 +8180,7 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|
|
|
|
|
#define PIPE_CONF_CHECK_FLAGS(name, mask) \
|
|
#define PIPE_CONF_CHECK_FLAGS(name, mask) \
|
|
if ((current_config->name ^ pipe_config->name) & (mask)) { \
|
|
if ((current_config->name ^ pipe_config->name) & (mask)) { \
|
|
- DRM_ERROR("mismatch in " #name " " \
|
|
|
|
|
|
+ DRM_ERROR("mismatch in " #name "(" #mask ") " \
|
|
"(expected %i, found %i)\n", \
|
|
"(expected %i, found %i)\n", \
|
|
current_config->name & (mask), \
|
|
current_config->name & (mask), \
|
|
pipe_config->name & (mask)); \
|
|
pipe_config->name & (mask)); \
|
|
@@ -8109,8 +8214,7 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|
PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start);
|
|
PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_start);
|
|
PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end);
|
|
PIPE_CONF_CHECK_I(adjusted_mode.crtc_vsync_end);
|
|
|
|
|
|
- if (!HAS_PCH_SPLIT(dev))
|
|
|
|
- PIPE_CONF_CHECK_I(pixel_multiplier);
|
|
|
|
|
|
+ PIPE_CONF_CHECK_I(pixel_multiplier);
|
|
|
|
|
|
PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
|
|
PIPE_CONF_CHECK_FLAGS(adjusted_mode.flags,
|
|
DRM_MODE_FLAG_INTERLACE);
|
|
DRM_MODE_FLAG_INTERLACE);
|
|
@@ -8141,6 +8245,7 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|
|
|
|
|
PIPE_CONF_CHECK_I(shared_dpll);
|
|
PIPE_CONF_CHECK_I(shared_dpll);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
|
|
|
|
+ PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
|
|
PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
|
|
|
|
|
|
@@ -8149,6 +8254,15 @@ intel_pipe_config_compare(struct drm_device *dev,
|
|
#undef PIPE_CONF_CHECK_FLAGS
|
|
#undef PIPE_CONF_CHECK_FLAGS
|
|
#undef PIPE_CONF_QUIRK
|
|
#undef PIPE_CONF_QUIRK
|
|
|
|
|
|
|
|
+ if (!IS_HASWELL(dev)) {
|
|
|
|
+ if (!intel_fuzzy_clock_check(current_config, pipe_config)) {
|
|
|
|
+ DRM_ERROR("mismatch in clock (expected %d, found %d)\n",
|
|
|
|
+ current_config->adjusted_mode.clock,
|
|
|
|
+ pipe_config->adjusted_mode.clock);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -8278,6 +8392,9 @@ check_crtc_state(struct drm_device *dev)
|
|
encoder->get_config(encoder, &pipe_config);
|
|
encoder->get_config(encoder, &pipe_config);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (dev_priv->display.get_clock)
|
|
|
|
+ dev_priv->display.get_clock(crtc, &pipe_config);
|
|
|
|
+
|
|
WARN(crtc->active != active,
|
|
WARN(crtc->active != active,
|
|
"crtc active state doesn't match with hw state "
|
|
"crtc active state doesn't match with hw state "
|
|
"(expected %i, found %i)\n", crtc->active, active);
|
|
"(expected %i, found %i)\n", crtc->active, active);
|
|
@@ -8569,8 +8686,16 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
|
|
} else if (set->crtc->fb != set->fb) {
|
|
} else if (set->crtc->fb != set->fb) {
|
|
/* If we have no fb then treat it as a full mode set */
|
|
/* If we have no fb then treat it as a full mode set */
|
|
if (set->crtc->fb == NULL) {
|
|
if (set->crtc->fb == NULL) {
|
|
- DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
|
|
|
|
- config->mode_changed = true;
|
|
|
|
|
|
+ struct intel_crtc *intel_crtc =
|
|
|
|
+ to_intel_crtc(set->crtc);
|
|
|
|
+
|
|
|
|
+ if (intel_crtc->active && i915_fastboot) {
|
|
|
|
+ DRM_DEBUG_KMS("crtc has no fb, will flip\n");
|
|
|
|
+ config->fb_changed = true;
|
|
|
|
+ } else {
|
|
|
|
+ DRM_DEBUG_KMS("inactive crtc, full mode set\n");
|
|
|
|
+ config->mode_changed = true;
|
|
|
|
+ }
|
|
} else if (set->fb == NULL) {
|
|
} else if (set->fb == NULL) {
|
|
config->mode_changed = true;
|
|
config->mode_changed = true;
|
|
} else if (set->fb->pixel_format !=
|
|
} else if (set->fb->pixel_format !=
|
|
@@ -8800,19 +8925,32 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
|
|
return val & DPLL_VCO_ENABLE;
|
|
return val & DPLL_VCO_ENABLE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
|
|
|
|
+ struct intel_shared_dpll *pll)
|
|
|
|
+{
|
|
|
|
+ I915_WRITE(PCH_FP0(pll->id), pll->hw_state.fp0);
|
|
|
|
+ I915_WRITE(PCH_FP1(pll->id), pll->hw_state.fp1);
|
|
|
|
+}
|
|
|
|
+
|
|
static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
|
|
static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
|
|
struct intel_shared_dpll *pll)
|
|
struct intel_shared_dpll *pll)
|
|
{
|
|
{
|
|
- uint32_t reg, val;
|
|
|
|
-
|
|
|
|
/* PCH refclock must be enabled first */
|
|
/* PCH refclock must be enabled first */
|
|
assert_pch_refclk_enabled(dev_priv);
|
|
assert_pch_refclk_enabled(dev_priv);
|
|
|
|
|
|
- reg = PCH_DPLL(pll->id);
|
|
|
|
- val = I915_READ(reg);
|
|
|
|
- val |= DPLL_VCO_ENABLE;
|
|
|
|
- I915_WRITE(reg, val);
|
|
|
|
- POSTING_READ(reg);
|
|
|
|
|
|
+ I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll);
|
|
|
|
+
|
|
|
|
+ /* Wait for the clocks to stabilize. */
|
|
|
|
+ POSTING_READ(PCH_DPLL(pll->id));
|
|
|
|
+ udelay(150);
|
|
|
|
+
|
|
|
|
+ /* The pixel multiplier can only be updated once the
|
|
|
|
+ * DPLL is enabled and the clocks are stable.
|
|
|
|
+ *
|
|
|
|
+ * So write it again.
|
|
|
|
+ */
|
|
|
|
+ I915_WRITE(PCH_DPLL(pll->id), pll->hw_state.dpll);
|
|
|
|
+ POSTING_READ(PCH_DPLL(pll->id));
|
|
udelay(200);
|
|
udelay(200);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -8821,7 +8959,6 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
|
|
{
|
|
{
|
|
struct drm_device *dev = dev_priv->dev;
|
|
struct drm_device *dev = dev_priv->dev;
|
|
struct intel_crtc *crtc;
|
|
struct intel_crtc *crtc;
|
|
- uint32_t reg, val;
|
|
|
|
|
|
|
|
/* Make sure no transcoder isn't still depending on us. */
|
|
/* Make sure no transcoder isn't still depending on us. */
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
|
|
@@ -8829,11 +8966,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
|
|
assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
|
|
assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
|
|
}
|
|
}
|
|
|
|
|
|
- reg = PCH_DPLL(pll->id);
|
|
|
|
- val = I915_READ(reg);
|
|
|
|
- val &= ~DPLL_VCO_ENABLE;
|
|
|
|
- I915_WRITE(reg, val);
|
|
|
|
- POSTING_READ(reg);
|
|
|
|
|
|
+ I915_WRITE(PCH_DPLL(pll->id), 0);
|
|
|
|
+ POSTING_READ(PCH_DPLL(pll->id));
|
|
udelay(200);
|
|
udelay(200);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -8852,6 +8986,7 @@ static void ibx_pch_dpll_init(struct drm_device *dev)
|
|
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
|
|
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
|
|
dev_priv->shared_dplls[i].id = i;
|
|
dev_priv->shared_dplls[i].id = i;
|
|
dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
|
|
dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
|
|
|
|
+ dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
|
|
dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
|
|
dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
|
|
dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
|
|
dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
|
|
dev_priv->shared_dplls[i].get_hw_state =
|
|
dev_priv->shared_dplls[i].get_hw_state =
|
|
@@ -9268,6 +9403,7 @@ static void intel_init_display(struct drm_device *dev)
|
|
dev_priv->display.update_plane = ironlake_update_plane;
|
|
dev_priv->display.update_plane = ironlake_update_plane;
|
|
} else if (HAS_PCH_SPLIT(dev)) {
|
|
} else if (HAS_PCH_SPLIT(dev)) {
|
|
dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
|
|
dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
|
|
|
|
+ dev_priv->display.get_clock = ironlake_crtc_clock_get;
|
|
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
|
|
dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
|
|
dev_priv->display.crtc_enable = ironlake_crtc_enable;
|
|
dev_priv->display.crtc_enable = ironlake_crtc_enable;
|
|
dev_priv->display.crtc_disable = ironlake_crtc_disable;
|
|
dev_priv->display.crtc_disable = ironlake_crtc_disable;
|
|
@@ -9275,6 +9411,7 @@ static void intel_init_display(struct drm_device *dev)
|
|
dev_priv->display.update_plane = ironlake_update_plane;
|
|
dev_priv->display.update_plane = ironlake_update_plane;
|
|
} else if (IS_VALLEYVIEW(dev)) {
|
|
} else if (IS_VALLEYVIEW(dev)) {
|
|
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
|
|
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
|
|
|
|
+ dev_priv->display.get_clock = i9xx_crtc_clock_get;
|
|
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
|
|
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
|
|
dev_priv->display.crtc_enable = valleyview_crtc_enable;
|
|
dev_priv->display.crtc_enable = valleyview_crtc_enable;
|
|
dev_priv->display.crtc_disable = i9xx_crtc_disable;
|
|
dev_priv->display.crtc_disable = i9xx_crtc_disable;
|
|
@@ -9282,6 +9419,7 @@ static void intel_init_display(struct drm_device *dev)
|
|
dev_priv->display.update_plane = i9xx_update_plane;
|
|
dev_priv->display.update_plane = i9xx_update_plane;
|
|
} else {
|
|
} else {
|
|
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
|
|
dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
|
|
|
|
+ dev_priv->display.get_clock = i9xx_crtc_clock_get;
|
|
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
|
|
dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
|
|
dev_priv->display.crtc_enable = i9xx_crtc_enable;
|
|
dev_priv->display.crtc_enable = i9xx_crtc_enable;
|
|
dev_priv->display.crtc_disable = i9xx_crtc_disable;
|
|
dev_priv->display.crtc_disable = i9xx_crtc_disable;
|
|
@@ -9566,7 +9704,7 @@ void intel_modeset_init(struct drm_device *dev)
|
|
INTEL_INFO(dev)->num_pipes,
|
|
INTEL_INFO(dev)->num_pipes,
|
|
INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
|
|
INTEL_INFO(dev)->num_pipes > 1 ? "s" : "");
|
|
|
|
|
|
- for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) {
|
|
|
|
|
|
+ for_each_pipe(i) {
|
|
intel_crtc_init(dev, i);
|
|
intel_crtc_init(dev, i);
|
|
for (j = 0; j < dev_priv->num_plane; j++) {
|
|
for (j = 0; j < dev_priv->num_plane; j++) {
|
|
ret = intel_plane_init(dev, i, j);
|
|
ret = intel_plane_init(dev, i, j);
|
|
@@ -9842,6 +9980,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
|
|
pipe);
|
|
pipe);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
|
|
|
+ base.head) {
|
|
|
|
+ if (!crtc->active)
|
|
|
|
+ continue;
|
|
|
|
+ if (dev_priv->display.get_clock)
|
|
|
|
+ dev_priv->display.get_clock(crtc,
|
|
|
|
+ &crtc->config);
|
|
|
|
+ }
|
|
|
|
+
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
list_for_each_entry(connector, &dev->mode_config.connector_list,
|
|
base.head) {
|
|
base.head) {
|
|
if (connector->get_hw_state(connector)) {
|
|
if (connector->get_hw_state(connector)) {
|
|
@@ -9872,6 +10019,22 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
|
|
|
|
|
|
intel_modeset_readout_hw_state(dev);
|
|
intel_modeset_readout_hw_state(dev);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Now that we have the config, copy it to each CRTC struct
|
|
|
|
+ * Note that this could go away if we move to using crtc_config
|
|
|
|
+ * checking everywhere.
|
|
|
|
+ */
|
|
|
|
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list,
|
|
|
|
+ base.head) {
|
|
|
|
+ if (crtc->active && i915_fastboot) {
|
|
|
|
+ intel_crtc_mode_from_pipe_config(crtc, &crtc->config);
|
|
|
|
+
|
|
|
|
+ DRM_DEBUG_KMS("[CRTC:%d] found active mode: ",
|
|
|
|
+ crtc->base.base.id);
|
|
|
|
+ drm_mode_debug_printmodeline(&crtc->base.mode);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/* HW state is read out, now we need to sanitize this mess. */
|
|
/* HW state is read out, now we need to sanitize this mess. */
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list,
|
|
base.head) {
|
|
base.head) {
|
|
@@ -10002,9 +10165,6 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_DEBUG_FS
|
|
|
|
-#include <linux/seq_file.h>
|
|
|
|
-
|
|
|
|
struct intel_display_error_state {
|
|
struct intel_display_error_state {
|
|
|
|
|
|
u32 power_well_driver;
|
|
u32 power_well_driver;
|
|
@@ -10148,4 +10308,3 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m,
|
|
err_printf(m, " BASE: %08x\n", error->cursor[i].base);
|
|
err_printf(m, " BASE: %08x\n", error->cursor[i].base);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-#endif
|
|
|