Revert "[COMMON] g2d: fix formula based on measured value"
authorhyesoo.yu <hyesoo.yu@samsung.com>
Thu, 24 Aug 2017 01:22:22 +0000 (10:22 +0900)
committerSeungchul Kim <sc377.kim@samsung.com>
Mon, 28 May 2018 05:27:39 +0000 (14:27 +0900)
This reverts commit 8b6985f10269521f49d54bcf17ee731cca671dd3.

Change-Id: I56b70b99e2e94378c9014dc3aad623fb769f46ad
Signed-off-by: hyesoo.yu <hyesoo.yu@samsung.com>
drivers/gpu/exynos/g2d/g2d.h
drivers/gpu/exynos/g2d/g2d_drv.c
drivers/gpu/exynos/g2d/g2d_perf.c
drivers/gpu/exynos/g2d/g2d_perf.h
drivers/gpu/exynos/g2d/g2d_uapi.h

index 50bf4b2db70fce21dc950887952c0e2074194693..77bb8903e8ea828f8748b350d67151fc186f1007 100644 (file)
@@ -47,32 +47,20 @@ enum g2d_priority {
 #define G2D_DEVICE_STATE_SUSPEND       1
 #define G2D_DEVICE_STATE_IOVMM_DISABLED        2
 
-enum g2d_hw_ppc_rot {
-       PPC_NO_ROTATE,
-       PPC_ROTATE,
-       PPC_ROT,
-};
-
-enum g2d_hw_ppc_fmt {
-       PPC_RGB,
-       PPC_YUV2P,
-       PPC_YUV2P_82,
-       PPC_FMT,
-};
-
-enum g2d_hw_ppc_sc {
-       PPC_NO_SCALE,
-       PPC_SC_UP,
-       PPC_SC_DOWN_1,
-       PPC_SC_DOWN_4,
-       PPC_SC_DOWN_9,
-       PPC_SC_DOWN_16,
-       PPC_SC,
-};
-
 enum g2d_hw_ppc {
-       PPC_COLORFILL = PPC_FMT * PPC_ROT * PPC_SC,
-       PPC_END,
+       G2D_PPC_DEFAULT,
+       G2D_PPC_SCALE,
+       G2D_PPC_ROTATE,
+       G2D_PPC_SCALE_ROTATE,
+       G2D_PPC_YUV2P,
+       G2D_PPC_YUV2P_SCALE,
+       G2D_PPC_YUV2P_ROTATE,
+       G2D_PPC_YUV2P_SCALE_ROTATE,
+       G2D_PPC_COLORFILL,
+       G2D_PPC_DST_DEFAULT,
+       G2D_PPC_DST_YUV2P,
+       G2D_PPC_DST_ROT,
+       G2D_PPC_END,
 };
 
 struct g2d_dvfs_table {
@@ -112,7 +100,7 @@ struct g2d_device {
 
        struct mutex                    lock_qos;
        struct list_head                qos_contexts;
-       u32 hw_ppc[PPC_END];
+       u32 hw_ppc[G2D_PPC_END];
 
        struct g2d_dvfs_table *dvfs_table;
        u32 dvfs_table_cnt;
index 5ef0fabb52096e037f29ba5655d78b93dcc00941..eb93763c6b6eb70a9ba90841d942718713206c50 100644 (file)
@@ -667,16 +667,10 @@ static int g2d_notifier_event(struct notifier_block *this,
        return NOTIFY_OK;
 }
 
-static unsigned int g2d_default_ppc[] = {
-       /* none sc_up x1 x1/4 x1/9 x1/16 */
-       3100, 3400, 2200, 3600, 5100, 7000, //rgb32 non-rotated
-       2700, 3300, 2000, 3000, 5200, 6500, //rgb32 rotated
-       2900, 3000, 2600, 3400, 5100, 11900, //yuv2p non-rotated
-       2000, 3200, 1900, 3300, 5200, 7000, //yuv2p rotated
-       1900, 2400, 1900, 2700, 3100, 4100, //8+2 non-rotated
-       900, 2500, 900, 2200, 2900, 3700, //8+2 rotated
-       3800, //colorfill
-};
+static unsigned int g2d_default_ppc[G2D_PPC_END] =
+       {3500, 3200, 3500, 3000,
+       3500, 3100, 3000, 2800,
+       3800, 3500, 2800, 2500};
 
 static struct g2d_dvfs_table g2d_default_dvfs_table[] = {
        {534000, 711000},
@@ -690,14 +684,15 @@ static struct g2d_dvfs_table g2d_default_dvfs_table[] = {
 static int g2d_parse_dt(struct g2d_device *g2d_dev)
 {
        struct device *dev = g2d_dev->dev;
-       int len;
+       int i, len;
 
        if (of_property_read_u32_array(dev->of_node, "hw_ppc",
-                       (u32 *)g2d_dev->hw_ppc, PPC_END)) {
+                       (u32 *)g2d_dev->hw_ppc,
+                       (size_t)(ARRAY_SIZE(g2d_dev->hw_ppc)))) {
                dev_err(dev, "Failed to parse device tree for hw ppc");
 
-               memcpy(g2d_dev->hw_ppc, g2d_default_ppc,
-                       sizeof(g2d_default_ppc[0]) * PPC_END);
+               for (i = 0; i < G2D_PPC_END; i++)
+                       g2d_dev->hw_ppc[i] = g2d_default_ppc[i];
        }
 
        len = of_property_count_u32_elems(dev->of_node, "g2d_dvfs_table");
index 1d409afb893411536b67311948e4265b40e906db..0f9183d7a39dd25dfe99a3e88086c48b66463a5b 100644 (file)
@@ -59,82 +59,109 @@ static bool g2d_still_need_perf(struct g2d_device *g2d_dev)
        return false;
 }
 
-static inline char perf_index_sc(struct g2d_performance_layer_data *layer)
-{
-       u32 basis = 1000;
-       u32 ratio = ((u64)layer->window_width *
-               layer->window_height * basis) /
-               (layer->crop_width * layer->crop_height);
-       int i;
-
-       if (ratio == basis)
-               return PPC_NO_SCALE;
-
-       if (ratio > basis)
-               return PPC_SC_UP;
-
-       for (i = PPC_SC_DOWN_1; i < PPC_SC_DOWN_16; i++) {
-               if (ratio > basis / i / i)
-                       return i;
-       }
-
-       return PPC_SC_DOWN_16;
-}
-
 static void g2d_set_device_frequency(struct g2d_context *g2d_ctx,
                                          struct g2d_performance_data *data)
 {
        struct g2d_device *g2d_dev = g2d_ctx->g2d_dev;
        struct g2d_performance_frame_data *frame;
-       struct g2d_performance_layer_data *layer;
-       u32 (*ppc)[PPC_SC] = (u32 (*)[PPC_SC])g2d_dev->hw_ppc;
-       unsigned int cycle, ip_clock, crop, window;
+       struct g2d_performance_layer_data *layer, *pair;
+       unsigned int cycle, cycle_src, cycle_dst, ip_clock;
+       unsigned int rot_size, no_rot_size;
+       unsigned int dst_ppc, ppc[G2D_MAX_IMAGES];
        int i, j;
-       int sc, fmt, rot;
+       char sc, yuv2p, rot, rot_skip, gap;
 
        cycle = 0;
+       gap = false;
 
        for (i = 0; i < data->num_frame; i++) {
                frame = &data->frame[i];
 
+               rot_size = 0;
+               no_rot_size = 0;
+               cycle_src = 0;
+
+               /*
+                * The rotate variable means that the rotated layers and
+                * non-rotated layers are mixed.
+                * If all layers are rotated or are non rotated, that is
+                * excluded.
+                */
                rot = 0;
                for (j = 0; j < frame->num_layers; j++) {
-                       if (perf_index_rotate(&frame->layer[j])) {
+                       if (is_perf_layer_rotate(&frame->layer[j]))
                                rot++;
-                               break;
-                       }
                }
+               rot_skip = (rot == frame->num_layers) ? 1 : 0;
 
                for (j = 0; j < frame->num_layers; j++) {
                        layer = &frame->layer[j];
 
-                       crop = (u32)layer->crop_width * layer->crop_height;
-                       window = (u32)layer->window_width * layer->window_height;
+                       yuv2p = is_perf_layer_yuv2p(layer) ? 1 : 0;
+                       sc = is_perf_layer_scaling(layer) ? 1 : 0;
+                       rot = !rot_skip && is_perf_layer_rotate(layer) ? 1 : 0;
 
-                       fmt = perf_index_fmt(layer);
-                       sc = perf_index_sc(layer);
+                       ppc[j] =
+                               g2d_dev->hw_ppc[(yuv2p << 2) | (rot << 1) | sc];
 
-                       if (fmt == PPC_FMT)
-                               return;
+                       cycle_src += layer->pixelcount / ppc[j];
 
-                       cycle += max(crop, window) / ppc[fmt * PPC_ROT + rot][sc];
+                       /*
+                        * check rotated size for cycle_dst. rotated size is
+                        * bigger than non-rotated size, g2d write direction
+                        * is vertical, and it affects performance.
+                        */
+                       if (is_perf_layer_rotate(layer))
+                               rot_size += layer->pixelcount;
+                       else
+                               no_rot_size += layer->pixelcount;
 
                        /*
-                        * If frame has colorfill layer on the bottom,
-                        * upper layaer is treated as opaque.
-                        * In this case, colorfill is not be processed
-                        * as much as the overlapping area.
+                        * The rotated layer affects the pair layer,
+                        * so we add the cycle using gap_ppc between pair
+                        * N layer and N+1 layer. The gap ppc is calculated
+                        * on odd layer and gap_pixelcount is pair layer's
+                        * nested region from 2 layers that means
+                        * the smaller region.
                         */
-                       if (!j && is_perf_frame_colorfill(frame)) {
-                               unsigned int pixelcount;
+                       if (rot && (yuv2p || sc))
+                               gap = true;
 
-                               pixelcount = frame->target_pixelcount -
-                                       layer->window_width * layer->window_height;
-                               if (pixelcount > 0)
-                                       cycle += pixelcount / g2d_dev->hw_ppc[PPC_COLORFILL];
+                       if (gap && (j & 0x1)) {
+                               unsigned int gap_pixelcount, gap_ppc;
 
+                               pair = &frame->layer[j - 1];
+                               gap = false;
+
+                               gap_ppc = (ppc[j] > ppc[j - 1]) ?
+                                       (ppc[j] - ppc[j - 1]) :
+                                       (ppc[j - 1] - ppc[j]);
+                               if (!gap_ppc)
+                                       continue;
+
+                               gap_ppc = (ppc[j] * ppc[j - 1]) / gap_ppc;
+
+                               gap_pixelcount = min(layer->pixelcount, pair->pixelcount);
+
+                               cycle_src += gap_pixelcount / gap_ppc;
                        }
                }
+
+               rot = (rot_size > no_rot_size) ? 1 : 0;
+               if (!rot && is_perf_frame_yuv2p(frame))
+                       dst_ppc = g2d_dev->hw_ppc[G2D_PPC_DST_YUV2P];
+               else if (!rot)
+                       dst_ppc = g2d_dev->hw_ppc[G2D_PPC_DST_DEFAULT];
+               else
+                       dst_ppc = g2d_dev->hw_ppc[G2D_PPC_DST_ROT];
+
+               cycle_dst = frame->target_pixelcount / dst_ppc;
+
+               cycle += max(cycle_src, cycle_dst);
+
+               if (is_perf_frame_colorfill(frame))
+                       cycle += frame->target_pixelcount /
+                                       g2d_dev->hw_ppc[G2D_PPC_COLORFILL];
        }
 
        /* ip_clock(Mhz) = cycles / time_in_ms * 1000 */
@@ -245,16 +272,6 @@ static void g2d_set_qos_frequency(struct g2d_context *g2d_ctx,
 void g2d_set_performance(struct g2d_context *ctx,
                                struct g2d_performance_data *data)
 {
-       int i;
-
-       if (data->num_frame > G2D_PERF_MAX_FRAMES)
-               return;
-
-       for (i = 0; i < data->num_frame; i++) {
-               if (data->frame[i].num_layers > G2D_MAX_IMAGES)
-                       return;
-       }
-
        g2d_set_qos_frequency(ctx, data);
        g2d_set_device_frequency(ctx, data);
 }
index 58fcb74b660a9b9be43bad2d92bc23a80e980ef2..a437824f81dc4d406cb112de2269f8958d634628 100644 (file)
 struct g2d_context;
 struct g2d_performance_data;
 
-#define perf_index_fmt(layer) \
-               ((((layer)->layer_attr) & G2D_PERF_LAYER_FMTMASK) >> 4)
-#define perf_index_rotate(layer) \
+#define is_perf_layer_yuv2p(layer) \
+               (((layer)->layer_attr) & G2D_PERF_LAYER_YUV2P)
+#define is_perf_layer_scaling(layer) \
+               (((layer)->layer_attr) & G2D_PERF_LAYER_SCALING)
+#define is_perf_layer_rotate(layer) \
                (((layer)->layer_attr) & G2D_PERF_LAYER_ROTATE)
+
+#define is_perf_frame_yuv2p(frame) \
+               (((frame)->frame_attr) & G2D_PERF_FRAME_YUV2P)
 #define is_perf_frame_colorfill(frame) \
                (((frame)->frame_attr) & G2D_PERF_FRAME_SOLIDCOLORFILL)
 
index 6a56ce2b0f908b7f508f5fdc89083979283a6d7c..f57600b7a78248442a2bc2583ec249b719be49d4 100644 (file)
@@ -212,23 +212,15 @@ struct g2d_task_data {
 /* flags of g2d_performance_layer_data.layer_attr */
 #define G2D_PERF_LAYER_ROTATE          (1 << 0)
 #define G2D_PERF_LAYER_SCALING         (1 << 1)
-#define G2D_PERF_LAYER_YUV2P           (1 << 4)
-#define G2D_PERF_LAYER_YUV2P_82        (1 << 5)
-#define G2D_PERF_LAYER_FMTMASK         (3 << 4)
+#define G2D_PERF_LAYER_YUV2P           (1 << 2)
 
 /*
  * struct g2d_performance_frame_data - description of needed performance.
- * @crop_width/height : the width and height of the image that
- *             participates in the image processing
- * @window_width/height : the width and height of valid rectangle,
- *             the region is drawn on target
+ * @pixelcount : the pixecount of layer, is used to calculate the frequency.
  * @layer_attr : attribute of layer affecting performance.
  */
 struct g2d_performance_layer_data {
-       __u16 crop_width;
-       __u16 crop_height;
-       __u16 window_width;
-       __u16 window_height;
+       __u32 pixelcount;
        __u32 layer_attr;
 };