diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 1205 |
1 files changed, 1025 insertions, 180 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a6f4cb5af185..6ed45a984230 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -27,6 +27,8 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
30 | #include <linux/circ_buf.h> | ||
31 | #include <linux/ctype.h> | ||
30 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
31 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
32 | #include <linux/export.h> | 34 | #include <linux/export.h> |
@@ -38,9 +40,6 @@ | |||
38 | #include <drm/i915_drm.h> | 40 | #include <drm/i915_drm.h> |
39 | #include "i915_drv.h" | 41 | #include "i915_drv.h" |
40 | 42 | ||
41 | #define DRM_I915_RING_DEBUG 1 | ||
42 | |||
43 | |||
44 | #if defined(CONFIG_DEBUG_FS) | 43 | #if defined(CONFIG_DEBUG_FS) |
45 | 44 | ||
46 | enum { | 45 | enum { |
@@ -54,6 +53,32 @@ static const char *yesno(int v) | |||
54 | return v ? "yes" : "no"; | 53 | return v ? "yes" : "no"; |
55 | } | 54 | } |
56 | 55 | ||
56 | /* As the drm_debugfs_init() routines are called before dev->dev_private is | ||
57 | * allocated we need to hook into the minor for release. */ | ||
58 | static int | ||
59 | drm_add_fake_info_node(struct drm_minor *minor, | ||
60 | struct dentry *ent, | ||
61 | const void *key) | ||
62 | { | ||
63 | struct drm_info_node *node; | ||
64 | |||
65 | node = kmalloc(sizeof(*node), GFP_KERNEL); | ||
66 | if (node == NULL) { | ||
67 | debugfs_remove(ent); | ||
68 | return -ENOMEM; | ||
69 | } | ||
70 | |||
71 | node->minor = minor; | ||
72 | node->dent = ent; | ||
73 | node->info_ent = (void *) key; | ||
74 | |||
75 | mutex_lock(&minor->debugfs_lock); | ||
76 | list_add(&node->list, &minor->debugfs_list); | ||
77 | mutex_unlock(&minor->debugfs_lock); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
57 | static int i915_capabilities(struct seq_file *m, void *data) | 82 | static int i915_capabilities(struct seq_file *m, void *data) |
58 | { | 83 | { |
59 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 84 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -145,6 +170,13 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
145 | seq_printf(m, " (%s)", obj->ring->name); | 170 | seq_printf(m, " (%s)", obj->ring->name); |
146 | } | 171 | } |
147 | 172 | ||
173 | static void describe_ctx(struct seq_file *m, struct i915_hw_context *ctx) | ||
174 | { | ||
175 | seq_putc(m, ctx->is_initialized ? 'I' : 'i'); | ||
176 | seq_putc(m, ctx->remap_slice ? 'R' : 'r'); | ||
177 | seq_putc(m, ' '); | ||
178 | } | ||
179 | |||
148 | static int i915_gem_object_list_info(struct seq_file *m, void *data) | 180 | static int i915_gem_object_list_info(struct seq_file *m, void *data) |
149 | { | 181 | { |
150 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 182 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
@@ -554,7 +586,53 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
554 | if (ret) | 586 | if (ret) |
555 | return ret; | 587 | return ret; |
556 | 588 | ||
557 | 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)) { | ||
558 | seq_printf(m, "Display IER:\t%08x\n", | 636 | seq_printf(m, "Display IER:\t%08x\n", |
559 | I915_READ(VLV_IER)); | 637 | I915_READ(VLV_IER)); |
560 | seq_printf(m, "Display IIR:\t%08x\n", | 638 | seq_printf(m, "Display IIR:\t%08x\n", |
@@ -626,7 +704,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) | |||
626 | seq_printf(m, "Interrupts received: %d\n", | 704 | seq_printf(m, "Interrupts received: %d\n", |
627 | atomic_read(&dev_priv->irq_received)); | 705 | atomic_read(&dev_priv->irq_received)); |
628 | for_each_ring(ring, dev_priv, i) { | 706 | for_each_ring(ring, dev_priv, i) { |
629 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 707 | if (INTEL_INFO(dev)->gen >= 6) { |
630 | seq_printf(m, | 708 | seq_printf(m, |
631 | "Graphics Interrupt mask (%s): %08x\n", | 709 | "Graphics Interrupt mask (%s): %08x\n", |
632 | ring->name, I915_READ_IMR(ring)); | 710 | ring->name, I915_READ_IMR(ring)); |
@@ -843,6 +921,8 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) | |||
843 | drm_i915_private_t *dev_priv = dev->dev_private; | 921 | drm_i915_private_t *dev_priv = dev->dev_private; |
844 | int ret; | 922 | int ret; |
845 | 923 | ||
924 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
925 | |||
846 | if (IS_GEN5(dev)) { | 926 | if (IS_GEN5(dev)) { |
847 | u16 rgvswctl = I915_READ16(MEMSWCTL); | 927 | u16 rgvswctl = I915_READ16(MEMSWCTL); |
848 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); | 928 | u16 rgvstat = I915_READ16(MEMSTAT_ILK); |
@@ -1321,6 +1401,8 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) | |||
1321 | return 0; | 1401 | return 0; |
1322 | } | 1402 | } |
1323 | 1403 | ||
1404 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
1405 | |||
1324 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 1406 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
1325 | if (ret) | 1407 | if (ret) |
1326 | return ret; | 1408 | return ret; |
@@ -1395,12 +1477,12 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | |||
1395 | { | 1477 | { |
1396 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1478 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1397 | struct drm_device *dev = node->minor->dev; | 1479 | struct drm_device *dev = node->minor->dev; |
1398 | drm_i915_private_t *dev_priv = dev->dev_private; | 1480 | struct intel_fbdev *ifbdev = NULL; |
1399 | struct intel_fbdev *ifbdev; | ||
1400 | struct intel_framebuffer *fb; | 1481 | struct intel_framebuffer *fb; |
1401 | int ret; | ||
1402 | 1482 | ||
1403 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | 1483 | #ifdef CONFIG_DRM_I915_FBDEV |
1484 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1485 | int ret = mutex_lock_interruptible(&dev->mode_config.mutex); | ||
1404 | if (ret) | 1486 | if (ret) |
1405 | return ret; | 1487 | return ret; |
1406 | 1488 | ||
@@ -1416,10 +1498,11 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) | |||
1416 | describe_obj(m, fb->obj); | 1498 | describe_obj(m, fb->obj); |
1417 | seq_putc(m, '\n'); | 1499 | seq_putc(m, '\n'); |
1418 | mutex_unlock(&dev->mode_config.mutex); | 1500 | mutex_unlock(&dev->mode_config.mutex); |
1501 | #endif | ||
1419 | 1502 | ||
1420 | mutex_lock(&dev->mode_config.fb_lock); | 1503 | mutex_lock(&dev->mode_config.fb_lock); |
1421 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { | 1504 | list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { |
1422 | if (&fb->base == ifbdev->helper.fb) | 1505 | if (ifbdev && &fb->base == ifbdev->helper.fb) |
1423 | continue; | 1506 | continue; |
1424 | 1507 | ||
1425 | seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ", | 1508 | seq_printf(m, "user size: %d x %d, depth %d, %d bpp, refcount %d, obj ", |
@@ -1442,6 +1525,7 @@ static int i915_context_status(struct seq_file *m, void *unused) | |||
1442 | struct drm_device *dev = node->minor->dev; | 1525 | struct drm_device *dev = node->minor->dev; |
1443 | drm_i915_private_t *dev_priv = dev->dev_private; | 1526 | drm_i915_private_t *dev_priv = dev->dev_private; |
1444 | struct intel_ring_buffer *ring; | 1527 | struct intel_ring_buffer *ring; |
1528 | struct i915_hw_context *ctx; | ||
1445 | int ret, i; | 1529 | int ret, i; |
1446 | 1530 | ||
1447 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); | 1531 | ret = mutex_lock_interruptible(&dev->mode_config.mutex); |
@@ -1460,12 +1544,15 @@ static int i915_context_status(struct seq_file *m, void *unused) | |||
1460 | seq_putc(m, '\n'); | 1544 | seq_putc(m, '\n'); |
1461 | } | 1545 | } |
1462 | 1546 | ||
1463 | for_each_ring(ring, dev_priv, i) { | 1547 | list_for_each_entry(ctx, &dev_priv->context_list, link) { |
1464 | if (ring->default_context) { | 1548 | seq_puts(m, "HW context "); |
1465 | seq_printf(m, "HW default context %s ring ", ring->name); | 1549 | describe_ctx(m, ctx); |
1466 | describe_obj(m, ring->default_context->obj); | 1550 | for_each_ring(ring, dev_priv, i) |
1467 | seq_putc(m, '\n'); | 1551 | if (ring->default_context == ctx) |
1468 | } | 1552 | seq_printf(m, "(default context %s) ", ring->name); |
1553 | |||
1554 | describe_obj(m, ctx->obj); | ||
1555 | seq_putc(m, '\n'); | ||
1469 | } | 1556 | } |
1470 | 1557 | ||
1471 | mutex_unlock(&dev->mode_config.mutex); | 1558 | mutex_unlock(&dev->mode_config.mutex); |
@@ -1536,7 +1623,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
1536 | I915_READ16(C0DRB3)); | 1623 | I915_READ16(C0DRB3)); |
1537 | seq_printf(m, "C1DRB3 = 0x%04x\n", | 1624 | seq_printf(m, "C1DRB3 = 0x%04x\n", |
1538 | I915_READ16(C1DRB3)); | 1625 | I915_READ16(C1DRB3)); |
1539 | } else if (IS_GEN6(dev) || IS_GEN7(dev)) { | 1626 | } else if (INTEL_INFO(dev)->gen >= 6) { |
1540 | seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", | 1627 | seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n", |
1541 | I915_READ(MAD_DIMM_C0)); | 1628 | I915_READ(MAD_DIMM_C0)); |
1542 | seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", | 1629 | seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n", |
@@ -1545,8 +1632,12 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
1545 | I915_READ(MAD_DIMM_C2)); | 1632 | I915_READ(MAD_DIMM_C2)); |
1546 | seq_printf(m, "TILECTL = 0x%08x\n", | 1633 | seq_printf(m, "TILECTL = 0x%08x\n", |
1547 | I915_READ(TILECTL)); | 1634 | I915_READ(TILECTL)); |
1548 | seq_printf(m, "ARB_MODE = 0x%08x\n", | 1635 | if (IS_GEN8(dev)) |
1549 | 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)); | ||
1550 | seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", | 1641 | seq_printf(m, "DISP_ARB_CTL = 0x%08x\n", |
1551 | I915_READ(DISP_ARB_CTL)); | 1642 | I915_READ(DISP_ARB_CTL)); |
1552 | } | 1643 | } |
@@ -1555,18 +1646,37 @@ static int i915_swizzle_info(struct seq_file *m, void *data) | |||
1555 | return 0; | 1646 | return 0; |
1556 | } | 1647 | } |
1557 | 1648 | ||
1558 | 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) |
1559 | { | 1650 | { |
1560 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
1561 | struct drm_device *dev = node->minor->dev; | ||
1562 | struct drm_i915_private *dev_priv = dev->dev_private; | 1651 | struct drm_i915_private *dev_priv = dev->dev_private; |
1563 | struct intel_ring_buffer *ring; | 1652 | struct intel_ring_buffer *ring; |
1564 | int i, ret; | 1653 | struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; |
1654 | int unused, i; | ||
1565 | 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; | ||
1566 | 1679 | ||
1567 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
1568 | if (ret) | ||
1569 | return ret; | ||
1570 | if (INTEL_INFO(dev)->gen == 6) | 1680 | if (INTEL_INFO(dev)->gen == 6) |
1571 | 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)); |
1572 | 1682 | ||
@@ -1585,6 +1695,22 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) | |||
1585 | 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); |
1586 | } | 1696 | } |
1587 | 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 | |||
1588 | mutex_unlock(&dev->struct_mutex); | 1714 | mutex_unlock(&dev->struct_mutex); |
1589 | 1715 | ||
1590 | return 0; | 1716 | return 0; |
@@ -1610,27 +1736,27 @@ static int i915_dpio_info(struct seq_file *m, void *data) | |||
1610 | seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL)); | 1736 | seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL)); |
1611 | 1737 | ||
1612 | seq_printf(m, "DPIO_DIV_A: 0x%08x\n", | 1738 | seq_printf(m, "DPIO_DIV_A: 0x%08x\n", |
1613 | vlv_dpio_read(dev_priv, _DPIO_DIV_A)); | 1739 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_A)); |
1614 | seq_printf(m, "DPIO_DIV_B: 0x%08x\n", | 1740 | seq_printf(m, "DPIO_DIV_B: 0x%08x\n", |
1615 | vlv_dpio_read(dev_priv, _DPIO_DIV_B)); | 1741 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_DIV_B)); |
1616 | 1742 | ||
1617 | seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n", | 1743 | seq_printf(m, "DPIO_REFSFR_A: 0x%08x\n", |
1618 | vlv_dpio_read(dev_priv, _DPIO_REFSFR_A)); | 1744 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_A)); |
1619 | seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n", | 1745 | seq_printf(m, "DPIO_REFSFR_B: 0x%08x\n", |
1620 | vlv_dpio_read(dev_priv, _DPIO_REFSFR_B)); | 1746 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_REFSFR_B)); |
1621 | 1747 | ||
1622 | seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n", | 1748 | seq_printf(m, "DPIO_CORE_CLK_A: 0x%08x\n", |
1623 | vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_A)); | 1749 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_A)); |
1624 | seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n", | 1750 | seq_printf(m, "DPIO_CORE_CLK_B: 0x%08x\n", |
1625 | vlv_dpio_read(dev_priv, _DPIO_CORE_CLK_B)); | 1751 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_CORE_CLK_B)); |
1626 | 1752 | ||
1627 | seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n", | 1753 | seq_printf(m, "DPIO_LPF_COEFF_A: 0x%08x\n", |
1628 | vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_A)); | 1754 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_A)); |
1629 | seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n", | 1755 | seq_printf(m, "DPIO_LPF_COEFF_B: 0x%08x\n", |
1630 | vlv_dpio_read(dev_priv, _DPIO_LPF_COEFF_B)); | 1756 | vlv_dpio_read(dev_priv, PIPE_A, _DPIO_LPF_COEFF_B)); |
1631 | 1757 | ||
1632 | seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n", | 1758 | seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n", |
1633 | vlv_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE)); | 1759 | vlv_dpio_read(dev_priv, PIPE_A, DPIO_FASTCLK_DISABLE)); |
1634 | 1760 | ||
1635 | mutex_unlock(&dev_priv->dpio_lock); | 1761 | mutex_unlock(&dev_priv->dpio_lock); |
1636 | 1762 | ||
@@ -1655,126 +1781,20 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) | |||
1655 | struct drm_info_node *node = m->private; | 1781 | struct drm_info_node *node = m->private; |
1656 | struct drm_device *dev = node->minor->dev; | 1782 | struct drm_device *dev = node->minor->dev; |
1657 | struct drm_i915_private *dev_priv = dev->dev_private; | 1783 | struct drm_i915_private *dev_priv = dev->dev_private; |
1658 | u32 psrstat, psrperf; | 1784 | u32 psrperf = 0; |
1659 | 1785 | bool enabled = false; | |
1660 | if (!IS_HASWELL(dev)) { | ||
1661 | seq_puts(m, "PSR not supported on this platform\n"); | ||
1662 | } else if (IS_HASWELL(dev) && I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE) { | ||
1663 | seq_puts(m, "PSR enabled\n"); | ||
1664 | } else { | ||
1665 | seq_puts(m, "PSR disabled: "); | ||
1666 | switch (dev_priv->no_psr_reason) { | ||
1667 | case PSR_NO_SOURCE: | ||
1668 | seq_puts(m, "not supported on this platform"); | ||
1669 | break; | ||
1670 | case PSR_NO_SINK: | ||
1671 | seq_puts(m, "not supported by panel"); | ||
1672 | break; | ||
1673 | case PSR_MODULE_PARAM: | ||
1674 | seq_puts(m, "disabled by flag"); | ||
1675 | break; | ||
1676 | case PSR_CRTC_NOT_ACTIVE: | ||
1677 | seq_puts(m, "crtc not active"); | ||
1678 | break; | ||
1679 | case PSR_PWR_WELL_ENABLED: | ||
1680 | seq_puts(m, "power well enabled"); | ||
1681 | break; | ||
1682 | case PSR_NOT_TILED: | ||
1683 | seq_puts(m, "not tiled"); | ||
1684 | break; | ||
1685 | case PSR_SPRITE_ENABLED: | ||
1686 | seq_puts(m, "sprite enabled"); | ||
1687 | break; | ||
1688 | case PSR_S3D_ENABLED: | ||
1689 | seq_puts(m, "stereo 3d enabled"); | ||
1690 | break; | ||
1691 | case PSR_INTERLACED_ENABLED: | ||
1692 | seq_puts(m, "interlaced enabled"); | ||
1693 | break; | ||
1694 | case PSR_HSW_NOT_DDIA: | ||
1695 | seq_puts(m, "HSW ties PSR to DDI A (eDP)"); | ||
1696 | break; | ||
1697 | default: | ||
1698 | seq_puts(m, "unknown reason"); | ||
1699 | } | ||
1700 | seq_puts(m, "\n"); | ||
1701 | return 0; | ||
1702 | } | ||
1703 | |||
1704 | psrstat = I915_READ(EDP_PSR_STATUS_CTL); | ||
1705 | |||
1706 | seq_puts(m, "PSR Current State: "); | ||
1707 | switch (psrstat & EDP_PSR_STATUS_STATE_MASK) { | ||
1708 | case EDP_PSR_STATUS_STATE_IDLE: | ||
1709 | seq_puts(m, "Reset state\n"); | ||
1710 | break; | ||
1711 | case EDP_PSR_STATUS_STATE_SRDONACK: | ||
1712 | seq_puts(m, "Wait for TG/Stream to send on frame of data after SRD conditions are met\n"); | ||
1713 | break; | ||
1714 | case EDP_PSR_STATUS_STATE_SRDENT: | ||
1715 | seq_puts(m, "SRD entry\n"); | ||
1716 | break; | ||
1717 | case EDP_PSR_STATUS_STATE_BUFOFF: | ||
1718 | seq_puts(m, "Wait for buffer turn off\n"); | ||
1719 | break; | ||
1720 | case EDP_PSR_STATUS_STATE_BUFON: | ||
1721 | seq_puts(m, "Wait for buffer turn on\n"); | ||
1722 | break; | ||
1723 | case EDP_PSR_STATUS_STATE_AUXACK: | ||
1724 | seq_puts(m, "Wait for AUX to acknowledge on SRD exit\n"); | ||
1725 | break; | ||
1726 | case EDP_PSR_STATUS_STATE_SRDOFFACK: | ||
1727 | seq_puts(m, "Wait for TG/Stream to acknowledge the SRD VDM exit\n"); | ||
1728 | break; | ||
1729 | default: | ||
1730 | seq_puts(m, "Unknown\n"); | ||
1731 | break; | ||
1732 | } | ||
1733 | |||
1734 | seq_puts(m, "Link Status: "); | ||
1735 | switch (psrstat & EDP_PSR_STATUS_LINK_MASK) { | ||
1736 | case EDP_PSR_STATUS_LINK_FULL_OFF: | ||
1737 | seq_puts(m, "Link is fully off\n"); | ||
1738 | break; | ||
1739 | case EDP_PSR_STATUS_LINK_FULL_ON: | ||
1740 | seq_puts(m, "Link is fully on\n"); | ||
1741 | break; | ||
1742 | case EDP_PSR_STATUS_LINK_STANDBY: | ||
1743 | seq_puts(m, "Link is in standby\n"); | ||
1744 | break; | ||
1745 | default: | ||
1746 | seq_puts(m, "Unknown\n"); | ||
1747 | break; | ||
1748 | } | ||
1749 | |||
1750 | seq_printf(m, "PSR Entry Count: %u\n", | ||
1751 | psrstat >> EDP_PSR_STATUS_COUNT_SHIFT & | ||
1752 | EDP_PSR_STATUS_COUNT_MASK); | ||
1753 | |||
1754 | seq_printf(m, "Max Sleep Timer Counter: %u\n", | ||
1755 | psrstat >> EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT & | ||
1756 | EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK); | ||
1757 | 1786 | ||
1758 | seq_printf(m, "Had AUX error: %s\n", | 1787 | seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support)); |
1759 | yesno(psrstat & EDP_PSR_STATUS_AUX_ERROR)); | 1788 | seq_printf(m, "Source_OK: %s\n", yesno(dev_priv->psr.source_ok)); |
1760 | 1789 | ||
1761 | seq_printf(m, "Sending AUX: %s\n", | 1790 | enabled = HAS_PSR(dev) && |
1762 | yesno(psrstat & EDP_PSR_STATUS_AUX_SENDING)); | 1791 | I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE; |
1792 | seq_printf(m, "Enabled: %s\n", yesno(enabled)); | ||
1763 | 1793 | ||
1764 | seq_printf(m, "Sending Idle: %s\n", | 1794 | if (HAS_PSR(dev)) |
1765 | yesno(psrstat & EDP_PSR_STATUS_SENDING_IDLE)); | 1795 | psrperf = I915_READ(EDP_PSR_PERF_CNT(dev)) & |
1766 | 1796 | EDP_PSR_PERF_CNT_MASK; | |
1767 | seq_printf(m, "Sending TP2 TP3: %s\n", | 1797 | seq_printf(m, "Performance_Counter: %u\n", psrperf); |
1768 | yesno(psrstat & EDP_PSR_STATUS_SENDING_TP2_TP3)); | ||
1769 | |||
1770 | seq_printf(m, "Sending TP1: %s\n", | ||
1771 | yesno(psrstat & EDP_PSR_STATUS_SENDING_TP1)); | ||
1772 | |||
1773 | seq_printf(m, "Idle Count: %u\n", | ||
1774 | psrstat & EDP_PSR_STATUS_IDLE_MASK); | ||
1775 | |||
1776 | psrperf = (I915_READ(EDP_PSR_PERF_CNT)) & EDP_PSR_PERF_CNT_MASK; | ||
1777 | seq_printf(m, "Performance Counter: %u\n", psrperf); | ||
1778 | 1798 | ||
1779 | return 0; | 1799 | return 0; |
1780 | } | 1800 | } |
@@ -1825,6 +1845,751 @@ static int i915_pc8_status(struct seq_file *m, void *unused) | |||
1825 | return 0; | 1845 | return 0; |
1826 | } | 1846 | } |
1827 | 1847 | ||
1848 | struct pipe_crc_info { | ||
1849 | const char *name; | ||
1850 | struct drm_device *dev; | ||
1851 | enum pipe pipe; | ||
1852 | }; | ||
1853 | |||
1854 | static int i915_pipe_crc_open(struct inode *inode, struct file *filep) | ||
1855 | { | ||
1856 | struct pipe_crc_info *info = inode->i_private; | ||
1857 | struct drm_i915_private *dev_priv = info->dev->dev_private; | ||
1858 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; | ||
1859 | |||
1860 | spin_lock_irq(&pipe_crc->lock); | ||
1861 | |||
1862 | if (pipe_crc->opened) { | ||
1863 | spin_unlock_irq(&pipe_crc->lock); | ||
1864 | return -EBUSY; /* already open */ | ||
1865 | } | ||
1866 | |||
1867 | pipe_crc->opened = true; | ||
1868 | filep->private_data = inode->i_private; | ||
1869 | |||
1870 | spin_unlock_irq(&pipe_crc->lock); | ||
1871 | |||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | static int i915_pipe_crc_release(struct inode *inode, struct file *filep) | ||
1876 | { | ||
1877 | struct pipe_crc_info *info = inode->i_private; | ||
1878 | struct drm_i915_private *dev_priv = info->dev->dev_private; | ||
1879 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; | ||
1880 | |||
1881 | spin_lock_irq(&pipe_crc->lock); | ||
1882 | pipe_crc->opened = false; | ||
1883 | spin_unlock_irq(&pipe_crc->lock); | ||
1884 | |||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1888 | /* (6 fields, 8 chars each, space separated (5) + '\n') */ | ||
1889 | #define PIPE_CRC_LINE_LEN (6 * 8 + 5 + 1) | ||
1890 | /* account for \'0' */ | ||
1891 | #define PIPE_CRC_BUFFER_LEN (PIPE_CRC_LINE_LEN + 1) | ||
1892 | |||
1893 | static int pipe_crc_data_count(struct intel_pipe_crc *pipe_crc) | ||
1894 | { | ||
1895 | assert_spin_locked(&pipe_crc->lock); | ||
1896 | return CIRC_CNT(pipe_crc->head, pipe_crc->tail, | ||
1897 | INTEL_PIPE_CRC_ENTRIES_NR); | ||
1898 | } | ||
1899 | |||
1900 | static ssize_t | ||
1901 | i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count, | ||
1902 | loff_t *pos) | ||
1903 | { | ||
1904 | struct pipe_crc_info *info = filep->private_data; | ||
1905 | struct drm_device *dev = info->dev; | ||
1906 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1907 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; | ||
1908 | char buf[PIPE_CRC_BUFFER_LEN]; | ||
1909 | int head, tail, n_entries, n; | ||
1910 | ssize_t bytes_read; | ||
1911 | |||
1912 | /* | ||
1913 | * Don't allow user space to provide buffers not big enough to hold | ||
1914 | * a line of data. | ||
1915 | */ | ||
1916 | if (count < PIPE_CRC_LINE_LEN) | ||
1917 | return -EINVAL; | ||
1918 | |||
1919 | if (pipe_crc->source == INTEL_PIPE_CRC_SOURCE_NONE) | ||
1920 | return 0; | ||
1921 | |||
1922 | /* nothing to read */ | ||
1923 | spin_lock_irq(&pipe_crc->lock); | ||
1924 | while (pipe_crc_data_count(pipe_crc) == 0) { | ||
1925 | int ret; | ||
1926 | |||
1927 | if (filep->f_flags & O_NONBLOCK) { | ||
1928 | spin_unlock_irq(&pipe_crc->lock); | ||
1929 | return -EAGAIN; | ||
1930 | } | ||
1931 | |||
1932 | ret = wait_event_interruptible_lock_irq(pipe_crc->wq, | ||
1933 | pipe_crc_data_count(pipe_crc), pipe_crc->lock); | ||
1934 | if (ret) { | ||
1935 | spin_unlock_irq(&pipe_crc->lock); | ||
1936 | return ret; | ||
1937 | } | ||
1938 | } | ||
1939 | |||
1940 | /* We now have one or more entries to read */ | ||
1941 | head = pipe_crc->head; | ||
1942 | tail = pipe_crc->tail; | ||
1943 | n_entries = min((size_t)CIRC_CNT(head, tail, INTEL_PIPE_CRC_ENTRIES_NR), | ||
1944 | count / PIPE_CRC_LINE_LEN); | ||
1945 | spin_unlock_irq(&pipe_crc->lock); | ||
1946 | |||
1947 | bytes_read = 0; | ||
1948 | n = 0; | ||
1949 | do { | ||
1950 | struct intel_pipe_crc_entry *entry = &pipe_crc->entries[tail]; | ||
1951 | int ret; | ||
1952 | |||
1953 | bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN, | ||
1954 | "%8u %8x %8x %8x %8x %8x\n", | ||
1955 | entry->frame, entry->crc[0], | ||
1956 | entry->crc[1], entry->crc[2], | ||
1957 | entry->crc[3], entry->crc[4]); | ||
1958 | |||
1959 | ret = copy_to_user(user_buf + n * PIPE_CRC_LINE_LEN, | ||
1960 | buf, PIPE_CRC_LINE_LEN); | ||
1961 | if (ret == PIPE_CRC_LINE_LEN) | ||
1962 | return -EFAULT; | ||
1963 | |||
1964 | BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR); | ||
1965 | tail = (tail + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1); | ||
1966 | n++; | ||
1967 | } while (--n_entries); | ||
1968 | |||
1969 | spin_lock_irq(&pipe_crc->lock); | ||
1970 | pipe_crc->tail = tail; | ||
1971 | spin_unlock_irq(&pipe_crc->lock); | ||
1972 | |||
1973 | return bytes_read; | ||
1974 | } | ||
1975 | |||
1976 | static const struct file_operations i915_pipe_crc_fops = { | ||
1977 | .owner = THIS_MODULE, | ||
1978 | .open = i915_pipe_crc_open, | ||
1979 | .read = i915_pipe_crc_read, | ||
1980 | .release = i915_pipe_crc_release, | ||
1981 | }; | ||
1982 | |||
1983 | static struct pipe_crc_info i915_pipe_crc_data[I915_MAX_PIPES] = { | ||
1984 | { | ||
1985 | .name = "i915_pipe_A_crc", | ||
1986 | .pipe = PIPE_A, | ||
1987 | }, | ||
1988 | { | ||
1989 | .name = "i915_pipe_B_crc", | ||
1990 | .pipe = PIPE_B, | ||
1991 | }, | ||
1992 | { | ||
1993 | .name = "i915_pipe_C_crc", | ||
1994 | .pipe = PIPE_C, | ||
1995 | }, | ||
1996 | }; | ||
1997 | |||
1998 | static int i915_pipe_crc_create(struct dentry *root, struct drm_minor *minor, | ||
1999 | enum pipe pipe) | ||
2000 | { | ||
2001 | struct drm_device *dev = minor->dev; | ||
2002 | struct dentry *ent; | ||
2003 | struct pipe_crc_info *info = &i915_pipe_crc_data[pipe]; | ||
2004 | |||
2005 | info->dev = dev; | ||
2006 | ent = debugfs_create_file(info->name, S_IRUGO, root, info, | ||
2007 | &i915_pipe_crc_fops); | ||
2008 | if (IS_ERR(ent)) | ||
2009 | return PTR_ERR(ent); | ||
2010 | |||
2011 | return drm_add_fake_info_node(minor, ent, info); | ||
2012 | } | ||
2013 | |||
2014 | static const char * const pipe_crc_sources[] = { | ||
2015 | "none", | ||
2016 | "plane1", | ||
2017 | "plane2", | ||
2018 | "pf", | ||
2019 | "pipe", | ||
2020 | "TV", | ||
2021 | "DP-B", | ||
2022 | "DP-C", | ||
2023 | "DP-D", | ||
2024 | "auto", | ||
2025 | }; | ||
2026 | |||
2027 | static const char *pipe_crc_source_name(enum intel_pipe_crc_source source) | ||
2028 | { | ||
2029 | BUILD_BUG_ON(ARRAY_SIZE(pipe_crc_sources) != INTEL_PIPE_CRC_SOURCE_MAX); | ||
2030 | return pipe_crc_sources[source]; | ||
2031 | } | ||
2032 | |||
2033 | static int display_crc_ctl_show(struct seq_file *m, void *data) | ||
2034 | { | ||
2035 | struct drm_device *dev = m->private; | ||
2036 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2037 | int i; | ||
2038 | |||
2039 | for (i = 0; i < I915_MAX_PIPES; i++) | ||
2040 | seq_printf(m, "%c %s\n", pipe_name(i), | ||
2041 | pipe_crc_source_name(dev_priv->pipe_crc[i].source)); | ||
2042 | |||
2043 | return 0; | ||
2044 | } | ||
2045 | |||
2046 | static int display_crc_ctl_open(struct inode *inode, struct file *file) | ||
2047 | { | ||
2048 | struct drm_device *dev = inode->i_private; | ||
2049 | |||
2050 | return single_open(file, display_crc_ctl_show, dev); | ||
2051 | } | ||
2052 | |||
2053 | static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, | ||
2054 | uint32_t *val) | ||
2055 | { | ||
2056 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) | ||
2057 | *source = INTEL_PIPE_CRC_SOURCE_PIPE; | ||
2058 | |||
2059 | switch (*source) { | ||
2060 | case INTEL_PIPE_CRC_SOURCE_PIPE: | ||
2061 | *val = PIPE_CRC_ENABLE | PIPE_CRC_INCLUDE_BORDER_I8XX; | ||
2062 | break; | ||
2063 | case INTEL_PIPE_CRC_SOURCE_NONE: | ||
2064 | *val = 0; | ||
2065 | break; | ||
2066 | default: | ||
2067 | return -EINVAL; | ||
2068 | } | ||
2069 | |||
2070 | return 0; | ||
2071 | } | ||
2072 | |||
2073 | static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe, | ||
2074 | enum intel_pipe_crc_source *source) | ||
2075 | { | ||
2076 | struct intel_encoder *encoder; | ||
2077 | struct intel_crtc *crtc; | ||
2078 | struct intel_digital_port *dig_port; | ||
2079 | int ret = 0; | ||
2080 | |||
2081 | *source = INTEL_PIPE_CRC_SOURCE_PIPE; | ||
2082 | |||
2083 | mutex_lock(&dev->mode_config.mutex); | ||
2084 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
2085 | base.head) { | ||
2086 | if (!encoder->base.crtc) | ||
2087 | continue; | ||
2088 | |||
2089 | crtc = to_intel_crtc(encoder->base.crtc); | ||
2090 | |||
2091 | if (crtc->pipe != pipe) | ||
2092 | continue; | ||
2093 | |||
2094 | switch (encoder->type) { | ||
2095 | case INTEL_OUTPUT_TVOUT: | ||
2096 | *source = INTEL_PIPE_CRC_SOURCE_TV; | ||
2097 | break; | ||
2098 | case INTEL_OUTPUT_DISPLAYPORT: | ||
2099 | case INTEL_OUTPUT_EDP: | ||
2100 | dig_port = enc_to_dig_port(&encoder->base); | ||
2101 | switch (dig_port->port) { | ||
2102 | case PORT_B: | ||
2103 | *source = INTEL_PIPE_CRC_SOURCE_DP_B; | ||
2104 | break; | ||
2105 | case PORT_C: | ||
2106 | *source = INTEL_PIPE_CRC_SOURCE_DP_C; | ||
2107 | break; | ||
2108 | case PORT_D: | ||
2109 | *source = INTEL_PIPE_CRC_SOURCE_DP_D; | ||
2110 | break; | ||
2111 | default: | ||
2112 | WARN(1, "nonexisting DP port %c\n", | ||
2113 | port_name(dig_port->port)); | ||
2114 | break; | ||
2115 | } | ||
2116 | break; | ||
2117 | } | ||
2118 | } | ||
2119 | mutex_unlock(&dev->mode_config.mutex); | ||
2120 | |||
2121 | return ret; | ||
2122 | } | ||
2123 | |||
2124 | static int vlv_pipe_crc_ctl_reg(struct drm_device *dev, | ||
2125 | enum pipe pipe, | ||
2126 | enum intel_pipe_crc_source *source, | ||
2127 | uint32_t *val) | ||
2128 | { | ||
2129 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2130 | bool need_stable_symbols = false; | ||
2131 | |||
2132 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { | ||
2133 | int ret = i9xx_pipe_crc_auto_source(dev, pipe, source); | ||
2134 | if (ret) | ||
2135 | return ret; | ||
2136 | } | ||
2137 | |||
2138 | switch (*source) { | ||
2139 | case INTEL_PIPE_CRC_SOURCE_PIPE: | ||
2140 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_VLV; | ||
2141 | break; | ||
2142 | case INTEL_PIPE_CRC_SOURCE_DP_B: | ||
2143 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_VLV; | ||
2144 | need_stable_symbols = true; | ||
2145 | break; | ||
2146 | case INTEL_PIPE_CRC_SOURCE_DP_C: | ||
2147 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_VLV; | ||
2148 | need_stable_symbols = true; | ||
2149 | break; | ||
2150 | case INTEL_PIPE_CRC_SOURCE_NONE: | ||
2151 | *val = 0; | ||
2152 | break; | ||
2153 | default: | ||
2154 | return -EINVAL; | ||
2155 | } | ||
2156 | |||
2157 | /* | ||
2158 | * When the pipe CRC tap point is after the transcoders we need | ||
2159 | * to tweak symbol-level features to produce a deterministic series of | ||
2160 | * symbols for a given frame. We need to reset those features only once | ||
2161 | * a frame (instead of every nth symbol): | ||
2162 | * - DC-balance: used to ensure a better clock recovery from the data | ||
2163 | * link (SDVO) | ||
2164 | * - DisplayPort scrambling: used for EMI reduction | ||
2165 | */ | ||
2166 | if (need_stable_symbols) { | ||
2167 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2168 | |||
2169 | WARN_ON(!IS_G4X(dev)); | ||
2170 | |||
2171 | tmp |= DC_BALANCE_RESET_VLV; | ||
2172 | if (pipe == PIPE_A) | ||
2173 | tmp |= PIPE_A_SCRAMBLE_RESET; | ||
2174 | else | ||
2175 | tmp |= PIPE_B_SCRAMBLE_RESET; | ||
2176 | |||
2177 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2178 | } | ||
2179 | |||
2180 | return 0; | ||
2181 | } | ||
2182 | |||
2183 | static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev, | ||
2184 | enum pipe pipe, | ||
2185 | enum intel_pipe_crc_source *source, | ||
2186 | uint32_t *val) | ||
2187 | { | ||
2188 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2189 | bool need_stable_symbols = false; | ||
2190 | |||
2191 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { | ||
2192 | int ret = i9xx_pipe_crc_auto_source(dev, pipe, source); | ||
2193 | if (ret) | ||
2194 | return ret; | ||
2195 | } | ||
2196 | |||
2197 | switch (*source) { | ||
2198 | case INTEL_PIPE_CRC_SOURCE_PIPE: | ||
2199 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX; | ||
2200 | break; | ||
2201 | case INTEL_PIPE_CRC_SOURCE_TV: | ||
2202 | if (!SUPPORTS_TV(dev)) | ||
2203 | return -EINVAL; | ||
2204 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE; | ||
2205 | break; | ||
2206 | case INTEL_PIPE_CRC_SOURCE_DP_B: | ||
2207 | if (!IS_G4X(dev)) | ||
2208 | return -EINVAL; | ||
2209 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_B_G4X; | ||
2210 | need_stable_symbols = true; | ||
2211 | break; | ||
2212 | case INTEL_PIPE_CRC_SOURCE_DP_C: | ||
2213 | if (!IS_G4X(dev)) | ||
2214 | return -EINVAL; | ||
2215 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_C_G4X; | ||
2216 | need_stable_symbols = true; | ||
2217 | break; | ||
2218 | case INTEL_PIPE_CRC_SOURCE_DP_D: | ||
2219 | if (!IS_G4X(dev)) | ||
2220 | return -EINVAL; | ||
2221 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_G4X; | ||
2222 | need_stable_symbols = true; | ||
2223 | break; | ||
2224 | case INTEL_PIPE_CRC_SOURCE_NONE: | ||
2225 | *val = 0; | ||
2226 | break; | ||
2227 | default: | ||
2228 | return -EINVAL; | ||
2229 | } | ||
2230 | |||
2231 | /* | ||
2232 | * When the pipe CRC tap point is after the transcoders we need | ||
2233 | * to tweak symbol-level features to produce a deterministic series of | ||
2234 | * symbols for a given frame. We need to reset those features only once | ||
2235 | * a frame (instead of every nth symbol): | ||
2236 | * - DC-balance: used to ensure a better clock recovery from the data | ||
2237 | * link (SDVO) | ||
2238 | * - DisplayPort scrambling: used for EMI reduction | ||
2239 | */ | ||
2240 | if (need_stable_symbols) { | ||
2241 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2242 | |||
2243 | WARN_ON(!IS_G4X(dev)); | ||
2244 | |||
2245 | I915_WRITE(PORT_DFT_I9XX, | ||
2246 | I915_READ(PORT_DFT_I9XX) | DC_BALANCE_RESET); | ||
2247 | |||
2248 | if (pipe == PIPE_A) | ||
2249 | tmp |= PIPE_A_SCRAMBLE_RESET; | ||
2250 | else | ||
2251 | tmp |= PIPE_B_SCRAMBLE_RESET; | ||
2252 | |||
2253 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2254 | } | ||
2255 | |||
2256 | return 0; | ||
2257 | } | ||
2258 | |||
2259 | static void vlv_undo_pipe_scramble_reset(struct drm_device *dev, | ||
2260 | enum pipe pipe) | ||
2261 | { | ||
2262 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2263 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2264 | |||
2265 | if (pipe == PIPE_A) | ||
2266 | tmp &= ~PIPE_A_SCRAMBLE_RESET; | ||
2267 | else | ||
2268 | tmp &= ~PIPE_B_SCRAMBLE_RESET; | ||
2269 | if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) | ||
2270 | tmp &= ~DC_BALANCE_RESET_VLV; | ||
2271 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2272 | |||
2273 | } | ||
2274 | |||
2275 | static void g4x_undo_pipe_scramble_reset(struct drm_device *dev, | ||
2276 | enum pipe pipe) | ||
2277 | { | ||
2278 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2279 | uint32_t tmp = I915_READ(PORT_DFT2_G4X); | ||
2280 | |||
2281 | if (pipe == PIPE_A) | ||
2282 | tmp &= ~PIPE_A_SCRAMBLE_RESET; | ||
2283 | else | ||
2284 | tmp &= ~PIPE_B_SCRAMBLE_RESET; | ||
2285 | I915_WRITE(PORT_DFT2_G4X, tmp); | ||
2286 | |||
2287 | if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) { | ||
2288 | I915_WRITE(PORT_DFT_I9XX, | ||
2289 | I915_READ(PORT_DFT_I9XX) & ~DC_BALANCE_RESET); | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, | ||
2294 | uint32_t *val) | ||
2295 | { | ||
2296 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) | ||
2297 | *source = INTEL_PIPE_CRC_SOURCE_PIPE; | ||
2298 | |||
2299 | switch (*source) { | ||
2300 | case INTEL_PIPE_CRC_SOURCE_PLANE1: | ||
2301 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_ILK; | ||
2302 | break; | ||
2303 | case INTEL_PIPE_CRC_SOURCE_PLANE2: | ||
2304 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_ILK; | ||
2305 | break; | ||
2306 | case INTEL_PIPE_CRC_SOURCE_PIPE: | ||
2307 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_ILK; | ||
2308 | break; | ||
2309 | case INTEL_PIPE_CRC_SOURCE_NONE: | ||
2310 | *val = 0; | ||
2311 | break; | ||
2312 | default: | ||
2313 | return -EINVAL; | ||
2314 | } | ||
2315 | |||
2316 | return 0; | ||
2317 | } | ||
2318 | |||
2319 | static int ivb_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, | ||
2320 | uint32_t *val) | ||
2321 | { | ||
2322 | if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) | ||
2323 | *source = INTEL_PIPE_CRC_SOURCE_PF; | ||
2324 | |||
2325 | switch (*source) { | ||
2326 | case INTEL_PIPE_CRC_SOURCE_PLANE1: | ||
2327 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PRIMARY_IVB; | ||
2328 | break; | ||
2329 | case INTEL_PIPE_CRC_SOURCE_PLANE2: | ||
2330 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_SPRITE_IVB; | ||
2331 | break; | ||
2332 | case INTEL_PIPE_CRC_SOURCE_PF: | ||
2333 | *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PF_IVB; | ||
2334 | break; | ||
2335 | case INTEL_PIPE_CRC_SOURCE_NONE: | ||
2336 | *val = 0; | ||
2337 | break; | ||
2338 | default: | ||
2339 | return -EINVAL; | ||
2340 | } | ||
2341 | |||
2342 | return 0; | ||
2343 | } | ||
2344 | |||
2345 | static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, | ||
2346 | enum intel_pipe_crc_source source) | ||
2347 | { | ||
2348 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2349 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; | ||
2350 | u32 val; | ||
2351 | int ret; | ||
2352 | |||
2353 | if (pipe_crc->source == source) | ||
2354 | return 0; | ||
2355 | |||
2356 | /* forbid changing the source without going back to 'none' */ | ||
2357 | if (pipe_crc->source && source) | ||
2358 | return -EINVAL; | ||
2359 | |||
2360 | if (IS_GEN2(dev)) | ||
2361 | ret = i8xx_pipe_crc_ctl_reg(&source, &val); | ||
2362 | else if (INTEL_INFO(dev)->gen < 5) | ||
2363 | ret = i9xx_pipe_crc_ctl_reg(dev, pipe, &source, &val); | ||
2364 | else if (IS_VALLEYVIEW(dev)) | ||
2365 | ret = vlv_pipe_crc_ctl_reg(dev,pipe, &source, &val); | ||
2366 | else if (IS_GEN5(dev) || IS_GEN6(dev)) | ||
2367 | ret = ilk_pipe_crc_ctl_reg(&source, &val); | ||
2368 | else | ||
2369 | ret = ivb_pipe_crc_ctl_reg(&source, &val); | ||
2370 | |||
2371 | if (ret != 0) | ||
2372 | return ret; | ||
2373 | |||
2374 | /* none -> real source transition */ | ||
2375 | if (source) { | ||
2376 | DRM_DEBUG_DRIVER("collecting CRCs for pipe %c, %s\n", | ||
2377 | pipe_name(pipe), pipe_crc_source_name(source)); | ||
2378 | |||
2379 | pipe_crc->entries = kzalloc(sizeof(*pipe_crc->entries) * | ||
2380 | INTEL_PIPE_CRC_ENTRIES_NR, | ||
2381 | GFP_KERNEL); | ||
2382 | if (!pipe_crc->entries) | ||
2383 | return -ENOMEM; | ||
2384 | |||
2385 | spin_lock_irq(&pipe_crc->lock); | ||
2386 | pipe_crc->head = 0; | ||
2387 | pipe_crc->tail = 0; | ||
2388 | spin_unlock_irq(&pipe_crc->lock); | ||
2389 | } | ||
2390 | |||
2391 | pipe_crc->source = source; | ||
2392 | |||
2393 | I915_WRITE(PIPE_CRC_CTL(pipe), val); | ||
2394 | POSTING_READ(PIPE_CRC_CTL(pipe)); | ||
2395 | |||
2396 | /* real source -> none transition */ | ||
2397 | if (source == INTEL_PIPE_CRC_SOURCE_NONE) { | ||
2398 | struct intel_pipe_crc_entry *entries; | ||
2399 | |||
2400 | DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n", | ||
2401 | pipe_name(pipe)); | ||
2402 | |||
2403 | intel_wait_for_vblank(dev, pipe); | ||
2404 | |||
2405 | spin_lock_irq(&pipe_crc->lock); | ||
2406 | entries = pipe_crc->entries; | ||
2407 | pipe_crc->entries = NULL; | ||
2408 | spin_unlock_irq(&pipe_crc->lock); | ||
2409 | |||
2410 | kfree(entries); | ||
2411 | |||
2412 | if (IS_G4X(dev)) | ||
2413 | g4x_undo_pipe_scramble_reset(dev, pipe); | ||
2414 | else if (IS_VALLEYVIEW(dev)) | ||
2415 | vlv_undo_pipe_scramble_reset(dev, pipe); | ||
2416 | } | ||
2417 | |||
2418 | return 0; | ||
2419 | } | ||
2420 | |||
2421 | /* | ||
2422 | * Parse pipe CRC command strings: | ||
2423 | * command: wsp* object wsp+ name wsp+ source wsp* | ||
2424 | * object: 'pipe' | ||
2425 | * name: (A | B | C) | ||
2426 | * source: (none | plane1 | plane2 | pf) | ||
2427 | * wsp: (#0x20 | #0x9 | #0xA)+ | ||
2428 | * | ||
2429 | * eg.: | ||
2430 | * "pipe A plane1" -> Start CRC computations on plane1 of pipe A | ||
2431 | * "pipe A none" -> Stop CRC | ||
2432 | */ | ||
2433 | static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words) | ||
2434 | { | ||
2435 | int n_words = 0; | ||
2436 | |||
2437 | while (*buf) { | ||
2438 | char *end; | ||
2439 | |||
2440 | /* skip leading white space */ | ||
2441 | buf = skip_spaces(buf); | ||
2442 | if (!*buf) | ||
2443 | break; /* end of buffer */ | ||
2444 | |||
2445 | /* find end of word */ | ||
2446 | for (end = buf; *end && !isspace(*end); end++) | ||
2447 | ; | ||
2448 | |||
2449 | if (n_words == max_words) { | ||
2450 | DRM_DEBUG_DRIVER("too many words, allowed <= %d\n", | ||
2451 | max_words); | ||
2452 | return -EINVAL; /* ran out of words[] before bytes */ | ||
2453 | } | ||
2454 | |||
2455 | if (*end) | ||
2456 | *end++ = '\0'; | ||
2457 | words[n_words++] = buf; | ||
2458 | buf = end; | ||
2459 | } | ||
2460 | |||
2461 | return n_words; | ||
2462 | } | ||
2463 | |||
2464 | enum intel_pipe_crc_object { | ||
2465 | PIPE_CRC_OBJECT_PIPE, | ||
2466 | }; | ||
2467 | |||
2468 | static const char * const pipe_crc_objects[] = { | ||
2469 | "pipe", | ||
2470 | }; | ||
2471 | |||
2472 | static int | ||
2473 | display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o) | ||
2474 | { | ||
2475 | int i; | ||
2476 | |||
2477 | for (i = 0; i < ARRAY_SIZE(pipe_crc_objects); i++) | ||
2478 | if (!strcmp(buf, pipe_crc_objects[i])) { | ||
2479 | *o = i; | ||
2480 | return 0; | ||
2481 | } | ||
2482 | |||
2483 | return -EINVAL; | ||
2484 | } | ||
2485 | |||
2486 | static int display_crc_ctl_parse_pipe(const char *buf, enum pipe *pipe) | ||
2487 | { | ||
2488 | const char name = buf[0]; | ||
2489 | |||
2490 | if (name < 'A' || name >= pipe_name(I915_MAX_PIPES)) | ||
2491 | return -EINVAL; | ||
2492 | |||
2493 | *pipe = name - 'A'; | ||
2494 | |||
2495 | return 0; | ||
2496 | } | ||
2497 | |||
2498 | static int | ||
2499 | display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s) | ||
2500 | { | ||
2501 | int i; | ||
2502 | |||
2503 | for (i = 0; i < ARRAY_SIZE(pipe_crc_sources); i++) | ||
2504 | if (!strcmp(buf, pipe_crc_sources[i])) { | ||
2505 | *s = i; | ||
2506 | return 0; | ||
2507 | } | ||
2508 | |||
2509 | return -EINVAL; | ||
2510 | } | ||
2511 | |||
2512 | static int display_crc_ctl_parse(struct drm_device *dev, char *buf, size_t len) | ||
2513 | { | ||
2514 | #define N_WORDS 3 | ||
2515 | int n_words; | ||
2516 | char *words[N_WORDS]; | ||
2517 | enum pipe pipe; | ||
2518 | enum intel_pipe_crc_object object; | ||
2519 | enum intel_pipe_crc_source source; | ||
2520 | |||
2521 | n_words = display_crc_ctl_tokenize(buf, words, N_WORDS); | ||
2522 | if (n_words != N_WORDS) { | ||
2523 | DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n", | ||
2524 | N_WORDS); | ||
2525 | return -EINVAL; | ||
2526 | } | ||
2527 | |||
2528 | if (display_crc_ctl_parse_object(words[0], &object) < 0) { | ||
2529 | DRM_DEBUG_DRIVER("unknown object %s\n", words[0]); | ||
2530 | return -EINVAL; | ||
2531 | } | ||
2532 | |||
2533 | if (display_crc_ctl_parse_pipe(words[1], &pipe) < 0) { | ||
2534 | DRM_DEBUG_DRIVER("unknown pipe %s\n", words[1]); | ||
2535 | return -EINVAL; | ||
2536 | } | ||
2537 | |||
2538 | if (display_crc_ctl_parse_source(words[2], &source) < 0) { | ||
2539 | DRM_DEBUG_DRIVER("unknown source %s\n", words[2]); | ||
2540 | return -EINVAL; | ||
2541 | } | ||
2542 | |||
2543 | return pipe_crc_set_source(dev, pipe, source); | ||
2544 | } | ||
2545 | |||
2546 | static ssize_t display_crc_ctl_write(struct file *file, const char __user *ubuf, | ||
2547 | size_t len, loff_t *offp) | ||
2548 | { | ||
2549 | struct seq_file *m = file->private_data; | ||
2550 | struct drm_device *dev = m->private; | ||
2551 | char *tmpbuf; | ||
2552 | int ret; | ||
2553 | |||
2554 | if (len == 0) | ||
2555 | return 0; | ||
2556 | |||
2557 | if (len > PAGE_SIZE - 1) { | ||
2558 | DRM_DEBUG_DRIVER("expected <%lu bytes into pipe crc control\n", | ||
2559 | PAGE_SIZE); | ||
2560 | return -E2BIG; | ||
2561 | } | ||
2562 | |||
2563 | tmpbuf = kmalloc(len + 1, GFP_KERNEL); | ||
2564 | if (!tmpbuf) | ||
2565 | return -ENOMEM; | ||
2566 | |||
2567 | if (copy_from_user(tmpbuf, ubuf, len)) { | ||
2568 | ret = -EFAULT; | ||
2569 | goto out; | ||
2570 | } | ||
2571 | tmpbuf[len] = '\0'; | ||
2572 | |||
2573 | ret = display_crc_ctl_parse(dev, tmpbuf, len); | ||
2574 | |||
2575 | out: | ||
2576 | kfree(tmpbuf); | ||
2577 | if (ret < 0) | ||
2578 | return ret; | ||
2579 | |||
2580 | *offp += len; | ||
2581 | return len; | ||
2582 | } | ||
2583 | |||
2584 | static const struct file_operations i915_display_crc_ctl_fops = { | ||
2585 | .owner = THIS_MODULE, | ||
2586 | .open = display_crc_ctl_open, | ||
2587 | .read = seq_read, | ||
2588 | .llseek = seq_lseek, | ||
2589 | .release = single_release, | ||
2590 | .write = display_crc_ctl_write | ||
2591 | }; | ||
2592 | |||
1828 | static int | 2593 | static int |
1829 | i915_wedged_get(void *data, u64 *val) | 2594 | i915_wedged_get(void *data, u64 *val) |
1830 | { | 2595 | { |
@@ -1885,6 +2650,72 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops, | |||
1885 | i915_ring_stop_get, i915_ring_stop_set, | 2650 | i915_ring_stop_get, i915_ring_stop_set, |
1886 | "0x%08llx\n"); | 2651 | "0x%08llx\n"); |
1887 | 2652 | ||
2653 | static int | ||
2654 | i915_ring_missed_irq_get(void *data, u64 *val) | ||
2655 | { | ||
2656 | struct drm_device *dev = data; | ||
2657 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2658 | |||
2659 | *val = dev_priv->gpu_error.missed_irq_rings; | ||
2660 | return 0; | ||
2661 | } | ||
2662 | |||
2663 | static int | ||
2664 | i915_ring_missed_irq_set(void *data, u64 val) | ||
2665 | { | ||
2666 | struct drm_device *dev = data; | ||
2667 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2668 | int ret; | ||
2669 | |||
2670 | /* Lock against concurrent debugfs callers */ | ||
2671 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
2672 | if (ret) | ||
2673 | return ret; | ||
2674 | dev_priv->gpu_error.missed_irq_rings = val; | ||
2675 | mutex_unlock(&dev->struct_mutex); | ||
2676 | |||
2677 | return 0; | ||
2678 | } | ||
2679 | |||
2680 | DEFINE_SIMPLE_ATTRIBUTE(i915_ring_missed_irq_fops, | ||
2681 | i915_ring_missed_irq_get, i915_ring_missed_irq_set, | ||
2682 | "0x%08llx\n"); | ||
2683 | |||
2684 | static int | ||
2685 | i915_ring_test_irq_get(void *data, u64 *val) | ||
2686 | { | ||
2687 | struct drm_device *dev = data; | ||
2688 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2689 | |||
2690 | *val = dev_priv->gpu_error.test_irq_rings; | ||
2691 | |||
2692 | return 0; | ||
2693 | } | ||
2694 | |||
2695 | static int | ||
2696 | i915_ring_test_irq_set(void *data, u64 val) | ||
2697 | { | ||
2698 | struct drm_device *dev = data; | ||
2699 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2700 | int ret; | ||
2701 | |||
2702 | DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val); | ||
2703 | |||
2704 | /* Lock against concurrent debugfs callers */ | ||
2705 | ret = mutex_lock_interruptible(&dev->struct_mutex); | ||
2706 | if (ret) | ||
2707 | return ret; | ||
2708 | |||
2709 | dev_priv->gpu_error.test_irq_rings = val; | ||
2710 | mutex_unlock(&dev->struct_mutex); | ||
2711 | |||
2712 | return 0; | ||
2713 | } | ||
2714 | |||
2715 | DEFINE_SIMPLE_ATTRIBUTE(i915_ring_test_irq_fops, | ||
2716 | i915_ring_test_irq_get, i915_ring_test_irq_set, | ||
2717 | "0x%08llx\n"); | ||
2718 | |||
1888 | #define DROP_UNBOUND 0x1 | 2719 | #define DROP_UNBOUND 0x1 |
1889 | #define DROP_BOUND 0x2 | 2720 | #define DROP_BOUND 0x2 |
1890 | #define DROP_RETIRE 0x4 | 2721 | #define DROP_RETIRE 0x4 |
@@ -1972,6 +2803,8 @@ i915_max_freq_get(void *data, u64 *val) | |||
1972 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 2803 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
1973 | return -ENODEV; | 2804 | return -ENODEV; |
1974 | 2805 | ||
2806 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
2807 | |||
1975 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 2808 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
1976 | if (ret) | 2809 | if (ret) |
1977 | return ret; | 2810 | return ret; |
@@ -1996,6 +2829,8 @@ i915_max_freq_set(void *data, u64 val) | |||
1996 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 2829 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
1997 | return -ENODEV; | 2830 | return -ENODEV; |
1998 | 2831 | ||
2832 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
2833 | |||
1999 | DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val); | 2834 | DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val); |
2000 | 2835 | ||
2001 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 2836 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
@@ -2034,6 +2869,8 @@ i915_min_freq_get(void *data, u64 *val) | |||
2034 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 2869 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
2035 | return -ENODEV; | 2870 | return -ENODEV; |
2036 | 2871 | ||
2872 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
2873 | |||
2037 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 2874 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
2038 | if (ret) | 2875 | if (ret) |
2039 | return ret; | 2876 | return ret; |
@@ -2058,6 +2895,8 @@ i915_min_freq_set(void *data, u64 val) | |||
2058 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 2895 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
2059 | return -ENODEV; | 2896 | return -ENODEV; |
2060 | 2897 | ||
2898 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
2899 | |||
2061 | DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val); | 2900 | DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val); |
2062 | 2901 | ||
2063 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); | 2902 | ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); |
@@ -2136,32 +2975,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_cache_sharing_fops, | |||
2136 | i915_cache_sharing_get, i915_cache_sharing_set, | 2975 | i915_cache_sharing_get, i915_cache_sharing_set, |
2137 | "%llu\n"); | 2976 | "%llu\n"); |
2138 | 2977 | ||
2139 | /* As the drm_debugfs_init() routines are called before dev->dev_private is | ||
2140 | * allocated we need to hook into the minor for release. */ | ||
2141 | static int | ||
2142 | drm_add_fake_info_node(struct drm_minor *minor, | ||
2143 | struct dentry *ent, | ||
2144 | const void *key) | ||
2145 | { | ||
2146 | struct drm_info_node *node; | ||
2147 | |||
2148 | node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); | ||
2149 | if (node == NULL) { | ||
2150 | debugfs_remove(ent); | ||
2151 | return -ENOMEM; | ||
2152 | } | ||
2153 | |||
2154 | node->minor = minor; | ||
2155 | node->dent = ent; | ||
2156 | node->info_ent = (void *) key; | ||
2157 | |||
2158 | mutex_lock(&minor->debugfs_lock); | ||
2159 | list_add(&node->list, &minor->debugfs_list); | ||
2160 | mutex_unlock(&minor->debugfs_lock); | ||
2161 | |||
2162 | return 0; | ||
2163 | } | ||
2164 | |||
2165 | static int i915_forcewake_open(struct inode *inode, struct file *file) | 2978 | static int i915_forcewake_open(struct inode *inode, struct file *file) |
2166 | { | 2979 | { |
2167 | struct drm_device *dev = inode->i_private; | 2980 | struct drm_device *dev = inode->i_private; |
@@ -2227,7 +3040,7 @@ static int i915_debugfs_create(struct dentry *root, | |||
2227 | return drm_add_fake_info_node(minor, ent, fops); | 3040 | return drm_add_fake_info_node(minor, ent, fops); |
2228 | } | 3041 | } |
2229 | 3042 | ||
2230 | static struct drm_info_list i915_debugfs_list[] = { | 3043 | static const struct drm_info_list i915_debugfs_list[] = { |
2231 | {"i915_capabilities", i915_capabilities, 0}, | 3044 | {"i915_capabilities", i915_capabilities, 0}, |
2232 | {"i915_gem_objects", i915_gem_object_info, 0}, | 3045 | {"i915_gem_objects", i915_gem_object_info, 0}, |
2233 | {"i915_gem_gtt", i915_gem_gtt_info, 0}, | 3046 | {"i915_gem_gtt", i915_gem_gtt_info, 0}, |
@@ -2269,7 +3082,7 @@ static struct drm_info_list i915_debugfs_list[] = { | |||
2269 | }; | 3082 | }; |
2270 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) | 3083 | #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) |
2271 | 3084 | ||
2272 | static struct i915_debugfs_files { | 3085 | static const struct i915_debugfs_files { |
2273 | const char *name; | 3086 | const char *name; |
2274 | const struct file_operations *fops; | 3087 | const struct file_operations *fops; |
2275 | } i915_debugfs_files[] = { | 3088 | } i915_debugfs_files[] = { |
@@ -2278,11 +3091,28 @@ static struct i915_debugfs_files { | |||
2278 | {"i915_min_freq", &i915_min_freq_fops}, | 3091 | {"i915_min_freq", &i915_min_freq_fops}, |
2279 | {"i915_cache_sharing", &i915_cache_sharing_fops}, | 3092 | {"i915_cache_sharing", &i915_cache_sharing_fops}, |
2280 | {"i915_ring_stop", &i915_ring_stop_fops}, | 3093 | {"i915_ring_stop", &i915_ring_stop_fops}, |
3094 | {"i915_ring_missed_irq", &i915_ring_missed_irq_fops}, | ||
3095 | {"i915_ring_test_irq", &i915_ring_test_irq_fops}, | ||
2281 | {"i915_gem_drop_caches", &i915_drop_caches_fops}, | 3096 | {"i915_gem_drop_caches", &i915_drop_caches_fops}, |
2282 | {"i915_error_state", &i915_error_state_fops}, | 3097 | {"i915_error_state", &i915_error_state_fops}, |
2283 | {"i915_next_seqno", &i915_next_seqno_fops}, | 3098 | {"i915_next_seqno", &i915_next_seqno_fops}, |
3099 | {"i915_display_crc_ctl", &i915_display_crc_ctl_fops}, | ||
2284 | }; | 3100 | }; |
2285 | 3101 | ||
3102 | void intel_display_crc_init(struct drm_device *dev) | ||
3103 | { | ||
3104 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3105 | int i; | ||
3106 | |||
3107 | for (i = 0; i < INTEL_INFO(dev)->num_pipes; i++) { | ||
3108 | struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[i]; | ||
3109 | |||
3110 | pipe_crc->opened = false; | ||
3111 | spin_lock_init(&pipe_crc->lock); | ||
3112 | init_waitqueue_head(&pipe_crc->wq); | ||
3113 | } | ||
3114 | } | ||
3115 | |||
2286 | int i915_debugfs_init(struct drm_minor *minor) | 3116 | int i915_debugfs_init(struct drm_minor *minor) |
2287 | { | 3117 | { |
2288 | int ret, i; | 3118 | int ret, i; |
@@ -2291,6 +3121,12 @@ int i915_debugfs_init(struct drm_minor *minor) | |||
2291 | if (ret) | 3121 | if (ret) |
2292 | return ret; | 3122 | return ret; |
2293 | 3123 | ||
3124 | for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) { | ||
3125 | ret = i915_pipe_crc_create(minor->debugfs_root, minor, i); | ||
3126 | if (ret) | ||
3127 | return ret; | ||
3128 | } | ||
3129 | |||
2294 | for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { | 3130 | for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { |
2295 | ret = i915_debugfs_create(minor->debugfs_root, minor, | 3131 | ret = i915_debugfs_create(minor->debugfs_root, minor, |
2296 | i915_debugfs_files[i].name, | 3132 | i915_debugfs_files[i].name, |
@@ -2310,8 +3146,17 @@ void i915_debugfs_cleanup(struct drm_minor *minor) | |||
2310 | 3146 | ||
2311 | drm_debugfs_remove_files(i915_debugfs_list, | 3147 | drm_debugfs_remove_files(i915_debugfs_list, |
2312 | I915_DEBUGFS_ENTRIES, minor); | 3148 | I915_DEBUGFS_ENTRIES, minor); |
3149 | |||
2313 | drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, | 3150 | drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops, |
2314 | 1, minor); | 3151 | 1, minor); |
3152 | |||
3153 | for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) { | ||
3154 | struct drm_info_list *info_list = | ||
3155 | (struct drm_info_list *)&i915_pipe_crc_data[i]; | ||
3156 | |||
3157 | drm_debugfs_remove_files(info_list, 1, minor); | ||
3158 | } | ||
3159 | |||
2315 | for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { | 3160 | for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) { |
2316 | struct drm_info_list *info_list = | 3161 | struct drm_info_list *info_list = |
2317 | (struct drm_info_list *) i915_debugfs_files[i].fops; | 3162 | (struct drm_info_list *) i915_debugfs_files[i].fops; |