drm: mali-dp: Add plane upscaling support
Enable the scaling engine for upscaling a single plane using the polyphase scaler. No image enhancement support or downscaling yet*, and composition result scaling is not implemented. * Downscaling a plane requires mclk > pxlclk. Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
This commit is contained in:

committed by
Liviu Dudau

parent
50c7512fd7
commit
28ce675b74
@@ -25,6 +25,9 @@
|
||||
#define MALIDP_LAYER_FORMAT 0x000
|
||||
#define MALIDP_LAYER_CONTROL 0x004
|
||||
#define LAYER_ENABLE (1 << 0)
|
||||
#define LAYER_FLOWCFG_MASK 7
|
||||
#define LAYER_FLOWCFG(x) (((x) & LAYER_FLOWCFG_MASK) << 1)
|
||||
#define LAYER_FLOWCFG_SCALE_SE 3
|
||||
#define LAYER_ROT_OFFSET 8
|
||||
#define LAYER_H_FLIP (1 << 10)
|
||||
#define LAYER_V_FLIP (1 << 11)
|
||||
@@ -133,16 +136,50 @@ static const struct drm_plane_funcs malidp_de_plane_funcs = {
|
||||
.atomic_print_state = malidp_plane_atomic_print_state,
|
||||
};
|
||||
|
||||
static int malidp_se_check_scaling(struct malidp_plane *mp,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
struct drm_crtc_state *crtc_state =
|
||||
drm_atomic_get_existing_crtc_state(state->state, state->crtc);
|
||||
struct malidp_crtc_state *mc;
|
||||
struct drm_rect clip = { 0 };
|
||||
u32 src_w, src_h;
|
||||
int ret;
|
||||
|
||||
if (!crtc_state)
|
||||
return -EINVAL;
|
||||
|
||||
clip.x2 = crtc_state->adjusted_mode.hdisplay;
|
||||
clip.y2 = crtc_state->adjusted_mode.vdisplay;
|
||||
ret = drm_plane_helper_check_state(state, &clip, 0, INT_MAX, true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
src_w = state->src_w >> 16;
|
||||
src_h = state->src_h >> 16;
|
||||
if ((state->crtc_w == src_w) && (state->crtc_h == src_h)) {
|
||||
/* Scaling not necessary for this plane. */
|
||||
mc->scaled_planes_mask &= ~(mp->layer->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mp->layer->id & (DE_SMART | DE_GRAPHICS2))
|
||||
return -EINVAL;
|
||||
|
||||
mc = to_malidp_crtc_state(crtc_state);
|
||||
|
||||
mc->scaled_planes_mask |= mp->layer->id;
|
||||
/* Defer scaling requirements calculation to the crtc check. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int malidp_de_plane_check(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
struct malidp_plane *mp = to_malidp_plane(plane);
|
||||
struct malidp_plane_state *ms = to_malidp_plane_state(state);
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_rect clip = { 0 };
|
||||
int i, ret;
|
||||
u32 src_w, src_h;
|
||||
|
||||
if (!state->crtc || !state->fb)
|
||||
return 0;
|
||||
@@ -163,9 +200,6 @@ static int malidp_de_plane_check(struct drm_plane *plane,
|
||||
}
|
||||
}
|
||||
|
||||
src_w = state->src_w >> 16;
|
||||
src_h = state->src_h >> 16;
|
||||
|
||||
if ((state->crtc_w > mp->hwdev->max_line_size) ||
|
||||
(state->crtc_h > mp->hwdev->max_line_size) ||
|
||||
(state->crtc_w < mp->hwdev->min_line_size) ||
|
||||
@@ -182,22 +216,16 @@ static int malidp_de_plane_check(struct drm_plane *plane,
|
||||
(state->fb->pitches[1] != state->fb->pitches[2]))
|
||||
return -EINVAL;
|
||||
|
||||
ret = malidp_se_check_scaling(mp, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* packed RGB888 / BGR888 can't be rotated or flipped */
|
||||
if (state->rotation != DRM_ROTATE_0 &&
|
||||
(fb->format->format == DRM_FORMAT_RGB888 ||
|
||||
fb->format->format == DRM_FORMAT_BGR888))
|
||||
return -EINVAL;
|
||||
|
||||
crtc_state = drm_atomic_get_existing_crtc_state(state->state, state->crtc);
|
||||
clip.x2 = crtc_state->adjusted_mode.hdisplay;
|
||||
clip.y2 = crtc_state->adjusted_mode.vdisplay;
|
||||
ret = drm_plane_helper_check_state(state, &clip,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
true, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ms->rotmem_size = 0;
|
||||
if (state->rotation & MALIDP_ROTATED_MASK) {
|
||||
int val;
|
||||
@@ -302,6 +330,16 @@ static void malidp_de_plane_update(struct drm_plane *plane,
|
||||
val &= ~LAYER_COMP_MASK;
|
||||
val |= LAYER_COMP_PIXEL;
|
||||
|
||||
val &= ~LAYER_FLOWCFG(LAYER_FLOWCFG_MASK);
|
||||
if (plane->state->crtc) {
|
||||
struct malidp_crtc_state *m =
|
||||
to_malidp_crtc_state(plane->state->crtc->state);
|
||||
|
||||
if (m->scaler_config.scale_enable &&
|
||||
m->scaler_config.plane_src_id == mp->layer->id)
|
||||
val |= LAYER_FLOWCFG(LAYER_FLOWCFG_SCALE_SE);
|
||||
}
|
||||
|
||||
/* set the 'enable layer' bit */
|
||||
val |= LAYER_ENABLE;
|
||||
|
||||
@@ -314,7 +352,8 @@ static void malidp_de_plane_disable(struct drm_plane *plane,
|
||||
{
|
||||
struct malidp_plane *mp = to_malidp_plane(plane);
|
||||
|
||||
malidp_hw_clearbits(mp->hwdev, LAYER_ENABLE,
|
||||
malidp_hw_clearbits(mp->hwdev,
|
||||
LAYER_ENABLE | LAYER_FLOWCFG(LAYER_FLOWCFG_MASK),
|
||||
mp->layer->base + MALIDP_LAYER_CONTROL);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user