Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d316aec authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Implement stolen reserved detection for ctg/elk



Finally managed to dig up enough hints as to where the stolen
reserved stuff lives on ctg/elk. So add the code to decode it.
This was a combination of old chipset specs, diggin up an old
elk grits release with an ctg/elk AubLoad etc.

This was only tested on an elk as I don't have a ctg here
unfortunately.

This leaves ilk as the only platform that doesn't have a way
to detect this stuff. Looking at the register contents on my
ilk, it might be that the elk way works there too, but I
can't be sure since I can't affect the amount of reserved
memory on that machine, and if I am to trust the register
contents, by default it would reserve 0 bytes.

v2: s/WARN_ON_ONCE/WARN_ON/ since it's in one time init code
    anyway (Paulo)

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 2db3366b
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -196,6 +196,29 @@ void i915_gem_cleanup_stolen(struct drm_device *dev)
	drm_mm_takedown(&dev_priv->mm.stolen);
}

static void g4x_get_stolen_reserved(struct drm_i915_private *dev_priv,
				    unsigned long *base, unsigned long *size)
{
	uint32_t reg_val = I915_READ(IS_GM45(dev_priv) ?
				     CTG_STOLEN_RESERVED :
				     ELK_STOLEN_RESERVED);
	unsigned long stolen_top = dev_priv->mm.stolen_base +
		dev_priv->gtt.stolen_size;

	*base = (reg_val & G4X_STOLEN_RESERVED_ADDR2_MASK) << 16;

	WARN_ON((reg_val & G4X_STOLEN_RESERVED_ADDR1_MASK) < *base);

	/* On these platforms, the register doesn't have a size field, so the
	 * size is the distance between the base and the top of the stolen
	 * memory. We also have the genuine case where base is zero and there's
	 * nothing reserved. */
	if (*base == 0)
		*size = 0;
	else
		*size = stolen_top - *base;
}

static void gen6_get_stolen_reserved(struct drm_i915_private *dev_priv,
				     unsigned long *base, unsigned long *size)
{
@@ -315,10 +338,12 @@ int i915_gem_init_stolen(struct drm_device *dev)
	switch (INTEL_INFO(dev_priv)->gen) {
	case 2:
	case 3:
		break;
	case 4:
		if (!IS_G4X(dev))
		if (IS_G4X(dev))
			g4x_get_stolen_reserved(dev_priv, &reserved_base,
						&reserved_size);
		break;
		/* fall through */
	case 5:
		/* Assume the gen6 maximum for the older platforms. */
		reserved_size = 1024 * 1024;
+5 −0
Original line number Diff line number Diff line
@@ -2494,6 +2494,11 @@ enum skl_disp_power_wells {

#define MCHBAR_MIRROR_BASE_SNB	0x140000

#define CTG_STOLEN_RESERVED		(MCHBAR_MIRROR_BASE + 0x34)
#define ELK_STOLEN_RESERVED		(MCHBAR_MIRROR_BASE + 0x48)
#define G4X_STOLEN_RESERVED_ADDR1_MASK	(0xFFFF << 16)
#define G4X_STOLEN_RESERVED_ADDR2_MASK	(0xFFF << 4)

/* Memory controller frequency in MCHBAR for Haswell (possible SNB+) */
#define DCLK (MCHBAR_MIRROR_BASE_SNB + 0x5e04)