[COMMON] fimc-is2: fix a TDNR wrong caculation bug
authorWooyeon Kim <wooy88.kim@samsung.com>
Fri, 1 Jun 2018 07:24:56 +0000 (16:24 +0900)
committerEunyoung Lee <ey470.lee@samsung.com>
Tue, 19 Jun 2018 08:49:16 +0000 (17:49 +0900)
 - when NI is set to same setfile NI value,
   it is not applied to right value.

Change-Id: Iecedbb1fd70cfdfc1cdef16c2ce9aea778247f54
Signed-off-by: Wooyeon Kim <wooy88.kim@samsung.com>
drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-mcscaler-v2.h
drivers/media/platform/exynos/fimc-is2/hardware/fimc-is-hw-tdnr-v2.c

index 86124fed7b377cadaf84dbd5ef73e253144a233e..272de61652f8cb70ebd82e55f6323d77c2cea3c6 100644 (file)
@@ -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 */
index 184cee3f0d1e917faf77a312fde7301b280469af..0a5749291d0c218452d5104b81c3355478044969 100644 (file)
@@ -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);