From: hyesoo.yu Date: Thu, 24 Aug 2017 01:22:22 +0000 (+0900) Subject: Revert "[COMMON] g2d: fix formula based on measured value" X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=022657dd2a6d14fb4036be8a64f2889e961ffba1;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Revert "[COMMON] g2d: fix formula based on measured value" This reverts commit 8b6985f10269521f49d54bcf17ee731cca671dd3. Change-Id: I56b70b99e2e94378c9014dc3aad623fb769f46ad Signed-off-by: hyesoo.yu --- diff --git a/drivers/gpu/exynos/g2d/g2d.h b/drivers/gpu/exynos/g2d/g2d.h index 50bf4b2db70f..77bb8903e8ea 100644 --- a/drivers/gpu/exynos/g2d/g2d.h +++ b/drivers/gpu/exynos/g2d/g2d.h @@ -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; diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index 5ef0fabb5209..eb93763c6b6e 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -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"); diff --git a/drivers/gpu/exynos/g2d/g2d_perf.c b/drivers/gpu/exynos/g2d/g2d_perf.c index 1d409afb8934..0f9183d7a39d 100644 --- a/drivers/gpu/exynos/g2d/g2d_perf.c +++ b/drivers/gpu/exynos/g2d/g2d_perf.c @@ -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); } diff --git a/drivers/gpu/exynos/g2d/g2d_perf.h b/drivers/gpu/exynos/g2d/g2d_perf.h index 58fcb74b660a..a437824f81dc 100644 --- a/drivers/gpu/exynos/g2d/g2d_perf.h +++ b/drivers/gpu/exynos/g2d/g2d_perf.h @@ -19,10 +19,15 @@ 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) diff --git a/drivers/gpu/exynos/g2d/g2d_uapi.h b/drivers/gpu/exynos/g2d/g2d_uapi.h index 6a56ce2b0f90..f57600b7a782 100644 --- a/drivers/gpu/exynos/g2d/g2d_uapi.h +++ b/drivers/gpu/exynos/g2d/g2d_uapi.h @@ -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; };