2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-22 20:23:57 +08:00

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>
This commit is contained in:
james qian wang (Arm Technology China) 2019-05-23 12:10:27 +01:00 committed by Liviu Dudau
parent 1f7f9ab790
commit 42b6f118f6
5 changed files with 85 additions and 7 deletions

View File

@ -610,6 +610,7 @@ static void d71_scaler_update(struct komeda_component *c,
ctrl = 0; ctrl = 0;
ctrl |= st->en_scaling ? SC_CTRL_SCL : 0; ctrl |= st->en_scaling ? SC_CTRL_SCL : 0;
ctrl |= st->en_alpha ? SC_CTRL_AP : 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_CONTROL, ctrl);
malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0])); malidp_write32(reg, BLK_INPUT_ID0, to_d71_input_id(&state->inputs[0]));

View File

@ -32,6 +32,9 @@ struct komeda_plane {
* Layers with same capabilities. * Layers with same capabilities.
*/ */
struct komeda_layer *layer; 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 */ /** @base: &drm_plane_state */
struct drm_plane_state base; struct drm_plane_state base;
/* private properties */ /* @img_enhancement: on/off image enhancement */
u8 img_enhancement : 1;
}; };
/** /**

View File

@ -254,7 +254,8 @@ struct komeda_scaler_state {
u16 hsize_in, vsize_in; u16 hsize_in, vsize_in;
u16 hsize_out, vsize_out; u16 hsize_out, vsize_out;
u8 en_scaling : 1, u8 en_scaling : 1,
en_alpha : 1; /* enable alpha processing */ en_alpha : 1, /* enable alpha processing */
en_img_enhancement : 1;
}; };
struct komeda_compiz { struct komeda_compiz {
@ -313,7 +314,8 @@ struct komeda_data_flow_cfg {
u32 rot; u32 rot;
int blending_zorder; int blending_zorder;
u8 pixel_blend_mode, layer_alpha; u8 pixel_blend_mode, layer_alpha;
u8 en_scaling : 1; u8 en_scaling : 1,
en_img_enhancement : 1;
}; };
struct komeda_pipeline_funcs { struct komeda_pipeline_funcs {

View File

@ -457,7 +457,7 @@ komeda_scaler_validate(void *user,
struct komeda_scaler *scaler; struct komeda_scaler *scaler;
int err = 0; int err = 0;
if (!dflow->en_scaling) if (!(dflow->en_scaling || dflow->en_img_enhancement))
return 0; return 0;
scaler = komeda_component_get_avail_scaler(dflow->input.component, 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->vsize_in = dflow->in_h;
st->hsize_out = dflow->out_w; st->hsize_out = dflow->out_w;
st->vsize_out = dflow->out_h; st->vsize_out = dflow->out_h;
st->en_scaling = dflow->en_scaling;
/* Enable alpha processing if the next stage needs the pixel alpha */ /* 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_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_add_input(&st->base, &dflow->input, 0);
komeda_component_set_output(&dflow->input, &scaler->base, 0); komeda_component_set_output(&dflow->input, &scaler->base, 0);

View File

@ -15,6 +15,7 @@ static int
komeda_plane_init_data_flow(struct drm_plane_state *st, komeda_plane_init_data_flow(struct drm_plane_state *st,
struct komeda_data_flow_cfg *dflow) struct komeda_data_flow_cfg *dflow)
{ {
struct komeda_plane_state *kplane_st = to_kplane_st(st);
struct drm_framebuffer *fb = st->fb; struct drm_framebuffer *fb = st->fb;
memset(dflow, 0, sizeof(*dflow)); 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 */ /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */
dflow->pixel_blend_mode = fb->format->has_alpha ? 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->layer_alpha = st->alpha >> 8;
dflow->out_x = st->crtc_x; 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_w = st->src_w >> 16;
dflow->in_h = st->src_h >> 16; dflow->in_h = st->src_h >> 16;
dflow->en_img_enhancement = kplane_st->img_enhancement;
komeda_complete_data_flow_cfg(dflow); komeda_complete_data_flow_cfg(dflow);
return 0; return 0;
@ -131,7 +134,7 @@ static void komeda_plane_reset(struct drm_plane *plane)
static struct drm_plane_state * static struct drm_plane_state *
komeda_plane_atomic_duplicate_state(struct drm_plane *plane) 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)) if (WARN_ON(!plane->state))
return NULL; return NULL;
@ -142,6 +145,10 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
__drm_atomic_helper_plane_duplicate_state(plane, &new->base); __drm_atomic_helper_plane_duplicate_state(plane, &new->base);
old = to_kplane_st(plane->state);
new->img_enhancement = old->img_enhancement;
return &new->base; return &new->base;
} }
@ -153,6 +160,40 @@ komeda_plane_atomic_destroy_state(struct drm_plane *plane,
kfree(to_kplane_st(state)); 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 static bool
komeda_plane_format_mod_supported(struct drm_plane *plane, komeda_plane_format_mod_supported(struct drm_plane *plane,
u32 format, u64 modifier) u32 format, u64 modifier)
@ -172,9 +213,33 @@ static const struct drm_plane_funcs komeda_plane_funcs = {
.reset = komeda_plane_reset, .reset = komeda_plane_reset,
.atomic_duplicate_state = komeda_plane_atomic_duplicate_state, .atomic_duplicate_state = komeda_plane_atomic_duplicate_state,
.atomic_destroy_state = komeda_plane_atomic_destroy_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, .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 */ /* for komeda, which is pipeline can be share between crtcs */
static u32 get_possible_crtcs(struct komeda_kms_dev *kms, static u32 get_possible_crtcs(struct komeda_kms_dev *kms,
struct komeda_pipeline *pipe) 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); drm_plane_helper_add(plane, &komeda_plane_helper_funcs);
err = komeda_plane_create_layer_properties(kplane, layer);
if (err)
goto cleanup;
return 0; return 0;
cleanup: cleanup:
komeda_plane_destroy(plane); komeda_plane_destroy(plane);