1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2015, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #include "type_support.h" 17 #include "ia_css_bnlm.host.h" 18 19 #ifndef IA_CSS_NO_DEBUG 20 #include "ia_css_debug.h" /* ia_css_debug_dtrace() */ 21 #endif 22 #include <assert_support.h> 23 24 #define BNLM_DIV_LUT_SIZE (12) 25 static const s32 div_lut_nearests[BNLM_DIV_LUT_SIZE] = { 26 0, 454, 948, 1484, 2070, 2710, 3412, 4184, 5035, 5978, 7025, 8191 27 }; 28 29 static const s32 div_lut_slopes[BNLM_DIV_LUT_SIZE] = { 30 -7760, -6960, -6216, -5536, -4912, -4344, -3832, -3360, -2936, -2552, -2208, -2208 31 }; 32 33 static const s32 div_lut_intercepts[BNLM_DIV_LUT_SIZE] = { 34 8184, 7752, 7336, 6928, 6536, 6152, 5776, 5416, 5064, 4728, 4408, 4408 35 }; 36 37 /* Encodes a look-up table from BNLM public parameters to vmem parameters. 38 * Input: 39 * lut : bnlm_lut struct containing encoded vmem parameters look-up table 40 * lut_thr : array containing threshold values for lut 41 * lut_val : array containing output values related to lut_thr 42 * lut_size: Size of lut_val array 43 */ 44 static inline void 45 bnlm_lut_encode(struct bnlm_lut *lut, const int32_t *lut_thr, 46 const s32 *lut_val, const uint32_t lut_size) 47 { 48 u32 blk, i; 49 const u32 block_size = 16; 50 const u32 total_blocks = ISP_VEC_NELEMS / block_size; 51 52 /* Create VMEM LUTs from the threshold and value arrays. 53 * 54 * Min size of the LUT is 2 entries. 55 * 56 * Max size of the LUT is 16 entries, so that the LUT can fit into a 57 * single group of 16 elements inside a vector. 58 * Then these elements are copied into other groups inside the same 59 * vector. If the LUT size is less than 16, then remaining elements are 60 * set to 0. 61 */ 62 assert((lut_size >= 2) && (lut_size <= block_size)); 63 /* array lut_thr has (lut_size-1) entries */ 64 for (i = 0; i < lut_size - 2; i++) { 65 /* Check if the lut_thr is monotonically increasing */ 66 assert(lut_thr[i] <= lut_thr[i + 1]); 67 } 68 69 /* Initialize */ 70 for (i = 0; i < total_blocks * block_size; i++) { 71 lut->thr[0][i] = 0; 72 lut->val[0][i] = 0; 73 } 74 75 /* Copy all data */ 76 for (i = 0; i < lut_size - 1; i++) { 77 lut->thr[0][i] = lut_thr[i]; 78 lut->val[0][i] = lut_val[i]; 79 } 80 lut->val[0][i] = lut_val[i]; /* val has one more element than thr */ 81 82 /* Copy data from first block to all blocks */ 83 for (blk = 1; blk < total_blocks; blk++) { 84 u32 blk_offset = blk * block_size; 85 86 for (i = 1; i < lut_size; i++) { 87 lut->thr[0][blk_offset + i] = lut->thr[0][i]; 88 lut->val[0][blk_offset + i] = lut->val[0][i]; 89 } 90 } 91 } 92 93 /* 94 * - Encodes BNLM public parameters into VMEM parameters 95 * - Generates VMEM parameters which will needed internally ISP 96 */ 97 void 98 ia_css_bnlm_vmem_encode( 99 struct bnlm_vmem_params *to, 100 const struct ia_css_bnlm_config *from, 101 size_t size) 102 { 103 int i; 104 (void)size; 105 106 /* Initialize LUTs in VMEM parameters */ 107 bnlm_lut_encode(&to->mu_root_lut, from->mu_root_lut_thr, from->mu_root_lut_val, 108 16); 109 bnlm_lut_encode(&to->sad_norm_lut, from->sad_norm_lut_thr, 110 from->sad_norm_lut_val, 16); 111 bnlm_lut_encode(&to->sig_detail_lut, from->sig_detail_lut_thr, 112 from->sig_detail_lut_val, 16); 113 bnlm_lut_encode(&to->sig_rad_lut, from->sig_rad_lut_thr, from->sig_rad_lut_val, 114 16); 115 bnlm_lut_encode(&to->rad_pow_lut, from->rad_pow_lut_thr, from->rad_pow_lut_val, 116 16); 117 bnlm_lut_encode(&to->nl_0_lut, from->nl_0_lut_thr, from->nl_0_lut_val, 16); 118 bnlm_lut_encode(&to->nl_1_lut, from->nl_1_lut_thr, from->nl_1_lut_val, 16); 119 bnlm_lut_encode(&to->nl_2_lut, from->nl_2_lut_thr, from->nl_2_lut_val, 16); 120 bnlm_lut_encode(&to->nl_3_lut, from->nl_3_lut_thr, from->nl_3_lut_val, 16); 121 122 /* Initialize arrays in VMEM parameters */ 123 memset(to->nl_th, 0, sizeof(to->nl_th)); 124 to->nl_th[0][0] = from->nl_th[0]; 125 to->nl_th[0][1] = from->nl_th[1]; 126 to->nl_th[0][2] = from->nl_th[2]; 127 128 memset(to->match_quality_max_idx, 0, sizeof(to->match_quality_max_idx)); 129 to->match_quality_max_idx[0][0] = from->match_quality_max_idx[0]; 130 to->match_quality_max_idx[0][1] = from->match_quality_max_idx[1]; 131 to->match_quality_max_idx[0][2] = from->match_quality_max_idx[2]; 132 to->match_quality_max_idx[0][3] = from->match_quality_max_idx[3]; 133 134 bnlm_lut_encode(&to->div_lut, div_lut_nearests, div_lut_slopes, 135 BNLM_DIV_LUT_SIZE); 136 memset(to->div_lut_intercepts, 0, sizeof(to->div_lut_intercepts)); 137 for (i = 0; i < BNLM_DIV_LUT_SIZE; i++) { 138 to->div_lut_intercepts[0][i] = div_lut_intercepts[i]; 139 } 140 141 memset(to->power_of_2, 0, sizeof(to->power_of_2)); 142 for (i = 0; i < (ISP_VEC_ELEMBITS - 1); i++) { 143 to->power_of_2[0][i] = 1 << i; 144 } 145 } 146 147 /* - Encodes BNLM public parameters into DMEM parameters */ 148 void 149 ia_css_bnlm_encode( 150 struct bnlm_dmem_params *to, 151 const struct ia_css_bnlm_config *from, 152 size_t size) 153 { 154 (void)size; 155 to->rad_enable = from->rad_enable; 156 to->rad_x_origin = from->rad_x_origin; 157 to->rad_y_origin = from->rad_y_origin; 158 to->avg_min_th = from->avg_min_th; 159 to->max_min_th = from->max_min_th; 160 161 to->exp_coeff_a = from->exp_coeff_a; 162 to->exp_coeff_b = from->exp_coeff_b; 163 to->exp_coeff_c = from->exp_coeff_c; 164 to->exp_exponent = from->exp_exponent; 165 } 166 167 /* Prints debug traces for BNLM public parameters */ 168 void 169 ia_css_bnlm_debug_trace( 170 const struct ia_css_bnlm_config *config, 171 unsigned int level) 172 { 173 if (!config) 174 return; 175 176 #ifndef IA_CSS_NO_DEBUG 177 ia_css_debug_dtrace(level, "BNLM:\n"); 178 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_enable", config->rad_enable); 179 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_x_origin", 180 config->rad_x_origin); 181 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_y_origin", 182 config->rad_y_origin); 183 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "avg_min_th", config->avg_min_th); 184 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "max_min_th", config->max_min_th); 185 186 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_a", 187 config->exp_coeff_a); 188 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_b", 189 config->exp_coeff_b); 190 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_c", 191 config->exp_coeff_c); 192 ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_exponent", 193 config->exp_exponent); 194 195 /* ToDo: print traces for LUTs */ 196 #endif /* IA_CSS_NO_DEBUG */ 197 } 198