drm/komeda: Add image enhancement support
authorjames qian wang (Arm Technology China) <james.qian.wang@arm.com>
Thu, 23 May 2019 11:10:27 +0000 (12:10 +0100)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Wed, 19 Jun 2019 10:42:16 +0000 (11:42 +0100)
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>
drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
drivers/gpu/drm/arm/display/komeda/komeda_kms.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
drivers/gpu/drm/arm/display/komeda/komeda_plane.c

index 2ea282c..1f7a5d5 100644 (file)
@@ -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]));
index db59a90..e6e059f 100644 (file)
@@ -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;
 };
 
 /**
index d0bf7d5..0e334f1 100644 (file)
@@ -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 {
index 01544c2..db34ea2 100644 (file)
@@ -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);
index d4f14ec..94268f4 100644 (file)
@@ -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);