diff options
Diffstat (limited to 'drivers')
26 files changed, 1361 insertions, 1174 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b427711be4be..962e75dc4781 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -850,6 +850,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
850 | .subvendor = PCI_ANY_ID, \ | 850 | .subvendor = PCI_ANY_ID, \ |
851 | .subdevice = PCI_ANY_ID, \ | 851 | .subdevice = PCI_ANY_ID, \ |
852 | } | 852 | } |
853 | ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */ | ||
853 | ID(PCI_DEVICE_ID_INTEL_82443LX_0), | 854 | ID(PCI_DEVICE_ID_INTEL_82443LX_0), |
854 | ID(PCI_DEVICE_ID_INTEL_82443BX_0), | 855 | ID(PCI_DEVICE_ID_INTEL_82443BX_0), |
855 | ID(PCI_DEVICE_ID_INTEL_82443GX_0), | 856 | ID(PCI_DEVICE_ID_INTEL_82443GX_0), |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index c92424ca1a55..5cf47ac2d401 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -76,7 +76,6 @@ static struct _intel_private { | |||
76 | struct resource ifp_resource; | 76 | struct resource ifp_resource; |
77 | int resource_valid; | 77 | int resource_valid; |
78 | struct page *scratch_page; | 78 | struct page *scratch_page; |
79 | dma_addr_t scratch_page_dma; | ||
80 | } intel_private; | 79 | } intel_private; |
81 | 80 | ||
82 | #define INTEL_GTT_GEN intel_private.driver->gen | 81 | #define INTEL_GTT_GEN intel_private.driver->gen |
@@ -306,9 +305,9 @@ static int intel_gtt_setup_scratch_page(void) | |||
306 | if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) | 305 | if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) |
307 | return -EINVAL; | 306 | return -EINVAL; |
308 | 307 | ||
309 | intel_private.scratch_page_dma = dma_addr; | 308 | intel_private.base.scratch_page_dma = dma_addr; |
310 | } else | 309 | } else |
311 | intel_private.scratch_page_dma = page_to_phys(page); | 310 | intel_private.base.scratch_page_dma = page_to_phys(page); |
312 | 311 | ||
313 | intel_private.scratch_page = page; | 312 | intel_private.scratch_page = page; |
314 | 313 | ||
@@ -631,7 +630,7 @@ static unsigned int intel_gtt_mappable_entries(void) | |||
631 | static void intel_gtt_teardown_scratch_page(void) | 630 | static void intel_gtt_teardown_scratch_page(void) |
632 | { | 631 | { |
633 | set_pages_wb(intel_private.scratch_page, 1); | 632 | set_pages_wb(intel_private.scratch_page, 1); |
634 | pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, | 633 | pci_unmap_page(intel_private.pcidev, intel_private.base.scratch_page_dma, |
635 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 634 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
636 | put_page(intel_private.scratch_page); | 635 | put_page(intel_private.scratch_page); |
637 | __free_page(intel_private.scratch_page); | 636 | __free_page(intel_private.scratch_page); |
@@ -681,6 +680,7 @@ static int intel_gtt_init(void) | |||
681 | iounmap(intel_private.registers); | 680 | iounmap(intel_private.registers); |
682 | return -ENOMEM; | 681 | return -ENOMEM; |
683 | } | 682 | } |
683 | intel_private.base.gtt = intel_private.gtt; | ||
684 | 684 | ||
685 | global_cache_flush(); /* FIXME: ? */ | 685 | global_cache_flush(); /* FIXME: ? */ |
686 | 686 | ||
@@ -975,7 +975,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) | |||
975 | unsigned int i; | 975 | unsigned int i; |
976 | 976 | ||
977 | for (i = first_entry; i < (first_entry + num_entries); i++) { | 977 | for (i = first_entry; i < (first_entry + num_entries); i++) { |
978 | intel_private.driver->write_entry(intel_private.scratch_page_dma, | 978 | intel_private.driver->write_entry(intel_private.base.scratch_page_dma, |
979 | i, 0); | 979 | i, 0); |
980 | } | 980 | } |
981 | readl(intel_private.gtt+i-1); | 981 | readl(intel_private.gtt+i-1); |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 956fd38d7c9e..2300ab1a2a77 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "drm_core.h" | 37 | #include "drm_core.h" |
38 | 38 | ||
39 | #include "linux/pci.h" | 39 | #include "linux/pci.h" |
40 | #include "linux/export.h" | ||
40 | 41 | ||
41 | /** | 42 | /** |
42 | * Get the bus id. | 43 | * Get the bus id. |
@@ -346,3 +347,4 @@ int drm_noop(struct drm_device *dev, void *data, | |||
346 | DRM_DEBUG("\n"); | 347 | DRM_DEBUG("\n"); |
347 | return 0; | 348 | return 0; |
348 | } | 349 | } |
350 | EXPORT_SYMBOL(drm_noop); | ||
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 808b255d7fc6..ce7fc77678b4 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
4 | 4 | ||
5 | ccflags-y := -Iinclude/drm | 5 | ccflags-y := -Iinclude/drm |
6 | i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | 6 | i915-y := i915_drv.o i915_dma.o i915_irq.o \ |
7 | i915_debugfs.o \ | 7 | i915_debugfs.o \ |
8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
9 | i915_gem.o \ | 9 | i915_gem.o \ |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index deaa657292b4..ae73288a9699 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -83,6 +83,7 @@ static int i915_capabilities(struct seq_file *m, void *data) | |||
83 | B(supports_tv); | 83 | B(supports_tv); |
84 | B(has_bsd_ring); | 84 | B(has_bsd_ring); |
85 | B(has_blt_ring); | 85 | B(has_blt_ring); |
86 | B(has_llc); | ||
86 | #undef B | 87 | #undef B |
87 | 88 | ||
88 | return 0; | 89 | return 0; |
@@ -563,45 +564,6 @@ static int i915_hws_info(struct seq_file *m, void *data) | |||
563 | return 0; | 564 | return 0; |
564 | } | 565 | } |
565 | 566 | ||
566 | static void i915_dump_object(struct seq_file *m, | ||
567 | struct io_mapping *mapping, | ||
568 | struct drm_i915_gem_object *obj) | ||
569 | { | ||
570 | int page, page_count, i; | ||
571 | |||
572 | page_count = obj->base.size / PAGE_SIZE; | ||
573 | for (page = 0; page < page_count; page++) { | ||
574 | u32 *mem = io_mapping_map_wc(mapping, | ||
575 | obj->gtt_offset + page * PAGE_SIZE); | ||
576 | for (i = 0; i < PAGE_SIZE; i += 4) | ||
577 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | ||
578 | io_mapping_unmap(mem); | ||
579 | } | ||
580 | } | ||
581 | |||
582 | static int i915_batchbuffer_info(struct seq_file *m, void *data) | ||
583 | { | ||
584 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
585 | struct drm_device *dev = node->minor->dev; | ||
586 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
587 | struct drm_i915_gem_object *obj; | ||
588 | int ret; | ||
589 | |||
590 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
591 | if (ret) | ||
592 | return ret; | ||
593 | |||
594 | list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { | ||
595 | if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { | ||
596 | seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); | ||
597 | i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); | ||
598 | } | ||
599 | } | ||
600 | |||
601 | mutex_unlock(&dev->struct_mutex); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static int i915_ringbuffer_data(struct seq_file *m, void *data) | 567 | static int i915_ringbuffer_data(struct seq_file *m, void *data) |
606 | { | 568 | { |
607 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 569 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -668,9 +630,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
668 | static const char *ring_str(int ring) | 630 | static const char *ring_str(int ring) |
669 | { | 631 | { |
670 | switch (ring) { | 632 | switch (ring) { |
671 | case RING_RENDER: return " render"; | 633 | case RCS: return "render"; |
672 | case RING_BSD: return " bsd"; | 634 | case VCS: return "bsd"; |
673 | case RING_BLT: return " blt"; | 635 | case BCS: return "blt"; |
674 | default: return ""; | 636 | default: return ""; |
675 | } | 637 | } |
676 | } | 638 | } |
@@ -713,7 +675,7 @@ static void print_error_buffers(struct seq_file *m, | |||
713 | seq_printf(m, "%s [%d]:\n", name, count); | 675 | seq_printf(m, "%s [%d]:\n", name, count); |
714 | 676 | ||
715 | while (count--) { | 677 | while (count--) { |
716 | seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", | 678 | seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", |
717 | err->gtt_offset, | 679 | err->gtt_offset, |
718 | err->size, | 680 | err->size, |
719 | err->read_domains, | 681 | err->read_domains, |
@@ -723,6 +685,7 @@ static void print_error_buffers(struct seq_file *m, | |||
723 | tiling_flag(err->tiling), | 685 | tiling_flag(err->tiling), |
724 | dirty_flag(err->dirty), | 686 | dirty_flag(err->dirty), |
725 | purgeable_flag(err->purgeable), | 687 | purgeable_flag(err->purgeable), |
688 | err->ring != -1 ? " " : "", | ||
726 | ring_str(err->ring), | 689 | ring_str(err->ring), |
727 | cache_level_str(err->cache_level)); | 690 | cache_level_str(err->cache_level)); |
728 | 691 | ||
@@ -736,6 +699,38 @@ static void print_error_buffers(struct seq_file *m, | |||
736 | } | 699 | } |
737 | } | 700 | } |
738 | 701 | ||
702 | static void i915_ring_error_state(struct seq_file *m, | ||
703 | struct drm_device *dev, | ||
704 | struct drm_i915_error_state *error, | ||
705 | unsigned ring) | ||
706 | { | ||
707 | seq_printf(m, "%s command stream:\n", ring_str(ring)); | ||
708 | seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]); | ||
709 | seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); | ||
710 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); | ||
711 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); | ||
712 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); | ||
713 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); | ||
714 | if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { | ||
715 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
716 | seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); | ||
717 | } | ||
718 | if (INTEL_INFO(dev)->gen >= 4) | ||
719 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); | ||
720 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); | ||
721 | if (INTEL_INFO(dev)->gen >= 6) { | ||
722 | seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); | ||
723 | seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); | ||
724 | seq_printf(m, " SYNC_0: 0x%08x\n", | ||
725 | error->semaphore_mboxes[ring][0]); | ||
726 | seq_printf(m, " SYNC_1: 0x%08x\n", | ||
727 | error->semaphore_mboxes[ring][1]); | ||
728 | } | ||
729 | seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); | ||
730 | seq_printf(m, " ring->head: 0x%08x\n", error->cpu_ring_head[ring]); | ||
731 | seq_printf(m, " ring->tail: 0x%08x\n", error->cpu_ring_tail[ring]); | ||
732 | } | ||
733 | |||
739 | static int i915_error_state(struct seq_file *m, void *unused) | 734 | static int i915_error_state(struct seq_file *m, void *unused) |
740 | { | 735 | { |
741 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 736 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -758,35 +753,20 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
758 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); | 753 | seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); |
759 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | 754 | seq_printf(m, "EIR: 0x%08x\n", error->eir); |
760 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); | 755 | seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); |
756 | |||
757 | for (i = 0; i < dev_priv->num_fence_regs; i++) | ||
758 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); | ||
759 | |||
761 | if (INTEL_INFO(dev)->gen >= 6) { | 760 | if (INTEL_INFO(dev)->gen >= 6) { |
762 | seq_printf(m, "ERROR: 0x%08x\n", error->error); | 761 | seq_printf(m, "ERROR: 0x%08x\n", error->error); |
763 | seq_printf(m, "Blitter command stream:\n"); | 762 | seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); |
764 | seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); | ||
765 | seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); | ||
766 | seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); | ||
767 | seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); | ||
768 | seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); | ||
769 | seq_printf(m, "Video (BSD) command stream:\n"); | ||
770 | seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); | ||
771 | seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); | ||
772 | seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); | ||
773 | seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); | ||
774 | seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); | ||
775 | } | ||
776 | seq_printf(m, "Render command stream:\n"); | ||
777 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
778 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | ||
779 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | ||
780 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | ||
781 | if (INTEL_INFO(dev)->gen >= 4) { | ||
782 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
783 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
784 | } | 763 | } |
785 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | ||
786 | seq_printf(m, " seqno: 0x%08x\n", error->seqno); | ||
787 | 764 | ||
788 | for (i = 0; i < dev_priv->num_fence_regs; i++) | 765 | i915_ring_error_state(m, dev, error, RCS); |
789 | seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); | 766 | if (HAS_BLT(dev)) |
767 | i915_ring_error_state(m, dev, error, BCS); | ||
768 | if (HAS_BSD(dev)) | ||
769 | i915_ring_error_state(m, dev, error, VCS); | ||
790 | 770 | ||
791 | if (error->active_bo) | 771 | if (error->active_bo) |
792 | print_error_buffers(m, "Active", | 772 | print_error_buffers(m, "Active", |
@@ -1414,9 +1394,108 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) | |||
1414 | return 0; | 1394 | return 0; |
1415 | } | 1395 | } |
1416 | 1396 | ||
1397 | static const char *swizzle_string(unsigned swizzle) | ||
1398 | { | ||
1399 | switch(swizzle) { | ||
1400 | case I915_BIT_6_SWIZZLE_NONE: | ||
1401 | return "none"; | ||
1402 | case I915_BIT_6_SWIZZLE_9: | ||
1403 | return "bit9"; | ||
1404 | case I915_BIT_6_SWIZZLE_9_10: | ||
1405 | return "bit9/bit10"; | ||
1406 | case I915_BIT_6_SWIZZLE_9_11: | ||
1407 | return "bit9/bit11"; | ||
1408 | case I915_BIT_6_SWIZZLE_9_10_11: | ||
1409 | return "bit9/bit10/bit11"; | ||
1410 | case I915_BIT_6_SWIZZLE_9_17: | ||
1411 | return "bit9/bit17"; | ||
1412 | case I915_BIT_6_SWIZZLE_9_10_17: | ||
1413 | return "bit9/bit10/bit17"; | ||
1414 | case I915_BIT_6_SWIZZLE_UNKNOWN: | ||
1415 | return "unkown"; | ||
1416 | } | ||
1417 | |||
1418 | return "bug"; | ||
1419 | } | ||
1420 | |||
1421 | static int i915_swizzle_info(struct seq_file *m, void *data) | ||
1422 | { | ||
1423 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1424 | struct drm_device *dev = node->minor->dev; | ||
1425 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1426 | |||
1427 | mutex_lock(&dev->struct_mutex); | ||
1428 | seq_printf(m, "bit6 swizzle for X-tiling = %s\n", | ||
1429 | swizzle_string(dev_priv->mm.bit_6_swizzle_x)); | ||
1430 | seq_printf(m, "bit6 swizzle for Y-tiling = %s\n", | ||
1431 | swizzle_string(dev_priv->mm.bit_6_swizzle_y)); | ||
1432 | |||
1433 | if (IS_GEN3(dev) || IS_GEN4(dev)) { | ||
1434 | seq_printf(m, "DDC = 0x%08x\n", | ||
1435 | I915_READ(DCC)); | ||
1436 | seq_printf(m, "C0DRB3 = 0x%04x\n", | ||
1437 | I915_READ16(C0DRB3)); | ||
1438 | seq_printf(m, "C1DRB3 = 0x%04x\n", | ||
1439 | I915_READ16(C1DRB3)); | ||
1440 | } else if (IS_GEN6(dev) || IS_GEN7(dev)) { | ||
1441 | seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", | ||
1442 | I915_READ(MAD_DIMM_C0)); | ||
1443 | seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", | ||
1444 | I915_READ(MAD_DIMM_C1)); | ||
1445 | seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n", | ||
1446 | I915_READ(MAD_DIMM_C2)); | ||
1447 | seq_printf(m, "TILECTL = 0x%08x\n", | ||
1448 | I915_READ(TILECTL)); | ||
1449 | seq_printf(m, "ARB_MODE = 0x%08x\n", | ||
1450 | I915_READ(ARB_MODE)); | ||
1451 | seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", | ||
1452 | I915_READ(DISP_ARB_CTL)); | ||
1453 | } | ||
1454 | mutex_unlock(&dev->struct_mutex); | ||
1455 | |||
1456 | return 0; | ||
1457 | } | ||
1458 | |||
1459 | static int i915_ppgtt_info(struct seq_file *m, void *data) | ||
1460 | { | ||
1461 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1462 | struct drm_device *dev = node->minor->dev; | ||
1463 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1464 | struct intel_ring_buffer *ring; | ||
1465 | int i, ret; | ||
1466 | |||
1467 | |||
1468 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1469 | if (ret) | ||
1470 | return ret; | ||
1471 | if (INTEL_INFO(dev)->gen == 6) | ||
1472 | seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); | ||
1473 | |||
1474 | for (i = 0; i < I915_NUM_RINGS; i++) { | ||
1475 | ring = &dev_priv->ring[i]; | ||
1476 | |||
1477 | seq_printf(m, "%s\n", ring->name); | ||
1478 | if (INTEL_INFO(dev)->gen == 7) | ||
1479 | seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring))); | ||
1480 | seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring))); | ||
1481 | seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", I915_READ(RING_PP_DIR_BASE_READ(ring))); | ||
1482 | seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring))); | ||
1483 | } | ||
1484 | if (dev_priv->mm.aliasing_ppgtt) { | ||
1485 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; | ||
1486 | |||
1487 | seq_printf(m, "aliasing PPGTT:\n"); | ||
1488 | seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); | ||
1489 | } | ||
1490 | seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); | ||
1491 | mutex_unlock(&dev->struct_mutex); | ||
1492 | |||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1417 | static int | 1496 | static int |
1418 | i915_wedged_open(struct inode *inode, | 1497 | i915_debugfs_common_open(struct inode *inode, |
1419 | struct file *filp) | 1498 | struct file *filp) |
1420 | { | 1499 | { |
1421 | filp->private_data = inode->i_private; | 1500 | filp->private_data = inode->i_private; |
1422 | return 0; | 1501 | return 0; |
@@ -1472,20 +1551,12 @@ i915_wedged_write(struct file *filp, | |||
1472 | 1551 | ||
1473 | static const struct file_operations i915_wedged_fops = { | 1552 | static const struct file_operations i915_wedged_fops = { |
1474 | .owner = THIS_MODULE, | 1553 | .owner = THIS_MODULE, |
1475 | .open = i915_wedged_open, | 1554 | .open = i915_debugfs_common_open, |
1476 | .read = i915_wedged_read, | 1555 | .read = i915_wedged_read, |
1477 | .write = i915_wedged_write, | 1556 | .write = i915_wedged_write, |
1478 | .llseek = default_llseek, | 1557 | .llseek = default_llseek, |
1479 | }; | 1558 | }; |
1480 | 1559 | ||
1481 | static int | ||
1482 | i915_max_freq_open(struct inode *inode, | ||
1483 | struct file *filp) | ||
1484 | { | ||
1485 | filp->private_data = inode->i_private; | ||
1486 | return 0; | ||
1487 | } | ||
1488 | |||
1489 | static ssize_t | 1560 | static ssize_t |
1490 | i915_max_freq_read(struct file *filp, | 1561 | i915_max_freq_read(struct file *filp, |
1491 | char __user *ubuf, | 1562 | char __user *ubuf, |
@@ -1542,20 +1613,12 @@ i915_max_freq_write(struct file *filp, | |||
1542 | 1613 | ||
1543 | static const struct file_operations i915_max_freq_fops = { | 1614 | static const struct file_operations i915_max_freq_fops = { |
1544 | .owner = THIS_MODULE, | 1615 | .owner = THIS_MODULE, |
1545 | .open = i915_max_freq_open, | 1616 | .open = i915_debugfs_common_open, |
1546 | .read = i915_max_freq_read, | 1617 | .read = i915_max_freq_read, |
1547 | .write = i915_max_freq_write, | 1618 | .write = i915_max_freq_write, |
1548 | .llseek = default_llseek, | 1619 | .llseek = default_llseek, |
1549 | }; | 1620 | }; |
1550 | 1621 | ||
1551 | static int | ||
1552 | i915_cache_sharing_open(struct inode *inode, | ||
1553 | struct file *filp) | ||
1554 | { | ||
1555 | filp->private_data = inode->i_private; | ||
1556 | return 0; | ||
1557 | } | ||
1558 | |||
1559 | static ssize_t | 1622 | static ssize_t |
1560 | i915_cache_sharing_read(struct file *filp, | 1623 | i915_cache_sharing_read(struct file *filp, |
1561 | char __user *ubuf, | 1624 | char __user *ubuf, |
@@ -1621,7 +1684,7 @@ i915_cache_sharing_write(struct file *filp, | |||
1621 | 1684 | ||
1622 | static const struct file_operations i915_cache_sharing_fops = { | 1685 | static const struct file_operations i915_cache_sharing_fops = { |
1623 | .owner = THIS_MODULE, | 1686 | .owner = THIS_MODULE, |
1624 | .open = i915_cache_sharing_open, | 1687 | .open = i915_debugfs_common_open, |
1625 | .read = i915_cache_sharing_read, | 1688 | .read = i915_cache_sharing_read, |
1626 | .write = i915_cache_sharing_write, | 1689 | .write = i915_cache_sharing_write, |
1627 | .llseek = default_llseek, | 1690 | .llseek = default_llseek, |
@@ -1653,21 +1716,6 @@ drm_add_fake_info_node(struct drm_minor *minor, | |||
1653 | return 0; | 1716 | return 0; |
1654 | } | 1717 | } |
1655 | 1718 | ||
1656 | static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) | ||
1657 | { | ||
1658 | struct drm_device *dev = minor->dev; | ||
1659 | struct dentry *ent; | ||
1660 | |||
1661 | ent = debugfs_create_file("i915_wedged", | ||
1662 | S_IRUGO | S_IWUSR, | ||
1663 | root, dev, | ||
1664 | &i915_wedged_fops); | ||
1665 | if (IS_ERR(ent)) | ||
1666 | return PTR_ERR(ent); | ||
1667 | |||
1668 | return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); | ||
1669 | } | ||
1670 | |||
1671 | static int i915_forcewake_open(struct inode *inode, struct file *file) | 1719 | static int i915_forcewake_open(struct inode *inode, struct file *file) |
1672 | { | 1720 | { |
1673 | struct drm_device *dev = inode->i_private; | 1721 | struct drm_device *dev = inode->i_private; |
@@ -1729,34 +1777,22 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) | |||
1729 | return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); | 1777 | return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); |
1730 | } | 1778 | } |
1731 | 1779 | ||
1732 | static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor) | 1780 | static int i915_debugfs_create(struct dentry *root, |
1781 | struct drm_minor *minor, | ||
1782 | const char *name, | ||
1783 | const struct file_operations *fops) | ||
1733 | { | 1784 | { |
1734 | struct drm_device *dev = minor->dev; | 1785 | struct drm_device *dev = minor->dev; |
1735 | struct dentry *ent; | 1786 | struct dentry *ent; |
1736 | 1787 | ||
1737 | ent = debugfs_create_file("i915_max_freq", | 1788 | ent = debugfs_create_file(name, |
1738 | S_IRUGO | S_IWUSR, | 1789 | S_IRUGO | S_IWUSR, |
1739 | root, dev, | 1790 | root, dev, |
1740 | &i915_max_freq_fops); | 1791 | fops); |
1741 | if (IS_ERR(ent)) | 1792 | if (IS_ERR(ent)) |
1742 | return PTR_ERR(ent); | 1793 | return PTR_ERR(ent); |
1743 | 1794 | ||
1744 | return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops); | 1795 | return drm_add_fake_info_node(minor, ent, fops); |
1745 | } | ||
1746 | |||
1747 | static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor) | ||
1748 | { | ||
1749 | struct drm_device *dev = minor->dev; | ||
1750 | struct dentry *ent; | ||
1751 | |||
1752 | ent = debugfs_create_file("i915_cache_sharing", | ||
1753 | S_IRUGO | S_IWUSR, | ||
1754 | root, dev, | ||
1755 | &i915_cache_sharing_fops); | ||
1756 | if (IS_ERR(ent)) | ||
1757 | return PTR_ERR(ent); | ||
1758 | |||
1759 | return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops); | ||
1760 | } | 1796 | } |
1761 | 1797 | ||
1762 | static struct drm_info_list i915_debugfs_list[] = { | 1798 | static struct drm_info_list i915_debugfs_list[] = { |
@@ -1782,7 +1818,6 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
1782 | {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, | 1818 | {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, |
1783 | {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, | 1819 | {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, |
1784 | {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, | 1820 | {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, |
1785 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | ||
1786 | {"i915_error_state", i915_error_state, 0}, | 1821 | {"i915_error_state", i915_error_state, 0}, |
1787 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, | 1822 | {"i915_rstdby_delays", i915_rstdby_delays, 0}, |
1788 | {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, | 1823 | {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, |
@@ -1798,6 +1833,8 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
1798 | {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, | 1833 | {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, |
1799 | {"i915_context_status", i915_context_status, 0}, | 1834 | {"i915_context_status", i915_context_status, 0}, |
1800 | {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, | 1835 | {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, |
1836 | {"i915_swizzle_info", i915_swizzle_info, 0}, | ||
1837 | {"i915_ppgtt_info", i915_ppgtt_info, 0}, | ||
1801 | }; | 1838 | }; |
1802 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) | 1839 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
1803 | 1840 | ||
@@ -1805,17 +1842,25 @@ int i915_debugfs_init(struct drm_minor *minor) | |||
1805 | { | 1842 | { |
1806 | int ret; | 1843 | int ret; |
1807 | 1844 | ||
1808 | ret = i915_wedged_create(minor->debugfs_root, minor); | 1845 | ret = i915_debugfs_create(minor->debugfs_root, minor, |
1846 | "i915_wedged", | ||
1847 | &i915_wedged_fops); | ||
1809 | if (ret) | 1848 | if (ret) |
1810 | return ret; | 1849 | return ret; |
1811 | 1850 | ||
1812 | ret = i915_forcewake_create(minor->debugfs_root, minor); | 1851 | ret = i915_forcewake_create(minor->debugfs_root, minor); |
1813 | if (ret) | 1852 | if (ret) |
1814 | return ret; | 1853 | return ret; |
1815 | ret = i915_max_freq_create(minor->debugfs_root, minor); | 1854 | |
1855 | ret = i915_debugfs_create(minor->debugfs_root, minor, | ||
1856 | "i915_max_freq", | ||
1857 | &i915_max_freq_fops); | ||
1816 | if (ret) | 1858 | if (ret) |
1817 | return ret; | 1859 | return ret; |
1818 | ret = i915_cache_sharing_create(minor->debugfs_root, minor); | 1860 | |
1861 | ret = i915_debugfs_create(minor->debugfs_root, minor, | ||
1862 | "i915_cache_sharing", | ||
1863 | &i915_cache_sharing_fops); | ||
1819 | if (ret) | 1864 | if (ret) |
1820 | return ret; | 1865 | return ret; |
1821 | 1866 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index ddfe3d902b2a..38dfcf91f400 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -784,6 +784,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
784 | case I915_PARAM_HAS_GEN7_SOL_RESET: | 784 | case I915_PARAM_HAS_GEN7_SOL_RESET: |
785 | value = 1; | 785 | value = 1; |
786 | break; | 786 | break; |
787 | case I915_PARAM_HAS_LLC: | ||
788 | value = HAS_LLC(dev); | ||
789 | break; | ||
787 | default: | 790 | default: |
788 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 791 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
789 | param->param); | 792 | param->param); |
@@ -1193,22 +1196,39 @@ static int i915_load_gem_init(struct drm_device *dev) | |||
1193 | /* Basic memrange allocator for stolen space */ | 1196 | /* Basic memrange allocator for stolen space */ |
1194 | drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); | 1197 | drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); |
1195 | 1198 | ||
1196 | /* Let GEM Manage all of the aperture. | 1199 | if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) { |
1197 | * | 1200 | /* PPGTT pdes are stolen from global gtt ptes, so shrink the |
1198 | * However, leave one page at the end still bound to the scratch page. | 1201 | * aperture accordingly when using aliasing ppgtt. */ |
1199 | * There are a number of places where the hardware apparently | 1202 | gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; |
1200 | * prefetches past the end of the object, and we've seen multiple | 1203 | /* For paranoia keep the guard page in between. */ |
1201 | * hangs with the GPU head pointer stuck in a batchbuffer bound | 1204 | gtt_size -= PAGE_SIZE; |
1202 | * at the last page of the aperture. One page should be enough to | 1205 | |
1203 | * keep any prefetching inside of the aperture. | 1206 | i915_gem_do_init(dev, 0, mappable_size, gtt_size); |
1204 | */ | 1207 | |
1205 | i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); | 1208 | ret = i915_gem_init_aliasing_ppgtt(dev); |
1209 | if (ret) | ||
1210 | return ret; | ||
1211 | } else { | ||
1212 | /* Let GEM Manage all of the aperture. | ||
1213 | * | ||
1214 | * However, leave one page at the end still bound to the scratch | ||
1215 | * page. There are a number of places where the hardware | ||
1216 | * apparently prefetches past the end of the object, and we've | ||
1217 | * seen multiple hangs with the GPU head pointer stuck in a | ||
1218 | * batchbuffer bound at the last page of the aperture. One page | ||
1219 | * should be enough to keep any prefetching inside of the | ||
1220 | * aperture. | ||
1221 | */ | ||
1222 | i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); | ||
1223 | } | ||
1206 | 1224 | ||
1207 | mutex_lock(&dev->struct_mutex); | 1225 | mutex_lock(&dev->struct_mutex); |
1208 | ret = i915_gem_init_ringbuffer(dev); | 1226 | ret = i915_gem_init_hw(dev); |
1209 | mutex_unlock(&dev->struct_mutex); | 1227 | mutex_unlock(&dev->struct_mutex); |
1210 | if (ret) | 1228 | if (ret) { |
1229 | i915_gem_cleanup_aliasing_ppgtt(dev); | ||
1211 | return ret; | 1230 | return ret; |
1231 | } | ||
1212 | 1232 | ||
1213 | /* Try to set up FBC with a reasonable compressed buffer size */ | 1233 | /* Try to set up FBC with a reasonable compressed buffer size */ |
1214 | if (I915_HAS_FBC(dev) && i915_powersave) { | 1234 | if (I915_HAS_FBC(dev) && i915_powersave) { |
@@ -1295,6 +1315,7 @@ cleanup_gem: | |||
1295 | mutex_lock(&dev->struct_mutex); | 1315 | mutex_lock(&dev->struct_mutex); |
1296 | i915_gem_cleanup_ringbuffer(dev); | 1316 | i915_gem_cleanup_ringbuffer(dev); |
1297 | mutex_unlock(&dev->struct_mutex); | 1317 | mutex_unlock(&dev->struct_mutex); |
1318 | i915_gem_cleanup_aliasing_ppgtt(dev); | ||
1298 | cleanup_vga_switcheroo: | 1319 | cleanup_vga_switcheroo: |
1299 | vga_switcheroo_unregister_client(dev->pdev); | 1320 | vga_switcheroo_unregister_client(dev->pdev); |
1300 | cleanup_vga_client: | 1321 | cleanup_vga_client: |
@@ -2129,7 +2150,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2129 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | 2150 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); |
2130 | 2151 | ||
2131 | mutex_lock(&dev->struct_mutex); | 2152 | mutex_lock(&dev->struct_mutex); |
2132 | ret = i915_gpu_idle(dev); | 2153 | ret = i915_gpu_idle(dev, true); |
2133 | if (ret) | 2154 | if (ret) |
2134 | DRM_ERROR("failed to idle hardware: %d\n", ret); | 2155 | DRM_ERROR("failed to idle hardware: %d\n", ret); |
2135 | mutex_unlock(&dev->struct_mutex); | 2156 | mutex_unlock(&dev->struct_mutex); |
@@ -2182,6 +2203,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
2182 | i915_gem_free_all_phys_object(dev); | 2203 | i915_gem_free_all_phys_object(dev); |
2183 | i915_gem_cleanup_ringbuffer(dev); | 2204 | i915_gem_cleanup_ringbuffer(dev); |
2184 | mutex_unlock(&dev->struct_mutex); | 2205 | mutex_unlock(&dev->struct_mutex); |
2206 | i915_gem_cleanup_aliasing_ppgtt(dev); | ||
2185 | if (I915_HAS_FBC(dev) && i915_powersave) | 2207 | if (I915_HAS_FBC(dev) && i915_powersave) |
2186 | i915_cleanup_compression(dev); | 2208 | i915_cleanup_compression(dev); |
2187 | drm_mm_takedown(&dev_priv->mm.stolen); | 2209 | drm_mm_takedown(&dev_priv->mm.stolen); |
@@ -2247,18 +2269,12 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
2247 | 2269 | ||
2248 | i915_gem_lastclose(dev); | 2270 | i915_gem_lastclose(dev); |
2249 | 2271 | ||
2250 | if (dev_priv->agp_heap) | ||
2251 | i915_mem_takedown(&(dev_priv->agp_heap)); | ||
2252 | |||
2253 | i915_dma_cleanup(dev); | 2272 | i915_dma_cleanup(dev); |
2254 | } | 2273 | } |
2255 | 2274 | ||
2256 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) | 2275 | void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) |
2257 | { | 2276 | { |
2258 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2259 | i915_gem_release(dev, file_priv); | 2277 | i915_gem_release(dev, file_priv); |
2260 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||
2261 | i915_mem_release(dev, file_priv, dev_priv->agp_heap); | ||
2262 | } | 2278 | } |
2263 | 2279 | ||
2264 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) | 2280 | void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) |
@@ -2277,11 +2293,11 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
2277 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), | 2293 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), |
2278 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), | 2294 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), |
2279 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2295 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2280 | DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), | 2296 | DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), |
2281 | DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), | 2297 | DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), |
2282 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2298 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2283 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), | 2299 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), |
2284 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2300 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2285 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2301 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2286 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), | 2302 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), |
2287 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 2303 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 308f81913562..189041984aba 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -103,6 +103,11 @@ MODULE_PARM_DESC(enable_hangcheck, | |||
103 | "WARNING: Disabling this can cause system wide hangs. " | 103 | "WARNING: Disabling this can cause system wide hangs. " |
104 | "(default: true)"); | 104 | "(default: true)"); |
105 | 105 | ||
106 | bool i915_enable_ppgtt __read_mostly = 1; | ||
107 | module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600); | ||
108 | MODULE_PARM_DESC(i915_enable_ppgtt, | ||
109 | "Enable PPGTT (default: true)"); | ||
110 | |||
106 | static struct drm_driver driver; | 111 | static struct drm_driver driver; |
107 | extern int intel_agp_enabled; | 112 | extern int intel_agp_enabled; |
108 | 113 | ||
@@ -198,7 +203,7 @@ static const struct intel_device_info intel_pineview_info = { | |||
198 | 203 | ||
199 | static const struct intel_device_info intel_ironlake_d_info = { | 204 | static const struct intel_device_info intel_ironlake_d_info = { |
200 | .gen = 5, | 205 | .gen = 5, |
201 | .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, | 206 | .need_gfx_hws = 1, .has_hotplug = 1, |
202 | .has_bsd_ring = 1, | 207 | .has_bsd_ring = 1, |
203 | }; | 208 | }; |
204 | 209 | ||
@@ -214,6 +219,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { | |||
214 | .need_gfx_hws = 1, .has_hotplug = 1, | 219 | .need_gfx_hws = 1, .has_hotplug = 1, |
215 | .has_bsd_ring = 1, | 220 | .has_bsd_ring = 1, |
216 | .has_blt_ring = 1, | 221 | .has_blt_ring = 1, |
222 | .has_llc = 1, | ||
217 | }; | 223 | }; |
218 | 224 | ||
219 | static const struct intel_device_info intel_sandybridge_m_info = { | 225 | static const struct intel_device_info intel_sandybridge_m_info = { |
@@ -222,6 +228,7 @@ static const struct intel_device_info intel_sandybridge_m_info = { | |||
222 | .has_fbc = 1, | 228 | .has_fbc = 1, |
223 | .has_bsd_ring = 1, | 229 | .has_bsd_ring = 1, |
224 | .has_blt_ring = 1, | 230 | .has_blt_ring = 1, |
231 | .has_llc = 1, | ||
225 | }; | 232 | }; |
226 | 233 | ||
227 | static const struct intel_device_info intel_ivybridge_d_info = { | 234 | static const struct intel_device_info intel_ivybridge_d_info = { |
@@ -229,6 +236,7 @@ static const struct intel_device_info intel_ivybridge_d_info = { | |||
229 | .need_gfx_hws = 1, .has_hotplug = 1, | 236 | .need_gfx_hws = 1, .has_hotplug = 1, |
230 | .has_bsd_ring = 1, | 237 | .has_bsd_ring = 1, |
231 | .has_blt_ring = 1, | 238 | .has_blt_ring = 1, |
239 | .has_llc = 1, | ||
232 | }; | 240 | }; |
233 | 241 | ||
234 | static const struct intel_device_info intel_ivybridge_m_info = { | 242 | static const struct intel_device_info intel_ivybridge_m_info = { |
@@ -237,6 +245,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { | |||
237 | .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ | 245 | .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ |
238 | .has_bsd_ring = 1, | 246 | .has_bsd_ring = 1, |
239 | .has_blt_ring = 1, | 247 | .has_blt_ring = 1, |
248 | .has_llc = 1, | ||
240 | }; | 249 | }; |
241 | 250 | ||
242 | static const struct pci_device_id pciidlist[] = { /* aka */ | 251 | static const struct pci_device_id pciidlist[] = { /* aka */ |
@@ -494,7 +503,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
494 | mutex_lock(&dev->struct_mutex); | 503 | mutex_lock(&dev->struct_mutex); |
495 | dev_priv->mm.suspended = 0; | 504 | dev_priv->mm.suspended = 0; |
496 | 505 | ||
497 | error = i915_gem_init_ringbuffer(dev); | 506 | error = i915_gem_init_hw(dev); |
498 | mutex_unlock(&dev->struct_mutex); | 507 | mutex_unlock(&dev->struct_mutex); |
499 | 508 | ||
500 | if (HAS_PCH_SPLIT(dev)) | 509 | if (HAS_PCH_SPLIT(dev)) |
@@ -633,7 +642,7 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags) | |||
633 | } | 642 | } |
634 | 643 | ||
635 | /** | 644 | /** |
636 | * i965_reset - reset chip after a hang | 645 | * i915_reset - reset chip after a hang |
637 | * @dev: drm device to reset | 646 | * @dev: drm device to reset |
638 | * @flags: reset domains | 647 | * @flags: reset domains |
639 | * | 648 | * |
@@ -709,12 +718,16 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
709 | !dev_priv->mm.suspended) { | 718 | !dev_priv->mm.suspended) { |
710 | dev_priv->mm.suspended = 0; | 719 | dev_priv->mm.suspended = 0; |
711 | 720 | ||
721 | i915_gem_init_swizzling(dev); | ||
722 | |||
712 | dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); | 723 | dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); |
713 | if (HAS_BSD(dev)) | 724 | if (HAS_BSD(dev)) |
714 | dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); | 725 | dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); |
715 | if (HAS_BLT(dev)) | 726 | if (HAS_BLT(dev)) |
716 | dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); | 727 | dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); |
717 | 728 | ||
729 | i915_gem_init_ppgtt(dev); | ||
730 | |||
718 | mutex_unlock(&dev->struct_mutex); | 731 | mutex_unlock(&dev->struct_mutex); |
719 | drm_irq_uninstall(dev); | 732 | drm_irq_uninstall(dev); |
720 | drm_mode_config_reset(dev); | 733 | drm_mode_config_reset(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9689ca38b2b3..922aed33035d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -135,6 +135,7 @@ struct drm_i915_fence_reg { | |||
135 | struct list_head lru_list; | 135 | struct list_head lru_list; |
136 | struct drm_i915_gem_object *obj; | 136 | struct drm_i915_gem_object *obj; |
137 | uint32_t setup_seqno; | 137 | uint32_t setup_seqno; |
138 | int pin_count; | ||
138 | }; | 139 | }; |
139 | 140 | ||
140 | struct sdvo_device_mapping { | 141 | struct sdvo_device_mapping { |
@@ -152,26 +153,25 @@ struct drm_i915_error_state { | |||
152 | u32 eir; | 153 | u32 eir; |
153 | u32 pgtbl_er; | 154 | u32 pgtbl_er; |
154 | u32 pipestat[I915_MAX_PIPES]; | 155 | u32 pipestat[I915_MAX_PIPES]; |
155 | u32 ipeir; | 156 | u32 tail[I915_NUM_RINGS]; |
156 | u32 ipehr; | 157 | u32 head[I915_NUM_RINGS]; |
157 | u32 instdone; | 158 | u32 ipeir[I915_NUM_RINGS]; |
158 | u32 acthd; | 159 | u32 ipehr[I915_NUM_RINGS]; |
160 | u32 instdone[I915_NUM_RINGS]; | ||
161 | u32 acthd[I915_NUM_RINGS]; | ||
162 | u32 semaphore_mboxes[I915_NUM_RINGS][I915_NUM_RINGS - 1]; | ||
163 | /* our own tracking of ring head and tail */ | ||
164 | u32 cpu_ring_head[I915_NUM_RINGS]; | ||
165 | u32 cpu_ring_tail[I915_NUM_RINGS]; | ||
159 | u32 error; /* gen6+ */ | 166 | u32 error; /* gen6+ */ |
160 | u32 bcs_acthd; /* gen6+ blt engine */ | 167 | u32 instpm[I915_NUM_RINGS]; |
161 | u32 bcs_ipehr; | 168 | u32 instps[I915_NUM_RINGS]; |
162 | u32 bcs_ipeir; | ||
163 | u32 bcs_instdone; | ||
164 | u32 bcs_seqno; | ||
165 | u32 vcs_acthd; /* gen6+ bsd engine */ | ||
166 | u32 vcs_ipehr; | ||
167 | u32 vcs_ipeir; | ||
168 | u32 vcs_instdone; | ||
169 | u32 vcs_seqno; | ||
170 | u32 instpm; | ||
171 | u32 instps; | ||
172 | u32 instdone1; | 169 | u32 instdone1; |
173 | u32 seqno; | 170 | u32 seqno[I915_NUM_RINGS]; |
174 | u64 bbaddr; | 171 | u64 bbaddr; |
172 | u32 fault_reg[I915_NUM_RINGS]; | ||
173 | u32 done_reg; | ||
174 | u32 faddr[I915_NUM_RINGS]; | ||
175 | u64 fence[I915_MAX_NUM_FENCES]; | 175 | u64 fence[I915_MAX_NUM_FENCES]; |
176 | struct timeval time; | 176 | struct timeval time; |
177 | struct drm_i915_error_object { | 177 | struct drm_i915_error_object { |
@@ -255,6 +255,17 @@ struct intel_device_info { | |||
255 | u8 supports_tv:1; | 255 | u8 supports_tv:1; |
256 | u8 has_bsd_ring:1; | 256 | u8 has_bsd_ring:1; |
257 | u8 has_blt_ring:1; | 257 | u8 has_blt_ring:1; |
258 | u8 has_llc:1; | ||
259 | }; | ||
260 | |||
261 | #define I915_PPGTT_PD_ENTRIES 512 | ||
262 | #define I915_PPGTT_PT_ENTRIES 1024 | ||
263 | struct i915_hw_ppgtt { | ||
264 | unsigned num_pd_entries; | ||
265 | struct page **pt_pages; | ||
266 | uint32_t pd_offset; | ||
267 | dma_addr_t *pt_dma_addr; | ||
268 | dma_addr_t scratch_page_dma_addr; | ||
258 | }; | 269 | }; |
259 | 270 | ||
260 | enum no_fbc_reason { | 271 | enum no_fbc_reason { |
@@ -335,7 +346,6 @@ typedef struct drm_i915_private { | |||
335 | 346 | ||
336 | int tex_lru_log_granularity; | 347 | int tex_lru_log_granularity; |
337 | int allow_batchbuffer; | 348 | int allow_batchbuffer; |
338 | struct mem_block *agp_heap; | ||
339 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 349 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
340 | int vblank_pipe; | 350 | int vblank_pipe; |
341 | int num_pipe; | 351 | int num_pipe; |
@@ -584,6 +594,9 @@ typedef struct drm_i915_private { | |||
584 | struct io_mapping *gtt_mapping; | 594 | struct io_mapping *gtt_mapping; |
585 | int gtt_mtrr; | 595 | int gtt_mtrr; |
586 | 596 | ||
597 | /** PPGTT used for aliasing the PPGTT with the GTT */ | ||
598 | struct i915_hw_ppgtt *aliasing_ppgtt; | ||
599 | |||
587 | struct shrinker inactive_shrinker; | 600 | struct shrinker inactive_shrinker; |
588 | 601 | ||
589 | /** | 602 | /** |
@@ -841,6 +854,8 @@ struct drm_i915_gem_object { | |||
841 | 854 | ||
842 | unsigned int cache_level:2; | 855 | unsigned int cache_level:2; |
843 | 856 | ||
857 | unsigned int has_aliasing_ppgtt_mapping:1; | ||
858 | |||
844 | struct page **pages; | 859 | struct page **pages; |
845 | 860 | ||
846 | /** | 861 | /** |
@@ -974,8 +989,11 @@ struct drm_i915_file_private { | |||
974 | 989 | ||
975 | #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) | 990 | #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) |
976 | #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) | 991 | #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) |
992 | #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) | ||
977 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) | 993 | #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) |
978 | 994 | ||
995 | #define HAS_ALIASING_PPGTT(dev) (INTEL_INFO(dev)->gen >=6) | ||
996 | |||
979 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) | 997 | #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) |
980 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) | 998 | #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) |
981 | 999 | ||
@@ -1018,6 +1036,7 @@ extern int i915_vbt_sdvo_panel_type __read_mostly; | |||
1018 | extern int i915_enable_rc6 __read_mostly; | 1036 | extern int i915_enable_rc6 __read_mostly; |
1019 | extern int i915_enable_fbc __read_mostly; | 1037 | extern int i915_enable_fbc __read_mostly; |
1020 | extern bool i915_enable_hangcheck __read_mostly; | 1038 | extern bool i915_enable_hangcheck __read_mostly; |
1039 | extern bool i915_enable_ppgtt __read_mostly; | ||
1021 | 1040 | ||
1022 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 1041 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
1023 | extern int i915_resume(struct drm_device *dev); | 1042 | extern int i915_resume(struct drm_device *dev); |
@@ -1079,18 +1098,6 @@ extern void i915_destroy_error_state(struct drm_device *dev); | |||
1079 | #endif | 1098 | #endif |
1080 | 1099 | ||
1081 | 1100 | ||
1082 | /* i915_mem.c */ | ||
1083 | extern int i915_mem_alloc(struct drm_device *dev, void *data, | ||
1084 | struct drm_file *file_priv); | ||
1085 | extern int i915_mem_free(struct drm_device *dev, void *data, | ||
1086 | struct drm_file *file_priv); | ||
1087 | extern int i915_mem_init_heap(struct drm_device *dev, void *data, | ||
1088 | struct drm_file *file_priv); | ||
1089 | extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, | ||
1090 | struct drm_file *file_priv); | ||
1091 | extern void i915_mem_takedown(struct mem_block **heap); | ||
1092 | extern void i915_mem_release(struct drm_device * dev, | ||
1093 | struct drm_file *file_priv, struct mem_block *heap); | ||
1094 | /* i915_gem.c */ | 1101 | /* i915_gem.c */ |
1095 | int i915_gem_init_ioctl(struct drm_device *dev, void *data, | 1102 | int i915_gem_init_ioctl(struct drm_device *dev, void *data, |
1096 | struct drm_file *file_priv); | 1103 | struct drm_file *file_priv); |
@@ -1181,6 +1188,24 @@ int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | |||
1181 | struct intel_ring_buffer *pipelined); | 1188 | struct intel_ring_buffer *pipelined); |
1182 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); | 1189 | int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); |
1183 | 1190 | ||
1191 | static inline void | ||
1192 | i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) | ||
1193 | { | ||
1194 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
1195 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
1196 | dev_priv->fence_regs[obj->fence_reg].pin_count++; | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | static inline void | ||
1201 | i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) | ||
1202 | { | ||
1203 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | ||
1204 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | ||
1205 | dev_priv->fence_regs[obj->fence_reg].pin_count--; | ||
1206 | } | ||
1207 | } | ||
1208 | |||
1184 | void i915_gem_retire_requests(struct drm_device *dev); | 1209 | void i915_gem_retire_requests(struct drm_device *dev); |
1185 | void i915_gem_reset(struct drm_device *dev); | 1210 | void i915_gem_reset(struct drm_device *dev); |
1186 | void i915_gem_clflush_object(struct drm_i915_gem_object *obj); | 1211 | void i915_gem_clflush_object(struct drm_i915_gem_object *obj); |
@@ -1188,19 +1213,22 @@ int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, | |||
1188 | uint32_t read_domains, | 1213 | uint32_t read_domains, |
1189 | uint32_t write_domain); | 1214 | uint32_t write_domain); |
1190 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); | 1215 | int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); |
1191 | int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); | 1216 | int __must_check i915_gem_init_hw(struct drm_device *dev); |
1217 | void i915_gem_init_swizzling(struct drm_device *dev); | ||
1218 | void i915_gem_init_ppgtt(struct drm_device *dev); | ||
1192 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1219 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
1193 | void i915_gem_do_init(struct drm_device *dev, | 1220 | void i915_gem_do_init(struct drm_device *dev, |
1194 | unsigned long start, | 1221 | unsigned long start, |
1195 | unsigned long mappable_end, | 1222 | unsigned long mappable_end, |
1196 | unsigned long end); | 1223 | unsigned long end); |
1197 | int __must_check i915_gpu_idle(struct drm_device *dev); | 1224 | int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire); |
1198 | int __must_check i915_gem_idle(struct drm_device *dev); | 1225 | int __must_check i915_gem_idle(struct drm_device *dev); |
1199 | int __must_check i915_add_request(struct intel_ring_buffer *ring, | 1226 | int __must_check i915_add_request(struct intel_ring_buffer *ring, |
1200 | struct drm_file *file, | 1227 | struct drm_file *file, |
1201 | struct drm_i915_gem_request *request); | 1228 | struct drm_i915_gem_request *request); |
1202 | int __must_check i915_wait_request(struct intel_ring_buffer *ring, | 1229 | int __must_check i915_wait_request(struct intel_ring_buffer *ring, |
1203 | uint32_t seqno); | 1230 | uint32_t seqno, |
1231 | bool do_retire); | ||
1204 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1232 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1205 | int __must_check | 1233 | int __must_check |
1206 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, | 1234 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
@@ -1227,6 +1255,14 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
1227 | enum i915_cache_level cache_level); | 1255 | enum i915_cache_level cache_level); |
1228 | 1256 | ||
1229 | /* i915_gem_gtt.c */ | 1257 | /* i915_gem_gtt.c */ |
1258 | int __must_check i915_gem_init_aliasing_ppgtt(struct drm_device *dev); | ||
1259 | void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev); | ||
1260 | void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, | ||
1261 | struct drm_i915_gem_object *obj, | ||
1262 | enum i915_cache_level cache_level); | ||
1263 | void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, | ||
1264 | struct drm_i915_gem_object *obj); | ||
1265 | |||
1230 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); | 1266 | void i915_gem_restore_gtt_mappings(struct drm_device *dev); |
1231 | int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); | 1267 | int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); |
1232 | void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, | 1268 | void i915_gem_gtt_rebind_object(struct drm_i915_gem_object *obj, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e55badb2d86d..f1193b194331 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -58,6 +58,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); | |||
58 | 58 | ||
59 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, | 59 | static int i915_gem_inactive_shrink(struct shrinker *shrinker, |
60 | struct shrink_control *sc); | 60 | struct shrink_control *sc); |
61 | static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); | ||
61 | 62 | ||
62 | /* some bookkeeping */ | 63 | /* some bookkeeping */ |
63 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, | 64 | static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, |
@@ -258,73 +259,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) | |||
258 | obj->tiling_mode != I915_TILING_NONE; | 259 | obj->tiling_mode != I915_TILING_NONE; |
259 | } | 260 | } |
260 | 261 | ||
261 | static inline void | ||
262 | slow_shmem_copy(struct page *dst_page, | ||
263 | int dst_offset, | ||
264 | struct page *src_page, | ||
265 | int src_offset, | ||
266 | int length) | ||
267 | { | ||
268 | char *dst_vaddr, *src_vaddr; | ||
269 | |||
270 | dst_vaddr = kmap(dst_page); | ||
271 | src_vaddr = kmap(src_page); | ||
272 | |||
273 | memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); | ||
274 | |||
275 | kunmap(src_page); | ||
276 | kunmap(dst_page); | ||
277 | } | ||
278 | |||
279 | static inline void | ||
280 | slow_shmem_bit17_copy(struct page *gpu_page, | ||
281 | int gpu_offset, | ||
282 | struct page *cpu_page, | ||
283 | int cpu_offset, | ||
284 | int length, | ||
285 | int is_read) | ||
286 | { | ||
287 | char *gpu_vaddr, *cpu_vaddr; | ||
288 | |||
289 | /* Use the unswizzled path if this page isn't affected. */ | ||
290 | if ((page_to_phys(gpu_page) & (1 << 17)) == 0) { | ||
291 | if (is_read) | ||
292 | return slow_shmem_copy(cpu_page, cpu_offset, | ||
293 | gpu_page, gpu_offset, length); | ||
294 | else | ||
295 | return slow_shmem_copy(gpu_page, gpu_offset, | ||
296 | cpu_page, cpu_offset, length); | ||
297 | } | ||
298 | |||
299 | gpu_vaddr = kmap(gpu_page); | ||
300 | cpu_vaddr = kmap(cpu_page); | ||
301 | |||
302 | /* Copy the data, XORing A6 with A17 (1). The user already knows he's | ||
303 | * XORing with the other bits (A9 for Y, A9 and A10 for X) | ||
304 | */ | ||
305 | while (length > 0) { | ||
306 | int cacheline_end = ALIGN(gpu_offset + 1, 64); | ||
307 | int this_length = min(cacheline_end - gpu_offset, length); | ||
308 | int swizzled_gpu_offset = gpu_offset ^ 64; | ||
309 | |||
310 | if (is_read) { | ||
311 | memcpy(cpu_vaddr + cpu_offset, | ||
312 | gpu_vaddr + swizzled_gpu_offset, | ||
313 | this_length); | ||
314 | } else { | ||
315 | memcpy(gpu_vaddr + swizzled_gpu_offset, | ||
316 | cpu_vaddr + cpu_offset, | ||
317 | this_length); | ||
318 | } | ||
319 | cpu_offset += this_length; | ||
320 | gpu_offset += this_length; | ||
321 | length -= this_length; | ||
322 | } | ||
323 | |||
324 | kunmap(cpu_page); | ||
325 | kunmap(gpu_page); | ||
326 | } | ||
327 | |||
328 | /** | 262 | /** |
329 | * This is the fast shmem pread path, which attempts to copy_from_user directly | 263 | * This is the fast shmem pread path, which attempts to copy_from_user directly |
330 | * from the backing pages of the object to the user's address space. On a | 264 | * from the backing pages of the object to the user's address space. On a |
@@ -385,6 +319,58 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, | |||
385 | return 0; | 319 | return 0; |
386 | } | 320 | } |
387 | 321 | ||
322 | static inline int | ||
323 | __copy_to_user_swizzled(char __user *cpu_vaddr, | ||
324 | const char *gpu_vaddr, int gpu_offset, | ||
325 | int length) | ||
326 | { | ||
327 | int ret, cpu_offset = 0; | ||
328 | |||
329 | while (length > 0) { | ||
330 | int cacheline_end = ALIGN(gpu_offset + 1, 64); | ||
331 | int this_length = min(cacheline_end - gpu_offset, length); | ||
332 | int swizzled_gpu_offset = gpu_offset ^ 64; | ||
333 | |||
334 | ret = __copy_to_user(cpu_vaddr + cpu_offset, | ||
335 | gpu_vaddr + swizzled_gpu_offset, | ||
336 | this_length); | ||
337 | if (ret) | ||
338 | return ret + length; | ||
339 | |||
340 | cpu_offset += this_length; | ||
341 | gpu_offset += this_length; | ||
342 | length -= this_length; | ||
343 | } | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static inline int | ||
349 | __copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, | ||
350 | const char *cpu_vaddr, | ||
351 | int length) | ||
352 | { | ||
353 | int ret, cpu_offset = 0; | ||
354 | |||
355 | while (length > 0) { | ||
356 | int cacheline_end = ALIGN(gpu_offset + 1, 64); | ||
357 | int this_length = min(cacheline_end - gpu_offset, length); | ||
358 | int swizzled_gpu_offset = gpu_offset ^ 64; | ||
359 | |||
360 | ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, | ||
361 | cpu_vaddr + cpu_offset, | ||
362 | this_length); | ||
363 | if (ret) | ||
364 | return ret + length; | ||
365 | |||
366 | cpu_offset += this_length; | ||
367 | gpu_offset += this_length; | ||
368 | length -= this_length; | ||
369 | } | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
388 | /** | 374 | /** |
389 | * This is the fallback shmem pread path, which allocates temporary storage | 375 | * This is the fallback shmem pread path, which allocates temporary storage |
390 | * in kernel space to copy_to_user into outside of the struct_mutex, so we | 376 | * in kernel space to copy_to_user into outside of the struct_mutex, so we |
@@ -398,72 +384,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, | |||
398 | struct drm_file *file) | 384 | struct drm_file *file) |
399 | { | 385 | { |
400 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; | 386 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
401 | struct mm_struct *mm = current->mm; | 387 | char __user *user_data; |
402 | struct page **user_pages; | ||
403 | ssize_t remain; | 388 | ssize_t remain; |
404 | loff_t offset, pinned_pages, i; | 389 | loff_t offset; |
405 | loff_t first_data_page, last_data_page, num_pages; | 390 | int shmem_page_offset, page_length, ret; |
406 | int shmem_page_offset; | 391 | int obj_do_bit17_swizzling, page_do_bit17_swizzling; |
407 | int data_page_index, data_page_offset; | ||
408 | int page_length; | ||
409 | int ret; | ||
410 | uint64_t data_ptr = args->data_ptr; | ||
411 | int do_bit17_swizzling; | ||
412 | 392 | ||
393 | user_data = (char __user *) (uintptr_t) args->data_ptr; | ||
413 | remain = args->size; | 394 | remain = args->size; |
414 | 395 | ||
415 | /* Pin the user pages containing the data. We can't fault while | 396 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); |
416 | * holding the struct mutex, yet we want to hold it while | ||
417 | * dereferencing the user data. | ||
418 | */ | ||
419 | first_data_page = data_ptr / PAGE_SIZE; | ||
420 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; | ||
421 | num_pages = last_data_page - first_data_page + 1; | ||
422 | 397 | ||
423 | user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); | 398 | offset = args->offset; |
424 | if (user_pages == NULL) | ||
425 | return -ENOMEM; | ||
426 | 399 | ||
427 | mutex_unlock(&dev->struct_mutex); | 400 | mutex_unlock(&dev->struct_mutex); |
428 | down_read(&mm->mmap_sem); | ||
429 | pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, | ||
430 | num_pages, 1, 0, user_pages, NULL); | ||
431 | up_read(&mm->mmap_sem); | ||
432 | mutex_lock(&dev->struct_mutex); | ||
433 | if (pinned_pages < num_pages) { | ||
434 | ret = -EFAULT; | ||
435 | goto out; | ||
436 | } | ||
437 | |||
438 | ret = i915_gem_object_set_cpu_read_domain_range(obj, | ||
439 | args->offset, | ||
440 | args->size); | ||
441 | if (ret) | ||
442 | goto out; | ||
443 | |||
444 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | ||
445 | |||
446 | offset = args->offset; | ||
447 | 401 | ||
448 | while (remain > 0) { | 402 | while (remain > 0) { |
449 | struct page *page; | 403 | struct page *page; |
404 | char *vaddr; | ||
450 | 405 | ||
451 | /* Operation in this page | 406 | /* Operation in this page |
452 | * | 407 | * |
453 | * shmem_page_offset = offset within page in shmem file | 408 | * shmem_page_offset = offset within page in shmem file |
454 | * data_page_index = page number in get_user_pages return | ||
455 | * data_page_offset = offset with data_page_index page. | ||
456 | * page_length = bytes to copy for this page | 409 | * page_length = bytes to copy for this page |
457 | */ | 410 | */ |
458 | shmem_page_offset = offset_in_page(offset); | 411 | shmem_page_offset = offset_in_page(offset); |
459 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; | ||
460 | data_page_offset = offset_in_page(data_ptr); | ||
461 | |||
462 | page_length = remain; | 412 | page_length = remain; |
463 | if ((shmem_page_offset + page_length) > PAGE_SIZE) | 413 | if ((shmem_page_offset + page_length) > PAGE_SIZE) |
464 | page_length = PAGE_SIZE - shmem_page_offset; | 414 | page_length = PAGE_SIZE - shmem_page_offset; |
465 | if ((data_page_offset + page_length) > PAGE_SIZE) | ||
466 | page_length = PAGE_SIZE - data_page_offset; | ||
467 | 415 | ||
468 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); | 416 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
469 | if (IS_ERR(page)) { | 417 | if (IS_ERR(page)) { |
@@ -471,36 +419,38 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, | |||
471 | goto out; | 419 | goto out; |
472 | } | 420 | } |
473 | 421 | ||
474 | if (do_bit17_swizzling) { | 422 | page_do_bit17_swizzling = obj_do_bit17_swizzling && |
475 | slow_shmem_bit17_copy(page, | 423 | (page_to_phys(page) & (1 << 17)) != 0; |
476 | shmem_page_offset, | 424 | |
477 | user_pages[data_page_index], | 425 | vaddr = kmap(page); |
478 | data_page_offset, | 426 | if (page_do_bit17_swizzling) |
479 | page_length, | 427 | ret = __copy_to_user_swizzled(user_data, |
480 | 1); | 428 | vaddr, shmem_page_offset, |
481 | } else { | 429 | page_length); |
482 | slow_shmem_copy(user_pages[data_page_index], | 430 | else |
483 | data_page_offset, | 431 | ret = __copy_to_user(user_data, |
484 | page, | 432 | vaddr + shmem_page_offset, |
485 | shmem_page_offset, | 433 | page_length); |
486 | page_length); | 434 | kunmap(page); |
487 | } | ||
488 | 435 | ||
489 | mark_page_accessed(page); | 436 | mark_page_accessed(page); |
490 | page_cache_release(page); | 437 | page_cache_release(page); |
491 | 438 | ||
439 | if (ret) { | ||
440 | ret = -EFAULT; | ||
441 | goto out; | ||
442 | } | ||
443 | |||
492 | remain -= page_length; | 444 | remain -= page_length; |
493 | data_ptr += page_length; | 445 | user_data += page_length; |
494 | offset += page_length; | 446 | offset += page_length; |
495 | } | 447 | } |
496 | 448 | ||
497 | out: | 449 | out: |
498 | for (i = 0; i < pinned_pages; i++) { | 450 | mutex_lock(&dev->struct_mutex); |
499 | SetPageDirty(user_pages[i]); | 451 | /* Fixup: Kill any reinstated backing storage pages */ |
500 | mark_page_accessed(user_pages[i]); | 452 | if (obj->madv == __I915_MADV_PURGED) |
501 | page_cache_release(user_pages[i]); | 453 | i915_gem_object_truncate(obj); |
502 | } | ||
503 | drm_free_large(user_pages); | ||
504 | 454 | ||
505 | return ret; | 455 | return ret; |
506 | } | 456 | } |
@@ -841,71 +791,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, | |||
841 | struct drm_file *file) | 791 | struct drm_file *file) |
842 | { | 792 | { |
843 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; | 793 | struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; |
844 | struct mm_struct *mm = current->mm; | ||
845 | struct page **user_pages; | ||
846 | ssize_t remain; | 794 | ssize_t remain; |
847 | loff_t offset, pinned_pages, i; | 795 | loff_t offset; |
848 | loff_t first_data_page, last_data_page, num_pages; | 796 | char __user *user_data; |
849 | int shmem_page_offset; | 797 | int shmem_page_offset, page_length, ret; |
850 | int data_page_index, data_page_offset; | 798 | int obj_do_bit17_swizzling, page_do_bit17_swizzling; |
851 | int page_length; | ||
852 | int ret; | ||
853 | uint64_t data_ptr = args->data_ptr; | ||
854 | int do_bit17_swizzling; | ||
855 | 799 | ||
800 | user_data = (char __user *) (uintptr_t) args->data_ptr; | ||
856 | remain = args->size; | 801 | remain = args->size; |
857 | 802 | ||
858 | /* Pin the user pages containing the data. We can't fault while | 803 | obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); |
859 | * holding the struct mutex, and all of the pwrite implementations | ||
860 | * want to hold it while dereferencing the user data. | ||
861 | */ | ||
862 | first_data_page = data_ptr / PAGE_SIZE; | ||
863 | last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; | ||
864 | num_pages = last_data_page - first_data_page + 1; | ||
865 | |||
866 | user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); | ||
867 | if (user_pages == NULL) | ||
868 | return -ENOMEM; | ||
869 | |||
870 | mutex_unlock(&dev->struct_mutex); | ||
871 | down_read(&mm->mmap_sem); | ||
872 | pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, | ||
873 | num_pages, 0, 0, user_pages, NULL); | ||
874 | up_read(&mm->mmap_sem); | ||
875 | mutex_lock(&dev->struct_mutex); | ||
876 | if (pinned_pages < num_pages) { | ||
877 | ret = -EFAULT; | ||
878 | goto out; | ||
879 | } | ||
880 | |||
881 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
882 | if (ret) | ||
883 | goto out; | ||
884 | |||
885 | do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); | ||
886 | 804 | ||
887 | offset = args->offset; | 805 | offset = args->offset; |
888 | obj->dirty = 1; | 806 | obj->dirty = 1; |
889 | 807 | ||
808 | mutex_unlock(&dev->struct_mutex); | ||
809 | |||
890 | while (remain > 0) { | 810 | while (remain > 0) { |
891 | struct page *page; | 811 | struct page *page; |
812 | char *vaddr; | ||
892 | 813 | ||
893 | /* Operation in this page | 814 | /* Operation in this page |
894 | * | 815 | * |
895 | * shmem_page_offset = offset within page in shmem file | 816 | * shmem_page_offset = offset within page in shmem file |
896 | * data_page_index = page number in get_user_pages return | ||
897 | * data_page_offset = offset with data_page_index page. | ||
898 | * page_length = bytes to copy for this page | 817 | * page_length = bytes to copy for this page |
899 | */ | 818 | */ |
900 | shmem_page_offset = offset_in_page(offset); | 819 | shmem_page_offset = offset_in_page(offset); |
901 | data_page_index = data_ptr / PAGE_SIZE - first_data_page; | ||
902 | data_page_offset = offset_in_page(data_ptr); | ||
903 | 820 | ||
904 | page_length = remain; | 821 | page_length = remain; |
905 | if ((shmem_page_offset + page_length) > PAGE_SIZE) | 822 | if ((shmem_page_offset + page_length) > PAGE_SIZE) |
906 | page_length = PAGE_SIZE - shmem_page_offset; | 823 | page_length = PAGE_SIZE - shmem_page_offset; |
907 | if ((data_page_offset + page_length) > PAGE_SIZE) | ||
908 | page_length = PAGE_SIZE - data_page_offset; | ||
909 | 824 | ||
910 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); | 825 | page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); |
911 | if (IS_ERR(page)) { | 826 | if (IS_ERR(page)) { |
@@ -913,34 +828,45 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, | |||
913 | goto out; | 828 | goto out; |
914 | } | 829 | } |
915 | 830 | ||
916 | if (do_bit17_swizzling) { | 831 | page_do_bit17_swizzling = obj_do_bit17_swizzling && |
917 | slow_shmem_bit17_copy(page, | 832 | (page_to_phys(page) & (1 << 17)) != 0; |
918 | shmem_page_offset, | 833 | |
919 | user_pages[data_page_index], | 834 | vaddr = kmap(page); |
920 | data_page_offset, | 835 | if (page_do_bit17_swizzling) |
921 | page_length, | 836 | ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, |
922 | 0); | 837 | user_data, |
923 | } else { | 838 | page_length); |
924 | slow_shmem_copy(page, | 839 | else |
925 | shmem_page_offset, | 840 | ret = __copy_from_user(vaddr + shmem_page_offset, |
926 | user_pages[data_page_index], | 841 | user_data, |
927 | data_page_offset, | 842 | page_length); |
928 | page_length); | 843 | kunmap(page); |
929 | } | ||
930 | 844 | ||
931 | set_page_dirty(page); | 845 | set_page_dirty(page); |
932 | mark_page_accessed(page); | 846 | mark_page_accessed(page); |
933 | page_cache_release(page); | 847 | page_cache_release(page); |
934 | 848 | ||
849 | if (ret) { | ||
850 | ret = -EFAULT; | ||
851 | goto out; | ||
852 | } | ||
853 | |||
935 | remain -= page_length; | 854 | remain -= page_length; |
936 | data_ptr += page_length; | 855 | user_data += page_length; |
937 | offset += page_length; | 856 | offset += page_length; |
938 | } | 857 | } |
939 | 858 | ||
940 | out: | 859 | out: |
941 | for (i = 0; i < pinned_pages; i++) | 860 | mutex_lock(&dev->struct_mutex); |
942 | page_cache_release(user_pages[i]); | 861 | /* Fixup: Kill any reinstated backing storage pages */ |
943 | drm_free_large(user_pages); | 862 | if (obj->madv == __I915_MADV_PURGED) |
863 | i915_gem_object_truncate(obj); | ||
864 | /* and flush dirty cachelines in case the object isn't in the cpu write | ||
865 | * domain anymore. */ | ||
866 | if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | ||
867 | i915_gem_clflush_object(obj); | ||
868 | intel_gtt_chipset_flush(); | ||
869 | } | ||
944 | 870 | ||
945 | return ret; | 871 | return ret; |
946 | } | 872 | } |
@@ -996,10 +922,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
996 | * pread/pwrite currently are reading and writing from the CPU | 922 | * pread/pwrite currently are reading and writing from the CPU |
997 | * perspective, requiring manual detiling by the client. | 923 | * perspective, requiring manual detiling by the client. |
998 | */ | 924 | */ |
999 | if (obj->phys_obj) | 925 | if (obj->phys_obj) { |
1000 | ret = i915_gem_phys_pwrite(dev, obj, args, file); | 926 | ret = i915_gem_phys_pwrite(dev, obj, args, file); |
1001 | else if (obj->gtt_space && | 927 | goto out; |
1002 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | 928 | } |
929 | |||
930 | if (obj->gtt_space && | ||
931 | obj->base.write_domain != I915_GEM_DOMAIN_CPU) { | ||
1003 | ret = i915_gem_object_pin(obj, 0, true); | 932 | ret = i915_gem_object_pin(obj, 0, true); |
1004 | if (ret) | 933 | if (ret) |
1005 | goto out; | 934 | goto out; |
@@ -1018,18 +947,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1018 | 947 | ||
1019 | out_unpin: | 948 | out_unpin: |
1020 | i915_gem_object_unpin(obj); | 949 | i915_gem_object_unpin(obj); |
1021 | } else { | ||
1022 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
1023 | if (ret) | ||
1024 | goto out; | ||
1025 | 950 | ||
1026 | ret = -EFAULT; | 951 | if (ret != -EFAULT) |
1027 | if (!i915_gem_object_needs_bit17_swizzle(obj)) | 952 | goto out; |
1028 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); | 953 | /* Fall through to the shmfs paths because the gtt paths might |
1029 | if (ret == -EFAULT) | 954 | * fail with non-page-backed user pointers (e.g. gtt mappings |
1030 | ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); | 955 | * when moving data between textures). */ |
1031 | } | 956 | } |
1032 | 957 | ||
958 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
959 | if (ret) | ||
960 | goto out; | ||
961 | |||
962 | ret = -EFAULT; | ||
963 | if (!i915_gem_object_needs_bit17_swizzle(obj)) | ||
964 | ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); | ||
965 | if (ret == -EFAULT) | ||
966 | ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); | ||
967 | |||
1033 | out: | 968 | out: |
1034 | drm_gem_object_unreference(&obj->base); | 969 | drm_gem_object_unreference(&obj->base); |
1035 | unlock: | 970 | unlock: |
@@ -1141,7 +1076,6 @@ int | |||
1141 | i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | 1076 | i915_gem_mmap_ioctl(struct drm_device *dev, void *data, |
1142 | struct drm_file *file) | 1077 | struct drm_file *file) |
1143 | { | 1078 | { |
1144 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1145 | struct drm_i915_gem_mmap *args = data; | 1079 | struct drm_i915_gem_mmap *args = data; |
1146 | struct drm_gem_object *obj; | 1080 | struct drm_gem_object *obj; |
1147 | unsigned long addr; | 1081 | unsigned long addr; |
@@ -1153,11 +1087,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
1153 | if (obj == NULL) | 1087 | if (obj == NULL) |
1154 | return -ENOENT; | 1088 | return -ENOENT; |
1155 | 1089 | ||
1156 | if (obj->size > dev_priv->mm.gtt_mappable_end) { | ||
1157 | drm_gem_object_unreference_unlocked(obj); | ||
1158 | return -E2BIG; | ||
1159 | } | ||
1160 | |||
1161 | down_write(¤t->mm->mmap_sem); | 1090 | down_write(¤t->mm->mmap_sem); |
1162 | addr = do_mmap(obj->filp, 0, args->size, | 1091 | addr = do_mmap(obj->filp, 0, args->size, |
1163 | PROT_READ | PROT_WRITE, MAP_SHARED, | 1092 | PROT_READ | PROT_WRITE, MAP_SHARED, |
@@ -1943,7 +1872,8 @@ i915_gem_retire_work_handler(struct work_struct *work) | |||
1943 | */ | 1872 | */ |
1944 | int | 1873 | int |
1945 | i915_wait_request(struct intel_ring_buffer *ring, | 1874 | i915_wait_request(struct intel_ring_buffer *ring, |
1946 | uint32_t seqno) | 1875 | uint32_t seqno, |
1876 | bool do_retire) | ||
1947 | { | 1877 | { |
1948 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | 1878 | drm_i915_private_t *dev_priv = ring->dev->dev_private; |
1949 | u32 ier; | 1879 | u32 ier; |
@@ -2027,7 +1957,7 @@ i915_wait_request(struct intel_ring_buffer *ring, | |||
2027 | * buffer to have made it to the inactive list, and we would need | 1957 | * buffer to have made it to the inactive list, and we would need |
2028 | * a separate wait queue to handle that. | 1958 | * a separate wait queue to handle that. |
2029 | */ | 1959 | */ |
2030 | if (ret == 0) | 1960 | if (ret == 0 && do_retire) |
2031 | i915_gem_retire_requests_ring(ring); | 1961 | i915_gem_retire_requests_ring(ring); |
2032 | 1962 | ||
2033 | return ret; | 1963 | return ret; |
@@ -2051,7 +1981,8 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) | |||
2051 | * it. | 1981 | * it. |
2052 | */ | 1982 | */ |
2053 | if (obj->active) { | 1983 | if (obj->active) { |
2054 | ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); | 1984 | ret = i915_wait_request(obj->ring, obj->last_rendering_seqno, |
1985 | true); | ||
2055 | if (ret) | 1986 | if (ret) |
2056 | return ret; | 1987 | return ret; |
2057 | } | 1988 | } |
@@ -2089,6 +2020,7 @@ static void i915_gem_object_finish_gtt(struct drm_i915_gem_object *obj) | |||
2089 | int | 2020 | int |
2090 | i915_gem_object_unbind(struct drm_i915_gem_object *obj) | 2021 | i915_gem_object_unbind(struct drm_i915_gem_object *obj) |
2091 | { | 2022 | { |
2023 | drm_i915_private_t *dev_priv = obj->base.dev->dev_private; | ||
2092 | int ret = 0; | 2024 | int ret = 0; |
2093 | 2025 | ||
2094 | if (obj->gtt_space == NULL) | 2026 | if (obj->gtt_space == NULL) |
@@ -2133,6 +2065,11 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) | |||
2133 | trace_i915_gem_object_unbind(obj); | 2065 | trace_i915_gem_object_unbind(obj); |
2134 | 2066 | ||
2135 | i915_gem_gtt_unbind_object(obj); | 2067 | i915_gem_gtt_unbind_object(obj); |
2068 | if (obj->has_aliasing_ppgtt_mapping) { | ||
2069 | i915_ppgtt_unbind_object(dev_priv->mm.aliasing_ppgtt, obj); | ||
2070 | obj->has_aliasing_ppgtt_mapping = 0; | ||
2071 | } | ||
2072 | |||
2136 | i915_gem_object_put_pages_gtt(obj); | 2073 | i915_gem_object_put_pages_gtt(obj); |
2137 | 2074 | ||
2138 | list_del_init(&obj->gtt_list); | 2075 | list_del_init(&obj->gtt_list); |
@@ -2172,7 +2109,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring, | |||
2172 | return 0; | 2109 | return 0; |
2173 | } | 2110 | } |
2174 | 2111 | ||
2175 | static int i915_ring_idle(struct intel_ring_buffer *ring) | 2112 | static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) |
2176 | { | 2113 | { |
2177 | int ret; | 2114 | int ret; |
2178 | 2115 | ||
@@ -2186,18 +2123,18 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) | |||
2186 | return ret; | 2123 | return ret; |
2187 | } | 2124 | } |
2188 | 2125 | ||
2189 | return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); | 2126 | return i915_wait_request(ring, i915_gem_next_request_seqno(ring), |
2127 | do_retire); | ||
2190 | } | 2128 | } |
2191 | 2129 | ||
2192 | int | 2130 | int i915_gpu_idle(struct drm_device *dev, bool do_retire) |
2193 | i915_gpu_idle(struct drm_device *dev) | ||
2194 | { | 2131 | { |
2195 | drm_i915_private_t *dev_priv = dev->dev_private; | 2132 | drm_i915_private_t *dev_priv = dev->dev_private; |
2196 | int ret, i; | 2133 | int ret, i; |
2197 | 2134 | ||
2198 | /* Flush everything onto the inactive list. */ | 2135 | /* Flush everything onto the inactive list. */ |
2199 | for (i = 0; i < I915_NUM_RINGS; i++) { | 2136 | for (i = 0; i < I915_NUM_RINGS; i++) { |
2200 | ret = i915_ring_idle(&dev_priv->ring[i]); | 2137 | ret = i915_ring_idle(&dev_priv->ring[i], do_retire); |
2201 | if (ret) | 2138 | if (ret) |
2202 | return ret; | 2139 | return ret; |
2203 | } | 2140 | } |
@@ -2400,7 +2337,8 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, | |||
2400 | if (!ring_passed_seqno(obj->last_fenced_ring, | 2337 | if (!ring_passed_seqno(obj->last_fenced_ring, |
2401 | obj->last_fenced_seqno)) { | 2338 | obj->last_fenced_seqno)) { |
2402 | ret = i915_wait_request(obj->last_fenced_ring, | 2339 | ret = i915_wait_request(obj->last_fenced_ring, |
2403 | obj->last_fenced_seqno); | 2340 | obj->last_fenced_seqno, |
2341 | true); | ||
2404 | if (ret) | 2342 | if (ret) |
2405 | return ret; | 2343 | return ret; |
2406 | } | 2344 | } |
@@ -2432,6 +2370,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj) | |||
2432 | 2370 | ||
2433 | if (obj->fence_reg != I915_FENCE_REG_NONE) { | 2371 | if (obj->fence_reg != I915_FENCE_REG_NONE) { |
2434 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; | 2372 | struct drm_i915_private *dev_priv = obj->base.dev->dev_private; |
2373 | |||
2374 | WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); | ||
2435 | i915_gem_clear_fence_reg(obj->base.dev, | 2375 | i915_gem_clear_fence_reg(obj->base.dev, |
2436 | &dev_priv->fence_regs[obj->fence_reg]); | 2376 | &dev_priv->fence_regs[obj->fence_reg]); |
2437 | 2377 | ||
@@ -2456,7 +2396,7 @@ i915_find_fence_reg(struct drm_device *dev, | |||
2456 | if (!reg->obj) | 2396 | if (!reg->obj) |
2457 | return reg; | 2397 | return reg; |
2458 | 2398 | ||
2459 | if (!reg->obj->pin_count) | 2399 | if (!reg->pin_count) |
2460 | avail = reg; | 2400 | avail = reg; |
2461 | } | 2401 | } |
2462 | 2402 | ||
@@ -2466,7 +2406,7 @@ i915_find_fence_reg(struct drm_device *dev, | |||
2466 | /* None available, try to steal one or wait for a user to finish */ | 2406 | /* None available, try to steal one or wait for a user to finish */ |
2467 | avail = first = NULL; | 2407 | avail = first = NULL; |
2468 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { | 2408 | list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { |
2469 | if (reg->obj->pin_count) | 2409 | if (reg->pin_count) |
2470 | continue; | 2410 | continue; |
2471 | 2411 | ||
2472 | if (first == NULL) | 2412 | if (first == NULL) |
@@ -2541,7 +2481,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | |||
2541 | if (!ring_passed_seqno(obj->last_fenced_ring, | 2481 | if (!ring_passed_seqno(obj->last_fenced_ring, |
2542 | reg->setup_seqno)) { | 2482 | reg->setup_seqno)) { |
2543 | ret = i915_wait_request(obj->last_fenced_ring, | 2483 | ret = i915_wait_request(obj->last_fenced_ring, |
2544 | reg->setup_seqno); | 2484 | reg->setup_seqno, |
2485 | true); | ||
2545 | if (ret) | 2486 | if (ret) |
2546 | return ret; | 2487 | return ret; |
2547 | } | 2488 | } |
@@ -2560,7 +2501,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, | |||
2560 | 2501 | ||
2561 | reg = i915_find_fence_reg(dev, pipelined); | 2502 | reg = i915_find_fence_reg(dev, pipelined); |
2562 | if (reg == NULL) | 2503 | if (reg == NULL) |
2563 | return -ENOSPC; | 2504 | return -EDEADLK; |
2564 | 2505 | ||
2565 | ret = i915_gem_object_flush_fence(obj, pipelined); | 2506 | ret = i915_gem_object_flush_fence(obj, pipelined); |
2566 | if (ret) | 2507 | if (ret) |
@@ -2660,6 +2601,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev, | |||
2660 | list_del_init(®->lru_list); | 2601 | list_del_init(®->lru_list); |
2661 | reg->obj = NULL; | 2602 | reg->obj = NULL; |
2662 | reg->setup_seqno = 0; | 2603 | reg->setup_seqno = 0; |
2604 | reg->pin_count = 0; | ||
2663 | } | 2605 | } |
2664 | 2606 | ||
2665 | /** | 2607 | /** |
@@ -2946,6 +2888,8 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) | |||
2946 | int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | 2888 | int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, |
2947 | enum i915_cache_level cache_level) | 2889 | enum i915_cache_level cache_level) |
2948 | { | 2890 | { |
2891 | struct drm_device *dev = obj->base.dev; | ||
2892 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2949 | int ret; | 2893 | int ret; |
2950 | 2894 | ||
2951 | if (obj->cache_level == cache_level) | 2895 | if (obj->cache_level == cache_level) |
@@ -2974,6 +2918,9 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
2974 | } | 2918 | } |
2975 | 2919 | ||
2976 | i915_gem_gtt_rebind_object(obj, cache_level); | 2920 | i915_gem_gtt_rebind_object(obj, cache_level); |
2921 | if (obj->has_aliasing_ppgtt_mapping) | ||
2922 | i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, | ||
2923 | obj, cache_level); | ||
2977 | } | 2924 | } |
2978 | 2925 | ||
2979 | if (cache_level == I915_CACHE_NONE) { | 2926 | if (cache_level == I915_CACHE_NONE) { |
@@ -3619,8 +3566,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, | |||
3619 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; | 3566 | obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
3620 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; | 3567 | obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
3621 | 3568 | ||
3622 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 3569 | if (HAS_LLC(dev)) { |
3623 | /* On Gen6, we can have the GPU use the LLC (the CPU | 3570 | /* On some devices, we can have the GPU use the LLC (the CPU |
3624 | * cache) for about a 10% performance improvement | 3571 | * cache) for about a 10% performance improvement |
3625 | * compared to uncached. Graphics requests other than | 3572 | * compared to uncached. Graphics requests other than |
3626 | * display scanout are coherent with the CPU in | 3573 | * display scanout are coherent with the CPU in |
@@ -3710,7 +3657,7 @@ i915_gem_idle(struct drm_device *dev) | |||
3710 | return 0; | 3657 | return 0; |
3711 | } | 3658 | } |
3712 | 3659 | ||
3713 | ret = i915_gpu_idle(dev); | 3660 | ret = i915_gpu_idle(dev, true); |
3714 | if (ret) { | 3661 | if (ret) { |
3715 | mutex_unlock(&dev->struct_mutex); | 3662 | mutex_unlock(&dev->struct_mutex); |
3716 | return ret; | 3663 | return ret; |
@@ -3745,12 +3692,71 @@ i915_gem_idle(struct drm_device *dev) | |||
3745 | return 0; | 3692 | return 0; |
3746 | } | 3693 | } |
3747 | 3694 | ||
3695 | void i915_gem_init_swizzling(struct drm_device *dev) | ||
3696 | { | ||
3697 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3698 | |||
3699 | if (INTEL_INFO(dev)->gen < 5 || | ||
3700 | dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) | ||
3701 | return; | ||
3702 | |||
3703 | I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) | | ||
3704 | DISP_TILE_SURFACE_SWIZZLING); | ||
3705 | |||
3706 | if (IS_GEN5(dev)) | ||
3707 | return; | ||
3708 | |||
3709 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL); | ||
3710 | if (IS_GEN6(dev)) | ||
3711 | I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB)); | ||
3712 | else | ||
3713 | I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB)); | ||
3714 | } | ||
3715 | |||
3716 | void i915_gem_init_ppgtt(struct drm_device *dev) | ||
3717 | { | ||
3718 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3719 | uint32_t pd_offset; | ||
3720 | struct intel_ring_buffer *ring; | ||
3721 | int i; | ||
3722 | |||
3723 | if (!dev_priv->mm.aliasing_ppgtt) | ||
3724 | return; | ||
3725 | |||
3726 | pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset; | ||
3727 | pd_offset /= 64; /* in cachelines, */ | ||
3728 | pd_offset <<= 16; | ||
3729 | |||
3730 | if (INTEL_INFO(dev)->gen == 6) { | ||
3731 | uint32_t ecochk = I915_READ(GAM_ECOCHK); | ||
3732 | I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | | ||
3733 | ECOCHK_PPGTT_CACHE64B); | ||
3734 | I915_WRITE(GFX_MODE, GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); | ||
3735 | } else if (INTEL_INFO(dev)->gen >= 7) { | ||
3736 | I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B); | ||
3737 | /* GFX_MODE is per-ring on gen7+ */ | ||
3738 | } | ||
3739 | |||
3740 | for (i = 0; i < I915_NUM_RINGS; i++) { | ||
3741 | ring = &dev_priv->ring[i]; | ||
3742 | |||
3743 | if (INTEL_INFO(dev)->gen >= 7) | ||
3744 | I915_WRITE(RING_MODE_GEN7(ring), | ||
3745 | GFX_MODE_ENABLE(GFX_PPGTT_ENABLE)); | ||
3746 | |||
3747 | I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); | ||
3748 | I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset); | ||
3749 | } | ||
3750 | } | ||
3751 | |||
3748 | int | 3752 | int |
3749 | i915_gem_init_ringbuffer(struct drm_device *dev) | 3753 | i915_gem_init_hw(struct drm_device *dev) |
3750 | { | 3754 | { |
3751 | drm_i915_private_t *dev_priv = dev->dev_private; | 3755 | drm_i915_private_t *dev_priv = dev->dev_private; |
3752 | int ret; | 3756 | int ret; |
3753 | 3757 | ||
3758 | i915_gem_init_swizzling(dev); | ||
3759 | |||
3754 | ret = intel_init_render_ring_buffer(dev); | 3760 | ret = intel_init_render_ring_buffer(dev); |
3755 | if (ret) | 3761 | if (ret) |
3756 | return ret; | 3762 | return ret; |
@@ -3769,6 +3775,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
3769 | 3775 | ||
3770 | dev_priv->next_seqno = 1; | 3776 | dev_priv->next_seqno = 1; |
3771 | 3777 | ||
3778 | i915_gem_init_ppgtt(dev); | ||
3779 | |||
3772 | return 0; | 3780 | return 0; |
3773 | 3781 | ||
3774 | cleanup_bsd_ring: | 3782 | cleanup_bsd_ring: |
@@ -3806,7 +3814,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | |||
3806 | mutex_lock(&dev->struct_mutex); | 3814 | mutex_lock(&dev->struct_mutex); |
3807 | dev_priv->mm.suspended = 0; | 3815 | dev_priv->mm.suspended = 0; |
3808 | 3816 | ||
3809 | ret = i915_gem_init_ringbuffer(dev); | 3817 | ret = i915_gem_init_hw(dev); |
3810 | if (ret != 0) { | 3818 | if (ret != 0) { |
3811 | mutex_unlock(&dev->struct_mutex); | 3819 | mutex_unlock(&dev->struct_mutex); |
3812 | return ret; | 3820 | return ret; |
@@ -4201,7 +4209,7 @@ rescan: | |||
4201 | * This has a dramatic impact to reduce the number of | 4209 | * This has a dramatic impact to reduce the number of |
4202 | * OOM-killer events whilst running the GPU aggressively. | 4210 | * OOM-killer events whilst running the GPU aggressively. |
4203 | */ | 4211 | */ |
4204 | if (i915_gpu_idle(dev) == 0) | 4212 | if (i915_gpu_idle(dev, true) == 0) |
4205 | goto rescan; | 4213 | goto rescan; |
4206 | } | 4214 | } |
4207 | mutex_unlock(&dev->struct_mutex); | 4215 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index ead5d00f91b0..097119caa36a 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -195,7 +195,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) | |||
195 | trace_i915_gem_evict_everything(dev, purgeable_only); | 195 | trace_i915_gem_evict_everything(dev, purgeable_only); |
196 | 196 | ||
197 | /* Flush everything (on to the inactive lists) and evict */ | 197 | /* Flush everything (on to the inactive lists) and evict */ |
198 | ret = i915_gpu_idle(dev); | 198 | ret = i915_gpu_idle(dev, true); |
199 | if (ret) | 199 | if (ret) |
200 | return ret; | 200 | return ret; |
201 | 201 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 65e1f0043f9d..81687af00893 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -203,9 +203,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, | |||
203 | cd->invalidate_domains |= invalidate_domains; | 203 | cd->invalidate_domains |= invalidate_domains; |
204 | cd->flush_domains |= flush_domains; | 204 | cd->flush_domains |= flush_domains; |
205 | if (flush_domains & I915_GEM_GPU_DOMAINS) | 205 | if (flush_domains & I915_GEM_GPU_DOMAINS) |
206 | cd->flush_rings |= obj->ring->id; | 206 | cd->flush_rings |= intel_ring_flag(obj->ring); |
207 | if (invalidate_domains & I915_GEM_GPU_DOMAINS) | 207 | if (invalidate_domains & I915_GEM_GPU_DOMAINS) |
208 | cd->flush_rings |= ring->id; | 208 | cd->flush_rings |= intel_ring_flag(ring); |
209 | } | 209 | } |
210 | 210 | ||
211 | struct eb_objects { | 211 | struct eb_objects { |
@@ -287,14 +287,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
287 | * exec_object list, so it should have a GTT space bound by now. | 287 | * exec_object list, so it should have a GTT space bound by now. |
288 | */ | 288 | */ |
289 | if (unlikely(target_offset == 0)) { | 289 | if (unlikely(target_offset == 0)) { |
290 | DRM_ERROR("No GTT space found for object %d\n", | 290 | DRM_DEBUG("No GTT space found for object %d\n", |
291 | reloc->target_handle); | 291 | reloc->target_handle); |
292 | return ret; | 292 | return ret; |
293 | } | 293 | } |
294 | 294 | ||
295 | /* Validate that the target is in a valid r/w GPU domain */ | 295 | /* Validate that the target is in a valid r/w GPU domain */ |
296 | if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { | 296 | if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { |
297 | DRM_ERROR("reloc with multiple write domains: " | 297 | DRM_DEBUG("reloc with multiple write domains: " |
298 | "obj %p target %d offset %d " | 298 | "obj %p target %d offset %d " |
299 | "read %08x write %08x", | 299 | "read %08x write %08x", |
300 | obj, reloc->target_handle, | 300 | obj, reloc->target_handle, |
@@ -303,8 +303,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
303 | reloc->write_domain); | 303 | reloc->write_domain); |
304 | return ret; | 304 | return ret; |
305 | } | 305 | } |
306 | if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) { | 306 | if (unlikely((reloc->write_domain | reloc->read_domains) |
307 | DRM_ERROR("reloc with read/write CPU domains: " | 307 | & ~I915_GEM_GPU_DOMAINS)) { |
308 | DRM_DEBUG("reloc with read/write non-GPU domains: " | ||
308 | "obj %p target %d offset %d " | 309 | "obj %p target %d offset %d " |
309 | "read %08x write %08x", | 310 | "read %08x write %08x", |
310 | obj, reloc->target_handle, | 311 | obj, reloc->target_handle, |
@@ -315,7 +316,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
315 | } | 316 | } |
316 | if (unlikely(reloc->write_domain && target_obj->pending_write_domain && | 317 | if (unlikely(reloc->write_domain && target_obj->pending_write_domain && |
317 | reloc->write_domain != target_obj->pending_write_domain)) { | 318 | reloc->write_domain != target_obj->pending_write_domain)) { |
318 | DRM_ERROR("Write domain conflict: " | 319 | DRM_DEBUG("Write domain conflict: " |
319 | "obj %p target %d offset %d " | 320 | "obj %p target %d offset %d " |
320 | "new %08x old %08x\n", | 321 | "new %08x old %08x\n", |
321 | obj, reloc->target_handle, | 322 | obj, reloc->target_handle, |
@@ -336,7 +337,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
336 | 337 | ||
337 | /* Check that the relocation address is valid... */ | 338 | /* Check that the relocation address is valid... */ |
338 | if (unlikely(reloc->offset > obj->base.size - 4)) { | 339 | if (unlikely(reloc->offset > obj->base.size - 4)) { |
339 | DRM_ERROR("Relocation beyond object bounds: " | 340 | DRM_DEBUG("Relocation beyond object bounds: " |
340 | "obj %p target %d offset %d size %d.\n", | 341 | "obj %p target %d offset %d size %d.\n", |
341 | obj, reloc->target_handle, | 342 | obj, reloc->target_handle, |
342 | (int) reloc->offset, | 343 | (int) reloc->offset, |
@@ -344,7 +345,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
344 | return ret; | 345 | return ret; |
345 | } | 346 | } |
346 | if (unlikely(reloc->offset & 3)) { | 347 | if (unlikely(reloc->offset & 3)) { |
347 | DRM_ERROR("Relocation not 4-byte aligned: " | 348 | DRM_DEBUG("Relocation not 4-byte aligned: " |
348 | "obj %p target %d offset %d.\n", | 349 | "obj %p target %d offset %d.\n", |
349 | obj, reloc->target_handle, | 350 | obj, reloc->target_handle, |
350 | (int) reloc->offset); | 351 | (int) reloc->offset); |
@@ -461,11 +462,60 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, | |||
461 | return ret; | 462 | return ret; |
462 | } | 463 | } |
463 | 464 | ||
465 | #define __EXEC_OBJECT_HAS_FENCE (1<<31) | ||
466 | |||
467 | static int | ||
468 | pin_and_fence_object(struct drm_i915_gem_object *obj, | ||
469 | struct intel_ring_buffer *ring) | ||
470 | { | ||
471 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | ||
472 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | ||
473 | bool need_fence, need_mappable; | ||
474 | int ret; | ||
475 | |||
476 | need_fence = | ||
477 | has_fenced_gpu_access && | ||
478 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
479 | obj->tiling_mode != I915_TILING_NONE; | ||
480 | need_mappable = | ||
481 | entry->relocation_count ? true : need_fence; | ||
482 | |||
483 | ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); | ||
484 | if (ret) | ||
485 | return ret; | ||
486 | |||
487 | if (has_fenced_gpu_access) { | ||
488 | if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { | ||
489 | if (obj->tiling_mode) { | ||
490 | ret = i915_gem_object_get_fence(obj, ring); | ||
491 | if (ret) | ||
492 | goto err_unpin; | ||
493 | |||
494 | entry->flags |= __EXEC_OBJECT_HAS_FENCE; | ||
495 | i915_gem_object_pin_fence(obj); | ||
496 | } else { | ||
497 | ret = i915_gem_object_put_fence(obj); | ||
498 | if (ret) | ||
499 | goto err_unpin; | ||
500 | } | ||
501 | } | ||
502 | obj->pending_fenced_gpu_access = need_fence; | ||
503 | } | ||
504 | |||
505 | entry->offset = obj->gtt_offset; | ||
506 | return 0; | ||
507 | |||
508 | err_unpin: | ||
509 | i915_gem_object_unpin(obj); | ||
510 | return ret; | ||
511 | } | ||
512 | |||
464 | static int | 513 | static int |
465 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | 514 | i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, |
466 | struct drm_file *file, | 515 | struct drm_file *file, |
467 | struct list_head *objects) | 516 | struct list_head *objects) |
468 | { | 517 | { |
518 | drm_i915_private_t *dev_priv = ring->dev->dev_private; | ||
469 | struct drm_i915_gem_object *obj; | 519 | struct drm_i915_gem_object *obj; |
470 | int ret, retry; | 520 | int ret, retry; |
471 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; | 521 | bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; |
@@ -518,6 +568,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
518 | list_for_each_entry(obj, objects, exec_list) { | 568 | list_for_each_entry(obj, objects, exec_list) { |
519 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 569 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; |
520 | bool need_fence, need_mappable; | 570 | bool need_fence, need_mappable; |
571 | |||
521 | if (!obj->gtt_space) | 572 | if (!obj->gtt_space) |
522 | continue; | 573 | continue; |
523 | 574 | ||
@@ -532,58 +583,55 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
532 | (need_mappable && !obj->map_and_fenceable)) | 583 | (need_mappable && !obj->map_and_fenceable)) |
533 | ret = i915_gem_object_unbind(obj); | 584 | ret = i915_gem_object_unbind(obj); |
534 | else | 585 | else |
535 | ret = i915_gem_object_pin(obj, | 586 | ret = pin_and_fence_object(obj, ring); |
536 | entry->alignment, | ||
537 | need_mappable); | ||
538 | if (ret) | 587 | if (ret) |
539 | goto err; | 588 | goto err; |
540 | |||
541 | entry++; | ||
542 | } | 589 | } |
543 | 590 | ||
544 | /* Bind fresh objects */ | 591 | /* Bind fresh objects */ |
545 | list_for_each_entry(obj, objects, exec_list) { | 592 | list_for_each_entry(obj, objects, exec_list) { |
546 | struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; | 593 | if (obj->gtt_space) |
547 | bool need_fence; | 594 | continue; |
548 | 595 | ||
549 | need_fence = | 596 | ret = pin_and_fence_object(obj, ring); |
550 | has_fenced_gpu_access && | 597 | if (ret) { |
551 | entry->flags & EXEC_OBJECT_NEEDS_FENCE && | 598 | int ret_ignore; |
552 | obj->tiling_mode != I915_TILING_NONE; | 599 | |
600 | /* This can potentially raise a harmless | ||
601 | * -EINVAL if we failed to bind in the above | ||
602 | * call. It cannot raise -EINTR since we know | ||
603 | * that the bo is freshly bound and so will | ||
604 | * not need to be flushed or waited upon. | ||
605 | */ | ||
606 | ret_ignore = i915_gem_object_unbind(obj); | ||
607 | (void)ret_ignore; | ||
608 | WARN_ON(obj->gtt_space); | ||
609 | break; | ||
610 | } | ||
611 | } | ||
553 | 612 | ||
554 | if (!obj->gtt_space) { | 613 | /* Decrement pin count for bound objects */ |
555 | bool need_mappable = | 614 | list_for_each_entry(obj, objects, exec_list) { |
556 | entry->relocation_count ? true : need_fence; | 615 | struct drm_i915_gem_exec_object2 *entry; |
557 | 616 | ||
558 | ret = i915_gem_object_pin(obj, | 617 | if (!obj->gtt_space) |
559 | entry->alignment, | 618 | continue; |
560 | need_mappable); | ||
561 | if (ret) | ||
562 | break; | ||
563 | } | ||
564 | 619 | ||
565 | if (has_fenced_gpu_access) { | 620 | entry = obj->exec_entry; |
566 | if (need_fence) { | 621 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { |
567 | ret = i915_gem_object_get_fence(obj, ring); | 622 | i915_gem_object_unpin_fence(obj); |
568 | if (ret) | 623 | entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; |
569 | break; | ||
570 | } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && | ||
571 | obj->tiling_mode == I915_TILING_NONE) { | ||
572 | /* XXX pipelined! */ | ||
573 | ret = i915_gem_object_put_fence(obj); | ||
574 | if (ret) | ||
575 | break; | ||
576 | } | ||
577 | obj->pending_fenced_gpu_access = need_fence; | ||
578 | } | 624 | } |
579 | 625 | ||
580 | entry->offset = obj->gtt_offset; | 626 | i915_gem_object_unpin(obj); |
581 | } | ||
582 | 627 | ||
583 | /* Decrement pin count for bound objects */ | 628 | /* ... and ensure ppgtt mapping exist if needed. */ |
584 | list_for_each_entry(obj, objects, exec_list) { | 629 | if (dev_priv->mm.aliasing_ppgtt && !obj->has_aliasing_ppgtt_mapping) { |
585 | if (obj->gtt_space) | 630 | i915_ppgtt_bind_object(dev_priv->mm.aliasing_ppgtt, |
586 | i915_gem_object_unpin(obj); | 631 | obj, obj->cache_level); |
632 | |||
633 | obj->has_aliasing_ppgtt_mapping = 1; | ||
634 | } | ||
587 | } | 635 | } |
588 | 636 | ||
589 | if (ret != -ENOSPC || retry > 1) | 637 | if (ret != -ENOSPC || retry > 1) |
@@ -600,16 +648,19 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, | |||
600 | } while (1); | 648 | } while (1); |
601 | 649 | ||
602 | err: | 650 | err: |
603 | obj = list_entry(obj->exec_list.prev, | 651 | list_for_each_entry_continue_reverse(obj, objects, exec_list) { |
604 | struct drm_i915_gem_object, | 652 | struct drm_i915_gem_exec_object2 *entry; |
605 | exec_list); | 653 | |
606 | while (objects != &obj->exec_list) { | 654 | if (!obj->gtt_space) |
607 | if (obj->gtt_space) | 655 | continue; |
608 | i915_gem_object_unpin(obj); | 656 | |
657 | entry = obj->exec_entry; | ||
658 | if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { | ||
659 | i915_gem_object_unpin_fence(obj); | ||
660 | entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; | ||
661 | } | ||
609 | 662 | ||
610 | obj = list_entry(obj->exec_list.prev, | 663 | i915_gem_object_unpin(obj); |
611 | struct drm_i915_gem_object, | ||
612 | exec_list); | ||
613 | } | 664 | } |
614 | 665 | ||
615 | return ret; | 666 | return ret; |
@@ -682,7 +733,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, | |||
682 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | 733 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, |
683 | exec[i].handle)); | 734 | exec[i].handle)); |
684 | if (&obj->base == NULL) { | 735 | if (&obj->base == NULL) { |
685 | DRM_ERROR("Invalid object handle %d at index %d\n", | 736 | DRM_DEBUG("Invalid object handle %d at index %d\n", |
686 | exec[i].handle, i); | 737 | exec[i].handle, i); |
687 | ret = -ENOENT; | 738 | ret = -ENOENT; |
688 | goto err; | 739 | goto err; |
@@ -1013,7 +1064,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1013 | int ret, mode, i; | 1064 | int ret, mode, i; |
1014 | 1065 | ||
1015 | if (!i915_gem_check_execbuffer(args)) { | 1066 | if (!i915_gem_check_execbuffer(args)) { |
1016 | DRM_ERROR("execbuf with invalid offset/length\n"); | 1067 | DRM_DEBUG("execbuf with invalid offset/length\n"); |
1017 | return -EINVAL; | 1068 | return -EINVAL; |
1018 | } | 1069 | } |
1019 | 1070 | ||
@@ -1028,20 +1079,20 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1028 | break; | 1079 | break; |
1029 | case I915_EXEC_BSD: | 1080 | case I915_EXEC_BSD: |
1030 | if (!HAS_BSD(dev)) { | 1081 | if (!HAS_BSD(dev)) { |
1031 | DRM_ERROR("execbuf with invalid ring (BSD)\n"); | 1082 | DRM_DEBUG("execbuf with invalid ring (BSD)\n"); |
1032 | return -EINVAL; | 1083 | return -EINVAL; |
1033 | } | 1084 | } |
1034 | ring = &dev_priv->ring[VCS]; | 1085 | ring = &dev_priv->ring[VCS]; |
1035 | break; | 1086 | break; |
1036 | case I915_EXEC_BLT: | 1087 | case I915_EXEC_BLT: |
1037 | if (!HAS_BLT(dev)) { | 1088 | if (!HAS_BLT(dev)) { |
1038 | DRM_ERROR("execbuf with invalid ring (BLT)\n"); | 1089 | DRM_DEBUG("execbuf with invalid ring (BLT)\n"); |
1039 | return -EINVAL; | 1090 | return -EINVAL; |
1040 | } | 1091 | } |
1041 | ring = &dev_priv->ring[BCS]; | 1092 | ring = &dev_priv->ring[BCS]; |
1042 | break; | 1093 | break; |
1043 | default: | 1094 | default: |
1044 | DRM_ERROR("execbuf with unknown ring: %d\n", | 1095 | DRM_DEBUG("execbuf with unknown ring: %d\n", |
1045 | (int)(args->flags & I915_EXEC_RING_MASK)); | 1096 | (int)(args->flags & I915_EXEC_RING_MASK)); |
1046 | return -EINVAL; | 1097 | return -EINVAL; |
1047 | } | 1098 | } |
@@ -1067,18 +1118,18 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1067 | } | 1118 | } |
1068 | break; | 1119 | break; |
1069 | default: | 1120 | default: |
1070 | DRM_ERROR("execbuf with unknown constants: %d\n", mode); | 1121 | DRM_DEBUG("execbuf with unknown constants: %d\n", mode); |
1071 | return -EINVAL; | 1122 | return -EINVAL; |
1072 | } | 1123 | } |
1073 | 1124 | ||
1074 | if (args->buffer_count < 1) { | 1125 | if (args->buffer_count < 1) { |
1075 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 1126 | DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); |
1076 | return -EINVAL; | 1127 | return -EINVAL; |
1077 | } | 1128 | } |
1078 | 1129 | ||
1079 | if (args->num_cliprects != 0) { | 1130 | if (args->num_cliprects != 0) { |
1080 | if (ring != &dev_priv->ring[RCS]) { | 1131 | if (ring != &dev_priv->ring[RCS]) { |
1081 | DRM_ERROR("clip rectangles are only valid with the render ring\n"); | 1132 | DRM_DEBUG("clip rectangles are only valid with the render ring\n"); |
1082 | return -EINVAL; | 1133 | return -EINVAL; |
1083 | } | 1134 | } |
1084 | 1135 | ||
@@ -1123,7 +1174,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1123 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, | 1174 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, |
1124 | exec[i].handle)); | 1175 | exec[i].handle)); |
1125 | if (&obj->base == NULL) { | 1176 | if (&obj->base == NULL) { |
1126 | DRM_ERROR("Invalid object handle %d at index %d\n", | 1177 | DRM_DEBUG("Invalid object handle %d at index %d\n", |
1127 | exec[i].handle, i); | 1178 | exec[i].handle, i); |
1128 | /* prevent error path from reading uninitialized data */ | 1179 | /* prevent error path from reading uninitialized data */ |
1129 | ret = -ENOENT; | 1180 | ret = -ENOENT; |
@@ -1131,7 +1182,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1131 | } | 1182 | } |
1132 | 1183 | ||
1133 | if (!list_empty(&obj->exec_list)) { | 1184 | if (!list_empty(&obj->exec_list)) { |
1134 | DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n", | 1185 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", |
1135 | obj, exec[i].handle, i); | 1186 | obj, exec[i].handle, i); |
1136 | ret = -EINVAL; | 1187 | ret = -EINVAL; |
1137 | goto err; | 1188 | goto err; |
@@ -1169,7 +1220,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1169 | 1220 | ||
1170 | /* Set the pending read domains for the batch buffer to COMMAND */ | 1221 | /* Set the pending read domains for the batch buffer to COMMAND */ |
1171 | if (batch_obj->base.pending_write_domain) { | 1222 | if (batch_obj->base.pending_write_domain) { |
1172 | DRM_ERROR("Attempting to use self-modifying batch buffer\n"); | 1223 | DRM_DEBUG("Attempting to use self-modifying batch buffer\n"); |
1173 | ret = -EINVAL; | 1224 | ret = -EINVAL; |
1174 | goto err; | 1225 | goto err; |
1175 | } | 1226 | } |
@@ -1186,7 +1237,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1186 | * so every billion or so execbuffers, we need to stall | 1237 | * so every billion or so execbuffers, we need to stall |
1187 | * the GPU in order to reset the counters. | 1238 | * the GPU in order to reset the counters. |
1188 | */ | 1239 | */ |
1189 | ret = i915_gpu_idle(dev); | 1240 | ret = i915_gpu_idle(dev, true); |
1190 | if (ret) | 1241 | if (ret) |
1191 | goto err; | 1242 | goto err; |
1192 | 1243 | ||
@@ -1274,7 +1325,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
1274 | int ret, i; | 1325 | int ret, i; |
1275 | 1326 | ||
1276 | if (args->buffer_count < 1) { | 1327 | if (args->buffer_count < 1) { |
1277 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 1328 | DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); |
1278 | return -EINVAL; | 1329 | return -EINVAL; |
1279 | } | 1330 | } |
1280 | 1331 | ||
@@ -1282,7 +1333,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
1282 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); | 1333 | exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); |
1283 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); | 1334 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); |
1284 | if (exec_list == NULL || exec2_list == NULL) { | 1335 | if (exec_list == NULL || exec2_list == NULL) { |
1285 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | 1336 | DRM_DEBUG("Failed to allocate exec list for %d buffers\n", |
1286 | args->buffer_count); | 1337 | args->buffer_count); |
1287 | drm_free_large(exec_list); | 1338 | drm_free_large(exec_list); |
1288 | drm_free_large(exec2_list); | 1339 | drm_free_large(exec2_list); |
@@ -1293,7 +1344,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
1293 | (uintptr_t) args->buffers_ptr, | 1344 | (uintptr_t) args->buffers_ptr, |
1294 | sizeof(*exec_list) * args->buffer_count); | 1345 | sizeof(*exec_list) * args->buffer_count); |
1295 | if (ret != 0) { | 1346 | if (ret != 0) { |
1296 | DRM_ERROR("copy %d exec entries failed %d\n", | 1347 | DRM_DEBUG("copy %d exec entries failed %d\n", |
1297 | args->buffer_count, ret); | 1348 | args->buffer_count, ret); |
1298 | drm_free_large(exec_list); | 1349 | drm_free_large(exec_list); |
1299 | drm_free_large(exec2_list); | 1350 | drm_free_large(exec2_list); |
@@ -1334,7 +1385,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
1334 | sizeof(*exec_list) * args->buffer_count); | 1385 | sizeof(*exec_list) * args->buffer_count); |
1335 | if (ret) { | 1386 | if (ret) { |
1336 | ret = -EFAULT; | 1387 | ret = -EFAULT; |
1337 | DRM_ERROR("failed to copy %d exec entries " | 1388 | DRM_DEBUG("failed to copy %d exec entries " |
1338 | "back to user (%d)\n", | 1389 | "back to user (%d)\n", |
1339 | args->buffer_count, ret); | 1390 | args->buffer_count, ret); |
1340 | } | 1391 | } |
@@ -1354,7 +1405,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1354 | int ret; | 1405 | int ret; |
1355 | 1406 | ||
1356 | if (args->buffer_count < 1) { | 1407 | if (args->buffer_count < 1) { |
1357 | DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); | 1408 | DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); |
1358 | return -EINVAL; | 1409 | return -EINVAL; |
1359 | } | 1410 | } |
1360 | 1411 | ||
@@ -1364,7 +1415,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1364 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), | 1415 | exec2_list = drm_malloc_ab(sizeof(*exec2_list), |
1365 | args->buffer_count); | 1416 | args->buffer_count); |
1366 | if (exec2_list == NULL) { | 1417 | if (exec2_list == NULL) { |
1367 | DRM_ERROR("Failed to allocate exec list for %d buffers\n", | 1418 | DRM_DEBUG("Failed to allocate exec list for %d buffers\n", |
1368 | args->buffer_count); | 1419 | args->buffer_count); |
1369 | return -ENOMEM; | 1420 | return -ENOMEM; |
1370 | } | 1421 | } |
@@ -1373,7 +1424,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1373 | (uintptr_t) args->buffers_ptr, | 1424 | (uintptr_t) args->buffers_ptr, |
1374 | sizeof(*exec2_list) * args->buffer_count); | 1425 | sizeof(*exec2_list) * args->buffer_count); |
1375 | if (ret != 0) { | 1426 | if (ret != 0) { |
1376 | DRM_ERROR("copy %d exec entries failed %d\n", | 1427 | DRM_DEBUG("copy %d exec entries failed %d\n", |
1377 | args->buffer_count, ret); | 1428 | args->buffer_count, ret); |
1378 | drm_free_large(exec2_list); | 1429 | drm_free_large(exec2_list); |
1379 | return -EFAULT; | 1430 | return -EFAULT; |
@@ -1388,7 +1439,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, | |||
1388 | sizeof(*exec2_list) * args->buffer_count); | 1439 | sizeof(*exec2_list) * args->buffer_count); |
1389 | if (ret) { | 1440 | if (ret) { |
1390 | ret = -EFAULT; | 1441 | ret = -EFAULT; |
1391 | DRM_ERROR("failed to copy %d exec entries " | 1442 | DRM_DEBUG("failed to copy %d exec entries " |
1392 | "back to user (%d)\n", | 1443 | "back to user (%d)\n", |
1393 | args->buffer_count, ret); | 1444 | args->buffer_count, ret); |
1394 | } | 1445 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6042c5e6d278..2eacd78bb93b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -29,6 +29,279 @@ | |||
29 | #include "i915_trace.h" | 29 | #include "i915_trace.h" |
30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
31 | 31 | ||
32 | /* PPGTT support for Sandybdrige/Gen6 and later */ | ||
33 | static void i915_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, | ||
34 | unsigned first_entry, | ||
35 | unsigned num_entries) | ||
36 | { | ||
37 | uint32_t *pt_vaddr; | ||
38 | uint32_t scratch_pte; | ||
39 | unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; | ||
40 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; | ||
41 | unsigned last_pte, i; | ||
42 | |||
43 | scratch_pte = GEN6_PTE_ADDR_ENCODE(ppgtt->scratch_page_dma_addr); | ||
44 | scratch_pte |= GEN6_PTE_VALID | GEN6_PTE_CACHE_LLC; | ||
45 | |||
46 | while (num_entries) { | ||
47 | last_pte = first_pte + num_entries; | ||
48 | if (last_pte > I915_PPGTT_PT_ENTRIES) | ||
49 | last_pte = I915_PPGTT_PT_ENTRIES; | ||
50 | |||
51 | pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); | ||
52 | |||
53 | for (i = first_pte; i < last_pte; i++) | ||
54 | pt_vaddr[i] = scratch_pte; | ||
55 | |||
56 | kunmap_atomic(pt_vaddr); | ||
57 | |||
58 | num_entries -= last_pte - first_pte; | ||
59 | first_pte = 0; | ||
60 | act_pd++; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | ||
65 | { | ||
66 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
67 | struct i915_hw_ppgtt *ppgtt; | ||
68 | uint32_t pd_entry; | ||
69 | unsigned first_pd_entry_in_global_pt; | ||
70 | uint32_t __iomem *pd_addr; | ||
71 | int i; | ||
72 | int ret = -ENOMEM; | ||
73 | |||
74 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 | ||
75 | * entries. For aliasing ppgtt support we just steal them at the end for | ||
76 | * now. */ | ||
77 | first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; | ||
78 | |||
79 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); | ||
80 | if (!ppgtt) | ||
81 | return ret; | ||
82 | |||
83 | ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; | ||
84 | ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries, | ||
85 | GFP_KERNEL); | ||
86 | if (!ppgtt->pt_pages) | ||
87 | goto err_ppgtt; | ||
88 | |||
89 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | ||
90 | ppgtt->pt_pages[i] = alloc_page(GFP_KERNEL); | ||
91 | if (!ppgtt->pt_pages[i]) | ||
92 | goto err_pt_alloc; | ||
93 | } | ||
94 | |||
95 | if (dev_priv->mm.gtt->needs_dmar) { | ||
96 | ppgtt->pt_dma_addr = kzalloc(sizeof(dma_addr_t) | ||
97 | *ppgtt->num_pd_entries, | ||
98 | GFP_KERNEL); | ||
99 | if (!ppgtt->pt_dma_addr) | ||
100 | goto err_pt_alloc; | ||
101 | } | ||
102 | |||
103 | pd_addr = dev_priv->mm.gtt->gtt + first_pd_entry_in_global_pt; | ||
104 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | ||
105 | dma_addr_t pt_addr; | ||
106 | if (dev_priv->mm.gtt->needs_dmar) { | ||
107 | pt_addr = pci_map_page(dev->pdev, ppgtt->pt_pages[i], | ||
108 | 0, 4096, | ||
109 | PCI_DMA_BIDIRECTIONAL); | ||
110 | |||
111 | if (pci_dma_mapping_error(dev->pdev, | ||
112 | pt_addr)) { | ||
113 | ret = -EIO; | ||
114 | goto err_pd_pin; | ||
115 | |||
116 | } | ||
117 | ppgtt->pt_dma_addr[i] = pt_addr; | ||
118 | } else | ||
119 | pt_addr = page_to_phys(ppgtt->pt_pages[i]); | ||
120 | |||
121 | pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); | ||
122 | pd_entry |= GEN6_PDE_VALID; | ||
123 | |||
124 | writel(pd_entry, pd_addr + i); | ||
125 | } | ||
126 | readl(pd_addr); | ||
127 | |||
128 | ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; | ||
129 | |||
130 | i915_ppgtt_clear_range(ppgtt, 0, | ||
131 | ppgtt->num_pd_entries*I915_PPGTT_PT_ENTRIES); | ||
132 | |||
133 | ppgtt->pd_offset = (first_pd_entry_in_global_pt)*sizeof(uint32_t); | ||
134 | |||
135 | dev_priv->mm.aliasing_ppgtt = ppgtt; | ||
136 | |||
137 | return 0; | ||
138 | |||
139 | err_pd_pin: | ||
140 | if (ppgtt->pt_dma_addr) { | ||
141 | for (i--; i >= 0; i--) | ||
142 | pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], | ||
143 | 4096, PCI_DMA_BIDIRECTIONAL); | ||
144 | } | ||
145 | err_pt_alloc: | ||
146 | kfree(ppgtt->pt_dma_addr); | ||
147 | for (i = 0; i < ppgtt->num_pd_entries; i++) { | ||
148 | if (ppgtt->pt_pages[i]) | ||
149 | __free_page(ppgtt->pt_pages[i]); | ||
150 | } | ||
151 | kfree(ppgtt->pt_pages); | ||
152 | err_ppgtt: | ||
153 | kfree(ppgtt); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev) | ||
159 | { | ||
160 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
161 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; | ||
162 | int i; | ||
163 | |||
164 | if (!ppgtt) | ||
165 | return; | ||
166 | |||
167 | if (ppgtt->pt_dma_addr) { | ||
168 | for (i = 0; i < ppgtt->num_pd_entries; i++) | ||
169 | pci_unmap_page(dev->pdev, ppgtt->pt_dma_addr[i], | ||
170 | 4096, PCI_DMA_BIDIRECTIONAL); | ||
171 | } | ||
172 | |||
173 | kfree(ppgtt->pt_dma_addr); | ||
174 | for (i = 0; i < ppgtt->num_pd_entries; i++) | ||
175 | __free_page(ppgtt->pt_pages[i]); | ||
176 | kfree(ppgtt->pt_pages); | ||
177 | kfree(ppgtt); | ||
178 | } | ||
179 | |||
180 | static void i915_ppgtt_insert_sg_entries(struct i915_hw_ppgtt *ppgtt, | ||
181 | struct scatterlist *sg_list, | ||
182 | unsigned sg_len, | ||
183 | unsigned first_entry, | ||
184 | uint32_t pte_flags) | ||
185 | { | ||
186 | uint32_t *pt_vaddr, pte; | ||
187 | unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; | ||
188 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; | ||
189 | unsigned i, j, m, segment_len; | ||
190 | dma_addr_t page_addr; | ||
191 | struct scatterlist *sg; | ||
192 | |||
193 | /* init sg walking */ | ||
194 | sg = sg_list; | ||
195 | i = 0; | ||
196 | segment_len = sg_dma_len(sg) >> PAGE_SHIFT; | ||
197 | m = 0; | ||
198 | |||
199 | while (i < sg_len) { | ||
200 | pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); | ||
201 | |||
202 | for (j = first_pte; j < I915_PPGTT_PT_ENTRIES; j++) { | ||
203 | page_addr = sg_dma_address(sg) + (m << PAGE_SHIFT); | ||
204 | pte = GEN6_PTE_ADDR_ENCODE(page_addr); | ||
205 | pt_vaddr[j] = pte | pte_flags; | ||
206 | |||
207 | /* grab the next page */ | ||
208 | m++; | ||
209 | if (m == segment_len) { | ||
210 | sg = sg_next(sg); | ||
211 | i++; | ||
212 | if (i == sg_len) | ||
213 | break; | ||
214 | |||
215 | segment_len = sg_dma_len(sg) >> PAGE_SHIFT; | ||
216 | m = 0; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | kunmap_atomic(pt_vaddr); | ||
221 | |||
222 | first_pte = 0; | ||
223 | act_pd++; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | static void i915_ppgtt_insert_pages(struct i915_hw_ppgtt *ppgtt, | ||
228 | unsigned first_entry, unsigned num_entries, | ||
229 | struct page **pages, uint32_t pte_flags) | ||
230 | { | ||
231 | uint32_t *pt_vaddr, pte; | ||
232 | unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES; | ||
233 | unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; | ||
234 | unsigned last_pte, i; | ||
235 | dma_addr_t page_addr; | ||
236 | |||
237 | while (num_entries) { | ||
238 | last_pte = first_pte + num_entries; | ||
239 | last_pte = min_t(unsigned, last_pte, I915_PPGTT_PT_ENTRIES); | ||
240 | |||
241 | pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]); | ||
242 | |||
243 | for (i = first_pte; i < last_pte; i++) { | ||
244 | page_addr = page_to_phys(*pages); | ||
245 | pte = GEN6_PTE_ADDR_ENCODE(page_addr); | ||
246 | pt_vaddr[i] = pte | pte_flags; | ||
247 | |||
248 | pages++; | ||
249 | } | ||
250 | |||
251 | kunmap_atomic(pt_vaddr); | ||
252 | |||
253 | num_entries -= last_pte - first_pte; | ||
254 | first_pte = 0; | ||
255 | act_pd++; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, | ||
260 | struct drm_i915_gem_object *obj, | ||
261 | enum i915_cache_level cache_level) | ||
262 | { | ||
263 | struct drm_device *dev = obj->base.dev; | ||
264 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
265 | uint32_t pte_flags = GEN6_PTE_VALID; | ||
266 | |||
267 | switch (cache_level) { | ||
268 | case I915_CACHE_LLC_MLC: | ||
269 | pte_flags |= GEN6_PTE_CACHE_LLC_MLC; | ||
270 | break; | ||
271 | case I915_CACHE_LLC: | ||
272 | pte_flags |= GEN6_PTE_CACHE_LLC; | ||
273 | break; | ||
274 | case I915_CACHE_NONE: | ||
275 | pte_flags |= GEN6_PTE_UNCACHED; | ||
276 | break; | ||
277 | default: | ||
278 | BUG(); | ||
279 | } | ||
280 | |||
281 | if (dev_priv->mm.gtt->needs_dmar) { | ||
282 | BUG_ON(!obj->sg_list); | ||
283 | |||
284 | i915_ppgtt_insert_sg_entries(ppgtt, | ||
285 | obj->sg_list, | ||
286 | obj->num_sg, | ||
287 | obj->gtt_space->start >> PAGE_SHIFT, | ||
288 | pte_flags); | ||
289 | } else | ||
290 | i915_ppgtt_insert_pages(ppgtt, | ||
291 | obj->gtt_space->start >> PAGE_SHIFT, | ||
292 | obj->base.size >> PAGE_SHIFT, | ||
293 | obj->pages, | ||
294 | pte_flags); | ||
295 | } | ||
296 | |||
297 | void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt, | ||
298 | struct drm_i915_gem_object *obj) | ||
299 | { | ||
300 | i915_ppgtt_clear_range(ppgtt, | ||
301 | obj->gtt_space->start >> PAGE_SHIFT, | ||
302 | obj->base.size >> PAGE_SHIFT); | ||
303 | } | ||
304 | |||
32 | /* XXX kill agp_type! */ | 305 | /* XXX kill agp_type! */ |
33 | static unsigned int cache_level_to_agp_type(struct drm_device *dev, | 306 | static unsigned int cache_level_to_agp_type(struct drm_device *dev, |
34 | enum i915_cache_level cache_level) | 307 | enum i915_cache_level cache_level) |
@@ -55,7 +328,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) | |||
55 | 328 | ||
56 | if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { | 329 | if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { |
57 | dev_priv->mm.interruptible = false; | 330 | dev_priv->mm.interruptible = false; |
58 | if (i915_gpu_idle(dev_priv->dev)) { | 331 | if (i915_gpu_idle(dev_priv->dev, false)) { |
59 | DRM_ERROR("Couldn't idle GPU\n"); | 332 | DRM_ERROR("Couldn't idle GPU\n"); |
60 | /* Wait a bit, in hopes it avoids the hang */ | 333 | /* Wait a bit, in hopes it avoids the hang */ |
61 | udelay(10); | 334 | udelay(10); |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 31d334d9d9da..1a9306665987 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -93,8 +93,23 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
93 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; | 93 | uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; |
94 | 94 | ||
95 | if (INTEL_INFO(dev)->gen >= 6) { | 95 | if (INTEL_INFO(dev)->gen >= 6) { |
96 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | 96 | uint32_t dimm_c0, dimm_c1; |
97 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | 97 | dimm_c0 = I915_READ(MAD_DIMM_C0); |
98 | dimm_c1 = I915_READ(MAD_DIMM_C1); | ||
99 | dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
100 | dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK; | ||
101 | /* Enable swizzling when the channels are populated with | ||
102 | * identically sized dimms. We don't need to check the 3rd | ||
103 | * channel because no cpu with gpu attached ships in that | ||
104 | * configuration. Also, swizzling only makes sense for 2 | ||
105 | * channels anyway. */ | ||
106 | if (dimm_c0 == dimm_c1) { | ||
107 | swizzle_x = I915_BIT_6_SWIZZLE_9_10; | ||
108 | swizzle_y = I915_BIT_6_SWIZZLE_9; | ||
109 | } else { | ||
110 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | ||
111 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | ||
112 | } | ||
98 | } else if (IS_GEN5(dev)) { | 113 | } else if (IS_GEN5(dev)) { |
99 | /* On Ironlake whatever DRAM config, GPU always do | 114 | /* On Ironlake whatever DRAM config, GPU always do |
100 | * same swizzling setup. | 115 | * same swizzling setup. |
@@ -107,10 +122,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) | |||
107 | */ | 122 | */ |
108 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; | 123 | swizzle_x = I915_BIT_6_SWIZZLE_NONE; |
109 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; | 124 | swizzle_y = I915_BIT_6_SWIZZLE_NONE; |
110 | } else if (IS_MOBILE(dev)) { | 125 | } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { |
111 | uint32_t dcc; | 126 | uint32_t dcc; |
112 | 127 | ||
113 | /* On mobile 9xx chipsets, channel interleave by the CPU is | 128 | /* On 9xx chipsets, channel interleave by the CPU is |
114 | * determined by DCC. For single-channel, neither the CPU | 129 | * determined by DCC. For single-channel, neither the CPU |
115 | * nor the GPU do swizzling. For dual channel interleaved, | 130 | * nor the GPU do swizzling. For dual channel interleaved, |
116 | * the GPU's interleave is bit 9 and 10 for X tiled, and bit | 131 | * the GPU's interleave is bit 9 and 10 for X tiled, and bit |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5bd4361ea84d..063b4577d4c6 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv, | |||
720 | reloc_offset = src->gtt_offset; | 720 | reloc_offset = src->gtt_offset; |
721 | for (page = 0; page < page_count; page++) { | 721 | for (page = 0; page < page_count; page++) { |
722 | unsigned long flags; | 722 | unsigned long flags; |
723 | void __iomem *s; | ||
724 | void *d; | 723 | void *d; |
725 | 724 | ||
726 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | 725 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); |
@@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv, | |||
728 | goto unwind; | 727 | goto unwind; |
729 | 728 | ||
730 | local_irq_save(flags); | 729 | local_irq_save(flags); |
731 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | 730 | if (reloc_offset < dev_priv->mm.gtt_mappable_end) { |
732 | reloc_offset); | 731 | void __iomem *s; |
733 | memcpy_fromio(d, s, PAGE_SIZE); | 732 | |
734 | io_mapping_unmap_atomic(s); | 733 | /* Simply ignore tiling or any overlapping fence. |
734 | * It's part of the error state, and this hopefully | ||
735 | * captures what the GPU read. | ||
736 | */ | ||
737 | |||
738 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, | ||
739 | reloc_offset); | ||
740 | memcpy_fromio(d, s, PAGE_SIZE); | ||
741 | io_mapping_unmap_atomic(s); | ||
742 | } else { | ||
743 | void *s; | ||
744 | |||
745 | drm_clflush_pages(&src->pages[page], 1); | ||
746 | |||
747 | s = kmap_atomic(src->pages[page]); | ||
748 | memcpy(d, s, PAGE_SIZE); | ||
749 | kunmap_atomic(s); | ||
750 | |||
751 | drm_clflush_pages(&src->pages[page], 1); | ||
752 | } | ||
735 | local_irq_restore(flags); | 753 | local_irq_restore(flags); |
736 | 754 | ||
737 | dst->pages[page] = d; | 755 | dst->pages[page] = d; |
@@ -804,7 +822,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, | |||
804 | err->tiling = obj->tiling_mode; | 822 | err->tiling = obj->tiling_mode; |
805 | err->dirty = obj->dirty; | 823 | err->dirty = obj->dirty; |
806 | err->purgeable = obj->madv != I915_MADV_WILLNEED; | 824 | err->purgeable = obj->madv != I915_MADV_WILLNEED; |
807 | err->ring = obj->ring ? obj->ring->id : 0; | 825 | err->ring = obj->ring ? obj->ring->id : -1; |
808 | err->cache_level = obj->cache_level; | 826 | err->cache_level = obj->cache_level; |
809 | 827 | ||
810 | if (++i == count) | 828 | if (++i == count) |
@@ -876,6 +894,46 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, | |||
876 | return NULL; | 894 | return NULL; |
877 | } | 895 | } |
878 | 896 | ||
897 | static void i915_record_ring_state(struct drm_device *dev, | ||
898 | struct drm_i915_error_state *error, | ||
899 | struct intel_ring_buffer *ring) | ||
900 | { | ||
901 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
902 | |||
903 | if (INTEL_INFO(dev)->gen >= 6) { | ||
904 | error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); | ||
905 | error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); | ||
906 | error->semaphore_mboxes[ring->id][0] | ||
907 | = I915_READ(RING_SYNC_0(ring->mmio_base)); | ||
908 | error->semaphore_mboxes[ring->id][1] | ||
909 | = I915_READ(RING_SYNC_1(ring->mmio_base)); | ||
910 | } | ||
911 | |||
912 | if (INTEL_INFO(dev)->gen >= 4) { | ||
913 | error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); | ||
914 | error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); | ||
915 | error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); | ||
916 | error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); | ||
917 | if (ring->id == RCS) { | ||
918 | error->instdone1 = I915_READ(INSTDONE1); | ||
919 | error->bbaddr = I915_READ64(BB_ADDR); | ||
920 | } | ||
921 | } else { | ||
922 | error->ipeir[ring->id] = I915_READ(IPEIR); | ||
923 | error->ipehr[ring->id] = I915_READ(IPEHR); | ||
924 | error->instdone[ring->id] = I915_READ(INSTDONE); | ||
925 | } | ||
926 | |||
927 | error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); | ||
928 | error->seqno[ring->id] = ring->get_seqno(ring); | ||
929 | error->acthd[ring->id] = intel_ring_get_active_head(ring); | ||
930 | error->head[ring->id] = I915_READ_HEAD(ring); | ||
931 | error->tail[ring->id] = I915_READ_TAIL(ring); | ||
932 | |||
933 | error->cpu_ring_head[ring->id] = ring->head; | ||
934 | error->cpu_ring_tail[ring->id] = ring->tail; | ||
935 | } | ||
936 | |||
879 | /** | 937 | /** |
880 | * i915_capture_error_state - capture an error record for later analysis | 938 | * i915_capture_error_state - capture an error record for later analysis |
881 | * @dev: drm device | 939 | * @dev: drm device |
@@ -900,7 +958,7 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
900 | return; | 958 | return; |
901 | 959 | ||
902 | /* Account for pipe specific data like PIPE*STAT */ | 960 | /* Account for pipe specific data like PIPE*STAT */ |
903 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | 961 | error = kzalloc(sizeof(*error), GFP_ATOMIC); |
904 | if (!error) { | 962 | if (!error) { |
905 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); | 963 | DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); |
906 | return; | 964 | return; |
@@ -909,47 +967,22 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
909 | DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", | 967 | DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", |
910 | dev->primary->index); | 968 | dev->primary->index); |
911 | 969 | ||
912 | error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); | ||
913 | error->eir = I915_READ(EIR); | 970 | error->eir = I915_READ(EIR); |
914 | error->pgtbl_er = I915_READ(PGTBL_ER); | 971 | error->pgtbl_er = I915_READ(PGTBL_ER); |
915 | for_each_pipe(pipe) | 972 | for_each_pipe(pipe) |
916 | error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); | 973 | error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); |
917 | error->instpm = I915_READ(INSTPM); | 974 | |
918 | error->error = 0; | ||
919 | if (INTEL_INFO(dev)->gen >= 6) { | 975 | if (INTEL_INFO(dev)->gen >= 6) { |
920 | error->error = I915_READ(ERROR_GEN6); | 976 | error->error = I915_READ(ERROR_GEN6); |
921 | 977 | error->done_reg = I915_READ(DONE_REG); | |
922 | error->bcs_acthd = I915_READ(BCS_ACTHD); | ||
923 | error->bcs_ipehr = I915_READ(BCS_IPEHR); | ||
924 | error->bcs_ipeir = I915_READ(BCS_IPEIR); | ||
925 | error->bcs_instdone = I915_READ(BCS_INSTDONE); | ||
926 | error->bcs_seqno = 0; | ||
927 | if (dev_priv->ring[BCS].get_seqno) | ||
928 | error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]); | ||
929 | |||
930 | error->vcs_acthd = I915_READ(VCS_ACTHD); | ||
931 | error->vcs_ipehr = I915_READ(VCS_IPEHR); | ||
932 | error->vcs_ipeir = I915_READ(VCS_IPEIR); | ||
933 | error->vcs_instdone = I915_READ(VCS_INSTDONE); | ||
934 | error->vcs_seqno = 0; | ||
935 | if (dev_priv->ring[VCS].get_seqno) | ||
936 | error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]); | ||
937 | } | ||
938 | if (INTEL_INFO(dev)->gen >= 4) { | ||
939 | error->ipeir = I915_READ(IPEIR_I965); | ||
940 | error->ipehr = I915_READ(IPEHR_I965); | ||
941 | error->instdone = I915_READ(INSTDONE_I965); | ||
942 | error->instps = I915_READ(INSTPS); | ||
943 | error->instdone1 = I915_READ(INSTDONE1); | ||
944 | error->acthd = I915_READ(ACTHD_I965); | ||
945 | error->bbaddr = I915_READ64(BB_ADDR); | ||
946 | } else { | ||
947 | error->ipeir = I915_READ(IPEIR); | ||
948 | error->ipehr = I915_READ(IPEHR); | ||
949 | error->instdone = I915_READ(INSTDONE); | ||
950 | error->acthd = I915_READ(ACTHD); | ||
951 | error->bbaddr = 0; | ||
952 | } | 978 | } |
979 | |||
980 | i915_record_ring_state(dev, error, &dev_priv->ring[RCS]); | ||
981 | if (HAS_BLT(dev)) | ||
982 | i915_record_ring_state(dev, error, &dev_priv->ring[BCS]); | ||
983 | if (HAS_BSD(dev)) | ||
984 | i915_record_ring_state(dev, error, &dev_priv->ring[VCS]); | ||
985 | |||
953 | i915_gem_record_fences(dev, error); | 986 | i915_gem_record_fences(dev, error); |
954 | 987 | ||
955 | /* Record the active batch and ring buffers */ | 988 | /* Record the active batch and ring buffers */ |
@@ -1017,11 +1050,12 @@ void i915_destroy_error_state(struct drm_device *dev) | |||
1017 | { | 1050 | { |
1018 | struct drm_i915_private *dev_priv = dev->dev_private; | 1051 | struct drm_i915_private *dev_priv = dev->dev_private; |
1019 | struct drm_i915_error_state *error; | 1052 | struct drm_i915_error_state *error; |
1053 | unsigned long flags; | ||
1020 | 1054 | ||
1021 | spin_lock(&dev_priv->error_lock); | 1055 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
1022 | error = dev_priv->first_error; | 1056 | error = dev_priv->first_error; |
1023 | dev_priv->first_error = NULL; | 1057 | dev_priv->first_error = NULL; |
1024 | spin_unlock(&dev_priv->error_lock); | 1058 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
1025 | 1059 | ||
1026 | if (error) | 1060 | if (error) |
1027 | i915_error_state_free(dev, error); | 1061 | i915_error_state_free(dev, error); |
@@ -1698,6 +1732,7 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1698 | dev_priv->last_instdone1 == instdone1) { | 1732 | dev_priv->last_instdone1 == instdone1) { |
1699 | if (dev_priv->hangcheck_count++ > 1) { | 1733 | if (dev_priv->hangcheck_count++ > 1) { |
1700 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | 1734 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); |
1735 | i915_handle_error(dev, true); | ||
1701 | 1736 | ||
1702 | if (!IS_GEN2(dev)) { | 1737 | if (!IS_GEN2(dev)) { |
1703 | /* Is the chip hanging on a WAIT_FOR_EVENT? | 1738 | /* Is the chip hanging on a WAIT_FOR_EVENT? |
@@ -1705,7 +1740,6 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1705 | * and break the hang. This should work on | 1740 | * and break the hang. This should work on |
1706 | * all but the second generation chipsets. | 1741 | * all but the second generation chipsets. |
1707 | */ | 1742 | */ |
1708 | |||
1709 | if (kick_ring(&dev_priv->ring[RCS])) | 1743 | if (kick_ring(&dev_priv->ring[RCS])) |
1710 | goto repeat; | 1744 | goto repeat; |
1711 | 1745 | ||
@@ -1718,7 +1752,6 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1718 | goto repeat; | 1752 | goto repeat; |
1719 | } | 1753 | } |
1720 | 1754 | ||
1721 | i915_handle_error(dev, true); | ||
1722 | return; | 1755 | return; |
1723 | } | 1756 | } |
1724 | } else { | 1757 | } else { |
diff --git a/drivers/gpu/drm/i915/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c deleted file mode 100644 index cc8f6d49cf20..000000000000 --- a/drivers/gpu/drm/i915/i915_mem.c +++ /dev/null | |||
@@ -1,387 +0,0 @@ | |||
1 | /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- | ||
2 | */ | ||
3 | /* | ||
4 | * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | ||
5 | * All Rights Reserved. | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
8 | * copy of this software and associated documentation files (the | ||
9 | * "Software"), to deal in the Software without restriction, including | ||
10 | * without limitation the rights to use, copy, modify, merge, publish, | ||
11 | * distribute, sub license, and/or sell copies of the Software, and to | ||
12 | * permit persons to whom the Software is furnished to do so, subject to | ||
13 | * the following conditions: | ||
14 | * | ||
15 | * The above copyright notice and this permission notice (including the | ||
16 | * next paragraph) shall be included in all copies or substantial portions | ||
17 | * of the Software. | ||
18 | * | ||
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
20 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
21 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
22 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
23 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
24 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
25 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drm.h" | ||
32 | #include "i915_drv.h" | ||
33 | |||
34 | /* This memory manager is integrated into the global/local lru | ||
35 | * mechanisms used by the clients. Specifically, it operates by | ||
36 | * setting the 'in_use' fields of the global LRU to indicate whether | ||
37 | * this region is privately allocated to a client. | ||
38 | * | ||
39 | * This does require the client to actually respect that field. | ||
40 | * | ||
41 | * Currently no effort is made to allocate 'private' memory in any | ||
42 | * clever way - the LRU information isn't used to determine which | ||
43 | * block to allocate, and the ring is drained prior to allocations -- | ||
44 | * in other words allocation is expensive. | ||
45 | */ | ||
46 | static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) | ||
47 | { | ||
48 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
49 | struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; | ||
50 | drm_i915_sarea_t *sarea_priv = master_priv->sarea_priv; | ||
51 | struct drm_tex_region *list; | ||
52 | unsigned shift, nr; | ||
53 | unsigned start; | ||
54 | unsigned end; | ||
55 | unsigned i; | ||
56 | int age; | ||
57 | |||
58 | shift = dev_priv->tex_lru_log_granularity; | ||
59 | nr = I915_NR_TEX_REGIONS; | ||
60 | |||
61 | start = p->start >> shift; | ||
62 | end = (p->start + p->size - 1) >> shift; | ||
63 | |||
64 | age = ++sarea_priv->texAge; | ||
65 | list = sarea_priv->texList; | ||
66 | |||
67 | /* Mark the regions with the new flag and update their age. Move | ||
68 | * them to head of list to preserve LRU semantics. | ||
69 | */ | ||
70 | for (i = start; i <= end; i++) { | ||
71 | list[i].in_use = in_use; | ||
72 | list[i].age = age; | ||
73 | |||
74 | /* remove_from_list(i) | ||
75 | */ | ||
76 | list[(unsigned)list[i].next].prev = list[i].prev; | ||
77 | list[(unsigned)list[i].prev].next = list[i].next; | ||
78 | |||
79 | /* insert_at_head(list, i) | ||
80 | */ | ||
81 | list[i].prev = nr; | ||
82 | list[i].next = list[nr].next; | ||
83 | list[(unsigned)list[nr].next].prev = i; | ||
84 | list[nr].next = i; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* Very simple allocator for agp memory, working on a static range | ||
89 | * already mapped into each client's address space. | ||
90 | */ | ||
91 | |||
92 | static struct mem_block *split_block(struct mem_block *p, int start, int size, | ||
93 | struct drm_file *file_priv) | ||
94 | { | ||
95 | /* Maybe cut off the start of an existing block */ | ||
96 | if (start > p->start) { | ||
97 | struct mem_block *newblock = kmalloc(sizeof(*newblock), | ||
98 | GFP_KERNEL); | ||
99 | if (!newblock) | ||
100 | goto out; | ||
101 | newblock->start = start; | ||
102 | newblock->size = p->size - (start - p->start); | ||
103 | newblock->file_priv = NULL; | ||
104 | newblock->next = p->next; | ||
105 | newblock->prev = p; | ||
106 | p->next->prev = newblock; | ||
107 | p->next = newblock; | ||
108 | p->size -= newblock->size; | ||
109 | p = newblock; | ||
110 | } | ||
111 | |||
112 | /* Maybe cut off the end of an existing block */ | ||
113 | if (size < p->size) { | ||
114 | struct mem_block *newblock = kmalloc(sizeof(*newblock), | ||
115 | GFP_KERNEL); | ||
116 | if (!newblock) | ||
117 | goto out; | ||
118 | newblock->start = start + size; | ||
119 | newblock->size = p->size - size; | ||
120 | newblock->file_priv = NULL; | ||
121 | newblock->next = p->next; | ||
122 | newblock->prev = p; | ||
123 | p->next->prev = newblock; | ||
124 | p->next = newblock; | ||
125 | p->size = size; | ||
126 | } | ||
127 | |||
128 | out: | ||
129 | /* Our block is in the middle */ | ||
130 | p->file_priv = file_priv; | ||
131 | return p; | ||
132 | } | ||
133 | |||
134 | static struct mem_block *alloc_block(struct mem_block *heap, int size, | ||
135 | int align2, struct drm_file *file_priv) | ||
136 | { | ||
137 | struct mem_block *p; | ||
138 | int mask = (1 << align2) - 1; | ||
139 | |||
140 | for (p = heap->next; p != heap; p = p->next) { | ||
141 | int start = (p->start + mask) & ~mask; | ||
142 | if (p->file_priv == NULL && start + size <= p->start + p->size) | ||
143 | return split_block(p, start, size, file_priv); | ||
144 | } | ||
145 | |||
146 | return NULL; | ||
147 | } | ||
148 | |||
149 | static struct mem_block *find_block(struct mem_block *heap, int start) | ||
150 | { | ||
151 | struct mem_block *p; | ||
152 | |||
153 | for (p = heap->next; p != heap; p = p->next) | ||
154 | if (p->start == start) | ||
155 | return p; | ||
156 | |||
157 | return NULL; | ||
158 | } | ||
159 | |||
160 | static void free_block(struct mem_block *p) | ||
161 | { | ||
162 | p->file_priv = NULL; | ||
163 | |||
164 | /* Assumes a single contiguous range. Needs a special file_priv in | ||
165 | * 'heap' to stop it being subsumed. | ||
166 | */ | ||
167 | if (p->next->file_priv == NULL) { | ||
168 | struct mem_block *q = p->next; | ||
169 | p->size += q->size; | ||
170 | p->next = q->next; | ||
171 | p->next->prev = p; | ||
172 | kfree(q); | ||
173 | } | ||
174 | |||
175 | if (p->prev->file_priv == NULL) { | ||
176 | struct mem_block *q = p->prev; | ||
177 | q->size += p->size; | ||
178 | q->next = p->next; | ||
179 | q->next->prev = q; | ||
180 | kfree(p); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /* Initialize. How to check for an uninitialized heap? | ||
185 | */ | ||
186 | static int init_heap(struct mem_block **heap, int start, int size) | ||
187 | { | ||
188 | struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); | ||
189 | |||
190 | if (!blocks) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | *heap = kmalloc(sizeof(**heap), GFP_KERNEL); | ||
194 | if (!*heap) { | ||
195 | kfree(blocks); | ||
196 | return -ENOMEM; | ||
197 | } | ||
198 | |||
199 | blocks->start = start; | ||
200 | blocks->size = size; | ||
201 | blocks->file_priv = NULL; | ||
202 | blocks->next = blocks->prev = *heap; | ||
203 | |||
204 | memset(*heap, 0, sizeof(**heap)); | ||
205 | (*heap)->file_priv = (struct drm_file *) -1; | ||
206 | (*heap)->next = (*heap)->prev = blocks; | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | /* Free all blocks associated with the releasing file. | ||
211 | */ | ||
212 | void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, | ||
213 | struct mem_block *heap) | ||
214 | { | ||
215 | struct mem_block *p; | ||
216 | |||
217 | if (!heap || !heap->next) | ||
218 | return; | ||
219 | |||
220 | for (p = heap->next; p != heap; p = p->next) { | ||
221 | if (p->file_priv == file_priv) { | ||
222 | p->file_priv = NULL; | ||
223 | mark_block(dev, p, 0); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | /* Assumes a single contiguous range. Needs a special file_priv in | ||
228 | * 'heap' to stop it being subsumed. | ||
229 | */ | ||
230 | for (p = heap->next; p != heap; p = p->next) { | ||
231 | while (p->file_priv == NULL && p->next->file_priv == NULL) { | ||
232 | struct mem_block *q = p->next; | ||
233 | p->size += q->size; | ||
234 | p->next = q->next; | ||
235 | p->next->prev = p; | ||
236 | kfree(q); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /* Shutdown. | ||
242 | */ | ||
243 | void i915_mem_takedown(struct mem_block **heap) | ||
244 | { | ||
245 | struct mem_block *p; | ||
246 | |||
247 | if (!*heap) | ||
248 | return; | ||
249 | |||
250 | for (p = (*heap)->next; p != *heap;) { | ||
251 | struct mem_block *q = p; | ||
252 | p = p->next; | ||
253 | kfree(q); | ||
254 | } | ||
255 | |||
256 | kfree(*heap); | ||
257 | *heap = NULL; | ||
258 | } | ||
259 | |||
260 | static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) | ||
261 | { | ||
262 | switch (region) { | ||
263 | case I915_MEM_REGION_AGP: | ||
264 | return &dev_priv->agp_heap; | ||
265 | default: | ||
266 | return NULL; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | /* IOCTL HANDLERS */ | ||
271 | |||
272 | int i915_mem_alloc(struct drm_device *dev, void *data, | ||
273 | struct drm_file *file_priv) | ||
274 | { | ||
275 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
276 | drm_i915_mem_alloc_t *alloc = data; | ||
277 | struct mem_block *block, **heap; | ||
278 | |||
279 | if (!dev_priv) { | ||
280 | DRM_ERROR("called with no initialization\n"); | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | |||
284 | heap = get_heap(dev_priv, alloc->region); | ||
285 | if (!heap || !*heap) | ||
286 | return -EFAULT; | ||
287 | |||
288 | /* Make things easier on ourselves: all allocations at least | ||
289 | * 4k aligned. | ||
290 | */ | ||
291 | if (alloc->alignment < 12) | ||
292 | alloc->alignment = 12; | ||
293 | |||
294 | block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); | ||
295 | |||
296 | if (!block) | ||
297 | return -ENOMEM; | ||
298 | |||
299 | mark_block(dev, block, 1); | ||
300 | |||
301 | if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, | ||
302 | sizeof(int))) { | ||
303 | DRM_ERROR("copy_to_user\n"); | ||
304 | return -EFAULT; | ||
305 | } | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | int i915_mem_free(struct drm_device *dev, void *data, | ||
311 | struct drm_file *file_priv) | ||
312 | { | ||
313 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
314 | drm_i915_mem_free_t *memfree = data; | ||
315 | struct mem_block *block, **heap; | ||
316 | |||
317 | if (!dev_priv) { | ||
318 | DRM_ERROR("called with no initialization\n"); | ||
319 | return -EINVAL; | ||
320 | } | ||
321 | |||
322 | heap = get_heap(dev_priv, memfree->region); | ||
323 | if (!heap || !*heap) | ||
324 | return -EFAULT; | ||
325 | |||
326 | block = find_block(*heap, memfree->region_offset); | ||
327 | if (!block) | ||
328 | return -EFAULT; | ||
329 | |||
330 | if (block->file_priv != file_priv) | ||
331 | return -EPERM; | ||
332 | |||
333 | mark_block(dev, block, 0); | ||
334 | free_block(block); | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | int i915_mem_init_heap(struct drm_device *dev, void *data, | ||
339 | struct drm_file *file_priv) | ||
340 | { | ||
341 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
342 | drm_i915_mem_init_heap_t *initheap = data; | ||
343 | struct mem_block **heap; | ||
344 | |||
345 | if (!dev_priv) { | ||
346 | DRM_ERROR("called with no initialization\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | heap = get_heap(dev_priv, initheap->region); | ||
351 | if (!heap) | ||
352 | return -EFAULT; | ||
353 | |||
354 | if (*heap) { | ||
355 | DRM_ERROR("heap already initialized?"); | ||
356 | return -EFAULT; | ||
357 | } | ||
358 | |||
359 | return init_heap(heap, initheap->start, initheap->size); | ||
360 | } | ||
361 | |||
362 | int i915_mem_destroy_heap(struct drm_device *dev, void *data, | ||
363 | struct drm_file *file_priv) | ||
364 | { | ||
365 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
366 | drm_i915_mem_destroy_heap_t *destroyheap = data; | ||
367 | struct mem_block **heap; | ||
368 | |||
369 | if (!dev_priv) { | ||
370 | DRM_ERROR("called with no initialization\n"); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | |||
374 | heap = get_heap(dev_priv, destroyheap->region); | ||
375 | if (!heap) { | ||
376 | DRM_ERROR("get_heap failed"); | ||
377 | return -EFAULT; | ||
378 | } | ||
379 | |||
380 | if (!*heap) { | ||
381 | DRM_ERROR("heap not initialized?"); | ||
382 | return -EFAULT; | ||
383 | } | ||
384 | |||
385 | i915_mem_takedown(heap); | ||
386 | return 0; | ||
387 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c3afb783cb9d..341ce44e732d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -86,12 +86,45 @@ | |||
86 | #define GEN6_MBC_SNPCR_LOW (2<<21) | 86 | #define GEN6_MBC_SNPCR_LOW (2<<21) |
87 | #define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ | 87 | #define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ |
88 | 88 | ||
89 | #define GEN6_MBCTL 0x0907c | ||
90 | #define GEN6_MBCTL_ENABLE_BOOT_FETCH (1 << 4) | ||
91 | #define GEN6_MBCTL_CTX_FETCH_NEEDED (1 << 3) | ||
92 | #define GEN6_MBCTL_BME_UPDATE_ENABLE (1 << 2) | ||
93 | #define GEN6_MBCTL_MAE_UPDATE_ENABLE (1 << 1) | ||
94 | #define GEN6_MBCTL_BOOT_FETCH_MECH (1 << 0) | ||
95 | |||
89 | #define GEN6_GDRST 0x941c | 96 | #define GEN6_GDRST 0x941c |
90 | #define GEN6_GRDOM_FULL (1 << 0) | 97 | #define GEN6_GRDOM_FULL (1 << 0) |
91 | #define GEN6_GRDOM_RENDER (1 << 1) | 98 | #define GEN6_GRDOM_RENDER (1 << 1) |
92 | #define GEN6_GRDOM_MEDIA (1 << 2) | 99 | #define GEN6_GRDOM_MEDIA (1 << 2) |
93 | #define GEN6_GRDOM_BLT (1 << 3) | 100 | #define GEN6_GRDOM_BLT (1 << 3) |
94 | 101 | ||
102 | /* PPGTT stuff */ | ||
103 | #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) | ||
104 | |||
105 | #define GEN6_PDE_VALID (1 << 0) | ||
106 | #define GEN6_PDE_LARGE_PAGE (2 << 0) /* use 32kb pages */ | ||
107 | /* gen6+ has bit 11-4 for physical addr bit 39-32 */ | ||
108 | #define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) | ||
109 | |||
110 | #define GEN6_PTE_VALID (1 << 0) | ||
111 | #define GEN6_PTE_UNCACHED (1 << 1) | ||
112 | #define GEN6_PTE_CACHE_LLC (2 << 1) | ||
113 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) | ||
114 | #define GEN6_PTE_CACHE_BITS (3 << 1) | ||
115 | #define GEN6_PTE_GFDT (1 << 3) | ||
116 | #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) | ||
117 | |||
118 | #define RING_PP_DIR_BASE(ring) ((ring)->mmio_base+0x228) | ||
119 | #define RING_PP_DIR_BASE_READ(ring) ((ring)->mmio_base+0x518) | ||
120 | #define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) | ||
121 | #define PP_DIR_DCLV_2G 0xffffffff | ||
122 | |||
123 | #define GAM_ECOCHK 0x4090 | ||
124 | #define ECOCHK_SNB_BIT (1<<10) | ||
125 | #define ECOCHK_PPGTT_CACHE64B (0x3<<3) | ||
126 | #define ECOCHK_PPGTT_CACHE4B (0x0<<3) | ||
127 | |||
95 | /* VGA stuff */ | 128 | /* VGA stuff */ |
96 | 129 | ||
97 | #define VGA_ST01_MDA 0x3ba | 130 | #define VGA_ST01_MDA 0x3ba |
@@ -295,6 +328,12 @@ | |||
295 | #define FENCE_REG_SANDYBRIDGE_0 0x100000 | 328 | #define FENCE_REG_SANDYBRIDGE_0 0x100000 |
296 | #define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 | 329 | #define SANDYBRIDGE_FENCE_PITCH_SHIFT 32 |
297 | 330 | ||
331 | /* control register for cpu gtt access */ | ||
332 | #define TILECTL 0x101000 | ||
333 | #define TILECTL_SWZCTL (1 << 0) | ||
334 | #define TILECTL_TLB_PREFETCH_DIS (1 << 2) | ||
335 | #define TILECTL_BACKSNOOP_DIS (1 << 3) | ||
336 | |||
298 | /* | 337 | /* |
299 | * Instruction and interrupt control regs | 338 | * Instruction and interrupt control regs |
300 | */ | 339 | */ |
@@ -318,7 +357,14 @@ | |||
318 | #define RING_MAX_IDLE(base) ((base)+0x54) | 357 | #define RING_MAX_IDLE(base) ((base)+0x54) |
319 | #define RING_HWS_PGA(base) ((base)+0x80) | 358 | #define RING_HWS_PGA(base) ((base)+0x80) |
320 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) | 359 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) |
360 | #define ARB_MODE 0x04030 | ||
361 | #define ARB_MODE_SWIZZLE_SNB (1<<4) | ||
362 | #define ARB_MODE_SWIZZLE_IVB (1<<5) | ||
363 | #define ARB_MODE_ENABLE(x) GFX_MODE_ENABLE(x) | ||
364 | #define ARB_MODE_DISABLE(x) GFX_MODE_DISABLE(x) | ||
321 | #define RENDER_HWS_PGA_GEN7 (0x04080) | 365 | #define RENDER_HWS_PGA_GEN7 (0x04080) |
366 | #define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) | ||
367 | #define DONE_REG 0x40b0 | ||
322 | #define BSD_HWS_PGA_GEN7 (0x04180) | 368 | #define BSD_HWS_PGA_GEN7 (0x04180) |
323 | #define BLT_HWS_PGA_GEN7 (0x04280) | 369 | #define BLT_HWS_PGA_GEN7 (0x04280) |
324 | #define RING_ACTHD(base) ((base)+0x74) | 370 | #define RING_ACTHD(base) ((base)+0x74) |
@@ -352,6 +398,12 @@ | |||
352 | #define IPEIR_I965 0x02064 | 398 | #define IPEIR_I965 0x02064 |
353 | #define IPEHR_I965 0x02068 | 399 | #define IPEHR_I965 0x02068 |
354 | #define INSTDONE_I965 0x0206c | 400 | #define INSTDONE_I965 0x0206c |
401 | #define RING_IPEIR(base) ((base)+0x64) | ||
402 | #define RING_IPEHR(base) ((base)+0x68) | ||
403 | #define RING_INSTDONE(base) ((base)+0x6c) | ||
404 | #define RING_INSTPS(base) ((base)+0x70) | ||
405 | #define RING_DMA_FADD(base) ((base)+0x78) | ||
406 | #define RING_INSTPM(base) ((base)+0xc0) | ||
355 | #define INSTPS 0x02070 /* 965+ only */ | 407 | #define INSTPS 0x02070 /* 965+ only */ |
356 | #define INSTDONE1 0x0207c /* 965+ only */ | 408 | #define INSTDONE1 0x0207c /* 965+ only */ |
357 | #define ACTHD_I965 0x02074 | 409 | #define ACTHD_I965 0x02074 |
@@ -365,14 +417,6 @@ | |||
365 | #define INSTDONE 0x02090 | 417 | #define INSTDONE 0x02090 |
366 | #define NOPID 0x02094 | 418 | #define NOPID 0x02094 |
367 | #define HWSTAM 0x02098 | 419 | #define HWSTAM 0x02098 |
368 | #define VCS_INSTDONE 0x1206C | ||
369 | #define VCS_IPEIR 0x12064 | ||
370 | #define VCS_IPEHR 0x12068 | ||
371 | #define VCS_ACTHD 0x12074 | ||
372 | #define BCS_INSTDONE 0x2206C | ||
373 | #define BCS_IPEIR 0x22064 | ||
374 | #define BCS_IPEHR 0x22068 | ||
375 | #define BCS_ACTHD 0x22074 | ||
376 | 420 | ||
377 | #define ERROR_GEN6 0x040a0 | 421 | #define ERROR_GEN6 0x040a0 |
378 | 422 | ||
@@ -391,10 +435,11 @@ | |||
391 | 435 | ||
392 | #define MI_MODE 0x0209c | 436 | #define MI_MODE 0x0209c |
393 | # define VS_TIMER_DISPATCH (1 << 6) | 437 | # define VS_TIMER_DISPATCH (1 << 6) |
394 | # define MI_FLUSH_ENABLE (1 << 11) | 438 | # define MI_FLUSH_ENABLE (1 << 12) |
395 | 439 | ||
396 | #define GFX_MODE 0x02520 | 440 | #define GFX_MODE 0x02520 |
397 | #define GFX_MODE_GEN7 0x0229c | 441 | #define GFX_MODE_GEN7 0x0229c |
442 | #define RING_MODE_GEN7(ring) ((ring)->mmio_base+0x29c) | ||
398 | #define GFX_RUN_LIST_ENABLE (1<<15) | 443 | #define GFX_RUN_LIST_ENABLE (1<<15) |
399 | #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) | 444 | #define GFX_TLB_INVALIDATE_ALWAYS (1<<13) |
400 | #define GFX_SURFACE_FAULT_ENABLE (1<<12) | 445 | #define GFX_SURFACE_FAULT_ENABLE (1<<12) |
@@ -1037,6 +1082,29 @@ | |||
1037 | #define C0DRB3 0x10206 | 1082 | #define C0DRB3 0x10206 |
1038 | #define C1DRB3 0x10606 | 1083 | #define C1DRB3 0x10606 |
1039 | 1084 | ||
1085 | /** snb MCH registers for reading the DRAM channel configuration */ | ||
1086 | #define MAD_DIMM_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5004) | ||
1087 | #define MAD_DIMM_C1 (MCHBAR_MIRROR_BASE_SNB + 0x5008) | ||
1088 | #define MAD_DIMM_C2 (MCHBAR_MIRROR_BASE_SNB + 0x500C) | ||
1089 | #define MAD_DIMM_ECC_MASK (0x3 << 24) | ||
1090 | #define MAD_DIMM_ECC_OFF (0x0 << 24) | ||
1091 | #define MAD_DIMM_ECC_IO_ON_LOGIC_OFF (0x1 << 24) | ||
1092 | #define MAD_DIMM_ECC_IO_OFF_LOGIC_ON (0x2 << 24) | ||
1093 | #define MAD_DIMM_ECC_ON (0x3 << 24) | ||
1094 | #define MAD_DIMM_ENH_INTERLEAVE (0x1 << 22) | ||
1095 | #define MAD_DIMM_RANK_INTERLEAVE (0x1 << 21) | ||
1096 | #define MAD_DIMM_B_WIDTH_X16 (0x1 << 20) /* X8 chips if unset */ | ||
1097 | #define MAD_DIMM_A_WIDTH_X16 (0x1 << 19) /* X8 chips if unset */ | ||
1098 | #define MAD_DIMM_B_DUAL_RANK (0x1 << 18) | ||
1099 | #define MAD_DIMM_A_DUAL_RANK (0x1 << 17) | ||
1100 | #define MAD_DIMM_A_SELECT (0x1 << 16) | ||
1101 | /* DIMM sizes are in multiples of 256mb. */ | ||
1102 | #define MAD_DIMM_B_SIZE_SHIFT 8 | ||
1103 | #define MAD_DIMM_B_SIZE_MASK (0xff << MAD_DIMM_B_SIZE_SHIFT) | ||
1104 | #define MAD_DIMM_A_SIZE_SHIFT 0 | ||
1105 | #define MAD_DIMM_A_SIZE_MASK (0xff << MAD_DIMM_A_SIZE_SHIFT) | ||
1106 | |||
1107 | |||
1040 | /* Clocking configuration register */ | 1108 | /* Clocking configuration register */ |
1041 | #define CLKCFG 0x10c00 | 1109 | #define CLKCFG 0x10c00 |
1042 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ | 1110 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ |
@@ -3742,4 +3810,16 @@ | |||
3742 | */ | 3810 | */ |
3743 | #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) | 3811 | #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) |
3744 | 3812 | ||
3813 | #define IBX_AUD_CONFIG_A 0xe2000 | ||
3814 | #define CPT_AUD_CONFIG_A 0xe5000 | ||
3815 | #define AUD_CONFIG_N_VALUE_INDEX (1 << 29) | ||
3816 | #define AUD_CONFIG_N_PROG_ENABLE (1 << 28) | ||
3817 | #define AUD_CONFIG_UPPER_N_SHIFT 20 | ||
3818 | #define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) | ||
3819 | #define AUD_CONFIG_LOWER_N_SHIFT 4 | ||
3820 | #define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) | ||
3821 | #define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16 | ||
3822 | #define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16) | ||
3823 | #define AUD_CONFIG_DISABLE_NCTS (1 << 3) | ||
3824 | |||
3745 | #endif /* _I915_REG_H_ */ | 3825 | #endif /* _I915_REG_H_ */ |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index cb912106d1a2..bae3edf956a4 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -208,7 +208,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev) | |||
208 | 208 | ||
209 | ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); | 209 | ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); |
210 | if (ret < 0) { | 210 | if (ret < 0) { |
211 | DRM_ERROR("failed to get supported _DSM functions\n"); | 211 | DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); |
212 | return false; | 212 | return false; |
213 | } | 213 | } |
214 | 214 | ||
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 63880e2e5cfd..50656339d922 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -572,7 +572,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, | |||
572 | DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); | 572 | DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); |
573 | return; | 573 | return; |
574 | } | 574 | } |
575 | dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); | 575 | dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); |
576 | if (!dev_priv->child_dev) { | 576 | if (!dev_priv->child_dev) { |
577 | DRM_DEBUG_KMS("No memory space for child device\n"); | 577 | DRM_DEBUG_KMS("No memory space for child device\n"); |
578 | return; | 578 | return; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 00fbff5ddd81..efe56a2c4f4b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -75,7 +75,7 @@ struct intel_limit { | |||
75 | intel_range_t dot, vco, n, m, m1, m2, p, p1; | 75 | intel_range_t dot, vco, n, m, m1, m2, p, p1; |
76 | intel_p2_t p2; | 76 | intel_p2_t p2; |
77 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, | 77 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
78 | int, int, intel_clock_t *); | 78 | int, int, intel_clock_t *, intel_clock_t *); |
79 | }; | 79 | }; |
80 | 80 | ||
81 | /* FDI */ | 81 | /* FDI */ |
@@ -83,17 +83,21 @@ struct intel_limit { | |||
83 | 83 | ||
84 | static bool | 84 | static bool |
85 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 85 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
86 | int target, int refclk, intel_clock_t *best_clock); | 86 | int target, int refclk, intel_clock_t *match_clock, |
87 | intel_clock_t *best_clock); | ||
87 | static bool | 88 | static bool |
88 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 89 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
89 | int target, int refclk, intel_clock_t *best_clock); | 90 | int target, int refclk, intel_clock_t *match_clock, |
91 | intel_clock_t *best_clock); | ||
90 | 92 | ||
91 | static bool | 93 | static bool |
92 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | 94 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
93 | int target, int refclk, intel_clock_t *best_clock); | 95 | int target, int refclk, intel_clock_t *match_clock, |
96 | intel_clock_t *best_clock); | ||
94 | static bool | 97 | static bool |
95 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, | 98 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, |
96 | int target, int refclk, intel_clock_t *best_clock); | 99 | int target, int refclk, intel_clock_t *match_clock, |
100 | intel_clock_t *best_clock); | ||
97 | 101 | ||
98 | static inline u32 /* units of 100MHz */ | 102 | static inline u32 /* units of 100MHz */ |
99 | intel_fdi_link_freq(struct drm_device *dev) | 103 | intel_fdi_link_freq(struct drm_device *dev) |
@@ -515,7 +519,8 @@ static bool intel_PLL_is_valid(struct drm_device *dev, | |||
515 | 519 | ||
516 | static bool | 520 | static bool |
517 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 521 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
518 | int target, int refclk, intel_clock_t *best_clock) | 522 | int target, int refclk, intel_clock_t *match_clock, |
523 | intel_clock_t *best_clock) | ||
519 | 524 | ||
520 | { | 525 | { |
521 | struct drm_device *dev = crtc->dev; | 526 | struct drm_device *dev = crtc->dev; |
@@ -562,6 +567,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
562 | if (!intel_PLL_is_valid(dev, limit, | 567 | if (!intel_PLL_is_valid(dev, limit, |
563 | &clock)) | 568 | &clock)) |
564 | continue; | 569 | continue; |
570 | if (match_clock && | ||
571 | clock.p != match_clock->p) | ||
572 | continue; | ||
565 | 573 | ||
566 | this_err = abs(clock.dot - target); | 574 | this_err = abs(clock.dot - target); |
567 | if (this_err < err) { | 575 | if (this_err < err) { |
@@ -578,7 +586,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
578 | 586 | ||
579 | static bool | 587 | static bool |
580 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 588 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
581 | int target, int refclk, intel_clock_t *best_clock) | 589 | int target, int refclk, intel_clock_t *match_clock, |
590 | intel_clock_t *best_clock) | ||
582 | { | 591 | { |
583 | struct drm_device *dev = crtc->dev; | 592 | struct drm_device *dev = crtc->dev; |
584 | struct drm_i915_private *dev_priv = dev->dev_private; | 593 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -625,6 +634,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
625 | if (!intel_PLL_is_valid(dev, limit, | 634 | if (!intel_PLL_is_valid(dev, limit, |
626 | &clock)) | 635 | &clock)) |
627 | continue; | 636 | continue; |
637 | if (match_clock && | ||
638 | clock.p != match_clock->p) | ||
639 | continue; | ||
628 | 640 | ||
629 | this_err = abs(clock.dot - target); | 641 | this_err = abs(clock.dot - target); |
630 | if (this_err < err_most) { | 642 | if (this_err < err_most) { |
@@ -642,7 +654,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
642 | 654 | ||
643 | static bool | 655 | static bool |
644 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | 656 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
645 | int target, int refclk, intel_clock_t *best_clock) | 657 | int target, int refclk, intel_clock_t *match_clock, |
658 | intel_clock_t *best_clock) | ||
646 | { | 659 | { |
647 | struct drm_device *dev = crtc->dev; | 660 | struct drm_device *dev = crtc->dev; |
648 | intel_clock_t clock; | 661 | intel_clock_t clock; |
@@ -668,7 +681,8 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
668 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | 681 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
669 | static bool | 682 | static bool |
670 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | 683 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
671 | int target, int refclk, intel_clock_t *best_clock) | 684 | int target, int refclk, intel_clock_t *match_clock, |
685 | intel_clock_t *best_clock) | ||
672 | { | 686 | { |
673 | intel_clock_t clock; | 687 | intel_clock_t clock; |
674 | if (target < 200000) { | 688 | if (target < 200000) { |
@@ -922,6 +936,10 @@ void assert_pipe(struct drm_i915_private *dev_priv, | |||
922 | u32 val; | 936 | u32 val; |
923 | bool cur_state; | 937 | bool cur_state; |
924 | 938 | ||
939 | /* if we need the pipe A quirk it must be always on */ | ||
940 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) | ||
941 | state = true; | ||
942 | |||
925 | reg = PIPECONF(pipe); | 943 | reg = PIPECONF(pipe); |
926 | val = I915_READ(reg); | 944 | val = I915_READ(reg); |
927 | cur_state = !!(val & PIPECONF_ENABLE); | 945 | cur_state = !!(val & PIPECONF_ENABLE); |
@@ -930,19 +948,24 @@ void assert_pipe(struct drm_i915_private *dev_priv, | |||
930 | pipe_name(pipe), state_string(state), state_string(cur_state)); | 948 | pipe_name(pipe), state_string(state), state_string(cur_state)); |
931 | } | 949 | } |
932 | 950 | ||
933 | static void assert_plane_enabled(struct drm_i915_private *dev_priv, | 951 | static void assert_plane(struct drm_i915_private *dev_priv, |
934 | enum plane plane) | 952 | enum plane plane, bool state) |
935 | { | 953 | { |
936 | int reg; | 954 | int reg; |
937 | u32 val; | 955 | u32 val; |
956 | bool cur_state; | ||
938 | 957 | ||
939 | reg = DSPCNTR(plane); | 958 | reg = DSPCNTR(plane); |
940 | val = I915_READ(reg); | 959 | val = I915_READ(reg); |
941 | WARN(!(val & DISPLAY_PLANE_ENABLE), | 960 | cur_state = !!(val & DISPLAY_PLANE_ENABLE); |
942 | "plane %c assertion failure, should be active but is disabled\n", | 961 | WARN(cur_state != state, |
943 | plane_name(plane)); | 962 | "plane %c assertion failure (expected %s, current %s)\n", |
963 | plane_name(plane), state_string(state), state_string(cur_state)); | ||
944 | } | 964 | } |
945 | 965 | ||
966 | #define assert_plane_enabled(d, p) assert_plane(d, p, true) | ||
967 | #define assert_plane_disabled(d, p) assert_plane(d, p, false) | ||
968 | |||
946 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, | 969 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, |
947 | enum pipe pipe) | 970 | enum pipe pipe) |
948 | { | 971 | { |
@@ -951,8 +974,14 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, | |||
951 | int cur_pipe; | 974 | int cur_pipe; |
952 | 975 | ||
953 | /* Planes are fixed to pipes on ILK+ */ | 976 | /* Planes are fixed to pipes on ILK+ */ |
954 | if (HAS_PCH_SPLIT(dev_priv->dev)) | 977 | if (HAS_PCH_SPLIT(dev_priv->dev)) { |
978 | reg = DSPCNTR(pipe); | ||
979 | val = I915_READ(reg); | ||
980 | WARN((val & DISPLAY_PLANE_ENABLE), | ||
981 | "plane %c assertion failure, should be disabled but not\n", | ||
982 | plane_name(pipe)); | ||
955 | return; | 983 | return; |
984 | } | ||
956 | 985 | ||
957 | /* Need to check both planes against the pipe */ | 986 | /* Need to check both planes against the pipe */ |
958 | for (i = 0; i < 2; i++) { | 987 | for (i = 0; i < 2; i++) { |
@@ -1071,7 +1100,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1071 | { | 1100 | { |
1072 | u32 val = I915_READ(reg); | 1101 | u32 val = I915_READ(reg); |
1073 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1102 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), |
1074 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1103 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1075 | reg, pipe_name(pipe)); | 1104 | reg, pipe_name(pipe)); |
1076 | } | 1105 | } |
1077 | 1106 | ||
@@ -2012,6 +2041,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
2012 | ret = i915_gem_object_get_fence(obj, pipelined); | 2041 | ret = i915_gem_object_get_fence(obj, pipelined); |
2013 | if (ret) | 2042 | if (ret) |
2014 | goto err_unpin; | 2043 | goto err_unpin; |
2044 | |||
2045 | i915_gem_object_pin_fence(obj); | ||
2015 | } | 2046 | } |
2016 | 2047 | ||
2017 | dev_priv->mm.interruptible = true; | 2048 | dev_priv->mm.interruptible = true; |
@@ -2024,6 +2055,12 @@ err_interruptible: | |||
2024 | return ret; | 2055 | return ret; |
2025 | } | 2056 | } |
2026 | 2057 | ||
2058 | void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) | ||
2059 | { | ||
2060 | i915_gem_object_unpin_fence(obj); | ||
2061 | i915_gem_object_unpin(obj); | ||
2062 | } | ||
2063 | |||
2027 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 2064 | static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
2028 | int x, int y) | 2065 | int x, int y) |
2029 | { | 2066 | { |
@@ -2255,7 +2292,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2255 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, | 2292 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, |
2256 | LEAVE_ATOMIC_MODE_SET); | 2293 | LEAVE_ATOMIC_MODE_SET); |
2257 | if (ret) { | 2294 | if (ret) { |
2258 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 2295 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
2259 | mutex_unlock(&dev->struct_mutex); | 2296 | mutex_unlock(&dev->struct_mutex); |
2260 | DRM_ERROR("failed to update base address\n"); | 2297 | DRM_ERROR("failed to update base address\n"); |
2261 | return ret; | 2298 | return ret; |
@@ -2263,7 +2300,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
2263 | 2300 | ||
2264 | if (old_fb) { | 2301 | if (old_fb) { |
2265 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 2302 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
2266 | i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); | 2303 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); |
2267 | } | 2304 | } |
2268 | 2305 | ||
2269 | mutex_unlock(&dev->struct_mutex); | 2306 | mutex_unlock(&dev->struct_mutex); |
@@ -3321,10 +3358,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
3321 | struct drm_device *dev = crtc->dev; | 3358 | struct drm_device *dev = crtc->dev; |
3322 | 3359 | ||
3323 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 3360 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
3361 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); | ||
3362 | assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); | ||
3324 | 3363 | ||
3325 | if (crtc->fb) { | 3364 | if (crtc->fb) { |
3326 | mutex_lock(&dev->struct_mutex); | 3365 | mutex_lock(&dev->struct_mutex); |
3327 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 3366 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
3328 | mutex_unlock(&dev->struct_mutex); | 3367 | mutex_unlock(&dev->struct_mutex); |
3329 | } | 3368 | } |
3330 | } | 3369 | } |
@@ -4521,6 +4560,7 @@ void sandybridge_update_wm(struct drm_device *dev) | |||
4521 | { | 4560 | { |
4522 | struct drm_i915_private *dev_priv = dev->dev_private; | 4561 | struct drm_i915_private *dev_priv = dev->dev_private; |
4523 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | 4562 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
4563 | u32 val; | ||
4524 | int fbc_wm, plane_wm, cursor_wm; | 4564 | int fbc_wm, plane_wm, cursor_wm; |
4525 | unsigned int enabled; | 4565 | unsigned int enabled; |
4526 | 4566 | ||
@@ -4529,8 +4569,10 @@ void sandybridge_update_wm(struct drm_device *dev) | |||
4529 | &sandybridge_display_wm_info, latency, | 4569 | &sandybridge_display_wm_info, latency, |
4530 | &sandybridge_cursor_wm_info, latency, | 4570 | &sandybridge_cursor_wm_info, latency, |
4531 | &plane_wm, &cursor_wm)) { | 4571 | &plane_wm, &cursor_wm)) { |
4532 | I915_WRITE(WM0_PIPEA_ILK, | 4572 | val = I915_READ(WM0_PIPEA_ILK); |
4533 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 4573 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); |
4574 | I915_WRITE(WM0_PIPEA_ILK, val | | ||
4575 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4534 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" | 4576 | DRM_DEBUG_KMS("FIFO watermarks For pipe A -" |
4535 | " plane %d, " "cursor: %d\n", | 4577 | " plane %d, " "cursor: %d\n", |
4536 | plane_wm, cursor_wm); | 4578 | plane_wm, cursor_wm); |
@@ -4541,8 +4583,10 @@ void sandybridge_update_wm(struct drm_device *dev) | |||
4541 | &sandybridge_display_wm_info, latency, | 4583 | &sandybridge_display_wm_info, latency, |
4542 | &sandybridge_cursor_wm_info, latency, | 4584 | &sandybridge_cursor_wm_info, latency, |
4543 | &plane_wm, &cursor_wm)) { | 4585 | &plane_wm, &cursor_wm)) { |
4544 | I915_WRITE(WM0_PIPEB_ILK, | 4586 | val = I915_READ(WM0_PIPEB_ILK); |
4545 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 4587 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); |
4588 | I915_WRITE(WM0_PIPEB_ILK, val | | ||
4589 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4546 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" | 4590 | DRM_DEBUG_KMS("FIFO watermarks For pipe B -" |
4547 | " plane %d, cursor: %d\n", | 4591 | " plane %d, cursor: %d\n", |
4548 | plane_wm, cursor_wm); | 4592 | plane_wm, cursor_wm); |
@@ -4555,8 +4599,10 @@ void sandybridge_update_wm(struct drm_device *dev) | |||
4555 | &sandybridge_display_wm_info, latency, | 4599 | &sandybridge_display_wm_info, latency, |
4556 | &sandybridge_cursor_wm_info, latency, | 4600 | &sandybridge_cursor_wm_info, latency, |
4557 | &plane_wm, &cursor_wm)) { | 4601 | &plane_wm, &cursor_wm)) { |
4558 | I915_WRITE(WM0_PIPEC_IVB, | 4602 | val = I915_READ(WM0_PIPEC_IVB); |
4559 | (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); | 4603 | val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); |
4604 | I915_WRITE(WM0_PIPEC_IVB, val | | ||
4605 | ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); | ||
4560 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" | 4606 | DRM_DEBUG_KMS("FIFO watermarks For pipe C -" |
4561 | " plane %d, cursor: %d\n", | 4607 | " plane %d, cursor: %d\n", |
4562 | plane_wm, cursor_wm); | 4608 | plane_wm, cursor_wm); |
@@ -4700,6 +4746,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, | |||
4700 | { | 4746 | { |
4701 | struct drm_i915_private *dev_priv = dev->dev_private; | 4747 | struct drm_i915_private *dev_priv = dev->dev_private; |
4702 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ | 4748 | int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ |
4749 | u32 val; | ||
4703 | int sprite_wm, reg; | 4750 | int sprite_wm, reg; |
4704 | int ret; | 4751 | int ret; |
4705 | 4752 | ||
@@ -4726,7 +4773,9 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, | |||
4726 | return; | 4773 | return; |
4727 | } | 4774 | } |
4728 | 4775 | ||
4729 | I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); | 4776 | val = I915_READ(reg); |
4777 | val &= ~WM0_PIPE_SPRITE_MASK; | ||
4778 | I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); | ||
4730 | DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); | 4779 | DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); |
4731 | 4780 | ||
4732 | 4781 | ||
@@ -4968,6 +5017,82 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4968 | return display_bpc != bpc; | 5017 | return display_bpc != bpc; |
4969 | } | 5018 | } |
4970 | 5019 | ||
5020 | static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) | ||
5021 | { | ||
5022 | struct drm_device *dev = crtc->dev; | ||
5023 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5024 | int refclk; | ||
5025 | |||
5026 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | ||
5027 | intel_panel_use_ssc(dev_priv) && num_connectors < 2) { | ||
5028 | refclk = dev_priv->lvds_ssc_freq * 1000; | ||
5029 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | ||
5030 | refclk / 1000); | ||
5031 | } else if (!IS_GEN2(dev)) { | ||
5032 | refclk = 96000; | ||
5033 | } else { | ||
5034 | refclk = 48000; | ||
5035 | } | ||
5036 | |||
5037 | return refclk; | ||
5038 | } | ||
5039 | |||
5040 | static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, | ||
5041 | intel_clock_t *clock) | ||
5042 | { | ||
5043 | /* SDVO TV has fixed PLL values depend on its clock range, | ||
5044 | this mirrors vbios setting. */ | ||
5045 | if (adjusted_mode->clock >= 100000 | ||
5046 | && adjusted_mode->clock < 140500) { | ||
5047 | clock->p1 = 2; | ||
5048 | clock->p2 = 10; | ||
5049 | clock->n = 3; | ||
5050 | clock->m1 = 16; | ||
5051 | clock->m2 = 8; | ||
5052 | } else if (adjusted_mode->clock >= 140500 | ||
5053 | && adjusted_mode->clock <= 200000) { | ||
5054 | clock->p1 = 1; | ||
5055 | clock->p2 = 10; | ||
5056 | clock->n = 6; | ||
5057 | clock->m1 = 12; | ||
5058 | clock->m2 = 8; | ||
5059 | } | ||
5060 | } | ||
5061 | |||
5062 | static void i9xx_update_pll_dividers(struct drm_crtc *crtc, | ||
5063 | intel_clock_t *clock, | ||
5064 | intel_clock_t *reduced_clock) | ||
5065 | { | ||
5066 | struct drm_device *dev = crtc->dev; | ||
5067 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5068 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
5069 | int pipe = intel_crtc->pipe; | ||
5070 | u32 fp, fp2 = 0; | ||
5071 | |||
5072 | if (IS_PINEVIEW(dev)) { | ||
5073 | fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; | ||
5074 | if (reduced_clock) | ||
5075 | fp2 = (1 << reduced_clock->n) << 16 | | ||
5076 | reduced_clock->m1 << 8 | reduced_clock->m2; | ||
5077 | } else { | ||
5078 | fp = clock->n << 16 | clock->m1 << 8 | clock->m2; | ||
5079 | if (reduced_clock) | ||
5080 | fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | | ||
5081 | reduced_clock->m2; | ||
5082 | } | ||
5083 | |||
5084 | I915_WRITE(FP0(pipe), fp); | ||
5085 | |||
5086 | intel_crtc->lowfreq_avail = false; | ||
5087 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | ||
5088 | reduced_clock && i915_powersave) { | ||
5089 | I915_WRITE(FP1(pipe), fp2); | ||
5090 | intel_crtc->lowfreq_avail = true; | ||
5091 | } else { | ||
5092 | I915_WRITE(FP1(pipe), fp); | ||
5093 | } | ||
5094 | } | ||
5095 | |||
4971 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | 5096 | static int i9xx_crtc_mode_set(struct drm_crtc *crtc, |
4972 | struct drm_display_mode *mode, | 5097 | struct drm_display_mode *mode, |
4973 | struct drm_display_mode *adjusted_mode, | 5098 | struct drm_display_mode *adjusted_mode, |
@@ -4981,7 +5106,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
4981 | int plane = intel_crtc->plane; | 5106 | int plane = intel_crtc->plane; |
4982 | int refclk, num_connectors = 0; | 5107 | int refclk, num_connectors = 0; |
4983 | intel_clock_t clock, reduced_clock; | 5108 | intel_clock_t clock, reduced_clock; |
4984 | u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; | 5109 | u32 dpll, dspcntr, pipeconf; |
4985 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; | 5110 | bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; |
4986 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; | 5111 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
4987 | struct drm_mode_config *mode_config = &dev->mode_config; | 5112 | struct drm_mode_config *mode_config = &dev->mode_config; |
@@ -5022,15 +5147,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5022 | num_connectors++; | 5147 | num_connectors++; |
5023 | } | 5148 | } |
5024 | 5149 | ||
5025 | if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { | 5150 | refclk = i9xx_get_refclk(crtc, num_connectors); |
5026 | refclk = dev_priv->lvds_ssc_freq * 1000; | ||
5027 | DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", | ||
5028 | refclk / 1000); | ||
5029 | } else if (!IS_GEN2(dev)) { | ||
5030 | refclk = 96000; | ||
5031 | } else { | ||
5032 | refclk = 48000; | ||
5033 | } | ||
5034 | 5151 | ||
5035 | /* | 5152 | /* |
5036 | * Returns a set of divisors for the desired target clock with the given | 5153 | * Returns a set of divisors for the desired target clock with the given |
@@ -5038,7 +5155,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5038 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. | 5155 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
5039 | */ | 5156 | */ |
5040 | limit = intel_limit(crtc, refclk); | 5157 | limit = intel_limit(crtc, refclk); |
5041 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); | 5158 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, |
5159 | &clock); | ||
5042 | if (!ok) { | 5160 | if (!ok) { |
5043 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); | 5161 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
5044 | return -EINVAL; | 5162 | return -EINVAL; |
@@ -5048,53 +5166,24 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5048 | intel_crtc_update_cursor(crtc, true); | 5166 | intel_crtc_update_cursor(crtc, true); |
5049 | 5167 | ||
5050 | if (is_lvds && dev_priv->lvds_downclock_avail) { | 5168 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
5169 | /* | ||
5170 | * Ensure we match the reduced clock's P to the target clock. | ||
5171 | * If the clocks don't match, we can't switch the display clock | ||
5172 | * by using the FP0/FP1. In such case we will disable the LVDS | ||
5173 | * downclock feature. | ||
5174 | */ | ||
5051 | has_reduced_clock = limit->find_pll(limit, crtc, | 5175 | has_reduced_clock = limit->find_pll(limit, crtc, |
5052 | dev_priv->lvds_downclock, | 5176 | dev_priv->lvds_downclock, |
5053 | refclk, | 5177 | refclk, |
5178 | &clock, | ||
5054 | &reduced_clock); | 5179 | &reduced_clock); |
5055 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { | ||
5056 | /* | ||
5057 | * If the different P is found, it means that we can't | ||
5058 | * switch the display clock by using the FP0/FP1. | ||
5059 | * In such case we will disable the LVDS downclock | ||
5060 | * feature. | ||
5061 | */ | ||
5062 | DRM_DEBUG_KMS("Different P is found for " | ||
5063 | "LVDS clock/downclock\n"); | ||
5064 | has_reduced_clock = 0; | ||
5065 | } | ||
5066 | } | ||
5067 | /* SDVO TV has fixed PLL values depend on its clock range, | ||
5068 | this mirrors vbios setting. */ | ||
5069 | if (is_sdvo && is_tv) { | ||
5070 | if (adjusted_mode->clock >= 100000 | ||
5071 | && adjusted_mode->clock < 140500) { | ||
5072 | clock.p1 = 2; | ||
5073 | clock.p2 = 10; | ||
5074 | clock.n = 3; | ||
5075 | clock.m1 = 16; | ||
5076 | clock.m2 = 8; | ||
5077 | } else if (adjusted_mode->clock >= 140500 | ||
5078 | && adjusted_mode->clock <= 200000) { | ||
5079 | clock.p1 = 1; | ||
5080 | clock.p2 = 10; | ||
5081 | clock.n = 6; | ||
5082 | clock.m1 = 12; | ||
5083 | clock.m2 = 8; | ||
5084 | } | ||
5085 | } | 5180 | } |
5086 | 5181 | ||
5087 | if (IS_PINEVIEW(dev)) { | 5182 | if (is_sdvo && is_tv) |
5088 | fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; | 5183 | i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); |
5089 | if (has_reduced_clock) | 5184 | |
5090 | fp2 = (1 << reduced_clock.n) << 16 | | 5185 | i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ? |
5091 | reduced_clock.m1 << 8 | reduced_clock.m2; | 5186 | &reduced_clock : NULL); |
5092 | } else { | ||
5093 | fp = clock.n << 16 | clock.m1 << 8 | clock.m2; | ||
5094 | if (has_reduced_clock) | ||
5095 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | | ||
5096 | reduced_clock.m2; | ||
5097 | } | ||
5098 | 5187 | ||
5099 | dpll = DPLL_VGA_MODE_DIS; | 5188 | dpll = DPLL_VGA_MODE_DIS; |
5100 | 5189 | ||
@@ -5168,8 +5257,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5168 | /* Set up the display plane register */ | 5257 | /* Set up the display plane register */ |
5169 | dspcntr = DISPPLANE_GAMMA_ENABLE; | 5258 | dspcntr = DISPPLANE_GAMMA_ENABLE; |
5170 | 5259 | ||
5171 | /* Ironlake's plane is forced to pipe, bit 24 is to | ||
5172 | enable color space conversion */ | ||
5173 | if (pipe == 0) | 5260 | if (pipe == 0) |
5174 | dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; | 5261 | dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; |
5175 | else | 5262 | else |
@@ -5204,7 +5291,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5204 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); | 5291 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); |
5205 | drm_mode_debug_printmodeline(mode); | 5292 | drm_mode_debug_printmodeline(mode); |
5206 | 5293 | ||
5207 | I915_WRITE(FP0(pipe), fp); | ||
5208 | I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); | 5294 | I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); |
5209 | 5295 | ||
5210 | POSTING_READ(DPLL(pipe)); | 5296 | POSTING_READ(DPLL(pipe)); |
@@ -5291,17 +5377,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5291 | I915_WRITE(DPLL(pipe), dpll); | 5377 | I915_WRITE(DPLL(pipe), dpll); |
5292 | } | 5378 | } |
5293 | 5379 | ||
5294 | intel_crtc->lowfreq_avail = false; | 5380 | if (HAS_PIPE_CXSR(dev)) { |
5295 | if (is_lvds && has_reduced_clock && i915_powersave) { | 5381 | if (intel_crtc->lowfreq_avail) { |
5296 | I915_WRITE(FP1(pipe), fp2); | ||
5297 | intel_crtc->lowfreq_avail = true; | ||
5298 | if (HAS_PIPE_CXSR(dev)) { | ||
5299 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); | 5382 | DRM_DEBUG_KMS("enabling CxSR downclocking\n"); |
5300 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; | 5383 | pipeconf |= PIPECONF_CXSR_DOWNCLOCK; |
5301 | } | 5384 | } else { |
5302 | } else { | ||
5303 | I915_WRITE(FP1(pipe), fp); | ||
5304 | if (HAS_PIPE_CXSR(dev)) { | ||
5305 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); | 5385 | DRM_DEBUG_KMS("disabling CxSR downclocking\n"); |
5306 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; | 5386 | pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; |
5307 | } | 5387 | } |
@@ -5584,7 +5664,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5584 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. | 5664 | * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. |
5585 | */ | 5665 | */ |
5586 | limit = intel_limit(crtc, refclk); | 5666 | limit = intel_limit(crtc, refclk); |
5587 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); | 5667 | ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, |
5668 | &clock); | ||
5588 | if (!ok) { | 5669 | if (!ok) { |
5589 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); | 5670 | DRM_ERROR("Couldn't find PLL settings for mode!\n"); |
5590 | return -EINVAL; | 5671 | return -EINVAL; |
@@ -5594,21 +5675,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5594 | intel_crtc_update_cursor(crtc, true); | 5675 | intel_crtc_update_cursor(crtc, true); |
5595 | 5676 | ||
5596 | if (is_lvds && dev_priv->lvds_downclock_avail) { | 5677 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
5678 | /* | ||
5679 | * Ensure we match the reduced clock's P to the target clock. | ||
5680 | * If the clocks don't match, we can't switch the display clock | ||
5681 | * by using the FP0/FP1. In such case we will disable the LVDS | ||
5682 | * downclock feature. | ||
5683 | */ | ||
5597 | has_reduced_clock = limit->find_pll(limit, crtc, | 5684 | has_reduced_clock = limit->find_pll(limit, crtc, |
5598 | dev_priv->lvds_downclock, | 5685 | dev_priv->lvds_downclock, |
5599 | refclk, | 5686 | refclk, |
5687 | &clock, | ||
5600 | &reduced_clock); | 5688 | &reduced_clock); |
5601 | if (has_reduced_clock && (clock.p != reduced_clock.p)) { | ||
5602 | /* | ||
5603 | * If the different P is found, it means that we can't | ||
5604 | * switch the display clock by using the FP0/FP1. | ||
5605 | * In such case we will disable the LVDS downclock | ||
5606 | * feature. | ||
5607 | */ | ||
5608 | DRM_DEBUG_KMS("Different P is found for " | ||
5609 | "LVDS clock/downclock\n"); | ||
5610 | has_reduced_clock = 0; | ||
5611 | } | ||
5612 | } | 5689 | } |
5613 | /* SDVO TV has fixed PLL values depend on its clock range, | 5690 | /* SDVO TV has fixed PLL values depend on its clock range, |
5614 | this mirrors vbios setting. */ | 5691 | this mirrors vbios setting. */ |
@@ -5957,12 +6034,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5957 | 6034 | ||
5958 | intel_wait_for_vblank(dev, pipe); | 6035 | intel_wait_for_vblank(dev, pipe); |
5959 | 6036 | ||
5960 | if (IS_GEN5(dev)) { | ||
5961 | /* enable address swizzle for tiling buffer */ | ||
5962 | temp = I915_READ(DISP_ARB_CTL); | ||
5963 | I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); | ||
5964 | } | ||
5965 | |||
5966 | I915_WRITE(DSPCNTR(plane), dspcntr); | 6037 | I915_WRITE(DSPCNTR(plane), dspcntr); |
5967 | POSTING_READ(DSPCNTR(plane)); | 6038 | POSTING_READ(DSPCNTR(plane)); |
5968 | 6039 | ||
@@ -6077,15 +6148,18 @@ static void ironlake_write_eld(struct drm_connector *connector, | |||
6077 | uint32_t i; | 6148 | uint32_t i; |
6078 | int len; | 6149 | int len; |
6079 | int hdmiw_hdmiedid; | 6150 | int hdmiw_hdmiedid; |
6151 | int aud_config; | ||
6080 | int aud_cntl_st; | 6152 | int aud_cntl_st; |
6081 | int aud_cntrl_st2; | 6153 | int aud_cntrl_st2; |
6082 | 6154 | ||
6083 | if (HAS_PCH_IBX(connector->dev)) { | 6155 | if (HAS_PCH_IBX(connector->dev)) { |
6084 | hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; | 6156 | hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; |
6157 | aud_config = IBX_AUD_CONFIG_A; | ||
6085 | aud_cntl_st = IBX_AUD_CNTL_ST_A; | 6158 | aud_cntl_st = IBX_AUD_CNTL_ST_A; |
6086 | aud_cntrl_st2 = IBX_AUD_CNTL_ST2; | 6159 | aud_cntrl_st2 = IBX_AUD_CNTL_ST2; |
6087 | } else { | 6160 | } else { |
6088 | hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; | 6161 | hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; |
6162 | aud_config = CPT_AUD_CONFIG_A; | ||
6089 | aud_cntl_st = CPT_AUD_CNTL_ST_A; | 6163 | aud_cntl_st = CPT_AUD_CNTL_ST_A; |
6090 | aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; | 6164 | aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; |
6091 | } | 6165 | } |
@@ -6093,6 +6167,7 @@ static void ironlake_write_eld(struct drm_connector *connector, | |||
6093 | i = to_intel_crtc(crtc)->pipe; | 6167 | i = to_intel_crtc(crtc)->pipe; |
6094 | hdmiw_hdmiedid += i * 0x100; | 6168 | hdmiw_hdmiedid += i * 0x100; |
6095 | aud_cntl_st += i * 0x100; | 6169 | aud_cntl_st += i * 0x100; |
6170 | aud_config += i * 0x100; | ||
6096 | 6171 | ||
6097 | DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); | 6172 | DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); |
6098 | 6173 | ||
@@ -6112,7 +6187,9 @@ static void ironlake_write_eld(struct drm_connector *connector, | |||
6112 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | 6187 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
6113 | DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); | 6188 | DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); |
6114 | eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ | 6189 | eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ |
6115 | } | 6190 | I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ |
6191 | } else | ||
6192 | I915_WRITE(aud_config, 0); | ||
6116 | 6193 | ||
6117 | if (intel_eld_uptodate(connector, | 6194 | if (intel_eld_uptodate(connector, |
6118 | aud_cntrl_st2, eldv, | 6195 | aud_cntrl_st2, eldv, |
@@ -7088,7 +7165,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
7088 | container_of(__work, struct intel_unpin_work, work); | 7165 | container_of(__work, struct intel_unpin_work, work); |
7089 | 7166 | ||
7090 | mutex_lock(&work->dev->struct_mutex); | 7167 | mutex_lock(&work->dev->struct_mutex); |
7091 | i915_gem_object_unpin(work->old_fb_obj); | 7168 | intel_unpin_fb_obj(work->old_fb_obj); |
7092 | drm_gem_object_unreference(&work->pending_flip_obj->base); | 7169 | drm_gem_object_unreference(&work->pending_flip_obj->base); |
7093 | drm_gem_object_unreference(&work->old_fb_obj->base); | 7170 | drm_gem_object_unreference(&work->old_fb_obj->base); |
7094 | 7171 | ||
@@ -7238,7 +7315,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, | |||
7238 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 7315 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
7239 | OUT_RING(fb->pitches[0]); | 7316 | OUT_RING(fb->pitches[0]); |
7240 | OUT_RING(obj->gtt_offset + offset); | 7317 | OUT_RING(obj->gtt_offset + offset); |
7241 | OUT_RING(MI_NOOP); | 7318 | OUT_RING(0); /* aux display base address, unused */ |
7242 | ADVANCE_LP_RING(); | 7319 | ADVANCE_LP_RING(); |
7243 | out: | 7320 | out: |
7244 | return ret; | 7321 | return ret; |
@@ -7830,7 +7907,8 @@ int intel_framebuffer_init(struct drm_device *dev, | |||
7830 | case DRM_FORMAT_VYUY: | 7907 | case DRM_FORMAT_VYUY: |
7831 | break; | 7908 | break; |
7832 | default: | 7909 | default: |
7833 | DRM_ERROR("unsupported pixel format\n"); | 7910 | DRM_DEBUG_KMS("unsupported pixel format %u\n", |
7911 | mode_cmd->pixel_format); | ||
7834 | return -EINVAL; | 7912 | return -EINVAL; |
7835 | } | 7913 | } |
7836 | 7914 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 94f860cce3f7..39eccf908a69 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -352,7 +352,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
352 | int recv_bytes; | 352 | int recv_bytes; |
353 | uint32_t status; | 353 | uint32_t status; |
354 | uint32_t aux_clock_divider; | 354 | uint32_t aux_clock_divider; |
355 | int try, precharge; | 355 | int try, precharge = 5; |
356 | 356 | ||
357 | intel_dp_check_edp(intel_dp); | 357 | intel_dp_check_edp(intel_dp); |
358 | /* The clock divider is based off the hrawclk, | 358 | /* The clock divider is based off the hrawclk, |
@@ -368,15 +368,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
368 | else | 368 | else |
369 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | 369 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ |
370 | } else if (HAS_PCH_SPLIT(dev)) | 370 | } else if (HAS_PCH_SPLIT(dev)) |
371 | aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ | 371 | aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */ |
372 | else | 372 | else |
373 | aux_clock_divider = intel_hrawclk(dev) / 2; | 373 | aux_clock_divider = intel_hrawclk(dev) / 2; |
374 | 374 | ||
375 | if (IS_GEN6(dev)) | ||
376 | precharge = 3; | ||
377 | else | ||
378 | precharge = 5; | ||
379 | |||
380 | /* Try to wait for any previous AUX channel activity */ | 375 | /* Try to wait for any previous AUX channel activity */ |
381 | for (try = 0; try < 3; try++) { | 376 | for (try = 0; try < 3; try++) { |
382 | status = I915_READ(ch_ctl); | 377 | status = I915_READ(ch_ctl); |
@@ -421,6 +416,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
421 | DP_AUX_CH_CTL_DONE | | 416 | DP_AUX_CH_CTL_DONE | |
422 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | 417 | DP_AUX_CH_CTL_TIME_OUT_ERROR | |
423 | DP_AUX_CH_CTL_RECEIVE_ERROR); | 418 | DP_AUX_CH_CTL_RECEIVE_ERROR); |
419 | |||
420 | if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
421 | DP_AUX_CH_CTL_RECEIVE_ERROR)) | ||
422 | continue; | ||
424 | if (status & DP_AUX_CH_CTL_DONE) | 423 | if (status & DP_AUX_CH_CTL_DONE) |
425 | break; | 424 | break; |
426 | } | 425 | } |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1348705faf6b..9cec6c3937fa 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -374,6 +374,7 @@ extern void intel_init_emon(struct drm_device *dev); | |||
374 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, | 374 | extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, |
375 | struct drm_i915_gem_object *obj, | 375 | struct drm_i915_gem_object *obj, |
376 | struct intel_ring_buffer *pipelined); | 376 | struct intel_ring_buffer *pipelined); |
377 | extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); | ||
377 | 378 | ||
378 | extern int intel_framebuffer_init(struct drm_device *dev, | 379 | extern int intel_framebuffer_init(struct drm_device *dev, |
379 | struct intel_framebuffer *ifb, | 380 | struct intel_framebuffer *ifb, |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index cdf17d4cc1f7..23a543cdfa99 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -227,7 +227,8 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, | |||
227 | } | 227 | } |
228 | overlay->last_flip_req = request->seqno; | 228 | overlay->last_flip_req = request->seqno; |
229 | overlay->flip_tail = tail; | 229 | overlay->flip_tail = tail; |
230 | ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); | 230 | ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, |
231 | true); | ||
231 | if (ret) | 232 | if (ret) |
232 | return ret; | 233 | return ret; |
233 | 234 | ||
@@ -448,7 +449,8 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) | |||
448 | if (overlay->last_flip_req == 0) | 449 | if (overlay->last_flip_req == 0) |
449 | return 0; | 450 | return 0; |
450 | 451 | ||
451 | ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); | 452 | ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, |
453 | true); | ||
452 | if (ret) | 454 | if (ret) |
453 | return ret; | 455 | return ret; |
454 | 456 | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 04d79fd1dc9d..c935cdaa2154 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -141,8 +141,8 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) | |||
141 | dev_priv->saveBLC_PWM_CTL2 = val; | 141 | dev_priv->saveBLC_PWM_CTL2 = val; |
142 | } else if (val == 0) { | 142 | } else if (val == 0) { |
143 | I915_WRITE(BLC_PWM_PCH_CTL2, | 143 | I915_WRITE(BLC_PWM_PCH_CTL2, |
144 | dev_priv->saveBLC_PWM_CTL); | 144 | dev_priv->saveBLC_PWM_CTL2); |
145 | val = dev_priv->saveBLC_PWM_CTL; | 145 | val = dev_priv->saveBLC_PWM_CTL2; |
146 | } | 146 | } |
147 | } else { | 147 | } else { |
148 | val = I915_READ(BLC_PWM_CTL); | 148 | val = I915_READ(BLC_PWM_CTL); |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1ab842c6032e..4956f1bff522 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -399,8 +399,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
399 | 399 | ||
400 | if (INTEL_INFO(dev)->gen > 3) { | 400 | if (INTEL_INFO(dev)->gen > 3) { |
401 | int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; | 401 | int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; |
402 | if (IS_GEN6(dev) || IS_GEN7(dev)) | ||
403 | mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; | ||
404 | I915_WRITE(MI_MODE, mode); | 402 | I915_WRITE(MI_MODE, mode); |
405 | if (IS_GEN7(dev)) | 403 | if (IS_GEN7(dev)) |
406 | I915_WRITE(GFX_MODE_GEN7, | 404 | I915_WRITE(GFX_MODE_GEN7, |
@@ -744,13 +742,13 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) | |||
744 | */ | 742 | */ |
745 | if (IS_GEN7(dev)) { | 743 | if (IS_GEN7(dev)) { |
746 | switch (ring->id) { | 744 | switch (ring->id) { |
747 | case RING_RENDER: | 745 | case RCS: |
748 | mmio = RENDER_HWS_PGA_GEN7; | 746 | mmio = RENDER_HWS_PGA_GEN7; |
749 | break; | 747 | break; |
750 | case RING_BLT: | 748 | case BCS: |
751 | mmio = BLT_HWS_PGA_GEN7; | 749 | mmio = BLT_HWS_PGA_GEN7; |
752 | break; | 750 | break; |
753 | case RING_BSD: | 751 | case VCS: |
754 | mmio = BSD_HWS_PGA_GEN7; | 752 | mmio = BSD_HWS_PGA_GEN7; |
755 | break; | 753 | break; |
756 | } | 754 | } |
@@ -1212,7 +1210,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring) | |||
1212 | 1210 | ||
1213 | static const struct intel_ring_buffer render_ring = { | 1211 | static const struct intel_ring_buffer render_ring = { |
1214 | .name = "render ring", | 1212 | .name = "render ring", |
1215 | .id = RING_RENDER, | 1213 | .id = RCS, |
1216 | .mmio_base = RENDER_RING_BASE, | 1214 | .mmio_base = RENDER_RING_BASE, |
1217 | .size = 32 * PAGE_SIZE, | 1215 | .size = 32 * PAGE_SIZE, |
1218 | .init = init_render_ring, | 1216 | .init = init_render_ring, |
@@ -1235,7 +1233,7 @@ static const struct intel_ring_buffer render_ring = { | |||
1235 | 1233 | ||
1236 | static const struct intel_ring_buffer bsd_ring = { | 1234 | static const struct intel_ring_buffer bsd_ring = { |
1237 | .name = "bsd ring", | 1235 | .name = "bsd ring", |
1238 | .id = RING_BSD, | 1236 | .id = VCS, |
1239 | .mmio_base = BSD_RING_BASE, | 1237 | .mmio_base = BSD_RING_BASE, |
1240 | .size = 32 * PAGE_SIZE, | 1238 | .size = 32 * PAGE_SIZE, |
1241 | .init = init_ring_common, | 1239 | .init = init_ring_common, |
@@ -1345,7 +1343,7 @@ gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) | |||
1345 | /* ring buffer for Video Codec for Gen6+ */ | 1343 | /* ring buffer for Video Codec for Gen6+ */ |
1346 | static const struct intel_ring_buffer gen6_bsd_ring = { | 1344 | static const struct intel_ring_buffer gen6_bsd_ring = { |
1347 | .name = "gen6 bsd ring", | 1345 | .name = "gen6 bsd ring", |
1348 | .id = RING_BSD, | 1346 | .id = VCS, |
1349 | .mmio_base = GEN6_BSD_RING_BASE, | 1347 | .mmio_base = GEN6_BSD_RING_BASE, |
1350 | .size = 32 * PAGE_SIZE, | 1348 | .size = 32 * PAGE_SIZE, |
1351 | .init = init_ring_common, | 1349 | .init = init_ring_common, |
@@ -1381,79 +1379,13 @@ blt_ring_put_irq(struct intel_ring_buffer *ring) | |||
1381 | GEN6_BLITTER_USER_INTERRUPT); | 1379 | GEN6_BLITTER_USER_INTERRUPT); |
1382 | } | 1380 | } |
1383 | 1381 | ||
1384 | |||
1385 | /* Workaround for some stepping of SNB, | ||
1386 | * each time when BLT engine ring tail moved, | ||
1387 | * the first command in the ring to be parsed | ||
1388 | * should be MI_BATCH_BUFFER_START | ||
1389 | */ | ||
1390 | #define NEED_BLT_WORKAROUND(dev) \ | ||
1391 | (IS_GEN6(dev) && (dev->pdev->revision < 8)) | ||
1392 | |||
1393 | static inline struct drm_i915_gem_object * | ||
1394 | to_blt_workaround(struct intel_ring_buffer *ring) | ||
1395 | { | ||
1396 | return ring->private; | ||
1397 | } | ||
1398 | |||
1399 | static int blt_ring_init(struct intel_ring_buffer *ring) | ||
1400 | { | ||
1401 | if (NEED_BLT_WORKAROUND(ring->dev)) { | ||
1402 | struct drm_i915_gem_object *obj; | ||
1403 | u32 *ptr; | ||
1404 | int ret; | ||
1405 | |||
1406 | obj = i915_gem_alloc_object(ring->dev, 4096); | ||
1407 | if (obj == NULL) | ||
1408 | return -ENOMEM; | ||
1409 | |||
1410 | ret = i915_gem_object_pin(obj, 4096, true); | ||
1411 | if (ret) { | ||
1412 | drm_gem_object_unreference(&obj->base); | ||
1413 | return ret; | ||
1414 | } | ||
1415 | |||
1416 | ptr = kmap(obj->pages[0]); | ||
1417 | *ptr++ = MI_BATCH_BUFFER_END; | ||
1418 | *ptr++ = MI_NOOP; | ||
1419 | kunmap(obj->pages[0]); | ||
1420 | |||
1421 | ret = i915_gem_object_set_to_gtt_domain(obj, false); | ||
1422 | if (ret) { | ||
1423 | i915_gem_object_unpin(obj); | ||
1424 | drm_gem_object_unreference(&obj->base); | ||
1425 | return ret; | ||
1426 | } | ||
1427 | |||
1428 | ring->private = obj; | ||
1429 | } | ||
1430 | |||
1431 | return init_ring_common(ring); | ||
1432 | } | ||
1433 | |||
1434 | static int blt_ring_begin(struct intel_ring_buffer *ring, | ||
1435 | int num_dwords) | ||
1436 | { | ||
1437 | if (ring->private) { | ||
1438 | int ret = intel_ring_begin(ring, num_dwords+2); | ||
1439 | if (ret) | ||
1440 | return ret; | ||
1441 | |||
1442 | intel_ring_emit(ring, MI_BATCH_BUFFER_START); | ||
1443 | intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset); | ||
1444 | |||
1445 | return 0; | ||
1446 | } else | ||
1447 | return intel_ring_begin(ring, 4); | ||
1448 | } | ||
1449 | |||
1450 | static int blt_ring_flush(struct intel_ring_buffer *ring, | 1382 | static int blt_ring_flush(struct intel_ring_buffer *ring, |
1451 | u32 invalidate, u32 flush) | 1383 | u32 invalidate, u32 flush) |
1452 | { | 1384 | { |
1453 | uint32_t cmd; | 1385 | uint32_t cmd; |
1454 | int ret; | 1386 | int ret; |
1455 | 1387 | ||
1456 | ret = blt_ring_begin(ring, 4); | 1388 | ret = intel_ring_begin(ring, 4); |
1457 | if (ret) | 1389 | if (ret) |
1458 | return ret; | 1390 | return ret; |
1459 | 1391 | ||
@@ -1468,22 +1400,12 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, | |||
1468 | return 0; | 1400 | return 0; |
1469 | } | 1401 | } |
1470 | 1402 | ||
1471 | static void blt_ring_cleanup(struct intel_ring_buffer *ring) | ||
1472 | { | ||
1473 | if (!ring->private) | ||
1474 | return; | ||
1475 | |||
1476 | i915_gem_object_unpin(ring->private); | ||
1477 | drm_gem_object_unreference(ring->private); | ||
1478 | ring->private = NULL; | ||
1479 | } | ||
1480 | |||
1481 | static const struct intel_ring_buffer gen6_blt_ring = { | 1403 | static const struct intel_ring_buffer gen6_blt_ring = { |
1482 | .name = "blt ring", | 1404 | .name = "blt ring", |
1483 | .id = RING_BLT, | 1405 | .id = BCS, |
1484 | .mmio_base = BLT_RING_BASE, | 1406 | .mmio_base = BLT_RING_BASE, |
1485 | .size = 32 * PAGE_SIZE, | 1407 | .size = 32 * PAGE_SIZE, |
1486 | .init = blt_ring_init, | 1408 | .init = init_ring_common, |
1487 | .write_tail = ring_write_tail, | 1409 | .write_tail = ring_write_tail, |
1488 | .flush = blt_ring_flush, | 1410 | .flush = blt_ring_flush, |
1489 | .add_request = gen6_add_request, | 1411 | .add_request = gen6_add_request, |
@@ -1491,7 +1413,6 @@ static const struct intel_ring_buffer gen6_blt_ring = { | |||
1491 | .irq_get = blt_ring_get_irq, | 1413 | .irq_get = blt_ring_get_irq, |
1492 | .irq_put = blt_ring_put_irq, | 1414 | .irq_put = blt_ring_put_irq, |
1493 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1415 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
1494 | .cleanup = blt_ring_cleanup, | ||
1495 | .sync_to = gen6_blt_ring_sync_to, | 1416 | .sync_to = gen6_blt_ring_sync_to, |
1496 | .semaphore_register = {MI_SEMAPHORE_SYNC_BR, | 1417 | .semaphore_register = {MI_SEMAPHORE_SYNC_BR, |
1497 | MI_SEMAPHORE_SYNC_BV, | 1418 | MI_SEMAPHORE_SYNC_BV, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 68281c96c558..c8b9cc0cd0dc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -1,13 +1,6 @@ | |||
1 | #ifndef _INTEL_RINGBUFFER_H_ | 1 | #ifndef _INTEL_RINGBUFFER_H_ |
2 | #define _INTEL_RINGBUFFER_H_ | 2 | #define _INTEL_RINGBUFFER_H_ |
3 | 3 | ||
4 | enum { | ||
5 | RCS = 0x0, | ||
6 | VCS, | ||
7 | BCS, | ||
8 | I915_NUM_RINGS, | ||
9 | }; | ||
10 | |||
11 | struct intel_hw_status_page { | 4 | struct intel_hw_status_page { |
12 | u32 __iomem *page_addr; | 5 | u32 __iomem *page_addr; |
13 | unsigned int gfx_addr; | 6 | unsigned int gfx_addr; |
@@ -36,10 +29,11 @@ struct intel_hw_status_page { | |||
36 | struct intel_ring_buffer { | 29 | struct intel_ring_buffer { |
37 | const char *name; | 30 | const char *name; |
38 | enum intel_ring_id { | 31 | enum intel_ring_id { |
39 | RING_RENDER = 0x1, | 32 | RCS = 0x0, |
40 | RING_BSD = 0x2, | 33 | VCS, |
41 | RING_BLT = 0x4, | 34 | BCS, |
42 | } id; | 35 | } id; |
36 | #define I915_NUM_RINGS 3 | ||
43 | u32 mmio_base; | 37 | u32 mmio_base; |
44 | void __iomem *virtual_start; | 38 | void __iomem *virtual_start; |
45 | struct drm_device *dev; | 39 | struct drm_device *dev; |
@@ -119,6 +113,12 @@ struct intel_ring_buffer { | |||
119 | void *private; | 113 | void *private; |
120 | }; | 114 | }; |
121 | 115 | ||
116 | static inline unsigned | ||
117 | intel_ring_flag(struct intel_ring_buffer *ring) | ||
118 | { | ||
119 | return 1 << ring->id; | ||
120 | } | ||
121 | |||
122 | static inline u32 | 122 | static inline u32 |
123 | intel_ring_sync_index(struct intel_ring_buffer *ring, | 123 | intel_ring_sync_index(struct intel_ring_buffer *ring, |
124 | struct intel_ring_buffer *other) | 124 | struct intel_ring_buffer *other) |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2288abf88cce..98444ab68bc3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -501,7 +501,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
501 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); | 501 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
502 | mutex_lock(&dev->struct_mutex); | 502 | mutex_lock(&dev->struct_mutex); |
503 | } | 503 | } |
504 | i915_gem_object_unpin(old_obj); | 504 | intel_unpin_fb_obj(old_obj); |
505 | } | 505 | } |
506 | 506 | ||
507 | out_unlock: | 507 | out_unlock: |
@@ -528,7 +528,7 @@ intel_disable_plane(struct drm_plane *plane) | |||
528 | goto out; | 528 | goto out; |
529 | 529 | ||
530 | mutex_lock(&dev->struct_mutex); | 530 | mutex_lock(&dev->struct_mutex); |
531 | i915_gem_object_unpin(intel_plane->obj); | 531 | intel_unpin_fb_obj(intel_plane->obj); |
532 | intel_plane->obj = NULL; | 532 | intel_plane->obj = NULL; |
533 | mutex_unlock(&dev->struct_mutex); | 533 | mutex_unlock(&dev->struct_mutex); |
534 | out: | 534 | out: |