Commit a21f9760 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: tune down the noise of the RP irq limit fail
  drm/i915: Remove the error message for unbinding pinned buffers
  drm/i915: Limit page allocations to lowmem (dma32) for i965
  drm/i915: always use RPNSWREQ for turbo change requests
  drm/i915: reject doubleclocked cea modes on dp
  drm/i915: Adding TV Out Missing modes.
  drm/i915: wait for a vblank to pass after tv detect
  drm/i915: no lvds quirk for HP t5740e Thin Client
  drm/i915: enable vdd when switching off the eDP panel
  drm/i915: Fix PCH PLL assertions to not assume CRTC:PLL relationship
  drm/i915: Always update RPS interrupts thresholds along with frequency
  drm/i915: properly handle interlaced bit for sdvo dtd conversion
  drm/i915: fix module unload since error_state rework
  drm/i915: be more careful when returning -ENXIO in gmbus transfer
parents 1ebf169a ef12dab7
...@@ -2032,6 +2032,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor) ...@@ -2032,6 +2032,8 @@ void i915_debugfs_cleanup(struct drm_minor *minor)
1, minor); 1, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops, drm_debugfs_remove_files((struct drm_info_list *) &i915_ring_stop_fops,
1, minor); 1, minor);
drm_debugfs_remove_files((struct drm_info_list *) &i915_error_state_fops,
1, minor);
} }
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
...@@ -2063,10 +2063,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) ...@@ -2063,10 +2063,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
if (obj->gtt_space == NULL) if (obj->gtt_space == NULL)
return 0; return 0;
if (obj->pin_count != 0) { if (obj->pin_count)
DRM_ERROR("Attempting to unbind pinned buffer\n"); return -EBUSY;
return -EINVAL;
}
ret = i915_gem_object_finish_gpu(obj); ret = i915_gem_object_finish_gpu(obj);
if (ret) if (ret)
...@@ -3293,6 +3291,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, ...@@ -3293,6 +3291,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct address_space *mapping; struct address_space *mapping;
u32 mask;
obj = kzalloc(sizeof(*obj), GFP_KERNEL); obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL) if (obj == NULL)
...@@ -3303,8 +3302,15 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, ...@@ -3303,8 +3302,15 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
return NULL; return NULL;
} }
mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) {
/* 965gm cannot relocate objects above 4GiB. */
mask &= ~__GFP_HIGHMEM;
mask |= __GFP_DMA32;
}
mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); mapping_set_gfp_mask(mapping, mask);
i915_gem_info_add_obj(dev_priv, size); i915_gem_info_add_obj(dev_priv, size);
......
...@@ -350,8 +350,8 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -350,8 +350,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
{ {
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
rps_work); rps_work);
u8 new_delay = dev_priv->cur_delay;
u32 pm_iir, pm_imr; u32 pm_iir, pm_imr;
u8 new_delay;
spin_lock_irq(&dev_priv->rps_lock); spin_lock_irq(&dev_priv->rps_lock);
pm_iir = dev_priv->pm_iir; pm_iir = dev_priv->pm_iir;
...@@ -360,41 +360,18 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -360,41 +360,18 @@ static void gen6_pm_rps_work(struct work_struct *work)
I915_WRITE(GEN6_PMIMR, 0); I915_WRITE(GEN6_PMIMR, 0);
spin_unlock_irq(&dev_priv->rps_lock); spin_unlock_irq(&dev_priv->rps_lock);
if (!pm_iir) if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0)
return; return;
mutex_lock(&dev_priv->dev->struct_mutex); mutex_lock(&dev_priv->dev->struct_mutex);
if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
if (dev_priv->cur_delay != dev_priv->max_delay) if (pm_iir & GEN6_PM_RP_UP_THRESHOLD)
new_delay = dev_priv->cur_delay + 1; new_delay = dev_priv->cur_delay + 1;
if (new_delay > dev_priv->max_delay) else
new_delay = dev_priv->max_delay; new_delay = dev_priv->cur_delay - 1;
} else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) {
gen6_gt_force_wake_get(dev_priv);
if (dev_priv->cur_delay != dev_priv->min_delay)
new_delay = dev_priv->cur_delay - 1;
if (new_delay < dev_priv->min_delay) {
new_delay = dev_priv->min_delay;
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
I915_READ(GEN6_RP_INTERRUPT_LIMITS) |
((new_delay << 16) & 0x3f0000));
} else {
/* Make sure we continue to get down interrupts
* until we hit the minimum frequency */
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000);
}
gen6_gt_force_wake_put(dev_priv);
}
gen6_set_rps(dev_priv->dev, new_delay); gen6_set_rps(dev_priv->dev, new_delay);
dev_priv->cur_delay = new_delay;
/*
* rps_lock not held here because clearing is non-destructive. There is
* an *extremely* unlikely race with gen6_rps_enable() that is prevented
* by holding struct_mutex for the duration of the write.
*/
mutex_unlock(&dev_priv->dev->struct_mutex); mutex_unlock(&dev_priv->dev->struct_mutex);
} }
......
...@@ -910,9 +910,10 @@ static void assert_pll(struct drm_i915_private *dev_priv, ...@@ -910,9 +910,10 @@ static void assert_pll(struct drm_i915_private *dev_priv,
/* For ILK+ */ /* For ILK+ */
static void assert_pch_pll(struct drm_i915_private *dev_priv, static void assert_pch_pll(struct drm_i915_private *dev_priv,
struct intel_crtc *intel_crtc, bool state) struct intel_pch_pll *pll,
struct intel_crtc *crtc,
bool state)
{ {
int reg;
u32 val; u32 val;
bool cur_state; bool cur_state;
...@@ -921,30 +922,37 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv, ...@@ -921,30 +922,37 @@ static void assert_pch_pll(struct drm_i915_private *dev_priv,
return; return;
} }
if (!intel_crtc->pch_pll) { if (WARN (!pll,
WARN(1, "asserting PCH PLL enabled with no PLL\n"); "asserting PCH PLL %s with no PLL\n", state_string(state)))
return; return;
}
if (HAS_PCH_CPT(dev_priv->dev)) { val = I915_READ(pll->pll_reg);
cur_state = !!(val & DPLL_VCO_ENABLE);
WARN(cur_state != state,
"PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
pll->pll_reg, state_string(state), state_string(cur_state), val);
/* Make sure the selected PLL is correctly attached to the transcoder */
if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
u32 pch_dpll; u32 pch_dpll;
pch_dpll = I915_READ(PCH_DPLL_SEL); pch_dpll = I915_READ(PCH_DPLL_SEL);
cur_state = pll->pll_reg == _PCH_DPLL_B;
/* Make sure the selected PLL is enabled to the transcoder */ if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
WARN(!((pch_dpll >> (4 * intel_crtc->pipe)) & 8), "PLL[%d] not attached to this transcoder %d: %08x\n",
"transcoder %d PLL not enabled\n", intel_crtc->pipe); cur_state, crtc->pipe, pch_dpll)) {
cur_state = !!(val >> (4*crtc->pipe + 3));
WARN(cur_state != state,
"PLL[%d] not %s on this transcoder %d: %08x\n",
pll->pll_reg == _PCH_DPLL_B,
state_string(state),
crtc->pipe,
val);
}
} }
reg = intel_crtc->pch_pll->pll_reg;
val = I915_READ(reg);
cur_state = !!(val & DPLL_VCO_ENABLE);
WARN(cur_state != state,
"PCH PLL state assertion failure (expected %s, current %s)\n",
state_string(state), state_string(cur_state));
} }
#define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true) #define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
#define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false) #define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, 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)
...@@ -1424,7 +1432,7 @@ static void intel_enable_pch_pll(struct intel_crtc *intel_crtc) ...@@ -1424,7 +1432,7 @@ static void intel_enable_pch_pll(struct intel_crtc *intel_crtc)
assert_pch_refclk_enabled(dev_priv); assert_pch_refclk_enabled(dev_priv);
if (pll->active++ && pll->on) { if (pll->active++ && pll->on) {
assert_pch_pll_enabled(dev_priv, intel_crtc); assert_pch_pll_enabled(dev_priv, pll, NULL);
return; return;
} }
...@@ -1460,12 +1468,12 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc) ...@@ -1460,12 +1468,12 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
intel_crtc->base.base.id); intel_crtc->base.base.id);
if (WARN_ON(pll->active == 0)) { if (WARN_ON(pll->active == 0)) {
assert_pch_pll_disabled(dev_priv, intel_crtc); assert_pch_pll_disabled(dev_priv, pll, NULL);
return; return;
} }
if (--pll->active) { if (--pll->active) {
assert_pch_pll_enabled(dev_priv, intel_crtc); assert_pch_pll_enabled(dev_priv, pll, NULL);
return; return;
} }
...@@ -1495,7 +1503,9 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv, ...@@ -1495,7 +1503,9 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
BUG_ON(dev_priv->info->gen < 5); BUG_ON(dev_priv->info->gen < 5);
/* Make sure PCH DPLL is enabled */ /* Make sure PCH DPLL is enabled */
assert_pch_pll_enabled(dev_priv, to_intel_crtc(crtc)); assert_pch_pll_enabled(dev_priv,
to_intel_crtc(crtc)->pch_pll,
to_intel_crtc(crtc));
/* FDI must be feeding us bits for PCH ports */ /* FDI must be feeding us bits for PCH ports */
assert_fdi_tx_enabled(dev_priv, pipe); assert_fdi_tx_enabled(dev_priv, pipe);
......
...@@ -266,6 +266,9 @@ intel_dp_mode_valid(struct drm_connector *connector, ...@@ -266,6 +266,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
if (mode->clock < 10000) if (mode->clock < 10000)
return MODE_CLOCK_LOW; return MODE_CLOCK_LOW;
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
return MODE_H_ILLEGAL;
return MODE_OK; return MODE_OK;
} }
...@@ -702,6 +705,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -702,6 +705,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode->clock = intel_dp->panel_fixed_mode->clock; mode->clock = intel_dp->panel_fixed_mode->clock;
} }
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
return false;
DRM_DEBUG_KMS("DP link computation with max lane count %i " DRM_DEBUG_KMS("DP link computation with max lane count %i "
"max bw %02x pixel clock %iKHz\n", "max bw %02x pixel clock %iKHz\n",
max_lane_count, bws[max_clock], mode->clock); max_lane_count, bws[max_clock], mode->clock);
...@@ -1154,11 +1160,10 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) ...@@ -1154,11 +1160,10 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
DRM_DEBUG_KMS("Turn eDP power off\n"); DRM_DEBUG_KMS("Turn eDP power off\n");
WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
ironlake_panel_vdd_off_sync(intel_dp); /* finish any pending work */
pp = ironlake_get_pp_control(dev_priv); pp = ironlake_get_pp_control(dev_priv);
pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
I915_WRITE(PCH_PP_CONTROL, pp); I915_WRITE(PCH_PP_CONTROL, pp);
POSTING_READ(PCH_PP_CONTROL); POSTING_READ(PCH_PP_CONTROL);
...@@ -1266,18 +1271,16 @@ static void intel_dp_prepare(struct drm_encoder *encoder) ...@@ -1266,18 +1271,16 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
{ {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
/* Make sure the panel is off before trying to change the mode. But also
* ensure that we have vdd while we switch off the panel. */
ironlake_edp_panel_vdd_on(intel_dp);
ironlake_edp_backlight_off(intel_dp); ironlake_edp_backlight_off(intel_dp);
ironlake_edp_panel_off(intel_dp); ironlake_edp_panel_off(intel_dp);
/* Wake up the sink first */
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_link_down(intel_dp); intel_dp_link_down(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, false); ironlake_edp_panel_vdd_off(intel_dp, false);
/* Make sure the panel is off before trying to
* change the mode
*/
} }
static void intel_dp_commit(struct drm_encoder *encoder) static void intel_dp_commit(struct drm_encoder *encoder)
...@@ -1309,10 +1312,11 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) ...@@ -1309,10 +1312,11 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
uint32_t dp_reg = I915_READ(intel_dp->output_reg); uint32_t dp_reg = I915_READ(intel_dp->output_reg);
if (mode != DRM_MODE_DPMS_ON) { if (mode != DRM_MODE_DPMS_ON) {
/* Switching the panel off requires vdd. */
ironlake_edp_panel_vdd_on(intel_dp);
ironlake_edp_backlight_off(intel_dp); ironlake_edp_backlight_off(intel_dp);
ironlake_edp_panel_off(intel_dp); ironlake_edp_panel_off(intel_dp);
ironlake_edp_panel_vdd_on(intel_dp);
intel_dp_sink_dpms(intel_dp, mode); intel_dp_sink_dpms(intel_dp, mode);
intel_dp_link_down(intel_dp); intel_dp_link_down(intel_dp);
ironlake_edp_panel_vdd_off(intel_dp, false); ironlake_edp_panel_vdd_off(intel_dp, false);
......
...@@ -396,11 +396,22 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -396,11 +396,22 @@ gmbus_xfer(struct i2c_adapter *adapter,
* Wait for bus to IDLE before clearing NAK. * Wait for bus to IDLE before clearing NAK.
* If we clear the NAK while bus is still active, then it will stay * If we clear the NAK while bus is still active, then it will stay
* active and the next transaction may fail. * active and the next transaction may fail.
*
* If no ACK is received during the address phase of a transaction, the
* adapter must report -ENXIO. It is not clear what to return if no ACK
* is received at other times. But we have to be careful to not return
* spurious -ENXIO because that will prevent i2c and drm edid functions
* from retrying. So return -ENXIO only when gmbus properly quiescents -
* timing out seems to happen when there _is_ a ddc chip present, but
* it's slow responding and only answers on the 2nd retry.
*/ */
ret = -ENXIO;
if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0,
10)) 10)) {
DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n", DRM_DEBUG_KMS("GMBUS [%s] timed out after NAK\n",
adapter->name); adapter->name);
ret = -ETIMEDOUT;
}
/* Toggle the Software Clear Interrupt bit. This has the effect /* Toggle the Software Clear Interrupt bit. This has the effect
* of resetting the GMBUS controller and so clearing the * of resetting the GMBUS controller and so clearing the
...@@ -414,14 +425,6 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -414,14 +425,6 @@ gmbus_xfer(struct i2c_adapter *adapter,
adapter->name, msgs[i].addr, adapter->name, msgs[i].addr,
(msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len); (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
/*
* If no ACK is received during the address phase of a transaction,
* the adapter must report -ENXIO.
* It is not clear what to return if no ACK is received at other times.
* So, we always return -ENXIO in all NAK cases, to ensure we send
* it at least during the one case that is specified.
*/
ret = -ENXIO;
goto out; goto out;
timeout: timeout:
......
...@@ -745,6 +745,14 @@ static const struct dmi_system_id intel_no_lvds[] = { ...@@ -745,6 +745,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
}, },
}, },
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Hewlett-Packard HP t5740e Thin Client",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"),
},
},
{ {
.callback = intel_no_lvds_dmi_callback, .callback = intel_no_lvds_dmi_callback,
.ident = "Hewlett-Packard t5745", .ident = "Hewlett-Packard t5745",
......
...@@ -2270,10 +2270,33 @@ void ironlake_disable_drps(struct drm_device *dev) ...@@ -2270,10 +2270,33 @@ void ironlake_disable_drps(struct drm_device *dev)
void gen6_set_rps(struct drm_device *dev, u8 val) void gen6_set_rps(struct drm_device *dev, u8 val)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
u32 swreq; u32 limits;
swreq = (val & 0x3ff) << 25; limits = 0;
I915_WRITE(GEN6_RPNSWREQ, swreq); if (val >= dev_priv->max_delay)
val = dev_priv->max_delay;
else
limits |= dev_priv->max_delay << 24;
if (val <= dev_priv->min_delay)
val = dev_priv->min_delay;
else
limits |= dev_priv->min_delay << 16;
if (val == dev_priv->cur_delay)
return;
I915_WRITE(GEN6_RPNSWREQ,
GEN6_FREQUENCY(val) |
GEN6_OFFSET(0) |
GEN6_AGGRESSIVE_TURBO);
/* Make sure we continue to get interrupts
* until we hit the minimum or maximum frequencies.
*/
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
dev_priv->cur_delay = val;
} }
void gen6_disable_rps(struct drm_device *dev) void gen6_disable_rps(struct drm_device *dev)
...@@ -2327,11 +2350,10 @@ int intel_enable_rc6(const struct drm_device *dev) ...@@ -2327,11 +2350,10 @@ int intel_enable_rc6(const struct drm_device *dev)
void gen6_enable_rps(struct drm_i915_private *dev_priv) void gen6_enable_rps(struct drm_i915_private *dev_priv)
{ {
struct intel_ring_buffer *ring; struct intel_ring_buffer *ring;
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); u32 rp_state_cap;
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); u32 gt_perf_status;
u32 pcu_mbox, rc6_mask = 0; u32 pcu_mbox, rc6_mask = 0;
u32 gtfifodbg; u32 gtfifodbg;
int cur_freq, min_freq, max_freq;
int rc6_mode; int rc6_mode;
int i; int i;
...@@ -2352,6 +2374,14 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -2352,6 +2374,14 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
gen6_gt_force_wake_get(dev_priv); gen6_gt_force_wake_get(dev_priv);
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
/* In units of 100MHz */
dev_priv->max_delay = rp_state_cap & 0xff;
dev_priv->min_delay = (rp_state_cap & 0xff0000) >> 16;
dev_priv->cur_delay = 0;
/* disable the counters and set deterministic thresholds */ /* disable the counters and set deterministic thresholds */
I915_WRITE(GEN6_RC_CONTROL, 0); I915_WRITE(GEN6_RC_CONTROL, 0);
...@@ -2399,8 +2429,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -2399,8 +2429,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
18 << 24 | dev_priv->max_delay << 24 |
6 << 16); dev_priv->min_delay << 16);
I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000);
I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000);
I915_WRITE(GEN6_RP_UP_EI, 100000); I915_WRITE(GEN6_RP_UP_EI, 100000);
...@@ -2408,7 +2438,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -2408,7 +2438,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
I915_WRITE(GEN6_RP_CONTROL, I915_WRITE(GEN6_RP_CONTROL,
GEN6_RP_MEDIA_TURBO | GEN6_RP_MEDIA_TURBO |
GEN6_RP_MEDIA_HW_MODE | GEN6_RP_MEDIA_HW_NORMAL_MODE |
GEN6_RP_MEDIA_IS_GFX | GEN6_RP_MEDIA_IS_GFX |
GEN6_RP_ENABLE | GEN6_RP_ENABLE |
GEN6_RP_UP_BUSY_AVG | GEN6_RP_UP_BUSY_AVG |
...@@ -2426,10 +2456,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -2426,10 +2456,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
500)) 500))
DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
min_freq = (rp_state_cap & 0xff0000) >> 16;
max_freq = rp_state_cap & 0xff;
cur_freq = (gt_perf_status & 0xff00) >> 8;
/* Check for overclock support */ /* Check for overclock support */
if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
500)) 500))
...@@ -2440,14 +2466,11 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -2440,14 +2466,11 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
500)) 500))
DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
if (pcu_mbox & (1<<31)) { /* OC supported */ if (pcu_mbox & (1<<31)) { /* OC supported */
max_freq = pcu_mbox & 0xff; dev_priv->max_delay = pcu_mbox & 0xff;
DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
} }
/* In units of 100MHz */ gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
dev_priv->max_delay = max_freq;
dev_priv->min_delay = min_freq;
dev_priv->cur_delay = cur_freq;
/* requires MSI enabled */ /* requires MSI enabled */
I915_WRITE(GEN6_PMIER, I915_WRITE(GEN6_PMIER,
...@@ -3580,8 +3603,9 @@ static void gen6_sanitize_pm(struct drm_device *dev) ...@@ -3580,8 +3603,9 @@ static void gen6_sanitize_pm(struct drm_device *dev)
limits |= (dev_priv->min_delay & 0x3f) << 16; limits |= (dev_priv->min_delay & 0x3f) << 16;
if (old != limits) { if (old != limits) {
DRM_ERROR("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS expected %08x, was %08x\n", /* Note that the known failure case is to read back 0. */
limits, old); DRM_DEBUG_DRIVER("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS "
"expected %08x, was %08x\n", limits, old);
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
} }
......
...@@ -783,10 +783,12 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, ...@@ -783,10 +783,12 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
((v_sync_len & 0x30) >> 4); ((v_sync_len & 0x30) >> 4);
dtd->part2.dtd_flags = 0x18; dtd->part2.dtd_flags = 0x18;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE;
if (mode->flags & DRM_MODE_FLAG_PHSYNC) if (mode->flags & DRM_MODE_FLAG_PHSYNC)
dtd->part2.dtd_flags |= 0x2; dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE;
if (mode->flags & DRM_MODE_FLAG_PVSYNC) if (mode->flags & DRM_MODE_FLAG_PVSYNC)
dtd->part2.dtd_flags |= 0x4; dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
dtd->part2.sdvo_flags = 0; dtd->part2.sdvo_flags = 0;
dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
...@@ -820,9 +822,11 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, ...@@ -820,9 +822,11 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->clock = dtd->part1.clock * 10; mode->clock = dtd->part1.clock * 10;
mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
if (dtd->part2.dtd_flags & 0x2) if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
mode->flags |= DRM_MODE_FLAG_INTERLACE;
if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
mode->flags |= DRM_MODE_FLAG_PHSYNC; mode->flags |= DRM_MODE_FLAG_PHSYNC;
if (dtd->part2.dtd_flags & 0x4) if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
mode->flags |= DRM_MODE_FLAG_PVSYNC; mode->flags |= DRM_MODE_FLAG_PVSYNC;
} }
......
...@@ -61,6 +61,11 @@ struct intel_sdvo_caps { ...@@ -61,6 +61,11 @@ struct intel_sdvo_caps {
u16 output_flags; u16 output_flags;
} __attribute__((packed)); } __attribute__((packed));
/* Note: SDVO detailed timing flags match EDID misc flags. */
#define DTD_FLAG_HSYNC_POSITIVE (1 << 1)
#define DTD_FLAG_VSYNC_POSITIVE (1 << 2)
#define DTD_FLAG_INTERLACE (1 << 7)
/** This matches the EDID DTD structure, more or less */ /** This matches the EDID DTD structure, more or less */
struct intel_sdvo_dtd { struct intel_sdvo_dtd {
struct { struct {
......
...@@ -673,6 +673,54 @@ static const struct tv_mode tv_modes[] = { ...@@ -673,6 +673,54 @@ static const struct tv_mode tv_modes[] = {
.filter_table = filter_table, .filter_table = filter_table,
}, },
{
.name = "480p",
.clock = 107520,
.refresh = 59940,
.oversample = TV_OVERSAMPLE_4X,
.component_only = 1,
.hsync_end = 64, .hblank_end = 122,
.hblank_start = 842, .htotal = 857,
.progressive = true, .trilevel_sync = false,
.vsync_start_f1 = 12, .vsync_start_f2 = 12,
.vsync_len = 12,
.veq_ena = false,
.vi_end_f1 = 44, .vi_end_f2 = 44,
.nbr_end = 479,
.burst_ena = false,
.filter_table = filter_table,
},
{
.name = "576p",
.clock = 107520,
.refresh = 50000,
.oversample = TV_OVERSAMPLE_4X,
.component_only = 1,
.hsync_end = 64, .hblank_end = 139,
.hblank_start = 859, .htotal = 863,
.progressive = true, .trilevel_sync = false,
.vsync_start_f1 = 10, .vsync_start_f2 = 10,
.vsync_len = 10,
.veq_ena = false,
.vi_end_f1 = 48, .vi_end_f2 = 48,
.nbr_end = 575,
.burst_ena = false,
.filter_table = filter_table,
},
{ {
.name = "720p@60Hz", .name = "720p@60Hz",
.clock = 148800, .clock = 148800,
...@@ -1194,6 +1242,11 @@ intel_tv_detect_type(struct intel_tv *intel_tv, ...@@ -1194,6 +1242,11 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
I915_WRITE(TV_CTL, save_tv_ctl); I915_WRITE(TV_CTL, save_tv_ctl);
POSTING_READ(TV_CTL);
/* For unknown reasons the hw barfs if we don't do this vblank wait. */
intel_wait_for_vblank(intel_tv->base.base.dev,
to_intel_crtc(intel_tv->base.base.crtc)->pipe);
/* Restore interrupt config */ /* Restore interrupt config */
if (connector->polled & DRM_CONNECTOR_POLL_HPD) { if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment