34,12 → 34,35 |
#include <linux/moduleparam.h> |
|
#include <drm/drmP.h> |
#include <drm/drm_atomic.h> |
#include <drm/drm_crtc.h> |
#include <drm/drm_fourcc.h> |
#include <drm/drm_crtc_helper.h> |
#include <drm/drm_fb_helper.h> |
#include <drm/drm_plane_helper.h> |
#include <drm/drm_atomic_helper.h> |
#include <drm/drm_edid.h> |
|
/** |
* DOC: overview |
* |
* The CRTC modeset helper library provides a default set_config implementation |
* in drm_crtc_helper_set_config(). Plus a few other convenience functions using |
* the same callbacks which drivers can use to e.g. restore the modeset |
* configuration on resume with drm_helper_resume_force_mode(). |
* |
* The driver callbacks are mostly compatible with the atomic modeset helpers, |
* except for the handling of the primary plane: Atomic helpers require that the |
* primary plane is implemented as a real standalone plane and not directly tied |
* to the CRTC state. For easier transition this library provides functions to |
* implement the old semantics required by the CRTC helpers using the new plane |
* and atomic helper callbacks. |
* |
* Drivers are strongly urged to convert to the atomic helpers (by way of first |
* converting to the plane helpers). New drivers must not use these functions |
* but need to implement the atomic interface instead, potentially using the |
* atomic helpers for that. |
*/ |
MODULE_AUTHOR("David Airlie, Jesse Barnes"); |
MODULE_DESCRIPTION("DRM KMS helper"); |
MODULE_LICENSE("GPL and additional rights"); |
871,3 → 894,112 |
drm_modeset_unlock_all(dev); |
} |
EXPORT_SYMBOL(drm_helper_resume_force_mode); |
|
/** |
* drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers |
* @crtc: DRM CRTC |
* @mode: DRM display mode which userspace requested |
* @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks |
* @x: x offset of the CRTC scanout area on the underlying framebuffer |
* @y: y offset of the CRTC scanout area on the underlying framebuffer |
* @old_fb: previous framebuffer |
* |
* This function implements a callback useable as the ->mode_set callback |
* required by the crtc helpers. Besides the atomic plane helper functions for |
* the primary plane the driver must also provide the ->mode_set_nofb callback |
* to set up the crtc. |
* |
* This is a transitional helper useful for converting drivers to the atomic |
* interfaces. |
*/ |
int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode, int x, int y, |
struct drm_framebuffer *old_fb) |
{ |
struct drm_crtc_state *crtc_state; |
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
int ret; |
|
if (crtc->funcs->atomic_duplicate_state) |
crtc_state = crtc->funcs->atomic_duplicate_state(crtc); |
else if (crtc->state) |
crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), |
GFP_KERNEL); |
else |
crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL); |
if (!crtc_state) |
return -ENOMEM; |
|
crtc_state->enable = true; |
crtc_state->planes_changed = true; |
crtc_state->mode_changed = true; |
drm_mode_copy(&crtc_state->mode, mode); |
drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode); |
|
if (crtc_funcs->atomic_check) { |
ret = crtc_funcs->atomic_check(crtc, crtc_state); |
if (ret) { |
kfree(crtc_state); |
|
return ret; |
} |
} |
|
swap(crtc->state, crtc_state); |
|
crtc_funcs->mode_set_nofb(crtc); |
|
if (crtc_state) { |
if (crtc->funcs->atomic_destroy_state) |
crtc->funcs->atomic_destroy_state(crtc, crtc_state); |
else |
kfree(crtc_state); |
} |
|
return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb); |
} |
EXPORT_SYMBOL(drm_helper_crtc_mode_set); |
|
/** |
* drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers |
* @crtc: DRM CRTC |
* @x: x offset of the CRTC scanout area on the underlying framebuffer |
* @y: y offset of the CRTC scanout area on the underlying framebuffer |
* @old_fb: previous framebuffer |
* |
* This function implements a callback useable as the ->mode_set_base used |
* required by the crtc helpers. The driver must provide the atomic plane helper |
* functions for the primary plane. |
* |
* This is a transitional helper useful for converting drivers to the atomic |
* interfaces. |
*/ |
int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, |
struct drm_framebuffer *old_fb) |
{ |
struct drm_plane_state *plane_state; |
struct drm_plane *plane = crtc->primary; |
|
if (plane->funcs->atomic_duplicate_state) |
plane_state = plane->funcs->atomic_duplicate_state(plane); |
else if (plane->state) |
plane_state = drm_atomic_helper_plane_duplicate_state(plane); |
else |
plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); |
if (!plane_state) |
return -ENOMEM; |
|
plane_state->crtc = crtc; |
drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb); |
plane_state->crtc_x = 0; |
plane_state->crtc_y = 0; |
plane_state->crtc_h = crtc->mode.vdisplay; |
plane_state->crtc_w = crtc->mode.hdisplay; |
plane_state->src_x = x << 16; |
plane_state->src_y = y << 16; |
plane_state->src_h = crtc->mode.vdisplay << 16; |
plane_state->src_w = crtc->mode.hdisplay << 16; |
|
return drm_plane_helper_commit(plane, plane_state, old_fb); |
} |
EXPORT_SYMBOL(drm_helper_crtc_mode_set_base); |