drm/fb-helper: Initialize fb-helper's preferred BPP in prepare function
Initialize the fb-helper's preferred_bpp field early from within drm_fb_helper_prepare(); instead of the later client hot-plugging callback. This simplifies the generic fbdev setup function. No real changes, but all drivers' fbdev code has to be adapted. v3: * build with CONFIG_DRM_FBDEV_EMULATION unset (kernel test bot) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230125200415.14123-7-tzimmermann@suse.de
This commit is contained in:
parent
ec9361a137
commit
6c80a93be6
11 changed files with 47 additions and 47 deletions
|
@ -129,7 +129,7 @@ int armada_fbdev_init(struct drm_device *dev)
|
||||||
|
|
||||||
priv->fbdev = fbh;
|
priv->fbdev = fbh;
|
||||||
|
|
||||||
drm_fb_helper_prepare(dev, fbh, &armada_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, fbh, 32, &armada_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, fbh);
|
ret = drm_fb_helper_init(dev, fbh);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -137,7 +137,7 @@ int armada_fbdev_init(struct drm_device *dev)
|
||||||
goto err_fb_helper;
|
goto err_fb_helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(fbh, 32);
|
ret = drm_fb_helper_initial_config(fbh);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DRM_ERROR("failed to set initial config\n");
|
DRM_ERROR("failed to set initial config\n");
|
||||||
goto err_fb_setup;
|
goto err_fb_setup;
|
||||||
|
|
|
@ -414,14 +414,30 @@ static void drm_fb_helper_damage_work(struct work_struct *work)
|
||||||
* drm_fb_helper_prepare - setup a drm_fb_helper structure
|
* drm_fb_helper_prepare - setup a drm_fb_helper structure
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
* @helper: driver-allocated fbdev helper structure to set up
|
* @helper: driver-allocated fbdev helper structure to set up
|
||||||
|
* @preferred_bpp: Preferred bits per pixel for the device.
|
||||||
* @funcs: pointer to structure of functions associate with this helper
|
* @funcs: pointer to structure of functions associate with this helper
|
||||||
*
|
*
|
||||||
* Sets up the bare minimum to make the framebuffer helper usable. This is
|
* Sets up the bare minimum to make the framebuffer helper usable. This is
|
||||||
* useful to implement race-free initialization of the polling helpers.
|
* useful to implement race-free initialization of the polling helpers.
|
||||||
*/
|
*/
|
||||||
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
||||||
|
unsigned int preferred_bpp,
|
||||||
const struct drm_fb_helper_funcs *funcs)
|
const struct drm_fb_helper_funcs *funcs)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Pick a preferred bpp of 32 if no value has been given. This
|
||||||
|
* will select XRGB8888 for the framebuffer formats. All drivers
|
||||||
|
* have to support XRGB8888 for backwards compatibility with legacy
|
||||||
|
* userspace, so it's the safe choice here.
|
||||||
|
*
|
||||||
|
* TODO: Replace struct drm_mode_config.preferred_depth and this
|
||||||
|
* bpp value with a preferred format that is given as struct
|
||||||
|
* drm_format_info. Then derive all other values from the
|
||||||
|
* format.
|
||||||
|
*/
|
||||||
|
if (!preferred_bpp)
|
||||||
|
preferred_bpp = 32;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&helper->kernel_fb_list);
|
INIT_LIST_HEAD(&helper->kernel_fb_list);
|
||||||
spin_lock_init(&helper->damage_lock);
|
spin_lock_init(&helper->damage_lock);
|
||||||
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
|
INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
|
||||||
|
@ -430,6 +446,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
||||||
mutex_init(&helper->lock);
|
mutex_init(&helper->lock);
|
||||||
helper->funcs = funcs;
|
helper->funcs = funcs;
|
||||||
helper->dev = dev;
|
helper->dev = dev;
|
||||||
|
helper->preferred_bpp = preferred_bpp;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_fb_helper_prepare);
|
EXPORT_SYMBOL(drm_fb_helper_prepare);
|
||||||
|
|
||||||
|
@ -2175,7 +2192,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper)
|
||||||
/**
|
/**
|
||||||
* drm_fb_helper_initial_config - setup a sane initial connector configuration
|
* drm_fb_helper_initial_config - setup a sane initial connector configuration
|
||||||
* @fb_helper: fb_helper device struct
|
* @fb_helper: fb_helper device struct
|
||||||
* @bpp_sel: bpp value to use for the framebuffer configuration
|
|
||||||
*
|
*
|
||||||
* Scans the CRTCs and connectors and tries to put together an initial setup.
|
* Scans the CRTCs and connectors and tries to put together an initial setup.
|
||||||
* At the moment, this is a cloned configuration across all heads with
|
* At the moment, this is a cloned configuration across all heads with
|
||||||
|
@ -2213,15 +2229,13 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper)
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* Zero if everything went ok, nonzero otherwise.
|
* Zero if everything went ok, nonzero otherwise.
|
||||||
*/
|
*/
|
||||||
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
|
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!drm_fbdev_emulation)
|
if (!drm_fbdev_emulation)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fb_helper->preferred_bpp = bpp_sel;
|
|
||||||
|
|
||||||
mutex_lock(&fb_helper->lock);
|
mutex_lock(&fb_helper->lock);
|
||||||
ret = __drm_fb_helper_initial_config_and_unlock(fb_helper);
|
ret = __drm_fb_helper_initial_config_and_unlock(fb_helper);
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
|
||||||
if (!drm_drv_uses_atomic_modeset(dev))
|
if (!drm_drv_uses_atomic_modeset(dev))
|
||||||
drm_helper_disable_unused_functions(dev);
|
drm_helper_disable_unused_functions(dev);
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp);
|
ret = drm_fb_helper_initial_config(fb_helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_cleanup;
|
goto err_cleanup;
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
|
||||||
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
|
fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
|
||||||
if (!fb_helper)
|
if (!fb_helper)
|
||||||
return;
|
return;
|
||||||
drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs);
|
drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fb_helper_generic_funcs);
|
||||||
|
|
||||||
ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
|
ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -462,21 +462,6 @@ void drm_fbdev_generic_setup(struct drm_device *dev,
|
||||||
goto err_drm_client_init;
|
goto err_drm_client_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Pick a preferred bpp of 32 if no value has been given. This
|
|
||||||
* will select XRGB8888 for the framebuffer formats. All drivers
|
|
||||||
* have to support XRGB8888 for backwards compatibility with legacy
|
|
||||||
* userspace, so it's the safe choice here.
|
|
||||||
*
|
|
||||||
* TODO: Replace struct drm_mode_config.preferred_depth and this
|
|
||||||
* bpp value with a preferred format that is given as struct
|
|
||||||
* drm_format_info. Then derive all other values from the
|
|
||||||
* format.
|
|
||||||
*/
|
|
||||||
if (!preferred_bpp)
|
|
||||||
preferred_bpp = 32;
|
|
||||||
fb_helper->preferred_bpp = preferred_bpp;
|
|
||||||
|
|
||||||
ret = drm_fbdev_client_hotplug(&fb_helper->client);
|
ret = drm_fbdev_client_hotplug(&fb_helper->client);
|
||||||
if (ret)
|
if (ret)
|
||||||
drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
|
drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
|
||||||
|
|
|
@ -163,7 +163,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
|
||||||
|
|
||||||
private->fb_helper = helper = &fbdev->drm_fb_helper;
|
private->fb_helper = helper = &fbdev->drm_fb_helper;
|
||||||
|
|
||||||
drm_fb_helper_prepare(dev, helper, &exynos_drm_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, helper, PREFERRED_BPP, &exynos_drm_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, helper);
|
ret = drm_fb_helper_init(dev, helper);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -172,7 +172,7 @@ int exynos_drm_fbdev_init(struct drm_device *dev)
|
||||||
goto err_init;
|
goto err_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
|
ret = drm_fb_helper_initial_config(helper);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
DRM_DEV_ERROR(dev->dev,
|
DRM_DEV_ERROR(dev->dev,
|
||||||
"failed to set up hw configuration.\n");
|
"failed to set up hw configuration.\n");
|
||||||
|
|
|
@ -409,7 +409,7 @@ int psb_fbdev_init(struct drm_device *dev)
|
||||||
|
|
||||||
dev_priv->fb_helper = fb_helper;
|
dev_priv->fb_helper = fb_helper;
|
||||||
|
|
||||||
drm_fb_helper_prepare(dev, fb_helper, &psb_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, fb_helper);
|
ret = drm_fb_helper_init(dev, fb_helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -418,7 +418,7 @@ int psb_fbdev_init(struct drm_device *dev)
|
||||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||||
drm_helper_disable_unused_functions(dev);
|
drm_helper_disable_unused_functions(dev);
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(fb_helper, 32);
|
ret = drm_fb_helper_initial_config(fb_helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
|
|
|
@ -520,10 +520,12 @@ int intel_fbdev_init(struct drm_device *dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_init(&ifbdev->hpd_lock);
|
mutex_init(&ifbdev->hpd_lock);
|
||||||
drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, &ifbdev->helper, 32, &intel_fb_helper_funcs);
|
||||||
|
|
||||||
if (!intel_fbdev_init_bios(dev, ifbdev))
|
if (intel_fbdev_init_bios(dev, ifbdev))
|
||||||
ifbdev->preferred_bpp = 32;
|
ifbdev->helper.preferred_bpp = ifbdev->preferred_bpp;
|
||||||
|
else
|
||||||
|
ifbdev->preferred_bpp = ifbdev->helper.preferred_bpp;
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, &ifbdev->helper);
|
ret = drm_fb_helper_init(dev, &ifbdev->helper);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -542,8 +544,7 @@ static void intel_fbdev_initial_config(void *data, async_cookie_t cookie)
|
||||||
struct intel_fbdev *ifbdev = data;
|
struct intel_fbdev *ifbdev = data;
|
||||||
|
|
||||||
/* Due to peculiar init order wrt to hpd handling this is separate. */
|
/* Due to peculiar init order wrt to hpd handling this is separate. */
|
||||||
if (drm_fb_helper_initial_config(&ifbdev->helper,
|
if (drm_fb_helper_initial_config(&ifbdev->helper))
|
||||||
ifbdev->preferred_bpp))
|
|
||||||
intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
|
intel_fbdev_unregister(to_i915(ifbdev->helper.dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
|
||||||
|
|
||||||
helper = &fbdev->base;
|
helper = &fbdev->base;
|
||||||
|
|
||||||
drm_fb_helper_prepare(dev, helper, &msm_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, helper, 32, &msm_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, helper);
|
ret = drm_fb_helper_init(dev, helper);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -159,7 +159,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(helper, 32);
|
ret = drm_fb_helper_initial_config(helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
|
|
|
@ -239,13 +239,13 @@ void omap_fbdev_init(struct drm_device *dev)
|
||||||
|
|
||||||
helper = &fbdev->base;
|
helper = &fbdev->base;
|
||||||
|
|
||||||
drm_fb_helper_prepare(dev, helper, &omap_fb_helper_funcs);
|
drm_fb_helper_prepare(dev, helper, 32, &omap_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(dev, helper);
|
ret = drm_fb_helper_init(dev, helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(helper, 32);
|
ret = drm_fb_helper_initial_config(helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
|
|
|
@ -348,7 +348,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
||||||
rfbdev->rdev = rdev;
|
rfbdev->rdev = rdev;
|
||||||
rdev->mode_info.rfbdev = rfbdev;
|
rdev->mode_info.rfbdev = rfbdev;
|
||||||
|
|
||||||
drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper,
|
drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, bpp_sel,
|
||||||
&radeon_fb_helper_funcs);
|
&radeon_fb_helper_funcs);
|
||||||
|
|
||||||
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper);
|
ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper);
|
||||||
|
@ -358,7 +358,7 @@ int radeon_fbdev_init(struct radeon_device *rdev)
|
||||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||||
drm_helper_disable_unused_functions(rdev->ddev);
|
drm_helper_disable_unused_functions(rdev->ddev);
|
||||||
|
|
||||||
ret = drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
|
ret = drm_fb_helper_initial_config(&rfbdev->helper);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fini;
|
goto fini;
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ static struct tegra_fbdev *tegra_fbdev_create(struct drm_device *drm)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_fb_helper_prepare(drm, &fbdev->base, &tegra_fb_helper_funcs);
|
drm_fb_helper_prepare(drm, &fbdev->base, 32, &tegra_fb_helper_funcs);
|
||||||
|
|
||||||
return fbdev;
|
return fbdev;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,6 @@ static void tegra_fbdev_free(struct tegra_fbdev *fbdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
|
static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
|
||||||
unsigned int preferred_bpp,
|
|
||||||
unsigned int num_crtc,
|
unsigned int num_crtc,
|
||||||
unsigned int max_connectors)
|
unsigned int max_connectors)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +332,7 @@ static int tegra_fbdev_init(struct tegra_fbdev *fbdev,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = drm_fb_helper_initial_config(&fbdev->base, preferred_bpp);
|
err = drm_fb_helper_initial_config(&fbdev->base);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(drm->dev, "failed to set initial configuration: %d\n",
|
dev_err(drm->dev, "failed to set initial configuration: %d\n",
|
||||||
err);
|
err);
|
||||||
|
@ -396,7 +395,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
|
||||||
struct tegra_drm *tegra = drm->dev_private;
|
struct tegra_drm *tegra = drm->dev_private;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = tegra_fbdev_init(tegra->fbdev, 32, drm->mode_config.num_crtc,
|
err = tegra_fbdev_init(tegra->fbdev, drm->mode_config.num_crtc,
|
||||||
drm->mode_config.num_connector);
|
drm->mode_config.num_connector);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -229,6 +229,7 @@ drm_fb_helper_from_client(struct drm_client_dev *client)
|
||||||
|
|
||||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||||
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
|
||||||
|
unsigned int preferred_bpp,
|
||||||
const struct drm_fb_helper_funcs *funcs);
|
const struct drm_fb_helper_funcs *funcs);
|
||||||
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);
|
void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper);
|
||||||
int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
|
int drm_fb_helper_init(struct drm_device *dev, struct drm_fb_helper *helper);
|
||||||
|
@ -284,7 +285,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
|
||||||
unsigned long arg);
|
unsigned long arg);
|
||||||
|
|
||||||
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
|
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
|
||||||
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
|
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
|
||||||
int drm_fb_helper_debug_enter(struct fb_info *info);
|
int drm_fb_helper_debug_enter(struct fb_info *info);
|
||||||
int drm_fb_helper_debug_leave(struct fb_info *info);
|
int drm_fb_helper_debug_leave(struct fb_info *info);
|
||||||
|
|
||||||
|
@ -293,6 +294,7 @@ void drm_fb_helper_output_poll_changed(struct drm_device *dev);
|
||||||
#else
|
#else
|
||||||
static inline void drm_fb_helper_prepare(struct drm_device *dev,
|
static inline void drm_fb_helper_prepare(struct drm_device *dev,
|
||||||
struct drm_fb_helper *helper,
|
struct drm_fb_helper *helper,
|
||||||
|
unsigned int preferred_bpp,
|
||||||
const struct drm_fb_helper_funcs *funcs)
|
const struct drm_fb_helper_funcs *funcs)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -455,8 +457,7 @@ static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper,
|
static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
|
||||||
int bpp_sel)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue