aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h8
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c211
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c18
3 files changed, 115 insertions, 122 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ef1c0b8f8d07..ed1edcf8704f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -132,6 +132,7 @@ typedef struct drm_i915_private {
132 int user_irq_refcount; 132 int user_irq_refcount;
133 /** Cached value of IMR to avoid reads in updating the bitfield */ 133 /** Cached value of IMR to avoid reads in updating the bitfield */
134 u32 irq_mask_reg; 134 u32 irq_mask_reg;
135 u32 pipestat[2];
135 136
136 int tex_lru_log_granularity; 137 int tex_lru_log_granularity;
137 int allow_batchbuffer; 138 int allow_batchbuffer;
@@ -446,6 +447,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data,
446 struct drm_file *file_priv); 447 struct drm_file *file_priv);
447extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); 448extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
448 449
450void
451i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
452
453void
454i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
455
456
449/* i915_mem.c */ 457/* i915_mem.c */
450extern int i915_mem_alloc(struct drm_device *dev, void *data, 458extern int i915_mem_alloc(struct drm_device *dev, void *data,
451 struct drm_file *file_priv); 459 struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 82752d6177a4..ca3ed1833908 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -33,11 +33,23 @@
33 33
34#define MAX_NOPID ((u32)~0) 34#define MAX_NOPID ((u32)~0)
35 35
36/** These are the interrupts used by the driver */ 36/**
37#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ 37 * Interrupts that are always left unmasked.
38 I915_ASLE_INTERRUPT | \ 38 *
39 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ 39 * Since pipe events are edge-triggered from the PIPESTAT register to IIR,
40 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) 40 * we leave them always unmasked in IMR and then control enabling them through
41 * PIPESTAT alone.
42 */
43#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
44 I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
45 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
46
47/** Interrupts that we mask and unmask at runtime. */
48#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
49
50/** These are all of the interrupts used by the driver */
51#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
52 I915_INTERRUPT_ENABLE_VAR)
41 53
42void 54void
43i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) 55i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
@@ -59,6 +71,41 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
59 } 71 }
60} 72}
61 73
74static inline u32
75i915_pipestat(int pipe)
76{
77 if (pipe == 0)
78 return PIPEASTAT;
79 if (pipe == 1)
80 return PIPEBSTAT;
81 BUG_ON(1);
82}
83
84void
85i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
86{
87 if ((dev_priv->pipestat[pipe] & mask) != mask) {
88 u32 reg = i915_pipestat(pipe);
89
90 dev_priv->pipestat[pipe] |= mask;
91 /* Enable the interrupt, clear any pending status */
92 I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16));
93 (void) I915_READ(reg);
94 }
95}
96
97void
98i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
99{
100 if ((dev_priv->pipestat[pipe] & mask) != 0) {
101 u32 reg = i915_pipestat(pipe);
102
103 dev_priv->pipestat[pipe] &= ~mask;
104 I915_WRITE(reg, dev_priv->pipestat[pipe]);
105 (void) I915_READ(reg);
106 }
107}
108
62/** 109/**
63 * i915_pipe_enabled - check if a pipe is enabled 110 * i915_pipe_enabled - check if a pipe is enabled
64 * @dev: DRM device 111 * @dev: DRM device
@@ -122,9 +169,11 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
122 struct drm_device *dev = (struct drm_device *) arg; 169 struct drm_device *dev = (struct drm_device *) arg;
123 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 170 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
124 u32 iir; 171 u32 iir;
125 u32 pipea_stats, pipeb_stats; 172 u32 pipea_stats = 0, pipeb_stats = 0;
126 int vblank = 0; 173 int vblank = 0;
174 unsigned long irqflags;
127 175
176 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
128 atomic_inc(&dev_priv->irq_received); 177 atomic_inc(&dev_priv->irq_received);
129 178
130 if (dev->pdev->msi_enabled) 179 if (dev->pdev->msi_enabled)
@@ -136,44 +185,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
136 I915_WRITE(IMR, dev_priv->irq_mask_reg); 185 I915_WRITE(IMR, dev_priv->irq_mask_reg);
137 (void) I915_READ(IMR); 186 (void) I915_READ(IMR);
138 } 187 }
188 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
139 return IRQ_NONE; 189 return IRQ_NONE;
140 } 190 }
141 191
142 /* 192 /*
143 * Clear the PIPE(A|B)STAT regs before the IIR otherwise 193 * Clear the PIPE(A|B)STAT regs before the IIR
144 * we may get extra interrupts.
145 */ 194 */
146 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) { 195 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
147 pipea_stats = I915_READ(PIPEASTAT); 196 pipea_stats = I915_READ(PIPEASTAT);
148 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
149 pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
150 PIPE_VBLANK_INTERRUPT_ENABLE);
151 else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
152 PIPE_VBLANK_INTERRUPT_STATUS)) {
153 vblank++;
154 drm_handle_vblank(dev, 0);
155 }
156
157 I915_WRITE(PIPEASTAT, pipea_stats); 197 I915_WRITE(PIPEASTAT, pipea_stats);
158 } 198 }
199
159 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) { 200 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
160 pipeb_stats = I915_READ(PIPEBSTAT); 201 pipeb_stats = I915_READ(PIPEBSTAT);
161 /* Ack the event */
162 I915_WRITE(PIPEBSTAT, pipeb_stats);
163
164 /* The vblank interrupt gets enabled even if we didn't ask for
165 it, so make sure it's shut down again */
166 if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
167 pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
168 PIPE_VBLANK_INTERRUPT_ENABLE);
169 else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
170 PIPE_VBLANK_INTERRUPT_STATUS)) {
171 vblank++;
172 drm_handle_vblank(dev, 1);
173 }
174
175 if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
176 opregion_asle_intr(dev);
177 I915_WRITE(PIPEBSTAT, pipeb_stats); 202 I915_WRITE(PIPEBSTAT, pipeb_stats);
178 } 203 }
179 204
@@ -182,6 +207,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
182 I915_WRITE(IMR, dev_priv->irq_mask_reg); 207 I915_WRITE(IMR, dev_priv->irq_mask_reg);
183 (void) I915_READ(IIR); /* Flush posted writes */ 208 (void) I915_READ(IIR); /* Flush posted writes */
184 209
210 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
211
185 if (dev_priv->sarea_priv) 212 if (dev_priv->sarea_priv)
186 dev_priv->sarea_priv->last_dispatch = 213 dev_priv->sarea_priv->last_dispatch =
187 READ_BREADCRUMB(dev_priv); 214 READ_BREADCRUMB(dev_priv);
@@ -191,7 +218,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
191 DRM_WAKEUP(&dev_priv->irq_queue); 218 DRM_WAKEUP(&dev_priv->irq_queue);
192 } 219 }
193 220
194 if (iir & I915_ASLE_INTERRUPT) 221 if (pipea_stats & I915_VBLANK_INTERRUPT_STATUS) {
222 vblank++;
223 drm_handle_vblank(dev, 0);
224 }
225
226 if (pipeb_stats & I915_VBLANK_INTERRUPT_STATUS) {
227 vblank++;
228 drm_handle_vblank(dev, 1);
229 }
230
231 if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
232 (iir & I915_ASLE_INTERRUPT))
195 opregion_asle_intr(dev); 233 opregion_asle_intr(dev);
196 234
197 return IRQ_HANDLED; 235 return IRQ_HANDLED;
@@ -330,48 +368,16 @@ int i915_irq_wait(struct drm_device *dev, void *data,
330int i915_enable_vblank(struct drm_device *dev, int pipe) 368int i915_enable_vblank(struct drm_device *dev, int pipe)
331{ 369{
332 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 370 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
333 u32 pipestat_reg = 0;
334 u32 pipestat;
335 u32 interrupt = 0;
336 unsigned long irqflags; 371 unsigned long irqflags;
337 372
338 switch (pipe) {
339 case 0:
340 pipestat_reg = PIPEASTAT;
341 interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
342 break;
343 case 1:
344 pipestat_reg = PIPEBSTAT;
345 interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
346 break;
347 default:
348 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
349 pipe);
350 return 0;
351 }
352
353 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 373 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
354 /* Enabling vblank events in IMR comes before PIPESTAT write, or
355 * there's a race where the PIPESTAT vblank bit gets set to 1, so
356 * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
357 * ISR flashes to 1, but the IIR bit doesn't get set to 1 because
358 * IMR masks it. It doesn't ever get set after we clear the masking
359 * in IMR because the ISR bit is edge, not level-triggered, on the
360 * OR of PIPESTAT bits.
361 */
362 i915_enable_irq(dev_priv, interrupt);
363 pipestat = I915_READ(pipestat_reg);
364 if (IS_I965G(dev)) 374 if (IS_I965G(dev))
365 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; 375 i915_enable_pipestat(dev_priv, pipe,
376 PIPE_START_VBLANK_INTERRUPT_ENABLE);
366 else 377 else
367 pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE; 378 i915_enable_pipestat(dev_priv, pipe,
368 /* Clear any stale interrupt status */ 379 PIPE_VBLANK_INTERRUPT_ENABLE);
369 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
370 PIPE_VBLANK_INTERRUPT_STATUS);
371 I915_WRITE(pipestat_reg, pipestat);
372 (void) I915_READ(pipestat_reg); /* Posting read */
373 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 380 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
374
375 return 0; 381 return 0;
376} 382}
377 383
@@ -381,37 +387,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
381void i915_disable_vblank(struct drm_device *dev, int pipe) 387void i915_disable_vblank(struct drm_device *dev, int pipe)
382{ 388{
383 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 389 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
384 u32 pipestat_reg = 0;
385 u32 pipestat;
386 u32 interrupt = 0;
387 unsigned long irqflags; 390 unsigned long irqflags;
388 391
389 switch (pipe) {
390 case 0:
391 pipestat_reg = PIPEASTAT;
392 interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
393 break;
394 case 1:
395 pipestat_reg = PIPEBSTAT;
396 interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
397 break;
398 default:
399 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
400 pipe);
401 return;
402 break;
403 }
404
405 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 392 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
406 i915_disable_irq(dev_priv, interrupt); 393 i915_disable_pipestat(dev_priv, pipe,
407 pipestat = I915_READ(pipestat_reg); 394 PIPE_VBLANK_INTERRUPT_ENABLE |
408 pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE | 395 PIPE_START_VBLANK_INTERRUPT_ENABLE);
409 PIPE_VBLANK_INTERRUPT_ENABLE);
410 /* Clear any stale interrupt status */
411 pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
412 PIPE_VBLANK_INTERRUPT_STATUS);
413 I915_WRITE(pipestat_reg, pipestat);
414 (void) I915_READ(pipestat_reg); /* Posting read */
415 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 396 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
416} 397}
417 398
@@ -476,8 +457,11 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
476 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 457 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
477 458
478 I915_WRITE(HWSTAM, 0xeffe); 459 I915_WRITE(HWSTAM, 0xeffe);
460 I915_WRITE(PIPEASTAT, 0);
461 I915_WRITE(PIPEBSTAT, 0);
479 I915_WRITE(IMR, 0xffffffff); 462 I915_WRITE(IMR, 0xffffffff);
480 I915_WRITE(IER, 0x0); 463 I915_WRITE(IER, 0x0);
464 (void) I915_READ(IER);
481} 465}
482 466
483int i915_driver_irq_postinstall(struct drm_device *dev) 467int i915_driver_irq_postinstall(struct drm_device *dev)
@@ -485,23 +469,28 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
485 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 469 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
486 int ret, num_pipes = 2; 470 int ret, num_pipes = 2;
487 471
488 /* Set initial unmasked IRQs to just the selected vblank pipes. */
489 dev_priv->irq_mask_reg = ~0;
490
491 ret = drm_vblank_init(dev, num_pipes); 472 ret = drm_vblank_init(dev, num_pipes);
492 if (ret) 473 if (ret)
493 return ret; 474 return ret;
494 475
495 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; 476 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
496 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
497 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
498 477
499 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 478 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
500 479
501 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK; 480 /* Unmask the interrupts that we always want on. */
481 dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
482
483 dev_priv->pipestat[0] = 0;
484 dev_priv->pipestat[1] = 0;
485
486 /* Disable pipe interrupt enables, clear pending pipe status */
487 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
488 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
489 /* Clear pending interrupt status */
490 I915_WRITE(IIR, I915_READ(IIR));
502 491
503 I915_WRITE(IMR, dev_priv->irq_mask_reg);
504 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); 492 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
493 I915_WRITE(IMR, dev_priv->irq_mask_reg);
505 (void) I915_READ(IER); 494 (void) I915_READ(IER);
506 495
507 opregion_enable_asle(dev); 496 opregion_enable_asle(dev);
@@ -513,7 +502,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
513void i915_driver_irq_uninstall(struct drm_device * dev) 502void i915_driver_irq_uninstall(struct drm_device * dev)
514{ 503{
515 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 504 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
516 u32 temp;
517 505
518 if (!dev_priv) 506 if (!dev_priv)
519 return; 507 return;
@@ -521,13 +509,12 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
521 dev_priv->vblank_pipe = 0; 509 dev_priv->vblank_pipe = 0;
522 510
523 I915_WRITE(HWSTAM, 0xffffffff); 511 I915_WRITE(HWSTAM, 0xffffffff);
512 I915_WRITE(PIPEASTAT, 0);
513 I915_WRITE(PIPEBSTAT, 0);
524 I915_WRITE(IMR, 0xffffffff); 514 I915_WRITE(IMR, 0xffffffff);
525 I915_WRITE(IER, 0x0); 515 I915_WRITE(IER, 0x0);
526 516
527 temp = I915_READ(PIPEASTAT); 517 I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
528 I915_WRITE(PIPEASTAT, temp); 518 I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
529 temp = I915_READ(PIPEBSTAT); 519 I915_WRITE(IIR, I915_READ(IIR));
530 I915_WRITE(PIPEBSTAT, temp);
531 temp = I915_READ(IIR);
532 I915_WRITE(IIR, temp);
533} 520}
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index 1787a0c7e3ab..13ae731a33db 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev)
235 struct opregion_asle *asle = dev_priv->opregion.asle; 235 struct opregion_asle *asle = dev_priv->opregion.asle;
236 236
237 if (asle) { 237 if (asle) {
238 u32 pipeb_stats = I915_READ(PIPEBSTAT);
239 if (IS_MOBILE(dev)) { 238 if (IS_MOBILE(dev)) {
240 /* Many devices trigger events with a write to the 239 unsigned long irqflags;
241 legacy backlight controller, so we need to ensure 240
242 that it's able to generate interrupts */ 241 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
243 I915_WRITE(PIPEBSTAT, pipeb_stats |= 242 i915_enable_pipestat(dev_priv, 1,
244 I915_LEGACY_BLC_EVENT_ENABLE); 243 I915_LEGACY_BLC_EVENT_ENABLE);
245 i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | 244 spin_unlock_irqrestore(&dev_priv->user_irq_lock,
246 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); 245 irqflags);
247 } else 246 }
248 i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
249 247
250 asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | 248 asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
251 ASLE_PFMB_EN; 249 ASLE_PFMB_EN;