summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_simple_kms_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_simple_kms_helper.c')
-rw-r--r--drivers/gpu/drm/drm_simple_kms_helper.c87
1 files changed, 62 insertions, 25 deletions
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c
index 0db36d2..7b6d26e 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -34,6 +34,12 @@ static const struct drm_encoder_funcs drm_simple_kms_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
+static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ return drm_atomic_add_affected_planes(state->state, crtc);
+}
+
static void drm_simple_kms_crtc_enable(struct drm_crtc *crtc)
{
struct drm_simple_display_pipe *pipe;
@@ -57,6 +63,7 @@ static void drm_simple_kms_crtc_disable(struct drm_crtc *crtc)
}
static const struct drm_crtc_helper_funcs drm_simple_kms_crtc_helper_funcs = {
+ .atomic_check = drm_simple_kms_crtc_check,
.disable = drm_simple_kms_crtc_disable,
.enable = drm_simple_kms_crtc_enable,
};
@@ -73,22 +80,9 @@ static const struct drm_crtc_funcs drm_simple_kms_crtc_funcs = {
static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *plane_state)
{
- struct drm_rect src = {
- .x1 = plane_state->src_x,
- .y1 = plane_state->src_y,
- .x2 = plane_state->src_x + plane_state->src_w,
- .y2 = plane_state->src_y + plane_state->src_h,
- };
- struct drm_rect dest = {
- .x1 = plane_state->crtc_x,
- .y1 = plane_state->crtc_y,
- .x2 = plane_state->crtc_x + plane_state->crtc_w,
- .y2 = plane_state->crtc_y + plane_state->crtc_h,
- };
struct drm_rect clip = { 0 };
struct drm_simple_display_pipe *pipe;
struct drm_crtc_state *crtc_state;
- bool visible;
int ret;
pipe = container_of(plane, struct drm_simple_display_pipe, plane);
@@ -102,17 +96,15 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane,
clip.x2 = crtc_state->adjusted_mode.hdisplay;
clip.y2 = crtc_state->adjusted_mode.vdisplay;
- ret = drm_plane_helper_check_update(plane, &pipe->crtc,
- plane_state->fb,
- &src, &dest, &clip,
- plane_state->rotation,
- DRM_PLANE_HELPER_NO_SCALING,
- DRM_PLANE_HELPER_NO_SCALING,
- false, true, &visible);
+
+ ret = drm_plane_helper_check_state(plane_state, &clip,
+ DRM_PLANE_HELPER_NO_SCALING,
+ DRM_PLANE_HELPER_NO_SCALING,
+ false, true);
if (ret)
return ret;
- if (!visible)
+ if (!plane_state->visible)
return -EINVAL;
if (!pipe->funcs || !pipe->funcs->check)
@@ -148,16 +140,61 @@ static const struct drm_plane_funcs drm_simple_kms_plane_funcs = {
};
/**
+ * drm_simple_display_pipe_attach_bridge - Attach a bridge to the display pipe
+ * @pipe: simple display pipe object
+ * @bridge: bridge to attach
+ *
+ * Makes it possible to still use the drm_simple_display_pipe helpers when
+ * a DRM bridge has to be used.
+ *
+ * Note that you probably want to initialize the pipe by passing a NULL
+ * connector to drm_simple_display_pipe_init().
+ *
+ * Returns:
+ * Zero on success, negative error code on failure.
+ */
+int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe,
+ struct drm_bridge *bridge)
+{
+ bridge->encoder = &pipe->encoder;
+ pipe->encoder.bridge = bridge;
+ return drm_bridge_attach(pipe->encoder.dev, bridge);
+}
+EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
+
+/**
+ * drm_simple_display_pipe_detach_bridge - Detach the bridge from the display pipe
+ * @pipe: simple display pipe object
+ *
+ * Detaches the drm bridge previously attached with
+ * drm_simple_display_pipe_attach_bridge()
+ */
+void drm_simple_display_pipe_detach_bridge(struct drm_simple_display_pipe *pipe)
+{
+ if (WARN_ON(!pipe->encoder.bridge))
+ return;
+
+ drm_bridge_detach(pipe->encoder.bridge);
+ pipe->encoder.bridge = NULL;
+}
+EXPORT_SYMBOL(drm_simple_display_pipe_detach_bridge);
+
+/**
* drm_simple_display_pipe_init - Initialize a simple display pipeline
* @dev: DRM device
* @pipe: simple display pipe object to initialize
* @funcs: callbacks for the display pipe (optional)
- * @formats: array of supported formats (%DRM_FORMAT_*)
+ * @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats
- * @connector: connector to attach and register
+ * @connector: connector to attach and register (optional)
*
* Sets up a display pipeline which consist of a really simple
- * plane-crtc-encoder pipe coupled with the provided connector.
+ * plane-crtc-encoder pipe.
+ *
+ * If a connector is supplied, the pipe will be coupled with the provided
+ * connector. You may supply a NULL connector when using drm bridges, that
+ * handle connectors themselves (see drm_simple_display_pipe_attach_bridge()).
+ *
* Teardown of a simple display pipe is all handled automatically by the drm
* core through calling drm_mode_config_cleanup(). Drivers afterwards need to
* release the memory for the structure themselves.
@@ -196,7 +233,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
encoder->possible_crtcs = 1 << drm_crtc_index(crtc);
ret = drm_encoder_init(dev, encoder, &drm_simple_kms_encoder_funcs,
DRM_MODE_ENCODER_NONE, NULL);
- if (ret)
+ if (ret || !connector)
return ret;
return drm_mode_connector_attach_encoder(connector, encoder);
OpenPOWER on IntegriCloud