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, |
