diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 109 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_context.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 35 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 504 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gpu_error.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 375 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 123 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 124 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 82 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 66 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 164 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 194 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_uncore.c | 58 |
19 files changed, 1806 insertions, 126 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 43866221cd4c..6ed45a984230 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -586,7 +586,53 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
| 586 | if (ret) | 586 | if (ret) |
| 587 | return ret; | 587 | return ret; |
| 588 | 588 | ||
| 589 | if (IS_VALLEYVIEW(dev)) { | 589 | if (INTEL_INFO(dev)->gen >= 8) { |
| 590 | int i; | ||
| 591 | seq_printf(m, "Master Interrupt Control:\t%08x\n", | ||
| 592 | I915_READ(GEN8_MASTER_IRQ)); | ||
| 593 | |||
| 594 | for (i = 0; i < 4; i++) { | ||
| 595 | seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", | ||
| 596 | i, I915_READ(GEN8_GT_IMR(i))); | ||
| 597 | seq_printf(m, "GT Interrupt IIR %d:\t%08x\n", | ||
| 598 | i, I915_READ(GEN8_GT_IIR(i))); | ||
| 599 | seq_printf(m, "GT Interrupt IER %d:\t%08x\n", | ||
| 600 | i, I915_READ(GEN8_GT_IER(i))); | ||
| 601 | } | ||
| 602 | |||
| 603 | for_each_pipe(i) { | ||
| 604 | seq_printf(m, "Pipe %c IMR:\t%08x\n", | ||
| 605 | pipe_name(i), | ||
| 606 | I915_READ(GEN8_DE_PIPE_IMR(i))); | ||
| 607 | seq_printf(m, "Pipe %c IIR:\t%08x\n", | ||
| 608 | pipe_name(i), | ||
| 609 | I915_READ(GEN8_DE_PIPE_IIR(i))); | ||
| 610 | seq_printf(m, "Pipe %c IER:\t%08x\n", | ||
| 611 | pipe_name(i), | ||
| 612 | I915_READ(GEN8_DE_PIPE_IER(i))); | ||
| 613 | } | ||
| 614 | |||
| 615 | seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", | ||
| 616 | I915_READ(GEN8_DE_PORT_IMR)); | ||
| 617 | seq_printf(m, "Display Engine port interrupt identity:\t%08x\n", | ||
| 618 | I915_READ(GEN8_DE_PORT_IIR)); | ||
| 619 | seq_printf(m, "Display Engine port interrupt enable:\t%08x\n", | ||
| 620 | I915_READ(GEN8_DE_PORT_IER)); | ||
| 621 | |||
| 622 | seq_printf(m, "Display Engine misc interrupt mask:\t%08x\n", | ||
| 623 | I915_READ(GEN8_DE_MISC_IMR)); | ||
| 624 | seq_printf(m, "Display Engine misc interrupt identity:\t%08x\n", | ||
| 625 | I915_READ(GEN8_DE_MISC_IIR)); | ||
| 626 | seq_printf(m, "Display Engine misc interrupt enable:\t%08x\n", | ||
| 627 | I915_READ(GEN8_DE_MISC_IER)); | ||
| 628 | |||
| 629 | seq_printf(m, "PCU interrupt mask:\t%08x\n", | ||
| 630 | I915_READ(GEN8_PCU_IMR)); | ||
| 631 | seq_printf(m, "PCU interrupt identity:\t%08x\n", | ||
| 632 | I915_READ(GEN8_PCU_IIR)); | ||
| 633 | seq_printf(m, "PCU interrupt enable:\t%08x\n", | ||
| 634 | I915_READ(GEN8_PCU_IER)); | ||
| 635 | } else if (IS_VALLEYVIEW(dev)) { | ||
| 590 | seq_printf(m, "Display IER:\t%08x\n", | 636 | seq_printf(m, "Display IER:\t%08x\n", |
| 591 | I915_READ(VLV_IER)); | 637 | I915_READ(VLV_IER)); |
| 592 | seq_printf(m, "Display IIR:\t%08x\n", | 638 | seq_printf(m, "Display IIR:\t%08x\n", |
| @@ -658,7 +704,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
| 658 | seq_printf(m, "Interrupts received: %d\n", | 704 | seq_printf(m, "Interrupts received: %d\n", |
| 659 | atomic_read(&dev_priv->irq_received)); | 705 | atomic_read(&dev_priv->irq_received)); |
| 660 | for_each_ring(ring, dev_priv, i) { | 706 | for_each_ring(ring, dev_priv, i) { |
| 661 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 707 | if (INTEL_INFO(dev)->gen >= 6) { |
| 662 | seq_printf(m, | 708 | seq_printf(m, |
| 663 | "Graphics Interrupt mask (%s): %08x\n", | 709 | "Graphics Interrupt mask (%s): %08x\n", |
| 664 | ring->name, I915_READ_IMR(ring)); | 710 | ring->name, I915_READ_IMR(ring)); |
| @@ -1577,7 +1623,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
| 1577 | I915_READ16(C0DRB3)); | 1623 | I915_READ16(C0DRB3)); |
| 1578 | seq_printf(m, "C1DRB3 = 0x%04x\n", | 1624 | seq_printf(m, "C1DRB3 = 0x%04x\n", |
| 1579 | I915_READ16(C1DRB3)); | 1625 | I915_READ16(C1DRB3)); |
| 1580 | } else if (IS_GEN6(dev) || IS_GEN7(dev)) { | 1626 | } else if (INTEL_INFO(dev)->gen >= 6) { |
| 1581 | seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", | 1627 | seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", |
| 1582 | I915_READ(MAD_DIMM_C0)); | 1628 | I915_READ(MAD_DIMM_C0)); |
| 1583 | seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", | 1629 | seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", |
| @@ -1586,8 +1632,12 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
| 1586 | I915_READ(MAD_DIMM_C2)); | 1632 | I915_READ(MAD_DIMM_C2)); |
| 1587 | seq_printf(m, "TILECTL = 0x%08x\n", | 1633 | seq_printf(m, "TILECTL = 0x%08x\n", |
| 1588 | I915_READ(TILECTL)); | 1634 | I915_READ(TILECTL)); |
| 1589 | seq_printf(m, "ARB_MODE = 0x%08x\n", | 1635 | if (IS_GEN8(dev)) |
| 1590 | I915_READ(ARB_MODE)); | 1636 | seq_printf(m, "GAMTARBMODE = 0x%08x\n", |
| 1637 | I915_READ(GAMTARBMODE)); | ||
| 1638 | else | ||
| 1639 | seq_printf(m, "ARB_MODE = 0x%08x\n", | ||
| 1640 | I915_READ(ARB_MODE)); | ||
| 1591 | seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", | 1641 | seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", |
| 1592 | I915_READ(DISP_ARB_CTL)); | 1642 | I915_READ(DISP_ARB_CTL)); |
| 1593 | } | 1643 | } |
| @@ -1596,18 +1646,37 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
| 1596 | return 0; | 1646 | return 0; |
| 1597 | } | 1647 | } |
| 1598 | 1648 | ||
| 1599 | static int i915_ppgtt_info(struct seq_file *m, void *data) | 1649 | static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) |
| 1600 | { | 1650 | { |
| 1601 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
| 1602 | struct drm_device *dev = node->minor->dev; | ||
| 1603 | struct drm_i915_private *dev_priv = dev->dev_private; | 1651 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1604 | struct intel_ring_buffer *ring; | 1652 | struct intel_ring_buffer *ring; |
| 1605 | int i, ret; | 1653 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; |
| 1654 | int unused, i; | ||
| 1606 | 1655 | ||
| 1656 | if (!ppgtt) | ||
| 1657 | return; | ||
| 1658 | |||
| 1659 | seq_printf(m, "Page directories: %d\n", ppgtt->num_pd_pages); | ||
| 1660 | seq_printf(m, "Page tables: %d\n", ppgtt->num_pt_pages); | ||
| 1661 | for_each_ring(ring, dev_priv, unused) { | ||
| 1662 | seq_printf(m, "%s\n", ring->name); | ||
| 1663 | for (i = 0; i < 4; i++) { | ||
| 1664 | u32 offset = 0x270 + i * 8; | ||
| 1665 | u64 pdp = I915_READ(ring->mmio_base + offset + 4); | ||
| 1666 | pdp <<= 32; | ||
| 1667 | pdp |= I915_READ(ring->mmio_base + offset); | ||
| 1668 | for (i = 0; i < 4; i++) | ||
| 1669 | seq_printf(m, "\tPDP%d 0x%016llx\n", i, pdp); | ||
| 1670 | } | ||
| 1671 | } | ||
| 1672 | } | ||
| 1673 | |||
| 1674 | static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) | ||
| 1675 | { | ||
| 1676 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1677 | struct intel_ring_buffer *ring; | ||
| 1678 | int i; | ||
| 1607 | 1679 | ||
| 1608 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 1609 | if (ret) | ||
| 1610 | return ret; | ||
| 1611 | if (INTEL_INFO(dev)->gen == 6) | 1680 | if (INTEL_INFO(dev)->gen == 6) |
| 1612 | seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); | 1681 | seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(GFX_MODE)); |
| 1613 | 1682 | ||
| @@ -1626,6 +1695,22 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) | |||
| 1626 | seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); | 1695 | seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); |
| 1627 | } | 1696 | } |
| 1628 | seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); | 1697 | seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK)); |
| 1698 | } | ||
| 1699 | |||
| 1700 | static int i915_ppgtt_info(struct seq_file *m, void *data) | ||
| 1701 | { | ||
| 1702 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
| 1703 | struct drm_device *dev = node->minor->dev; | ||
| 1704 | |||
| 1705 | int ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
| 1706 | if (ret) | ||
| 1707 | return ret; | ||
| 1708 | |||
| 1709 | if (INTEL_INFO(dev)->gen >= 8) | ||
| 1710 | gen8_ppgtt_info(m, dev); | ||
| 1711 | else if (INTEL_INFO(dev)->gen >= 6) | ||
| 1712 | gen6_ppgtt_info(m, dev); | ||
| 1713 | |||
| 1629 | mutex_unlock(&dev->struct_mutex); | 1714 | mutex_unlock(&dev->struct_mutex); |
| 1630 | 1715 | ||
| 1631 | return 0; | 1716 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a0804fa1e306..989be12cdd6e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -336,6 +336,24 @@ static const struct intel_device_info intel_haswell_m_info = { | |||
| 336 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | 336 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, |
| 337 | }; | 337 | }; |
| 338 | 338 | ||
| 339 | static const struct intel_device_info intel_broadwell_d_info = { | ||
| 340 | .is_preliminary = 1, | ||
| 341 | .gen = 8, .num_pipes = 3, | ||
| 342 | .need_gfx_hws = 1, .has_hotplug = 1, | ||
| 343 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | ||
| 344 | .has_llc = 1, | ||
| 345 | .has_ddi = 1, | ||
| 346 | }; | ||
| 347 | |||
| 348 | static const struct intel_device_info intel_broadwell_m_info = { | ||
| 349 | .is_preliminary = 1, | ||
| 350 | .gen = 8, .is_mobile = 1, .num_pipes = 3, | ||
| 351 | .need_gfx_hws = 1, .has_hotplug = 1, | ||
| 352 | .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, | ||
| 353 | .has_llc = 1, | ||
| 354 | .has_ddi = 1, | ||
| 355 | }; | ||
| 356 | |||
| 339 | /* | 357 | /* |
| 340 | * Make sure any device matches here are from most specific to most | 358 | * Make sure any device matches here are from most specific to most |
| 341 | * general. For example, since the Quanta match is based on the subsystem | 359 | * general. For example, since the Quanta match is based on the subsystem |
| @@ -367,7 +385,9 @@ static const struct intel_device_info intel_haswell_m_info = { | |||
| 367 | INTEL_HSW_D_IDS(&intel_haswell_d_info), \ | 385 | INTEL_HSW_D_IDS(&intel_haswell_d_info), \ |
| 368 | INTEL_HSW_M_IDS(&intel_haswell_m_info), \ | 386 | INTEL_HSW_M_IDS(&intel_haswell_m_info), \ |
| 369 | INTEL_VLV_M_IDS(&intel_valleyview_m_info), \ | 387 | INTEL_VLV_M_IDS(&intel_valleyview_m_info), \ |
| 370 | INTEL_VLV_D_IDS(&intel_valleyview_d_info) | 388 | INTEL_VLV_D_IDS(&intel_valleyview_d_info), \ |
| 389 | INTEL_BDW_M_IDS(&intel_broadwell_m_info), \ | ||
| 390 | INTEL_BDW_D_IDS(&intel_broadwell_d_info) | ||
| 371 | 391 | ||
| 372 | static const struct pci_device_id pciidlist[] = { /* aka */ | 392 | static const struct pci_device_id pciidlist[] = { /* aka */ |
| 373 | INTEL_PCI_IDS, | 393 | INTEL_PCI_IDS, |
| @@ -428,6 +448,12 @@ void intel_detect_pch(struct drm_device *dev) | |||
| 428 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); | 448 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); |
| 429 | WARN_ON(!IS_HASWELL(dev)); | 449 | WARN_ON(!IS_HASWELL(dev)); |
| 430 | WARN_ON(IS_ULT(dev)); | 450 | WARN_ON(IS_ULT(dev)); |
| 451 | } else if (IS_BROADWELL(dev)) { | ||
| 452 | dev_priv->pch_type = PCH_LPT; | ||
| 453 | dev_priv->pch_id = | ||
| 454 | INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; | ||
| 455 | DRM_DEBUG_KMS("This is Broadwell, assuming " | ||
| 456 | "LynxPoint LP PCH\n"); | ||
| 431 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { | 457 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { |
| 432 | dev_priv->pch_type = PCH_LPT; | 458 | dev_priv->pch_type = PCH_LPT; |
| 433 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); | 459 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); |
| @@ -452,6 +478,12 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) | |||
| 452 | if (INTEL_INFO(dev)->gen < 6) | 478 | if (INTEL_INFO(dev)->gen < 6) |
| 453 | return 0; | 479 | return 0; |
| 454 | 480 | ||
| 481 | /* Until we get further testing... */ | ||
| 482 | if (IS_GEN8(dev)) { | ||
| 483 | WARN_ON(!i915_preliminary_hw_support); | ||
| 484 | return 0; | ||
| 485 | } | ||
| 486 | |||
| 455 | if (i915_semaphores >= 0) | 487 | if (i915_semaphores >= 0) |
| 456 | return i915_semaphores; | 488 | return i915_semaphores; |
| 457 | 489 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b0dd4ea8133f..8600c315b4c4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -118,6 +118,10 @@ enum intel_display_power_domain { | |||
| 118 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ | 118 | #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ |
| 119 | BIT(POWER_DOMAIN_PIPE_A) | \ | 119 | BIT(POWER_DOMAIN_PIPE_A) | \ |
| 120 | BIT(POWER_DOMAIN_TRANSCODER_EDP)) | 120 | BIT(POWER_DOMAIN_TRANSCODER_EDP)) |
| 121 | #define BDW_ALWAYS_ON_POWER_DOMAINS ( \ | ||
| 122 | BIT(POWER_DOMAIN_PIPE_A) | \ | ||
| 123 | BIT(POWER_DOMAIN_TRANSCODER_EDP) | \ | ||
| 124 | BIT(POWER_DOMAIN_PIPE_A_PANEL_FITTER)) | ||
| 121 | 125 | ||
| 122 | enum hpd_pin { | 126 | enum hpd_pin { |
| 123 | HPD_NONE = 0, | 127 | HPD_NONE = 0, |
| @@ -575,10 +579,21 @@ struct i915_gtt { | |||
| 575 | struct i915_hw_ppgtt { | 579 | struct i915_hw_ppgtt { |
| 576 | struct i915_address_space base; | 580 | struct i915_address_space base; |
| 577 | unsigned num_pd_entries; | 581 | unsigned num_pd_entries; |
| 578 | struct page **pt_pages; | 582 | union { |
| 579 | uint32_t pd_offset; | 583 | struct page **pt_pages; |
| 580 | dma_addr_t *pt_dma_addr; | 584 | struct page *gen8_pt_pages; |
| 581 | 585 | }; | |
| 586 | struct page *pd_pages; | ||
| 587 | int num_pd_pages; | ||
| 588 | int num_pt_pages; | ||
| 589 | union { | ||
| 590 | uint32_t pd_offset; | ||
| 591 | dma_addr_t pd_dma_addr[4]; | ||
| 592 | }; | ||
| 593 | union { | ||
| 594 | dma_addr_t *pt_dma_addr; | ||
| 595 | dma_addr_t *gen8_pt_dma_addr[4]; | ||
| 596 | }; | ||
| 582 | int (*enable)(struct drm_device *dev); | 597 | int (*enable)(struct drm_device *dev); |
| 583 | }; | 598 | }; |
| 584 | 599 | ||
| @@ -1322,7 +1337,10 @@ typedef struct drm_i915_private { | |||
| 1322 | struct mutex dpio_lock; | 1337 | struct mutex dpio_lock; |
| 1323 | 1338 | ||
| 1324 | /** Cached value of IMR to avoid reads in updating the bitfield */ | 1339 | /** Cached value of IMR to avoid reads in updating the bitfield */ |
| 1325 | u32 irq_mask; | 1340 | union { |
| 1341 | u32 irq_mask; | ||
| 1342 | u32 de_irq_mask[I915_MAX_PIPES]; | ||
| 1343 | }; | ||
| 1326 | u32 gt_irq_mask; | 1344 | u32 gt_irq_mask; |
| 1327 | u32 pm_irq_mask; | 1345 | u32 pm_irq_mask; |
| 1328 | 1346 | ||
| @@ -1733,6 +1751,7 @@ struct drm_i915_file_private { | |||
| 1733 | (dev)->pdev->device == 0x010A) | 1751 | (dev)->pdev->device == 0x010A) |
| 1734 | #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) | 1752 | #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) |
| 1735 | #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) | 1753 | #define IS_HASWELL(dev) (INTEL_INFO(dev)->is_haswell) |
| 1754 | #define IS_BROADWELL(dev) (INTEL_INFO(dev)->gen == 8) | ||
| 1736 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) | 1755 | #define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) |
| 1737 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ | 1756 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ |
| 1738 | ((dev)->pdev->device & 0xFF00) == 0x0C00) | 1757 | ((dev)->pdev->device & 0xFF00) == 0x0C00) |
| @@ -1754,6 +1773,7 @@ struct drm_i915_file_private { | |||
| 1754 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) | 1773 | #define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) |
| 1755 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) | 1774 | #define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) |
| 1756 | #define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7) | 1775 | #define IS_GEN7(dev) (INTEL_INFO(dev)->gen == 7) |
| 1776 | #define IS_GEN8(dev) (INTEL_INFO(dev)->gen == 8) | ||
| 1757 | 1777 | ||
| 1758 | #define RENDER_RING (1<<RCS) | 1778 | #define RENDER_RING (1<<RCS) |
| 1759 | #define BSD_RING (1<<VCS) | 1779 | #define BSD_RING (1<<VCS) |
| @@ -1790,12 +1810,12 @@ struct drm_i915_file_private { | |||
| 1790 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) | 1810 | #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) |
| 1791 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) | 1811 | #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) |
| 1792 | 1812 | ||
| 1793 | #define HAS_IPS(dev) (IS_ULT(dev)) | 1813 | #define HAS_IPS(dev) (IS_ULT(dev) || IS_BROADWELL(dev)) |
| 1794 | 1814 | ||
| 1795 | #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) | 1815 | #define HAS_DDI(dev) (INTEL_INFO(dev)->has_ddi) |
| 1796 | #define HAS_POWER_WELL(dev) (IS_HASWELL(dev)) | 1816 | #define HAS_POWER_WELL(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 1797 | #define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) | 1817 | #define HAS_FPGA_DBG_UNCLAIMED(dev) (INTEL_INFO(dev)->has_fpga_dbg) |
| 1798 | #define HAS_PSR(dev) (IS_HASWELL(dev)) | 1818 | #define HAS_PSR(dev) (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 1799 | 1819 | ||
| 1800 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 | 1820 | #define INTEL_PCH_DEVICE_ID_MASK 0xff00 |
| 1801 | #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 | 1821 | #define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e7b39d731db6..12bbd5eac70d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -2954,6 +2954,7 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg, | |||
| 2954 | obj->stride, obj->tiling_mode); | 2954 | obj->stride, obj->tiling_mode); |
| 2955 | 2955 | ||
| 2956 | switch (INTEL_INFO(dev)->gen) { | 2956 | switch (INTEL_INFO(dev)->gen) { |
| 2957 | case 8: | ||
| 2957 | case 7: | 2958 | case 7: |
| 2958 | case 6: | 2959 | case 6: |
| 2959 | case 5: | 2960 | case 5: |
| @@ -4361,6 +4362,8 @@ void i915_gem_init_swizzling(struct drm_device *dev) | |||
| 4361 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB)); | 4362 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_SNB)); |
| 4362 | else if (IS_GEN7(dev)) | 4363 | else if (IS_GEN7(dev)) |
| 4363 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); | 4364 | I915_WRITE(ARB_MODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_IVB)); |
| 4365 | else if (IS_GEN8(dev)) | ||
| 4366 | I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_SWIZZLE_BDW)); | ||
| 4364 | else | 4367 | else |
| 4365 | BUG(); | 4368 | BUG(); |
| 4366 | } | 4369 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index cc619c138777..72a3df32292f 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
| @@ -117,6 +117,9 @@ static int get_context_size(struct drm_device *dev) | |||
| 117 | else | 117 | else |
| 118 | ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; | 118 | ret = GEN7_CXT_TOTAL_SIZE(reg) * 64; |
| 119 | break; | 119 | break; |
| 120 | case 8: | ||
| 121 | ret = GEN8_CXT_TOTAL_SIZE; | ||
| 122 | break; | ||
| 120 | default: | 123 | default: |
| 121 | BUG(); | 124 | BUG(); |
| 122 | } | 125 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 0ce0d47e4b0f..885d595e0e02 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
| @@ -212,6 +212,7 @@ static int | |||
| 212 | relocate_entry_cpu(struct drm_i915_gem_object *obj, | 212 | relocate_entry_cpu(struct drm_i915_gem_object *obj, |
| 213 | struct drm_i915_gem_relocation_entry *reloc) | 213 | struct drm_i915_gem_relocation_entry *reloc) |
| 214 | { | 214 | { |
| 215 | struct drm_device *dev = obj->base.dev; | ||
| 215 | uint32_t page_offset = offset_in_page(reloc->offset); | 216 | uint32_t page_offset = offset_in_page(reloc->offset); |
| 216 | char *vaddr; | 217 | char *vaddr; |
| 217 | int ret = -EINVAL; | 218 | int ret = -EINVAL; |
| @@ -223,6 +224,19 @@ relocate_entry_cpu(struct drm_i915_gem_object *obj, | |||
| 223 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | 224 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, |
| 224 | reloc->offset >> PAGE_SHIFT)); | 225 | reloc->offset >> PAGE_SHIFT)); |
| 225 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | 226 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; |
| 227 | |||
| 228 | if (INTEL_INFO(dev)->gen >= 8) { | ||
| 229 | page_offset = offset_in_page(page_offset + sizeof(uint32_t)); | ||
| 230 | |||
| 231 | if (page_offset == 0) { | ||
| 232 | kunmap_atomic(vaddr); | ||
| 233 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | ||
| 234 | (reloc->offset + sizeof(uint32_t)) >> PAGE_SHIFT)); | ||
| 235 | } | ||
| 236 | |||
| 237 | *(uint32_t *)(vaddr + page_offset) = 0; | ||
| 238 | } | ||
| 239 | |||
| 226 | kunmap_atomic(vaddr); | 240 | kunmap_atomic(vaddr); |
| 227 | 241 | ||
| 228 | return 0; | 242 | return 0; |
| @@ -253,6 +267,21 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, | |||
| 253 | reloc_entry = (uint32_t __iomem *) | 267 | reloc_entry = (uint32_t __iomem *) |
| 254 | (reloc_page + offset_in_page(reloc->offset)); | 268 | (reloc_page + offset_in_page(reloc->offset)); |
| 255 | iowrite32(reloc->delta, reloc_entry); | 269 | iowrite32(reloc->delta, reloc_entry); |
| 270 | |||
| 271 | if (INTEL_INFO(dev)->gen >= 8) { | ||
| 272 | reloc_entry += 1; | ||
| 273 | |||
| 274 | if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) { | ||
| 275 | io_mapping_unmap_atomic(reloc_page); | ||
| 276 | reloc_page = io_mapping_map_atomic_wc( | ||
| 277 | dev_priv->gtt.mappable, | ||
| 278 | reloc->offset + sizeof(uint32_t)); | ||
| 279 | reloc_entry = reloc_page; | ||
| 280 | } | ||
| 281 | |||
| 282 | iowrite32(0, reloc_entry); | ||
| 283 | } | ||
| 284 | |||
| 256 | io_mapping_unmap_atomic(reloc_page); | 285 | io_mapping_unmap_atomic(reloc_page); |
| 257 | 286 | ||
| 258 | return 0; | 287 | return 0; |
| @@ -323,7 +352,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
| 323 | return 0; | 352 | return 0; |
| 324 | 353 | ||
| 325 | /* Check that the relocation address is valid... */ | 354 | /* Check that the relocation address is valid... */ |
| 326 | if (unlikely(reloc->offset > obj->base.size - 4)) { | 355 | if (unlikely(reloc->offset > |
| 356 | obj->base.size - (INTEL_INFO(dev)->gen >= 8 ? 8 : 4))) { | ||
| 327 | DRM_DEBUG("Relocation beyond object bounds: " | 357 | DRM_DEBUG("Relocation beyond object bounds: " |
| 328 | "obj %p target %d offset %d size %d.\n", | 358 | "obj %p target %d offset %d size %d.\n", |
| 329 | obj, reloc->target_handle, | 359 | obj, reloc->target_handle, |
| @@ -1116,8 +1146,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
| 1116 | 1146 | ||
| 1117 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure | 1147 | /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure |
| 1118 | * batch" bit. Hence we need to pin secure batches into the global gtt. | 1148 | * batch" bit. Hence we need to pin secure batches into the global gtt. |
| 1119 | * hsw should have this fixed, but let's be paranoid and do it | 1149 | * hsw should have this fixed, but bdw mucks it up again. */ |
| 1120 | * unconditionally for now. */ | ||
| 1121 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) | 1150 | if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping) |
| 1122 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); | 1151 | i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level); |
| 1123 | 1152 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c4c42e7cbd7b..3620a1b0a73c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | 30 | ||
| 31 | #define GEN6_PPGTT_PD_ENTRIES 512 | 31 | #define GEN6_PPGTT_PD_ENTRIES 512 |
| 32 | #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) | 32 | #define I915_PPGTT_PT_ENTRIES (PAGE_SIZE / sizeof(gen6_gtt_pte_t)) |
| 33 | typedef uint64_t gen8_gtt_pte_t; | ||
| 34 | typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; | ||
| 33 | 35 | ||
| 34 | /* PPGTT stuff */ | 36 | /* PPGTT stuff */ |
| 35 | #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) | 37 | #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) |
| @@ -57,6 +59,41 @@ | |||
| 57 | #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) | 59 | #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) |
| 58 | #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) | 60 | #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) |
| 59 | 61 | ||
| 62 | #define GEN8_PTES_PER_PAGE (PAGE_SIZE / sizeof(gen8_gtt_pte_t)) | ||
| 63 | #define GEN8_PDES_PER_PAGE (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t)) | ||
| 64 | #define GEN8_LEGACY_PDPS 4 | ||
| 65 | |||
| 66 | #define PPAT_UNCACHED_INDEX (_PAGE_PWT | _PAGE_PCD) | ||
| 67 | #define PPAT_CACHED_PDE_INDEX 0 /* WB LLC */ | ||
| 68 | #define PPAT_CACHED_INDEX _PAGE_PAT /* WB LLCeLLC */ | ||
| 69 | #define PPAT_DISPLAY_ELLC_INDEX _PAGE_PCD /* WT eLLC */ | ||
| 70 | |||
| 71 | static inline gen8_gtt_pte_t gen8_pte_encode(dma_addr_t addr, | ||
| 72 | enum i915_cache_level level, | ||
| 73 | bool valid) | ||
| 74 | { | ||
| 75 | gen8_gtt_pte_t pte = valid ? _PAGE_PRESENT | _PAGE_RW : 0; | ||
| 76 | pte |= addr; | ||
| 77 | if (level != I915_CACHE_NONE) | ||
| 78 | pte |= PPAT_CACHED_INDEX; | ||
| 79 | else | ||
| 80 | pte |= PPAT_UNCACHED_INDEX; | ||
| 81 | return pte; | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline gen8_ppgtt_pde_t gen8_pde_encode(struct drm_device *dev, | ||
| 85 | dma_addr_t addr, | ||
| 86 | enum i915_cache_level level) | ||
| 87 | { | ||
| 88 | gen8_ppgtt_pde_t pde = _PAGE_PRESENT | _PAGE_RW; | ||
| 89 | pde |= addr; | ||
| 90 | if (level != I915_CACHE_NONE) | ||
| 91 | pde |= PPAT_CACHED_PDE_INDEX; | ||
| 92 | else | ||
| 93 | pde |= PPAT_UNCACHED_INDEX; | ||
| 94 | return pde; | ||
| 95 | } | ||
| 96 | |||
| 60 | static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, | 97 | static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, |
| 61 | enum i915_cache_level level, | 98 | enum i915_cache_level level, |
| 62 | bool valid) | 99 | bool valid) |
| @@ -158,6 +195,257 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, | |||
| 158 | return pte; | 195 | return pte; |
| 159 | } | 196 | } |
| 160 | 197 | ||
| 198 | /* Broadwell Page Directory Pointer Descriptors */ | ||
| 199 | static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry, | ||
| 200 | uint64_t val) | ||
| 201 | { | ||
| 202 | int ret; | ||
| 203 | |||
| 204 | BUG_ON(entry >= 4); | ||
| 205 | |||
| 206 | ret = intel_ring_begin(ring, 6); | ||
| 207 | if (ret) | ||
| 208 | return ret; | ||
| 209 | |||
| 210 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | ||
| 211 | intel_ring_emit(ring, GEN8_RING_PDP_UDW(ring, entry)); | ||
| 212 | intel_ring_emit(ring, (u32)(val >> 32)); | ||
| 213 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | ||
| 214 | intel_ring_emit(ring, GEN8_RING_PDP_LDW(ring, entry)); | ||
| 215 | intel_ring_emit(ring, (u32)(val)); | ||
| 216 | intel_ring_advance(ring); | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int gen8_ppgtt_enable(struct drm_device *dev) | ||
| 222 | { | ||
| 223 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 224 | struct intel_ring_buffer *ring; | ||
| 225 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; | ||
| 226 | int i, j, ret; | ||
| 227 | |||
| 228 | /* bit of a hack to find the actual last used pd */ | ||
| 229 | int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE; | ||
| 230 | |||
| 231 | for_each_ring(ring, dev_priv, j) { | ||
| 232 | I915_WRITE(RING_MODE_GEN7(ring), | ||
| 233 | _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); | ||
| 234 | } | ||
| 235 | |||
| 236 | for (i = used_pd - 1; i >= 0; i--) { | ||
| 237 | dma_addr_t addr = ppgtt->pd_dma_addr[i]; | ||
| 238 | for_each_ring(ring, dev_priv, j) { | ||
| 239 | ret = gen8_write_pdp(ring, i, addr); | ||
| 240 | if (ret) | ||
| 241 | return ret; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static void gen8_ppgtt_clear_range(struct i915_address_space *vm, | ||
| 248 | unsigned first_entry, | ||
| 249 | unsigned num_entries, | ||
| 250 | bool use_scratch) | ||
| 251 | { | ||
| 252 | struct i915_hw_ppgtt *ppgtt = | ||
| 253 | container_of(vm, struct i915_hw_ppgtt, base); | ||
| 254 | gen8_gtt_pte_t *pt_vaddr, scratch_pte; | ||
| 255 | unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE; | ||
| 256 | unsigned first_pte = first_entry % GEN8_PTES_PER_PAGE; | ||
| 257 | unsigned last_pte, i; | ||
| 258 | |||
| 259 | scratch_pte = gen8_pte_encode(ppgtt->base.scratch.addr, | ||
| 260 | I915_CACHE_LLC, use_scratch); | ||
| 261 | |||
| 262 | while (num_entries) { | ||
| 263 | struct page *page_table = &ppgtt->gen8_pt_pages[act_pt]; | ||
| 264 | |||
| 265 | last_pte = first_pte + num_entries; | ||
| 266 | if (last_pte > GEN8_PTES_PER_PAGE) | ||
| 267 | last_pte = GEN8_PTES_PER_PAGE; | ||
| 268 | |||
| 269 | pt_vaddr = kmap_atomic(page_table); | ||
| 270 | |||
| 271 | for (i = first_pte; i < last_pte; i++) | ||
| 272 | pt_vaddr[i] = scratch_pte; | ||
| 273 | |||
| 274 | kunmap_atomic(pt_vaddr); | ||
| 275 | |||
| 276 | num_entries -= last_pte - first_pte; | ||
| 277 | first_pte = 0; | ||
| 278 | act_pt++; | ||
| 279 | } | ||
| 280 | } | ||
| 281 | |||
| 282 | static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, | ||
| 283 | struct sg_table *pages, | ||
| 284 | unsigned first_entry, | ||
| 285 | enum i915_cache_level cache_level) | ||
| 286 | { | ||
| 287 | struct i915_hw_ppgtt *ppgtt = | ||
| 288 | container_of(vm, struct i915_hw_ppgtt, base); | ||
| 289 | gen8_gtt_pte_t *pt_vaddr; | ||
| 290 | unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE; | ||
| 291 | unsigned act_pte = first_entry % GEN8_PTES_PER_PAGE; | ||
| 292 | struct sg_page_iter sg_iter; | ||
| 293 | |||
| 294 | pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]); | ||
| 295 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { | ||
| 296 | dma_addr_t page_addr; | ||
| 297 | |||
| 298 | page_addr = sg_dma_address(sg_iter.sg) + | ||
| 299 | (sg_iter.sg_pgoffset << PAGE_SHIFT); | ||
| 300 | pt_vaddr[act_pte] = gen8_pte_encode(page_addr, cache_level, | ||
| 301 | true); | ||
| 302 | if (++act_pte == GEN8_PTES_PER_PAGE) { | ||
| 303 | kunmap_atomic(pt_vaddr); | ||
| 304 | act_pt++; | ||
| 305 | pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]); | ||
| 306 | act_pte = 0; | ||
| 307 | |||
| 308 | } | ||
| 309 | } | ||
| 310 | kunmap_atomic(pt_vaddr); | ||
| 311 | } | ||
| 312 | |||
| 313 | static void gen8_ppgtt_cleanup(struct i915_address_space *vm) | ||
| 314 | { | ||
| 315 | struct i915_hw_ppgtt *ppgtt = | ||
| 316 | container_of(vm, struct i915_hw_ppgtt, base); | ||
| 317 | int i, j; | ||
| 318 | |||
| 319 | for (i = 0; i < ppgtt->num_pd_pages ; i++) { | ||
| 320 | if (ppgtt->pd_dma_addr[i]) { | ||
| 321 | pci_unmap_page(ppgtt->base.dev->pdev, | ||
| 322 | ppgtt->pd_dma_addr[i], | ||
| 323 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
| 324 | |||
| 325 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | ||
| 326 | dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; | ||
| 327 | if (addr) | ||
| 328 | pci_unmap_page(ppgtt->base.dev->pdev, | ||
| 329 | addr, | ||
| 330 | PAGE_SIZE, | ||
| 331 | PCI_DMA_BIDIRECTIONAL); | ||
| 332 | |||
| 333 | } | ||
| 334 | } | ||
| 335 | kfree(ppgtt->gen8_pt_dma_addr[i]); | ||
| 336 | } | ||
| 337 | |||
| 338 | __free_pages(ppgtt->gen8_pt_pages, ppgtt->num_pt_pages << PAGE_SHIFT); | ||
| 339 | __free_pages(ppgtt->pd_pages, ppgtt->num_pd_pages << PAGE_SHIFT); | ||
| 340 | } | ||
| 341 | |||
| 342 | /** | ||
| 343 | * GEN8 legacy ppgtt programming is accomplished through 4 PDP registers with a | ||
| 344 | * net effect resembling a 2-level page table in normal x86 terms. Each PDP | ||
| 345 | * represents 1GB of memory | ||
| 346 | * 4 * 512 * 512 * 4096 = 4GB legacy 32b address space. | ||
| 347 | * | ||
| 348 | * TODO: Do something with the size parameter | ||
| 349 | **/ | ||
| 350 | static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) | ||
| 351 | { | ||
| 352 | struct page *pt_pages; | ||
| 353 | int i, j, ret = -ENOMEM; | ||
| 354 | const int max_pdp = DIV_ROUND_UP(size, 1 << 30); | ||
| 355 | const int num_pt_pages = GEN8_PDES_PER_PAGE * max_pdp; | ||
| 356 | |||
| 357 | if (size % (1<<30)) | ||
| 358 | DRM_INFO("Pages will be wasted unless GTT size (%llu) is divisible by 1GB\n", size); | ||
| 359 | |||
| 360 | /* FIXME: split allocation into smaller pieces. For now we only ever do | ||
| 361 | * this once, but with full PPGTT, the multiple contiguous allocations | ||
| 362 | * will be bad. | ||
| 363 | */ | ||
| 364 | ppgtt->pd_pages = alloc_pages(GFP_KERNEL, get_order(max_pdp << PAGE_SHIFT)); | ||
| 365 | if (!ppgtt->pd_pages) | ||
| 366 | return -ENOMEM; | ||
| 367 | |||
| 368 | pt_pages = alloc_pages(GFP_KERNEL, get_order(num_pt_pages << PAGE_SHIFT)); | ||
| 369 | if (!pt_pages) { | ||
| 370 | __free_pages(ppgtt->pd_pages, get_order(max_pdp << PAGE_SHIFT)); | ||
| 371 | return -ENOMEM; | ||
| 372 | } | ||
| 373 | |||
| 374 | ppgtt->gen8_pt_pages = pt_pages; | ||
| 375 | ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); | ||
| 376 | ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); | ||
| 377 | ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; | ||
| 378 | ppgtt->enable = gen8_ppgtt_enable; | ||
| 379 | ppgtt->base.clear_range = gen8_ppgtt_clear_range; | ||
| 380 | ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; | ||
| 381 | ppgtt->base.cleanup = gen8_ppgtt_cleanup; | ||
| 382 | |||
| 383 | BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); | ||
| 384 | |||
| 385 | /* | ||
| 386 | * - Create a mapping for the page directories. | ||
| 387 | * - For each page directory: | ||
| 388 | * allocate space for page table mappings. | ||
| 389 | * map each page table | ||
| 390 | */ | ||
| 391 | for (i = 0; i < max_pdp; i++) { | ||
| 392 | dma_addr_t temp; | ||
| 393 | temp = pci_map_page(ppgtt->base.dev->pdev, | ||
| 394 | &ppgtt->pd_pages[i], 0, | ||
| 395 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
| 396 | if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) | ||
| 397 | goto err_out; | ||
| 398 | |||
| 399 | ppgtt->pd_dma_addr[i] = temp; | ||
| 400 | |||
| 401 | ppgtt->gen8_pt_dma_addr[i] = kmalloc(sizeof(dma_addr_t) * GEN8_PDES_PER_PAGE, GFP_KERNEL); | ||
| 402 | if (!ppgtt->gen8_pt_dma_addr[i]) | ||
| 403 | goto err_out; | ||
| 404 | |||
| 405 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | ||
| 406 | struct page *p = &pt_pages[i * GEN8_PDES_PER_PAGE + j]; | ||
| 407 | temp = pci_map_page(ppgtt->base.dev->pdev, | ||
| 408 | p, 0, PAGE_SIZE, | ||
| 409 | PCI_DMA_BIDIRECTIONAL); | ||
| 410 | |||
| 411 | if (pci_dma_mapping_error(ppgtt->base.dev->pdev, temp)) | ||
| 412 | goto err_out; | ||
| 413 | |||
| 414 | ppgtt->gen8_pt_dma_addr[i][j] = temp; | ||
| 415 | } | ||
| 416 | } | ||
| 417 | |||
| 418 | /* For now, the PPGTT helper functions all require that the PDEs are | ||
| 419 | * plugged in correctly. So we do that now/here. For aliasing PPGTT, we | ||
| 420 | * will never need to touch the PDEs again */ | ||
| 421 | for (i = 0; i < max_pdp; i++) { | ||
| 422 | gen8_ppgtt_pde_t *pd_vaddr; | ||
| 423 | pd_vaddr = kmap_atomic(&ppgtt->pd_pages[i]); | ||
| 424 | for (j = 0; j < GEN8_PDES_PER_PAGE; j++) { | ||
| 425 | dma_addr_t addr = ppgtt->gen8_pt_dma_addr[i][j]; | ||
| 426 | pd_vaddr[j] = gen8_pde_encode(ppgtt->base.dev, addr, | ||
| 427 | I915_CACHE_LLC); | ||
| 428 | } | ||
| 429 | kunmap_atomic(pd_vaddr); | ||
| 430 | } | ||
| 431 | |||
| 432 | ppgtt->base.clear_range(&ppgtt->base, 0, | ||
| 433 | ppgtt->num_pd_entries * GEN8_PTES_PER_PAGE, | ||
| 434 | true); | ||
| 435 | |||
| 436 | DRM_DEBUG_DRIVER("Allocated %d pages for page directories (%d wasted)\n", | ||
| 437 | ppgtt->num_pd_pages, ppgtt->num_pd_pages - max_pdp); | ||
| 438 | DRM_DEBUG_DRIVER("Allocated %d pages for page tables (%lld wasted)\n", | ||
| 439 | ppgtt->num_pt_pages, | ||
| 440 | (ppgtt->num_pt_pages - num_pt_pages) + | ||
| 441 | size % (1<<30)); | ||
| 442 | return 0; | ||
| 443 | |||
| 444 | err_out: | ||
| 445 | ppgtt->base.cleanup(&ppgtt->base); | ||
| 446 | return ret; | ||
| 447 | } | ||
| 448 | |||
| 161 | static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) | 449 | static void gen6_write_pdes(struct i915_hw_ppgtt *ppgtt) |
| 162 | { | 450 | { |
| 163 | struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private; | 451 | struct drm_i915_private *dev_priv = ppgtt->base.dev->dev_private; |
| @@ -410,6 +698,8 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
| 410 | 698 | ||
| 411 | if (INTEL_INFO(dev)->gen < 8) | 699 | if (INTEL_INFO(dev)->gen < 8) |
| 412 | ret = gen6_ppgtt_init(ppgtt); | 700 | ret = gen6_ppgtt_init(ppgtt); |
| 701 | else if (IS_GEN8(dev)) | ||
| 702 | ret = gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); | ||
| 413 | else | 703 | else |
| 414 | BUG(); | 704 | BUG(); |
| 415 | 705 | ||
| @@ -573,6 +863,57 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | |||
| 573 | return 0; | 863 | return 0; |
| 574 | } | 864 | } |
| 575 | 865 | ||
| 866 | static inline void gen8_set_pte(void __iomem *addr, gen8_gtt_pte_t pte) | ||
| 867 | { | ||
| 868 | #ifdef writeq | ||
| 869 | writeq(pte, addr); | ||
| 870 | #else | ||
| 871 | iowrite32((u32)pte, addr); | ||
| 872 | iowrite32(pte >> 32, addr + 4); | ||
| 873 | #endif | ||
| 874 | } | ||
| 875 | |||
| 876 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | ||
| 877 | struct sg_table *st, | ||
| 878 | unsigned int first_entry, | ||
| 879 | enum i915_cache_level level) | ||
| 880 | { | ||
| 881 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | ||
| 882 | gen8_gtt_pte_t __iomem *gtt_entries = | ||
| 883 | (gen8_gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry; | ||
| 884 | int i = 0; | ||
| 885 | struct sg_page_iter sg_iter; | ||
| 886 | dma_addr_t addr; | ||
| 887 | |||
| 888 | for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { | ||
| 889 | addr = sg_dma_address(sg_iter.sg) + | ||
| 890 | (sg_iter.sg_pgoffset << PAGE_SHIFT); | ||
| 891 | gen8_set_pte(>t_entries[i], | ||
| 892 | gen8_pte_encode(addr, level, true)); | ||
| 893 | i++; | ||
| 894 | } | ||
| 895 | |||
| 896 | /* | ||
| 897 | * XXX: This serves as a posting read to make sure that the PTE has | ||
| 898 | * actually been updated. There is some concern that even though | ||
| 899 | * registers and PTEs are within the same BAR that they are potentially | ||
| 900 | * of NUMA access patterns. Therefore, even with the way we assume | ||
| 901 | * hardware should work, we must keep this posting read for paranoia. | ||
| 902 | */ | ||
| 903 | if (i != 0) | ||
| 904 | WARN_ON(readq(>t_entries[i-1]) | ||
| 905 | != gen8_pte_encode(addr, level, true)); | ||
| 906 | |||
| 907 | #if 0 /* TODO: Still needed on GEN8? */ | ||
| 908 | /* This next bit makes the above posting read even more important. We | ||
| 909 | * want to flush the TLBs only after we're certain all the PTE updates | ||
| 910 | * have finished. | ||
| 911 | */ | ||
| 912 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | ||
| 913 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | ||
| 914 | #endif | ||
| 915 | } | ||
| 916 | |||
| 576 | /* | 917 | /* |
| 577 | * Binds an object into the global gtt with the specified cache level. The object | 918 | * Binds an object into the global gtt with the specified cache level. The object |
| 578 | * will be accessible to the GPU via commands whose operands reference offsets | 919 | * will be accessible to the GPU via commands whose operands reference offsets |
| @@ -615,6 +956,30 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm, | |||
| 615 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | 956 | POSTING_READ(GFX_FLSH_CNTL_GEN6); |
| 616 | } | 957 | } |
| 617 | 958 | ||
| 959 | static void gen8_ggtt_clear_range(struct i915_address_space *vm, | ||
| 960 | unsigned int first_entry, | ||
| 961 | unsigned int num_entries, | ||
| 962 | bool use_scratch) | ||
| 963 | { | ||
| 964 | struct drm_i915_private *dev_priv = vm->dev->dev_private; | ||
| 965 | gen8_gtt_pte_t scratch_pte, __iomem *gtt_base = | ||
| 966 | (gen8_gtt_pte_t __iomem *) dev_priv->gtt.gsm + first_entry; | ||
| 967 | const int max_entries = gtt_total_entries(dev_priv->gtt) - first_entry; | ||
| 968 | int i; | ||
| 969 | |||
| 970 | if (WARN(num_entries > max_entries, | ||
| 971 | "First entry = %d; Num entries = %d (max=%d)\n", | ||
| 972 | first_entry, num_entries, max_entries)) | ||
| 973 | num_entries = max_entries; | ||
| 974 | |||
| 975 | scratch_pte = gen8_pte_encode(vm->scratch.addr, | ||
| 976 | I915_CACHE_LLC, | ||
| 977 | use_scratch); | ||
| 978 | for (i = 0; i < num_entries; i++) | ||
| 979 | gen8_set_pte(>t_base[i], scratch_pte); | ||
| 980 | readl(gtt_base); | ||
| 981 | } | ||
| 982 | |||
| 618 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, | 983 | static void gen6_ggtt_clear_range(struct i915_address_space *vm, |
| 619 | unsigned int first_entry, | 984 | unsigned int first_entry, |
| 620 | unsigned int num_entries, | 985 | unsigned int num_entries, |
| @@ -638,7 +1003,6 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, | |||
| 638 | readl(gtt_base); | 1003 | readl(gtt_base); |
| 639 | } | 1004 | } |
| 640 | 1005 | ||
| 641 | |||
| 642 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, | 1006 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, |
| 643 | struct sg_table *st, | 1007 | struct sg_table *st, |
| 644 | unsigned int pg_start, | 1008 | unsigned int pg_start, |
| @@ -720,6 +1084,7 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node, | |||
| 720 | *end -= 4096; | 1084 | *end -= 4096; |
| 721 | } | 1085 | } |
| 722 | } | 1086 | } |
| 1087 | |||
| 723 | void i915_gem_setup_global_gtt(struct drm_device *dev, | 1088 | void i915_gem_setup_global_gtt(struct drm_device *dev, |
| 724 | unsigned long start, | 1089 | unsigned long start, |
| 725 | unsigned long mappable_end, | 1090 | unsigned long mappable_end, |
| @@ -817,7 +1182,8 @@ void i915_gem_init_global_gtt(struct drm_device *dev) | |||
| 817 | 1182 | ||
| 818 | DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); | 1183 | DRM_ERROR("Aliased PPGTT setup failed %d\n", ret); |
| 819 | drm_mm_takedown(&dev_priv->gtt.base.mm); | 1184 | drm_mm_takedown(&dev_priv->gtt.base.mm); |
| 820 | gtt_size += GEN6_PPGTT_PD_ENTRIES * PAGE_SIZE; | 1185 | if (INTEL_INFO(dev)->gen < 8) |
| 1186 | gtt_size += GEN6_PPGTT_PD_ENTRIES*PAGE_SIZE; | ||
| 821 | } | 1187 | } |
| 822 | i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); | 1188 | i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); |
| 823 | } | 1189 | } |
| @@ -867,6 +1233,15 @@ static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl) | |||
| 867 | return snb_gmch_ctl << 20; | 1233 | return snb_gmch_ctl << 20; |
| 868 | } | 1234 | } |
| 869 | 1235 | ||
| 1236 | static inline unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl) | ||
| 1237 | { | ||
| 1238 | bdw_gmch_ctl >>= BDW_GMCH_GGMS_SHIFT; | ||
| 1239 | bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK; | ||
| 1240 | if (bdw_gmch_ctl) | ||
| 1241 | bdw_gmch_ctl = 1 << bdw_gmch_ctl; | ||
| 1242 | return bdw_gmch_ctl << 20; | ||
| 1243 | } | ||
| 1244 | |||
| 870 | static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) | 1245 | static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) |
| 871 | { | 1246 | { |
| 872 | snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT; | 1247 | snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT; |
| @@ -874,6 +1249,108 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) | |||
| 874 | return snb_gmch_ctl << 25; /* 32 MB units */ | 1249 | return snb_gmch_ctl << 25; /* 32 MB units */ |
| 875 | } | 1250 | } |
| 876 | 1251 | ||
| 1252 | static inline size_t gen8_get_stolen_size(u16 bdw_gmch_ctl) | ||
| 1253 | { | ||
| 1254 | bdw_gmch_ctl >>= BDW_GMCH_GMS_SHIFT; | ||
| 1255 | bdw_gmch_ctl &= BDW_GMCH_GMS_MASK; | ||
| 1256 | return bdw_gmch_ctl << 25; /* 32 MB units */ | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | static int ggtt_probe_common(struct drm_device *dev, | ||
| 1260 | size_t gtt_size) | ||
| 1261 | { | ||
| 1262 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1263 | phys_addr_t gtt_bus_addr; | ||
| 1264 | int ret; | ||
| 1265 | |||
| 1266 | /* For Modern GENs the PTEs and register space are split in the BAR */ | ||
| 1267 | gtt_bus_addr = pci_resource_start(dev->pdev, 0) + | ||
| 1268 | (pci_resource_len(dev->pdev, 0) / 2); | ||
| 1269 | |||
| 1270 | dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size); | ||
| 1271 | if (!dev_priv->gtt.gsm) { | ||
| 1272 | DRM_ERROR("Failed to map the gtt page table\n"); | ||
| 1273 | return -ENOMEM; | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | ret = setup_scratch_page(dev); | ||
| 1277 | if (ret) { | ||
| 1278 | DRM_ERROR("Scratch setup failed\n"); | ||
| 1279 | /* iounmap will also get called at remove, but meh */ | ||
| 1280 | iounmap(dev_priv->gtt.gsm); | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | return ret; | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability | ||
| 1287 | * bits. When using advanced contexts each context stores its own PAT, but | ||
| 1288 | * writing this data shouldn't be harmful even in those cases. */ | ||
| 1289 | static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv) | ||
| 1290 | { | ||
| 1291 | #define GEN8_PPAT_UC (0<<0) | ||
| 1292 | #define GEN8_PPAT_WC (1<<0) | ||
| 1293 | #define GEN8_PPAT_WT (2<<0) | ||
| 1294 | #define GEN8_PPAT_WB (3<<0) | ||
| 1295 | #define GEN8_PPAT_ELLC_OVERRIDE (0<<2) | ||
| 1296 | /* FIXME(BDW): Bspec is completely confused about cache control bits. */ | ||
| 1297 | #define GEN8_PPAT_LLC (1<<2) | ||
| 1298 | #define GEN8_PPAT_LLCELLC (2<<2) | ||
| 1299 | #define GEN8_PPAT_LLCeLLC (3<<2) | ||
| 1300 | #define GEN8_PPAT_AGE(x) (x<<4) | ||
| 1301 | #define GEN8_PPAT(i, x) ((uint64_t) (x) << ((i) * 8)) | ||
| 1302 | uint64_t pat; | ||
| 1303 | |||
| 1304 | pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */ | ||
| 1305 | GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */ | ||
| 1306 | GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */ | ||
| 1307 | GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */ | ||
| 1308 | GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) | | ||
| 1309 | GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) | | ||
| 1310 | GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) | | ||
| 1311 | GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3)); | ||
| 1312 | |||
| 1313 | /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b | ||
| 1314 | * write would work. */ | ||
| 1315 | I915_WRITE(GEN8_PRIVATE_PAT, pat); | ||
| 1316 | I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | static int gen8_gmch_probe(struct drm_device *dev, | ||
| 1320 | size_t *gtt_total, | ||
| 1321 | size_t *stolen, | ||
| 1322 | phys_addr_t *mappable_base, | ||
| 1323 | unsigned long *mappable_end) | ||
| 1324 | { | ||
| 1325 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1326 | unsigned int gtt_size; | ||
| 1327 | u16 snb_gmch_ctl; | ||
| 1328 | int ret; | ||
| 1329 | |||
| 1330 | /* TODO: We're not aware of mappable constraints on gen8 yet */ | ||
| 1331 | *mappable_base = pci_resource_start(dev->pdev, 2); | ||
| 1332 | *mappable_end = pci_resource_len(dev->pdev, 2); | ||
| 1333 | |||
| 1334 | if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(39))) | ||
| 1335 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(39)); | ||
| 1336 | |||
| 1337 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
| 1338 | |||
| 1339 | *stolen = gen8_get_stolen_size(snb_gmch_ctl); | ||
| 1340 | |||
| 1341 | gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); | ||
| 1342 | *gtt_total = (gtt_size / sizeof(gen8_gtt_pte_t)) << PAGE_SHIFT; | ||
| 1343 | |||
| 1344 | gen8_setup_private_ppat(dev_priv); | ||
| 1345 | |||
| 1346 | ret = ggtt_probe_common(dev, gtt_size); | ||
| 1347 | |||
| 1348 | dev_priv->gtt.base.clear_range = gen8_ggtt_clear_range; | ||
| 1349 | dev_priv->gtt.base.insert_entries = gen8_ggtt_insert_entries; | ||
| 1350 | |||
| 1351 | return ret; | ||
| 1352 | } | ||
| 1353 | |||
| 877 | static int gen6_gmch_probe(struct drm_device *dev, | 1354 | static int gen6_gmch_probe(struct drm_device *dev, |
| 878 | size_t *gtt_total, | 1355 | size_t *gtt_total, |
| 879 | size_t *stolen, | 1356 | size_t *stolen, |
| @@ -881,7 +1358,6 @@ static int gen6_gmch_probe(struct drm_device *dev, | |||
| 881 | unsigned long *mappable_end) | 1358 | unsigned long *mappable_end) |
| 882 | { | 1359 | { |
| 883 | struct drm_i915_private *dev_priv = dev->dev_private; | 1360 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 884 | phys_addr_t gtt_bus_addr; | ||
| 885 | unsigned int gtt_size; | 1361 | unsigned int gtt_size; |
| 886 | u16 snb_gmch_ctl; | 1362 | u16 snb_gmch_ctl; |
| 887 | int ret; | 1363 | int ret; |
| @@ -901,24 +1377,13 @@ static int gen6_gmch_probe(struct drm_device *dev, | |||
| 901 | if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(40))) | 1377 | if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(40))) |
| 902 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40)); | 1378 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40)); |
| 903 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 1379 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
| 904 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); | ||
| 905 | 1380 | ||
| 906 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); | 1381 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); |
| 907 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; | ||
| 908 | |||
| 909 | /* For Modern GENs the PTEs and register space are split in the BAR */ | ||
| 910 | gtt_bus_addr = pci_resource_start(dev->pdev, 0) + | ||
| 911 | (pci_resource_len(dev->pdev, 0) / 2); | ||
| 912 | 1382 | ||
| 913 | dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size); | 1383 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); |
| 914 | if (!dev_priv->gtt.gsm) { | 1384 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; |
| 915 | DRM_ERROR("Failed to map the gtt page table\n"); | ||
| 916 | return -ENOMEM; | ||
| 917 | } | ||
| 918 | 1385 | ||
| 919 | ret = setup_scratch_page(dev); | 1386 | ret = ggtt_probe_common(dev, gtt_size); |
| 920 | if (ret) | ||
| 921 | DRM_ERROR("Scratch setup failed\n"); | ||
| 922 | 1387 | ||
| 923 | dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; | 1388 | dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; |
| 924 | dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; | 1389 | dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; |
| @@ -972,7 +1437,7 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
| 972 | if (INTEL_INFO(dev)->gen <= 5) { | 1437 | if (INTEL_INFO(dev)->gen <= 5) { |
| 973 | gtt->gtt_probe = i915_gmch_probe; | 1438 | gtt->gtt_probe = i915_gmch_probe; |
| 974 | gtt->base.cleanup = i915_gmch_remove; | 1439 | gtt->base.cleanup = i915_gmch_remove; |
| 975 | } else { | 1440 | } else if (INTEL_INFO(dev)->gen < 8) { |
| 976 | gtt->gtt_probe = gen6_gmch_probe; | 1441 | gtt->gtt_probe = gen6_gmch_probe; |
| 977 | gtt->base.cleanup = gen6_gmch_remove; | 1442 | gtt->base.cleanup = gen6_gmch_remove; |
| 978 | if (IS_HASWELL(dev) && dev_priv->ellc_size) | 1443 | if (IS_HASWELL(dev) && dev_priv->ellc_size) |
| @@ -985,6 +1450,9 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
| 985 | gtt->base.pte_encode = ivb_pte_encode; | 1450 | gtt->base.pte_encode = ivb_pte_encode; |
| 986 | else | 1451 | else |
| 987 | gtt->base.pte_encode = snb_pte_encode; | 1452 | gtt->base.pte_encode = snb_pte_encode; |
| 1453 | } else { | ||
| 1454 | dev_priv->gtt.gtt_probe = gen8_gmch_probe; | ||
| 1455 | dev_priv->gtt.base.cleanup = gen6_gmch_remove; | ||
| 988 | } | 1456 | } |
| 989 | 1457 | ||
| 990 | ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, | 1458 | ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, |
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a8bb213da79f..79dcb8f896c6 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
| @@ -624,6 +624,7 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
| 624 | 624 | ||
| 625 | /* Fences */ | 625 | /* Fences */ |
| 626 | switch (INTEL_INFO(dev)->gen) { | 626 | switch (INTEL_INFO(dev)->gen) { |
| 627 | case 8: | ||
| 627 | case 7: | 628 | case 7: |
| 628 | case 6: | 629 | case 6: |
| 629 | for (i = 0; i < dev_priv->num_fence_regs; i++) | 630 | for (i = 0; i < dev_priv->num_fence_regs; i++) |
| @@ -1044,6 +1045,7 @@ void i915_get_extra_instdone(struct drm_device *dev, uint32_t *instdone) | |||
| 1044 | default: | 1045 | default: |
| 1045 | WARN_ONCE(1, "Unsupported platform\n"); | 1046 | WARN_ONCE(1, "Unsupported platform\n"); |
| 1046 | case 7: | 1047 | case 7: |
| 1048 | case 8: | ||
| 1047 | instdone[0] = I915_READ(GEN7_INSTDONE_1); | 1049 | instdone[0] = I915_READ(GEN7_INSTDONE_1); |
| 1048 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); | 1050 | instdone[1] = I915_READ(GEN7_SC_INSTDONE); |
| 1049 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); | 1051 | instdone[2] = I915_READ(GEN7_SAMPLER_INSTDONE); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d26f65212472..5d1dedc02f15 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -270,6 +270,21 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, | |||
| 270 | } | 270 | } |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev, | ||
| 274 | enum pipe pipe, bool enable) | ||
| 275 | { | ||
| 276 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 277 | |||
| 278 | assert_spin_locked(&dev_priv->irq_lock); | ||
| 279 | |||
| 280 | if (enable) | ||
| 281 | dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_FIFO_UNDERRUN; | ||
| 282 | else | ||
| 283 | dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_FIFO_UNDERRUN; | ||
| 284 | I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); | ||
| 285 | POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); | ||
| 286 | } | ||
| 287 | |||
| 273 | /** | 288 | /** |
| 274 | * ibx_display_interrupt_update - update SDEIMR | 289 | * ibx_display_interrupt_update - update SDEIMR |
| 275 | * @dev_priv: driver private | 290 | * @dev_priv: driver private |
| @@ -382,6 +397,8 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, | |||
| 382 | ironlake_set_fifo_underrun_reporting(dev, pipe, enable); | 397 | ironlake_set_fifo_underrun_reporting(dev, pipe, enable); |
| 383 | else if (IS_GEN7(dev)) | 398 | else if (IS_GEN7(dev)) |
| 384 | ivybridge_set_fifo_underrun_reporting(dev, pipe, enable); | 399 | ivybridge_set_fifo_underrun_reporting(dev, pipe, enable); |
| 400 | else if (IS_GEN8(dev)) | ||
| 401 | broadwell_set_fifo_underrun_reporting(dev, pipe, enable); | ||
| 385 | 402 | ||
| 386 | done: | 403 | done: |
| 387 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | 404 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
| @@ -1151,6 +1168,56 @@ static void snb_gt_irq_handler(struct drm_device *dev, | |||
| 1151 | ivybridge_parity_error_irq_handler(dev, gt_iir); | 1168 | ivybridge_parity_error_irq_handler(dev, gt_iir); |
| 1152 | } | 1169 | } |
| 1153 | 1170 | ||
| 1171 | static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, | ||
| 1172 | struct drm_i915_private *dev_priv, | ||
| 1173 | u32 master_ctl) | ||
| 1174 | { | ||
| 1175 | u32 rcs, bcs, vcs; | ||
| 1176 | uint32_t tmp = 0; | ||
| 1177 | irqreturn_t ret = IRQ_NONE; | ||
| 1178 | |||
| 1179 | if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) { | ||
| 1180 | tmp = I915_READ(GEN8_GT_IIR(0)); | ||
| 1181 | if (tmp) { | ||
| 1182 | ret = IRQ_HANDLED; | ||
| 1183 | rcs = tmp >> GEN8_RCS_IRQ_SHIFT; | ||
| 1184 | bcs = tmp >> GEN8_BCS_IRQ_SHIFT; | ||
| 1185 | if (rcs & GT_RENDER_USER_INTERRUPT) | ||
| 1186 | notify_ring(dev, &dev_priv->ring[RCS]); | ||
| 1187 | if (bcs & GT_RENDER_USER_INTERRUPT) | ||
| 1188 | notify_ring(dev, &dev_priv->ring[BCS]); | ||
| 1189 | I915_WRITE(GEN8_GT_IIR(0), tmp); | ||
| 1190 | } else | ||
| 1191 | DRM_ERROR("The master control interrupt lied (GT0)!\n"); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | if (master_ctl & GEN8_GT_VCS1_IRQ) { | ||
| 1195 | tmp = I915_READ(GEN8_GT_IIR(1)); | ||
| 1196 | if (tmp) { | ||
| 1197 | ret = IRQ_HANDLED; | ||
| 1198 | vcs = tmp >> GEN8_VCS1_IRQ_SHIFT; | ||
| 1199 | if (vcs & GT_RENDER_USER_INTERRUPT) | ||
| 1200 | notify_ring(dev, &dev_priv->ring[VCS]); | ||
| 1201 | I915_WRITE(GEN8_GT_IIR(1), tmp); | ||
| 1202 | } else | ||
| 1203 | DRM_ERROR("The master control interrupt lied (GT1)!\n"); | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | if (master_ctl & GEN8_GT_VECS_IRQ) { | ||
| 1207 | tmp = I915_READ(GEN8_GT_IIR(3)); | ||
| 1208 | if (tmp) { | ||
| 1209 | ret = IRQ_HANDLED; | ||
| 1210 | vcs = tmp >> GEN8_VECS_IRQ_SHIFT; | ||
| 1211 | if (vcs & GT_RENDER_USER_INTERRUPT) | ||
| 1212 | notify_ring(dev, &dev_priv->ring[VECS]); | ||
| 1213 | I915_WRITE(GEN8_GT_IIR(3), tmp); | ||
| 1214 | } else | ||
| 1215 | DRM_ERROR("The master control interrupt lied (GT3)!\n"); | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | return ret; | ||
| 1219 | } | ||
| 1220 | |||
| 1154 | #define HPD_STORM_DETECT_PERIOD 1000 | 1221 | #define HPD_STORM_DETECT_PERIOD 1000 |
| 1155 | #define HPD_STORM_THRESHOLD 5 | 1222 | #define HPD_STORM_THRESHOLD 5 |
| 1156 | 1223 | ||
| @@ -1724,6 +1791,117 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) | |||
| 1724 | return ret; | 1791 | return ret; |
| 1725 | } | 1792 | } |
| 1726 | 1793 | ||
| 1794 | static irqreturn_t gen8_irq_handler(int irq, void *arg) | ||
| 1795 | { | ||
| 1796 | struct drm_device *dev = arg; | ||
| 1797 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1798 | u32 master_ctl; | ||
| 1799 | irqreturn_t ret = IRQ_NONE; | ||
| 1800 | uint32_t tmp = 0; | ||
| 1801 | enum pipe pipe; | ||
| 1802 | |||
| 1803 | atomic_inc(&dev_priv->irq_received); | ||
| 1804 | |||
| 1805 | master_ctl = I915_READ(GEN8_MASTER_IRQ); | ||
| 1806 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; | ||
| 1807 | if (!master_ctl) | ||
| 1808 | return IRQ_NONE; | ||
| 1809 | |||
| 1810 | I915_WRITE(GEN8_MASTER_IRQ, 0); | ||
| 1811 | POSTING_READ(GEN8_MASTER_IRQ); | ||
| 1812 | |||
| 1813 | ret = gen8_gt_irq_handler(dev, dev_priv, master_ctl); | ||
| 1814 | |||
| 1815 | if (master_ctl & GEN8_DE_MISC_IRQ) { | ||
| 1816 | tmp = I915_READ(GEN8_DE_MISC_IIR); | ||
| 1817 | if (tmp & GEN8_DE_MISC_GSE) | ||
| 1818 | intel_opregion_asle_intr(dev); | ||
| 1819 | else if (tmp) | ||
| 1820 | DRM_ERROR("Unexpected DE Misc interrupt\n"); | ||
| 1821 | else | ||
| 1822 | DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); | ||
| 1823 | |||
| 1824 | if (tmp) { | ||
| 1825 | I915_WRITE(GEN8_DE_MISC_IIR, tmp); | ||
| 1826 | ret = IRQ_HANDLED; | ||
| 1827 | } | ||
| 1828 | } | ||
| 1829 | |||
| 1830 | if (master_ctl & GEN8_DE_PORT_IRQ) { | ||
| 1831 | tmp = I915_READ(GEN8_DE_PORT_IIR); | ||
| 1832 | if (tmp & GEN8_AUX_CHANNEL_A) | ||
| 1833 | dp_aux_irq_handler(dev); | ||
| 1834 | else if (tmp) | ||
| 1835 | DRM_ERROR("Unexpected DE Port interrupt\n"); | ||
| 1836 | else | ||
| 1837 | DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); | ||
| 1838 | |||
| 1839 | if (tmp) { | ||
| 1840 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); | ||
| 1841 | ret = IRQ_HANDLED; | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | for_each_pipe(pipe) { | ||
| 1846 | uint32_t pipe_iir; | ||
| 1847 | |||
| 1848 | if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) | ||
| 1849 | continue; | ||
| 1850 | |||
| 1851 | pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); | ||
| 1852 | if (pipe_iir & GEN8_PIPE_VBLANK) | ||
| 1853 | drm_handle_vblank(dev, pipe); | ||
| 1854 | |||
| 1855 | if (pipe_iir & GEN8_PIPE_FLIP_DONE) { | ||
| 1856 | intel_prepare_page_flip(dev, pipe); | ||
| 1857 | intel_finish_page_flip_plane(dev, pipe); | ||
| 1858 | } | ||
| 1859 | |||
| 1860 | if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) | ||
| 1861 | hsw_pipe_crc_irq_handler(dev, pipe); | ||
| 1862 | |||
| 1863 | if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) { | ||
| 1864 | if (intel_set_cpu_fifo_underrun_reporting(dev, pipe, | ||
| 1865 | false)) | ||
| 1866 | DRM_DEBUG_DRIVER("Pipe %c FIFO underrun\n", | ||
| 1867 | pipe_name(pipe)); | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | if (pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS) { | ||
| 1871 | DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", | ||
| 1872 | pipe_name(pipe), | ||
| 1873 | pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS); | ||
| 1874 | } | ||
| 1875 | |||
| 1876 | if (pipe_iir) { | ||
| 1877 | ret = IRQ_HANDLED; | ||
| 1878 | I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); | ||
| 1879 | } else | ||
| 1880 | DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | if (!HAS_PCH_NOP(dev) && master_ctl & GEN8_DE_PCH_IRQ) { | ||
| 1884 | /* | ||
| 1885 | * FIXME(BDW): Assume for now that the new interrupt handling | ||
| 1886 | * scheme also closed the SDE interrupt handling race we've seen | ||
| 1887 | * on older pch-split platforms. But this needs testing. | ||
| 1888 | */ | ||
| 1889 | u32 pch_iir = I915_READ(SDEIIR); | ||
| 1890 | |||
| 1891 | cpt_irq_handler(dev, pch_iir); | ||
| 1892 | |||
| 1893 | if (pch_iir) { | ||
| 1894 | I915_WRITE(SDEIIR, pch_iir); | ||
| 1895 | ret = IRQ_HANDLED; | ||
| 1896 | } | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); | ||
| 1900 | POSTING_READ(GEN8_MASTER_IRQ); | ||
| 1901 | |||
| 1902 | return ret; | ||
| 1903 | } | ||
| 1904 | |||
| 1727 | static void i915_error_wake_up(struct drm_i915_private *dev_priv, | 1905 | static void i915_error_wake_up(struct drm_i915_private *dev_priv, |
| 1728 | bool reset_completed) | 1906 | bool reset_completed) |
| 1729 | { | 1907 | { |
| @@ -2077,6 +2255,22 @@ static int valleyview_enable_vblank(struct drm_device *dev, int pipe) | |||
| 2077 | return 0; | 2255 | return 0; |
| 2078 | } | 2256 | } |
| 2079 | 2257 | ||
| 2258 | static int gen8_enable_vblank(struct drm_device *dev, int pipe) | ||
| 2259 | { | ||
| 2260 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2261 | unsigned long irqflags; | ||
| 2262 | |||
| 2263 | if (!i915_pipe_enabled(dev, pipe)) | ||
| 2264 | return -EINVAL; | ||
| 2265 | |||
| 2266 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
| 2267 | dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_VBLANK; | ||
| 2268 | I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); | ||
| 2269 | POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); | ||
| 2270 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
| 2271 | return 0; | ||
| 2272 | } | ||
| 2273 | |||
| 2080 | /* Called from drm generic code, passed 'crtc' which | 2274 | /* Called from drm generic code, passed 'crtc' which |
| 2081 | * we use as a pipe index | 2275 | * we use as a pipe index |
| 2082 | */ | 2276 | */ |
| @@ -2125,6 +2319,21 @@ static void valleyview_disable_vblank(struct drm_device *dev, int pipe) | |||
| 2125 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 2319 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
| 2126 | } | 2320 | } |
| 2127 | 2321 | ||
| 2322 | static void gen8_disable_vblank(struct drm_device *dev, int pipe) | ||
| 2323 | { | ||
| 2324 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2325 | unsigned long irqflags; | ||
| 2326 | |||
| 2327 | if (!i915_pipe_enabled(dev, pipe)) | ||
| 2328 | return; | ||
| 2329 | |||
| 2330 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | ||
| 2331 | dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_VBLANK; | ||
| 2332 | I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); | ||
| 2333 | POSTING_READ(GEN8_DE_PIPE_IMR(pipe)); | ||
| 2334 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
| 2335 | } | ||
| 2336 | |||
| 2128 | static u32 | 2337 | static u32 |
| 2129 | ring_last_seqno(struct intel_ring_buffer *ring) | 2338 | ring_last_seqno(struct intel_ring_buffer *ring) |
| 2130 | { | 2339 | { |
| @@ -2459,6 +2668,53 @@ static void valleyview_irq_preinstall(struct drm_device *dev) | |||
| 2459 | POSTING_READ(VLV_IER); | 2668 | POSTING_READ(VLV_IER); |
| 2460 | } | 2669 | } |
| 2461 | 2670 | ||
| 2671 | static void gen8_irq_preinstall(struct drm_device *dev) | ||
| 2672 | { | ||
| 2673 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2674 | int pipe; | ||
| 2675 | |||
| 2676 | atomic_set(&dev_priv->irq_received, 0); | ||
| 2677 | |||
| 2678 | I915_WRITE(GEN8_MASTER_IRQ, 0); | ||
| 2679 | POSTING_READ(GEN8_MASTER_IRQ); | ||
| 2680 | |||
| 2681 | /* IIR can theoretically queue up two events. Be paranoid */ | ||
| 2682 | #define GEN8_IRQ_INIT_NDX(type, which) do { \ | ||
| 2683 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ | ||
| 2684 | POSTING_READ(GEN8_##type##_IMR(which)); \ | ||
| 2685 | I915_WRITE(GEN8_##type##_IER(which), 0); \ | ||
| 2686 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ | ||
| 2687 | POSTING_READ(GEN8_##type##_IIR(which)); \ | ||
| 2688 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ | ||
| 2689 | } while (0) | ||
| 2690 | |||
| 2691 | #define GEN8_IRQ_INIT(type) do { \ | ||
| 2692 | I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ | ||
| 2693 | POSTING_READ(GEN8_##type##_IMR); \ | ||
| 2694 | I915_WRITE(GEN8_##type##_IER, 0); \ | ||
| 2695 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ | ||
| 2696 | POSTING_READ(GEN8_##type##_IIR); \ | ||
| 2697 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ | ||
| 2698 | } while (0) | ||
| 2699 | |||
| 2700 | GEN8_IRQ_INIT_NDX(GT, 0); | ||
| 2701 | GEN8_IRQ_INIT_NDX(GT, 1); | ||
| 2702 | GEN8_IRQ_INIT_NDX(GT, 2); | ||
| 2703 | GEN8_IRQ_INIT_NDX(GT, 3); | ||
| 2704 | |||
| 2705 | for_each_pipe(pipe) { | ||
| 2706 | GEN8_IRQ_INIT_NDX(DE_PIPE, pipe); | ||
| 2707 | } | ||
| 2708 | |||
| 2709 | GEN8_IRQ_INIT(DE_PORT); | ||
| 2710 | GEN8_IRQ_INIT(DE_MISC); | ||
| 2711 | GEN8_IRQ_INIT(PCU); | ||
| 2712 | #undef GEN8_IRQ_INIT | ||
| 2713 | #undef GEN8_IRQ_INIT_NDX | ||
| 2714 | |||
| 2715 | POSTING_READ(GEN8_PCU_IIR); | ||
| 2716 | } | ||
| 2717 | |||
| 2462 | static void ibx_hpd_irq_setup(struct drm_device *dev) | 2718 | static void ibx_hpd_irq_setup(struct drm_device *dev) |
| 2463 | { | 2719 | { |
| 2464 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2720 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| @@ -2664,6 +2920,117 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
| 2664 | return 0; | 2920 | return 0; |
| 2665 | } | 2921 | } |
| 2666 | 2922 | ||
| 2923 | static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) | ||
| 2924 | { | ||
| 2925 | int i; | ||
| 2926 | |||
| 2927 | /* These are interrupts we'll toggle with the ring mask register */ | ||
| 2928 | uint32_t gt_interrupts[] = { | ||
| 2929 | GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | | ||
| 2930 | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | | ||
| 2931 | GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT, | ||
| 2932 | GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT | | ||
| 2933 | GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, | ||
| 2934 | 0, | ||
| 2935 | GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT | ||
| 2936 | }; | ||
| 2937 | |||
| 2938 | for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++) { | ||
| 2939 | u32 tmp = I915_READ(GEN8_GT_IIR(i)); | ||
| 2940 | if (tmp) | ||
| 2941 | DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n", | ||
| 2942 | i, tmp); | ||
| 2943 | I915_WRITE(GEN8_GT_IMR(i), ~gt_interrupts[i]); | ||
| 2944 | I915_WRITE(GEN8_GT_IER(i), gt_interrupts[i]); | ||
| 2945 | } | ||
| 2946 | POSTING_READ(GEN8_GT_IER(0)); | ||
| 2947 | } | ||
| 2948 | |||
| 2949 | static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | ||
| 2950 | { | ||
| 2951 | struct drm_device *dev = dev_priv->dev; | ||
| 2952 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | | ||
| 2953 | GEN8_PIPE_CDCLK_CRC_DONE | | ||
| 2954 | GEN8_PIPE_FIFO_UNDERRUN | | ||
| 2955 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | ||
| 2956 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; | ||
| 2957 | int pipe; | ||
| 2958 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; | ||
| 2959 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; | ||
| 2960 | dev_priv->de_irq_mask[PIPE_C] = ~de_pipe_masked; | ||
| 2961 | |||
| 2962 | for_each_pipe(pipe) { | ||
| 2963 | u32 tmp = I915_READ(GEN8_DE_PIPE_IIR(pipe)); | ||
| 2964 | if (tmp) | ||
| 2965 | DRM_ERROR("Interrupt (%d) should have been masked in pre-install 0x%08x\n", | ||
| 2966 | pipe, tmp); | ||
| 2967 | I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]); | ||
| 2968 | I915_WRITE(GEN8_DE_PIPE_IER(pipe), de_pipe_enables); | ||
| 2969 | } | ||
| 2970 | POSTING_READ(GEN8_DE_PIPE_ISR(0)); | ||
| 2971 | |||
| 2972 | I915_WRITE(GEN8_DE_PORT_IMR, ~GEN8_AUX_CHANNEL_A); | ||
| 2973 | I915_WRITE(GEN8_DE_PORT_IER, GEN8_AUX_CHANNEL_A); | ||
| 2974 | POSTING_READ(GEN8_DE_PORT_IER); | ||
| 2975 | } | ||
| 2976 | |||
| 2977 | static int gen8_irq_postinstall(struct drm_device *dev) | ||
| 2978 | { | ||
| 2979 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2980 | |||
| 2981 | gen8_gt_irq_postinstall(dev_priv); | ||
| 2982 | gen8_de_irq_postinstall(dev_priv); | ||
| 2983 | |||
| 2984 | ibx_irq_postinstall(dev); | ||
| 2985 | |||
| 2986 | I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); | ||
| 2987 | POSTING_READ(GEN8_MASTER_IRQ); | ||
| 2988 | |||
| 2989 | return 0; | ||
| 2990 | } | ||
| 2991 | |||
| 2992 | static void gen8_irq_uninstall(struct drm_device *dev) | ||
| 2993 | { | ||
| 2994 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 2995 | int pipe; | ||
| 2996 | |||
| 2997 | if (!dev_priv) | ||
| 2998 | return; | ||
| 2999 | |||
| 3000 | atomic_set(&dev_priv->irq_received, 0); | ||
| 3001 | |||
| 3002 | I915_WRITE(GEN8_MASTER_IRQ, 0); | ||
| 3003 | |||
| 3004 | #define GEN8_IRQ_FINI_NDX(type, which) do { \ | ||
| 3005 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ | ||
| 3006 | I915_WRITE(GEN8_##type##_IER(which), 0); \ | ||
| 3007 | I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ | ||
| 3008 | } while (0) | ||
| 3009 | |||
| 3010 | #define GEN8_IRQ_FINI(type) do { \ | ||
| 3011 | I915_WRITE(GEN8_##type##_IMR, 0xffffffff); \ | ||
| 3012 | I915_WRITE(GEN8_##type##_IER, 0); \ | ||
| 3013 | I915_WRITE(GEN8_##type##_IIR, 0xffffffff); \ | ||
| 3014 | } while (0) | ||
| 3015 | |||
| 3016 | GEN8_IRQ_FINI_NDX(GT, 0); | ||
| 3017 | GEN8_IRQ_FINI_NDX(GT, 1); | ||
| 3018 | GEN8_IRQ_FINI_NDX(GT, 2); | ||
| 3019 | GEN8_IRQ_FINI_NDX(GT, 3); | ||
| 3020 | |||
| 3021 | for_each_pipe(pipe) { | ||
| 3022 | GEN8_IRQ_FINI_NDX(DE_PIPE, pipe); | ||
| 3023 | } | ||
| 3024 | |||
| 3025 | GEN8_IRQ_FINI(DE_PORT); | ||
| 3026 | GEN8_IRQ_FINI(DE_MISC); | ||
| 3027 | GEN8_IRQ_FINI(PCU); | ||
| 3028 | #undef GEN8_IRQ_FINI | ||
| 3029 | #undef GEN8_IRQ_FINI_NDX | ||
| 3030 | |||
| 3031 | POSTING_READ(GEN8_PCU_IIR); | ||
| 3032 | } | ||
| 3033 | |||
| 2667 | static void valleyview_irq_uninstall(struct drm_device *dev) | 3034 | static void valleyview_irq_uninstall(struct drm_device *dev) |
| 2668 | { | 3035 | { |
| 2669 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 3036 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
| @@ -3443,6 +3810,14 @@ void intel_irq_init(struct drm_device *dev) | |||
| 3443 | dev->driver->enable_vblank = valleyview_enable_vblank; | 3810 | dev->driver->enable_vblank = valleyview_enable_vblank; |
| 3444 | dev->driver->disable_vblank = valleyview_disable_vblank; | 3811 | dev->driver->disable_vblank = valleyview_disable_vblank; |
| 3445 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; | 3812 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; |
| 3813 | } else if (IS_GEN8(dev)) { | ||
| 3814 | dev->driver->irq_handler = gen8_irq_handler; | ||
| 3815 | dev->driver->irq_preinstall = gen8_irq_preinstall; | ||
| 3816 | dev->driver->irq_postinstall = gen8_irq_postinstall; | ||
| 3817 | dev->driver->irq_uninstall = gen8_irq_uninstall; | ||
| 3818 | dev->driver->enable_vblank = gen8_enable_vblank; | ||
| 3819 | dev->driver->disable_vblank = gen8_disable_vblank; | ||
| 3820 | dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; | ||
| 3446 | } else if (HAS_PCH_SPLIT(dev)) { | 3821 | } else if (HAS_PCH_SPLIT(dev)) { |
| 3447 | dev->driver->irq_handler = ironlake_irq_handler; | 3822 | dev->driver->irq_handler = ironlake_irq_handler; |
| 3448 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | 3823 | dev->driver->irq_preinstall = ironlake_irq_preinstall; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 04896da9001c..f9eafb6ed523 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -110,6 +110,9 @@ | |||
| 110 | #define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) | 110 | #define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) |
| 111 | #define PP_DIR_DCLV_2G 0xffffffff | 111 | #define PP_DIR_DCLV_2G 0xffffffff |
| 112 | 112 | ||
| 113 | #define GEN8_RING_PDP_UDW(ring, n) ((ring)->mmio_base+0x270 + ((n) * 8 + 4)) | ||
| 114 | #define GEN8_RING_PDP_LDW(ring, n) ((ring)->mmio_base+0x270 + (n) * 8) | ||
| 115 | |||
| 113 | #define GAM_ECOCHK 0x4090 | 116 | #define GAM_ECOCHK 0x4090 |
| 114 | #define ECOCHK_SNB_BIT (1<<10) | 117 | #define ECOCHK_SNB_BIT (1<<10) |
| 115 | #define HSW_ECOCHK_ARB_PRIO_SOL (1<<6) | 118 | #define HSW_ECOCHK_ARB_PRIO_SOL (1<<6) |
| @@ -247,6 +250,7 @@ | |||
| 247 | #define MI_BATCH_NON_SECURE_HSW (1<<13) | 250 | #define MI_BATCH_NON_SECURE_HSW (1<<13) |
| 248 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) | 251 | #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) |
| 249 | #define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */ | 252 | #define MI_BATCH_GTT (2<<6) /* aliased with (1<<7) on gen4 */ |
| 253 | #define MI_BATCH_BUFFER_START_GEN8 MI_INSTR(0x31, 1) | ||
| 250 | #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ | 254 | #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ |
| 251 | #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) | 255 | #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) |
| 252 | #define MI_SEMAPHORE_UPDATE (1<<21) | 256 | #define MI_SEMAPHORE_UPDATE (1<<21) |
| @@ -655,6 +659,9 @@ | |||
| 655 | #define ARB_MODE 0x04030 | 659 | #define ARB_MODE 0x04030 |
| 656 | #define ARB_MODE_SWIZZLE_SNB (1<<4) | 660 | #define ARB_MODE_SWIZZLE_SNB (1<<4) |
| 657 | #define ARB_MODE_SWIZZLE_IVB (1<<5) | 661 | #define ARB_MODE_SWIZZLE_IVB (1<<5) |
| 662 | #define GAMTARBMODE 0x04a08 | ||
| 663 | #define ARB_MODE_BWGTLB_DISABLE (1<<9) | ||
| 664 | #define ARB_MODE_SWIZZLE_BDW (1<<1) | ||
| 658 | #define RENDER_HWS_PGA_GEN7 (0x04080) | 665 | #define RENDER_HWS_PGA_GEN7 (0x04080) |
| 659 | #define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) | 666 | #define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) |
| 660 | #define RING_FAULT_GTTSEL_MASK (1<<11) | 667 | #define RING_FAULT_GTTSEL_MASK (1<<11) |
| @@ -662,6 +669,7 @@ | |||
| 662 | #define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) | 669 | #define RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3) |
| 663 | #define RING_FAULT_VALID (1<<0) | 670 | #define RING_FAULT_VALID (1<<0) |
| 664 | #define DONE_REG 0x40b0 | 671 | #define DONE_REG 0x40b0 |
| 672 | #define GEN8_PRIVATE_PAT 0x40e0 | ||
| 665 | #define BSD_HWS_PGA_GEN7 (0x04180) | 673 | #define BSD_HWS_PGA_GEN7 (0x04180) |
| 666 | #define BLT_HWS_PGA_GEN7 (0x04280) | 674 | #define BLT_HWS_PGA_GEN7 (0x04280) |
| 667 | #define VEBOX_HWS_PGA_GEN7 (0x04380) | 675 | #define VEBOX_HWS_PGA_GEN7 (0x04380) |
| @@ -741,6 +749,7 @@ | |||
| 741 | #define FPGA_DBG_RM_NOCLAIM (1<<31) | 749 | #define FPGA_DBG_RM_NOCLAIM (1<<31) |
| 742 | 750 | ||
| 743 | #define DERRMR 0x44050 | 751 | #define DERRMR 0x44050 |
| 752 | /* Note that HBLANK events are reserved on bdw+ */ | ||
| 744 | #define DERRMR_PIPEA_SCANLINE (1<<0) | 753 | #define DERRMR_PIPEA_SCANLINE (1<<0) |
| 745 | #define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1) | 754 | #define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1) |
| 746 | #define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2) | 755 | #define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2) |
| @@ -774,6 +783,7 @@ | |||
| 774 | #define _3D_CHICKEN3 0x02090 | 783 | #define _3D_CHICKEN3 0x02090 |
| 775 | #define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10) | 784 | #define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10) |
| 776 | #define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5) | 785 | #define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5) |
| 786 | #define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(x) ((x)<<1) | ||
| 777 | 787 | ||
| 778 | #define MI_MODE 0x0209c | 788 | #define MI_MODE 0x0209c |
| 779 | # define VS_TIMER_DISPATCH (1 << 6) | 789 | # define VS_TIMER_DISPATCH (1 << 6) |
| @@ -1820,6 +1830,9 @@ | |||
| 1820 | * on HSW) - so the final size is 66944 bytes, which rounds to 17 pages. | 1830 | * on HSW) - so the final size is 66944 bytes, which rounds to 17 pages. |
| 1821 | */ | 1831 | */ |
| 1822 | #define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE) | 1832 | #define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE) |
| 1833 | /* Same as Haswell, but 72064 bytes now. */ | ||
| 1834 | #define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE) | ||
| 1835 | |||
| 1823 | 1836 | ||
| 1824 | #define VLV_CLK_CTL2 0x101104 | 1837 | #define VLV_CLK_CTL2 0x101104 |
| 1825 | #define CLK_CTL2_CZCOUNT_30NS_SHIFT 28 | 1838 | #define CLK_CTL2_CZCOUNT_30NS_SHIFT 28 |
| @@ -1950,8 +1963,8 @@ | |||
| 1950 | #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) | 1963 | #define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B) |
| 1951 | #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) | 1964 | #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B) |
| 1952 | 1965 | ||
| 1953 | /* HSW eDP PSR registers */ | 1966 | /* HSW+ eDP PSR registers */ |
| 1954 | #define EDP_PSR_BASE(dev) 0x64800 | 1967 | #define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800) |
| 1955 | #define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0) | 1968 | #define EDP_PSR_CTL(dev) (EDP_PSR_BASE(dev) + 0) |
| 1956 | #define EDP_PSR_ENABLE (1<<31) | 1969 | #define EDP_PSR_ENABLE (1<<31) |
| 1957 | #define EDP_PSR_LINK_DISABLE (0<<27) | 1970 | #define EDP_PSR_LINK_DISABLE (0<<27) |
| @@ -3241,6 +3254,18 @@ | |||
| 3241 | #define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL) | 3254 | #define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL) |
| 3242 | #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) | 3255 | #define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT) |
| 3243 | 3256 | ||
| 3257 | #define _PIPE_MISC_A 0x70030 | ||
| 3258 | #define _PIPE_MISC_B 0x71030 | ||
| 3259 | #define PIPEMISC_DITHER_BPC_MASK (7<<5) | ||
| 3260 | #define PIPEMISC_DITHER_8_BPC (0<<5) | ||
| 3261 | #define PIPEMISC_DITHER_10_BPC (1<<5) | ||
| 3262 | #define PIPEMISC_DITHER_6_BPC (2<<5) | ||
| 3263 | #define PIPEMISC_DITHER_12_BPC (3<<5) | ||
| 3264 | #define PIPEMISC_DITHER_ENABLE (1<<4) | ||
| 3265 | #define PIPEMISC_DITHER_TYPE_MASK (3<<2) | ||
| 3266 | #define PIPEMISC_DITHER_TYPE_SP (0<<2) | ||
| 3267 | #define PIPEMISC(pipe) _PIPE(pipe, _PIPE_MISC_A, _PIPE_MISC_B) | ||
| 3268 | |||
| 3244 | #define VLV_DPFLIPSTAT (VLV_DISPLAY_BASE + 0x70028) | 3269 | #define VLV_DPFLIPSTAT (VLV_DISPLAY_BASE + 0x70028) |
| 3245 | #define PIPEB_LINE_COMPARE_INT_EN (1<<29) | 3270 | #define PIPEB_LINE_COMPARE_INT_EN (1<<29) |
| 3246 | #define PIPEB_HLINE_INT_EN (1<<28) | 3271 | #define PIPEB_HLINE_INT_EN (1<<28) |
| @@ -3371,6 +3396,7 @@ | |||
| 3371 | #define WM1_LP_LATENCY_MASK (0x7f<<24) | 3396 | #define WM1_LP_LATENCY_MASK (0x7f<<24) |
| 3372 | #define WM1_LP_FBC_MASK (0xf<<20) | 3397 | #define WM1_LP_FBC_MASK (0xf<<20) |
| 3373 | #define WM1_LP_FBC_SHIFT 20 | 3398 | #define WM1_LP_FBC_SHIFT 20 |
| 3399 | #define WM1_LP_FBC_SHIFT_BDW 19 | ||
| 3374 | #define WM1_LP_SR_MASK (0x7ff<<8) | 3400 | #define WM1_LP_SR_MASK (0x7ff<<8) |
| 3375 | #define WM1_LP_SR_SHIFT 8 | 3401 | #define WM1_LP_SR_SHIFT 8 |
| 3376 | #define WM1_LP_CURSOR_MASK (0xff) | 3402 | #define WM1_LP_CURSOR_MASK (0xff) |
| @@ -4011,6 +4037,71 @@ | |||
| 4011 | #define GTIIR 0x44018 | 4037 | #define GTIIR 0x44018 |
| 4012 | #define GTIER 0x4401c | 4038 | #define GTIER 0x4401c |
| 4013 | 4039 | ||
| 4040 | #define GEN8_MASTER_IRQ 0x44200 | ||
| 4041 | #define GEN8_MASTER_IRQ_CONTROL (1<<31) | ||
| 4042 | #define GEN8_PCU_IRQ (1<<30) | ||
| 4043 | #define GEN8_DE_PCH_IRQ (1<<23) | ||
| 4044 | #define GEN8_DE_MISC_IRQ (1<<22) | ||
| 4045 | #define GEN8_DE_PORT_IRQ (1<<20) | ||
| 4046 | #define GEN8_DE_PIPE_C_IRQ (1<<18) | ||
| 4047 | #define GEN8_DE_PIPE_B_IRQ (1<<17) | ||
| 4048 | #define GEN8_DE_PIPE_A_IRQ (1<<16) | ||
| 4049 | #define GEN8_DE_PIPE_IRQ(pipe) (1<<(16+pipe)) | ||
| 4050 | #define GEN8_GT_VECS_IRQ (1<<6) | ||
| 4051 | #define GEN8_GT_VCS2_IRQ (1<<3) | ||
| 4052 | #define GEN8_GT_VCS1_IRQ (1<<2) | ||
| 4053 | #define GEN8_GT_BCS_IRQ (1<<1) | ||
| 4054 | #define GEN8_GT_RCS_IRQ (1<<0) | ||
| 4055 | |||
| 4056 | #define GEN8_GT_ISR(which) (0x44300 + (0x10 * (which))) | ||
| 4057 | #define GEN8_GT_IMR(which) (0x44304 + (0x10 * (which))) | ||
| 4058 | #define GEN8_GT_IIR(which) (0x44308 + (0x10 * (which))) | ||
| 4059 | #define GEN8_GT_IER(which) (0x4430c + (0x10 * (which))) | ||
| 4060 | |||
| 4061 | #define GEN8_BCS_IRQ_SHIFT 16 | ||
| 4062 | #define GEN8_RCS_IRQ_SHIFT 0 | ||
| 4063 | #define GEN8_VCS2_IRQ_SHIFT 16 | ||
| 4064 | #define GEN8_VCS1_IRQ_SHIFT 0 | ||
| 4065 | #define GEN8_VECS_IRQ_SHIFT 0 | ||
| 4066 | |||
| 4067 | #define GEN8_DE_PIPE_ISR(pipe) (0x44400 + (0x10 * (pipe))) | ||
| 4068 | #define GEN8_DE_PIPE_IMR(pipe) (0x44404 + (0x10 * (pipe))) | ||
| 4069 | #define GEN8_DE_PIPE_IIR(pipe) (0x44408 + (0x10 * (pipe))) | ||
| 4070 | #define GEN8_DE_PIPE_IER(pipe) (0x4440c + (0x10 * (pipe))) | ||
| 4071 | #define GEN8_PIPE_FIFO_UNDERRUN (1 << 31) | ||
| 4072 | #define GEN8_PIPE_CDCLK_CRC_ERROR (1 << 29) | ||
| 4073 | #define GEN8_PIPE_CDCLK_CRC_DONE (1 << 28) | ||
| 4074 | #define GEN8_PIPE_CURSOR_FAULT (1 << 10) | ||
| 4075 | #define GEN8_PIPE_SPRITE_FAULT (1 << 9) | ||
| 4076 | #define GEN8_PIPE_PRIMARY_FAULT (1 << 8) | ||
| 4077 | #define GEN8_PIPE_SPRITE_FLIP_DONE (1 << 5) | ||
| 4078 | #define GEN8_PIPE_FLIP_DONE (1 << 4) | ||
| 4079 | #define GEN8_PIPE_SCAN_LINE_EVENT (1 << 2) | ||
| 4080 | #define GEN8_PIPE_VSYNC (1 << 1) | ||
| 4081 | #define GEN8_PIPE_VBLANK (1 << 0) | ||
| 4082 | #define GEN8_DE_PIPE_IRQ_FAULT_ERRORS \ | ||
| 4083 | (GEN8_PIPE_CURSOR_FAULT | \ | ||
| 4084 | GEN8_PIPE_SPRITE_FAULT | \ | ||
| 4085 | GEN8_PIPE_PRIMARY_FAULT) | ||
| 4086 | |||
| 4087 | #define GEN8_DE_PORT_ISR 0x44440 | ||
| 4088 | #define GEN8_DE_PORT_IMR 0x44444 | ||
| 4089 | #define GEN8_DE_PORT_IIR 0x44448 | ||
| 4090 | #define GEN8_DE_PORT_IER 0x4444c | ||
| 4091 | #define GEN8_PORT_DP_A_HOTPLUG (1 << 3) | ||
| 4092 | #define GEN8_AUX_CHANNEL_A (1 << 0) | ||
| 4093 | |||
| 4094 | #define GEN8_DE_MISC_ISR 0x44460 | ||
| 4095 | #define GEN8_DE_MISC_IMR 0x44464 | ||
| 4096 | #define GEN8_DE_MISC_IIR 0x44468 | ||
| 4097 | #define GEN8_DE_MISC_IER 0x4446c | ||
| 4098 | #define GEN8_DE_MISC_GSE (1 << 27) | ||
| 4099 | |||
| 4100 | #define GEN8_PCU_ISR 0x444e0 | ||
| 4101 | #define GEN8_PCU_IMR 0x444e4 | ||
| 4102 | #define GEN8_PCU_IIR 0x444e8 | ||
| 4103 | #define GEN8_PCU_IER 0x444ec | ||
| 4104 | |||
| 4014 | #define ILK_DISPLAY_CHICKEN2 0x42004 | 4105 | #define ILK_DISPLAY_CHICKEN2 0x42004 |
| 4015 | /* Required on all Ironlake and Sandybridge according to the B-Spec. */ | 4106 | /* Required on all Ironlake and Sandybridge according to the B-Spec. */ |
| 4016 | #define ILK_ELPIN_409_SELECT (1 << 25) | 4107 | #define ILK_ELPIN_409_SELECT (1 << 25) |
| @@ -4036,8 +4127,14 @@ | |||
| 4036 | # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) | 4127 | # define CHICKEN3_DGMG_DONE_FIX_DISABLE (1 << 2) |
| 4037 | 4128 | ||
| 4038 | #define CHICKEN_PAR1_1 0x42080 | 4129 | #define CHICKEN_PAR1_1 0x42080 |
| 4130 | #define DPA_MASK_VBLANK_SRD (1 << 15) | ||
| 4039 | #define FORCE_ARB_IDLE_PLANES (1 << 14) | 4131 | #define FORCE_ARB_IDLE_PLANES (1 << 14) |
| 4040 | 4132 | ||
| 4133 | #define _CHICKEN_PIPESL_1_A 0x420b0 | ||
| 4134 | #define _CHICKEN_PIPESL_1_B 0x420b4 | ||
| 4135 | #define DPRS_MASK_VBLANK_SRD (1 << 0) | ||
| 4136 | #define CHICKEN_PIPESL_1(pipe) _PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B) | ||
| 4137 | |||
| 4041 | #define DISP_ARB_CTL 0x45000 | 4138 | #define DISP_ARB_CTL 0x45000 |
| 4042 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) | 4139 | #define DISP_TILE_SURFACE_SWIZZLING (1<<13) |
| 4043 | #define DISP_FBC_WM_DIS (1<<15) | 4140 | #define DISP_FBC_WM_DIS (1<<15) |
| @@ -4048,6 +4145,8 @@ | |||
| 4048 | /* GEN7 chicken */ | 4145 | /* GEN7 chicken */ |
| 4049 | #define GEN7_COMMON_SLICE_CHICKEN1 0x7010 | 4146 | #define GEN7_COMMON_SLICE_CHICKEN1 0x7010 |
| 4050 | # define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) | 4147 | # define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) |
| 4148 | #define COMMON_SLICE_CHICKEN2 0x7014 | ||
| 4149 | # define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0) | ||
| 4051 | 4150 | ||
| 4052 | #define GEN7_L3CNTLREG1 0xB01C | 4151 | #define GEN7_L3CNTLREG1 0xB01C |
| 4053 | #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C | 4152 | #define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C |
| @@ -4876,6 +4975,7 @@ | |||
| 4876 | #define GEN6_PCODE_WRITE_D_COMP 0x11 | 4975 | #define GEN6_PCODE_WRITE_D_COMP 0x11 |
| 4877 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) | 4976 | #define GEN6_ENCODE_RC6_VID(mv) (((mv) - 245) / 5) |
| 4878 | #define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) | 4977 | #define GEN6_DECODE_RC6_VID(vids) (((vids) * 5) + 245) |
| 4978 | #define DISPLAY_IPS_CONTROL 0x19 | ||
| 4879 | #define GEN6_PCODE_DATA 0x138128 | 4979 | #define GEN6_PCODE_DATA 0x138128 |
| 4880 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 | 4980 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 |
| 4881 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 | 4981 | #define GEN6_PCODE_FREQ_RING_RATIO_SHIFT 16 |
| @@ -4913,6 +5013,7 @@ | |||
| 4913 | #define GEN7_HALF_SLICE_CHICKEN1 0xe100 /* IVB GT1 + VLV */ | 5013 | #define GEN7_HALF_SLICE_CHICKEN1 0xe100 /* IVB GT1 + VLV */ |
| 4914 | #define GEN7_HALF_SLICE_CHICKEN1_GT2 0xf100 | 5014 | #define GEN7_HALF_SLICE_CHICKEN1_GT2 0xf100 |
| 4915 | #define GEN7_MAX_PS_THREAD_DEP (8<<12) | 5015 | #define GEN7_MAX_PS_THREAD_DEP (8<<12) |
| 5016 | #define GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE (1<<10) | ||
| 4916 | #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) | 5017 | #define GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE (1<<3) |
| 4917 | 5018 | ||
| 4918 | #define GEN7_ROW_CHICKEN2 0xe4f4 | 5019 | #define GEN7_ROW_CHICKEN2 0xe4f4 |
| @@ -4922,6 +5023,10 @@ | |||
| 4922 | #define HSW_ROW_CHICKEN3 0xe49c | 5023 | #define HSW_ROW_CHICKEN3 0xe49c |
| 4923 | #define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6) | 5024 | #define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6) |
| 4924 | 5025 | ||
| 5026 | #define HALF_SLICE_CHICKEN3 0xe184 | ||
| 5027 | #define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8) | ||
| 5028 | #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) | ||
| 5029 | |||
| 4925 | #define G4X_AUD_VID_DID (dev_priv->info->display_mmio_offset + 0x62020) | 5030 | #define G4X_AUD_VID_DID (dev_priv->info->display_mmio_offset + 0x62020) |
| 4926 | #define INTEL_AUDIO_DEVCL 0x808629FB | 5031 | #define INTEL_AUDIO_DEVCL 0x808629FB |
| 4927 | #define INTEL_AUDIO_DEVBLC 0x80862801 | 5032 | #define INTEL_AUDIO_DEVBLC 0x80862801 |
| @@ -5139,6 +5244,7 @@ | |||
| 5139 | #define DDI_BUF_CTL_B 0x64100 | 5244 | #define DDI_BUF_CTL_B 0x64100 |
| 5140 | #define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B) | 5245 | #define DDI_BUF_CTL(port) _PORT(port, DDI_BUF_CTL_A, DDI_BUF_CTL_B) |
| 5141 | #define DDI_BUF_CTL_ENABLE (1<<31) | 5246 | #define DDI_BUF_CTL_ENABLE (1<<31) |
| 5247 | /* Haswell */ | ||
| 5142 | #define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */ | 5248 | #define DDI_BUF_EMP_400MV_0DB_HSW (0<<24) /* Sel0 */ |
| 5143 | #define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */ | 5249 | #define DDI_BUF_EMP_400MV_3_5DB_HSW (1<<24) /* Sel1 */ |
| 5144 | #define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */ | 5250 | #define DDI_BUF_EMP_400MV_6DB_HSW (2<<24) /* Sel2 */ |
| @@ -5148,6 +5254,16 @@ | |||
| 5148 | #define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */ | 5254 | #define DDI_BUF_EMP_600MV_6DB_HSW (6<<24) /* Sel6 */ |
| 5149 | #define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */ | 5255 | #define DDI_BUF_EMP_800MV_0DB_HSW (7<<24) /* Sel7 */ |
| 5150 | #define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */ | 5256 | #define DDI_BUF_EMP_800MV_3_5DB_HSW (8<<24) /* Sel8 */ |
| 5257 | /* Broadwell */ | ||
| 5258 | #define DDI_BUF_EMP_400MV_0DB_BDW (0<<24) /* Sel0 */ | ||
| 5259 | #define DDI_BUF_EMP_400MV_3_5DB_BDW (1<<24) /* Sel1 */ | ||
| 5260 | #define DDI_BUF_EMP_400MV_6DB_BDW (2<<24) /* Sel2 */ | ||
| 5261 | #define DDI_BUF_EMP_600MV_0DB_BDW (3<<24) /* Sel3 */ | ||
| 5262 | #define DDI_BUF_EMP_600MV_3_5DB_BDW (4<<24) /* Sel4 */ | ||
| 5263 | #define DDI_BUF_EMP_600MV_6DB_BDW (5<<24) /* Sel5 */ | ||
| 5264 | #define DDI_BUF_EMP_800MV_0DB_BDW (6<<24) /* Sel6 */ | ||
| 5265 | #define DDI_BUF_EMP_800MV_3_5DB_BDW (7<<24) /* Sel7 */ | ||
| 5266 | #define DDI_BUF_EMP_1200MV_0DB_BDW (8<<24) /* Sel8 */ | ||
| 5151 | #define DDI_BUF_EMP_MASK (0xf<<24) | 5267 | #define DDI_BUF_EMP_MASK (0xf<<24) |
| 5152 | #define DDI_BUF_PORT_REVERSAL (1<<16) | 5268 | #define DDI_BUF_PORT_REVERSAL (1<<16) |
| 5153 | #define DDI_BUF_IS_IDLE (1<<7) | 5269 | #define DDI_BUF_IS_IDLE (1<<7) |
| @@ -5257,6 +5373,9 @@ | |||
| 5257 | #define LCPLL_PLL_LOCK (1<<30) | 5373 | #define LCPLL_PLL_LOCK (1<<30) |
| 5258 | #define LCPLL_CLK_FREQ_MASK (3<<26) | 5374 | #define LCPLL_CLK_FREQ_MASK (3<<26) |
| 5259 | #define LCPLL_CLK_FREQ_450 (0<<26) | 5375 | #define LCPLL_CLK_FREQ_450 (0<<26) |
| 5376 | #define LCPLL_CLK_FREQ_54O_BDW (1<<26) | ||
| 5377 | #define LCPLL_CLK_FREQ_337_5_BDW (2<<26) | ||
| 5378 | #define LCPLL_CLK_FREQ_675_BDW (3<<26) | ||
| 5260 | #define LCPLL_CD_CLOCK_DISABLE (1<<25) | 5379 | #define LCPLL_CD_CLOCK_DISABLE (1<<25) |
| 5261 | #define LCPLL_CD2X_CLOCK_DISABLE (1<<23) | 5380 | #define LCPLL_CD2X_CLOCK_DISABLE (1<<23) |
| 5262 | #define LCPLL_POWER_DOWN_ALLOW (1<<22) | 5381 | #define LCPLL_POWER_DOWN_ALLOW (1<<22) |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 2e01bd3a5d8c..b5b1b9b23adf 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -822,16 +822,15 @@ void intel_crt_init(struct drm_device *dev) | |||
| 822 | crt->base.mode_set = intel_crt_mode_set; | 822 | crt->base.mode_set = intel_crt_mode_set; |
| 823 | crt->base.disable = intel_disable_crt; | 823 | crt->base.disable = intel_disable_crt; |
| 824 | crt->base.enable = intel_enable_crt; | 824 | crt->base.enable = intel_enable_crt; |
| 825 | if (IS_HASWELL(dev)) | ||
| 826 | crt->base.get_config = hsw_crt_get_config; | ||
| 827 | else | ||
| 828 | crt->base.get_config = intel_crt_get_config; | ||
| 829 | if (I915_HAS_HOTPLUG(dev)) | 825 | if (I915_HAS_HOTPLUG(dev)) |
| 830 | crt->base.hpd_pin = HPD_CRT; | 826 | crt->base.hpd_pin = HPD_CRT; |
| 831 | if (HAS_DDI(dev)) | 827 | if (HAS_DDI(dev)) { |
| 828 | crt->base.get_config = hsw_crt_get_config; | ||
| 832 | crt->base.get_hw_state = intel_ddi_get_hw_state; | 829 | crt->base.get_hw_state = intel_ddi_get_hw_state; |
| 833 | else | 830 | } else { |
| 831 | crt->base.get_config = intel_crt_get_config; | ||
| 834 | crt->base.get_hw_state = intel_crt_get_hw_state; | 832 | crt->base.get_hw_state = intel_crt_get_hw_state; |
| 833 | } | ||
| 835 | intel_connector->get_hw_state = intel_connector_get_hw_state; | 834 | intel_connector->get_hw_state = intel_connector_get_hw_state; |
| 836 | 835 | ||
| 837 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 836 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 31f4fe271388..1591576a6101 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -72,6 +72,45 @@ static const u32 hsw_ddi_translations_hdmi[] = { | |||
| 72 | 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */ | 72 | 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */ |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | static const u32 bdw_ddi_translations_edp[] = { | ||
| 76 | 0x00FFFFFF, 0x00000012, /* DP parameters */ | ||
| 77 | 0x00EBAFFF, 0x00020011, | ||
| 78 | 0x00C71FFF, 0x0006000F, | ||
| 79 | 0x00FFFFFF, 0x00020011, | ||
| 80 | 0x00DB6FFF, 0x0005000F, | ||
| 81 | 0x00BEEFFF, 0x000A000C, | ||
| 82 | 0x00FFFFFF, 0x0005000F, | ||
| 83 | 0x00DB6FFF, 0x000A000C, | ||
| 84 | 0x00FFFFFF, 0x000A000C, | ||
| 85 | 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ | ||
| 86 | }; | ||
| 87 | |||
| 88 | static const u32 bdw_ddi_translations_dp[] = { | ||
| 89 | 0x00FFFFFF, 0x0007000E, /* DP parameters */ | ||
| 90 | 0x00D75FFF, 0x000E000A, | ||
| 91 | 0x00BEFFFF, 0x00140006, | ||
| 92 | 0x00FFFFFF, 0x000E000A, | ||
| 93 | 0x00D75FFF, 0x00180004, | ||
| 94 | 0x80CB2FFF, 0x001B0002, | ||
| 95 | 0x00F7DFFF, 0x00180004, | ||
| 96 | 0x80D75FFF, 0x001B0002, | ||
| 97 | 0x80FFFFFF, 0x001B0002, | ||
| 98 | 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ | ||
| 99 | }; | ||
| 100 | |||
| 101 | static const u32 bdw_ddi_translations_fdi[] = { | ||
| 102 | 0x00FFFFFF, 0x0001000E, /* FDI parameters */ | ||
| 103 | 0x00D75FFF, 0x0004000A, | ||
| 104 | 0x00C30FFF, 0x00070006, | ||
| 105 | 0x00AAAFFF, 0x000C0000, | ||
| 106 | 0x00FFFFFF, 0x0004000A, | ||
| 107 | 0x00D75FFF, 0x00090004, | ||
| 108 | 0x00C30FFF, 0x000C0000, | ||
| 109 | 0x00FFFFFF, 0x00070006, | ||
| 110 | 0x00D75FFF, 0x000C0000, | ||
| 111 | 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ | ||
| 112 | }; | ||
| 113 | |||
| 75 | enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) | 114 | enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) |
| 76 | { | 115 | { |
| 77 | struct drm_encoder *encoder = &intel_encoder->base; | 116 | struct drm_encoder *encoder = &intel_encoder->base; |
| @@ -92,8 +131,9 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) | |||
| 92 | } | 131 | } |
| 93 | } | 132 | } |
| 94 | 133 | ||
| 95 | /* On Haswell, DDI port buffers must be programmed with correct values | 134 | /* |
| 96 | * in advance. The buffer values are different for FDI and DP modes, | 135 | * Starting with Haswell, DDI port buffers must be programmed with correct |
| 136 | * values in advance. The buffer values are different for FDI and DP modes, | ||
| 97 | * but the HDMI/DVI fields are shared among those. So we program the DDI | 137 | * but the HDMI/DVI fields are shared among those. So we program the DDI |
| 98 | * in either FDI or DP modes only, as HDMI connections will work with both | 138 | * in either FDI or DP modes only, as HDMI connections will work with both |
| 99 | * of those | 139 | * of those |
| @@ -103,10 +143,47 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) | |||
| 103 | struct drm_i915_private *dev_priv = dev->dev_private; | 143 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 104 | u32 reg; | 144 | u32 reg; |
| 105 | int i; | 145 | int i; |
| 106 | const u32 *ddi_translations = (port == PORT_E) ? | ||
| 107 | hsw_ddi_translations_fdi : | ||
| 108 | hsw_ddi_translations_dp; | ||
| 109 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | 146 | int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; |
| 147 | const u32 *ddi_translations_fdi; | ||
| 148 | const u32 *ddi_translations_dp; | ||
| 149 | const u32 *ddi_translations_edp; | ||
| 150 | const u32 *ddi_translations; | ||
| 151 | |||
| 152 | if (IS_BROADWELL(dev)) { | ||
| 153 | ddi_translations_fdi = bdw_ddi_translations_fdi; | ||
| 154 | ddi_translations_dp = bdw_ddi_translations_dp; | ||
| 155 | ddi_translations_edp = bdw_ddi_translations_edp; | ||
| 156 | } else if (IS_HASWELL(dev)) { | ||
| 157 | ddi_translations_fdi = hsw_ddi_translations_fdi; | ||
| 158 | ddi_translations_dp = hsw_ddi_translations_dp; | ||
| 159 | ddi_translations_edp = hsw_ddi_translations_dp; | ||
| 160 | } else { | ||
| 161 | WARN(1, "ddi translation table missing\n"); | ||
| 162 | ddi_translations_edp = bdw_ddi_translations_dp; | ||
| 163 | ddi_translations_fdi = bdw_ddi_translations_fdi; | ||
| 164 | ddi_translations_dp = bdw_ddi_translations_dp; | ||
| 165 | } | ||
| 166 | |||
| 167 | switch (port) { | ||
| 168 | case PORT_A: | ||
| 169 | ddi_translations = ddi_translations_edp; | ||
| 170 | break; | ||
| 171 | case PORT_B: | ||
| 172 | case PORT_C: | ||
| 173 | ddi_translations = ddi_translations_dp; | ||
| 174 | break; | ||
| 175 | case PORT_D: | ||
| 176 | if (intel_dpd_is_edp(dev)) | ||
| 177 | ddi_translations = ddi_translations_edp; | ||
| 178 | else | ||
| 179 | ddi_translations = ddi_translations_dp; | ||
| 180 | break; | ||
| 181 | case PORT_E: | ||
| 182 | ddi_translations = ddi_translations_fdi; | ||
| 183 | break; | ||
| 184 | default: | ||
| 185 | BUG(); | ||
| 186 | } | ||
| 110 | 187 | ||
| 111 | for (i = 0, reg = DDI_BUF_TRANS(port); | 188 | for (i = 0, reg = DDI_BUF_TRANS(port); |
| 112 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { | 189 | i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { |
| @@ -756,7 +833,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) | |||
| 756 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 833 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 757 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); | 834 | struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); |
| 758 | struct drm_encoder *encoder = &intel_encoder->base; | 835 | struct drm_encoder *encoder = &intel_encoder->base; |
| 759 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 836 | struct drm_device *dev = crtc->dev; |
| 837 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 760 | enum pipe pipe = intel_crtc->pipe; | 838 | enum pipe pipe = intel_crtc->pipe; |
| 761 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; | 839 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
| 762 | enum port port = intel_ddi_get_encoder_port(intel_encoder); | 840 | enum port port = intel_ddi_get_encoder_port(intel_encoder); |
| @@ -792,10 +870,11 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) | |||
| 792 | if (cpu_transcoder == TRANSCODER_EDP) { | 870 | if (cpu_transcoder == TRANSCODER_EDP) { |
| 793 | switch (pipe) { | 871 | switch (pipe) { |
| 794 | case PIPE_A: | 872 | case PIPE_A: |
| 795 | /* Can only use the always-on power well for eDP when | 873 | /* On Haswell, can only use the always-on power well for |
| 796 | * not using the panel fitter, and when not using motion | 874 | * eDP when not using the panel fitter, and when not |
| 797 | * blur mitigation (which we don't support). */ | 875 | * using motion blur mitigation (which we don't |
| 798 | if (intel_crtc->config.pch_pfit.enabled) | 876 | * support). */ |
| 877 | if (IS_HASWELL(dev) && intel_crtc->config.pch_pfit.enabled) | ||
| 799 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; | 878 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
| 800 | else | 879 | else |
| 801 | temp |= TRANS_DDI_EDP_INPUT_A_ON; | 880 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
| @@ -1156,18 +1235,29 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) | |||
| 1156 | 1235 | ||
| 1157 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) | 1236 | int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) |
| 1158 | { | 1237 | { |
| 1238 | struct drm_device *dev = dev_priv->dev; | ||
| 1159 | uint32_t lcpll = I915_READ(LCPLL_CTL); | 1239 | uint32_t lcpll = I915_READ(LCPLL_CTL); |
| 1240 | uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; | ||
| 1160 | 1241 | ||
| 1161 | if (lcpll & LCPLL_CD_SOURCE_FCLK) | 1242 | if (lcpll & LCPLL_CD_SOURCE_FCLK) { |
| 1162 | return 800000; | 1243 | return 800000; |
| 1163 | else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) | 1244 | } else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) { |
| 1164 | return 450000; | 1245 | return 450000; |
| 1165 | else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) | 1246 | } else if (freq == LCPLL_CLK_FREQ_450) { |
| 1166 | return 450000; | 1247 | return 450000; |
| 1167 | else if (IS_ULT(dev_priv->dev)) | 1248 | } else if (IS_HASWELL(dev)) { |
| 1168 | return 337500; | 1249 | if (IS_ULT(dev)) |
| 1169 | else | 1250 | return 337500; |
| 1170 | return 540000; | 1251 | else |
| 1252 | return 540000; | ||
| 1253 | } else { | ||
| 1254 | if (freq == LCPLL_CLK_FREQ_54O_BDW) | ||
| 1255 | return 540000; | ||
| 1256 | else if (freq == LCPLL_CLK_FREQ_337_5_BDW) | ||
| 1257 | return 337500; | ||
| 1258 | else | ||
| 1259 | return 675000; | ||
| 1260 | } | ||
| 1171 | } | 1261 | } |
| 1172 | 1262 | ||
| 1173 | void intel_ddi_pll_init(struct drm_device *dev) | 1263 | void intel_ddi_pll_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e92f170f55f7..3cddd508d110 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2156,7 +2156,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, | |||
| 2156 | else | 2156 | else |
| 2157 | dspcntr &= ~DISPPLANE_TILED; | 2157 | dspcntr &= ~DISPPLANE_TILED; |
| 2158 | 2158 | ||
| 2159 | if (IS_HASWELL(dev)) | 2159 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 2160 | dspcntr &= ~DISPPLANE_TRICKLE_FEED_DISABLE; | 2160 | dspcntr &= ~DISPPLANE_TRICKLE_FEED_DISABLE; |
| 2161 | else | 2161 | else |
| 2162 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; | 2162 | dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; |
| @@ -2176,7 +2176,7 @@ static int ironlake_update_plane(struct drm_crtc *crtc, | |||
| 2176 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); | 2176 | I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); |
| 2177 | I915_MODIFY_DISPBASE(DSPSURF(plane), | 2177 | I915_MODIFY_DISPBASE(DSPSURF(plane), |
| 2178 | i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); | 2178 | i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); |
| 2179 | if (IS_HASWELL(dev)) { | 2179 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
| 2180 | I915_WRITE(DSPOFFSET(plane), (y << 16) | x); | 2180 | I915_WRITE(DSPOFFSET(plane), (y << 16) | x); |
| 2181 | } else { | 2181 | } else { |
| 2182 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); | 2182 | I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); |
| @@ -3393,15 +3393,26 @@ void hsw_enable_ips(struct intel_crtc *crtc) | |||
| 3393 | * only after intel_enable_plane. And intel_enable_plane already waits | 3393 | * only after intel_enable_plane. And intel_enable_plane already waits |
| 3394 | * for a vblank, so all we need to do here is to enable the IPS bit. */ | 3394 | * for a vblank, so all we need to do here is to enable the IPS bit. */ |
| 3395 | assert_plane_enabled(dev_priv, crtc->plane); | 3395 | assert_plane_enabled(dev_priv, crtc->plane); |
| 3396 | I915_WRITE(IPS_CTL, IPS_ENABLE); | 3396 | if (IS_BROADWELL(crtc->base.dev)) { |
| 3397 | 3397 | mutex_lock(&dev_priv->rps.hw_lock); | |
| 3398 | /* The bit only becomes 1 in the next vblank, so this wait here is | 3398 | WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0xc0000000)); |
| 3399 | * essentially intel_wait_for_vblank. If we don't have this and don't | 3399 | mutex_unlock(&dev_priv->rps.hw_lock); |
| 3400 | * wait for vblanks until the end of crtc_enable, then the HW state | 3400 | /* Quoting Art Runyan: "its not safe to expect any particular |
| 3401 | * readout code will complain that the expected IPS_CTL value is not the | 3401 | * value in IPS_CTL bit 31 after enabling IPS through the |
| 3402 | * one we read. */ | 3402 | * mailbox." Therefore we need to defer waiting on the state |
| 3403 | if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) | 3403 | * change. |
| 3404 | DRM_ERROR("Timed out waiting for IPS enable\n"); | 3404 | * TODO: need to fix this for state checker |
| 3405 | */ | ||
| 3406 | } else { | ||
| 3407 | I915_WRITE(IPS_CTL, IPS_ENABLE); | ||
| 3408 | /* The bit only becomes 1 in the next vblank, so this wait here | ||
| 3409 | * is essentially intel_wait_for_vblank. If we don't have this | ||
| 3410 | * and don't wait for vblanks until the end of crtc_enable, then | ||
| 3411 | * the HW state readout code will complain that the expected | ||
| 3412 | * IPS_CTL value is not the one we read. */ | ||
| 3413 | if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) | ||
| 3414 | DRM_ERROR("Timed out waiting for IPS enable\n"); | ||
| 3415 | } | ||
| 3405 | } | 3416 | } |
| 3406 | 3417 | ||
| 3407 | void hsw_disable_ips(struct intel_crtc *crtc) | 3418 | void hsw_disable_ips(struct intel_crtc *crtc) |
| @@ -3413,7 +3424,12 @@ void hsw_disable_ips(struct intel_crtc *crtc) | |||
| 3413 | return; | 3424 | return; |
| 3414 | 3425 | ||
| 3415 | assert_plane_enabled(dev_priv, crtc->plane); | 3426 | assert_plane_enabled(dev_priv, crtc->plane); |
| 3416 | I915_WRITE(IPS_CTL, 0); | 3427 | if (IS_BROADWELL(crtc->base.dev)) { |
| 3428 | mutex_lock(&dev_priv->rps.hw_lock); | ||
| 3429 | WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); | ||
| 3430 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
| 3431 | } else | ||
| 3432 | I915_WRITE(IPS_CTL, 0); | ||
| 3417 | POSTING_READ(IPS_CTL); | 3433 | POSTING_READ(IPS_CTL); |
| 3418 | 3434 | ||
| 3419 | /* We need to wait for a vblank before we can disable the plane. */ | 3435 | /* We need to wait for a vblank before we can disable the plane. */ |
| @@ -4244,7 +4260,7 @@ static bool ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, | |||
| 4244 | return false; | 4260 | return false; |
| 4245 | } | 4261 | } |
| 4246 | 4262 | ||
| 4247 | if (IS_HASWELL(dev)) { | 4263 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
| 4248 | if (pipe_config->fdi_lanes > 2) { | 4264 | if (pipe_config->fdi_lanes > 2) { |
| 4249 | DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n", | 4265 | DRM_DEBUG_KMS("only 2 lanes on haswell, required: %i lanes\n", |
| 4250 | pipe_config->fdi_lanes); | 4266 | pipe_config->fdi_lanes); |
| @@ -5818,14 +5834,16 @@ static void intel_set_pipe_csc(struct drm_crtc *crtc) | |||
| 5818 | 5834 | ||
| 5819 | static void haswell_set_pipeconf(struct drm_crtc *crtc) | 5835 | static void haswell_set_pipeconf(struct drm_crtc *crtc) |
| 5820 | { | 5836 | { |
| 5821 | struct drm_i915_private *dev_priv = crtc->dev->dev_private; | 5837 | struct drm_device *dev = crtc->dev; |
| 5838 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5822 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 5839 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 5840 | enum pipe pipe = intel_crtc->pipe; | ||
| 5823 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; | 5841 | enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
| 5824 | uint32_t val; | 5842 | uint32_t val; |
| 5825 | 5843 | ||
| 5826 | val = 0; | 5844 | val = 0; |
| 5827 | 5845 | ||
| 5828 | if (intel_crtc->config.dither) | 5846 | if (IS_HASWELL(dev) && intel_crtc->config.dither) |
| 5829 | val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); | 5847 | val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP); |
| 5830 | 5848 | ||
| 5831 | if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) | 5849 | if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) |
| @@ -5838,6 +5856,33 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) | |||
| 5838 | 5856 | ||
| 5839 | I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); | 5857 | I915_WRITE(GAMMA_MODE(intel_crtc->pipe), GAMMA_MODE_MODE_8BIT); |
| 5840 | POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); | 5858 | POSTING_READ(GAMMA_MODE(intel_crtc->pipe)); |
| 5859 | |||
| 5860 | if (IS_BROADWELL(dev)) { | ||
| 5861 | val = 0; | ||
| 5862 | |||
| 5863 | switch (intel_crtc->config.pipe_bpp) { | ||
| 5864 | case 18: | ||
| 5865 | val |= PIPEMISC_DITHER_6_BPC; | ||
| 5866 | break; | ||
| 5867 | case 24: | ||
| 5868 | val |= PIPEMISC_DITHER_8_BPC; | ||
| 5869 | break; | ||
| 5870 | case 30: | ||
| 5871 | val |= PIPEMISC_DITHER_10_BPC; | ||
| 5872 | break; | ||
| 5873 | case 36: | ||
| 5874 | val |= PIPEMISC_DITHER_12_BPC; | ||
| 5875 | break; | ||
| 5876 | default: | ||
| 5877 | /* Case prevented by pipe_config_set_bpp. */ | ||
| 5878 | BUG(); | ||
| 5879 | } | ||
| 5880 | |||
| 5881 | if (intel_crtc->config.dither) | ||
| 5882 | val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP; | ||
| 5883 | |||
| 5884 | I915_WRITE(PIPEMISC(pipe), val); | ||
| 5885 | } | ||
| 5841 | } | 5886 | } |
| 5842 | 5887 | ||
| 5843 | static bool ironlake_compute_clocks(struct drm_crtc *crtc, | 5888 | static bool ironlake_compute_clocks(struct drm_crtc *crtc, |
| @@ -7159,7 +7204,7 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) | |||
| 7159 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | 7204 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
| 7160 | cntl |= CURSOR_MODE_DISABLE; | 7205 | cntl |= CURSOR_MODE_DISABLE; |
| 7161 | } | 7206 | } |
| 7162 | if (IS_HASWELL(dev)) { | 7207 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
| 7163 | cntl |= CURSOR_PIPE_CSC_ENABLE; | 7208 | cntl |= CURSOR_PIPE_CSC_ENABLE; |
| 7164 | cntl &= ~CURSOR_TRICKLE_FEED_DISABLE; | 7209 | cntl &= ~CURSOR_TRICKLE_FEED_DISABLE; |
| 7165 | } | 7210 | } |
| @@ -7215,7 +7260,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, | |||
| 7215 | if (!visible && !intel_crtc->cursor_visible) | 7260 | if (!visible && !intel_crtc->cursor_visible) |
| 7216 | return; | 7261 | return; |
| 7217 | 7262 | ||
| 7218 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { | 7263 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) { |
| 7219 | I915_WRITE(CURPOS_IVB(pipe), pos); | 7264 | I915_WRITE(CURPOS_IVB(pipe), pos); |
| 7220 | ivb_update_cursor(crtc, base); | 7265 | ivb_update_cursor(crtc, base); |
| 7221 | } else { | 7266 | } else { |
| @@ -10337,7 +10382,7 @@ static void intel_init_display(struct drm_device *dev) | |||
| 10337 | dev_priv->display.write_eld = ironlake_write_eld; | 10382 | dev_priv->display.write_eld = ironlake_write_eld; |
| 10338 | dev_priv->display.modeset_global_resources = | 10383 | dev_priv->display.modeset_global_resources = |
| 10339 | ivb_modeset_global_resources; | 10384 | ivb_modeset_global_resources; |
| 10340 | } else if (IS_HASWELL(dev)) { | 10385 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { |
| 10341 | dev_priv->display.fdi_link_train = hsw_fdi_link_train; | 10386 | dev_priv->display.fdi_link_train = hsw_fdi_link_train; |
| 10342 | dev_priv->display.write_eld = haswell_write_eld; | 10387 | dev_priv->display.write_eld = haswell_write_eld; |
| 10343 | dev_priv->display.modeset_global_resources = | 10388 | dev_priv->display.modeset_global_resources = |
| @@ -10369,6 +10414,7 @@ static void intel_init_display(struct drm_device *dev) | |||
| 10369 | dev_priv->display.queue_flip = intel_gen6_queue_flip; | 10414 | dev_priv->display.queue_flip = intel_gen6_queue_flip; |
| 10370 | break; | 10415 | break; |
| 10371 | case 7: | 10416 | case 7: |
| 10417 | case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */ | ||
| 10372 | dev_priv->display.queue_flip = intel_gen7_queue_flip; | 10418 | dev_priv->display.queue_flip = intel_gen7_queue_flip; |
| 10373 | break; | 10419 | break; |
| 10374 | } | 10420 | } |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 045d46475121..eb8139da9763 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -405,6 +405,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
| 405 | uint32_t status; | 405 | uint32_t status; |
| 406 | int try, precharge, clock = 0; | 406 | int try, precharge, clock = 0; |
| 407 | bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); | 407 | bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev); |
| 408 | uint32_t timeout; | ||
| 408 | 409 | ||
| 409 | /* dp aux is extremely sensitive to irq latency, hence request the | 410 | /* dp aux is extremely sensitive to irq latency, hence request the |
| 410 | * lowest possible wakeup latency and so prevent the cpu from going into | 411 | * lowest possible wakeup latency and so prevent the cpu from going into |
| @@ -419,6 +420,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
| 419 | else | 420 | else |
| 420 | precharge = 5; | 421 | precharge = 5; |
| 421 | 422 | ||
| 423 | if (IS_BROADWELL(dev) && ch_ctl == DPA_AUX_CH_CTL) | ||
| 424 | timeout = DP_AUX_CH_CTL_TIME_OUT_600us; | ||
| 425 | else | ||
| 426 | timeout = DP_AUX_CH_CTL_TIME_OUT_400us; | ||
| 427 | |||
| 422 | intel_aux_display_runtime_get(dev_priv); | 428 | intel_aux_display_runtime_get(dev_priv); |
| 423 | 429 | ||
| 424 | /* Try to wait for any previous AUX channel activity */ | 430 | /* Try to wait for any previous AUX channel activity */ |
| @@ -454,7 +460,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
| 454 | I915_WRITE(ch_ctl, | 460 | I915_WRITE(ch_ctl, |
| 455 | DP_AUX_CH_CTL_SEND_BUSY | | 461 | DP_AUX_CH_CTL_SEND_BUSY | |
| 456 | (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | | 462 | (has_aux_irq ? DP_AUX_CH_CTL_INTERRUPT : 0) | |
| 457 | DP_AUX_CH_CTL_TIME_OUT_400us | | 463 | timeout | |
| 458 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | 464 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | |
| 459 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | 465 | (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | |
| 460 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | 466 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | |
| @@ -1610,6 +1616,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) | |||
| 1610 | uint32_t max_sleep_time = 0x1f; | 1616 | uint32_t max_sleep_time = 0x1f; |
| 1611 | uint32_t idle_frames = 1; | 1617 | uint32_t idle_frames = 1; |
| 1612 | uint32_t val = 0x0; | 1618 | uint32_t val = 0x0; |
| 1619 | const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; | ||
| 1613 | 1620 | ||
| 1614 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { | 1621 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { |
| 1615 | val |= EDP_PSR_LINK_STANDBY; | 1622 | val |= EDP_PSR_LINK_STANDBY; |
| @@ -1620,7 +1627,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) | |||
| 1620 | val |= EDP_PSR_LINK_DISABLE; | 1627 | val |= EDP_PSR_LINK_DISABLE; |
| 1621 | 1628 | ||
| 1622 | I915_WRITE(EDP_PSR_CTL(dev), val | | 1629 | I915_WRITE(EDP_PSR_CTL(dev), val | |
| 1623 | EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES | | 1630 | IS_BROADWELL(dev) ? 0 : link_entry_time | |
| 1624 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | | 1631 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
| 1625 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | | 1632 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
| 1626 | EDP_PSR_ENABLE); | 1633 | EDP_PSR_ENABLE); |
| @@ -1957,7 +1964,7 @@ intel_dp_voltage_max(struct intel_dp *intel_dp) | |||
| 1957 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1964 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
| 1958 | enum port port = dp_to_dig_port(intel_dp)->port; | 1965 | enum port port = dp_to_dig_port(intel_dp)->port; |
| 1959 | 1966 | ||
| 1960 | if (IS_VALLEYVIEW(dev)) | 1967 | if (IS_VALLEYVIEW(dev) || IS_BROADWELL(dev)) |
| 1961 | return DP_TRAIN_VOLTAGE_SWING_1200; | 1968 | return DP_TRAIN_VOLTAGE_SWING_1200; |
| 1962 | else if (IS_GEN7(dev) && port == PORT_A) | 1969 | else if (IS_GEN7(dev) && port == PORT_A) |
| 1963 | return DP_TRAIN_VOLTAGE_SWING_800; | 1970 | return DP_TRAIN_VOLTAGE_SWING_800; |
| @@ -1973,7 +1980,18 @@ intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) | |||
| 1973 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 1980 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
| 1974 | enum port port = dp_to_dig_port(intel_dp)->port; | 1981 | enum port port = dp_to_dig_port(intel_dp)->port; |
| 1975 | 1982 | ||
| 1976 | if (HAS_DDI(dev)) { | 1983 | if (IS_BROADWELL(dev)) { |
| 1984 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
| 1985 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
| 1986 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
| 1987 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
| 1988 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
| 1989 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
| 1990 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
| 1991 | default: | ||
| 1992 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
| 1993 | } | ||
| 1994 | } else if (IS_HASWELL(dev)) { | ||
| 1977 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | 1995 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { |
| 1978 | case DP_TRAIN_VOLTAGE_SWING_400: | 1996 | case DP_TRAIN_VOLTAGE_SWING_400: |
| 1979 | return DP_TRAIN_PRE_EMPHASIS_9_5; | 1997 | return DP_TRAIN_PRE_EMPHASIS_9_5; |
| @@ -2285,6 +2303,41 @@ intel_hsw_signal_levels(uint8_t train_set) | |||
| 2285 | } | 2303 | } |
| 2286 | } | 2304 | } |
| 2287 | 2305 | ||
| 2306 | static uint32_t | ||
| 2307 | intel_bdw_signal_levels(uint8_t train_set) | ||
| 2308 | { | ||
| 2309 | int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | | ||
| 2310 | DP_TRAIN_PRE_EMPHASIS_MASK); | ||
| 2311 | switch (signal_levels) { | ||
| 2312 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: | ||
| 2313 | return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */ | ||
| 2314 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
| 2315 | return DDI_BUF_EMP_400MV_3_5DB_BDW; /* Sel1 */ | ||
| 2316 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: | ||
| 2317 | return DDI_BUF_EMP_400MV_6DB_BDW; /* Sel2 */ | ||
| 2318 | |||
| 2319 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0: | ||
| 2320 | return DDI_BUF_EMP_600MV_0DB_BDW; /* Sel3 */ | ||
| 2321 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
| 2322 | return DDI_BUF_EMP_600MV_3_5DB_BDW; /* Sel4 */ | ||
| 2323 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6: | ||
| 2324 | return DDI_BUF_EMP_600MV_6DB_BDW; /* Sel5 */ | ||
| 2325 | |||
| 2326 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: | ||
| 2327 | return DDI_BUF_EMP_800MV_0DB_BDW; /* Sel6 */ | ||
| 2328 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
| 2329 | return DDI_BUF_EMP_800MV_3_5DB_BDW; /* Sel7 */ | ||
| 2330 | |||
| 2331 | case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0: | ||
| 2332 | return DDI_BUF_EMP_1200MV_0DB_BDW; /* Sel8 */ | ||
| 2333 | |||
| 2334 | default: | ||
| 2335 | DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" | ||
| 2336 | "0x%x\n", signal_levels); | ||
| 2337 | return DDI_BUF_EMP_400MV_0DB_BDW; /* Sel0 */ | ||
| 2338 | } | ||
| 2339 | } | ||
| 2340 | |||
| 2288 | /* Properly updates "DP" with the correct signal levels. */ | 2341 | /* Properly updates "DP" with the correct signal levels. */ |
| 2289 | static void | 2342 | static void |
| 2290 | intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) | 2343 | intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) |
| @@ -2295,7 +2348,10 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp, uint32_t *DP) | |||
| 2295 | uint32_t signal_levels, mask; | 2348 | uint32_t signal_levels, mask; |
| 2296 | uint8_t train_set = intel_dp->train_set[0]; | 2349 | uint8_t train_set = intel_dp->train_set[0]; |
| 2297 | 2350 | ||
| 2298 | if (HAS_DDI(dev)) { | 2351 | if (IS_BROADWELL(dev)) { |
| 2352 | signal_levels = intel_bdw_signal_levels(train_set); | ||
| 2353 | mask = DDI_BUF_EMP_MASK; | ||
| 2354 | } else if (IS_HASWELL(dev)) { | ||
| 2299 | signal_levels = intel_hsw_signal_levels(train_set); | 2355 | signal_levels = intel_hsw_signal_levels(train_set); |
| 2300 | mask = DDI_BUF_EMP_MASK; | 2356 | mask = DDI_BUF_EMP_MASK; |
| 2301 | } else if (IS_VALLEYVIEW(dev)) { | 2357 | } else if (IS_VALLEYVIEW(dev)) { |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 51a8336dec2e..03f9ca70530c 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -847,7 +847,7 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi) | |||
| 847 | 847 | ||
| 848 | if (IS_G4X(dev)) | 848 | if (IS_G4X(dev)) |
| 849 | return 165000; | 849 | return 165000; |
| 850 | else if (IS_HASWELL(dev)) | 850 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) |
| 851 | return 300000; | 851 | return 300000; |
| 852 | else | 852 | else |
| 853 | return 225000; | 853 | return 225000; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 09ac9e79830f..0a07d7c9cafc 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -2291,7 +2291,9 @@ static uint32_t ilk_compute_fbc_wm(const struct hsw_pipe_wm_parameters *params, | |||
| 2291 | 2291 | ||
| 2292 | static unsigned int ilk_display_fifo_size(const struct drm_device *dev) | 2292 | static unsigned int ilk_display_fifo_size(const struct drm_device *dev) |
| 2293 | { | 2293 | { |
| 2294 | if (INTEL_INFO(dev)->gen >= 7) | 2294 | if (INTEL_INFO(dev)->gen >= 8) |
| 2295 | return 3072; | ||
| 2296 | else if (INTEL_INFO(dev)->gen >= 7) | ||
| 2295 | return 768; | 2297 | return 768; |
| 2296 | else | 2298 | else |
| 2297 | return 512; | 2299 | return 512; |
| @@ -2336,7 +2338,9 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev, | |||
| 2336 | } | 2338 | } |
| 2337 | 2339 | ||
| 2338 | /* clamp to max that the registers can hold */ | 2340 | /* clamp to max that the registers can hold */ |
| 2339 | if (INTEL_INFO(dev)->gen >= 7) | 2341 | if (INTEL_INFO(dev)->gen >= 8) |
| 2342 | max = level == 0 ? 255 : 2047; | ||
| 2343 | else if (INTEL_INFO(dev)->gen >= 7) | ||
| 2340 | /* IVB/HSW primary/sprite plane watermarks */ | 2344 | /* IVB/HSW primary/sprite plane watermarks */ |
| 2341 | max = level == 0 ? 127 : 1023; | 2345 | max = level == 0 ? 127 : 1023; |
| 2342 | else if (!is_sprite) | 2346 | else if (!is_sprite) |
| @@ -2366,10 +2370,13 @@ static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, | |||
| 2366 | } | 2370 | } |
| 2367 | 2371 | ||
| 2368 | /* Calculate the maximum FBC watermark */ | 2372 | /* Calculate the maximum FBC watermark */ |
| 2369 | static unsigned int ilk_fbc_wm_max(void) | 2373 | static unsigned int ilk_fbc_wm_max(struct drm_device *dev) |
| 2370 | { | 2374 | { |
| 2371 | /* max that registers can hold */ | 2375 | /* max that registers can hold */ |
| 2372 | return 15; | 2376 | if (INTEL_INFO(dev)->gen >= 8) |
| 2377 | return 31; | ||
| 2378 | else | ||
| 2379 | return 15; | ||
| 2373 | } | 2380 | } |
| 2374 | 2381 | ||
| 2375 | static void ilk_compute_wm_maximums(struct drm_device *dev, | 2382 | static void ilk_compute_wm_maximums(struct drm_device *dev, |
| @@ -2381,7 +2388,7 @@ static void ilk_compute_wm_maximums(struct drm_device *dev, | |||
| 2381 | max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false); | 2388 | max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false); |
| 2382 | max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); | 2389 | max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); |
| 2383 | max->cur = ilk_cursor_wm_max(dev, level, config); | 2390 | max->cur = ilk_cursor_wm_max(dev, level, config); |
| 2384 | max->fbc = ilk_fbc_wm_max(); | 2391 | max->fbc = ilk_fbc_wm_max(dev); |
| 2385 | } | 2392 | } |
| 2386 | 2393 | ||
| 2387 | static bool ilk_validate_wm_level(int level, | 2394 | static bool ilk_validate_wm_level(int level, |
| @@ -2722,10 +2729,18 @@ static void hsw_compute_wm_results(struct drm_device *dev, | |||
| 2722 | if (!r->enable) | 2729 | if (!r->enable) |
| 2723 | break; | 2730 | break; |
| 2724 | 2731 | ||
| 2725 | results->wm_lp[wm_lp - 1] = HSW_WM_LP_VAL(level * 2, | 2732 | results->wm_lp[wm_lp - 1] = WM3_LP_EN | |
| 2726 | r->fbc_val, | 2733 | ((level * 2) << WM1_LP_LATENCY_SHIFT) | |
| 2727 | r->pri_val, | 2734 | (r->pri_val << WM1_LP_SR_SHIFT) | |
| 2728 | r->cur_val); | 2735 | r->cur_val; |
| 2736 | |||
| 2737 | if (INTEL_INFO(dev)->gen >= 8) | ||
| 2738 | results->wm_lp[wm_lp - 1] |= | ||
| 2739 | r->fbc_val << WM1_LP_FBC_SHIFT_BDW; | ||
| 2740 | else | ||
| 2741 | results->wm_lp[wm_lp - 1] |= | ||
| 2742 | r->fbc_val << WM1_LP_FBC_SHIFT; | ||
| 2743 | |||
| 2729 | results->wm_lp_spr[wm_lp - 1] = r->spr_val; | 2744 | results->wm_lp_spr[wm_lp - 1] = r->spr_val; |
| 2730 | } | 2745 | } |
| 2731 | 2746 | ||
| @@ -3747,6 +3762,78 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev) | |||
| 3747 | I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs); | 3762 | I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs); |
| 3748 | } | 3763 | } |
| 3749 | 3764 | ||
| 3765 | static void gen8_enable_rps(struct drm_device *dev) | ||
| 3766 | { | ||
| 3767 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 3768 | struct intel_ring_buffer *ring; | ||
| 3769 | uint32_t rc6_mask = 0, rp_state_cap; | ||
| 3770 | int unused; | ||
| 3771 | |||
| 3772 | /* 1a: Software RC state - RC0 */ | ||
| 3773 | I915_WRITE(GEN6_RC_STATE, 0); | ||
| 3774 | |||
| 3775 | /* 1c & 1d: Get forcewake during program sequence. Although the driver | ||
| 3776 | * hasn't enabled a state yet where we need forcewake, BIOS may have.*/ | ||
| 3777 | gen6_gt_force_wake_get(dev_priv); | ||
| 3778 | |||
| 3779 | /* 2a: Disable RC states. */ | ||
| 3780 | I915_WRITE(GEN6_RC_CONTROL, 0); | ||
| 3781 | |||
| 3782 | rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | ||
| 3783 | |||
| 3784 | /* 2b: Program RC6 thresholds.*/ | ||
| 3785 | I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16); | ||
| 3786 | I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ | ||
| 3787 | I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ | ||
| 3788 | for_each_ring(ring, dev_priv, unused) | ||
| 3789 | I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); | ||
| 3790 | I915_WRITE(GEN6_RC_SLEEP, 0); | ||
| 3791 | I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */ | ||
| 3792 | |||
| 3793 | /* 3: Enable RC6 */ | ||
| 3794 | if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) | ||
| 3795 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE; | ||
| 3796 | DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off"); | ||
| 3797 | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | | ||
| 3798 | GEN6_RC_CTL_EI_MODE(1) | | ||
| 3799 | rc6_mask); | ||
| 3800 | |||
| 3801 | /* 4 Program defaults and thresholds for RPS*/ | ||
| 3802 | I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(10)); /* Request 500 MHz */ | ||
| 3803 | I915_WRITE(GEN6_RC_VIDEO_FREQ, HSW_FREQUENCY(12)); /* Request 600 MHz */ | ||
| 3804 | /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ | ||
| 3805 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ | ||
| 3806 | |||
| 3807 | /* Docs recommend 900MHz, and 300 MHz respectively */ | ||
| 3808 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | ||
| 3809 | dev_priv->rps.max_delay << 24 | | ||
| 3810 | dev_priv->rps.min_delay << 16); | ||
| 3811 | |||
| 3812 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ | ||
| 3813 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ | ||
| 3814 | I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */ | ||
| 3815 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */ | ||
| 3816 | |||
| 3817 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | ||
| 3818 | |||
| 3819 | /* 5: Enable RPS */ | ||
| 3820 | I915_WRITE(GEN6_RP_CONTROL, | ||
| 3821 | GEN6_RP_MEDIA_TURBO | | ||
| 3822 | GEN6_RP_MEDIA_HW_NORMAL_MODE | | ||
| 3823 | GEN6_RP_MEDIA_IS_GFX | | ||
| 3824 | GEN6_RP_ENABLE | | ||
| 3825 | GEN6_RP_UP_BUSY_AVG | | ||
| 3826 | GEN6_RP_DOWN_IDLE_AVG); | ||
| 3827 | |||
| 3828 | /* 6: Ring frequency + overclocking (our driver does this later */ | ||
| 3829 | |||
| 3830 | gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); | ||
| 3831 | |||
| 3832 | gen6_enable_rps_interrupts(dev); | ||
| 3833 | |||
| 3834 | gen6_gt_force_wake_put(dev_priv); | ||
| 3835 | } | ||
| 3836 | |||
| 3750 | static void gen6_enable_rps(struct drm_device *dev) | 3837 | static void gen6_enable_rps(struct drm_device *dev) |
| 3751 | { | 3838 | { |
| 3752 | struct drm_i915_private *dev_priv = dev->dev_private; | 3839 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -3909,7 +3996,10 @@ void gen6_update_ring_freq(struct drm_device *dev) | |||
| 3909 | int diff = dev_priv->rps.max_delay - gpu_freq; | 3996 | int diff = dev_priv->rps.max_delay - gpu_freq; |
| 3910 | unsigned int ia_freq = 0, ring_freq = 0; | 3997 | unsigned int ia_freq = 0, ring_freq = 0; |
| 3911 | 3998 | ||
| 3912 | if (IS_HASWELL(dev)) { | 3999 | if (INTEL_INFO(dev)->gen >= 8) { |
| 4000 | /* max(2 * GT, DDR). NB: GT is 50MHz units */ | ||
| 4001 | ring_freq = max(min_ring_freq, gpu_freq); | ||
| 4002 | } else if (IS_HASWELL(dev)) { | ||
| 3913 | ring_freq = mult_frac(gpu_freq, 5, 4); | 4003 | ring_freq = mult_frac(gpu_freq, 5, 4); |
| 3914 | ring_freq = max(min_ring_freq, ring_freq); | 4004 | ring_freq = max(min_ring_freq, ring_freq); |
| 3915 | /* leave ia_freq as the default, chosen by cpufreq */ | 4005 | /* leave ia_freq as the default, chosen by cpufreq */ |
| @@ -4873,6 +4963,9 @@ static void intel_gen6_powersave_work(struct work_struct *work) | |||
| 4873 | 4963 | ||
| 4874 | if (IS_VALLEYVIEW(dev)) { | 4964 | if (IS_VALLEYVIEW(dev)) { |
| 4875 | valleyview_enable_rps(dev); | 4965 | valleyview_enable_rps(dev); |
| 4966 | } else if (IS_BROADWELL(dev)) { | ||
| 4967 | gen8_enable_rps(dev); | ||
| 4968 | gen6_update_ring_freq(dev); | ||
| 4876 | } else { | 4969 | } else { |
| 4877 | gen6_enable_rps(dev); | 4970 | gen6_enable_rps(dev); |
| 4878 | gen6_update_ring_freq(dev); | 4971 | gen6_update_ring_freq(dev); |
| @@ -5181,6 +5274,50 @@ static void lpt_suspend_hw(struct drm_device *dev) | |||
| 5181 | } | 5274 | } |
| 5182 | } | 5275 | } |
| 5183 | 5276 | ||
| 5277 | static void gen8_init_clock_gating(struct drm_device *dev) | ||
| 5278 | { | ||
| 5279 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 5280 | enum pipe i; | ||
| 5281 | |||
| 5282 | I915_WRITE(WM3_LP_ILK, 0); | ||
| 5283 | I915_WRITE(WM2_LP_ILK, 0); | ||
| 5284 | I915_WRITE(WM1_LP_ILK, 0); | ||
| 5285 | |||
| 5286 | /* FIXME(BDW): Check all the w/a, some might only apply to | ||
| 5287 | * pre-production hw. */ | ||
| 5288 | |||
| 5289 | WARN(!i915_preliminary_hw_support, | ||
| 5290 | "GEN8_CENTROID_PIXEL_OPT_DIS not be needed for production\n"); | ||
| 5291 | I915_WRITE(HALF_SLICE_CHICKEN3, | ||
| 5292 | _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS)); | ||
| 5293 | I915_WRITE(HALF_SLICE_CHICKEN3, | ||
| 5294 | _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); | ||
| 5295 | I915_WRITE(GAMTARBMODE, _MASKED_BIT_ENABLE(ARB_MODE_BWGTLB_DISABLE)); | ||
| 5296 | |||
| 5297 | I915_WRITE(_3D_CHICKEN3, | ||
| 5298 | _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH(2)); | ||
| 5299 | |||
| 5300 | I915_WRITE(COMMON_SLICE_CHICKEN2, | ||
| 5301 | _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE)); | ||
| 5302 | |||
| 5303 | I915_WRITE(GEN7_HALF_SLICE_CHICKEN1, | ||
| 5304 | _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE)); | ||
| 5305 | |||
| 5306 | /* WaSwitchSolVfFArbitrationPriority */ | ||
| 5307 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); | ||
| 5308 | |||
| 5309 | /* WaPsrDPAMaskVBlankInSRD */ | ||
| 5310 | I915_WRITE(CHICKEN_PAR1_1, | ||
| 5311 | I915_READ(CHICKEN_PAR1_1) | DPA_MASK_VBLANK_SRD); | ||
| 5312 | |||
| 5313 | /* WaPsrDPRSUnmaskVBlankInSRD */ | ||
| 5314 | for_each_pipe(i) { | ||
| 5315 | I915_WRITE(CHICKEN_PIPESL_1(i), | ||
| 5316 | I915_READ(CHICKEN_PIPESL_1(i) | | ||
| 5317 | DPRS_MASK_VBLANK_SRD)); | ||
| 5318 | } | ||
| 5319 | } | ||
| 5320 | |||
| 5184 | static void haswell_init_clock_gating(struct drm_device *dev) | 5321 | static void haswell_init_clock_gating(struct drm_device *dev) |
| 5185 | { | 5322 | { |
| 5186 | struct drm_i915_private *dev_priv = dev->dev_private; | 5323 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -5511,7 +5648,9 @@ static bool is_always_on_power_domain(struct drm_device *dev, | |||
| 5511 | 5648 | ||
| 5512 | BUG_ON(BIT(domain) & ~POWER_DOMAIN_MASK); | 5649 | BUG_ON(BIT(domain) & ~POWER_DOMAIN_MASK); |
| 5513 | 5650 | ||
| 5514 | if (IS_HASWELL(dev)) { | 5651 | if (IS_BROADWELL(dev)) { |
| 5652 | always_on_domains = BDW_ALWAYS_ON_POWER_DOMAINS; | ||
| 5653 | } else if (IS_HASWELL(dev)) { | ||
| 5515 | always_on_domains = HSW_ALWAYS_ON_POWER_DOMAINS; | 5654 | always_on_domains = HSW_ALWAYS_ON_POWER_DOMAINS; |
| 5516 | } else { | 5655 | } else { |
| 5517 | WARN_ON(1); | 5656 | WARN_ON(1); |
| @@ -5833,6 +5972,8 @@ void intel_init_pm(struct drm_device *dev) | |||
| 5833 | dev_priv->display.update_wm = NULL; | 5972 | dev_priv->display.update_wm = NULL; |
| 5834 | } | 5973 | } |
| 5835 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; | 5974 | dev_priv->display.init_clock_gating = haswell_init_clock_gating; |
| 5975 | } else if (INTEL_INFO(dev)->gen == 8) { | ||
| 5976 | dev_priv->display.init_clock_gating = gen8_init_clock_gating; | ||
| 5836 | } else | 5977 | } else |
| 5837 | dev_priv->display.update_wm = NULL; | 5978 | dev_priv->display.update_wm = NULL; |
| 5838 | } else if (IS_VALLEYVIEW(dev)) { | 5979 | } else if (IS_VALLEYVIEW(dev)) { |
| @@ -5995,4 +6136,3 @@ void intel_pm_init(struct drm_device *dev) | |||
| 5995 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, | 6136 | INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, |
| 5996 | intel_gen6_powersave_work); | 6137 | intel_gen6_powersave_work); |
| 5997 | } | 6138 | } |
| 5998 | |||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2dec134f75eb..b620337e6d67 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -360,6 +360,47 @@ gen7_render_ring_flush(struct intel_ring_buffer *ring, | |||
| 360 | return 0; | 360 | return 0; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| 363 | static int | ||
| 364 | gen8_render_ring_flush(struct intel_ring_buffer *ring, | ||
| 365 | u32 invalidate_domains, u32 flush_domains) | ||
| 366 | { | ||
| 367 | u32 flags = 0; | ||
| 368 | u32 scratch_addr = ring->scratch.gtt_offset + 128; | ||
| 369 | int ret; | ||
| 370 | |||
| 371 | flags |= PIPE_CONTROL_CS_STALL; | ||
| 372 | |||
| 373 | if (flush_domains) { | ||
| 374 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | ||
| 375 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | ||
| 376 | } | ||
| 377 | if (invalidate_domains) { | ||
| 378 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
| 379 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
| 380 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
| 381 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
| 382 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
| 383 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
| 384 | flags |= PIPE_CONTROL_QW_WRITE; | ||
| 385 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; | ||
| 386 | } | ||
| 387 | |||
| 388 | ret = intel_ring_begin(ring, 6); | ||
| 389 | if (ret) | ||
| 390 | return ret; | ||
| 391 | |||
| 392 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(6)); | ||
| 393 | intel_ring_emit(ring, flags); | ||
| 394 | intel_ring_emit(ring, scratch_addr); | ||
| 395 | intel_ring_emit(ring, 0); | ||
| 396 | intel_ring_emit(ring, 0); | ||
| 397 | intel_ring_emit(ring, 0); | ||
| 398 | intel_ring_advance(ring); | ||
| 399 | |||
| 400 | return 0; | ||
| 401 | |||
| 402 | } | ||
| 403 | |||
| 363 | static void ring_write_tail(struct intel_ring_buffer *ring, | 404 | static void ring_write_tail(struct intel_ring_buffer *ring, |
| 364 | u32 value) | 405 | u32 value) |
| 365 | { | 406 | { |
| @@ -1066,6 +1107,52 @@ hsw_vebox_put_irq(struct intel_ring_buffer *ring) | |||
| 1066 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | 1107 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); |
| 1067 | } | 1108 | } |
| 1068 | 1109 | ||
| 1110 | static bool | ||
| 1111 | gen8_ring_get_irq(struct intel_ring_buffer *ring) | ||
| 1112 | { | ||
| 1113 | struct drm_device *dev = ring->dev; | ||
| 1114 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1115 | unsigned long flags; | ||
| 1116 | |||
| 1117 | if (!dev->irq_enabled) | ||
| 1118 | return false; | ||
| 1119 | |||
| 1120 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
| 1121 | if (ring->irq_refcount++ == 0) { | ||
| 1122 | if (HAS_L3_DPF(dev) && ring->id == RCS) { | ||
| 1123 | I915_WRITE_IMR(ring, | ||
| 1124 | ~(ring->irq_enable_mask | | ||
| 1125 | GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); | ||
| 1126 | } else { | ||
| 1127 | I915_WRITE_IMR(ring, ~ring->irq_enable_mask); | ||
| 1128 | } | ||
| 1129 | POSTING_READ(RING_IMR(ring->mmio_base)); | ||
| 1130 | } | ||
| 1131 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
| 1132 | |||
| 1133 | return true; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | static void | ||
| 1137 | gen8_ring_put_irq(struct intel_ring_buffer *ring) | ||
| 1138 | { | ||
| 1139 | struct drm_device *dev = ring->dev; | ||
| 1140 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1141 | unsigned long flags; | ||
| 1142 | |||
| 1143 | spin_lock_irqsave(&dev_priv->irq_lock, flags); | ||
| 1144 | if (--ring->irq_refcount == 0) { | ||
| 1145 | if (HAS_L3_DPF(dev) && ring->id == RCS) { | ||
| 1146 | I915_WRITE_IMR(ring, | ||
| 1147 | ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); | ||
| 1148 | } else { | ||
| 1149 | I915_WRITE_IMR(ring, ~0); | ||
| 1150 | } | ||
| 1151 | POSTING_READ(RING_IMR(ring->mmio_base)); | ||
| 1152 | } | ||
| 1153 | spin_unlock_irqrestore(&dev_priv->irq_lock, flags); | ||
| 1154 | } | ||
| 1155 | |||
| 1069 | static int | 1156 | static int |
| 1070 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, | 1157 | i965_dispatch_execbuffer(struct intel_ring_buffer *ring, |
| 1071 | u32 offset, u32 length, | 1158 | u32 offset, u32 length, |
| @@ -1624,6 +1711,8 @@ static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring, | |||
| 1624 | return ret; | 1711 | return ret; |
| 1625 | 1712 | ||
| 1626 | cmd = MI_FLUSH_DW; | 1713 | cmd = MI_FLUSH_DW; |
| 1714 | if (INTEL_INFO(ring->dev)->gen >= 8) | ||
| 1715 | cmd += 1; | ||
| 1627 | /* | 1716 | /* |
| 1628 | * Bspec vol 1c.5 - video engine command streamer: | 1717 | * Bspec vol 1c.5 - video engine command streamer: |
| 1629 | * "If ENABLED, all TLBs will be invalidated once the flush | 1718 | * "If ENABLED, all TLBs will be invalidated once the flush |
| @@ -1635,9 +1724,38 @@ static int gen6_bsd_ring_flush(struct intel_ring_buffer *ring, | |||
| 1635 | MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; | 1724 | MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW; |
| 1636 | intel_ring_emit(ring, cmd); | 1725 | intel_ring_emit(ring, cmd); |
| 1637 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); | 1726 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
| 1727 | if (INTEL_INFO(ring->dev)->gen >= 8) { | ||
| 1728 | intel_ring_emit(ring, 0); /* upper addr */ | ||
| 1729 | intel_ring_emit(ring, 0); /* value */ | ||
| 1730 | } else { | ||
| 1731 | intel_ring_emit(ring, 0); | ||
| 1732 | intel_ring_emit(ring, MI_NOOP); | ||
| 1733 | } | ||
| 1734 | intel_ring_advance(ring); | ||
| 1735 | return 0; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | static int | ||
| 1739 | gen8_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, | ||
| 1740 | u32 offset, u32 len, | ||
| 1741 | unsigned flags) | ||
| 1742 | { | ||
| 1743 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
| 1744 | bool ppgtt = dev_priv->mm.aliasing_ppgtt != NULL && | ||
| 1745 | !(flags & I915_DISPATCH_SECURE); | ||
| 1746 | int ret; | ||
| 1747 | |||
| 1748 | ret = intel_ring_begin(ring, 4); | ||
| 1749 | if (ret) | ||
| 1750 | return ret; | ||
| 1751 | |||
| 1752 | /* FIXME(BDW): Address space and security selectors. */ | ||
| 1753 | intel_ring_emit(ring, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8)); | ||
| 1754 | intel_ring_emit(ring, offset); | ||
| 1638 | intel_ring_emit(ring, 0); | 1755 | intel_ring_emit(ring, 0); |
| 1639 | intel_ring_emit(ring, MI_NOOP); | 1756 | intel_ring_emit(ring, MI_NOOP); |
| 1640 | intel_ring_advance(ring); | 1757 | intel_ring_advance(ring); |
| 1758 | |||
| 1641 | return 0; | 1759 | return 0; |
| 1642 | } | 1760 | } |
| 1643 | 1761 | ||
| @@ -1697,6 +1815,8 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
| 1697 | return ret; | 1815 | return ret; |
| 1698 | 1816 | ||
| 1699 | cmd = MI_FLUSH_DW; | 1817 | cmd = MI_FLUSH_DW; |
| 1818 | if (INTEL_INFO(ring->dev)->gen >= 8) | ||
| 1819 | cmd += 1; | ||
| 1700 | /* | 1820 | /* |
| 1701 | * Bspec vol 1c.3 - blitter engine command streamer: | 1821 | * Bspec vol 1c.3 - blitter engine command streamer: |
| 1702 | * "If ENABLED, all TLBs will be invalidated once the flush | 1822 | * "If ENABLED, all TLBs will be invalidated once the flush |
| @@ -1708,8 +1828,13 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, | |||
| 1708 | MI_FLUSH_DW_OP_STOREDW; | 1828 | MI_FLUSH_DW_OP_STOREDW; |
| 1709 | intel_ring_emit(ring, cmd); | 1829 | intel_ring_emit(ring, cmd); |
| 1710 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); | 1830 | intel_ring_emit(ring, I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT); |
| 1711 | intel_ring_emit(ring, 0); | 1831 | if (INTEL_INFO(ring->dev)->gen >= 8) { |
| 1712 | intel_ring_emit(ring, MI_NOOP); | 1832 | intel_ring_emit(ring, 0); /* upper addr */ |
| 1833 | intel_ring_emit(ring, 0); /* value */ | ||
| 1834 | } else { | ||
| 1835 | intel_ring_emit(ring, 0); | ||
| 1836 | intel_ring_emit(ring, MI_NOOP); | ||
| 1837 | } | ||
| 1713 | intel_ring_advance(ring); | 1838 | intel_ring_advance(ring); |
| 1714 | 1839 | ||
| 1715 | if (IS_GEN7(dev) && flush) | 1840 | if (IS_GEN7(dev) && flush) |
| @@ -1732,8 +1857,14 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 1732 | ring->flush = gen7_render_ring_flush; | 1857 | ring->flush = gen7_render_ring_flush; |
| 1733 | if (INTEL_INFO(dev)->gen == 6) | 1858 | if (INTEL_INFO(dev)->gen == 6) |
| 1734 | ring->flush = gen6_render_ring_flush; | 1859 | ring->flush = gen6_render_ring_flush; |
| 1735 | ring->irq_get = gen6_ring_get_irq; | 1860 | if (INTEL_INFO(dev)->gen >= 8) { |
| 1736 | ring->irq_put = gen6_ring_put_irq; | 1861 | ring->flush = gen8_render_ring_flush; |
| 1862 | ring->irq_get = gen8_ring_get_irq; | ||
| 1863 | ring->irq_put = gen8_ring_put_irq; | ||
| 1864 | } else { | ||
| 1865 | ring->irq_get = gen6_ring_get_irq; | ||
| 1866 | ring->irq_put = gen6_ring_put_irq; | ||
| 1867 | } | ||
| 1737 | ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; | 1868 | ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; |
| 1738 | ring->get_seqno = gen6_ring_get_seqno; | 1869 | ring->get_seqno = gen6_ring_get_seqno; |
| 1739 | ring->set_seqno = ring_set_seqno; | 1870 | ring->set_seqno = ring_set_seqno; |
| @@ -1775,6 +1906,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 1775 | ring->write_tail = ring_write_tail; | 1906 | ring->write_tail = ring_write_tail; |
| 1776 | if (IS_HASWELL(dev)) | 1907 | if (IS_HASWELL(dev)) |
| 1777 | ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; | 1908 | ring->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; |
| 1909 | else if (IS_GEN8(dev)) | ||
| 1910 | ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; | ||
| 1778 | else if (INTEL_INFO(dev)->gen >= 6) | 1911 | else if (INTEL_INFO(dev)->gen >= 6) |
| 1779 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 1912 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; |
| 1780 | else if (INTEL_INFO(dev)->gen >= 4) | 1913 | else if (INTEL_INFO(dev)->gen >= 4) |
| @@ -1888,7 +2021,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
| 1888 | ring->id = VCS; | 2021 | ring->id = VCS; |
| 1889 | 2022 | ||
| 1890 | ring->write_tail = ring_write_tail; | 2023 | ring->write_tail = ring_write_tail; |
| 1891 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 2024 | if (INTEL_INFO(dev)->gen >= 6) { |
| 1892 | ring->mmio_base = GEN6_BSD_RING_BASE; | 2025 | ring->mmio_base = GEN6_BSD_RING_BASE; |
| 1893 | /* gen6 bsd needs a special wa for tail updates */ | 2026 | /* gen6 bsd needs a special wa for tail updates */ |
| 1894 | if (IS_GEN6(dev)) | 2027 | if (IS_GEN6(dev)) |
| @@ -1897,10 +2030,20 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) | |||
| 1897 | ring->add_request = gen6_add_request; | 2030 | ring->add_request = gen6_add_request; |
| 1898 | ring->get_seqno = gen6_ring_get_seqno; | 2031 | ring->get_seqno = gen6_ring_get_seqno; |
| 1899 | ring->set_seqno = ring_set_seqno; | 2032 | ring->set_seqno = ring_set_seqno; |
| 1900 | ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; | 2033 | if (INTEL_INFO(dev)->gen >= 8) { |
| 1901 | ring->irq_get = gen6_ring_get_irq; | 2034 | ring->irq_enable_mask = |
| 1902 | ring->irq_put = gen6_ring_put_irq; | 2035 | GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; |
| 1903 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 2036 | ring->irq_get = gen8_ring_get_irq; |
| 2037 | ring->irq_put = gen8_ring_put_irq; | ||
| 2038 | ring->dispatch_execbuffer = | ||
| 2039 | gen8_ring_dispatch_execbuffer; | ||
| 2040 | } else { | ||
| 2041 | ring->irq_enable_mask = GT_BSD_USER_INTERRUPT; | ||
| 2042 | ring->irq_get = gen6_ring_get_irq; | ||
| 2043 | ring->irq_put = gen6_ring_put_irq; | ||
| 2044 | ring->dispatch_execbuffer = | ||
| 2045 | gen6_ring_dispatch_execbuffer; | ||
| 2046 | } | ||
| 1904 | ring->sync_to = gen6_ring_sync; | 2047 | ring->sync_to = gen6_ring_sync; |
| 1905 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR; | 2048 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VR; |
| 1906 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID; | 2049 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_INVALID; |
| @@ -1946,10 +2089,18 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) | |||
| 1946 | ring->add_request = gen6_add_request; | 2089 | ring->add_request = gen6_add_request; |
| 1947 | ring->get_seqno = gen6_ring_get_seqno; | 2090 | ring->get_seqno = gen6_ring_get_seqno; |
| 1948 | ring->set_seqno = ring_set_seqno; | 2091 | ring->set_seqno = ring_set_seqno; |
| 1949 | ring->irq_enable_mask = GT_BLT_USER_INTERRUPT; | 2092 | if (INTEL_INFO(dev)->gen >= 8) { |
| 1950 | ring->irq_get = gen6_ring_get_irq; | 2093 | ring->irq_enable_mask = |
| 1951 | ring->irq_put = gen6_ring_put_irq; | 2094 | GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; |
| 1952 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 2095 | ring->irq_get = gen8_ring_get_irq; |
| 2096 | ring->irq_put = gen8_ring_put_irq; | ||
| 2097 | ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; | ||
| 2098 | } else { | ||
| 2099 | ring->irq_enable_mask = GT_BLT_USER_INTERRUPT; | ||
| 2100 | ring->irq_get = gen6_ring_get_irq; | ||
| 2101 | ring->irq_put = gen6_ring_put_irq; | ||
| 2102 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | ||
| 2103 | } | ||
| 1953 | ring->sync_to = gen6_ring_sync; | 2104 | ring->sync_to = gen6_ring_sync; |
| 1954 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR; | 2105 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_BR; |
| 1955 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV; | 2106 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_BV; |
| @@ -1978,10 +2129,19 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) | |||
| 1978 | ring->add_request = gen6_add_request; | 2129 | ring->add_request = gen6_add_request; |
| 1979 | ring->get_seqno = gen6_ring_get_seqno; | 2130 | ring->get_seqno = gen6_ring_get_seqno; |
| 1980 | ring->set_seqno = ring_set_seqno; | 2131 | ring->set_seqno = ring_set_seqno; |
| 1981 | ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; | 2132 | |
| 1982 | ring->irq_get = hsw_vebox_get_irq; | 2133 | if (INTEL_INFO(dev)->gen >= 8) { |
| 1983 | ring->irq_put = hsw_vebox_put_irq; | 2134 | ring->irq_enable_mask = |
| 1984 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | 2135 | GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; |
| 2136 | ring->irq_get = gen8_ring_get_irq; | ||
| 2137 | ring->irq_put = gen8_ring_put_irq; | ||
| 2138 | ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; | ||
| 2139 | } else { | ||
| 2140 | ring->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; | ||
| 2141 | ring->irq_get = hsw_vebox_get_irq; | ||
| 2142 | ring->irq_put = hsw_vebox_put_irq; | ||
| 2143 | ring->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; | ||
| 2144 | } | ||
| 1985 | ring->sync_to = gen6_ring_sync; | 2145 | ring->sync_to = gen6_ring_sync; |
| 1986 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER; | 2146 | ring->semaphore_register[RCS] = MI_SEMAPHORE_SYNC_VER; |
| 1987 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV; | 2147 | ring->semaphore_register[VCS] = MI_SEMAPHORE_SYNC_VEV; |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 07b13dcb7fde..b9fabf826f7d 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -260,14 +260,14 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 260 | if (obj->tiling_mode != I915_TILING_NONE) | 260 | if (obj->tiling_mode != I915_TILING_NONE) |
| 261 | sprctl |= SPRITE_TILED; | 261 | sprctl |= SPRITE_TILED; |
| 262 | 262 | ||
| 263 | if (IS_HASWELL(dev)) | 263 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 264 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; | 264 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; |
| 265 | else | 265 | else |
| 266 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; | 266 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
| 267 | 267 | ||
| 268 | sprctl |= SPRITE_ENABLE; | 268 | sprctl |= SPRITE_ENABLE; |
| 269 | 269 | ||
| 270 | if (IS_HASWELL(dev)) | 270 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 271 | sprctl |= SPRITE_PIPE_CSC_ENABLE; | 271 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
| 272 | 272 | ||
| 273 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, | 273 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, |
| @@ -306,7 +306,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 306 | 306 | ||
| 307 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET | 307 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
| 308 | * register */ | 308 | * register */ |
| 309 | if (IS_HASWELL(dev)) | 309 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| 310 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); | 310 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
| 311 | else if (obj->tiling_mode != I915_TILING_NONE) | 311 | else if (obj->tiling_mode != I915_TILING_NONE) |
| 312 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); | 312 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
| @@ -1092,6 +1092,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
| 1092 | break; | 1092 | break; |
| 1093 | 1093 | ||
| 1094 | case 7: | 1094 | case 7: |
| 1095 | case 8: | ||
| 1095 | if (IS_IVYBRIDGE(dev)) { | 1096 | if (IS_IVYBRIDGE(dev)) { |
| 1096 | intel_plane->can_scale = true; | 1097 | intel_plane->can_scale = true; |
| 1097 | intel_plane->max_downscale = 2; | 1098 | intel_plane->max_downscale = 2; |
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index f6fae35c568e..f9883ceff946 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c | |||
| @@ -93,7 +93,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
| 93 | { | 93 | { |
| 94 | u32 forcewake_ack; | 94 | u32 forcewake_ack; |
| 95 | 95 | ||
| 96 | if (IS_HASWELL(dev_priv->dev)) | 96 | if (IS_HASWELL(dev_priv->dev) || IS_GEN8(dev_priv->dev)) |
| 97 | forcewake_ack = FORCEWAKE_ACK_HSW; | 97 | forcewake_ack = FORCEWAKE_ACK_HSW; |
| 98 | else | 98 | else |
| 99 | forcewake_ack = FORCEWAKE_MT_ACK; | 99 | forcewake_ack = FORCEWAKE_MT_ACK; |
| @@ -112,7 +112,8 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
| 112 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); | 112 | DRM_ERROR("Timed out waiting for forcewake to ack request.\n"); |
| 113 | 113 | ||
| 114 | /* WaRsForcewakeWaitTC0:ivb,hsw */ | 114 | /* WaRsForcewakeWaitTC0:ivb,hsw */ |
| 115 | __gen6_gt_wait_for_thread_c0(dev_priv); | 115 | if (INTEL_INFO(dev_priv->dev)->gen < 8) |
| 116 | __gen6_gt_wait_for_thread_c0(dev_priv); | ||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | 119 | static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) |
| @@ -459,6 +460,46 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) | |||
| 459 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ | 460 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ |
| 460 | } | 461 | } |
| 461 | 462 | ||
| 463 | static const u32 gen8_shadowed_regs[] = { | ||
| 464 | FORCEWAKE_MT, | ||
| 465 | GEN6_RPNSWREQ, | ||
| 466 | GEN6_RC_VIDEO_FREQ, | ||
| 467 | RING_TAIL(RENDER_RING_BASE), | ||
| 468 | RING_TAIL(GEN6_BSD_RING_BASE), | ||
| 469 | RING_TAIL(VEBOX_RING_BASE), | ||
| 470 | RING_TAIL(BLT_RING_BASE), | ||
| 471 | /* TODO: Other registers are not yet used */ | ||
| 472 | }; | ||
| 473 | |||
| 474 | static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg) | ||
| 475 | { | ||
| 476 | int i; | ||
| 477 | for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++) | ||
| 478 | if (reg == gen8_shadowed_regs[i]) | ||
| 479 | return true; | ||
| 480 | |||
| 481 | return false; | ||
| 482 | } | ||
| 483 | |||
| 484 | #define __gen8_write(x) \ | ||
| 485 | static void \ | ||
| 486 | gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ | ||
| 487 | bool __needs_put = !is_gen8_shadowed(dev_priv, reg); \ | ||
| 488 | REG_WRITE_HEADER; \ | ||
| 489 | if (__needs_put) { \ | ||
| 490 | dev_priv->uncore.funcs.force_wake_get(dev_priv); \ | ||
| 491 | } \ | ||
| 492 | __raw_i915_write##x(dev_priv, reg, val); \ | ||
| 493 | if (__needs_put) { \ | ||
| 494 | dev_priv->uncore.funcs.force_wake_put(dev_priv); \ | ||
| 495 | } \ | ||
| 496 | spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \ | ||
| 497 | } | ||
| 498 | |||
| 499 | __gen8_write(8) | ||
| 500 | __gen8_write(16) | ||
| 501 | __gen8_write(32) | ||
| 502 | __gen8_write(64) | ||
| 462 | __hsw_write(8) | 503 | __hsw_write(8) |
| 463 | __hsw_write(16) | 504 | __hsw_write(16) |
| 464 | __hsw_write(32) | 505 | __hsw_write(32) |
| @@ -476,6 +517,7 @@ __gen4_write(16) | |||
| 476 | __gen4_write(32) | 517 | __gen4_write(32) |
| 477 | __gen4_write(64) | 518 | __gen4_write(64) |
| 478 | 519 | ||
| 520 | #undef __gen8_write | ||
| 479 | #undef __hsw_write | 521 | #undef __hsw_write |
| 480 | #undef __gen6_write | 522 | #undef __gen6_write |
| 481 | #undef __gen5_write | 523 | #undef __gen5_write |
| @@ -492,7 +534,7 @@ void intel_uncore_init(struct drm_device *dev) | |||
| 492 | if (IS_VALLEYVIEW(dev)) { | 534 | if (IS_VALLEYVIEW(dev)) { |
| 493 | dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get; | 535 | dev_priv->uncore.funcs.force_wake_get = vlv_force_wake_get; |
| 494 | dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put; | 536 | dev_priv->uncore.funcs.force_wake_put = vlv_force_wake_put; |
| 495 | } else if (IS_HASWELL(dev)) { | 537 | } else if (IS_HASWELL(dev) || IS_GEN8(dev)) { |
| 496 | dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; | 538 | dev_priv->uncore.funcs.force_wake_get = __gen6_gt_force_wake_mt_get; |
| 497 | dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; | 539 | dev_priv->uncore.funcs.force_wake_put = __gen6_gt_force_wake_mt_put; |
| 498 | } else if (IS_IVYBRIDGE(dev)) { | 540 | } else if (IS_IVYBRIDGE(dev)) { |
| @@ -534,6 +576,16 @@ void intel_uncore_init(struct drm_device *dev) | |||
| 534 | } | 576 | } |
| 535 | 577 | ||
| 536 | switch (INTEL_INFO(dev)->gen) { | 578 | switch (INTEL_INFO(dev)->gen) { |
| 579 | default: | ||
| 580 | dev_priv->uncore.funcs.mmio_writeb = gen8_write8; | ||
| 581 | dev_priv->uncore.funcs.mmio_writew = gen8_write16; | ||
| 582 | dev_priv->uncore.funcs.mmio_writel = gen8_write32; | ||
| 583 | dev_priv->uncore.funcs.mmio_writeq = gen8_write64; | ||
| 584 | dev_priv->uncore.funcs.mmio_readb = gen6_read8; | ||
| 585 | dev_priv->uncore.funcs.mmio_readw = gen6_read16; | ||
| 586 | dev_priv->uncore.funcs.mmio_readl = gen6_read32; | ||
| 587 | dev_priv->uncore.funcs.mmio_readq = gen6_read64; | ||
| 588 | break; | ||
| 537 | case 7: | 589 | case 7: |
| 538 | case 6: | 590 | case 6: |
| 539 | if (IS_HASWELL(dev)) { | 591 | if (IS_HASWELL(dev)) { |
