OSDN Git Service

drm/komeda: Add writeback scaling support
authorjames qian wang (Arm Technology China) <james.qian.wang@arm.com>
Thu, 23 May 2019 11:10:15 +0000 (12:10 +0100)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Wed, 19 Jun 2019 10:42:16 +0000 (11:42 +0100)
1. Add scaler to writeback pipeline to enable the writeback scaling support
2. Display HW can not do upscaling for writeback, check it when validate.

v2: Rebase

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/komeda_pipeline.h
drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
drivers/gpu/drm/arm/display/komeda/komeda_plane.c
drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c

index 400af21..9ffe11c 100644 (file)
@@ -470,4 +470,6 @@ void komeda_pipeline_disable(struct komeda_pipeline *pipe,
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
                            struct drm_atomic_state *old_state);
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
index a5300ef..9f07ef6 100644 (file)
@@ -390,6 +390,7 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
                        struct komeda_data_flow_cfg *dflow)
 {
        u32 hsize_in, vsize_in, hsize_out, vsize_out;
+       u32 max_upscaling;
 
        hsize_in = dflow->in_w;
        vsize_in = dflow->in_h;
@@ -408,13 +409,21 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler,
                return -EINVAL;
        }
 
-       if (!scaling_ratio_valid(hsize_in, hsize_out, scaler->max_upscaling,
+       /* If input comes from compiz that means the scaling is for writeback
+        * and scaler can not do upscaling for writeback
+        */
+       if (has_bit(dflow->input.component->id, KOMEDA_PIPELINE_COMPIZS))
+               max_upscaling = 1;
+       else
+               max_upscaling = scaler->max_upscaling;
+
+       if (!scaling_ratio_valid(hsize_in, hsize_out, max_upscaling,
                                 scaler->max_downscaling)) {
                DRM_DEBUG_ATOMIC("Invalid horizontal scaling ratio");
                return -EINVAL;
        }
 
-       if (!scaling_ratio_valid(vsize_in, vsize_out, scaler->max_upscaling,
+       if (!scaling_ratio_valid(vsize_in, vsize_out, max_upscaling,
                                 scaler->max_downscaling)) {
                DRM_DEBUG_ATOMIC("Invalid vertical scaling ratio");
                return -EINVAL;
@@ -614,6 +623,17 @@ komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr,
        return 0;
 }
 
+void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow)
+{
+       u32 w = dflow->in_w;
+       u32 h = dflow->in_h;
+
+       if (drm_rotation_90_or_270(dflow->rot))
+               swap(w, h);
+
+       dflow->en_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+}
+
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
                                 struct komeda_plane_state *kplane_st,
                                 struct komeda_crtc_state *kcrtc_st,
@@ -641,16 +661,18 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
        return err;
 }
 
+/* writeback data path: compiz -> scaler -> wb_layer -> memory */
 int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
                              struct drm_connector_state *conn_st,
                              struct komeda_crtc_state *kcrtc_st,
                              struct komeda_data_flow_cfg *dflow)
 {
-       if ((dflow->in_w != dflow->out_w) ||
-           (dflow->in_h != dflow->out_h)) {
-               DRM_DEBUG_ATOMIC("current do not support scaling writeback.\n");
-               return -EINVAL;
-       }
+       struct drm_connector *conn = conn_st->connector;
+       int err;
+
+       err = komeda_scaler_validate(conn, kcrtc_st, dflow);
+       if (err)
+               return err;
 
        return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
index d536c28..d4f14ec 100644 (file)
@@ -16,7 +16,6 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
                            struct komeda_data_flow_cfg *dflow)
 {
        struct drm_framebuffer *fb = st->fb;
-       u32 w, h;
 
        memset(dflow, 0, sizeof(*dflow));
 
@@ -37,12 +36,7 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
        dflow->in_w = st->src_w >> 16;
        dflow->in_h = st->src_h >> 16;
 
-       w = dflow->in_w;
-       h = dflow->in_h;
-       if (drm_rotation_90_or_270(dflow->rot))
-               swap(w, h);
-
-       dflow->en_scaling = (w != dflow->out_w) || (h != dflow->out_h);
+       komeda_complete_data_flow_cfg(dflow);
 
        return 0;
 }
index 0c1a422..eed5212 100644 (file)
@@ -31,6 +31,8 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
        dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
        dflow->rot = DRM_MODE_ROTATE_0;
 
+       komeda_complete_data_flow_cfg(dflow);
+
        return 0;
 }