diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 367fb8b2d5fa..97b34f377fe8 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -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 * @dev: DRM device * @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 * * Sets up the bare minimum to make the framebuffer helper usable. This is * useful to implement race-free initialization of the polling helpers. */ 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) { + /* + * 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); spin_lock_init(&helper->damage_lock); INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); @@ -430,10 +446,23 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, mutex_init(&helper->lock); helper->funcs = funcs; helper->dev = dev; + helper->preferred_bpp = preferred_bpp; } EXPORT_SYMBOL(drm_fb_helper_prepare); /** + * drm_fb_helper_unprepare - clean up a drm_fb_helper structure + * @fb_helper: driver-allocated fbdev helper structure to set up + * + * Cleans up the framebuffer helper. Inverse of drm_fb_helper_prepare(). + */ +void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper) +{ + mutex_destroy(&fb_helper->lock); +} +EXPORT_SYMBOL(drm_fb_helper_unprepare); + +/** * drm_fb_helper_init - initialize a &struct drm_fb_helper * @dev: drm device * @fb_helper: driver-allocated fbdev helper structure to initialize @@ -559,7 +588,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) } mutex_unlock(&kernel_fb_helper_lock); - mutex_destroy(&fb_helper->lock); + drm_fb_helper_unprepare(fb_helper); if (!fb_helper->client.funcs) drm_client_release(&fb_helper->client); @@ -1772,7 +1801,7 @@ static uint32_t drm_fb_helper_find_color_mode_format(struct drm_fb_helper *fb_he return drm_fb_helper_find_format(fb_helper, formats, format_count, bpp, depth); } -static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp, +static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { struct drm_client_dev *client = &fb_helper->client; @@ -1817,7 +1846,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe surface_format = drm_fb_helper_find_color_mode_format(fb_helper, plane->format_types, plane->format_count, - preferred_bpp); + fb_helper->preferred_bpp); if (surface_format != DRM_FORMAT_INVALID) break; /* found supported format */ } @@ -1889,7 +1918,7 @@ static int __drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int prefe return 0; } -static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferred_bpp, +static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, struct drm_fb_helper_surface_size *sizes) { struct drm_client_dev *client = &fb_helper->client; @@ -1898,7 +1927,7 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr int ret; mutex_lock(&client->modeset_mutex); - ret = __drm_fb_helper_find_sizes(fb_helper, preferred_bpp, sizes); + ret = __drm_fb_helper_find_sizes(fb_helper, sizes); mutex_unlock(&client->modeset_mutex); if (ret) @@ -1920,14 +1949,13 @@ static int drm_fb_helper_find_sizes(struct drm_fb_helper *fb_helper, int preferr * Allocates the backing storage and sets up the fbdev info structure through * the ->fb_probe callback. */ -static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, - int preferred_bpp) +static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper) { struct drm_client_dev *client = &fb_helper->client; struct drm_fb_helper_surface_size sizes; int ret; - ret = drm_fb_helper_find_sizes(fb_helper, preferred_bpp, &sizes); + ret = drm_fb_helper_find_sizes(fb_helper, &sizes); if (ret) { /* First time: disable all crtc's.. */ if (!fb_helper->deferred_setup) @@ -2105,8 +2133,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) /* Note: Drops fb_helper->lock before returning. */ static int -__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, - int bpp_sel) +__drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper) { struct drm_device *dev = fb_helper->dev; struct fb_info *info; @@ -2117,10 +2144,9 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, height = dev->mode_config.max_height; drm_client_modeset_probe(&fb_helper->client, width, height); - ret = drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); + ret = drm_fb_helper_single_fb_probe(fb_helper); if (ret < 0) { if (ret == -EAGAIN) { - fb_helper->preferred_bpp = bpp_sel; fb_helper->deferred_setup = true; ret = 0; } @@ -2166,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 * @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. * At the moment, this is a cloned configuration across all heads with @@ -2204,7 +2229,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper, * RETURNS: * 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; @@ -2212,7 +2237,7 @@ int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) return 0; mutex_lock(&fb_helper->lock); - ret = __drm_fb_helper_initial_config_and_unlock(fb_helper, bpp_sel); + ret = __drm_fb_helper_initial_config_and_unlock(fb_helper); return ret; } @@ -2248,8 +2273,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) mutex_lock(&fb_helper->lock); if (fb_helper->deferred_setup) { - err = __drm_fb_helper_initial_config_and_unlock(fb_helper, - fb_helper->preferred_bpp); + err = __drm_fb_helper_initial_config_and_unlock(fb_helper); return err; } |