From 6585e21c74b43be0dbaa2914ce13f396f07de27a Mon Sep 17 00:00:00 2001 From: Wooyeon Kim Date: Fri, 1 Jun 2018 16:24:56 +0900 Subject: [PATCH] [COMMON] fimc-is2: fix a TDNR wrong caculation bug - when NI is set to same setfile NI value, it is not applied to right value. Change-Id: Iecedbb1fd70cfdfc1cdef16c2ce9aea778247f54 Signed-off-by: Wooyeon Kim --- .../hardware/fimc-is-hw-mcscaler-v2.h | 5 +- .../fimc-is2/hardware/fimc-is-hw-tdnr-v2.c | 89 ++++++++++--------- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h index 86124fed7b37..272de61652f8 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h @@ -89,8 +89,9 @@ enum mcsc_block_set_ctrl { #define INTERPOLATE_NUMERATOR(Y1, Y2, diff_x_x1) \ (((Y2) - (Y1)) * (diff_x_x1)) << INTERPOLATE_SHIFT #define GET_LINEAR_INTERPOLATE_VALUE(Y1, Y2, diff_x2_x1, diff_x_x1) \ - ((INTERPOLATE_NUMERATOR((int)Y1, (int)Y2, diff_x_x1)) / (diff_x2_x1)) + \ - (((int)(Y1) << INTERPOLATE_SHIFT)) + (diff_x2_x1) ? (((INTERPOLATE_NUMERATOR((int)Y1, (int)Y2, diff_x_x1)) / (diff_x2_x1)) + \ + (((int)(Y1) << INTERPOLATE_SHIFT))) : \ + (int)(Y1) << INTERPOLATE_SHIFT #define RESTORE_SHIFT_VALUE(value) ((int)(value) >> INTERPOLATE_SHIFT) /* DDK delivered NI to multiply 10 */ diff --git a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-tdnr-v2.c b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-tdnr-v2.c index 184cee3f0d1e..0a5749291d0c 100644 --- a/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-tdnr-v2.c +++ b/drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-tdnr-v2.c @@ -310,25 +310,37 @@ static void translate_temporal_factor(struct temporal_ni_dep_config *temporal_cf temporal_cfg->uv_offset = interpolated_factor.temporal_motion_detection_luma_off ? 255 : 0; - /* value = 16 * (1 - source / 256) */ + /* value = 16 * (1 - source / 256) + * = 2^4 - source / 2^4 + * = (2^8 - source) / 2^4 + */ temp_val = (1 << (8 + INTERPOLATE_SHIFT)) - (ulong)interpolated_factor.temporal_weight_luma_power_base; temporal_cfg->temporal_weight_coeff_y1 = (u32)(temp_val >> (4 + INTERPOLATE_SHIFT)); - /* value = 16 * (1 - (source1 / 256) * (source2 / 256)) */ - temp_val = interpolated_factor.temporal_weight_luma_power_base * - interpolated_factor.temporal_weight_luma_power_gamma; - temporal_cfg->temporal_weight_coeff_y2 = 16 - - (u32)(temp_val >> (12 + INTERPOLATE_SHIFT * 2)); - /* value = 16 * (1 - source / 256) */ + /* value = 16 * (1 - (source1 / 256) * (source2 / 256)) + * = 2^4 - ((source1 * source2) / 2^12) + * = (2^16 - source1 * source2) / 2^12 + */ + temp_val = RESTORE_SHIFT_VALUE(interpolated_factor.temporal_weight_luma_power_base) * + RESTORE_SHIFT_VALUE(interpolated_factor.temporal_weight_luma_power_gamma); + temporal_cfg->temporal_weight_coeff_y2 = ((1 << 16) - temp_val) >> 12; + + /* value = 16 * (1 - source / 256) + * = 2^4 - source / 2^4 + * = (2^8 - source) / 2^4 + */ temp_val = (1 << (8 + INTERPOLATE_SHIFT)) - (ulong)interpolated_factor.temporal_weight_chroma_power_base; temporal_cfg->temporal_weight_coeff_uv1 = (u32)(temp_val >> (4 + INTERPOLATE_SHIFT)); - /* value = 16 * (1 - (source1 / 256) * (source2 / 256)) */ - temp_val = interpolated_factor.temporal_weight_chroma_power_base * - interpolated_factor.temporal_weight_chroma_power_gamma; - temporal_cfg->temporal_weight_coeff_uv2 = 16 - - (u32)(temp_val >> (12 + INTERPOLATE_SHIFT * 2)); + + /* value = 16 * (1 - (source1 / 256) * (source2 / 256)) + * = 2^4 - ((source1 * source2) / 2^12) + * = (2^16 - source1 * source2) / 2^12 + */ + temp_val = RESTORE_SHIFT_VALUE(interpolated_factor.temporal_weight_chroma_power_base) * + RESTORE_SHIFT_VALUE(interpolated_factor.temporal_weight_chroma_power_gamma); + temporal_cfg->temporal_weight_coeff_uv2 = ((1 << 16) - temp_val) >> 12; } static void translate_regional_factor(struct regional_ni_dep_config *regional_cfg, @@ -348,7 +360,10 @@ static void translate_spatial_factor(struct spatial_ni_dep_config *spatial_cfg, { ulong temp_val = 0; - /* value = 16 * (1 - source / 256) */ + /* value = 16 * (1 - source / 256) + * = 2^4 - source / 2^4 + * = (2^8 - source) / 2^4 + */ temp_val = (1 << (8 + INTERPOLATE_SHIFT)) - (ulong)interpolated_factor.spatial_power; spatial_cfg->spatial_gain = (u32)(temp_val >> (4 + INTERPOLATE_SHIFT)); @@ -720,35 +735,25 @@ static void reconfigure_ni_depended_tuneset(tdnr_setfile_contents *tdnr_tuneset, struct ni_dep_factors top_ni_factor = tdnr_tuneset->ni_dep_factors[top_ni_index]; - if (bottom_ni_index == top_ni_index) { - /* if actual NI == ref NI, - * use reference NI factor - */ - interpolated_factor = bottom_ni_factor; - } else { - /* if BOTTOM NI < actual NI < TOP NI, - * value is get by linear interpolation - */ - interpolate_temporal_factor(&interpolated_factor, - noise_index, - bottom_ni_factor, - top_ni_factor); - - interpolate_regional_factor(&interpolated_factor, - noise_index, - bottom_ni_factor, - top_ni_factor); - - interpolate_spatial_factor(&interpolated_factor, - noise_index, - bottom_ni_factor, - top_ni_factor); - - interpolate_yuv_table_factor(&interpolated_factor, - noise_index, - bottom_ni_factor, - top_ni_factor); - } + interpolate_temporal_factor(&interpolated_factor, + noise_index, + bottom_ni_factor, + top_ni_factor); + + interpolate_regional_factor(&interpolated_factor, + noise_index, + bottom_ni_factor, + top_ni_factor); + + interpolate_spatial_factor(&interpolated_factor, + noise_index, + bottom_ni_factor, + top_ni_factor); + + interpolate_yuv_table_factor(&interpolated_factor, + noise_index, + bottom_ni_factor, + top_ni_factor); /* re_configure interpolated NI depended factor to SFR configurations */ translate_temporal_factor(&tdnr_cfgs->temporal_dep_cfg, interpolated_factor); -- 2.20.1