diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-01 17:12:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-01 17:12:27 -0400 |
commit | 709d015bb810a3377feaee3093d110a17e919019 (patch) | |
tree | 7a003395ddf648950de114f1da6968c879d8c164 /drivers | |
parent | 08a66859e69264f3223560d06b88e80c1a6a6387 (diff) | |
parent | e3a815fcd38043b8f1bb526123d8ab6ae01deb77 (diff) |
Merge branch 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel
* 'drm-intel-next' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel: (41 commits)
drm/i915: add HAS_BSD check to i915_getparam
drm/i915: Honor sync polarity from VBT panel timing descriptors
drm/i915: Unmask interrupt for render engine on Sandybridge
drm/i915: Fix PIPE_CONTROL command on Sandybridge
drm/i915: Fix up address spaces in slow_kernel_write()
drm/i915: Use non-atomic kmap for slow copy paths
drm/i915: Avoid moving from CPU domain during pwrite
drm/i915: Cleanup after failed initialization of ringbuffers
drm/i915: Reject bind_to_gtt() early if object > aperture
drm/i915: Check error code whilst moving buffer to GTT domain.
drm/i915: Remove spurious warning "Failure to install fence"
drm/i915: Rebind bo if currently bound with incorrect alignment.
drm/i915: Include pitch in set_base debug statement.
drm/i915: Only print "nothing to do" debug message as required.
drm/i915: Propagate error from unbinding an unfenceable object.
drm/i915: Avoid nesting of domain changes when setting display plane
drm/i915: Hold the spinlock whilst resetting unpin_work along error path
drm/i915: Only print an message if there was an error
drm/i915: Clean up leftover bits from hws move to ring structure.
drm/i915: Add CxSR support on Pineview DDR3
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 82 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 711 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 209 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 897 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 182 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 82 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_trace.h | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 281 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 849 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 124 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 2 |
20 files changed, 2586 insertions, 1081 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index e8ea6825822c..9344216183a4 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -1059,7 +1059,7 @@ static void intel_i9xx_setup_flush(void) | |||
1059 | } | 1059 | } |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static int intel_i915_configure(void) | 1062 | static int intel_i9xx_configure(void) |
1063 | { | 1063 | { |
1064 | struct aper_size_info_fixed *current_size; | 1064 | struct aper_size_info_fixed *current_size; |
1065 | u32 temp; | 1065 | u32 temp; |
@@ -1207,6 +1207,38 @@ static int intel_i9xx_fetch_size(void) | |||
1207 | return 0; | 1207 | return 0; |
1208 | } | 1208 | } |
1209 | 1209 | ||
1210 | static int intel_i915_get_gtt_size(void) | ||
1211 | { | ||
1212 | int size; | ||
1213 | |||
1214 | if (IS_G33) { | ||
1215 | u16 gmch_ctrl; | ||
1216 | |||
1217 | /* G33's GTT size defined in gmch_ctrl */ | ||
1218 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
1219 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | ||
1220 | case G33_PGETBL_SIZE_1M: | ||
1221 | size = 1024; | ||
1222 | break; | ||
1223 | case G33_PGETBL_SIZE_2M: | ||
1224 | size = 2048; | ||
1225 | break; | ||
1226 | default: | ||
1227 | dev_info(&agp_bridge->dev->dev, | ||
1228 | "unknown page table size 0x%x, assuming 512KB\n", | ||
1229 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | ||
1230 | size = 512; | ||
1231 | } | ||
1232 | } else { | ||
1233 | /* On previous hardware, the GTT size was just what was | ||
1234 | * required to map the aperture. | ||
1235 | */ | ||
1236 | size = agp_bridge->driver->fetch_size(); | ||
1237 | } | ||
1238 | |||
1239 | return KB(size); | ||
1240 | } | ||
1241 | |||
1210 | /* The intel i915 automatically initializes the agp aperture during POST. | 1242 | /* The intel i915 automatically initializes the agp aperture during POST. |
1211 | * Use the memory already set aside for in the GTT. | 1243 | * Use the memory already set aside for in the GTT. |
1212 | */ | 1244 | */ |
@@ -1216,7 +1248,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1216 | struct aper_size_info_fixed *size; | 1248 | struct aper_size_info_fixed *size; |
1217 | int num_entries; | 1249 | int num_entries; |
1218 | u32 temp, temp2; | 1250 | u32 temp, temp2; |
1219 | int gtt_map_size = 256 * 1024; | 1251 | int gtt_map_size; |
1220 | 1252 | ||
1221 | size = agp_bridge->current_size; | 1253 | size = agp_bridge->current_size; |
1222 | page_order = size->page_order; | 1254 | page_order = size->page_order; |
@@ -1226,8 +1258,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1226 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | 1258 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); |
1227 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); | 1259 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); |
1228 | 1260 | ||
1229 | if (IS_G33) | 1261 | gtt_map_size = intel_i915_get_gtt_size(); |
1230 | gtt_map_size = 1024 * 1024; /* 1M on G33 */ | 1262 | |
1231 | intel_private.gtt = ioremap(temp2, gtt_map_size); | 1263 | intel_private.gtt = ioremap(temp2, gtt_map_size); |
1232 | if (!intel_private.gtt) | 1264 | if (!intel_private.gtt) |
1233 | return -ENOMEM; | 1265 | return -ENOMEM; |
@@ -1422,7 +1454,7 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
1422 | .size_type = FIXED_APER_SIZE, | 1454 | .size_type = FIXED_APER_SIZE, |
1423 | .num_aperture_sizes = 4, | 1455 | .num_aperture_sizes = 4, |
1424 | .needs_scratch_page = true, | 1456 | .needs_scratch_page = true, |
1425 | .configure = intel_i915_configure, | 1457 | .configure = intel_i9xx_configure, |
1426 | .fetch_size = intel_i9xx_fetch_size, | 1458 | .fetch_size = intel_i9xx_fetch_size, |
1427 | .cleanup = intel_i915_cleanup, | 1459 | .cleanup = intel_i915_cleanup, |
1428 | .mask_memory = intel_i810_mask_memory, | 1460 | .mask_memory = intel_i810_mask_memory, |
@@ -1455,7 +1487,7 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
1455 | .size_type = FIXED_APER_SIZE, | 1487 | .size_type = FIXED_APER_SIZE, |
1456 | .num_aperture_sizes = 4, | 1488 | .num_aperture_sizes = 4, |
1457 | .needs_scratch_page = true, | 1489 | .needs_scratch_page = true, |
1458 | .configure = intel_i915_configure, | 1490 | .configure = intel_i9xx_configure, |
1459 | .fetch_size = intel_i9xx_fetch_size, | 1491 | .fetch_size = intel_i9xx_fetch_size, |
1460 | .cleanup = intel_i915_cleanup, | 1492 | .cleanup = intel_i915_cleanup, |
1461 | .mask_memory = intel_i965_mask_memory, | 1493 | .mask_memory = intel_i965_mask_memory, |
@@ -1488,7 +1520,7 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
1488 | .size_type = FIXED_APER_SIZE, | 1520 | .size_type = FIXED_APER_SIZE, |
1489 | .num_aperture_sizes = 4, | 1521 | .num_aperture_sizes = 4, |
1490 | .needs_scratch_page = true, | 1522 | .needs_scratch_page = true, |
1491 | .configure = intel_i915_configure, | 1523 | .configure = intel_i9xx_configure, |
1492 | .fetch_size = intel_i9xx_fetch_size, | 1524 | .fetch_size = intel_i9xx_fetch_size, |
1493 | .cleanup = intel_i915_cleanup, | 1525 | .cleanup = intel_i915_cleanup, |
1494 | .mask_memory = intel_i965_mask_memory, | 1526 | .mask_memory = intel_i965_mask_memory, |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 95639017bdbe..da78f2c0d909 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -22,6 +22,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
22 | intel_fb.o \ | 22 | intel_fb.o \ |
23 | intel_tv.o \ | 23 | intel_tv.o \ |
24 | intel_dvo.o \ | 24 | intel_dvo.o \ |
25 | intel_ringbuffer.o \ | ||
25 | intel_overlay.o \ | 26 | intel_overlay.o \ |
26 | dvo_ch7xxx.o \ | 27 | dvo_ch7xxx.o \ |
27 | dvo_ch7017.o \ | 28 | dvo_ch7017.o \ |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 322070c0c631..52510ad8b25d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -77,7 +77,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
77 | case ACTIVE_LIST: | 77 | case ACTIVE_LIST: |
78 | seq_printf(m, "Active:\n"); | 78 | seq_printf(m, "Active:\n"); |
79 | lock = &dev_priv->mm.active_list_lock; | 79 | lock = &dev_priv->mm.active_list_lock; |
80 | head = &dev_priv->mm.active_list; | 80 | head = &dev_priv->render_ring.active_list; |
81 | break; | 81 | break; |
82 | case INACTIVE_LIST: | 82 | case INACTIVE_LIST: |
83 | seq_printf(m, "Inactive:\n"); | 83 | seq_printf(m, "Inactive:\n"); |
@@ -129,7 +129,8 @@ static int i915_gem_request_info(struct seq_file *m, void *data) | |||
129 | struct drm_i915_gem_request *gem_request; | 129 | struct drm_i915_gem_request *gem_request; |
130 | 130 | ||
131 | seq_printf(m, "Request:\n"); | 131 | seq_printf(m, "Request:\n"); |
132 | list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { | 132 | list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, |
133 | list) { | ||
133 | seq_printf(m, " %d @ %d\n", | 134 | seq_printf(m, " %d @ %d\n", |
134 | gem_request->seqno, | 135 | gem_request->seqno, |
135 | (int) (jiffies - gem_request->emitted_jiffies)); | 136 | (int) (jiffies - gem_request->emitted_jiffies)); |
@@ -143,9 +144,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) | |||
143 | struct drm_device *dev = node->minor->dev; | 144 | struct drm_device *dev = node->minor->dev; |
144 | drm_i915_private_t *dev_priv = dev->dev_private; | 145 | drm_i915_private_t *dev_priv = dev->dev_private; |
145 | 146 | ||
146 | if (dev_priv->hw_status_page != NULL) { | 147 | if (dev_priv->render_ring.status_page.page_addr != NULL) { |
147 | seq_printf(m, "Current sequence: %d\n", | 148 | seq_printf(m, "Current sequence: %d\n", |
148 | i915_get_gem_seqno(dev)); | 149 | i915_get_gem_seqno(dev, &dev_priv->render_ring)); |
149 | } else { | 150 | } else { |
150 | seq_printf(m, "Current sequence: hws uninitialized\n"); | 151 | seq_printf(m, "Current sequence: hws uninitialized\n"); |
151 | } | 152 | } |
@@ -195,9 +196,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
195 | } | 196 | } |
196 | seq_printf(m, "Interrupts received: %d\n", | 197 | seq_printf(m, "Interrupts received: %d\n", |
197 | atomic_read(&dev_priv->irq_received)); | 198 | atomic_read(&dev_priv->irq_received)); |
198 | if (dev_priv->hw_status_page != NULL) { | 199 | if (dev_priv->render_ring.status_page.page_addr != NULL) { |
199 | seq_printf(m, "Current sequence: %d\n", | 200 | seq_printf(m, "Current sequence: %d\n", |
200 | i915_get_gem_seqno(dev)); | 201 | i915_get_gem_seqno(dev, &dev_priv->render_ring)); |
201 | } else { | 202 | } else { |
202 | seq_printf(m, "Current sequence: hws uninitialized\n"); | 203 | seq_printf(m, "Current sequence: hws uninitialized\n"); |
203 | } | 204 | } |
@@ -251,7 +252,7 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
251 | int i; | 252 | int i; |
252 | volatile u32 *hws; | 253 | volatile u32 *hws; |
253 | 254 | ||
254 | hws = (volatile u32 *)dev_priv->hw_status_page; | 255 | hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; |
255 | if (hws == NULL) | 256 | if (hws == NULL) |
256 | return 0; | 257 | return 0; |
257 | 258 | ||
@@ -287,7 +288,8 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) | |||
287 | 288 | ||
288 | spin_lock(&dev_priv->mm.active_list_lock); | 289 | spin_lock(&dev_priv->mm.active_list_lock); |
289 | 290 | ||
290 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 291 | list_for_each_entry(obj_priv, &dev_priv->render_ring.active_list, |
292 | list) { | ||
291 | obj = &obj_priv->base; | 293 | obj = &obj_priv->base; |
292 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { | 294 | if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { |
293 | ret = i915_gem_object_get_pages(obj, 0); | 295 | ret = i915_gem_object_get_pages(obj, 0); |
@@ -317,14 +319,14 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) | |||
317 | u8 *virt; | 319 | u8 *virt; |
318 | uint32_t *ptr, off; | 320 | uint32_t *ptr, off; |
319 | 321 | ||
320 | if (!dev_priv->ring.ring_obj) { | 322 | if (!dev_priv->render_ring.gem_object) { |
321 | seq_printf(m, "No ringbuffer setup\n"); | 323 | seq_printf(m, "No ringbuffer setup\n"); |
322 | return 0; | 324 | return 0; |
323 | } | 325 | } |
324 | 326 | ||
325 | virt = dev_priv->ring.virtual_start; | 327 | virt = dev_priv->render_ring.virtual_start; |
326 | 328 | ||
327 | for (off = 0; off < dev_priv->ring.Size; off += 4) { | 329 | for (off = 0; off < dev_priv->render_ring.size; off += 4) { |
328 | ptr = (uint32_t *)(virt + off); | 330 | ptr = (uint32_t *)(virt + off); |
329 | seq_printf(m, "%08x : %08x\n", off, *ptr); | 331 | seq_printf(m, "%08x : %08x\n", off, *ptr); |
330 | } | 332 | } |
@@ -344,7 +346,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
344 | 346 | ||
345 | seq_printf(m, "RingHead : %08x\n", head); | 347 | seq_printf(m, "RingHead : %08x\n", head); |
346 | seq_printf(m, "RingTail : %08x\n", tail); | 348 | seq_printf(m, "RingTail : %08x\n", tail); |
347 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | 349 | seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); |
348 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | 350 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); |
349 | 351 | ||
350 | return 0; | 352 | return 0; |
@@ -489,11 +491,14 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) | |||
489 | struct drm_device *dev = node->minor->dev; | 491 | struct drm_device *dev = node->minor->dev; |
490 | drm_i915_private_t *dev_priv = dev->dev_private; | 492 | drm_i915_private_t *dev_priv = dev->dev_private; |
491 | u16 rgvswctl = I915_READ16(MEMSWCTL); | 493 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
494 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); | ||
492 | 495 | ||
493 | seq_printf(m, "Last command: 0x%01x\n", (rgvswctl >> 13) & 0x3); | 496 | seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); |
494 | seq_printf(m, "Command status: %d\n", (rgvswctl >> 12) & 1); | 497 | seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); |
495 | seq_printf(m, "P%d DELAY 0x%02x\n", (rgvswctl >> 8) & 0xf, | 498 | seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> |
496 | rgvswctl & 0x3f); | 499 | MEMSTAT_VID_SHIFT); |
500 | seq_printf(m, "Current P-state: %d\n", | ||
501 | (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); | ||
497 | 502 | ||
498 | return 0; | 503 | return 0; |
499 | } | 504 | } |
@@ -508,7 +513,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) | |||
508 | 513 | ||
509 | for (i = 0; i < 16; i++) { | 514 | for (i = 0; i < 16; i++) { |
510 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); | 515 | delayfreq = I915_READ(PXVFREQ_BASE + i * 4); |
511 | seq_printf(m, "P%02dVIDFREQ: 0x%08x\n", i, delayfreq); | 516 | seq_printf(m, "P%02dVIDFREQ: 0x%08x (VID: %d)\n", i, delayfreq, |
517 | (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); | ||
512 | } | 518 | } |
513 | 519 | ||
514 | return 0; | 520 | return 0; |
@@ -541,6 +547,8 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
541 | struct drm_device *dev = node->minor->dev; | 547 | struct drm_device *dev = node->minor->dev; |
542 | drm_i915_private_t *dev_priv = dev->dev_private; | 548 | drm_i915_private_t *dev_priv = dev->dev_private; |
543 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 549 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
550 | u32 rstdbyctl = I915_READ(MCHBAR_RENDER_STANDBY); | ||
551 | u16 crstandvid = I915_READ16(CRSTANDVID); | ||
544 | 552 | ||
545 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? | 553 | seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? |
546 | "yes" : "no"); | 554 | "yes" : "no"); |
@@ -555,9 +563,13 @@ static int i915_drpc_info(struct seq_file *m, void *unused) | |||
555 | rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); | 563 | rgvmodectl & MEMMODE_RCLK_GATE ? "yes" : "no"); |
556 | seq_printf(m, "Starting frequency: P%d\n", | 564 | seq_printf(m, "Starting frequency: P%d\n", |
557 | (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); | 565 | (rgvmodectl & MEMMODE_FSTART_MASK) >> MEMMODE_FSTART_SHIFT); |
558 | seq_printf(m, "Max frequency: P%d\n", | 566 | seq_printf(m, "Max P-state: P%d\n", |
559 | (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); | 567 | (rgvmodectl & MEMMODE_FMAX_MASK) >> MEMMODE_FMAX_SHIFT); |
560 | seq_printf(m, "Min frequency: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); | 568 | seq_printf(m, "Min P-state: P%d\n", (rgvmodectl & MEMMODE_FMIN_MASK)); |
569 | seq_printf(m, "RS1 VID: %d\n", (crstandvid & 0x3f)); | ||
570 | seq_printf(m, "RS2 VID: %d\n", ((crstandvid >> 8) & 0x3f)); | ||
571 | seq_printf(m, "Render standby enabled: %s\n", | ||
572 | (rstdbyctl & RCX_SW_EXIT) ? "no" : "yes"); | ||
561 | 573 | ||
562 | return 0; | 574 | return 0; |
563 | } | 575 | } |
@@ -621,6 +633,36 @@ static int i915_sr_status(struct seq_file *m, void *unused) | |||
621 | return 0; | 633 | return 0; |
622 | } | 634 | } |
623 | 635 | ||
636 | static int i915_emon_status(struct seq_file *m, void *unused) | ||
637 | { | ||
638 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
639 | struct drm_device *dev = node->minor->dev; | ||
640 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
641 | unsigned long temp, chipset, gfx; | ||
642 | |||
643 | temp = i915_mch_val(dev_priv); | ||
644 | chipset = i915_chipset_val(dev_priv); | ||
645 | gfx = i915_gfx_val(dev_priv); | ||
646 | |||
647 | seq_printf(m, "GMCH temp: %ld\n", temp); | ||
648 | seq_printf(m, "Chipset power: %ld\n", chipset); | ||
649 | seq_printf(m, "GFX power: %ld\n", gfx); | ||
650 | seq_printf(m, "Total power: %ld\n", chipset + gfx); | ||
651 | |||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int i915_gfxec(struct seq_file *m, void *unused) | ||
656 | { | ||
657 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
658 | struct drm_device *dev = node->minor->dev; | ||
659 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
660 | |||
661 | seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
624 | static int | 666 | static int |
625 | i915_wedged_open(struct inode *inode, | 667 | i915_wedged_open(struct inode *inode, |
626 | struct file *filp) | 668 | struct file *filp) |
@@ -743,6 +785,8 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
743 | {"i915_delayfreq_table", i915_delayfreq_table, 0}, | 785 | {"i915_delayfreq_table", i915_delayfreq_table, 0}, |
744 | {"i915_inttoext_table", i915_inttoext_table, 0}, | 786 | {"i915_inttoext_table", i915_inttoext_table, 0}, |
745 | {"i915_drpc_info", i915_drpc_info, 0}, | 787 | {"i915_drpc_info", i915_drpc_info, 0}, |
788 | {"i915_emon_status", i915_emon_status, 0}, | ||
789 | {"i915_gfxec", i915_gfxec, 0}, | ||
746 | {"i915_fbc_status", i915_fbc_status, 0}, | 790 | {"i915_fbc_status", i915_fbc_status, 0}, |
747 | {"i915_sr_status", i915_sr_status, 0}, | 791 | {"i915_sr_status", i915_sr_status, 0}, |
748 | }; | 792 | }; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2a6b5de5ae5d..84ce95602f00 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -40,84 +40,6 @@ | |||
40 | #include <linux/vga_switcheroo.h> | 40 | #include <linux/vga_switcheroo.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | 42 | ||
43 | /* Really want an OS-independent resettable timer. Would like to have | ||
44 | * this loop run for (eg) 3 sec, but have the timer reset every time | ||
45 | * the head pointer changes, so that EBUSY only happens if the ring | ||
46 | * actually stalls for (eg) 3 seconds. | ||
47 | */ | ||
48 | int i915_wait_ring(struct drm_device * dev, int n, const char *caller) | ||
49 | { | ||
50 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
51 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | ||
52 | u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; | ||
53 | u32 last_acthd = I915_READ(acthd_reg); | ||
54 | u32 acthd; | ||
55 | u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
56 | int i; | ||
57 | |||
58 | trace_i915_ring_wait_begin (dev); | ||
59 | |||
60 | for (i = 0; i < 100000; i++) { | ||
61 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
62 | acthd = I915_READ(acthd_reg); | ||
63 | ring->space = ring->head - (ring->tail + 8); | ||
64 | if (ring->space < 0) | ||
65 | ring->space += ring->Size; | ||
66 | if (ring->space >= n) { | ||
67 | trace_i915_ring_wait_end (dev); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | if (dev->primary->master) { | ||
72 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
73 | if (master_priv->sarea_priv) | ||
74 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | ||
75 | } | ||
76 | |||
77 | |||
78 | if (ring->head != last_head) | ||
79 | i = 0; | ||
80 | if (acthd != last_acthd) | ||
81 | i = 0; | ||
82 | |||
83 | last_head = ring->head; | ||
84 | last_acthd = acthd; | ||
85 | msleep_interruptible(10); | ||
86 | |||
87 | } | ||
88 | |||
89 | trace_i915_ring_wait_end (dev); | ||
90 | return -EBUSY; | ||
91 | } | ||
92 | |||
93 | /* As a ringbuffer is only allowed to wrap between instructions, fill | ||
94 | * the tail with NOOPs. | ||
95 | */ | ||
96 | int i915_wrap_ring(struct drm_device *dev) | ||
97 | { | ||
98 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
99 | volatile unsigned int *virt; | ||
100 | int rem; | ||
101 | |||
102 | rem = dev_priv->ring.Size - dev_priv->ring.tail; | ||
103 | if (dev_priv->ring.space < rem) { | ||
104 | int ret = i915_wait_ring(dev, rem, __func__); | ||
105 | if (ret) | ||
106 | return ret; | ||
107 | } | ||
108 | dev_priv->ring.space -= rem; | ||
109 | |||
110 | virt = (unsigned int *) | ||
111 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); | ||
112 | rem /= 4; | ||
113 | while (rem--) | ||
114 | *virt++ = MI_NOOP; | ||
115 | |||
116 | dev_priv->ring.tail = 0; | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | /** | 43 | /** |
122 | * Sets up the hardware status page for devices that need a physical address | 44 | * Sets up the hardware status page for devices that need a physical address |
123 | * in the register. | 45 | * in the register. |
@@ -133,10 +55,11 @@ static int i915_init_phys_hws(struct drm_device *dev) | |||
133 | DRM_ERROR("Can not allocate hardware status page\n"); | 55 | DRM_ERROR("Can not allocate hardware status page\n"); |
134 | return -ENOMEM; | 56 | return -ENOMEM; |
135 | } | 57 | } |
136 | dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | 58 | dev_priv->render_ring.status_page.page_addr |
59 | = dev_priv->status_page_dmah->vaddr; | ||
137 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | 60 | dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; |
138 | 61 | ||
139 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | 62 | memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); |
140 | 63 | ||
141 | if (IS_I965G(dev)) | 64 | if (IS_I965G(dev)) |
142 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & | 65 | dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & |
@@ -159,8 +82,8 @@ static void i915_free_hws(struct drm_device *dev) | |||
159 | dev_priv->status_page_dmah = NULL; | 82 | dev_priv->status_page_dmah = NULL; |
160 | } | 83 | } |
161 | 84 | ||
162 | if (dev_priv->status_gfx_addr) { | 85 | if (dev_priv->render_ring.status_page.gfx_addr) { |
163 | dev_priv->status_gfx_addr = 0; | 86 | dev_priv->render_ring.status_page.gfx_addr = 0; |
164 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | 87 | drm_core_ioremapfree(&dev_priv->hws_map, dev); |
165 | } | 88 | } |
166 | 89 | ||
@@ -172,7 +95,7 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
172 | { | 95 | { |
173 | drm_i915_private_t *dev_priv = dev->dev_private; | 96 | drm_i915_private_t *dev_priv = dev->dev_private; |
174 | struct drm_i915_master_private *master_priv; | 97 | struct drm_i915_master_private *master_priv; |
175 | drm_i915_ring_buffer_t *ring = &(dev_priv->ring); | 98 | struct intel_ring_buffer *ring = &dev_priv->render_ring; |
176 | 99 | ||
177 | /* | 100 | /* |
178 | * We should never lose context on the ring with modesetting | 101 | * We should never lose context on the ring with modesetting |
@@ -185,7 +108,7 @@ void i915_kernel_lost_context(struct drm_device * dev) | |||
185 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | 108 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; |
186 | ring->space = ring->head - (ring->tail + 8); | 109 | ring->space = ring->head - (ring->tail + 8); |
187 | if (ring->space < 0) | 110 | if (ring->space < 0) |
188 | ring->space += ring->Size; | 111 | ring->space += ring->size; |
189 | 112 | ||
190 | if (!dev->primary->master) | 113 | if (!dev->primary->master) |
191 | return; | 114 | return; |
@@ -205,12 +128,9 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
205 | if (dev->irq_enabled) | 128 | if (dev->irq_enabled) |
206 | drm_irq_uninstall(dev); | 129 | drm_irq_uninstall(dev); |
207 | 130 | ||
208 | if (dev_priv->ring.virtual_start) { | 131 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); |
209 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | 132 | if (HAS_BSD(dev)) |
210 | dev_priv->ring.virtual_start = NULL; | 133 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); |
211 | dev_priv->ring.map.handle = NULL; | ||
212 | dev_priv->ring.map.size = 0; | ||
213 | } | ||
214 | 134 | ||
215 | /* Clear the HWS virtual address at teardown */ | 135 | /* Clear the HWS virtual address at teardown */ |
216 | if (I915_NEED_GFX_HWS(dev)) | 136 | if (I915_NEED_GFX_HWS(dev)) |
@@ -233,24 +153,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
233 | } | 153 | } |
234 | 154 | ||
235 | if (init->ring_size != 0) { | 155 | if (init->ring_size != 0) { |
236 | if (dev_priv->ring.ring_obj != NULL) { | 156 | if (dev_priv->render_ring.gem_object != NULL) { |
237 | i915_dma_cleanup(dev); | 157 | i915_dma_cleanup(dev); |
238 | DRM_ERROR("Client tried to initialize ringbuffer in " | 158 | DRM_ERROR("Client tried to initialize ringbuffer in " |
239 | "GEM mode\n"); | 159 | "GEM mode\n"); |
240 | return -EINVAL; | 160 | return -EINVAL; |
241 | } | 161 | } |
242 | 162 | ||
243 | dev_priv->ring.Size = init->ring_size; | 163 | dev_priv->render_ring.size = init->ring_size; |
244 | 164 | ||
245 | dev_priv->ring.map.offset = init->ring_start; | 165 | dev_priv->render_ring.map.offset = init->ring_start; |
246 | dev_priv->ring.map.size = init->ring_size; | 166 | dev_priv->render_ring.map.size = init->ring_size; |
247 | dev_priv->ring.map.type = 0; | 167 | dev_priv->render_ring.map.type = 0; |
248 | dev_priv->ring.map.flags = 0; | 168 | dev_priv->render_ring.map.flags = 0; |
249 | dev_priv->ring.map.mtrr = 0; | 169 | dev_priv->render_ring.map.mtrr = 0; |
250 | 170 | ||
251 | drm_core_ioremap_wc(&dev_priv->ring.map, dev); | 171 | drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); |
252 | 172 | ||
253 | if (dev_priv->ring.map.handle == NULL) { | 173 | if (dev_priv->render_ring.map.handle == NULL) { |
254 | i915_dma_cleanup(dev); | 174 | i915_dma_cleanup(dev); |
255 | DRM_ERROR("can not ioremap virtual address for" | 175 | DRM_ERROR("can not ioremap virtual address for" |
256 | " ring buffer\n"); | 176 | " ring buffer\n"); |
@@ -258,7 +178,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | |||
258 | } | 178 | } |
259 | } | 179 | } |
260 | 180 | ||
261 | dev_priv->ring.virtual_start = dev_priv->ring.map.handle; | 181 | dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; |
262 | 182 | ||
263 | dev_priv->cpp = init->cpp; | 183 | dev_priv->cpp = init->cpp; |
264 | dev_priv->back_offset = init->back_offset; | 184 | dev_priv->back_offset = init->back_offset; |
@@ -278,26 +198,29 @@ static int i915_dma_resume(struct drm_device * dev) | |||
278 | { | 198 | { |
279 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 199 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
280 | 200 | ||
201 | struct intel_ring_buffer *ring; | ||
281 | DRM_DEBUG_DRIVER("%s\n", __func__); | 202 | DRM_DEBUG_DRIVER("%s\n", __func__); |
282 | 203 | ||
283 | if (dev_priv->ring.map.handle == NULL) { | 204 | ring = &dev_priv->render_ring; |
205 | |||
206 | if (ring->map.handle == NULL) { | ||
284 | DRM_ERROR("can not ioremap virtual address for" | 207 | DRM_ERROR("can not ioremap virtual address for" |
285 | " ring buffer\n"); | 208 | " ring buffer\n"); |
286 | return -ENOMEM; | 209 | return -ENOMEM; |
287 | } | 210 | } |
288 | 211 | ||
289 | /* Program Hardware Status Page */ | 212 | /* Program Hardware Status Page */ |
290 | if (!dev_priv->hw_status_page) { | 213 | if (!ring->status_page.page_addr) { |
291 | DRM_ERROR("Can not find hardware status page\n"); | 214 | DRM_ERROR("Can not find hardware status page\n"); |
292 | return -EINVAL; | 215 | return -EINVAL; |
293 | } | 216 | } |
294 | DRM_DEBUG_DRIVER("hw status page @ %p\n", | 217 | DRM_DEBUG_DRIVER("hw status page @ %p\n", |
295 | dev_priv->hw_status_page); | 218 | ring->status_page.page_addr); |
296 | 219 | if (ring->status_page.gfx_addr != 0) | |
297 | if (dev_priv->status_gfx_addr != 0) | 220 | ring->setup_status_page(dev, ring); |
298 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | ||
299 | else | 221 | else |
300 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | 222 | I915_WRITE(HWS_PGA, dev_priv->dma_status_page); |
223 | |||
301 | DRM_DEBUG_DRIVER("Enabled hardware status page\n"); | 224 | DRM_DEBUG_DRIVER("Enabled hardware status page\n"); |
302 | 225 | ||
303 | return 0; | 226 | return 0; |
@@ -407,9 +330,8 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) | |||
407 | { | 330 | { |
408 | drm_i915_private_t *dev_priv = dev->dev_private; | 331 | drm_i915_private_t *dev_priv = dev->dev_private; |
409 | int i; | 332 | int i; |
410 | RING_LOCALS; | ||
411 | 333 | ||
412 | if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) | 334 | if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) |
413 | return -EINVAL; | 335 | return -EINVAL; |
414 | 336 | ||
415 | BEGIN_LP_RING((dwords+1)&~1); | 337 | BEGIN_LP_RING((dwords+1)&~1); |
@@ -442,9 +364,7 @@ i915_emit_box(struct drm_device *dev, | |||
442 | struct drm_clip_rect *boxes, | 364 | struct drm_clip_rect *boxes, |
443 | int i, int DR1, int DR4) | 365 | int i, int DR1, int DR4) |
444 | { | 366 | { |
445 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
446 | struct drm_clip_rect box = boxes[i]; | 367 | struct drm_clip_rect box = boxes[i]; |
447 | RING_LOCALS; | ||
448 | 368 | ||
449 | if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { | 369 | if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { |
450 | DRM_ERROR("Bad box %d,%d..%d,%d\n", | 370 | DRM_ERROR("Bad box %d,%d..%d,%d\n", |
@@ -481,7 +401,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
481 | { | 401 | { |
482 | drm_i915_private_t *dev_priv = dev->dev_private; | 402 | drm_i915_private_t *dev_priv = dev->dev_private; |
483 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 403 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
484 | RING_LOCALS; | ||
485 | 404 | ||
486 | dev_priv->counter++; | 405 | dev_priv->counter++; |
487 | if (dev_priv->counter > 0x7FFFFFFFUL) | 406 | if (dev_priv->counter > 0x7FFFFFFFUL) |
@@ -535,10 +454,8 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
535 | drm_i915_batchbuffer_t * batch, | 454 | drm_i915_batchbuffer_t * batch, |
536 | struct drm_clip_rect *cliprects) | 455 | struct drm_clip_rect *cliprects) |
537 | { | 456 | { |
538 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
539 | int nbox = batch->num_cliprects; | 457 | int nbox = batch->num_cliprects; |
540 | int i = 0, count; | 458 | int i = 0, count; |
541 | RING_LOCALS; | ||
542 | 459 | ||
543 | if ((batch->start | batch->used) & 0x7) { | 460 | if ((batch->start | batch->used) & 0x7) { |
544 | DRM_ERROR("alignment"); | 461 | DRM_ERROR("alignment"); |
@@ -587,7 +504,6 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
587 | drm_i915_private_t *dev_priv = dev->dev_private; | 504 | drm_i915_private_t *dev_priv = dev->dev_private; |
588 | struct drm_i915_master_private *master_priv = | 505 | struct drm_i915_master_private *master_priv = |
589 | dev->primary->master->driver_priv; | 506 | dev->primary->master->driver_priv; |
590 | RING_LOCALS; | ||
591 | 507 | ||
592 | if (!master_priv->sarea_priv) | 508 | if (!master_priv->sarea_priv) |
593 | return -EINVAL; | 509 | return -EINVAL; |
@@ -640,7 +556,8 @@ static int i915_quiescent(struct drm_device * dev) | |||
640 | drm_i915_private_t *dev_priv = dev->dev_private; | 556 | drm_i915_private_t *dev_priv = dev->dev_private; |
641 | 557 | ||
642 | i915_kernel_lost_context(dev); | 558 | i915_kernel_lost_context(dev); |
643 | return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__); | 559 | return intel_wait_ring_buffer(dev, &dev_priv->render_ring, |
560 | dev_priv->render_ring.size - 8); | ||
644 | } | 561 | } |
645 | 562 | ||
646 | static int i915_flush_ioctl(struct drm_device *dev, void *data, | 563 | static int i915_flush_ioctl(struct drm_device *dev, void *data, |
@@ -827,6 +744,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
827 | /* depends on GEM */ | 744 | /* depends on GEM */ |
828 | value = dev_priv->has_gem; | 745 | value = dev_priv->has_gem; |
829 | break; | 746 | break; |
747 | case I915_PARAM_HAS_BSD: | ||
748 | value = HAS_BSD(dev); | ||
749 | break; | ||
830 | default: | 750 | default: |
831 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 751 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
832 | param->param); | 752 | param->param); |
@@ -882,6 +802,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
882 | { | 802 | { |
883 | drm_i915_private_t *dev_priv = dev->dev_private; | 803 | drm_i915_private_t *dev_priv = dev->dev_private; |
884 | drm_i915_hws_addr_t *hws = data; | 804 | drm_i915_hws_addr_t *hws = data; |
805 | struct intel_ring_buffer *ring = &dev_priv->render_ring; | ||
885 | 806 | ||
886 | if (!I915_NEED_GFX_HWS(dev)) | 807 | if (!I915_NEED_GFX_HWS(dev)) |
887 | return -EINVAL; | 808 | return -EINVAL; |
@@ -898,7 +819,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
898 | 819 | ||
899 | DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); | 820 | DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); |
900 | 821 | ||
901 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | 822 | ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); |
902 | 823 | ||
903 | dev_priv->hws_map.offset = dev->agp->base + hws->addr; | 824 | dev_priv->hws_map.offset = dev->agp->base + hws->addr; |
904 | dev_priv->hws_map.size = 4*1024; | 825 | dev_priv->hws_map.size = 4*1024; |
@@ -909,19 +830,19 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
909 | drm_core_ioremap_wc(&dev_priv->hws_map, dev); | 830 | drm_core_ioremap_wc(&dev_priv->hws_map, dev); |
910 | if (dev_priv->hws_map.handle == NULL) { | 831 | if (dev_priv->hws_map.handle == NULL) { |
911 | i915_dma_cleanup(dev); | 832 | i915_dma_cleanup(dev); |
912 | dev_priv->status_gfx_addr = 0; | 833 | ring->status_page.gfx_addr = 0; |
913 | DRM_ERROR("can not ioremap virtual address for" | 834 | DRM_ERROR("can not ioremap virtual address for" |
914 | " G33 hw status page\n"); | 835 | " G33 hw status page\n"); |
915 | return -ENOMEM; | 836 | return -ENOMEM; |
916 | } | 837 | } |
917 | dev_priv->hw_status_page = dev_priv->hws_map.handle; | 838 | ring->status_page.page_addr = dev_priv->hws_map.handle; |
839 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
840 | I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); | ||
918 | 841 | ||
919 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
920 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | ||
921 | DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", | 842 | DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", |
922 | dev_priv->status_gfx_addr); | 843 | ring->status_page.gfx_addr); |
923 | DRM_DEBUG_DRIVER("load hws at %p\n", | 844 | DRM_DEBUG_DRIVER("load hws at %p\n", |
924 | dev_priv->hw_status_page); | 845 | ring->status_page.page_addr); |
925 | return 0; | 846 | return 0; |
926 | } | 847 | } |
927 | 848 | ||
@@ -1539,14 +1460,11 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
1539 | master->driver_priv = NULL; | 1460 | master->driver_priv = NULL; |
1540 | } | 1461 | } |
1541 | 1462 | ||
1542 | static void i915_get_mem_freq(struct drm_device *dev) | 1463 | static void i915_pineview_get_mem_freq(struct drm_device *dev) |
1543 | { | 1464 | { |
1544 | drm_i915_private_t *dev_priv = dev->dev_private; | 1465 | drm_i915_private_t *dev_priv = dev->dev_private; |
1545 | u32 tmp; | 1466 | u32 tmp; |
1546 | 1467 | ||
1547 | if (!IS_PINEVIEW(dev)) | ||
1548 | return; | ||
1549 | |||
1550 | tmp = I915_READ(CLKCFG); | 1468 | tmp = I915_READ(CLKCFG); |
1551 | 1469 | ||
1552 | switch (tmp & CLKCFG_FSB_MASK) { | 1470 | switch (tmp & CLKCFG_FSB_MASK) { |
@@ -1575,8 +1493,525 @@ static void i915_get_mem_freq(struct drm_device *dev) | |||
1575 | dev_priv->mem_freq = 800; | 1493 | dev_priv->mem_freq = 800; |
1576 | break; | 1494 | break; |
1577 | } | 1495 | } |
1496 | |||
1497 | /* detect pineview DDR3 setting */ | ||
1498 | tmp = I915_READ(CSHRDDR3CTL); | ||
1499 | dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0; | ||
1500 | } | ||
1501 | |||
1502 | static void i915_ironlake_get_mem_freq(struct drm_device *dev) | ||
1503 | { | ||
1504 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1505 | u16 ddrpll, csipll; | ||
1506 | |||
1507 | ddrpll = I915_READ16(DDRMPLL1); | ||
1508 | csipll = I915_READ16(CSIPLL0); | ||
1509 | |||
1510 | switch (ddrpll & 0xff) { | ||
1511 | case 0xc: | ||
1512 | dev_priv->mem_freq = 800; | ||
1513 | break; | ||
1514 | case 0x10: | ||
1515 | dev_priv->mem_freq = 1066; | ||
1516 | break; | ||
1517 | case 0x14: | ||
1518 | dev_priv->mem_freq = 1333; | ||
1519 | break; | ||
1520 | case 0x18: | ||
1521 | dev_priv->mem_freq = 1600; | ||
1522 | break; | ||
1523 | default: | ||
1524 | DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n", | ||
1525 | ddrpll & 0xff); | ||
1526 | dev_priv->mem_freq = 0; | ||
1527 | break; | ||
1528 | } | ||
1529 | |||
1530 | dev_priv->r_t = dev_priv->mem_freq; | ||
1531 | |||
1532 | switch (csipll & 0x3ff) { | ||
1533 | case 0x00c: | ||
1534 | dev_priv->fsb_freq = 3200; | ||
1535 | break; | ||
1536 | case 0x00e: | ||
1537 | dev_priv->fsb_freq = 3733; | ||
1538 | break; | ||
1539 | case 0x010: | ||
1540 | dev_priv->fsb_freq = 4266; | ||
1541 | break; | ||
1542 | case 0x012: | ||
1543 | dev_priv->fsb_freq = 4800; | ||
1544 | break; | ||
1545 | case 0x014: | ||
1546 | dev_priv->fsb_freq = 5333; | ||
1547 | break; | ||
1548 | case 0x016: | ||
1549 | dev_priv->fsb_freq = 5866; | ||
1550 | break; | ||
1551 | case 0x018: | ||
1552 | dev_priv->fsb_freq = 6400; | ||
1553 | break; | ||
1554 | default: | ||
1555 | DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n", | ||
1556 | csipll & 0x3ff); | ||
1557 | dev_priv->fsb_freq = 0; | ||
1558 | break; | ||
1559 | } | ||
1560 | |||
1561 | if (dev_priv->fsb_freq == 3200) { | ||
1562 | dev_priv->c_m = 0; | ||
1563 | } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) { | ||
1564 | dev_priv->c_m = 1; | ||
1565 | } else { | ||
1566 | dev_priv->c_m = 2; | ||
1567 | } | ||
1568 | } | ||
1569 | |||
1570 | struct v_table { | ||
1571 | u8 vid; | ||
1572 | unsigned long vd; /* in .1 mil */ | ||
1573 | unsigned long vm; /* in .1 mil */ | ||
1574 | u8 pvid; | ||
1575 | }; | ||
1576 | |||
1577 | static struct v_table v_table[] = { | ||
1578 | { 0, 16125, 15000, 0x7f, }, | ||
1579 | { 1, 16000, 14875, 0x7e, }, | ||
1580 | { 2, 15875, 14750, 0x7d, }, | ||
1581 | { 3, 15750, 14625, 0x7c, }, | ||
1582 | { 4, 15625, 14500, 0x7b, }, | ||
1583 | { 5, 15500, 14375, 0x7a, }, | ||
1584 | { 6, 15375, 14250, 0x79, }, | ||
1585 | { 7, 15250, 14125, 0x78, }, | ||
1586 | { 8, 15125, 14000, 0x77, }, | ||
1587 | { 9, 15000, 13875, 0x76, }, | ||
1588 | { 10, 14875, 13750, 0x75, }, | ||
1589 | { 11, 14750, 13625, 0x74, }, | ||
1590 | { 12, 14625, 13500, 0x73, }, | ||
1591 | { 13, 14500, 13375, 0x72, }, | ||
1592 | { 14, 14375, 13250, 0x71, }, | ||
1593 | { 15, 14250, 13125, 0x70, }, | ||
1594 | { 16, 14125, 13000, 0x6f, }, | ||
1595 | { 17, 14000, 12875, 0x6e, }, | ||
1596 | { 18, 13875, 12750, 0x6d, }, | ||
1597 | { 19, 13750, 12625, 0x6c, }, | ||
1598 | { 20, 13625, 12500, 0x6b, }, | ||
1599 | { 21, 13500, 12375, 0x6a, }, | ||
1600 | { 22, 13375, 12250, 0x69, }, | ||
1601 | { 23, 13250, 12125, 0x68, }, | ||
1602 | { 24, 13125, 12000, 0x67, }, | ||
1603 | { 25, 13000, 11875, 0x66, }, | ||
1604 | { 26, 12875, 11750, 0x65, }, | ||
1605 | { 27, 12750, 11625, 0x64, }, | ||
1606 | { 28, 12625, 11500, 0x63, }, | ||
1607 | { 29, 12500, 11375, 0x62, }, | ||
1608 | { 30, 12375, 11250, 0x61, }, | ||
1609 | { 31, 12250, 11125, 0x60, }, | ||
1610 | { 32, 12125, 11000, 0x5f, }, | ||
1611 | { 33, 12000, 10875, 0x5e, }, | ||
1612 | { 34, 11875, 10750, 0x5d, }, | ||
1613 | { 35, 11750, 10625, 0x5c, }, | ||
1614 | { 36, 11625, 10500, 0x5b, }, | ||
1615 | { 37, 11500, 10375, 0x5a, }, | ||
1616 | { 38, 11375, 10250, 0x59, }, | ||
1617 | { 39, 11250, 10125, 0x58, }, | ||
1618 | { 40, 11125, 10000, 0x57, }, | ||
1619 | { 41, 11000, 9875, 0x56, }, | ||
1620 | { 42, 10875, 9750, 0x55, }, | ||
1621 | { 43, 10750, 9625, 0x54, }, | ||
1622 | { 44, 10625, 9500, 0x53, }, | ||
1623 | { 45, 10500, 9375, 0x52, }, | ||
1624 | { 46, 10375, 9250, 0x51, }, | ||
1625 | { 47, 10250, 9125, 0x50, }, | ||
1626 | { 48, 10125, 9000, 0x4f, }, | ||
1627 | { 49, 10000, 8875, 0x4e, }, | ||
1628 | { 50, 9875, 8750, 0x4d, }, | ||
1629 | { 51, 9750, 8625, 0x4c, }, | ||
1630 | { 52, 9625, 8500, 0x4b, }, | ||
1631 | { 53, 9500, 8375, 0x4a, }, | ||
1632 | { 54, 9375, 8250, 0x49, }, | ||
1633 | { 55, 9250, 8125, 0x48, }, | ||
1634 | { 56, 9125, 8000, 0x47, }, | ||
1635 | { 57, 9000, 7875, 0x46, }, | ||
1636 | { 58, 8875, 7750, 0x45, }, | ||
1637 | { 59, 8750, 7625, 0x44, }, | ||
1638 | { 60, 8625, 7500, 0x43, }, | ||
1639 | { 61, 8500, 7375, 0x42, }, | ||
1640 | { 62, 8375, 7250, 0x41, }, | ||
1641 | { 63, 8250, 7125, 0x40, }, | ||
1642 | { 64, 8125, 7000, 0x3f, }, | ||
1643 | { 65, 8000, 6875, 0x3e, }, | ||
1644 | { 66, 7875, 6750, 0x3d, }, | ||
1645 | { 67, 7750, 6625, 0x3c, }, | ||
1646 | { 68, 7625, 6500, 0x3b, }, | ||
1647 | { 69, 7500, 6375, 0x3a, }, | ||
1648 | { 70, 7375, 6250, 0x39, }, | ||
1649 | { 71, 7250, 6125, 0x38, }, | ||
1650 | { 72, 7125, 6000, 0x37, }, | ||
1651 | { 73, 7000, 5875, 0x36, }, | ||
1652 | { 74, 6875, 5750, 0x35, }, | ||
1653 | { 75, 6750, 5625, 0x34, }, | ||
1654 | { 76, 6625, 5500, 0x33, }, | ||
1655 | { 77, 6500, 5375, 0x32, }, | ||
1656 | { 78, 6375, 5250, 0x31, }, | ||
1657 | { 79, 6250, 5125, 0x30, }, | ||
1658 | { 80, 6125, 5000, 0x2f, }, | ||
1659 | { 81, 6000, 4875, 0x2e, }, | ||
1660 | { 82, 5875, 4750, 0x2d, }, | ||
1661 | { 83, 5750, 4625, 0x2c, }, | ||
1662 | { 84, 5625, 4500, 0x2b, }, | ||
1663 | { 85, 5500, 4375, 0x2a, }, | ||
1664 | { 86, 5375, 4250, 0x29, }, | ||
1665 | { 87, 5250, 4125, 0x28, }, | ||
1666 | { 88, 5125, 4000, 0x27, }, | ||
1667 | { 89, 5000, 3875, 0x26, }, | ||
1668 | { 90, 4875, 3750, 0x25, }, | ||
1669 | { 91, 4750, 3625, 0x24, }, | ||
1670 | { 92, 4625, 3500, 0x23, }, | ||
1671 | { 93, 4500, 3375, 0x22, }, | ||
1672 | { 94, 4375, 3250, 0x21, }, | ||
1673 | { 95, 4250, 3125, 0x20, }, | ||
1674 | { 96, 4125, 3000, 0x1f, }, | ||
1675 | { 97, 4125, 3000, 0x1e, }, | ||
1676 | { 98, 4125, 3000, 0x1d, }, | ||
1677 | { 99, 4125, 3000, 0x1c, }, | ||
1678 | { 100, 4125, 3000, 0x1b, }, | ||
1679 | { 101, 4125, 3000, 0x1a, }, | ||
1680 | { 102, 4125, 3000, 0x19, }, | ||
1681 | { 103, 4125, 3000, 0x18, }, | ||
1682 | { 104, 4125, 3000, 0x17, }, | ||
1683 | { 105, 4125, 3000, 0x16, }, | ||
1684 | { 106, 4125, 3000, 0x15, }, | ||
1685 | { 107, 4125, 3000, 0x14, }, | ||
1686 | { 108, 4125, 3000, 0x13, }, | ||
1687 | { 109, 4125, 3000, 0x12, }, | ||
1688 | { 110, 4125, 3000, 0x11, }, | ||
1689 | { 111, 4125, 3000, 0x10, }, | ||
1690 | { 112, 4125, 3000, 0x0f, }, | ||
1691 | { 113, 4125, 3000, 0x0e, }, | ||
1692 | { 114, 4125, 3000, 0x0d, }, | ||
1693 | { 115, 4125, 3000, 0x0c, }, | ||
1694 | { 116, 4125, 3000, 0x0b, }, | ||
1695 | { 117, 4125, 3000, 0x0a, }, | ||
1696 | { 118, 4125, 3000, 0x09, }, | ||
1697 | { 119, 4125, 3000, 0x08, }, | ||
1698 | { 120, 1125, 0, 0x07, }, | ||
1699 | { 121, 1000, 0, 0x06, }, | ||
1700 | { 122, 875, 0, 0x05, }, | ||
1701 | { 123, 750, 0, 0x04, }, | ||
1702 | { 124, 625, 0, 0x03, }, | ||
1703 | { 125, 500, 0, 0x02, }, | ||
1704 | { 126, 375, 0, 0x01, }, | ||
1705 | { 127, 0, 0, 0x00, }, | ||
1706 | }; | ||
1707 | |||
1708 | struct cparams { | ||
1709 | int i; | ||
1710 | int t; | ||
1711 | int m; | ||
1712 | int c; | ||
1713 | }; | ||
1714 | |||
1715 | static struct cparams cparams[] = { | ||
1716 | { 1, 1333, 301, 28664 }, | ||
1717 | { 1, 1066, 294, 24460 }, | ||
1718 | { 1, 800, 294, 25192 }, | ||
1719 | { 0, 1333, 276, 27605 }, | ||
1720 | { 0, 1066, 276, 27605 }, | ||
1721 | { 0, 800, 231, 23784 }, | ||
1722 | }; | ||
1723 | |||
1724 | unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | ||
1725 | { | ||
1726 | u64 total_count, diff, ret; | ||
1727 | u32 count1, count2, count3, m = 0, c = 0; | ||
1728 | unsigned long now = jiffies_to_msecs(jiffies), diff1; | ||
1729 | int i; | ||
1730 | |||
1731 | diff1 = now - dev_priv->last_time1; | ||
1732 | |||
1733 | count1 = I915_READ(DMIEC); | ||
1734 | count2 = I915_READ(DDREC); | ||
1735 | count3 = I915_READ(CSIEC); | ||
1736 | |||
1737 | total_count = count1 + count2 + count3; | ||
1738 | |||
1739 | /* FIXME: handle per-counter overflow */ | ||
1740 | if (total_count < dev_priv->last_count1) { | ||
1741 | diff = ~0UL - dev_priv->last_count1; | ||
1742 | diff += total_count; | ||
1743 | } else { | ||
1744 | diff = total_count - dev_priv->last_count1; | ||
1745 | } | ||
1746 | |||
1747 | for (i = 0; i < ARRAY_SIZE(cparams); i++) { | ||
1748 | if (cparams[i].i == dev_priv->c_m && | ||
1749 | cparams[i].t == dev_priv->r_t) { | ||
1750 | m = cparams[i].m; | ||
1751 | c = cparams[i].c; | ||
1752 | break; | ||
1753 | } | ||
1754 | } | ||
1755 | |||
1756 | div_u64(diff, diff1); | ||
1757 | ret = ((m * diff) + c); | ||
1758 | div_u64(ret, 10); | ||
1759 | |||
1760 | dev_priv->last_count1 = total_count; | ||
1761 | dev_priv->last_time1 = now; | ||
1762 | |||
1763 | return ret; | ||
1764 | } | ||
1765 | |||
1766 | unsigned long i915_mch_val(struct drm_i915_private *dev_priv) | ||
1767 | { | ||
1768 | unsigned long m, x, b; | ||
1769 | u32 tsfs; | ||
1770 | |||
1771 | tsfs = I915_READ(TSFS); | ||
1772 | |||
1773 | m = ((tsfs & TSFS_SLOPE_MASK) >> TSFS_SLOPE_SHIFT); | ||
1774 | x = I915_READ8(TR1); | ||
1775 | |||
1776 | b = tsfs & TSFS_INTR_MASK; | ||
1777 | |||
1778 | return ((m * x) / 127) - b; | ||
1779 | } | ||
1780 | |||
1781 | static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) | ||
1782 | { | ||
1783 | unsigned long val = 0; | ||
1784 | int i; | ||
1785 | |||
1786 | for (i = 0; i < ARRAY_SIZE(v_table); i++) { | ||
1787 | if (v_table[i].pvid == pxvid) { | ||
1788 | if (IS_MOBILE(dev_priv->dev)) | ||
1789 | val = v_table[i].vm; | ||
1790 | else | ||
1791 | val = v_table[i].vd; | ||
1792 | } | ||
1793 | } | ||
1794 | |||
1795 | return val; | ||
1796 | } | ||
1797 | |||
1798 | void i915_update_gfx_val(struct drm_i915_private *dev_priv) | ||
1799 | { | ||
1800 | struct timespec now, diff1; | ||
1801 | u64 diff; | ||
1802 | unsigned long diffms; | ||
1803 | u32 count; | ||
1804 | |||
1805 | getrawmonotonic(&now); | ||
1806 | diff1 = timespec_sub(now, dev_priv->last_time2); | ||
1807 | |||
1808 | /* Don't divide by 0 */ | ||
1809 | diffms = diff1.tv_sec * 1000 + diff1.tv_nsec / 1000000; | ||
1810 | if (!diffms) | ||
1811 | return; | ||
1812 | |||
1813 | count = I915_READ(GFXEC); | ||
1814 | |||
1815 | if (count < dev_priv->last_count2) { | ||
1816 | diff = ~0UL - dev_priv->last_count2; | ||
1817 | diff += count; | ||
1818 | } else { | ||
1819 | diff = count - dev_priv->last_count2; | ||
1820 | } | ||
1821 | |||
1822 | dev_priv->last_count2 = count; | ||
1823 | dev_priv->last_time2 = now; | ||
1824 | |||
1825 | /* More magic constants... */ | ||
1826 | diff = diff * 1181; | ||
1827 | div_u64(diff, diffms * 10); | ||
1828 | dev_priv->gfx_power = diff; | ||
1578 | } | 1829 | } |
1579 | 1830 | ||
1831 | unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) | ||
1832 | { | ||
1833 | unsigned long t, corr, state1, corr2, state2; | ||
1834 | u32 pxvid, ext_v; | ||
1835 | |||
1836 | pxvid = I915_READ(PXVFREQ_BASE + (dev_priv->cur_delay * 4)); | ||
1837 | pxvid = (pxvid >> 24) & 0x7f; | ||
1838 | ext_v = pvid_to_extvid(dev_priv, pxvid); | ||
1839 | |||
1840 | state1 = ext_v; | ||
1841 | |||
1842 | t = i915_mch_val(dev_priv); | ||
1843 | |||
1844 | /* Revel in the empirically derived constants */ | ||
1845 | |||
1846 | /* Correction factor in 1/100000 units */ | ||
1847 | if (t > 80) | ||
1848 | corr = ((t * 2349) + 135940); | ||
1849 | else if (t >= 50) | ||
1850 | corr = ((t * 964) + 29317); | ||
1851 | else /* < 50 */ | ||
1852 | corr = ((t * 301) + 1004); | ||
1853 | |||
1854 | corr = corr * ((150142 * state1) / 10000 - 78642); | ||
1855 | corr /= 100000; | ||
1856 | corr2 = (corr * dev_priv->corr); | ||
1857 | |||
1858 | state2 = (corr2 * state1) / 10000; | ||
1859 | state2 /= 100; /* convert to mW */ | ||
1860 | |||
1861 | i915_update_gfx_val(dev_priv); | ||
1862 | |||
1863 | return dev_priv->gfx_power + state2; | ||
1864 | } | ||
1865 | |||
1866 | /* Global for IPS driver to get at the current i915 device */ | ||
1867 | static struct drm_i915_private *i915_mch_dev; | ||
1868 | /* | ||
1869 | * Lock protecting IPS related data structures | ||
1870 | * - i915_mch_dev | ||
1871 | * - dev_priv->max_delay | ||
1872 | * - dev_priv->min_delay | ||
1873 | * - dev_priv->fmax | ||
1874 | * - dev_priv->gpu_busy | ||
1875 | */ | ||
1876 | DEFINE_SPINLOCK(mchdev_lock); | ||
1877 | |||
1878 | /** | ||
1879 | * i915_read_mch_val - return value for IPS use | ||
1880 | * | ||
1881 | * Calculate and return a value for the IPS driver to use when deciding whether | ||
1882 | * we have thermal and power headroom to increase CPU or GPU power budget. | ||
1883 | */ | ||
1884 | unsigned long i915_read_mch_val(void) | ||
1885 | { | ||
1886 | struct drm_i915_private *dev_priv; | ||
1887 | unsigned long chipset_val, graphics_val, ret = 0; | ||
1888 | |||
1889 | spin_lock(&mchdev_lock); | ||
1890 | if (!i915_mch_dev) | ||
1891 | goto out_unlock; | ||
1892 | dev_priv = i915_mch_dev; | ||
1893 | |||
1894 | chipset_val = i915_chipset_val(dev_priv); | ||
1895 | graphics_val = i915_gfx_val(dev_priv); | ||
1896 | |||
1897 | ret = chipset_val + graphics_val; | ||
1898 | |||
1899 | out_unlock: | ||
1900 | spin_unlock(&mchdev_lock); | ||
1901 | |||
1902 | return ret; | ||
1903 | } | ||
1904 | EXPORT_SYMBOL_GPL(i915_read_mch_val); | ||
1905 | |||
1906 | /** | ||
1907 | * i915_gpu_raise - raise GPU frequency limit | ||
1908 | * | ||
1909 | * Raise the limit; IPS indicates we have thermal headroom. | ||
1910 | */ | ||
1911 | bool i915_gpu_raise(void) | ||
1912 | { | ||
1913 | struct drm_i915_private *dev_priv; | ||
1914 | bool ret = true; | ||
1915 | |||
1916 | spin_lock(&mchdev_lock); | ||
1917 | if (!i915_mch_dev) { | ||
1918 | ret = false; | ||
1919 | goto out_unlock; | ||
1920 | } | ||
1921 | dev_priv = i915_mch_dev; | ||
1922 | |||
1923 | if (dev_priv->max_delay > dev_priv->fmax) | ||
1924 | dev_priv->max_delay--; | ||
1925 | |||
1926 | out_unlock: | ||
1927 | spin_unlock(&mchdev_lock); | ||
1928 | |||
1929 | return ret; | ||
1930 | } | ||
1931 | EXPORT_SYMBOL_GPL(i915_gpu_raise); | ||
1932 | |||
1933 | /** | ||
1934 | * i915_gpu_lower - lower GPU frequency limit | ||
1935 | * | ||
1936 | * IPS indicates we're close to a thermal limit, so throttle back the GPU | ||
1937 | * frequency maximum. | ||
1938 | */ | ||
1939 | bool i915_gpu_lower(void) | ||
1940 | { | ||
1941 | struct drm_i915_private *dev_priv; | ||
1942 | bool ret = true; | ||
1943 | |||
1944 | spin_lock(&mchdev_lock); | ||
1945 | if (!i915_mch_dev) { | ||
1946 | ret = false; | ||
1947 | goto out_unlock; | ||
1948 | } | ||
1949 | dev_priv = i915_mch_dev; | ||
1950 | |||
1951 | if (dev_priv->max_delay < dev_priv->min_delay) | ||
1952 | dev_priv->max_delay++; | ||
1953 | |||
1954 | out_unlock: | ||
1955 | spin_unlock(&mchdev_lock); | ||
1956 | |||
1957 | return ret; | ||
1958 | } | ||
1959 | EXPORT_SYMBOL_GPL(i915_gpu_lower); | ||
1960 | |||
1961 | /** | ||
1962 | * i915_gpu_busy - indicate GPU business to IPS | ||
1963 | * | ||
1964 | * Tell the IPS driver whether or not the GPU is busy. | ||
1965 | */ | ||
1966 | bool i915_gpu_busy(void) | ||
1967 | { | ||
1968 | struct drm_i915_private *dev_priv; | ||
1969 | bool ret = false; | ||
1970 | |||
1971 | spin_lock(&mchdev_lock); | ||
1972 | if (!i915_mch_dev) | ||
1973 | goto out_unlock; | ||
1974 | dev_priv = i915_mch_dev; | ||
1975 | |||
1976 | ret = dev_priv->busy; | ||
1977 | |||
1978 | out_unlock: | ||
1979 | spin_unlock(&mchdev_lock); | ||
1980 | |||
1981 | return ret; | ||
1982 | } | ||
1983 | EXPORT_SYMBOL_GPL(i915_gpu_busy); | ||
1984 | |||
1985 | /** | ||
1986 | * i915_gpu_turbo_disable - disable graphics turbo | ||
1987 | * | ||
1988 | * Disable graphics turbo by resetting the max frequency and setting the | ||
1989 | * current frequency to the default. | ||
1990 | */ | ||
1991 | bool i915_gpu_turbo_disable(void) | ||
1992 | { | ||
1993 | struct drm_i915_private *dev_priv; | ||
1994 | bool ret = true; | ||
1995 | |||
1996 | spin_lock(&mchdev_lock); | ||
1997 | if (!i915_mch_dev) { | ||
1998 | ret = false; | ||
1999 | goto out_unlock; | ||
2000 | } | ||
2001 | dev_priv = i915_mch_dev; | ||
2002 | |||
2003 | dev_priv->max_delay = dev_priv->fstart; | ||
2004 | |||
2005 | if (!ironlake_set_drps(dev_priv->dev, dev_priv->fstart)) | ||
2006 | ret = false; | ||
2007 | |||
2008 | out_unlock: | ||
2009 | spin_unlock(&mchdev_lock); | ||
2010 | |||
2011 | return ret; | ||
2012 | } | ||
2013 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | ||
2014 | |||
1580 | /** | 2015 | /** |
1581 | * i915_driver_load - setup chip and create an initial config | 2016 | * i915_driver_load - setup chip and create an initial config |
1582 | * @dev: DRM device | 2017 | * @dev: DRM device |
@@ -1594,7 +2029,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1594 | resource_size_t base, size; | 2029 | resource_size_t base, size; |
1595 | int ret = 0, mmio_bar; | 2030 | int ret = 0, mmio_bar; |
1596 | uint32_t agp_size, prealloc_size, prealloc_start; | 2031 | uint32_t agp_size, prealloc_size, prealloc_start; |
1597 | |||
1598 | /* i915 has 4 more counters */ | 2032 | /* i915 has 4 more counters */ |
1599 | dev->counters += 4; | 2033 | dev->counters += 4; |
1600 | dev->types[6] = _DRM_STAT_IRQ; | 2034 | dev->types[6] = _DRM_STAT_IRQ; |
@@ -1672,6 +2106,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1672 | dev_priv->has_gem = 0; | 2106 | dev_priv->has_gem = 0; |
1673 | } | 2107 | } |
1674 | 2108 | ||
2109 | if (dev_priv->has_gem == 0 && | ||
2110 | drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
2111 | DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); | ||
2112 | ret = -ENODEV; | ||
2113 | goto out_iomapfree; | ||
2114 | } | ||
2115 | |||
1675 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 2116 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1676 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 2117 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1677 | if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { | 2118 | if (IS_G4X(dev) || IS_IRONLAKE(dev) || IS_GEN6(dev)) { |
@@ -1691,7 +2132,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1691 | goto out_workqueue_free; | 2132 | goto out_workqueue_free; |
1692 | } | 2133 | } |
1693 | 2134 | ||
1694 | i915_get_mem_freq(dev); | 2135 | if (IS_PINEVIEW(dev)) |
2136 | i915_pineview_get_mem_freq(dev); | ||
2137 | else if (IS_IRONLAKE(dev)) | ||
2138 | i915_ironlake_get_mem_freq(dev); | ||
1695 | 2139 | ||
1696 | /* On the 945G/GM, the chipset reports the MSI capability on the | 2140 | /* On the 945G/GM, the chipset reports the MSI capability on the |
1697 | * integrated graphics even though the support isn't actually there | 2141 | * integrated graphics even though the support isn't actually there |
@@ -1709,7 +2153,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1709 | 2153 | ||
1710 | spin_lock_init(&dev_priv->user_irq_lock); | 2154 | spin_lock_init(&dev_priv->user_irq_lock); |
1711 | spin_lock_init(&dev_priv->error_lock); | 2155 | spin_lock_init(&dev_priv->error_lock); |
1712 | dev_priv->user_irq_refcount = 0; | ||
1713 | dev_priv->trace_irq_seqno = 0; | 2156 | dev_priv->trace_irq_seqno = 0; |
1714 | 2157 | ||
1715 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 2158 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
@@ -1738,6 +2181,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1738 | 2181 | ||
1739 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, | 2182 | setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, |
1740 | (unsigned long) dev); | 2183 | (unsigned long) dev); |
2184 | |||
2185 | spin_lock(&mchdev_lock); | ||
2186 | i915_mch_dev = dev_priv; | ||
2187 | dev_priv->mchdev_lock = &mchdev_lock; | ||
2188 | spin_unlock(&mchdev_lock); | ||
2189 | |||
1741 | return 0; | 2190 | return 0; |
1742 | 2191 | ||
1743 | out_workqueue_free: | 2192 | out_workqueue_free: |
@@ -1759,6 +2208,10 @@ int i915_driver_unload(struct drm_device *dev) | |||
1759 | 2208 | ||
1760 | i915_destroy_error_state(dev); | 2209 | i915_destroy_error_state(dev); |
1761 | 2210 | ||
2211 | spin_lock(&mchdev_lock); | ||
2212 | i915_mch_dev = NULL; | ||
2213 | spin_unlock(&mchdev_lock); | ||
2214 | |||
1762 | destroy_workqueue(dev_priv->wq); | 2215 | destroy_workqueue(dev_priv->wq); |
1763 | del_timer_sync(&dev_priv->hangcheck_timer); | 2216 | del_timer_sync(&dev_priv->hangcheck_timer); |
1764 | 2217 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5c51e45ab68d..423dc90c1e20 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -60,95 +60,95 @@ extern int intel_agp_enabled; | |||
60 | .subdevice = PCI_ANY_ID, \ | 60 | .subdevice = PCI_ANY_ID, \ |
61 | .driver_data = (unsigned long) info } | 61 | .driver_data = (unsigned long) info } |
62 | 62 | ||
63 | const static struct intel_device_info intel_i830_info = { | 63 | static const struct intel_device_info intel_i830_info = { |
64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, | 64 | .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | const static struct intel_device_info intel_845g_info = { | 67 | static const struct intel_device_info intel_845g_info = { |
68 | .is_i8xx = 1, | 68 | .is_i8xx = 1, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | const static struct intel_device_info intel_i85x_info = { | 71 | static const struct intel_device_info intel_i85x_info = { |
72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, | 72 | .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, |
73 | .cursor_needs_physical = 1, | 73 | .cursor_needs_physical = 1, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | const static struct intel_device_info intel_i865g_info = { | 76 | static const struct intel_device_info intel_i865g_info = { |
77 | .is_i8xx = 1, | 77 | .is_i8xx = 1, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | const static struct intel_device_info intel_i915g_info = { | 80 | static const struct intel_device_info intel_i915g_info = { |
81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, | 81 | .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1, |
82 | }; | 82 | }; |
83 | const static struct intel_device_info intel_i915gm_info = { | 83 | static const struct intel_device_info intel_i915gm_info = { |
84 | .is_i9xx = 1, .is_mobile = 1, | 84 | .is_i9xx = 1, .is_mobile = 1, |
85 | .cursor_needs_physical = 1, | 85 | .cursor_needs_physical = 1, |
86 | }; | 86 | }; |
87 | const static struct intel_device_info intel_i945g_info = { | 87 | static const struct intel_device_info intel_i945g_info = { |
88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, | 88 | .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1, |
89 | }; | 89 | }; |
90 | const static struct intel_device_info intel_i945gm_info = { | 90 | static const struct intel_device_info intel_i945gm_info = { |
91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, | 91 | .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, |
92 | .has_hotplug = 1, .cursor_needs_physical = 1, | 92 | .has_hotplug = 1, .cursor_needs_physical = 1, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | const static struct intel_device_info intel_i965g_info = { | 95 | static const struct intel_device_info intel_i965g_info = { |
96 | .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, | 96 | .is_i965g = 1, .is_i9xx = 1, .has_hotplug = 1, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | const static struct intel_device_info intel_i965gm_info = { | 99 | static const struct intel_device_info intel_i965gm_info = { |
100 | .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, | 100 | .is_i965g = 1, .is_mobile = 1, .is_i965gm = 1, .is_i9xx = 1, |
101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, | 101 | .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, |
102 | .has_hotplug = 1, | 102 | .has_hotplug = 1, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | const static struct intel_device_info intel_g33_info = { | 105 | static const struct intel_device_info intel_g33_info = { |
106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 106 | .is_g33 = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
107 | .has_hotplug = 1, | 107 | .has_hotplug = 1, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | const static struct intel_device_info intel_g45_info = { | 110 | static const struct intel_device_info intel_g45_info = { |
111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 111 | .is_i965g = 1, .is_g4x = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
112 | .has_pipe_cxsr = 1, | 112 | .has_pipe_cxsr = 1, |
113 | .has_hotplug = 1, | 113 | .has_hotplug = 1, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | const static struct intel_device_info intel_gm45_info = { | 116 | static const struct intel_device_info intel_gm45_info = { |
117 | .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, | 117 | .is_i965g = 1, .is_mobile = 1, .is_g4x = 1, .is_i9xx = 1, |
118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, | 118 | .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, |
119 | .has_pipe_cxsr = 1, | 119 | .has_pipe_cxsr = 1, |
120 | .has_hotplug = 1, | 120 | .has_hotplug = 1, |
121 | }; | 121 | }; |
122 | 122 | ||
123 | const static struct intel_device_info intel_pineview_info = { | 123 | static const struct intel_device_info intel_pineview_info = { |
124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 124 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
125 | .need_gfx_hws = 1, | 125 | .need_gfx_hws = 1, |
126 | .has_hotplug = 1, | 126 | .has_hotplug = 1, |
127 | }; | 127 | }; |
128 | 128 | ||
129 | const static struct intel_device_info intel_ironlake_d_info = { | 129 | static const struct intel_device_info intel_ironlake_d_info = { |
130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 130 | .is_ironlake = 1, .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
131 | .has_pipe_cxsr = 1, | 131 | .has_pipe_cxsr = 1, |
132 | .has_hotplug = 1, | 132 | .has_hotplug = 1, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | const static struct intel_device_info intel_ironlake_m_info = { | 135 | static const struct intel_device_info intel_ironlake_m_info = { |
136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, | 136 | .is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1, |
137 | .need_gfx_hws = 1, .has_rc6 = 1, | 137 | .need_gfx_hws = 1, .has_rc6 = 1, |
138 | .has_hotplug = 1, | 138 | .has_hotplug = 1, |
139 | }; | 139 | }; |
140 | 140 | ||
141 | const static struct intel_device_info intel_sandybridge_d_info = { | 141 | static const struct intel_device_info intel_sandybridge_d_info = { |
142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 142 | .is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
143 | .has_hotplug = 1, .is_gen6 = 1, | 143 | .has_hotplug = 1, .is_gen6 = 1, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | const static struct intel_device_info intel_sandybridge_m_info = { | 146 | static const struct intel_device_info intel_sandybridge_m_info = { |
147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, | 147 | .is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, |
148 | .has_hotplug = 1, .is_gen6 = 1, | 148 | .has_hotplug = 1, .is_gen6 = 1, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | const static struct pci_device_id pciidlist[] = { | 151 | static const struct pci_device_id pciidlist[] = { |
152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), | 152 | INTEL_VGA_DEVICE(0x3577, &intel_i830_info), |
153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), | 153 | INTEL_VGA_DEVICE(0x2562, &intel_845g_info), |
154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), | 154 | INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), |
@@ -340,7 +340,7 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
340 | /* | 340 | /* |
341 | * Clear request list | 341 | * Clear request list |
342 | */ | 342 | */ |
343 | i915_gem_retire_requests(dev); | 343 | i915_gem_retire_requests(dev, &dev_priv->render_ring); |
344 | 344 | ||
345 | if (need_display) | 345 | if (need_display) |
346 | i915_save_display(dev); | 346 | i915_save_display(dev); |
@@ -370,6 +370,7 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
370 | } | 370 | } |
371 | } else { | 371 | } else { |
372 | DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); | 372 | DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); |
373 | mutex_unlock(&dev->struct_mutex); | ||
373 | return -ENODEV; | 374 | return -ENODEV; |
374 | } | 375 | } |
375 | 376 | ||
@@ -388,33 +389,10 @@ int i965_reset(struct drm_device *dev, u8 flags) | |||
388 | * switched away). | 389 | * switched away). |
389 | */ | 390 | */ |
390 | if (drm_core_check_feature(dev, DRIVER_MODESET) || | 391 | if (drm_core_check_feature(dev, DRIVER_MODESET) || |
391 | !dev_priv->mm.suspended) { | 392 | !dev_priv->mm.suspended) { |
392 | drm_i915_ring_buffer_t *ring = &dev_priv->ring; | 393 | struct intel_ring_buffer *ring = &dev_priv->render_ring; |
393 | struct drm_gem_object *obj = ring->ring_obj; | ||
394 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
395 | dev_priv->mm.suspended = 0; | 394 | dev_priv->mm.suspended = 0; |
396 | 395 | ring->init(dev, ring); | |
397 | /* Stop the ring if it's running. */ | ||
398 | I915_WRITE(PRB0_CTL, 0); | ||
399 | I915_WRITE(PRB0_TAIL, 0); | ||
400 | I915_WRITE(PRB0_HEAD, 0); | ||
401 | |||
402 | /* Initialize the ring. */ | ||
403 | I915_WRITE(PRB0_START, obj_priv->gtt_offset); | ||
404 | I915_WRITE(PRB0_CTL, | ||
405 | ((obj->size - 4096) & RING_NR_PAGES) | | ||
406 | RING_NO_REPORT | | ||
407 | RING_VALID); | ||
408 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
409 | i915_kernel_lost_context(dev); | ||
410 | else { | ||
411 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
412 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | ||
413 | ring->space = ring->head - (ring->tail + 8); | ||
414 | if (ring->space < 0) | ||
415 | ring->space += ring->Size; | ||
416 | } | ||
417 | |||
418 | mutex_unlock(&dev->struct_mutex); | 396 | mutex_unlock(&dev->struct_mutex); |
419 | drm_irq_uninstall(dev); | 397 | drm_irq_uninstall(dev); |
420 | drm_irq_install(dev); | 398 | drm_irq_install(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7f797ef1ab39..9ed8ecd95801 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "i915_reg.h" | 33 | #include "i915_reg.h" |
34 | #include "intel_bios.h" | 34 | #include "intel_bios.h" |
35 | #include "intel_ringbuffer.h" | ||
35 | #include <linux/io-mapping.h> | 36 | #include <linux/io-mapping.h> |
36 | 37 | ||
37 | /* General customization: | 38 | /* General customization: |
@@ -55,6 +56,8 @@ enum plane { | |||
55 | 56 | ||
56 | #define I915_NUM_PIPE 2 | 57 | #define I915_NUM_PIPE 2 |
57 | 58 | ||
59 | #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | ||
60 | |||
58 | /* Interface history: | 61 | /* Interface history: |
59 | * | 62 | * |
60 | * 1.1: Original. | 63 | * 1.1: Original. |
@@ -89,16 +92,6 @@ struct drm_i915_gem_phys_object { | |||
89 | struct drm_gem_object *cur_obj; | 92 | struct drm_gem_object *cur_obj; |
90 | }; | 93 | }; |
91 | 94 | ||
92 | typedef struct _drm_i915_ring_buffer { | ||
93 | unsigned long Size; | ||
94 | u8 *virtual_start; | ||
95 | int head; | ||
96 | int tail; | ||
97 | int space; | ||
98 | drm_local_map_t map; | ||
99 | struct drm_gem_object *ring_obj; | ||
100 | } drm_i915_ring_buffer_t; | ||
101 | |||
102 | struct mem_block { | 95 | struct mem_block { |
103 | struct mem_block *next; | 96 | struct mem_block *next; |
104 | struct mem_block *prev; | 97 | struct mem_block *prev; |
@@ -241,17 +234,15 @@ typedef struct drm_i915_private { | |||
241 | void __iomem *regs; | 234 | void __iomem *regs; |
242 | 235 | ||
243 | struct pci_dev *bridge_dev; | 236 | struct pci_dev *bridge_dev; |
244 | drm_i915_ring_buffer_t ring; | 237 | struct intel_ring_buffer render_ring; |
238 | struct intel_ring_buffer bsd_ring; | ||
245 | 239 | ||
246 | drm_dma_handle_t *status_page_dmah; | 240 | drm_dma_handle_t *status_page_dmah; |
247 | void *hw_status_page; | ||
248 | void *seqno_page; | 241 | void *seqno_page; |
249 | dma_addr_t dma_status_page; | 242 | dma_addr_t dma_status_page; |
250 | uint32_t counter; | 243 | uint32_t counter; |
251 | unsigned int status_gfx_addr; | ||
252 | unsigned int seqno_gfx_addr; | 244 | unsigned int seqno_gfx_addr; |
253 | drm_local_map_t hws_map; | 245 | drm_local_map_t hws_map; |
254 | struct drm_gem_object *hws_obj; | ||
255 | struct drm_gem_object *seqno_obj; | 246 | struct drm_gem_object *seqno_obj; |
256 | struct drm_gem_object *pwrctx; | 247 | struct drm_gem_object *pwrctx; |
257 | 248 | ||
@@ -267,8 +258,6 @@ typedef struct drm_i915_private { | |||
267 | atomic_t irq_received; | 258 | atomic_t irq_received; |
268 | /** Protects user_irq_refcount and irq_mask_reg */ | 259 | /** Protects user_irq_refcount and irq_mask_reg */ |
269 | spinlock_t user_irq_lock; | 260 | spinlock_t user_irq_lock; |
270 | /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ | ||
271 | int user_irq_refcount; | ||
272 | u32 trace_irq_seqno; | 261 | u32 trace_irq_seqno; |
273 | /** Cached value of IMR to avoid reads in updating the bitfield */ | 262 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
274 | u32 irq_mask_reg; | 263 | u32 irq_mask_reg; |
@@ -334,7 +323,7 @@ typedef struct drm_i915_private { | |||
334 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 323 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
335 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 324 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
336 | 325 | ||
337 | unsigned int fsb_freq, mem_freq; | 326 | unsigned int fsb_freq, mem_freq, is_ddr3; |
338 | 327 | ||
339 | spinlock_t error_lock; | 328 | spinlock_t error_lock; |
340 | struct drm_i915_error_state *first_error; | 329 | struct drm_i915_error_state *first_error; |
@@ -514,18 +503,7 @@ typedef struct drm_i915_private { | |||
514 | */ | 503 | */ |
515 | struct list_head shrink_list; | 504 | struct list_head shrink_list; |
516 | 505 | ||
517 | /** | ||
518 | * List of objects currently involved in rendering from the | ||
519 | * ringbuffer. | ||
520 | * | ||
521 | * Includes buffers having the contents of their GPU caches | ||
522 | * flushed, not necessarily primitives. last_rendering_seqno | ||
523 | * represents when the rendering involved will be completed. | ||
524 | * | ||
525 | * A reference is held on the buffer while on this list. | ||
526 | */ | ||
527 | spinlock_t active_list_lock; | 506 | spinlock_t active_list_lock; |
528 | struct list_head active_list; | ||
529 | 507 | ||
530 | /** | 508 | /** |
531 | * List of objects which are not in the ringbuffer but which | 509 | * List of objects which are not in the ringbuffer but which |
@@ -563,12 +541,6 @@ typedef struct drm_i915_private { | |||
563 | struct list_head fence_list; | 541 | struct list_head fence_list; |
564 | 542 | ||
565 | /** | 543 | /** |
566 | * List of breadcrumbs associated with GPU requests currently | ||
567 | * outstanding. | ||
568 | */ | ||
569 | struct list_head request_list; | ||
570 | |||
571 | /** | ||
572 | * We leave the user IRQ off as much as possible, | 544 | * We leave the user IRQ off as much as possible, |
573 | * but this means that requests will finish and never | 545 | * but this means that requests will finish and never |
574 | * be retired once the system goes idle. Set a timer to | 546 | * be retired once the system goes idle. Set a timer to |
@@ -644,6 +616,18 @@ typedef struct drm_i915_private { | |||
644 | u8 cur_delay; | 616 | u8 cur_delay; |
645 | u8 min_delay; | 617 | u8 min_delay; |
646 | u8 max_delay; | 618 | u8 max_delay; |
619 | u8 fmax; | ||
620 | u8 fstart; | ||
621 | |||
622 | u64 last_count1; | ||
623 | unsigned long last_time1; | ||
624 | u64 last_count2; | ||
625 | struct timespec last_time2; | ||
626 | unsigned long gfx_power; | ||
627 | int c_m; | ||
628 | int r_t; | ||
629 | u8 corr; | ||
630 | spinlock_t *mchdev_lock; | ||
647 | 631 | ||
648 | enum no_fbc_reason no_fbc_reason; | 632 | enum no_fbc_reason no_fbc_reason; |
649 | 633 | ||
@@ -671,19 +655,64 @@ struct drm_i915_gem_object { | |||
671 | * (has pending rendering), and is not set if it's on inactive (ready | 655 | * (has pending rendering), and is not set if it's on inactive (ready |
672 | * to be unbound). | 656 | * to be unbound). |
673 | */ | 657 | */ |
674 | int active; | 658 | unsigned int active : 1; |
675 | 659 | ||
676 | /** | 660 | /** |
677 | * This is set if the object has been written to since last bound | 661 | * This is set if the object has been written to since last bound |
678 | * to the GTT | 662 | * to the GTT |
679 | */ | 663 | */ |
680 | int dirty; | 664 | unsigned int dirty : 1; |
665 | |||
666 | /** | ||
667 | * Fence register bits (if any) for this object. Will be set | ||
668 | * as needed when mapped into the GTT. | ||
669 | * Protected by dev->struct_mutex. | ||
670 | * | ||
671 | * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) | ||
672 | */ | ||
673 | int fence_reg : 5; | ||
674 | |||
675 | /** | ||
676 | * Used for checking the object doesn't appear more than once | ||
677 | * in an execbuffer object list. | ||
678 | */ | ||
679 | unsigned int in_execbuffer : 1; | ||
680 | |||
681 | /** | ||
682 | * Advice: are the backing pages purgeable? | ||
683 | */ | ||
684 | unsigned int madv : 2; | ||
685 | |||
686 | /** | ||
687 | * Refcount for the pages array. With the current locking scheme, there | ||
688 | * are at most two concurrent users: Binding a bo to the gtt and | ||
689 | * pwrite/pread using physical addresses. So two bits for a maximum | ||
690 | * of two users are enough. | ||
691 | */ | ||
692 | unsigned int pages_refcount : 2; | ||
693 | #define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 | ||
694 | |||
695 | /** | ||
696 | * Current tiling mode for the object. | ||
697 | */ | ||
698 | unsigned int tiling_mode : 2; | ||
699 | |||
700 | /** How many users have pinned this object in GTT space. The following | ||
701 | * users can each hold at most one reference: pwrite/pread, pin_ioctl | ||
702 | * (via user_pin_count), execbuffer (objects are not allowed multiple | ||
703 | * times for the same batchbuffer), and the framebuffer code. When | ||
704 | * switching/pageflipping, the framebuffer code has at most two buffers | ||
705 | * pinned per crtc. | ||
706 | * | ||
707 | * In the worst case this is 1 + 1 + 1 + 2*2 = 7. That would fit into 3 | ||
708 | * bits with absolutely no headroom. So use 4 bits. */ | ||
709 | int pin_count : 4; | ||
710 | #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf | ||
681 | 711 | ||
682 | /** AGP memory structure for our GTT binding. */ | 712 | /** AGP memory structure for our GTT binding. */ |
683 | DRM_AGP_MEM *agp_mem; | 713 | DRM_AGP_MEM *agp_mem; |
684 | 714 | ||
685 | struct page **pages; | 715 | struct page **pages; |
686 | int pages_refcount; | ||
687 | 716 | ||
688 | /** | 717 | /** |
689 | * Current offset of the object in GTT space. | 718 | * Current offset of the object in GTT space. |
@@ -692,26 +721,18 @@ struct drm_i915_gem_object { | |||
692 | */ | 721 | */ |
693 | uint32_t gtt_offset; | 722 | uint32_t gtt_offset; |
694 | 723 | ||
724 | /* Which ring is refering to is this object */ | ||
725 | struct intel_ring_buffer *ring; | ||
726 | |||
695 | /** | 727 | /** |
696 | * Fake offset for use by mmap(2) | 728 | * Fake offset for use by mmap(2) |
697 | */ | 729 | */ |
698 | uint64_t mmap_offset; | 730 | uint64_t mmap_offset; |
699 | 731 | ||
700 | /** | ||
701 | * Fence register bits (if any) for this object. Will be set | ||
702 | * as needed when mapped into the GTT. | ||
703 | * Protected by dev->struct_mutex. | ||
704 | */ | ||
705 | int fence_reg; | ||
706 | |||
707 | /** How many users have pinned this object in GTT space */ | ||
708 | int pin_count; | ||
709 | |||
710 | /** Breadcrumb of last rendering to the buffer. */ | 732 | /** Breadcrumb of last rendering to the buffer. */ |
711 | uint32_t last_rendering_seqno; | 733 | uint32_t last_rendering_seqno; |
712 | 734 | ||
713 | /** Current tiling mode for the object. */ | 735 | /** Current tiling stride for the object, if it's tiled. */ |
714 | uint32_t tiling_mode; | ||
715 | uint32_t stride; | 736 | uint32_t stride; |
716 | 737 | ||
717 | /** Record of address bit 17 of each page at last unbind. */ | 738 | /** Record of address bit 17 of each page at last unbind. */ |
@@ -734,17 +755,6 @@ struct drm_i915_gem_object { | |||
734 | struct drm_i915_gem_phys_object *phys_obj; | 755 | struct drm_i915_gem_phys_object *phys_obj; |
735 | 756 | ||
736 | /** | 757 | /** |
737 | * Used for checking the object doesn't appear more than once | ||
738 | * in an execbuffer object list. | ||
739 | */ | ||
740 | int in_execbuffer; | ||
741 | |||
742 | /** | ||
743 | * Advice: are the backing pages purgeable? | ||
744 | */ | ||
745 | int madv; | ||
746 | |||
747 | /** | ||
748 | * Number of crtcs where this object is currently the fb, but | 758 | * Number of crtcs where this object is currently the fb, but |
749 | * will be page flipped away on the next vblank. When it | 759 | * will be page flipped away on the next vblank. When it |
750 | * reaches 0, dev_priv->pending_flip_queue will be woken up. | 760 | * reaches 0, dev_priv->pending_flip_queue will be woken up. |
@@ -765,6 +775,9 @@ struct drm_i915_gem_object { | |||
765 | * an emission time with seqnos for tracking how far ahead of the GPU we are. | 775 | * an emission time with seqnos for tracking how far ahead of the GPU we are. |
766 | */ | 776 | */ |
767 | struct drm_i915_gem_request { | 777 | struct drm_i915_gem_request { |
778 | /** On Which ring this request was generated */ | ||
779 | struct intel_ring_buffer *ring; | ||
780 | |||
768 | /** GEM sequence number associated with this request. */ | 781 | /** GEM sequence number associated with this request. */ |
769 | uint32_t seqno; | 782 | uint32_t seqno; |
770 | 783 | ||
@@ -821,6 +834,11 @@ extern int i915_emit_box(struct drm_device *dev, | |||
821 | struct drm_clip_rect *boxes, | 834 | struct drm_clip_rect *boxes, |
822 | int i, int DR1, int DR4); | 835 | int i, int DR1, int DR4); |
823 | extern int i965_reset(struct drm_device *dev, u8 flags); | 836 | extern int i965_reset(struct drm_device *dev, u8 flags); |
837 | extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); | ||
838 | extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); | ||
839 | extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); | ||
840 | extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); | ||
841 | |||
824 | 842 | ||
825 | /* i915_irq.c */ | 843 | /* i915_irq.c */ |
826 | void i915_hangcheck_elapsed(unsigned long data); | 844 | void i915_hangcheck_elapsed(unsigned long data); |
@@ -829,9 +847,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, | |||
829 | struct drm_file *file_priv); | 847 | struct drm_file *file_priv); |
830 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 848 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
831 | struct drm_file *file_priv); | 849 | struct drm_file *file_priv); |
832 | void i915_user_irq_get(struct drm_device *dev); | ||
833 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno); | 850 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno); |
834 | void i915_user_irq_put(struct drm_device *dev); | ||
835 | extern void i915_enable_interrupt (struct drm_device *dev); | 851 | extern void i915_enable_interrupt (struct drm_device *dev); |
836 | 852 | ||
837 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 853 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
@@ -849,6 +865,11 @@ extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); | |||
849 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 865 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
850 | struct drm_file *file_priv); | 866 | struct drm_file *file_priv); |
851 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); | 867 | extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); |
868 | extern void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask); | ||
869 | extern void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, | ||
870 | u32 mask); | ||
871 | extern void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, | ||
872 | u32 mask); | ||
852 | 873 | ||
853 | void | 874 | void |
854 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | 875 | i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
@@ -922,11 +943,13 @@ void i915_gem_object_unpin(struct drm_gem_object *obj); | |||
922 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 943 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
923 | void i915_gem_release_mmap(struct drm_gem_object *obj); | 944 | void i915_gem_release_mmap(struct drm_gem_object *obj); |
924 | void i915_gem_lastclose(struct drm_device *dev); | 945 | void i915_gem_lastclose(struct drm_device *dev); |
925 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 946 | uint32_t i915_get_gem_seqno(struct drm_device *dev, |
947 | struct intel_ring_buffer *ring); | ||
926 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); | 948 | bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); |
927 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 949 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
928 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); | 950 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); |
929 | void i915_gem_retire_requests(struct drm_device *dev); | 951 | void i915_gem_retire_requests(struct drm_device *dev, |
952 | struct intel_ring_buffer *ring); | ||
930 | void i915_gem_retire_work_handler(struct work_struct *work); | 953 | void i915_gem_retire_work_handler(struct work_struct *work); |
931 | void i915_gem_clflush_object(struct drm_gem_object *obj); | 954 | void i915_gem_clflush_object(struct drm_gem_object *obj); |
932 | int i915_gem_object_set_domain(struct drm_gem_object *obj, | 955 | int i915_gem_object_set_domain(struct drm_gem_object *obj, |
@@ -937,9 +960,13 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | |||
937 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 960 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
938 | unsigned long end); | 961 | unsigned long end); |
939 | int i915_gem_idle(struct drm_device *dev); | 962 | int i915_gem_idle(struct drm_device *dev); |
940 | uint32_t i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | 963 | uint32_t i915_add_request(struct drm_device *dev, |
941 | uint32_t flush_domains); | 964 | struct drm_file *file_priv, |
942 | int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible); | 965 | uint32_t flush_domains, |
966 | struct intel_ring_buffer *ring); | ||
967 | int i915_do_wait_request(struct drm_device *dev, | ||
968 | uint32_t seqno, int interruptible, | ||
969 | struct intel_ring_buffer *ring); | ||
943 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 970 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
944 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 971 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
945 | int write); | 972 | int write); |
@@ -1015,7 +1042,7 @@ extern void g4x_disable_fbc(struct drm_device *dev); | |||
1015 | extern void intel_disable_fbc(struct drm_device *dev); | 1042 | extern void intel_disable_fbc(struct drm_device *dev); |
1016 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); | 1043 | extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); |
1017 | extern bool intel_fbc_enabled(struct drm_device *dev); | 1044 | extern bool intel_fbc_enabled(struct drm_device *dev); |
1018 | 1045 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |
1019 | extern void intel_detect_pch (struct drm_device *dev); | 1046 | extern void intel_detect_pch (struct drm_device *dev); |
1020 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1047 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
1021 | 1048 | ||
@@ -1026,7 +1053,8 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1026 | * has access to the ring. | 1053 | * has access to the ring. |
1027 | */ | 1054 | */ |
1028 | #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ | 1055 | #define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ |
1029 | if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \ | 1056 | if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \ |
1057 | == NULL) \ | ||
1030 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ | 1058 | LOCK_TEST_WITH_RETURN(dev, file_priv); \ |
1031 | } while (0) | 1059 | } while (0) |
1032 | 1060 | ||
@@ -1039,35 +1067,31 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1039 | #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) | 1067 | #define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) |
1040 | #define I915_READ64(reg) readq(dev_priv->regs + (reg)) | 1068 | #define I915_READ64(reg) readq(dev_priv->regs + (reg)) |
1041 | #define POSTING_READ(reg) (void)I915_READ(reg) | 1069 | #define POSTING_READ(reg) (void)I915_READ(reg) |
1070 | #define POSTING_READ16(reg) (void)I915_READ16(reg) | ||
1042 | 1071 | ||
1043 | #define I915_VERBOSE 0 | 1072 | #define I915_VERBOSE 0 |
1044 | 1073 | ||
1045 | #define RING_LOCALS volatile unsigned int *ring_virt__; | 1074 | #define BEGIN_LP_RING(n) do { \ |
1046 | 1075 | drm_i915_private_t *dev_priv = dev->dev_private; \ | |
1047 | #define BEGIN_LP_RING(n) do { \ | 1076 | if (I915_VERBOSE) \ |
1048 | int bytes__ = 4*(n); \ | 1077 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
1049 | if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ | 1078 | intel_ring_begin(dev, &dev_priv->render_ring, 4*(n)); \ |
1050 | /* a wrap must occur between instructions so pad beforehand */ \ | ||
1051 | if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ | ||
1052 | i915_wrap_ring(dev); \ | ||
1053 | if (unlikely (dev_priv->ring.space < bytes__)) \ | ||
1054 | i915_wait_ring(dev, bytes__, __func__); \ | ||
1055 | ring_virt__ = (unsigned int *) \ | ||
1056 | (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ | ||
1057 | dev_priv->ring.tail += bytes__; \ | ||
1058 | dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ | ||
1059 | dev_priv->ring.space -= bytes__; \ | ||
1060 | } while (0) | 1079 | } while (0) |
1061 | 1080 | ||
1062 | #define OUT_RING(n) do { \ | 1081 | |
1063 | if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ | 1082 | #define OUT_RING(x) do { \ |
1064 | *ring_virt__++ = (n); \ | 1083 | drm_i915_private_t *dev_priv = dev->dev_private; \ |
1084 | if (I915_VERBOSE) \ | ||
1085 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | ||
1086 | intel_ring_emit(dev, &dev_priv->render_ring, x); \ | ||
1065 | } while (0) | 1087 | } while (0) |
1066 | 1088 | ||
1067 | #define ADVANCE_LP_RING() do { \ | 1089 | #define ADVANCE_LP_RING() do { \ |
1090 | drm_i915_private_t *dev_priv = dev->dev_private; \ | ||
1068 | if (I915_VERBOSE) \ | 1091 | if (I915_VERBOSE) \ |
1069 | DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ | 1092 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ |
1070 | I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ | 1093 | dev_priv->render_ring.tail); \ |
1094 | intel_ring_advance(dev, &dev_priv->render_ring); \ | ||
1071 | } while(0) | 1095 | } while(0) |
1072 | 1096 | ||
1073 | /** | 1097 | /** |
@@ -1085,14 +1109,12 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1085 | * | 1109 | * |
1086 | * The area from dword 0x20 to 0x3ff is available for driver usage. | 1110 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
1087 | */ | 1111 | */ |
1088 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) | 1112 | #define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ |
1113 | (dev_priv->render_ring.status_page.page_addr))[reg]) | ||
1089 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) | 1114 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
1090 | #define I915_GEM_HWS_INDEX 0x20 | 1115 | #define I915_GEM_HWS_INDEX 0x20 |
1091 | #define I915_BREADCRUMB_INDEX 0x21 | 1116 | #define I915_BREADCRUMB_INDEX 0x21 |
1092 | 1117 | ||
1093 | extern int i915_wrap_ring(struct drm_device * dev); | ||
1094 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | ||
1095 | |||
1096 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) | 1118 | #define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) |
1097 | 1119 | ||
1098 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) | 1120 | #define IS_I830(dev) ((dev)->pci_device == 0x3577) |
@@ -1138,6 +1160,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
1138 | (dev)->pci_device == 0x2A42 || \ | 1160 | (dev)->pci_device == 0x2A42 || \ |
1139 | (dev)->pci_device == 0x2E42) | 1161 | (dev)->pci_device == 0x2E42) |
1140 | 1162 | ||
1163 | #define HAS_BSD(dev) (IS_IRONLAKE(dev) || IS_G4X(dev)) | ||
1141 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 1164 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
1142 | 1165 | ||
1143 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1166 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 112699f71fa4..9ded3dae6c87 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -35,8 +35,6 @@ | |||
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | 37 | ||
38 | #define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) | ||
39 | |||
40 | static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 38 | static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
41 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
42 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
@@ -169,7 +167,7 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) | |||
169 | obj_priv->tiling_mode != I915_TILING_NONE; | 167 | obj_priv->tiling_mode != I915_TILING_NONE; |
170 | } | 168 | } |
171 | 169 | ||
172 | static inline int | 170 | static inline void |
173 | slow_shmem_copy(struct page *dst_page, | 171 | slow_shmem_copy(struct page *dst_page, |
174 | int dst_offset, | 172 | int dst_offset, |
175 | struct page *src_page, | 173 | struct page *src_page, |
@@ -178,25 +176,16 @@ slow_shmem_copy(struct page *dst_page, | |||
178 | { | 176 | { |
179 | char *dst_vaddr, *src_vaddr; | 177 | char *dst_vaddr, *src_vaddr; |
180 | 178 | ||
181 | dst_vaddr = kmap_atomic(dst_page, KM_USER0); | 179 | dst_vaddr = kmap(dst_page); |
182 | if (dst_vaddr == NULL) | 180 | src_vaddr = kmap(src_page); |
183 | return -ENOMEM; | ||
184 | |||
185 | src_vaddr = kmap_atomic(src_page, KM_USER1); | ||
186 | if (src_vaddr == NULL) { | ||
187 | kunmap_atomic(dst_vaddr, KM_USER0); | ||
188 | return -ENOMEM; | ||
189 | } | ||
190 | 181 | ||
191 | memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); | 182 | memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); |
192 | 183 | ||
193 | kunmap_atomic(src_vaddr, KM_USER1); | 184 | kunmap(src_page); |
194 | kunmap_atomic(dst_vaddr, KM_USER0); | 185 | kunmap(dst_page); |
195 | |||
196 | return 0; | ||
197 | } | 186 | } |
198 | 187 | ||
199 | static inline int | 188 | static inline void |
200 | slow_shmem_bit17_copy(struct page *gpu_page, | 189 | slow_shmem_bit17_copy(struct page *gpu_page, |
201 | int gpu_offset, | 190 | int gpu_offset, |
202 | struct page *cpu_page, | 191 | struct page *cpu_page, |
@@ -216,15 +205,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, | |||
216 | cpu_page, cpu_offset, length); | 205 | cpu_page, cpu_offset, length); |
217 | } | 206 | } |
218 | 207 | ||
219 | gpu_vaddr = kmap_atomic(gpu_page, KM_USER0); | 208 | gpu_vaddr = kmap(gpu_page); |
220 | if (gpu_vaddr == NULL) | 209 | cpu_vaddr = kmap(cpu_page); |
221 | return -ENOMEM; | ||
222 | |||
223 | cpu_vaddr = kmap_atomic(cpu_page, KM_USER1); | ||
224 | if (cpu_vaddr == NULL) { | ||
225 | kunmap_atomic(gpu_vaddr, KM_USER0); | ||
226 | return -ENOMEM; | ||
227 | } | ||
228 | 210 | ||
229 | /* Copy the data, XORing A6 with A17 (1). The user already knows he's | 211 | /* Copy the data, XORing A6 with A17 (1). The user already knows he's |
230 | * XORing with the other bits (A9 for Y, A9 and A10 for X) | 212 | * XORing with the other bits (A9 for Y, A9 and A10 for X) |
@@ -248,10 +230,8 @@ slow_shmem_bit17_copy(struct page *gpu_page, | |||
248 | length -= this_length; | 230 | length -= this_length; |
249 | } | 231 | } |
250 | 232 | ||
251 | kunmap_atomic(cpu_vaddr, KM_USER1); | 233 | kunmap(cpu_page); |
252 | kunmap_atomic(gpu_vaddr, KM_USER0); | 234 | kunmap(gpu_page); |
253 | |||
254 | return 0; | ||
255 | } | 235 | } |
256 | 236 | ||
257 | /** | 237 | /** |
@@ -427,21 +407,19 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
427 | page_length = PAGE_SIZE - data_page_offset; | 407 | page_length = PAGE_SIZE - data_page_offset; |
428 | 408 | ||
429 | if (do_bit17_swizzling) { | 409 | if (do_bit17_swizzling) { |
430 | ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | 410 | slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], |
431 | shmem_page_offset, | ||
432 | user_pages[data_page_index], | ||
433 | data_page_offset, | ||
434 | page_length, | ||
435 | 1); | ||
436 | } else { | ||
437 | ret = slow_shmem_copy(user_pages[data_page_index], | ||
438 | data_page_offset, | ||
439 | obj_priv->pages[shmem_page_index], | ||
440 | shmem_page_offset, | 411 | shmem_page_offset, |
441 | page_length); | 412 | user_pages[data_page_index], |
413 | data_page_offset, | ||
414 | page_length, | ||
415 | 1); | ||
416 | } else { | ||
417 | slow_shmem_copy(user_pages[data_page_index], | ||
418 | data_page_offset, | ||
419 | obj_priv->pages[shmem_page_index], | ||
420 | shmem_page_offset, | ||
421 | page_length); | ||
442 | } | 422 | } |
443 | if (ret) | ||
444 | goto fail_put_pages; | ||
445 | 423 | ||
446 | remain -= page_length; | 424 | remain -= page_length; |
447 | data_ptr += page_length; | 425 | data_ptr += page_length; |
@@ -531,25 +509,24 @@ fast_user_write(struct io_mapping *mapping, | |||
531 | * page faults | 509 | * page faults |
532 | */ | 510 | */ |
533 | 511 | ||
534 | static inline int | 512 | static inline void |
535 | slow_kernel_write(struct io_mapping *mapping, | 513 | slow_kernel_write(struct io_mapping *mapping, |
536 | loff_t gtt_base, int gtt_offset, | 514 | loff_t gtt_base, int gtt_offset, |
537 | struct page *user_page, int user_offset, | 515 | struct page *user_page, int user_offset, |
538 | int length) | 516 | int length) |
539 | { | 517 | { |
540 | char *src_vaddr, *dst_vaddr; | 518 | char __iomem *dst_vaddr; |
541 | unsigned long unwritten; | 519 | char *src_vaddr; |
542 | 520 | ||
543 | dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base); | 521 | dst_vaddr = io_mapping_map_wc(mapping, gtt_base); |
544 | src_vaddr = kmap_atomic(user_page, KM_USER1); | 522 | src_vaddr = kmap(user_page); |
545 | unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset, | 523 | |
546 | src_vaddr + user_offset, | 524 | memcpy_toio(dst_vaddr + gtt_offset, |
547 | length); | 525 | src_vaddr + user_offset, |
548 | kunmap_atomic(src_vaddr, KM_USER1); | 526 | length); |
549 | io_mapping_unmap_atomic(dst_vaddr); | 527 | |
550 | if (unwritten) | 528 | kunmap(user_page); |
551 | return -EFAULT; | 529 | io_mapping_unmap(dst_vaddr); |
552 | return 0; | ||
553 | } | 530 | } |
554 | 531 | ||
555 | static inline int | 532 | static inline int |
@@ -722,18 +699,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
722 | if ((data_page_offset + page_length) > PAGE_SIZE) | 699 | if ((data_page_offset + page_length) > PAGE_SIZE) |
723 | page_length = PAGE_SIZE - data_page_offset; | 700 | page_length = PAGE_SIZE - data_page_offset; |
724 | 701 | ||
725 | ret = slow_kernel_write(dev_priv->mm.gtt_mapping, | 702 | slow_kernel_write(dev_priv->mm.gtt_mapping, |
726 | gtt_page_base, gtt_page_offset, | 703 | gtt_page_base, gtt_page_offset, |
727 | user_pages[data_page_index], | 704 | user_pages[data_page_index], |
728 | data_page_offset, | 705 | data_page_offset, |
729 | page_length); | 706 | page_length); |
730 | |||
731 | /* If we get a fault while copying data, then (presumably) our | ||
732 | * source page isn't available. Return the error and we'll | ||
733 | * retry in the slow path. | ||
734 | */ | ||
735 | if (ret) | ||
736 | goto out_unpin_object; | ||
737 | 707 | ||
738 | remain -= page_length; | 708 | remain -= page_length; |
739 | offset += page_length; | 709 | offset += page_length; |
@@ -902,21 +872,19 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, | |||
902 | page_length = PAGE_SIZE - data_page_offset; | 872 | page_length = PAGE_SIZE - data_page_offset; |
903 | 873 | ||
904 | if (do_bit17_swizzling) { | 874 | if (do_bit17_swizzling) { |
905 | ret = slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], | 875 | slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], |
906 | shmem_page_offset, | ||
907 | user_pages[data_page_index], | ||
908 | data_page_offset, | ||
909 | page_length, | ||
910 | 0); | ||
911 | } else { | ||
912 | ret = slow_shmem_copy(obj_priv->pages[shmem_page_index], | ||
913 | shmem_page_offset, | 876 | shmem_page_offset, |
914 | user_pages[data_page_index], | 877 | user_pages[data_page_index], |
915 | data_page_offset, | 878 | data_page_offset, |
916 | page_length); | 879 | page_length, |
880 | 0); | ||
881 | } else { | ||
882 | slow_shmem_copy(obj_priv->pages[shmem_page_index], | ||
883 | shmem_page_offset, | ||
884 | user_pages[data_page_index], | ||
885 | data_page_offset, | ||
886 | page_length); | ||
917 | } | 887 | } |
918 | if (ret) | ||
919 | goto fail_put_pages; | ||
920 | 888 | ||
921 | remain -= page_length; | 889 | remain -= page_length; |
922 | data_ptr += page_length; | 890 | data_ptr += page_length; |
@@ -973,7 +941,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
973 | if (obj_priv->phys_obj) | 941 | if (obj_priv->phys_obj) |
974 | ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); | 942 | ret = i915_gem_phys_pwrite(dev, obj, args, file_priv); |
975 | else if (obj_priv->tiling_mode == I915_TILING_NONE && | 943 | else if (obj_priv->tiling_mode == I915_TILING_NONE && |
976 | dev->gtt_total != 0) { | 944 | dev->gtt_total != 0 && |
945 | obj->write_domain != I915_GEM_DOMAIN_CPU) { | ||
977 | ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); | 946 | ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv); |
978 | if (ret == -EFAULT) { | 947 | if (ret == -EFAULT) { |
979 | ret = i915_gem_gtt_pwrite_slow(dev, obj, args, | 948 | ret = i915_gem_gtt_pwrite_slow(dev, obj, args, |
@@ -1484,11 +1453,14 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) | |||
1484 | } | 1453 | } |
1485 | 1454 | ||
1486 | static void | 1455 | static void |
1487 | i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) | 1456 | i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno, |
1457 | struct intel_ring_buffer *ring) | ||
1488 | { | 1458 | { |
1489 | struct drm_device *dev = obj->dev; | 1459 | struct drm_device *dev = obj->dev; |
1490 | drm_i915_private_t *dev_priv = dev->dev_private; | 1460 | drm_i915_private_t *dev_priv = dev->dev_private; |
1491 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1461 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1462 | BUG_ON(ring == NULL); | ||
1463 | obj_priv->ring = ring; | ||
1492 | 1464 | ||
1493 | /* Add a reference if we're newly entering the active list. */ | 1465 | /* Add a reference if we're newly entering the active list. */ |
1494 | if (!obj_priv->active) { | 1466 | if (!obj_priv->active) { |
@@ -1497,8 +1469,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) | |||
1497 | } | 1469 | } |
1498 | /* Move from whatever list we were on to the tail of execution. */ | 1470 | /* Move from whatever list we were on to the tail of execution. */ |
1499 | spin_lock(&dev_priv->mm.active_list_lock); | 1471 | spin_lock(&dev_priv->mm.active_list_lock); |
1500 | list_move_tail(&obj_priv->list, | 1472 | list_move_tail(&obj_priv->list, &ring->active_list); |
1501 | &dev_priv->mm.active_list); | ||
1502 | spin_unlock(&dev_priv->mm.active_list_lock); | 1473 | spin_unlock(&dev_priv->mm.active_list_lock); |
1503 | obj_priv->last_rendering_seqno = seqno; | 1474 | obj_priv->last_rendering_seqno = seqno; |
1504 | } | 1475 | } |
@@ -1551,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
1551 | BUG_ON(!list_empty(&obj_priv->gpu_write_list)); | 1522 | BUG_ON(!list_empty(&obj_priv->gpu_write_list)); |
1552 | 1523 | ||
1553 | obj_priv->last_rendering_seqno = 0; | 1524 | obj_priv->last_rendering_seqno = 0; |
1525 | obj_priv->ring = NULL; | ||
1554 | if (obj_priv->active) { | 1526 | if (obj_priv->active) { |
1555 | obj_priv->active = 0; | 1527 | obj_priv->active = 0; |
1556 | drm_gem_object_unreference(obj); | 1528 | drm_gem_object_unreference(obj); |
@@ -1560,7 +1532,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
1560 | 1532 | ||
1561 | static void | 1533 | static void |
1562 | i915_gem_process_flushing_list(struct drm_device *dev, | 1534 | i915_gem_process_flushing_list(struct drm_device *dev, |
1563 | uint32_t flush_domains, uint32_t seqno) | 1535 | uint32_t flush_domains, uint32_t seqno, |
1536 | struct intel_ring_buffer *ring) | ||
1564 | { | 1537 | { |
1565 | drm_i915_private_t *dev_priv = dev->dev_private; | 1538 | drm_i915_private_t *dev_priv = dev->dev_private; |
1566 | struct drm_i915_gem_object *obj_priv, *next; | 1539 | struct drm_i915_gem_object *obj_priv, *next; |
@@ -1571,12 +1544,13 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1571 | struct drm_gem_object *obj = &obj_priv->base; | 1544 | struct drm_gem_object *obj = &obj_priv->base; |
1572 | 1545 | ||
1573 | if ((obj->write_domain & flush_domains) == | 1546 | if ((obj->write_domain & flush_domains) == |
1574 | obj->write_domain) { | 1547 | obj->write_domain && |
1548 | obj_priv->ring->ring_flag == ring->ring_flag) { | ||
1575 | uint32_t old_write_domain = obj->write_domain; | 1549 | uint32_t old_write_domain = obj->write_domain; |
1576 | 1550 | ||
1577 | obj->write_domain = 0; | 1551 | obj->write_domain = 0; |
1578 | list_del_init(&obj_priv->gpu_write_list); | 1552 | list_del_init(&obj_priv->gpu_write_list); |
1579 | i915_gem_object_move_to_active(obj, seqno); | 1553 | i915_gem_object_move_to_active(obj, seqno, ring); |
1580 | 1554 | ||
1581 | /* update the fence lru list */ | 1555 | /* update the fence lru list */ |
1582 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { | 1556 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { |
@@ -1593,31 +1567,15 @@ i915_gem_process_flushing_list(struct drm_device *dev, | |||
1593 | } | 1567 | } |
1594 | } | 1568 | } |
1595 | 1569 | ||
1596 | #define PIPE_CONTROL_FLUSH(addr) \ | ||
1597 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | ||
1598 | PIPE_CONTROL_DEPTH_STALL); \ | ||
1599 | OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | ||
1600 | OUT_RING(0); \ | ||
1601 | OUT_RING(0); \ | ||
1602 | |||
1603 | /** | ||
1604 | * Creates a new sequence number, emitting a write of it to the status page | ||
1605 | * plus an interrupt, which will trigger i915_user_interrupt_handler. | ||
1606 | * | ||
1607 | * Must be called with struct_lock held. | ||
1608 | * | ||
1609 | * Returned sequence numbers are nonzero on success. | ||
1610 | */ | ||
1611 | uint32_t | 1570 | uint32_t |
1612 | i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | 1571 | i915_add_request(struct drm_device *dev, struct drm_file *file_priv, |
1613 | uint32_t flush_domains) | 1572 | uint32_t flush_domains, struct intel_ring_buffer *ring) |
1614 | { | 1573 | { |
1615 | drm_i915_private_t *dev_priv = dev->dev_private; | 1574 | drm_i915_private_t *dev_priv = dev->dev_private; |
1616 | struct drm_i915_file_private *i915_file_priv = NULL; | 1575 | struct drm_i915_file_private *i915_file_priv = NULL; |
1617 | struct drm_i915_gem_request *request; | 1576 | struct drm_i915_gem_request *request; |
1618 | uint32_t seqno; | 1577 | uint32_t seqno; |
1619 | int was_empty; | 1578 | int was_empty; |
1620 | RING_LOCALS; | ||
1621 | 1579 | ||
1622 | if (file_priv != NULL) | 1580 | if (file_priv != NULL) |
1623 | i915_file_priv = file_priv->driver_priv; | 1581 | i915_file_priv = file_priv->driver_priv; |
@@ -1626,62 +1584,14 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1626 | if (request == NULL) | 1584 | if (request == NULL) |
1627 | return 0; | 1585 | return 0; |
1628 | 1586 | ||
1629 | /* Grab the seqno we're going to make this request be, and bump the | 1587 | seqno = ring->add_request(dev, ring, file_priv, flush_domains); |
1630 | * next (skipping 0 so it can be the reserved no-seqno value). | ||
1631 | */ | ||
1632 | seqno = dev_priv->mm.next_gem_seqno; | ||
1633 | dev_priv->mm.next_gem_seqno++; | ||
1634 | if (dev_priv->mm.next_gem_seqno == 0) | ||
1635 | dev_priv->mm.next_gem_seqno++; | ||
1636 | |||
1637 | if (HAS_PIPE_CONTROL(dev)) { | ||
1638 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | ||
1639 | |||
1640 | /* | ||
1641 | * Workaround qword write incoherence by flushing the | ||
1642 | * PIPE_NOTIFY buffers out to memory before requesting | ||
1643 | * an interrupt. | ||
1644 | */ | ||
1645 | BEGIN_LP_RING(32); | ||
1646 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1647 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | ||
1648 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1649 | OUT_RING(seqno); | ||
1650 | OUT_RING(0); | ||
1651 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1652 | scratch_addr += 128; /* write to separate cachelines */ | ||
1653 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1654 | scratch_addr += 128; | ||
1655 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1656 | scratch_addr += 128; | ||
1657 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1658 | scratch_addr += 128; | ||
1659 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1660 | scratch_addr += 128; | ||
1661 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
1662 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
1663 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
1664 | PIPE_CONTROL_NOTIFY); | ||
1665 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
1666 | OUT_RING(seqno); | ||
1667 | OUT_RING(0); | ||
1668 | ADVANCE_LP_RING(); | ||
1669 | } else { | ||
1670 | BEGIN_LP_RING(4); | ||
1671 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
1672 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
1673 | OUT_RING(seqno); | ||
1674 | |||
1675 | OUT_RING(MI_USER_INTERRUPT); | ||
1676 | ADVANCE_LP_RING(); | ||
1677 | } | ||
1678 | |||
1679 | DRM_DEBUG_DRIVER("%d\n", seqno); | ||
1680 | 1588 | ||
1681 | request->seqno = seqno; | 1589 | request->seqno = seqno; |
1590 | request->ring = ring; | ||
1682 | request->emitted_jiffies = jiffies; | 1591 | request->emitted_jiffies = jiffies; |
1683 | was_empty = list_empty(&dev_priv->mm.request_list); | 1592 | was_empty = list_empty(&ring->request_list); |
1684 | list_add_tail(&request->list, &dev_priv->mm.request_list); | 1593 | list_add_tail(&request->list, &ring->request_list); |
1594 | |||
1685 | if (i915_file_priv) { | 1595 | if (i915_file_priv) { |
1686 | list_add_tail(&request->client_list, | 1596 | list_add_tail(&request->client_list, |
1687 | &i915_file_priv->mm.request_list); | 1597 | &i915_file_priv->mm.request_list); |
@@ -1693,7 +1603,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1693 | * domain we're flushing with our flush. | 1603 | * domain we're flushing with our flush. |
1694 | */ | 1604 | */ |
1695 | if (flush_domains != 0) | 1605 | if (flush_domains != 0) |
1696 | i915_gem_process_flushing_list(dev, flush_domains, seqno); | 1606 | i915_gem_process_flushing_list(dev, flush_domains, seqno, ring); |
1697 | 1607 | ||
1698 | if (!dev_priv->mm.suspended) { | 1608 | if (!dev_priv->mm.suspended) { |
1699 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1609 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
@@ -1710,20 +1620,16 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1710 | * before signalling the CPU | 1620 | * before signalling the CPU |
1711 | */ | 1621 | */ |
1712 | static uint32_t | 1622 | static uint32_t |
1713 | i915_retire_commands(struct drm_device *dev) | 1623 | i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) |
1714 | { | 1624 | { |
1715 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1716 | uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | ||
1717 | uint32_t flush_domains = 0; | 1625 | uint32_t flush_domains = 0; |
1718 | RING_LOCALS; | ||
1719 | 1626 | ||
1720 | /* The sampler always gets flushed on i965 (sigh) */ | 1627 | /* The sampler always gets flushed on i965 (sigh) */ |
1721 | if (IS_I965G(dev)) | 1628 | if (IS_I965G(dev)) |
1722 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; | 1629 | flush_domains |= I915_GEM_DOMAIN_SAMPLER; |
1723 | BEGIN_LP_RING(2); | 1630 | |
1724 | OUT_RING(cmd); | 1631 | ring->flush(dev, ring, |
1725 | OUT_RING(0); /* noop */ | 1632 | I915_GEM_DOMAIN_COMMAND, flush_domains); |
1726 | ADVANCE_LP_RING(); | ||
1727 | return flush_domains; | 1633 | return flush_domains; |
1728 | } | 1634 | } |
1729 | 1635 | ||
@@ -1743,11 +1649,11 @@ i915_gem_retire_request(struct drm_device *dev, | |||
1743 | * by the ringbuffer to the flushing/inactive lists as appropriate. | 1649 | * by the ringbuffer to the flushing/inactive lists as appropriate. |
1744 | */ | 1650 | */ |
1745 | spin_lock(&dev_priv->mm.active_list_lock); | 1651 | spin_lock(&dev_priv->mm.active_list_lock); |
1746 | while (!list_empty(&dev_priv->mm.active_list)) { | 1652 | while (!list_empty(&request->ring->active_list)) { |
1747 | struct drm_gem_object *obj; | 1653 | struct drm_gem_object *obj; |
1748 | struct drm_i915_gem_object *obj_priv; | 1654 | struct drm_i915_gem_object *obj_priv; |
1749 | 1655 | ||
1750 | obj_priv = list_first_entry(&dev_priv->mm.active_list, | 1656 | obj_priv = list_first_entry(&request->ring->active_list, |
1751 | struct drm_i915_gem_object, | 1657 | struct drm_i915_gem_object, |
1752 | list); | 1658 | list); |
1753 | obj = &obj_priv->base; | 1659 | obj = &obj_priv->base; |
@@ -1794,35 +1700,33 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) | |||
1794 | } | 1700 | } |
1795 | 1701 | ||
1796 | uint32_t | 1702 | uint32_t |
1797 | i915_get_gem_seqno(struct drm_device *dev) | 1703 | i915_get_gem_seqno(struct drm_device *dev, |
1704 | struct intel_ring_buffer *ring) | ||
1798 | { | 1705 | { |
1799 | drm_i915_private_t *dev_priv = dev->dev_private; | 1706 | return ring->get_gem_seqno(dev, ring); |
1800 | |||
1801 | if (HAS_PIPE_CONTROL(dev)) | ||
1802 | return ((volatile u32 *)(dev_priv->seqno_page))[0]; | ||
1803 | else | ||
1804 | return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); | ||
1805 | } | 1707 | } |
1806 | 1708 | ||
1807 | /** | 1709 | /** |
1808 | * This function clears the request list as sequence numbers are passed. | 1710 | * This function clears the request list as sequence numbers are passed. |
1809 | */ | 1711 | */ |
1810 | void | 1712 | void |
1811 | i915_gem_retire_requests(struct drm_device *dev) | 1713 | i915_gem_retire_requests(struct drm_device *dev, |
1714 | struct intel_ring_buffer *ring) | ||
1812 | { | 1715 | { |
1813 | drm_i915_private_t *dev_priv = dev->dev_private; | 1716 | drm_i915_private_t *dev_priv = dev->dev_private; |
1814 | uint32_t seqno; | 1717 | uint32_t seqno; |
1815 | 1718 | ||
1816 | if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list)) | 1719 | if (!ring->status_page.page_addr |
1720 | || list_empty(&ring->request_list)) | ||
1817 | return; | 1721 | return; |
1818 | 1722 | ||
1819 | seqno = i915_get_gem_seqno(dev); | 1723 | seqno = i915_get_gem_seqno(dev, ring); |
1820 | 1724 | ||
1821 | while (!list_empty(&dev_priv->mm.request_list)) { | 1725 | while (!list_empty(&ring->request_list)) { |
1822 | struct drm_i915_gem_request *request; | 1726 | struct drm_i915_gem_request *request; |
1823 | uint32_t retiring_seqno; | 1727 | uint32_t retiring_seqno; |
1824 | 1728 | ||
1825 | request = list_first_entry(&dev_priv->mm.request_list, | 1729 | request = list_first_entry(&ring->request_list, |
1826 | struct drm_i915_gem_request, | 1730 | struct drm_i915_gem_request, |
1827 | list); | 1731 | list); |
1828 | retiring_seqno = request->seqno; | 1732 | retiring_seqno = request->seqno; |
@@ -1840,7 +1744,8 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
1840 | 1744 | ||
1841 | if (unlikely (dev_priv->trace_irq_seqno && | 1745 | if (unlikely (dev_priv->trace_irq_seqno && |
1842 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { | 1746 | i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { |
1843 | i915_user_irq_put(dev); | 1747 | |
1748 | ring->user_irq_put(dev, ring); | ||
1844 | dev_priv->trace_irq_seqno = 0; | 1749 | dev_priv->trace_irq_seqno = 0; |
1845 | } | 1750 | } |
1846 | } | 1751 | } |
@@ -1856,15 +1761,22 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1856 | dev = dev_priv->dev; | 1761 | dev = dev_priv->dev; |
1857 | 1762 | ||
1858 | mutex_lock(&dev->struct_mutex); | 1763 | mutex_lock(&dev->struct_mutex); |
1859 | i915_gem_retire_requests(dev); | 1764 | i915_gem_retire_requests(dev, &dev_priv->render_ring); |
1765 | |||
1766 | if (HAS_BSD(dev)) | ||
1767 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
1768 | |||
1860 | if (!dev_priv->mm.suspended && | 1769 | if (!dev_priv->mm.suspended && |
1861 | !list_empty(&dev_priv->mm.request_list)) | 1770 | (!list_empty(&dev_priv->render_ring.request_list) || |
1771 | (HAS_BSD(dev) && | ||
1772 | !list_empty(&dev_priv->bsd_ring.request_list)))) | ||
1862 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); | 1773 | queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); |
1863 | mutex_unlock(&dev->struct_mutex); | 1774 | mutex_unlock(&dev->struct_mutex); |
1864 | } | 1775 | } |
1865 | 1776 | ||
1866 | int | 1777 | int |
1867 | i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | 1778 | i915_do_wait_request(struct drm_device *dev, uint32_t seqno, |
1779 | int interruptible, struct intel_ring_buffer *ring) | ||
1868 | { | 1780 | { |
1869 | drm_i915_private_t *dev_priv = dev->dev_private; | 1781 | drm_i915_private_t *dev_priv = dev->dev_private; |
1870 | u32 ier; | 1782 | u32 ier; |
@@ -1875,7 +1787,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |||
1875 | if (atomic_read(&dev_priv->mm.wedged)) | 1787 | if (atomic_read(&dev_priv->mm.wedged)) |
1876 | return -EIO; | 1788 | return -EIO; |
1877 | 1789 | ||
1878 | if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { | 1790 | if (!i915_seqno_passed(ring->get_gem_seqno(dev, ring), seqno)) { |
1879 | if (HAS_PCH_SPLIT(dev)) | 1791 | if (HAS_PCH_SPLIT(dev)) |
1880 | ier = I915_READ(DEIER) | I915_READ(GTIER); | 1792 | ier = I915_READ(DEIER) | I915_READ(GTIER); |
1881 | else | 1793 | else |
@@ -1889,19 +1801,21 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |||
1889 | 1801 | ||
1890 | trace_i915_gem_request_wait_begin(dev, seqno); | 1802 | trace_i915_gem_request_wait_begin(dev, seqno); |
1891 | 1803 | ||
1892 | dev_priv->mm.waiting_gem_seqno = seqno; | 1804 | ring->waiting_gem_seqno = seqno; |
1893 | i915_user_irq_get(dev); | 1805 | ring->user_irq_get(dev, ring); |
1894 | if (interruptible) | 1806 | if (interruptible) |
1895 | ret = wait_event_interruptible(dev_priv->irq_queue, | 1807 | ret = wait_event_interruptible(ring->irq_queue, |
1896 | i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | 1808 | i915_seqno_passed( |
1897 | atomic_read(&dev_priv->mm.wedged)); | 1809 | ring->get_gem_seqno(dev, ring), seqno) |
1810 | || atomic_read(&dev_priv->mm.wedged)); | ||
1898 | else | 1811 | else |
1899 | wait_event(dev_priv->irq_queue, | 1812 | wait_event(ring->irq_queue, |
1900 | i915_seqno_passed(i915_get_gem_seqno(dev), seqno) || | 1813 | i915_seqno_passed( |
1901 | atomic_read(&dev_priv->mm.wedged)); | 1814 | ring->get_gem_seqno(dev, ring), seqno) |
1815 | || atomic_read(&dev_priv->mm.wedged)); | ||
1902 | 1816 | ||
1903 | i915_user_irq_put(dev); | 1817 | ring->user_irq_put(dev, ring); |
1904 | dev_priv->mm.waiting_gem_seqno = 0; | 1818 | ring->waiting_gem_seqno = 0; |
1905 | 1819 | ||
1906 | trace_i915_gem_request_wait_end(dev, seqno); | 1820 | trace_i915_gem_request_wait_end(dev, seqno); |
1907 | } | 1821 | } |
@@ -1910,7 +1824,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |||
1910 | 1824 | ||
1911 | if (ret && ret != -ERESTARTSYS) | 1825 | if (ret && ret != -ERESTARTSYS) |
1912 | DRM_ERROR("%s returns %d (awaiting %d at %d)\n", | 1826 | DRM_ERROR("%s returns %d (awaiting %d at %d)\n", |
1913 | __func__, ret, seqno, i915_get_gem_seqno(dev)); | 1827 | __func__, ret, seqno, ring->get_gem_seqno(dev, ring)); |
1914 | 1828 | ||
1915 | /* Directly dispatch request retiring. While we have the work queue | 1829 | /* Directly dispatch request retiring. While we have the work queue |
1916 | * to handle this, the waiter on a request often wants an associated | 1830 | * to handle this, the waiter on a request often wants an associated |
@@ -1918,7 +1832,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |||
1918 | * a separate wait queue to handle that. | 1832 | * a separate wait queue to handle that. |
1919 | */ | 1833 | */ |
1920 | if (ret == 0) | 1834 | if (ret == 0) |
1921 | i915_gem_retire_requests(dev); | 1835 | i915_gem_retire_requests(dev, ring); |
1922 | 1836 | ||
1923 | return ret; | 1837 | return ret; |
1924 | } | 1838 | } |
@@ -1928,9 +1842,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible) | |||
1928 | * request and object lists appropriately for that event. | 1842 | * request and object lists appropriately for that event. |
1929 | */ | 1843 | */ |
1930 | static int | 1844 | static int |
1931 | i915_wait_request(struct drm_device *dev, uint32_t seqno) | 1845 | i915_wait_request(struct drm_device *dev, uint32_t seqno, |
1846 | struct intel_ring_buffer *ring) | ||
1932 | { | 1847 | { |
1933 | return i915_do_wait_request(dev, seqno, 1); | 1848 | return i915_do_wait_request(dev, seqno, 1, ring); |
1934 | } | 1849 | } |
1935 | 1850 | ||
1936 | static void | 1851 | static void |
@@ -1939,71 +1854,29 @@ i915_gem_flush(struct drm_device *dev, | |||
1939 | uint32_t flush_domains) | 1854 | uint32_t flush_domains) |
1940 | { | 1855 | { |
1941 | drm_i915_private_t *dev_priv = dev->dev_private; | 1856 | drm_i915_private_t *dev_priv = dev->dev_private; |
1942 | uint32_t cmd; | ||
1943 | RING_LOCALS; | ||
1944 | |||
1945 | #if WATCH_EXEC | ||
1946 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | ||
1947 | invalidate_domains, flush_domains); | ||
1948 | #endif | ||
1949 | trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, | ||
1950 | invalidate_domains, flush_domains); | ||
1951 | |||
1952 | if (flush_domains & I915_GEM_DOMAIN_CPU) | 1857 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
1953 | drm_agp_chipset_flush(dev); | 1858 | drm_agp_chipset_flush(dev); |
1859 | dev_priv->render_ring.flush(dev, &dev_priv->render_ring, | ||
1860 | invalidate_domains, | ||
1861 | flush_domains); | ||
1862 | |||
1863 | if (HAS_BSD(dev)) | ||
1864 | dev_priv->bsd_ring.flush(dev, &dev_priv->bsd_ring, | ||
1865 | invalidate_domains, | ||
1866 | flush_domains); | ||
1867 | } | ||
1954 | 1868 | ||
1955 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | 1869 | static void |
1956 | /* | 1870 | i915_gem_flush_ring(struct drm_device *dev, |
1957 | * read/write caches: | 1871 | uint32_t invalidate_domains, |
1958 | * | 1872 | uint32_t flush_domains, |
1959 | * I915_GEM_DOMAIN_RENDER is always invalidated, but is | 1873 | struct intel_ring_buffer *ring) |
1960 | * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is | 1874 | { |
1961 | * also flushed at 2d versus 3d pipeline switches. | 1875 | if (flush_domains & I915_GEM_DOMAIN_CPU) |
1962 | * | 1876 | drm_agp_chipset_flush(dev); |
1963 | * read-only caches: | 1877 | ring->flush(dev, ring, |
1964 | * | 1878 | invalidate_domains, |
1965 | * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if | 1879 | flush_domains); |
1966 | * MI_READ_FLUSH is set, and is always flushed on 965. | ||
1967 | * | ||
1968 | * I915_GEM_DOMAIN_COMMAND may not exist? | ||
1969 | * | ||
1970 | * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is | ||
1971 | * invalidated when MI_EXE_FLUSH is set. | ||
1972 | * | ||
1973 | * I915_GEM_DOMAIN_VERTEX, which exists on 965, is | ||
1974 | * invalidated with every MI_FLUSH. | ||
1975 | * | ||
1976 | * TLBs: | ||
1977 | * | ||
1978 | * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND | ||
1979 | * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and | ||
1980 | * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER | ||
1981 | * are flushed at any MI_FLUSH. | ||
1982 | */ | ||
1983 | |||
1984 | cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | ||
1985 | if ((invalidate_domains|flush_domains) & | ||
1986 | I915_GEM_DOMAIN_RENDER) | ||
1987 | cmd &= ~MI_NO_WRITE_FLUSH; | ||
1988 | if (!IS_I965G(dev)) { | ||
1989 | /* | ||
1990 | * On the 965, the sampler cache always gets flushed | ||
1991 | * and this bit is reserved. | ||
1992 | */ | ||
1993 | if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | ||
1994 | cmd |= MI_READ_FLUSH; | ||
1995 | } | ||
1996 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | ||
1997 | cmd |= MI_EXE_FLUSH; | ||
1998 | |||
1999 | #if WATCH_EXEC | ||
2000 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | ||
2001 | #endif | ||
2002 | BEGIN_LP_RING(2); | ||
2003 | OUT_RING(cmd); | ||
2004 | OUT_RING(MI_NOOP); | ||
2005 | ADVANCE_LP_RING(); | ||
2006 | } | ||
2007 | } | 1880 | } |
2008 | 1881 | ||
2009 | /** | 1882 | /** |
@@ -2030,7 +1903,8 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj) | |||
2030 | DRM_INFO("%s: object %p wait for seqno %08x\n", | 1903 | DRM_INFO("%s: object %p wait for seqno %08x\n", |
2031 | __func__, obj, obj_priv->last_rendering_seqno); | 1904 | __func__, obj, obj_priv->last_rendering_seqno); |
2032 | #endif | 1905 | #endif |
2033 | ret = i915_wait_request(dev, obj_priv->last_rendering_seqno); | 1906 | ret = i915_wait_request(dev, |
1907 | obj_priv->last_rendering_seqno, obj_priv->ring); | ||
2034 | if (ret != 0) | 1908 | if (ret != 0) |
2035 | return ret; | 1909 | return ret; |
2036 | } | 1910 | } |
@@ -2146,11 +2020,14 @@ i915_gpu_idle(struct drm_device *dev) | |||
2146 | { | 2020 | { |
2147 | drm_i915_private_t *dev_priv = dev->dev_private; | 2021 | drm_i915_private_t *dev_priv = dev->dev_private; |
2148 | bool lists_empty; | 2022 | bool lists_empty; |
2149 | uint32_t seqno; | 2023 | uint32_t seqno1, seqno2; |
2024 | int ret; | ||
2150 | 2025 | ||
2151 | spin_lock(&dev_priv->mm.active_list_lock); | 2026 | spin_lock(&dev_priv->mm.active_list_lock); |
2152 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | 2027 | lists_empty = (list_empty(&dev_priv->mm.flushing_list) && |
2153 | list_empty(&dev_priv->mm.active_list); | 2028 | list_empty(&dev_priv->render_ring.active_list) && |
2029 | (!HAS_BSD(dev) || | ||
2030 | list_empty(&dev_priv->bsd_ring.active_list))); | ||
2154 | spin_unlock(&dev_priv->mm.active_list_lock); | 2031 | spin_unlock(&dev_priv->mm.active_list_lock); |
2155 | 2032 | ||
2156 | if (lists_empty) | 2033 | if (lists_empty) |
@@ -2158,11 +2035,25 @@ i915_gpu_idle(struct drm_device *dev) | |||
2158 | 2035 | ||
2159 | /* Flush everything onto the inactive list. */ | 2036 | /* Flush everything onto the inactive list. */ |
2160 | i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); | 2037 | i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); |
2161 | seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS); | 2038 | seqno1 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, |
2162 | if (seqno == 0) | 2039 | &dev_priv->render_ring); |
2040 | if (seqno1 == 0) | ||
2163 | return -ENOMEM; | 2041 | return -ENOMEM; |
2042 | ret = i915_wait_request(dev, seqno1, &dev_priv->render_ring); | ||
2043 | |||
2044 | if (HAS_BSD(dev)) { | ||
2045 | seqno2 = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS, | ||
2046 | &dev_priv->bsd_ring); | ||
2047 | if (seqno2 == 0) | ||
2048 | return -ENOMEM; | ||
2049 | |||
2050 | ret = i915_wait_request(dev, seqno2, &dev_priv->bsd_ring); | ||
2051 | if (ret) | ||
2052 | return ret; | ||
2053 | } | ||
2054 | |||
2164 | 2055 | ||
2165 | return i915_wait_request(dev, seqno); | 2056 | return ret; |
2166 | } | 2057 | } |
2167 | 2058 | ||
2168 | static int | 2059 | static int |
@@ -2175,7 +2066,9 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
2175 | spin_lock(&dev_priv->mm.active_list_lock); | 2066 | spin_lock(&dev_priv->mm.active_list_lock); |
2176 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 2067 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
2177 | list_empty(&dev_priv->mm.flushing_list) && | 2068 | list_empty(&dev_priv->mm.flushing_list) && |
2178 | list_empty(&dev_priv->mm.active_list)); | 2069 | list_empty(&dev_priv->render_ring.active_list) && |
2070 | (!HAS_BSD(dev) | ||
2071 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2179 | spin_unlock(&dev_priv->mm.active_list_lock); | 2072 | spin_unlock(&dev_priv->mm.active_list_lock); |
2180 | 2073 | ||
2181 | if (lists_empty) | 2074 | if (lists_empty) |
@@ -2195,7 +2088,9 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
2195 | spin_lock(&dev_priv->mm.active_list_lock); | 2088 | spin_lock(&dev_priv->mm.active_list_lock); |
2196 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | 2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && |
2197 | list_empty(&dev_priv->mm.flushing_list) && | 2090 | list_empty(&dev_priv->mm.flushing_list) && |
2198 | list_empty(&dev_priv->mm.active_list)); | 2091 | list_empty(&dev_priv->render_ring.active_list) && |
2092 | (!HAS_BSD(dev) | ||
2093 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2199 | spin_unlock(&dev_priv->mm.active_list_lock); | 2094 | spin_unlock(&dev_priv->mm.active_list_lock); |
2200 | BUG_ON(!lists_empty); | 2095 | BUG_ON(!lists_empty); |
2201 | 2096 | ||
@@ -2209,8 +2104,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2209 | struct drm_gem_object *obj; | 2104 | struct drm_gem_object *obj; |
2210 | int ret; | 2105 | int ret; |
2211 | 2106 | ||
2107 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
2108 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | ||
2212 | for (;;) { | 2109 | for (;;) { |
2213 | i915_gem_retire_requests(dev); | 2110 | i915_gem_retire_requests(dev, render_ring); |
2111 | |||
2112 | if (HAS_BSD(dev)) | ||
2113 | i915_gem_retire_requests(dev, bsd_ring); | ||
2214 | 2114 | ||
2215 | /* If there's an inactive buffer available now, grab it | 2115 | /* If there's an inactive buffer available now, grab it |
2216 | * and be done. | 2116 | * and be done. |
@@ -2234,14 +2134,30 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2234 | * things, wait for the next to finish and hopefully leave us | 2134 | * things, wait for the next to finish and hopefully leave us |
2235 | * a buffer to evict. | 2135 | * a buffer to evict. |
2236 | */ | 2136 | */ |
2237 | if (!list_empty(&dev_priv->mm.request_list)) { | 2137 | if (!list_empty(&render_ring->request_list)) { |
2138 | struct drm_i915_gem_request *request; | ||
2139 | |||
2140 | request = list_first_entry(&render_ring->request_list, | ||
2141 | struct drm_i915_gem_request, | ||
2142 | list); | ||
2143 | |||
2144 | ret = i915_wait_request(dev, | ||
2145 | request->seqno, request->ring); | ||
2146 | if (ret) | ||
2147 | return ret; | ||
2148 | |||
2149 | continue; | ||
2150 | } | ||
2151 | |||
2152 | if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | ||
2238 | struct drm_i915_gem_request *request; | 2153 | struct drm_i915_gem_request *request; |
2239 | 2154 | ||
2240 | request = list_first_entry(&dev_priv->mm.request_list, | 2155 | request = list_first_entry(&bsd_ring->request_list, |
2241 | struct drm_i915_gem_request, | 2156 | struct drm_i915_gem_request, |
2242 | list); | 2157 | list); |
2243 | 2158 | ||
2244 | ret = i915_wait_request(dev, request->seqno); | 2159 | ret = i915_wait_request(dev, |
2160 | request->seqno, request->ring); | ||
2245 | if (ret) | 2161 | if (ret) |
2246 | return ret; | 2162 | return ret; |
2247 | 2163 | ||
@@ -2268,10 +2184,13 @@ i915_gem_evict_something(struct drm_device *dev, int min_size) | |||
2268 | if (obj != NULL) { | 2184 | if (obj != NULL) { |
2269 | uint32_t seqno; | 2185 | uint32_t seqno; |
2270 | 2186 | ||
2271 | i915_gem_flush(dev, | 2187 | i915_gem_flush_ring(dev, |
2188 | obj->write_domain, | ||
2272 | obj->write_domain, | 2189 | obj->write_domain, |
2273 | obj->write_domain); | 2190 | obj_priv->ring); |
2274 | seqno = i915_add_request(dev, NULL, obj->write_domain); | 2191 | seqno = i915_add_request(dev, NULL, |
2192 | obj->write_domain, | ||
2193 | obj_priv->ring); | ||
2275 | if (seqno == 0) | 2194 | if (seqno == 0) |
2276 | return -ENOMEM; | 2195 | return -ENOMEM; |
2277 | continue; | 2196 | continue; |
@@ -2299,6 +2218,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, | |||
2299 | struct inode *inode; | 2218 | struct inode *inode; |
2300 | struct page *page; | 2219 | struct page *page; |
2301 | 2220 | ||
2221 | BUG_ON(obj_priv->pages_refcount | ||
2222 | == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); | ||
2223 | |||
2302 | if (obj_priv->pages_refcount++ != 0) | 2224 | if (obj_priv->pages_refcount++ != 0) |
2303 | return 0; | 2225 | return 0; |
2304 | 2226 | ||
@@ -2697,6 +2619,14 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2697 | return -EINVAL; | 2619 | return -EINVAL; |
2698 | } | 2620 | } |
2699 | 2621 | ||
2622 | /* If the object is bigger than the entire aperture, reject it early | ||
2623 | * before evicting everything in a vain attempt to find space. | ||
2624 | */ | ||
2625 | if (obj->size > dev->gtt_total) { | ||
2626 | DRM_ERROR("Attempting to bind an object larger than the aperture\n"); | ||
2627 | return -E2BIG; | ||
2628 | } | ||
2629 | |||
2700 | search_free: | 2630 | search_free: |
2701 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, | 2631 | free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, |
2702 | obj->size, alignment, 0); | 2632 | obj->size, alignment, 0); |
@@ -2807,6 +2737,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | |||
2807 | { | 2737 | { |
2808 | struct drm_device *dev = obj->dev; | 2738 | struct drm_device *dev = obj->dev; |
2809 | uint32_t old_write_domain; | 2739 | uint32_t old_write_domain; |
2740 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
2810 | 2741 | ||
2811 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) | 2742 | if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
2812 | return; | 2743 | return; |
@@ -2814,7 +2745,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | |||
2814 | /* Queue the GPU write cache flushing we need. */ | 2745 | /* Queue the GPU write cache flushing we need. */ |
2815 | old_write_domain = obj->write_domain; | 2746 | old_write_domain = obj->write_domain; |
2816 | i915_gem_flush(dev, 0, obj->write_domain); | 2747 | i915_gem_flush(dev, 0, obj->write_domain); |
2817 | (void) i915_add_request(dev, NULL, obj->write_domain); | 2748 | (void) i915_add_request(dev, NULL, obj->write_domain, obj_priv->ring); |
2818 | BUG_ON(obj->write_domain); | 2749 | BUG_ON(obj->write_domain); |
2819 | 2750 | ||
2820 | trace_i915_gem_object_change_domain(obj, | 2751 | trace_i915_gem_object_change_domain(obj, |
@@ -2954,23 +2885,24 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) | |||
2954 | DRM_INFO("%s: object %p wait for seqno %08x\n", | 2885 | DRM_INFO("%s: object %p wait for seqno %08x\n", |
2955 | __func__, obj, obj_priv->last_rendering_seqno); | 2886 | __func__, obj, obj_priv->last_rendering_seqno); |
2956 | #endif | 2887 | #endif |
2957 | ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); | 2888 | ret = i915_do_wait_request(dev, |
2889 | obj_priv->last_rendering_seqno, | ||
2890 | 0, | ||
2891 | obj_priv->ring); | ||
2958 | if (ret != 0) | 2892 | if (ret != 0) |
2959 | return ret; | 2893 | return ret; |
2960 | } | 2894 | } |
2961 | 2895 | ||
2896 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2897 | |||
2962 | old_write_domain = obj->write_domain; | 2898 | old_write_domain = obj->write_domain; |
2963 | old_read_domains = obj->read_domains; | 2899 | old_read_domains = obj->read_domains; |
2964 | 2900 | ||
2965 | obj->read_domains &= I915_GEM_DOMAIN_GTT; | ||
2966 | |||
2967 | i915_gem_object_flush_cpu_write_domain(obj); | ||
2968 | |||
2969 | /* It should now be out of any other write domains, and we can update | 2901 | /* It should now be out of any other write domains, and we can update |
2970 | * the domain values for our changes. | 2902 | * the domain values for our changes. |
2971 | */ | 2903 | */ |
2972 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | 2904 | BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); |
2973 | obj->read_domains |= I915_GEM_DOMAIN_GTT; | 2905 | obj->read_domains = I915_GEM_DOMAIN_GTT; |
2974 | obj->write_domain = I915_GEM_DOMAIN_GTT; | 2906 | obj->write_domain = I915_GEM_DOMAIN_GTT; |
2975 | obj_priv->dirty = 1; | 2907 | obj_priv->dirty = 1; |
2976 | 2908 | ||
@@ -3354,9 +3286,13 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3354 | obj_priv->tiling_mode != I915_TILING_NONE; | 3286 | obj_priv->tiling_mode != I915_TILING_NONE; |
3355 | 3287 | ||
3356 | /* Check fence reg constraints and rebind if necessary */ | 3288 | /* Check fence reg constraints and rebind if necessary */ |
3357 | if (need_fence && !i915_gem_object_fence_offset_ok(obj, | 3289 | if (need_fence && |
3358 | obj_priv->tiling_mode)) | 3290 | !i915_gem_object_fence_offset_ok(obj, |
3359 | i915_gem_object_unbind(obj); | 3291 | obj_priv->tiling_mode)) { |
3292 | ret = i915_gem_object_unbind(obj); | ||
3293 | if (ret) | ||
3294 | return ret; | ||
3295 | } | ||
3360 | 3296 | ||
3361 | /* Choose the GTT offset for our buffer and put it there. */ | 3297 | /* Choose the GTT offset for our buffer and put it there. */ |
3362 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); | 3298 | ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment); |
@@ -3370,9 +3306,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3370 | if (need_fence) { | 3306 | if (need_fence) { |
3371 | ret = i915_gem_object_get_fence_reg(obj); | 3307 | ret = i915_gem_object_get_fence_reg(obj); |
3372 | if (ret != 0) { | 3308 | if (ret != 0) { |
3373 | if (ret != -EBUSY && ret != -ERESTARTSYS) | ||
3374 | DRM_ERROR("Failure to install fence: %d\n", | ||
3375 | ret); | ||
3376 | i915_gem_object_unpin(obj); | 3309 | i915_gem_object_unpin(obj); |
3377 | return ret; | 3310 | return ret; |
3378 | } | 3311 | } |
@@ -3545,62 +3478,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3545 | return 0; | 3478 | return 0; |
3546 | } | 3479 | } |
3547 | 3480 | ||
3548 | /** Dispatch a batchbuffer to the ring | ||
3549 | */ | ||
3550 | static int | ||
3551 | i915_dispatch_gem_execbuffer(struct drm_device *dev, | ||
3552 | struct drm_i915_gem_execbuffer2 *exec, | ||
3553 | struct drm_clip_rect *cliprects, | ||
3554 | uint64_t exec_offset) | ||
3555 | { | ||
3556 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3557 | int nbox = exec->num_cliprects; | ||
3558 | int i = 0, count; | ||
3559 | uint32_t exec_start, exec_len; | ||
3560 | RING_LOCALS; | ||
3561 | |||
3562 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
3563 | exec_len = (uint32_t) exec->batch_len; | ||
3564 | |||
3565 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | ||
3566 | |||
3567 | count = nbox ? nbox : 1; | ||
3568 | |||
3569 | for (i = 0; i < count; i++) { | ||
3570 | if (i < nbox) { | ||
3571 | int ret = i915_emit_box(dev, cliprects, i, | ||
3572 | exec->DR1, exec->DR4); | ||
3573 | if (ret) | ||
3574 | return ret; | ||
3575 | } | ||
3576 | |||
3577 | if (IS_I830(dev) || IS_845G(dev)) { | ||
3578 | BEGIN_LP_RING(4); | ||
3579 | OUT_RING(MI_BATCH_BUFFER); | ||
3580 | OUT_RING(exec_start | MI_BATCH_NON_SECURE); | ||
3581 | OUT_RING(exec_start + exec_len - 4); | ||
3582 | OUT_RING(0); | ||
3583 | ADVANCE_LP_RING(); | ||
3584 | } else { | ||
3585 | BEGIN_LP_RING(2); | ||
3586 | if (IS_I965G(dev)) { | ||
3587 | OUT_RING(MI_BATCH_BUFFER_START | | ||
3588 | (2 << 6) | | ||
3589 | MI_BATCH_NON_SECURE_I965); | ||
3590 | OUT_RING(exec_start); | ||
3591 | } else { | ||
3592 | OUT_RING(MI_BATCH_BUFFER_START | | ||
3593 | (2 << 6)); | ||
3594 | OUT_RING(exec_start | MI_BATCH_NON_SECURE); | ||
3595 | } | ||
3596 | ADVANCE_LP_RING(); | ||
3597 | } | ||
3598 | } | ||
3599 | |||
3600 | /* XXX breadcrumb */ | ||
3601 | return 0; | ||
3602 | } | ||
3603 | |||
3604 | /* Throttle our rendering by waiting until the ring has completed our requests | 3481 | /* Throttle our rendering by waiting until the ring has completed our requests |
3605 | * emitted over 20 msec ago. | 3482 | * emitted over 20 msec ago. |
3606 | * | 3483 | * |
@@ -3629,7 +3506,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv) | |||
3629 | if (time_after_eq(request->emitted_jiffies, recent_enough)) | 3506 | if (time_after_eq(request->emitted_jiffies, recent_enough)) |
3630 | break; | 3507 | break; |
3631 | 3508 | ||
3632 | ret = i915_wait_request(dev, request->seqno); | 3509 | ret = i915_wait_request(dev, request->seqno, request->ring); |
3633 | if (ret != 0) | 3510 | if (ret != 0) |
3634 | break; | 3511 | break; |
3635 | } | 3512 | } |
@@ -3786,10 +3663,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3786 | uint32_t seqno, flush_domains, reloc_index; | 3663 | uint32_t seqno, flush_domains, reloc_index; |
3787 | int pin_tries, flips; | 3664 | int pin_tries, flips; |
3788 | 3665 | ||
3666 | struct intel_ring_buffer *ring = NULL; | ||
3667 | |||
3789 | #if WATCH_EXEC | 3668 | #if WATCH_EXEC |
3790 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", | 3669 | DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", |
3791 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); | 3670 | (int) args->buffers_ptr, args->buffer_count, args->batch_len); |
3792 | #endif | 3671 | #endif |
3672 | if (args->flags & I915_EXEC_BSD) { | ||
3673 | if (!HAS_BSD(dev)) { | ||
3674 | DRM_ERROR("execbuf with wrong flag\n"); | ||
3675 | return -EINVAL; | ||
3676 | } | ||
3677 | ring = &dev_priv->bsd_ring; | ||
3678 | } else { | ||
3679 | ring = &dev_priv->render_ring; | ||
3680 | } | ||
3681 | |||
3793 | 3682 | ||
3794 | if (args->buffer_count < 1) { | 3683 | if (args->buffer_count < 1) { |
3795 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3684 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
@@ -3902,11 +3791,19 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3902 | if (ret != -ENOSPC || pin_tries >= 1) { | 3791 | if (ret != -ENOSPC || pin_tries >= 1) { |
3903 | if (ret != -ERESTARTSYS) { | 3792 | if (ret != -ERESTARTSYS) { |
3904 | unsigned long long total_size = 0; | 3793 | unsigned long long total_size = 0; |
3905 | for (i = 0; i < args->buffer_count; i++) | 3794 | int num_fences = 0; |
3795 | for (i = 0; i < args->buffer_count; i++) { | ||
3796 | obj_priv = object_list[i]->driver_private; | ||
3797 | |||
3906 | total_size += object_list[i]->size; | 3798 | total_size += object_list[i]->size; |
3907 | DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n", | 3799 | num_fences += |
3800 | exec_list[i].flags & EXEC_OBJECT_NEEDS_FENCE && | ||
3801 | obj_priv->tiling_mode != I915_TILING_NONE; | ||
3802 | } | ||
3803 | DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes, %d fences: %d\n", | ||
3908 | pinned+1, args->buffer_count, | 3804 | pinned+1, args->buffer_count, |
3909 | total_size, ret); | 3805 | total_size, num_fences, |
3806 | ret); | ||
3910 | DRM_ERROR("%d objects [%d pinned], " | 3807 | DRM_ERROR("%d objects [%d pinned], " |
3911 | "%d object bytes [%d pinned], " | 3808 | "%d object bytes [%d pinned], " |
3912 | "%d/%d gtt bytes\n", | 3809 | "%d/%d gtt bytes\n", |
@@ -3976,9 +3873,16 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3976 | i915_gem_flush(dev, | 3873 | i915_gem_flush(dev, |
3977 | dev->invalidate_domains, | 3874 | dev->invalidate_domains, |
3978 | dev->flush_domains); | 3875 | dev->flush_domains); |
3979 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) | 3876 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { |
3980 | (void)i915_add_request(dev, file_priv, | 3877 | (void)i915_add_request(dev, file_priv, |
3981 | dev->flush_domains); | 3878 | dev->flush_domains, |
3879 | &dev_priv->render_ring); | ||
3880 | |||
3881 | if (HAS_BSD(dev)) | ||
3882 | (void)i915_add_request(dev, file_priv, | ||
3883 | dev->flush_domains, | ||
3884 | &dev_priv->bsd_ring); | ||
3885 | } | ||
3982 | } | 3886 | } |
3983 | 3887 | ||
3984 | for (i = 0; i < args->buffer_count; i++) { | 3888 | for (i = 0; i < args->buffer_count; i++) { |
@@ -4015,7 +3919,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
4015 | #endif | 3919 | #endif |
4016 | 3920 | ||
4017 | /* Exec the batchbuffer */ | 3921 | /* Exec the batchbuffer */ |
4018 | ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset); | 3922 | ret = ring->dispatch_gem_execbuffer(dev, ring, args, |
3923 | cliprects, exec_offset); | ||
4019 | if (ret) { | 3924 | if (ret) { |
4020 | DRM_ERROR("dispatch failed %d\n", ret); | 3925 | DRM_ERROR("dispatch failed %d\n", ret); |
4021 | goto err; | 3926 | goto err; |
@@ -4025,7 +3930,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
4025 | * Ensure that the commands in the batch buffer are | 3930 | * Ensure that the commands in the batch buffer are |
4026 | * finished before the interrupt fires | 3931 | * finished before the interrupt fires |
4027 | */ | 3932 | */ |
4028 | flush_domains = i915_retire_commands(dev); | 3933 | flush_domains = i915_retire_commands(dev, ring); |
4029 | 3934 | ||
4030 | i915_verify_inactive(dev, __FILE__, __LINE__); | 3935 | i915_verify_inactive(dev, __FILE__, __LINE__); |
4031 | 3936 | ||
@@ -4036,12 +3941,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
4036 | * *some* interrupts representing completion of buffers that we can | 3941 | * *some* interrupts representing completion of buffers that we can |
4037 | * wait on when trying to clear up gtt space). | 3942 | * wait on when trying to clear up gtt space). |
4038 | */ | 3943 | */ |
4039 | seqno = i915_add_request(dev, file_priv, flush_domains); | 3944 | seqno = i915_add_request(dev, file_priv, flush_domains, ring); |
4040 | BUG_ON(seqno == 0); | 3945 | BUG_ON(seqno == 0); |
4041 | for (i = 0; i < args->buffer_count; i++) { | 3946 | for (i = 0; i < args->buffer_count; i++) { |
4042 | struct drm_gem_object *obj = object_list[i]; | 3947 | struct drm_gem_object *obj = object_list[i]; |
3948 | obj_priv = to_intel_bo(obj); | ||
4043 | 3949 | ||
4044 | i915_gem_object_move_to_active(obj, seqno); | 3950 | i915_gem_object_move_to_active(obj, seqno, ring); |
4045 | #if WATCH_LRU | 3951 | #if WATCH_LRU |
4046 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); | 3952 | DRM_INFO("%s: move to exec list %p\n", __func__, obj); |
4047 | #endif | 3953 | #endif |
@@ -4153,7 +4059,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
4153 | exec2.DR4 = args->DR4; | 4059 | exec2.DR4 = args->DR4; |
4154 | exec2.num_cliprects = args->num_cliprects; | 4060 | exec2.num_cliprects = args->num_cliprects; |
4155 | exec2.cliprects_ptr = args->cliprects_ptr; | 4061 | exec2.cliprects_ptr = args->cliprects_ptr; |
4156 | exec2.flags = 0; | 4062 | exec2.flags = I915_EXEC_RENDER; |
4157 | 4063 | ||
4158 | ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); | 4064 | ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); |
4159 | if (!ret) { | 4065 | if (!ret) { |
@@ -4239,7 +4145,20 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4239 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 4145 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
4240 | int ret; | 4146 | int ret; |
4241 | 4147 | ||
4148 | BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); | ||
4149 | |||
4242 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4150 | i915_verify_inactive(dev, __FILE__, __LINE__); |
4151 | |||
4152 | if (obj_priv->gtt_space != NULL) { | ||
4153 | if (alignment == 0) | ||
4154 | alignment = i915_gem_get_gtt_alignment(obj); | ||
4155 | if (obj_priv->gtt_offset & (alignment - 1)) { | ||
4156 | ret = i915_gem_object_unbind(obj); | ||
4157 | if (ret) | ||
4158 | return ret; | ||
4159 | } | ||
4160 | } | ||
4161 | |||
4243 | if (obj_priv->gtt_space == NULL) { | 4162 | if (obj_priv->gtt_space == NULL) { |
4244 | ret = i915_gem_object_bind_to_gtt(obj, alignment); | 4163 | ret = i915_gem_object_bind_to_gtt(obj, alignment); |
4245 | if (ret) | 4164 | if (ret) |
@@ -4392,6 +4311,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4392 | struct drm_i915_gem_busy *args = data; | 4311 | struct drm_i915_gem_busy *args = data; |
4393 | struct drm_gem_object *obj; | 4312 | struct drm_gem_object *obj; |
4394 | struct drm_i915_gem_object *obj_priv; | 4313 | struct drm_i915_gem_object *obj_priv; |
4314 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4395 | 4315 | ||
4396 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 4316 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
4397 | if (obj == NULL) { | 4317 | if (obj == NULL) { |
@@ -4406,7 +4326,10 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4406 | * actually unmasked, and our working set ends up being larger than | 4326 | * actually unmasked, and our working set ends up being larger than |
4407 | * required. | 4327 | * required. |
4408 | */ | 4328 | */ |
4409 | i915_gem_retire_requests(dev); | 4329 | i915_gem_retire_requests(dev, &dev_priv->render_ring); |
4330 | |||
4331 | if (HAS_BSD(dev)) | ||
4332 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
4410 | 4333 | ||
4411 | obj_priv = to_intel_bo(obj); | 4334 | obj_priv = to_intel_bo(obj); |
4412 | /* Don't count being on the flushing list against the object being | 4335 | /* Don't count being on the flushing list against the object being |
@@ -4573,7 +4496,10 @@ i915_gem_idle(struct drm_device *dev) | |||
4573 | 4496 | ||
4574 | mutex_lock(&dev->struct_mutex); | 4497 | mutex_lock(&dev->struct_mutex); |
4575 | 4498 | ||
4576 | if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) { | 4499 | if (dev_priv->mm.suspended || |
4500 | (dev_priv->render_ring.gem_object == NULL) || | ||
4501 | (HAS_BSD(dev) && | ||
4502 | dev_priv->bsd_ring.gem_object == NULL)) { | ||
4577 | mutex_unlock(&dev->struct_mutex); | 4503 | mutex_unlock(&dev->struct_mutex); |
4578 | return 0; | 4504 | return 0; |
4579 | } | 4505 | } |
@@ -4654,71 +4580,6 @@ err: | |||
4654 | return ret; | 4580 | return ret; |
4655 | } | 4581 | } |
4656 | 4582 | ||
4657 | static int | ||
4658 | i915_gem_init_hws(struct drm_device *dev) | ||
4659 | { | ||
4660 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4661 | struct drm_gem_object *obj; | ||
4662 | struct drm_i915_gem_object *obj_priv; | ||
4663 | int ret; | ||
4664 | |||
4665 | /* If we need a physical address for the status page, it's already | ||
4666 | * initialized at driver load time. | ||
4667 | */ | ||
4668 | if (!I915_NEED_GFX_HWS(dev)) | ||
4669 | return 0; | ||
4670 | |||
4671 | obj = i915_gem_alloc_object(dev, 4096); | ||
4672 | if (obj == NULL) { | ||
4673 | DRM_ERROR("Failed to allocate status page\n"); | ||
4674 | ret = -ENOMEM; | ||
4675 | goto err; | ||
4676 | } | ||
4677 | obj_priv = to_intel_bo(obj); | ||
4678 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
4679 | |||
4680 | ret = i915_gem_object_pin(obj, 4096); | ||
4681 | if (ret != 0) { | ||
4682 | drm_gem_object_unreference(obj); | ||
4683 | goto err_unref; | ||
4684 | } | ||
4685 | |||
4686 | dev_priv->status_gfx_addr = obj_priv->gtt_offset; | ||
4687 | |||
4688 | dev_priv->hw_status_page = kmap(obj_priv->pages[0]); | ||
4689 | if (dev_priv->hw_status_page == NULL) { | ||
4690 | DRM_ERROR("Failed to map status page.\n"); | ||
4691 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
4692 | ret = -EINVAL; | ||
4693 | goto err_unpin; | ||
4694 | } | ||
4695 | |||
4696 | if (HAS_PIPE_CONTROL(dev)) { | ||
4697 | ret = i915_gem_init_pipe_control(dev); | ||
4698 | if (ret) | ||
4699 | goto err_unpin; | ||
4700 | } | ||
4701 | |||
4702 | dev_priv->hws_obj = obj; | ||
4703 | memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
4704 | if (IS_GEN6(dev)) { | ||
4705 | I915_WRITE(HWS_PGA_GEN6, dev_priv->status_gfx_addr); | ||
4706 | I915_READ(HWS_PGA_GEN6); /* posting read */ | ||
4707 | } else { | ||
4708 | I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); | ||
4709 | I915_READ(HWS_PGA); /* posting read */ | ||
4710 | } | ||
4711 | DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr); | ||
4712 | |||
4713 | return 0; | ||
4714 | |||
4715 | err_unpin: | ||
4716 | i915_gem_object_unpin(obj); | ||
4717 | err_unref: | ||
4718 | drm_gem_object_unreference(obj); | ||
4719 | err: | ||
4720 | return 0; | ||
4721 | } | ||
4722 | 4583 | ||
4723 | static void | 4584 | static void |
4724 | i915_gem_cleanup_pipe_control(struct drm_device *dev) | 4585 | i915_gem_cleanup_pipe_control(struct drm_device *dev) |
@@ -4737,146 +4598,46 @@ i915_gem_cleanup_pipe_control(struct drm_device *dev) | |||
4737 | dev_priv->seqno_page = NULL; | 4598 | dev_priv->seqno_page = NULL; |
4738 | } | 4599 | } |
4739 | 4600 | ||
4740 | static void | ||
4741 | i915_gem_cleanup_hws(struct drm_device *dev) | ||
4742 | { | ||
4743 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4744 | struct drm_gem_object *obj; | ||
4745 | struct drm_i915_gem_object *obj_priv; | ||
4746 | |||
4747 | if (dev_priv->hws_obj == NULL) | ||
4748 | return; | ||
4749 | |||
4750 | obj = dev_priv->hws_obj; | ||
4751 | obj_priv = to_intel_bo(obj); | ||
4752 | |||
4753 | kunmap(obj_priv->pages[0]); | ||
4754 | i915_gem_object_unpin(obj); | ||
4755 | drm_gem_object_unreference(obj); | ||
4756 | dev_priv->hws_obj = NULL; | ||
4757 | |||
4758 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
4759 | dev_priv->hw_status_page = NULL; | ||
4760 | |||
4761 | if (HAS_PIPE_CONTROL(dev)) | ||
4762 | i915_gem_cleanup_pipe_control(dev); | ||
4763 | |||
4764 | /* Write high address into HWS_PGA when disabling. */ | ||
4765 | I915_WRITE(HWS_PGA, 0x1ffff000); | ||
4766 | } | ||
4767 | |||
4768 | int | 4601 | int |
4769 | i915_gem_init_ringbuffer(struct drm_device *dev) | 4602 | i915_gem_init_ringbuffer(struct drm_device *dev) |
4770 | { | 4603 | { |
4771 | drm_i915_private_t *dev_priv = dev->dev_private; | 4604 | drm_i915_private_t *dev_priv = dev->dev_private; |
4772 | struct drm_gem_object *obj; | ||
4773 | struct drm_i915_gem_object *obj_priv; | ||
4774 | drm_i915_ring_buffer_t *ring = &dev_priv->ring; | ||
4775 | int ret; | 4605 | int ret; |
4776 | u32 head; | ||
4777 | |||
4778 | ret = i915_gem_init_hws(dev); | ||
4779 | if (ret != 0) | ||
4780 | return ret; | ||
4781 | 4606 | ||
4782 | obj = i915_gem_alloc_object(dev, 128 * 1024); | 4607 | dev_priv->render_ring = render_ring; |
4783 | if (obj == NULL) { | ||
4784 | DRM_ERROR("Failed to allocate ringbuffer\n"); | ||
4785 | i915_gem_cleanup_hws(dev); | ||
4786 | return -ENOMEM; | ||
4787 | } | ||
4788 | obj_priv = to_intel_bo(obj); | ||
4789 | 4608 | ||
4790 | ret = i915_gem_object_pin(obj, 4096); | 4609 | if (!I915_NEED_GFX_HWS(dev)) { |
4791 | if (ret != 0) { | 4610 | dev_priv->render_ring.status_page.page_addr |
4792 | drm_gem_object_unreference(obj); | 4611 | = dev_priv->status_page_dmah->vaddr; |
4793 | i915_gem_cleanup_hws(dev); | 4612 | memset(dev_priv->render_ring.status_page.page_addr, |
4794 | return ret; | 4613 | 0, PAGE_SIZE); |
4795 | } | 4614 | } |
4796 | 4615 | ||
4797 | /* Set up the kernel mapping for the ring. */ | 4616 | if (HAS_PIPE_CONTROL(dev)) { |
4798 | ring->Size = obj->size; | 4617 | ret = i915_gem_init_pipe_control(dev); |
4799 | 4618 | if (ret) | |
4800 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | 4619 | return ret; |
4801 | ring->map.size = obj->size; | ||
4802 | ring->map.type = 0; | ||
4803 | ring->map.flags = 0; | ||
4804 | ring->map.mtrr = 0; | ||
4805 | |||
4806 | drm_core_ioremap_wc(&ring->map, dev); | ||
4807 | if (ring->map.handle == NULL) { | ||
4808 | DRM_ERROR("Failed to map ringbuffer.\n"); | ||
4809 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | ||
4810 | i915_gem_object_unpin(obj); | ||
4811 | drm_gem_object_unreference(obj); | ||
4812 | i915_gem_cleanup_hws(dev); | ||
4813 | return -EINVAL; | ||
4814 | } | ||
4815 | ring->ring_obj = obj; | ||
4816 | ring->virtual_start = ring->map.handle; | ||
4817 | |||
4818 | /* Stop the ring if it's running. */ | ||
4819 | I915_WRITE(PRB0_CTL, 0); | ||
4820 | I915_WRITE(PRB0_TAIL, 0); | ||
4821 | I915_WRITE(PRB0_HEAD, 0); | ||
4822 | |||
4823 | /* Initialize the ring. */ | ||
4824 | I915_WRITE(PRB0_START, obj_priv->gtt_offset); | ||
4825 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
4826 | |||
4827 | /* G45 ring initialization fails to reset head to zero */ | ||
4828 | if (head != 0) { | ||
4829 | DRM_ERROR("Ring head not reset to zero " | ||
4830 | "ctl %08x head %08x tail %08x start %08x\n", | ||
4831 | I915_READ(PRB0_CTL), | ||
4832 | I915_READ(PRB0_HEAD), | ||
4833 | I915_READ(PRB0_TAIL), | ||
4834 | I915_READ(PRB0_START)); | ||
4835 | I915_WRITE(PRB0_HEAD, 0); | ||
4836 | |||
4837 | DRM_ERROR("Ring head forced to zero " | ||
4838 | "ctl %08x head %08x tail %08x start %08x\n", | ||
4839 | I915_READ(PRB0_CTL), | ||
4840 | I915_READ(PRB0_HEAD), | ||
4841 | I915_READ(PRB0_TAIL), | ||
4842 | I915_READ(PRB0_START)); | ||
4843 | } | ||
4844 | |||
4845 | I915_WRITE(PRB0_CTL, | ||
4846 | ((obj->size - 4096) & RING_NR_PAGES) | | ||
4847 | RING_NO_REPORT | | ||
4848 | RING_VALID); | ||
4849 | |||
4850 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
4851 | |||
4852 | /* If the head is still not zero, the ring is dead */ | ||
4853 | if (head != 0) { | ||
4854 | DRM_ERROR("Ring initialization failed " | ||
4855 | "ctl %08x head %08x tail %08x start %08x\n", | ||
4856 | I915_READ(PRB0_CTL), | ||
4857 | I915_READ(PRB0_HEAD), | ||
4858 | I915_READ(PRB0_TAIL), | ||
4859 | I915_READ(PRB0_START)); | ||
4860 | return -EIO; | ||
4861 | } | 4620 | } |
4862 | 4621 | ||
4863 | /* Update our cache of the ring state */ | 4622 | ret = intel_init_ring_buffer(dev, &dev_priv->render_ring); |
4864 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 4623 | if (ret) |
4865 | i915_kernel_lost_context(dev); | 4624 | goto cleanup_pipe_control; |
4866 | else { | ||
4867 | ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
4868 | ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; | ||
4869 | ring->space = ring->head - (ring->tail + 8); | ||
4870 | if (ring->space < 0) | ||
4871 | ring->space += ring->Size; | ||
4872 | } | ||
4873 | 4625 | ||
4874 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { | 4626 | if (HAS_BSD(dev)) { |
4875 | I915_WRITE(MI_MODE, | 4627 | dev_priv->bsd_ring = bsd_ring; |
4876 | (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | 4628 | ret = intel_init_ring_buffer(dev, &dev_priv->bsd_ring); |
4629 | if (ret) | ||
4630 | goto cleanup_render_ring; | ||
4877 | } | 4631 | } |
4878 | 4632 | ||
4879 | return 0; | 4633 | return 0; |
4634 | |||
4635 | cleanup_render_ring: | ||
4636 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); | ||
4637 | cleanup_pipe_control: | ||
4638 | if (HAS_PIPE_CONTROL(dev)) | ||
4639 | i915_gem_cleanup_pipe_control(dev); | ||
4640 | return ret; | ||
4880 | } | 4641 | } |
4881 | 4642 | ||
4882 | void | 4643 | void |
@@ -4884,17 +4645,11 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) | |||
4884 | { | 4645 | { |
4885 | drm_i915_private_t *dev_priv = dev->dev_private; | 4646 | drm_i915_private_t *dev_priv = dev->dev_private; |
4886 | 4647 | ||
4887 | if (dev_priv->ring.ring_obj == NULL) | 4648 | intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); |
4888 | return; | 4649 | if (HAS_BSD(dev)) |
4889 | 4650 | intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); | |
4890 | drm_core_ioremapfree(&dev_priv->ring.map, dev); | 4651 | if (HAS_PIPE_CONTROL(dev)) |
4891 | 4652 | i915_gem_cleanup_pipe_control(dev); | |
4892 | i915_gem_object_unpin(dev_priv->ring.ring_obj); | ||
4893 | drm_gem_object_unreference(dev_priv->ring.ring_obj); | ||
4894 | dev_priv->ring.ring_obj = NULL; | ||
4895 | memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); | ||
4896 | |||
4897 | i915_gem_cleanup_hws(dev); | ||
4898 | } | 4653 | } |
4899 | 4654 | ||
4900 | int | 4655 | int |
@@ -4922,12 +4677,14 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
4922 | } | 4677 | } |
4923 | 4678 | ||
4924 | spin_lock(&dev_priv->mm.active_list_lock); | 4679 | spin_lock(&dev_priv->mm.active_list_lock); |
4925 | BUG_ON(!list_empty(&dev_priv->mm.active_list)); | 4680 | BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); |
4681 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.active_list)); | ||
4926 | spin_unlock(&dev_priv->mm.active_list_lock); | 4682 | spin_unlock(&dev_priv->mm.active_list_lock); |
4927 | 4683 | ||
4928 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | 4684 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); |
4929 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); | 4685 | BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); |
4930 | BUG_ON(!list_empty(&dev_priv->mm.request_list)); | 4686 | BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); |
4687 | BUG_ON(HAS_BSD(dev) && !list_empty(&dev_priv->bsd_ring.request_list)); | ||
4931 | mutex_unlock(&dev->struct_mutex); | 4688 | mutex_unlock(&dev->struct_mutex); |
4932 | 4689 | ||
4933 | drm_irq_install(dev); | 4690 | drm_irq_install(dev); |
@@ -4966,18 +4723,20 @@ i915_gem_load(struct drm_device *dev) | |||
4966 | drm_i915_private_t *dev_priv = dev->dev_private; | 4723 | drm_i915_private_t *dev_priv = dev->dev_private; |
4967 | 4724 | ||
4968 | spin_lock_init(&dev_priv->mm.active_list_lock); | 4725 | spin_lock_init(&dev_priv->mm.active_list_lock); |
4969 | INIT_LIST_HEAD(&dev_priv->mm.active_list); | ||
4970 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4726 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4971 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); | 4727 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); |
4972 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4728 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4973 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | ||
4974 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4729 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
4730 | INIT_LIST_HEAD(&dev_priv->render_ring.active_list); | ||
4731 | INIT_LIST_HEAD(&dev_priv->render_ring.request_list); | ||
4732 | if (HAS_BSD(dev)) { | ||
4733 | INIT_LIST_HEAD(&dev_priv->bsd_ring.active_list); | ||
4734 | INIT_LIST_HEAD(&dev_priv->bsd_ring.request_list); | ||
4735 | } | ||
4975 | for (i = 0; i < 16; i++) | 4736 | for (i = 0; i < 16; i++) |
4976 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); | 4737 | INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); |
4977 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, | 4738 | INIT_DELAYED_WORK(&dev_priv->mm.retire_work, |
4978 | i915_gem_retire_work_handler); | 4739 | i915_gem_retire_work_handler); |
4979 | dev_priv->mm.next_gem_seqno = 1; | ||
4980 | |||
4981 | spin_lock(&shrink_list_lock); | 4740 | spin_lock(&shrink_list_lock); |
4982 | list_add(&dev_priv->mm.shrink_list, &shrink_list); | 4741 | list_add(&dev_priv->mm.shrink_list, &shrink_list); |
4983 | spin_unlock(&shrink_list_lock); | 4742 | spin_unlock(&shrink_list_lock); |
@@ -5209,7 +4968,9 @@ i915_gpu_is_active(struct drm_device *dev) | |||
5209 | 4968 | ||
5210 | spin_lock(&dev_priv->mm.active_list_lock); | 4969 | spin_lock(&dev_priv->mm.active_list_lock); |
5211 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && | 4970 | lists_empty = list_empty(&dev_priv->mm.flushing_list) && |
5212 | list_empty(&dev_priv->mm.active_list); | 4971 | list_empty(&dev_priv->render_ring.active_list); |
4972 | if (HAS_BSD(dev)) | ||
4973 | lists_empty &= list_empty(&dev_priv->bsd_ring.active_list); | ||
5213 | spin_unlock(&dev_priv->mm.active_list_lock); | 4974 | spin_unlock(&dev_priv->mm.active_list_lock); |
5214 | 4975 | ||
5215 | return !lists_empty; | 4976 | return !lists_empty; |
@@ -5254,8 +5015,10 @@ rescan: | |||
5254 | continue; | 5015 | continue; |
5255 | 5016 | ||
5256 | spin_unlock(&shrink_list_lock); | 5017 | spin_unlock(&shrink_list_lock); |
5018 | i915_gem_retire_requests(dev, &dev_priv->render_ring); | ||
5257 | 5019 | ||
5258 | i915_gem_retire_requests(dev); | 5020 | if (HAS_BSD(dev)) |
5021 | i915_gem_retire_requests(dev, &dev_priv->bsd_ring); | ||
5259 | 5022 | ||
5260 | list_for_each_entry_safe(obj_priv, next_obj, | 5023 | list_for_each_entry_safe(obj_priv, next_obj, |
5261 | &dev_priv->mm.inactive_list, | 5024 | &dev_priv->mm.inactive_list, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8c3f0802686d..2479be001e40 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -53,7 +53,7 @@ | |||
53 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | 53 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) |
54 | 54 | ||
55 | /** Interrupts that we mask and unmask at runtime. */ | 55 | /** Interrupts that we mask and unmask at runtime. */ |
56 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | 56 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT | I915_BSD_USER_INTERRUPT) |
57 | 57 | ||
58 | #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ | 58 | #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ |
59 | PIPE_VBLANK_INTERRUPT_STATUS) | 59 | PIPE_VBLANK_INTERRUPT_STATUS) |
@@ -74,7 +74,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | static inline void | 77 | void |
78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) | 78 | ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) |
79 | { | 79 | { |
80 | if ((dev_priv->gt_irq_mask_reg & mask) != mask) { | 80 | if ((dev_priv->gt_irq_mask_reg & mask) != mask) { |
@@ -115,7 +115,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) | |||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | static inline void | 118 | void |
119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) | 119 | i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) |
120 | { | 120 | { |
121 | if ((dev_priv->irq_mask_reg & mask) != mask) { | 121 | if ((dev_priv->irq_mask_reg & mask) != mask) { |
@@ -278,10 +278,9 @@ static void i915_handle_rps_change(struct drm_device *dev) | |||
278 | { | 278 | { |
279 | drm_i915_private_t *dev_priv = dev->dev_private; | 279 | drm_i915_private_t *dev_priv = dev->dev_private; |
280 | u32 busy_up, busy_down, max_avg, min_avg; | 280 | u32 busy_up, busy_down, max_avg, min_avg; |
281 | u16 rgvswctl; | ||
282 | u8 new_delay = dev_priv->cur_delay; | 281 | u8 new_delay = dev_priv->cur_delay; |
283 | 282 | ||
284 | I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS) & ~MEMINT_EVAL_CHG); | 283 | I915_WRITE16(MEMINTRSTS, MEMINT_EVAL_CHG); |
285 | busy_up = I915_READ(RCPREVBSYTUPAVG); | 284 | busy_up = I915_READ(RCPREVBSYTUPAVG); |
286 | busy_down = I915_READ(RCPREVBSYTDNAVG); | 285 | busy_down = I915_READ(RCPREVBSYTDNAVG); |
287 | max_avg = I915_READ(RCBMAXAVG); | 286 | max_avg = I915_READ(RCBMAXAVG); |
@@ -300,27 +299,8 @@ static void i915_handle_rps_change(struct drm_device *dev) | |||
300 | new_delay = dev_priv->min_delay; | 299 | new_delay = dev_priv->min_delay; |
301 | } | 300 | } |
302 | 301 | ||
303 | DRM_DEBUG("rps change requested: %d -> %d\n", | 302 | if (ironlake_set_drps(dev, new_delay)) |
304 | dev_priv->cur_delay, new_delay); | 303 | dev_priv->cur_delay = new_delay; |
305 | |||
306 | rgvswctl = I915_READ(MEMSWCTL); | ||
307 | if (rgvswctl & MEMCTL_CMD_STS) { | ||
308 | DRM_ERROR("gpu busy, RCS change rejected\n"); | ||
309 | return; /* still busy with another command */ | ||
310 | } | ||
311 | |||
312 | /* Program the new state */ | ||
313 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
314 | (new_delay << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
315 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
316 | POSTING_READ(MEMSWCTL); | ||
317 | |||
318 | rgvswctl |= MEMCTL_CMD_STS; | ||
319 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
320 | |||
321 | dev_priv->cur_delay = new_delay; | ||
322 | |||
323 | DRM_DEBUG("rps changed\n"); | ||
324 | 304 | ||
325 | return; | 305 | return; |
326 | } | 306 | } |
@@ -331,6 +311,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
331 | int ret = IRQ_NONE; | 311 | int ret = IRQ_NONE; |
332 | u32 de_iir, gt_iir, de_ier, pch_iir; | 312 | u32 de_iir, gt_iir, de_ier, pch_iir; |
333 | struct drm_i915_master_private *master_priv; | 313 | struct drm_i915_master_private *master_priv; |
314 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
334 | 315 | ||
335 | /* disable master interrupt before clearing iir */ | 316 | /* disable master interrupt before clearing iir */ |
336 | de_ier = I915_READ(DEIER); | 317 | de_ier = I915_READ(DEIER); |
@@ -354,13 +335,16 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
354 | } | 335 | } |
355 | 336 | ||
356 | if (gt_iir & GT_PIPE_NOTIFY) { | 337 | if (gt_iir & GT_PIPE_NOTIFY) { |
357 | u32 seqno = i915_get_gem_seqno(dev); | 338 | u32 seqno = render_ring->get_gem_seqno(dev, render_ring); |
358 | dev_priv->mm.irq_gem_seqno = seqno; | 339 | render_ring->irq_gem_seqno = seqno; |
359 | trace_i915_gem_request_complete(dev, seqno); | 340 | trace_i915_gem_request_complete(dev, seqno); |
360 | DRM_WAKEUP(&dev_priv->irq_queue); | 341 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
361 | dev_priv->hangcheck_count = 0; | 342 | dev_priv->hangcheck_count = 0; |
362 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 343 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
363 | } | 344 | } |
345 | if (gt_iir & GT_BSD_USER_INTERRUPT) | ||
346 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
347 | |||
364 | 348 | ||
365 | if (de_iir & DE_GSE) | 349 | if (de_iir & DE_GSE) |
366 | ironlake_opregion_gse_intr(dev); | 350 | ironlake_opregion_gse_intr(dev); |
@@ -388,7 +372,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
388 | } | 372 | } |
389 | 373 | ||
390 | if (de_iir & DE_PCU_EVENT) { | 374 | if (de_iir & DE_PCU_EVENT) { |
391 | I915_WRITE(MEMINTRSTS, I915_READ(MEMINTRSTS)); | 375 | I915_WRITE16(MEMINTRSTS, I915_READ(MEMINTRSTS)); |
392 | i915_handle_rps_change(dev); | 376 | i915_handle_rps_change(dev); |
393 | } | 377 | } |
394 | 378 | ||
@@ -536,17 +520,18 @@ i915_ringbuffer_last_batch(struct drm_device *dev) | |||
536 | */ | 520 | */ |
537 | bbaddr = 0; | 521 | bbaddr = 0; |
538 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; | 522 | head = I915_READ(PRB0_HEAD) & HEAD_ADDR; |
539 | ring = (u32 *)(dev_priv->ring.virtual_start + head); | 523 | ring = (u32 *)(dev_priv->render_ring.virtual_start + head); |
540 | 524 | ||
541 | while (--ring >= (u32 *)dev_priv->ring.virtual_start) { | 525 | while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { |
542 | bbaddr = i915_get_bbaddr(dev, ring); | 526 | bbaddr = i915_get_bbaddr(dev, ring); |
543 | if (bbaddr) | 527 | if (bbaddr) |
544 | break; | 528 | break; |
545 | } | 529 | } |
546 | 530 | ||
547 | if (bbaddr == 0) { | 531 | if (bbaddr == 0) { |
548 | ring = (u32 *)(dev_priv->ring.virtual_start + dev_priv->ring.Size); | 532 | ring = (u32 *)(dev_priv->render_ring.virtual_start |
549 | while (--ring >= (u32 *)dev_priv->ring.virtual_start) { | 533 | + dev_priv->render_ring.size); |
534 | while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { | ||
550 | bbaddr = i915_get_bbaddr(dev, ring); | 535 | bbaddr = i915_get_bbaddr(dev, ring); |
551 | if (bbaddr) | 536 | if (bbaddr) |
552 | break; | 537 | break; |
@@ -587,7 +572,7 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
587 | return; | 572 | return; |
588 | } | 573 | } |
589 | 574 | ||
590 | error->seqno = i915_get_gem_seqno(dev); | 575 | error->seqno = i915_get_gem_seqno(dev, &dev_priv->render_ring); |
591 | error->eir = I915_READ(EIR); | 576 | error->eir = I915_READ(EIR); |
592 | error->pgtbl_er = I915_READ(PGTBL_ER); | 577 | error->pgtbl_er = I915_READ(PGTBL_ER); |
593 | error->pipeastat = I915_READ(PIPEASTAT); | 578 | error->pipeastat = I915_READ(PIPEASTAT); |
@@ -615,7 +600,9 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
615 | batchbuffer[0] = NULL; | 600 | batchbuffer[0] = NULL; |
616 | batchbuffer[1] = NULL; | 601 | batchbuffer[1] = NULL; |
617 | count = 0; | 602 | count = 0; |
618 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 603 | list_for_each_entry(obj_priv, |
604 | &dev_priv->render_ring.active_list, list) { | ||
605 | |||
619 | struct drm_gem_object *obj = &obj_priv->base; | 606 | struct drm_gem_object *obj = &obj_priv->base; |
620 | 607 | ||
621 | if (batchbuffer[0] == NULL && | 608 | if (batchbuffer[0] == NULL && |
@@ -639,7 +626,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
639 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | 626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); |
640 | 627 | ||
641 | /* Record the ringbuffer */ | 628 | /* Record the ringbuffer */ |
642 | error->ringbuffer = i915_error_object_create(dev, dev_priv->ring.ring_obj); | 629 | error->ringbuffer = i915_error_object_create(dev, |
630 | dev_priv->render_ring.gem_object); | ||
643 | 631 | ||
644 | /* Record buffers on the active list. */ | 632 | /* Record buffers on the active list. */ |
645 | error->active_bo = NULL; | 633 | error->active_bo = NULL; |
@@ -651,7 +639,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
651 | 639 | ||
652 | if (error->active_bo) { | 640 | if (error->active_bo) { |
653 | int i = 0; | 641 | int i = 0; |
654 | list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { | 642 | list_for_each_entry(obj_priv, |
643 | &dev_priv->render_ring.active_list, list) { | ||
655 | struct drm_gem_object *obj = &obj_priv->base; | 644 | struct drm_gem_object *obj = &obj_priv->base; |
656 | 645 | ||
657 | error->active_bo[i].size = obj->size; | 646 | error->active_bo[i].size = obj->size; |
@@ -703,24 +692,13 @@ void i915_destroy_error_state(struct drm_device *dev) | |||
703 | i915_error_state_free(dev, error); | 692 | i915_error_state_free(dev, error); |
704 | } | 693 | } |
705 | 694 | ||
706 | /** | 695 | static void i915_report_and_clear_eir(struct drm_device *dev) |
707 | * i915_handle_error - handle an error interrupt | ||
708 | * @dev: drm device | ||
709 | * | ||
710 | * Do some basic checking of regsiter state at error interrupt time and | ||
711 | * dump it to the syslog. Also call i915_capture_error_state() to make | ||
712 | * sure we get a record and make it available in debugfs. Fire a uevent | ||
713 | * so userspace knows something bad happened (should trigger collection | ||
714 | * of a ring dump etc.). | ||
715 | */ | ||
716 | static void i915_handle_error(struct drm_device *dev, bool wedged) | ||
717 | { | 696 | { |
718 | struct drm_i915_private *dev_priv = dev->dev_private; | 697 | struct drm_i915_private *dev_priv = dev->dev_private; |
719 | u32 eir = I915_READ(EIR); | 698 | u32 eir = I915_READ(EIR); |
720 | u32 pipea_stats = I915_READ(PIPEASTAT); | ||
721 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
722 | 699 | ||
723 | i915_capture_error_state(dev); | 700 | if (!eir) |
701 | return; | ||
724 | 702 | ||
725 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | 703 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", |
726 | eir); | 704 | eir); |
@@ -766,6 +744,9 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
766 | } | 744 | } |
767 | 745 | ||
768 | if (eir & I915_ERROR_MEMORY_REFRESH) { | 746 | if (eir & I915_ERROR_MEMORY_REFRESH) { |
747 | u32 pipea_stats = I915_READ(PIPEASTAT); | ||
748 | u32 pipeb_stats = I915_READ(PIPEBSTAT); | ||
749 | |||
769 | printk(KERN_ERR "memory refresh error\n"); | 750 | printk(KERN_ERR "memory refresh error\n"); |
770 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | 751 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", |
771 | pipea_stats); | 752 | pipea_stats); |
@@ -822,6 +803,24 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
822 | I915_WRITE(EMR, I915_READ(EMR) | eir); | 803 | I915_WRITE(EMR, I915_READ(EMR) | eir); |
823 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | 804 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); |
824 | } | 805 | } |
806 | } | ||
807 | |||
808 | /** | ||
809 | * i915_handle_error - handle an error interrupt | ||
810 | * @dev: drm device | ||
811 | * | ||
812 | * Do some basic checking of regsiter state at error interrupt time and | ||
813 | * dump it to the syslog. Also call i915_capture_error_state() to make | ||
814 | * sure we get a record and make it available in debugfs. Fire a uevent | ||
815 | * so userspace knows something bad happened (should trigger collection | ||
816 | * of a ring dump etc.). | ||
817 | */ | ||
818 | static void i915_handle_error(struct drm_device *dev, bool wedged) | ||
819 | { | ||
820 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
821 | |||
822 | i915_capture_error_state(dev); | ||
823 | i915_report_and_clear_eir(dev); | ||
825 | 824 | ||
826 | if (wedged) { | 825 | if (wedged) { |
827 | atomic_set(&dev_priv->mm.wedged, 1); | 826 | atomic_set(&dev_priv->mm.wedged, 1); |
@@ -829,7 +828,7 @@ static void i915_handle_error(struct drm_device *dev, bool wedged) | |||
829 | /* | 828 | /* |
830 | * Wakeup waiting processes so they don't hang | 829 | * Wakeup waiting processes so they don't hang |
831 | */ | 830 | */ |
832 | DRM_WAKEUP(&dev_priv->irq_queue); | 831 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
833 | } | 832 | } |
834 | 833 | ||
835 | queue_work(dev_priv->wq, &dev_priv->error_work); | 834 | queue_work(dev_priv->wq, &dev_priv->error_work); |
@@ -848,6 +847,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
848 | unsigned long irqflags; | 847 | unsigned long irqflags; |
849 | int irq_received; | 848 | int irq_received; |
850 | int ret = IRQ_NONE; | 849 | int ret = IRQ_NONE; |
850 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
851 | 851 | ||
852 | atomic_inc(&dev_priv->irq_received); | 852 | atomic_inc(&dev_priv->irq_received); |
853 | 853 | ||
@@ -928,14 +928,18 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
928 | } | 928 | } |
929 | 929 | ||
930 | if (iir & I915_USER_INTERRUPT) { | 930 | if (iir & I915_USER_INTERRUPT) { |
931 | u32 seqno = i915_get_gem_seqno(dev); | 931 | u32 seqno = |
932 | dev_priv->mm.irq_gem_seqno = seqno; | 932 | render_ring->get_gem_seqno(dev, render_ring); |
933 | render_ring->irq_gem_seqno = seqno; | ||
933 | trace_i915_gem_request_complete(dev, seqno); | 934 | trace_i915_gem_request_complete(dev, seqno); |
934 | DRM_WAKEUP(&dev_priv->irq_queue); | 935 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); |
935 | dev_priv->hangcheck_count = 0; | 936 | dev_priv->hangcheck_count = 0; |
936 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 937 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
937 | } | 938 | } |
938 | 939 | ||
940 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | ||
941 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
942 | |||
939 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) | 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) |
940 | intel_prepare_page_flip(dev, 0); | 944 | intel_prepare_page_flip(dev, 0); |
941 | 945 | ||
@@ -984,7 +988,6 @@ static int i915_emit_irq(struct drm_device * dev) | |||
984 | { | 988 | { |
985 | drm_i915_private_t *dev_priv = dev->dev_private; | 989 | drm_i915_private_t *dev_priv = dev->dev_private; |
986 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 990 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
987 | RING_LOCALS; | ||
988 | 991 | ||
989 | i915_kernel_lost_context(dev); | 992 | i915_kernel_lost_context(dev); |
990 | 993 | ||
@@ -1006,43 +1009,13 @@ static int i915_emit_irq(struct drm_device * dev) | |||
1006 | return dev_priv->counter; | 1009 | return dev_priv->counter; |
1007 | } | 1010 | } |
1008 | 1011 | ||
1009 | void i915_user_irq_get(struct drm_device *dev) | ||
1010 | { | ||
1011 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
1012 | unsigned long irqflags; | ||
1013 | |||
1014 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
1015 | if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) { | ||
1016 | if (HAS_PCH_SPLIT(dev)) | ||
1017 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | ||
1018 | else | ||
1019 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | ||
1020 | } | ||
1021 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
1022 | } | ||
1023 | |||
1024 | void i915_user_irq_put(struct drm_device *dev) | ||
1025 | { | ||
1026 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
1027 | unsigned long irqflags; | ||
1028 | |||
1029 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
1030 | BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0); | ||
1031 | if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) { | ||
1032 | if (HAS_PCH_SPLIT(dev)) | ||
1033 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | ||
1034 | else | ||
1035 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | ||
1036 | } | ||
1037 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
1038 | } | ||
1039 | |||
1040 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) | 1012 | void i915_trace_irq_get(struct drm_device *dev, u32 seqno) |
1041 | { | 1013 | { |
1042 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1014 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1015 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
1043 | 1016 | ||
1044 | if (dev_priv->trace_irq_seqno == 0) | 1017 | if (dev_priv->trace_irq_seqno == 0) |
1045 | i915_user_irq_get(dev); | 1018 | render_ring->user_irq_get(dev, render_ring); |
1046 | 1019 | ||
1047 | dev_priv->trace_irq_seqno = seqno; | 1020 | dev_priv->trace_irq_seqno = seqno; |
1048 | } | 1021 | } |
@@ -1052,6 +1025,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
1052 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1025 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1053 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | 1026 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; |
1054 | int ret = 0; | 1027 | int ret = 0; |
1028 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
1055 | 1029 | ||
1056 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, | 1030 | DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, |
1057 | READ_BREADCRUMB(dev_priv)); | 1031 | READ_BREADCRUMB(dev_priv)); |
@@ -1065,10 +1039,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) | |||
1065 | if (master_priv->sarea_priv) | 1039 | if (master_priv->sarea_priv) |
1066 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | 1040 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; |
1067 | 1041 | ||
1068 | i915_user_irq_get(dev); | 1042 | render_ring->user_irq_get(dev, render_ring); |
1069 | DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, | 1043 | DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, |
1070 | READ_BREADCRUMB(dev_priv) >= irq_nr); | 1044 | READ_BREADCRUMB(dev_priv) >= irq_nr); |
1071 | i915_user_irq_put(dev); | 1045 | render_ring->user_irq_put(dev, render_ring); |
1072 | 1046 | ||
1073 | if (ret == -EBUSY) { | 1047 | if (ret == -EBUSY) { |
1074 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", | 1048 | DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", |
@@ -1087,7 +1061,7 @@ int i915_irq_emit(struct drm_device *dev, void *data, | |||
1087 | drm_i915_irq_emit_t *emit = data; | 1061 | drm_i915_irq_emit_t *emit = data; |
1088 | int result; | 1062 | int result; |
1089 | 1063 | ||
1090 | if (!dev_priv || !dev_priv->ring.virtual_start) { | 1064 | if (!dev_priv || !dev_priv->render_ring.virtual_start) { |
1091 | DRM_ERROR("called with no initialization\n"); | 1065 | DRM_ERROR("called with no initialization\n"); |
1092 | return -EINVAL; | 1066 | return -EINVAL; |
1093 | } | 1067 | } |
@@ -1233,9 +1207,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data, | |||
1233 | return -EINVAL; | 1207 | return -EINVAL; |
1234 | } | 1208 | } |
1235 | 1209 | ||
1236 | struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) { | 1210 | struct drm_i915_gem_request * |
1211 | i915_get_tail_request(struct drm_device *dev) | ||
1212 | { | ||
1237 | drm_i915_private_t *dev_priv = dev->dev_private; | 1213 | drm_i915_private_t *dev_priv = dev->dev_private; |
1238 | return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list); | 1214 | return list_entry(dev_priv->render_ring.request_list.prev, |
1215 | struct drm_i915_gem_request, list); | ||
1239 | } | 1216 | } |
1240 | 1217 | ||
1241 | /** | 1218 | /** |
@@ -1260,8 +1237,10 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1260 | acthd = I915_READ(ACTHD_I965); | 1237 | acthd = I915_READ(ACTHD_I965); |
1261 | 1238 | ||
1262 | /* If all work is done then ACTHD clearly hasn't advanced. */ | 1239 | /* If all work is done then ACTHD clearly hasn't advanced. */ |
1263 | if (list_empty(&dev_priv->mm.request_list) || | 1240 | if (list_empty(&dev_priv->render_ring.request_list) || |
1264 | i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) { | 1241 | i915_seqno_passed(i915_get_gem_seqno(dev, |
1242 | &dev_priv->render_ring), | ||
1243 | i915_get_tail_request(dev)->seqno)) { | ||
1265 | dev_priv->hangcheck_count = 0; | 1244 | dev_priv->hangcheck_count = 0; |
1266 | return; | 1245 | return; |
1267 | } | 1246 | } |
@@ -1314,7 +1293,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1314 | /* enable kind of interrupts always enabled */ | 1293 | /* enable kind of interrupts always enabled */ |
1315 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 1294 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1316 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | 1295 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; |
1317 | u32 render_mask = GT_PIPE_NOTIFY; | 1296 | u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; |
1318 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1297 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1319 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1298 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1320 | 1299 | ||
@@ -1328,7 +1307,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1328 | (void) I915_READ(DEIER); | 1307 | (void) I915_READ(DEIER); |
1329 | 1308 | ||
1330 | /* user interrupt should be enabled, but masked initial */ | 1309 | /* user interrupt should be enabled, but masked initial */ |
1331 | dev_priv->gt_irq_mask_reg = 0xffffffff; | 1310 | dev_priv->gt_irq_mask_reg = ~render_mask; |
1332 | dev_priv->gt_irq_enable_reg = render_mask; | 1311 | dev_priv->gt_irq_enable_reg = render_mask; |
1333 | 1312 | ||
1334 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1313 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
@@ -1391,7 +1370,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1391 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 1370 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
1392 | u32 error_mask; | 1371 | u32 error_mask; |
1393 | 1372 | ||
1394 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 1373 | DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); |
1374 | |||
1375 | if (HAS_BSD(dev)) | ||
1376 | DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); | ||
1395 | 1377 | ||
1396 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; | 1378 | dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; |
1397 | 1379 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f3e39cc46f0d..64b0a3afd92b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -334,6 +334,7 @@ | |||
334 | #define I915_DEBUG_INTERRUPT (1<<2) | 334 | #define I915_DEBUG_INTERRUPT (1<<2) |
335 | #define I915_USER_INTERRUPT (1<<1) | 335 | #define I915_USER_INTERRUPT (1<<1) |
336 | #define I915_ASLE_INTERRUPT (1<<0) | 336 | #define I915_ASLE_INTERRUPT (1<<0) |
337 | #define I915_BSD_USER_INTERRUPT (1<<25) | ||
337 | #define EIR 0x020b0 | 338 | #define EIR 0x020b0 |
338 | #define EMR 0x020b4 | 339 | #define EMR 0x020b4 |
339 | #define ESR 0x020b8 | 340 | #define ESR 0x020b8 |
@@ -368,6 +369,36 @@ | |||
368 | #define BB_ADDR 0x02140 /* 8 bytes */ | 369 | #define BB_ADDR 0x02140 /* 8 bytes */ |
369 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ | 370 | #define GFX_FLSH_CNTL 0x02170 /* 915+ only */ |
370 | 371 | ||
372 | /* GEN6 interrupt control */ | ||
373 | #define GEN6_RENDER_HWSTAM 0x2098 | ||
374 | #define GEN6_RENDER_IMR 0x20a8 | ||
375 | #define GEN6_RENDER_CONTEXT_SWITCH_INTERRUPT (1 << 8) | ||
376 | #define GEN6_RENDER_PPGTT_PAGE_FAULT (1 << 7) | ||
377 | #define GEN6_RENDER TIMEOUT_COUNTER_EXPIRED (1 << 6) | ||
378 | #define GEN6_RENDER_L3_PARITY_ERROR (1 << 5) | ||
379 | #define GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT (1 << 4) | ||
380 | #define GEN6_RENDER_COMMAND_PARSER_MASTER_ERROR (1 << 3) | ||
381 | #define GEN6_RENDER_SYNC_STATUS (1 << 2) | ||
382 | #define GEN6_RENDER_DEBUG_INTERRUPT (1 << 1) | ||
383 | #define GEN6_RENDER_USER_INTERRUPT (1 << 0) | ||
384 | |||
385 | #define GEN6_BLITTER_HWSTAM 0x22098 | ||
386 | #define GEN6_BLITTER_IMR 0x220a8 | ||
387 | #define GEN6_BLITTER_MI_FLUSH_DW_NOTIFY_INTERRUPT (1 << 26) | ||
388 | #define GEN6_BLITTER_COMMAND_PARSER_MASTER_ERROR (1 << 25) | ||
389 | #define GEN6_BLITTER_SYNC_STATUS (1 << 24) | ||
390 | #define GEN6_BLITTER_USER_INTERRUPT (1 << 22) | ||
391 | /* | ||
392 | * BSD (bit stream decoder instruction and interrupt control register defines | ||
393 | * (G4X and Ironlake only) | ||
394 | */ | ||
395 | |||
396 | #define BSD_RING_TAIL 0x04030 | ||
397 | #define BSD_RING_HEAD 0x04034 | ||
398 | #define BSD_RING_START 0x04038 | ||
399 | #define BSD_RING_CTL 0x0403c | ||
400 | #define BSD_RING_ACTHD 0x04074 | ||
401 | #define BSD_HWS_PGA 0x04080 | ||
371 | 402 | ||
372 | /* | 403 | /* |
373 | * Framebuffer compression (915+ only) | 404 | * Framebuffer compression (915+ only) |
@@ -805,6 +836,10 @@ | |||
805 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) | 836 | #define DCC_CHANNEL_XOR_DISABLE (1 << 10) |
806 | #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) | 837 | #define DCC_CHANNEL_XOR_BIT_17 (1 << 9) |
807 | 838 | ||
839 | /** Pineview MCH register contains DDR3 setting */ | ||
840 | #define CSHRDDR3CTL 0x101a8 | ||
841 | #define CSHRDDR3CTL_DDR3 (1 << 2) | ||
842 | |||
808 | /** 965 MCH register controlling DRAM channel configuration */ | 843 | /** 965 MCH register controlling DRAM channel configuration */ |
809 | #define C0DRB3 0x10206 | 844 | #define C0DRB3 0x10206 |
810 | #define C1DRB3 0x10606 | 845 | #define C1DRB3 0x10606 |
@@ -826,6 +861,12 @@ | |||
826 | #define CLKCFG_MEM_800 (3 << 4) | 861 | #define CLKCFG_MEM_800 (3 << 4) |
827 | #define CLKCFG_MEM_MASK (7 << 4) | 862 | #define CLKCFG_MEM_MASK (7 << 4) |
828 | 863 | ||
864 | #define TR1 0x11006 | ||
865 | #define TSFS 0x11020 | ||
866 | #define TSFS_SLOPE_MASK 0x0000ff00 | ||
867 | #define TSFS_SLOPE_SHIFT 8 | ||
868 | #define TSFS_INTR_MASK 0x000000ff | ||
869 | |||
829 | #define CRSTANDVID 0x11100 | 870 | #define CRSTANDVID 0x11100 |
830 | #define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ | 871 | #define PXVFREQ_BASE 0x11110 /* P[0-15]VIDFREQ (0x1114c) (Ironlake) */ |
831 | #define PXVFREQ_PX_MASK 0x7f000000 | 872 | #define PXVFREQ_PX_MASK 0x7f000000 |
@@ -964,6 +1005,41 @@ | |||
964 | #define MEMSTAT_SRC_CTL_STDBY 3 | 1005 | #define MEMSTAT_SRC_CTL_STDBY 3 |
965 | #define RCPREVBSYTUPAVG 0x113b8 | 1006 | #define RCPREVBSYTUPAVG 0x113b8 |
966 | #define RCPREVBSYTDNAVG 0x113bc | 1007 | #define RCPREVBSYTDNAVG 0x113bc |
1008 | #define SDEW 0x1124c | ||
1009 | #define CSIEW0 0x11250 | ||
1010 | #define CSIEW1 0x11254 | ||
1011 | #define CSIEW2 0x11258 | ||
1012 | #define PEW 0x1125c | ||
1013 | #define DEW 0x11270 | ||
1014 | #define MCHAFE 0x112c0 | ||
1015 | #define CSIEC 0x112e0 | ||
1016 | #define DMIEC 0x112e4 | ||
1017 | #define DDREC 0x112e8 | ||
1018 | #define PEG0EC 0x112ec | ||
1019 | #define PEG1EC 0x112f0 | ||
1020 | #define GFXEC 0x112f4 | ||
1021 | #define RPPREVBSYTUPAVG 0x113b8 | ||
1022 | #define RPPREVBSYTDNAVG 0x113bc | ||
1023 | #define ECR 0x11600 | ||
1024 | #define ECR_GPFE (1<<31) | ||
1025 | #define ECR_IMONE (1<<30) | ||
1026 | #define ECR_CAP_MASK 0x0000001f /* Event range, 0-31 */ | ||
1027 | #define OGW0 0x11608 | ||
1028 | #define OGW1 0x1160c | ||
1029 | #define EG0 0x11610 | ||
1030 | #define EG1 0x11614 | ||
1031 | #define EG2 0x11618 | ||
1032 | #define EG3 0x1161c | ||
1033 | #define EG4 0x11620 | ||
1034 | #define EG5 0x11624 | ||
1035 | #define EG6 0x11628 | ||
1036 | #define EG7 0x1162c | ||
1037 | #define PXW 0x11664 | ||
1038 | #define PXWL 0x11680 | ||
1039 | #define LCFUSE02 0x116c0 | ||
1040 | #define LCFUSE_HIV_MASK 0x000000ff | ||
1041 | #define CSIPLL0 0x12c10 | ||
1042 | #define DDRMPLL1 0X12c20 | ||
967 | #define PEG_BAND_GAP_DATA 0x14d68 | 1043 | #define PEG_BAND_GAP_DATA 0x14d68 |
968 | 1044 | ||
969 | /* | 1045 | /* |
@@ -1055,7 +1131,6 @@ | |||
1055 | #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) | 1131 | #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) |
1056 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) | 1132 | #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) |
1057 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ | 1133 | #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ |
1058 | #define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f | ||
1059 | 1134 | ||
1060 | #define PORT_HOTPLUG_STAT 0x61114 | 1135 | #define PORT_HOTPLUG_STAT 0x61114 |
1061 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) | 1136 | #define HDMIB_HOTPLUG_INT_STATUS (1 << 29) |
@@ -2355,6 +2430,8 @@ | |||
2355 | #define GT_PIPE_NOTIFY (1 << 4) | 2430 | #define GT_PIPE_NOTIFY (1 << 4) |
2356 | #define GT_SYNC_STATUS (1 << 2) | 2431 | #define GT_SYNC_STATUS (1 << 2) |
2357 | #define GT_USER_INTERRUPT (1 << 0) | 2432 | #define GT_USER_INTERRUPT (1 << 0) |
2433 | #define GT_BSD_USER_INTERRUPT (1 << 5) | ||
2434 | |||
2358 | 2435 | ||
2359 | #define GTISR 0x44010 | 2436 | #define GTISR 0x44010 |
2360 | #define GTIMR 0x44014 | 2437 | #define GTIMR 0x44014 |
@@ -2690,6 +2767,9 @@ | |||
2690 | #define SDVO_ENCODING (0) | 2767 | #define SDVO_ENCODING (0) |
2691 | #define TMDS_ENCODING (2 << 10) | 2768 | #define TMDS_ENCODING (2 << 10) |
2692 | #define NULL_PACKET_VSYNC_ENABLE (1 << 9) | 2769 | #define NULL_PACKET_VSYNC_ENABLE (1 << 9) |
2770 | /* CPT */ | ||
2771 | #define HDMI_MODE_SELECT (1 << 9) | ||
2772 | #define DVI_MODE_SELECT (0) | ||
2693 | #define SDVOB_BORDER_ENABLE (1 << 7) | 2773 | #define SDVOB_BORDER_ENABLE (1 << 7) |
2694 | #define AUDIO_ENABLE (1 << 6) | 2774 | #define AUDIO_ENABLE (1 << 6) |
2695 | #define VSYNC_ACTIVE_HIGH (1 << 4) | 2775 | #define VSYNC_ACTIVE_HIGH (1 << 4) |
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 9e4c45f68d6e..fab21760dd57 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h | |||
@@ -53,23 +53,6 @@ TRACE_EVENT(i915_gem_object_bind, | |||
53 | __entry->obj, __entry->gtt_offset) | 53 | __entry->obj, __entry->gtt_offset) |
54 | ); | 54 | ); |
55 | 55 | ||
56 | TRACE_EVENT(i915_gem_object_clflush, | ||
57 | |||
58 | TP_PROTO(struct drm_gem_object *obj), | ||
59 | |||
60 | TP_ARGS(obj), | ||
61 | |||
62 | TP_STRUCT__entry( | ||
63 | __field(struct drm_gem_object *, obj) | ||
64 | ), | ||
65 | |||
66 | TP_fast_assign( | ||
67 | __entry->obj = obj; | ||
68 | ), | ||
69 | |||
70 | TP_printk("obj=%p", __entry->obj) | ||
71 | ); | ||
72 | |||
73 | TRACE_EVENT(i915_gem_object_change_domain, | 56 | TRACE_EVENT(i915_gem_object_change_domain, |
74 | 57 | ||
75 | TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), | 58 | TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), |
@@ -132,6 +115,13 @@ DECLARE_EVENT_CLASS(i915_gem_object, | |||
132 | TP_printk("obj=%p", __entry->obj) | 115 | TP_printk("obj=%p", __entry->obj) |
133 | ); | 116 | ); |
134 | 117 | ||
118 | DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, | ||
119 | |||
120 | TP_PROTO(struct drm_gem_object *obj), | ||
121 | |||
122 | TP_ARGS(obj) | ||
123 | ); | ||
124 | |||
135 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, | 125 | DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, |
136 | 126 | ||
137 | TP_PROTO(struct drm_gem_object *obj), | 127 | TP_PROTO(struct drm_gem_object *obj), |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4c748d8f73d6..96f75d7f6633 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -95,6 +95,16 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | |||
95 | panel_fixed_mode->clock = dvo_timing->clock * 10; | 95 | panel_fixed_mode->clock = dvo_timing->clock * 10; |
96 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | 96 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; |
97 | 97 | ||
98 | if (dvo_timing->hsync_positive) | ||
99 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
100 | else | ||
101 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
102 | |||
103 | if (dvo_timing->vsync_positive) | ||
104 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
105 | else | ||
106 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
107 | |||
98 | /* Some VBTs have bogus h/vtotal values */ | 108 | /* Some VBTs have bogus h/vtotal values */ |
99 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 109 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
100 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | 110 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e16ac5a28c3c..22ff38455731 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -217,7 +217,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
217 | { | 217 | { |
218 | struct drm_device *dev = connector->dev; | 218 | struct drm_device *dev = connector->dev; |
219 | struct drm_i915_private *dev_priv = dev->dev_private; | 219 | struct drm_i915_private *dev_priv = dev->dev_private; |
220 | u32 hotplug_en; | 220 | u32 hotplug_en, orig, stat; |
221 | bool ret = false; | ||
221 | int i, tries = 0; | 222 | int i, tries = 0; |
222 | 223 | ||
223 | if (HAS_PCH_SPLIT(dev)) | 224 | if (HAS_PCH_SPLIT(dev)) |
@@ -232,8 +233,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
232 | tries = 2; | 233 | tries = 2; |
233 | else | 234 | else |
234 | tries = 1; | 235 | tries = 1; |
235 | hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 236 | hotplug_en = orig = I915_READ(PORT_HOTPLUG_EN); |
236 | hotplug_en &= CRT_FORCE_HOTPLUG_MASK; | 237 | hotplug_en &= CRT_HOTPLUG_MASK; |
237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 238 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
238 | 239 | ||
239 | if (IS_G4X(dev)) | 240 | if (IS_G4X(dev)) |
@@ -255,11 +256,17 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
255 | } while (time_after(timeout, jiffies)); | 256 | } while (time_after(timeout, jiffies)); |
256 | } | 257 | } |
257 | 258 | ||
258 | if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != | 259 | stat = I915_READ(PORT_HOTPLUG_STAT); |
259 | CRT_HOTPLUG_MONITOR_NONE) | 260 | if ((stat & CRT_HOTPLUG_MONITOR_MASK) != CRT_HOTPLUG_MONITOR_NONE) |
260 | return true; | 261 | ret = true; |
262 | |||
263 | /* clear the interrupt we just generated, if any */ | ||
264 | I915_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); | ||
261 | 265 | ||
262 | return false; | 266 | /* and put the bits back */ |
267 | I915_WRITE(PORT_HOTPLUG_EN, orig); | ||
268 | |||
269 | return ret; | ||
263 | } | 270 | } |
264 | 271 | ||
265 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | 272 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) |
@@ -569,7 +576,7 @@ void intel_crt_init(struct drm_device *dev) | |||
569 | (1 << INTEL_ANALOG_CLONE_BIT) | | 576 | (1 << INTEL_ANALOG_CLONE_BIT) | |
570 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 577 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); |
571 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 578 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
572 | connector->interlace_allowed = 0; | 579 | connector->interlace_allowed = 1; |
573 | connector->doublescan_allowed = 0; | 580 | connector->doublescan_allowed = 0; |
574 | 581 | ||
575 | drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); | 582 | drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f469a84cacfd..88a1ab7c05ce 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1029,19 +1029,28 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1029 | void i8xx_disable_fbc(struct drm_device *dev) | 1029 | void i8xx_disable_fbc(struct drm_device *dev) |
1030 | { | 1030 | { |
1031 | struct drm_i915_private *dev_priv = dev->dev_private; | 1031 | struct drm_i915_private *dev_priv = dev->dev_private; |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
1032 | u32 fbc_ctl; | 1033 | u32 fbc_ctl; |
1033 | 1034 | ||
1034 | if (!I915_HAS_FBC(dev)) | 1035 | if (!I915_HAS_FBC(dev)) |
1035 | return; | 1036 | return; |
1036 | 1037 | ||
1038 | if (!(I915_READ(FBC_CONTROL) & FBC_CTL_EN)) | ||
1039 | return; /* Already off, just return */ | ||
1040 | |||
1037 | /* Disable compression */ | 1041 | /* Disable compression */ |
1038 | fbc_ctl = I915_READ(FBC_CONTROL); | 1042 | fbc_ctl = I915_READ(FBC_CONTROL); |
1039 | fbc_ctl &= ~FBC_CTL_EN; | 1043 | fbc_ctl &= ~FBC_CTL_EN; |
1040 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1044 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1041 | 1045 | ||
1042 | /* Wait for compressing bit to clear */ | 1046 | /* Wait for compressing bit to clear */ |
1043 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) | 1047 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { |
1044 | ; /* nothing */ | 1048 | if (time_after(jiffies, timeout)) { |
1049 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | ||
1050 | break; | ||
1051 | } | ||
1052 | ; /* do nothing */ | ||
1053 | } | ||
1045 | 1054 | ||
1046 | intel_wait_for_vblank(dev); | 1055 | intel_wait_for_vblank(dev); |
1047 | 1056 | ||
@@ -1239,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc, | |||
1239 | return; | 1248 | return; |
1240 | 1249 | ||
1241 | out_disable: | 1250 | out_disable: |
1242 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
1243 | /* Multiple disables should be harmless */ | 1251 | /* Multiple disables should be harmless */ |
1244 | if (intel_fbc_enabled(dev)) | 1252 | if (intel_fbc_enabled(dev)) { |
1253 | DRM_DEBUG_KMS("unsupported config, disabling FBC\n"); | ||
1245 | intel_disable_fbc(dev); | 1254 | intel_disable_fbc(dev); |
1255 | } | ||
1246 | } | 1256 | } |
1247 | 1257 | ||
1248 | static int | 1258 | static int |
@@ -1386,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1386 | Start = obj_priv->gtt_offset; | 1396 | Start = obj_priv->gtt_offset; |
1387 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); | 1397 | Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); |
1388 | 1398 | ||
1389 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y); | 1399 | DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", |
1400 | Start, Offset, x, y, crtc->fb->pitch); | ||
1390 | I915_WRITE(dspstride, crtc->fb->pitch); | 1401 | I915_WRITE(dspstride, crtc->fb->pitch); |
1391 | if (IS_I965G(dev)) { | 1402 | if (IS_I965G(dev)) { |
1392 | I915_WRITE(dspbase, Offset); | 1403 | I915_WRITE(dspbase, Offset); |
@@ -2345,6 +2356,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | |||
2345 | if (mode->clock * 3 > 27000 * 4) | 2356 | if (mode->clock * 3 > 27000 * 4) |
2346 | return MODE_CLOCK_HIGH; | 2357 | return MODE_CLOCK_HIGH; |
2347 | } | 2358 | } |
2359 | |||
2360 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
2348 | return true; | 2361 | return true; |
2349 | } | 2362 | } |
2350 | 2363 | ||
@@ -2629,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
2629 | 2642 | ||
2630 | struct cxsr_latency { | 2643 | struct cxsr_latency { |
2631 | int is_desktop; | 2644 | int is_desktop; |
2645 | int is_ddr3; | ||
2632 | unsigned long fsb_freq; | 2646 | unsigned long fsb_freq; |
2633 | unsigned long mem_freq; | 2647 | unsigned long mem_freq; |
2634 | unsigned long display_sr; | 2648 | unsigned long display_sr; |
@@ -2638,33 +2652,45 @@ struct cxsr_latency { | |||
2638 | }; | 2652 | }; |
2639 | 2653 | ||
2640 | static struct cxsr_latency cxsr_latency_table[] = { | 2654 | static struct cxsr_latency cxsr_latency_table[] = { |
2641 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2655 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
2642 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2656 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
2643 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2657 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
2644 | 2658 | {1, 1, 800, 667, 6420, 36420, 6873, 36873}, /* DDR3-667 SC */ | |
2645 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | 2659 | {1, 1, 800, 800, 5902, 35902, 6318, 36318}, /* DDR3-800 SC */ |
2646 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | 2660 | |
2647 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | 2661 | {1, 0, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ |
2648 | 2662 | {1, 0, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | |
2649 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | 2663 | {1, 0, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ |
2650 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | 2664 | {1, 1, 667, 667, 6438, 36438, 6911, 36911}, /* DDR3-667 SC */ |
2651 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | 2665 | {1, 1, 667, 800, 5941, 35941, 6377, 36377}, /* DDR3-800 SC */ |
2652 | 2666 | ||
2653 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | 2667 | {1, 0, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ |
2654 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | 2668 | {1, 0, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ |
2655 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | 2669 | {1, 0, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ |
2656 | 2670 | {1, 1, 400, 667, 6509, 36509, 7062, 37062}, /* DDR3-667 SC */ | |
2657 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | 2671 | {1, 1, 400, 800, 5985, 35985, 6501, 36501}, /* DDR3-800 SC */ |
2658 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | 2672 | |
2659 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | 2673 | {0, 0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ |
2660 | 2674 | {0, 0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | |
2661 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | 2675 | {0, 0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ |
2662 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | 2676 | {0, 1, 800, 667, 6476, 36476, 6955, 36955}, /* DDR3-667 SC */ |
2663 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | 2677 | {0, 1, 800, 800, 5958, 35958, 6400, 36400}, /* DDR3-800 SC */ |
2678 | |||
2679 | {0, 0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
2680 | {0, 0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
2681 | {0, 0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
2682 | {0, 1, 667, 667, 6494, 36494, 6993, 36993}, /* DDR3-667 SC */ | ||
2683 | {0, 1, 667, 800, 5998, 35998, 6460, 36460}, /* DDR3-800 SC */ | ||
2684 | |||
2685 | {0, 0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
2686 | {0, 0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
2687 | {0, 0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
2688 | {0, 1, 400, 667, 6566, 36566, 7145, 37145}, /* DDR3-667 SC */ | ||
2689 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | ||
2664 | }; | 2690 | }; |
2665 | 2691 | ||
2666 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | 2692 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, |
2667 | int mem) | 2693 | int fsb, int mem) |
2668 | { | 2694 | { |
2669 | int i; | 2695 | int i; |
2670 | struct cxsr_latency *latency; | 2696 | struct cxsr_latency *latency; |
@@ -2675,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | |||
2675 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | 2701 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { |
2676 | latency = &cxsr_latency_table[i]; | 2702 | latency = &cxsr_latency_table[i]; |
2677 | if (is_desktop == latency->is_desktop && | 2703 | if (is_desktop == latency->is_desktop && |
2704 | is_ddr3 == latency->is_ddr3 && | ||
2678 | fsb == latency->fsb_freq && mem == latency->mem_freq) | 2705 | fsb == latency->fsb_freq && mem == latency->mem_freq) |
2679 | return latency; | 2706 | return latency; |
2680 | } | 2707 | } |
@@ -2789,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
2789 | struct cxsr_latency *latency; | 2816 | struct cxsr_latency *latency; |
2790 | int sr_clock; | 2817 | int sr_clock; |
2791 | 2818 | ||
2792 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq, | 2819 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
2793 | dev_priv->mem_freq); | 2820 | dev_priv->fsb_freq, dev_priv->mem_freq); |
2794 | if (!latency) { | 2821 | if (!latency) { |
2795 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 2822 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
2796 | pineview_disable_cxsr(dev); | 2823 | pineview_disable_cxsr(dev); |
@@ -3772,6 +3799,18 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3772 | } | 3799 | } |
3773 | } | 3800 | } |
3774 | 3801 | ||
3802 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
3803 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | ||
3804 | /* the chip adds 2 halflines automatically */ | ||
3805 | adjusted_mode->crtc_vdisplay -= 1; | ||
3806 | adjusted_mode->crtc_vtotal -= 1; | ||
3807 | adjusted_mode->crtc_vblank_start -= 1; | ||
3808 | adjusted_mode->crtc_vblank_end -= 1; | ||
3809 | adjusted_mode->crtc_vsync_end -= 1; | ||
3810 | adjusted_mode->crtc_vsync_start -= 1; | ||
3811 | } else | ||
3812 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | ||
3813 | |||
3775 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | | 3814 | I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | |
3776 | ((adjusted_mode->crtc_htotal - 1) << 16)); | 3815 | ((adjusted_mode->crtc_htotal - 1) << 16)); |
3777 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | | 3816 | I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | |
@@ -4436,6 +4475,8 @@ static void intel_idle_update(struct work_struct *work) | |||
4436 | 4475 | ||
4437 | mutex_lock(&dev->struct_mutex); | 4476 | mutex_lock(&dev->struct_mutex); |
4438 | 4477 | ||
4478 | i915_update_gfx_val(dev_priv); | ||
4479 | |||
4439 | if (IS_I945G(dev) || IS_I945GM(dev)) { | 4480 | if (IS_I945G(dev) || IS_I945GM(dev)) { |
4440 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); | 4481 | DRM_DEBUG_DRIVER("enable memory self refresh on 945\n"); |
4441 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); | 4482 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN); |
@@ -4564,12 +4605,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
4564 | spin_lock_irqsave(&dev->event_lock, flags); | 4605 | spin_lock_irqsave(&dev->event_lock, flags); |
4565 | work = intel_crtc->unpin_work; | 4606 | work = intel_crtc->unpin_work; |
4566 | if (work == NULL || !work->pending) { | 4607 | if (work == NULL || !work->pending) { |
4567 | if (work && !work->pending) { | ||
4568 | obj_priv = to_intel_bo(work->pending_flip_obj); | ||
4569 | DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", | ||
4570 | obj_priv, | ||
4571 | atomic_read(&obj_priv->pending_flip)); | ||
4572 | } | ||
4573 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4608 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4574 | return; | 4609 | return; |
4575 | } | 4610 | } |
@@ -4629,14 +4664,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4629 | unsigned long flags; | 4664 | unsigned long flags; |
4630 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; | 4665 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; |
4631 | int ret, pipesrc; | 4666 | int ret, pipesrc; |
4632 | RING_LOCALS; | ||
4633 | 4667 | ||
4634 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4668 | work = kzalloc(sizeof *work, GFP_KERNEL); |
4635 | if (work == NULL) | 4669 | if (work == NULL) |
4636 | return -ENOMEM; | 4670 | return -ENOMEM; |
4637 | 4671 | ||
4638 | mutex_lock(&dev->struct_mutex); | ||
4639 | |||
4640 | work->event = event; | 4672 | work->event = event; |
4641 | work->dev = crtc->dev; | 4673 | work->dev = crtc->dev; |
4642 | intel_fb = to_intel_framebuffer(crtc->fb); | 4674 | intel_fb = to_intel_framebuffer(crtc->fb); |
@@ -4646,10 +4678,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4646 | /* We borrow the event spin lock for protecting unpin_work */ | 4678 | /* We borrow the event spin lock for protecting unpin_work */ |
4647 | spin_lock_irqsave(&dev->event_lock, flags); | 4679 | spin_lock_irqsave(&dev->event_lock, flags); |
4648 | if (intel_crtc->unpin_work) { | 4680 | if (intel_crtc->unpin_work) { |
4649 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4650 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4681 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4651 | kfree(work); | 4682 | kfree(work); |
4652 | mutex_unlock(&dev->struct_mutex); | 4683 | |
4684 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4653 | return -EBUSY; | 4685 | return -EBUSY; |
4654 | } | 4686 | } |
4655 | intel_crtc->unpin_work = work; | 4687 | intel_crtc->unpin_work = work; |
@@ -4658,13 +4690,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4658 | intel_fb = to_intel_framebuffer(fb); | 4690 | intel_fb = to_intel_framebuffer(fb); |
4659 | obj = intel_fb->obj; | 4691 | obj = intel_fb->obj; |
4660 | 4692 | ||
4693 | mutex_lock(&dev->struct_mutex); | ||
4661 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 4694 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4662 | if (ret != 0) { | 4695 | if (ret != 0) { |
4663 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4664 | to_intel_bo(obj)); | ||
4665 | kfree(work); | ||
4666 | intel_crtc->unpin_work = NULL; | ||
4667 | mutex_unlock(&dev->struct_mutex); | 4696 | mutex_unlock(&dev->struct_mutex); |
4697 | |||
4698 | spin_lock_irqsave(&dev->event_lock, flags); | ||
4699 | intel_crtc->unpin_work = NULL; | ||
4700 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
4701 | |||
4702 | kfree(work); | ||
4703 | |||
4704 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4705 | to_intel_bo(obj)); | ||
4668 | return ret; | 4706 | return ret; |
4669 | } | 4707 | } |
4670 | 4708 | ||
@@ -5023,10 +5061,32 @@ err_unref: | |||
5023 | return NULL; | 5061 | return NULL; |
5024 | } | 5062 | } |
5025 | 5063 | ||
5064 | bool ironlake_set_drps(struct drm_device *dev, u8 val) | ||
5065 | { | ||
5066 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5067 | u16 rgvswctl; | ||
5068 | |||
5069 | rgvswctl = I915_READ16(MEMSWCTL); | ||
5070 | if (rgvswctl & MEMCTL_CMD_STS) { | ||
5071 | DRM_DEBUG("gpu busy, RCS change rejected\n"); | ||
5072 | return false; /* still busy with another command */ | ||
5073 | } | ||
5074 | |||
5075 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
5076 | (val << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5077 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
5078 | POSTING_READ16(MEMSWCTL); | ||
5079 | |||
5080 | rgvswctl |= MEMCTL_CMD_STS; | ||
5081 | I915_WRITE16(MEMSWCTL, rgvswctl); | ||
5082 | |||
5083 | return true; | ||
5084 | } | ||
5085 | |||
5026 | void ironlake_enable_drps(struct drm_device *dev) | 5086 | void ironlake_enable_drps(struct drm_device *dev) |
5027 | { | 5087 | { |
5028 | struct drm_i915_private *dev_priv = dev->dev_private; | 5088 | struct drm_i915_private *dev_priv = dev->dev_private; |
5029 | u32 rgvmodectl = I915_READ(MEMMODECTL), rgvswctl; | 5089 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5030 | u8 fmax, fmin, fstart, vstart; | 5090 | u8 fmax, fmin, fstart, vstart; |
5031 | int i = 0; | 5091 | int i = 0; |
5032 | 5092 | ||
@@ -5045,13 +5105,21 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5045 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); | 5105 | fmin = (rgvmodectl & MEMMODE_FMIN_MASK); |
5046 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> | 5106 | fstart = (rgvmodectl & MEMMODE_FSTART_MASK) >> |
5047 | MEMMODE_FSTART_SHIFT; | 5107 | MEMMODE_FSTART_SHIFT; |
5108 | fstart = fmax; | ||
5109 | |||
5048 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> | 5110 | vstart = (I915_READ(PXVFREQ_BASE + (fstart * 4)) & PXVFREQ_PX_MASK) >> |
5049 | PXVFREQ_PX_SHIFT; | 5111 | PXVFREQ_PX_SHIFT; |
5050 | 5112 | ||
5051 | dev_priv->max_delay = fstart; /* can't go to fmax w/o IPS */ | 5113 | dev_priv->fmax = fstart; /* IPS callback will increase this */ |
5114 | dev_priv->fstart = fstart; | ||
5115 | |||
5116 | dev_priv->max_delay = fmax; | ||
5052 | dev_priv->min_delay = fmin; | 5117 | dev_priv->min_delay = fmin; |
5053 | dev_priv->cur_delay = fstart; | 5118 | dev_priv->cur_delay = fstart; |
5054 | 5119 | ||
5120 | DRM_DEBUG_DRIVER("fmax: %d, fmin: %d, fstart: %d\n", fmax, fmin, | ||
5121 | fstart); | ||
5122 | |||
5055 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); | 5123 | I915_WRITE(MEMINTREN, MEMINT_CX_SUPR_EN | MEMINT_EVAL_CHG_EN); |
5056 | 5124 | ||
5057 | /* | 5125 | /* |
@@ -5073,20 +5141,19 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5073 | } | 5141 | } |
5074 | msleep(1); | 5142 | msleep(1); |
5075 | 5143 | ||
5076 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | 5144 | ironlake_set_drps(dev, fstart); |
5077 | (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5078 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
5079 | POSTING_READ(MEMSWCTL); | ||
5080 | 5145 | ||
5081 | rgvswctl |= MEMCTL_CMD_STS; | 5146 | dev_priv->last_count1 = I915_READ(0x112e4) + I915_READ(0x112e8) + |
5082 | I915_WRITE(MEMSWCTL, rgvswctl); | 5147 | I915_READ(0x112e0); |
5148 | dev_priv->last_time1 = jiffies_to_msecs(jiffies); | ||
5149 | dev_priv->last_count2 = I915_READ(0x112f4); | ||
5150 | getrawmonotonic(&dev_priv->last_time2); | ||
5083 | } | 5151 | } |
5084 | 5152 | ||
5085 | void ironlake_disable_drps(struct drm_device *dev) | 5153 | void ironlake_disable_drps(struct drm_device *dev) |
5086 | { | 5154 | { |
5087 | struct drm_i915_private *dev_priv = dev->dev_private; | 5155 | struct drm_i915_private *dev_priv = dev->dev_private; |
5088 | u32 rgvswctl; | 5156 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
5089 | u8 fstart; | ||
5090 | 5157 | ||
5091 | /* Ack interrupts, disable EFC interrupt */ | 5158 | /* Ack interrupts, disable EFC interrupt */ |
5092 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); | 5159 | I915_WRITE(MEMINTREN, I915_READ(MEMINTREN) & ~MEMINT_EVAL_CHG_EN); |
@@ -5096,11 +5163,7 @@ void ironlake_disable_drps(struct drm_device *dev) | |||
5096 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); | 5163 | I915_WRITE(DEIMR, I915_READ(DEIMR) | DE_PCU_EVENT); |
5097 | 5164 | ||
5098 | /* Go back to the starting frequency */ | 5165 | /* Go back to the starting frequency */ |
5099 | fstart = (I915_READ(MEMMODECTL) & MEMMODE_FSTART_MASK) >> | 5166 | ironlake_set_drps(dev, dev_priv->fstart); |
5100 | MEMMODE_FSTART_SHIFT; | ||
5101 | rgvswctl = (MEMCTL_CMD_CHFREQ << MEMCTL_CMD_SHIFT) | | ||
5102 | (fstart << MEMCTL_FREQ_SHIFT) | MEMCTL_SFCAVM; | ||
5103 | I915_WRITE(MEMSWCTL, rgvswctl); | ||
5104 | msleep(1); | 5167 | msleep(1); |
5105 | rgvswctl |= MEMCTL_CMD_STS; | 5168 | rgvswctl |= MEMCTL_CMD_STS; |
5106 | I915_WRITE(MEMSWCTL, rgvswctl); | 5169 | I915_WRITE(MEMSWCTL, rgvswctl); |
@@ -5108,6 +5171,92 @@ void ironlake_disable_drps(struct drm_device *dev) | |||
5108 | 5171 | ||
5109 | } | 5172 | } |
5110 | 5173 | ||
5174 | static unsigned long intel_pxfreq(u32 vidfreq) | ||
5175 | { | ||
5176 | unsigned long freq; | ||
5177 | int div = (vidfreq & 0x3f0000) >> 16; | ||
5178 | int post = (vidfreq & 0x3000) >> 12; | ||
5179 | int pre = (vidfreq & 0x7); | ||
5180 | |||
5181 | if (!pre) | ||
5182 | return 0; | ||
5183 | |||
5184 | freq = ((div * 133333) / ((1<<post) * pre)); | ||
5185 | |||
5186 | return freq; | ||
5187 | } | ||
5188 | |||
5189 | void intel_init_emon(struct drm_device *dev) | ||
5190 | { | ||
5191 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5192 | u32 lcfuse; | ||
5193 | u8 pxw[16]; | ||
5194 | int i; | ||
5195 | |||
5196 | /* Disable to program */ | ||
5197 | I915_WRITE(ECR, 0); | ||
5198 | POSTING_READ(ECR); | ||
5199 | |||
5200 | /* Program energy weights for various events */ | ||
5201 | I915_WRITE(SDEW, 0x15040d00); | ||
5202 | I915_WRITE(CSIEW0, 0x007f0000); | ||
5203 | I915_WRITE(CSIEW1, 0x1e220004); | ||
5204 | I915_WRITE(CSIEW2, 0x04000004); | ||
5205 | |||
5206 | for (i = 0; i < 5; i++) | ||
5207 | I915_WRITE(PEW + (i * 4), 0); | ||
5208 | for (i = 0; i < 3; i++) | ||
5209 | I915_WRITE(DEW + (i * 4), 0); | ||
5210 | |||
5211 | /* Program P-state weights to account for frequency power adjustment */ | ||
5212 | for (i = 0; i < 16; i++) { | ||
5213 | u32 pxvidfreq = I915_READ(PXVFREQ_BASE + (i * 4)); | ||
5214 | unsigned long freq = intel_pxfreq(pxvidfreq); | ||
5215 | unsigned long vid = (pxvidfreq & PXVFREQ_PX_MASK) >> | ||
5216 | PXVFREQ_PX_SHIFT; | ||
5217 | unsigned long val; | ||
5218 | |||
5219 | val = vid * vid; | ||
5220 | val *= (freq / 1000); | ||
5221 | val *= 255; | ||
5222 | val /= (127*127*900); | ||
5223 | if (val > 0xff) | ||
5224 | DRM_ERROR("bad pxval: %ld\n", val); | ||
5225 | pxw[i] = val; | ||
5226 | } | ||
5227 | /* Render standby states get 0 weight */ | ||
5228 | pxw[14] = 0; | ||
5229 | pxw[15] = 0; | ||
5230 | |||
5231 | for (i = 0; i < 4; i++) { | ||
5232 | u32 val = (pxw[i*4] << 24) | (pxw[(i*4)+1] << 16) | | ||
5233 | (pxw[(i*4)+2] << 8) | (pxw[(i*4)+3]); | ||
5234 | I915_WRITE(PXW + (i * 4), val); | ||
5235 | } | ||
5236 | |||
5237 | /* Adjust magic regs to magic values (more experimental results) */ | ||
5238 | I915_WRITE(OGW0, 0); | ||
5239 | I915_WRITE(OGW1, 0); | ||
5240 | I915_WRITE(EG0, 0x00007f00); | ||
5241 | I915_WRITE(EG1, 0x0000000e); | ||
5242 | I915_WRITE(EG2, 0x000e0000); | ||
5243 | I915_WRITE(EG3, 0x68000300); | ||
5244 | I915_WRITE(EG4, 0x42000000); | ||
5245 | I915_WRITE(EG5, 0x00140031); | ||
5246 | I915_WRITE(EG6, 0); | ||
5247 | I915_WRITE(EG7, 0); | ||
5248 | |||
5249 | for (i = 0; i < 8; i++) | ||
5250 | I915_WRITE(PXWL + (i * 4), 0); | ||
5251 | |||
5252 | /* Enable PMON + select events */ | ||
5253 | I915_WRITE(ECR, 0x80000019); | ||
5254 | |||
5255 | lcfuse = I915_READ(LCFUSE02); | ||
5256 | |||
5257 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | ||
5258 | } | ||
5259 | |||
5111 | void intel_init_clock_gating(struct drm_device *dev) | 5260 | void intel_init_clock_gating(struct drm_device *dev) |
5112 | { | 5261 | { |
5113 | struct drm_i915_private *dev_priv = dev->dev_private; | 5262 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5277,11 +5426,13 @@ static void intel_init_display(struct drm_device *dev) | |||
5277 | dev_priv->display.update_wm = NULL; | 5426 | dev_priv->display.update_wm = NULL; |
5278 | } else if (IS_PINEVIEW(dev)) { | 5427 | } else if (IS_PINEVIEW(dev)) { |
5279 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), | 5428 | if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev), |
5429 | dev_priv->is_ddr3, | ||
5280 | dev_priv->fsb_freq, | 5430 | dev_priv->fsb_freq, |
5281 | dev_priv->mem_freq)) { | 5431 | dev_priv->mem_freq)) { |
5282 | DRM_INFO("failed to find known CxSR latency " | 5432 | DRM_INFO("failed to find known CxSR latency " |
5283 | "(found fsb freq %d, mem freq %d), " | 5433 | "(found ddr%s fsb freq %d, mem freq %d), " |
5284 | "disabling CxSR\n", | 5434 | "disabling CxSR\n", |
5435 | (dev_priv->is_ddr3 == 1) ? "3": "2", | ||
5285 | dev_priv->fsb_freq, dev_priv->mem_freq); | 5436 | dev_priv->fsb_freq, dev_priv->mem_freq); |
5286 | /* Disable CxSR and never update its watermark again */ | 5437 | /* Disable CxSR and never update its watermark again */ |
5287 | pineview_disable_cxsr(dev); | 5438 | pineview_disable_cxsr(dev); |
@@ -5354,8 +5505,10 @@ void intel_modeset_init(struct drm_device *dev) | |||
5354 | 5505 | ||
5355 | intel_init_clock_gating(dev); | 5506 | intel_init_clock_gating(dev); |
5356 | 5507 | ||
5357 | if (IS_IRONLAKE_M(dev)) | 5508 | if (IS_IRONLAKE_M(dev)) { |
5358 | ironlake_enable_drps(dev); | 5509 | ironlake_enable_drps(dev); |
5510 | intel_init_emon(dev); | ||
5511 | } | ||
5359 | 5512 | ||
5360 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); | 5513 | INIT_WORK(&dev_priv->idle_work, intel_idle_update); |
5361 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, | 5514 | setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b1c9a27c27a..49b54f05d3cf 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -576,7 +576,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
576 | struct intel_encoder *intel_encoder; | 576 | struct intel_encoder *intel_encoder; |
577 | struct intel_dp_priv *dp_priv; | 577 | struct intel_dp_priv *dp_priv; |
578 | 578 | ||
579 | if (!encoder || encoder->crtc != crtc) | 579 | if (encoder->crtc != crtc) |
580 | continue; | 580 | continue; |
581 | 581 | ||
582 | intel_encoder = enc_to_intel_encoder(encoder); | 582 | intel_encoder = enc_to_intel_encoder(encoder); |
@@ -675,10 +675,9 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
675 | dp_priv->link_configuration[1] = dp_priv->lane_count; | 675 | dp_priv->link_configuration[1] = dp_priv->lane_count; |
676 | 676 | ||
677 | /* | 677 | /* |
678 | * Check for DPCD version > 1.1, | 678 | * Check for DPCD version > 1.1 and enhanced framing support |
679 | * enable enahanced frame stuff in that case | ||
680 | */ | 679 | */ |
681 | if (dp_priv->dpcd[0] >= 0x11) { | 680 | if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { |
682 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 681 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
683 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 682 | dp_priv->DP |= DP_ENHANCED_FRAMING; |
684 | } | 683 | } |
@@ -1208,6 +1207,8 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1208 | if (dp_priv->dpcd[0] != 0) | 1207 | if (dp_priv->dpcd[0] != 0) |
1209 | status = connector_status_connected; | 1208 | status = connector_status_connected; |
1210 | } | 1209 | } |
1210 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | ||
1211 | dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | ||
1211 | return status; | 1212 | return status; |
1212 | } | 1213 | } |
1213 | 1214 | ||
@@ -1352,7 +1353,7 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
1352 | struct intel_encoder *intel_encoder = NULL; | 1353 | struct intel_encoder *intel_encoder = NULL; |
1353 | 1354 | ||
1354 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 1355 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
1355 | if (!encoder || encoder->crtc != crtc) | 1356 | if (encoder->crtc != crtc) |
1356 | continue; | 1357 | continue; |
1357 | 1358 | ||
1358 | intel_encoder = enc_to_intel_encoder(encoder); | 1359 | intel_encoder = enc_to_intel_encoder(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 6f53cf7fbc50..f8c76e64bb77 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -105,7 +105,11 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /* Flush everything out, we'll be doing GTT only from now on */ | 107 | /* Flush everything out, we'll be doing GTT only from now on */ |
108 | i915_gem_object_set_to_gtt_domain(fbo, 1); | 108 | ret = i915_gem_object_set_to_gtt_domain(fbo, 1); |
109 | if (ret) { | ||
110 | DRM_ERROR("failed to bind fb: %d.\n", ret); | ||
111 | goto out_unpin; | ||
112 | } | ||
109 | 113 | ||
110 | info = framebuffer_alloc(0, device); | 114 | info = framebuffer_alloc(0, device); |
111 | if (!info) { | 115 | if (!info) { |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 65727f0a79a3..83bd764b000e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -59,8 +59,11 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
59 | SDVO_VSYNC_ACTIVE_HIGH | | 59 | SDVO_VSYNC_ACTIVE_HIGH | |
60 | SDVO_HSYNC_ACTIVE_HIGH; | 60 | SDVO_HSYNC_ACTIVE_HIGH; |
61 | 61 | ||
62 | if (hdmi_priv->has_hdmi_sink) | 62 | if (hdmi_priv->has_hdmi_sink) { |
63 | sdvox |= SDVO_AUDIO_ENABLE; | 63 | sdvox |= SDVO_AUDIO_ENABLE; |
64 | if (HAS_PCH_CPT(dev)) | ||
65 | sdvox |= HDMI_MODE_SELECT; | ||
66 | } | ||
64 | 67 | ||
65 | if (intel_crtc->pipe == 1) { | 68 | if (intel_crtc->pipe == 1) { |
66 | if (HAS_PCH_CPT(dev)) | 69 | if (HAS_PCH_CPT(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index b0e17b06eb6e..d7ad5139d17c 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -211,9 +211,8 @@ static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) | |||
211 | static int intel_overlay_on(struct intel_overlay *overlay) | 211 | static int intel_overlay_on(struct intel_overlay *overlay) |
212 | { | 212 | { |
213 | struct drm_device *dev = overlay->dev; | 213 | struct drm_device *dev = overlay->dev; |
214 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
215 | int ret; | 214 | int ret; |
216 | RING_LOCALS; | 215 | drm_i915_private_t *dev_priv = dev->dev_private; |
217 | 216 | ||
218 | BUG_ON(overlay->active); | 217 | BUG_ON(overlay->active); |
219 | 218 | ||
@@ -227,11 +226,13 @@ static int intel_overlay_on(struct intel_overlay *overlay) | |||
227 | OUT_RING(MI_NOOP); | 226 | OUT_RING(MI_NOOP); |
228 | ADVANCE_LP_RING(); | 227 | ADVANCE_LP_RING(); |
229 | 228 | ||
230 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 229 | overlay->last_flip_req = |
230 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
231 | if (overlay->last_flip_req == 0) | 231 | if (overlay->last_flip_req == 0) |
232 | return -ENOMEM; | 232 | return -ENOMEM; |
233 | 233 | ||
234 | ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | 234 | ret = i915_do_wait_request(dev, |
235 | overlay->last_flip_req, 1, &dev_priv->render_ring); | ||
235 | if (ret != 0) | 236 | if (ret != 0) |
236 | return ret; | 237 | return ret; |
237 | 238 | ||
@@ -248,7 +249,6 @@ static void intel_overlay_continue(struct intel_overlay *overlay, | |||
248 | drm_i915_private_t *dev_priv = dev->dev_private; | 249 | drm_i915_private_t *dev_priv = dev->dev_private; |
249 | u32 flip_addr = overlay->flip_addr; | 250 | u32 flip_addr = overlay->flip_addr; |
250 | u32 tmp; | 251 | u32 tmp; |
251 | RING_LOCALS; | ||
252 | 252 | ||
253 | BUG_ON(!overlay->active); | 253 | BUG_ON(!overlay->active); |
254 | 254 | ||
@@ -265,7 +265,8 @@ static void intel_overlay_continue(struct intel_overlay *overlay, | |||
265 | OUT_RING(flip_addr); | 265 | OUT_RING(flip_addr); |
266 | ADVANCE_LP_RING(); | 266 | ADVANCE_LP_RING(); |
267 | 267 | ||
268 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 268 | overlay->last_flip_req = |
269 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
269 | } | 270 | } |
270 | 271 | ||
271 | static int intel_overlay_wait_flip(struct intel_overlay *overlay) | 272 | static int intel_overlay_wait_flip(struct intel_overlay *overlay) |
@@ -274,10 +275,10 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) | |||
274 | drm_i915_private_t *dev_priv = dev->dev_private; | 275 | drm_i915_private_t *dev_priv = dev->dev_private; |
275 | int ret; | 276 | int ret; |
276 | u32 tmp; | 277 | u32 tmp; |
277 | RING_LOCALS; | ||
278 | 278 | ||
279 | if (overlay->last_flip_req != 0) { | 279 | if (overlay->last_flip_req != 0) { |
280 | ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | 280 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
281 | 1, &dev_priv->render_ring); | ||
281 | if (ret == 0) { | 282 | if (ret == 0) { |
282 | overlay->last_flip_req = 0; | 283 | overlay->last_flip_req = 0; |
283 | 284 | ||
@@ -296,11 +297,13 @@ static int intel_overlay_wait_flip(struct intel_overlay *overlay) | |||
296 | OUT_RING(MI_NOOP); | 297 | OUT_RING(MI_NOOP); |
297 | ADVANCE_LP_RING(); | 298 | ADVANCE_LP_RING(); |
298 | 299 | ||
299 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 300 | overlay->last_flip_req = |
301 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
300 | if (overlay->last_flip_req == 0) | 302 | if (overlay->last_flip_req == 0) |
301 | return -ENOMEM; | 303 | return -ENOMEM; |
302 | 304 | ||
303 | ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | 305 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
306 | 1, &dev_priv->render_ring); | ||
304 | if (ret != 0) | 307 | if (ret != 0) |
305 | return ret; | 308 | return ret; |
306 | 309 | ||
@@ -314,9 +317,8 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
314 | { | 317 | { |
315 | u32 flip_addr = overlay->flip_addr; | 318 | u32 flip_addr = overlay->flip_addr; |
316 | struct drm_device *dev = overlay->dev; | 319 | struct drm_device *dev = overlay->dev; |
317 | drm_i915_private_t *dev_priv = dev->dev_private; | 320 | drm_i915_private_t *dev_priv = dev->dev_private; |
318 | int ret; | 321 | int ret; |
319 | RING_LOCALS; | ||
320 | 322 | ||
321 | BUG_ON(!overlay->active); | 323 | BUG_ON(!overlay->active); |
322 | 324 | ||
@@ -336,11 +338,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
336 | OUT_RING(MI_NOOP); | 338 | OUT_RING(MI_NOOP); |
337 | ADVANCE_LP_RING(); | 339 | ADVANCE_LP_RING(); |
338 | 340 | ||
339 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 341 | overlay->last_flip_req = |
342 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
340 | if (overlay->last_flip_req == 0) | 343 | if (overlay->last_flip_req == 0) |
341 | return -ENOMEM; | 344 | return -ENOMEM; |
342 | 345 | ||
343 | ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | 346 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
347 | 1, &dev_priv->render_ring); | ||
344 | if (ret != 0) | 348 | if (ret != 0) |
345 | return ret; | 349 | return ret; |
346 | 350 | ||
@@ -354,11 +358,13 @@ static int intel_overlay_off(struct intel_overlay *overlay) | |||
354 | OUT_RING(MI_NOOP); | 358 | OUT_RING(MI_NOOP); |
355 | ADVANCE_LP_RING(); | 359 | ADVANCE_LP_RING(); |
356 | 360 | ||
357 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 361 | overlay->last_flip_req = |
362 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
358 | if (overlay->last_flip_req == 0) | 363 | if (overlay->last_flip_req == 0) |
359 | return -ENOMEM; | 364 | return -ENOMEM; |
360 | 365 | ||
361 | ret = i915_do_wait_request(dev, overlay->last_flip_req, 1); | 366 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
367 | 1, &dev_priv->render_ring); | ||
362 | if (ret != 0) | 368 | if (ret != 0) |
363 | return ret; | 369 | return ret; |
364 | 370 | ||
@@ -390,22 +396,23 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | |||
390 | int interruptible) | 396 | int interruptible) |
391 | { | 397 | { |
392 | struct drm_device *dev = overlay->dev; | 398 | struct drm_device *dev = overlay->dev; |
393 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
394 | struct drm_gem_object *obj; | 399 | struct drm_gem_object *obj; |
400 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
395 | u32 flip_addr; | 401 | u32 flip_addr; |
396 | int ret; | 402 | int ret; |
397 | RING_LOCALS; | ||
398 | 403 | ||
399 | if (overlay->hw_wedged == HW_WEDGED) | 404 | if (overlay->hw_wedged == HW_WEDGED) |
400 | return -EIO; | 405 | return -EIO; |
401 | 406 | ||
402 | if (overlay->last_flip_req == 0) { | 407 | if (overlay->last_flip_req == 0) { |
403 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 408 | overlay->last_flip_req = |
409 | i915_add_request(dev, NULL, 0, &dev_priv->render_ring); | ||
404 | if (overlay->last_flip_req == 0) | 410 | if (overlay->last_flip_req == 0) |
405 | return -ENOMEM; | 411 | return -ENOMEM; |
406 | } | 412 | } |
407 | 413 | ||
408 | ret = i915_do_wait_request(dev, overlay->last_flip_req, interruptible); | 414 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
415 | interruptible, &dev_priv->render_ring); | ||
409 | if (ret != 0) | 416 | if (ret != 0) |
410 | return ret; | 417 | return ret; |
411 | 418 | ||
@@ -429,12 +436,13 @@ int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, | |||
429 | OUT_RING(MI_NOOP); | 436 | OUT_RING(MI_NOOP); |
430 | ADVANCE_LP_RING(); | 437 | ADVANCE_LP_RING(); |
431 | 438 | ||
432 | overlay->last_flip_req = i915_add_request(dev, NULL, 0); | 439 | overlay->last_flip_req = i915_add_request(dev, NULL, |
440 | 0, &dev_priv->render_ring); | ||
433 | if (overlay->last_flip_req == 0) | 441 | if (overlay->last_flip_req == 0) |
434 | return -ENOMEM; | 442 | return -ENOMEM; |
435 | 443 | ||
436 | ret = i915_do_wait_request(dev, overlay->last_flip_req, | 444 | ret = i915_do_wait_request(dev, overlay->last_flip_req, |
437 | interruptible); | 445 | interruptible, &dev_priv->render_ring); |
438 | if (ret != 0) | 446 | if (ret != 0) |
439 | return ret; | 447 | return ret; |
440 | 448 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c new file mode 100644 index 000000000000..cea4f1a8709e --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -0,0 +1,849 @@ | |||
1 | /* | ||
2 | * Copyright © 2008-2010 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Eric Anholt <eric@anholt.net> | ||
25 | * Zou Nan hai <nanhai.zou@intel.com> | ||
26 | * Xiang Hai hao<haihao.xiang@intel.com> | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include "drmP.h" | ||
31 | #include "drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | #include "i915_drm.h" | ||
34 | #include "i915_trace.h" | ||
35 | |||
36 | static void | ||
37 | render_ring_flush(struct drm_device *dev, | ||
38 | struct intel_ring_buffer *ring, | ||
39 | u32 invalidate_domains, | ||
40 | u32 flush_domains) | ||
41 | { | ||
42 | #if WATCH_EXEC | ||
43 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | ||
44 | invalidate_domains, flush_domains); | ||
45 | #endif | ||
46 | u32 cmd; | ||
47 | trace_i915_gem_request_flush(dev, ring->next_seqno, | ||
48 | invalidate_domains, flush_domains); | ||
49 | |||
50 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | ||
51 | /* | ||
52 | * read/write caches: | ||
53 | * | ||
54 | * I915_GEM_DOMAIN_RENDER is always invalidated, but is | ||
55 | * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is | ||
56 | * also flushed at 2d versus 3d pipeline switches. | ||
57 | * | ||
58 | * read-only caches: | ||
59 | * | ||
60 | * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if | ||
61 | * MI_READ_FLUSH is set, and is always flushed on 965. | ||
62 | * | ||
63 | * I915_GEM_DOMAIN_COMMAND may not exist? | ||
64 | * | ||
65 | * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is | ||
66 | * invalidated when MI_EXE_FLUSH is set. | ||
67 | * | ||
68 | * I915_GEM_DOMAIN_VERTEX, which exists on 965, is | ||
69 | * invalidated with every MI_FLUSH. | ||
70 | * | ||
71 | * TLBs: | ||
72 | * | ||
73 | * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND | ||
74 | * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and | ||
75 | * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER | ||
76 | * are flushed at any MI_FLUSH. | ||
77 | */ | ||
78 | |||
79 | cmd = MI_FLUSH | MI_NO_WRITE_FLUSH; | ||
80 | if ((invalidate_domains|flush_domains) & | ||
81 | I915_GEM_DOMAIN_RENDER) | ||
82 | cmd &= ~MI_NO_WRITE_FLUSH; | ||
83 | if (!IS_I965G(dev)) { | ||
84 | /* | ||
85 | * On the 965, the sampler cache always gets flushed | ||
86 | * and this bit is reserved. | ||
87 | */ | ||
88 | if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER) | ||
89 | cmd |= MI_READ_FLUSH; | ||
90 | } | ||
91 | if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) | ||
92 | cmd |= MI_EXE_FLUSH; | ||
93 | |||
94 | #if WATCH_EXEC | ||
95 | DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); | ||
96 | #endif | ||
97 | intel_ring_begin(dev, ring, 8); | ||
98 | intel_ring_emit(dev, ring, cmd); | ||
99 | intel_ring_emit(dev, ring, MI_NOOP); | ||
100 | intel_ring_advance(dev, ring); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static unsigned int render_ring_get_head(struct drm_device *dev, | ||
105 | struct intel_ring_buffer *ring) | ||
106 | { | ||
107 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
108 | return I915_READ(PRB0_HEAD) & HEAD_ADDR; | ||
109 | } | ||
110 | |||
111 | static unsigned int render_ring_get_tail(struct drm_device *dev, | ||
112 | struct intel_ring_buffer *ring) | ||
113 | { | ||
114 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
115 | return I915_READ(PRB0_TAIL) & TAIL_ADDR; | ||
116 | } | ||
117 | |||
118 | static unsigned int render_ring_get_active_head(struct drm_device *dev, | ||
119 | struct intel_ring_buffer *ring) | ||
120 | { | ||
121 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
122 | u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; | ||
123 | |||
124 | return I915_READ(acthd_reg); | ||
125 | } | ||
126 | |||
127 | static void render_ring_advance_ring(struct drm_device *dev, | ||
128 | struct intel_ring_buffer *ring) | ||
129 | { | ||
130 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
131 | I915_WRITE(PRB0_TAIL, ring->tail); | ||
132 | } | ||
133 | |||
134 | static int init_ring_common(struct drm_device *dev, | ||
135 | struct intel_ring_buffer *ring) | ||
136 | { | ||
137 | u32 head; | ||
138 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
139 | struct drm_i915_gem_object *obj_priv; | ||
140 | obj_priv = to_intel_bo(ring->gem_object); | ||
141 | |||
142 | /* Stop the ring if it's running. */ | ||
143 | I915_WRITE(ring->regs.ctl, 0); | ||
144 | I915_WRITE(ring->regs.head, 0); | ||
145 | I915_WRITE(ring->regs.tail, 0); | ||
146 | |||
147 | /* Initialize the ring. */ | ||
148 | I915_WRITE(ring->regs.start, obj_priv->gtt_offset); | ||
149 | head = ring->get_head(dev, ring); | ||
150 | |||
151 | /* G45 ring initialization fails to reset head to zero */ | ||
152 | if (head != 0) { | ||
153 | DRM_ERROR("%s head not reset to zero " | ||
154 | "ctl %08x head %08x tail %08x start %08x\n", | ||
155 | ring->name, | ||
156 | I915_READ(ring->regs.ctl), | ||
157 | I915_READ(ring->regs.head), | ||
158 | I915_READ(ring->regs.tail), | ||
159 | I915_READ(ring->regs.start)); | ||
160 | |||
161 | I915_WRITE(ring->regs.head, 0); | ||
162 | |||
163 | DRM_ERROR("%s head forced to zero " | ||
164 | "ctl %08x head %08x tail %08x start %08x\n", | ||
165 | ring->name, | ||
166 | I915_READ(ring->regs.ctl), | ||
167 | I915_READ(ring->regs.head), | ||
168 | I915_READ(ring->regs.tail), | ||
169 | I915_READ(ring->regs.start)); | ||
170 | } | ||
171 | |||
172 | I915_WRITE(ring->regs.ctl, | ||
173 | ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | ||
174 | | RING_NO_REPORT | RING_VALID); | ||
175 | |||
176 | head = I915_READ(ring->regs.head) & HEAD_ADDR; | ||
177 | /* If the head is still not zero, the ring is dead */ | ||
178 | if (head != 0) { | ||
179 | DRM_ERROR("%s initialization failed " | ||
180 | "ctl %08x head %08x tail %08x start %08x\n", | ||
181 | ring->name, | ||
182 | I915_READ(ring->regs.ctl), | ||
183 | I915_READ(ring->regs.head), | ||
184 | I915_READ(ring->regs.tail), | ||
185 | I915_READ(ring->regs.start)); | ||
186 | return -EIO; | ||
187 | } | ||
188 | |||
189 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
190 | i915_kernel_lost_context(dev); | ||
191 | else { | ||
192 | ring->head = ring->get_head(dev, ring); | ||
193 | ring->tail = ring->get_tail(dev, ring); | ||
194 | ring->space = ring->head - (ring->tail + 8); | ||
195 | if (ring->space < 0) | ||
196 | ring->space += ring->size; | ||
197 | } | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int init_render_ring(struct drm_device *dev, | ||
202 | struct intel_ring_buffer *ring) | ||
203 | { | ||
204 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
205 | int ret = init_ring_common(dev, ring); | ||
206 | if (IS_I9XX(dev) && !IS_GEN3(dev)) { | ||
207 | I915_WRITE(MI_MODE, | ||
208 | (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); | ||
209 | } | ||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | #define PIPE_CONTROL_FLUSH(addr) \ | ||
214 | do { \ | ||
215 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ | ||
216 | PIPE_CONTROL_DEPTH_STALL | 2); \ | ||
217 | OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ | ||
218 | OUT_RING(0); \ | ||
219 | OUT_RING(0); \ | ||
220 | } while (0) | ||
221 | |||
222 | /** | ||
223 | * Creates a new sequence number, emitting a write of it to the status page | ||
224 | * plus an interrupt, which will trigger i915_user_interrupt_handler. | ||
225 | * | ||
226 | * Must be called with struct_lock held. | ||
227 | * | ||
228 | * Returned sequence numbers are nonzero on success. | ||
229 | */ | ||
230 | static u32 | ||
231 | render_ring_add_request(struct drm_device *dev, | ||
232 | struct intel_ring_buffer *ring, | ||
233 | struct drm_file *file_priv, | ||
234 | u32 flush_domains) | ||
235 | { | ||
236 | u32 seqno; | ||
237 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
238 | seqno = intel_ring_get_seqno(dev, ring); | ||
239 | |||
240 | if (IS_GEN6(dev)) { | ||
241 | BEGIN_LP_RING(6); | ||
242 | OUT_RING(GFX_OP_PIPE_CONTROL | 3); | ||
243 | OUT_RING(PIPE_CONTROL_QW_WRITE | | ||
244 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | | ||
245 | PIPE_CONTROL_NOTIFY); | ||
246 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
247 | OUT_RING(seqno); | ||
248 | OUT_RING(0); | ||
249 | OUT_RING(0); | ||
250 | ADVANCE_LP_RING(); | ||
251 | } else if (HAS_PIPE_CONTROL(dev)) { | ||
252 | u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; | ||
253 | |||
254 | /* | ||
255 | * Workaround qword write incoherence by flushing the | ||
256 | * PIPE_NOTIFY buffers out to memory before requesting | ||
257 | * an interrupt. | ||
258 | */ | ||
259 | BEGIN_LP_RING(32); | ||
260 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
261 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); | ||
262 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
263 | OUT_RING(seqno); | ||
264 | OUT_RING(0); | ||
265 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
266 | scratch_addr += 128; /* write to separate cachelines */ | ||
267 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
268 | scratch_addr += 128; | ||
269 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
270 | scratch_addr += 128; | ||
271 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
272 | scratch_addr += 128; | ||
273 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
274 | scratch_addr += 128; | ||
275 | PIPE_CONTROL_FLUSH(scratch_addr); | ||
276 | OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | | ||
277 | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | | ||
278 | PIPE_CONTROL_NOTIFY); | ||
279 | OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); | ||
280 | OUT_RING(seqno); | ||
281 | OUT_RING(0); | ||
282 | ADVANCE_LP_RING(); | ||
283 | } else { | ||
284 | BEGIN_LP_RING(4); | ||
285 | OUT_RING(MI_STORE_DWORD_INDEX); | ||
286 | OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
287 | OUT_RING(seqno); | ||
288 | |||
289 | OUT_RING(MI_USER_INTERRUPT); | ||
290 | ADVANCE_LP_RING(); | ||
291 | } | ||
292 | return seqno; | ||
293 | } | ||
294 | |||
295 | static u32 | ||
296 | render_ring_get_gem_seqno(struct drm_device *dev, | ||
297 | struct intel_ring_buffer *ring) | ||
298 | { | ||
299 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
300 | if (HAS_PIPE_CONTROL(dev)) | ||
301 | return ((volatile u32 *)(dev_priv->seqno_page))[0]; | ||
302 | else | ||
303 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | ||
304 | } | ||
305 | |||
306 | static void | ||
307 | render_ring_get_user_irq(struct drm_device *dev, | ||
308 | struct intel_ring_buffer *ring) | ||
309 | { | ||
310 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
311 | unsigned long irqflags; | ||
312 | |||
313 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
314 | if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) { | ||
315 | if (HAS_PCH_SPLIT(dev)) | ||
316 | ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | ||
317 | else | ||
318 | i915_enable_irq(dev_priv, I915_USER_INTERRUPT); | ||
319 | } | ||
320 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
321 | } | ||
322 | |||
323 | static void | ||
324 | render_ring_put_user_irq(struct drm_device *dev, | ||
325 | struct intel_ring_buffer *ring) | ||
326 | { | ||
327 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
328 | unsigned long irqflags; | ||
329 | |||
330 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | ||
331 | BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0); | ||
332 | if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) { | ||
333 | if (HAS_PCH_SPLIT(dev)) | ||
334 | ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); | ||
335 | else | ||
336 | i915_disable_irq(dev_priv, I915_USER_INTERRUPT); | ||
337 | } | ||
338 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | ||
339 | } | ||
340 | |||
341 | static void render_setup_status_page(struct drm_device *dev, | ||
342 | struct intel_ring_buffer *ring) | ||
343 | { | ||
344 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
345 | if (IS_GEN6(dev)) { | ||
346 | I915_WRITE(HWS_PGA_GEN6, ring->status_page.gfx_addr); | ||
347 | I915_READ(HWS_PGA_GEN6); /* posting read */ | ||
348 | } else { | ||
349 | I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); | ||
350 | I915_READ(HWS_PGA); /* posting read */ | ||
351 | } | ||
352 | |||
353 | } | ||
354 | |||
355 | void | ||
356 | bsd_ring_flush(struct drm_device *dev, | ||
357 | struct intel_ring_buffer *ring, | ||
358 | u32 invalidate_domains, | ||
359 | u32 flush_domains) | ||
360 | { | ||
361 | intel_ring_begin(dev, ring, 8); | ||
362 | intel_ring_emit(dev, ring, MI_FLUSH); | ||
363 | intel_ring_emit(dev, ring, MI_NOOP); | ||
364 | intel_ring_advance(dev, ring); | ||
365 | } | ||
366 | |||
367 | static inline unsigned int bsd_ring_get_head(struct drm_device *dev, | ||
368 | struct intel_ring_buffer *ring) | ||
369 | { | ||
370 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
371 | return I915_READ(BSD_RING_HEAD) & HEAD_ADDR; | ||
372 | } | ||
373 | |||
374 | static inline unsigned int bsd_ring_get_tail(struct drm_device *dev, | ||
375 | struct intel_ring_buffer *ring) | ||
376 | { | ||
377 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
378 | return I915_READ(BSD_RING_TAIL) & TAIL_ADDR; | ||
379 | } | ||
380 | |||
381 | static inline unsigned int bsd_ring_get_active_head(struct drm_device *dev, | ||
382 | struct intel_ring_buffer *ring) | ||
383 | { | ||
384 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
385 | return I915_READ(BSD_RING_ACTHD); | ||
386 | } | ||
387 | |||
388 | static inline void bsd_ring_advance_ring(struct drm_device *dev, | ||
389 | struct intel_ring_buffer *ring) | ||
390 | { | ||
391 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
392 | I915_WRITE(BSD_RING_TAIL, ring->tail); | ||
393 | } | ||
394 | |||
395 | static int init_bsd_ring(struct drm_device *dev, | ||
396 | struct intel_ring_buffer *ring) | ||
397 | { | ||
398 | return init_ring_common(dev, ring); | ||
399 | } | ||
400 | |||
401 | static u32 | ||
402 | bsd_ring_add_request(struct drm_device *dev, | ||
403 | struct intel_ring_buffer *ring, | ||
404 | struct drm_file *file_priv, | ||
405 | u32 flush_domains) | ||
406 | { | ||
407 | u32 seqno; | ||
408 | seqno = intel_ring_get_seqno(dev, ring); | ||
409 | intel_ring_begin(dev, ring, 4); | ||
410 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | ||
411 | intel_ring_emit(dev, ring, | ||
412 | I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); | ||
413 | intel_ring_emit(dev, ring, seqno); | ||
414 | intel_ring_emit(dev, ring, MI_USER_INTERRUPT); | ||
415 | intel_ring_advance(dev, ring); | ||
416 | |||
417 | DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); | ||
418 | |||
419 | return seqno; | ||
420 | } | ||
421 | |||
422 | static void bsd_setup_status_page(struct drm_device *dev, | ||
423 | struct intel_ring_buffer *ring) | ||
424 | { | ||
425 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
426 | I915_WRITE(BSD_HWS_PGA, ring->status_page.gfx_addr); | ||
427 | I915_READ(BSD_HWS_PGA); | ||
428 | } | ||
429 | |||
430 | static void | ||
431 | bsd_ring_get_user_irq(struct drm_device *dev, | ||
432 | struct intel_ring_buffer *ring) | ||
433 | { | ||
434 | /* do nothing */ | ||
435 | } | ||
436 | static void | ||
437 | bsd_ring_put_user_irq(struct drm_device *dev, | ||
438 | struct intel_ring_buffer *ring) | ||
439 | { | ||
440 | /* do nothing */ | ||
441 | } | ||
442 | |||
443 | static u32 | ||
444 | bsd_ring_get_gem_seqno(struct drm_device *dev, | ||
445 | struct intel_ring_buffer *ring) | ||
446 | { | ||
447 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | ||
448 | } | ||
449 | |||
450 | static int | ||
451 | bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev, | ||
452 | struct intel_ring_buffer *ring, | ||
453 | struct drm_i915_gem_execbuffer2 *exec, | ||
454 | struct drm_clip_rect *cliprects, | ||
455 | uint64_t exec_offset) | ||
456 | { | ||
457 | uint32_t exec_start; | ||
458 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
459 | intel_ring_begin(dev, ring, 2); | ||
460 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | | ||
461 | (2 << 6) | MI_BATCH_NON_SECURE_I965); | ||
462 | intel_ring_emit(dev, ring, exec_start); | ||
463 | intel_ring_advance(dev, ring); | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | |||
468 | static int | ||
469 | render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | ||
470 | struct intel_ring_buffer *ring, | ||
471 | struct drm_i915_gem_execbuffer2 *exec, | ||
472 | struct drm_clip_rect *cliprects, | ||
473 | uint64_t exec_offset) | ||
474 | { | ||
475 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
476 | int nbox = exec->num_cliprects; | ||
477 | int i = 0, count; | ||
478 | uint32_t exec_start, exec_len; | ||
479 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | ||
480 | exec_len = (uint32_t) exec->batch_len; | ||
481 | |||
482 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | ||
483 | |||
484 | count = nbox ? nbox : 1; | ||
485 | |||
486 | for (i = 0; i < count; i++) { | ||
487 | if (i < nbox) { | ||
488 | int ret = i915_emit_box(dev, cliprects, i, | ||
489 | exec->DR1, exec->DR4); | ||
490 | if (ret) | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | if (IS_I830(dev) || IS_845G(dev)) { | ||
495 | intel_ring_begin(dev, ring, 4); | ||
496 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER); | ||
497 | intel_ring_emit(dev, ring, | ||
498 | exec_start | MI_BATCH_NON_SECURE); | ||
499 | intel_ring_emit(dev, ring, exec_start + exec_len - 4); | ||
500 | intel_ring_emit(dev, ring, 0); | ||
501 | } else { | ||
502 | intel_ring_begin(dev, ring, 4); | ||
503 | if (IS_I965G(dev)) { | ||
504 | intel_ring_emit(dev, ring, | ||
505 | MI_BATCH_BUFFER_START | (2 << 6) | ||
506 | | MI_BATCH_NON_SECURE_I965); | ||
507 | intel_ring_emit(dev, ring, exec_start); | ||
508 | } else { | ||
509 | intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | ||
510 | | (2 << 6)); | ||
511 | intel_ring_emit(dev, ring, exec_start | | ||
512 | MI_BATCH_NON_SECURE); | ||
513 | } | ||
514 | } | ||
515 | intel_ring_advance(dev, ring); | ||
516 | } | ||
517 | |||
518 | /* XXX breadcrumb */ | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static void cleanup_status_page(struct drm_device *dev, | ||
523 | struct intel_ring_buffer *ring) | ||
524 | { | ||
525 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
526 | struct drm_gem_object *obj; | ||
527 | struct drm_i915_gem_object *obj_priv; | ||
528 | |||
529 | obj = ring->status_page.obj; | ||
530 | if (obj == NULL) | ||
531 | return; | ||
532 | obj_priv = to_intel_bo(obj); | ||
533 | |||
534 | kunmap(obj_priv->pages[0]); | ||
535 | i915_gem_object_unpin(obj); | ||
536 | drm_gem_object_unreference(obj); | ||
537 | ring->status_page.obj = NULL; | ||
538 | |||
539 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
540 | } | ||
541 | |||
542 | static int init_status_page(struct drm_device *dev, | ||
543 | struct intel_ring_buffer *ring) | ||
544 | { | ||
545 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
546 | struct drm_gem_object *obj; | ||
547 | struct drm_i915_gem_object *obj_priv; | ||
548 | int ret; | ||
549 | |||
550 | obj = i915_gem_alloc_object(dev, 4096); | ||
551 | if (obj == NULL) { | ||
552 | DRM_ERROR("Failed to allocate status page\n"); | ||
553 | ret = -ENOMEM; | ||
554 | goto err; | ||
555 | } | ||
556 | obj_priv = to_intel_bo(obj); | ||
557 | obj_priv->agp_type = AGP_USER_CACHED_MEMORY; | ||
558 | |||
559 | ret = i915_gem_object_pin(obj, 4096); | ||
560 | if (ret != 0) { | ||
561 | goto err_unref; | ||
562 | } | ||
563 | |||
564 | ring->status_page.gfx_addr = obj_priv->gtt_offset; | ||
565 | ring->status_page.page_addr = kmap(obj_priv->pages[0]); | ||
566 | if (ring->status_page.page_addr == NULL) { | ||
567 | memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); | ||
568 | goto err_unpin; | ||
569 | } | ||
570 | ring->status_page.obj = obj; | ||
571 | memset(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
572 | |||
573 | ring->setup_status_page(dev, ring); | ||
574 | DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", | ||
575 | ring->name, ring->status_page.gfx_addr); | ||
576 | |||
577 | return 0; | ||
578 | |||
579 | err_unpin: | ||
580 | i915_gem_object_unpin(obj); | ||
581 | err_unref: | ||
582 | drm_gem_object_unreference(obj); | ||
583 | err: | ||
584 | return ret; | ||
585 | } | ||
586 | |||
587 | |||
588 | int intel_init_ring_buffer(struct drm_device *dev, | ||
589 | struct intel_ring_buffer *ring) | ||
590 | { | ||
591 | int ret; | ||
592 | struct drm_i915_gem_object *obj_priv; | ||
593 | struct drm_gem_object *obj; | ||
594 | ring->dev = dev; | ||
595 | |||
596 | if (I915_NEED_GFX_HWS(dev)) { | ||
597 | ret = init_status_page(dev, ring); | ||
598 | if (ret) | ||
599 | return ret; | ||
600 | } | ||
601 | |||
602 | obj = i915_gem_alloc_object(dev, ring->size); | ||
603 | if (obj == NULL) { | ||
604 | DRM_ERROR("Failed to allocate ringbuffer\n"); | ||
605 | ret = -ENOMEM; | ||
606 | goto cleanup; | ||
607 | } | ||
608 | |||
609 | ring->gem_object = obj; | ||
610 | |||
611 | ret = i915_gem_object_pin(obj, ring->alignment); | ||
612 | if (ret != 0) { | ||
613 | drm_gem_object_unreference(obj); | ||
614 | goto cleanup; | ||
615 | } | ||
616 | |||
617 | obj_priv = to_intel_bo(obj); | ||
618 | ring->map.size = ring->size; | ||
619 | ring->map.offset = dev->agp->base + obj_priv->gtt_offset; | ||
620 | ring->map.type = 0; | ||
621 | ring->map.flags = 0; | ||
622 | ring->map.mtrr = 0; | ||
623 | |||
624 | drm_core_ioremap_wc(&ring->map, dev); | ||
625 | if (ring->map.handle == NULL) { | ||
626 | DRM_ERROR("Failed to map ringbuffer.\n"); | ||
627 | i915_gem_object_unpin(obj); | ||
628 | drm_gem_object_unreference(obj); | ||
629 | ret = -EINVAL; | ||
630 | goto cleanup; | ||
631 | } | ||
632 | |||
633 | ring->virtual_start = ring->map.handle; | ||
634 | ret = ring->init(dev, ring); | ||
635 | if (ret != 0) { | ||
636 | intel_cleanup_ring_buffer(dev, ring); | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
641 | i915_kernel_lost_context(dev); | ||
642 | else { | ||
643 | ring->head = ring->get_head(dev, ring); | ||
644 | ring->tail = ring->get_tail(dev, ring); | ||
645 | ring->space = ring->head - (ring->tail + 8); | ||
646 | if (ring->space < 0) | ||
647 | ring->space += ring->size; | ||
648 | } | ||
649 | INIT_LIST_HEAD(&ring->active_list); | ||
650 | INIT_LIST_HEAD(&ring->request_list); | ||
651 | return ret; | ||
652 | cleanup: | ||
653 | cleanup_status_page(dev, ring); | ||
654 | return ret; | ||
655 | } | ||
656 | |||
657 | void intel_cleanup_ring_buffer(struct drm_device *dev, | ||
658 | struct intel_ring_buffer *ring) | ||
659 | { | ||
660 | if (ring->gem_object == NULL) | ||
661 | return; | ||
662 | |||
663 | drm_core_ioremapfree(&ring->map, dev); | ||
664 | |||
665 | i915_gem_object_unpin(ring->gem_object); | ||
666 | drm_gem_object_unreference(ring->gem_object); | ||
667 | ring->gem_object = NULL; | ||
668 | cleanup_status_page(dev, ring); | ||
669 | } | ||
670 | |||
671 | int intel_wrap_ring_buffer(struct drm_device *dev, | ||
672 | struct intel_ring_buffer *ring) | ||
673 | { | ||
674 | unsigned int *virt; | ||
675 | int rem; | ||
676 | rem = ring->size - ring->tail; | ||
677 | |||
678 | if (ring->space < rem) { | ||
679 | int ret = intel_wait_ring_buffer(dev, ring, rem); | ||
680 | if (ret) | ||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | virt = (unsigned int *)(ring->virtual_start + ring->tail); | ||
685 | rem /= 4; | ||
686 | while (rem--) | ||
687 | *virt++ = MI_NOOP; | ||
688 | |||
689 | ring->tail = 0; | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | int intel_wait_ring_buffer(struct drm_device *dev, | ||
695 | struct intel_ring_buffer *ring, int n) | ||
696 | { | ||
697 | unsigned long end; | ||
698 | |||
699 | trace_i915_ring_wait_begin (dev); | ||
700 | end = jiffies + 3 * HZ; | ||
701 | do { | ||
702 | ring->head = ring->get_head(dev, ring); | ||
703 | ring->space = ring->head - (ring->tail + 8); | ||
704 | if (ring->space < 0) | ||
705 | ring->space += ring->size; | ||
706 | if (ring->space >= n) { | ||
707 | trace_i915_ring_wait_end (dev); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | if (dev->primary->master) { | ||
712 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
713 | if (master_priv->sarea_priv) | ||
714 | master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; | ||
715 | } | ||
716 | |||
717 | yield(); | ||
718 | } while (!time_after(jiffies, end)); | ||
719 | trace_i915_ring_wait_end (dev); | ||
720 | return -EBUSY; | ||
721 | } | ||
722 | |||
723 | void intel_ring_begin(struct drm_device *dev, | ||
724 | struct intel_ring_buffer *ring, int n) | ||
725 | { | ||
726 | if (unlikely(ring->tail + n > ring->size)) | ||
727 | intel_wrap_ring_buffer(dev, ring); | ||
728 | if (unlikely(ring->space < n)) | ||
729 | intel_wait_ring_buffer(dev, ring, n); | ||
730 | } | ||
731 | |||
732 | void intel_ring_emit(struct drm_device *dev, | ||
733 | struct intel_ring_buffer *ring, unsigned int data) | ||
734 | { | ||
735 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
736 | *virt = data; | ||
737 | ring->tail += 4; | ||
738 | ring->tail &= ring->size - 1; | ||
739 | ring->space -= 4; | ||
740 | } | ||
741 | |||
742 | void intel_ring_advance(struct drm_device *dev, | ||
743 | struct intel_ring_buffer *ring) | ||
744 | { | ||
745 | ring->advance_ring(dev, ring); | ||
746 | } | ||
747 | |||
748 | void intel_fill_struct(struct drm_device *dev, | ||
749 | struct intel_ring_buffer *ring, | ||
750 | void *data, | ||
751 | unsigned int len) | ||
752 | { | ||
753 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
754 | BUG_ON((len&~(4-1)) != 0); | ||
755 | intel_ring_begin(dev, ring, len); | ||
756 | memcpy(virt, data, len); | ||
757 | ring->tail += len; | ||
758 | ring->tail &= ring->size - 1; | ||
759 | ring->space -= len; | ||
760 | intel_ring_advance(dev, ring); | ||
761 | } | ||
762 | |||
763 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
764 | struct intel_ring_buffer *ring) | ||
765 | { | ||
766 | u32 seqno; | ||
767 | seqno = ring->next_seqno; | ||
768 | |||
769 | /* reserve 0 for non-seqno */ | ||
770 | if (++ring->next_seqno == 0) | ||
771 | ring->next_seqno = 1; | ||
772 | return seqno; | ||
773 | } | ||
774 | |||
775 | struct intel_ring_buffer render_ring = { | ||
776 | .name = "render ring", | ||
777 | .regs = { | ||
778 | .ctl = PRB0_CTL, | ||
779 | .head = PRB0_HEAD, | ||
780 | .tail = PRB0_TAIL, | ||
781 | .start = PRB0_START | ||
782 | }, | ||
783 | .ring_flag = I915_EXEC_RENDER, | ||
784 | .size = 32 * PAGE_SIZE, | ||
785 | .alignment = PAGE_SIZE, | ||
786 | .virtual_start = NULL, | ||
787 | .dev = NULL, | ||
788 | .gem_object = NULL, | ||
789 | .head = 0, | ||
790 | .tail = 0, | ||
791 | .space = 0, | ||
792 | .next_seqno = 1, | ||
793 | .user_irq_refcount = 0, | ||
794 | .irq_gem_seqno = 0, | ||
795 | .waiting_gem_seqno = 0, | ||
796 | .setup_status_page = render_setup_status_page, | ||
797 | .init = init_render_ring, | ||
798 | .get_head = render_ring_get_head, | ||
799 | .get_tail = render_ring_get_tail, | ||
800 | .get_active_head = render_ring_get_active_head, | ||
801 | .advance_ring = render_ring_advance_ring, | ||
802 | .flush = render_ring_flush, | ||
803 | .add_request = render_ring_add_request, | ||
804 | .get_gem_seqno = render_ring_get_gem_seqno, | ||
805 | .user_irq_get = render_ring_get_user_irq, | ||
806 | .user_irq_put = render_ring_put_user_irq, | ||
807 | .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, | ||
808 | .status_page = {NULL, 0, NULL}, | ||
809 | .map = {0,} | ||
810 | }; | ||
811 | |||
812 | /* ring buffer for bit-stream decoder */ | ||
813 | |||
814 | struct intel_ring_buffer bsd_ring = { | ||
815 | .name = "bsd ring", | ||
816 | .regs = { | ||
817 | .ctl = BSD_RING_CTL, | ||
818 | .head = BSD_RING_HEAD, | ||
819 | .tail = BSD_RING_TAIL, | ||
820 | .start = BSD_RING_START | ||
821 | }, | ||
822 | .ring_flag = I915_EXEC_BSD, | ||
823 | .size = 32 * PAGE_SIZE, | ||
824 | .alignment = PAGE_SIZE, | ||
825 | .virtual_start = NULL, | ||
826 | .dev = NULL, | ||
827 | .gem_object = NULL, | ||
828 | .head = 0, | ||
829 | .tail = 0, | ||
830 | .space = 0, | ||
831 | .next_seqno = 1, | ||
832 | .user_irq_refcount = 0, | ||
833 | .irq_gem_seqno = 0, | ||
834 | .waiting_gem_seqno = 0, | ||
835 | .setup_status_page = bsd_setup_status_page, | ||
836 | .init = init_bsd_ring, | ||
837 | .get_head = bsd_ring_get_head, | ||
838 | .get_tail = bsd_ring_get_tail, | ||
839 | .get_active_head = bsd_ring_get_active_head, | ||
840 | .advance_ring = bsd_ring_advance_ring, | ||
841 | .flush = bsd_ring_flush, | ||
842 | .add_request = bsd_ring_add_request, | ||
843 | .get_gem_seqno = bsd_ring_get_gem_seqno, | ||
844 | .user_irq_get = bsd_ring_get_user_irq, | ||
845 | .user_irq_put = bsd_ring_put_user_irq, | ||
846 | .dispatch_gem_execbuffer = bsd_ring_dispatch_gem_execbuffer, | ||
847 | .status_page = {NULL, 0, NULL}, | ||
848 | .map = {0,} | ||
849 | }; | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h new file mode 100644 index 000000000000..d5568d3766de --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -0,0 +1,124 @@ | |||
1 | #ifndef _INTEL_RINGBUFFER_H_ | ||
2 | #define _INTEL_RINGBUFFER_H_ | ||
3 | |||
4 | struct intel_hw_status_page { | ||
5 | void *page_addr; | ||
6 | unsigned int gfx_addr; | ||
7 | struct drm_gem_object *obj; | ||
8 | }; | ||
9 | |||
10 | struct drm_i915_gem_execbuffer2; | ||
11 | struct intel_ring_buffer { | ||
12 | const char *name; | ||
13 | struct ring_regs { | ||
14 | u32 ctl; | ||
15 | u32 head; | ||
16 | u32 tail; | ||
17 | u32 start; | ||
18 | } regs; | ||
19 | unsigned int ring_flag; | ||
20 | unsigned long size; | ||
21 | unsigned int alignment; | ||
22 | void *virtual_start; | ||
23 | struct drm_device *dev; | ||
24 | struct drm_gem_object *gem_object; | ||
25 | |||
26 | unsigned int head; | ||
27 | unsigned int tail; | ||
28 | unsigned int space; | ||
29 | u32 next_seqno; | ||
30 | struct intel_hw_status_page status_page; | ||
31 | |||
32 | u32 irq_gem_seqno; /* last seq seem at irq time */ | ||
33 | u32 waiting_gem_seqno; | ||
34 | int user_irq_refcount; | ||
35 | void (*user_irq_get)(struct drm_device *dev, | ||
36 | struct intel_ring_buffer *ring); | ||
37 | void (*user_irq_put)(struct drm_device *dev, | ||
38 | struct intel_ring_buffer *ring); | ||
39 | void (*setup_status_page)(struct drm_device *dev, | ||
40 | struct intel_ring_buffer *ring); | ||
41 | |||
42 | int (*init)(struct drm_device *dev, | ||
43 | struct intel_ring_buffer *ring); | ||
44 | |||
45 | unsigned int (*get_head)(struct drm_device *dev, | ||
46 | struct intel_ring_buffer *ring); | ||
47 | unsigned int (*get_tail)(struct drm_device *dev, | ||
48 | struct intel_ring_buffer *ring); | ||
49 | unsigned int (*get_active_head)(struct drm_device *dev, | ||
50 | struct intel_ring_buffer *ring); | ||
51 | void (*advance_ring)(struct drm_device *dev, | ||
52 | struct intel_ring_buffer *ring); | ||
53 | void (*flush)(struct drm_device *dev, | ||
54 | struct intel_ring_buffer *ring, | ||
55 | u32 invalidate_domains, | ||
56 | u32 flush_domains); | ||
57 | u32 (*add_request)(struct drm_device *dev, | ||
58 | struct intel_ring_buffer *ring, | ||
59 | struct drm_file *file_priv, | ||
60 | u32 flush_domains); | ||
61 | u32 (*get_gem_seqno)(struct drm_device *dev, | ||
62 | struct intel_ring_buffer *ring); | ||
63 | int (*dispatch_gem_execbuffer)(struct drm_device *dev, | ||
64 | struct intel_ring_buffer *ring, | ||
65 | struct drm_i915_gem_execbuffer2 *exec, | ||
66 | struct drm_clip_rect *cliprects, | ||
67 | uint64_t exec_offset); | ||
68 | |||
69 | /** | ||
70 | * List of objects currently involved in rendering from the | ||
71 | * ringbuffer. | ||
72 | * | ||
73 | * Includes buffers having the contents of their GPU caches | ||
74 | * flushed, not necessarily primitives. last_rendering_seqno | ||
75 | * represents when the rendering involved will be completed. | ||
76 | * | ||
77 | * A reference is held on the buffer while on this list. | ||
78 | */ | ||
79 | struct list_head active_list; | ||
80 | |||
81 | /** | ||
82 | * List of breadcrumbs associated with GPU requests currently | ||
83 | * outstanding. | ||
84 | */ | ||
85 | struct list_head request_list; | ||
86 | |||
87 | wait_queue_head_t irq_queue; | ||
88 | drm_local_map_t map; | ||
89 | }; | ||
90 | |||
91 | static inline u32 | ||
92 | intel_read_status_page(struct intel_ring_buffer *ring, | ||
93 | int reg) | ||
94 | { | ||
95 | u32 *regs = ring->status_page.page_addr; | ||
96 | return regs[reg]; | ||
97 | } | ||
98 | |||
99 | int intel_init_ring_buffer(struct drm_device *dev, | ||
100 | struct intel_ring_buffer *ring); | ||
101 | void intel_cleanup_ring_buffer(struct drm_device *dev, | ||
102 | struct intel_ring_buffer *ring); | ||
103 | int intel_wait_ring_buffer(struct drm_device *dev, | ||
104 | struct intel_ring_buffer *ring, int n); | ||
105 | int intel_wrap_ring_buffer(struct drm_device *dev, | ||
106 | struct intel_ring_buffer *ring); | ||
107 | void intel_ring_begin(struct drm_device *dev, | ||
108 | struct intel_ring_buffer *ring, int n); | ||
109 | void intel_ring_emit(struct drm_device *dev, | ||
110 | struct intel_ring_buffer *ring, u32 data); | ||
111 | void intel_fill_struct(struct drm_device *dev, | ||
112 | struct intel_ring_buffer *ring, | ||
113 | void *data, | ||
114 | unsigned int len); | ||
115 | void intel_ring_advance(struct drm_device *dev, | ||
116 | struct intel_ring_buffer *ring); | ||
117 | |||
118 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
119 | struct intel_ring_buffer *ring); | ||
120 | |||
121 | extern struct intel_ring_buffer render_ring; | ||
122 | extern struct intel_ring_buffer bsd_ring; | ||
123 | |||
124 | #endif /* _INTEL_RINGBUFFER_H_ */ | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index aba72c489a2f..76993ac16cc1 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1479,7 +1479,7 @@ intel_find_analog_connector(struct drm_device *dev) | |||
1479 | intel_encoder = enc_to_intel_encoder(encoder); | 1479 | intel_encoder = enc_to_intel_encoder(encoder); |
1480 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { | 1480 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { |
1481 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1481 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1482 | if (connector && encoder == intel_attached_encoder(connector)) | 1482 | if (encoder == intel_attached_encoder(connector)) |
1483 | return connector; | 1483 | return connector; |
1484 | } | 1484 | } |
1485 | } | 1485 | } |