diff options
Diffstat (limited to 'drivers/gpu/drm/drm_simple_kms_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_simple_kms_helper.c | 113 | 
1 files changed, 88 insertions, 25 deletions
diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 0db36d27e90b..7bae08c2bf0a 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) @@ -133,7 +125,33 @@ static void drm_simple_kms_plane_atomic_update(struct drm_plane *plane,  	pipe->funcs->update(pipe, pstate);  } +static int drm_simple_kms_plane_prepare_fb(struct drm_plane *plane, +					   struct drm_plane_state *state) +{ +	struct drm_simple_display_pipe *pipe; + +	pipe = container_of(plane, struct drm_simple_display_pipe, plane); +	if (!pipe->funcs || !pipe->funcs->prepare_fb) +		return 0; + +	return pipe->funcs->prepare_fb(pipe, state); +} + +static void drm_simple_kms_plane_cleanup_fb(struct drm_plane *plane, +					    struct drm_plane_state *state) +{ +	struct drm_simple_display_pipe *pipe; + +	pipe = container_of(plane, struct drm_simple_display_pipe, plane); +	if (!pipe->funcs || !pipe->funcs->cleanup_fb) +		return; + +	pipe->funcs->cleanup_fb(pipe, state); +} +  static const struct drm_plane_helper_funcs drm_simple_kms_plane_helper_funcs = { +	.prepare_fb = drm_simple_kms_plane_prepare_fb, +	.cleanup_fb = drm_simple_kms_plane_cleanup_fb,  	.atomic_check = drm_simple_kms_plane_atomic_check,  	.atomic_update = drm_simple_kms_plane_atomic_update,  }; @@ -148,16 +166,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 +259,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);  |