Bspec lists different VT-d guard numbers (the number of dummy
padding PTEs) for different platforms and plane types. Use those
instead of just assuming the max glk+ number for everything.
This could avoid a bit of overhead on older platforms due to
reduced padding, and it makes it easier to cross check with the
spec.
Note that VLV/CHV do not document this w/a at all, so not sure
if it's actually needed or not. Nor do we actually know how much
padding is required if it is needed. For now use the same 128
PTEs that we use for snb-bdw primary planes.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250122151755.6928-5-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
else
plane->min_alignment = i9xx_plane_min_alignment;
+ /* FIXME undocumented for VLV/CHV so not sure what's actually needed */
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ plane->vtd_guard = 128;
+
if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
plane->update_arm = i830_plane_update_arm;
} else {
else
cursor->min_alignment = i9xx_cursor_min_alignment;
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ cursor->vtd_guard = 2;
+
cursor->update_arm = i9xx_cursor_update_arm;
cursor->disable_arm = i9xx_cursor_disable_arm;
cursor->get_hw_state = i9xx_cursor_get_hw_state;
struct i915_address_space *dpt_vm;
unsigned int min_alignment;
+ unsigned int vtd_guard;
};
enum intel_hotplug_state {
enum plane_id id;
enum pipe pipe;
bool need_async_flip_toggle_wa;
+ u8 vtd_guard;
u32 frontbuffer_bit;
struct {
return min_alignment;
}
+static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb)
+{
+ struct drm_i915_private *i915 = to_i915(fb->dev);
+ struct intel_plane *plane;
+ unsigned int vtd_guard = 0;
+
+ for_each_intel_plane(&i915->drm, plane) {
+ if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
+ continue;
+
+ vtd_guard = max_t(unsigned int, vtd_guard, plane->vtd_guard);
+ }
+
+ return vtd_guard;
+}
+
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
{
struct drm_gem_object *obj = intel_fb_bo(&fb->base);
}
fb->min_alignment = intel_fb_min_alignment(&fb->base);
+ fb->vtd_guard = intel_fb_vtd_guard(&fb->base);
return 0;
}
const struct intel_fb_view *view,
unsigned int rotation)
{
- struct drm_i915_private *i915 = to_i915(fb->dev);
unsigned int vtd_guard;
int color_plane;
- if (!intel_scanout_needs_vtd_wa(i915))
+ vtd_guard = to_intel_framebuffer(fb)->vtd_guard;
+ if (!vtd_guard)
return 0;
- vtd_guard = 168;
-
for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) {
unsigned int stride, tile;
plane->min_alignment = vlv_plane_min_alignment;
plane->min_cdclk = vlv_plane_min_cdclk;
+ /* FIXME undocumented for VLV/CHV so not sure what's actually needed */
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ plane->vtd_guard = 128;
+
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
formats = chv_pipe_b_sprite_formats;
num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
plane->min_alignment = g4x_sprite_min_alignment;
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ plane->vtd_guard = 64;
+
formats = snb_sprite_formats;
num_formats = ARRAY_SIZE(snb_sprite_formats);
plane->min_alignment = g4x_sprite_min_alignment;
plane->min_cdclk = g4x_sprite_min_cdclk;
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ plane->vtd_guard = 64;
+
if (IS_SANDYBRIDGE(dev_priv)) {
formats = snb_sprite_formats;
num_formats = ARRAY_SIZE(snb_sprite_formats);
else
plane->min_alignment = skl_plane_min_alignment;
+ if (intel_scanout_needs_vtd_wa(dev_priv))
+ plane->vtd_guard = DISPLAY_VER(dev_priv) >= 10 ? 168 : 136;
+
if (DISPLAY_VER(dev_priv) >= 11) {
plane->update_noarm = icl_plane_update_noarm;
plane->update_arm = icl_plane_update_arm;