On Thu, 05 Jun 2014, ville.syrjala@xxxxxxxxxxxxxxx wrote: > From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > > On most gen2-4 platforms the GTT can be (or maybe always is?) > inside the stolen memory region. If that's the case, reduce the > size of the stolen memory appropriately to make make sure we > don't clobber the GTT. > > v2: Deal with gen4 36 bit physical address Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80151 > Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_gem_stolen.c | 44 ++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/i915_reg.h | 3 +++ > 2 files changed, 47 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c > index 62ef55b..7465ab0 100644 > --- a/drivers/gpu/drm/i915/i915_gem_stolen.c > +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c > @@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) > if (base == 0) > return 0; > > + /* make sure we don't clobber the GTT if it's within stolen memory */ > + if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) { > + struct { > + u32 start, end; > + } stolen[2] = { > + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, > + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, > + }; > + u64 gtt_start, gtt_end; > + > + gtt_start = I915_READ(PGTBL_CTL); > + if (IS_GEN4(dev)) > + gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) | > + (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; > + else > + gtt_start &= PGTBL_ADDRESS_LO_MASK; > + gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4; > + > + if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) > + stolen[0].end = gtt_start; > + if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end) > + stolen[1].start = gtt_end; > + > + /* pick the larger of the two chunks */ > + if (stolen[0].end - stolen[0].start > > + stolen[1].end - stolen[1].start) { > + base = stolen[0].start; > + dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start; > + } else { > + base = stolen[1].start; > + dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start; > + } > + > + if (stolen[0].start != stolen[1].start || > + stolen[0].end != stolen[1].end) { > + DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n", > + (unsigned long long) gtt_start, > + (unsigned long long) gtt_end - 1); > + DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", > + base, base + (u32) dev_priv->gtt.stolen_size - 1); > + } > + } > + > + > /* Verify that nothing else uses this physical address. Stolen > * memory should be reserved by the BIOS and hidden from the > * kernel. So if the region is already marked as busy, something > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 247be2a..619924b 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -978,6 +978,9 @@ enum punit_power_well { > /* > * Instruction and interrupt control regs > */ > +#define PGTBL_CTL 0x02020 > +#define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */ > +#define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */ > #define PGTBL_ER 0x02024 > #define RENDER_RING_BASE 0x02000 > #define BSD_RING_BASE 0x04000 > -- > 1.8.5.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx