drm_fb_helper.c revision 1450
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Copyright (c) 2006-2009 Red Hat Inc.
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Copyright (c) 2006-2008, 2013, Intel Corporation
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * DRM framebuffer helper functions
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Permission to use, copy, modify, distribute, and sell this software and its
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * documentation for any purpose is hereby granted without fee, provided that
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * the above copyright notice appear in all copies and that both that copyright
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * notice and this permission notice appear in supporting documentation, and
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * that the name of the copyright holders not be used in advertising or
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * publicity pertaining to distribution of the software without specific,
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * written prior permission. The copyright holders make no representations
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * about the suitability of this software for any purpose. It is provided "as
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * is" without express or implied warranty.
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * OF THIS SOFTWARE.
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Authors:
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Dave Airlie <airlied@linux.ie>
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Jesse Barnes <jesse.barnes@intel.com>
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * DOC: fbdev helpers
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * The fb helper functions are useful to provide an fbdev on top of a drm kernel
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * mode setting driver. They can be used mostly independantely from the crtc
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * helper functions used by many drivers to implement the kernel mode setting
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * interfaces.
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Initialization is done as a three-step process with drm_fb_helper_init(),
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * Drivers with fancier requirements than the default beheviour can override the
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * second step with their own code. Teardown is done with drm_fb_helper_fini().
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * At runtime drivers should restore the fbdev console by calling
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * should also notify the fb helper code from updates to the output
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * configuration by calling drm_fb_helper_hotplug_event(). For easier
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * integration with the output polling code in drm_crtc_helper.c the modeset
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * code proves a ->output_poll_changed callback.
74ccdc8ff418998513e72e36e77dc954d77e3e10~suv * All other functions exported by the fb helper library can be used to
f7b499d11542a2d5f93ba2d3c7c268e6d6d045bb~suv * implement the fbdev driver interface by the driver.
if (!fb_helper_connector)
goto fail;
fail:
return -ENOMEM;
struct drm_crtc *c;
return c->fb;
return NULL;
bool error = false;
return error;
int ret;
if (ret)
error = true;
if (ret)
error = true;
return error;
bool drm_fb_helper_force_kernel_mode(void)
if (ret)
error = true;
return error;
crtcs_bound++;
bound++;
kfree(helper->connector_info, dev->mode_config.num_connector * sizeof(struct drm_fb_helper_connector *));
kfree(helper->crtc_info[i].mode_set.connectors, INTELFB_CONN_LIMIT * sizeof(struct drm_connector *));
return -ENOMEM;
fb_helper->connector_info = kcalloc(dev->mode_config.num_connector, sizeof(struct drm_fb_helper_connector *), GFP_KERNEL);
return -ENOMEM;
for (i = 0; i < crtc_count; i++) {
sizeof(struct drm_connector *),
goto out_free;
return -ENOMEM;
int preferred_bpp)
int ret = 0;
int crtc_count = 0;
int gamma_size = 0;
crtc_count = 0;
if (desired_mode) {
if (gamma_size == 0)
crtc_count++;
if (ret < 0)
return ret;
int count = 0;
return count;
static struct drm_display_mode *drm_has_preferred_mode(struct drm_fb_helper_connector *fb_connector, int width, int height)
return mode;
return NULL;
static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
return mode;
goto create_mode;
return mode;
if (mode)
return mode;
bool enable;
if (strict)
return enable;
bool *enabled)
bool any_enabled = false;
if (any_enabled)
int count, i, j;
bool can_clone = false;
count = 0;
if (enabled[i])
count++;
can_clone = true;
if (!enabled[i])
if (!modes[i]) {
can_clone = false;
if (!enabled[j])
can_clone = false;
if (can_clone) {
can_clone = true;
if (!enabled[i])
if (!modes[i])
can_clone = false;
if (can_clone) {
if (enabled[i] == false)
if (!modes[i]) {
return best_score;
if (!crtcs)
return best_score;
my_score++;
my_score++;
my_score++;
if (!encoder)
goto out;
sizeof(struct drm_fb_helper_crtc *));
out:
return best_score;
bool *enabled;
goto errout1;
goto errout2;
int count = 0;
if (count == 0) {
bool ret = 0;
if (mode == 0) {
if (ret == true)
return ret;
return size;