xref: /linux/drivers/gpu/drm/i915/display/intel_initial_plane.c (revision 6bb14ea387fee901b62a29af568f39eeac23e451)
1 // SPDX-License-Identifier: MIT
2 /* Copyright © 2025 Intel Corporation */
3 
4 #include <drm/intel/display_parent_interface.h>
5 
6 #include "intel_display_core.h"
7 #include "intel_display_types.h"
8 #include "intel_initial_plane.h"
9 
10 void intel_initial_plane_vblank_wait(struct intel_crtc *crtc)
11 {
12 	struct intel_display *display = to_intel_display(crtc);
13 
14 	display->parent->initial_plane->vblank_wait(&crtc->base);
15 }
16 
17 static void
18 intel_find_initial_plane_obj(struct intel_crtc *crtc,
19 			     struct intel_initial_plane_config plane_configs[])
20 {
21 	struct intel_display *display = to_intel_display(crtc);
22 
23 	display->parent->initial_plane->find_obj(&crtc->base, plane_configs);
24 }
25 
26 static void plane_config_fini(struct intel_display *display,
27 			      struct intel_initial_plane_config *plane_config)
28 {
29 	if (plane_config->fb) {
30 		struct drm_framebuffer *fb = &plane_config->fb->base;
31 
32 		/* We may only have the stub and not a full framebuffer */
33 		if (drm_framebuffer_read_refcount(fb))
34 			drm_framebuffer_put(fb);
35 		else
36 			kfree(fb);
37 	}
38 
39 	display->parent->initial_plane->config_fini(plane_config);
40 }
41 
42 void intel_initial_plane_config(struct intel_display *display)
43 {
44 	struct intel_initial_plane_config plane_configs[I915_MAX_PIPES] = {};
45 	struct intel_crtc *crtc;
46 
47 	for_each_intel_crtc(display->drm, crtc) {
48 		const struct intel_crtc_state *crtc_state =
49 			to_intel_crtc_state(crtc->base.state);
50 		struct intel_initial_plane_config *plane_config =
51 			&plane_configs[crtc->pipe];
52 
53 		if (!crtc_state->hw.active)
54 			continue;
55 
56 		/*
57 		 * Note that reserving the BIOS fb up front prevents us
58 		 * from stuffing other stolen allocations like the ring
59 		 * on top.  This prevents some ugliness at boot time, and
60 		 * can even allow for smooth boot transitions if the BIOS
61 		 * fb is large enough for the active pipe configuration.
62 		 */
63 		display->funcs.display->get_initial_plane_config(crtc, plane_config);
64 
65 		/*
66 		 * If the fb is shared between multiple heads, we'll
67 		 * just get the first one.
68 		 */
69 		intel_find_initial_plane_obj(crtc, plane_configs);
70 
71 		if (display->funcs.display->fixup_initial_plane_config(crtc, plane_config))
72 			intel_initial_plane_vblank_wait(crtc);
73 
74 		plane_config_fini(display, plane_config);
75 	}
76 }
77