diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_perf.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_perf.c | 125 |
1 files changed, 15 insertions, 110 deletions
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index ccb20230df2c..664b96bb65a3 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c | |||
@@ -1680,107 +1680,6 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx, | |||
1680 | } | 1680 | } |
1681 | 1681 | ||
1682 | /* | 1682 | /* |
1683 | * Same as gen8_update_reg_state_unlocked only through the batchbuffer. This | ||
1684 | * is only used by the kernel context. | ||
1685 | */ | ||
1686 | static int gen8_emit_oa_config(struct i915_request *rq, | ||
1687 | const struct i915_oa_config *oa_config) | ||
1688 | { | ||
1689 | struct drm_i915_private *dev_priv = rq->i915; | ||
1690 | /* The MMIO offsets for Flex EU registers aren't contiguous */ | ||
1691 | u32 flex_mmio[] = { | ||
1692 | i915_mmio_reg_offset(EU_PERF_CNTL0), | ||
1693 | i915_mmio_reg_offset(EU_PERF_CNTL1), | ||
1694 | i915_mmio_reg_offset(EU_PERF_CNTL2), | ||
1695 | i915_mmio_reg_offset(EU_PERF_CNTL3), | ||
1696 | i915_mmio_reg_offset(EU_PERF_CNTL4), | ||
1697 | i915_mmio_reg_offset(EU_PERF_CNTL5), | ||
1698 | i915_mmio_reg_offset(EU_PERF_CNTL6), | ||
1699 | }; | ||
1700 | u32 *cs; | ||
1701 | int i; | ||
1702 | |||
1703 | cs = intel_ring_begin(rq, ARRAY_SIZE(flex_mmio) * 2 + 4); | ||
1704 | if (IS_ERR(cs)) | ||
1705 | return PTR_ERR(cs); | ||
1706 | |||
1707 | *cs++ = MI_LOAD_REGISTER_IMM(ARRAY_SIZE(flex_mmio) + 1); | ||
1708 | |||
1709 | *cs++ = i915_mmio_reg_offset(GEN8_OACTXCONTROL); | ||
1710 | *cs++ = (dev_priv->perf.oa.period_exponent << GEN8_OA_TIMER_PERIOD_SHIFT) | | ||
1711 | (dev_priv->perf.oa.periodic ? GEN8_OA_TIMER_ENABLE : 0) | | ||
1712 | GEN8_OA_COUNTER_RESUME; | ||
1713 | |||
1714 | for (i = 0; i < ARRAY_SIZE(flex_mmio); i++) { | ||
1715 | u32 mmio = flex_mmio[i]; | ||
1716 | |||
1717 | /* | ||
1718 | * This arbitrary default will select the 'EU FPU0 Pipeline | ||
1719 | * Active' event. In the future it's anticipated that there | ||
1720 | * will be an explicit 'No Event' we can select, but not | ||
1721 | * yet... | ||
1722 | */ | ||
1723 | u32 value = 0; | ||
1724 | |||
1725 | if (oa_config) { | ||
1726 | u32 j; | ||
1727 | |||
1728 | for (j = 0; j < oa_config->flex_regs_len; j++) { | ||
1729 | if (i915_mmio_reg_offset(oa_config->flex_regs[j].addr) == mmio) { | ||
1730 | value = oa_config->flex_regs[j].value; | ||
1731 | break; | ||
1732 | } | ||
1733 | } | ||
1734 | } | ||
1735 | |||
1736 | *cs++ = mmio; | ||
1737 | *cs++ = value; | ||
1738 | } | ||
1739 | |||
1740 | *cs++ = MI_NOOP; | ||
1741 | intel_ring_advance(rq, cs); | ||
1742 | |||
1743 | return 0; | ||
1744 | } | ||
1745 | |||
1746 | static int gen8_switch_to_updated_kernel_context(struct drm_i915_private *dev_priv, | ||
1747 | const struct i915_oa_config *oa_config) | ||
1748 | { | ||
1749 | struct intel_engine_cs *engine = dev_priv->engine[RCS]; | ||
1750 | struct i915_timeline *timeline; | ||
1751 | struct i915_request *rq; | ||
1752 | int ret; | ||
1753 | |||
1754 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | ||
1755 | |||
1756 | i915_retire_requests(dev_priv); | ||
1757 | |||
1758 | rq = i915_request_alloc(engine, dev_priv->kernel_context); | ||
1759 | if (IS_ERR(rq)) | ||
1760 | return PTR_ERR(rq); | ||
1761 | |||
1762 | ret = gen8_emit_oa_config(rq, oa_config); | ||
1763 | if (ret) { | ||
1764 | i915_request_add(rq); | ||
1765 | return ret; | ||
1766 | } | ||
1767 | |||
1768 | /* Queue this switch after all other activity */ | ||
1769 | list_for_each_entry(timeline, &dev_priv->gt.timelines, link) { | ||
1770 | struct i915_request *prev; | ||
1771 | |||
1772 | prev = i915_gem_active_raw(&timeline->last_request, | ||
1773 | &dev_priv->drm.struct_mutex); | ||
1774 | if (prev) | ||
1775 | i915_request_await_dma_fence(rq, &prev->fence); | ||
1776 | } | ||
1777 | |||
1778 | i915_request_add(rq); | ||
1779 | |||
1780 | return 0; | ||
1781 | } | ||
1782 | |||
1783 | /* | ||
1784 | * Manages updating the per-context aspects of the OA stream | 1683 | * Manages updating the per-context aspects of the OA stream |
1785 | * configuration across all contexts. | 1684 | * configuration across all contexts. |
1786 | * | 1685 | * |
@@ -1808,17 +1707,13 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | |||
1808 | const struct i915_oa_config *oa_config) | 1707 | const struct i915_oa_config *oa_config) |
1809 | { | 1708 | { |
1810 | struct intel_engine_cs *engine = dev_priv->engine[RCS]; | 1709 | struct intel_engine_cs *engine = dev_priv->engine[RCS]; |
1710 | unsigned int map_type = i915_coherent_map_type(dev_priv); | ||
1811 | struct i915_gem_context *ctx; | 1711 | struct i915_gem_context *ctx; |
1712 | struct i915_request *rq; | ||
1812 | int ret; | 1713 | int ret; |
1813 | unsigned int wait_flags = I915_WAIT_LOCKED; | ||
1814 | 1714 | ||
1815 | lockdep_assert_held(&dev_priv->drm.struct_mutex); | 1715 | lockdep_assert_held(&dev_priv->drm.struct_mutex); |
1816 | 1716 | ||
1817 | /* Switch away from any user context. */ | ||
1818 | ret = gen8_switch_to_updated_kernel_context(dev_priv, oa_config); | ||
1819 | if (ret) | ||
1820 | return ret; | ||
1821 | |||
1822 | /* | 1717 | /* |
1823 | * The OA register config is setup through the context image. This image | 1718 | * The OA register config is setup through the context image. This image |
1824 | * might be written to by the GPU on context switch (in particular on | 1719 | * might be written to by the GPU on context switch (in particular on |
@@ -1833,7 +1728,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | |||
1833 | * the GPU from any submitted work. | 1728 | * the GPU from any submitted work. |
1834 | */ | 1729 | */ |
1835 | ret = i915_gem_wait_for_idle(dev_priv, | 1730 | ret = i915_gem_wait_for_idle(dev_priv, |
1836 | wait_flags, | 1731 | I915_WAIT_LOCKED, |
1837 | MAX_SCHEDULE_TIMEOUT); | 1732 | MAX_SCHEDULE_TIMEOUT); |
1838 | if (ret) | 1733 | if (ret) |
1839 | return ret; | 1734 | return ret; |
@@ -1847,7 +1742,7 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | |||
1847 | if (!ce->state) | 1742 | if (!ce->state) |
1848 | continue; | 1743 | continue; |
1849 | 1744 | ||
1850 | regs = i915_gem_object_pin_map(ce->state->obj, I915_MAP_WB); | 1745 | regs = i915_gem_object_pin_map(ce->state->obj, map_type); |
1851 | if (IS_ERR(regs)) | 1746 | if (IS_ERR(regs)) |
1852 | return PTR_ERR(regs); | 1747 | return PTR_ERR(regs); |
1853 | 1748 | ||
@@ -1859,7 +1754,17 @@ static int gen8_configure_all_contexts(struct drm_i915_private *dev_priv, | |||
1859 | i915_gem_object_unpin_map(ce->state->obj); | 1754 | i915_gem_object_unpin_map(ce->state->obj); |
1860 | } | 1755 | } |
1861 | 1756 | ||
1862 | return ret; | 1757 | /* |
1758 | * Apply the configuration by doing one context restore of the edited | ||
1759 | * context image. | ||
1760 | */ | ||
1761 | rq = i915_request_alloc(engine, dev_priv->kernel_context); | ||
1762 | if (IS_ERR(rq)) | ||
1763 | return PTR_ERR(rq); | ||
1764 | |||
1765 | i915_request_add(rq); | ||
1766 | |||
1767 | return 0; | ||
1863 | } | 1768 | } |
1864 | 1769 | ||
1865 | static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, | 1770 | static int gen8_enable_metric_set(struct drm_i915_private *dev_priv, |