isp_wdr3.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  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. #define WDR3_WW (32)
  61. #define WDR3_HH (32)
  62. #define WDR3_MAX_VALUE (1023)
  63. #define WDR3_GAIN_SHIFT (2)
  64. #define WDR3_NORMALIZE (1024)
  65. #define WDR3_NORMALIZE_SHIFT (10)
  66. #ifdef ISP_WDR_V3_20BIT
  67. #define MODULE_INPUT_BIT_DEPTH (20)
  68. #else
  69. #define MODULE_INPUT_BIT_DEPTH (12)
  70. #endif
  71. #define MODULE_OUTPUT_BIT_DEPTH (12)
  72. extern MrvAllRegister_t *all_regs;
  73. #ifdef ISP_WDR_V3
  74. static void wdr3_hw_init(struct isp_ic_dev *dev)
  75. {
  76. struct isp_wdr3_context *wdr3 = &dev->wdr3;
  77. u32 isp_wdr3_shift_0;
  78. u32 isp_wdr3_shift_1;
  79. u32 width, height;
  80. u32 slice_block_area_factor;
  81. u32 slice_value_weight[4];
  82. u32 slice_pixel_slope_merge;
  83. u32 slice_pixel_base_merge;
  84. u32 slice_pixel_slope_adjust;
  85. u32 slice_pixel_base_adjust;
  86. u32 slice_pixel_slope_entropy;
  87. u32 slice_pixel_base_entropy;
  88. u32 slice_sigma_height;
  89. u32 slice_sigma_width;
  90. u32 slice_sigma_value;
  91. u32 slice_block_width;
  92. u32 slice_block_height;
  93. u32 isp_wdr3_block_size;
  94. u32 isp_wdr3_block_area_factor;
  95. u32 isp_wdr3_value_weight;
  96. u32 isp_wdr3_pixel_slope;
  97. u32 isp_wdr3_entropy_slope;
  98. u32 isp_wdr3_sigma_width;
  99. u32 isp_wdr3_sigma_height;
  100. u32 isp_wdr3_sigma_value;
  101. u32 isp_wdr3_block_flag_width;
  102. u32 isp_wdr3_block_flag_height;
  103. u32 isp_wdr3_strength;
  104. u32 width_left;
  105. u32 width_count = 0;
  106. u32 height_left;
  107. u32 height_count = 0;
  108. u32 val;
  109. bool reg_flag = false;
  110. int i, pos;
  111. pr_info("enter %s\n", __func__);
  112. width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
  113. height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
  114. pr_info("wdr3 res: %d %d \n", width, height);
  115. /* firware initilization */
  116. slice_pixel_slope_merge = 128;
  117. slice_pixel_base_merge = 0;
  118. slice_pixel_slope_adjust = 128;
  119. slice_pixel_base_adjust = 0;
  120. slice_pixel_slope_entropy = 204;
  121. slice_pixel_base_entropy = 716;
  122. slice_value_weight[0] = 6;
  123. slice_value_weight[1] = 5;
  124. slice_value_weight[2] = 5;
  125. slice_value_weight[3] = 16;
  126. slice_block_width = width / WDR3_WW;
  127. slice_block_height = height / WDR3_HH;
  128. slice_block_area_factor =
  129. WDR3_NORMALIZE * WDR3_NORMALIZE / (slice_block_width *
  130. slice_block_height);
  131. slice_sigma_height =
  132. WDR3_NORMALIZE * WDR3_NORMALIZE / slice_block_height;
  133. slice_sigma_width = WDR3_NORMALIZE * WDR3_NORMALIZE / slice_block_width;
  134. slice_sigma_value = WDR3_NORMALIZE * WDR3_NORMALIZE / WDR3_MAX_VALUE;
  135. /* block flag configuration */
  136. width_left = width - slice_block_width * WDR3_WW;
  137. height_left = height - slice_block_height * WDR3_HH;
  138. isp_wdr3_block_flag_width = 0;
  139. isp_wdr3_block_flag_height = 0;
  140. for (i = 0, width_count = 0;
  141. (i < WDR3_WW) && (width_count < width_left); i++, width_count++) {
  142. isp_wdr3_block_flag_width |= (1 << i);
  143. }
  144. for (i = 0, height_count = 0;
  145. (i < WDR3_HH) && (height_count < height_left);
  146. i++, height_count++) {
  147. isp_wdr3_block_flag_height |= (1 << i);
  148. }
  149. slice_pixel_base_adjust += 255;
  150. slice_pixel_base_merge += 255;
  151. #ifndef __KERNEL__
  152. //NOTE: register isp_wdr3_shift is read-only register on fpga, can not write
  153. //NOTE: it is used by cmodel, So it should be config.
  154. u32 slice_pixel_shift;
  155. u32 slice_output_shift;
  156. u32 isp_wdr3_shift;
  157. slice_pixel_shift = MODULE_INPUT_BIT_DEPTH - 5;
  158. slice_output_shift = MODULE_INPUT_BIT_DEPTH - MODULE_OUTPUT_BIT_DEPTH;
  159. isp_wdr3_shift = isp_read_reg(dev, REG_ADDR(isp_wdr3_shift));
  160. REG_SET_SLICE(isp_wdr3_shift, WDR3_PIXEL_SHIFT_BIT, slice_pixel_shift);
  161. REG_SET_SLICE(isp_wdr3_shift, WDR3_OUTPUT_SHIFT_BIT,
  162. slice_output_shift);
  163. isp_write_reg(dev, REG_ADDR(isp_wdr3_shift), isp_wdr3_shift);
  164. #endif
  165. isp_wdr3_block_size = isp_read_reg(dev, REG_ADDR(isp_wdr3_block_size));
  166. REG_SET_SLICE(isp_wdr3_block_size, WDR3_BLOCK_WIDTH, slice_block_width);
  167. REG_SET_SLICE(isp_wdr3_block_size, WDR3_BLOCK_HEIGHT,
  168. slice_block_height);
  169. isp_write_reg(dev, REG_ADDR(isp_wdr3_block_size), isp_wdr3_block_size);
  170. isp_wdr3_block_area_factor =
  171. isp_read_reg(dev, REG_ADDR(isp_wdr3_block_area_factor));
  172. REG_SET_SLICE(isp_wdr3_block_area_factor, WDR3_BLOCK_AREA_INVERSE,
  173. slice_block_area_factor);
  174. isp_write_reg(dev, REG_ADDR(isp_wdr3_block_area_factor),
  175. isp_wdr3_block_area_factor);
  176. isp_wdr3_value_weight =
  177. isp_read_reg(dev, REG_ADDR(isp_wdr3_value_weight));
  178. REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_0,
  179. slice_value_weight[0]);
  180. REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_1,
  181. slice_value_weight[1]);
  182. REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_2,
  183. slice_value_weight[2]);
  184. REG_SET_SLICE(isp_wdr3_value_weight, WDR3_VALUE_WEIGHT_3,
  185. slice_value_weight[3]);
  186. isp_write_reg(dev, REG_ADDR(isp_wdr3_value_weight),
  187. isp_wdr3_value_weight);
  188. isp_wdr3_strength = isp_read_reg(dev, REG_ADDR(isp_wdr3_strength));
  189. REG_SET_SLICE(isp_wdr3_strength, WDR3_MAXIMUM_GAIN, wdr3->max_gain);
  190. REG_SET_SLICE(isp_wdr3_strength, WDR3_GLOBAL_STRENGTH,
  191. wdr3->global_strength);
  192. REG_SET_SLICE(isp_wdr3_strength, WDR3_LOCAL_STRENGTH,
  193. 128);
  194. REG_SET_SLICE(isp_wdr3_strength, WDR3_TOTAL_STRENGTH, wdr3->strength);
  195. isp_write_reg(dev, REG_ADDR(isp_wdr3_strength), isp_wdr3_strength);
  196. isp_wdr3_pixel_slope =
  197. isp_read_reg(dev, REG_ADDR(isp_wdr3_pixel_slope));
  198. REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_ADJUST_BASE,
  199. slice_pixel_base_adjust);
  200. REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_ADJUST_SLOPE,
  201. slice_pixel_slope_adjust);
  202. REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_MERGE_BASE,
  203. slice_pixel_base_merge);
  204. REG_SET_SLICE(isp_wdr3_pixel_slope, WDR3_PIXEL_MERGE_SLOPE,
  205. slice_pixel_slope_merge);
  206. isp_write_reg(dev, REG_ADDR(isp_wdr3_pixel_slope),
  207. isp_wdr3_pixel_slope);
  208. isp_wdr3_entropy_slope =
  209. isp_read_reg(dev, REG_ADDR(isp_wdr3_entropy_slope));
  210. REG_SET_SLICE(isp_wdr3_entropy_slope, WDR3_ENTROPY_BASE,
  211. slice_pixel_base_entropy);
  212. REG_SET_SLICE(isp_wdr3_entropy_slope, WDR3_ENTROPY_SLOPE,
  213. slice_pixel_slope_entropy);
  214. isp_write_reg(dev, REG_ADDR(isp_wdr3_entropy_slope),
  215. isp_wdr3_entropy_slope);
  216. isp_wdr3_sigma_width =
  217. isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_width));
  218. REG_SET_SLICE(isp_wdr3_sigma_width, WDR3_BILITERAL_WIDTH_SIGMA,
  219. slice_sigma_width);
  220. isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_width),
  221. isp_wdr3_sigma_width);
  222. isp_wdr3_sigma_height =
  223. isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_height));
  224. REG_SET_SLICE(isp_wdr3_sigma_height, WDR3_BILITERAL_HEIGHT_SIGMA,
  225. slice_sigma_height);
  226. isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_height),
  227. isp_wdr3_sigma_height);
  228. isp_wdr3_sigma_value =
  229. isp_read_reg(dev, REG_ADDR(isp_wdr3_sigma_value));
  230. REG_SET_SLICE(isp_wdr3_sigma_value, WDR3_BILITERAL_VALUE_SIGMA,
  231. slice_sigma_value);
  232. isp_write_reg(dev, REG_ADDR(isp_wdr3_sigma_value),
  233. isp_wdr3_sigma_value);
  234. isp_write_reg(dev, REG_ADDR(isp_wdr3_block_flag_width),
  235. isp_wdr3_block_flag_width);
  236. isp_write_reg(dev, REG_ADDR(isp_wdr3_block_flag_height),
  237. isp_wdr3_block_flag_height);
  238. for (i = 0; i < 5; i++) {
  239. reg_flag = i < 4;
  240. pos = i * 3;
  241. val =
  242. wdr3->histogram[pos] << (reg_flag ?
  243. WDR3_HISTOGRAM_CURVE0_SHIFT :
  244. WDR3_HISTOGRAM_CURVE1_SHIFT);
  245. val |=
  246. wdr3->histogram[pos +
  247. 1] << (reg_flag ?
  248. WDR3_HISTOGRAM_CURVE1_SHIFT :
  249. WDR3_HISTOGRAM_CURVE2_SHIFT);
  250. if (reg_flag)
  251. REG_SET_SLICE(val, WDR3_HISTOGRAM_CURVE2,
  252. wdr3->histogram[pos + 2]);
  253. isp_write_reg(dev, REG_ADDR(isp_wdr3_histogram[i]), val);
  254. val =
  255. wdr3->entropy[pos] << (reg_flag ?
  256. WDR3_ENTROPY_CONVERT0_SHIFT :
  257. WDR3_ENTROPY_CONVERT1_SHIFT);
  258. val |=
  259. wdr3->entropy[pos +
  260. 1] << (reg_flag ? WDR3_ENTROPY_CONVERT1_SHIFT
  261. : WDR3_ENTROPY_CONVERT2_SHIFT);
  262. if (reg_flag)
  263. REG_SET_SLICE(val, WDR3_ENTROPY_CONVERT2,
  264. wdr3->entropy[pos + 2]);
  265. isp_write_reg(dev, REG_ADDR(isp_wdr3_entropy[i]), val);
  266. val =
  267. wdr3->gamma_pre[pos] << (reg_flag ?
  268. WDR3_GAMMA_PRE_CURVE0_SHIFT :
  269. WDR3_GAMMA_PRE_CURVE1_SHIFT);
  270. val |=
  271. wdr3->gamma_pre[pos +
  272. 1] << (reg_flag ?
  273. WDR3_GAMMA_PRE_CURVE1_SHIFT :
  274. WDR3_GAMMA_PRE_CURVE2_SHIFT);
  275. if (reg_flag)
  276. REG_SET_SLICE(val, WDR3_GAMMA_PRE_CURVE2,
  277. wdr3->gamma_pre[pos + 2]);
  278. isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_pre[i]), val);
  279. val =
  280. wdr3->gamma_up[pos] << (reg_flag ?
  281. WDR3_GAMMA_UP_CURVE0_SHIFT :
  282. WDR3_GAMMA_UP_CURVE1_SHIFT);
  283. val |=
  284. wdr3->gamma_up[pos +
  285. 1] << (reg_flag ? WDR3_GAMMA_UP_CURVE1_SHIFT
  286. : WDR3_GAMMA_UP_CURVE2_SHIFT);
  287. if (reg_flag)
  288. REG_SET_SLICE(val, WDR3_GAMMA_UP_CURVE2,
  289. wdr3->gamma_up[pos + 2]);
  290. isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_up[i]), val);
  291. val =
  292. wdr3->gamma_down[pos] << (reg_flag ?
  293. WDR3_GAMMA_DOWN_CURVE0_SHIFT :
  294. WDR3_GAMMA_DOWN_CURVE1_SHIFT);
  295. val |=
  296. wdr3->gamma_down[pos +
  297. 1] << (reg_flag ?
  298. WDR3_GAMMA_DOWN_CURVE1_SHIFT :
  299. WDR3_GAMMA_DOWN_CURVE2_SHIFT);
  300. if (reg_flag)
  301. REG_SET_SLICE(val, WDR3_GAMMA_DOWN_CURVE2,
  302. wdr3->gamma_down[pos + 2]);
  303. isp_write_reg(dev, REG_ADDR(isp_wdr3_gamma_down[i]), val);
  304. val =
  305. wdr3->distance_weight[pos] << (reg_flag ?
  306. WDR3_DISTANCE_WEIGHT_CURVE0_SHIFT
  307. :
  308. WDR3_DISTANCE_WEIGHT_CURVE1_SHIFT);
  309. val |=
  310. wdr3->distance_weight[pos +
  311. 1] << (reg_flag ?
  312. WDR3_DISTANCE_WEIGHT_CURVE1_SHIFT
  313. :
  314. WDR3_DISTANCE_WEIGHT_CURVE2_SHIFT);
  315. if (reg_flag)
  316. REG_SET_SLICE(val, WDR3_DISTANCE_WEIGHT_CURVE2,
  317. wdr3->distance_weight[pos + 2]);
  318. isp_write_reg(dev, REG_ADDR(isp_wdr3_distance_weight[i]), val);
  319. val =
  320. wdr3->difference_weight[pos] << (reg_flag ?
  321. WDR3_DIFFERENCE_WEIGHT_CURVE0_SHIFT
  322. :
  323. WDR3_DIFFERENCE_WEIGHT_CURVE1_SHIFT);
  324. val |=
  325. wdr3->difference_weight[pos +
  326. 1] << (reg_flag ?
  327. WDR3_DIFFERENCE_WEIGHT_CURVE1_SHIFT
  328. :
  329. WDR3_DIFFERENCE_WEIGHT_CURVE2_SHIFT);
  330. if (reg_flag)
  331. REG_SET_SLICE(val, WDR3_DIFFERENCE_WEIGHT_CURVE2,
  332. wdr3->difference_weight[pos + 2]);
  333. isp_write_reg(dev, REG_ADDR(isp_wdr3_difference_weight[i]),
  334. val);
  335. }
  336. for (i = 0; i < 7; i++) {
  337. val = 0;
  338. REG_SET_SLICE(val, WDR3_GLOBAL_CURVE_INVERT0,
  339. wdr3->invert_curve[i * 2]);
  340. REG_SET_SLICE(val, WDR3_GLOBAL_CURVE_INVERT1,
  341. wdr3->invert_curve[i * 2 + 1]);
  342. isp_write_reg(dev, REG_ADDR(isp_wdr3_invert_curve[i]), val);
  343. val = 0;
  344. REG_SET_SLICE(val, WDR3_LINEAR_CURVE_INVERT0,
  345. wdr3->invert_linear[i * 2]);
  346. REG_SET_SLICE(val, WDR3_LINEAR_CURVE_INVERT1,
  347. wdr3->invert_linear[i * 2 + 1]);
  348. isp_write_reg(dev, REG_ADDR(isp_wdr3_invert_linear[i]), val);
  349. }
  350. isp_wdr3_shift_0 = 0;
  351. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT0, wdr3->shift[0]);
  352. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT1, wdr3->shift[1]);
  353. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT2, wdr3->shift[2]);
  354. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT3, wdr3->shift[3]);
  355. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT4, wdr3->shift[4]);
  356. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT5, wdr3->shift[5]);
  357. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT6, wdr3->shift[6]);
  358. REG_SET_SLICE(isp_wdr3_shift_0, WDR3_HISTOGRAM_SHIFT7, wdr3->shift[7]);
  359. isp_write_reg(dev, REG_ADDR(isp_wdr3_shift_0), isp_wdr3_shift_0);
  360. isp_wdr3_shift_1 = 0;
  361. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT8, wdr3->shift[8]);
  362. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT9, wdr3->shift[9]);
  363. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT10,
  364. wdr3->shift[10]);
  365. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT11,
  366. wdr3->shift[11]);
  367. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT12,
  368. wdr3->shift[12]);
  369. REG_SET_SLICE(isp_wdr3_shift_1, WDR3_HISTOGRAM_SHIFT13,
  370. wdr3->shift[13]);
  371. isp_write_reg(dev, REG_ADDR(isp_wdr3_shift_1), isp_wdr3_shift_1);
  372. {
  373. uint32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
  374. REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 1);
  375. isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
  376. }
  377. }
  378. #endif
  379. int isp_enable_wdr3(struct isp_ic_dev *dev)
  380. {
  381. #ifndef ISP_WDR_V3
  382. pr_err("unsupported function: %s", __func__);
  383. return -EINVAL;
  384. #else
  385. struct isp_wdr3_context *wdr3 = &dev->wdr3;
  386. int32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
  387. wdr3->enable = true;
  388. REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 1);
  389. isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
  390. {
  391. uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
  392. REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
  393. isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
  394. }
  395. return 0;
  396. #endif
  397. }
  398. int isp_disable_wdr3(struct isp_ic_dev *dev)
  399. {
  400. #ifndef ISP_WDR_V3
  401. pr_err("unsupported function: %s", __func__);
  402. return -EINVAL;
  403. #else
  404. struct isp_wdr3_context *wdr3 = &dev->wdr3;
  405. int32_t isp_wdr3_ctrl = isp_read_reg(dev, REG_ADDR(isp_wdr3_ctrl));
  406. wdr3->enable = false;
  407. REG_SET_SLICE(isp_wdr3_ctrl, WDR3_ENABLE, 0);
  408. isp_write_reg(dev, REG_ADDR(isp_wdr3_ctrl), isp_wdr3_ctrl);
  409. {
  410. uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
  411. REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
  412. isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
  413. }
  414. return 0;
  415. #endif
  416. }
  417. int isp_u_wdr3(struct isp_ic_dev *dev)
  418. {
  419. #ifndef ISP_WDR_V3
  420. pr_err("unsupported function: %s", __func__);
  421. return -EINVAL;
  422. #else
  423. wdr3_hw_init(dev);
  424. return 0;
  425. #endif
  426. }
  427. int isp_s_wdr3(struct isp_ic_dev *dev)
  428. {
  429. #ifndef ISP_WDR_V3
  430. pr_err("unsupported function: %s", __func__);
  431. return -EINVAL;
  432. #else
  433. struct isp_wdr3_context *wdr3 = &dev->wdr3;
  434. u32 isp_wdr3_strength = isp_read_reg(dev, REG_ADDR(isp_wdr3_strength));
  435. u32 width = isp_read_reg(dev, REG_ADDR(isp_acq_h_size));
  436. u32 height = isp_read_reg(dev, REG_ADDR(isp_acq_v_size));
  437. width /= 32;
  438. height /= 32;
  439. REG_SET_SLICE(isp_wdr3_strength, WDR3_MAXIMUM_GAIN, wdr3->max_gain);
  440. REG_SET_SLICE(isp_wdr3_strength, WDR3_GLOBAL_STRENGTH,
  441. wdr3->global_strength);
  442. REG_SET_SLICE(isp_wdr3_strength, WDR3_LOCAL_STRENGTH, 128);
  443. REG_SET_SLICE(isp_wdr3_strength, WDR3_TOTAL_STRENGTH, wdr3->strength);
  444. isp_write_reg(dev, REG_ADDR(isp_wdr3_block_size),
  445. width | (height << 9));
  446. isp_write_reg(dev, REG_ADDR(isp_wdr3_strength), isp_wdr3_strength);
  447. isp_write_reg(dev, REG_ADDR(isp_wdr3_strength_shd), isp_wdr3_strength); /* cmodel use */
  448. {
  449. uint32_t isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
  450. REG_SET_SLICE(isp_ctrl, MRV_ISP_ISP_GEN_CFG_UPD, 1);
  451. isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
  452. }
  453. return 0;
  454. #endif
  455. }