Merge tag 'drm-intel-fixes-2014-04-04' of git://anongit.freedesktop.org/drm-intel into drm-next
Merge window -fixes pull request as usual. Well, I did sneak in Jani's drm_i915_private_t typedef removal, need to have fun with a big sed job too ;-) Otherwise: - hdmi interlaced fixes (Jesse&Ville) - pipe error/underrun/crc tracking fixes, regression in late 3.14-rc (but not cc: stable since only really relevant for igt runs) - large cursor wm fixes (Chris) - fix gpu turbo boost/throttle again, was getting stuck due to vlv rps patches (Chris+Imre) - fix runtime pm fallout (Paulo) - bios framebuffer inherit fix (Chris) - a few smaller things * tag 'drm-intel-fixes-2014-04-04' of git://anongit.freedesktop.org/drm-intel: (196 commits) Skip intel_crt_init for Dell XPS 8700 drm/i915: vlv: fix RPS interrupt mask setting Revert "drm/i915/vlv: fixup DDR freq detection per Punit spec" drm/i915: move power domain init earlier during system resume drm/i915: Fix the computation of required fb size for pipe drm/i915: don't get/put runtime PM at the debugfs forcewake file drm/i915: fix WARNs when reading DDI state while suspended drm/i915: don't read cursor registers on powered down pipes drm/i915: get runtime PM at i915_display_info drm/i915: don't read pp_ctrl_reg if we're suspended drm/i915: get runtime PM at i915_reg_read_ioctl drm/i915: don't schedule force_wake_timer at gen6_read drm/i915: vlv: reserve the GT power context only once during driver init drm/i915: prefer struct drm_i915_private to drm_i915_private_t drm/i915/overlay: prefer struct drm_i915_private to drm_i915_private_t drm/i915/ringbuffer: prefer struct drm_i915_private to drm_i915_private_t drm/i915/display: prefer struct drm_i915_private to drm_i915_private_t drm/i915/irq: prefer struct drm_i915_private to drm_i915_private_t drm/i915/gem: prefer struct drm_i915_private to drm_i915_private_t drm/i915/dma: prefer struct drm_i915_private to drm_i915_private_t ...
This commit is contained in:
@@ -82,7 +82,7 @@ static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
|
||||
|
||||
/* For display hotplug interrupt */
|
||||
static void
|
||||
ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
|
||||
ironlake_enable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
|
||||
{
|
||||
assert_spin_locked(&dev_priv->irq_lock);
|
||||
|
||||
@@ -100,7 +100,7 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
|
||||
}
|
||||
|
||||
static void
|
||||
ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
|
||||
ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask)
|
||||
{
|
||||
assert_spin_locked(&dev_priv->irq_lock);
|
||||
|
||||
@@ -596,7 +596,7 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
|
||||
*/
|
||||
static void i915_enable_asle_pipestat(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!dev_priv->opregion.asle || !IS_MOBILE(dev))
|
||||
@@ -624,7 +624,7 @@ static void i915_enable_asle_pipestat(struct drm_device *dev)
|
||||
static int
|
||||
i915_pipe_enabled(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
/* Locking is horribly broken here, but whatever. */
|
||||
@@ -648,7 +648,7 @@ static u32 i8xx_get_vblank_counter(struct drm_device *dev, int pipe)
|
||||
*/
|
||||
static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long high_frame;
|
||||
unsigned long low_frame;
|
||||
u32 high1, high2, low, pixel, vbl_start;
|
||||
@@ -704,7 +704,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
|
||||
|
||||
static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int reg = PIPE_FRMCOUNT_GM45(pipe);
|
||||
|
||||
if (!i915_pipe_enabled(dev, pipe)) {
|
||||
@@ -718,33 +718,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
|
||||
|
||||
/* raw reads, only for fast reads of display block, no need for forcewake etc. */
|
||||
#define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__))
|
||||
#define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__))
|
||||
|
||||
static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
uint32_t status;
|
||||
int reg;
|
||||
|
||||
if (INTEL_INFO(dev)->gen < 7) {
|
||||
status = pipe == PIPE_A ?
|
||||
DE_PIPEA_VBLANK :
|
||||
DE_PIPEB_VBLANK;
|
||||
if (INTEL_INFO(dev)->gen >= 8) {
|
||||
status = GEN8_PIPE_VBLANK;
|
||||
reg = GEN8_DE_PIPE_ISR(pipe);
|
||||
} else if (INTEL_INFO(dev)->gen >= 7) {
|
||||
status = DE_PIPE_VBLANK_IVB(pipe);
|
||||
reg = DEISR;
|
||||
} else {
|
||||
switch (pipe) {
|
||||
default:
|
||||
case PIPE_A:
|
||||
status = DE_PIPEA_VBLANK_IVB;
|
||||
break;
|
||||
case PIPE_B:
|
||||
status = DE_PIPEB_VBLANK_IVB;
|
||||
break;
|
||||
case PIPE_C:
|
||||
status = DE_PIPEC_VBLANK_IVB;
|
||||
break;
|
||||
}
|
||||
status = DE_PIPE_VBLANK(pipe);
|
||||
reg = DEISR;
|
||||
}
|
||||
|
||||
return __raw_i915_read32(dev_priv, DEISR) & status;
|
||||
return __raw_i915_read32(dev_priv, reg) & status;
|
||||
}
|
||||
|
||||
static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
||||
@@ -802,7 +794,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
|
||||
else
|
||||
position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3;
|
||||
|
||||
if (HAS_PCH_SPLIT(dev)) {
|
||||
if (HAS_DDI(dev)) {
|
||||
/*
|
||||
* On HSW HDMI outputs there seems to be a 2 line
|
||||
* difference, whereas eDP has the normal 1 line
|
||||
* difference that earlier platforms have. External
|
||||
* DP is unknown. For now just check for the 2 line
|
||||
* difference case on all output types on HSW+.
|
||||
*
|
||||
* This might misinterpret the scanline counter being
|
||||
* one line too far along on eDP, but that's less
|
||||
* dangerous than the alternative since that would lead
|
||||
* the vblank timestamp code astray when it sees a
|
||||
* scanline count before vblank_start during a vblank
|
||||
* interrupt.
|
||||
*/
|
||||
in_vbl = ilk_pipe_in_vblank_locked(dev, pipe);
|
||||
if ((in_vbl && (position == vbl_start - 2 ||
|
||||
position == vbl_start - 1)) ||
|
||||
(!in_vbl && (position == vbl_end - 2 ||
|
||||
position == vbl_end - 1)))
|
||||
position = (position + 2) % vtotal;
|
||||
} else if (HAS_PCH_SPLIT(dev)) {
|
||||
/*
|
||||
* The scanline counter increments at the leading edge
|
||||
* of hsync, ie. it completely misses the active portion
|
||||
@@ -946,8 +959,8 @@ static bool intel_hpd_irq_event(struct drm_device *dev,
|
||||
|
||||
static void i915_hotplug_work_func(struct work_struct *work)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
|
||||
hotplug_work);
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private, hotplug_work);
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct intel_connector *intel_connector;
|
||||
@@ -1022,7 +1035,7 @@ static void intel_hpd_irq_uninstall(struct drm_i915_private *dev_priv)
|
||||
|
||||
static void ironlake_rps_change_irq_handler(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 busy_up, busy_down, max_avg, min_avg;
|
||||
u8 new_delay;
|
||||
|
||||
@@ -1071,47 +1084,10 @@ static void notify_ring(struct drm_device *dev,
|
||||
i915_queue_hangcheck(dev);
|
||||
}
|
||||
|
||||
void gen6_set_pm_mask(struct drm_i915_private *dev_priv,
|
||||
u32 pm_iir, int new_delay)
|
||||
{
|
||||
if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
|
||||
if (new_delay >= dev_priv->rps.max_freq_softlimit) {
|
||||
/* Mask UP THRESHOLD Interrupts */
|
||||
I915_WRITE(GEN6_PMINTRMSK,
|
||||
I915_READ(GEN6_PMINTRMSK) |
|
||||
GEN6_PM_RP_UP_THRESHOLD);
|
||||
dev_priv->rps.rp_up_masked = true;
|
||||
}
|
||||
if (dev_priv->rps.rp_down_masked) {
|
||||
/* UnMask DOWN THRESHOLD Interrupts */
|
||||
I915_WRITE(GEN6_PMINTRMSK,
|
||||
I915_READ(GEN6_PMINTRMSK) &
|
||||
~GEN6_PM_RP_DOWN_THRESHOLD);
|
||||
dev_priv->rps.rp_down_masked = false;
|
||||
}
|
||||
} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
|
||||
if (new_delay <= dev_priv->rps.min_freq_softlimit) {
|
||||
/* Mask DOWN THRESHOLD Interrupts */
|
||||
I915_WRITE(GEN6_PMINTRMSK,
|
||||
I915_READ(GEN6_PMINTRMSK) |
|
||||
GEN6_PM_RP_DOWN_THRESHOLD);
|
||||
dev_priv->rps.rp_down_masked = true;
|
||||
}
|
||||
|
||||
if (dev_priv->rps.rp_up_masked) {
|
||||
/* UnMask UP THRESHOLD Interrupts */
|
||||
I915_WRITE(GEN6_PMINTRMSK,
|
||||
I915_READ(GEN6_PMINTRMSK) &
|
||||
~GEN6_PM_RP_UP_THRESHOLD);
|
||||
dev_priv->rps.rp_up_masked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen6_pm_rps_work(struct work_struct *work)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
|
||||
rps.work);
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private, rps.work);
|
||||
u32 pm_iir;
|
||||
int new_delay, adj;
|
||||
|
||||
@@ -1119,13 +1095,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
|
||||
pm_iir = dev_priv->rps.pm_iir;
|
||||
dev_priv->rps.pm_iir = 0;
|
||||
/* Make sure not to corrupt PMIMR state used by ringbuffer code */
|
||||
snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
|
||||
snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
/* Make sure we didn't queue anything we're not going to process. */
|
||||
WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
|
||||
WARN_ON(pm_iir & ~dev_priv->pm_rps_events);
|
||||
|
||||
if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
|
||||
if ((pm_iir & dev_priv->pm_rps_events) == 0)
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
@@ -1167,7 +1143,6 @@ static void gen6_pm_rps_work(struct work_struct *work)
|
||||
dev_priv->rps.min_freq_softlimit,
|
||||
dev_priv->rps.max_freq_softlimit);
|
||||
|
||||
gen6_set_pm_mask(dev_priv, pm_iir, new_delay);
|
||||
dev_priv->rps.last_adj = new_delay - dev_priv->rps.cur_freq;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||
@@ -1190,8 +1165,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
|
||||
*/
|
||||
static void ivybridge_parity_work(struct work_struct *work)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
|
||||
l3_parity.error_work);
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private, l3_parity.error_work);
|
||||
u32 error_status, row, bank, subbank;
|
||||
char *parity_event[6];
|
||||
uint32_t misccpctl;
|
||||
@@ -1263,7 +1238,7 @@ out:
|
||||
|
||||
static void ivybridge_parity_error_irq_handler(struct drm_device *dev, u32 iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (!HAS_L3_DPF(dev))
|
||||
return;
|
||||
@@ -1374,7 +1349,7 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
|
||||
u32 hotplug_trigger,
|
||||
const u32 *hpd)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
bool storm_detected = false;
|
||||
|
||||
@@ -1430,14 +1405,14 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
|
||||
|
||||
static void gmbus_irq_handler(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
wake_up_all(&dev_priv->gmbus_wait_queue);
|
||||
}
|
||||
|
||||
static void dp_aux_irq_handler(struct drm_device *dev)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
wake_up_all(&dev_priv->gmbus_wait_queue);
|
||||
}
|
||||
@@ -1543,10 +1518,10 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe)
|
||||
* the work queue. */
|
||||
static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
|
||||
{
|
||||
if (pm_iir & GEN6_PM_RPS_EVENTS) {
|
||||
if (pm_iir & dev_priv->pm_rps_events) {
|
||||
spin_lock(&dev_priv->irq_lock);
|
||||
dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS;
|
||||
snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RPS_EVENTS);
|
||||
dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events;
|
||||
snb_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
|
||||
spin_unlock(&dev_priv->irq_lock);
|
||||
|
||||
queue_work(dev_priv->wq, &dev_priv->rps.work);
|
||||
@@ -1637,7 +1612,7 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
|
||||
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 iir, gt_iir, pm_iir;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
@@ -1684,7 +1659,7 @@ out:
|
||||
|
||||
static void ibx_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK;
|
||||
|
||||
@@ -1791,7 +1766,7 @@ static void cpt_serr_int_handler(struct drm_device *dev)
|
||||
|
||||
static void cpt_irq_handler(struct drm_device *dev, u32 pch_iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT;
|
||||
|
||||
@@ -1915,7 +1890,7 @@ static void ivb_display_irq_handler(struct drm_device *dev, u32 de_iir)
|
||||
static irqreturn_t ironlake_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 de_iir, gt_iir, de_ier, sde_ier = 0;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
@@ -2126,8 +2101,8 @@ static void i915_error_work_func(struct work_struct *work)
|
||||
{
|
||||
struct i915_gpu_error *error = container_of(work, struct i915_gpu_error,
|
||||
work);
|
||||
drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t,
|
||||
gpu_error);
|
||||
struct drm_i915_private *dev_priv =
|
||||
container_of(error, struct drm_i915_private, gpu_error);
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
char *error_event[] = { I915_ERROR_UEVENT "=1", NULL };
|
||||
char *reset_event[] = { I915_RESET_UEVENT "=1", NULL };
|
||||
@@ -2336,7 +2311,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged,
|
||||
|
||||
static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct drm_i915_gem_object *obj;
|
||||
@@ -2385,7 +2360,7 @@ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, in
|
||||
*/
|
||||
static int i915_enable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!i915_pipe_enabled(dev, pipe))
|
||||
@@ -2409,7 +2384,7 @@ static int i915_enable_vblank(struct drm_device *dev, int pipe)
|
||||
|
||||
static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
|
||||
DE_PIPE_VBLANK(pipe);
|
||||
@@ -2426,7 +2401,7 @@ static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
|
||||
|
||||
static int valleyview_enable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
if (!i915_pipe_enabled(dev, pipe))
|
||||
@@ -2461,7 +2436,7 @@ static int gen8_enable_vblank(struct drm_device *dev, int pipe)
|
||||
*/
|
||||
static void i915_disable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||
@@ -2476,7 +2451,7 @@ static void i915_disable_vblank(struct drm_device *dev, int pipe)
|
||||
|
||||
static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) :
|
||||
DE_PIPE_VBLANK(pipe);
|
||||
@@ -2488,7 +2463,7 @@ static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
|
||||
|
||||
static void valleyview_disable_vblank(struct drm_device *dev, int pipe)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
||||
@@ -2530,29 +2505,43 @@ static struct intel_ring_buffer *
|
||||
semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = ring->dev->dev_private;
|
||||
u32 cmd, ipehr, acthd, acthd_min;
|
||||
u32 cmd, ipehr, head;
|
||||
int i;
|
||||
|
||||
ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
|
||||
if ((ipehr & ~(0x3 << 16)) !=
|
||||
(MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | MI_SEMAPHORE_REGISTER))
|
||||
return NULL;
|
||||
|
||||
/* ACTHD is likely pointing to the dword after the actual command,
|
||||
* so scan backwards until we find the MBOX.
|
||||
/*
|
||||
* HEAD is likely pointing to the dword after the actual command,
|
||||
* so scan backwards until we find the MBOX. But limit it to just 3
|
||||
* dwords. Note that we don't care about ACTHD here since that might
|
||||
* point at at batch, and semaphores are always emitted into the
|
||||
* ringbuffer itself.
|
||||
*/
|
||||
acthd = intel_ring_get_active_head(ring) & HEAD_ADDR;
|
||||
acthd_min = max((int)acthd - 3 * 4, 0);
|
||||
do {
|
||||
cmd = ioread32(ring->virtual_start + acthd);
|
||||
head = I915_READ_HEAD(ring) & HEAD_ADDR;
|
||||
|
||||
for (i = 4; i; --i) {
|
||||
/*
|
||||
* Be paranoid and presume the hw has gone off into the wild -
|
||||
* our ring is smaller than what the hardware (and hence
|
||||
* HEAD_ADDR) allows. Also handles wrap-around.
|
||||
*/
|
||||
head &= ring->size - 1;
|
||||
|
||||
/* This here seems to blow up */
|
||||
cmd = ioread32(ring->virtual_start + head);
|
||||
if (cmd == ipehr)
|
||||
break;
|
||||
|
||||
acthd -= 4;
|
||||
if (acthd < acthd_min)
|
||||
return NULL;
|
||||
} while (1);
|
||||
head -= 4;
|
||||
}
|
||||
|
||||
*seqno = ioread32(ring->virtual_start+acthd+4)+1;
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
*seqno = ioread32(ring->virtual_start + head + 4) + 1;
|
||||
return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3];
|
||||
}
|
||||
|
||||
@@ -2586,7 +2575,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv)
|
||||
}
|
||||
|
||||
static enum intel_ring_hangcheck_action
|
||||
ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
|
||||
ring_stuck(struct intel_ring_buffer *ring, u64 acthd)
|
||||
{
|
||||
struct drm_device *dev = ring->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
@@ -2641,7 +2630,7 @@ ring_stuck(struct intel_ring_buffer *ring, u32 acthd)
|
||||
static void i915_hangcheck_elapsed(unsigned long data)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *)data;
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_ring_buffer *ring;
|
||||
int i;
|
||||
int busy_count = 0, rings_hung = 0;
|
||||
@@ -2654,7 +2643,8 @@ static void i915_hangcheck_elapsed(unsigned long data)
|
||||
return;
|
||||
|
||||
for_each_ring(ring, dev_priv, i) {
|
||||
u32 seqno, acthd;
|
||||
u64 acthd;
|
||||
u32 seqno;
|
||||
bool busy = true;
|
||||
|
||||
semaphore_clear_deadlocks(dev_priv);
|
||||
@@ -2799,7 +2789,7 @@ static void gen5_gt_irq_preinstall(struct drm_device *dev)
|
||||
*/
|
||||
static void ironlake_irq_preinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
I915_WRITE(HWSTAM, 0xeffe);
|
||||
|
||||
@@ -2814,7 +2804,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
|
||||
|
||||
static void valleyview_irq_preinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
/* VLV magic */
|
||||
@@ -2890,7 +2880,7 @@ static void gen8_irq_preinstall(struct drm_device *dev)
|
||||
|
||||
static void ibx_hpd_irq_setup(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct intel_encoder *intel_encoder;
|
||||
u32 hotplug_irqs, hotplug, enabled_irqs = 0;
|
||||
@@ -2925,17 +2915,16 @@ static void ibx_hpd_irq_setup(struct drm_device *dev)
|
||||
|
||||
static void ibx_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 mask;
|
||||
|
||||
if (HAS_PCH_NOP(dev))
|
||||
return;
|
||||
|
||||
if (HAS_PCH_IBX(dev)) {
|
||||
mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER |
|
||||
SDE_TRANSA_FIFO_UNDER | SDE_POISON;
|
||||
mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
|
||||
} else {
|
||||
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT;
|
||||
mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
|
||||
|
||||
I915_WRITE(SERR_INT, I915_READ(SERR_INT));
|
||||
}
|
||||
@@ -2972,7 +2961,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
|
||||
POSTING_READ(GTIER);
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 6) {
|
||||
pm_irqs |= GEN6_PM_RPS_EVENTS;
|
||||
pm_irqs |= dev_priv->pm_rps_events;
|
||||
|
||||
if (HAS_VEBOX(dev))
|
||||
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
|
||||
@@ -2988,27 +2977,26 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
|
||||
static int ironlake_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
unsigned long irqflags;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 display_mask, extra_mask;
|
||||
|
||||
if (INTEL_INFO(dev)->gen >= 7) {
|
||||
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
|
||||
DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
|
||||
DE_PLANEB_FLIP_DONE_IVB |
|
||||
DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB |
|
||||
DE_ERR_INT_IVB);
|
||||
DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
|
||||
extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
|
||||
DE_PIPEA_VBLANK_IVB);
|
||||
DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
|
||||
|
||||
I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
|
||||
} else {
|
||||
display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
|
||||
DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
|
||||
DE_AUX_CHANNEL_A |
|
||||
DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
|
||||
DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
|
||||
DE_POISON);
|
||||
extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT;
|
||||
extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
|
||||
DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
|
||||
}
|
||||
|
||||
dev_priv->irq_mask = ~display_mask;
|
||||
@@ -3126,7 +3114,7 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv)
|
||||
|
||||
static int valleyview_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
dev_priv->irq_mask = ~0;
|
||||
@@ -3193,9 +3181,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
|
||||
GEN8_PIPE_CDCLK_CRC_DONE |
|
||||
GEN8_PIPE_FIFO_UNDERRUN |
|
||||
GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
|
||||
uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK;
|
||||
uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
|
||||
GEN8_PIPE_FIFO_UNDERRUN;
|
||||
int pipe;
|
||||
dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
|
||||
dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;
|
||||
@@ -3273,7 +3261,7 @@ static void gen8_irq_uninstall(struct drm_device *dev)
|
||||
|
||||
static void valleyview_irq_uninstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
int pipe;
|
||||
|
||||
@@ -3304,7 +3292,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev)
|
||||
|
||||
static void ironlake_irq_uninstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
if (!dev_priv)
|
||||
return;
|
||||
@@ -3335,7 +3323,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
|
||||
|
||||
static void i8xx_irq_preinstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
for_each_pipe(pipe)
|
||||
@@ -3347,7 +3335,7 @@ static void i8xx_irq_preinstall(struct drm_device * dev)
|
||||
|
||||
static int i8xx_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
unsigned long irqflags;
|
||||
|
||||
I915_WRITE16(EMR,
|
||||
@@ -3385,7 +3373,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev)
|
||||
static bool i8xx_handle_vblank(struct drm_device *dev,
|
||||
int plane, int pipe, u32 iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u16 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
|
||||
|
||||
if (!drm_handle_vblank(dev, pipe))
|
||||
@@ -3413,7 +3401,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
|
||||
static irqreturn_t i8xx_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u16 iir, new_iir;
|
||||
u32 pipe_stats[2];
|
||||
unsigned long irqflags;
|
||||
@@ -3483,7 +3471,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
|
||||
|
||||
static void i8xx_irq_uninstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
for_each_pipe(pipe) {
|
||||
@@ -3498,7 +3486,7 @@ static void i8xx_irq_uninstall(struct drm_device * dev)
|
||||
|
||||
static void i915_irq_preinstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
if (I915_HAS_HOTPLUG(dev)) {
|
||||
@@ -3516,7 +3504,7 @@ static void i915_irq_preinstall(struct drm_device * dev)
|
||||
|
||||
static int i915_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 enable_mask;
|
||||
unsigned long irqflags;
|
||||
|
||||
@@ -3570,7 +3558,7 @@ static int i915_irq_postinstall(struct drm_device *dev)
|
||||
static bool i915_handle_vblank(struct drm_device *dev,
|
||||
int plane, int pipe, u32 iir)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 flip_pending = DISPLAY_PLANE_FLIP_PENDING(plane);
|
||||
|
||||
if (!drm_handle_vblank(dev, pipe))
|
||||
@@ -3598,7 +3586,7 @@ static bool i915_handle_vblank(struct drm_device *dev,
|
||||
static irqreturn_t i915_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
|
||||
unsigned long irqflags;
|
||||
u32 flip_mask =
|
||||
@@ -3704,7 +3692,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
|
||||
|
||||
static void i915_irq_uninstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
intel_hpd_irq_uninstall(dev_priv);
|
||||
@@ -3728,7 +3716,7 @@ static void i915_irq_uninstall(struct drm_device * dev)
|
||||
|
||||
static void i965_irq_preinstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
I915_WRITE(PORT_HOTPLUG_EN, 0);
|
||||
@@ -3744,7 +3732,7 @@ static void i965_irq_preinstall(struct drm_device * dev)
|
||||
|
||||
static int i965_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 enable_mask;
|
||||
u32 error_mask;
|
||||
unsigned long irqflags;
|
||||
@@ -3803,7 +3791,7 @@ static int i965_irq_postinstall(struct drm_device *dev)
|
||||
|
||||
static void i915_hpd_irq_setup(struct drm_device *dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
struct intel_encoder *intel_encoder;
|
||||
u32 hotplug_en;
|
||||
@@ -3835,7 +3823,7 @@ static void i915_hpd_irq_setup(struct drm_device *dev)
|
||||
static irqreturn_t i965_irq_handler(int irq, void *arg)
|
||||
{
|
||||
struct drm_device *dev = (struct drm_device *) arg;
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 iir, new_iir;
|
||||
u32 pipe_stats[I915_MAX_PIPES];
|
||||
unsigned long irqflags;
|
||||
@@ -3953,7 +3941,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
|
||||
|
||||
static void i965_irq_uninstall(struct drm_device * dev)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
int pipe;
|
||||
|
||||
if (!dev_priv)
|
||||
@@ -3978,7 +3966,7 @@ static void i965_irq_uninstall(struct drm_device * dev)
|
||||
|
||||
static void intel_hpd_irq_reenable(unsigned long data)
|
||||
{
|
||||
drm_i915_private_t *dev_priv = (drm_i915_private_t *)data;
|
||||
struct drm_i915_private *dev_priv = (struct drm_i915_private *)data;
|
||||
struct drm_device *dev = dev_priv->dev;
|
||||
struct drm_mode_config *mode_config = &dev->mode_config;
|
||||
unsigned long irqflags;
|
||||
@@ -4020,6 +4008,9 @@ void intel_irq_init(struct drm_device *dev)
|
||||
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work);
|
||||
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
|
||||
|
||||
/* Let's track the enabled rps events */
|
||||
dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
|
||||
|
||||
setup_timer(&dev_priv->gpu_error.hangcheck_timer,
|
||||
i915_hangcheck_elapsed,
|
||||
(unsigned long) dev);
|
||||
|
Referens i nytt ärende
Block a user