The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: oushixiong1025@163.com,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	Shixiong Ou <oushixiong@kylinos.cn>,
	Tiger Liu <liuyihu@kylinos.cn>
Subject: Re: [PATCH] drm/fb-helper: add fbdev screen expended mode display support
Date: Fri, 7 Nov 2025 11:06:14 +0100	[thread overview]
Message-ID: <15166a78-b603-464a-8fa5-b7dd43d55029@suse.de> (raw)
In-Reply-To: <20251107092641.111431-1-oushixiong1025@163.com>



Am 07.11.25 um 10:26 schrieb oushixiong1025@163.com:
> From: Shixiong Ou <oushixiong@kylinos.cn>
>
> Add fbdev screen extended mode display support

What? What is this about?

>
> Signed-off-by: Tiger Liu <liuyihu@kylinos.cn>
> Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
> ---
>   drivers/gpu/drm/drm_fb_helper.c | 143 ++++++++++++++++++++++++++++++--
>   1 file changed, 135 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 53e9dc0543de..a6ec03bf3aef 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -78,6 +78,17 @@ MODULE_PARM_DESC(drm_leak_fbdev_smem,
>   		 "Allow unsafe leaking fbdev physical smem address [default=false]");
>   #endif
>   
> +#define SCREEN_CLONE			0x0
> +#define SCREEN_EXPAND_HORIZONTAL	0x1
> +#define SCREEN_EXPAND_VERTICAL		0x2
> +
> +static bool drm_fbdev_screen_expand_mode_enabled;
> +static int drm_fbdev_screen_mode = SCREEN_CLONE;
> +module_param_named(screen_mode, drm_fbdev_screen_mode, int, 0444);
> +MODULE_PARM_DESC(screen_mode,
> +		 "Screen display of the fbdev. [0 = clone(default), 1 = expand horizontally,"
> +		 "2 = expand vertically]");
> +
>   static LIST_HEAD(kernel_fb_helper_list);
>   static DEFINE_MUTEX(kernel_fb_helper_lock);
>   
> @@ -1345,15 +1356,35 @@ int drm_fb_helper_set_par(struct fb_info *info)
>   }
>   EXPORT_SYMBOL(drm_fb_helper_set_par);
>   
> -static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy)
> +static void pan_set_locked(struct drm_client_dev *client,
> +			   int dx, int dy)
>   {
>   	struct drm_mode_set *mode_set;
> +	int screen_x_offset = dx;
> +	int screen_y_offset = dy;
>   
> -	mutex_lock(&fb_helper->client.modeset_mutex);
> -	drm_client_for_each_modeset(mode_set, &fb_helper->client) {
> -		mode_set->x += dx;
> -		mode_set->y += dy;
> +	drm_client_for_each_modeset(mode_set, client) {
> +		if (drm_fbdev_screen_expand_mode_enabled) {
> +			if (drm_fbdev_screen_mode == SCREEN_EXPAND_HORIZONTAL) {
> +				mode_set->x += screen_x_offset;
> +				mode_set->y += screen_y_offset;
> +				screen_x_offset += mode_set->mode->hdisplay;
> +			} else if (drm_fbdev_screen_mode == SCREEN_EXPAND_VERTICAL) {
> +				mode_set->x += screen_x_offset;
> +				mode_set->y += screen_y_offset;
> +				screen_y_offset += mode_set->mode->vdisplay;
> +			}
> +		} else {
> +			mode_set->x = screen_x_offset;
> +			mode_set->y = screen_y_offset;
> +		}
>   	}
> +}
> +
> +static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy)
> +{
> +	mutex_lock(&fb_helper->client.modeset_mutex);
> +	pan_set_locked(&fb_helper->client, dx, dy);
>   	mutex_unlock(&fb_helper->client.modeset_mutex);
>   }
>   
> @@ -1387,10 +1418,8 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
>   
>   	mutex_lock(&client->modeset_mutex);
>   	drm_modeset_lock_all(fb_helper->dev);
> +	pan_set_locked(client, var->xoffset, var->yoffset);
>   	drm_client_for_each_modeset(modeset, client) {
> -		modeset->x = var->xoffset;
> -		modeset->y = var->yoffset;
> -
>   		if (modeset->num_connectors) {
>   			ret = drm_mode_set_config_internal(modeset);
>   			if (!ret) {
> @@ -1461,6 +1490,94 @@ static uint32_t drm_fb_helper_find_format(struct drm_fb_helper *fb_helper, const
>   	return DRM_FORMAT_INVALID;
>   }
>   
> +/*
> + * Check if the device supports extended mode
> + *
> + * return true if the device supports extended mode,
> + * otherwise return false.
> + */
> +static bool drm_fb_helper_validate_extended_mode(struct drm_fb_helper *fb_helper,
> +						 struct drm_fb_helper_surface_size *sizes)
> +{
> +	struct drm_client_dev *client = &fb_helper->client;
> +	struct drm_device *dev = fb_helper->dev;
> +	struct drm_mode_config *config = &dev->mode_config;
> +	struct drm_mode_set *mode_set;
> +	u32 crtc_count;
> +
> +	drm_client_for_each_modeset(mode_set, client) {
> +		crtc_count++;
> +
> +		for (int j = 0; j < mode_set->num_connectors; j++) {
> +			struct drm_connector *connector = mode_set->connectors[j];
> +
> +			if (connector->has_tile) {
> +				drm_dbg_kms(client->dev,
> +					    "Don't support extended with tile mode connector yet\n");
> +				return false;
> +			}
> +		}
> +	}
> +
> +	if (crtc_count < 2) {
> +		drm_dbg_kms(client->dev,
> +			    "Only support extended mode when device have mult-crtcs\n");
> +		return false;
> +	}
> +
> +	if (drm_fbdev_screen_mode == SCREEN_EXPAND_HORIZONTAL) {
> +		u32 x = 0;
> +
> +		drm_client_for_each_modeset(mode_set, client) {
> +			struct drm_display_mode *desired_mode;
> +
> +			desired_mode = mode_set->mode;
> +			x = mode_set->x;
> +			sizes->fb_width = sizes->surface_width  += desired_mode->hdisplay;
> +			sizes->surface_height =
> +				min_t(u32, desired_mode->vdisplay + mode_set->y,
> +				      sizes->surface_height);
> +			sizes->fb_height = min_t(u32, desired_mode->vdisplay + mode_set->y,
> +						 sizes->fb_height);
> +		}
> +		sizes->fb_width = sizes->surface_width += x;
> +
> +		if (sizes->fb_width > config->max_width) {
> +			drm_dbg_kms(client->dev,
> +				    "screen_buffer total width %d > config width %d\n",
> +				    sizes->fb_width, config->max_width);
> +			return false;
> +		}
> +	} else if (drm_fbdev_screen_mode == SCREEN_EXPAND_VERTICAL) {
> +		u32 y = 0;
> +
> +		drm_client_for_each_modeset(mode_set, client) {
> +			struct drm_display_mode *desired_mode;
> +
> +			desired_mode = mode_set->mode;
> +			y = mode_set->y;
> +			sizes->fb_height = sizes->surface_height += desired_mode->vdisplay;
> +			sizes->surface_width =
> +				min_t(u32, desired_mode->hdisplay + mode_set->x,
> +				      sizes->surface_width);
> +			sizes->fb_width = min_t(u32, desired_mode->hdisplay + mode_set->x,
> +						sizes->fb_width);
> +		}
> +		sizes->fb_height = sizes->surface_height += y;
> +
> +		if (sizes->fb_height > config->max_height) {
> +			drm_dbg_kms(client->dev,
> +				    "screen_buffer_total_height %d > config height %d\n",
> +				    sizes->fb_height, config->max_height);
> +			return false;
> +		}
> +	} else {
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>   static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
>   				      struct drm_fb_helper_surface_size *sizes)
>   {
> @@ -1527,6 +1644,16 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper,
>   
>   	/* first up get a count of crtcs now in use and new min/maxes width/heights */
>   	crtc_count = 0;
> +
> +	/* Check if we support extended mode. If we do, we will adjust the sizes accordingly. */
> +	if (drm_fbdev_screen_mode &&
> +		drm_fb_helper_validate_extended_mode(fb_helper, sizes)) {
> +		drm_fbdev_screen_expand_mode_enabled = true;
> +		drm_dbg_kms(dev, "Extended mode: horizontal expansion, width: %d, height: %d\n",
> +			    sizes->surface_width, sizes->surface_height);
> +		return 0;
> +	}
> +
>   	drm_client_for_each_modeset(mode_set, client) {
>   		struct drm_display_mode *desired_mode;
>   		int x, y, j;

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



  reply	other threads:[~2025-11-07 10:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-07  9:26 [PATCH] drm/fb-helper: add fbdev screen expended mode display support oushixiong1025
2025-11-07 10:06 ` Thomas Zimmermann [this message]
2025-11-10  5:54   ` Shixiong Ou
2025-11-10  7:17     ` Thomas Zimmermann
2025-11-10 12:54 ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15166a78-b603-464a-8fa5-b7dd43d55029@suse.de \
    --to=tzimmermann@suse.de \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuyihu@kylinos.cn \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=oushixiong1025@163.com \
    --cc=oushixiong@kylinos.cn \
    --cc=simona@ffwll.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox