[Intel-gfx] [PATCH 15/20] drm/i915: turbo & RC6 support for VLV v2

Ben Widawsky ben at bwidawsk.net
Wed Mar 20 00:38:03 CET 2013


On Tue, Mar 19, 2013 at 03:35:55PM -0700, Jesse Barnes wrote:
> On Tue, 19 Mar 2013 15:27:36 -0700
> Ben Widawsky <ben at bwidawsk.net> wrote:
> 
> > On Fri, Mar 08, 2013 at 10:45:58AM -0800, Jesse Barnes wrote:
> > > From: Ben Widawsky <ben at bwidawsk.net>
> > > 
> > > Uses slightly different interfaces than other platforms.
> > > 
> > > v2: track actual set freq, not requested (Rohit)
> > >     fix debug prints in init code (Jesse)
> > > 
> > > Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> > 
> > One important question is how is our punit code going to interact with
> > the other potential users? It seems a bunch of power management drivers
> > would also want to touch this uC.
> 
> Pretty sure the PUnit has to deal with concurrent access... if not
> we'll have to add common routines for all drivers to use and do proper
> locking.
> 
> > > +
> > > +	valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &pval);
> > > +	if ((pval >> 8) != val)
> > > +		DRM_DEBUG_DRIVER("punit overrode freq: %d requested, but got %d\n",
> > > +			  val, pval >> 8);
> > I'm debating whether this is a useful thing to do here... You either get
> > the frequency or you don't. Really it would seem more useful to me to
> > check things are sane when you first enter the function (ie. did the
> > last request do what you want). But I don't care what you end up with.
> 
> It's not really a matter of sanity, it's more about what state the
> platform is in.  If the Punit decides things are getting too hot for
> example, it may clamp your freq down.  That's totally ok and normal
> though, and may change in future calls.
> 
> > I suppose if you wanted to make things a bit cleaner you could extract
> > just the frequency setting part, since most of this function is
> > identical to gen6 set rps.
> 
> I was afraid more changes would creep in over time, but yeah that's a
> possibility.  I have a couple more changes here before I consider that.
> 
> > > +
> > > +	/* Make sure we continue to get interrupts
> > > +	 * until we hit the minimum or maximum frequencies.
> > > +	 */
> > > +	I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
> > > +
> > > +	dev_priv->rps.cur_delay = pval >> 8;
> > > +
> > > +	trace_intel_gpu_freq_change(val * 50);
> > Based on our IRC discussion, I believe the value in this trace is wrong.
> 
> Ah yeah, correct.  I can just trace val here maybe, or I"ll have to put
> this off until I post the real frequencies.
> 
> > > +static void valleyview_enable_rps(struct drm_device *dev)
> > > +{
> > > +	struct drm_i915_private *dev_priv = dev->dev_private;
> > > +	struct intel_ring_buffer *ring;
> > > +	u32 gtfifodbg, val;
> > > +	int i;
> > > +
> > > +	WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
> > 
> > Should we check FB_GFX_TURBO_EN_FUSE here?
> 
> I guess it wouldn't hurt.
> 
> > > +
> > > +	if ((gtfifodbg = I915_READ(GTFIFODBG))) {
> > > +		DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
> > > +		I915_WRITE(GTFIFODBG, gtfifodbg);
> > > +	}
> > > +
> > > +	gen6_gt_force_wake_get(dev_priv);
> > > +
> > > +	I915_WRITE(GEN6_RC_SLEEP, 0);
> > You've dropped GEN6_RC1_WAKE_RATE_LIMIT. Intentional?
> 
> Uh I should have commented that.  I *think* it was intentional since
> RC1 doesn't exist on VLV, but I'll have to check.
> 
> > > +	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 0x00280000);
> > > +	I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000);
> > > +	I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 0x19);
> > 
> > Don't use 0x19, use 25 since we use 25 in the gen6 path
> 
> Ok.
> 
> > > +
> > > +	for_each_ring(ring, dev_priv, i)
> > > +		I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
> > > +
> > > +	I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
> > > +	I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
> > > +
> > > +	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
> > > +	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
> > > +	I915_WRITE(GEN6_RP_UP_EI, 66000);
> > > +	I915_WRITE(GEN6_RP_DOWN_EI, 350000);
> > > +
> > > +	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
> > 
> > I can't find most of the above values, but, I'll assume they're correct.
> > I'd also suggest converging on either all decimal, or all hex, just to
> > make things less confusing.
> 
> A comment about units probably wouldn't hurt either.  Ok.
> 
> > > +
> > > +	I915_WRITE(GEN6_RP_CONTROL,
> > > +		   GEN6_RP_MEDIA_TURBO |
> > > +		   GEN6_RP_MEDIA_HW_NORMAL_MODE |
> > > +		   GEN6_RP_MEDIA_IS_GFX |
> > > +		   GEN6_RP_ENABLE |
> > > +		   GEN6_RP_UP_BUSY_AVG |
> > > +		   GEN6_RP_DOWN_IDLE_CONT);
> > > +
> > 
> > > +	/* allows RC6 residency counter to work */
> > > +	I915_WRITE(0x138104, 0xffff00ff);
> > This is writing read only registers. Should be:
> > I915_WRITE(0x138104, 0x800000ff);
> > 
> > Also, just for though, we may want to use the upper bits instead of the
> > lower ones...
> 
> I think the upper bits are a mask, and all the low 8 bits are
> writeable, so maybe 0x00ff00ff?  I'll have to test that.

This was a typo on my part, it should be 0x80ff00ff. Sorry about that. I
haven't read the rest of the email yet. It popped into my head while I
was out.

> 
> > 
> > > +	I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE);
> > > +
> > 
> > So the following stuff doesn't seem to jive in the docs I'm reading. Can
> > you double check your docs, and the silicon. I tried to punt this to IRC
> > but you didn't respond. These IOSF registers are all 32 bits, so I'm not
> > sure how this is supposed to work.
> > 
> > > +	valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS1, &val);
> > > +	DRM_DEBUG_DRIVER("max GPU freq: %d\n", val);
> > > +	dev_priv->rps.max_delay = val;
> > val >> 16 && 0xff?
> > 
> > 
> > > +
> > > +	valleyview_punit_read(dev_priv, PUNIT_REG_GPU_LFM, &val);
> > > +	DRM_DEBUG_DRIVER("min GPU freq: %d\n", val);
> > > +	dev_priv->rps.min_delay = val;
> > val & 0xff?
> > > +
> > > +	valleyview_punit_read(dev_priv, PUNIT_FUSE_BUS2, &val);
> > > +	DRM_DEBUG_DRIVER("max GPLL freq: %d\n", val);
> > 
> > One doc suggests this is actually offset 0x87, bits 7:0
> 
> Hm I'll check these out; the different docs talk about different bit
> fields, but I think they're offsets into the fuse bus array.
> 
> > 
> > > +
> > > +	valleyview_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS, &val);
> > > +	DRM_DEBUG_DRIVER("DDR speed: ");
> > > +	if (drm_debug & DRM_UT_DRIVER) {
> > > +		if (((val >> 6) & 3) == 0) {
> > > +			dev_priv->mem_freq = 800;
> > > +			printk("800 MHz\n");
> > > +		} else if (((val >> 6) & 3) == 1) {
> > > +			printk("1066 MHz\n");
> > > +			dev_priv->mem_freq = 1066;
> > > +		} else if (((val >> 6) & 3) == 2) {
> > > +			printk("1333 MHz\n");
> > > +			dev_priv->mem_freq = 1333;
> > > +		} else if (((val >> 6) & 3) == 3)
> > > +			printk("invalid\n");
> > > +	}
> > 
> > printk?
> > could be one line, but would print 1332:
> > dev_priv->mem_freq = 800 + (266 * (val >> 6) & 3))
> 
> Yeah because the DRM_DEBUG above doesn't have a newline.  I like your
> calculation better.
> 
> Thanks for checking these out; I know wading through these docs is no
> fun.
> 
> -- 
> Jesse Barnes, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ben Widawsky, Intel Open Source Technology Center



More information about the Intel-gfx mailing list