Commit c0a8e444 authored by Imre Deak's avatar Imre Deak
Browse files

drm/radeon: Pass along the format info from .fb_create() to drm_helper_mode_fill_fb_struct()

Plumb the format info from .fb_create() all the way to
drm_helper_mode_fill_fb_struct() to avoid the redundant
lookup.

For the fbdev case a manual drm_get_format_info() lookup
is needed.

The patch is based on the driver parts of the patchset at Link:
below, which missed converting the radeon driver.

Due to the absence of this change in the patchset at Link:, after the
Fixed: commit below, radeon_framebuffer_init() ->
drm_helper_mode_fill_fb_struct() set drm_framebuffer::format incorrectly
to NULL, which lead to the !fb->format WARN() in drm_framebuffer_init()
and causing framebuffer creation to fail. This patch fixes both of these
issues.

v2: Amend the commit log mentioning the functional issues the patch
    fixes. (Tomi)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: amd-gfx@lists.freedesktop.org
Cc: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Fixes: 41ab92d3 ("drm: Make passing of format info to drm_helper_mode_fill_fb_struct() mandatory")
Link: https://lore.kernel.org/all/20250701090722.13645-1-ville.syrjala@linux.intel.com


Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Tested-by: default avatarLinux Kernel Functional Testing <lkft@linaro.org>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://lore.kernel.org/r/20250805175752.690504-4-imre.deak@intel.com
parent d2b524c9
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1297,12 +1297,13 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
int
radeon_framebuffer_init(struct drm_device *dev,
			struct drm_framebuffer *fb,
			const struct drm_format_info *info,
			const struct drm_mode_fb_cmd2 *mode_cmd,
			struct drm_gem_object *obj)
{
	int ret;
	fb->obj[0] = obj;
	drm_helper_mode_fill_fb_struct(dev, fb, NULL, mode_cmd);
	drm_helper_mode_fill_fb_struct(dev, fb, info, mode_cmd);
	ret = drm_framebuffer_init(dev, fb, &radeon_fb_funcs);
	if (ret) {
		fb->obj[0] = NULL;
@@ -1341,7 +1342,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
		return ERR_PTR(-ENOMEM);
	}

	ret = radeon_framebuffer_init(dev, fb, mode_cmd, obj);
	ret = radeon_framebuffer_init(dev, fb, info, mode_cmd, obj);
	if (ret) {
		kfree(fb);
		drm_gem_object_put(obj);
+6 −5
Original line number Diff line number Diff line
@@ -53,10 +53,10 @@ static void radeon_fbdev_destroy_pinned_object(struct drm_gem_object *gobj)
}

static int radeon_fbdev_create_pinned_object(struct drm_fb_helper *fb_helper,
					     const struct drm_format_info *info,
					     struct drm_mode_fb_cmd2 *mode_cmd,
					     struct drm_gem_object **gobj_p)
{
	const struct drm_format_info *info;
	struct radeon_device *rdev = fb_helper->dev->dev_private;
	struct drm_gem_object *gobj = NULL;
	struct radeon_bo *rbo = NULL;
@@ -67,8 +67,6 @@ static int radeon_fbdev_create_pinned_object(struct drm_fb_helper *fb_helper,
	int height = mode_cmd->height;
	u32 cpp;

	info = drm_get_format_info(rdev_to_drm(rdev), mode_cmd->pixel_format,
				   mode_cmd->modifier[0]);
	cpp = info->cpp[0];

	/* need to align pitch with crtc limits */
@@ -206,6 +204,7 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
				    struct drm_fb_helper_surface_size *sizes)
{
	struct radeon_device *rdev = fb_helper->dev->dev_private;
	const struct drm_format_info *format_info;
	struct drm_mode_fb_cmd2 mode_cmd = { };
	struct fb_info *info;
	struct drm_gem_object *gobj;
@@ -224,7 +223,9 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
							  sizes->surface_depth);

	ret = radeon_fbdev_create_pinned_object(fb_helper, &mode_cmd, &gobj);
	format_info = drm_get_format_info(rdev_to_drm(rdev), mode_cmd.pixel_format,
					  mode_cmd.modifier[0]);
	ret = radeon_fbdev_create_pinned_object(fb_helper, format_info, &mode_cmd, &gobj);
	if (ret) {
		DRM_ERROR("failed to create fbcon object %d\n", ret);
		return ret;
@@ -236,7 +237,7 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
		ret = -ENOMEM;
		goto err_radeon_fbdev_destroy_pinned_object;
	}
	ret = radeon_framebuffer_init(rdev_to_drm(rdev), fb, &mode_cmd, gobj);
	ret = radeon_framebuffer_init(rdev_to_drm(rdev), fb, format_info, &mode_cmd, gobj);
	if (ret) {
		DRM_ERROR("failed to initialize framebuffer %d\n", ret);
		goto err_kfree;
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

struct drm_fb_helper;
struct drm_fb_helper_surface_size;
struct drm_format_info;

struct edid;
struct drm_edid;
@@ -890,6 +891,7 @@ extern void
radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
int radeon_framebuffer_init(struct drm_device *dev,
			     struct drm_framebuffer *rfb,
			     const struct drm_format_info *info,
			     const struct drm_mode_fb_cmd2 *mode_cmd,
			     struct drm_gem_object *obj);