[Intel-gfx] [PATCH 3/3] drm/i915: Only grab correct forcewake for the engine with execlists
Chris Wilson
chris at chris-wilson.co.uk
Thu Apr 7 14:59:40 UTC 2016
On Thu, Apr 07, 2016 at 03:36:04PM +0100, Tvrtko Ursulin wrote:
>
> On 07/04/16 15:24, Chris Wilson wrote:
> >On Thu, Apr 07, 2016 at 03:05:40PM +0100, Tvrtko Ursulin wrote:
> >>@@ -2099,6 +2101,12 @@ logical_ring_init(struct drm_device *dev, struct intel_engine_cs *engine)
> >>
> >> logical_ring_init_platform_invariants(engine);
> >>
> >>+ engine->fw_domains_elsp =
> >>+ intel_reg_write_fw_domains(dev_priv, RING_ELSP(engine));
> >>+ engine->fw_domains_csb =
> >>+ intel_reg_write_fw_domains(dev_priv,
> >>+ RING_CONTEXT_STATUS_PTR(engine));
> >
> >So is write a superset of fw? Tends to be reads that require fw more
> >than writes (gen6/7 fifo, gen8 write shadowing).
> >
> >I think we need a READ | WRITE direction field.
>
> Hm, yes embedding too much knowledge in the caller, how about just:
>
> engine->fw_domains_csb = intel_reg_read_fw_domains(dev_priv,
> RING_CONTEXT_STATUS_PTR(engine));
>
> engine->fw_domains_csb |= intel_reg_write_fw_domains(dev_priv,
> RING_CONTEXT_STATUS_PTR(engine));
See my other mail for a mockup of some code. Something along these
lines.
> >>+/**
> >>+ * intel_reg_write_fw_domains - which forcewake domains are needed to write a register
> >>+ * @dev_priv: pointer to struct drm_i915_private
> >>+ * @reg: register in question
> >>+ *
> >>+ * Returns a set of forcewake domains required to be taken with for example
> >>+ * intel_uncore_forcewake_get for the specified register to be writable with the
> >>+ * raw mmio accessors.
> >>+ */
> >>+enum forcewake_domains
> >>+intel_reg_write_fw_domains(struct drm_i915_private *dev_priv, i915_reg_t reg)
> >>+{
> >>+ enum forcewake_domains fw_domains;
> >>+
> >>+ if (intel_vgpu_active(dev_priv->dev))
> >>+ return 0;
> >>+
> >>+ switch (INTEL_INFO(dev_priv)->gen) {
> >>+ case 9:
> >>+ fw_domains = __gen9_reg_write_fw_domains(i915_mmio_reg_offset(reg));
> >>+ break;
> >>+ case 8:
> >>+ if (IS_CHERRYVIEW(dev_priv))
> >>+ fw_domains = __chv_reg_write_fw_domains(i915_mmio_reg_offset(reg));
> >>+ else
> >>+ fw_domains = __gen8_reg_write_fw_domains(i915_mmio_reg_offset(reg));
> >>+ break;
> >>+ default:
> >>+ MISSING_CASE(INTEL_INFO(dev_priv)->gen);
> >>+ case 7:
> >>+ case 6:
> >
> >This is actually a tricky one. gen6/7 maintain a FIFO to store mmio
> >writes whilst it is powered down. If we fill that fifo we drop writes
> >(and that fifo is shared with functions on the device, i.e. it is not
> >ours to fill exclusively). So should we be saving that if you want to
> >make lots of writes you should take this forcewake domain. Yes. We should
> >report what domains they would require, it is still up to the caller as
> >to whether they risk the FIFO overflowing, but they should have the right
> >information to hand.
>
> Missed that. But it isn't part of forcewake domains. So what would
> you return? Fake out a new domain just complicates things and adds
> cost for everyone. Maybe better just to limit the whole thing to
> gen8+ and leave olders platforms untouched?
It is the FORCEWAKE_RENDER to flush the write FIFO, it is just not clear
in the implementation (i.e. we have never done that explicitly - I do
remember at odd times counting register writes though...). Only in a few
places (over ring init) have we explicitly taken the fw domain across writes.
I'm leaning towards reporting that they do require the domain, with a
note saying about the fifo. It is a specialized interface after all that
is going to be using in fairly gen-specific paths (and erring on the
side of caution when used outside of that is wise).
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list