diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c')
| -rw-r--r-- | drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 157 |
1 files changed, 95 insertions, 62 deletions
diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c index 49bdabea8ed5..098c3b5ff2b2 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c @@ -7,6 +7,8 @@ #include <drm/drm_atomic.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_framebuffer.h> +#include <drm/drm_gem_atomic_helper.h> #include "mdp4_kms.h" @@ -18,12 +20,6 @@ struct mdp4_plane { const char *name; enum mdp4_pipe pipe; - - uint32_t caps; - uint32_t nformats; - uint32_t formats[32]; - - bool enabled; }; #define to_mdp4_plane(x) container_of(x, struct mdp4_plane, base) @@ -57,15 +53,6 @@ static struct mdp4_kms *get_kms(struct drm_plane *plane) return to_mdp4_kms(to_mdp_kms(priv->kms)); } -static void mdp4_plane_destroy(struct drm_plane *plane) -{ - struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); - - drm_plane_cleanup(plane); - - kfree(mdp4_plane); -} - /* helper to install properties which are common to planes and crtcs */ static void mdp4_plane_install_properties(struct drm_plane *plane, struct drm_mode_object *obj) @@ -83,26 +70,34 @@ static int mdp4_plane_set_property(struct drm_plane *plane, static const struct drm_plane_funcs mdp4_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .destroy = mdp4_plane_destroy, .set_property = mdp4_plane_set_property, .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; +static int mdp4_plane_prepare_fb(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + if (!new_state->fb) + return 0; + + drm_gem_plane_helper_prepare_fb(plane, new_state); + + return msm_framebuffer_prepare(new_state->fb, false); +} + static void mdp4_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); - struct mdp4_kms *mdp4_kms = get_kms(plane); - struct msm_kms *kms = &mdp4_kms->base.base; struct drm_framebuffer *fb = old_state->fb; if (!fb) return; DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id); - msm_framebuffer_cleanup(fb, kms->aspace); + msm_framebuffer_cleanup(fb, false); } @@ -130,7 +125,7 @@ static void mdp4_plane_atomic_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = { - .prepare_fb = msm_atomic_prepare_fb, + .prepare_fb = mdp4_plane_prepare_fb, .cleanup_fb = mdp4_plane_cleanup_fb, .atomic_check = mdp4_plane_atomic_check, .atomic_update = mdp4_plane_atomic_update, @@ -141,7 +136,6 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, { struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); - struct msm_kms *kms = &mdp4_kms->base.base; enum mdp4_pipe pipe = mdp4_plane->pipe; mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), @@ -153,13 +147,13 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), - msm_framebuffer_iova(fb, kms->aspace, 0)); + msm_framebuffer_iova(fb, 0)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe), - msm_framebuffer_iova(fb, kms->aspace, 1)); + msm_framebuffer_iova(fb, 1)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe), - msm_framebuffer_iova(fb, kms->aspace, 2)); + msm_framebuffer_iova(fb, 2)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe), - msm_framebuffer_iova(fb, kms->aspace, 3)); + msm_framebuffer_iova(fb, 3)); } static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms, @@ -202,7 +196,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); struct mdp4_kms *mdp4_kms = get_kms(plane); enum mdp4_pipe pipe = mdp4_plane->pipe; - const struct mdp_format *format; + const struct msm_format *format; uint32_t op_mode = 0; uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT; uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT; @@ -225,7 +219,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, fb->base.id, src_x, src_y, src_w, src_h, crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); - format = to_mdp_format(msm_framebuffer_format(fb)); + format = msm_framebuffer_format(fb); if (src_w > (crtc_w * DOWN_SCALE_MAX)) { DRM_DEV_ERROR(dev->dev, "Width down scaling exceeds limits!\n"); @@ -251,7 +245,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, uint32_t sel_unit = SCALE_FIR; op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN; - if (MDP_FORMAT_IS_YUV(format)) { + if (MSM_FORMAT_IS_YUV(format)) { if (crtc_w > src_w) sel_unit = SCALE_PIXEL_RPT; else if (crtc_w <= (src_w / 4)) @@ -267,7 +261,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, uint32_t sel_unit = SCALE_FIR; op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN; - if (MDP_FORMAT_IS_YUV(format)) { + if (MSM_FORMAT_IS_YUV(format)) { if (crtc_h > src_h) sel_unit = SCALE_PIXEL_RPT; @@ -300,24 +294,25 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe), MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | - MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | - MDP4_PIPE_SRC_FORMAT_G_BPC(format->bpc_g) | - MDP4_PIPE_SRC_FORMAT_B_BPC(format->bpc_b) | + MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r_cr) | + MDP4_PIPE_SRC_FORMAT_G_BPC(format->bpc_g_y) | + MDP4_PIPE_SRC_FORMAT_B_BPC(format->bpc_b_cb) | COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) | - MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | + MDP4_PIPE_SRC_FORMAT_CPP(format->bpp - 1) | MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) | MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) | MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT(frame_type) | - COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); + COND(format->flags & MSM_FORMAT_FLAG_UNPACK_TIGHT, + MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe), - MDP4_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) | - MDP4_PIPE_SRC_UNPACK_ELEM1(format->unpack[1]) | - MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) | - MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); + MDP4_PIPE_SRC_UNPACK_ELEM0(format->element[0]) | + MDP4_PIPE_SRC_UNPACK_ELEM1(format->element[1]) | + MDP4_PIPE_SRC_UNPACK_ELEM2(format->element[2]) | + MDP4_PIPE_SRC_UNPACK_ELEM3(format->element[3])); - if (MDP_FORMAT_IS_YUV(format)) { + if (MSM_FORMAT_IS_YUV(format)) { struct csc_cfg *csc = mdp_get_default_csc_cfg(CSC_YUV2RGB); op_mode |= MDP4_PIPE_OP_MODE_SRC_YCBCR; @@ -355,37 +350,81 @@ static const uint64_t supported_format_modifiers[] = { DRM_FORMAT_MOD_INVALID }; +static const uint32_t mdp4_rgb_formats[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, +}; + +static const uint32_t mdp4_rgb_yuv_formats[] = { + DRM_FORMAT_ARGB8888, + DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGBA8888, + DRM_FORMAT_BGRA8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_RGB888, + DRM_FORMAT_BGR888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV16, + DRM_FORMAT_NV61, + DRM_FORMAT_VYUY, + DRM_FORMAT_UYVY, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_YUV420, + DRM_FORMAT_YVU420, +}; + /* initialize plane */ struct drm_plane *mdp4_plane_init(struct drm_device *dev, enum mdp4_pipe pipe_id, bool private_plane) { struct drm_plane *plane = NULL; struct mdp4_plane *mdp4_plane; - int ret; enum drm_plane_type type; + uint32_t pipe_caps; + const uint32_t *formats; + size_t nformats; + + type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - mdp4_plane = kzalloc(sizeof(*mdp4_plane), GFP_KERNEL); - if (!mdp4_plane) { - ret = -ENOMEM; - goto fail; + pipe_caps = mdp4_pipe_caps(pipe_id); + if (pipe_supports_yuv(pipe_caps)) { + formats = mdp4_rgb_yuv_formats; + nformats = ARRAY_SIZE(mdp4_rgb_yuv_formats); + } else { + formats = mdp4_rgb_formats; + nformats = ARRAY_SIZE(mdp4_rgb_formats); } + mdp4_plane = drmm_universal_plane_alloc(dev, struct mdp4_plane, base, + 0xff, &mdp4_plane_funcs, + formats, nformats, + supported_format_modifiers, + type, NULL); + if (IS_ERR(mdp4_plane)) + return ERR_CAST(mdp4_plane); + plane = &mdp4_plane->base; mdp4_plane->pipe = pipe_id; mdp4_plane->name = pipe_names[pipe_id]; - mdp4_plane->caps = mdp4_pipe_caps(pipe_id); - - mdp4_plane->nformats = mdp_get_formats(mdp4_plane->formats, - ARRAY_SIZE(mdp4_plane->formats), - !pipe_supports_yuv(mdp4_plane->caps)); - - type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; - ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, - mdp4_plane->formats, mdp4_plane->nformats, - supported_format_modifiers, type, NULL); - if (ret) - goto fail; drm_plane_helper_add(plane, &mdp4_plane_helper_funcs); @@ -394,10 +433,4 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, drm_plane_enable_fb_damage_clips(plane); return plane; - -fail: - if (plane) - mdp4_plane_destroy(plane); - - return ERR_PTR(ret); } |
