Skip to content

Commit

Permalink
drm/sti: implement atomic_check for the planes
Browse files Browse the repository at this point in the history
Atomic update should never fail. Thus all checks must be done in
the atomic_check function for each plane (gdp, hqvdp and cursor).

Signed-off-by: Vincent Abriou <vincent.abriou@st.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
  • Loading branch information
Vincent Abriou committed Feb 26, 2016
1 parent 0b9d041 commit dd86dc2
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 168 deletions.
90 changes: 58 additions & 32 deletions drivers/gpu/drm/sti/sti_cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
* for STMicroelectronics.
* License terms: GNU General Public License (GPL), version 2
*/
#include <drm/drmP.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>

#include "sti_compositor.h"
#include "sti_cursor.h"
Expand Down Expand Up @@ -110,42 +108,39 @@ static void sti_cursor_init(struct sti_cursor *cursor)
(b * 5);
}

static void sti_cursor_atomic_update(struct drm_plane *drm_plane,
struct drm_plane_state *oldstate)
static int sti_cursor_atomic_check(struct drm_plane *drm_plane,
struct drm_plane_state *state)
{
struct drm_plane_state *state = drm_plane->state;
struct sti_plane *plane = to_sti_plane(drm_plane);
struct sti_cursor *cursor = to_sti_cursor(plane);
struct drm_crtc *crtc = state->crtc;
struct sti_mixer *mixer = to_sti_mixer(crtc);
struct drm_framebuffer *fb = state->fb;
struct drm_display_mode *mode = &crtc->mode;
int dst_x = state->crtc_x;
int dst_y = state->crtc_y;
int dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
int dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
struct drm_crtc_state *crtc_state;
struct drm_display_mode *mode;
int dst_x, dst_y, dst_w, dst_h;
int src_w, src_h;

/* no need for further checks if the plane is being disabled */
if (!crtc || !fb)
return 0;

crtc_state = drm_atomic_get_crtc_state(state->state, crtc);
mode = &crtc_state->mode;
dst_x = state->crtc_x;
dst_y = state->crtc_y;
dst_w = clamp_val(state->crtc_w, 0, mode->crtc_hdisplay - dst_x);
dst_h = clamp_val(state->crtc_h, 0, mode->crtc_vdisplay - dst_y);
/* src_x are in 16.16 format */
int src_w = state->src_w >> 16;
int src_h = state->src_h >> 16;
struct drm_gem_cma_object *cma_obj;
u32 y, x;
u32 val;

DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n",
crtc->base.id, sti_mixer_to_str(mixer),
drm_plane->base.id, sti_plane_to_str(plane));
DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", dst_w, dst_h, dst_x, dst_y);

dev_dbg(cursor->dev, "%s %s\n", __func__,
sti_plane_to_str(plane));
src_w = state->src_w >> 16;
src_h = state->src_h >> 16;

if (src_w < STI_CURS_MIN_SIZE ||
src_h < STI_CURS_MIN_SIZE ||
src_w > STI_CURS_MAX_SIZE ||
src_h > STI_CURS_MAX_SIZE) {
DRM_ERROR("Invalid cursor size (%dx%d)\n",
src_w, src_h);
return;
return -EINVAL;
}

/* If the cursor size has changed, re-allocated the pixmap */
Expand All @@ -169,16 +164,46 @@ static void sti_cursor_atomic_update(struct drm_plane *drm_plane,
GFP_KERNEL | GFP_DMA);
if (!cursor->pixmap.base) {
DRM_ERROR("Failed to allocate memory for pixmap\n");
return;
return -EINVAL;
}
}

cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
if (!cma_obj) {
if (!drm_fb_cma_get_gem_obj(fb, 0)) {
DRM_ERROR("Can't get CMA GEM object for fb\n");
return;
return -EINVAL;
}

DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n",
crtc->base.id, sti_mixer_to_str(to_sti_mixer(crtc)),
drm_plane->base.id, sti_plane_to_str(plane));
DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", dst_w, dst_h, dst_x, dst_y);

return 0;
}

static void sti_cursor_atomic_update(struct drm_plane *drm_plane,
struct drm_plane_state *oldstate)
{
struct drm_plane_state *state = drm_plane->state;
struct sti_plane *plane = to_sti_plane(drm_plane);
struct sti_cursor *cursor = to_sti_cursor(plane);
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
struct drm_display_mode *mode;
int dst_x, dst_y;
struct drm_gem_cma_object *cma_obj;
u32 y, x;
u32 val;

if (!crtc || !fb)
return;

mode = &crtc->mode;
dst_x = state->crtc_x;
dst_y = state->crtc_y;

cma_obj = drm_fb_cma_get_gem_obj(fb, 0);

/* Convert ARGB8888 to CLUT8 */
sti_cursor_argb8888_to_clut8(cursor, (u32 *)cma_obj->vaddr);

Expand Down Expand Up @@ -212,7 +237,6 @@ static void sti_cursor_atomic_disable(struct drm_plane *drm_plane,
struct drm_plane_state *oldstate)
{
struct sti_plane *plane = to_sti_plane(drm_plane);
struct sti_mixer *mixer = to_sti_mixer(drm_plane->crtc);

if (!drm_plane->crtc) {
DRM_DEBUG_DRIVER("drm plane:%d not enabled\n",
Expand All @@ -221,13 +245,15 @@ static void sti_cursor_atomic_disable(struct drm_plane *drm_plane,
}

DRM_DEBUG_DRIVER("CRTC:%d (%s) drm plane:%d (%s)\n",
drm_plane->crtc->base.id, sti_mixer_to_str(mixer),
drm_plane->crtc->base.id,
sti_mixer_to_str(to_sti_mixer(drm_plane->crtc)),
drm_plane->base.id, sti_plane_to_str(plane));

plane->status = STI_PLANE_DISABLING;
}

static const struct drm_plane_helper_funcs sti_cursor_helpers_funcs = {
.atomic_check = sti_cursor_atomic_check,
.atomic_update = sti_cursor_atomic_update,
.atomic_disable = sti_cursor_atomic_disable,
};
Expand Down
Loading

0 comments on commit dd86dc2

Please sign in to comment.