Convert repaper to explicit primary plane, CRTC and encoder objects. Keep shadow-plane helpers, framebuffer access handling and no-scaling plane-state validation from simple-KMS path.
Signed-off-by: Ze Huang <[email protected]> --- drivers/gpu/drm/tiny/repaper.c | 130 +++++++++++++++++++++++++++++++++-------- 1 file changed, 105 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index c8270591afc7..23be9c762803 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -22,6 +22,7 @@ #include <linux/thermal.h> #include <drm/clients/drm_client_setup.h> +#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> @@ -38,7 +39,6 @@ #include <drm/drm_rect.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> #define REPAPER_RID_G2_COG_ID 0x12 @@ -65,7 +65,9 @@ enum repaper_epd_border_byte { struct repaper_epd { struct drm_device drm; - struct drm_simple_display_pipe pipe; + struct drm_plane plane; + struct drm_crtc crtc; + struct drm_encoder encoder; const struct drm_display_mode *mode; struct drm_connector connector; struct spi_device *spi; @@ -622,26 +624,24 @@ static void power_off(struct repaper_epd *epd) gpiod_set_value_cansleep(epd->discharge, 0); } -static enum drm_mode_status repaper_pipe_mode_valid(struct drm_simple_display_pipe *pipe, - const struct drm_display_mode *mode) +static enum drm_mode_status repaper_crtc_helper_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) { - struct drm_crtc *crtc = &pipe->crtc; struct repaper_epd *epd = drm_to_epd(crtc->dev); return drm_crtc_helper_mode_valid_fixed(crtc, mode, epd->mode); } -static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) +static void repaper_crtc_helper_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { - struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev); + struct repaper_epd *epd = drm_to_epd(crtc->dev); struct spi_device *spi = epd->spi; struct device *dev = &spi->dev; bool dc_ok = false; int i, ret, idx; - if (!drm_dev_enter(pipe->crtc.dev, &idx)) + if (!drm_dev_enter(crtc->dev, &idx)) return; DRM_DEBUG_DRIVER("\n"); @@ -771,9 +771,10 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, drm_dev_exit(idx); } -static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe) +static void repaper_crtc_helper_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { - struct repaper_epd *epd = drm_to_epd(pipe->crtc.dev); + struct repaper_epd *epd = drm_to_epd(crtc->dev); struct spi_device *spi = epd->spi; unsigned int line; @@ -827,14 +828,15 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe) power_off(epd); } -static void repaper_pipe_update(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *old_state) +static void repaper_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_commit *commit) { - struct drm_plane_state *state = pipe->plane.state; + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(commit, plane); + struct drm_plane_state *state = plane->state; struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); struct drm_rect rect; - if (!pipe->crtc.state->active) + if (!state->crtc || !state->crtc->state->active) return; if (drm_atomic_helper_damage_merged(old_state, state, &rect)) @@ -842,12 +844,72 @@ static void repaper_pipe_update(struct drm_simple_display_pipe *pipe, &shadow_plane_state->fmtcnv_state); } -static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = { - .mode_valid = repaper_pipe_mode_valid, - .enable = repaper_pipe_enable, - .disable = repaper_pipe_disable, - .update = repaper_pipe_update, - DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, +static const struct drm_plane_funcs repaper_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + DRM_GEM_SHADOW_PLANE_FUNCS, +}; + +static int repaper_plane_helper_atomic_check(struct drm_plane *plane, + struct drm_atomic_commit *state) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_crtc *crtc = plane_state->crtc; + struct drm_crtc_state *crtc_state = NULL; + int ret; + + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + return ret; +} + +static const struct drm_plane_helper_funcs repaper_plane_helper_funcs = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = repaper_plane_helper_atomic_check, + .atomic_update = repaper_plane_helper_atomic_update, +}; + +static int repaper_crtc_helper_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_commit *state) +{ + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + int ret; + + if (!crtc_state->enable) + goto out; + + ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state); + if (ret) + return ret; + +out: + return drm_atomic_add_affected_planes(state, crtc); +} + +static const struct drm_crtc_helper_funcs repaper_crtc_helper_funcs = { + .mode_valid = repaper_crtc_helper_mode_valid, + .atomic_check = repaper_crtc_helper_atomic_check, + .atomic_enable = repaper_crtc_helper_atomic_enable, + .atomic_disable = repaper_crtc_helper_atomic_disable, +}; + +static const struct drm_crtc_funcs repaper_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .reset = drm_atomic_helper_crtc_reset, + .destroy = drm_crtc_cleanup, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +}; + +static const struct drm_encoder_funcs repaper_encoder_funcs = { + .destroy = drm_encoder_cleanup, }; static int repaper_connector_get_modes(struct drm_connector *connector) @@ -1102,9 +1164,27 @@ static int repaper_probe(struct spi_device *spi) if (ret) return ret; - ret = drm_simple_display_pipe_init(drm, &epd->pipe, &repaper_pipe_funcs, - repaper_formats, ARRAY_SIZE(repaper_formats), - NULL, &epd->connector); + ret = drm_universal_plane_init(drm, &epd->plane, 0, + &repaper_plane_funcs, + repaper_formats, ARRAY_SIZE(repaper_formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + return ret; + drm_plane_helper_add(&epd->plane, &repaper_plane_helper_funcs); + + ret = drm_crtc_init_with_planes(drm, &epd->crtc, &epd->plane, NULL, + &repaper_crtc_funcs, NULL); + if (ret) + return ret; + drm_crtc_helper_add(&epd->crtc, &repaper_crtc_helper_funcs); + + ret = drm_encoder_init(drm, &epd->encoder, &repaper_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); + if (ret) + return ret; + epd->encoder.possible_crtcs = drm_crtc_mask(&epd->crtc); + + ret = drm_connector_attach_encoder(&epd->connector, &epd->encoder); if (ret) return ret; -- 2.55.0
