isp_wdr4.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /****************************************************************************
  2. *
  3. * The MIT License (MIT)
  4. *
  5. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. *
  25. *****************************************************************************
  26. *
  27. * The GPL License (GPL)
  28. *
  29. * Copyright (c) 2020 VeriSilicon Holdings Co., Ltd.
  30. *
  31. * This program is free software; you can redistribute it and/or
  32. * modify it under the terms of the GNU General Public License
  33. * as published by the Free Software Foundation; either version 2
  34. * of the License, or (at your option) any later version.
  35. *
  36. * This program is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with this program;
  43. *
  44. *****************************************************************************
  45. *
  46. * Note: This software is released under dual MIT and GPL licenses. A
  47. * recipient may use this file under the terms of either the MIT license or
  48. * GPL License. If you wish to use only one license not the other, you can
  49. * indicate your decision by deleting one of the above license notices in your
  50. * version of this file.
  51. *
  52. *****************************************************************************/
  53. #ifdef __KERNEL__
  54. #include <linux/io.h>
  55. #include <linux/module.h>
  56. #endif
  57. #include "mrv_all_bits.h"
  58. #include "isp_ioctl.h"
  59. #include "isp_types.h"
  60. #ifdef ISP_WDR_V4
  61. #define WDR4_WW (32)
  62. #define WDR4_HH (32)
  63. #define WDR4_MAX_VALUE (1048575)
  64. #define WDR4_GAIN_SHIFT (2)
  65. #define WDR4_NORMALIZE (1024)
  66. #define WDR4_NORMALIZE_SHIFT (10)
  67. #ifdef ISP_WDR_V4_20BIT
  68. #define MODULE_INPUT_BIT_DEPTH (20)
  69. #else
  70. #define MODULE_INPUT_BIT_DEPTH (12)
  71. #endif
  72. #define MODULE_OUTPUT_BIT_DEPTH (12)
  73. extern MrvAllRegister_t *all_regs;
  74. static void wdr4_config_curve(struct isp_ic_dev *dev)
  75. {
  76. struct isp_wdr4_context *wdr4 = &dev->wdr4;
  77. u32 pos, i , val;
  78. //u32 isp_wdr4_shift_0;
  79. //u32 isp_wdr4_shift0_0;
  80. //initialize the histogram && entropy && gamma_pre && gamma_up && gamma_down && invert_linear
  81. for (i = 0; i < 7; i++) {
  82. u32 val_high_bit, val_low_bit;
  83. pos = i * 3;
  84. //get the curve that combined with high && low data
  85. val_high_bit = (wdr4->histogram[pos] >> 10) & (0x3ff);
  86. val_low_bit = wdr4->histogram[pos] & (0x3ff);
  87. val = val_low_bit << WDR4_HISTOGRAM_CURVE0_0_SHIFT ;
  88. val |= wdr4->histogram[pos +1];
  89. isp_write_reg(dev, REG_ADDR(isp_wdr4_histogram_0) + i * 2 * ISP_REG_GAP, val);
  90. val = val_high_bit << WDR4_HISTOGRAM_CURVE0_0_SHIFT ;
  91. if (pos + 2 < WDR4_BIN) {
  92. val |= wdr4->histogram[pos +2];
  93. }
  94. isp_write_reg(dev, REG_ADDR(isp_wdr4_histogram_0) + (i *2 + 1) * ISP_REG_GAP, val);
  95. //get the value that combined with high && low data
  96. val_high_bit = (wdr4->gamma_pre[pos] >> 10) & 0x3ff;
  97. val_low_bit = (wdr4->gamma_pre[pos] & 0x3ff) ;
  98. val = val_low_bit << WDR4_GAMMA_PRE_CURVE0_1_SHIFT ;
  99. val |= wdr4->gamma_pre[pos +1];
  100. isp_write_reg(dev, REG_ADDR(isp_wdr4_gamma_pre_0) + (i * 2) * ISP_REG_GAP, val);
  101. val = val_high_bit << WDR4_GAMMA_PRE_CURVE0_1_SHIFT ;
  102. if (pos + 2 < WDR4_BIN)
  103. val |= wdr4->gamma_pre[pos +2];
  104. isp_write_reg(dev, REG_ADDR(isp_wdr4_gamma_pre_0) + (i *2 + 1) * ISP_REG_GAP, val);
  105. //get the value that combined with high && low data
  106. val_high_bit = (wdr4->gamma_up[pos] >> 10) & 0x3ff;
  107. val_low_bit = (wdr4->gamma_up[pos] & 0x3ff);
  108. val = val_low_bit <<WDR4_GAMMA_UP_CURVE0_0_SHIFT;
  109. val |= wdr4->gamma_up[pos +1];
  110. isp_write_reg(dev, REG_ADDR(isp_wdr4_gamma_up_0) + (i * 2) * ISP_REG_GAP, val);
  111. val = val_high_bit <<WDR4_GAMMA_UP_CURVE0_1_SHIFT;
  112. if (pos + 2 < WDR4_BIN)
  113. val |= wdr4->gamma_up[pos +2];
  114. isp_write_reg(dev, REG_ADDR(isp_wdr4_gamma_up_0) + (i *2 + 1) * ISP_REG_GAP, val);
  115. //get the value that combined with high && low data
  116. val_high_bit = (wdr4->invert_linear[pos] >> 9) & 0x1ff;
  117. val_low_bit = (wdr4->invert_linear[pos] & 0x1ff);
  118. val = val_low_bit << WDR4_LINEAR_CURVE_INVERT0_0_SHIFT;
  119. val |= wdr4->invert_linear[pos +1];
  120. isp_write_reg(dev, REG_ADDR(isp_wdr4_invert_linear_0) + (i * 2) * ISP_REG_GAP, val);
  121. val = val_high_bit << WDR4_LINEAR_CURVE_INVERT0_0_SHIFT;
  122. if (pos + 2 < WDR4_BIN)
  123. val |= wdr4->invert_linear[pos +2];
  124. isp_write_reg(dev, REG_ADDR(isp_wdr4_invert_linear_0) + (i *2 + 1) * ISP_REG_GAP, val);
  125. if (pos + 2 < WDR4_BIN) {
  126. val = wdr4->entropy[pos] << WDR4_ENTROPY_CONVERT0_SHIFT ;
  127. val |= wdr4->entropy[pos +1] << WDR4_ENTROPY_CONVERT1_SHIFT;
  128. val |= wdr4->entropy[pos +2] << WDR4_ENTROPY_CONVERT2_SHIFT;
  129. } else { //the lasw two entropy
  130. val = wdr4->entropy[pos] << WDR4_ENTROPY_CONVERT18_SHIFT ;
  131. val |= wdr4->entropy[pos +1] << WDR4_ENTROPY_CONVERT19_SHIFT;
  132. }
  133. isp_write_reg(dev, REG_ADDR(isp_wdr4_entropy_0) + i * ISP_REG_GAP, val);
  134. if (pos + 2 < WDR4_BIN) {
  135. val = wdr4->gamma_down[pos] << WDR4_GAMMA_DOWN_CURVE0_SHIFT ;
  136. val |= wdr4->gamma_down[pos +1] << WDR4_GAMMA_DOWN_CURVE1_SHIFT;
  137. val |= wdr4->gamma_down[pos +2] << WDR4_GAMMA_DOWN_CURVE2_SHIFT;
  138. } else { //the lasw two entropy
  139. val = wdr4->gamma_down[pos] << WDR4_GAMMA_DOWN_CURVE18_SHIFT ;
  140. val |= wdr4->gamma_down[pos +1] << WDR4_GAMMA_DOWN_CURVE19_SHIFT;
  141. }
  142. isp_write_reg(dev, REG_ADDR(isp_wdr4_gamma_down_0) + i * ISP_REG_GAP, val);
  143. }
  144. //config the distance weight && different weight && SMOOTH INVERT
  145. for (i = 0 ; i < 5 ; i++) {
  146. pos = i * ISP_REG_GAP;
  147. val = wdr4->distance_weight[pos] << WDR4_DISTANCE_WEIGHT_CURVE0_SHIFT ;
  148. val |= wdr4->distance_weight[pos +1] << WDR4_DISTANCE_WEIGHT_CURVE1_SHIFT;
  149. val |= wdr4->distance_weight[pos +2] << WDR4_DISTANCE_WEIGHT_CURVE2_SHIFT;
  150. val |= wdr4->distance_weight[pos +3] << WDR4_DISTANCE_WEIGHT_CURVE3_SHIFT;
  151. isp_write_reg(dev, REG_ADDR(isp_wdr4_distance_weight_0) + i * ISP_REG_GAP, val);
  152. val = wdr4->difference_weight[pos] << WDR4_DIFFERENCE_WEIGHT_CURVE0_SHIFT ;
  153. val |= wdr4->difference_weight[pos +1] << WDR4_DIFFERENCE_WEIGHT_CURVE1_SHIFT;
  154. val |= wdr4->difference_weight[pos +2] << WDR4_DIFFERENCE_WEIGHT_CURVE2_SHIFT;
  155. val |= wdr4->difference_weight[pos +3] << WDR4_DIFFERENCE_WEIGHT_CURVE3_SHIFT;
  156. isp_write_reg(dev, REG_ADDR(isp_wdr4_difference_weight_0) + i * ISP_REG_GAP, val);
  157. val = wdr4->smooth_invert[pos] << WDR4_SMOOTH_INVERT_CURVE0_SHIFT ;
  158. val |= wdr4->smooth_invert[pos +1] << WDR4_SMOOTH_INVERT_CURVE1_SHIFT;
  159. val |= wdr4->smooth_invert[pos +2] << WDR4_SMOOTH_INVERT_CURVE2_SHIFT;
  160. val |= wdr4->smooth_invert[pos +3] << WDR4_SMOOTH_INVERT_CURVE3_SHIFT;
  161. isp_write_reg(dev, REG_ADDR(isp_wdr4_smooth_invert_0) + i * ISP_REG_GAP, val);
  162. }
  163. for (i = 0; i < 10; i++) {
  164. val = 0;
  165. REG_SET_SLICE(val, WDR4_GLOBAL_CURVE_INVERT0,
  166. wdr4->invert_curve[i * 2]);
  167. REG_SET_SLICE(val, WDR4_GLOBAL_CURVE_INVERT1,
  168. wdr4->invert_curve[i * 2 + 1]);
  169. isp_write_reg(dev, REG_ADDR(isp_wdr4_invert_curve_0) + i * ISP_REG_GAP, val);
  170. }
  171. for (i = 0 ; i < 4; i++) {
  172. val = 0 ;
  173. pos = i * 6;
  174. if (pos + 3 > WDR4_BIN) {
  175. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT18, wdr4->shift[ pos +0]);
  176. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT19, wdr4->shift[ pos +1]);
  177. } else {
  178. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT0, wdr4->shift[ pos +0]);
  179. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT1, wdr4->shift[ pos +1]);
  180. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT2, wdr4->shift[ pos +2]);
  181. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT3, wdr4->shift[ pos +3]);
  182. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT4, wdr4->shift[ pos +4]);
  183. REG_SET_SLICE(val, WDR4_HISTOGRAM_SHIFT5, wdr4->shift[ pos +5]);
  184. }
  185. isp_write_reg(dev, REG_ADDR(isp_wdr4_shift_0) + i * ISP_REG_GAP, val);
  186. }
  187. for (i = 0 ; i < 3; i++) {
  188. val = 0 ;
  189. pos = i * 8;
  190. if (pos + 5 > WDR4_BIN) {
  191. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT16, wdr4->shift0[ pos +0]);
  192. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT17, wdr4->shift0[ pos +1]);
  193. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT18, wdr4->shift0[ pos +2]);
  194. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT19, wdr4->shift0[ pos +3]);
  195. } else {
  196. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT0, wdr4->shift0[ pos +0]);
  197. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT1, wdr4->shift0[ pos +1]);
  198. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT2, wdr4->shift0[ pos +2]);
  199. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT3, wdr4->shift0[ pos +3]);
  200. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT4, wdr4->shift0[ pos +4]);
  201. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT5, wdr4->shift0[ pos +5]);
  202. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT6, wdr4->shift0[ pos +6]);
  203. REG_SET_SLICE(val, WDR4_HISTOGRAM0_SHIFT7, wdr4->shift0[ pos +7]);
  204. }
  205. isp_write_reg(dev, REG_ADDR(isp_wdr4_shift0_0) + i * ISP_REG_GAP, val);
  206. }
  207. }
  208. static void wdr4_hw_init(struct isp_ic_dev *dev)
  209. {
  210. // struct isp_wdr4_context *wdr4 = &dev->wdr4;
  211. u32 width, height;
  212. u32 slice_sigma_height;
  213. u32 slice_sigma_width;
  214. u32 slice_sigma_value;
  215. u32 slice_block_width;
  216. u32 slice_block_height;
  217. u32 isp_wdr4_block_size;
  218. u32 slice_block_area_inverse;
  219. u32 isp_wdr4_value_weight;
  220. u32 isp_wdr4_pixel_slope;
  221. u32 isp_wdr4_entropy_slope;
  222. u32 isp_wdr4_sigma_width;
  223. u32 isp_wdr4_sigma_height;
  224. u32 isp_wdr4_sigma_value;
  225. u32 isp_wdr4_block_flag_width;
  226. u32 isp_wdr4_block_flag_height;
  227. u32 isp_wdr4_strength;
  228. u32 isp_wdr4_block_area_factor;
  229. u32 width_left;
  230. u32 width_count = 0;
  231. u32 height_left;
  232. u32 height_count = 0;
  233. u32 isp_wdr4_strength_0 = 0, isp_wdr4_strength_1 = 0, isp_wdr4_contrast = 0;
  234. int i;
  235. u8 isp_wdr4_low_strength, isp_wdr4_high_strength, isp_wdr4_global_strength;
  236. u8 isp_wdr4_local_strength;
  237. u32 slice_pixel_shift;
  238. u32 slice_output_shift;// isp_wdr4_normalize_shift;
  239. u32 isp_wdr4_shift;// isp_wdr4_gain_shift_bit;
  240. pr_info("enter %s\n", __func__);
  241. width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
  242. height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
  243. pr_info("isp_wdr4 res: %d %d \n", width, height);
  244. /* firware initilization */
  245. isp_wdr4_strength = 128; // valid values: [0,128]; isp_wdr4 will merge original and enhanced image
  246. // together based on this value.
  247. // 128: use enhanced image completely; 0: use original image completely
  248. isp_wdr4_low_strength = 16; // Valid values: [0,255]; if hdr off, limit the maximum gain for image enhancement
  249. // if hdr on, control low light area information. Higher:haver more low light information
  250. isp_wdr4_high_strength = 60; //valid values:[0, 128]: control high light area information. Higher:have more high
  251. // light information
  252. isp_wdr4_global_strength = 128; // Valid values: [0,128]
  253. // isp_wdr4 will increase global contrast based on this value.
  254. // 128: use strongest contrast; 0: on contrast increasing.
  255. isp_wdr4_local_strength = 128; // valid values: [0,128]
  256. // wdr4 will increase local contrast based on this value.
  257. // 128: use strongest contrast; 0: on contrast increasing.
  258. isp_wdr4_strength_0 = isp_read_reg(dev, REG_ADDR(isp_wdr4_strength_0));
  259. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_LOCAL_STRENGTH, isp_wdr4_local_strength);
  260. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_GLOBAL_STRENGTH, isp_wdr4_global_strength);
  261. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_LOW_STRENGTH, isp_wdr4_low_strength);
  262. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_TOTAL_STRENGTH,isp_wdr4_strength);
  263. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_0), isp_wdr4_strength_0);
  264. isp_wdr4_strength_1 = isp_read_reg(dev, REG_ADDR(isp_wdr4_strength_1));
  265. REG_SET_SLICE(isp_wdr4_strength_1, WDR4_HIGH_STRENGTH, isp_wdr4_high_strength);
  266. REG_SET_SLICE(isp_wdr4_strength_1, WDR4_DRC_BAYER_RATIO, 14);
  267. REG_SET_SLICE(isp_wdr4_strength_1, WDR4_DRC_BAYER_RATIOLSVS, 14);
  268. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_1), isp_wdr4_strength_1);
  269. isp_wdr4_contrast = isp_read_reg(dev, REG_ADDR(isp_wdr4_contrast));
  270. REG_SET_SLICE(isp_wdr4_contrast , WDR4_CONTRAST ,0); //valid values:[-1023~1023]:control contrast of image,.higher:image have stronger contrast
  271. REG_SET_SLICE(isp_wdr4_contrast , WDR4_FLAT_STRENGTH ,8);//valid values:[0, 19]:adjust flat area. Higher:flat area stretched more strong
  272. REG_SET_SLICE(isp_wdr4_contrast , WDR4_FLAT_THR ,1); //valid values:[0, 20]:judge flat region.
  273. isp_write_reg(dev, REG_ADDR(isp_wdr4_contrast), isp_wdr4_contrast);
  274. isp_wdr4_pixel_slope = isp_read_reg(dev, REG_ADDR(isp_wdr4_pixel_slope));
  275. REG_SET_SLICE(isp_wdr4_pixel_slope , WDR4_PIXEL_MERGE_SLOPE , 128);
  276. REG_SET_SLICE(isp_wdr4_pixel_slope , WDR4_PIXEL_MERGE_BASE , 128);
  277. REG_SET_SLICE(isp_wdr4_pixel_slope , WDR4_PIXEL_ADJUST_SLOPE ,128);
  278. REG_SET_SLICE(isp_wdr4_pixel_slope , WDR4_PIXEL_ADJUST_BASE , 128);
  279. isp_write_reg(dev, REG_ADDR(isp_wdr4_pixel_slope), isp_wdr4_pixel_slope);
  280. isp_wdr4_entropy_slope = isp_read_reg(dev, REG_ADDR(isp_wdr4_entropy_slope));
  281. REG_SET_SLICE(isp_wdr4_entropy_slope , WDR4_ENTROPY_SLOPE , 0xc8);
  282. REG_SET_SLICE(isp_wdr4_entropy_slope , WDR4_ENTROPY_BASE ,0x02bc);
  283. isp_write_reg(dev, REG_ADDR(isp_wdr4_entropy_slope), isp_wdr4_entropy_slope);
  284. isp_wdr4_value_weight = isp_read_reg(dev, REG_ADDR(isp_wdr4_value_weight));
  285. REG_SET_SLICE(isp_wdr4_value_weight , WDR4_VALUE_WEIGHT_0 , 6);
  286. REG_SET_SLICE(isp_wdr4_value_weight , WDR4_VALUE_WEIGHT_1 , 5);
  287. REG_SET_SLICE(isp_wdr4_value_weight , WDR4_VALUE_WEIGHT_2 , 5);
  288. REG_SET_SLICE(isp_wdr4_value_weight , WDR4_VALUE_WEIGHT_3 , 16);
  289. isp_write_reg(dev, REG_ADDR(isp_wdr4_value_weight), isp_wdr4_value_weight);
  290. slice_block_width = width / WDR4_WW;
  291. slice_block_height = height / WDR4_HH;
  292. isp_wdr4_block_size = 0;
  293. REG_SET_SLICE(isp_wdr4_block_size, WDR4_BLOCK_WIDTH, slice_block_width);
  294. REG_SET_SLICE(isp_wdr4_block_size, WDR4_BLOCK_HEIGHT, slice_block_height);
  295. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_size), isp_wdr4_block_size);
  296. slice_block_area_inverse =
  297. WDR4_NORMALIZE * WDR4_NORMALIZE / (slice_block_width *
  298. slice_block_height);
  299. isp_wdr4_block_area_factor = isp_read_reg(dev, REG_ADDR(isp_wdr4_block_area_factor));
  300. REG_SET_SLICE(isp_wdr4_block_area_factor, WDR4_BLOCK_AREA_INVERSE, slice_block_area_inverse);
  301. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_area_factor), isp_wdr4_block_area_factor);
  302. slice_sigma_height =
  303. WDR4_NORMALIZE * WDR4_NORMALIZE / slice_block_height;
  304. slice_sigma_width = WDR4_NORMALIZE * WDR4_NORMALIZE / slice_block_width;
  305. slice_sigma_value = WDR4_NORMALIZE * WDR4_NORMALIZE/ WDR4_MAX_VALUE;
  306. isp_wdr4_sigma_width =
  307. isp_read_reg(dev, REG_ADDR(isp_wdr4_sigma_width));
  308. REG_SET_SLICE(isp_wdr4_sigma_width, WDR4_BILITERAL_WIDTH_SIGMA,
  309. slice_sigma_width);
  310. isp_write_reg(dev, REG_ADDR(isp_wdr4_sigma_width),
  311. isp_wdr4_sigma_width);
  312. isp_wdr4_sigma_height = isp_read_reg(dev, REG_ADDR(isp_wdr4_sigma_height));
  313. REG_SET_SLICE(isp_wdr4_sigma_height, WDR4_BILITERAL_HEIGHT_SIGMA,
  314. slice_sigma_height);
  315. isp_write_reg(dev, REG_ADDR(isp_wdr4_sigma_height),
  316. isp_wdr4_sigma_height);
  317. isp_wdr4_sigma_value = isp_read_reg(dev, REG_ADDR(isp_wdr4_sigma_value));
  318. REG_SET_SLICE(isp_wdr4_sigma_value, WDR4_BILITERAL_VALUE_SIGMA,
  319. slice_sigma_value);
  320. isp_write_reg(dev, REG_ADDR(isp_wdr4_sigma_value),
  321. isp_wdr4_sigma_value);
  322. /* block flag configuration */
  323. width_left = width - slice_block_width * WDR4_WW;
  324. height_left = height - slice_block_height * WDR4_HH;
  325. // isp_wdr4_gain_shift_bit = 8;
  326. // isp_wdr4_normalize_shift = 10;
  327. slice_pixel_shift = MODULE_INPUT_BIT_DEPTH - 15;
  328. slice_output_shift = MODULE_INPUT_BIT_DEPTH - MODULE_OUTPUT_BIT_DEPTH;
  329. isp_wdr4_shift = isp_read_reg(dev, REG_ADDR(isp_wdr4_shift));
  330. REG_SET_SLICE(isp_wdr4_shift, WDR4_PIXEL_SHIFT_BIT, slice_pixel_shift);
  331. REG_SET_SLICE(isp_wdr4_shift, WDR4_OUTPUT_SHIFT_BIT,
  332. slice_output_shift);
  333. isp_write_reg(dev, REG_ADDR(isp_wdr4_shift), isp_wdr4_shift);
  334. /* block flag configuration */
  335. width_left = width - slice_block_width * WDR4_WW;
  336. height_left = height - slice_block_height * WDR4_HH;
  337. isp_wdr4_block_flag_width = 0;
  338. isp_wdr4_block_flag_height = 0;
  339. for (i = 0, width_count = 0;
  340. (i < WDR4_WW) && (width_count < width_left); i++, width_count++) {
  341. isp_wdr4_block_flag_width |= (1 << i);
  342. }
  343. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_flag_width), isp_wdr4_block_flag_width);
  344. for (i = 0, height_count = 0;
  345. (i < WDR4_HH) && (height_count < height_left);
  346. i++, height_count++) {
  347. isp_wdr4_block_flag_height |= (1 << i);
  348. }
  349. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_flag_height), isp_wdr4_block_flag_height);
  350. isp_wdr4_block_size = isp_read_reg(dev, REG_ADDR(isp_wdr4_block_size));
  351. REG_SET_SLICE(isp_wdr4_block_size, WDR4_BLOCK_WIDTH, slice_block_width);
  352. REG_SET_SLICE(isp_wdr4_block_size, WDR4_BLOCK_HEIGHT,
  353. slice_block_height);
  354. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_size), isp_wdr4_block_size);
  355. wdr4_config_curve(dev);
  356. #if 1
  357. {
  358. uint32_t isp_wdr4_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr4_ctrl));
  359. REG_SET_SLICE(isp_wdr4_ctrl, WDR4_ENABLE, 1);
  360. isp_write_reg(dev, REG_ADDR(isp_wdr4_ctrl), isp_wdr4_ctrl);
  361. }
  362. #endif
  363. }
  364. int isp_enable_wdr4(struct isp_ic_dev *dev)
  365. {
  366. #ifndef ISP_WDR_V4
  367. pr_err("unsupported function: %s", __func__);
  368. return -EINVAL;
  369. #else
  370. int32_t isp_wdr4_ctrl;
  371. struct isp_wdr4_context *wdr4 = &dev->wdr4;
  372. isp_read_reg(dev, REG_ADDR(isp_pre_filt_ctrl));
  373. isp_read_reg(dev, REG_ADDR(isp_dmsc_cac_y_norm_shd));
  374. isp_wdr4_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr4_ctrl));
  375. wdr4->enable = true;
  376. REG_SET_SLICE(isp_wdr4_ctrl, WDR4_ENABLE, 1);
  377. isp_write_reg(dev, REG_ADDR(isp_wdr4_ctrl), isp_wdr4_ctrl);
  378. return 0;
  379. #endif
  380. }
  381. int isp_disable_wdr4(struct isp_ic_dev *dev)
  382. {
  383. #ifndef ISP_WDR_V4
  384. pr_err("unsupported function: %s", __func__);
  385. return -EINVAL;
  386. #else
  387. struct isp_wdr4_context *wdr4 = &dev->wdr4;
  388. int32_t isp_wdr4_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr4_ctrl));
  389. wdr4->enable = false;
  390. REG_SET_SLICE(isp_wdr4_ctrl, WDR4_ENABLE, 0);
  391. isp_write_reg(dev, REG_ADDR(isp_wdr4_ctrl), isp_wdr4_ctrl);
  392. return 0;
  393. #endif
  394. }
  395. int isp_u_wdr4(struct isp_ic_dev *dev)
  396. {
  397. #ifndef ISP_WDR_V4
  398. pr_err("unsupported function: %s", __func__);
  399. return -EINVAL;
  400. #else
  401. wdr4_hw_init(dev);
  402. return 0;
  403. #endif
  404. }
  405. int isp_s_wdr4(struct isp_ic_dev *dev)
  406. {
  407. #ifndef ISP_WDR_V4
  408. pr_err("unsupported function: %s", __func__);
  409. return -EINVAL;
  410. #else
  411. struct isp_wdr4_context *wdr4 = &dev->wdr4;
  412. u32 isp_wdr4_strength_0 = isp_read_reg(dev, REG_ADDR(isp_wdr4_strength_0));
  413. u32 isp_wdr4_strength_1 = isp_read_reg(dev, REG_ADDR(isp_wdr4_strength_1));
  414. u32 isp_wdr4_contrast = isp_read_reg(dev, REG_ADDR(isp_wdr4_contrast));
  415. u32 width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
  416. u32 height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
  417. width /= 32;
  418. height /= 32;
  419. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_LOW_STRENGTH, wdr4->low_gain);
  420. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_GLOBAL_STRENGTH,
  421. wdr4->global_strength);
  422. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_LOCAL_STRENGTH, 128);
  423. REG_SET_SLICE(isp_wdr4_strength_0, WDR4_TOTAL_STRENGTH, wdr4->strength);
  424. REG_SET_SLICE(isp_wdr4_strength_1, WDR4_HIGH_STRENGTH, wdr4->high_strength);
  425. REG_SET_SLICE(isp_wdr4_contrast , WDR4_CONTRAST, wdr4->contrast); //valid values:[-1023~1023]:control contrast of image,.higher:image have stronger contrast
  426. REG_SET_SLICE(isp_wdr4_contrast , WDR4_FLAT_STRENGTH, wdr4->flat_strength);//valid values:[0, 19]:adjust flat area. Higher:flat area stretched more strong
  427. REG_SET_SLICE(isp_wdr4_contrast , WDR4_FLAT_THR, wdr4->flat_threshold); //valid values:[0, 20]:judge flat region.
  428. isp_write_reg(dev, REG_ADDR(isp_wdr4_contrast), isp_wdr4_contrast);
  429. isp_write_reg(dev, REG_ADDR(isp_wdr4_block_size),
  430. width | (height << 9));
  431. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_0), isp_wdr4_strength_0);
  432. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_1), isp_wdr4_strength_1);
  433. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_0_shd), isp_wdr4_strength_0); /* cmodel use */
  434. isp_write_reg(dev, REG_ADDR(isp_wdr4_strength_1_shd), isp_wdr4_strength_1); /* cmodel use */
  435. return 0;
  436. #endif
  437. }
  438. #endif