Commit 7608867d authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-fixes-2014-12-04' of...

Merge tag 'drm-intel-next-fixes-2014-12-04' of git://anongit.freedesktop.org/drm-intel into drm-next

Fixes for 3.20. I did stick the gen3/4 reset work from Ville in because we
have an awful lot of gen4 mesa hangs, and with this reset should also work
on vintage i965g/gm (we already have reset for g4x/gen4.5). So should help
to appease users suffering from these hangs. Otherwise all over.

This is the last 3.20 pull from me, from here on Jani will take over. By Ville Syrjälä (8) and others
* tag 'drm-intel-next-fixes-2014-12-04' of git://anongit.freedesktop.org/drm-intel:
  drm/i915: Reject modeset when the same digital port is used more than once
  drm/i915: mask RPS IRQs properly when disabling RPS
  drm/i915: Tune down spurious CRC interrupt warning
  drm/i915: Fix context object leak for legacy contexts
  drm/i915/skl: Update in Gen9 multi-engine forcewake range
  drm/i915/eDP: When enabling panel VDD cancel pending disable worker
  drm/i915: Handle runtime pm in the CRC setup code
  drm/i915: Disable crtcs gracefully before GPU reset on gen3/4
  drm/i915: Grab modeset locks for GPU rest on pre-ctg
  drm/i915: Implement GPU reset for g33
  drm/i915: Implement GPU reset for 915/945
  drm/i915: Restore the display config after a GPU reset on gen4
  drm/i915: Fix gen4 GPU reset
  drm/i915: Stop gathering error states for CS error interrupts
  drm/i915: Disallow pin ioctl completely for kms drivers
  drm/i915: Only warn the first time we attempt to mmio whilst suspended
  drm/i915/chv: Enable AVI, SPD and HDMI infoframes for CHV.
  drm/i915: Don't clobber crtc->new_config when nothing changes
parents 047b35f2 00f0b378
...@@ -3338,6 +3338,11 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, ...@@ -3338,6 +3338,11 @@ static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe,
if (pipe_crc->source && source) if (pipe_crc->source && source)
return -EINVAL; return -EINVAL;
if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) {
DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
return -EIO;
}
if (IS_GEN2(dev)) if (IS_GEN2(dev))
ret = i8xx_pipe_crc_ctl_reg(&source, &val); ret = i8xx_pipe_crc_ctl_reg(&source, &val);
else if (INTEL_INFO(dev)->gen < 5) else if (INTEL_INFO(dev)->gen < 5)
......
...@@ -2574,11 +2574,13 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) ...@@ -2574,11 +2574,13 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request)
list_del(&request->list); list_del(&request->list);
i915_gem_request_remove_from_client(request); i915_gem_request_remove_from_client(request);
if (i915.enable_execlists && ctx) { if (ctx) {
if (i915.enable_execlists) {
struct intel_engine_cs *ring = request->ring; struct intel_engine_cs *ring = request->ring;
if (ctx != ring->default_context) if (ctx != ring->default_context)
intel_lr_context_unpin(ring, ctx); intel_lr_context_unpin(ring, ctx);
}
i915_gem_context_unreference(ctx); i915_gem_context_unreference(ctx);
} }
kfree(request); kfree(request);
...@@ -4263,7 +4265,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, ...@@ -4263,7 +4265,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret; int ret;
if (INTEL_INFO(dev)->gen >= 6) if (drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV; return -ENODEV;
ret = i915_mutex_lock_interruptible(dev); ret = i915_mutex_lock_interruptible(dev);
...@@ -4319,6 +4321,9 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data, ...@@ -4319,6 +4321,9 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret; int ret;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
ret = i915_mutex_lock_interruptible(dev); ret = i915_mutex_lock_interruptible(dev);
if (ret) if (ret)
return ret; return ret;
......
...@@ -231,9 +231,6 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, ...@@ -231,9 +231,6 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
assert_spin_locked(&dev_priv->irq_lock); assert_spin_locked(&dev_priv->irq_lock);
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
new_val = dev_priv->pm_irq_mask; new_val = dev_priv->pm_irq_mask;
new_val &= ~interrupt_mask; new_val &= ~interrupt_mask;
new_val |= (~enabled_irq_mask & interrupt_mask); new_val |= (~enabled_irq_mask & interrupt_mask);
...@@ -247,14 +244,26 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, ...@@ -247,14 +244,26 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{ {
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
snb_update_pm_irq(dev_priv, mask, mask); snb_update_pm_irq(dev_priv, mask, mask);
} }
void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask) static void __gen6_disable_pm_irq(struct drm_i915_private *dev_priv,
uint32_t mask)
{ {
snb_update_pm_irq(dev_priv, mask, 0); snb_update_pm_irq(dev_priv, mask, 0);
} }
void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
{
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
return;
__gen6_disable_pm_irq(dev_priv, mask);
}
void gen6_reset_rps_interrupts(struct drm_device *dev) void gen6_reset_rps_interrupts(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -289,16 +298,20 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) ...@@ -289,16 +298,20 @@ void gen6_disable_rps_interrupts(struct drm_device *dev)
cancel_work_sync(&dev_priv->rps.work); cancel_work_sync(&dev_priv->rps.work);
spin_lock_irq(&dev_priv->irq_lock);
I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ?
~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0);
__gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events);
I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) &
~dev_priv->pm_rps_events); ~dev_priv->pm_rps_events);
I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);
I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);
spin_lock_irq(&dev_priv->irq_lock);
dev_priv->rps.pm_iir = 0; dev_priv->rps.pm_iir = 0;
spin_unlock_irq(&dev_priv->irq_lock);
I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock);
} }
/** /**
...@@ -1339,10 +1352,8 @@ static void snb_gt_irq_handler(struct drm_device *dev, ...@@ -1339,10 +1352,8 @@ static void snb_gt_irq_handler(struct drm_device *dev,
if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT | if (gt_iir & (GT_BLT_CS_ERROR_INTERRUPT |
GT_BSD_CS_ERROR_INTERRUPT | GT_BSD_CS_ERROR_INTERRUPT |
GT_RENDER_CS_MASTER_ERROR_INTERRUPT)) { GT_RENDER_CS_MASTER_ERROR_INTERRUPT))
i915_handle_error(dev, false, "GT error interrupt 0x%08x", DRM_DEBUG("Command parser error, gt_iir 0x%08x\n", gt_iir);
gt_iir);
}
if (gt_iir & GT_PARITY_ERROR(dev)) if (gt_iir & GT_PARITY_ERROR(dev))
ivybridge_parity_error_irq_handler(dev, gt_iir); ivybridge_parity_error_irq_handler(dev, gt_iir);
...@@ -1623,7 +1634,7 @@ static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe, ...@@ -1623,7 +1634,7 @@ static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
if (!pipe_crc->entries) { if (!pipe_crc->entries) {
spin_unlock(&pipe_crc->lock); spin_unlock(&pipe_crc->lock);
DRM_ERROR("spurious interrupt\n"); DRM_DEBUG_KMS("spurious interrupt\n");
return; return;
} }
...@@ -1731,11 +1742,8 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) ...@@ -1731,11 +1742,8 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
if (pm_iir & PM_VEBOX_USER_INTERRUPT) if (pm_iir & PM_VEBOX_USER_INTERRUPT)
notify_ring(dev_priv->dev, &dev_priv->ring[VECS]); notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) { if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT)
i915_handle_error(dev_priv->dev, false, DRM_DEBUG("Command parser error, pm_iir 0x%08x\n", pm_iir);
"VEBOX CS error interrupt 0x%08x",
pm_iir);
}
} }
} }
...@@ -2428,6 +2436,9 @@ static void i915_error_work_func(struct work_struct *work) ...@@ -2428,6 +2436,9 @@ static void i915_error_work_func(struct work_struct *work)
* simulated reset via debugs, so get an RPM reference. * simulated reset via debugs, so get an RPM reference.
*/ */
intel_runtime_pm_get(dev_priv); intel_runtime_pm_get(dev_priv);
intel_prepare_reset(dev);
/* /*
* All state reset _must_ be completed before we update the * All state reset _must_ be completed before we update the
* reset counter, for otherwise waiters might miss the reset * reset counter, for otherwise waiters might miss the reset
...@@ -2436,7 +2447,7 @@ static void i915_error_work_func(struct work_struct *work) ...@@ -2436,7 +2447,7 @@ static void i915_error_work_func(struct work_struct *work)
*/ */
ret = i915_reset(dev); ret = i915_reset(dev);
intel_display_handle_reset(dev); intel_finish_reset(dev);
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
...@@ -3746,9 +3757,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) ...@@ -3746,9 +3757,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
*/ */
spin_lock(&dev_priv->irq_lock); spin_lock(&dev_priv->irq_lock);
if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
i915_handle_error(dev, false, DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
"Command parser error, iir 0x%08x",
iir);
for_each_pipe(dev_priv, pipe) { for_each_pipe(dev_priv, pipe) {
int reg = PIPESTAT(pipe); int reg = PIPESTAT(pipe);
...@@ -3929,9 +3938,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) ...@@ -3929,9 +3938,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
*/ */
spin_lock(&dev_priv->irq_lock); spin_lock(&dev_priv->irq_lock);
if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
i915_handle_error(dev, false, DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
"Command parser error, iir 0x%08x",
iir);
for_each_pipe(dev_priv, pipe) { for_each_pipe(dev_priv, pipe) {
int reg = PIPESTAT(pipe); int reg = PIPESTAT(pipe);
...@@ -4154,9 +4161,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) ...@@ -4154,9 +4161,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
*/ */
spin_lock(&dev_priv->irq_lock); spin_lock(&dev_priv->irq_lock);
if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
i915_handle_error(dev, false, DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
"Command parser error, iir 0x%08x",
iir);
for_each_pipe(dev_priv, pipe) { for_each_pipe(dev_priv, pipe) {
int reg = PIPESTAT(pipe); int reg = PIPESTAT(pipe);
......
...@@ -78,11 +78,12 @@ ...@@ -78,11 +78,12 @@
/* Graphics reset regs */ /* Graphics reset regs */
#define I965_GDRST 0xc0 /* PCI config register */ #define I915_GDRST 0xc0 /* PCI config register */
#define GRDOM_FULL (0<<2) #define GRDOM_FULL (0<<2)
#define GRDOM_RENDER (1<<2) #define GRDOM_RENDER (1<<2)
#define GRDOM_MEDIA (3<<2) #define GRDOM_MEDIA (3<<2)
#define GRDOM_MASK (3<<2) #define GRDOM_MASK (3<<2)
#define GRDOM_RESET_STATUS (1<<1)
#define GRDOM_RESET_ENABLE (1<<0) #define GRDOM_RESET_ENABLE (1<<0)
#define ILK_GDSR 0x2ca4 /* MCHBAR offset */ #define ILK_GDSR 0x2ca4 /* MCHBAR offset */
......
...@@ -2765,25 +2765,10 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, ...@@ -2765,25 +2765,10 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
return 0; return 0;
} }
void intel_display_handle_reset(struct drm_device *dev) static void intel_complete_page_flips(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc; struct drm_crtc *crtc;
/*
* Flips in the rings have been nuked by the reset,
* so complete all pending flips so that user space
* will get its events and not get stuck.
*
* Also update the base address of all primary
* planes to the the last fb to make sure we're
* showing the correct fb after a reset.
*
* Need to make two loops over the crtcs so that we
* don't try to grab a crtc mutex before the
* pending_flip_queue really got woken up.
*/
for_each_crtc(dev, crtc) { for_each_crtc(dev, crtc) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum plane plane = intel_crtc->plane; enum plane plane = intel_crtc->plane;
...@@ -2791,6 +2776,12 @@ void intel_display_handle_reset(struct drm_device *dev) ...@@ -2791,6 +2776,12 @@ void intel_display_handle_reset(struct drm_device *dev)
intel_prepare_page_flip(dev, plane); intel_prepare_page_flip(dev, plane);
intel_finish_page_flip_plane(dev, plane); intel_finish_page_flip_plane(dev, plane);
} }
}
static void intel_update_primary_planes(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
for_each_crtc(dev, crtc) { for_each_crtc(dev, crtc) {
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
...@@ -2810,6 +2801,79 @@ void intel_display_handle_reset(struct drm_device *dev) ...@@ -2810,6 +2801,79 @@ void intel_display_handle_reset(struct drm_device *dev)
} }
} }
void intel_prepare_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_crtc *crtc;
/* no reset support for gen2 */
if (IS_GEN2(dev))
return;
/* reset doesn't touch the display */
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
return;
drm_modeset_lock_all(dev);
/*
* Disabling the crtcs gracefully seems nicer. Also the
* g33 docs say we should at least disable all the planes.
*/
for_each_intel_crtc(dev, crtc) {
if (crtc->active)
dev_priv->display.crtc_disable(&crtc->base);
}
}
void intel_finish_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
/*
* Flips in the rings will be nuked by the reset,
* so complete all pending flips so that user space
* will get its events and not get stuck.
*/
intel_complete_page_flips(dev);
/* no reset support for gen2 */
if (IS_GEN2(dev))
return;
/* reset doesn't touch the display */
if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) {
/*
* Flips in the rings have been nuked by the reset,
* so update the base address of all primary
* planes to the the last fb to make sure we're
* showing the correct fb after a reset.
*/
intel_update_primary_planes(dev);
return;
}
/*
* The display has been reset as well,
* so need a full re-initialization.
*/
intel_runtime_pm_disable_interrupts(dev_priv);
intel_runtime_pm_enable_interrupts(dev_priv);
intel_modeset_init_hw(dev);
spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->display.hpd_irq_setup)
dev_priv->display.hpd_irq_setup(dev);
spin_unlock_irq(&dev_priv->irq_lock);
intel_modeset_setup_hw_state(dev, true);
intel_hpd_init(dev_priv);
drm_modeset_unlock_all(dev);
}
static int static int
intel_finish_fb(struct drm_framebuffer *old_fb) intel_finish_fb(struct drm_framebuffer *old_fb)
{ {
...@@ -10089,6 +10153,48 @@ static bool check_encoder_cloning(struct intel_crtc *crtc) ...@@ -10089,6 +10153,48 @@ static bool check_encoder_cloning(struct intel_crtc *crtc)
return true; return true;
} }
static bool check_digital_port_conflicts(struct drm_device *dev)
{
struct intel_connector *connector;
unsigned int used_ports = 0;
/*
* Walk the connector list instead of the encoder
* list to detect the problem on ddi platforms
* where there's just one encoder per digital port.
*/
list_for_each_entry(connector,
&dev->mode_config.connector_list, base.head) {
struct intel_encoder *encoder = connector->new_encoder;
if (!encoder)
continue;
WARN_ON(!encoder->new_crtc);
switch (encoder->type) {
unsigned int port_mask;
case INTEL_OUTPUT_UNKNOWN:
if (WARN_ON(!HAS_DDI(dev)))
break;
case INTEL_OUTPUT_DISPLAYPORT:
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
port_mask = 1 << enc_to_dig_port(&encoder->base)->port;
/* the same port mustn't appear more than once */
if (used_ports & port_mask)
return false;
used_ports |= port_mask;
default:
break;
}
}
return true;
}
static struct intel_crtc_config * static struct intel_crtc_config *
intel_modeset_pipe_config(struct drm_crtc *crtc, intel_modeset_pipe_config(struct drm_crtc *crtc,
struct drm_framebuffer *fb, struct drm_framebuffer *fb,
...@@ -10105,6 +10211,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, ...@@ -10105,6 +10211,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (!check_digital_port_conflicts(dev)) {
DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n");
return ERR_PTR(-EINVAL);
}
pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
if (!pipe_config) if (!pipe_config)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -10907,7 +11018,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc, ...@@ -10907,7 +11018,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc,
} }
intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config,
"[modeset]"); "[modeset]");
to_intel_crtc(crtc)->new_config = pipe_config;
out: out:
return pipe_config; return pipe_config;
...@@ -10933,6 +11043,9 @@ static int __intel_set_mode(struct drm_crtc *crtc, ...@@ -10933,6 +11043,9 @@ static int __intel_set_mode(struct drm_crtc *crtc,
*saved_mode = crtc->mode; *saved_mode = crtc->mode;
if (modeset_pipes)
to_intel_crtc(crtc)->new_config = pipe_config;
/* /*
* See if the config requires any additional preparation, e.g. * See if the config requires any additional preparation, e.g.
* to adjust global state with pipes off. We need to do this * to adjust global state with pipes off. We need to do this
...@@ -11466,12 +11579,12 @@ static int intel_crtc_set_config(struct drm_mode_set *set) ...@@ -11466,12 +11579,12 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
ret = PTR_ERR(pipe_config); ret = PTR_ERR(pipe_config);
goto fail; goto fail;
} else if (pipe_config) { } else if (pipe_config) {
if (to_intel_crtc(set->crtc)->new_config->has_audio != if (pipe_config->has_audio !=
to_intel_crtc(set->crtc)->config.has_audio) to_intel_crtc(set->crtc)->config.has_audio)
config->mode_changed = true; config->mode_changed = true;
/* Force mode sets for any infoframe stuff */ /* Force mode sets for any infoframe stuff */
if (to_intel_crtc(set->crtc)->new_config->has_infoframe || if (pipe_config->has_infoframe ||
to_intel_crtc(set->crtc)->config.has_infoframe) to_intel_crtc(set->crtc)->config.has_infoframe)
config->mode_changed = true; config->mode_changed = true;
} }
......
...@@ -1503,6 +1503,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) ...@@ -1503,6 +1503,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp)
if (!is_edp(intel_dp)) if (!is_edp(intel_dp))
return false; return false;
cancel_delayed_work(&intel_dp->panel_vdd_work);
intel_dp->want_panel_vdd = true; intel_dp->want_panel_vdd = true;
if (edp_have_panel_vdd(intel_dp)) if (edp_have_panel_vdd(intel_dp))
......
...@@ -958,7 +958,8 @@ unsigned long intel_gen4_compute_page_offset(int *x, int *y, ...@@ -958,7 +958,8 @@ unsigned long intel_gen4_compute_page_offset(int *x, int *y,
unsigned int tiling_mode, unsigned int tiling_mode,
unsigned int bpp, unsigned int bpp,
unsigned int pitch); unsigned int pitch);
void intel_display_handle_reset(struct drm_device *dev); void intel_prepare_reset(struct drm_device *dev);
void intel_finish_reset(struct drm_device *dev);
void hsw_enable_pc8(struct drm_i915_private *dev_priv); void hsw_enable_pc8(struct drm_i915_private *dev_priv);
void hsw_disable_pc8(struct drm_i915_private *dev_priv); void hsw_disable_pc8(struct drm_i915_private *dev_priv);
void intel_dp_get_m_n(struct intel_crtc *crtc, void intel_dp_get_m_n(struct intel_crtc *crtc,
......
...@@ -1461,10 +1461,13 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder) ...@@ -1461,10 +1461,13 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder)
static void chv_hdmi_pre_enable(struct intel_encoder *encoder) static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
{ {
struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
struct intel_hdmi *intel_hdmi = &dport->hdmi;
struct drm_device *dev = encoder->base.dev; struct drm_device *dev = encoder->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 = struct intel_crtc *intel_crtc =
to_intel_crtc(encoder->base.crtc); to_intel_crtc(encoder->base.crtc);
struct drm_display_mode *adjusted_mode =
&intel_crtc->config.adjusted_mode;
enum dpio_channel ch = vlv_dport_to_channel(dport); enum dpio_channel ch = vlv_dport_to_channel(dport);
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
int data, i; int data, i;
...@@ -1589,6 +1592,10 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) ...@@ -1589,6 +1592,10 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpio_lock); mutex_unlock(&dev_priv->dpio_lock);
intel_hdmi->set_infoframes(&encoder->base,
intel_crtc->config.has_hdmi_sink,
adjusted_mode);
intel_enable_hdmi(encoder); intel_enable_hdmi(encoder);
vlv_wait_port_ready(dev_priv, dport); vlv_wait_port_ready(dev_priv, dport);
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
static void static void
assert_device_not_suspended(struct drm_i915_private *dev_priv) assert_device_not_suspended(struct drm_i915_private *dev_priv)
{ {
WARN(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended, WARN_ONCE(HAS_RUNTIME_PM(dev_priv->dev) && dev_priv->pm.suspended,
"Device suspended\n"); "Device suspended\n");
} }
...@@ -671,18 +671,22 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv) ...@@ -671,18 +671,22 @@ void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
REG_RANGE((reg), 0x22000, 0x24000)) REG_RANGE((reg), 0x22000, 0x24000))
#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \ #define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
REG_RANGE((reg), 0xC00, 0x2000) REG_RANGE((reg), 0xB00, 0x2000)
#define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \ #define FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg) \
(REG_RANGE((reg), 0x2000, 0x4000) || \ (REG_RANGE((reg), 0x2000, 0x2700) || \
REG_RANGE((reg), 0x3000, 0x4000) || \
REG_RANGE((reg), 0x5200, 0x8000) || \ REG_RANGE((reg), 0x5200, 0x8000) || \
REG_RANGE((reg), 0x8140, 0x8160) || \
REG_RANGE((reg), 0x8300, 0x8500) || \ REG_RANGE((reg), 0x8300, 0x8500) || \
REG_RANGE((reg), 0x8C00, 0x8D00) || \ REG_RANGE((reg), 0x8C00, 0x8D00) || \
REG_RANGE((reg), 0xB000, 0xB480) || \ REG_RANGE((reg), 0xB000, 0xB480) || \
REG_RANGE((reg), 0xE000, 0xE800)) REG_RANGE((reg), 0xE000, 0xE900) || \
REG_RANGE((reg), 0x24400, 0x24800))
#define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \ #define FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) \
(REG_RANGE((reg), 0x8800, 0x8A00) || \ (REG_RANGE((reg), 0x8130, 0x8140) || \
REG_RANGE((reg), 0x8800, 0x8A00) || \
REG_RANGE((reg), 0xD000, 0xD800) || \ REG_RANGE((reg), 0xD000, 0xD800) || \
REG_RANGE((reg), 0x12000, 0x14000) || \ REG_RANGE((reg), 0x12000, 0x14000) || \
REG_RANGE((reg), 0x1A000, 0x1EA00) || \ REG_RANGE((reg), 0x1A000, 0x1EA00) || \
...@@ -1345,41 +1349,34 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev, ...@@ -1345,41 +1349,34 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev,
return 0; return 0;
} }
static int i965_reset_complete(struct drm_device *dev) static int i915_reset_complete(struct drm_device *dev)
{ {
u8 gdrst; u8 gdrst;
pci_read_config_byte(dev->pdev, I965_GDRST, &gdrst); pci_read_config_byte(dev->pdev, I915_GDRST, &gdrst);
return (gdrst & GRDOM_RESET_ENABLE) == 0; return (gdrst & GRDOM_RESET_STATUS) == 0;
} }
static int i965_do_reset(struct drm_device *dev) static int i915_do_reset(struct drm_device *dev)
{ {
int ret; /* assert reset for at least 20 usec */
pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE);
/* FIXME: i965g/gm need a display save/restore for gpu reset. */ udelay(20);
return -ENODEV; pci_write_config_byte(dev->pdev, I915_GDRST, 0);
/*
* Set the domains we want to reset (GRDOM/bits 2 and 3) as
* well as the reset bit (GR/bit 0). Setting the GR bit
* triggers the reset; when done, the hardware will clear it.
*/
pci_write_config_byte(dev->pdev, I965_GDRST,
GRDOM_RENDER | GRDOM_RESET_ENABLE);
ret = wait_for(i965_reset_complete(dev), 500);
if (ret)
return ret;
pci_write_config_byte(dev->pdev, I965_GDRST, return wait_for(i915_reset_complete(dev), 500);
GRDOM_MEDIA | GRDOM_RESET_ENABLE); }
ret = wait_for(i965_reset_complete(dev), 500);
if (ret)
return ret;
pci_write_config_byte(dev->pdev, I965_GDRST, 0); static int g4x_reset_complete(struct drm_device *dev)
{
u8 gdrst;
pci_read_config_byte(dev->pdev, I915_GDRST, &gdrst);
return (gdrst & GRDOM_RESET_ENABLE) == 0;
}
return 0; static int g33_do_reset(struct drm_device *dev)
{
pci_write_config_byte(dev->pdev, I915_GDRST, GRDOM_RESET_ENABLE);
return wait_for(g4x_reset_complete(dev), 500);
} }
static int g4x_do_reset(struct drm_device *dev) static int g4x_do_reset(struct drm_device *dev)
...@@ -1387,9 +1384,9 @@ static int g4x_do_reset(struct drm_device *dev) ...@@ -1387,9 +1384,9 @@ static int g4x_do_reset(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret; int ret;
pci_write_config_byte(dev->pdev, I965_GDRST, pci_write_config_byte(dev->pdev, I915_GDRST,
GRDOM_RENDER | GRDOM_RESET_ENABLE); GRDOM_RENDER | GRDOM_RESET_ENABLE);
ret = wait_for(i965_reset_complete(dev), 500); ret = wait_for(g4x_reset_complete(dev), 500);
if (ret) if (ret)
return ret; return ret;
...@@ -1397,9 +1394,9 @@ static int g4x_do_reset(struct drm_device *dev) ...@@ -1397,9 +1394,9 @@ static int g4x_do_reset(struct drm_device *dev)
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE); I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE);
POSTING_READ(VDECCLK_GATE_D); POSTING_READ(VDECCLK_GATE_D);
pci_write_config_byte(dev->pdev, I965_GDRST, pci_write_config_byte(dev->pdev, I915_GDRST,
GRDOM_MEDIA | GRDOM_RESET_ENABLE); GRDOM_MEDIA | GRDOM_RESET_ENABLE);
ret = wait_for(i965_reset_complete(dev), 500); ret = wait_for(g4x_reset_complete(dev), 500);
if (ret) if (ret)
return ret; return ret;
...@@ -1407,7 +1404,7 @@ static int g4x_do_reset(struct drm_device *dev) ...@@ -1407,7 +1404,7 @@ static int g4x_do_reset(struct drm_device *dev)
I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE); I915_WRITE(VDECCLK_GATE_D, I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE);
POSTING_READ(VDECCLK_GATE_D); POSTING_READ(VDECCLK_GATE_D);
pci_write_config_byte(dev->pdev, I965_GDRST, 0); pci_write_config_byte(dev->pdev, I915_GDRST, 0);
return 0; return 0;
} }
...@@ -1465,8 +1462,10 @@ int intel_gpu_reset(struct drm_device *dev) ...@@ -1465,8 +1462,10 @@ int intel_gpu_reset(struct drm_device *dev)
return ironlake_do_reset(dev); return ironlake_do_reset(dev);
else if (IS_G4X(dev)) else if (IS_G4X(dev))
return g4x_do_reset(dev); return g4x_do_reset(dev);
else if (IS_GEN4(dev)) else if (IS_G33(dev))
return i965_do_reset(dev); return g33_do_reset(dev);
else if (INTEL_INFO(dev)->gen >= 3)
return i915_do_reset(dev);
else else
return -ENODEV; return -ENODEV;
} }
......
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