diff options
author | james qian wang (Arm Technology China) <james.qian.wang@arm.com> | 2019-05-23 12:10:27 +0100 |
---|---|---|
committer | Liviu Dudau <Liviu.Dudau@arm.com> | 2019-06-19 11:42:16 +0100 |
commit | 42b6f118f6d11268d652ce4946fef25a2611c39d (patch) | |
tree | 604caff6e250c6ed5e5781aadc5ad75e28f76daf /drivers/gpu/drm/arm | |
parent | 1f7f9ab7900ec92c0beac0660cdce37d6af02d38 (diff) | |
download | linux-42b6f118f6d11268d652ce4946fef25a2611c39d.tar.bz2 |
drm/komeda: Add image enhancement support
Besides scaling, Arm display scaler also can support image enhancement.
For support it, Add a new property "img_enhancement" to plane, then user
can turn on/off it by this property, and kernel follow user's requirement
to maitain the state and enable/disable the real HW image enhancement.
v2: Rebase and rename "needs_img_enhancement" to "en_img_enhancement"
Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Diffstat (limited to 'drivers/gpu/drm/arm')
5 files changed, 85 insertions, 7 deletions
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c index 2ea282c6a156..1f7a5d572b1a 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c @@ -610,6 +610,7 @@ static void d71_scaler_update(struct komeda_component *c, ctrl = 0; ctrl |= st->en_scaling ? SC_CTRL_SCL : 0; ctrl |= st->en_alpha ? SC_CTRL_AP : 0; + ctrl |= st->en_img_enhancement ? SC_CTRL_IENH : 0; malidp_write32(reg, BLK_CONTROL, ctrl); malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0])); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index db59a9042beb..e6e059f2af52 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -32,6 +32,9 @@ struct komeda_plane { * Layers with same capabilities. */ struct komeda_layer *layer; + + /** @prop_img_enhancement: for on/off image enhancement */ + struct drm_property *prop_img_enhancement; }; /** @@ -44,7 +47,8 @@ struct komeda_plane_state { /** @base: &drm_plane_state */ struct drm_plane_state base; - /* private properties */ + /* @img_enhancement: on/off image enhancement */ + u8 img_enhancement : 1; }; /** diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index d0bf7d5b39a7..0e334f1cf18b 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -254,7 +254,8 @@ struct komeda_scaler_state { u16 hsize_in, vsize_in; u16 hsize_out, vsize_out; u8 en_scaling : 1, - en_alpha : 1; /* enable alpha processing */ + en_alpha : 1, /* enable alpha processing */ + en_img_enhancement : 1; }; struct komeda_compiz { @@ -313,7 +314,8 @@ struct komeda_data_flow_cfg { u32 rot; int blending_zorder; u8 pixel_blend_mode, layer_alpha; - u8 en_scaling : 1; + u8 en_scaling : 1, + en_img_enhancement : 1; }; struct komeda_pipeline_funcs { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 01544c274848..db34ea26760c 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -457,7 +457,7 @@ komeda_scaler_validate(void *user, struct komeda_scaler *scaler; int err = 0; - if (!dflow->en_scaling) + if (!(dflow->en_scaling || dflow->en_img_enhancement)) return 0; scaler = komeda_component_get_avail_scaler(dflow->input.component, @@ -482,9 +482,11 @@ komeda_scaler_validate(void *user, st->vsize_in = dflow->in_h; st->hsize_out = dflow->out_w; st->vsize_out = dflow->out_h; - st->en_scaling = dflow->en_scaling; + /* Enable alpha processing if the next stage needs the pixel alpha */ st->en_alpha = dflow->pixel_blend_mode != DRM_MODE_BLEND_PIXEL_NONE; + st->en_scaling = dflow->en_scaling; + st->en_img_enhancement = dflow->en_img_enhancement; komeda_component_add_input(&st->base, &dflow->input, 0); komeda_component_set_output(&dflow->input, &scaler->base, 0); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index d4f14ecf6e2a..94268f49e83e 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -15,6 +15,7 @@ static int komeda_plane_init_data_flow(struct drm_plane_state *st, struct komeda_data_flow_cfg *dflow) { + struct komeda_plane_state *kplane_st = to_kplane_st(st); struct drm_framebuffer *fb = st->fb; memset(dflow, 0, sizeof(*dflow)); @@ -23,7 +24,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st, /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */ dflow->pixel_blend_mode = fb->format->has_alpha ? - st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE; + st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE; dflow->layer_alpha = st->alpha >> 8; dflow->out_x = st->crtc_x; @@ -36,6 +37,8 @@ komeda_plane_init_data_flow(struct drm_plane_state *st, dflow->in_w = st->src_w >> 16; dflow->in_h = st->src_h >> 16; + dflow->en_img_enhancement = kplane_st->img_enhancement; + komeda_complete_data_flow_cfg(dflow); return 0; @@ -131,7 +134,7 @@ static void komeda_plane_reset(struct drm_plane *plane) static struct drm_plane_state * komeda_plane_atomic_duplicate_state(struct drm_plane *plane) { - struct komeda_plane_state *new; + struct komeda_plane_state *new, *old; if (WARN_ON(!plane->state)) return NULL; @@ -142,6 +145,10 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane) __drm_atomic_helper_plane_duplicate_state(plane, &new->base); + old = to_kplane_st(plane->state); + + new->img_enhancement = old->img_enhancement; + return &new->base; } @@ -153,6 +160,40 @@ komeda_plane_atomic_destroy_state(struct drm_plane *plane, kfree(to_kplane_st(state)); } +static int +komeda_plane_atomic_get_property(struct drm_plane *plane, + const struct drm_plane_state *state, + struct drm_property *property, + uint64_t *val) +{ + struct komeda_plane *kplane = to_kplane(plane); + struct komeda_plane_state *st = to_kplane_st(state); + + if (property == kplane->prop_img_enhancement) + *val = st->img_enhancement; + else + return -EINVAL; + + return 0; +} + +static int +komeda_plane_atomic_set_property(struct drm_plane *plane, + struct drm_plane_state *state, + struct drm_property *property, + uint64_t val) +{ + struct komeda_plane *kplane = to_kplane(plane); + struct komeda_plane_state *st = to_kplane_st(state); + + if (property == kplane->prop_img_enhancement) + st->img_enhancement = !!val; + else + return -EINVAL; + + return 0; +} + static bool komeda_plane_format_mod_supported(struct drm_plane *plane, u32 format, u64 modifier) @@ -172,9 +213,33 @@ static const struct drm_plane_funcs komeda_plane_funcs = { .reset = komeda_plane_reset, .atomic_duplicate_state = komeda_plane_atomic_duplicate_state, .atomic_destroy_state = komeda_plane_atomic_destroy_state, + .atomic_get_property = komeda_plane_atomic_get_property, + .atomic_set_property = komeda_plane_atomic_set_property, .format_mod_supported = komeda_plane_format_mod_supported, }; +static int +komeda_plane_create_layer_properties(struct komeda_plane *kplane, + struct komeda_layer *layer) +{ + struct drm_device *drm = kplane->base.dev; + struct drm_plane *plane = &kplane->base; + struct drm_property *prop = NULL; + + /* property: layer image_enhancement */ + if (layer->base.supported_outputs & KOMEDA_PIPELINE_SCALERS) { + prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC, + "img_enhancement"); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&plane->base, prop, 0); + kplane->prop_img_enhancement = prop; + } + + return 0; +} + /* for komeda, which is pipeline can be share between crtcs */ static u32 get_possible_crtcs(struct komeda_kms_dev *kms, struct komeda_pipeline *pipe) @@ -236,6 +301,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms, drm_plane_helper_add(plane, &komeda_plane_helper_funcs); + err = komeda_plane_create_layer_properties(kplane, layer); + if (err) + goto cleanup; + return 0; cleanup: komeda_plane_destroy(plane); |