isp_miv2.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  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_MIV2_RY
  61. static void mi_set_slice(u32* val, u32 mask, u32 slice);
  62. extern MrvAllRegister_t *all_regs;
  63. static int getRawBit(u32 type, u32 *bit, u32 *len)
  64. {
  65. *len = 16;
  66. switch (type) {
  67. case ISP_PICBUF_TYPE_RAW8:
  68. *bit = 0;
  69. *len = 8;
  70. break;
  71. #if 1
  72. case ISP_PICBUF_TYPE_RAW10:
  73. *bit = 1;
  74. break;
  75. case ISP_PICBUF_TYPE_RAW12:
  76. *bit = 2;
  77. break;
  78. case ISP_PICBUF_TYPE_RAW14:
  79. *bit = 3;
  80. break;
  81. case ISP_PICBUF_TYPE_RAW16:
  82. *bit = 4;
  83. break;
  84. #else /* WA */
  85. case ISP_PICBUF_TYPE_RAW10:
  86. case ISP_PICBUF_TYPE_RAW12:
  87. case ISP_PICBUF_TYPE_RAW14:
  88. case ISP_PICBUF_TYPE_RAW16:
  89. *bit = 4;
  90. break;
  91. #endif
  92. default:
  93. pr_err("unsupport raw formt: %d\n", type);
  94. return -1;
  95. }
  96. return 0;
  97. }
  98. static bool isYuv(int type)
  99. {
  100. return (type == ISP_PICBUF_TYPE_YCbCr444) ||
  101. (type == ISP_PICBUF_TYPE_YCbCr422) ||
  102. (type == ISP_PICBUF_TYPE_YCbCr420) ||
  103. (type == ISP_PICBUF_TYPE_YCbCr400);
  104. }
  105. static bool isRaw(u32 type)
  106. {
  107. return (type == ISP_PICBUF_TYPE_RAW8) ||
  108. (type == ISP_PICBUF_TYPE_RAW10) ||
  109. (type == ISP_PICBUF_TYPE_RAW12) ||
  110. (type == ISP_PICBUF_TYPE_RAW14) || (type == ISP_PICBUF_TYPE_RAW16);
  111. }
  112. static void set_rgb_buffer(struct isp_ic_dev *dev, struct isp_buffer_context *buf)
  113. {
  114. u32 addr = buf->path == 0 ? REG_ADDR(miv2_mp_y_base_ad_init) :
  115. (buf->path ==
  116. 1) ? REG_ADDR(miv2_sp1_y_base_ad_init) :
  117. REG_ADDR(miv2_sp2_y_base_ad_init);
  118. if (buf->type == ISP_PICBUF_TYPE_RGB888) {
  119. isp_write_reg(dev, addr, (buf->addr_y & MP_Y_BASE_AD_MASK));
  120. isp_write_reg(dev, addr + 1 * 4,
  121. (buf->size_y & MP_Y_SIZE_MASK));
  122. isp_write_reg(dev, addr + 2 * 4, 0);
  123. isp_write_reg(dev, addr + 7 * 4,
  124. (buf->addr_cb & MP_CB_BASE_AD_MASK));
  125. isp_write_reg(dev, addr + 8 * 4,
  126. (buf->size_cb & MP_CB_SIZE_MASK));
  127. isp_write_reg(dev, addr + 9 * 4, 0);
  128. isp_write_reg(dev, addr + 10 * 4,
  129. (buf->addr_cr & MP_CR_BASE_AD_MASK));
  130. isp_write_reg(dev, addr + 11 * 4,
  131. (buf->size_cr & MP_CR_SIZE_MASK));
  132. isp_write_reg(dev, addr + 12 * 4, 0);
  133. }
  134. }
  135. /*#define PP_LINE_ENTRY*/
  136. #define PP_LINE_NUM 80*2
  137. static void set_yuv_buffer(struct isp_ic_dev *dev, struct isp_buffer_context *buf)
  138. {
  139. u32 addr = buf->path == 0 ? REG_ADDR(miv2_mp_y_base_ad_init) :
  140. (buf->path == 1) ? REG_ADDR(miv2_sp1_y_base_ad_init) :
  141. (buf->path == 2) ? REG_ADDR(miv2_sp2_y_base_ad_init) :
  142. REG_ADDR(isp_mi_pp_y_base_ad_init);
  143. if (isYuv(buf->type)) {
  144. isp_write_reg(dev, addr, (buf->addr_y & MP_Y_BASE_AD_MASK));
  145. isp_write_reg(dev, addr + 1 * 4,
  146. (buf->size_y & MP_Y_SIZE_MASK));
  147. isp_write_reg(dev, addr + 2 * 4, 0);
  148. isp_write_reg(dev, addr + 7 * 4,
  149. (buf->addr_cb & MP_CB_BASE_AD_MASK));
  150. isp_write_reg(dev, addr + 8 * 4,
  151. (buf->size_cb & MP_CB_SIZE_MASK));
  152. isp_write_reg(dev, addr + 9 * 4, 0);
  153. isp_write_reg(dev, addr + 10 * 4,
  154. (buf->addr_cr & MP_CR_BASE_AD_MASK));
  155. isp_write_reg(dev, addr + 11 * 4,
  156. (buf->size_cr & MP_CR_SIZE_MASK));
  157. isp_write_reg(dev, addr + 12 * 4, 0);
  158. }
  159. }
  160. static void set_raw_buffer(struct isp_ic_dev *dev, struct isp_buffer_context *buf)
  161. {
  162. u32 addr = buf->path == ISP_MI_PATH_MP ? REG_ADDR(miv2_mp_raw_base_ad_init) :
  163. (buf->path == ISP_MI_PATH_SP2_BP) ? REG_ADDR(miv2_sp2_raw_base_ad_init) :
  164. (buf->path == ISP_MI_PATH_PP) ?REG_ADDR(isp_mi_pp_y_base_ad_init):
  165. #ifdef ISP_MI_MCM_WR_RY
  166. (buf->path == ISP_MI_MCM_WR0) ?REG_ADDR(miv2_mcm_raw0_base_ad_init):
  167. (buf->path == ISP_MI_MCM_WR1) ?REG_ADDR(miv2_mcm_raw1_base_ad_init):
  168. #endif
  169. #ifdef ISP_MI_HDR_RY
  170. (buf->path == ISP_MI_HDR_L) ?REG_ADDR(isp_mi_hdr_l_base_ad_init):
  171. (buf->path == ISP_MI_HDR_S) ?REG_ADDR(isp_mi_hdr_s_base_ad_init):
  172. (buf->path == ISP_MI_HDR_VS) ?REG_ADDR(isp_mi_hdr_vs_base_ad_init):
  173. #endif
  174. 0;
  175. uint32_t line_num = isp_read_reg(dev, REG_ADDR(mi_sp1_ppw_ycbcr_entry_line_num));
  176. if ((buf->path == ISP_MI_PATH_PP) && (line_num != 0)) {
  177. buf->addr_y = dev->pp_write.buf_addr;
  178. buf->size_y = dev->pp_write.buf_size;
  179. }
  180. /*isp_info("%s path %d type %d addr %08x line_num = %d buf_addr = 0x%x, buf_size = %d\n",
  181. __func__, buf->path, buf->type, addr, line_num, buf->addr_y, buf->size_y);*/
  182. if (isRaw(buf->type)) {
  183. if (addr != 0) {
  184. isp_write_reg(dev, addr,
  185. (buf->addr_y & MP_RAW_BASE_AD_MASK));
  186. isp_write_reg(dev, addr + 4,
  187. (buf->size_y & MP_RAW_SIZE_MASK));
  188. isp_write_reg(dev, addr + 2 * 4, 0);
  189. }
  190. }
  191. }
  192. int isp_set_buffer(struct isp_ic_dev *dev, struct isp_buffer_context *buf)
  193. {
  194. if (!dev || !buf) {
  195. pr_err("NULL pointer %s\n", __func__);
  196. return -1;
  197. }
  198. set_yuv_buffer(dev, buf);
  199. set_raw_buffer(dev, buf);
  200. set_rgb_buffer(dev, buf);
  201. return 0;
  202. }
  203. static int calc_raw_lval(int width, int out_mode, int align_mode)
  204. {
  205. u32 lval = 0;
  206. if (align_mode == ISP_MI_DATA_ALIGN_16BIT_MODE) {
  207. if ((out_mode == IC_MI_DATAMODE_RAW10) ||
  208. (out_mode == IC_MI_DATAMODE_RAW12) ||
  209. (out_mode == IC_MI_DATAMODE_RAW14)) {
  210. lval = (width + 7) / 8;
  211. }
  212. } else if (align_mode == ISP_MI_DATA_ALIGN_128BIT_MODE) {
  213. if (out_mode == IC_MI_DATAMODE_RAW10){
  214. lval = (width + 12 - 1)/12;
  215. }else if(out_mode == IC_MI_DATAMODE_RAW12){
  216. lval = (width + 10 - 1)/10;
  217. }else if(out_mode == IC_MI_DATAMODE_RAW14){
  218. lval = (width + 9 - 1)/9;
  219. }else{
  220. lval = (width + 128 - 1)/128;
  221. }
  222. } else {
  223. if (out_mode == IC_MI_DATAMODE_RAW10) {
  224. lval = (width * 10 + 127) / 128;
  225. } else if (out_mode == IC_MI_DATAMODE_RAW12) {
  226. lval = (width * 12 + 127) / 128;
  227. } else if (out_mode == IC_MI_DATAMODE_RAW14) {
  228. lval = (width * 14 + 127) / 128;
  229. } else if (out_mode == IC_MI_DATAMODE_RAW16) {
  230. lval = (width * 16 + 127) / 128;
  231. } else {
  232. lval = (width * 8 + 127) / 128;
  233. }
  234. }
  235. return lval;
  236. }
  237. struct isp_dma_path_context{
  238. u32 ctrl_addr;
  239. u32 fmt_addr;
  240. u32 bus_cfg_addr;
  241. u32 bus_id_addr;
  242. u32 mi_imsc_addr;
  243. u32 rd_fmt_align;
  244. u32 rd_raw_bit;
  245. u32 rd_cfg_upd;
  246. u32 rd_auto_upd;
  247. u32 pic_start_addr;
  248. u32 pic_width;
  249. u32 pic_height;
  250. u32 pic_llength;
  251. u32 pic_size;
  252. u32 pic_lval;
  253. u32 path_enable_mask;
  254. u32 path_dma_start_mask;
  255. };
  256. int isp_ioc_cfg_dma(struct isp_ic_dev *dev, void __user *args)
  257. {
  258. u32 llength, miv2_imsc, miv2_ctrl,path_ctrl,path_fmt;
  259. struct isp_dma_context dma;
  260. //u32 path_bus_cfg;
  261. u32 bus_id;
  262. u32 path_rd_fmt_bit = 0;
  263. u8 id;
  264. struct isp_dma_path_context dma_path_ctx[] =
  265. #ifndef ISP_MI_PP_READ_RY
  266. {{REG_ADDR(miv2_mcm_ctrl), REG_ADDR(miv2_mcm_fmt), REG_ADDR(miv2_mcm_bus_cfg), REG_ADDR(miv2_mcm_bus_id),
  267. REG_ADDR(miv2_imsc), MCM_RD_FMT_ALIGNED_MASK, MCM_RD_RAW_BIT_MASK, MCM_RD_CFG_UPD_MASK, MCM_RD_AUTO_UPDATE_MASK, \
  268. REG_ADDR(miv2_mcm_dma_raw_pic_start_ad), REG_ADDR(miv2_mcm_dma_raw_pic_width), 0, \
  269. REG_ADDR(miv2_mcm_dma_raw_pic_llength), REG_ADDR(miv2_mcm_dma_raw_pic_size), \
  270. REG_ADDR(miv2_mcm_dma_raw_pic_lval), MCM_RAW_RDMA_PATH_ENABLE_MASK, MCM_RAW_RDMA_START_MASK},
  271. #ifdef ISP_MI_HDR_RY
  272. {REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(miv2_imsc2), \
  273. HDR_RD_RAW_ALIGNED_MASK, HDR_RD_L_BIT_MASK, HDR_RD_RAW_CFG_UPDATE_MASK,HDR_RD_RAW_CFG_UPDATE_MASK, \
  274. REG_ADDR(isp_mi_hdr_dma_l_base_ad_init), REG_ADDR(isp_mi_hdr_dma_pic_width), REG_ADDR(isp_mi_hdr_dma_pic_height), \
  275. REG_ADDR(isp_mi_hdr_dma_l_llength), REG_ADDR(isp_mi_hdr_dma_l_size_init), \
  276. REG_ADDR(isp_mi_hdr_dma_l_lval), 0, HDR_DMA_START_MASK},
  277. {REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(miv2_imsc2), \
  278. HDR_RD_RAW_ALIGNED_MASK, HDR_RD_S_BIT_MASK, HDR_RD_RAW_CFG_UPDATE_MASK,HDR_RD_RAW_CFG_UPDATE_MASK, \
  279. REG_ADDR(isp_mi_hdr_dma_s_base_ad_init), REG_ADDR(isp_mi_hdr_dma_pic_width), REG_ADDR(isp_mi_hdr_dma_pic_height), \
  280. REG_ADDR(isp_mi_hdr_dma_s_llength), REG_ADDR(isp_mi_hdr_dma_s_size_init), \
  281. REG_ADDR(isp_mi_hdr_dma_s_lval), 0, HDR_DMA_START_MASK},
  282. {REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(miv2_imsc2), \
  283. HDR_RD_RAW_ALIGNED_MASK, HDR_RD_VS_BIT_MASK, HDR_RD_RAW_CFG_UPDATE_MASK,HDR_RD_RAW_CFG_UPDATE_MASK, \
  284. REG_ADDR(isp_mi_hdr_dma_vs_base_ad_init), REG_ADDR(isp_mi_hdr_pic_width), REG_ADDR(isp_mi_hdr_dma_pic_height), \
  285. REG_ADDR(isp_mi_hdr_dma_vs_llength), REG_ADDR(isp_mi_hdr_dma_vs_size_init), \
  286. REG_ADDR(isp_mi_hdr_dma_vs_lval), 0, HDR_DMA_START_MASK}
  287. #endif
  288. };
  289. #else
  290. {{REG_ADDR(isp_mi_pp_ctrl), REG_ADDR(isp_mi_pp_fmt), 0, 0, REG_ADDR(miv2_imsc2), \
  291. PP_RD_RAW_ALIGNED_MASK, PP_RD_RAW_BIT_MASK, PP_MI_CFG_UPD_MASK, PP_RD_YUV_CFG_UPDATE_MASK, \
  292. REG_ADDR(isp_mi_pp_dma_y_pic_start_ad), REG_ADDR(isp_mi_pp_dma_y_pic_width), 0, \
  293. REG_ADDR(isp_mi_pp_dma_y_pic_llength), REG_ADDR(isp_mi_pp_dma_y_pic_size), \
  294. REG_ADDR(isp_mi_pp_dma_y_pic_lval), 0, PP_DMA_START_MASK}};
  295. #endif
  296. if (dev == NULL || args == NULL) {
  297. isp_info("input wrong parameter %s\n", __func__);
  298. return -1;
  299. }
  300. isp_info("enter %s\n", __func__);
  301. viv_check_retval(copy_from_user(&dma, args, sizeof(dma)));
  302. id = dma.id;
  303. if ( id > ISP_MI_DMA_ID_MAX){
  304. isp_info("id config wrong %s\n", __func__);
  305. return -1;
  306. }
  307. path_fmt = isp_read_reg(dev, dma_path_ctx[id].fmt_addr);
  308. #ifdef ISP_MI_PP_READ_RY
  309. path_fmt |= 0x80000000;
  310. #endif
  311. miv2_imsc = isp_read_reg(dev, dma_path_ctx[id].mi_imsc_addr);
  312. miv2_ctrl = isp_read_reg(dev, REG_ADDR(miv2_ctrl));
  313. path_ctrl = isp_read_reg(dev, dma_path_ctx[id].ctrl_addr);
  314. //if ( dma_path_ctx[id].bus_cfg_addr != 0) {
  315. // path_bus_cfg = isp_read_reg(dev, dma_path_ctx[id].bus_cfg_addr);
  316. //}
  317. if ( dma_path_ctx[id].bus_id_addr != 0) {
  318. bus_id = isp_read_reg(dev, dma_path_ctx[id].bus_id_addr);
  319. }
  320. if ( dma.align == ISP_MI_DATA_UNALIGN_MODE ) {
  321. switch(dma.type){
  322. case ISP_PICBUF_TYPE_RAW10:
  323. llength = calc_raw_lval(dma.width,IC_MI_DATAMODE_RAW10, ISP_MI_DATA_UNALIGN_MODE);
  324. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 1);
  325. break;
  326. case ISP_PICBUF_TYPE_RAW12:
  327. llength = calc_raw_lval(dma.width,IC_MI_DATAMODE_RAW12,ISP_MI_DATA_UNALIGN_MODE);
  328. if (id >= ISP_MI_DMA_ID_HDR_L && id <= ISP_MI_DMA_ID_HDR_VS) {
  329. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 0); //mi dma hdr stitch raw only support raw12 and raw16
  330. } else {
  331. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 2);
  332. }
  333. break;
  334. case ISP_PICBUF_TYPE_RAW14:
  335. llength = calc_raw_lval(dma.width,IC_MI_DATAMODE_RAW14, ISP_MI_DATA_UNALIGN_MODE);
  336. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 3);
  337. break;
  338. case ISP_PICBUF_TYPE_RAW16:
  339. llength = calc_raw_lval(dma.width,IC_MI_DATAMODE_RAW16, ISP_MI_DATA_UNALIGN_MODE);
  340. if (id >= ISP_MI_DMA_ID_HDR_L && id <= ISP_MI_DMA_ID_HDR_VS) {
  341. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 1); //mi dma hdr stitch raw only support raw12 and raw16
  342. } else {
  343. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, 4);
  344. }
  345. break;
  346. default:
  347. return -EFAULT;
  348. }
  349. llength <<= 4;
  350. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_fmt_align, dma.align);
  351. } else {
  352. getRawBit(dma.type, &path_rd_fmt_bit, &llength); //The old version load all kinds of raw format with raw16 format except raw8
  353. llength = dma.width * llength / 8;
  354. if (id >= ISP_MI_DMA_ID_HDR_L && id <= ISP_MI_DMA_ID_HDR_VS) {
  355. path_rd_fmt_bit = 1;
  356. }
  357. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_raw_bit, path_rd_fmt_bit);
  358. mi_set_slice(&path_fmt, dma_path_ctx[id].rd_fmt_align, dma.align); // 2:align mode1
  359. }
  360. /* if (llength != 8)
  361. REG_SET_SLICE(mcm_bus_cfg, MCM_RD_SWAP_RAW, 1);*/
  362. //path_ctrl |= PP_RD_YUV_CFG_UPDATE_MASK; //PP_INIT_OFFSET_EN_MASK | PP_INIT_BASE_EN_MASK |
  363. #ifdef POST_ISP_SDK_TEST
  364. isp_write_reg(dev, dma_path_ctx[id].pic_start_addr, (MCM_DMA_RAW_PIC_START_AD_MASK & dma.base));
  365. #endif
  366. isp_write_reg(dev,dma_path_ctx[id].pic_width, (MCM_DMA_RAW_PIC_WIDTH_MASK & dma.width));
  367. if (dma_path_ctx[id].pic_height) {
  368. isp_write_reg(dev,dma_path_ctx[id].pic_height, dma.height);
  369. }
  370. isp_write_reg(dev, dma_path_ctx[id].pic_llength, (MCM_DMA_RAW_PIC_LLENGTH_MASK & llength));
  371. isp_write_reg(dev,dma_path_ctx[id].pic_size, (MCM_DMA_RAW_PIC_SIZE_MASK & (llength * dma.height)));
  372. isp_write_reg(dev, dma_path_ctx[id].pic_lval, (MCM_DMA_RAW_PIC_WIDTH_MASK & llength));
  373. isp_write_reg(dev, dma_path_ctx[id].fmt_addr, path_fmt);
  374. //isp_write_reg(dev, REG_ADDR(miv2_mcm_bus_cfg), path_bus_cfg);
  375. #ifdef ISP_MI_PP_READ_RY
  376. isp_write_reg(dev, REG_ADDR(mi_pp_dma_y_pic_height), dma.height);
  377. isp_write_reg(dev, REG_ADDR(mi_pp_y_lval_bytes), llength);
  378. // isp_write_reg(dev, 0x55c0, dma.height);
  379. // isp_write_reg(dev, 0x55c4, dma.height);
  380. // isp_write_reg(dev, 0x55c8, dma.height);
  381. // isp_write_reg(dev, 0x55cc, llength);
  382. //isp_write_reg(dev, dma_path_ctx[id].mi_imsc_addr, miv2_imsc | PPR_DMA_READY_MASK); /* modify by wuyi for line entry mode enabled pp dma */
  383. #else
  384. isp_write_reg(dev, dma_path_ctx[id].mi_imsc_addr, miv2_imsc | 0x01800025); /* enabled jdp, sp2_raw, mp_raw, mcm */
  385. #endif
  386. if(id == ISP_MI_DMA_ID_MCM_PP) {
  387. miv2_ctrl |= (dma_path_ctx[id].path_enable_mask );//| dma_path_ctx[id].path_dma_start_mask);
  388. //path_ctrl |= 0xfa;
  389. mi_set_slice(&path_ctrl, dma_path_ctx[id].rd_cfg_upd, 1);
  390. mi_set_slice(&path_ctrl, dma_path_ctx[id].rd_auto_upd, 1);
  391. REG_SET_SLICE(bus_id, MCM_BUS_SW_EN, 1);
  392. REG_SET_SLICE(bus_id, MCM_RD_ID_EN, 1);
  393. if (dma_path_ctx[id].bus_id_addr) {
  394. isp_write_reg(dev, dma_path_ctx[id].bus_id_addr, bus_id);
  395. }
  396. isp_write_reg(dev,dma_path_ctx[id].ctrl_addr, path_ctrl);
  397. isp_write_reg(dev, REG_ADDR(miv2_ctrl), miv2_ctrl);
  398. #ifdef ISP_MI_HDR_RY
  399. } else {
  400. REG_SET_SLICE(path_fmt, HDR_RD_STR, dma.rd_wr_str);
  401. //config wr str, l,s,vs bit and wr raw aligned same with rd str,l,s,vs bit and wr raw aligned
  402. path_fmt |= ((path_fmt >> HDR_RD_STR_SHIFT) &0x3ff) ;
  403. isp_write_reg(dev, dma_path_ctx[id].fmt_addr, path_fmt);
  404. /*hdr mi dma path enable in mi hdr ctrl register*/
  405. path_ctrl |= (dma_path_ctx[id].path_enable_mask) ; //| dma_path_ctx[id].path_dma_start_mask);
  406. REG_SET_SLICE(path_ctrl, HDR_INIT_OFFSET_EN, 1);
  407. REG_SET_SLICE(path_ctrl, HDR_INIT_BASE_EN, 1);
  408. REG_SET_SLICE(bus_id, HDR_BUS_SW_EN, 1);
  409. REG_SET_SLICE(bus_id, HDR_RD_ID_EN, 1);
  410. if (dma_path_ctx[id].bus_id_addr) {
  411. isp_write_reg(dev, dma_path_ctx[id].bus_id_addr, bus_id);
  412. }
  413. isp_write_reg(dev,dma_path_ctx[id].ctrl_addr, path_ctrl);
  414. #endif
  415. }
  416. return 0;
  417. }
  418. /* only support read raw */
  419. int isp_ioc_start_dma_read(struct isp_ic_dev *dev, void __user *args)
  420. {
  421. start_dma_path_t dma_path;
  422. u32 mi_hdr_fmt;
  423. u32 mi_path_ctrl;
  424. u32 mi_hdr_ret_ctrl;
  425. u32 rd_wr_str;
  426. if (dev == NULL || args == NULL) {
  427. isp_info("input wrong parameter %s\n", __func__);
  428. return -1;
  429. }
  430. isp_info("enter %s\n", __func__);
  431. viv_check_retval(copy_from_user(&dma_path, args, sizeof(dma_path)));
  432. if (dma_path == ISP_MI_DMA_PATH_MCM_PP) {
  433. #ifndef ISP_MI_PP_READ_RY
  434. mi_path_ctrl = isp_read_reg(dev,REG_ADDR(miv2_ctrl));
  435. REG_SET_SLICE(mi_path_ctrl, MCM_RAW_RDMA_START, 1);
  436. isp_write_reg(dev,REG_ADDR(miv2_ctrl), mi_path_ctrl);
  437. #else
  438. mi_path_ctrl = isp_read_reg(dev,REG_ADDR(miv2_ctrl));
  439. #ifdef POST_ISP_SDK_TEST
  440. REG_SET_SLICE(mi_path_ctrl, PP_DMA_START, 1);/*add by shenwuyi must open for sdk test case*/
  441. #endif
  442. isp_write_reg(dev,REG_ADDR(miv2_ctrl), mi_path_ctrl);
  443. #endif
  444. } else if (dma_path == ISP_MI_DMA_PATH_HDR) {
  445. isp_write_reg(dev, REG_ADDR(isp_mi_hdr_ret_bus_timeo), 0x00000001); //disable bus time out interrupt
  446. mi_hdr_ret_ctrl = isp_read_reg(dev,REG_ADDR(isp_hdr_ret_ctrl));
  447. REG_SET_SLICE(mi_hdr_ret_ctrl, HDR_RT_VSYNC_POL, 1);
  448. REG_SET_SLICE(mi_hdr_ret_ctrl, HDR_RETIMING_ENABLE, 1);
  449. REG_SET_SLICE(mi_hdr_ret_ctrl, DUMP_MODE_EN, 1);
  450. mi_hdr_fmt = isp_read_reg(dev,REG_ADDR(isp_mi_hdr_fmt));
  451. rd_wr_str = (mi_hdr_fmt & HDR_RD_STR_MASK)>>HDR_RD_STR_SHIFT;
  452. if (rd_wr_str == 0) {
  453. REG_SET_SLICE(mi_hdr_ret_ctrl, EXPOSURE_COUNT, 1);
  454. } else if (rd_wr_str == 1|| rd_wr_str == 3) {
  455. REG_SET_SLICE(mi_hdr_ret_ctrl, EXPOSURE_COUNT, 2);
  456. if (rd_wr_str == 3) {
  457. REG_SET_SLICE(mi_hdr_ret_ctrl, L_VS_COMBINING_ENABLE, 1);
  458. }
  459. } else if (rd_wr_str == 2) {
  460. REG_SET_SLICE(mi_hdr_ret_ctrl, EXPOSURE_COUNT, 0);
  461. }
  462. isp_write_reg(dev, REG_ADDR(isp_mi_hdr_dma_start_by_lines), 0x360);//0x10); //the written lines count of the last appearing frame after which start dma read
  463. isp_write_reg(dev,REG_ADDR(isp_hdr_ret_ctrl), mi_hdr_ret_ctrl);
  464. mi_path_ctrl = isp_read_reg(dev,REG_ADDR(isp_mi_hdr_ctrl));
  465. REG_SET_SLICE(mi_path_ctrl, HDR_RD_RAW_CFG_UPDATE, 1);
  466. REG_SET_SLICE(mi_path_ctrl, HDR_RD_RAW_AUTO_UPDATE, 1);
  467. REG_SET_SLICE(mi_path_ctrl, HDR_DMA_START, 1);
  468. isp_write_reg(dev,REG_ADDR(isp_mi_hdr_ctrl), mi_path_ctrl);
  469. }
  470. return 0;
  471. }
  472. #define PATHNUM ISP_MI_PATH_ID_MAX// hw related
  473. // only config write bits, SP2 read bit at 3dnr.c
  474. // read defined is same as write
  475. struct miv2_format_bit {
  476. u32 nyv, nv12;
  477. u32 raw_aligned, yuv_aligned;
  478. u32 raw_bit, yuv_str;
  479. u32 yuv_fmt, yuv_bit, jdp_fmt;
  480. };
  481. static struct miv2_format_bit fmt_bit[PATHNUM] = {
  482. {
  483. .nyv = 3 << 13, .nv12 = 1 << 12,
  484. .raw_aligned = 3 << 10,
  485. .yuv_aligned = 1 << 9,
  486. .raw_bit = 7 << 6,
  487. .yuv_str = 3 << 4,
  488. .yuv_fmt = 3 << 2,
  489. .yuv_bit = 1 << 1,
  490. .jdp_fmt = 1,
  491. },
  492. {
  493. .nyv = 3 << 7,
  494. .nv12 = 1 << 6,
  495. .yuv_aligned = 1 << 5,
  496. .yuv_str = 3 << 3,
  497. .yuv_fmt = 3 << 1,
  498. .yuv_bit = 1,
  499. },
  500. {
  501. .nyv = 3 << 12,
  502. .nv12 = 1 << 11,
  503. .raw_aligned = 3 << 9,
  504. .yuv_aligned = 1 << 8,
  505. .raw_bit = 7 << 5,
  506. .yuv_str = 3 << 3,
  507. .yuv_fmt = 3 << 1,
  508. .yuv_bit = 1,
  509. },
  510. #ifdef ISP_MI_MCM_WR_RY
  511. {
  512. .nyv = 0,
  513. .nv12 = 0,
  514. .raw_aligned = 3 << 14,
  515. .raw_bit = 3 << 4,
  516. .yuv_aligned = 0,
  517. .yuv_str = 0,
  518. .yuv_fmt = 0,
  519. .yuv_bit = 0,
  520. },
  521. {
  522. .nyv = 0,
  523. .nv12 = 0,
  524. .raw_aligned = 3 << 16,
  525. .raw_bit = 3 << 8,
  526. .yuv_aligned = 0,
  527. .yuv_str = 0,
  528. .yuv_fmt = 0,
  529. .yuv_bit = 0,
  530. },
  531. #endif
  532. #ifdef ISP_MI_PP_WRITE_RY
  533. {
  534. .nyv = 3 << 7,
  535. .nv12 = 1 << 6,
  536. .raw_aligned = 3 << 14,
  537. .raw_bit = 7 << 11,
  538. .yuv_aligned = 1 << 5,
  539. .yuv_str = 3 << 3,
  540. .yuv_fmt = 3 << 1,
  541. .yuv_bit = 1,
  542. },
  543. #endif
  544. #ifdef ISP_MI_HDR_RY
  545. {
  546. .nyv = 0,
  547. .nv12 = 0,
  548. .raw_aligned = 3 << 8,
  549. .raw_bit = 3 << 2,
  550. .yuv_aligned = 0,
  551. .yuv_str = 0,
  552. .yuv_fmt = 0,
  553. .yuv_bit = 0,
  554. },
  555. {
  556. .nyv = 0,
  557. .nv12 = 0,
  558. .raw_aligned = 3 << 8,
  559. .raw_bit = 3 << 4,
  560. .yuv_aligned = 0,
  561. .yuv_str = 0,
  562. .yuv_fmt = 0,
  563. .yuv_bit = 0,
  564. },
  565. {
  566. .nyv = 0,
  567. .nv12 = 0,
  568. .raw_aligned = 3 << 8,
  569. .raw_bit = 3 << 6,
  570. .yuv_aligned = 0,
  571. .yuv_str = 0,
  572. .yuv_fmt = 0,
  573. .yuv_bit = 0,
  574. },
  575. #endif
  576. };
  577. static u32 bit_shift(u32 i) {
  578. u32 shift = 0;
  579. while(!(i&1)) {
  580. shift++;
  581. i >>= 1;
  582. }
  583. return shift;
  584. }
  585. void mi_set_slice(u32* val, u32 mask, u32 slice)
  586. {
  587. // mp, sp1, sp2 mcm postpath have different masks.
  588. if (mask) {
  589. *val &= ~mask;
  590. *val |= (slice << bit_shift(mask));
  591. }
  592. }
  593. struct miv2_path_address {
  594. u32 bus_cfg_addr;
  595. u32 bus_id_addr;
  596. u32 bus_timeo_addr; //axi bus time out waiting ctrl register
  597. u32 path_ctrl_addr;
  598. u32 format_addr;
  599. u32 y_length_addr;
  600. u32 raw_llength_addr;
  601. u32 raw_pic_width_addr;
  602. u32 raw_pic_height_addr;
  603. u32 raw_pic_size_addr;
  604. u32 ycbcr_enable_bit;
  605. u32 raw_enable_bit;
  606. u32 format_conv_ctrl;
  607. u32 wr_raw_swap_bit;
  608. };
  609. static void disable_bus_timeo_intr(struct isp_ic_dev *dev, u32 bus_addr)
  610. {
  611. u32 val;
  612. isp_info("%s bus timeo interrupt register addr 0x%08x\n", __func__, bus_addr);
  613. val = isp_read_reg(dev, bus_addr);
  614. REG_SET_SLICE(val, MP_BUS_TIMEO_INTERRUPT_DISABLE, 1);
  615. isp_write_reg(dev, bus_addr, val);
  616. }
  617. static void set_data_path(int id, struct isp_mi_data_path_context *path,
  618. struct isp_ic_dev *dev)
  619. {
  620. u32 bus_cfg, bus_id;
  621. u32 format;
  622. u32 miv2_ctrl;
  623. u32 path_ctrl;
  624. u32 lval;
  625. u32 acq_proc;
  626. u32 mcm_bus_cfg = isp_read_reg(dev, REG_ADDR(miv2_mcm_bus_cfg));
  627. u32 conv_format_ctrl = 0;
  628. u32 y_length_addr;
  629. u32 y_llength = 0;
  630. #ifdef ISP_MI_PP_WRITE_RY
  631. u32 isp_ctrl;
  632. #endif
  633. // please take care the register order
  634. #if 0
  635. struct miv2_path_address path_list[PATHNUM] = {
  636. { 0x1318, 0x131c, 0x1310, 0x1314, 0x1330, 0x13a0, 0x13a4, 0x13a8, 0x13ac, 1, 0x0c6c },
  637. { 0x1434, 0x1438, 0x142c, 0x1430, 0x144c, 0, 0, 0, 8, 0x106c },
  638. { 0x14ec, 0x14f0, 0x14e4, 0x14e8, 0x1504, 0x1574, 0x1578, 0x157c, 0x1580, 0x10, 0x116c },
  639. };
  640. #else
  641. //id 0 is mp path;id 1 is sp path;id 2 is sp2 path;
  642. //id 3 is post process path write;
  643. struct miv2_path_address path_list[PATHNUM] = {
  644. {
  645. REG_ADDR(miv2_mp_bus_cfg), REG_ADDR(miv2_mp_bus_id), REG_ADDR(miv2_mp_bus_timeo), REG_ADDR(miv2_mp_ctrl),
  646. REG_ADDR(miv2_mp_fmt), REG_ADDR(miv2_mp_y_llength), REG_ADDR(miv2_mp_raw_llength),
  647. REG_ADDR(miv2_mp_raw_pic_width), REG_ADDR(miv2_mp_raw_pic_height), REG_ADDR(miv2_mp_raw_pic_size),
  648. MP_YCBCR_PATH_ENABLE_MASK, MP_RAW_PATH_ENABLE_MASK, REG_ADDR(mrsz_format_conv_ctrl), MP_WR_SWAP_RAW_MASK
  649. },
  650. {
  651. REG_ADDR(miv2_sp1_bus_cfg), REG_ADDR(miv2_sp1_bus_id), REG_ADDR(miv2_sp1_bus_timeo), REG_ADDR(miv2_sp1_ctrl),
  652. REG_ADDR(miv2_sp1_fmt), REG_ADDR(miv2_sp1_y_llength), 0,
  653. 0, 0, 0,
  654. SP1_YCBCR_PATH_ENABLE_MASK, 0, REG_ADDR(srsz_phase_format_conv_ctr), 0,
  655. },
  656. {
  657. REG_ADDR(miv2_sp2_bus_cfg), REG_ADDR(miv2_sp2_bus_id), REG_ADDR(miv2_sp2_bus_timeo), REG_ADDR(miv2_sp2_ctrl),
  658. REG_ADDR(miv2_sp2_fmt), REG_ADDR(miv2_sp2_y_llength), REG_ADDR(miv2_sp2_raw_llength),
  659. REG_ADDR(miv2_sp2_raw_pic_width), REG_ADDR(miv2_sp2_raw_pic_height), REG_ADDR(miv2_sp2_raw_pic_size),
  660. SP2_YCBCR_PATH_ENABLE_MASK, SP2_RAW_PATH_ENABLE_MASK, REG_ADDR(srsz2_phase_format_conv_ctr),
  661. SP2_WR_SWAP_RAW_MASK
  662. },
  663. #ifdef ISP_MI_MCM_WR_RY
  664. {
  665. REG_ADDR(miv2_mcm_bus_cfg), REG_ADDR(miv2_mcm_bus_id), REG_ADDR(miv2_mcm_bus_timeo), REG_ADDR(miv2_mcm_ctrl),
  666. REG_ADDR(miv2_mcm_fmt), 0, REG_ADDR(miv2_mcm_raw0_llength),
  667. REG_ADDR(miv2_mcm_raw0_pic_width), REG_ADDR(miv2_mcm_raw0_pic_height), REG_ADDR(miv2_mcm_raw0_pic_size),
  668. 0, MCM_RAW0_PATH_ENABLE_MASK, 0, MCM_WR0_SWAP_RAW_MASK
  669. },
  670. {
  671. REG_ADDR(miv2_mcm_bus_cfg), REG_ADDR(miv2_mcm_bus_id), REG_ADDR(miv2_mcm_bus_timeo), REG_ADDR(miv2_mcm_ctrl),
  672. REG_ADDR(miv2_mcm_fmt), 0, REG_ADDR(miv2_mcm_raw1_llength),
  673. REG_ADDR(miv2_mcm_raw1_pic_width), REG_ADDR(miv2_mcm_raw1_pic_height), REG_ADDR(miv2_mcm_raw1_pic_size),
  674. 0, MCM_RAW1_PATH_ENABLE_MASK, 0, MCM_WR1_SWAP_RAW_MASK
  675. },
  676. #endif
  677. {
  678. REG_ADDR(isp_mi_pp_data_swap), REG_ADDR(miv2_sp1_bus_id), REG_ADDR(miv2_sp1_bus_timeo), REG_ADDR(isp_mi_pp_ctrl),
  679. REG_ADDR(isp_mi_pp_fmt), REG_ADDR(isp_mi_pp_y_llength), REG_ADDR(mi_pp_y_lval_bytes),
  680. REG_ADDR(isp_mi_pp_y_pic_width), REG_ADDR(isp_mi_pp_y_pic_height), REG_ADDR(isp_mi_pp_y_pic_size),
  681. PP_WRITE_PATH_ENABLE_MASK, PP_WRITE_PATH_ENABLE_MASK, 0,PP_WR_SWAP_Y_MASK
  682. },
  683. #ifdef ISP_MI_HDR_RY
  684. {
  685. REG_ADDR(isp_mi_hdr_ret_bus_cfg), REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(isp_mi_hdr_ret_bus_timeo),
  686. REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_l_llength),
  687. REG_ADDR(isp_mi_hdr_pic_width), REG_ADDR(isp_mi_hdr_pic_height), REG_ADDR(isp_mi_hdr_l_size_init),
  688. 0, HDR_WR_ENABLE_MASK, 0, HDR_WR_SWAP_RAW_MASK
  689. },
  690. {
  691. REG_ADDR(isp_mi_hdr_ret_bus_cfg), REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(isp_mi_hdr_ret_bus_timeo),
  692. REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_s_llength),
  693. REG_ADDR(isp_mi_hdr_pic_width), REG_ADDR(isp_mi_hdr_pic_height), REG_ADDR(isp_mi_hdr_s_size_init),
  694. 0, HDR_WR_ENABLE_MASK, 0, HDR_WR_SWAP_RAW_MASK
  695. },
  696. {
  697. REG_ADDR(isp_mi_hdr_ret_bus_cfg), REG_ADDR(isp_mi_hdr_ret_bus_id), REG_ADDR(isp_mi_hdr_ret_bus_timeo),
  698. REG_ADDR(isp_mi_hdr_ctrl), REG_ADDR(isp_mi_hdr_fmt), 0, REG_ADDR(isp_mi_hdr_vs_llength),
  699. REG_ADDR(isp_mi_hdr_pic_width), REG_ADDR(isp_mi_hdr_pic_height), REG_ADDR(isp_mi_hdr_vs_size_init),
  700. 0, HDR_WR_ENABLE_MASK, 0, HDR_WR_SWAP_RAW_MASK
  701. },
  702. #endif
  703. };
  704. #endif
  705. if (!path->enable) {
  706. disable_bus_timeo_intr(dev, path_list[id].bus_timeo_addr);
  707. return;
  708. }
  709. if (path->hscale || path->vscale || dev->is.enable) {
  710. if (id <= ISP_MI_PATH_SP2_BP)
  711. isp_set_scaling(id, dev, dev->is.enable, dev->crop[id].enabled);
  712. else
  713. isp_set_scaling(id, dev, dev->is.enable, 0);
  714. }
  715. miv2_ctrl = isp_read_reg(dev, REG_ADDR(miv2_ctrl));
  716. if(path_list[id].bus_cfg_addr)
  717. bus_cfg = isp_read_reg(dev, path_list[id].bus_cfg_addr);
  718. format = isp_read_reg(dev, path_list[id].format_addr);
  719. if (path_list[id].format_conv_ctrl) {
  720. conv_format_ctrl = isp_read_reg(dev, path_list[id].format_conv_ctrl);
  721. }
  722. pr_debug("mi %s id %d fmt_bit[id].raw_bit 0x%08x miv2_ctrl 0x%08x ", __func__, id, path_list[id].raw_enable_bit, miv2_ctrl);
  723. path_ctrl = isp_read_reg(dev, path_list[id].path_ctrl_addr);
  724. switch (path->out_mode) {
  725. case IC_MI_DATAMODE_YUV444:
  726. mi_set_slice(&format, fmt_bit[id].yuv_fmt, 2);
  727. miv2_ctrl |= path_list[id].ycbcr_enable_bit;
  728. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_OUTPUT, 3);
  729. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_INPUT, 2);
  730. break;
  731. case IC_MI_DATAMODE_YUV422:
  732. mi_set_slice(&format, fmt_bit[id].yuv_fmt, 1);
  733. miv2_ctrl |= path_list[id].ycbcr_enable_bit;
  734. break;
  735. case IC_MI_DATAMODE_YUV420:
  736. mi_set_slice(&format, fmt_bit[id].yuv_fmt, 0);
  737. miv2_ctrl |= path_list[id].ycbcr_enable_bit;
  738. break;
  739. case IC_MI_DATAMODE_YUV400:
  740. case IC_MI_DATAMODE_JPEG:
  741. mi_set_slice(&format, fmt_bit[id].jdp_fmt, 1);
  742. REG_SET_SLICE(miv2_ctrl, MP_JDP_PATH_ENABLE, 1);
  743. break;
  744. case IC_MI_DATAMODE_RAW8:
  745. mi_set_slice(&format, fmt_bit[id].raw_bit, 0);
  746. miv2_ctrl |= path_list[id].raw_enable_bit;
  747. break;
  748. case IC_MI_DATAMODE_RAW10:
  749. mi_set_slice(&format, fmt_bit[id].raw_bit, 1);
  750. miv2_ctrl |= path_list[id].raw_enable_bit;
  751. mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  752. break;
  753. case IC_MI_DATAMODE_RAW12:
  754. #ifdef ISP_MI_HDR_RY
  755. if (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS) {
  756. mi_set_slice(&format, fmt_bit[id].raw_bit, 0);
  757. path_ctrl |= path_list[id].raw_enable_bit;
  758. //mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  759. }
  760. #endif
  761. if (id <= ISP_MI_PATH_PP) {
  762. mi_set_slice(&format, fmt_bit[id].raw_bit, 2);
  763. miv2_ctrl |= path_list[id].raw_enable_bit;
  764. mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  765. }
  766. break;
  767. case IC_MI_DATAMODE_RAW14:
  768. mi_set_slice(&format, fmt_bit[id].raw_bit, 3);
  769. miv2_ctrl |= path_list[id].raw_enable_bit;
  770. mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  771. break;
  772. case IC_MI_DATAMODE_RAW16:
  773. #ifdef ISP_MI_HDR_RY
  774. if (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS) {
  775. mi_set_slice(&format, fmt_bit[id].raw_bit, 1);
  776. path_ctrl |= path_list[id].raw_enable_bit;
  777. //mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  778. }
  779. #endif
  780. if (id <= ISP_MI_PATH_PP) {
  781. mi_set_slice(&format, fmt_bit[id].raw_bit, 4);
  782. miv2_ctrl |= path_list[id].raw_enable_bit;
  783. mi_set_slice(&bus_cfg, path_list[id].wr_raw_swap_bit, 1);
  784. }
  785. break;
  786. case IC_MI_DATAMODE_RGB888:
  787. mi_set_slice(&format, fmt_bit[id].yuv_fmt, 2);
  788. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_OUTPUT, 6);
  789. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_INPUT, 2);
  790. miv2_ctrl |= path_list[id].ycbcr_enable_bit;
  791. break;
  792. default:
  793. pr_err("mi %s unsupport format: %d", __func__, path->out_mode);
  794. return;
  795. }
  796. switch (path->data_layout) {
  797. case IC_MI_DATASTORAGE_PLANAR:
  798. mi_set_slice(&format, fmt_bit[id].yuv_str, 2);
  799. break;
  800. case IC_MI_DATASTORAGE_SEMIPLANAR:
  801. mi_set_slice(&format, fmt_bit[id].yuv_str, 0);
  802. break;
  803. case IC_MI_DATASTORAGE_INTERLEAVED:
  804. mi_set_slice(&format, fmt_bit[id].yuv_str, 1);
  805. break;
  806. default:
  807. break;
  808. }
  809. mi_set_slice(&format, fmt_bit[id].yuv_bit, path->yuv_bit);
  810. if(path->yuv_bit){
  811. if(path->data_alignMode){
  812. mi_set_slice(&format, fmt_bit[id].yuv_aligned, 1);
  813. }else{
  814. mi_set_slice(&format, fmt_bit[id].yuv_aligned, 0);
  815. }
  816. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_10_ENABLE, 1);
  817. REG_SET_SLICE(conv_format_ctrl, MRV_MRSZ_COVERT_10_METHOD, 0);
  818. }
  819. mi_set_slice(&format, fmt_bit[id].raw_aligned, path->data_alignMode);
  820. if (id == ISP_MI_PATH_MP)
  821. REG_SET_SLICE(bus_cfg, MP_WR_BURST_LEN, dev->mi.burst_len);
  822. REG_SET_SLICE(mcm_bus_cfg, MCM_WR_BURST_LEN, dev->mi.burst_len);
  823. if(path->yuv_bit){//
  824. if(path->data_alignMode){//aligned mode
  825. lval = (path->out_width + 12 - 1)/12;
  826. //printf("zw debug lval = 0x%x\n",lval);
  827. }else{ //unaligned mode
  828. lval = (path->out_width * 10 + 127)/128;
  829. }
  830. y_llength =lval<<4;
  831. //printf("zw debug y_llength = 0x%x\n",y_llength);
  832. }else{ //8bit output
  833. y_llength = ALIGN_16BYTE(path->out_width);
  834. }
  835. y_length_addr = path_list[id].y_length_addr;
  836. if (y_length_addr) {
  837. isp_write_reg(dev, y_length_addr, y_llength);
  838. isp_write_reg(dev, y_length_addr + 4, path->out_width);
  839. isp_write_reg(dev, y_length_addr + 8, path->out_height);
  840. isp_write_reg(dev, y_length_addr + 12,
  841. y_llength * path->out_height);
  842. }
  843. // aev2, 3dnr
  844. if (id == ISP_MI_PATH_MP) {
  845. if (dev->exp2.enable) {
  846. REG_SET_SLICE(miv2_ctrl, MP_JDP_PATH_ENABLE, 1);
  847. #ifdef ISP_AEV2_V2_RY
  848. REG_SET_SLICE(format, MP_WR_JDP_DP_BIT, 1);
  849. #endif
  850. } else {
  851. REG_SET_SLICE(miv2_ctrl, MP_JDP_PATH_ENABLE, 0);
  852. }
  853. }
  854. if ((id == ISP_MI_PATH_MP && (miv2_ctrl & MP_RAW_PATH_ENABLE_MASK)) ||
  855. (id == ISP_MI_PATH_SP2_BP && (miv2_ctrl & SP2_RAW_PATH_ENABLE_MASK))
  856. #ifdef ISP_MI_MCM_WR_RY
  857. || (id == ISP_MI_MCM_WR0 && (miv2_ctrl & MCM_RAW0_PATH_ENABLE_MASK)) ||
  858. (id == ISP_MI_MCM_WR1 && (miv2_ctrl & MCM_RAW1_PATH_ENABLE_MASK))
  859. #endif
  860. #ifdef ISP_MI_PP_WRITE_RY
  861. || (id == ISP_MI_PATH_PP && ((path->out_mode == IC_MI_DATAMODE_RAW8) ||
  862. (path->out_mode == IC_MI_DATAMODE_RAW10) || (path->out_mode == IC_MI_DATAMODE_RAW12) ||
  863. (path->out_mode == IC_MI_DATAMODE_RAW14) || (path->out_mode == IC_MI_DATAMODE_RAW16)))
  864. #endif
  865. #ifdef ISP_MI_HDR_RY
  866. || (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS)
  867. #endif
  868. ) {
  869. lval =
  870. calc_raw_lval(path->out_width, path->out_mode,
  871. path->data_alignMode);
  872. y_llength = lval <<4;
  873. isp_write_reg(dev, path_list[id].raw_llength_addr, y_llength);
  874. isp_write_reg(dev, path_list[id].raw_pic_width_addr, path->out_width);
  875. isp_write_reg(dev, path_list[id].raw_pic_height_addr, path->out_height);
  876. isp_write_reg(dev, path_list[id].raw_pic_size_addr, path->out_height * y_llength );
  877. #ifdef ISP_MI_MCM_WR_RY
  878. if (id == ISP_MI_MCM_WR0 || id == ISP_MI_MCM_WR1) {
  879. isp_write_reg(dev, REG_ADDR(miv2_mcm_raw0_lval_bytes), y_llength);
  880. }
  881. #endif
  882. #ifdef ISP_MI_PP_WRITE_RY
  883. //ppw line entry mode, llength need to align with 256.
  884. //llength is line length, lval is line availble data.
  885. #if 1/*should check by VV, if align with 256 is needed*/
  886. uint32_t line_num = isp_read_reg(dev, REG_ADDR(mi_sp1_ppw_ycbcr_entry_line_num));
  887. /*TODO shenweiyi to enable */
  888. if (line_num != 0) {
  889. y_llength = y_llength & 0xff ? (y_llength & 0xffffff00 + 0x100):y_llength;
  890. }
  891. isp_info("%s:line_num = %d y_llength = 0x%x\n", __func__, line_num, y_llength);
  892. isp_write_reg(dev, REG_ADDR(isp_mi_pp_y_llength), y_llength);
  893. isp_write_reg(dev, path_list[id].raw_pic_size_addr, path->out_height * y_llength );
  894. #else
  895. if (id == ISP_MI_PATH_PP) {
  896. uint32_t line_num = isp_read_reg(dev, REG_ADDR(mi_sp1_ppw_ycbcr_entry_line_num));
  897. if (line_num != 0) {
  898. y_llength = (y_llength & 0xff) ? ((y_llength + 0xff) &(~0xff)):y_llength;
  899. }
  900. isp_write_reg(dev, REG_ADDR(isp_mi_pp_y_llength), y_llength);
  901. isp_write_reg(dev, path_list[id].raw_pic_size_addr, path->out_height * y_llength );
  902. }
  903. #endif
  904. #endif
  905. #if defined(ISP_MI_HDR_RY)
  906. if (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS)
  907. isp_write_reg(dev, path_list[id].raw_llength_addr+4, y_llength);
  908. #endif
  909. }
  910. #ifdef ISP_MI_HDR_RY
  911. if (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS) {
  912. REG_SET_SLICE(path_ctrl, HDR_MI_CFG_UPD, 1);
  913. REG_SET_SLICE(path_ctrl, HDR_AUTO_UPDATE, 1);
  914. path_ctrl |= (HDR_INIT_OFFSET_EN_MASK | HDR_INIT_BASE_EN_MASK);
  915. }
  916. #endif
  917. if (id <= ISP_MI_PATH_PP) {
  918. REG_SET_SLICE(path_ctrl, MP_MI_CFG_UPD, 1);
  919. REG_SET_SLICE(path_ctrl, MP_AUTO_UPDATE, 1);
  920. //path_ctrl |= 0x05;
  921. path_ctrl |= (MP_INIT_BASE_EN_MASK | MP_INIT_OFFSET_EN_MASK);
  922. }
  923. #ifdef ISP_MI_MCM_WR_RY
  924. if (id <= ISP_MI_MCM_WR1 && id >= ISP_MI_MCM_WR0) {
  925. REG_SET_SLICE(path_ctrl, MCM_WR_CFG_UPD, 1);
  926. REG_SET_SLICE(path_ctrl, MCM_WR_AUTO_UPDATE, 1);
  927. //path_ctrl |= 0x05;
  928. path_ctrl |= (MCM_INIT_BASE_EN_MASK | MCM_INIT_OFFSET_EN_MASK);
  929. }
  930. #endif
  931. isp_info("%s:path_ctrl 0x%08x\n", __func__, path_ctrl);
  932. acq_proc = isp_read_reg(dev, REG_ADDR(isp_acq_prop));
  933. isp_write_reg(dev, REG_ADDR(isp_acq_prop),
  934. acq_proc & ~MRV_ISP_LATENCY_FIFO_SELECTION_MASK);
  935. bus_id = isp_read_reg(dev, path_list[id].bus_id_addr);
  936. if (id == ISP_MI_PATH_SP) {
  937. bus_id <<= 4;
  938. }
  939. bus_id |= MP_WR_ID_EN_MASK;
  940. if (id == ISP_MI_PATH_SP2_BP) {
  941. bus_id |= SP2_BUS_SW_EN_MASK;
  942. // REG_SET_SLICE(bus_cfg, SP2_WR_SWAP_Y, 1);
  943. #ifdef ISP_MI_HDR_RY
  944. } else if (id >= ISP_MI_HDR_L && id <= ISP_MI_HDR_VS ) {
  945. bus_id |= HDR_BUS_SW_EN_MASK;
  946. #endif
  947. } else {
  948. bus_id |= MP_BUS_SW_EN_MASK;
  949. }
  950. if (path_list[id].bus_id_addr)
  951. isp_write_reg(dev, path_list[id].bus_id_addr, bus_id);
  952. if (path_list[id].bus_cfg_addr)
  953. isp_write_reg(dev, path_list[id].bus_cfg_addr, bus_cfg);
  954. isp_write_reg(dev, REG_ADDR(miv2_mcm_bus_cfg), mcm_bus_cfg);
  955. #ifdef ISP_MI_PP_WRITE_RY
  956. isp_ctrl = isp_read_reg(dev, REG_ADDR(isp_ctrl));
  957. if (id == ISP_MI_PATH_PP && ((path->out_mode == IC_MI_DATAMODE_RAW8) ||
  958. (path->out_mode == IC_MI_DATAMODE_RAW10) || (path->out_mode == IC_MI_DATAMODE_RAW12) ||
  959. (path->out_mode == IC_MI_DATAMODE_RAW14) || (path->out_mode == IC_MI_DATAMODE_RAW16))) { //pp path output raw
  960. format |= PP_WR_RAW_SEL_MASK;
  961. REG_SET_SLICE(format, PP_WR_RAW_SEL, 1);
  962. REG_SET_SLICE(isp_ctrl, PP_WRITE_SEL, 0);
  963. isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
  964. } else {
  965. REG_SET_SLICE(format, PP_WR_RAW_SEL, 0);
  966. REG_SET_SLICE(isp_ctrl, PP_WRITE_SEL, 1);
  967. isp_write_reg(dev, REG_ADDR(isp_ctrl), isp_ctrl);
  968. }
  969. #endif
  970. isp_write_reg(dev, path_list[id].format_addr, format);
  971. isp_write_reg(dev, REG_ADDR(miv2_ctrl), miv2_ctrl);
  972. isp_write_reg(dev, path_list[id].path_ctrl_addr, path_ctrl);
  973. if (path_list[id].format_conv_ctrl)
  974. isp_write_reg(dev, path_list[id].format_conv_ctrl, conv_format_ctrl);
  975. }
  976. int isp_mi_start(struct isp_ic_dev *dev)
  977. {
  978. int i;
  979. struct isp_mi_context mi = *(&dev->mi);
  980. u32 imsc, miv2_mcm_bus_id;
  981. isp_info("enter %s\n", __func__);
  982. miv2_mcm_bus_id = isp_read_reg(dev, REG_ADDR(miv2_mcm_bus_id));
  983. miv2_mcm_bus_id |= MCM_BUS_SW_EN_MASK;
  984. isp_write_reg(dev, REG_ADDR(miv2_mcm_bus_id), miv2_mcm_bus_id);
  985. for (i = 0; i < ISP_MI_PATH_ID_MAX; i++) {
  986. set_data_path(i, &mi.path[i], dev);
  987. }
  988. imsc = isp_read_reg(dev, REG_ADDR(miv2_imsc));
  989. isp_write_reg(dev, REG_ADDR(miv2_imsc),
  990. imsc | (MP_YCBCR_FRAME_END_MASK | MP_RAW_FRAME_END_MASK |
  991. WRAP_MP_Y_MASK | WRAP_MP_CB_MASK | WRAP_MP_CR_MASK |
  992. WRAP_MP_RAW_MASK | WRAP_MP_JDP_MASK | MCM_RAW0_FRAME_END_MASK |
  993. SP1_YCBCR_FRAME_END_MASK | WRAP_SP1_Y_MASK |MCM_RAW1_FRAME_END_MASK|
  994. WRAP_SP1_CB_MASK | WRAP_SP1_CR_MASK |
  995. SP2_YCBCR_FRAME_END_MASK | WRAP_SP2_Y_MASK |
  996. WRAP_SP2_CB_MASK | WRAP_SP2_CR_MASK |
  997. SP2_RAW_FRAME_END_MASK | MP_JDP_FRAME_END_MASK));
  998. //isp_write_reg(dev, REG_ADDR(miv2_imsc1), 0x7ffffff);
  999. isp_write_reg(dev, REG_ADDR(miv2_imsc1), (MI_MP_BUS_TIMEO_MASK | MI_SP1_BUS_TIMEO_MASK | MI_SP2_BUS_TIMEO_MASK |
  1000. MI_MP_BUS_BUSERR_MASK | MI_SP1_BUS_BUSERR_MASK | MI_SP2_BUS_BUSERR_MASK));
  1001. #ifdef ISP_MI_PP_WRITE_RY
  1002. imsc = isp_read_reg(dev, REG_ADDR(miv2_imsc2));
  1003. isp_write_reg(dev, REG_ADDR(miv2_imsc2),
  1004. imsc | ( PPW_U_BUF_FULL_MASK | PPW_Y_BUF_FULL_MASK |
  1005. PPW_V_BUF_FULL_MASK | PPR_Y_BUF_FULL_MASK | SP2_RAW2_W_BUF_FULL_MASK |
  1006. SP2_RAW2_R_BUF_FULL_MASK | HDR_W_BUF_FULL_MASK | HDR_R_BUF_FULL_MASK |
  1007. WRAP_SP2_RAW_MASK | WRAP_PPW_CR_MASK | WRAP_PPW_CB_MASK | //WRAP_PPW_Y_MASK |
  1008. SP2_RAW2_FRAME_END_MASK | PPW_FRAME_END_MASK | HDR_VS_DMA_READY_MASK |
  1009. HDR_S_DMA_READY_MASK | HDR_L_DMA_READY_MASK | HDR_L_DMA_READY_MASK |
  1010. WRAP_HDR_VS_MASK | WRAP_HDR_S_MASK | WRAP_HDR_L_MASK | HDR_VS_FRAME_END_MASK |
  1011. HDR_S_FRAME_END_MASK | HDR_L_FRAME_END_MASK | MI_RT_BUS_BUSERR_MASK |
  1012. MI_RT_BUS_TIMEO_MASK));
  1013. #endif
  1014. isp_write_reg(dev, REG_ADDR(miv2_imsc3), 0x3f);
  1015. /*add by shenwuyi for ppline entry must close for sdk test case*/
  1016. #ifndef POST_ISP_SDK_TEST
  1017. isp_write_reg(dev, REG_ADDR(miv2_imsc), 0x19);
  1018. isp_write_reg(dev, REG_ADDR(miv2_imsc1), 0);
  1019. isp_write_reg(dev, REG_ADDR(miv2_imsc2), 0);
  1020. #endif
  1021. return 0;
  1022. }
  1023. int isp_mi_stop(struct isp_ic_dev *dev)
  1024. {
  1025. isp_info("enter %s\n", __func__);
  1026. #ifdef ISP_MI_PP_WRITE_RY
  1027. isp_write_reg(dev, REG_ADDR(miv2_imsc2), 0);
  1028. #endif
  1029. isp_write_reg(dev, REG_ADDR(miv2_imsc3), 0);
  1030. isp_write_reg(dev, REG_ADDR(miv2_imsc), 0);
  1031. isp_write_reg(dev, REG_ADDR(miv2_imsc1), 0);
  1032. isp_write_reg(dev, REG_ADDR(miv2_ctrl), 0UL);
  1033. return 0;
  1034. }
  1035. u32 isp_read_mi_irq(struct isp_ic_dev *dev)
  1036. {
  1037. return isp_read_reg(dev, REG_ADDR(miv2_mis));
  1038. }
  1039. void isp_reset_mi_irq(struct isp_ic_dev *dev, u32 icr)
  1040. {
  1041. isp_write_reg(dev, REG_ADDR(miv2_icr), icr);
  1042. }
  1043. int isp_set_bp_buffer(struct isp_ic_dev *dev, struct isp_bp_buffer_context *buf)
  1044. {
  1045. return 0;
  1046. }
  1047. #ifdef ISP_MI_PP_WRITE_RY
  1048. int isp_set_ppw_line_num(struct isp_ic_dev *dev)
  1049. {
  1050. if (dev == NULL) {
  1051. pr_err("Wrong input %s\n", __func__);
  1052. return -1;
  1053. }
  1054. isp_info("enter %s\n", __func__);
  1055. isp_write_reg(dev, REG_ADDR(mi_sp1_ppw_ycbcr_entry_line_num), dev->pp_write.entry_line_num);
  1056. isp_info("exit %s\n", __func__);
  1057. return 0;
  1058. }
  1059. int isp_get_ppw_pic_cnt(struct isp_ic_dev *dev, u16* pic_cnt)
  1060. {
  1061. if (dev == NULL) {
  1062. pr_err("Wrong input %s\n", __func__);
  1063. return -1;
  1064. }
  1065. isp_info("enter %s\n", __func__);
  1066. *pic_cnt = isp_read_reg(dev, REG_ADDR(mi_sp1_ppw_ycbcr_entry_pic_cnt));
  1067. isp_info("exit %s\n", __func__);
  1068. return 0;
  1069. }
  1070. #endif
  1071. #ifdef ISP_MI_PP_READ_RY
  1072. int isp_cfg_pp_dma_line_entry(struct isp_ic_dev *dev)
  1073. {
  1074. isp_info("enter %s\n", __func__);
  1075. uint32_t path_ctrl = isp_read_reg(dev, REG_ADDR(isp_mi_pp_ctrl));
  1076. pp_dma_line_entry_t* pp_dam_line_entry = &dev->pp_dma_line_entry;
  1077. if (dev == NULL) {
  1078. pr_err("Wrong input %s\n", __func__);
  1079. return -1;
  1080. }
  1081. isp_write_reg(dev, REG_ADDR(mi_pp_dma_y_entry_line_num), pp_dam_line_entry->entry_line_num);
  1082. isp_write_reg(dev, REG_ADDR(mi_pp_dma_y_buf_line_num), pp_dam_line_entry->buf_line_num);
  1083. #ifndef POST_ISP_SDK_TEST
  1084. isp_write_reg(dev, 0x00005598, pp_dam_line_entry->buf_addr);/*add by shenwuyi for line entry mode*/
  1085. mi_set_slice(&path_ctrl, PP_RD_YUV_CFG_UPDATE_MASK, 1);
  1086. isp_write_reg(dev, REG_ADDR(isp_mi_pp_ctrl), path_ctrl);
  1087. #endif
  1088. isp_info("exit %s\n", __func__);
  1089. return 0;
  1090. }
  1091. #endif
  1092. #endif