/* * If the FB is too big, just don't use it since fbdev is not very * important and we should probably use that space with FBC or other * features.
*/ if (IS_ENABLED(CONFIG_FRAMEBUFFER_CONSOLE) &&
mem == i915->mm.stolen_region &&
size * 2 > i915->dsm.usable_size) {
drm_dbg_kms(display->drm, "Initial FB size exceeds half of stolen, discarding\n"); return NULL;
}
obj = i915_gem_object_create_region_at(mem, phys_base, size,
I915_BO_ALLOC_USER |
I915_BO_PREALLOC); if (IS_ERR(obj)) {
drm_dbg_kms(display->drm, "Failed to preallocate initial FB in %s\n",
mem->region.name); return NULL;
}
/* * Mark it WT ahead of time to avoid changing the * cache_level during fbdev initialization. The * unbind there would get stuck waiting for rcu.
*/
i915_gem_object_set_cache_coherency(obj, HAS_WT(i915) ?
I915_CACHE_WT : I915_CACHE_NONE);
switch (plane_config->tiling) { case I915_TILING_NONE: break; case I915_TILING_X: case I915_TILING_Y:
obj->tiling_and_stride =
plane_config->fb->base.pitches[0] |
plane_config->tiling; break; default:
MISSING_CASE(plane_config->tiling); goto err_obj;
}
/* * MTL GOP likes to place the framebuffer high up in ggtt, * which can cause problems for ggtt_reserve_guc_top(). * Try to pin it to a low ggtt address instead to avoid that.
*/
base = 0;
if (base != plane_config->base) { struct i915_ggtt *ggtt = to_gt(i915)->ggtt; int ret;
/* * Make sure the original and new locations * can't overlap. That would corrupt the original * PTEs which are still being used for scanout.
*/
ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &orig_mm,
size, plane_config->base,
I915_COLOR_UNEVICTABLE, PIN_NOEVICT); if (ret) goto err_obj;
}
vma = i915_vma_instance(obj, &to_gt(i915)->ggtt->vm, NULL); if (IS_ERR(vma)) goto err_obj;
retry:
pinctl = PIN_GLOBAL | PIN_OFFSET_FIXED | base; if (!i915_gem_object_is_lmem(obj))
pinctl |= PIN_MAPPABLE; if (i915_vma_pin(vma, 0, 0, pinctl)) { if (drm_mm_node_allocated(&orig_mm)) {
drm_mm_remove_node(&orig_mm); /* * Try again, but this time pin * it to its original location.
*/
base = plane_config->base; goto retry;
} goto err_obj;
}
if (i915_gem_object_is_tiled(obj) &&
!i915_vma_is_map_and_fenceable(vma)) goto err_obj;
if (drm_mm_node_allocated(&orig_mm))
drm_mm_remove_node(&orig_mm);
drm_dbg_kms(display->drm, "Initial plane fb bound to 0x%x in the ggtt (original 0x%x)\n",
i915_ggtt_offset(vma), plane_config->base);
return vma;
err_obj: if (drm_mm_node_allocated(&orig_mm))
drm_mm_remove_node(&orig_mm);
i915_gem_object_put(obj); return NULL;
}
switch (fb->modifier) { case DRM_FORMAT_MOD_LINEAR: case I915_FORMAT_MOD_X_TILED: case I915_FORMAT_MOD_Y_TILED: case I915_FORMAT_MOD_4_TILED: break; default:
drm_dbg(display->drm, "Unsupported modifier for initial FB: 0x%llx\n",
fb->modifier); returnfalse;
}
vma = initial_plane_vma(display, plane_config); if (!vma) returnfalse;
/* * TODO: * Disable planes if get_initial_plane_config() failed. * Make sure things work if the surface base is not page aligned.
*/ if (!plane_config->fb) return;
/* * Failed to alloc the obj, check to see if we should share * an fb with another CRTC instead
*/ if (intel_reuse_initial_plane_obj(crtc, plane_configs, &fb, &vma)) goto valid_fb;
/* * We've failed to reconstruct the BIOS FB. Current display state * indicates that the primary plane is visible, but has a NULL FB, * which will lead to problems later if we don't fix it up. The * simplest solution is to just disable the primary plane now and * pretend the BIOS never had it enabled.
*/
intel_plane_disable_noatomic(crtc, plane);
if (!to_intel_crtc_state(crtc->base.state)->uapi.active) continue;
/* * Note that reserving the BIOS fb up front prevents us * from stuffing other stolen allocations like the ring * on top. This prevents some ugliness at boot time, and * can even allow for smooth boot transitions if the BIOS * fb is large enough for the active pipe configuration.
*/
display->funcs.display->get_initial_plane_config(crtc, plane_config);
/* * If the fb is shared between multiple heads, we'll * just get the first one.
*/
intel_find_initial_plane_obj(crtc, plane_configs);
if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config))
intel_plane_initial_vblank_wait(crtc);
plane_config_fini(plane_config);
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.