static bool need_fbc_vtd_wa(struct drm_i915_private *dev_priv) { /* WaFbcTurnOffFbcWhenHyperVisorIsUsed:skl,bxt */ if (intel_vtd_active() && (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))) { DRM_INFO("Disabling framebuffer compression (FBC) to prevent screen flicker with VT-d enabled\n"); return true; } return false; }
int i915_gem_init_stolen(struct drm_i915_private *dev_priv) { resource_size_t reserved_base, stolen_top; resource_size_t reserved_total, reserved_size; mutex_init(&dev_priv->mm.stolen_lock); if (intel_vgpu_active(dev_priv)) { DRM_INFO("iGVT-g active, disabling use of stolen memory\n"); return 0; } if (intel_vtd_active() && INTEL_GEN(dev_priv) < 8) { DRM_INFO("DMAR active, disabling use of stolen memory\n"); return 0; } if (resource_size(&intel_graphics_stolen_res) == 0) return 0; dev_priv->dsm = intel_graphics_stolen_res; if (i915_adjust_stolen(dev_priv, &dev_priv->dsm)) return 0; GEM_BUG_ON(dev_priv->dsm.start == 0); GEM_BUG_ON(dev_priv->dsm.end <= dev_priv->dsm.start); stolen_top = dev_priv->dsm.end + 1; reserved_base = stolen_top; reserved_size = 0; switch (INTEL_GEN(dev_priv)) { case 2: case 3: break; case 4: if (!IS_G4X(dev_priv)) break; /* fall through */ case 5: g4x_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; case 6: gen6_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; case 7: if (IS_VALLEYVIEW(dev_priv)) vlv_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); else gen7_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; case 8: case 9: case 10: if (IS_LP(dev_priv)) chv_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); else bdw_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; case 11: default: icl_get_stolen_reserved(dev_priv, &reserved_base, &reserved_size); break; } /* * Our expectation is that the reserved space is at the top of the * stolen region and *never* at the bottom. If we see !reserved_base, * it likely means we failed to read the registers correctly. */ if (!reserved_base) { DRM_ERROR("inconsistent reservation %pa + %pa; ignoring\n", &reserved_base, &reserved_size); reserved_base = stolen_top; reserved_size = 0; } dev_priv->dsm_reserved = (struct resource) DEFINE_RES_MEM(reserved_base, reserved_size); if (!resource_contains(&dev_priv->dsm, &dev_priv->dsm_reserved)) { DRM_ERROR("Stolen reserved area %pR outside stolen memory %pR\n", &dev_priv->dsm_reserved, &dev_priv->dsm); return 0; } /* It is possible for the reserved area to end before the end of stolen * memory, so just consider the start. */ reserved_total = stolen_top - reserved_base; DRM_DEBUG_DRIVER("Memory reserved for graphics device: %lluK, usable: %lluK\n", (u64)resource_size(&dev_priv->dsm) >> 10, ((u64)resource_size(&dev_priv->dsm) - reserved_total) >> 10); dev_priv->stolen_usable_size = resource_size(&dev_priv->dsm) - reserved_total; /* Basic memrange allocator for stolen space. */ drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->stolen_usable_size); return 0; }